diff --git a/.commit-template b/.commit-template index 2c8b5cf89..4eba4eed5 100644 --- a/.commit-template +++ b/.commit-template @@ -1,23 +1,14 @@ -# *************** OpenPilot commits guidelines *************** +# *************** LibrePilot commits guidelines *************** # Each commit needs to have a message like the following sample: -# OP-1150 UI for thermal calibration: Connect State machine to UI +# LP-188 Determine AccelTau based on usage # # It needs to begin with a reference to one or more Jira tickets followed by a short description. # If needed add a longer description in the following lines, after an empty line. # -# Before committing, ensure your code is properly formatted using: +# Before committing, ensure your code is properly formatted using: # make uncrustify_all # You can format flight or ground code only using respectively # uncrustify_flight or uncrustify_ground -# -# To automatically create a review, append the following smart commit messages: -# +review OPReview -# -# To append the commit to an existing review, use the following smart commit message: -# +review OPReview-NNN -# For example "+review OPReview-609" -# -# *NOTE* leave an empty line between the commit message and "smart commit command" -# Smart commits commands need to starts immediately at first column + diff --git a/.drone.sec b/.drone.sec new file mode 100644 index 000000000..955632341 --- /dev/null +++ b/.drone.sec @@ -0,0 +1 @@ +eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.UPh8KqupamxDSZ-xztWqWKqG7ur8WGg4dW22PRVGchjWsMa_zyuTEEDkl67z_jdHKkxEerWE8J4sROWVixi_xWvEl7OgXlt7H9c4iWtGTyp7n9ibeS1wgDoYes3LbRu9lRTxiTb-8Y-MgY0zeAHTBIQHmECETKF_CE4QkPHjSQCfbb_chn4vIqryM11-QctxDwysR4VC5AO1uA4hB0RReixOuSQFI-LbuLvBozEgsrYe5dFo7-oQJt7-e2-UFoEhomTPZcWc02NznX-GjlaZxpxQQXra5NyN5--aiL2C8kcPYfnEfU4dYudNsm2tDlnxhBPA1Ji3FnDSBp_ZunsvRQ.GGds6H6tZW_Qzh2T.KjsjOsBbAmfhUIWYXJBMcrChr1ckykuPZ8XERPGWuSoMbXkklHGj0MCehIWNDuLX_wPM1wTvZE8unFJIYwYGybYQ8omAHDGOkEM3YDs6VnJ9Y8zBl6wnvTvtsQsrQWqU8vdodzSP62F81wCDCCauOFewz_gjzl6n_1Ajxj9CqTfCR17Gcuui6nrqkn0A5qikWuZz8qsUaQ94t0qVRWOFcZ4NQMH8NJwZCYW0JAAsvoQOidc2dB5zkwx3pzc2hItmzwZq3uVgWr5RFgp2LzBd.45hdSTLtI4gU9-GjkOlZ1A \ No newline at end of file diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 000000000..3cc9d4365 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,48 @@ +build: + image: teaci/msys$$arch + pull: true + shell: mingw$$arch + commands: + - if [ $$arch = 32 ]; then target=i686; fi + - if [ $$arch = 64 ]; then target=x86_64; fi + - echo -e "[librepilot-mingw]\nSigLevel = Optional TrustAll\nServer = http://download.librepilot.org/repo/mingw" >> /etc/pacman.conf + - pacman -Syu --noconfirm --noprogressbar --needed git unzip tar mingw-w64-${target}-toolchain mingw-w64-${target}-ccache mingw-w64-${target}-qt5 mingw-w64-${target}-SDL mingw-w64-${target}-mesa mingw-w64-${target}-openssl mingw-w64-${target}-gdal-minimal mingw-w64-${target}-OpenSceneGraph mingw-w64-${target}-osgearth + - mingw32-make all_sdk_install + - git config core.filemode false + - mingw32-make build-info && cat build/build-info.txt + - mingw32-make opfw_resource + - mingw32-make gcs + - mingw32-make package + - mv `ls build/LibrePilot-*.exe` build/$$BRANCH-$$COMMIT-$$arch-package.exe + +clone: + depth: 1000 + tags: true + +matrix: + arch: + - 32 + - 64 + +publish: + bintray: + username: marcproe + api_key: $$BINTRAY_API_KEY + artifacts: + - file: build/$$BRANCH-$$COMMIT-$$arch-package.exe + owner: librepilot + type: executable + repository: LibrePilot + package: next + version: Windows + publish: true + override: true + target: $$BRANCH-$${COMMIT:0:6}-$$arch-tea-ci-package.exe + +notify: + webhook: + urls: + - https://hooks.slack.com/services/$$SLACK_HOOK + content_type: application/json + template: > + {"text": "Tea-CI Build #{{ build.number }} finished with a {{ build.status }} status. If successful, the packages for {{ build.branch }} $${COMMIT:0:8} can be downloaded "} diff --git a/.gitattributes b/.gitattributes index 9b4c80545..cb13e8da3 100644 --- a/.gitattributes +++ b/.gitattributes @@ -32,3 +32,8 @@ /Makefile text eol=lf # More attributes are defined in per-directory .gitattributes which override this file + +# Not needed in source distribution for building GCS +/artwork/ export-ignore +/flight/ export-ignore +/hardware/ export-ignore diff --git a/.gitignore b/.gitignore index 303c236df..514d54238 100644 --- a/.gitignore +++ b/.gitignore @@ -5,8 +5,7 @@ /3rdparty # Ignore user config -config - +/config # Exclude temporary and system files Thumbs.db @@ -37,9 +36,10 @@ ground/gcs/.settings # Ignore .pro.user files *.pro.user - # Misc artifacts *.exe +*.log +*.opl /ground/gcs/share/translations/extract-mimetypes.xq /ground/gcs/src/experimental/tools/DocumentationHelper/ui_mainwindow.h /ground/gcs/src/libs/qextserialport/.hg @@ -59,8 +59,8 @@ ground/gcs/.settings /androidgcs/gen/ # Ignore Eclipse Projects and Metadata -/.cproject -/.project +.cproject +.project /.metadata /.settings /.pydevproject diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..06c8fe0e8 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,22 @@ +language: cpp + +sudo: required + +dist: trusty + +before_install: + - sudo add-apt-repository ppa:librepilot/tools -y + - sudo apt-get update -q + - sudo apt-get install -y libc6-i386 libudev-dev libusb-1.0-0-dev libsdl1.2-dev python libopenscenegraph-dev libosgearth-dev qt56-meta-minimal qt56svg qt56script qt56serialport qt56multimedia qt56translations qt56tools + - make build_sdk_install + +script: + - make config_new CCACHE=ccache + - make all_flight + - make opfw_resource + - make gcs + +git: + depth: 500 + +cache: ccache diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 15544b42b..6f3f11e01 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,40 +1,82 @@ -How to build from source? -========================= +# How to build from source? -Both development environment and GCS are supported on Windows, Linux and Mac OS X +Both development environment and GCS are supported on Windows, Linux and Mac OS X. + +# Install prerequisites The first step is to Install all OS specific prerequisites. -###Mac OS X -Install XCode and its relatated command line tools (follow Apple documentation). -Install git, curl and p7zip. You can use brew `brew install git curl p7zip` or macport: `sudo port install git curl p7zip` -###Ubuntu - sudo apt-get install git build-essential curl gdb wget debhelper p7zip-full unzip flex bison libsdl1.2-dev libudev-dev libusb-1.0-0-dev libc6-i386 mesa-common-dev +## Mac OS X + +Install XCode and its relatated command line tools (follow Apple documentation). Install git, curl and p7zip. + +You can use brew with `brew install git curl p7zip` or macport with `sudo port install git curl p7zip`. -###Windows -Install [msysGIT](https://msysgit.github.io/) under `C:\git` +## Ubuntu -Clone LibrePilot Git repository. -Open Git Bash and run + sudo apt-get install git build-essential curl gdb wget debhelper p7zip-full unzip flex bison libsdl1.2-dev libudev-dev libusb-1.0-0-dev libc6-i386 mesa-common-dev - cd /path/to/LibrePilot_root - ./make/scripts/win_sdk_install.sh -You can build using the `/path/to/LibrePilot_root/make/winx86/bin/make` wrapper to call `mingw32-make.exe` as: +## Windows - ./make/winx86/bin/make all_sdk_install -or call `mingw32-make` directly +### Install [Msys2](https://msys2.github.io/) - mingw32-make all_sdk_install +Follow the instructions on the web site. You can either install the i686 (Win32) or x86_64 (Win64) version. +It is recommended to go for the Win64 Shell if possible. +The x86_64 version has both Win32 and Win64 shells and it is possible to build both i686 and x86_64 applications. -##Setup the build environment and build -The `all_sdk_install` target will automatically retrieve and install all needed tools (qt, arm gcc etc.) in a local folder `/path/to/LibrePilot_root/tools` +### Add the LibrePilot MinGW package repository +Add the following lines at the end of your /etc/pacman.conf file: + + [librepilot-mingw] + SigLevel = Optional TrustAll + Server = http://download.librepilot.org/repo/mingw + +### Install required packages + +#### For i686 applications + +Start a MinGW-w64 Win64 Shell or a MinGW-w64 Win32 Shell. + + pacman -Sy + pacman -S --needed git unzip tar mingw-w64-i686-toolchain mingw-w64-i686-ccache mingw-w64-i686-qt5 mingw-w64-i686-SDL mingw-w64-i686-mesa mingw-w64-i686-openssl mingw-w64-i686-gdal-minimal mingw-w64-i686-OpenSceneGraph mingw-w64-i686-osgearth + +Optionally install debug packages: + + pacman -S --needed mingw-w64-i686-OpenSceneGraph-debug mingw-w64-i686-osgearth-debug + +#### For x86_64 applications + +Start a MinGW-w64 Win64 Shell. + + pacman -Sy + pacman -S --needed git unzip tar mingw-w64-x86_64-toolchain mingw-w64-x86_64-ccache mingw-w64-x86_64-qt5 mingw-w64-x86_64-SDL mingw-w64-x86_64-mesa mingw-w64-x86_64-openssl mingw-w64-x86_64-gdal-minimal mingw-w64-x86_64-OpenSceneGraph mingw-w64-x86_64-osgearth + +Optionally install debug packages: + + pacman -S --needed mingw-w64-x86_64-OpenSceneGraph-debug mingw-w64-x86_64-osgearth-debug + +**NOTE** On Windows you need to run the mingw version of make, which is `mingw32-make` + + +# Setup the build environment and build + +The `all_sdk_install` target will automatically retrieve and install all needed tools (qt, arm gcc, etc.) in a local folder `/path/to/LibrePilot_root/tools` + +## Ubuntu / Mac OS X make all_sdk_install make package +## Windows + + mingw32-make all_sdk_install + mingw32-make package + The `package` target will build the complete installable package for the current platform. -Run make with no arguments to show the complete list of supported targets. +You can build the `all` target to just build the software. + +Run `make` with no arguments to show the complete list of supported targets. diff --git a/CREDITS.txt b/CREDITS.txt index b405a4d11..45d4a9c37 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -3,6 +3,7 @@ Sergiy Anikeyev David Ankers Fredrik Arvidsson Pedro Assuncao +Rafael Bachmann Werner Backes Jose Barros Alex Beck @@ -24,6 +25,7 @@ James Cotton Kalyn Doerr Steve Doll James Duley +Heikko Ellermaa Piotr Esden-Tempski Steve Evans Peter Farnworth @@ -43,6 +45,7 @@ Nuno Guedes Peter Gunnarsson Erik Gustavsson Dean Hall +Harold Hankins Joe Hlebasko Andy Honecker Patrick Huebner @@ -50,6 +53,7 @@ Ryan Hunt Mark James Paul Jewell Michael Johnston +Mateusz Kaduk Stefan Karlsson Ricky King Thorsten Klose @@ -68,6 +72,7 @@ Pablo Lema Matt Lipski David Llama Jasper Van Loenen +Ákos Máté Ben Matthews Greg Matthews Guy McCaldin @@ -79,6 +84,7 @@ Ken Northup Craig Nuttall Bertrand Oresve Angus Peart +Pablo Francisco Pérez Hidalgo John Pike Jorge Pombo Marcos Dmytro Poplavskiy @@ -116,9 +122,12 @@ Kevin Vertucio Alex Vrubel Mike Walters Sam Wang +Tianhe Wang Brian Webb Justin Welander Mat Wellington Kendal Wells David Willis Dmitriy Zaitsev +Vladimir Zidar + diff --git a/Makefile b/Makefile index 7184cfab2..4fc9f0369 100644 --- a/Makefile +++ b/Makefile @@ -78,14 +78,10 @@ endef define DESCRIPTION_LONG := The LibrePilot open source project was founded in July 2015. It focuses on research and development of software and hardware to be used in a variety of applications including vehicle control and stabilization, unmanned autonomous vehicles and robotics. -One of the project’s primary goals is to provide an open and collaborative environment making it the ideal home for development of innovative ideas. +One of the project's primary goals is to provide an open and collaborative environment making it the ideal home for development of innovative ideas. endef -# Set up default build configurations (debug | release) -GCS_BUILD_CONF := release -GOOGLE_API_VERSION := 14 - # Clean out undesirable variables from the environment and command-line # to remove the chance that they will cause problems with our build define SANITIZE_VAR @@ -110,15 +106,6 @@ $(foreach var, $(SANITIZE_GCC_VARS), $(eval $(call SANITIZE_VAR,$(var),disallowe SANITIZE_DEPRECATED_VARS := USE_BOOTLOADER CLEAN_BUILD $(foreach var, $(SANITIZE_DEPRECATED_VARS), $(eval $(call SANITIZE_VAR,$(var),deprecated))) -# Make sure this isn't being run as root unless installing (no whoami on Windows, but that is ok here) -ifeq ($(shell whoami 2>/dev/null),root) - ifeq ($(filter install uninstall,$(MAKECMDGOALS)),) - ifndef FAKEROOTKEY - $(error You should not be running this as root) - endif - endif -endif - # Decide on a verbosity level based on the V= parameter export AT := @ ifndef V @@ -130,14 +117,7 @@ else ifeq ($(V), 0) else ifeq ($(V), 1) endif -# Make sure we know few things about the architecture before including -# the tools.mk to ensure that we download/install the right tools. -UNAME := $(shell uname) -ARCH := $(shell uname -m) -# Here and everywhere if not Linux or Mac then assume Windows -ifeq ($(filter Linux Darwin, $(UNAME)), ) - UNAME := Windows -endif +ARCH := $(call get_arch) # Include tools installers include $(ROOT_DIR)/make/tools.mk @@ -147,18 +127,38 @@ include $(ROOT_DIR)/make/tools.mk # We almost need to consider autoconf/automake instead of this ifeq ($(UNAME), Linux) - QT_SPEC := linux-g++ - UAVOBJGENERATOR := $(BUILD_DIR)/uavobjgenerator/uavobjgenerator + UAVOBJGENERATOR := $(BUILD_DIR)/uavobjgenerator/uavobjgenerator + GCS_WITH_OSG := 1 + GCS_WITH_OSGEARTH := 1 + GCS_COPY_OSG := 0 else ifeq ($(UNAME), Darwin) - QT_SPEC := macx-g++ - UAVOBJGENERATOR := $(BUILD_DIR)/uavobjgenerator/uavobjgenerator + UAVOBJGENERATOR := $(BUILD_DIR)/uavobjgenerator/uavobjgenerator + GCS_WITH_OSG := 1 + GCS_WITH_OSGEARTH := 0 + GCS_COPY_OSG := 1 else ifeq ($(UNAME), Windows) - QT_SPEC := win32-g++ UAVOBJGENERATOR := $(BUILD_DIR)/uavobjgenerator/uavobjgenerator.exe + GCS_WITH_OSG := 1 + GCS_WITH_OSGEARTH := 1 + GCS_COPY_OSG := 1 endif export UAVOBJGENERATOR +# Set up default build configurations (debug | release) +GCS_BUILD_CONF := release + +# Set extra configuration +ifeq ($(GCS_WITH_OSG), 1) + GCS_EXTRA_CONF += osg + ifeq ($(GCS_COPY_OSG), 1) + GCS_EXTRA_CONF += copy_osg + endif + ifeq ($(GCS_WITH_OSGEARTH), 1) + GCS_EXTRA_CONF += osgearth + endif +endif + ############################## # # All targets @@ -192,7 +192,7 @@ uavobjgenerator: $(UAVOBJGENERATOR) $(UAVOBJGENERATOR): | $(UAVOBJGENERATOR_DIR) $(V1) cd $(UAVOBJGENERATOR_DIR) && \ ( [ -f Makefile ] || $(QMAKE) $(ROOT_DIR)/ground/uavobjgenerator/uavobjgenerator.pro \ - -spec $(QT_SPEC) CONFIG+=$(GCS_BUILD_CONF) CONFIG+=$(GCS_SILENT) ) && \ + CONFIG+='$(GCS_BUILD_CONF) $(GCS_EXTRA_CONF)' ) && \ $(MAKE) --no-print-directory -w UAVOBJ_TARGETS := gcs flight python matlab java wireshark @@ -240,7 +240,8 @@ endif FLIGHT_OUT_DIR := $(BUILD_DIR)/firmware DIRS += $(FLIGHT_OUT_DIR) -include $(ROOT_DIR)/flight/Makefile +# Might not be here in source package +-include $(ROOT_DIR)/flight/Makefile ############################## # @@ -251,10 +252,8 @@ include $(ROOT_DIR)/flight/Makefile .PHONY: all_ground all_ground: gcs uploader -ifeq ($(V), 1) - GCS_SILENT := -else - GCS_SILENT := silent +ifneq ($(V), 1) + GCS_EXTRA_CONF += silent endif GCS_DIR := $(BUILD_DIR)/$(GCS_SMALL_NAME)_$(GCS_BUILD_CONF) @@ -266,7 +265,7 @@ GCS_MAKEFILE := $(GCS_DIR)/Makefile gcs_qmake $(GCS_MAKEFILE): | $(GCS_DIR) $(V1) cd $(GCS_DIR) && \ $(QMAKE) $(ROOT_DIR)/ground/gcs/gcs.pro \ - -spec $(QT_SPEC) -r CONFIG+=$(GCS_BUILD_CONF) CONFIG+=$(GCS_SILENT) \ + -r CONFIG+='$(GCS_BUILD_CONF) $(GCS_EXTRA_CONF)' \ 'GCS_BIG_NAME="$(GCS_BIG_NAME)"' GCS_SMALL_NAME=$(GCS_SMALL_NAME) \ 'ORG_BIG_NAME="$(ORG_BIG_NAME)"' ORG_SMALL_NAME=$(ORG_SMALL_NAME) \ 'WIKI_URL_ROOT="$(WIKI_URL_ROOT)"' \ @@ -300,7 +299,7 @@ UPLOADER_MAKEFILE := $(UPLOADER_DIR)/Makefile uploader_qmake $(UPLOADER_MAKEFILE): | $(UPLOADER_DIR) $(V1) cd $(UPLOADER_DIR) && \ $(QMAKE) $(ROOT_DIR)/ground/gcs/src/experimental/USB_UPLOAD_TOOL/upload.pro \ - -spec $(QT_SPEC) -r CONFIG+=$(GCS_BUILD_CONF) CONFIG+=$(GCS_SILENT) $(GCS_QMAKE_OPTS) + -r CONFIG+='$(GCS_BUILD_CONF) $(GCS_EXTRA_CONF)' $(GCS_QMAKE_OPTS) .PHONY: uploader uploader: $(UPLOADER_MAKEFILE) @@ -312,174 +311,6 @@ uploader_clean: $(V1) [ ! -d "$(UPLOADER_DIR)" ] || $(RM) -r "$(UPLOADER_DIR)" -# We want to take snapshots of the UAVOs at each point that they change -# to allow the GCS to be compatible with as many versions as possible. -# We always include a pseudo collection called "srctree" which represents -# the UAVOs in the source tree. So not necessary to add current tree UAVO -# hash here, it is always included. - -# Find the git hashes of each commit that changes uavobjects with: -# git log --format=%h -- shared/uavobjectdefinition/ | head -n 2 -# List only UAVO hashes of past releases, do not list current hash. -# Past compatible versions are so far: RELEASE-12.10.2 -UAVO_GIT_VERSIONS := 5e14f53 - -# All versions includes also the current source tree UAVO hash -UAVO_ALL_VERSIONS := $(UAVO_GIT_VERSIONS) srctree - -# This is where the UAVO collections are stored -UAVO_COLLECTION_DIR := $(BUILD_DIR)/uavo-collections - -# $(1) git hash of a UAVO snapshot -define UAVO_COLLECTION_GIT_TEMPLATE - -# Make the output directory that will contain all of the synthetics for the -# uavo collection referenced by the git hash $(1) -$$(UAVO_COLLECTION_DIR)/$(1): - $$(V1) $(MKDIR) -p $$(UAVO_COLLECTION_DIR)/$(1) - -# Extract the snapshot of shared/uavobjectdefinition from git hash $(1) -$$(UAVO_COLLECTION_DIR)/$(1)/uavo-xml.tar: | $$(UAVO_COLLECTION_DIR)/$(1) -$$(UAVO_COLLECTION_DIR)/$(1)/uavo-xml.tar: - $$(V0) @$(ECHO) " UAVOTAR $(1)" - $$(V1) $(GIT) archive $(1) -o $$@ -- shared/uavobjectdefinition/ - -# Extract the uavo xml files from our snapshot -$$(UAVO_COLLECTION_DIR)/$(1)/uavo-xml: $$(UAVO_COLLECTION_DIR)/$(1)/uavo-xml.tar - $$(V0) @$(ECHO) " UAVOUNTAR $(1)" - $$(V1) $(RM) -rf $$@ - $$(V1) $(MKDIR) -p $$@ - $$(V1) $(TAR) -C $$(call toprel, $$@) -xf $$(call toprel, $$<) || $(RM) -rf $$@ -endef - -# Map the current working directory into the set of UAVO collections -$(UAVO_COLLECTION_DIR)/srctree: - $(V1) $(MKDIR) -p $@ - -$(UAVO_COLLECTION_DIR)/srctree/uavo-xml: | $(UAVO_COLLECTION_DIR)/srctree -$(UAVO_COLLECTION_DIR)/srctree/uavo-xml: $(UAVOBJ_XML_DIR) - $(V1) $(LN) -sf $(ROOT_DIR) $(UAVO_COLLECTION_DIR)/srctree/uavo-xml - -# $(1) git hash (or symbolic name) of a UAVO snapshot -define UAVO_COLLECTION_BUILD_TEMPLATE - -# This leaves us with a (broken) symlink that points to the full sha1sum of the collection -$$(UAVO_COLLECTION_DIR)/$(1)/uavohash: $$(UAVO_COLLECTION_DIR)/$(1)/uavo-xml - # Compute the sha1 hash for this UAVO collection - # The sed bit truncates the UAVO hash to 16 hex digits - $$(V1) $$(VERSION_INFO) \ - --uavodir=$$(UAVO_COLLECTION_DIR)/$(1)/uavo-xml/shared/uavobjectdefinition \ - --format='$$$${UAVO_HASH}' | \ - $(SED) -e 's|\(................\).*|\1|' > $$@ - - $$(V0) @$(ECHO) " UAVOHASH $(1) ->" $$$$(cat $$(UAVO_COLLECTION_DIR)/$(1)/uavohash) - -# Generate the java uavobjects for this UAVO collection -$$(UAVO_COLLECTION_DIR)/$(1)/java-build/java: $$(UAVO_COLLECTION_DIR)/$(1)/uavohash - $$(V0) @$(ECHO) " UAVOJAVA $(1) " $$$$(cat $$(UAVO_COLLECTION_DIR)/$(1)/uavohash) - $$(V1) $(MKDIR) -p $$@ - $$(V1) ( \ - cd $$(UAVO_COLLECTION_DIR)/$(1)/java-build && \ - $$(UAVOBJGENERATOR) -java $$(UAVO_COLLECTION_DIR)/$(1)/uavo-xml/shared/uavobjectdefinition $$(ROOT_DIR) ; \ - ) - -# Build a jar file for this UAVO collection -$$(UAVO_COLLECTION_DIR)/$(1)/java-build/uavobjects.jar: | $$(ANDROIDGCS_ASSETS_DIR)/uavos -$$(UAVO_COLLECTION_DIR)/$(1)/java-build/uavobjects.jar: $$(UAVO_COLLECTION_DIR)/$(1)/java-build/java - $$(V0) @$(ECHO) " UAVOJAR $(1) " $$$$(cat $$(UAVO_COLLECTION_DIR)/$(1)/uavohash) - $$(V1) ( \ - HASH=$$$$(cat $$(UAVO_COLLECTION_DIR)/$(1)/uavohash) && \ - cd $$(UAVO_COLLECTION_DIR)/$(1)/java-build && \ - $(JAVAC) java/*.java \ - $$(ROOT_DIR)/androidgcs/src/org/openpilot/uavtalk/UAVDataObject.java \ - $$(ROOT_DIR)/androidgcs/src/org/openpilot/uavtalk/UAVObject*.java \ - $$(ROOT_DIR)/androidgcs/src/org/openpilot/uavtalk/UAVMetaObject.java \ - -d . && \ - find ./org/openpilot/uavtalk/uavobjects -type f -name '*.class' > classlist.txt && \ - $(JAR) cf tmp_uavobjects.jar @classlist.txt && \ - $$(ANDROID_DX) \ - --dex \ - --output $$(ANDROIDGCS_ASSETS_DIR)/uavos/$$$${HASH}.jar \ - tmp_uavobjects.jar && \ - $(LN) -sf $$(ANDROIDGCS_ASSETS_DIR)/uavos/$$$${HASH}.jar uavobjects.jar \ - ) - -endef - -# One of these for each element of UAVO_GIT_VERSIONS so we can extract the UAVOs from git -$(foreach githash, $(UAVO_GIT_VERSIONS), $(eval $(call UAVO_COLLECTION_GIT_TEMPLATE,$(githash)))) - -# One of these for each UAVO_ALL_VERSIONS which includes the ones in the srctree -$(foreach githash, $(UAVO_ALL_VERSIONS), $(eval $(call UAVO_COLLECTION_BUILD_TEMPLATE,$(githash)))) - -.PHONY: uavo-collections_java -uavo-collections_java: $(foreach githash, $(UAVO_ALL_VERSIONS), $(UAVO_COLLECTION_DIR)/$(githash)/java-build/uavobjects.jar) - -.PHONY: uavo-collections -uavo-collections: uavo-collections_java - -.PHONY: uavo-collections_clean -uavo-collections_clean: - @$(ECHO) " CLEAN $(call toprel, $(UAVO_COLLECTION_DIR))" - $(V1) [ ! -d "$(UAVO_COLLECTION_DIR)" ] || $(RM) -r $(UAVO_COLLECTION_DIR) - -############################## -# -# Unit Tests -# -############################## - -ALL_UNITTESTS := logfs math lednotification - -# Build the directory for the unit tests -UT_OUT_DIR := $(BUILD_DIR)/unit_tests -DIRS += $(UT_OUT_DIR) - -.PHONY: all_ut -all_ut: $(addsuffix _elf, $(addprefix ut_, $(ALL_UNITTESTS))) - -.PHONY: all_ut_xml -all_ut_xml: $(addsuffix _xml, $(addprefix ut_, $(ALL_UNITTESTS))) - -.PHONY: all_ut_run -all_ut_run: $(addsuffix _run, $(addprefix ut_, $(ALL_UNITTESTS))) - -.PHONY: all_ut_clean -all_ut_clean: - @$(ECHO) " CLEAN $(call toprel, $(UT_OUT_DIR))" - $(V1) [ ! -d "$(UT_OUT_DIR)" ] || $(RM) -r "$(UT_OUT_DIR)" - -# $(1) = Unit test name -define UT_TEMPLATE -.PHONY: ut_$(1) -ut_$(1): ut_$(1)_run - -ut_$(1)_%: $$(UT_OUT_DIR) - $(V1) $(MKDIR) -p $(UT_OUT_DIR)/$(1) - $(V1) cd $(ROOT_DIR)/flight/tests/$(1) && \ - $$(MAKE) -r --no-print-directory \ - BUILD_TYPE=ut \ - BOARD_SHORT_NAME=$(1) \ - TOPDIR=$(ROOT_DIR)/flight/tests/$(1) \ - OUTDIR="$(UT_OUT_DIR)/$(1)" \ - TARGET=$(1) \ - $$* - -.PHONY: ut_$(1)_clean -ut_$(1)_clean: - @$(ECHO) " CLEAN $(call toprel, $(UT_OUT_DIR)/$(1))" - $(V1) [ ! -d "$(UT_OUT_DIR)/$(1)" ] || $(RM) -r "$(UT_OUT_DIR)/$(1)" -endef - -# Expand the unittest rules -$(foreach ut, $(ALL_UNITTESTS), $(eval $(call UT_TEMPLATE,$(ut)))) - -# Disable parallel make when the all_ut_run target is requested otherwise the TAP -# output is interleaved with the rest of the make output. -ifneq ($(strip $(filter all_ut_run,$(MAKECMDGOALS))),) -.NOTPARALLEL: - $(info $(EMPTY) NOTE Parallel make disabled by all_ut_run target so we have sane console output) -endif ############################## # @@ -487,7 +318,7 @@ endif # ############################## # Firmware files to package -PACKAGE_FW_TARGETS := fw_coptercontrol fw_oplinkmini fw_revolution fw_osd fw_revoproto fw_gpsplatinum fw_revonano +PACKAGE_FW_TARGETS := fw_coptercontrol fw_oplinkmini fw_revolution fw_osd fw_revoproto fw_gpsplatinum fw_revonano fw_sparky2 # Rules to generate GCS resources used to embed firmware binaries into the GCS. # They are used later by the vehicle setup wizard to update board firmware. @@ -506,7 +337,7 @@ OPFW_FILES := $(foreach fw_targ, $(PACKAGE_FW_TARGETS), $(FIRMWARE_DIR)/$(fw_tar OPFW_CONTENTS := \ \ \ - $(foreach fw_file, $(OPFW_FILES), $(fw_file)) \ + $(foreach fw_file, $(OPFW_FILES), $(call system_path,$(fw_file))) \ \ @@ -550,19 +381,22 @@ include $(ROOT_DIR)/package/$(UNAME).mk # Source for distribution # ############################## -$(DIST_VER_INFO): .git/index | $(DIST_DIR) +FORCE: + +$(DIST_VER_INFO): FORCE | $(DIST_DIR) $(V1) $(VERSION_INFO) --jsonpath="$(DIST_DIR)" -$(DIST_TAR): $(DIST_VER_INFO) .git/index | $(DIST_DIR) +$(DIST_TAR): $(DIST_VER_INFO) | $(DIST_DIR) @$(ECHO) " SOURCE FOR DISTRIBUTION $(call toprel, $(DIST_TAR))" $(V1) git archive --prefix="$(PACKAGE_NAME)/" -o "$(DIST_TAR)" HEAD $(V1) tar --append --file="$(DIST_TAR)" \ + --owner=root --group=root --mtime="`git show -s --format=%ci`" \ --transform='s,.*version-info.json,$(PACKAGE_NAME)/version-info.json,' \ $(call toprel, "$(DIST_VER_INFO)") $(DIST_TAR_GZ): $(DIST_TAR) @$(ECHO) " SOURCE FOR DISTRIBUTION $(call toprel, $(DIST_TAR_GZ))" - $(V1) gzip -kf "$(DIST_TAR)" + $(V1) gzip -knf "$(DIST_TAR)" .PHONY: dist_tar_gz dist_tar_gz: $(DIST_TAR_GZ) @@ -574,12 +408,14 @@ dist: dist_tar_gz $(FW_DIST_TAR): $(PACKAGE_FW_TARGETS) | $(DIST_DIR) @$(ECHO) " FIRMWARE FOR DISTRIBUTION $(call toprel, $(FW_DIST_TAR))" $(V1) tar -c --file="$(FW_DIST_TAR)" --directory=$(FLIGHT_OUT_DIR) \ + --owner=root --group=root --mtime="`git show -s --format=%ci`" \ --transform='s,^,firmware/,' \ + --force-local \ $(foreach fw_targ,$(PACKAGE_FW_TARGETS),$(fw_targ)/$(fw_targ).opfw) $(FW_DIST_TAR_GZ): $(FW_DIST_TAR) @$(ECHO) " FIRMWARE FOR DISTRIBUTION $(call toprel, $(FW_DIST_TAR_GZ))" - $(V1) gzip -kf "$(FW_DIST_TAR)" + $(V1) gzip -knf "$(FW_DIST_TAR)" .PHONY: fw_dist_tar_gz fw_dist_tar_gz: $(FW_DIST_TAR_GZ) @@ -604,6 +440,9 @@ define UNCRUSTIFY_TEMPLATE uncrustify_$(1): @$(ECHO) "Auto-formatting $(1) source code" $(V1) UNCRUSTIFY_CONFIG="$(ROOT_DIR)/make/uncrustify/uncrustify.cfg" $(SHELL) make/scripts/uncrustify.sh $(call toprel, $(2)) + +.PHONY: pretty_$(1) +pretty_$(1): uncrustify_$(1) endef $(foreach uncrustify_targ, $(UNCRUSTIFY_TARGETS), $(eval $(call UNCRUSTIFY_TEMPLATE,$(uncrustify_targ),$(ROOT_DIR)/$(uncrustify_targ)))) @@ -611,6 +450,9 @@ $(foreach uncrustify_targ, $(UNCRUSTIFY_TARGETS), $(eval $(call UNCRUSTIFY_TEMPL .PHONY: uncrustify_all uncrustify_all: $(addprefix uncrustify_,$(UNCRUSTIFY_TARGETS)) +.PHONY: pretty +pretty: $(addprefix pretty_,$(UNCRUSTIFY_TARGETS)) + ############################## # # Doxygen documentation @@ -668,8 +510,10 @@ build-info: | $(BUILD_DIR) # ############################## -CONFIG_OPTS := $(addsuffix \n,$(MAKEOVERRIDES)) -CONFIG_OPTS := $(addprefix override$(SPACE),$(CONFIG_OPTS)) +CONFIG_OPTS := $(subst \$(SPACE),%SPACE_PLACEHOLDER%,$(MAKEOVERRIDES)) +CONFIG_OPTS := $(addprefix override%SPACE_PLACEHOLDER%,$(CONFIG_OPTS)) +CONFIG_OPTS := $(subst $(SPACE),\n,$(CONFIG_OPTS))\n +CONFIG_OPTS := $(subst %SPACE_PLACEHOLDER%,$(SPACE),$(CONFIG_OPTS)) .PHONY: config_new config_new: @@ -681,12 +525,59 @@ config_append: .PHONY: config_show config_show: - @cat $(CONFIG_FILE) + @cat $(CONFIG_FILE) | sed 's/override *//' .PHONY: config_clean config_clean: rm -f $(CONFIG_FILE) +.PHONY: config_help +config_help: + @$(ECHO) " The build system has a simple system for persistent configuration" + @$(ECHO) + @$(ECHO) " To set persistent configuration variables you, for example, do:" + @$(ECHO) " $(MAKE) config_new CCACHE=ccache GCS_WITH_OSG=0" + @$(ECHO) + @$(ECHO) " To add to the existing configuration do:" + @$(ECHO) " $(MAKE) config_append GCS_BUILD_CONF=debug" + @$(ECHO) + @$(ECHO) " To reset the configuration to defaults do:" + @$(ECHO) " $(MAKE) config_clean" + @$(ECHO) + @$(ECHO) " To show the current configuration:" + @$(ECHO) " $(MAKE) config_show" + @$(ECHO) + @$(ECHO) " You can override any make variable this way, but these are the useful ones" + @$(ECHO) " shown with their current (or default values):" + @$(ECHO) + @$(ECHO) " GCS_BUILD_CONF=$(GCS_BUILD_CONF)" + @$(ECHO) " GCS build type" + @$(ECHO) " Options: debug or release" + @$(ECHO) + @$(ECHO) " GCS_WITH_OSG=$(GCS_WITH_OSG)" + @$(ECHO) " Build the GCS with OpenSceneGraph support, this enables the PFD Model View" + @$(ECHO) " Options: 0 or 1" + @$(ECHO) + @$(ECHO) " GCS_WITH_OSGEARTH=$(GCS_WITH_OSGEARTH)" + @$(ECHO) " Build the GCS with osgEarth support, this enables extra PFD terrain views" + @$(ECHO) " Options: 0 or 1" + @$(ECHO) + @$(ECHO) " GCS_COPY_OSG=$(GCS_COPY_OSG)" + @$(ECHO) " Copy OpenSceneGraph/osgEarth libraries into the build" + @$(ECHO) " (Needed unless using system versions)" + @$(ECHO) " Options: 0 or 1" + @$(ECHO) + @$(ECHO) " CCACHE=$(CCACHE)" + @$(ECHO) " A prefix to compiler invocations, usually 'ccache' or 'path/to/ccache'" + @$(ECHO) + @$(ECHO) " QMAKE=$(QMAKE)" + @$(ECHO) " How to invoke qmake, usually 'qmake', 'qmake-qt5' or 'path/to/qmake'" + @$(ECHO) + @$(ECHO) " WITH_PREBUILT_FIRMWARE=$(WITH_PREBUILT_FIRMWARE)" + @$(ECHO) " Set to path of prebuilt firmware or empty to build firmware when needed" +# TODO: add other things like downloads and tools directories, linux make install parameters + + ############################## # @@ -721,9 +612,7 @@ help: @$(ECHO) " arm_sdk_install - Install the GNU ARM gcc toolchain" @$(ECHO) " qt_sdk_install - Install the QT development tools" @$(ECHO) " nsis_install - Install the NSIS Unicode (Windows only)" - @$(ECHO) " sdl_install - Install the SDL library (Windows only)" @$(ECHO) " mesawin_install - Install the OpenGL32 DLL (Windows only)" - @$(ECHO) " openssl_install - Install the OpenSSL libraries (Windows only)" @$(ECHO) " uncrustify_install - Install the Uncrustify source code beautifier" @$(ECHO) " doxygen_install - Install the Doxygen documentation generator" @$(ECHO) " gtest_install - Install the GoogleTest framework" @@ -830,9 +719,9 @@ help: @$(ECHO) " install - Install GCS to \"DESTDIR\" with prefix \"prefix\" (Linux only)" @$(ECHO) @$(ECHO) " [Code Formatting]" - @$(ECHO) " uncrustify_ - Reformat code according to the project's standards" + @$(ECHO) " pretty_ - Reformat code according to the project's standards" @$(ECHO) " Supported sources are ($(UNCRUSTIFY_TARGETS))" - @$(ECHO) " uncrustify_all - Reformat all source code" + @$(ECHO) " pretty - Reformat all source code" @$(ECHO) @$(ECHO) " [Code Documentation]" @$(ECHO) " docs_ - Generate HTML documentation for " @@ -842,6 +731,7 @@ help: @$(ECHO) " docs_all_clean - Delete all generated documentation" @$(ECHO) @$(ECHO) " [Configuration]" + @$(ECHO) " config_help - Show information on how to configure the build" @$(ECHO) " config_new - Place your make arguments in the config file" @$(ECHO) " config_append - Place your make arguments in the config file but append" @$(ECHO) " config_clean - Removes the config file" diff --git a/README.md b/README.md index a809c2559..44efb113b 100644 --- a/README.md +++ b/README.md @@ -30,9 +30,16 @@ Links for the LibrePilot Project - [Main project web site](https://www.librepilot.org) - [Project forums](https://forum.librepilot.org) +- [Software downloads](https://librepilot.atlassian.net/wiki/display/LPDOC/Downloads) +- [Wiki](https://librepilot.atlassian.net/wiki/display/LPDOC/Welcome) - [Source code repository](https://bitbucket.org/librepilot) - [Mirror](https://github.com/librepilot) - [Issue tracker](https://librepilot.atlassian.net) - [Gitter Chat](https://gitter.im/librepilot/LibrePilot) - IRC: #LibrePilot on FreeNode + +| Builder | Status | +|:-------------|:--------------| +| Travis CI |[![Build Status](https://travis-ci.org/librepilot/LibrePilot.svg?branch=next)](https://travis-ci.org/librepilot/LibrePilot)| +| Tea CI |[![Build Status](https://tea-ci.org/api/badges/librepilot/LibrePilot/status.svg?branch=next)](https://tea-ci.org/librepilot/LibrePilot)| diff --git a/WHATSNEW.txt b/WHATSNEW.txt index 8073bdc06..d7d67078a 100644 --- a/WHATSNEW.txt +++ b/WHATSNEW.txt @@ -1,3 +1,229 @@ +-- RELEASE-16.09 - Second LibrePilot Release -- Black Rhino +This is the second LibrePilot release. + +This release introduces new features and new hardware support like Sparky2 board and improved external mag support. + +New hardware support: + Sparky2 board, Auxiliary Magnetometer: I2C and Naza GPS, Revo FlexiIO port usage e.g. PPM+GPS + +New input modes: + Jeti Ex.Bus, Graupner Hott, FlySky IBus, PPM up to 16 channels, Revo/Sparky2 as OpenLRS receiver. + +New telemetry protocols: + MSP, MAVLink. OSD devices that use those protocols may now be connected directly (e.g.: minimosd with MWOSD). + +New Flight oriented features: + AlwaysStabilizeWhenArmed (Airmode) using switch, Measurement based D term gives smoother flight + SuperExpo (you may need half expo value compared to rel15.09), Camera tilt compensation, + Autotune module (except CC3D). + +GCS improvements: + PFD with terrain / OsgEarth improvements + Failsafe settings using GUI + Vehicle and Transmitter wizard improvements + +Known issues: + * [LP-289] - pidcontrol ne and down have nan dz if kp is zero + +The full list of bug fixes and enhancements in this release is available here: +https://librepilot.atlassian.net/issues/?filter=10500 + + +Release Notes - LibrePilot - Version REL-16.09 + +** Sub-task + * [LP-120] - Add Ublox GPS + I2C Mag to Wizard + +** Bug + * [LP-59] - Replace openpilot email address in packaging + * [LP-83] - Bricking of Revo and Sparky2 + * [LP-111] - Fix directory hash calculated to only include tracked files + * [LP-119] - #if used instead of #ifdef in pios_msheap.c + * [LP-139] - Erroneous warning about missing pfd.svg + * [LP-143] - Fix the "firmware upload no responding" issue + * [LP-145] - CC3D GPS issue + * [LP-154] - Fix gitignore - bare config causes all config directories to be ignored. + * [LP-160] - Set default AccelTau value + * [LP-165] - Acro+ factor range in TxPID + * [LP-167] - Stable version checker points to bad url + * [LP-171] - Acro+ Link Roll and Pitch affects all banks + * [LP-175] - Fix src rpm name + * [LP-181] - QT5.5 : PFD parts are broken + * [LP-182] - CC3D/Revonano OPlink Telemetry issue @38400 + * [LP-184] - make: incremental build issues + * [LP-185] - Debian dist detection broken + * [LP-191] - Make TxWizard more robust + * [LP-193] - Remove Libpng warnings + * [LP-197] - QT-5.5.1 broken translations + * [LP-198] - Cannot detect lost of PPM signal + * [LP-204] - Fast_invsqrtf() issue + * [LP-205] - Rate trainer wobble at max angle + * [LP-206] - AlwaysStabilizeWhenArmed need to be disabled at takeoff/landing + * [LP-209] - Oplm link_quality still good with link lost + * [LP-215] - OpLink controller Tx should force failsafe if PPM stream fails + * [LP-216] - GCS misbehaves on high DPI devices + * [LP-218] - msys2 provided opengl library breaks GCS + * [LP-221] - Increase Revo System stack size + * [LP-222] - Building osg and osgearth fails + * [LP-223] - Unit tests build is broken + * [LP-228] - CC3D reboot while import config file + * [LP-241] - Allow CruiseControl for Rate mode at least + * [LP-245] - GCS unsaved data prompt when nothing changed + * [LP-249] - Fix bug introduced in LP-235 + * [LP-251] - UAVObjectGeneratorGCS::process_object uses incorrect param null check + * [LP-252] - GPSv9 drops packets + * [LP-257] - OSX compile issue introduced by a93f182 + * [LP-258] - Update flight controller in real time locks to basic tab + * [LP-261] - Upgrade GCS map versions + * [LP-263] - GCS default config updates + * [LP-266] - pitch virtual board rotation in gui is limited to 90 degrees + * [LP-273] - Reset Mag alarm when going back to Basic complementary fusion algorithm + * [LP-274] - Consistent Attitude board rotation values for all boards + * [LP-275] - OSX build errors + * [LP-277] - OPMap compilation warning + * [LP-281] - PIOS_SENSORS_GetInstanceByType() has incorrect matching operator + * [LP-285] - Tx Wizard : Set Accessory neutral to middle range + * [LP-289] - pidcontrol ne and down have nan dz if kp is zero + * [LP-290] - Windows GCS uninstall is very long + * [LP-299] - gcc5 building isnan issue + * [LP-305] - GCS crashes shortly after start on OSX - when loading OPMap gadget + * [LP-309] - When arming with accessory switch, disarming timeout doesn't work. + * [LP-310] - osg: random GCS crashes when switching or closing PFDQml gadgets + * [LP-312] - GCS config - attitude - mag tab offers sparky2 i2c port on revo + * [LP-313] - using UAVObjectBrowser filter text always enables metadata display + * [LP-321] - MSP in ReceiverPort menu for RevoNano + * [LP-333] - Sparky2 I2CPort needs GPIO_PuPd_UP instead of NOPULL + * [LP-339] - Avoid AutoTakeOff flight mode while already armed + * [LP-341] - VCP doesn't work on Windows 10 or 8.1 + * [LP-362] - GCS crashes when logging to file with -log command line argument + * [LP-363] - OPMap missing tiles + * [LP-369] - Fix availability condition for VCP + * [LP-382] - MSP stack overflow on PID save op. + * [LP-387] - Sparky2 analog port mapping + * [LP-388] - Wrong AuxMag calibration due to wrong initial settings + * [LP-391] - Some CC3D ports cause a boot issue and re-init to defaults. + * [LP-392] - Revo attitude settings is missing the "Zero gyro when arming" checkbox + * [LP-395] - Raise BoardSteadyMaxVariance to support some boards having higher gyro noise + * [LP-400] - Doxygen document build fails with latex errors + * [LP-401] - Reboot is required after AutoTune is set in FMS + * [LP-406] - Windows driver fails to install + * [LP-409] - make fw_dist fails on windows + * [LP-421] - GCS setup wizard welcome panel is too big on high dpi screens + * [LP-423] - HMC5x83 driver dereferences null pointer + * [LP-424] - pios_openlrs.c has incorrect reference to rfm22b_id + * [LP-429] - changes to FlightModeSettings do not trigger a configuration check + * [LP-444] - I2C alarm + * [LP-447] - ESC calibration failure with FVT LitteBee 20A + + +** Story + * [LP-32] - osgearth integration (follow up cleanups) + +** New Feature + * [LP-29] - osgearth integration + * [LP-149] - Add STM32F427/429/437/439 chip support, preparation for brand new board. + * [LP-212] - Support DJI GPS and mag combo uses one port + * [LP-214] - Camera tilt compensation + * [LP-233] - OneShot42 / MultiShot support + * [LP-280] - After firmware boots, start calibration when vehicle is not moving + * [LP-286] - Port search field in UAVBrowser from TL + * [LP-291] - Port MSP support from dRonin + * [LP-298] - Create iBus support for RX + * [LP-327] - Wait for board to be steady before calibrating gyro + * [LP-364] - Port and improve MavLink support from dRonin + * [LP-425] - Add Credits to the About dialog + +** Task + * [LP-2] - Upgrade to Qt 5.5 + * [LP-30] - osg/osgearth/marble build scripts + * [LP-40] - Add support for TravisCI + * [LP-72] - Sparky 2 support + * [LP-73] - External Mags on I2C + * [LP-76] - Port Tau Labs Autotune to LP + * [LP-88] - Remove OpenPilot branding from .commit-template + * [LP-140] - Update Logo files in Artwork + * [LP-186] - Add copyright to qml and js files + * [LP-187] - Use Msys2 + * [LP-194] - Hide Yaw Attitude related parameter from Stabilization panel + * [LP-195] - Update World Magnetic Model + * [LP-200] - Remove Opie + * [LP-201] - Update Y6 mixer + * [LP-208] - Upgrade to Qt 5.6 + * [LP-230] - PFD refresh after recent additions + * [LP-247] - Add Naza GPS/Mag to Wizard + * [LP-267] - Enable more options in the current GUI for fusion algorithm + * [LP-292] - Oplink tab cleanup + * [LP-306] - Update Ubuntu PPA to build with osgearth + * [LP-307] - Set up Tea CI + * [LP-315] - Update vehicle templates + * [LP-317] - Update RPM packaging for osgearth + * [LP-325] - Reduce the threshold for ASWA switch + * [LP-328] - Sparky2 reboots constantly with only USB power and unpowered external mag + * [LP-330] - Fix copyright symbol in all code, make it consistent + * [LP-349] - shut up the plan warning alarm + * [LP-373] - Add bitbucket pipelines + * [LP-374] - Build x86_64 windows on TeaCI as well. + * [LP-394] - Upload build results from Tea-Ci + +** Improvement + * [LP-96] - Review CPU idle time counter + * [LP-97] - Unify Init process between revo*-cc3d boards + * [LP-104] - HOTT SUMD support + * [LP-147] - Rc transmitter wizard : Auto detect flight mode number + * [LP-150] - Run Attitude calculation on CC/CC3D at slower rate than gyro samples + * [LP-151] - Settable OPLink (and FC) Device ID + * [LP-164] - change OSX dmg .webloc to point to LP website + * [LP-168] - Copy the same content and url list as www.librepilot.org in README.md + * [LP-174] - Add current value display to RcInput tab + * [LP-176] - Allow overriding of package type + * [LP-177] - Make debian package src use pre-compiled firmware + * [LP-178] - Add pass through feature for FixedWing + * [LP-179] - Highlight stabilization mode currently used + * [LP-183] - upgrade GCS uav object generator to Qt 5.5 + * [LP-190] - Add openLRSng Rx support to OPLink/Revo + * [LP-196] - JETI EX Bus communication protocol support + * [LP-207] - EventDispatcher: Add "fast" callbacks + * [LP-219] - OPLink module should accept more than 8 PPM channels + * [LP-232] - Display flight mode alarm while setup + * [LP-235] - Make Failsafe settings more user friendly by allowing them to be set in the Configuration tab + * [LP-238] - Consolidate CPP firmware requirements within apps/boot-defs.mk + * [LP-239] - GPS on Flexi IO on Revo + * [LP-240] - Aux Mag setup help and GUI + * [LP-254] - Set CruiseControl default CruiseControlMaxThrust to 100 + * [LP-256] - Sparky2 timers and output banks and PPM + * [LP-268] - Add TX and RX packet rates to OPLink stats. + * [LP-269] - IoT Stream Service + * [LP-272] - Altitude velocity Integral default value is set too high + * [LP-276] - Measurement based D term + * [LP-293] - Add AlarmString() to alarms library. + * [LP-295] - OP-1900 fix autotakeoff/landing to not break fixed wing + * [LP-302] - Change motor numbering on config - vehicle tab to directional like NW + * [LP-304] - Improvements for performance counters + * [LP-311] - GCS jumps back to Basic Stabilization if FC changes anything + * [LP-322] - USB Com Bridge functionality on OPLink + * [LP-324] - MSP on Sparky2 + * [LP-326] - supporting 16 channels PPM + * [LP-335] - add support for address sanitizer in GCS build system + * [LP-338] - upgrade GCS to Qt 5.6.1 + * [LP-340] - AutoTune fix some time measurement issues in original code + * [LP-342] - pios_exti to allow runtime (re)configuration + * [LP-343] - PIOS_COM_Available() needs to give out more details about RX and TX availability + * [LP-352] - Increase Expo effect for high rates + * [LP-354] - Add Ublox AssistNow Autonomous setting + * [LP-361] - Led notification improvements + * [LP-365] - Cleanup com port setup in pios_board.c for coptercontrol + * [LP-366] - Set default velocity and altitude in gcs for new waypoints + * [LP-377] - ComBridge Speed settings delete + * [LP-379] - Add receiverActivity to RC Input tab + * [LP-390] - Fix UAVO telemetry errors + * [LP-396] - Yaw AcroPlus controls in GUI + * [LP-410] - silence GCS logs + * [LP-411] - AutoTune Limit Outer PIDs on Powerful Multicopters - dRonin PR 1283 + * [LP-417] - Heartbeat LED on OPLink + * [LP-428] - Reduce the threshold for arming switch + * [LP-441] - Template - Wizard dialog on small screens + + -- RELEASE-15.09 - First LibrePilot Release -- Supermoon Eclipse This is the first LibrePilot release. The main focus of this release is to bring back support for CC3D and a general re-branding of the GCS. diff --git a/artwork/3D Model/backgrounds/default_background.psd b/artwork/3D Model/backgrounds/default_background.psd deleted file mode 100644 index 4f4dc4adf..000000000 Binary files a/artwork/3D Model/backgrounds/default_background.psd and /dev/null differ diff --git a/artwork/Logo/LP_logo_horizontal.png b/artwork/Logo/LP_logo_horizontal.png new file mode 100644 index 000000000..4a216529c Binary files /dev/null and b/artwork/Logo/LP_logo_horizontal.png differ diff --git a/artwork/Logo/LP_logo_square.png b/artwork/Logo/LP_logo_square.png new file mode 100644 index 000000000..65a686edc Binary files /dev/null and b/artwork/Logo/LP_logo_square.png differ diff --git a/artwork/Logo/LibrePilot_logo.svg b/artwork/Logo/LibrePilot_logo.svg new file mode 100644 index 000000000..b791a5470 --- /dev/null +++ b/artwork/Logo/LibrePilot_logo.svg @@ -0,0 +1,725 @@ + + + + + LibrePilot Logo + + + + + + image/svg+xml + + LibrePilot Logo + July 2015 + + + LibrePilot + + + www.librepilot.org + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/artwork/Logo/CopterControl Logo.svg b/artwork/Logo/OpenPilot/CopterControl Logo.svg similarity index 100% rename from artwork/Logo/CopterControl Logo.svg rename to artwork/Logo/OpenPilot/CopterControl Logo.svg diff --git a/artwork/Logo/OpenPilot Logo.zip b/artwork/Logo/OpenPilot/OpenPilot Logo.zip similarity index 100% rename from artwork/Logo/OpenPilot Logo.zip rename to artwork/Logo/OpenPilot/OpenPilot Logo.zip diff --git a/artwork/3D Model/backgrounds/default_background.png b/artwork/backgrounds/default_background.png similarity index 100% rename from artwork/3D Model/backgrounds/default_background.png rename to artwork/backgrounds/default_background.png diff --git a/artwork/3D Model/backgrounds/standard/01.png b/artwork/backgrounds/standard/01.png similarity index 100% rename from artwork/3D Model/backgrounds/standard/01.png rename to artwork/backgrounds/standard/01.png diff --git a/artwork/3D Model/backgrounds/standard/02.png b/artwork/backgrounds/standard/02.png similarity index 100% rename from artwork/3D Model/backgrounds/standard/02.png rename to artwork/backgrounds/standard/02.png diff --git a/artwork/3D Model/backgrounds/standard/03.png b/artwork/backgrounds/standard/03.png similarity index 100% rename from artwork/3D Model/backgrounds/standard/03.png rename to artwork/backgrounds/standard/03.png diff --git a/artwork/3D Model/backgrounds/standard/04.png b/artwork/backgrounds/standard/04.png similarity index 100% rename from artwork/3D Model/backgrounds/standard/04.png rename to artwork/backgrounds/standard/04.png diff --git a/artwork/3D Model/backgrounds/standard/05.png b/artwork/backgrounds/standard/05.png similarity index 100% rename from artwork/3D Model/backgrounds/standard/05.png rename to artwork/backgrounds/standard/05.png diff --git a/artwork/3D Model/backgrounds/standard/06.png b/artwork/backgrounds/standard/06.png similarity index 100% rename from artwork/3D Model/backgrounds/standard/06.png rename to artwork/backgrounds/standard/06.png diff --git a/artwork/3D Model/backgrounds/standard/07.png b/artwork/backgrounds/standard/07.png similarity index 100% rename from artwork/3D Model/backgrounds/standard/07.png rename to artwork/backgrounds/standard/07.png diff --git a/artwork/3D Model/backgrounds/standard/08.png b/artwork/backgrounds/standard/08.png similarity index 100% rename from artwork/3D Model/backgrounds/standard/08.png rename to artwork/backgrounds/standard/08.png diff --git a/artwork/3D Model/backgrounds/standard/09.png b/artwork/backgrounds/standard/09.png similarity index 100% rename from artwork/3D Model/backgrounds/standard/09.png rename to artwork/backgrounds/standard/09.png diff --git a/artwork/3D Model/backgrounds/standard/10.png b/artwork/backgrounds/standard/10.png similarity index 100% rename from artwork/3D Model/backgrounds/standard/10.png rename to artwork/backgrounds/standard/10.png diff --git a/artwork/3D Model/backgrounds/standard/11.png b/artwork/backgrounds/standard/11.png similarity index 100% rename from artwork/3D Model/backgrounds/standard/11.png rename to artwork/backgrounds/standard/11.png diff --git a/artwork/3D Model/backgrounds/standard/12.png b/artwork/backgrounds/standard/12.png similarity index 100% rename from artwork/3D Model/backgrounds/standard/12.png rename to artwork/backgrounds/standard/12.png diff --git a/artwork/3D Model/backgrounds/standard/13.jpg b/artwork/backgrounds/standard/13.jpg similarity index 100% rename from artwork/3D Model/backgrounds/standard/13.jpg rename to artwork/backgrounds/standard/13.jpg diff --git a/artwork/3D Model/backgrounds/wide/01w.png b/artwork/backgrounds/wide/01w.png similarity index 100% rename from artwork/3D Model/backgrounds/wide/01w.png rename to artwork/backgrounds/wide/01w.png diff --git a/artwork/3D Model/backgrounds/wide/02w.png b/artwork/backgrounds/wide/02w.png similarity index 100% rename from artwork/3D Model/backgrounds/wide/02w.png rename to artwork/backgrounds/wide/02w.png diff --git a/artwork/3D Model/backgrounds/wide/03w.png b/artwork/backgrounds/wide/03w.png similarity index 100% rename from artwork/3D Model/backgrounds/wide/03w.png rename to artwork/backgrounds/wide/03w.png diff --git a/artwork/3D Model/backgrounds/wide/04w.png b/artwork/backgrounds/wide/04w.png similarity index 100% rename from artwork/3D Model/backgrounds/wide/04w.png rename to artwork/backgrounds/wide/04w.png diff --git a/artwork/3D Model/backgrounds/wide/05w.png b/artwork/backgrounds/wide/05w.png similarity index 100% rename from artwork/3D Model/backgrounds/wide/05w.png rename to artwork/backgrounds/wide/05w.png diff --git a/artwork/3D Model/backgrounds/wide/06w.png b/artwork/backgrounds/wide/06w.png similarity index 100% rename from artwork/3D Model/backgrounds/wide/06w.png rename to artwork/backgrounds/wide/06w.png diff --git a/artwork/3D Model/backgrounds/wide/07w.png b/artwork/backgrounds/wide/07w.png similarity index 100% rename from artwork/3D Model/backgrounds/wide/07w.png rename to artwork/backgrounds/wide/07w.png diff --git a/artwork/3D Model/backgrounds/wide/08w.png b/artwork/backgrounds/wide/08w.png similarity index 100% rename from artwork/3D Model/backgrounds/wide/08w.png rename to artwork/backgrounds/wide/08w.png diff --git a/artwork/3D Model/backgrounds/wide/09w.png b/artwork/backgrounds/wide/09w.png similarity index 100% rename from artwork/3D Model/backgrounds/wide/09w.png rename to artwork/backgrounds/wide/09w.png diff --git a/artwork/3D Model/backgrounds/wide/10w.png b/artwork/backgrounds/wide/10w.png similarity index 100% rename from artwork/3D Model/backgrounds/wide/10w.png rename to artwork/backgrounds/wide/10w.png diff --git a/artwork/3D Model/backgrounds/wide/11w.png b/artwork/backgrounds/wide/11w.png similarity index 100% rename from artwork/3D Model/backgrounds/wide/11w.png rename to artwork/backgrounds/wide/11w.png diff --git a/artwork/3D Model/backgrounds/wide/12w.png b/artwork/backgrounds/wide/12w.png similarity index 100% rename from artwork/3D Model/backgrounds/wide/12w.png rename to artwork/backgrounds/wide/12w.png diff --git a/artwork/3D Model/backgrounds/wide/13w.jpg b/artwork/backgrounds/wide/13w.jpg similarity index 100% rename from artwork/3D Model/backgrounds/wide/13w.jpg rename to artwork/backgrounds/wide/13w.jpg diff --git a/bitbucket-pipelines.yml b/bitbucket-pipelines.yml new file mode 100644 index 000000000..b73f5e6aa --- /dev/null +++ b/bitbucket-pipelines.yml @@ -0,0 +1,11 @@ +pipelines: + default: + - step: + script: + - add-apt-repository ppa:librepilot/tools -y + - apt-get update -q + - apt-get install -y libc6-i386 libudev-dev libusb-1.0-0-dev libsdl1.2-dev python libopenscenegraph-dev libosgearth-dev qt56-meta-minimal qt56svg qt56script qt56serialport qt56multimedia qt56translations qt56tools + - make build_sdk_install + - make all_flight + - make opfw_resource + - make gcs diff --git a/fix_vehicle_templates.py b/fix_vehicle_templates.py new file mode 100644 index 000000000..8fa723bc5 --- /dev/null +++ b/fix_vehicle_templates.py @@ -0,0 +1,62 @@ +#!/usr/bin/python + + ############################################################################### + # + # The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + # Script to update vehicle templates files to match current UAVO structure + # and data. + # + ############################################################################### + +import json +import re +import collections +import fnmatch +import os + +class DecimalEncoder(json.JSONEncoder): + def default(self, obj): + if isinstance(obj, Decimal): + return float(obj) + return json.JSONEncoder.default(self, obj) + +json.encoder.FLOAT_REPR = lambda o: format(o, '.17g') + +files = [] +for root, dirnames, filenames in os.walk('ground/gcs/src/share/vehicletemplates/'): + for filename in fnmatch.filter(filenames, '*.optmpl'): + files.append(os.path.join(root, filename)) + +for f in files: + data = json.load(open(f, 'r'), object_pairs_hook=collections.OrderedDict) + + for item in data['objects']: + fieldsToRemove = [] + for i in item['fields']: + name = i['name'] + values = i['values'] + if re.compile('ThrustPIDScaleCurve').match(name): + i['type'] = "int8" + for j in values: + j['value'] = int(j['value'] * 100) + elif re.compile('AcroInsanityFactor').match(name): + i['type'] = "int8" + value = 0 + for j in values: + value = int(j['value'] * 100) + values.pop() + values.append({'name': 'roll', 'value': value}) + values.append({'name': 'pitch', 'value': value}) + values.append({'name': 'yaw', 'value': value}) + elif re.compile('FeedForward').match(name): + fieldsToRemove.append(i) + elif re.compile('MaxAccel').match(name): + fieldsToRemove.append(i) + elif re.compile('AccelTime').match(name): + fieldsToRemove.append(i) + elif re.compile('DecelTime').match(name): + fieldsToRemove.append(i) + for field in fieldsToRemove: + item['fields'].remove(field) + with open(f, 'w') as outfile: + json.dump(data, outfile, indent=4, separators=(',', ': '), cls=DecimalEncoder) diff --git a/flight/Makefile b/flight/Makefile index f1eb313e9..7540aa364 100644 --- a/flight/Makefile +++ b/flight/Makefile @@ -8,7 +8,7 @@ export OPUAVTALK := $(FLIGHT_ROOT_DIR)/uavtalk export FLIGHT_OUT_DIR ?= $(CURDIR) # Define supported board lists -ALL_BOARDS := coptercontrol oplinkmini revolution osd revoproto simposix discoveryf4bare gpsplatinum revonano +ALL_BOARDS := coptercontrol oplinkmini revolution osd revoproto simposix discoveryf4bare gpsplatinum revonano sparky2 # Short names of each board (used to display board name in parallel builds) coptercontrol_short := 'cc ' @@ -17,6 +17,7 @@ revolution_short := 'revo' osd_short := 'osd ' revoproto_short := 'revp' revonano_short := 'revn' +sparky2_short := 'spk2' simposix_short := 'posx' discoveryf4bare_short := 'df4b' gpsplatinum_short := 'gps9' @@ -254,3 +255,62 @@ flight_uavobjects: $(UAVOBJGENERATOR) $(V1) cd $(FLIGHT_UAVOBJ_DIR) && \ $(UAVOBJGENERATOR) -flight $(UAVOBJ_XML_DIR) $(FLIGHT_ROOT_DIR)/.. + +############################## +# +# Unit Tests +# +############################## + +ALL_UNITTESTS := logfs math lednotification + +# Build the directory for the unit tests +UT_OUT_DIR := $(BUILD_DIR)/unit_tests +DIRS += $(UT_OUT_DIR) + +.PHONY: all_ut +all_ut: $(addsuffix _elf, $(addprefix ut_, $(ALL_UNITTESTS))) + +.PHONY: all_ut_xml +all_ut_xml: $(addsuffix _xml, $(addprefix ut_, $(ALL_UNITTESTS))) + +.PHONY: all_ut_run +all_ut_run: $(addsuffix _run, $(addprefix ut_, $(ALL_UNITTESTS))) + +.PHONY: all_ut_clean +all_ut_clean: + @$(ECHO) " CLEAN $(call toprel, $(UT_OUT_DIR))" + $(V1) [ ! -d "$(UT_OUT_DIR)" ] || $(RM) -r "$(UT_OUT_DIR)" + +# $(1) = Unit test name +define UT_TEMPLATE +.PHONY: ut_$(1) +ut_$(1): ut_$(1)_run + +ut_$(1)_%: $$(UT_OUT_DIR) + $(V1) $(MKDIR) -p $(UT_OUT_DIR)/$(1) + $(V1) cd $(ROOT_DIR)/flight/tests/$(1) && \ + $$(MAKE) -r --no-print-directory \ + BUILD_TYPE=ut \ + BOARD_SHORT_NAME=$(1) \ + TOPDIR=$(ROOT_DIR)/flight/tests/$(1) \ + OUTDIR="$(UT_OUT_DIR)/$(1)" \ + TARGET=$(1) \ + $$* + +.PHONY: ut_$(1)_clean +ut_$(1)_clean: + @$(ECHO) " CLEAN $(call toprel, $(UT_OUT_DIR)/$(1))" + $(V1) [ ! -d "$(UT_OUT_DIR)/$(1)" ] || $(RM) -r "$(UT_OUT_DIR)/$(1)" +endef + +# Expand the unittest rules +$(foreach ut, $(ALL_UNITTESTS), $(eval $(call UT_TEMPLATE,$(ut)))) + +# Disable parallel make when the all_ut_run target is requested otherwise the TAP +# output is interleaved with the rest of the make output. +ifneq ($(strip $(filter all_ut_run,$(MAKECMDGOALS))),) +.NOTPARALLEL: + $(info $(EMPTY) NOTE Parallel make disabled by all_ut_run target so we have sane console output) +endif + diff --git a/flight/Project/Windows USB/OpenPilot-CDC.inf b/flight/Project/WindowsUSB/OpenPilot-CDC.inf similarity index 100% rename from flight/Project/Windows USB/OpenPilot-CDC.inf rename to flight/Project/WindowsUSB/OpenPilot-CDC.inf diff --git a/flight/Project/Windows USB/openpilot-cdc_amd64.cat b/flight/Project/WindowsUSB/openpilot-cdc_amd64.cat similarity index 100% rename from flight/Project/Windows USB/openpilot-cdc_amd64.cat rename to flight/Project/WindowsUSB/openpilot-cdc_amd64.cat diff --git a/flight/Project/Windows USB/openpilot-cdc_x86.cat b/flight/Project/WindowsUSB/openpilot-cdc_x86.cat similarity index 100% rename from flight/Project/Windows USB/openpilot-cdc_x86.cat rename to flight/Project/WindowsUSB/openpilot-cdc_x86.cat diff --git a/flight/libraries/WorldMagModel.c b/flight/libraries/WorldMagModel.c index 262740e1b..cff140387 100644 --- a/flight/libraries/WorldMagModel.c +++ b/flight/libraries/WorldMagModel.c @@ -2,11 +2,12 @@ ****************************************************************************** * * @file WorldMagModel.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @brief Source file for the World Magnetic Model * This is a port of code available from the US NOAA. * - * The hard coded coefficients should be valid until 2015. + * The hard coded coefficients should be valid until 2020. * * Updated coeffs from .. * http://www.ngdc.noaa.gov/geomag/WMM/wmm_ddownload.shtml @@ -60,96 +61,96 @@ // first column not used but it will be optimized out by compiler static const float CoeffFile[91][6] = { { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }, - { 1.0f, 0.0f, -29496.6f, 0.0f, 11.6f, 0.0f }, - { 1.0f, 1.0f, -1586.3f, 4944.4f, 16.5f, -25.9f }, - { 2.0f, 0.0f, -2396.6f, 0.0f, -12.1f, 0.0f }, - { 2.0f, 1.0f, 3026.1f, -2707.7f, -4.4f, -22.5f }, - { 2.0f, 2.0f, 1668.6f, -576.1f, 1.9f, -11.8f }, - { 3.0f, 0.0f, 1340.1f, 0.0f, 0.4f, 0.0f }, - { 3.0f, 1.0f, -2326.2f, -160.2f, -4.1f, 7.3f }, - { 3.0f, 2.0f, 1231.9f, 251.9f, -2.9f, -3.9f }, - { 3.0f, 3.0f, 634.0f, -536.6f, -7.7f, -2.6f }, - { 4.0f, 0.0f, 912.6f, 0.0f, -1.8f, 0.0f }, - { 4.0f, 1.0f, 808.9f, 286.4f, 2.3f, 1.1f }, - { 4.0f, 2.0f, 166.7f, -211.2f, -8.7f, 2.7f }, - { 4.0f, 3.0f, -357.1f, 164.3f, 4.6f, 3.9f }, - { 4.0f, 4.0f, 89.4f, -309.1f, -2.1f, -0.8f }, - { 5.0f, 0.0f, -230.9f, 0.0f, -1.0f, 0.0f }, - { 5.0f, 1.0f, 357.2f, 44.6f, 0.6f, 0.4f }, - { 5.0f, 2.0f, 200.3f, 188.9f, -1.8f, 1.8f }, - { 5.0f, 3.0f, -141.1f, -118.2f, -1.0f, 1.2f }, - { 5.0f, 4.0f, -163.0f, 0.0f, 0.9f, 4.0f }, - { 5.0f, 5.0f, -7.8f, 100.9f, 1.0f, -0.6f }, - { 6.0f, 0.0f, 72.8f, 0.0f, -0.2f, 0.0f }, - { 6.0f, 1.0f, 68.6f, -20.8f, -0.2f, -0.2f }, - { 6.0f, 2.0f, 76.0f, 44.1f, -0.1f, -2.1f }, - { 6.0f, 3.0f, -141.4f, 61.5f, 2.0f, -0.4f }, - { 6.0f, 4.0f, -22.8f, -66.3f, -1.7f, -0.6f }, - { 6.0f, 5.0f, 13.2f, 3.1f, -0.3f, 0.5f }, - { 6.0f, 6.0f, -77.9f, 55.0f, 1.7f, 0.9f }, - { 7.0f, 0.0f, 80.5f, 0.0f, 0.1f, 0.0f }, - { 7.0f, 1.0f, -75.1f, -57.9f, -0.1f, 0.7f }, - { 7.0f, 2.0f, -4.7f, -21.1f, -0.6f, 0.3f }, - { 7.0f, 3.0f, 45.3f, 6.5f, 1.3f, -0.1f }, - { 7.0f, 4.0f, 13.9f, 24.9f, 0.4f, -0.1f }, - { 7.0f, 5.0f, 10.4f, 7.0f, 0.3f, -0.8f }, - { 7.0f, 6.0f, 1.7f, -27.7f, -0.7f, -0.3f }, - { 7.0f, 7.0f, 4.9f, -3.3f, 0.6f, 0.3f }, - { 8.0f, 0.0f, 24.4f, 0.0f, -0.1f, 0.0f }, - { 8.0f, 1.0f, 8.1f, 11.0f, 0.1f, -0.1f }, - { 8.0f, 2.0f, -14.5f, -20.0f, -0.6f, 0.2f }, - { 8.0f, 3.0f, -5.6f, 11.9f, 0.2f, 0.4f }, - { 8.0f, 4.0f, -19.3f, -17.4f, -0.2f, 0.4f }, - { 8.0f, 5.0f, 11.5f, 16.7f, 0.3f, 0.1f }, - { 8.0f, 6.0f, 10.9f, 7.0f, 0.3f, -0.1f }, - { 8.0f, 7.0f, -14.1f, -10.8f, -0.6f, 0.4f }, - { 8.0f, 8.0f, -3.7f, 1.7f, 0.2f, 0.3f }, + { 1.0f, 0.0f, -29438.5f, 0.0f, 10.7f, 0.0f }, + { 1.0f, 1.0f, -1501.1f, 4796.2f, 17.9f, -26.8f }, + { 2.0f, 0.0f, -2445.3f, 0.0f, -8.6f, 0.0f }, + { 2.0f, 1.0f, 3012.5f, -2845.6f, -3.3f, -27.1f }, + { 2.0f, 2.0f, 1676.6f, -642.0f, 2.4f, -13.3f }, + { 3.0f, 0.0f, 1351.1f, 0.0f, 3.1f, 0.0f }, + { 3.0f, 1.0f, -2352.3f, -115.3f, -6.2f, 8.4f }, + { 3.0f, 2.0f, 1225.6f, 245.0f, -0.4f, -0.4f }, + { 3.0f, 3.0f, 581.9f, -538.3f, -10.4f, 2.3f }, + { 4.0f, 0.0f, 907.2f, 0.0f, -0.4f, 0.0f }, + { 4.0f, 1.0f, 813.7f, 283.4f, 0.8f, -0.6f }, + { 4.0f, 2.0f, 120.3f, -188.6f, -9.2f, 5.3f }, + { 4.0f, 3.0f, -335.0f, 180.9f, 4.0f, 3.0f }, + { 4.0f, 4.0f, 70.3f, -329.5f, -4.2f, -5.3f }, + { 5.0f, 0.0f, -232.6f, 0.0f, -0.2f, 0.0f }, + { 5.0f, 1.0f, 360.1f, 47.4f, 0.1f, 0.4f }, + { 5.0f, 2.0f, 192.4f, 196.9f, -1.4f, 1.6f }, + { 5.0f, 3.0f, -141.0f, -119.4f, 0.0f, -1.1f }, + { 5.0f, 4.0f, -157.4f, 16.1f, 1.3f, 3.3f }, + { 5.0f, 5.0f, 4.3f, 100.1f, 3.8f, 0.1f }, + { 6.0f, 0.0f, 69.5f, 0.0f, -0.5f, 0.0f }, + { 6.0f, 1.0f, 67.4f, -20.7f, -0.2f, 0.0f }, + { 6.0f, 2.0f, 72.8f, 33.2f, -0.6f, -2.2f }, + { 6.0f, 3.0f, -129.8f, 58.8f, 2.4f, -0.7f }, + { 6.0f, 4.0f, -29.0f, -66.5f, -1.1f, 0.1f }, + { 6.0f, 5.0f, 13.2f, 7.3f, 0.3f, 1.0f }, + { 6.0f, 6.0f, -70.9f, 62.5f, 1.5f, 1.3f }, + { 7.0f, 0.0f, 81.6f, 0.0f, 0.2f, 0.0f }, + { 7.0f, 1.0f, -76.1f, -54.1f, -0.2f, 0.7f }, + { 7.0f, 2.0f, -6.8f, -19.4f, -0.4f, 0.5f }, + { 7.0f, 3.0f, 51.9f, 5.6f, 1.3f, -0.2f }, + { 7.0f, 4.0f, 15.0f, 24.4f, 0.2f, -0.1f }, + { 7.0f, 5.0f, 9.3f, 3.3f, -0.4f, -0.7f }, + { 7.0f, 6.0f, -2.8f, -27.5f, -0.9f, 0.1f }, + { 7.0f, 7.0f, 6.7f, -2.3f, 0.3f, 0.1f }, + { 8.0f, 0.0f, 24.0f, 0.0f, 0.0f, 0.0f }, + { 8.0f, 1.0f, 8.6f, 10.2f, 0.1f, -0.3f }, + { 8.0f, 2.0f, -16.9f, -18.1f, -0.5f, 0.3f }, + { 8.0f, 3.0f, -3.2f, 13.2f, 0.5f, 0.3f }, + { 8.0f, 4.0f, -20.6f, -14.6f, -0.2f, 0.6f }, + { 8.0f, 5.0f, 13.3f, 16.2f, 0.4f, -0.1f }, + { 8.0f, 6.0f, 11.7f, 5.7f, 0.2f, -0.2f }, + { 8.0f, 7.0f, -16.0f, -9.1f, -0.4f, 0.3f }, + { 8.0f, 8.0f, -2.0f, 2.2f, 0.3f, 0.0f }, { 9.0f, 0.0f, 5.4f, 0.0f, 0.0f, 0.0f }, - { 9.0f, 1.0f, 9.4f, -20.5f, -0.1f, 0.0f }, - { 9.0f, 2.0f, 3.4f, 11.5f, 0.0f, -0.2f }, - { 9.0f, 3.0f, -5.2f, 12.8f, 0.3f, 0.0f }, - { 9.0f, 4.0f, 3.1f, -7.2f, -0.4f, -0.1f }, - { 9.0f, 5.0f, -12.4f, -7.4f, -0.3f, 0.1f }, - { 9.0f, 6.0f, -0.7f, 8.0f, 0.1f, 0.0f }, - { 9.0f, 7.0f, 8.4f, 2.1f, -0.1f, -0.2f }, - { 9.0f, 8.0f, -8.5f, -6.1f, -0.4f, 0.3f }, - { 9.0f, 9.0f, -10.1f, 7.0f, -0.2f, 0.2f }, - { 10.0f, 0.0f, -2.0f, 0.0f, 0.0f, 0.0f }, - { 10.0f, 1.0f, -6.3f, 2.8f, 0.0f, 0.1f }, - { 10.0f, 2.0f, 0.9f, -0.1f, -0.1f, -0.1f }, - { 10.0f, 3.0f, -1.1f, 4.7f, 0.2f, 0.0f }, - { 10.0f, 4.0f, -0.2f, 4.4f, 0.0f, -0.1f }, - { 10.0f, 5.0f, 2.5f, -7.2f, -0.1f, -0.1f }, - { 10.0f, 6.0f, -0.3f, -1.0f, -0.2f, 0.0f }, - { 10.0f, 7.0f, 2.2f, -3.9f, 0.0f, -0.1f }, - { 10.0f, 8.0f, 3.1f, -2.0f, -0.1f, -0.2f }, - { 10.0f, 9.0f, -1.0f, -2.0f, -0.2f, 0.0f }, - { 10.0f, 10.0f, -2.8f, -8.3f, -0.2f, -0.1f }, - { 11.0f, 0.0f, 3.0f, 0.0f, 0.0f, 0.0f }, - { 11.0f, 1.0f, -1.5f, 0.2f, 0.0f, 0.0f }, - { 11.0f, 2.0f, -2.1f, 1.7f, 0.0f, 0.1f }, - { 11.0f, 3.0f, 1.7f, -0.6f, 0.1f, 0.0f }, - { 11.0f, 4.0f, -0.5f, -1.8f, 0.0f, 0.1f }, - { 11.0f, 5.0f, 0.5f, 0.9f, 0.0f, 0.0f }, - { 11.0f, 6.0f, -0.8f, -0.4f, 0.0f, 0.1f }, - { 11.0f, 7.0f, 0.4f, -2.5f, 0.0f, 0.0f }, - { 11.0f, 8.0f, 1.8f, -1.3f, 0.0f, -0.1f }, - { 11.0f, 9.0f, 0.1f, -2.1f, 0.0f, -0.1f }, - { 11.0f, 10.0f, 0.7f, -1.9f, -0.1f, 0.0f }, - { 11.0f, 11.0f, 3.8f, -1.8f, 0.0f, -0.1f }, - { 12.0f, 0.0f, -2.2f, 0.0f, 0.0f, 0.0f }, - { 12.0f, 1.0f, -0.2f, -0.9f, 0.0f, 0.0f }, - { 12.0f, 2.0f, 0.3f, 0.3f, 0.1f, 0.0f }, - { 12.0f, 3.0f, 1.0f, 2.1f, 0.1f, 0.0f }, - { 12.0f, 4.0f, -0.6f, -2.5f, -0.1f, 0.0f }, - { 12.0f, 5.0f, 0.9f, 0.5f, 0.0f, 0.0f }, - { 12.0f, 6.0f, -0.1f, 0.6f, 0.0f, 0.1f }, - { 12.0f, 7.0f, 0.5f, 0.0f, 0.0f, 0.0f }, - { 12.0f, 8.0f, -0.4f, 0.1f, 0.0f, 0.0f }, - { 12.0f, 9.0f, -0.4f, 0.3f, 0.0f, 0.0f }, + { 9.0f, 1.0f, 8.8f, -21.6f, -0.1f, -0.2f }, + { 9.0f, 2.0f, 3.1f, 10.8f, -0.1f, -0.1f }, + { 9.0f, 3.0f, -3.1f, 11.7f, 0.4f, -0.2f }, + { 9.0f, 4.0f, 0.6f, -6.8f, -0.5f, 0.1f }, + { 9.0f, 5.0f, -13.3f, -6.9f, -0.2f, 0.1f }, + { 9.0f, 6.0f, -0.1f, 7.8f, 0.1f, 0.0f }, + { 9.0f, 7.0f, 8.7f, 1.0f, 0.0f, -0.2f }, + { 9.0f, 8.0f, -9.1f, -3.9f, -0.2f, 0.4f }, + { 9.0f, 9.0f, -10.5f, 8.5f, -0.1f, 0.3f }, + { 10.0f, 0.0f, -1.9f, 0.0f, 0.0f, 0.0f }, + { 10.0f, 1.0f, -6.5f, 3.3f, 0.0f, 0.1f }, + { 10.0f, 2.0f, 0.2f, -0.3f, -0.1f, -0.1f }, + { 10.0f, 3.0f, 0.6f, 4.6f, 0.3f, 0.0f }, + { 10.0f, 4.0f, -0.6f, 4.4f, -0.1f, 0.0f }, + { 10.0f, 5.0f, 1.7f, -7.9f, -0.1f, -0.2f }, + { 10.0f, 6.0f, -0.7f, -0.6f, -0.1f, 0.1f }, + { 10.0f, 7.0f, 2.1f, -4.1f, 0.0f, -0.1f }, + { 10.0f, 8.0f, 2.3f, -2.8f, -0.2f, -0.2f }, + { 10.0f, 9.0f, -1.8f, -1.1f, -0.1f, 0.1f }, + { 10.0f, 10.0f, -3.6f, -8.7f, -0.2f, -0.1f }, + { 11.0f, 0.0f, 3.1f, 0.0f, 0.0f, 0.0f }, + { 11.0f, 1.0f, -1.5f, -0.1f, 0.0f, 0.0f }, + { 11.0f, 2.0f, -2.3f, 2.1f, -0.1f, 0.1f }, + { 11.0f, 3.0f, 2.1f, -0.7f, 0.1f, 0.0f }, + { 11.0f, 4.0f, -0.9f, -1.1f, 0.0f, 0.1f }, + { 11.0f, 5.0f, 0.6f, 0.7f, 0.0f, 0.0f }, + { 11.0f, 6.0f, -0.7f, -0.2f, 0.0f, 0.0f }, + { 11.0f, 7.0f, 0.2f, -2.1f, 0.0f, 0.1f }, + { 11.0f, 8.0f, 1.7f, -1.5f, 0.0f, 0.0f }, + { 11.0f, 9.0f, -0.2f, -2.5f, 0.0f, -0.1f }, + { 11.0f, 10.0f, 0.4f, -2.0f, -0.1f, 0.0f }, + { 11.0f, 11.0f, 3.5f, -2.3f, -0.1f, -0.1f }, + { 12.0f, 0.0f, -2.0f, 0.0f, 0.1f, 0.0f }, + { 12.0f, 1.0f, -0.3f, -1.0f, 0.0f, 0.0f }, + { 12.0f, 2.0f, 0.4f, 0.5f, 0.0f, 0.0f }, + { 12.0f, 3.0f, 1.3f, 1.8f, 0.1f, -0.1f }, + { 12.0f, 4.0f, -0.9f, -2.2f, -0.1f, 0.0f }, + { 12.0f, 5.0f, 0.9f, 0.3f, 0.0f, 0.0f }, + { 12.0f, 6.0f, 0.1f, 0.7f, 0.1f, 0.0f }, + { 12.0f, 7.0f, 0.5f, -0.1f, 0.0f, 0.0f }, + { 12.0f, 8.0f, -0.4f, 0.3f, 0.0f, 0.0f }, + { 12.0f, 9.0f, -0.4f, 0.2f, 0.0f, 0.0f }, { 12.0f, 10.0f, 0.2f, -0.9f, 0.0f, 0.0f }, - { 12.0f, 11.0f, -0.8f, -0.2f, -0.1f, 0.0f }, - { 12.0f, 12.0f, 0.0f, 0.9f, 0.1f, 0.0f } + { 12.0f, 11.0f, -0.9f, -0.2f, 0.0f, 0.0f }, + { 12.0f, 12.0f, 0.0f, 0.7f, 0.0f, 0.0f } }; static WMMtype_Ellipsoid *Ellip = NULL; @@ -190,10 +191,10 @@ int WMM_Initialize() MagneticModel->nMaxSecVar = WMM_MAX_SECULAR_VARIATION_MODEL_DEGREES; MagneticModel->SecularVariationUsed = 0; - // Really, Really needs to be read from a file - out of date in 2015 at latest + // Really, Really needs to be read from a file - out of date in 2020 at latest MagneticModel->EditionDate = 0.0f; /* OP change. Originally 5.7863328170559505e-307, truncates to 0.0f */ - MagneticModel->epoch = 2010.0f; - sprintf(MagneticModel->ModelName, "WMM-2010"); + MagneticModel->epoch = 2015.0f; + sprintf(MagneticModel->ModelName, "WMM-2015"); return 0; // OK } diff --git a/flight/libraries/alarms.c b/flight/libraries/alarms.c index db555ad8e..7cc7f39aa 100644 --- a/flight/libraries/alarms.c +++ b/flight/libraries/alarms.c @@ -6,7 +6,8 @@ * @brief OpenPilot System libraries are available to all OP modules. * @{ * @file alarms.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @brief Library for setting and clearing system alarms * @see The GNU Public License (GPL) Version 3 * @@ -281,6 +282,107 @@ SystemAlarmsAlarmOptions AlarmsGetHighestSeverity() return highest; } + +static const char *const systemalarms_severity_names[] = { + [SYSTEMALARMS_ALARM_UNINITIALISED] = "UNINITIALISED", + [SYSTEMALARMS_ALARM_OK] = "OK", + [SYSTEMALARMS_ALARM_WARNING] = "WARNING", + [SYSTEMALARMS_ALARM_CRITICAL] = "CRITICAL", + [SYSTEMALARMS_ALARM_ERROR] = "ERROR" +}; + +static const char *const systemalarms_alarm_names[] = { + [SYSTEMALARMS_ALARM_SYSTEMCONFIGURATION] = "CONFIG", + [SYSTEMALARMS_ALARM_BOOTFAULT] = "BOOT", + [SYSTEMALARMS_ALARM_OUTOFMEMORY] = "MEM", + [SYSTEMALARMS_ALARM_STACKOVERFLOW] = "STACK", + [SYSTEMALARMS_ALARM_CPUOVERLOAD] = "CPU", + [SYSTEMALARMS_ALARM_EVENTSYSTEM] = "EVENT", + [SYSTEMALARMS_ALARM_TELEMETRY] = "TELEMETRY", + [SYSTEMALARMS_ALARM_RECEIVER] = "INPUT", + [SYSTEMALARMS_ALARM_MANUALCONTROL] = "MANUAL", + [SYSTEMALARMS_ALARM_ACTUATOR] = "ACTUATOR", + [SYSTEMALARMS_ALARM_ATTITUDE] = "ATTI", + [SYSTEMALARMS_ALARM_SENSORS] = "SENSOR", + [SYSTEMALARMS_ALARM_MAGNETOMETER] = "MAG", + [SYSTEMALARMS_ALARM_AIRSPEED] = "AIRSPD", + [SYSTEMALARMS_ALARM_STABILIZATION] = "STAB", + [SYSTEMALARMS_ALARM_GUIDANCE] = "GUIDANCE", + [SYSTEMALARMS_ALARM_PATHPLAN] = "PLAN", + [SYSTEMALARMS_ALARM_BATTERY] = "BATT", + [SYSTEMALARMS_ALARM_FLIGHTTIME] = "TIME", + [SYSTEMALARMS_ALARM_I2C] = "I2C", + [SYSTEMALARMS_ALARM_GPS] = "GPS", +}; + +static const char *const systemalarms_extendedalarmstatus_names[] = { + [SYSTEMALARMS_EXTENDEDALARMSTATUS_REBOOTREQUIRED] = "CFG:REBOOT", + [SYSTEMALARMS_EXTENDEDALARMSTATUS_FLIGHTMODE] = "CFG:FLIGHTMODE", + [SYSTEMALARMS_EXTENDEDALARMSTATUS_UNSUPPORTEDCONFIG_ONESHOT] = "CFG:ONESHOT", + [SYSTEMALARMS_EXTENDEDALARMSTATUS_BADTHROTTLEORCOLLECTIVEINPUTRANGE] = "CFG:THR-COL", +}; + +size_t AlarmString(SystemAlarmsData *alarm, char *buffer, size_t buffer_size, SystemAlarmsAlarmOptions level, SystemAlarmsAlarmOptions *highestSeverity) +{ + size_t pos = 0; + + PIOS_STATIC_ASSERT(NELEMENTS(systemalarms_alarm_names) == SYSTEMALARMS_ALARM_NUMELEM); + + for (unsigned severity = SYSTEMALARMS_ALARM_ERROR; severity >= level; --severity) { + // should we prepend severity level here? No, not for now. + + for (unsigned i = 0; i < SYSTEMALARMS_ALARM_NUMELEM; ++i) { + if ((SystemAlarmsAlarmToArray(alarm->Alarm)[i] == severity) + && (systemalarms_alarm_names[i])) { + if (highestSeverity) { // they are already sorted by severity as we are processing in specific order + *highestSeverity = severity; + highestSeverity = 0; + } + + // in which case should we dig into extended alarm status? + // looks like SYSTEMALARMS_ALARM_SYSTEMCONFIGURATION sets most of the extended alarms + // except SYSTEMALARMS_ALARM_BOOTFAULT which also sets SYSTEMALARMS_EXTENDEDALARMSTATUS_REBOOTREQUIRED + + const char *current_msg = systemalarms_alarm_names[i]; + + switch (i) { + case SYSTEMALARMS_ALARM_SYSTEMCONFIGURATION: + if (alarm->ExtendedAlarmStatus.SystemConfiguration < NELEMENTS(systemalarms_extendedalarmstatus_names)) { + current_msg = systemalarms_extendedalarmstatus_names[alarm->ExtendedAlarmStatus.SystemConfiguration]; + } + break; + + case SYSTEMALARMS_ALARM_BOOTFAULT: + if (alarm->ExtendedAlarmStatus.BootFault < NELEMENTS(systemalarms_extendedalarmstatus_names)) { + current_msg = systemalarms_extendedalarmstatus_names[alarm->ExtendedAlarmStatus.BootFault]; + } + break; + } + + int current_len = strlen(current_msg); + + if ((pos + current_len + 1) > buffer_size) { + break; + } + + memcpy(buffer + pos, current_msg, current_len); + + pos += current_len; + + buffer[pos++] = ','; + } + } + } + + if (pos > 0) { + --pos; // get rid of that trailing separator. + } + + buffer[pos] = 0; + + return pos; // return length of the string in buffer. Actual bytes written is +1 +} + /** * @} * @} diff --git a/flight/libraries/auxmagsupport.c b/flight/libraries/auxmagsupport.c index 3d27e336a..68c620e6f 100644 --- a/flight/libraries/auxmagsupport.c +++ b/flight/libraries/auxmagsupport.c @@ -2,7 +2,8 @@ ****************************************************************************** * * @file auxmagsupport.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014. * @brief Functions to handle aux mag data and calibration. * -- * @see The GNU Public License (GPL) Version 3 @@ -37,16 +38,30 @@ AuxMagSettingsTypeOptions option; void auxmagsupport_reload_settings() { + AuxMagSettingsData cal; + float magQuat[4]; + float R[3][3]; + + AuxMagSettingsGet(&cal); + mag_bias[0] = cal.mag_bias.X; + mag_bias[1] = cal.mag_bias.Y; + mag_bias[2] = cal.mag_bias.Z; + + // convert the RPY mag board rotation to into a rotation matrix + // rotate the vector into the level hover frame (the attitude frame) + const float magRpy[3] = { cal.BoardRotation.Roll, cal.BoardRotation.Pitch, cal.BoardRotation.Yaw }; + RPY2Quaternion(magRpy, magQuat); + Quaternion2R(magQuat, R); + + // the mag transform only scales the raw mag values + matrix_mult_3x3f((float(*)[3])AuxMagSettingsmag_transformToArray(cal.mag_transform), R, mag_transform); + + // GPSV9, Ext (unused), and Flexi AuxMagSettingsTypeGet(&option); - float a[3][3]; - float b[3][3]; - float rotz; - AuxMagSettingsmag_transformArrayGet((float *)a); - AuxMagSettingsOrientationGet(&rotz); - rotz = DEG2RAD(rotz); - rot_about_axis_z(rotz, b); - matrix_mult_3x3f(a, b, mag_transform); - AuxMagSettingsmag_biasArrayGet(mag_bias); + + const uint8_t status = AUXMAGSENSOR_STATUS_NONE; + // next sample from other external mags will provide the right status if present + AuxMagSensorStatusSet((uint8_t *)&status); } void auxmagsupport_publish_samples(float mags[3], uint8_t status) diff --git a/flight/libraries/inc/alarms.h b/flight/libraries/inc/alarms.h index 304916dbc..afcbfac24 100644 --- a/flight/libraries/inc/alarms.h +++ b/flight/libraries/inc/alarms.h @@ -5,7 +5,8 @@ * @addtogroup OpenPilotLibraries OpenPilot System Libraries * @{ * @file alarms.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @brief Include file of the alarm library * @see The GNU Public License (GPL) Version 3 * @@ -48,6 +49,8 @@ int32_t AlarmsHasErrors(); int32_t AlarmsHasCritical(); SystemAlarmsAlarmOptions AlarmsGetHighestSeverity(); +size_t AlarmString(SystemAlarmsData *alarm, char *buffer, size_t buffer_size, SystemAlarmsAlarmOptions level, SystemAlarmsAlarmOptions *highestSeverity); + #endif // ALARMS_H /** diff --git a/flight/libraries/inc/optypes.h b/flight/libraries/inc/optypes.h index 6b9080db7..677e8bf61 100644 --- a/flight/libraries/inc/optypes.h +++ b/flight/libraries/inc/optypes.h @@ -50,15 +50,18 @@ extern const Color_t Color_White; #define COLOR_BLACK { .R = 0x00, .G = 0x00, .B = 0x00 } #define COLOR_OFF COLOR_BLACK #define COLOR_RED { .R = 0xFF, .G = 0x00, .B = 0x00 } +#define COLOR_DARKRED { .R = 0x80, .G = 0x00, .B = 0x00 } #define COLOR_LIME { .R = 0x00, .G = 0xFF, .B = 0x00 } #define COLOR_BLUE { .R = 0x00, .G = 0x00, .B = 0xFF } -#define COLOR_YELLOW { .R = 0xFF, .G = 0xFF, .B = 0x00 } +#define COLOR_YELLOW { .R = 0xCC, .G = 0xCC, .B = 0x00 } #define COLOR_CIAN { .R = 0x00, .G = 0xFF, .B = 0xFF } #define COLOR_MAGENTA { .R = 0xFF, .G = 0x00, .B = 0xFF } #define COLOR_NAVY { .R = 0x00, .G = 0x00, .B = 0x80 } #define COLOR_GREEN { .R = 0x00, .G = 0x80, .B = 0x00 } #define COLOR_PURPLE { .R = 0x80, .G = 0x00, .B = 0x80 } #define COLOR_TEAL { .R = 0x00, .G = 0x80, .B = 0x80 } -#define COLOR_ORANGE { .R = 0xFF, .G = 0xA5, .B = 0x00 } +#define COLOR_ORANGE { .R = 0xAA, .G = 0x44, .B = 0x00 } #define COLOR_WHITE { .R = 0xAA, .G = 0xAA, .B = 0xAA } + + #endif /* UTIL_H */ diff --git a/flight/libraries/insgps13state.c b/flight/libraries/insgps13state.c index cb41469c8..c311f05d3 100644 --- a/flight/libraries/insgps13state.c +++ b/flight/libraries/insgps13state.c @@ -280,11 +280,11 @@ void INSSetBaroVar(float baro_var) void INSSetMagNorth(float B[3]) { - float mag = sqrtf(B[0] * B[0] + B[1] * B[1] + B[2] * B[2]); + float invmag = invsqrtf(B[0] * B[0] + B[1] * B[1] + B[2] * B[2]); - ekf.Be[0] = B[0] / mag; - ekf.Be[1] = B[1] / mag; - ekf.Be[2] = B[2] / mag; + ekf.Be[0] = B[0] * invmag; + ekf.Be[1] = B[1] * invmag; + ekf.Be[2] = B[2] * invmag; } void INSStatePrediction(float gyro_data[3], float accel_data[3], float dT) @@ -305,7 +305,7 @@ void INSStatePrediction(float gyro_data[3], float accel_data[3], float dT) // EKF prediction step LinearizeFG(ekf.X, U, ekf.F, ekf.G); RungeKutta(ekf.X, U, dT); - invqmag = fast_invsqrtf(ekf.X[6] * ekf.X[6] + ekf.X[7] * ekf.X[7] + ekf.X[8] * ekf.X[8] + ekf.X[9] * ekf.X[9]); + invqmag = invsqrtf(ekf.X[6] * ekf.X[6] + ekf.X[7] * ekf.X[7] + ekf.X[8] * ekf.X[8] + ekf.X[9] * ekf.X[9]); ekf.X[6] *= invqmag; ekf.X[7] *= invqmag; ekf.X[8] *= invqmag; @@ -390,7 +390,7 @@ void INSCorrection(float mag_data[3], float Pos[3], float Vel[3], if (SensorsUsed & MAG_SENSORS) { - float invBmag = fast_invsqrtf(mag_data[0] * mag_data[0] + mag_data[1] * mag_data[1] + mag_data[2] * mag_data[2]); + float invBmag = invsqrtf(mag_data[0] * mag_data[0] + mag_data[1] * mag_data[1] + mag_data[2] * mag_data[2]); Z[6] = mag_data[0] * invBmag; Z[7] = mag_data[1] * invBmag; Z[8] = mag_data[2] * invBmag; @@ -404,7 +404,7 @@ void INSCorrection(float mag_data[3], float Pos[3], float Vel[3], MeasurementEq(ekf.X, ekf.Be, Y); SerialUpdate(ekf.H, ekf.R, Z, Y, ekf.P, ekf.X, SensorsUsed); - float invqmag = fast_invsqrtf(ekf.X[6] * ekf.X[6] + ekf.X[7] * ekf.X[7] + ekf.X[8] * ekf.X[8] + ekf.X[9] * ekf.X[9]); + float invqmag = invsqrtf(ekf.X[6] * ekf.X[6] + ekf.X[7] * ekf.X[7] + ekf.X[8] * ekf.X[8] + ekf.X[9] * ekf.X[9]); ekf.X[6] *= invqmag; ekf.X[7] *= invqmag; ekf.X[8] *= invqmag; diff --git a/flight/libraries/math/mathmisc.c b/flight/libraries/math/mathmisc.c index 25ddc9559..f1bff5751 100644 --- a/flight/libraries/math/mathmisc.c +++ b/flight/libraries/math/mathmisc.c @@ -5,8 +5,9 @@ * @addtogroup Reuseable math functions * @{ * - * @file mathmisc.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. + * @file mathmisc.c + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. * @brief Reuseable math functions * * @see The GNU Public License (GPL) Version 3 @@ -28,5 +29,17 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include -// space deliberately left empty, any non inline misc math functions can go here +void pseudo_windowed_variance_init(pw_variance_t *variance, int32_t window_size) +{ + variance->new_sma = 0.0f; + variance->new_smsa = 0.0f; + variance->p1 = 1.0f / (float)window_size; + variance->p2 = 1.0f - variance->p1; +} + +float pseudo_windowed_variance_get(pw_variance_t *variance) +{ + return variance->new_smsa - variance->new_sma * variance->new_sma; +} diff --git a/flight/libraries/math/mathmisc.h b/flight/libraries/math/mathmisc.h index 68026f682..f586d65ea 100644 --- a/flight/libraries/math/mathmisc.h +++ b/flight/libraries/math/mathmisc.h @@ -6,7 +6,8 @@ * @{ * * @file mathmisc.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. * @brief Reuseable math functions * * @see The GNU Public License (GPL) Version 3 @@ -34,6 +35,38 @@ #include #include +typedef struct { + float p1; + float p2; + float new_sma; + float new_smsa; +} pw_variance_t; + +/*** + * initialize pseudo windowed + * @param variance the instance to be initialized + * @param window_size size of the sample window + */ +void pseudo_windowed_variance_init(pw_variance_t *variance, int32_t window_size); + +/*** + * Push a new sample + * @param variance the working instance + * @param sample the new sample + */ +static inline void pseudo_windowed_variance_push_sample(pw_variance_t *variance, float sample) +{ + variance->new_sma = variance->new_sma * variance->p2 + sample * variance->p1; + variance->new_smsa = variance->new_smsa * variance->p2 + sample * sample * variance->p1; +} + +/*** + * Get the current variance value + * @param variance the working instance + * @return + */ +float pseudo_windowed_variance_get(pw_variance_t *variance); + // returns min(boundary1,boundary2) if valmax(boundary1,boundary2) // returns val if min(boundary1,boundary2)<=val<=max(boundary1,boundary2) @@ -119,28 +152,12 @@ static inline float y_on_curve(float x, const pointf points[], int num_points) // Find the y value on the selected line. return y_on_line(x, &points[end_point - 1], &points[end_point]); } -// Fast inverse square root implementation from "quake3-1.32b/code/game/q_math.c" -// http://en.wikipedia.org/wiki/Fast_inverse_square_root -static inline float fast_invsqrtf(float number) +static inline float invsqrtf(float number) { - float x2, y; - const float threehalfs = 1.5F; - - union { - float f; - uint32_t u; - } i; - - x2 = number * 0.5F; - y = number; - - i.f = y; // evil floating point bit level hacking - i.u = 0x5f3759df - (i.u >> 1); // what the fxck? - y = i.f; - y = y * (threehalfs - (x2 * y * y)); // 1st iteration -// y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed + float y; + y = 1.0f / sqrtf(number); return y; } diff --git a/flight/libraries/math/pid.c b/flight/libraries/math/pid.c index e03e6e97b..6e962c306 100644 --- a/flight/libraries/math/pid.c +++ b/flight/libraries/math/pid.c @@ -76,7 +76,7 @@ float pid_apply(struct pid *pid, const float err, float dT) * This version of apply uses setpoint weighting for the derivative component so the gain * on the gyro derivative can be different than the gain on the setpoint derivative */ -float pid_apply_setpoint(struct pid *pid, const pid_scaler *scaler, const float setpoint, const float measured, float dT) +float pid_apply_setpoint(struct pid *pid, const pid_scaler *scaler, const float setpoint, const float measured, float dT, bool meas_based_d_term) { float err = setpoint - measured; @@ -85,9 +85,18 @@ float pid_apply_setpoint(struct pid *pid, const pid_scaler *scaler, const float pid->iAccumulator = boundf(pid->iAccumulator, pid->iLim * -1000.0f, pid->iLim * 1000.0f); // Calculate DT1 term, + float diff; + float derr = (-measured); + + if (!meas_based_d_term) { + derr += deriv_gamma * setpoint; + } + + diff = derr - pid->lastErr; + pid->lastErr = derr; + float dterm = 0; - float diff = ((deriv_gamma * setpoint - measured) - pid->lastErr); - pid->lastErr = (deriv_gamma * setpoint - measured); + if (pid->d > 0.0f && dT > 0.0f) { // low pass filter derivative term. below formula is the same as // dterm = (1-alpha)*pid->lastDer + alpha * (...)/dT @@ -95,7 +104,6 @@ float pid_apply_setpoint(struct pid *pid, const pid_scaler *scaler, const float dterm = pid->lastDer + dT / (dT + deriv_tau) * ((scaler->d * diff * pid->d / dT) - pid->lastDer); pid->lastDer = dterm; } - return (err * scaler->p * pid->p) + pid->iAccumulator / 1000.0f + dterm; } diff --git a/flight/libraries/math/pid.h b/flight/libraries/math/pid.h index 9b81cebad..b6d9e2ae6 100644 --- a/flight/libraries/math/pid.h +++ b/flight/libraries/math/pid.h @@ -70,7 +70,7 @@ typedef struct pid_scaler_s { // ! Methods to use the pid structures float pid_apply(struct pid *pid, const float err, float dT); -float pid_apply_setpoint(struct pid *pid, const pid_scaler *scaler, const float setpoint, const float measured, float dT); +float pid_apply_setpoint(struct pid *pid, const pid_scaler *scaler, const float setpoint, const float measured, float dT, bool meas_based_d_term); void pid_zero(struct pid *pid); void pid_configure(struct pid *pid, float p, float i, float d, float iLim); void pid_configure_derivative(float cutoff, float gamma); diff --git a/ground/gcs/src/libs/glc_lib/COPYING b/flight/libraries/mavlink/COPYING.txt similarity index 100% rename from ground/gcs/src/libs/glc_lib/COPYING rename to flight/libraries/mavlink/COPYING.txt diff --git a/flight/libraries/mavlink/config.h b/flight/libraries/mavlink/config.h new file mode 100644 index 000000000..db7db0d7d --- /dev/null +++ b/flight/libraries/mavlink/config.h @@ -0,0 +1 @@ +#define MAVLINK_VERSION "1.0.7" diff --git a/flight/libraries/mavlink/v1.0/checksum.h b/flight/libraries/mavlink/v1.0/checksum.h new file mode 100644 index 000000000..73f6738af --- /dev/null +++ b/flight/libraries/mavlink/v1.0/checksum.h @@ -0,0 +1,89 @@ +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _CHECKSUM_H_ +#define _CHECKSUM_H_ + + +/** + * + * CALCULATE THE CHECKSUM + * + */ + +#define X25_INIT_CRC 0xffff +#define X25_VALIDATE_CRC 0xf0b8 + +/** + * @brief Accumulate the X.25 CRC by adding one char at a time. + * + * The checksum function adds the hash of one char at a time to the + * 16 bit checksum (uint16_t). + * + * @param data new char to hash + * @param crcAccum the already accumulated checksum + **/ +static inline void crc_accumulate(uint8_t data, uint16_t *crcAccum) +{ + /*Accumulate one byte of data into the CRC*/ + uint8_t tmp; + + tmp = data ^ (uint8_t)(*crcAccum & 0xff); + tmp ^= (tmp << 4); + *crcAccum = (*crcAccum >> 8) ^ (tmp << 8) ^ (tmp << 3) ^ (tmp >> 4); +} + +/** + * @brief Initiliaze the buffer for the X.25 CRC + * + * @param crcAccum the 16 bit X.25 CRC + */ +static inline void crc_init(uint16_t *crcAccum) +{ + *crcAccum = X25_INIT_CRC; +} + + +/** + * @brief Calculates the X.25 checksum on a byte buffer + * + * @param pBuffer buffer containing the byte array to hash + * @param length length of the byte array + * @return the checksum over the buffer bytes + **/ +static inline uint16_t crc_calculate(const uint8_t *pBuffer, uint16_t length) +{ + uint16_t crcTmp; + + crc_init(&crcTmp); + while (length--) { + crc_accumulate(*pBuffer++, &crcTmp); + } + return crcTmp; +} + +/** + * @brief Accumulate the X.25 CRC by adding an array of bytes + * + * The checksum function adds the hash of one char at a time to the + * 16 bit checksum (uint16_t). + * + * @param data new bytes to hash + * @param crcAccum the already accumulated checksum + **/ +static inline void crc_accumulate_buffer(uint16_t *crcAccum, const char *pBuffer, uint8_t length) +{ + const uint8_t *p = (const uint8_t *)pBuffer; + + while (length--) { + crc_accumulate(*p++, crcAccum); + } +} + + +#endif /* _CHECKSUM_H_ */ + +#ifdef __cplusplus +} +#endif diff --git a/flight/libraries/mavlink/v1.0/common/common.h b/flight/libraries/mavlink/v1.0/common/common.h new file mode 100644 index 000000000..b14b96898 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/common.h @@ -0,0 +1,1020 @@ +/** @file + * @brief MAVLink comm protocol generated from common.xml + * @see http://qgroundcontrol.org/mavlink/ + */ +#ifndef COMMON_H +#define COMMON_H + +#ifdef __cplusplus +extern "C" { +#endif + +// MESSAGE LENGTHS AND CRCS + +#ifndef MAVLINK_MESSAGE_LENGTHS +#define MAVLINK_MESSAGE_LENGTHS { 9, 31, 12, 0, 14, 28, 3, 32, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 20, 2, 25, 23, 30, 101, 22, 26, 16, 14, 28, 32, 28, 28, 22, 22, 21, 6, 6, 37, 4, 4, 2, 2, 4, 2, 2, 3, 13, 12, 19, 17, 15, 15, 27, 25, 18, 18, 20, 20, 9, 34, 26, 46, 36, 0, 6, 4, 0, 21, 18, 0, 0, 0, 20, 0, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 56, 42, 33, 0, 0, 0, 0, 0, 0, 0, 26, 32, 32, 20, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 30, 18, 18, 51, 9, 0 } +#endif + +#ifndef MAVLINK_MESSAGE_CRCS +#define MAVLINK_MESSAGE_CRCS { 50, 124, 137, 0, 237, 217, 104, 119, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 0, 214, 159, 220, 168, 24, 23, 170, 144, 67, 115, 39, 246, 185, 104, 237, 244, 222, 212, 9, 254, 230, 28, 28, 132, 221, 232, 11, 153, 41, 39, 214, 223, 141, 33, 15, 3, 100, 24, 239, 238, 30, 240, 183, 130, 130, 0, 148, 21, 0, 52, 124, 0, 0, 0, 20, 0, 152, 143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 231, 183, 63, 54, 0, 0, 0, 0, 0, 0, 0, 175, 102, 158, 208, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 49, 170, 44, 83, 46, 0 } +#endif + +#ifndef MAVLINK_MESSAGE_INFO +#define MAVLINK_MESSAGE_INFO \ + { MAVLINK_MESSAGE_INFO_HEARTBEAT, MAVLINK_MESSAGE_INFO_SYS_STATUS, MAVLINK_MESSAGE_INFO_SYSTEM_TIME, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, MAVLINK_MESSAGE_INFO_PING, MAVLINK_MESSAGE_INFO_CHANGE_OPERATOR_CONTROL, MAVLINK_MESSAGE_INFO_CHANGE_OPERATOR_CONTROL_ACK, MAVLINK_MESSAGE_INFO_AUTH_KEY, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, MAVLINK_MESSAGE_INFO_SET_MODE, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, MAVLINK_MESSAGE_INFO_PARAM_REQUEST_READ, MAVLINK_MESSAGE_INFO_PARAM_REQUEST_LIST, MAVLINK_MESSAGE_INFO_PARAM_VALUE, MAVLINK_MESSAGE_INFO_PARAM_SET, MAVLINK_MESSAGE_INFO_GPS_RAW_INT, MAVLINK_MESSAGE_INFO_GPS_STATUS, MAVLINK_MESSAGE_INFO_SCALED_IMU, MAVLINK_MESSAGE_INFO_RAW_IMU, MAVLINK_MESSAGE_INFO_RAW_PRESSURE, MAVLINK_MESSAGE_INFO_SCALED_PRESSURE, MAVLINK_MESSAGE_INFO_ATTITUDE, MAVLINK_MESSAGE_INFO_ATTITUDE_QUATERNION, MAVLINK_MESSAGE_INFO_LOCAL_POSITION_NED, MAVLINK_MESSAGE_INFO_GLOBAL_POSITION_INT, MAVLINK_MESSAGE_INFO_RC_CHANNELS_SCALED, MAVLINK_MESSAGE_INFO_RC_CHANNELS_RAW, MAVLINK_MESSAGE_INFO_SERVO_OUTPUT_RAW, MAVLINK_MESSAGE_INFO_MISSION_REQUEST_PARTIAL_LIST, MAVLINK_MESSAGE_INFO_MISSION_WRITE_PARTIAL_LIST, MAVLINK_MESSAGE_INFO_MISSION_ITEM, MAVLINK_MESSAGE_INFO_MISSION_REQUEST, MAVLINK_MESSAGE_INFO_MISSION_SET_CURRENT, MAVLINK_MESSAGE_INFO_MISSION_CURRENT, MAVLINK_MESSAGE_INFO_MISSION_REQUEST_LIST, MAVLINK_MESSAGE_INFO_MISSION_COUNT, MAVLINK_MESSAGE_INFO_MISSION_CLEAR_ALL, MAVLINK_MESSAGE_INFO_MISSION_ITEM_REACHED, MAVLINK_MESSAGE_INFO_MISSION_ACK, MAVLINK_MESSAGE_INFO_SET_GPS_GLOBAL_ORIGIN, MAVLINK_MESSAGE_INFO_GPS_GLOBAL_ORIGIN, MAVLINK_MESSAGE_INFO_SET_LOCAL_POSITION_SETPOINT, MAVLINK_MESSAGE_INFO_LOCAL_POSITION_SETPOINT, MAVLINK_MESSAGE_INFO_GLOBAL_POSITION_SETPOINT_INT, MAVLINK_MESSAGE_INFO_SET_GLOBAL_POSITION_SETPOINT_INT, MAVLINK_MESSAGE_INFO_SAFETY_SET_ALLOWED_AREA, MAVLINK_MESSAGE_INFO_SAFETY_ALLOWED_AREA, MAVLINK_MESSAGE_INFO_SET_ROLL_PITCH_YAW_THRUST, MAVLINK_MESSAGE_INFO_SET_ROLL_PITCH_YAW_SPEED_THRUST, MAVLINK_MESSAGE_INFO_ROLL_PITCH_YAW_THRUST_SETPOINT, MAVLINK_MESSAGE_INFO_ROLL_PITCH_YAW_SPEED_THRUST_SETPOINT, MAVLINK_MESSAGE_INFO_SET_QUAD_MOTORS_SETPOINT, MAVLINK_MESSAGE_INFO_SET_QUAD_SWARM_ROLL_PITCH_YAW_THRUST, MAVLINK_MESSAGE_INFO_NAV_CONTROLLER_OUTPUT, MAVLINK_MESSAGE_INFO_SET_QUAD_SWARM_LED_ROLL_PITCH_YAW_THRUST, MAVLINK_MESSAGE_INFO_STATE_CORRECTION, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, MAVLINK_MESSAGE_INFO_REQUEST_DATA_STREAM, MAVLINK_MESSAGE_INFO_DATA_STREAM, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, MAVLINK_MESSAGE_INFO_MANUAL_CONTROL, MAVLINK_MESSAGE_INFO_RC_CHANNELS_OVERRIDE, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, MAVLINK_MESSAGE_INFO_VFR_HUD, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, MAVLINK_MESSAGE_INFO_COMMAND_LONG, MAVLINK_MESSAGE_INFO_COMMAND_ACK, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, MAVLINK_MESSAGE_INFO_LOCAL_POSITION_NED_SYSTEM_GLOBAL_OFFSET, MAVLINK_MESSAGE_INFO_HIL_STATE, MAVLINK_MESSAGE_INFO_HIL_CONTROLS, MAVLINK_MESSAGE_INFO_HIL_RC_INPUTS_RAW, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, MAVLINK_MESSAGE_INFO_OPTICAL_FLOW, MAVLINK_MESSAGE_INFO_GLOBAL_VISION_POSITION_ESTIMATE, MAVLINK_MESSAGE_INFO_VISION_POSITION_ESTIMATE, MAVLINK_MESSAGE_INFO_VISION_SPEED_ESTIMATE, MAVLINK_MESSAGE_INFO_VICON_POSITION_ESTIMATE, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + }, MAVLINK_MESSAGE_INFO_MEMORY_VECT, MAVLINK_MESSAGE_INFO_DEBUG_VECT, MAVLINK_MESSAGE_INFO_NAMED_VALUE_FLOAT, MAVLINK_MESSAGE_INFO_NAMED_VALUE_INT, MAVLINK_MESSAGE_INFO_STATUSTEXT, MAVLINK_MESSAGE_INFO_DEBUG, { "EMPTY", 0, { \ + { "", "", MAVLINK_TYPE_CHAR, 0, 0, 0 } \ + } \ + } \ + } +#endif // ifndef MAVLINK_MESSAGE_INFO + +#include "../protocol.h" + +#define MAVLINK_ENABLED_COMMON + +// ENUM DEFINITIONS + + +/** @brief Micro air vehicle / autopilot classes. This identifies the individual model. */ +#ifndef HAVE_ENUM_MAV_AUTOPILOT +#define HAVE_ENUM_MAV_AUTOPILOT +enum MAV_AUTOPILOT { + MAV_AUTOPILOT_GENERIC = 0, /* Generic autopilot, full support for everything | */ + MAV_AUTOPILOT_PIXHAWK = 1, /* PIXHAWK autopilot, http://pixhawk.ethz.ch | */ + MAV_AUTOPILOT_SLUGS = 2, /* SLUGS autopilot, http://slugsuav.soe.ucsc.edu | */ + MAV_AUTOPILOT_ARDUPILOTMEGA = 3, /* ArduPilotMega / ArduCopter, http://diydrones.com | */ + MAV_AUTOPILOT_OPENPILOT = 4, /* OpenPilot, http://openpilot.org | */ + MAV_AUTOPILOT_GENERIC_WAYPOINTS_ONLY = 5, /* Generic autopilot only supporting simple waypoints | */ + MAV_AUTOPILOT_GENERIC_WAYPOINTS_AND_SIMPLE_NAVIGATION_ONLY = 6, /* Generic autopilot supporting waypoints and other simple navigation commands | */ + MAV_AUTOPILOT_GENERIC_MISSION_FULL = 7, /* Generic autopilot supporting the full mission command set | */ + MAV_AUTOPILOT_INVALID = 8, /* No valid autopilot, e.g. a GCS or other MAVLink component | */ + MAV_AUTOPILOT_PPZ = 9, /* PPZ UAV - http://nongnu.org/paparazzi | */ + MAV_AUTOPILOT_UDB = 10, /* UAV Dev Board | */ + MAV_AUTOPILOT_FP = 11, /* FlexiPilot | */ + MAV_AUTOPILOT_PX4 = 12, /* PX4 Autopilot - http://pixhawk.ethz.ch/px4/ | */ + MAV_AUTOPILOT_ENUM_END = 13, /* | */ +}; +#endif + +/** @brief */ +#ifndef HAVE_ENUM_MAV_TYPE +#define HAVE_ENUM_MAV_TYPE +enum MAV_TYPE { + MAV_TYPE_GENERIC = 0, /* Generic micro air vehicle. | */ + MAV_TYPE_FIXED_WING = 1, /* Fixed wing aircraft. | */ + MAV_TYPE_QUADROTOR = 2, /* Quadrotor | */ + MAV_TYPE_COAXIAL = 3, /* Coaxial helicopter | */ + MAV_TYPE_HELICOPTER = 4, /* Normal helicopter with tail rotor. | */ + MAV_TYPE_ANTENNA_TRACKER = 5, /* Ground installation | */ + MAV_TYPE_GCS = 6, /* Operator control unit / ground control station | */ + MAV_TYPE_AIRSHIP = 7, /* Airship, controlled | */ + MAV_TYPE_FREE_BALLOON = 8, /* Free balloon, uncontrolled | */ + MAV_TYPE_ROCKET = 9, /* Rocket | */ + MAV_TYPE_GROUND_ROVER = 10, /* Ground rover | */ + MAV_TYPE_SURFACE_BOAT = 11, /* Surface vessel, boat, ship | */ + MAV_TYPE_SUBMARINE = 12, /* Submarine | */ + MAV_TYPE_HEXAROTOR = 13, /* Hexarotor | */ + MAV_TYPE_OCTOROTOR = 14, /* Octorotor | */ + MAV_TYPE_TRICOPTER = 15, /* Octorotor | */ + MAV_TYPE_FLAPPING_WING = 16, /* Flapping wing | */ + MAV_TYPE_KITE = 17, /* Flapping wing | */ + MAV_TYPE_ENUM_END = 18, /* | */ +}; +#endif // ifndef HAVE_ENUM_MAV_TYPE + +/** @brief These flags encode the MAV mode. */ +#ifndef HAVE_ENUM_MAV_MODE_FLAG +#define HAVE_ENUM_MAV_MODE_FLAG +enum MAV_MODE_FLAG { + MAV_MODE_FLAG_CUSTOM_MODE_ENABLED = 1, /* 0b00000001 Reserved for future use. | */ + MAV_MODE_FLAG_TEST_ENABLED = 2, /* 0b00000010 system has a test mode enabled. This flag is intended for temporary system tests and should not be used for stable implementations. | */ + MAV_MODE_FLAG_AUTO_ENABLED = 4, /* 0b00000100 autonomous mode enabled, system finds its own goal positions. Guided flag can be set or not, depends on the actual implementation. | */ + MAV_MODE_FLAG_GUIDED_ENABLED = 8, /* 0b00001000 guided mode enabled, system flies MISSIONs / mission items. | */ + MAV_MODE_FLAG_STABILIZE_ENABLED = 16, /* 0b00010000 system stabilizes electronically its attitude (and optionally position). It needs however further control inputs to move around. | */ + MAV_MODE_FLAG_HIL_ENABLED = 32, /* 0b00100000 hardware in the loop simulation. All motors / actuators are blocked, but internal software is full operational. | */ + MAV_MODE_FLAG_MANUAL_INPUT_ENABLED = 64, /* 0b01000000 remote control input is enabled. | */ + MAV_MODE_FLAG_SAFETY_ARMED = 128, /* 0b10000000 MAV safety set to armed. Motors are enabled / running / can start. Ready to fly. | */ + MAV_MODE_FLAG_ENUM_END = 129, /* | */ +}; +#endif + +/** @brief These values encode the bit positions of the decode position. These values can be used to read the value of a flag bit by combining the base_mode variable with AND with the flag position value. The result will be either 0 or 1, depending on if the flag is set or not. */ +#ifndef HAVE_ENUM_MAV_MODE_FLAG_DECODE_POSITION +#define HAVE_ENUM_MAV_MODE_FLAG_DECODE_POSITION +enum MAV_MODE_FLAG_DECODE_POSITION { + MAV_MODE_FLAG_DECODE_POSITION_CUSTOM_MODE = 1, /* Eighth bit: 00000001 | */ + MAV_MODE_FLAG_DECODE_POSITION_TEST = 2, /* Seventh bit: 00000010 | */ + MAV_MODE_FLAG_DECODE_POSITION_AUTO = 4, /* Sixt bit: 00000100 | */ + MAV_MODE_FLAG_DECODE_POSITION_GUIDED = 8, /* Fifth bit: 00001000 | */ + MAV_MODE_FLAG_DECODE_POSITION_STABILIZE = 16, /* Fourth bit: 00010000 | */ + MAV_MODE_FLAG_DECODE_POSITION_HIL = 32, /* Third bit: 00100000 | */ + MAV_MODE_FLAG_DECODE_POSITION_MANUAL = 64, /* Second bit: 01000000 | */ + MAV_MODE_FLAG_DECODE_POSITION_SAFETY = 128, /* First bit: 10000000 | */ + MAV_MODE_FLAG_DECODE_POSITION_ENUM_END = 129, /* | */ +}; +#endif + +/** @brief Override command, pauses current mission execution and moves immediately to a position */ +#ifndef HAVE_ENUM_MAV_GOTO +#define HAVE_ENUM_MAV_GOTO +enum MAV_GOTO { + MAV_GOTO_DO_HOLD = 0, /* Hold at the current position. | */ + MAV_GOTO_DO_CONTINUE = 1, /* Continue with the next item in mission execution. | */ + MAV_GOTO_HOLD_AT_CURRENT_POSITION = 2, /* Hold at the current position of the system | */ + MAV_GOTO_HOLD_AT_SPECIFIED_POSITION = 3, /* Hold at the position specified in the parameters of the DO_HOLD action | */ + MAV_GOTO_ENUM_END = 4, /* | */ +}; +#endif + +/** @brief These defines are predefined OR-combined mode flags. There is no need to use values from this enum, but it + simplifies the use of the mode flags. Note that manual input is enabled in all modes as a safety override. */ +#ifndef HAVE_ENUM_MAV_MODE +#define HAVE_ENUM_MAV_MODE +enum MAV_MODE { + MAV_MODE_PREFLIGHT = 0, /* System is not ready to fly, booting, calibrating, etc. No flag is set. | */ + MAV_MODE_MANUAL_DISARMED = 64, /* System is allowed to be active, under manual (RC) control, no stabilization | */ + MAV_MODE_TEST_DISARMED = 66, /* UNDEFINED mode. This solely depends on the autopilot - use with caution, intended for developers only. | */ + MAV_MODE_STABILIZE_DISARMED = 80, /* System is allowed to be active, under assisted RC control. | */ + MAV_MODE_GUIDED_DISARMED = 88, /* System is allowed to be active, under autonomous control, manual setpoint | */ + MAV_MODE_AUTO_DISARMED = 92, /* System is allowed to be active, under autonomous control and navigation (the trajectory is decided onboard and not pre-programmed by MISSIONs) | */ + MAV_MODE_MANUAL_ARMED = 192, /* System is allowed to be active, under manual (RC) control, no stabilization | */ + MAV_MODE_TEST_ARMED = 194, /* UNDEFINED mode. This solely depends on the autopilot - use with caution, intended for developers only. | */ + MAV_MODE_STABILIZE_ARMED = 208, /* System is allowed to be active, under assisted RC control. | */ + MAV_MODE_GUIDED_ARMED = 216, /* System is allowed to be active, under autonomous control, manual setpoint | */ + MAV_MODE_AUTO_ARMED = 220, /* System is allowed to be active, under autonomous control and navigation (the trajectory is decided onboard and not pre-programmed by MISSIONs) | */ + MAV_MODE_ENUM_END = 221, /* | */ +}; +#endif + +/** @brief */ +#ifndef HAVE_ENUM_MAV_STATE +#define HAVE_ENUM_MAV_STATE +enum MAV_STATE { + MAV_STATE_UNINIT = 0, /* Uninitialized system, state is unknown. | */ + MAV_STATE_BOOT = 1, /* System is booting up. | */ + MAV_STATE_CALIBRATING = 2, /* System is calibrating and not flight-ready. | */ + MAV_STATE_STANDBY = 3, /* System is grounded and on standby. It can be launched any time. | */ + MAV_STATE_ACTIVE = 4, /* System is active and might be already airborne. Motors are engaged. | */ + MAV_STATE_CRITICAL = 5, /* System is in a non-normal flight mode. It can however still navigate. | */ + MAV_STATE_EMERGENCY = 6, /* System is in a non-normal flight mode. It lost control over parts or over the whole airframe. It is in mayday and going down. | */ + MAV_STATE_POWEROFF = 7, /* System just initialized its power-down sequence, will shut down now. | */ + MAV_STATE_ENUM_END = 8, /* | */ +}; +#endif + +/** @brief */ +#ifndef HAVE_ENUM_MAV_COMPONENT +#define HAVE_ENUM_MAV_COMPONENT +enum MAV_COMPONENT { + MAV_COMP_ID_ALL = 0, /* | */ + MAV_COMP_ID_CAMERA = 100, /* | */ + MAV_COMP_ID_SERVO1 = 140, /* | */ + MAV_COMP_ID_SERVO2 = 141, /* | */ + MAV_COMP_ID_SERVO3 = 142, /* | */ + MAV_COMP_ID_SERVO4 = 143, /* | */ + MAV_COMP_ID_SERVO5 = 144, /* | */ + MAV_COMP_ID_SERVO6 = 145, /* | */ + MAV_COMP_ID_SERVO7 = 146, /* | */ + MAV_COMP_ID_SERVO8 = 147, /* | */ + MAV_COMP_ID_SERVO9 = 148, /* | */ + MAV_COMP_ID_SERVO10 = 149, /* | */ + MAV_COMP_ID_SERVO11 = 150, /* | */ + MAV_COMP_ID_SERVO12 = 151, /* | */ + MAV_COMP_ID_SERVO13 = 152, /* | */ + MAV_COMP_ID_SERVO14 = 153, /* | */ + MAV_COMP_ID_MAPPER = 180, /* | */ + MAV_COMP_ID_MISSIONPLANNER = 190, /* | */ + MAV_COMP_ID_PATHPLANNER = 195, /* | */ + MAV_COMP_ID_IMU = 200, /* | */ + MAV_COMP_ID_IMU_2 = 201, /* | */ + MAV_COMP_ID_IMU_3 = 202, /* | */ + MAV_COMP_ID_GPS = 220, /* | */ + MAV_COMP_ID_UDP_BRIDGE = 240, /* | */ + MAV_COMP_ID_UART_BRIDGE = 241, /* | */ + MAV_COMP_ID_SYSTEM_CONTROL = 250, /* | */ + MAV_COMPONENT_ENUM_END = 251, /* | */ +}; +#endif // ifndef HAVE_ENUM_MAV_COMPONENT + +/** @brief */ +#ifndef HAVE_ENUM_MAV_FRAME +#define HAVE_ENUM_MAV_FRAME +enum MAV_FRAME { + MAV_FRAME_GLOBAL = 0, /* Global coordinate frame, WGS84 coordinate system. First value / x: latitude, second value / y: longitude, third value / z: positive altitude over mean sea level (MSL) | */ + MAV_FRAME_LOCAL_NED = 1, /* Local coordinate frame, Z-up (x: north, y: east, z: down). | */ + MAV_FRAME_MISSION = 2, /* NOT a coordinate frame, indicates a mission command. | */ + MAV_FRAME_GLOBAL_RELATIVE_ALT = 3, /* Global coordinate frame, WGS84 coordinate system, relative altitude over ground with respect to the home position. First value / x: latitude, second value / y: longitude, third value / z: positive altitude with 0 being at the altitude of the home location. | */ + MAV_FRAME_LOCAL_ENU = 4, /* Local coordinate frame, Z-down (x: east, y: north, z: up) | */ + MAV_FRAME_ENUM_END = 5, /* | */ +}; +#endif + +/** @brief */ +#ifndef HAVE_ENUM_MAVLINK_DATA_STREAM_TYPE +#define HAVE_ENUM_MAVLINK_DATA_STREAM_TYPE +enum MAVLINK_DATA_STREAM_TYPE { + MAVLINK_DATA_STREAM_IMG_JPEG = 1, /* | */ + MAVLINK_DATA_STREAM_IMG_BMP = 2, /* | */ + MAVLINK_DATA_STREAM_IMG_RAW8U = 3, /* | */ + MAVLINK_DATA_STREAM_IMG_RAW32U = 4, /* | */ + MAVLINK_DATA_STREAM_IMG_PGM = 5, /* | */ + MAVLINK_DATA_STREAM_IMG_PNG = 6, /* | */ + MAVLINK_DATA_STREAM_TYPE_ENUM_END = 7, /* | */ +}; +#endif + +/** @brief Commands to be executed by the MAV. They can be executed on user request, or as part of a mission script. If the action is used in a mission, the parameter mapping to the waypoint/mission message is as follows: Param 1, Param 2, Param 3, Param 4, X: Param 5, Y:Param 6, Z:Param 7. This command list is similar what ARINC 424 is for commercial aircraft: A data format how to interpret waypoint/mission data. */ +#ifndef HAVE_ENUM_MAV_CMD +#define HAVE_ENUM_MAV_CMD +enum MAV_CMD { + MAV_CMD_NAV_WAYPOINT = 16, /* Navigate to MISSION. |Hold time in decimal seconds. (ignored by fixed wing, time to stay at MISSION for rotary wing)| Acceptance radius in meters (if the sphere with this radius is hit, the MISSION counts as reached)| 0 to pass through the WP, if > 0 radius in meters to pass by WP. Positive value for clockwise orbit, negative value for counter-clockwise orbit. Allows trajectory control.| Desired yaw angle at MISSION (rotary wing)| Latitude| Longitude| Altitude| */ + MAV_CMD_NAV_LOITER_UNLIM = 17, /* Loiter around this MISSION an unlimited amount of time |Empty| Empty| Radius around MISSION, in meters. If positive loiter clockwise, else counter-clockwise| Desired yaw angle.| Latitude| Longitude| Altitude| */ + MAV_CMD_NAV_LOITER_TURNS = 18, /* Loiter around this MISSION for X turns |Turns| Empty| Radius around MISSION, in meters. If positive loiter clockwise, else counter-clockwise| Desired yaw angle.| Latitude| Longitude| Altitude| */ + MAV_CMD_NAV_LOITER_TIME = 19, /* Loiter around this MISSION for X seconds |Seconds (decimal)| Empty| Radius around MISSION, in meters. If positive loiter clockwise, else counter-clockwise| Desired yaw angle.| Latitude| Longitude| Altitude| */ + MAV_CMD_NAV_RETURN_TO_LAUNCH = 20, /* Return to launch location |Empty| Empty| Empty| Empty| Empty| Empty| Empty| */ + MAV_CMD_NAV_LAND = 21, /* Land at location |Empty| Empty| Empty| Desired yaw angle.| Latitude| Longitude| Altitude| */ + MAV_CMD_NAV_TAKEOFF = 22, /* Takeoff from ground / hand |Minimum pitch (if airspeed sensor present), desired pitch without sensor| Empty| Empty| Yaw angle (if magnetometer present), ignored without magnetometer| Latitude| Longitude| Altitude| */ + MAV_CMD_NAV_ROI = 80, /* Sets the region of interest (ROI) for a sensor set or the vehicle itself. This can then be used by the vehicles control system to control the vehicle attitude and the attitude of various sensors such as cameras. |Region of intereset mode. (see MAV_ROI enum)| MISSION index/ target ID. (see MAV_ROI enum)| ROI index (allows a vehicle to manage multiple ROI's)| Empty| x the location of the fixed ROI (see MAV_FRAME)| y| z| */ + MAV_CMD_NAV_PATHPLANNING = 81, /* Control autonomous path planning on the MAV. |0: Disable local obstacle avoidance / local path planning (without resetting map), 1: Enable local path planning, 2: Enable and reset local path planning| 0: Disable full path planning (without resetting map), 1: Enable, 2: Enable and reset map/occupancy grid, 3: Enable and reset planned route, but not occupancy grid| Empty| Yaw angle at goal, in compass degrees, [0..360]| Latitude/X of goal| Longitude/Y of goal| Altitude/Z of goal| */ + MAV_CMD_NAV_LAST = 95, /* NOP - This command is only used to mark the upper limit of the NAV/ACTION commands in the enumeration |Empty| Empty| Empty| Empty| Empty| Empty| Empty| */ + MAV_CMD_CONDITION_DELAY = 112, /* Delay mission state machine. |Delay in seconds (decimal)| Empty| Empty| Empty| Empty| Empty| Empty| */ + MAV_CMD_CONDITION_CHANGE_ALT = 113, /* Ascend/descend at rate. Delay mission state machine until desired altitude reached. |Descent / Ascend rate (m/s)| Empty| Empty| Empty| Empty| Empty| Finish Altitude| */ + MAV_CMD_CONDITION_DISTANCE = 114, /* Delay mission state machine until within desired distance of next NAV point. |Distance (meters)| Empty| Empty| Empty| Empty| Empty| Empty| */ + MAV_CMD_CONDITION_YAW = 115, /* Reach a certain target angle. |target angle: [0-360], 0 is north| speed during yaw change:[deg per second]| direction: negative: counter clockwise, positive: clockwise [-1,1]| relative offset or absolute angle: [ 1,0]| Empty| Empty| Empty| */ + MAV_CMD_CONDITION_LAST = 159, /* NOP - This command is only used to mark the upper limit of the CONDITION commands in the enumeration |Empty| Empty| Empty| Empty| Empty| Empty| Empty| */ + MAV_CMD_DO_SET_MODE = 176, /* Set system mode. |Mode, as defined by ENUM MAV_MODE| Empty| Empty| Empty| Empty| Empty| Empty| */ + MAV_CMD_DO_JUMP = 177, /* Jump to the desired command in the mission list. Repeat this action only the specified number of times |Sequence number| Repeat count| Empty| Empty| Empty| Empty| Empty| */ + MAV_CMD_DO_CHANGE_SPEED = 178, /* Change speed and/or throttle set points. |Speed type (0=Airspeed, 1=Ground Speed)| Speed (m/s, -1 indicates no change)| Throttle ( Percent, -1 indicates no change)| Empty| Empty| Empty| Empty| */ + MAV_CMD_DO_SET_HOME = 179, /* Changes the home location either to the current location or a specified location. |Use current (1=use current location, 0=use specified location)| Empty| Empty| Empty| Latitude| Longitude| Altitude| */ + MAV_CMD_DO_SET_PARAMETER = 180, /* Set a system parameter. Caution! Use of this command requires knowledge of the numeric enumeration value of the parameter. |Parameter number| Parameter value| Empty| Empty| Empty| Empty| Empty| */ + MAV_CMD_DO_SET_RELAY = 181, /* Set a relay to a condition. |Relay number| Setting (1=on, 0=off, others possible depending on system hardware)| Empty| Empty| Empty| Empty| Empty| */ + MAV_CMD_DO_REPEAT_RELAY = 182, /* Cycle a relay on and off for a desired number of cyles with a desired period. |Relay number| Cycle count| Cycle time (seconds, decimal)| Empty| Empty| Empty| Empty| */ + MAV_CMD_DO_SET_SERVO = 183, /* Set a servo to a desired PWM value. |Servo number| PWM (microseconds, 1000 to 2000 typical)| Empty| Empty| Empty| Empty| Empty| */ + MAV_CMD_DO_REPEAT_SERVO = 184, /* Cycle a between its nominal setting and a desired PWM for a desired number of cycles with a desired period. |Servo number| PWM (microseconds, 1000 to 2000 typical)| Cycle count| Cycle time (seconds)| Empty| Empty| Empty| */ + MAV_CMD_DO_CONTROL_VIDEO = 200, /* Control onboard camera system. |Camera ID (-1 for all)| Transmission: 0: disabled, 1: enabled compressed, 2: enabled raw| Transmission mode: 0: video stream, >0: single images every n seconds (decimal)| Recording: 0: disabled, 1: enabled compressed, 2: enabled raw| Empty| Empty| Empty| */ + MAV_CMD_DO_LAST = 240, /* NOP - This command is only used to mark the upper limit of the DO commands in the enumeration |Empty| Empty| Empty| Empty| Empty| Empty| Empty| */ + MAV_CMD_PREFLIGHT_CALIBRATION = 241, /* Trigger calibration. This command will be only accepted if in pre-flight mode. |Gyro calibration: 0: no, 1: yes| Magnetometer calibration: 0: no, 1: yes| Ground pressure: 0: no, 1: yes| Radio calibration: 0: no, 1: yes| Empty| Empty| Empty| */ + MAV_CMD_PREFLIGHT_SET_SENSOR_OFFSETS = 242, /* Set sensor offsets. This command will be only accepted if in pre-flight mode. |Sensor to adjust the offsets for: 0: gyros, 1: accelerometer, 2: magnetometer, 3: barometer, 4: optical flow| X axis offset (or generic dimension 1), in the sensor's raw units| Y axis offset (or generic dimension 2), in the sensor's raw units| Z axis offset (or generic dimension 3), in the sensor's raw units| Generic dimension 4, in the sensor's raw units| Generic dimension 5, in the sensor's raw units| Generic dimension 6, in the sensor's raw units| */ + MAV_CMD_PREFLIGHT_STORAGE = 245, /* Request storage of different parameter values and logs. This command will be only accepted if in pre-flight mode. |Parameter storage: 0: READ FROM FLASH/EEPROM, 1: WRITE CURRENT TO FLASH/EEPROM| Mission storage: 0: READ FROM FLASH/EEPROM, 1: WRITE CURRENT TO FLASH/EEPROM| Reserved| Reserved| Empty| Empty| Empty| */ + MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN = 246, /* Request the reboot or shutdown of system components. |0: Do nothing for autopilot, 1: Reboot autopilot, 2: Shutdown autopilot.| 0: Do nothing for onboard computer, 1: Reboot onboard computer, 2: Shutdown onboard computer.| Reserved| Reserved| Empty| Empty| Empty| */ + MAV_CMD_OVERRIDE_GOTO = 252, /* Hold / continue the current action |MAV_GOTO_DO_HOLD: hold MAV_GOTO_DO_CONTINUE: continue with next item in mission plan| MAV_GOTO_HOLD_AT_CURRENT_POSITION: Hold at current position MAV_GOTO_HOLD_AT_SPECIFIED_POSITION: hold at specified position| MAV_FRAME coordinate frame of hold point| Desired yaw angle in degrees| Latitude / X position| Longitude / Y position| Altitude / Z position| */ + MAV_CMD_MISSION_START = 300, /* start running a mission |first_item: the first mission item to run| last_item: the last mission item to run (after this item is run, the mission ends)| */ + MAV_CMD_COMPONENT_ARM_DISARM = 400, /* Arms / Disarms a component |1 to arm, 0 to disarm| */ + MAV_CMD_ENUM_END = 401, /* | */ +}; +#endif // ifndef HAVE_ENUM_MAV_CMD + +/** @brief Data stream IDs. A data stream is not a fixed set of messages, but rather a + recommendation to the autopilot software. Individual autopilots may or may not obey + the recommended messages. */ +#ifndef HAVE_ENUM_MAV_DATA_STREAM +#define HAVE_ENUM_MAV_DATA_STREAM +enum MAV_DATA_STREAM { + MAV_DATA_STREAM_ALL = 0, /* Enable all data streams | */ + MAV_DATA_STREAM_RAW_SENSORS = 1, /* Enable IMU_RAW, GPS_RAW, GPS_STATUS packets. | */ + MAV_DATA_STREAM_EXTENDED_STATUS = 2, /* Enable GPS_STATUS, CONTROL_STATUS, AUX_STATUS | */ + MAV_DATA_STREAM_RC_CHANNELS = 3, /* Enable RC_CHANNELS_SCALED, RC_CHANNELS_RAW, SERVO_OUTPUT_RAW | */ + MAV_DATA_STREAM_RAW_CONTROLLER = 4, /* Enable ATTITUDE_CONTROLLER_OUTPUT, POSITION_CONTROLLER_OUTPUT, NAV_CONTROLLER_OUTPUT. | */ + MAV_DATA_STREAM_POSITION = 6, /* Enable LOCAL_POSITION, GLOBAL_POSITION/GLOBAL_POSITION_INT messages. | */ + MAV_DATA_STREAM_EXTRA1 = 10, /* Dependent on the autopilot | */ + MAV_DATA_STREAM_EXTRA2 = 11, /* Dependent on the autopilot | */ + MAV_DATA_STREAM_EXTRA3 = 12, /* Dependent on the autopilot | */ + MAV_DATA_STREAM_ENUM_END = 13, /* | */ +}; +#endif + +/** @brief The ROI (region of interest) for the vehicle. This can be + be used by the vehicle for camera/vehicle attitude alignment (see + MAV_CMD_NAV_ROI). */ +#ifndef HAVE_ENUM_MAV_ROI +#define HAVE_ENUM_MAV_ROI +enum MAV_ROI { + MAV_ROI_NONE = 0, /* No region of interest. | */ + MAV_ROI_WPNEXT = 1, /* Point toward next MISSION. | */ + MAV_ROI_WPINDEX = 2, /* Point toward given MISSION. | */ + MAV_ROI_LOCATION = 3, /* Point toward fixed location. | */ + MAV_ROI_TARGET = 4, /* Point toward of given id. | */ + MAV_ROI_ENUM_END = 5, /* | */ +}; +#endif + +/** @brief ACK / NACK / ERROR values as a result of MAV_CMDs and for mission item transmission. */ +#ifndef HAVE_ENUM_MAV_CMD_ACK +#define HAVE_ENUM_MAV_CMD_ACK +enum MAV_CMD_ACK { + MAV_CMD_ACK_OK = 1, /* Command / mission item is ok. | */ + MAV_CMD_ACK_ERR_FAIL = 2, /* Generic error message if none of the other reasons fails or if no detailed error reporting is implemented. | */ + MAV_CMD_ACK_ERR_ACCESS_DENIED = 3, /* The system is refusing to accept this command from this source / communication partner. | */ + MAV_CMD_ACK_ERR_NOT_SUPPORTED = 4, /* Command or mission item is not supported, other commands would be accepted. | */ + MAV_CMD_ACK_ERR_COORDINATE_FRAME_NOT_SUPPORTED = 5, /* The coordinate frame of this command / mission item is not supported. | */ + MAV_CMD_ACK_ERR_COORDINATES_OUT_OF_RANGE = 6, /* The coordinate frame of this command is ok, but he coordinate values exceed the safety limits of this system. This is a generic error, please use the more specific error messages below if possible. | */ + MAV_CMD_ACK_ERR_X_LAT_OUT_OF_RANGE = 7, /* The X or latitude value is out of range. | */ + MAV_CMD_ACK_ERR_Y_LON_OUT_OF_RANGE = 8, /* The Y or longitude value is out of range. | */ + MAV_CMD_ACK_ERR_Z_ALT_OUT_OF_RANGE = 9, /* The Z or altitude value is out of range. | */ + MAV_CMD_ACK_ENUM_END = 10, /* | */ +}; +#endif + +/** @brief Specifies the datatype of a MAVLink parameter. */ +#ifndef HAVE_ENUM_MAV_PARAM_TYPE +#define HAVE_ENUM_MAV_PARAM_TYPE +enum MAV_PARAM_TYPE { + MAV_PARAM_TYPE_UINT8 = 1, /* 8-bit unsigned integer | */ + MAV_PARAM_TYPE_INT8 = 2, /* 8-bit signed integer | */ + MAV_PARAM_TYPE_UINT16 = 3, /* 16-bit unsigned integer | */ + MAV_PARAM_TYPE_INT16 = 4, /* 16-bit signed integer | */ + MAV_PARAM_TYPE_UINT32 = 5, /* 32-bit unsigned integer | */ + MAV_PARAM_TYPE_INT32 = 6, /* 32-bit signed integer | */ + MAV_PARAM_TYPE_UINT64 = 7, /* 64-bit unsigned integer | */ + MAV_PARAM_TYPE_INT64 = 8, /* 64-bit signed integer | */ + MAV_PARAM_TYPE_REAL32 = 9, /* 32-bit floating-point | */ + MAV_PARAM_TYPE_REAL64 = 10, /* 64-bit floating-point | */ + MAV_PARAM_TYPE_ENUM_END = 11, /* | */ +}; +#endif + +/** @brief result from a mavlink command */ +#ifndef HAVE_ENUM_MAV_RESULT +#define HAVE_ENUM_MAV_RESULT +enum MAV_RESULT { + MAV_RESULT_ACCEPTED = 0, /* Command ACCEPTED and EXECUTED | */ + MAV_RESULT_TEMPORARILY_REJECTED = 1, /* Command TEMPORARY REJECTED/DENIED | */ + MAV_RESULT_DENIED = 2, /* Command PERMANENTLY DENIED | */ + MAV_RESULT_UNSUPPORTED = 3, /* Command UNKNOWN/UNSUPPORTED | */ + MAV_RESULT_FAILED = 4, /* Command executed, but failed | */ + MAV_RESULT_ENUM_END = 5, /* | */ +}; +#endif + +/** @brief result in a mavlink mission ack */ +#ifndef HAVE_ENUM_MAV_MISSION_RESULT +#define HAVE_ENUM_MAV_MISSION_RESULT +enum MAV_MISSION_RESULT { + MAV_MISSION_ACCEPTED = 0, /* mission accepted OK | */ + MAV_MISSION_ERROR = 1, /* generic error / not accepting mission commands at all right now | */ + MAV_MISSION_UNSUPPORTED_FRAME = 2, /* coordinate frame is not supported | */ + MAV_MISSION_UNSUPPORTED = 3, /* command is not supported | */ + MAV_MISSION_NO_SPACE = 4, /* mission item exceeds storage space | */ + MAV_MISSION_INVALID = 5, /* one of the parameters has an invalid value | */ + MAV_MISSION_INVALID_PARAM1 = 6, /* param1 has an invalid value | */ + MAV_MISSION_INVALID_PARAM2 = 7, /* param2 has an invalid value | */ + MAV_MISSION_INVALID_PARAM3 = 8, /* param3 has an invalid value | */ + MAV_MISSION_INVALID_PARAM4 = 9, /* param4 has an invalid value | */ + MAV_MISSION_INVALID_PARAM5_X = 10, /* x/param5 has an invalid value | */ + MAV_MISSION_INVALID_PARAM6_Y = 11, /* y/param6 has an invalid value | */ + MAV_MISSION_INVALID_PARAM7 = 12, /* param7 has an invalid value | */ + MAV_MISSION_INVALID_SEQUENCE = 13, /* received waypoint out of sequence | */ + MAV_MISSION_DENIED = 14, /* not accepting any mission commands from this communication partner | */ + MAV_MISSION_RESULT_ENUM_END = 15, /* | */ +}; +#endif + +/** @brief Indicates the severity level, generally used for status messages to indicate their relative urgency. Based on RFC-5424 using expanded definitions at: http://www.kiwisyslog.com/kb/info:-syslog-message-levels/. */ +#ifndef HAVE_ENUM_MAV_SEVERITY +#define HAVE_ENUM_MAV_SEVERITY +enum MAV_SEVERITY { + MAV_SEVERITY_EMERGENCY = 0, /* System is unusable. This is a "panic" condition. | */ + MAV_SEVERITY_ALERT = 1, /* Action should be taken immediately. Indicates error in non-critical systems. | */ + MAV_SEVERITY_CRITICAL = 2, /* Action must be taken immediately. Indicates failure in a primary system. | */ + MAV_SEVERITY_ERROR = 3, /* Indicates an error in secondary/redundant systems. | */ + MAV_SEVERITY_WARNING = 4, /* Indicates about a possible future error if this is not resolved within a given timeframe. Example would be a low battery warning. | */ + MAV_SEVERITY_NOTICE = 5, /* An unusual event has occured, though not an error condition. This should be investigated for the root cause. | */ + MAV_SEVERITY_INFO = 6, /* Normal operational messages. Useful for logging. No action is required for these messages. | */ + MAV_SEVERITY_DEBUG = 7, /* Useful non-operational messages that can assist in debugging. These should not occur during normal operation. | */ + MAV_SEVERITY_ENUM_END = 8, /* | */ +}; +#endif + + +// MAVLINK VERSION + +#ifndef MAVLINK_VERSION +#define MAVLINK_VERSION 3 +#endif + +#if (MAVLINK_VERSION == 0) +#undef MAVLINK_VERSION +#define MAVLINK_VERSION 3 +#endif + +// MESSAGE DEFINITIONS +#include "./mavlink_msg_heartbeat.h" +#include "./mavlink_msg_sys_status.h" +#include "./mavlink_msg_system_time.h" +#include "./mavlink_msg_ping.h" +#include "./mavlink_msg_change_operator_control.h" +#include "./mavlink_msg_change_operator_control_ack.h" +#include "./mavlink_msg_auth_key.h" +#include "./mavlink_msg_set_mode.h" +#include "./mavlink_msg_param_request_read.h" +#include "./mavlink_msg_param_request_list.h" +#include "./mavlink_msg_param_value.h" +#include "./mavlink_msg_param_set.h" +#include "./mavlink_msg_gps_raw_int.h" +#include "./mavlink_msg_gps_status.h" +#include "./mavlink_msg_scaled_imu.h" +#include "./mavlink_msg_raw_imu.h" +#include "./mavlink_msg_raw_pressure.h" +#include "./mavlink_msg_scaled_pressure.h" +#include "./mavlink_msg_attitude.h" +#include "./mavlink_msg_attitude_quaternion.h" +#include "./mavlink_msg_local_position_ned.h" +#include "./mavlink_msg_global_position_int.h" +#include "./mavlink_msg_rc_channels_scaled.h" +#include "./mavlink_msg_rc_channels_raw.h" +#include "./mavlink_msg_servo_output_raw.h" +#include "./mavlink_msg_mission_request_partial_list.h" +#include "./mavlink_msg_mission_write_partial_list.h" +#include "./mavlink_msg_mission_item.h" +#include "./mavlink_msg_mission_request.h" +#include "./mavlink_msg_mission_set_current.h" +#include "./mavlink_msg_mission_current.h" +#include "./mavlink_msg_mission_request_list.h" +#include "./mavlink_msg_mission_count.h" +#include "./mavlink_msg_mission_clear_all.h" +#include "./mavlink_msg_mission_item_reached.h" +#include "./mavlink_msg_mission_ack.h" +#include "./mavlink_msg_set_gps_global_origin.h" +#include "./mavlink_msg_gps_global_origin.h" +#include "./mavlink_msg_set_local_position_setpoint.h" +#include "./mavlink_msg_local_position_setpoint.h" +#include "./mavlink_msg_global_position_setpoint_int.h" +#include "./mavlink_msg_set_global_position_setpoint_int.h" +#include "./mavlink_msg_safety_set_allowed_area.h" +#include "./mavlink_msg_safety_allowed_area.h" +#include "./mavlink_msg_set_roll_pitch_yaw_thrust.h" +#include "./mavlink_msg_set_roll_pitch_yaw_speed_thrust.h" +#include "./mavlink_msg_roll_pitch_yaw_thrust_setpoint.h" +#include "./mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint.h" +#include "./mavlink_msg_set_quad_motors_setpoint.h" +#include "./mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust.h" +#include "./mavlink_msg_nav_controller_output.h" +#include "./mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust.h" +#include "./mavlink_msg_state_correction.h" +#include "./mavlink_msg_request_data_stream.h" +#include "./mavlink_msg_data_stream.h" +#include "./mavlink_msg_manual_control.h" +#include "./mavlink_msg_rc_channels_override.h" +#include "./mavlink_msg_vfr_hud.h" +#include "./mavlink_msg_command_long.h" +#include "./mavlink_msg_command_ack.h" +#include "./mavlink_msg_local_position_ned_system_global_offset.h" +#include "./mavlink_msg_hil_state.h" +#include "./mavlink_msg_hil_controls.h" +#include "./mavlink_msg_hil_rc_inputs_raw.h" +#include "./mavlink_msg_optical_flow.h" +#include "./mavlink_msg_global_vision_position_estimate.h" +#include "./mavlink_msg_vision_position_estimate.h" +#include "./mavlink_msg_vision_speed_estimate.h" +#include "./mavlink_msg_vicon_position_estimate.h" +#include "./mavlink_msg_memory_vect.h" +#include "./mavlink_msg_debug_vect.h" +#include "./mavlink_msg_named_value_float.h" +#include "./mavlink_msg_named_value_int.h" +#include "./mavlink_msg_statustext.h" +#include "./mavlink_msg_debug.h" + +#ifdef __cplusplus +} +#endif // __cplusplus +#endif // COMMON_H diff --git a/flight/libraries/mavlink/v1.0/common/custom_types.h b/flight/libraries/mavlink/v1.0/common/custom_types.h new file mode 100644 index 000000000..03c233adf --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/custom_types.h @@ -0,0 +1,25 @@ +/* Dervied from minimosd-extra code at https://github.com/diydrones/MinimOSD-Extra/blob/master/MinimOsd-Extra/OSD_Panels.ino (GPLv3) */ + + +#ifndef _CUSTOM_TYPES_H +#define _CUSTOM_TYPES_H + +#define CUSTOM_MODE_STAB 0 /* manual airframe angle with manual throttle */ +#define CUSTOM_MODE_ACRO 1 /* manual body-frame angular rate with manual throttle */ +#define CUSTOM_MODE_ALTH 2 /* manual airframe angle with automatic throttle */ +#define CUSTOM_MODE_AUTO 3 /* fully automatic waypoint control using mission commands */ +#define CUSTOM_MODE_GUIDED 4 /* fully automatic fly to coordinate or fly at velocity/direction using GCS immediate commands */ +#define CUSTOM_MODE_LOITER 5 /* automatic horizontal acceleration with automatic throttle */ +#define CUSTOM_MODE_RTL 6 /* automatic return to launching point */ +#define CUSTOM_MODE_CIRCLE 7 /* automatic circular flight with automatic throttle */ +#define CUSTOM_MODE_POSH 8 /* Position: auto control; deprecated? */ +#define CUSTOM_MODE_LAND 9 /* automatic landing with horizontal position control */ +#define CUSTOM_MODE_OFLOITER 10 /* deprecated */ +#define CUSTOM_MODE_DRIFT 11 /* semi-automous position, yaw and throttle control */ +#define CUSTOM_MODE_SPORT 13 /* manual earth-frame angular rate control with manual throttle */ +#define CUSTOM_MODE_FLIP 14 /* automatically flip the vehicle on the roll axis */ +#define CUSTOM_MODE_ATUN 15 /* automatically tune the vehicle's roll and pitch gains */ +#define CUSTOM_MODE_PHLD 16 /* automatic position hold with manual override, with automatic throttle */ +#define CUSTOM_MODE_BRAK 17 /* full-brake using inertial/GPS system, no pilot input */ + +#endif // ifndef _CUSTOM_TYPES_H diff --git a/flight/libraries/mavlink/v1.0/common/mavlink.h b/flight/libraries/mavlink/v1.0/common/mavlink.h new file mode 100644 index 000000000..1dbae5126 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink.h @@ -0,0 +1,27 @@ +/** @file + * @brief MAVLink comm protocol built from common.xml + * @see http://pixhawk.ethz.ch/software/mavlink + */ +#ifndef MAVLINK_H +#define MAVLINK_H + +#ifndef MAVLINK_STX +#define MAVLINK_STX 254 +#endif + +#ifndef MAVLINK_ENDIAN +#define MAVLINK_ENDIAN MAVLINK_LITTLE_ENDIAN +#endif + +#ifndef MAVLINK_ALIGNED_FIELDS +#define MAVLINK_ALIGNED_FIELDS 1 +#endif + +#ifndef MAVLINK_CRC_EXTRA +#define MAVLINK_CRC_EXTRA 1 +#endif + +#include "version.h" +#include "common.h" + +#endif // MAVLINK_H diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_attitude.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_attitude.h new file mode 100644 index 000000000..418043290 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_attitude.h @@ -0,0 +1,276 @@ +// MESSAGE ATTITUDE PACKING + +#define MAVLINK_MSG_ID_ATTITUDE 30 + +typedef struct __mavlink_attitude_t { + uint32_t time_boot_ms; ///< Timestamp (milliseconds since system boot) + float roll; ///< Roll angle (rad) + float pitch; ///< Pitch angle (rad) + float yaw; ///< Yaw angle (rad) + float rollspeed; ///< Roll angular speed (rad/s) + float pitchspeed; ///< Pitch angular speed (rad/s) + float yawspeed; ///< Yaw angular speed (rad/s) +} mavlink_attitude_t; + +#define MAVLINK_MSG_ID_ATTITUDE_LEN 28 +#define MAVLINK_MSG_ID_30_LEN 28 + + +#define MAVLINK_MESSAGE_INFO_ATTITUDE \ + { \ + "ATTITUDE", \ + 7, \ + { \ + { "time_boot_ms", NULL, MAVLINK_TYPE_UINT32_T, 0, 0, offsetof(mavlink_attitude_t, time_boot_ms) }, \ + { "roll", NULL, MAVLINK_TYPE_FLOAT, 0, 4, offsetof(mavlink_attitude_t, roll) }, \ + { "pitch", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_attitude_t, pitch) }, \ + { "yaw", NULL, MAVLINK_TYPE_FLOAT, 0, 12, offsetof(mavlink_attitude_t, yaw) }, \ + { "rollspeed", NULL, MAVLINK_TYPE_FLOAT, 0, 16, offsetof(mavlink_attitude_t, rollspeed) }, \ + { "pitchspeed", NULL, MAVLINK_TYPE_FLOAT, 0, 20, offsetof(mavlink_attitude_t, pitchspeed) }, \ + { "yawspeed", NULL, MAVLINK_TYPE_FLOAT, 0, 24, offsetof(mavlink_attitude_t, yawspeed) }, \ + } \ + } + + +/** + * @brief Pack a attitude message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param roll Roll angle (rad) + * @param pitch Pitch angle (rad) + * @param yaw Yaw angle (rad) + * @param rollspeed Roll angular speed (rad/s) + * @param pitchspeed Pitch angular speed (rad/s) + * @param yawspeed Yaw angular speed (rad/s) + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_attitude_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint32_t time_boot_ms, float roll, float pitch, float yaw, float rollspeed, float pitchspeed, float yawspeed) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[28]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_float(buf, 4, roll); + _mav_put_float(buf, 8, pitch); + _mav_put_float(buf, 12, yaw); + _mav_put_float(buf, 16, rollspeed); + _mav_put_float(buf, 20, pitchspeed); + _mav_put_float(buf, 24, yawspeed); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 28); +#else + mavlink_attitude_t packet; + packet.time_boot_ms = time_boot_ms; + packet.roll = roll; + packet.pitch = pitch; + packet.yaw = yaw; + packet.rollspeed = rollspeed; + packet.pitchspeed = pitchspeed; + packet.yawspeed = yawspeed; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 28); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_ATTITUDE; + return mavlink_finalize_message(msg, system_id, component_id, 28, 39); +} + +/** + * @brief Pack a attitude message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param roll Roll angle (rad) + * @param pitch Pitch angle (rad) + * @param yaw Yaw angle (rad) + * @param rollspeed Roll angular speed (rad/s) + * @param pitchspeed Pitch angular speed (rad/s) + * @param yawspeed Yaw angular speed (rad/s) + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_attitude_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint32_t time_boot_ms, float roll, float pitch, float yaw, float rollspeed, float pitchspeed, float yawspeed) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[28]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_float(buf, 4, roll); + _mav_put_float(buf, 8, pitch); + _mav_put_float(buf, 12, yaw); + _mav_put_float(buf, 16, rollspeed); + _mav_put_float(buf, 20, pitchspeed); + _mav_put_float(buf, 24, yawspeed); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 28); +#else + mavlink_attitude_t packet; + packet.time_boot_ms = time_boot_ms; + packet.roll = roll; + packet.pitch = pitch; + packet.yaw = yaw; + packet.rollspeed = rollspeed; + packet.pitchspeed = pitchspeed; + packet.yawspeed = yawspeed; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 28); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_ATTITUDE; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 28, 39); +} + +/** + * @brief Encode a attitude struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param attitude C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_attitude_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_attitude_t *attitude) +{ + return mavlink_msg_attitude_pack(system_id, component_id, msg, attitude->time_boot_ms, attitude->roll, attitude->pitch, attitude->yaw, attitude->rollspeed, attitude->pitchspeed, attitude->yawspeed); +} + +/** + * @brief Send a attitude message + * @param chan MAVLink channel to send the message + * + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param roll Roll angle (rad) + * @param pitch Pitch angle (rad) + * @param yaw Yaw angle (rad) + * @param rollspeed Roll angular speed (rad/s) + * @param pitchspeed Pitch angular speed (rad/s) + * @param yawspeed Yaw angular speed (rad/s) + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_attitude_send(mavlink_channel_t chan, uint32_t time_boot_ms, float roll, float pitch, float yaw, float rollspeed, float pitchspeed, float yawspeed) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[28]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_float(buf, 4, roll); + _mav_put_float(buf, 8, pitch); + _mav_put_float(buf, 12, yaw); + _mav_put_float(buf, 16, rollspeed); + _mav_put_float(buf, 20, pitchspeed); + _mav_put_float(buf, 24, yawspeed); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_ATTITUDE, buf, 28, 39); +#else + mavlink_attitude_t packet; + packet.time_boot_ms = time_boot_ms; + packet.roll = roll; + packet.pitch = pitch; + packet.yaw = yaw; + packet.rollspeed = rollspeed; + packet.pitchspeed = pitchspeed; + packet.yawspeed = yawspeed; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_ATTITUDE, (const char *)&packet, 28, 39); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE ATTITUDE UNPACKING + + +/** + * @brief Get field time_boot_ms from attitude message + * + * @return Timestamp (milliseconds since system boot) + */ +static inline uint32_t mavlink_msg_attitude_get_time_boot_ms(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint32_t(msg, 0); +} + +/** + * @brief Get field roll from attitude message + * + * @return Roll angle (rad) + */ +static inline float mavlink_msg_attitude_get_roll(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 4); +} + +/** + * @brief Get field pitch from attitude message + * + * @return Pitch angle (rad) + */ +static inline float mavlink_msg_attitude_get_pitch(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 8); +} + +/** + * @brief Get field yaw from attitude message + * + * @return Yaw angle (rad) + */ +static inline float mavlink_msg_attitude_get_yaw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 12); +} + +/** + * @brief Get field rollspeed from attitude message + * + * @return Roll angular speed (rad/s) + */ +static inline float mavlink_msg_attitude_get_rollspeed(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 16); +} + +/** + * @brief Get field pitchspeed from attitude message + * + * @return Pitch angular speed (rad/s) + */ +static inline float mavlink_msg_attitude_get_pitchspeed(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 20); +} + +/** + * @brief Get field yawspeed from attitude message + * + * @return Yaw angular speed (rad/s) + */ +static inline float mavlink_msg_attitude_get_yawspeed(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 24); +} + +/** + * @brief Decode a attitude message into a struct + * + * @param msg The message to decode + * @param attitude C-struct to decode the message contents into + */ +static inline void mavlink_msg_attitude_decode(const mavlink_message_t *msg, mavlink_attitude_t *attitude) +{ +#if MAVLINK_NEED_BYTE_SWAP + attitude->time_boot_ms = mavlink_msg_attitude_get_time_boot_ms(msg); + attitude->roll = mavlink_msg_attitude_get_roll(msg); + attitude->pitch = mavlink_msg_attitude_get_pitch(msg); + attitude->yaw = mavlink_msg_attitude_get_yaw(msg); + attitude->rollspeed = mavlink_msg_attitude_get_rollspeed(msg); + attitude->pitchspeed = mavlink_msg_attitude_get_pitchspeed(msg); + attitude->yawspeed = mavlink_msg_attitude_get_yawspeed(msg); +#else + memcpy(attitude, _MAV_PAYLOAD(msg), 28); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_attitude_quaternion.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_attitude_quaternion.h new file mode 100644 index 000000000..02310aa25 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_attitude_quaternion.h @@ -0,0 +1,298 @@ +// MESSAGE ATTITUDE_QUATERNION PACKING + +#define MAVLINK_MSG_ID_ATTITUDE_QUATERNION 31 + +typedef struct __mavlink_attitude_quaternion_t { + uint32_t time_boot_ms; ///< Timestamp (milliseconds since system boot) + float q1; ///< Quaternion component 1 + float q2; ///< Quaternion component 2 + float q3; ///< Quaternion component 3 + float q4; ///< Quaternion component 4 + float rollspeed; ///< Roll angular speed (rad/s) + float pitchspeed; ///< Pitch angular speed (rad/s) + float yawspeed; ///< Yaw angular speed (rad/s) +} mavlink_attitude_quaternion_t; + +#define MAVLINK_MSG_ID_ATTITUDE_QUATERNION_LEN 32 +#define MAVLINK_MSG_ID_31_LEN 32 + + +#define MAVLINK_MESSAGE_INFO_ATTITUDE_QUATERNION \ + { \ + "ATTITUDE_QUATERNION", \ + 8, \ + { \ + { "time_boot_ms", NULL, MAVLINK_TYPE_UINT32_T, 0, 0, offsetof(mavlink_attitude_quaternion_t, time_boot_ms) }, \ + { "q1", NULL, MAVLINK_TYPE_FLOAT, 0, 4, offsetof(mavlink_attitude_quaternion_t, q1) }, \ + { "q2", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_attitude_quaternion_t, q2) }, \ + { "q3", NULL, MAVLINK_TYPE_FLOAT, 0, 12, offsetof(mavlink_attitude_quaternion_t, q3) }, \ + { "q4", NULL, MAVLINK_TYPE_FLOAT, 0, 16, offsetof(mavlink_attitude_quaternion_t, q4) }, \ + { "rollspeed", NULL, MAVLINK_TYPE_FLOAT, 0, 20, offsetof(mavlink_attitude_quaternion_t, rollspeed) }, \ + { "pitchspeed", NULL, MAVLINK_TYPE_FLOAT, 0, 24, offsetof(mavlink_attitude_quaternion_t, pitchspeed) }, \ + { "yawspeed", NULL, MAVLINK_TYPE_FLOAT, 0, 28, offsetof(mavlink_attitude_quaternion_t, yawspeed) }, \ + } \ + } + + +/** + * @brief Pack a attitude_quaternion message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param q1 Quaternion component 1 + * @param q2 Quaternion component 2 + * @param q3 Quaternion component 3 + * @param q4 Quaternion component 4 + * @param rollspeed Roll angular speed (rad/s) + * @param pitchspeed Pitch angular speed (rad/s) + * @param yawspeed Yaw angular speed (rad/s) + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_attitude_quaternion_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint32_t time_boot_ms, float q1, float q2, float q3, float q4, float rollspeed, float pitchspeed, float yawspeed) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[32]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_float(buf, 4, q1); + _mav_put_float(buf, 8, q2); + _mav_put_float(buf, 12, q3); + _mav_put_float(buf, 16, q4); + _mav_put_float(buf, 20, rollspeed); + _mav_put_float(buf, 24, pitchspeed); + _mav_put_float(buf, 28, yawspeed); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 32); +#else + mavlink_attitude_quaternion_t packet; + packet.time_boot_ms = time_boot_ms; + packet.q1 = q1; + packet.q2 = q2; + packet.q3 = q3; + packet.q4 = q4; + packet.rollspeed = rollspeed; + packet.pitchspeed = pitchspeed; + packet.yawspeed = yawspeed; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 32); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_ATTITUDE_QUATERNION; + return mavlink_finalize_message(msg, system_id, component_id, 32, 246); +} + +/** + * @brief Pack a attitude_quaternion message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param q1 Quaternion component 1 + * @param q2 Quaternion component 2 + * @param q3 Quaternion component 3 + * @param q4 Quaternion component 4 + * @param rollspeed Roll angular speed (rad/s) + * @param pitchspeed Pitch angular speed (rad/s) + * @param yawspeed Yaw angular speed (rad/s) + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_attitude_quaternion_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint32_t time_boot_ms, float q1, float q2, float q3, float q4, float rollspeed, float pitchspeed, float yawspeed) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[32]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_float(buf, 4, q1); + _mav_put_float(buf, 8, q2); + _mav_put_float(buf, 12, q3); + _mav_put_float(buf, 16, q4); + _mav_put_float(buf, 20, rollspeed); + _mav_put_float(buf, 24, pitchspeed); + _mav_put_float(buf, 28, yawspeed); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 32); +#else + mavlink_attitude_quaternion_t packet; + packet.time_boot_ms = time_boot_ms; + packet.q1 = q1; + packet.q2 = q2; + packet.q3 = q3; + packet.q4 = q4; + packet.rollspeed = rollspeed; + packet.pitchspeed = pitchspeed; + packet.yawspeed = yawspeed; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 32); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_ATTITUDE_QUATERNION; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 32, 246); +} + +/** + * @brief Encode a attitude_quaternion struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param attitude_quaternion C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_attitude_quaternion_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_attitude_quaternion_t *attitude_quaternion) +{ + return mavlink_msg_attitude_quaternion_pack(system_id, component_id, msg, attitude_quaternion->time_boot_ms, attitude_quaternion->q1, attitude_quaternion->q2, attitude_quaternion->q3, attitude_quaternion->q4, attitude_quaternion->rollspeed, attitude_quaternion->pitchspeed, attitude_quaternion->yawspeed); +} + +/** + * @brief Send a attitude_quaternion message + * @param chan MAVLink channel to send the message + * + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param q1 Quaternion component 1 + * @param q2 Quaternion component 2 + * @param q3 Quaternion component 3 + * @param q4 Quaternion component 4 + * @param rollspeed Roll angular speed (rad/s) + * @param pitchspeed Pitch angular speed (rad/s) + * @param yawspeed Yaw angular speed (rad/s) + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_attitude_quaternion_send(mavlink_channel_t chan, uint32_t time_boot_ms, float q1, float q2, float q3, float q4, float rollspeed, float pitchspeed, float yawspeed) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[32]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_float(buf, 4, q1); + _mav_put_float(buf, 8, q2); + _mav_put_float(buf, 12, q3); + _mav_put_float(buf, 16, q4); + _mav_put_float(buf, 20, rollspeed); + _mav_put_float(buf, 24, pitchspeed); + _mav_put_float(buf, 28, yawspeed); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_ATTITUDE_QUATERNION, buf, 32, 246); +#else + mavlink_attitude_quaternion_t packet; + packet.time_boot_ms = time_boot_ms; + packet.q1 = q1; + packet.q2 = q2; + packet.q3 = q3; + packet.q4 = q4; + packet.rollspeed = rollspeed; + packet.pitchspeed = pitchspeed; + packet.yawspeed = yawspeed; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_ATTITUDE_QUATERNION, (const char *)&packet, 32, 246); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE ATTITUDE_QUATERNION UNPACKING + + +/** + * @brief Get field time_boot_ms from attitude_quaternion message + * + * @return Timestamp (milliseconds since system boot) + */ +static inline uint32_t mavlink_msg_attitude_quaternion_get_time_boot_ms(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint32_t(msg, 0); +} + +/** + * @brief Get field q1 from attitude_quaternion message + * + * @return Quaternion component 1 + */ +static inline float mavlink_msg_attitude_quaternion_get_q1(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 4); +} + +/** + * @brief Get field q2 from attitude_quaternion message + * + * @return Quaternion component 2 + */ +static inline float mavlink_msg_attitude_quaternion_get_q2(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 8); +} + +/** + * @brief Get field q3 from attitude_quaternion message + * + * @return Quaternion component 3 + */ +static inline float mavlink_msg_attitude_quaternion_get_q3(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 12); +} + +/** + * @brief Get field q4 from attitude_quaternion message + * + * @return Quaternion component 4 + */ +static inline float mavlink_msg_attitude_quaternion_get_q4(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 16); +} + +/** + * @brief Get field rollspeed from attitude_quaternion message + * + * @return Roll angular speed (rad/s) + */ +static inline float mavlink_msg_attitude_quaternion_get_rollspeed(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 20); +} + +/** + * @brief Get field pitchspeed from attitude_quaternion message + * + * @return Pitch angular speed (rad/s) + */ +static inline float mavlink_msg_attitude_quaternion_get_pitchspeed(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 24); +} + +/** + * @brief Get field yawspeed from attitude_quaternion message + * + * @return Yaw angular speed (rad/s) + */ +static inline float mavlink_msg_attitude_quaternion_get_yawspeed(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 28); +} + +/** + * @brief Decode a attitude_quaternion message into a struct + * + * @param msg The message to decode + * @param attitude_quaternion C-struct to decode the message contents into + */ +static inline void mavlink_msg_attitude_quaternion_decode(const mavlink_message_t *msg, mavlink_attitude_quaternion_t *attitude_quaternion) +{ +#if MAVLINK_NEED_BYTE_SWAP + attitude_quaternion->time_boot_ms = mavlink_msg_attitude_quaternion_get_time_boot_ms(msg); + attitude_quaternion->q1 = mavlink_msg_attitude_quaternion_get_q1(msg); + attitude_quaternion->q2 = mavlink_msg_attitude_quaternion_get_q2(msg); + attitude_quaternion->q3 = mavlink_msg_attitude_quaternion_get_q3(msg); + attitude_quaternion->q4 = mavlink_msg_attitude_quaternion_get_q4(msg); + attitude_quaternion->rollspeed = mavlink_msg_attitude_quaternion_get_rollspeed(msg); + attitude_quaternion->pitchspeed = mavlink_msg_attitude_quaternion_get_pitchspeed(msg); + attitude_quaternion->yawspeed = mavlink_msg_attitude_quaternion_get_yawspeed(msg); +#else + memcpy(attitude_quaternion, _MAV_PAYLOAD(msg), 32); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_auth_key.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_auth_key.h new file mode 100644 index 000000000..429526c98 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_auth_key.h @@ -0,0 +1,145 @@ +// MESSAGE AUTH_KEY PACKING + +#define MAVLINK_MSG_ID_AUTH_KEY 7 + +typedef struct __mavlink_auth_key_t { + char key[32]; ///< key +} mavlink_auth_key_t; + +#define MAVLINK_MSG_ID_AUTH_KEY_LEN 32 +#define MAVLINK_MSG_ID_7_LEN 32 + +#define MAVLINK_MSG_AUTH_KEY_FIELD_KEY_LEN 32 + +#define MAVLINK_MESSAGE_INFO_AUTH_KEY \ + { \ + "AUTH_KEY", \ + 1, \ + { \ + { "key", NULL, MAVLINK_TYPE_CHAR, 32, 0, offsetof(mavlink_auth_key_t, key) }, \ + } \ + } + + +/** + * @brief Pack a auth_key message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param key key + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_auth_key_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + const char *key) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[32]; + + _mav_put_char_array(buf, 0, key, 32); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 32); +#else + mavlink_auth_key_t packet; + + mav_array_memcpy(packet.key, key, sizeof(char) * 32); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 32); +#endif + + msg->msgid = MAVLINK_MSG_ID_AUTH_KEY; + return mavlink_finalize_message(msg, system_id, component_id, 32, 119); +} + +/** + * @brief Pack a auth_key message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param key key + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_auth_key_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + const char *key) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[32]; + + _mav_put_char_array(buf, 0, key, 32); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 32); +#else + mavlink_auth_key_t packet; + + mav_array_memcpy(packet.key, key, sizeof(char) * 32); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 32); +#endif + + msg->msgid = MAVLINK_MSG_ID_AUTH_KEY; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 32, 119); +} + +/** + * @brief Encode a auth_key struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param auth_key C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_auth_key_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_auth_key_t *auth_key) +{ + return mavlink_msg_auth_key_pack(system_id, component_id, msg, auth_key->key); +} + +/** + * @brief Send a auth_key message + * @param chan MAVLink channel to send the message + * + * @param key key + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_auth_key_send(mavlink_channel_t chan, const char *key) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[32]; + + _mav_put_char_array(buf, 0, key, 32); + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_AUTH_KEY, buf, 32, 119); +#else + mavlink_auth_key_t packet; + + mav_array_memcpy(packet.key, key, sizeof(char) * 32); + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_AUTH_KEY, (const char *)&packet, 32, 119); +#endif +} + +#endif + +// MESSAGE AUTH_KEY UNPACKING + + +/** + * @brief Get field key from auth_key message + * + * @return key + */ +static inline uint16_t mavlink_msg_auth_key_get_key(const mavlink_message_t *msg, char *key) +{ + return _MAV_RETURN_char_array(msg, key, 32, 0); +} + +/** + * @brief Decode a auth_key message into a struct + * + * @param msg The message to decode + * @param auth_key C-struct to decode the message contents into + */ +static inline void mavlink_msg_auth_key_decode(const mavlink_message_t *msg, mavlink_auth_key_t *auth_key) +{ +#if MAVLINK_NEED_BYTE_SWAP + mavlink_msg_auth_key_get_key(msg, auth_key->key); +#else + memcpy(auth_key, _MAV_PAYLOAD(msg), 32); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_change_operator_control.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_change_operator_control.h new file mode 100644 index 000000000..b519dcd4d --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_change_operator_control.h @@ -0,0 +1,205 @@ +// MESSAGE CHANGE_OPERATOR_CONTROL PACKING + +#define MAVLINK_MSG_ID_CHANGE_OPERATOR_CONTROL 5 + +typedef struct __mavlink_change_operator_control_t { + uint8_t target_system; ///< System the GCS requests control for + uint8_t control_request; ///< 0: request control of this MAV, 1: Release control of this MAV + uint8_t version; ///< 0: key as plaintext, 1-255: future, different hashing/encryption variants. The GCS should in general use the safest mode possible initially and then gradually move down the encryption level if it gets a NACK message indicating an encryption mismatch. + char passkey[25]; ///< Password / Key, depending on version plaintext or encrypted. 25 or less characters, NULL terminated. The characters may involve A-Z, a-z, 0-9, and "!?,.-" +} mavlink_change_operator_control_t; + +#define MAVLINK_MSG_ID_CHANGE_OPERATOR_CONTROL_LEN 28 +#define MAVLINK_MSG_ID_5_LEN 28 + +#define MAVLINK_MSG_CHANGE_OPERATOR_CONTROL_FIELD_PASSKEY_LEN 25 + +#define MAVLINK_MESSAGE_INFO_CHANGE_OPERATOR_CONTROL \ + { \ + "CHANGE_OPERATOR_CONTROL", \ + 4, \ + { \ + { "target_system", NULL, MAVLINK_TYPE_UINT8_T, 0, 0, offsetof(mavlink_change_operator_control_t, target_system) }, \ + { "control_request", NULL, MAVLINK_TYPE_UINT8_T, 0, 1, offsetof(mavlink_change_operator_control_t, control_request) }, \ + { "version", NULL, MAVLINK_TYPE_UINT8_T, 0, 2, offsetof(mavlink_change_operator_control_t, version) }, \ + { "passkey", NULL, MAVLINK_TYPE_CHAR, 25, 3, offsetof(mavlink_change_operator_control_t, passkey) }, \ + } \ + } + + +/** + * @brief Pack a change_operator_control message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param target_system System the GCS requests control for + * @param control_request 0: request control of this MAV, 1: Release control of this MAV + * @param version 0: key as plaintext, 1-255: future, different hashing/encryption variants. The GCS should in general use the safest mode possible initially and then gradually move down the encryption level if it gets a NACK message indicating an encryption mismatch. + * @param passkey Password / Key, depending on version plaintext or encrypted. 25 or less characters, NULL terminated. The characters may involve A-Z, a-z, 0-9, and "!?,.-" + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_change_operator_control_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t target_system, uint8_t control_request, uint8_t version, const char *passkey) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[28]; + _mav_put_uint8_t(buf, 0, target_system); + _mav_put_uint8_t(buf, 1, control_request); + _mav_put_uint8_t(buf, 2, version); + _mav_put_char_array(buf, 3, passkey, 25); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 28); +#else + mavlink_change_operator_control_t packet; + packet.target_system = target_system; + packet.control_request = control_request; + packet.version = version; + mav_array_memcpy(packet.passkey, passkey, sizeof(char) * 25); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 28); +#endif + + msg->msgid = MAVLINK_MSG_ID_CHANGE_OPERATOR_CONTROL; + return mavlink_finalize_message(msg, system_id, component_id, 28, 217); +} + +/** + * @brief Pack a change_operator_control message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param target_system System the GCS requests control for + * @param control_request 0: request control of this MAV, 1: Release control of this MAV + * @param version 0: key as plaintext, 1-255: future, different hashing/encryption variants. The GCS should in general use the safest mode possible initially and then gradually move down the encryption level if it gets a NACK message indicating an encryption mismatch. + * @param passkey Password / Key, depending on version plaintext or encrypted. 25 or less characters, NULL terminated. The characters may involve A-Z, a-z, 0-9, and "!?,.-" + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_change_operator_control_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t target_system, uint8_t control_request, uint8_t version, const char *passkey) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[28]; + _mav_put_uint8_t(buf, 0, target_system); + _mav_put_uint8_t(buf, 1, control_request); + _mav_put_uint8_t(buf, 2, version); + _mav_put_char_array(buf, 3, passkey, 25); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 28); +#else + mavlink_change_operator_control_t packet; + packet.target_system = target_system; + packet.control_request = control_request; + packet.version = version; + mav_array_memcpy(packet.passkey, passkey, sizeof(char) * 25); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 28); +#endif + + msg->msgid = MAVLINK_MSG_ID_CHANGE_OPERATOR_CONTROL; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 28, 217); +} + +/** + * @brief Encode a change_operator_control struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param change_operator_control C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_change_operator_control_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_change_operator_control_t *change_operator_control) +{ + return mavlink_msg_change_operator_control_pack(system_id, component_id, msg, change_operator_control->target_system, change_operator_control->control_request, change_operator_control->version, change_operator_control->passkey); +} + +/** + * @brief Send a change_operator_control message + * @param chan MAVLink channel to send the message + * + * @param target_system System the GCS requests control for + * @param control_request 0: request control of this MAV, 1: Release control of this MAV + * @param version 0: key as plaintext, 1-255: future, different hashing/encryption variants. The GCS should in general use the safest mode possible initially and then gradually move down the encryption level if it gets a NACK message indicating an encryption mismatch. + * @param passkey Password / Key, depending on version plaintext or encrypted. 25 or less characters, NULL terminated. The characters may involve A-Z, a-z, 0-9, and "!?,.-" + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_change_operator_control_send(mavlink_channel_t chan, uint8_t target_system, uint8_t control_request, uint8_t version, const char *passkey) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[28]; + _mav_put_uint8_t(buf, 0, target_system); + _mav_put_uint8_t(buf, 1, control_request); + _mav_put_uint8_t(buf, 2, version); + _mav_put_char_array(buf, 3, passkey, 25); + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_CHANGE_OPERATOR_CONTROL, buf, 28, 217); +#else + mavlink_change_operator_control_t packet; + packet.target_system = target_system; + packet.control_request = control_request; + packet.version = version; + mav_array_memcpy(packet.passkey, passkey, sizeof(char) * 25); + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_CHANGE_OPERATOR_CONTROL, (const char *)&packet, 28, 217); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE CHANGE_OPERATOR_CONTROL UNPACKING + + +/** + * @brief Get field target_system from change_operator_control message + * + * @return System the GCS requests control for + */ +static inline uint8_t mavlink_msg_change_operator_control_get_target_system(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 0); +} + +/** + * @brief Get field control_request from change_operator_control message + * + * @return 0: request control of this MAV, 1: Release control of this MAV + */ +static inline uint8_t mavlink_msg_change_operator_control_get_control_request(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 1); +} + +/** + * @brief Get field version from change_operator_control message + * + * @return 0: key as plaintext, 1-255: future, different hashing/encryption variants. The GCS should in general use the safest mode possible initially and then gradually move down the encryption level if it gets a NACK message indicating an encryption mismatch. + */ +static inline uint8_t mavlink_msg_change_operator_control_get_version(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 2); +} + +/** + * @brief Get field passkey from change_operator_control message + * + * @return Password / Key, depending on version plaintext or encrypted. 25 or less characters, NULL terminated. The characters may involve A-Z, a-z, 0-9, and "!?,.-" + */ +static inline uint16_t mavlink_msg_change_operator_control_get_passkey(const mavlink_message_t *msg, char *passkey) +{ + return _MAV_RETURN_char_array(msg, passkey, 25, 3); +} + +/** + * @brief Decode a change_operator_control message into a struct + * + * @param msg The message to decode + * @param change_operator_control C-struct to decode the message contents into + */ +static inline void mavlink_msg_change_operator_control_decode(const mavlink_message_t *msg, mavlink_change_operator_control_t *change_operator_control) +{ +#if MAVLINK_NEED_BYTE_SWAP + change_operator_control->target_system = mavlink_msg_change_operator_control_get_target_system(msg); + change_operator_control->control_request = mavlink_msg_change_operator_control_get_control_request(msg); + change_operator_control->version = mavlink_msg_change_operator_control_get_version(msg); + mavlink_msg_change_operator_control_get_passkey(msg, change_operator_control->passkey); +#else + memcpy(change_operator_control, _MAV_PAYLOAD(msg), 28); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_change_operator_control_ack.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_change_operator_control_ack.h new file mode 100644 index 000000000..fc8f80fb5 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_change_operator_control_ack.h @@ -0,0 +1,188 @@ +// MESSAGE CHANGE_OPERATOR_CONTROL_ACK PACKING + +#define MAVLINK_MSG_ID_CHANGE_OPERATOR_CONTROL_ACK 6 + +typedef struct __mavlink_change_operator_control_ack_t { + uint8_t gcs_system_id; ///< ID of the GCS this message + uint8_t control_request; ///< 0: request control of this MAV, 1: Release control of this MAV + uint8_t ack; ///< 0: ACK, 1: NACK: Wrong passkey, 2: NACK: Unsupported passkey encryption method, 3: NACK: Already under control +} mavlink_change_operator_control_ack_t; + +#define MAVLINK_MSG_ID_CHANGE_OPERATOR_CONTROL_ACK_LEN 3 +#define MAVLINK_MSG_ID_6_LEN 3 + + +#define MAVLINK_MESSAGE_INFO_CHANGE_OPERATOR_CONTROL_ACK \ + { \ + "CHANGE_OPERATOR_CONTROL_ACK", \ + 3, \ + { \ + { "gcs_system_id", NULL, MAVLINK_TYPE_UINT8_T, 0, 0, offsetof(mavlink_change_operator_control_ack_t, gcs_system_id) }, \ + { "control_request", NULL, MAVLINK_TYPE_UINT8_T, 0, 1, offsetof(mavlink_change_operator_control_ack_t, control_request) }, \ + { "ack", NULL, MAVLINK_TYPE_UINT8_T, 0, 2, offsetof(mavlink_change_operator_control_ack_t, ack) }, \ + } \ + } + + +/** + * @brief Pack a change_operator_control_ack message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param gcs_system_id ID of the GCS this message + * @param control_request 0: request control of this MAV, 1: Release control of this MAV + * @param ack 0: ACK, 1: NACK: Wrong passkey, 2: NACK: Unsupported passkey encryption method, 3: NACK: Already under control + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_change_operator_control_ack_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t gcs_system_id, uint8_t control_request, uint8_t ack) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[3]; + _mav_put_uint8_t(buf, 0, gcs_system_id); + _mav_put_uint8_t(buf, 1, control_request); + _mav_put_uint8_t(buf, 2, ack); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 3); +#else + mavlink_change_operator_control_ack_t packet; + packet.gcs_system_id = gcs_system_id; + packet.control_request = control_request; + packet.ack = ack; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 3); +#endif + + msg->msgid = MAVLINK_MSG_ID_CHANGE_OPERATOR_CONTROL_ACK; + return mavlink_finalize_message(msg, system_id, component_id, 3, 104); +} + +/** + * @brief Pack a change_operator_control_ack message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param gcs_system_id ID of the GCS this message + * @param control_request 0: request control of this MAV, 1: Release control of this MAV + * @param ack 0: ACK, 1: NACK: Wrong passkey, 2: NACK: Unsupported passkey encryption method, 3: NACK: Already under control + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_change_operator_control_ack_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t gcs_system_id, uint8_t control_request, uint8_t ack) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[3]; + _mav_put_uint8_t(buf, 0, gcs_system_id); + _mav_put_uint8_t(buf, 1, control_request); + _mav_put_uint8_t(buf, 2, ack); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 3); +#else + mavlink_change_operator_control_ack_t packet; + packet.gcs_system_id = gcs_system_id; + packet.control_request = control_request; + packet.ack = ack; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 3); +#endif + + msg->msgid = MAVLINK_MSG_ID_CHANGE_OPERATOR_CONTROL_ACK; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 3, 104); +} + +/** + * @brief Encode a change_operator_control_ack struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param change_operator_control_ack C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_change_operator_control_ack_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_change_operator_control_ack_t *change_operator_control_ack) +{ + return mavlink_msg_change_operator_control_ack_pack(system_id, component_id, msg, change_operator_control_ack->gcs_system_id, change_operator_control_ack->control_request, change_operator_control_ack->ack); +} + +/** + * @brief Send a change_operator_control_ack message + * @param chan MAVLink channel to send the message + * + * @param gcs_system_id ID of the GCS this message + * @param control_request 0: request control of this MAV, 1: Release control of this MAV + * @param ack 0: ACK, 1: NACK: Wrong passkey, 2: NACK: Unsupported passkey encryption method, 3: NACK: Already under control + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_change_operator_control_ack_send(mavlink_channel_t chan, uint8_t gcs_system_id, uint8_t control_request, uint8_t ack) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[3]; + _mav_put_uint8_t(buf, 0, gcs_system_id); + _mav_put_uint8_t(buf, 1, control_request); + _mav_put_uint8_t(buf, 2, ack); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_CHANGE_OPERATOR_CONTROL_ACK, buf, 3, 104); +#else + mavlink_change_operator_control_ack_t packet; + packet.gcs_system_id = gcs_system_id; + packet.control_request = control_request; + packet.ack = ack; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_CHANGE_OPERATOR_CONTROL_ACK, (const char *)&packet, 3, 104); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE CHANGE_OPERATOR_CONTROL_ACK UNPACKING + + +/** + * @brief Get field gcs_system_id from change_operator_control_ack message + * + * @return ID of the GCS this message + */ +static inline uint8_t mavlink_msg_change_operator_control_ack_get_gcs_system_id(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 0); +} + +/** + * @brief Get field control_request from change_operator_control_ack message + * + * @return 0: request control of this MAV, 1: Release control of this MAV + */ +static inline uint8_t mavlink_msg_change_operator_control_ack_get_control_request(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 1); +} + +/** + * @brief Get field ack from change_operator_control_ack message + * + * @return 0: ACK, 1: NACK: Wrong passkey, 2: NACK: Unsupported passkey encryption method, 3: NACK: Already under control + */ +static inline uint8_t mavlink_msg_change_operator_control_ack_get_ack(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 2); +} + +/** + * @brief Decode a change_operator_control_ack message into a struct + * + * @param msg The message to decode + * @param change_operator_control_ack C-struct to decode the message contents into + */ +static inline void mavlink_msg_change_operator_control_ack_decode(const mavlink_message_t *msg, mavlink_change_operator_control_ack_t *change_operator_control_ack) +{ +#if MAVLINK_NEED_BYTE_SWAP + change_operator_control_ack->gcs_system_id = mavlink_msg_change_operator_control_ack_get_gcs_system_id(msg); + change_operator_control_ack->control_request = mavlink_msg_change_operator_control_ack_get_control_request(msg); + change_operator_control_ack->ack = mavlink_msg_change_operator_control_ack_get_ack(msg); +#else + memcpy(change_operator_control_ack, _MAV_PAYLOAD(msg), 3); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_command_ack.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_command_ack.h new file mode 100644 index 000000000..2550ec30f --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_command_ack.h @@ -0,0 +1,166 @@ +// MESSAGE COMMAND_ACK PACKING + +#define MAVLINK_MSG_ID_COMMAND_ACK 77 + +typedef struct __mavlink_command_ack_t { + uint16_t command; ///< Command ID, as defined by MAV_CMD enum. + uint8_t result; ///< See MAV_RESULT enum +} mavlink_command_ack_t; + +#define MAVLINK_MSG_ID_COMMAND_ACK_LEN 3 +#define MAVLINK_MSG_ID_77_LEN 3 + + +#define MAVLINK_MESSAGE_INFO_COMMAND_ACK \ + { \ + "COMMAND_ACK", \ + 2, \ + { \ + { "command", NULL, MAVLINK_TYPE_UINT16_T, 0, 0, offsetof(mavlink_command_ack_t, command) }, \ + { "result", NULL, MAVLINK_TYPE_UINT8_T, 0, 2, offsetof(mavlink_command_ack_t, result) }, \ + } \ + } + + +/** + * @brief Pack a command_ack message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param command Command ID, as defined by MAV_CMD enum. + * @param result See MAV_RESULT enum + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_command_ack_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint16_t command, uint8_t result) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[3]; + _mav_put_uint16_t(buf, 0, command); + _mav_put_uint8_t(buf, 2, result); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 3); +#else + mavlink_command_ack_t packet; + packet.command = command; + packet.result = result; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 3); +#endif + + msg->msgid = MAVLINK_MSG_ID_COMMAND_ACK; + return mavlink_finalize_message(msg, system_id, component_id, 3, 143); +} + +/** + * @brief Pack a command_ack message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param command Command ID, as defined by MAV_CMD enum. + * @param result See MAV_RESULT enum + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_command_ack_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint16_t command, uint8_t result) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[3]; + _mav_put_uint16_t(buf, 0, command); + _mav_put_uint8_t(buf, 2, result); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 3); +#else + mavlink_command_ack_t packet; + packet.command = command; + packet.result = result; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 3); +#endif + + msg->msgid = MAVLINK_MSG_ID_COMMAND_ACK; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 3, 143); +} + +/** + * @brief Encode a command_ack struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param command_ack C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_command_ack_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_command_ack_t *command_ack) +{ + return mavlink_msg_command_ack_pack(system_id, component_id, msg, command_ack->command, command_ack->result); +} + +/** + * @brief Send a command_ack message + * @param chan MAVLink channel to send the message + * + * @param command Command ID, as defined by MAV_CMD enum. + * @param result See MAV_RESULT enum + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_command_ack_send(mavlink_channel_t chan, uint16_t command, uint8_t result) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[3]; + _mav_put_uint16_t(buf, 0, command); + _mav_put_uint8_t(buf, 2, result); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_COMMAND_ACK, buf, 3, 143); +#else + mavlink_command_ack_t packet; + packet.command = command; + packet.result = result; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_COMMAND_ACK, (const char *)&packet, 3, 143); +#endif +} + +#endif + +// MESSAGE COMMAND_ACK UNPACKING + + +/** + * @brief Get field command from command_ack message + * + * @return Command ID, as defined by MAV_CMD enum. + */ +static inline uint16_t mavlink_msg_command_ack_get_command(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 0); +} + +/** + * @brief Get field result from command_ack message + * + * @return See MAV_RESULT enum + */ +static inline uint8_t mavlink_msg_command_ack_get_result(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 2); +} + +/** + * @brief Decode a command_ack message into a struct + * + * @param msg The message to decode + * @param command_ack C-struct to decode the message contents into + */ +static inline void mavlink_msg_command_ack_decode(const mavlink_message_t *msg, mavlink_command_ack_t *command_ack) +{ +#if MAVLINK_NEED_BYTE_SWAP + command_ack->command = mavlink_msg_command_ack_get_command(msg); + command_ack->result = mavlink_msg_command_ack_get_result(msg); +#else + memcpy(command_ack, _MAV_PAYLOAD(msg), 3); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_command_long.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_command_long.h new file mode 100644 index 000000000..ad481c8d8 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_command_long.h @@ -0,0 +1,364 @@ +// MESSAGE COMMAND_LONG PACKING + +#define MAVLINK_MSG_ID_COMMAND_LONG 76 + +typedef struct __mavlink_command_long_t { + float param1; ///< Parameter 1, as defined by MAV_CMD enum. + float param2; ///< Parameter 2, as defined by MAV_CMD enum. + float param3; ///< Parameter 3, as defined by MAV_CMD enum. + float param4; ///< Parameter 4, as defined by MAV_CMD enum. + float param5; ///< Parameter 5, as defined by MAV_CMD enum. + float param6; ///< Parameter 6, as defined by MAV_CMD enum. + float param7; ///< Parameter 7, as defined by MAV_CMD enum. + uint16_t command; ///< Command ID, as defined by MAV_CMD enum. + uint8_t target_system; ///< System which should execute the command + uint8_t target_component; ///< Component which should execute the command, 0 for all components + uint8_t confirmation; ///< 0: First transmission of this command. 1-255: Confirmation transmissions (e.g. for kill command) +} mavlink_command_long_t; + +#define MAVLINK_MSG_ID_COMMAND_LONG_LEN 33 +#define MAVLINK_MSG_ID_76_LEN 33 + + +#define MAVLINK_MESSAGE_INFO_COMMAND_LONG \ + { \ + "COMMAND_LONG", \ + 11, \ + { \ + { "param1", NULL, MAVLINK_TYPE_FLOAT, 0, 0, offsetof(mavlink_command_long_t, param1) }, \ + { "param2", NULL, MAVLINK_TYPE_FLOAT, 0, 4, offsetof(mavlink_command_long_t, param2) }, \ + { "param3", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_command_long_t, param3) }, \ + { "param4", NULL, MAVLINK_TYPE_FLOAT, 0, 12, offsetof(mavlink_command_long_t, param4) }, \ + { "param5", NULL, MAVLINK_TYPE_FLOAT, 0, 16, offsetof(mavlink_command_long_t, param5) }, \ + { "param6", NULL, MAVLINK_TYPE_FLOAT, 0, 20, offsetof(mavlink_command_long_t, param6) }, \ + { "param7", NULL, MAVLINK_TYPE_FLOAT, 0, 24, offsetof(mavlink_command_long_t, param7) }, \ + { "command", NULL, MAVLINK_TYPE_UINT16_T, 0, 28, offsetof(mavlink_command_long_t, command) }, \ + { "target_system", NULL, MAVLINK_TYPE_UINT8_T, 0, 30, offsetof(mavlink_command_long_t, target_system) }, \ + { "target_component", NULL, MAVLINK_TYPE_UINT8_T, 0, 31, offsetof(mavlink_command_long_t, target_component) }, \ + { "confirmation", NULL, MAVLINK_TYPE_UINT8_T, 0, 32, offsetof(mavlink_command_long_t, confirmation) }, \ + } \ + } + + +/** + * @brief Pack a command_long message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param target_system System which should execute the command + * @param target_component Component which should execute the command, 0 for all components + * @param command Command ID, as defined by MAV_CMD enum. + * @param confirmation 0: First transmission of this command. 1-255: Confirmation transmissions (e.g. for kill command) + * @param param1 Parameter 1, as defined by MAV_CMD enum. + * @param param2 Parameter 2, as defined by MAV_CMD enum. + * @param param3 Parameter 3, as defined by MAV_CMD enum. + * @param param4 Parameter 4, as defined by MAV_CMD enum. + * @param param5 Parameter 5, as defined by MAV_CMD enum. + * @param param6 Parameter 6, as defined by MAV_CMD enum. + * @param param7 Parameter 7, as defined by MAV_CMD enum. + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_command_long_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, uint16_t command, uint8_t confirmation, float param1, float param2, float param3, float param4, float param5, float param6, float param7) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[33]; + _mav_put_float(buf, 0, param1); + _mav_put_float(buf, 4, param2); + _mav_put_float(buf, 8, param3); + _mav_put_float(buf, 12, param4); + _mav_put_float(buf, 16, param5); + _mav_put_float(buf, 20, param6); + _mav_put_float(buf, 24, param7); + _mav_put_uint16_t(buf, 28, command); + _mav_put_uint8_t(buf, 30, target_system); + _mav_put_uint8_t(buf, 31, target_component); + _mav_put_uint8_t(buf, 32, confirmation); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 33); +#else + mavlink_command_long_t packet; + packet.param1 = param1; + packet.param2 = param2; + packet.param3 = param3; + packet.param4 = param4; + packet.param5 = param5; + packet.param6 = param6; + packet.param7 = param7; + packet.command = command; + packet.target_system = target_system; + packet.target_component = target_component; + packet.confirmation = confirmation; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 33); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_COMMAND_LONG; + return mavlink_finalize_message(msg, system_id, component_id, 33, 152); +} + +/** + * @brief Pack a command_long message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param target_system System which should execute the command + * @param target_component Component which should execute the command, 0 for all components + * @param command Command ID, as defined by MAV_CMD enum. + * @param confirmation 0: First transmission of this command. 1-255: Confirmation transmissions (e.g. for kill command) + * @param param1 Parameter 1, as defined by MAV_CMD enum. + * @param param2 Parameter 2, as defined by MAV_CMD enum. + * @param param3 Parameter 3, as defined by MAV_CMD enum. + * @param param4 Parameter 4, as defined by MAV_CMD enum. + * @param param5 Parameter 5, as defined by MAV_CMD enum. + * @param param6 Parameter 6, as defined by MAV_CMD enum. + * @param param7 Parameter 7, as defined by MAV_CMD enum. + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_command_long_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, uint16_t command, uint8_t confirmation, float param1, float param2, float param3, float param4, float param5, float param6, float param7) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[33]; + _mav_put_float(buf, 0, param1); + _mav_put_float(buf, 4, param2); + _mav_put_float(buf, 8, param3); + _mav_put_float(buf, 12, param4); + _mav_put_float(buf, 16, param5); + _mav_put_float(buf, 20, param6); + _mav_put_float(buf, 24, param7); + _mav_put_uint16_t(buf, 28, command); + _mav_put_uint8_t(buf, 30, target_system); + _mav_put_uint8_t(buf, 31, target_component); + _mav_put_uint8_t(buf, 32, confirmation); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 33); +#else + mavlink_command_long_t packet; + packet.param1 = param1; + packet.param2 = param2; + packet.param3 = param3; + packet.param4 = param4; + packet.param5 = param5; + packet.param6 = param6; + packet.param7 = param7; + packet.command = command; + packet.target_system = target_system; + packet.target_component = target_component; + packet.confirmation = confirmation; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 33); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_COMMAND_LONG; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 33, 152); +} + +/** + * @brief Encode a command_long struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param command_long C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_command_long_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_command_long_t *command_long) +{ + return mavlink_msg_command_long_pack(system_id, component_id, msg, command_long->target_system, command_long->target_component, command_long->command, command_long->confirmation, command_long->param1, command_long->param2, command_long->param3, command_long->param4, command_long->param5, command_long->param6, command_long->param7); +} + +/** + * @brief Send a command_long message + * @param chan MAVLink channel to send the message + * + * @param target_system System which should execute the command + * @param target_component Component which should execute the command, 0 for all components + * @param command Command ID, as defined by MAV_CMD enum. + * @param confirmation 0: First transmission of this command. 1-255: Confirmation transmissions (e.g. for kill command) + * @param param1 Parameter 1, as defined by MAV_CMD enum. + * @param param2 Parameter 2, as defined by MAV_CMD enum. + * @param param3 Parameter 3, as defined by MAV_CMD enum. + * @param param4 Parameter 4, as defined by MAV_CMD enum. + * @param param5 Parameter 5, as defined by MAV_CMD enum. + * @param param6 Parameter 6, as defined by MAV_CMD enum. + * @param param7 Parameter 7, as defined by MAV_CMD enum. + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_command_long_send(mavlink_channel_t chan, uint8_t target_system, uint8_t target_component, uint16_t command, uint8_t confirmation, float param1, float param2, float param3, float param4, float param5, float param6, float param7) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[33]; + _mav_put_float(buf, 0, param1); + _mav_put_float(buf, 4, param2); + _mav_put_float(buf, 8, param3); + _mav_put_float(buf, 12, param4); + _mav_put_float(buf, 16, param5); + _mav_put_float(buf, 20, param6); + _mav_put_float(buf, 24, param7); + _mav_put_uint16_t(buf, 28, command); + _mav_put_uint8_t(buf, 30, target_system); + _mav_put_uint8_t(buf, 31, target_component); + _mav_put_uint8_t(buf, 32, confirmation); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_COMMAND_LONG, buf, 33, 152); +#else + mavlink_command_long_t packet; + packet.param1 = param1; + packet.param2 = param2; + packet.param3 = param3; + packet.param4 = param4; + packet.param5 = param5; + packet.param6 = param6; + packet.param7 = param7; + packet.command = command; + packet.target_system = target_system; + packet.target_component = target_component; + packet.confirmation = confirmation; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_COMMAND_LONG, (const char *)&packet, 33, 152); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE COMMAND_LONG UNPACKING + + +/** + * @brief Get field target_system from command_long message + * + * @return System which should execute the command + */ +static inline uint8_t mavlink_msg_command_long_get_target_system(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 30); +} + +/** + * @brief Get field target_component from command_long message + * + * @return Component which should execute the command, 0 for all components + */ +static inline uint8_t mavlink_msg_command_long_get_target_component(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 31); +} + +/** + * @brief Get field command from command_long message + * + * @return Command ID, as defined by MAV_CMD enum. + */ +static inline uint16_t mavlink_msg_command_long_get_command(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 28); +} + +/** + * @brief Get field confirmation from command_long message + * + * @return 0: First transmission of this command. 1-255: Confirmation transmissions (e.g. for kill command) + */ +static inline uint8_t mavlink_msg_command_long_get_confirmation(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 32); +} + +/** + * @brief Get field param1 from command_long message + * + * @return Parameter 1, as defined by MAV_CMD enum. + */ +static inline float mavlink_msg_command_long_get_param1(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 0); +} + +/** + * @brief Get field param2 from command_long message + * + * @return Parameter 2, as defined by MAV_CMD enum. + */ +static inline float mavlink_msg_command_long_get_param2(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 4); +} + +/** + * @brief Get field param3 from command_long message + * + * @return Parameter 3, as defined by MAV_CMD enum. + */ +static inline float mavlink_msg_command_long_get_param3(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 8); +} + +/** + * @brief Get field param4 from command_long message + * + * @return Parameter 4, as defined by MAV_CMD enum. + */ +static inline float mavlink_msg_command_long_get_param4(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 12); +} + +/** + * @brief Get field param5 from command_long message + * + * @return Parameter 5, as defined by MAV_CMD enum. + */ +static inline float mavlink_msg_command_long_get_param5(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 16); +} + +/** + * @brief Get field param6 from command_long message + * + * @return Parameter 6, as defined by MAV_CMD enum. + */ +static inline float mavlink_msg_command_long_get_param6(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 20); +} + +/** + * @brief Get field param7 from command_long message + * + * @return Parameter 7, as defined by MAV_CMD enum. + */ +static inline float mavlink_msg_command_long_get_param7(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 24); +} + +/** + * @brief Decode a command_long message into a struct + * + * @param msg The message to decode + * @param command_long C-struct to decode the message contents into + */ +static inline void mavlink_msg_command_long_decode(const mavlink_message_t *msg, mavlink_command_long_t *command_long) +{ +#if MAVLINK_NEED_BYTE_SWAP + command_long->param1 = mavlink_msg_command_long_get_param1(msg); + command_long->param2 = mavlink_msg_command_long_get_param2(msg); + command_long->param3 = mavlink_msg_command_long_get_param3(msg); + command_long->param4 = mavlink_msg_command_long_get_param4(msg); + command_long->param5 = mavlink_msg_command_long_get_param5(msg); + command_long->param6 = mavlink_msg_command_long_get_param6(msg); + command_long->param7 = mavlink_msg_command_long_get_param7(msg); + command_long->command = mavlink_msg_command_long_get_command(msg); + command_long->target_system = mavlink_msg_command_long_get_target_system(msg); + command_long->target_component = mavlink_msg_command_long_get_target_component(msg); + command_long->confirmation = mavlink_msg_command_long_get_confirmation(msg); +#else + memcpy(command_long, _MAV_PAYLOAD(msg), 33); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_data_stream.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_data_stream.h new file mode 100644 index 000000000..84e5884e4 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_data_stream.h @@ -0,0 +1,188 @@ +// MESSAGE DATA_STREAM PACKING + +#define MAVLINK_MSG_ID_DATA_STREAM 67 + +typedef struct __mavlink_data_stream_t { + uint16_t message_rate; ///< The requested interval between two messages of this type + uint8_t stream_id; ///< The ID of the requested data stream + uint8_t on_off; ///< 1 stream is enabled, 0 stream is stopped. +} mavlink_data_stream_t; + +#define MAVLINK_MSG_ID_DATA_STREAM_LEN 4 +#define MAVLINK_MSG_ID_67_LEN 4 + + +#define MAVLINK_MESSAGE_INFO_DATA_STREAM \ + { \ + "DATA_STREAM", \ + 3, \ + { \ + { "message_rate", NULL, MAVLINK_TYPE_UINT16_T, 0, 0, offsetof(mavlink_data_stream_t, message_rate) }, \ + { "stream_id", NULL, MAVLINK_TYPE_UINT8_T, 0, 2, offsetof(mavlink_data_stream_t, stream_id) }, \ + { "on_off", NULL, MAVLINK_TYPE_UINT8_T, 0, 3, offsetof(mavlink_data_stream_t, on_off) }, \ + } \ + } + + +/** + * @brief Pack a data_stream message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param stream_id The ID of the requested data stream + * @param message_rate The requested interval between two messages of this type + * @param on_off 1 stream is enabled, 0 stream is stopped. + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_data_stream_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t stream_id, uint16_t message_rate, uint8_t on_off) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[4]; + _mav_put_uint16_t(buf, 0, message_rate); + _mav_put_uint8_t(buf, 2, stream_id); + _mav_put_uint8_t(buf, 3, on_off); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 4); +#else + mavlink_data_stream_t packet; + packet.message_rate = message_rate; + packet.stream_id = stream_id; + packet.on_off = on_off; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 4); +#endif + + msg->msgid = MAVLINK_MSG_ID_DATA_STREAM; + return mavlink_finalize_message(msg, system_id, component_id, 4, 21); +} + +/** + * @brief Pack a data_stream message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param stream_id The ID of the requested data stream + * @param message_rate The requested interval between two messages of this type + * @param on_off 1 stream is enabled, 0 stream is stopped. + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_data_stream_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t stream_id, uint16_t message_rate, uint8_t on_off) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[4]; + _mav_put_uint16_t(buf, 0, message_rate); + _mav_put_uint8_t(buf, 2, stream_id); + _mav_put_uint8_t(buf, 3, on_off); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 4); +#else + mavlink_data_stream_t packet; + packet.message_rate = message_rate; + packet.stream_id = stream_id; + packet.on_off = on_off; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 4); +#endif + + msg->msgid = MAVLINK_MSG_ID_DATA_STREAM; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 4, 21); +} + +/** + * @brief Encode a data_stream struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param data_stream C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_data_stream_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_data_stream_t *data_stream) +{ + return mavlink_msg_data_stream_pack(system_id, component_id, msg, data_stream->stream_id, data_stream->message_rate, data_stream->on_off); +} + +/** + * @brief Send a data_stream message + * @param chan MAVLink channel to send the message + * + * @param stream_id The ID of the requested data stream + * @param message_rate The requested interval between two messages of this type + * @param on_off 1 stream is enabled, 0 stream is stopped. + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_data_stream_send(mavlink_channel_t chan, uint8_t stream_id, uint16_t message_rate, uint8_t on_off) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[4]; + _mav_put_uint16_t(buf, 0, message_rate); + _mav_put_uint8_t(buf, 2, stream_id); + _mav_put_uint8_t(buf, 3, on_off); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_DATA_STREAM, buf, 4, 21); +#else + mavlink_data_stream_t packet; + packet.message_rate = message_rate; + packet.stream_id = stream_id; + packet.on_off = on_off; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_DATA_STREAM, (const char *)&packet, 4, 21); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE DATA_STREAM UNPACKING + + +/** + * @brief Get field stream_id from data_stream message + * + * @return The ID of the requested data stream + */ +static inline uint8_t mavlink_msg_data_stream_get_stream_id(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 2); +} + +/** + * @brief Get field message_rate from data_stream message + * + * @return The requested interval between two messages of this type + */ +static inline uint16_t mavlink_msg_data_stream_get_message_rate(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 0); +} + +/** + * @brief Get field on_off from data_stream message + * + * @return 1 stream is enabled, 0 stream is stopped. + */ +static inline uint8_t mavlink_msg_data_stream_get_on_off(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 3); +} + +/** + * @brief Decode a data_stream message into a struct + * + * @param msg The message to decode + * @param data_stream C-struct to decode the message contents into + */ +static inline void mavlink_msg_data_stream_decode(const mavlink_message_t *msg, mavlink_data_stream_t *data_stream) +{ +#if MAVLINK_NEED_BYTE_SWAP + data_stream->message_rate = mavlink_msg_data_stream_get_message_rate(msg); + data_stream->stream_id = mavlink_msg_data_stream_get_stream_id(msg); + data_stream->on_off = mavlink_msg_data_stream_get_on_off(msg); +#else + memcpy(data_stream, _MAV_PAYLOAD(msg), 4); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_debug.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_debug.h new file mode 100644 index 000000000..b46cf8423 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_debug.h @@ -0,0 +1,188 @@ +// MESSAGE DEBUG PACKING + +#define MAVLINK_MSG_ID_DEBUG 254 + +typedef struct __mavlink_debug_t { + uint32_t time_boot_ms; ///< Timestamp (milliseconds since system boot) + float value; ///< DEBUG value + uint8_t ind; ///< index of debug variable +} mavlink_debug_t; + +#define MAVLINK_MSG_ID_DEBUG_LEN 9 +#define MAVLINK_MSG_ID_254_LEN 9 + + +#define MAVLINK_MESSAGE_INFO_DEBUG \ + { \ + "DEBUG", \ + 3, \ + { \ + { "time_boot_ms", NULL, MAVLINK_TYPE_UINT32_T, 0, 0, offsetof(mavlink_debug_t, time_boot_ms) }, \ + { "value", NULL, MAVLINK_TYPE_FLOAT, 0, 4, offsetof(mavlink_debug_t, value) }, \ + { "ind", NULL, MAVLINK_TYPE_UINT8_T, 0, 8, offsetof(mavlink_debug_t, ind) }, \ + } \ + } + + +/** + * @brief Pack a debug message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param ind index of debug variable + * @param value DEBUG value + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_debug_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint32_t time_boot_ms, uint8_t ind, float value) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[9]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_float(buf, 4, value); + _mav_put_uint8_t(buf, 8, ind); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 9); +#else + mavlink_debug_t packet; + packet.time_boot_ms = time_boot_ms; + packet.value = value; + packet.ind = ind; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 9); +#endif + + msg->msgid = MAVLINK_MSG_ID_DEBUG; + return mavlink_finalize_message(msg, system_id, component_id, 9, 46); +} + +/** + * @brief Pack a debug message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param ind index of debug variable + * @param value DEBUG value + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_debug_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint32_t time_boot_ms, uint8_t ind, float value) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[9]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_float(buf, 4, value); + _mav_put_uint8_t(buf, 8, ind); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 9); +#else + mavlink_debug_t packet; + packet.time_boot_ms = time_boot_ms; + packet.value = value; + packet.ind = ind; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 9); +#endif + + msg->msgid = MAVLINK_MSG_ID_DEBUG; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 9, 46); +} + +/** + * @brief Encode a debug struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param debug C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_debug_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_debug_t *debug) +{ + return mavlink_msg_debug_pack(system_id, component_id, msg, debug->time_boot_ms, debug->ind, debug->value); +} + +/** + * @brief Send a debug message + * @param chan MAVLink channel to send the message + * + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param ind index of debug variable + * @param value DEBUG value + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_debug_send(mavlink_channel_t chan, uint32_t time_boot_ms, uint8_t ind, float value) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[9]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_float(buf, 4, value); + _mav_put_uint8_t(buf, 8, ind); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_DEBUG, buf, 9, 46); +#else + mavlink_debug_t packet; + packet.time_boot_ms = time_boot_ms; + packet.value = value; + packet.ind = ind; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_DEBUG, (const char *)&packet, 9, 46); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE DEBUG UNPACKING + + +/** + * @brief Get field time_boot_ms from debug message + * + * @return Timestamp (milliseconds since system boot) + */ +static inline uint32_t mavlink_msg_debug_get_time_boot_ms(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint32_t(msg, 0); +} + +/** + * @brief Get field ind from debug message + * + * @return index of debug variable + */ +static inline uint8_t mavlink_msg_debug_get_ind(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 8); +} + +/** + * @brief Get field value from debug message + * + * @return DEBUG value + */ +static inline float mavlink_msg_debug_get_value(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 4); +} + +/** + * @brief Decode a debug message into a struct + * + * @param msg The message to decode + * @param debug C-struct to decode the message contents into + */ +static inline void mavlink_msg_debug_decode(const mavlink_message_t *msg, mavlink_debug_t *debug) +{ +#if MAVLINK_NEED_BYTE_SWAP + debug->time_boot_ms = mavlink_msg_debug_get_time_boot_ms(msg); + debug->value = mavlink_msg_debug_get_value(msg); + debug->ind = mavlink_msg_debug_get_ind(msg); +#else + memcpy(debug, _MAV_PAYLOAD(msg), 9); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_debug_vect.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_debug_vect.h new file mode 100644 index 000000000..ac1c6df35 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_debug_vect.h @@ -0,0 +1,227 @@ +// MESSAGE DEBUG_VECT PACKING + +#define MAVLINK_MSG_ID_DEBUG_VECT 250 + +typedef struct __mavlink_debug_vect_t { + uint64_t time_usec; ///< Timestamp + float x; ///< x + float y; ///< y + float z; ///< z + char name[10]; ///< Name +} mavlink_debug_vect_t; + +#define MAVLINK_MSG_ID_DEBUG_VECT_LEN 30 +#define MAVLINK_MSG_ID_250_LEN 30 + +#define MAVLINK_MSG_DEBUG_VECT_FIELD_NAME_LEN 10 + +#define MAVLINK_MESSAGE_INFO_DEBUG_VECT \ + { \ + "DEBUG_VECT", \ + 5, \ + { \ + { "time_usec", NULL, MAVLINK_TYPE_UINT64_T, 0, 0, offsetof(mavlink_debug_vect_t, time_usec) }, \ + { "x", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_debug_vect_t, x) }, \ + { "y", NULL, MAVLINK_TYPE_FLOAT, 0, 12, offsetof(mavlink_debug_vect_t, y) }, \ + { "z", NULL, MAVLINK_TYPE_FLOAT, 0, 16, offsetof(mavlink_debug_vect_t, z) }, \ + { "name", NULL, MAVLINK_TYPE_CHAR, 10, 20, offsetof(mavlink_debug_vect_t, name) }, \ + } \ + } + + +/** + * @brief Pack a debug_vect message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param name Name + * @param time_usec Timestamp + * @param x x + * @param y y + * @param z z + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_debug_vect_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + const char *name, uint64_t time_usec, float x, float y, float z) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[30]; + _mav_put_uint64_t(buf, 0, time_usec); + _mav_put_float(buf, 8, x); + _mav_put_float(buf, 12, y); + _mav_put_float(buf, 16, z); + _mav_put_char_array(buf, 20, name, 10); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 30); +#else + mavlink_debug_vect_t packet; + packet.time_usec = time_usec; + packet.x = x; + packet.y = y; + packet.z = z; + mav_array_memcpy(packet.name, name, sizeof(char) * 10); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 30); +#endif + + msg->msgid = MAVLINK_MSG_ID_DEBUG_VECT; + return mavlink_finalize_message(msg, system_id, component_id, 30, 49); +} + +/** + * @brief Pack a debug_vect message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param name Name + * @param time_usec Timestamp + * @param x x + * @param y y + * @param z z + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_debug_vect_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + const char *name, uint64_t time_usec, float x, float y, float z) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[30]; + _mav_put_uint64_t(buf, 0, time_usec); + _mav_put_float(buf, 8, x); + _mav_put_float(buf, 12, y); + _mav_put_float(buf, 16, z); + _mav_put_char_array(buf, 20, name, 10); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 30); +#else + mavlink_debug_vect_t packet; + packet.time_usec = time_usec; + packet.x = x; + packet.y = y; + packet.z = z; + mav_array_memcpy(packet.name, name, sizeof(char) * 10); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 30); +#endif + + msg->msgid = MAVLINK_MSG_ID_DEBUG_VECT; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 30, 49); +} + +/** + * @brief Encode a debug_vect struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param debug_vect C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_debug_vect_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_debug_vect_t *debug_vect) +{ + return mavlink_msg_debug_vect_pack(system_id, component_id, msg, debug_vect->name, debug_vect->time_usec, debug_vect->x, debug_vect->y, debug_vect->z); +} + +/** + * @brief Send a debug_vect message + * @param chan MAVLink channel to send the message + * + * @param name Name + * @param time_usec Timestamp + * @param x x + * @param y y + * @param z z + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_debug_vect_send(mavlink_channel_t chan, const char *name, uint64_t time_usec, float x, float y, float z) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[30]; + _mav_put_uint64_t(buf, 0, time_usec); + _mav_put_float(buf, 8, x); + _mav_put_float(buf, 12, y); + _mav_put_float(buf, 16, z); + _mav_put_char_array(buf, 20, name, 10); + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_DEBUG_VECT, buf, 30, 49); +#else + mavlink_debug_vect_t packet; + packet.time_usec = time_usec; + packet.x = x; + packet.y = y; + packet.z = z; + mav_array_memcpy(packet.name, name, sizeof(char) * 10); + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_DEBUG_VECT, (const char *)&packet, 30, 49); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE DEBUG_VECT UNPACKING + + +/** + * @brief Get field name from debug_vect message + * + * @return Name + */ +static inline uint16_t mavlink_msg_debug_vect_get_name(const mavlink_message_t *msg, char *name) +{ + return _MAV_RETURN_char_array(msg, name, 10, 20); +} + +/** + * @brief Get field time_usec from debug_vect message + * + * @return Timestamp + */ +static inline uint64_t mavlink_msg_debug_vect_get_time_usec(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint64_t(msg, 0); +} + +/** + * @brief Get field x from debug_vect message + * + * @return x + */ +static inline float mavlink_msg_debug_vect_get_x(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 8); +} + +/** + * @brief Get field y from debug_vect message + * + * @return y + */ +static inline float mavlink_msg_debug_vect_get_y(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 12); +} + +/** + * @brief Get field z from debug_vect message + * + * @return z + */ +static inline float mavlink_msg_debug_vect_get_z(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 16); +} + +/** + * @brief Decode a debug_vect message into a struct + * + * @param msg The message to decode + * @param debug_vect C-struct to decode the message contents into + */ +static inline void mavlink_msg_debug_vect_decode(const mavlink_message_t *msg, mavlink_debug_vect_t *debug_vect) +{ +#if MAVLINK_NEED_BYTE_SWAP + debug_vect->time_usec = mavlink_msg_debug_vect_get_time_usec(msg); + debug_vect->x = mavlink_msg_debug_vect_get_x(msg); + debug_vect->y = mavlink_msg_debug_vect_get_y(msg); + debug_vect->z = mavlink_msg_debug_vect_get_z(msg); + mavlink_msg_debug_vect_get_name(msg, debug_vect->name); +#else + memcpy(debug_vect, _MAV_PAYLOAD(msg), 30); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_global_position_int.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_global_position_int.h new file mode 100644 index 000000000..24b7e9ec5 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_global_position_int.h @@ -0,0 +1,320 @@ +// MESSAGE GLOBAL_POSITION_INT PACKING + +#define MAVLINK_MSG_ID_GLOBAL_POSITION_INT 33 + +typedef struct __mavlink_global_position_int_t { + uint32_t time_boot_ms; ///< Timestamp (milliseconds since system boot) + int32_t lat; ///< Latitude, expressed as * 1E7 + int32_t lon; ///< Longitude, expressed as * 1E7 + int32_t alt; ///< Altitude in meters, expressed as * 1000 (millimeters), above MSL + int32_t relative_alt; ///< Altitude above ground in meters, expressed as * 1000 (millimeters) + int16_t vx; ///< Ground X Speed (Latitude), expressed as m/s * 100 + int16_t vy; ///< Ground Y Speed (Longitude), expressed as m/s * 100 + int16_t vz; ///< Ground Z Speed (Altitude), expressed as m/s * 100 + uint16_t hdg; ///< Compass heading in degrees * 100, 0.0..359.99 degrees. If unknown, set to: 65535 +} mavlink_global_position_int_t; + +#define MAVLINK_MSG_ID_GLOBAL_POSITION_INT_LEN 28 +#define MAVLINK_MSG_ID_33_LEN 28 + + +#define MAVLINK_MESSAGE_INFO_GLOBAL_POSITION_INT \ + { \ + "GLOBAL_POSITION_INT", \ + 9, \ + { \ + { "time_boot_ms", NULL, MAVLINK_TYPE_UINT32_T, 0, 0, offsetof(mavlink_global_position_int_t, time_boot_ms) }, \ + { "lat", NULL, MAVLINK_TYPE_INT32_T, 0, 4, offsetof(mavlink_global_position_int_t, lat) }, \ + { "lon", NULL, MAVLINK_TYPE_INT32_T, 0, 8, offsetof(mavlink_global_position_int_t, lon) }, \ + { "alt", NULL, MAVLINK_TYPE_INT32_T, 0, 12, offsetof(mavlink_global_position_int_t, alt) }, \ + { "relative_alt", NULL, MAVLINK_TYPE_INT32_T, 0, 16, offsetof(mavlink_global_position_int_t, relative_alt) }, \ + { "vx", NULL, MAVLINK_TYPE_INT16_T, 0, 20, offsetof(mavlink_global_position_int_t, vx) }, \ + { "vy", NULL, MAVLINK_TYPE_INT16_T, 0, 22, offsetof(mavlink_global_position_int_t, vy) }, \ + { "vz", NULL, MAVLINK_TYPE_INT16_T, 0, 24, offsetof(mavlink_global_position_int_t, vz) }, \ + { "hdg", NULL, MAVLINK_TYPE_UINT16_T, 0, 26, offsetof(mavlink_global_position_int_t, hdg) }, \ + } \ + } + + +/** + * @brief Pack a global_position_int message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param lat Latitude, expressed as * 1E7 + * @param lon Longitude, expressed as * 1E7 + * @param alt Altitude in meters, expressed as * 1000 (millimeters), above MSL + * @param relative_alt Altitude above ground in meters, expressed as * 1000 (millimeters) + * @param vx Ground X Speed (Latitude), expressed as m/s * 100 + * @param vy Ground Y Speed (Longitude), expressed as m/s * 100 + * @param vz Ground Z Speed (Altitude), expressed as m/s * 100 + * @param hdg Compass heading in degrees * 100, 0.0..359.99 degrees. If unknown, set to: 65535 + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_global_position_int_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint32_t time_boot_ms, int32_t lat, int32_t lon, int32_t alt, int32_t relative_alt, int16_t vx, int16_t vy, int16_t vz, uint16_t hdg) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[28]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_int32_t(buf, 4, lat); + _mav_put_int32_t(buf, 8, lon); + _mav_put_int32_t(buf, 12, alt); + _mav_put_int32_t(buf, 16, relative_alt); + _mav_put_int16_t(buf, 20, vx); + _mav_put_int16_t(buf, 22, vy); + _mav_put_int16_t(buf, 24, vz); + _mav_put_uint16_t(buf, 26, hdg); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 28); +#else + mavlink_global_position_int_t packet; + packet.time_boot_ms = time_boot_ms; + packet.lat = lat; + packet.lon = lon; + packet.alt = alt; + packet.relative_alt = relative_alt; + packet.vx = vx; + packet.vy = vy; + packet.vz = vz; + packet.hdg = hdg; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 28); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_GLOBAL_POSITION_INT; + return mavlink_finalize_message(msg, system_id, component_id, 28, 104); +} + +/** + * @brief Pack a global_position_int message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param lat Latitude, expressed as * 1E7 + * @param lon Longitude, expressed as * 1E7 + * @param alt Altitude in meters, expressed as * 1000 (millimeters), above MSL + * @param relative_alt Altitude above ground in meters, expressed as * 1000 (millimeters) + * @param vx Ground X Speed (Latitude), expressed as m/s * 100 + * @param vy Ground Y Speed (Longitude), expressed as m/s * 100 + * @param vz Ground Z Speed (Altitude), expressed as m/s * 100 + * @param hdg Compass heading in degrees * 100, 0.0..359.99 degrees. If unknown, set to: 65535 + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_global_position_int_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint32_t time_boot_ms, int32_t lat, int32_t lon, int32_t alt, int32_t relative_alt, int16_t vx, int16_t vy, int16_t vz, uint16_t hdg) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[28]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_int32_t(buf, 4, lat); + _mav_put_int32_t(buf, 8, lon); + _mav_put_int32_t(buf, 12, alt); + _mav_put_int32_t(buf, 16, relative_alt); + _mav_put_int16_t(buf, 20, vx); + _mav_put_int16_t(buf, 22, vy); + _mav_put_int16_t(buf, 24, vz); + _mav_put_uint16_t(buf, 26, hdg); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 28); +#else + mavlink_global_position_int_t packet; + packet.time_boot_ms = time_boot_ms; + packet.lat = lat; + packet.lon = lon; + packet.alt = alt; + packet.relative_alt = relative_alt; + packet.vx = vx; + packet.vy = vy; + packet.vz = vz; + packet.hdg = hdg; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 28); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_GLOBAL_POSITION_INT; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 28, 104); +} + +/** + * @brief Encode a global_position_int struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param global_position_int C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_global_position_int_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_global_position_int_t *global_position_int) +{ + return mavlink_msg_global_position_int_pack(system_id, component_id, msg, global_position_int->time_boot_ms, global_position_int->lat, global_position_int->lon, global_position_int->alt, global_position_int->relative_alt, global_position_int->vx, global_position_int->vy, global_position_int->vz, global_position_int->hdg); +} + +/** + * @brief Send a global_position_int message + * @param chan MAVLink channel to send the message + * + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param lat Latitude, expressed as * 1E7 + * @param lon Longitude, expressed as * 1E7 + * @param alt Altitude in meters, expressed as * 1000 (millimeters), above MSL + * @param relative_alt Altitude above ground in meters, expressed as * 1000 (millimeters) + * @param vx Ground X Speed (Latitude), expressed as m/s * 100 + * @param vy Ground Y Speed (Longitude), expressed as m/s * 100 + * @param vz Ground Z Speed (Altitude), expressed as m/s * 100 + * @param hdg Compass heading in degrees * 100, 0.0..359.99 degrees. If unknown, set to: 65535 + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_global_position_int_send(mavlink_channel_t chan, uint32_t time_boot_ms, int32_t lat, int32_t lon, int32_t alt, int32_t relative_alt, int16_t vx, int16_t vy, int16_t vz, uint16_t hdg) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[28]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_int32_t(buf, 4, lat); + _mav_put_int32_t(buf, 8, lon); + _mav_put_int32_t(buf, 12, alt); + _mav_put_int32_t(buf, 16, relative_alt); + _mav_put_int16_t(buf, 20, vx); + _mav_put_int16_t(buf, 22, vy); + _mav_put_int16_t(buf, 24, vz); + _mav_put_uint16_t(buf, 26, hdg); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_GLOBAL_POSITION_INT, buf, 28, 104); +#else + mavlink_global_position_int_t packet; + packet.time_boot_ms = time_boot_ms; + packet.lat = lat; + packet.lon = lon; + packet.alt = alt; + packet.relative_alt = relative_alt; + packet.vx = vx; + packet.vy = vy; + packet.vz = vz; + packet.hdg = hdg; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_GLOBAL_POSITION_INT, (const char *)&packet, 28, 104); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE GLOBAL_POSITION_INT UNPACKING + + +/** + * @brief Get field time_boot_ms from global_position_int message + * + * @return Timestamp (milliseconds since system boot) + */ +static inline uint32_t mavlink_msg_global_position_int_get_time_boot_ms(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint32_t(msg, 0); +} + +/** + * @brief Get field lat from global_position_int message + * + * @return Latitude, expressed as * 1E7 + */ +static inline int32_t mavlink_msg_global_position_int_get_lat(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int32_t(msg, 4); +} + +/** + * @brief Get field lon from global_position_int message + * + * @return Longitude, expressed as * 1E7 + */ +static inline int32_t mavlink_msg_global_position_int_get_lon(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int32_t(msg, 8); +} + +/** + * @brief Get field alt from global_position_int message + * + * @return Altitude in meters, expressed as * 1000 (millimeters), above MSL + */ +static inline int32_t mavlink_msg_global_position_int_get_alt(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int32_t(msg, 12); +} + +/** + * @brief Get field relative_alt from global_position_int message + * + * @return Altitude above ground in meters, expressed as * 1000 (millimeters) + */ +static inline int32_t mavlink_msg_global_position_int_get_relative_alt(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int32_t(msg, 16); +} + +/** + * @brief Get field vx from global_position_int message + * + * @return Ground X Speed (Latitude), expressed as m/s * 100 + */ +static inline int16_t mavlink_msg_global_position_int_get_vx(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 20); +} + +/** + * @brief Get field vy from global_position_int message + * + * @return Ground Y Speed (Longitude), expressed as m/s * 100 + */ +static inline int16_t mavlink_msg_global_position_int_get_vy(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 22); +} + +/** + * @brief Get field vz from global_position_int message + * + * @return Ground Z Speed (Altitude), expressed as m/s * 100 + */ +static inline int16_t mavlink_msg_global_position_int_get_vz(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 24); +} + +/** + * @brief Get field hdg from global_position_int message + * + * @return Compass heading in degrees * 100, 0.0..359.99 degrees. If unknown, set to: 65535 + */ +static inline uint16_t mavlink_msg_global_position_int_get_hdg(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 26); +} + +/** + * @brief Decode a global_position_int message into a struct + * + * @param msg The message to decode + * @param global_position_int C-struct to decode the message contents into + */ +static inline void mavlink_msg_global_position_int_decode(const mavlink_message_t *msg, mavlink_global_position_int_t *global_position_int) +{ +#if MAVLINK_NEED_BYTE_SWAP + global_position_int->time_boot_ms = mavlink_msg_global_position_int_get_time_boot_ms(msg); + global_position_int->lat = mavlink_msg_global_position_int_get_lat(msg); + global_position_int->lon = mavlink_msg_global_position_int_get_lon(msg); + global_position_int->alt = mavlink_msg_global_position_int_get_alt(msg); + global_position_int->relative_alt = mavlink_msg_global_position_int_get_relative_alt(msg); + global_position_int->vx = mavlink_msg_global_position_int_get_vx(msg); + global_position_int->vy = mavlink_msg_global_position_int_get_vy(msg); + global_position_int->vz = mavlink_msg_global_position_int_get_vz(msg); + global_position_int->hdg = mavlink_msg_global_position_int_get_hdg(msg); +#else + memcpy(global_position_int, _MAV_PAYLOAD(msg), 28); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_global_position_setpoint_int.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_global_position_setpoint_int.h new file mode 100644 index 000000000..a95193613 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_global_position_setpoint_int.h @@ -0,0 +1,232 @@ +// MESSAGE GLOBAL_POSITION_SETPOINT_INT PACKING + +#define MAVLINK_MSG_ID_GLOBAL_POSITION_SETPOINT_INT 52 + +typedef struct __mavlink_global_position_setpoint_int_t { + int32_t latitude; ///< WGS84 Latitude position in degrees * 1E7 + int32_t longitude; ///< WGS84 Longitude position in degrees * 1E7 + int32_t altitude; ///< WGS84 Altitude in meters * 1000 (positive for up) + int16_t yaw; ///< Desired yaw angle in degrees * 100 + uint8_t coordinate_frame; ///< Coordinate frame - valid values are only MAV_FRAME_GLOBAL or MAV_FRAME_GLOBAL_RELATIVE_ALT +} mavlink_global_position_setpoint_int_t; + +#define MAVLINK_MSG_ID_GLOBAL_POSITION_SETPOINT_INT_LEN 15 +#define MAVLINK_MSG_ID_52_LEN 15 + + +#define MAVLINK_MESSAGE_INFO_GLOBAL_POSITION_SETPOINT_INT \ + { \ + "GLOBAL_POSITION_SETPOINT_INT", \ + 5, \ + { \ + { "latitude", NULL, MAVLINK_TYPE_INT32_T, 0, 0, offsetof(mavlink_global_position_setpoint_int_t, latitude) }, \ + { "longitude", NULL, MAVLINK_TYPE_INT32_T, 0, 4, offsetof(mavlink_global_position_setpoint_int_t, longitude) }, \ + { "altitude", NULL, MAVLINK_TYPE_INT32_T, 0, 8, offsetof(mavlink_global_position_setpoint_int_t, altitude) }, \ + { "yaw", NULL, MAVLINK_TYPE_INT16_T, 0, 12, offsetof(mavlink_global_position_setpoint_int_t, yaw) }, \ + { "coordinate_frame", NULL, MAVLINK_TYPE_UINT8_T, 0, 14, offsetof(mavlink_global_position_setpoint_int_t, coordinate_frame) }, \ + } \ + } + + +/** + * @brief Pack a global_position_setpoint_int message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param coordinate_frame Coordinate frame - valid values are only MAV_FRAME_GLOBAL or MAV_FRAME_GLOBAL_RELATIVE_ALT + * @param latitude WGS84 Latitude position in degrees * 1E7 + * @param longitude WGS84 Longitude position in degrees * 1E7 + * @param altitude WGS84 Altitude in meters * 1000 (positive for up) + * @param yaw Desired yaw angle in degrees * 100 + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_global_position_setpoint_int_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t coordinate_frame, int32_t latitude, int32_t longitude, int32_t altitude, int16_t yaw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[15]; + _mav_put_int32_t(buf, 0, latitude); + _mav_put_int32_t(buf, 4, longitude); + _mav_put_int32_t(buf, 8, altitude); + _mav_put_int16_t(buf, 12, yaw); + _mav_put_uint8_t(buf, 14, coordinate_frame); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 15); +#else + mavlink_global_position_setpoint_int_t packet; + packet.latitude = latitude; + packet.longitude = longitude; + packet.altitude = altitude; + packet.yaw = yaw; + packet.coordinate_frame = coordinate_frame; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 15); +#endif + + msg->msgid = MAVLINK_MSG_ID_GLOBAL_POSITION_SETPOINT_INT; + return mavlink_finalize_message(msg, system_id, component_id, 15, 141); +} + +/** + * @brief Pack a global_position_setpoint_int message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param coordinate_frame Coordinate frame - valid values are only MAV_FRAME_GLOBAL or MAV_FRAME_GLOBAL_RELATIVE_ALT + * @param latitude WGS84 Latitude position in degrees * 1E7 + * @param longitude WGS84 Longitude position in degrees * 1E7 + * @param altitude WGS84 Altitude in meters * 1000 (positive for up) + * @param yaw Desired yaw angle in degrees * 100 + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_global_position_setpoint_int_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t coordinate_frame, int32_t latitude, int32_t longitude, int32_t altitude, int16_t yaw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[15]; + _mav_put_int32_t(buf, 0, latitude); + _mav_put_int32_t(buf, 4, longitude); + _mav_put_int32_t(buf, 8, altitude); + _mav_put_int16_t(buf, 12, yaw); + _mav_put_uint8_t(buf, 14, coordinate_frame); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 15); +#else + mavlink_global_position_setpoint_int_t packet; + packet.latitude = latitude; + packet.longitude = longitude; + packet.altitude = altitude; + packet.yaw = yaw; + packet.coordinate_frame = coordinate_frame; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 15); +#endif + + msg->msgid = MAVLINK_MSG_ID_GLOBAL_POSITION_SETPOINT_INT; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 15, 141); +} + +/** + * @brief Encode a global_position_setpoint_int struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param global_position_setpoint_int C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_global_position_setpoint_int_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_global_position_setpoint_int_t *global_position_setpoint_int) +{ + return mavlink_msg_global_position_setpoint_int_pack(system_id, component_id, msg, global_position_setpoint_int->coordinate_frame, global_position_setpoint_int->latitude, global_position_setpoint_int->longitude, global_position_setpoint_int->altitude, global_position_setpoint_int->yaw); +} + +/** + * @brief Send a global_position_setpoint_int message + * @param chan MAVLink channel to send the message + * + * @param coordinate_frame Coordinate frame - valid values are only MAV_FRAME_GLOBAL or MAV_FRAME_GLOBAL_RELATIVE_ALT + * @param latitude WGS84 Latitude position in degrees * 1E7 + * @param longitude WGS84 Longitude position in degrees * 1E7 + * @param altitude WGS84 Altitude in meters * 1000 (positive for up) + * @param yaw Desired yaw angle in degrees * 100 + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_global_position_setpoint_int_send(mavlink_channel_t chan, uint8_t coordinate_frame, int32_t latitude, int32_t longitude, int32_t altitude, int16_t yaw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[15]; + _mav_put_int32_t(buf, 0, latitude); + _mav_put_int32_t(buf, 4, longitude); + _mav_put_int32_t(buf, 8, altitude); + _mav_put_int16_t(buf, 12, yaw); + _mav_put_uint8_t(buf, 14, coordinate_frame); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_GLOBAL_POSITION_SETPOINT_INT, buf, 15, 141); +#else + mavlink_global_position_setpoint_int_t packet; + packet.latitude = latitude; + packet.longitude = longitude; + packet.altitude = altitude; + packet.yaw = yaw; + packet.coordinate_frame = coordinate_frame; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_GLOBAL_POSITION_SETPOINT_INT, (const char *)&packet, 15, 141); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE GLOBAL_POSITION_SETPOINT_INT UNPACKING + + +/** + * @brief Get field coordinate_frame from global_position_setpoint_int message + * + * @return Coordinate frame - valid values are only MAV_FRAME_GLOBAL or MAV_FRAME_GLOBAL_RELATIVE_ALT + */ +static inline uint8_t mavlink_msg_global_position_setpoint_int_get_coordinate_frame(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 14); +} + +/** + * @brief Get field latitude from global_position_setpoint_int message + * + * @return WGS84 Latitude position in degrees * 1E7 + */ +static inline int32_t mavlink_msg_global_position_setpoint_int_get_latitude(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int32_t(msg, 0); +} + +/** + * @brief Get field longitude from global_position_setpoint_int message + * + * @return WGS84 Longitude position in degrees * 1E7 + */ +static inline int32_t mavlink_msg_global_position_setpoint_int_get_longitude(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int32_t(msg, 4); +} + +/** + * @brief Get field altitude from global_position_setpoint_int message + * + * @return WGS84 Altitude in meters * 1000 (positive for up) + */ +static inline int32_t mavlink_msg_global_position_setpoint_int_get_altitude(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int32_t(msg, 8); +} + +/** + * @brief Get field yaw from global_position_setpoint_int message + * + * @return Desired yaw angle in degrees * 100 + */ +static inline int16_t mavlink_msg_global_position_setpoint_int_get_yaw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 12); +} + +/** + * @brief Decode a global_position_setpoint_int message into a struct + * + * @param msg The message to decode + * @param global_position_setpoint_int C-struct to decode the message contents into + */ +static inline void mavlink_msg_global_position_setpoint_int_decode(const mavlink_message_t *msg, mavlink_global_position_setpoint_int_t *global_position_setpoint_int) +{ +#if MAVLINK_NEED_BYTE_SWAP + global_position_setpoint_int->latitude = mavlink_msg_global_position_setpoint_int_get_latitude(msg); + global_position_setpoint_int->longitude = mavlink_msg_global_position_setpoint_int_get_longitude(msg); + global_position_setpoint_int->altitude = mavlink_msg_global_position_setpoint_int_get_altitude(msg); + global_position_setpoint_int->yaw = mavlink_msg_global_position_setpoint_int_get_yaw(msg); + global_position_setpoint_int->coordinate_frame = mavlink_msg_global_position_setpoint_int_get_coordinate_frame(msg); +#else + memcpy(global_position_setpoint_int, _MAV_PAYLOAD(msg), 15); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_global_vision_position_estimate.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_global_vision_position_estimate.h new file mode 100644 index 000000000..cbf500a82 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_global_vision_position_estimate.h @@ -0,0 +1,276 @@ +// MESSAGE GLOBAL_VISION_POSITION_ESTIMATE PACKING + +#define MAVLINK_MSG_ID_GLOBAL_VISION_POSITION_ESTIMATE 101 + +typedef struct __mavlink_global_vision_position_estimate_t { + uint64_t usec; ///< Timestamp (milliseconds) + float x; ///< Global X position + float y; ///< Global Y position + float z; ///< Global Z position + float roll; ///< Roll angle in rad + float pitch; ///< Pitch angle in rad + float yaw; ///< Yaw angle in rad +} mavlink_global_vision_position_estimate_t; + +#define MAVLINK_MSG_ID_GLOBAL_VISION_POSITION_ESTIMATE_LEN 32 +#define MAVLINK_MSG_ID_101_LEN 32 + + +#define MAVLINK_MESSAGE_INFO_GLOBAL_VISION_POSITION_ESTIMATE \ + { \ + "GLOBAL_VISION_POSITION_ESTIMATE", \ + 7, \ + { \ + { "usec", NULL, MAVLINK_TYPE_UINT64_T, 0, 0, offsetof(mavlink_global_vision_position_estimate_t, usec) }, \ + { "x", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_global_vision_position_estimate_t, x) }, \ + { "y", NULL, MAVLINK_TYPE_FLOAT, 0, 12, offsetof(mavlink_global_vision_position_estimate_t, y) }, \ + { "z", NULL, MAVLINK_TYPE_FLOAT, 0, 16, offsetof(mavlink_global_vision_position_estimate_t, z) }, \ + { "roll", NULL, MAVLINK_TYPE_FLOAT, 0, 20, offsetof(mavlink_global_vision_position_estimate_t, roll) }, \ + { "pitch", NULL, MAVLINK_TYPE_FLOAT, 0, 24, offsetof(mavlink_global_vision_position_estimate_t, pitch) }, \ + { "yaw", NULL, MAVLINK_TYPE_FLOAT, 0, 28, offsetof(mavlink_global_vision_position_estimate_t, yaw) }, \ + } \ + } + + +/** + * @brief Pack a global_vision_position_estimate message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param usec Timestamp (milliseconds) + * @param x Global X position + * @param y Global Y position + * @param z Global Z position + * @param roll Roll angle in rad + * @param pitch Pitch angle in rad + * @param yaw Yaw angle in rad + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_global_vision_position_estimate_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint64_t usec, float x, float y, float z, float roll, float pitch, float yaw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[32]; + _mav_put_uint64_t(buf, 0, usec); + _mav_put_float(buf, 8, x); + _mav_put_float(buf, 12, y); + _mav_put_float(buf, 16, z); + _mav_put_float(buf, 20, roll); + _mav_put_float(buf, 24, pitch); + _mav_put_float(buf, 28, yaw); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 32); +#else + mavlink_global_vision_position_estimate_t packet; + packet.usec = usec; + packet.x = x; + packet.y = y; + packet.z = z; + packet.roll = roll; + packet.pitch = pitch; + packet.yaw = yaw; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 32); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_GLOBAL_VISION_POSITION_ESTIMATE; + return mavlink_finalize_message(msg, system_id, component_id, 32, 102); +} + +/** + * @brief Pack a global_vision_position_estimate message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param usec Timestamp (milliseconds) + * @param x Global X position + * @param y Global Y position + * @param z Global Z position + * @param roll Roll angle in rad + * @param pitch Pitch angle in rad + * @param yaw Yaw angle in rad + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_global_vision_position_estimate_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint64_t usec, float x, float y, float z, float roll, float pitch, float yaw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[32]; + _mav_put_uint64_t(buf, 0, usec); + _mav_put_float(buf, 8, x); + _mav_put_float(buf, 12, y); + _mav_put_float(buf, 16, z); + _mav_put_float(buf, 20, roll); + _mav_put_float(buf, 24, pitch); + _mav_put_float(buf, 28, yaw); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 32); +#else + mavlink_global_vision_position_estimate_t packet; + packet.usec = usec; + packet.x = x; + packet.y = y; + packet.z = z; + packet.roll = roll; + packet.pitch = pitch; + packet.yaw = yaw; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 32); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_GLOBAL_VISION_POSITION_ESTIMATE; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 32, 102); +} + +/** + * @brief Encode a global_vision_position_estimate struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param global_vision_position_estimate C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_global_vision_position_estimate_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_global_vision_position_estimate_t *global_vision_position_estimate) +{ + return mavlink_msg_global_vision_position_estimate_pack(system_id, component_id, msg, global_vision_position_estimate->usec, global_vision_position_estimate->x, global_vision_position_estimate->y, global_vision_position_estimate->z, global_vision_position_estimate->roll, global_vision_position_estimate->pitch, global_vision_position_estimate->yaw); +} + +/** + * @brief Send a global_vision_position_estimate message + * @param chan MAVLink channel to send the message + * + * @param usec Timestamp (milliseconds) + * @param x Global X position + * @param y Global Y position + * @param z Global Z position + * @param roll Roll angle in rad + * @param pitch Pitch angle in rad + * @param yaw Yaw angle in rad + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_global_vision_position_estimate_send(mavlink_channel_t chan, uint64_t usec, float x, float y, float z, float roll, float pitch, float yaw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[32]; + _mav_put_uint64_t(buf, 0, usec); + _mav_put_float(buf, 8, x); + _mav_put_float(buf, 12, y); + _mav_put_float(buf, 16, z); + _mav_put_float(buf, 20, roll); + _mav_put_float(buf, 24, pitch); + _mav_put_float(buf, 28, yaw); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_GLOBAL_VISION_POSITION_ESTIMATE, buf, 32, 102); +#else + mavlink_global_vision_position_estimate_t packet; + packet.usec = usec; + packet.x = x; + packet.y = y; + packet.z = z; + packet.roll = roll; + packet.pitch = pitch; + packet.yaw = yaw; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_GLOBAL_VISION_POSITION_ESTIMATE, (const char *)&packet, 32, 102); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE GLOBAL_VISION_POSITION_ESTIMATE UNPACKING + + +/** + * @brief Get field usec from global_vision_position_estimate message + * + * @return Timestamp (milliseconds) + */ +static inline uint64_t mavlink_msg_global_vision_position_estimate_get_usec(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint64_t(msg, 0); +} + +/** + * @brief Get field x from global_vision_position_estimate message + * + * @return Global X position + */ +static inline float mavlink_msg_global_vision_position_estimate_get_x(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 8); +} + +/** + * @brief Get field y from global_vision_position_estimate message + * + * @return Global Y position + */ +static inline float mavlink_msg_global_vision_position_estimate_get_y(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 12); +} + +/** + * @brief Get field z from global_vision_position_estimate message + * + * @return Global Z position + */ +static inline float mavlink_msg_global_vision_position_estimate_get_z(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 16); +} + +/** + * @brief Get field roll from global_vision_position_estimate message + * + * @return Roll angle in rad + */ +static inline float mavlink_msg_global_vision_position_estimate_get_roll(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 20); +} + +/** + * @brief Get field pitch from global_vision_position_estimate message + * + * @return Pitch angle in rad + */ +static inline float mavlink_msg_global_vision_position_estimate_get_pitch(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 24); +} + +/** + * @brief Get field yaw from global_vision_position_estimate message + * + * @return Yaw angle in rad + */ +static inline float mavlink_msg_global_vision_position_estimate_get_yaw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 28); +} + +/** + * @brief Decode a global_vision_position_estimate message into a struct + * + * @param msg The message to decode + * @param global_vision_position_estimate C-struct to decode the message contents into + */ +static inline void mavlink_msg_global_vision_position_estimate_decode(const mavlink_message_t *msg, mavlink_global_vision_position_estimate_t *global_vision_position_estimate) +{ +#if MAVLINK_NEED_BYTE_SWAP + global_vision_position_estimate->usec = mavlink_msg_global_vision_position_estimate_get_usec(msg); + global_vision_position_estimate->x = mavlink_msg_global_vision_position_estimate_get_x(msg); + global_vision_position_estimate->y = mavlink_msg_global_vision_position_estimate_get_y(msg); + global_vision_position_estimate->z = mavlink_msg_global_vision_position_estimate_get_z(msg); + global_vision_position_estimate->roll = mavlink_msg_global_vision_position_estimate_get_roll(msg); + global_vision_position_estimate->pitch = mavlink_msg_global_vision_position_estimate_get_pitch(msg); + global_vision_position_estimate->yaw = mavlink_msg_global_vision_position_estimate_get_yaw(msg); +#else + memcpy(global_vision_position_estimate, _MAV_PAYLOAD(msg), 32); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_gps_global_origin.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_gps_global_origin.h new file mode 100644 index 000000000..900cefcc1 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_gps_global_origin.h @@ -0,0 +1,188 @@ +// MESSAGE GPS_GLOBAL_ORIGIN PACKING + +#define MAVLINK_MSG_ID_GPS_GLOBAL_ORIGIN 49 + +typedef struct __mavlink_gps_global_origin_t { + int32_t latitude; ///< Latitude (WGS84), expressed as * 1E7 + int32_t longitude; ///< Longitude (WGS84), expressed as * 1E7 + int32_t altitude; ///< Altitude(WGS84), expressed as * 1000 +} mavlink_gps_global_origin_t; + +#define MAVLINK_MSG_ID_GPS_GLOBAL_ORIGIN_LEN 12 +#define MAVLINK_MSG_ID_49_LEN 12 + + +#define MAVLINK_MESSAGE_INFO_GPS_GLOBAL_ORIGIN \ + { \ + "GPS_GLOBAL_ORIGIN", \ + 3, \ + { \ + { "latitude", NULL, MAVLINK_TYPE_INT32_T, 0, 0, offsetof(mavlink_gps_global_origin_t, latitude) }, \ + { "longitude", NULL, MAVLINK_TYPE_INT32_T, 0, 4, offsetof(mavlink_gps_global_origin_t, longitude) }, \ + { "altitude", NULL, MAVLINK_TYPE_INT32_T, 0, 8, offsetof(mavlink_gps_global_origin_t, altitude) }, \ + } \ + } + + +/** + * @brief Pack a gps_global_origin message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param latitude Latitude (WGS84), expressed as * 1E7 + * @param longitude Longitude (WGS84), expressed as * 1E7 + * @param altitude Altitude(WGS84), expressed as * 1000 + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_gps_global_origin_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + int32_t latitude, int32_t longitude, int32_t altitude) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[12]; + _mav_put_int32_t(buf, 0, latitude); + _mav_put_int32_t(buf, 4, longitude); + _mav_put_int32_t(buf, 8, altitude); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 12); +#else + mavlink_gps_global_origin_t packet; + packet.latitude = latitude; + packet.longitude = longitude; + packet.altitude = altitude; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 12); +#endif + + msg->msgid = MAVLINK_MSG_ID_GPS_GLOBAL_ORIGIN; + return mavlink_finalize_message(msg, system_id, component_id, 12, 39); +} + +/** + * @brief Pack a gps_global_origin message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param latitude Latitude (WGS84), expressed as * 1E7 + * @param longitude Longitude (WGS84), expressed as * 1E7 + * @param altitude Altitude(WGS84), expressed as * 1000 + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_gps_global_origin_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + int32_t latitude, int32_t longitude, int32_t altitude) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[12]; + _mav_put_int32_t(buf, 0, latitude); + _mav_put_int32_t(buf, 4, longitude); + _mav_put_int32_t(buf, 8, altitude); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 12); +#else + mavlink_gps_global_origin_t packet; + packet.latitude = latitude; + packet.longitude = longitude; + packet.altitude = altitude; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 12); +#endif + + msg->msgid = MAVLINK_MSG_ID_GPS_GLOBAL_ORIGIN; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 12, 39); +} + +/** + * @brief Encode a gps_global_origin struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param gps_global_origin C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_gps_global_origin_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_gps_global_origin_t *gps_global_origin) +{ + return mavlink_msg_gps_global_origin_pack(system_id, component_id, msg, gps_global_origin->latitude, gps_global_origin->longitude, gps_global_origin->altitude); +} + +/** + * @brief Send a gps_global_origin message + * @param chan MAVLink channel to send the message + * + * @param latitude Latitude (WGS84), expressed as * 1E7 + * @param longitude Longitude (WGS84), expressed as * 1E7 + * @param altitude Altitude(WGS84), expressed as * 1000 + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_gps_global_origin_send(mavlink_channel_t chan, int32_t latitude, int32_t longitude, int32_t altitude) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[12]; + _mav_put_int32_t(buf, 0, latitude); + _mav_put_int32_t(buf, 4, longitude); + _mav_put_int32_t(buf, 8, altitude); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_GPS_GLOBAL_ORIGIN, buf, 12, 39); +#else + mavlink_gps_global_origin_t packet; + packet.latitude = latitude; + packet.longitude = longitude; + packet.altitude = altitude; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_GPS_GLOBAL_ORIGIN, (const char *)&packet, 12, 39); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE GPS_GLOBAL_ORIGIN UNPACKING + + +/** + * @brief Get field latitude from gps_global_origin message + * + * @return Latitude (WGS84), expressed as * 1E7 + */ +static inline int32_t mavlink_msg_gps_global_origin_get_latitude(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int32_t(msg, 0); +} + +/** + * @brief Get field longitude from gps_global_origin message + * + * @return Longitude (WGS84), expressed as * 1E7 + */ +static inline int32_t mavlink_msg_gps_global_origin_get_longitude(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int32_t(msg, 4); +} + +/** + * @brief Get field altitude from gps_global_origin message + * + * @return Altitude(WGS84), expressed as * 1000 + */ +static inline int32_t mavlink_msg_gps_global_origin_get_altitude(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int32_t(msg, 8); +} + +/** + * @brief Decode a gps_global_origin message into a struct + * + * @param msg The message to decode + * @param gps_global_origin C-struct to decode the message contents into + */ +static inline void mavlink_msg_gps_global_origin_decode(const mavlink_message_t *msg, mavlink_gps_global_origin_t *gps_global_origin) +{ +#if MAVLINK_NEED_BYTE_SWAP + gps_global_origin->latitude = mavlink_msg_gps_global_origin_get_latitude(msg); + gps_global_origin->longitude = mavlink_msg_gps_global_origin_get_longitude(msg); + gps_global_origin->altitude = mavlink_msg_gps_global_origin_get_altitude(msg); +#else + memcpy(gps_global_origin, _MAV_PAYLOAD(msg), 12); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_gps_raw_int.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_gps_raw_int.h new file mode 100644 index 000000000..5e004cead --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_gps_raw_int.h @@ -0,0 +1,342 @@ +// MESSAGE GPS_RAW_INT PACKING + +#define MAVLINK_MSG_ID_GPS_RAW_INT 24 + +typedef struct __mavlink_gps_raw_int_t { + uint64_t time_usec; ///< Timestamp (microseconds since UNIX epoch or microseconds since system boot) + int32_t lat; ///< Latitude in 1E7 degrees + int32_t lon; ///< Longitude in 1E7 degrees + int32_t alt; ///< Altitude in 1E3 meters (millimeters) above MSL + uint16_t eph; ///< GPS HDOP horizontal dilution of position in cm (m*100). If unknown, set to: 65535 + uint16_t epv; ///< GPS VDOP horizontal dilution of position in cm (m*100). If unknown, set to: 65535 + uint16_t vel; ///< GPS ground speed (m/s * 100). If unknown, set to: 65535 + uint16_t cog; ///< Course over ground (NOT heading, but direction of movement) in degrees * 100, 0.0..359.99 degrees. If unknown, set to: 65535 + uint8_t fix_type; ///< 0-1: no fix, 2: 2D fix, 3: 3D fix. Some applications will not use the value of this field unless it is at least two, so always correctly fill in the fix. + uint8_t satellites_visible; ///< Number of satellites visible. If unknown, set to 255 +} mavlink_gps_raw_int_t; + +#define MAVLINK_MSG_ID_GPS_RAW_INT_LEN 30 +#define MAVLINK_MSG_ID_24_LEN 30 + + +#define MAVLINK_MESSAGE_INFO_GPS_RAW_INT \ + { \ + "GPS_RAW_INT", \ + 10, \ + { \ + { "time_usec", NULL, MAVLINK_TYPE_UINT64_T, 0, 0, offsetof(mavlink_gps_raw_int_t, time_usec) }, \ + { "lat", NULL, MAVLINK_TYPE_INT32_T, 0, 8, offsetof(mavlink_gps_raw_int_t, lat) }, \ + { "lon", NULL, MAVLINK_TYPE_INT32_T, 0, 12, offsetof(mavlink_gps_raw_int_t, lon) }, \ + { "alt", NULL, MAVLINK_TYPE_INT32_T, 0, 16, offsetof(mavlink_gps_raw_int_t, alt) }, \ + { "eph", NULL, MAVLINK_TYPE_UINT16_T, 0, 20, offsetof(mavlink_gps_raw_int_t, eph) }, \ + { "epv", NULL, MAVLINK_TYPE_UINT16_T, 0, 22, offsetof(mavlink_gps_raw_int_t, epv) }, \ + { "vel", NULL, MAVLINK_TYPE_UINT16_T, 0, 24, offsetof(mavlink_gps_raw_int_t, vel) }, \ + { "cog", NULL, MAVLINK_TYPE_UINT16_T, 0, 26, offsetof(mavlink_gps_raw_int_t, cog) }, \ + { "fix_type", NULL, MAVLINK_TYPE_UINT8_T, 0, 28, offsetof(mavlink_gps_raw_int_t, fix_type) }, \ + { "satellites_visible", NULL, MAVLINK_TYPE_UINT8_T, 0, 29, offsetof(mavlink_gps_raw_int_t, satellites_visible) }, \ + } \ + } + + +/** + * @brief Pack a gps_raw_int message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param time_usec Timestamp (microseconds since UNIX epoch or microseconds since system boot) + * @param fix_type 0-1: no fix, 2: 2D fix, 3: 3D fix. Some applications will not use the value of this field unless it is at least two, so always correctly fill in the fix. + * @param lat Latitude in 1E7 degrees + * @param lon Longitude in 1E7 degrees + * @param alt Altitude in 1E3 meters (millimeters) above MSL + * @param eph GPS HDOP horizontal dilution of position in cm (m*100). If unknown, set to: 65535 + * @param epv GPS VDOP horizontal dilution of position in cm (m*100). If unknown, set to: 65535 + * @param vel GPS ground speed (m/s * 100). If unknown, set to: 65535 + * @param cog Course over ground (NOT heading, but direction of movement) in degrees * 100, 0.0..359.99 degrees. If unknown, set to: 65535 + * @param satellites_visible Number of satellites visible. If unknown, set to 255 + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_gps_raw_int_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint64_t time_usec, uint8_t fix_type, int32_t lat, int32_t lon, int32_t alt, uint16_t eph, uint16_t epv, uint16_t vel, uint16_t cog, uint8_t satellites_visible) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[30]; + _mav_put_uint64_t(buf, 0, time_usec); + _mav_put_int32_t(buf, 8, lat); + _mav_put_int32_t(buf, 12, lon); + _mav_put_int32_t(buf, 16, alt); + _mav_put_uint16_t(buf, 20, eph); + _mav_put_uint16_t(buf, 22, epv); + _mav_put_uint16_t(buf, 24, vel); + _mav_put_uint16_t(buf, 26, cog); + _mav_put_uint8_t(buf, 28, fix_type); + _mav_put_uint8_t(buf, 29, satellites_visible); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 30); +#else + mavlink_gps_raw_int_t packet; + packet.time_usec = time_usec; + packet.lat = lat; + packet.lon = lon; + packet.alt = alt; + packet.eph = eph; + packet.epv = epv; + packet.vel = vel; + packet.cog = cog; + packet.fix_type = fix_type; + packet.satellites_visible = satellites_visible; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 30); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_GPS_RAW_INT; + return mavlink_finalize_message(msg, system_id, component_id, 30, 24); +} + +/** + * @brief Pack a gps_raw_int message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param time_usec Timestamp (microseconds since UNIX epoch or microseconds since system boot) + * @param fix_type 0-1: no fix, 2: 2D fix, 3: 3D fix. Some applications will not use the value of this field unless it is at least two, so always correctly fill in the fix. + * @param lat Latitude in 1E7 degrees + * @param lon Longitude in 1E7 degrees + * @param alt Altitude in 1E3 meters (millimeters) above MSL + * @param eph GPS HDOP horizontal dilution of position in cm (m*100). If unknown, set to: 65535 + * @param epv GPS VDOP horizontal dilution of position in cm (m*100). If unknown, set to: 65535 + * @param vel GPS ground speed (m/s * 100). If unknown, set to: 65535 + * @param cog Course over ground (NOT heading, but direction of movement) in degrees * 100, 0.0..359.99 degrees. If unknown, set to: 65535 + * @param satellites_visible Number of satellites visible. If unknown, set to 255 + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_gps_raw_int_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint64_t time_usec, uint8_t fix_type, int32_t lat, int32_t lon, int32_t alt, uint16_t eph, uint16_t epv, uint16_t vel, uint16_t cog, uint8_t satellites_visible) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[30]; + _mav_put_uint64_t(buf, 0, time_usec); + _mav_put_int32_t(buf, 8, lat); + _mav_put_int32_t(buf, 12, lon); + _mav_put_int32_t(buf, 16, alt); + _mav_put_uint16_t(buf, 20, eph); + _mav_put_uint16_t(buf, 22, epv); + _mav_put_uint16_t(buf, 24, vel); + _mav_put_uint16_t(buf, 26, cog); + _mav_put_uint8_t(buf, 28, fix_type); + _mav_put_uint8_t(buf, 29, satellites_visible); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 30); +#else + mavlink_gps_raw_int_t packet; + packet.time_usec = time_usec; + packet.lat = lat; + packet.lon = lon; + packet.alt = alt; + packet.eph = eph; + packet.epv = epv; + packet.vel = vel; + packet.cog = cog; + packet.fix_type = fix_type; + packet.satellites_visible = satellites_visible; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 30); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_GPS_RAW_INT; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 30, 24); +} + +/** + * @brief Encode a gps_raw_int struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param gps_raw_int C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_gps_raw_int_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_gps_raw_int_t *gps_raw_int) +{ + return mavlink_msg_gps_raw_int_pack(system_id, component_id, msg, gps_raw_int->time_usec, gps_raw_int->fix_type, gps_raw_int->lat, gps_raw_int->lon, gps_raw_int->alt, gps_raw_int->eph, gps_raw_int->epv, gps_raw_int->vel, gps_raw_int->cog, gps_raw_int->satellites_visible); +} + +/** + * @brief Send a gps_raw_int message + * @param chan MAVLink channel to send the message + * + * @param time_usec Timestamp (microseconds since UNIX epoch or microseconds since system boot) + * @param fix_type 0-1: no fix, 2: 2D fix, 3: 3D fix. Some applications will not use the value of this field unless it is at least two, so always correctly fill in the fix. + * @param lat Latitude in 1E7 degrees + * @param lon Longitude in 1E7 degrees + * @param alt Altitude in 1E3 meters (millimeters) above MSL + * @param eph GPS HDOP horizontal dilution of position in cm (m*100). If unknown, set to: 65535 + * @param epv GPS VDOP horizontal dilution of position in cm (m*100). If unknown, set to: 65535 + * @param vel GPS ground speed (m/s * 100). If unknown, set to: 65535 + * @param cog Course over ground (NOT heading, but direction of movement) in degrees * 100, 0.0..359.99 degrees. If unknown, set to: 65535 + * @param satellites_visible Number of satellites visible. If unknown, set to 255 + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_gps_raw_int_send(mavlink_channel_t chan, uint64_t time_usec, uint8_t fix_type, int32_t lat, int32_t lon, int32_t alt, uint16_t eph, uint16_t epv, uint16_t vel, uint16_t cog, uint8_t satellites_visible) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[30]; + _mav_put_uint64_t(buf, 0, time_usec); + _mav_put_int32_t(buf, 8, lat); + _mav_put_int32_t(buf, 12, lon); + _mav_put_int32_t(buf, 16, alt); + _mav_put_uint16_t(buf, 20, eph); + _mav_put_uint16_t(buf, 22, epv); + _mav_put_uint16_t(buf, 24, vel); + _mav_put_uint16_t(buf, 26, cog); + _mav_put_uint8_t(buf, 28, fix_type); + _mav_put_uint8_t(buf, 29, satellites_visible); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_GPS_RAW_INT, buf, 30, 24); +#else + mavlink_gps_raw_int_t packet; + packet.time_usec = time_usec; + packet.lat = lat; + packet.lon = lon; + packet.alt = alt; + packet.eph = eph; + packet.epv = epv; + packet.vel = vel; + packet.cog = cog; + packet.fix_type = fix_type; + packet.satellites_visible = satellites_visible; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_GPS_RAW_INT, (const char *)&packet, 30, 24); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE GPS_RAW_INT UNPACKING + + +/** + * @brief Get field time_usec from gps_raw_int message + * + * @return Timestamp (microseconds since UNIX epoch or microseconds since system boot) + */ +static inline uint64_t mavlink_msg_gps_raw_int_get_time_usec(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint64_t(msg, 0); +} + +/** + * @brief Get field fix_type from gps_raw_int message + * + * @return 0-1: no fix, 2: 2D fix, 3: 3D fix. Some applications will not use the value of this field unless it is at least two, so always correctly fill in the fix. + */ +static inline uint8_t mavlink_msg_gps_raw_int_get_fix_type(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 28); +} + +/** + * @brief Get field lat from gps_raw_int message + * + * @return Latitude in 1E7 degrees + */ +static inline int32_t mavlink_msg_gps_raw_int_get_lat(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int32_t(msg, 8); +} + +/** + * @brief Get field lon from gps_raw_int message + * + * @return Longitude in 1E7 degrees + */ +static inline int32_t mavlink_msg_gps_raw_int_get_lon(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int32_t(msg, 12); +} + +/** + * @brief Get field alt from gps_raw_int message + * + * @return Altitude in 1E3 meters (millimeters) above MSL + */ +static inline int32_t mavlink_msg_gps_raw_int_get_alt(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int32_t(msg, 16); +} + +/** + * @brief Get field eph from gps_raw_int message + * + * @return GPS HDOP horizontal dilution of position in cm (m*100). If unknown, set to: 65535 + */ +static inline uint16_t mavlink_msg_gps_raw_int_get_eph(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 20); +} + +/** + * @brief Get field epv from gps_raw_int message + * + * @return GPS VDOP horizontal dilution of position in cm (m*100). If unknown, set to: 65535 + */ +static inline uint16_t mavlink_msg_gps_raw_int_get_epv(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 22); +} + +/** + * @brief Get field vel from gps_raw_int message + * + * @return GPS ground speed (m/s * 100). If unknown, set to: 65535 + */ +static inline uint16_t mavlink_msg_gps_raw_int_get_vel(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 24); +} + +/** + * @brief Get field cog from gps_raw_int message + * + * @return Course over ground (NOT heading, but direction of movement) in degrees * 100, 0.0..359.99 degrees. If unknown, set to: 65535 + */ +static inline uint16_t mavlink_msg_gps_raw_int_get_cog(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 26); +} + +/** + * @brief Get field satellites_visible from gps_raw_int message + * + * @return Number of satellites visible. If unknown, set to 255 + */ +static inline uint8_t mavlink_msg_gps_raw_int_get_satellites_visible(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 29); +} + +/** + * @brief Decode a gps_raw_int message into a struct + * + * @param msg The message to decode + * @param gps_raw_int C-struct to decode the message contents into + */ +static inline void mavlink_msg_gps_raw_int_decode(const mavlink_message_t *msg, mavlink_gps_raw_int_t *gps_raw_int) +{ +#if MAVLINK_NEED_BYTE_SWAP + gps_raw_int->time_usec = mavlink_msg_gps_raw_int_get_time_usec(msg); + gps_raw_int->lat = mavlink_msg_gps_raw_int_get_lat(msg); + gps_raw_int->lon = mavlink_msg_gps_raw_int_get_lon(msg); + gps_raw_int->alt = mavlink_msg_gps_raw_int_get_alt(msg); + gps_raw_int->eph = mavlink_msg_gps_raw_int_get_eph(msg); + gps_raw_int->epv = mavlink_msg_gps_raw_int_get_epv(msg); + gps_raw_int->vel = mavlink_msg_gps_raw_int_get_vel(msg); + gps_raw_int->cog = mavlink_msg_gps_raw_int_get_cog(msg); + gps_raw_int->fix_type = mavlink_msg_gps_raw_int_get_fix_type(msg); + gps_raw_int->satellites_visible = mavlink_msg_gps_raw_int_get_satellites_visible(msg); +#else + memcpy(gps_raw_int, _MAV_PAYLOAD(msg), 30); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_gps_status.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_gps_status.h new file mode 100644 index 000000000..3bf151c26 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_gps_status.h @@ -0,0 +1,253 @@ +// MESSAGE GPS_STATUS PACKING + +#define MAVLINK_MSG_ID_GPS_STATUS 25 + +typedef struct __mavlink_gps_status_t { + uint8_t satellites_visible; ///< Number of satellites visible + uint8_t satellite_prn[20]; ///< Global satellite ID + uint8_t satellite_used[20]; ///< 0: Satellite not used, 1: used for localization + uint8_t satellite_elevation[20]; ///< Elevation (0: right on top of receiver, 90: on the horizon) of satellite + uint8_t satellite_azimuth[20]; ///< Direction of satellite, 0: 0 deg, 255: 360 deg. + uint8_t satellite_snr[20]; ///< Signal to noise ratio of satellite +} mavlink_gps_status_t; + +#define MAVLINK_MSG_ID_GPS_STATUS_LEN 101 +#define MAVLINK_MSG_ID_25_LEN 101 + +#define MAVLINK_MSG_GPS_STATUS_FIELD_SATELLITE_PRN_LEN 20 +#define MAVLINK_MSG_GPS_STATUS_FIELD_SATELLITE_USED_LEN 20 +#define MAVLINK_MSG_GPS_STATUS_FIELD_SATELLITE_ELEVATION_LEN 20 +#define MAVLINK_MSG_GPS_STATUS_FIELD_SATELLITE_AZIMUTH_LEN 20 +#define MAVLINK_MSG_GPS_STATUS_FIELD_SATELLITE_SNR_LEN 20 + +#define MAVLINK_MESSAGE_INFO_GPS_STATUS \ + { \ + "GPS_STATUS", \ + 6, \ + { \ + { "satellites_visible", NULL, MAVLINK_TYPE_UINT8_T, 0, 0, offsetof(mavlink_gps_status_t, satellites_visible) }, \ + { "satellite_prn", NULL, MAVLINK_TYPE_UINT8_T, 20, 1, offsetof(mavlink_gps_status_t, satellite_prn) }, \ + { "satellite_used", NULL, MAVLINK_TYPE_UINT8_T, 20, 21, offsetof(mavlink_gps_status_t, satellite_used) }, \ + { "satellite_elevation", NULL, MAVLINK_TYPE_UINT8_T, 20, 41, offsetof(mavlink_gps_status_t, satellite_elevation) }, \ + { "satellite_azimuth", NULL, MAVLINK_TYPE_UINT8_T, 20, 61, offsetof(mavlink_gps_status_t, satellite_azimuth) }, \ + { "satellite_snr", NULL, MAVLINK_TYPE_UINT8_T, 20, 81, offsetof(mavlink_gps_status_t, satellite_snr) }, \ + } \ + } + + +/** + * @brief Pack a gps_status message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param satellites_visible Number of satellites visible + * @param satellite_prn Global satellite ID + * @param satellite_used 0: Satellite not used, 1: used for localization + * @param satellite_elevation Elevation (0: right on top of receiver, 90: on the horizon) of satellite + * @param satellite_azimuth Direction of satellite, 0: 0 deg, 255: 360 deg. + * @param satellite_snr Signal to noise ratio of satellite + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_gps_status_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t satellites_visible, const uint8_t *satellite_prn, const uint8_t *satellite_used, const uint8_t *satellite_elevation, const uint8_t *satellite_azimuth, const uint8_t *satellite_snr) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[101]; + _mav_put_uint8_t(buf, 0, satellites_visible); + _mav_put_uint8_t_array(buf, 1, satellite_prn, 20); + _mav_put_uint8_t_array(buf, 21, satellite_used, 20); + _mav_put_uint8_t_array(buf, 41, satellite_elevation, 20); + _mav_put_uint8_t_array(buf, 61, satellite_azimuth, 20); + _mav_put_uint8_t_array(buf, 81, satellite_snr, 20); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 101); +#else + mavlink_gps_status_t packet; + packet.satellites_visible = satellites_visible; + mav_array_memcpy(packet.satellite_prn, satellite_prn, sizeof(uint8_t) * 20); + mav_array_memcpy(packet.satellite_used, satellite_used, sizeof(uint8_t) * 20); + mav_array_memcpy(packet.satellite_elevation, satellite_elevation, sizeof(uint8_t) * 20); + mav_array_memcpy(packet.satellite_azimuth, satellite_azimuth, sizeof(uint8_t) * 20); + mav_array_memcpy(packet.satellite_snr, satellite_snr, sizeof(uint8_t) * 20); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 101); +#endif + + msg->msgid = MAVLINK_MSG_ID_GPS_STATUS; + return mavlink_finalize_message(msg, system_id, component_id, 101, 23); +} + +/** + * @brief Pack a gps_status message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param satellites_visible Number of satellites visible + * @param satellite_prn Global satellite ID + * @param satellite_used 0: Satellite not used, 1: used for localization + * @param satellite_elevation Elevation (0: right on top of receiver, 90: on the horizon) of satellite + * @param satellite_azimuth Direction of satellite, 0: 0 deg, 255: 360 deg. + * @param satellite_snr Signal to noise ratio of satellite + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_gps_status_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t satellites_visible, const uint8_t *satellite_prn, const uint8_t *satellite_used, const uint8_t *satellite_elevation, const uint8_t *satellite_azimuth, const uint8_t *satellite_snr) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[101]; + _mav_put_uint8_t(buf, 0, satellites_visible); + _mav_put_uint8_t_array(buf, 1, satellite_prn, 20); + _mav_put_uint8_t_array(buf, 21, satellite_used, 20); + _mav_put_uint8_t_array(buf, 41, satellite_elevation, 20); + _mav_put_uint8_t_array(buf, 61, satellite_azimuth, 20); + _mav_put_uint8_t_array(buf, 81, satellite_snr, 20); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 101); +#else + mavlink_gps_status_t packet; + packet.satellites_visible = satellites_visible; + mav_array_memcpy(packet.satellite_prn, satellite_prn, sizeof(uint8_t) * 20); + mav_array_memcpy(packet.satellite_used, satellite_used, sizeof(uint8_t) * 20); + mav_array_memcpy(packet.satellite_elevation, satellite_elevation, sizeof(uint8_t) * 20); + mav_array_memcpy(packet.satellite_azimuth, satellite_azimuth, sizeof(uint8_t) * 20); + mav_array_memcpy(packet.satellite_snr, satellite_snr, sizeof(uint8_t) * 20); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 101); +#endif + + msg->msgid = MAVLINK_MSG_ID_GPS_STATUS; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 101, 23); +} + +/** + * @brief Encode a gps_status struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param gps_status C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_gps_status_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_gps_status_t *gps_status) +{ + return mavlink_msg_gps_status_pack(system_id, component_id, msg, gps_status->satellites_visible, gps_status->satellite_prn, gps_status->satellite_used, gps_status->satellite_elevation, gps_status->satellite_azimuth, gps_status->satellite_snr); +} + +/** + * @brief Send a gps_status message + * @param chan MAVLink channel to send the message + * + * @param satellites_visible Number of satellites visible + * @param satellite_prn Global satellite ID + * @param satellite_used 0: Satellite not used, 1: used for localization + * @param satellite_elevation Elevation (0: right on top of receiver, 90: on the horizon) of satellite + * @param satellite_azimuth Direction of satellite, 0: 0 deg, 255: 360 deg. + * @param satellite_snr Signal to noise ratio of satellite + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_gps_status_send(mavlink_channel_t chan, uint8_t satellites_visible, const uint8_t *satellite_prn, const uint8_t *satellite_used, const uint8_t *satellite_elevation, const uint8_t *satellite_azimuth, const uint8_t *satellite_snr) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[101]; + _mav_put_uint8_t(buf, 0, satellites_visible); + _mav_put_uint8_t_array(buf, 1, satellite_prn, 20); + _mav_put_uint8_t_array(buf, 21, satellite_used, 20); + _mav_put_uint8_t_array(buf, 41, satellite_elevation, 20); + _mav_put_uint8_t_array(buf, 61, satellite_azimuth, 20); + _mav_put_uint8_t_array(buf, 81, satellite_snr, 20); + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_GPS_STATUS, buf, 101, 23); +#else + mavlink_gps_status_t packet; + packet.satellites_visible = satellites_visible; + mav_array_memcpy(packet.satellite_prn, satellite_prn, sizeof(uint8_t) * 20); + mav_array_memcpy(packet.satellite_used, satellite_used, sizeof(uint8_t) * 20); + mav_array_memcpy(packet.satellite_elevation, satellite_elevation, sizeof(uint8_t) * 20); + mav_array_memcpy(packet.satellite_azimuth, satellite_azimuth, sizeof(uint8_t) * 20); + mav_array_memcpy(packet.satellite_snr, satellite_snr, sizeof(uint8_t) * 20); + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_GPS_STATUS, (const char *)&packet, 101, 23); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE GPS_STATUS UNPACKING + + +/** + * @brief Get field satellites_visible from gps_status message + * + * @return Number of satellites visible + */ +static inline uint8_t mavlink_msg_gps_status_get_satellites_visible(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 0); +} + +/** + * @brief Get field satellite_prn from gps_status message + * + * @return Global satellite ID + */ +static inline uint16_t mavlink_msg_gps_status_get_satellite_prn(const mavlink_message_t *msg, uint8_t *satellite_prn) +{ + return _MAV_RETURN_uint8_t_array(msg, satellite_prn, 20, 1); +} + +/** + * @brief Get field satellite_used from gps_status message + * + * @return 0: Satellite not used, 1: used for localization + */ +static inline uint16_t mavlink_msg_gps_status_get_satellite_used(const mavlink_message_t *msg, uint8_t *satellite_used) +{ + return _MAV_RETURN_uint8_t_array(msg, satellite_used, 20, 21); +} + +/** + * @brief Get field satellite_elevation from gps_status message + * + * @return Elevation (0: right on top of receiver, 90: on the horizon) of satellite + */ +static inline uint16_t mavlink_msg_gps_status_get_satellite_elevation(const mavlink_message_t *msg, uint8_t *satellite_elevation) +{ + return _MAV_RETURN_uint8_t_array(msg, satellite_elevation, 20, 41); +} + +/** + * @brief Get field satellite_azimuth from gps_status message + * + * @return Direction of satellite, 0: 0 deg, 255: 360 deg. + */ +static inline uint16_t mavlink_msg_gps_status_get_satellite_azimuth(const mavlink_message_t *msg, uint8_t *satellite_azimuth) +{ + return _MAV_RETURN_uint8_t_array(msg, satellite_azimuth, 20, 61); +} + +/** + * @brief Get field satellite_snr from gps_status message + * + * @return Signal to noise ratio of satellite + */ +static inline uint16_t mavlink_msg_gps_status_get_satellite_snr(const mavlink_message_t *msg, uint8_t *satellite_snr) +{ + return _MAV_RETURN_uint8_t_array(msg, satellite_snr, 20, 81); +} + +/** + * @brief Decode a gps_status message into a struct + * + * @param msg The message to decode + * @param gps_status C-struct to decode the message contents into + */ +static inline void mavlink_msg_gps_status_decode(const mavlink_message_t *msg, mavlink_gps_status_t *gps_status) +{ +#if MAVLINK_NEED_BYTE_SWAP + gps_status->satellites_visible = mavlink_msg_gps_status_get_satellites_visible(msg); + mavlink_msg_gps_status_get_satellite_prn(msg, gps_status->satellite_prn); + mavlink_msg_gps_status_get_satellite_used(msg, gps_status->satellite_used); + mavlink_msg_gps_status_get_satellite_elevation(msg, gps_status->satellite_elevation); + mavlink_msg_gps_status_get_satellite_azimuth(msg, gps_status->satellite_azimuth); + mavlink_msg_gps_status_get_satellite_snr(msg, gps_status->satellite_snr); +#else + memcpy(gps_status, _MAV_PAYLOAD(msg), 101); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_heartbeat.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_heartbeat.h new file mode 100644 index 000000000..0167f8801 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_heartbeat.h @@ -0,0 +1,251 @@ +// MESSAGE HEARTBEAT PACKING + +#define MAVLINK_MSG_ID_HEARTBEAT 0 + +typedef struct __mavlink_heartbeat_t { + uint32_t custom_mode; ///< A bitfield for use for autopilot-specific flags. + uint8_t type; ///< Type of the MAV (quadrotor, helicopter, etc., up to 15 types, defined in MAV_TYPE ENUM) + uint8_t autopilot; ///< Autopilot type / class. defined in MAV_AUTOPILOT ENUM + uint8_t base_mode; ///< System mode bitfield, see MAV_MODE_FLAGS ENUM in mavlink/include/mavlink_types.h + uint8_t system_status; ///< System status flag, see MAV_STATE ENUM + uint8_t mavlink_version; ///< MAVLink version, not writable by user, gets added by protocol because of magic data type: uint8_t_mavlink_version +} mavlink_heartbeat_t; + +#define MAVLINK_MSG_ID_HEARTBEAT_LEN 9 +#define MAVLINK_MSG_ID_0_LEN 9 + + +#define MAVLINK_MESSAGE_INFO_HEARTBEAT \ + { \ + "HEARTBEAT", \ + 6, \ + { \ + { "custom_mode", NULL, MAVLINK_TYPE_UINT32_T, 0, 0, offsetof(mavlink_heartbeat_t, custom_mode) }, \ + { "type", NULL, MAVLINK_TYPE_UINT8_T, 0, 4, offsetof(mavlink_heartbeat_t, type) }, \ + { "autopilot", NULL, MAVLINK_TYPE_UINT8_T, 0, 5, offsetof(mavlink_heartbeat_t, autopilot) }, \ + { "base_mode", NULL, MAVLINK_TYPE_UINT8_T, 0, 6, offsetof(mavlink_heartbeat_t, base_mode) }, \ + { "system_status", NULL, MAVLINK_TYPE_UINT8_T, 0, 7, offsetof(mavlink_heartbeat_t, system_status) }, \ + { "mavlink_version", NULL, MAVLINK_TYPE_UINT8_T, 0, 8, offsetof(mavlink_heartbeat_t, mavlink_version) }, \ + } \ + } + + +/** + * @brief Pack a heartbeat message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param type Type of the MAV (quadrotor, helicopter, etc., up to 15 types, defined in MAV_TYPE ENUM) + * @param autopilot Autopilot type / class. defined in MAV_AUTOPILOT ENUM + * @param base_mode System mode bitfield, see MAV_MODE_FLAGS ENUM in mavlink/include/mavlink_types.h + * @param custom_mode A bitfield for use for autopilot-specific flags. + * @param system_status System status flag, see MAV_STATE ENUM + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_heartbeat_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t type, uint8_t autopilot, uint8_t base_mode, uint32_t custom_mode, uint8_t system_status) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[9]; + _mav_put_uint32_t(buf, 0, custom_mode); + _mav_put_uint8_t(buf, 4, type); + _mav_put_uint8_t(buf, 5, autopilot); + _mav_put_uint8_t(buf, 6, base_mode); + _mav_put_uint8_t(buf, 7, system_status); + _mav_put_uint8_t(buf, 8, 3); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 9); +#else + mavlink_heartbeat_t packet; + packet.custom_mode = custom_mode; + packet.type = type; + packet.autopilot = autopilot; + packet.base_mode = base_mode; + packet.system_status = system_status; + packet.mavlink_version = 3; + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 9); + +#endif + + msg->msgid = MAVLINK_MSG_ID_HEARTBEAT; + return mavlink_finalize_message(msg, system_id, component_id, 9, 50); +} + +/** + * @brief Pack a heartbeat message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param type Type of the MAV (quadrotor, helicopter, etc., up to 15 types, defined in MAV_TYPE ENUM) + * @param autopilot Autopilot type / class. defined in MAV_AUTOPILOT ENUM + * @param base_mode System mode bitfield, see MAV_MODE_FLAGS ENUM in mavlink/include/mavlink_types.h + * @param custom_mode A bitfield for use for autopilot-specific flags. + * @param system_status System status flag, see MAV_STATE ENUM + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_heartbeat_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t type, uint8_t autopilot, uint8_t base_mode, uint32_t custom_mode, uint8_t system_status) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[9]; + _mav_put_uint32_t(buf, 0, custom_mode); + _mav_put_uint8_t(buf, 4, type); + _mav_put_uint8_t(buf, 5, autopilot); + _mav_put_uint8_t(buf, 6, base_mode); + _mav_put_uint8_t(buf, 7, system_status); + _mav_put_uint8_t(buf, 8, 3); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 9); +#else + mavlink_heartbeat_t packet; + packet.custom_mode = custom_mode; + packet.type = type; + packet.autopilot = autopilot; + packet.base_mode = base_mode; + packet.system_status = system_status; + packet.mavlink_version = 3; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 9); +#endif + + msg->msgid = MAVLINK_MSG_ID_HEARTBEAT; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 9, 50); +} + +/** + * @brief Encode a heartbeat struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param heartbeat C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_heartbeat_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_heartbeat_t *heartbeat) +{ + return mavlink_msg_heartbeat_pack(system_id, component_id, msg, heartbeat->type, heartbeat->autopilot, heartbeat->base_mode, heartbeat->custom_mode, heartbeat->system_status); +} + +/** + * @brief Send a heartbeat message + * @param chan MAVLink channel to send the message + * + * @param type Type of the MAV (quadrotor, helicopter, etc., up to 15 types, defined in MAV_TYPE ENUM) + * @param autopilot Autopilot type / class. defined in MAV_AUTOPILOT ENUM + * @param base_mode System mode bitfield, see MAV_MODE_FLAGS ENUM in mavlink/include/mavlink_types.h + * @param custom_mode A bitfield for use for autopilot-specific flags. + * @param system_status System status flag, see MAV_STATE ENUM + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_heartbeat_send(mavlink_channel_t chan, uint8_t type, uint8_t autopilot, uint8_t base_mode, uint32_t custom_mode, uint8_t system_status) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[9]; + _mav_put_uint32_t(buf, 0, custom_mode); + _mav_put_uint8_t(buf, 4, type); + _mav_put_uint8_t(buf, 5, autopilot); + _mav_put_uint8_t(buf, 6, base_mode); + _mav_put_uint8_t(buf, 7, system_status); + _mav_put_uint8_t(buf, 8, 3); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_HEARTBEAT, buf, 9, 50); +#else + mavlink_heartbeat_t packet; + packet.custom_mode = custom_mode; + packet.type = type; + packet.autopilot = autopilot; + packet.base_mode = base_mode; + packet.system_status = system_status; + packet.mavlink_version = 3; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_HEARTBEAT, (const char *)&packet, 9, 50); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE HEARTBEAT UNPACKING + + +/** + * @brief Get field type from heartbeat message + * + * @return Type of the MAV (quadrotor, helicopter, etc., up to 15 types, defined in MAV_TYPE ENUM) + */ +static inline uint8_t mavlink_msg_heartbeat_get_type(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 4); +} + +/** + * @brief Get field autopilot from heartbeat message + * + * @return Autopilot type / class. defined in MAV_AUTOPILOT ENUM + */ +static inline uint8_t mavlink_msg_heartbeat_get_autopilot(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 5); +} + +/** + * @brief Get field base_mode from heartbeat message + * + * @return System mode bitfield, see MAV_MODE_FLAGS ENUM in mavlink/include/mavlink_types.h + */ +static inline uint8_t mavlink_msg_heartbeat_get_base_mode(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 6); +} + +/** + * @brief Get field custom_mode from heartbeat message + * + * @return A bitfield for use for autopilot-specific flags. + */ +static inline uint32_t mavlink_msg_heartbeat_get_custom_mode(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint32_t(msg, 0); +} + +/** + * @brief Get field system_status from heartbeat message + * + * @return System status flag, see MAV_STATE ENUM + */ +static inline uint8_t mavlink_msg_heartbeat_get_system_status(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 7); +} + +/** + * @brief Get field mavlink_version from heartbeat message + * + * @return MAVLink version, not writable by user, gets added by protocol because of magic data type: uint8_t_mavlink_version + */ +static inline uint8_t mavlink_msg_heartbeat_get_mavlink_version(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 8); +} + +/** + * @brief Decode a heartbeat message into a struct + * + * @param msg The message to decode + * @param heartbeat C-struct to decode the message contents into + */ +static inline void mavlink_msg_heartbeat_decode(const mavlink_message_t *msg, mavlink_heartbeat_t *heartbeat) +{ +#if MAVLINK_NEED_BYTE_SWAP + heartbeat->custom_mode = mavlink_msg_heartbeat_get_custom_mode(msg); + heartbeat->type = mavlink_msg_heartbeat_get_type(msg); + heartbeat->autopilot = mavlink_msg_heartbeat_get_autopilot(msg); + heartbeat->base_mode = mavlink_msg_heartbeat_get_base_mode(msg); + heartbeat->system_status = mavlink_msg_heartbeat_get_system_status(msg); + heartbeat->mavlink_version = mavlink_msg_heartbeat_get_mavlink_version(msg); +#else + memcpy(heartbeat, _MAV_PAYLOAD(msg), 9); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_hil_controls.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_hil_controls.h new file mode 100644 index 000000000..1d2f7a8f3 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_hil_controls.h @@ -0,0 +1,364 @@ +// MESSAGE HIL_CONTROLS PACKING + +#define MAVLINK_MSG_ID_HIL_CONTROLS 91 + +typedef struct __mavlink_hil_controls_t { + uint64_t time_usec; ///< Timestamp (microseconds since UNIX epoch or microseconds since system boot) + float roll_ailerons; ///< Control output -1 .. 1 + float pitch_elevator; ///< Control output -1 .. 1 + float yaw_rudder; ///< Control output -1 .. 1 + float throttle; ///< Throttle 0 .. 1 + float aux1; ///< Aux 1, -1 .. 1 + float aux2; ///< Aux 2, -1 .. 1 + float aux3; ///< Aux 3, -1 .. 1 + float aux4; ///< Aux 4, -1 .. 1 + uint8_t mode; ///< System mode (MAV_MODE) + uint8_t nav_mode; ///< Navigation mode (MAV_NAV_MODE) +} mavlink_hil_controls_t; + +#define MAVLINK_MSG_ID_HIL_CONTROLS_LEN 42 +#define MAVLINK_MSG_ID_91_LEN 42 + + +#define MAVLINK_MESSAGE_INFO_HIL_CONTROLS \ + { \ + "HIL_CONTROLS", \ + 11, \ + { \ + { "time_usec", NULL, MAVLINK_TYPE_UINT64_T, 0, 0, offsetof(mavlink_hil_controls_t, time_usec) }, \ + { "roll_ailerons", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_hil_controls_t, roll_ailerons) }, \ + { "pitch_elevator", NULL, MAVLINK_TYPE_FLOAT, 0, 12, offsetof(mavlink_hil_controls_t, pitch_elevator) }, \ + { "yaw_rudder", NULL, MAVLINK_TYPE_FLOAT, 0, 16, offsetof(mavlink_hil_controls_t, yaw_rudder) }, \ + { "throttle", NULL, MAVLINK_TYPE_FLOAT, 0, 20, offsetof(mavlink_hil_controls_t, throttle) }, \ + { "aux1", NULL, MAVLINK_TYPE_FLOAT, 0, 24, offsetof(mavlink_hil_controls_t, aux1) }, \ + { "aux2", NULL, MAVLINK_TYPE_FLOAT, 0, 28, offsetof(mavlink_hil_controls_t, aux2) }, \ + { "aux3", NULL, MAVLINK_TYPE_FLOAT, 0, 32, offsetof(mavlink_hil_controls_t, aux3) }, \ + { "aux4", NULL, MAVLINK_TYPE_FLOAT, 0, 36, offsetof(mavlink_hil_controls_t, aux4) }, \ + { "mode", NULL, MAVLINK_TYPE_UINT8_T, 0, 40, offsetof(mavlink_hil_controls_t, mode) }, \ + { "nav_mode", NULL, MAVLINK_TYPE_UINT8_T, 0, 41, offsetof(mavlink_hil_controls_t, nav_mode) }, \ + } \ + } + + +/** + * @brief Pack a hil_controls message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param time_usec Timestamp (microseconds since UNIX epoch or microseconds since system boot) + * @param roll_ailerons Control output -1 .. 1 + * @param pitch_elevator Control output -1 .. 1 + * @param yaw_rudder Control output -1 .. 1 + * @param throttle Throttle 0 .. 1 + * @param aux1 Aux 1, -1 .. 1 + * @param aux2 Aux 2, -1 .. 1 + * @param aux3 Aux 3, -1 .. 1 + * @param aux4 Aux 4, -1 .. 1 + * @param mode System mode (MAV_MODE) + * @param nav_mode Navigation mode (MAV_NAV_MODE) + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_hil_controls_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint64_t time_usec, float roll_ailerons, float pitch_elevator, float yaw_rudder, float throttle, float aux1, float aux2, float aux3, float aux4, uint8_t mode, uint8_t nav_mode) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[42]; + _mav_put_uint64_t(buf, 0, time_usec); + _mav_put_float(buf, 8, roll_ailerons); + _mav_put_float(buf, 12, pitch_elevator); + _mav_put_float(buf, 16, yaw_rudder); + _mav_put_float(buf, 20, throttle); + _mav_put_float(buf, 24, aux1); + _mav_put_float(buf, 28, aux2); + _mav_put_float(buf, 32, aux3); + _mav_put_float(buf, 36, aux4); + _mav_put_uint8_t(buf, 40, mode); + _mav_put_uint8_t(buf, 41, nav_mode); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 42); +#else + mavlink_hil_controls_t packet; + packet.time_usec = time_usec; + packet.roll_ailerons = roll_ailerons; + packet.pitch_elevator = pitch_elevator; + packet.yaw_rudder = yaw_rudder; + packet.throttle = throttle; + packet.aux1 = aux1; + packet.aux2 = aux2; + packet.aux3 = aux3; + packet.aux4 = aux4; + packet.mode = mode; + packet.nav_mode = nav_mode; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 42); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_HIL_CONTROLS; + return mavlink_finalize_message(msg, system_id, component_id, 42, 63); +} + +/** + * @brief Pack a hil_controls message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param time_usec Timestamp (microseconds since UNIX epoch or microseconds since system boot) + * @param roll_ailerons Control output -1 .. 1 + * @param pitch_elevator Control output -1 .. 1 + * @param yaw_rudder Control output -1 .. 1 + * @param throttle Throttle 0 .. 1 + * @param aux1 Aux 1, -1 .. 1 + * @param aux2 Aux 2, -1 .. 1 + * @param aux3 Aux 3, -1 .. 1 + * @param aux4 Aux 4, -1 .. 1 + * @param mode System mode (MAV_MODE) + * @param nav_mode Navigation mode (MAV_NAV_MODE) + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_hil_controls_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint64_t time_usec, float roll_ailerons, float pitch_elevator, float yaw_rudder, float throttle, float aux1, float aux2, float aux3, float aux4, uint8_t mode, uint8_t nav_mode) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[42]; + _mav_put_uint64_t(buf, 0, time_usec); + _mav_put_float(buf, 8, roll_ailerons); + _mav_put_float(buf, 12, pitch_elevator); + _mav_put_float(buf, 16, yaw_rudder); + _mav_put_float(buf, 20, throttle); + _mav_put_float(buf, 24, aux1); + _mav_put_float(buf, 28, aux2); + _mav_put_float(buf, 32, aux3); + _mav_put_float(buf, 36, aux4); + _mav_put_uint8_t(buf, 40, mode); + _mav_put_uint8_t(buf, 41, nav_mode); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 42); +#else + mavlink_hil_controls_t packet; + packet.time_usec = time_usec; + packet.roll_ailerons = roll_ailerons; + packet.pitch_elevator = pitch_elevator; + packet.yaw_rudder = yaw_rudder; + packet.throttle = throttle; + packet.aux1 = aux1; + packet.aux2 = aux2; + packet.aux3 = aux3; + packet.aux4 = aux4; + packet.mode = mode; + packet.nav_mode = nav_mode; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 42); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_HIL_CONTROLS; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 42, 63); +} + +/** + * @brief Encode a hil_controls struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param hil_controls C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_hil_controls_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_hil_controls_t *hil_controls) +{ + return mavlink_msg_hil_controls_pack(system_id, component_id, msg, hil_controls->time_usec, hil_controls->roll_ailerons, hil_controls->pitch_elevator, hil_controls->yaw_rudder, hil_controls->throttle, hil_controls->aux1, hil_controls->aux2, hil_controls->aux3, hil_controls->aux4, hil_controls->mode, hil_controls->nav_mode); +} + +/** + * @brief Send a hil_controls message + * @param chan MAVLink channel to send the message + * + * @param time_usec Timestamp (microseconds since UNIX epoch or microseconds since system boot) + * @param roll_ailerons Control output -1 .. 1 + * @param pitch_elevator Control output -1 .. 1 + * @param yaw_rudder Control output -1 .. 1 + * @param throttle Throttle 0 .. 1 + * @param aux1 Aux 1, -1 .. 1 + * @param aux2 Aux 2, -1 .. 1 + * @param aux3 Aux 3, -1 .. 1 + * @param aux4 Aux 4, -1 .. 1 + * @param mode System mode (MAV_MODE) + * @param nav_mode Navigation mode (MAV_NAV_MODE) + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_hil_controls_send(mavlink_channel_t chan, uint64_t time_usec, float roll_ailerons, float pitch_elevator, float yaw_rudder, float throttle, float aux1, float aux2, float aux3, float aux4, uint8_t mode, uint8_t nav_mode) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[42]; + _mav_put_uint64_t(buf, 0, time_usec); + _mav_put_float(buf, 8, roll_ailerons); + _mav_put_float(buf, 12, pitch_elevator); + _mav_put_float(buf, 16, yaw_rudder); + _mav_put_float(buf, 20, throttle); + _mav_put_float(buf, 24, aux1); + _mav_put_float(buf, 28, aux2); + _mav_put_float(buf, 32, aux3); + _mav_put_float(buf, 36, aux4); + _mav_put_uint8_t(buf, 40, mode); + _mav_put_uint8_t(buf, 41, nav_mode); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_HIL_CONTROLS, buf, 42, 63); +#else + mavlink_hil_controls_t packet; + packet.time_usec = time_usec; + packet.roll_ailerons = roll_ailerons; + packet.pitch_elevator = pitch_elevator; + packet.yaw_rudder = yaw_rudder; + packet.throttle = throttle; + packet.aux1 = aux1; + packet.aux2 = aux2; + packet.aux3 = aux3; + packet.aux4 = aux4; + packet.mode = mode; + packet.nav_mode = nav_mode; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_HIL_CONTROLS, (const char *)&packet, 42, 63); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE HIL_CONTROLS UNPACKING + + +/** + * @brief Get field time_usec from hil_controls message + * + * @return Timestamp (microseconds since UNIX epoch or microseconds since system boot) + */ +static inline uint64_t mavlink_msg_hil_controls_get_time_usec(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint64_t(msg, 0); +} + +/** + * @brief Get field roll_ailerons from hil_controls message + * + * @return Control output -1 .. 1 + */ +static inline float mavlink_msg_hil_controls_get_roll_ailerons(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 8); +} + +/** + * @brief Get field pitch_elevator from hil_controls message + * + * @return Control output -1 .. 1 + */ +static inline float mavlink_msg_hil_controls_get_pitch_elevator(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 12); +} + +/** + * @brief Get field yaw_rudder from hil_controls message + * + * @return Control output -1 .. 1 + */ +static inline float mavlink_msg_hil_controls_get_yaw_rudder(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 16); +} + +/** + * @brief Get field throttle from hil_controls message + * + * @return Throttle 0 .. 1 + */ +static inline float mavlink_msg_hil_controls_get_throttle(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 20); +} + +/** + * @brief Get field aux1 from hil_controls message + * + * @return Aux 1, -1 .. 1 + */ +static inline float mavlink_msg_hil_controls_get_aux1(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 24); +} + +/** + * @brief Get field aux2 from hil_controls message + * + * @return Aux 2, -1 .. 1 + */ +static inline float mavlink_msg_hil_controls_get_aux2(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 28); +} + +/** + * @brief Get field aux3 from hil_controls message + * + * @return Aux 3, -1 .. 1 + */ +static inline float mavlink_msg_hil_controls_get_aux3(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 32); +} + +/** + * @brief Get field aux4 from hil_controls message + * + * @return Aux 4, -1 .. 1 + */ +static inline float mavlink_msg_hil_controls_get_aux4(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 36); +} + +/** + * @brief Get field mode from hil_controls message + * + * @return System mode (MAV_MODE) + */ +static inline uint8_t mavlink_msg_hil_controls_get_mode(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 40); +} + +/** + * @brief Get field nav_mode from hil_controls message + * + * @return Navigation mode (MAV_NAV_MODE) + */ +static inline uint8_t mavlink_msg_hil_controls_get_nav_mode(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 41); +} + +/** + * @brief Decode a hil_controls message into a struct + * + * @param msg The message to decode + * @param hil_controls C-struct to decode the message contents into + */ +static inline void mavlink_msg_hil_controls_decode(const mavlink_message_t *msg, mavlink_hil_controls_t *hil_controls) +{ +#if MAVLINK_NEED_BYTE_SWAP + hil_controls->time_usec = mavlink_msg_hil_controls_get_time_usec(msg); + hil_controls->roll_ailerons = mavlink_msg_hil_controls_get_roll_ailerons(msg); + hil_controls->pitch_elevator = mavlink_msg_hil_controls_get_pitch_elevator(msg); + hil_controls->yaw_rudder = mavlink_msg_hil_controls_get_yaw_rudder(msg); + hil_controls->throttle = mavlink_msg_hil_controls_get_throttle(msg); + hil_controls->aux1 = mavlink_msg_hil_controls_get_aux1(msg); + hil_controls->aux2 = mavlink_msg_hil_controls_get_aux2(msg); + hil_controls->aux3 = mavlink_msg_hil_controls_get_aux3(msg); + hil_controls->aux4 = mavlink_msg_hil_controls_get_aux4(msg); + hil_controls->mode = mavlink_msg_hil_controls_get_mode(msg); + hil_controls->nav_mode = mavlink_msg_hil_controls_get_nav_mode(msg); +#else + memcpy(hil_controls, _MAV_PAYLOAD(msg), 42); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_hil_rc_inputs_raw.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_hil_rc_inputs_raw.h new file mode 100644 index 000000000..107dc9441 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_hil_rc_inputs_raw.h @@ -0,0 +1,430 @@ +// MESSAGE HIL_RC_INPUTS_RAW PACKING + +#define MAVLINK_MSG_ID_HIL_RC_INPUTS_RAW 92 + +typedef struct __mavlink_hil_rc_inputs_raw_t { + uint64_t time_usec; ///< Timestamp (microseconds since UNIX epoch or microseconds since system boot) + uint16_t chan1_raw; ///< RC channel 1 value, in microseconds + uint16_t chan2_raw; ///< RC channel 2 value, in microseconds + uint16_t chan3_raw; ///< RC channel 3 value, in microseconds + uint16_t chan4_raw; ///< RC channel 4 value, in microseconds + uint16_t chan5_raw; ///< RC channel 5 value, in microseconds + uint16_t chan6_raw; ///< RC channel 6 value, in microseconds + uint16_t chan7_raw; ///< RC channel 7 value, in microseconds + uint16_t chan8_raw; ///< RC channel 8 value, in microseconds + uint16_t chan9_raw; ///< RC channel 9 value, in microseconds + uint16_t chan10_raw; ///< RC channel 10 value, in microseconds + uint16_t chan11_raw; ///< RC channel 11 value, in microseconds + uint16_t chan12_raw; ///< RC channel 12 value, in microseconds + uint8_t rssi; ///< Receive signal strength indicator, 0: 0%, 255: 100% +} mavlink_hil_rc_inputs_raw_t; + +#define MAVLINK_MSG_ID_HIL_RC_INPUTS_RAW_LEN 33 +#define MAVLINK_MSG_ID_92_LEN 33 + + +#define MAVLINK_MESSAGE_INFO_HIL_RC_INPUTS_RAW \ + { \ + "HIL_RC_INPUTS_RAW", \ + 14, \ + { \ + { "time_usec", NULL, MAVLINK_TYPE_UINT64_T, 0, 0, offsetof(mavlink_hil_rc_inputs_raw_t, time_usec) }, \ + { "chan1_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 8, offsetof(mavlink_hil_rc_inputs_raw_t, chan1_raw) }, \ + { "chan2_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 10, offsetof(mavlink_hil_rc_inputs_raw_t, chan2_raw) }, \ + { "chan3_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 12, offsetof(mavlink_hil_rc_inputs_raw_t, chan3_raw) }, \ + { "chan4_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 14, offsetof(mavlink_hil_rc_inputs_raw_t, chan4_raw) }, \ + { "chan5_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 16, offsetof(mavlink_hil_rc_inputs_raw_t, chan5_raw) }, \ + { "chan6_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 18, offsetof(mavlink_hil_rc_inputs_raw_t, chan6_raw) }, \ + { "chan7_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 20, offsetof(mavlink_hil_rc_inputs_raw_t, chan7_raw) }, \ + { "chan8_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 22, offsetof(mavlink_hil_rc_inputs_raw_t, chan8_raw) }, \ + { "chan9_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 24, offsetof(mavlink_hil_rc_inputs_raw_t, chan9_raw) }, \ + { "chan10_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 26, offsetof(mavlink_hil_rc_inputs_raw_t, chan10_raw) }, \ + { "chan11_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 28, offsetof(mavlink_hil_rc_inputs_raw_t, chan11_raw) }, \ + { "chan12_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 30, offsetof(mavlink_hil_rc_inputs_raw_t, chan12_raw) }, \ + { "rssi", NULL, MAVLINK_TYPE_UINT8_T, 0, 32, offsetof(mavlink_hil_rc_inputs_raw_t, rssi) }, \ + } \ + } + + +/** + * @brief Pack a hil_rc_inputs_raw message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param time_usec Timestamp (microseconds since UNIX epoch or microseconds since system boot) + * @param chan1_raw RC channel 1 value, in microseconds + * @param chan2_raw RC channel 2 value, in microseconds + * @param chan3_raw RC channel 3 value, in microseconds + * @param chan4_raw RC channel 4 value, in microseconds + * @param chan5_raw RC channel 5 value, in microseconds + * @param chan6_raw RC channel 6 value, in microseconds + * @param chan7_raw RC channel 7 value, in microseconds + * @param chan8_raw RC channel 8 value, in microseconds + * @param chan9_raw RC channel 9 value, in microseconds + * @param chan10_raw RC channel 10 value, in microseconds + * @param chan11_raw RC channel 11 value, in microseconds + * @param chan12_raw RC channel 12 value, in microseconds + * @param rssi Receive signal strength indicator, 0: 0%, 255: 100% + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_hil_rc_inputs_raw_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint64_t time_usec, uint16_t chan1_raw, uint16_t chan2_raw, uint16_t chan3_raw, uint16_t chan4_raw, uint16_t chan5_raw, uint16_t chan6_raw, uint16_t chan7_raw, uint16_t chan8_raw, uint16_t chan9_raw, uint16_t chan10_raw, uint16_t chan11_raw, uint16_t chan12_raw, uint8_t rssi) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[33]; + _mav_put_uint64_t(buf, 0, time_usec); + _mav_put_uint16_t(buf, 8, chan1_raw); + _mav_put_uint16_t(buf, 10, chan2_raw); + _mav_put_uint16_t(buf, 12, chan3_raw); + _mav_put_uint16_t(buf, 14, chan4_raw); + _mav_put_uint16_t(buf, 16, chan5_raw); + _mav_put_uint16_t(buf, 18, chan6_raw); + _mav_put_uint16_t(buf, 20, chan7_raw); + _mav_put_uint16_t(buf, 22, chan8_raw); + _mav_put_uint16_t(buf, 24, chan9_raw); + _mav_put_uint16_t(buf, 26, chan10_raw); + _mav_put_uint16_t(buf, 28, chan11_raw); + _mav_put_uint16_t(buf, 30, chan12_raw); + _mav_put_uint8_t(buf, 32, rssi); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 33); +#else + mavlink_hil_rc_inputs_raw_t packet; + packet.time_usec = time_usec; + packet.chan1_raw = chan1_raw; + packet.chan2_raw = chan2_raw; + packet.chan3_raw = chan3_raw; + packet.chan4_raw = chan4_raw; + packet.chan5_raw = chan5_raw; + packet.chan6_raw = chan6_raw; + packet.chan7_raw = chan7_raw; + packet.chan8_raw = chan8_raw; + packet.chan9_raw = chan9_raw; + packet.chan10_raw = chan10_raw; + packet.chan11_raw = chan11_raw; + packet.chan12_raw = chan12_raw; + packet.rssi = rssi; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 33); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_HIL_RC_INPUTS_RAW; + return mavlink_finalize_message(msg, system_id, component_id, 33, 54); +} + +/** + * @brief Pack a hil_rc_inputs_raw message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param time_usec Timestamp (microseconds since UNIX epoch or microseconds since system boot) + * @param chan1_raw RC channel 1 value, in microseconds + * @param chan2_raw RC channel 2 value, in microseconds + * @param chan3_raw RC channel 3 value, in microseconds + * @param chan4_raw RC channel 4 value, in microseconds + * @param chan5_raw RC channel 5 value, in microseconds + * @param chan6_raw RC channel 6 value, in microseconds + * @param chan7_raw RC channel 7 value, in microseconds + * @param chan8_raw RC channel 8 value, in microseconds + * @param chan9_raw RC channel 9 value, in microseconds + * @param chan10_raw RC channel 10 value, in microseconds + * @param chan11_raw RC channel 11 value, in microseconds + * @param chan12_raw RC channel 12 value, in microseconds + * @param rssi Receive signal strength indicator, 0: 0%, 255: 100% + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_hil_rc_inputs_raw_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint64_t time_usec, uint16_t chan1_raw, uint16_t chan2_raw, uint16_t chan3_raw, uint16_t chan4_raw, uint16_t chan5_raw, uint16_t chan6_raw, uint16_t chan7_raw, uint16_t chan8_raw, uint16_t chan9_raw, uint16_t chan10_raw, uint16_t chan11_raw, uint16_t chan12_raw, uint8_t rssi) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[33]; + _mav_put_uint64_t(buf, 0, time_usec); + _mav_put_uint16_t(buf, 8, chan1_raw); + _mav_put_uint16_t(buf, 10, chan2_raw); + _mav_put_uint16_t(buf, 12, chan3_raw); + _mav_put_uint16_t(buf, 14, chan4_raw); + _mav_put_uint16_t(buf, 16, chan5_raw); + _mav_put_uint16_t(buf, 18, chan6_raw); + _mav_put_uint16_t(buf, 20, chan7_raw); + _mav_put_uint16_t(buf, 22, chan8_raw); + _mav_put_uint16_t(buf, 24, chan9_raw); + _mav_put_uint16_t(buf, 26, chan10_raw); + _mav_put_uint16_t(buf, 28, chan11_raw); + _mav_put_uint16_t(buf, 30, chan12_raw); + _mav_put_uint8_t(buf, 32, rssi); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 33); +#else + mavlink_hil_rc_inputs_raw_t packet; + packet.time_usec = time_usec; + packet.chan1_raw = chan1_raw; + packet.chan2_raw = chan2_raw; + packet.chan3_raw = chan3_raw; + packet.chan4_raw = chan4_raw; + packet.chan5_raw = chan5_raw; + packet.chan6_raw = chan6_raw; + packet.chan7_raw = chan7_raw; + packet.chan8_raw = chan8_raw; + packet.chan9_raw = chan9_raw; + packet.chan10_raw = chan10_raw; + packet.chan11_raw = chan11_raw; + packet.chan12_raw = chan12_raw; + packet.rssi = rssi; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 33); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_HIL_RC_INPUTS_RAW; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 33, 54); +} + +/** + * @brief Encode a hil_rc_inputs_raw struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param hil_rc_inputs_raw C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_hil_rc_inputs_raw_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_hil_rc_inputs_raw_t *hil_rc_inputs_raw) +{ + return mavlink_msg_hil_rc_inputs_raw_pack(system_id, component_id, msg, hil_rc_inputs_raw->time_usec, hil_rc_inputs_raw->chan1_raw, hil_rc_inputs_raw->chan2_raw, hil_rc_inputs_raw->chan3_raw, hil_rc_inputs_raw->chan4_raw, hil_rc_inputs_raw->chan5_raw, hil_rc_inputs_raw->chan6_raw, hil_rc_inputs_raw->chan7_raw, hil_rc_inputs_raw->chan8_raw, hil_rc_inputs_raw->chan9_raw, hil_rc_inputs_raw->chan10_raw, hil_rc_inputs_raw->chan11_raw, hil_rc_inputs_raw->chan12_raw, hil_rc_inputs_raw->rssi); +} + +/** + * @brief Send a hil_rc_inputs_raw message + * @param chan MAVLink channel to send the message + * + * @param time_usec Timestamp (microseconds since UNIX epoch or microseconds since system boot) + * @param chan1_raw RC channel 1 value, in microseconds + * @param chan2_raw RC channel 2 value, in microseconds + * @param chan3_raw RC channel 3 value, in microseconds + * @param chan4_raw RC channel 4 value, in microseconds + * @param chan5_raw RC channel 5 value, in microseconds + * @param chan6_raw RC channel 6 value, in microseconds + * @param chan7_raw RC channel 7 value, in microseconds + * @param chan8_raw RC channel 8 value, in microseconds + * @param chan9_raw RC channel 9 value, in microseconds + * @param chan10_raw RC channel 10 value, in microseconds + * @param chan11_raw RC channel 11 value, in microseconds + * @param chan12_raw RC channel 12 value, in microseconds + * @param rssi Receive signal strength indicator, 0: 0%, 255: 100% + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_hil_rc_inputs_raw_send(mavlink_channel_t chan, uint64_t time_usec, uint16_t chan1_raw, uint16_t chan2_raw, uint16_t chan3_raw, uint16_t chan4_raw, uint16_t chan5_raw, uint16_t chan6_raw, uint16_t chan7_raw, uint16_t chan8_raw, uint16_t chan9_raw, uint16_t chan10_raw, uint16_t chan11_raw, uint16_t chan12_raw, uint8_t rssi) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[33]; + _mav_put_uint64_t(buf, 0, time_usec); + _mav_put_uint16_t(buf, 8, chan1_raw); + _mav_put_uint16_t(buf, 10, chan2_raw); + _mav_put_uint16_t(buf, 12, chan3_raw); + _mav_put_uint16_t(buf, 14, chan4_raw); + _mav_put_uint16_t(buf, 16, chan5_raw); + _mav_put_uint16_t(buf, 18, chan6_raw); + _mav_put_uint16_t(buf, 20, chan7_raw); + _mav_put_uint16_t(buf, 22, chan8_raw); + _mav_put_uint16_t(buf, 24, chan9_raw); + _mav_put_uint16_t(buf, 26, chan10_raw); + _mav_put_uint16_t(buf, 28, chan11_raw); + _mav_put_uint16_t(buf, 30, chan12_raw); + _mav_put_uint8_t(buf, 32, rssi); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_HIL_RC_INPUTS_RAW, buf, 33, 54); +#else + mavlink_hil_rc_inputs_raw_t packet; + packet.time_usec = time_usec; + packet.chan1_raw = chan1_raw; + packet.chan2_raw = chan2_raw; + packet.chan3_raw = chan3_raw; + packet.chan4_raw = chan4_raw; + packet.chan5_raw = chan5_raw; + packet.chan6_raw = chan6_raw; + packet.chan7_raw = chan7_raw; + packet.chan8_raw = chan8_raw; + packet.chan9_raw = chan9_raw; + packet.chan10_raw = chan10_raw; + packet.chan11_raw = chan11_raw; + packet.chan12_raw = chan12_raw; + packet.rssi = rssi; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_HIL_RC_INPUTS_RAW, (const char *)&packet, 33, 54); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE HIL_RC_INPUTS_RAW UNPACKING + + +/** + * @brief Get field time_usec from hil_rc_inputs_raw message + * + * @return Timestamp (microseconds since UNIX epoch or microseconds since system boot) + */ +static inline uint64_t mavlink_msg_hil_rc_inputs_raw_get_time_usec(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint64_t(msg, 0); +} + +/** + * @brief Get field chan1_raw from hil_rc_inputs_raw message + * + * @return RC channel 1 value, in microseconds + */ +static inline uint16_t mavlink_msg_hil_rc_inputs_raw_get_chan1_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 8); +} + +/** + * @brief Get field chan2_raw from hil_rc_inputs_raw message + * + * @return RC channel 2 value, in microseconds + */ +static inline uint16_t mavlink_msg_hil_rc_inputs_raw_get_chan2_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 10); +} + +/** + * @brief Get field chan3_raw from hil_rc_inputs_raw message + * + * @return RC channel 3 value, in microseconds + */ +static inline uint16_t mavlink_msg_hil_rc_inputs_raw_get_chan3_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 12); +} + +/** + * @brief Get field chan4_raw from hil_rc_inputs_raw message + * + * @return RC channel 4 value, in microseconds + */ +static inline uint16_t mavlink_msg_hil_rc_inputs_raw_get_chan4_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 14); +} + +/** + * @brief Get field chan5_raw from hil_rc_inputs_raw message + * + * @return RC channel 5 value, in microseconds + */ +static inline uint16_t mavlink_msg_hil_rc_inputs_raw_get_chan5_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 16); +} + +/** + * @brief Get field chan6_raw from hil_rc_inputs_raw message + * + * @return RC channel 6 value, in microseconds + */ +static inline uint16_t mavlink_msg_hil_rc_inputs_raw_get_chan6_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 18); +} + +/** + * @brief Get field chan7_raw from hil_rc_inputs_raw message + * + * @return RC channel 7 value, in microseconds + */ +static inline uint16_t mavlink_msg_hil_rc_inputs_raw_get_chan7_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 20); +} + +/** + * @brief Get field chan8_raw from hil_rc_inputs_raw message + * + * @return RC channel 8 value, in microseconds + */ +static inline uint16_t mavlink_msg_hil_rc_inputs_raw_get_chan8_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 22); +} + +/** + * @brief Get field chan9_raw from hil_rc_inputs_raw message + * + * @return RC channel 9 value, in microseconds + */ +static inline uint16_t mavlink_msg_hil_rc_inputs_raw_get_chan9_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 24); +} + +/** + * @brief Get field chan10_raw from hil_rc_inputs_raw message + * + * @return RC channel 10 value, in microseconds + */ +static inline uint16_t mavlink_msg_hil_rc_inputs_raw_get_chan10_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 26); +} + +/** + * @brief Get field chan11_raw from hil_rc_inputs_raw message + * + * @return RC channel 11 value, in microseconds + */ +static inline uint16_t mavlink_msg_hil_rc_inputs_raw_get_chan11_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 28); +} + +/** + * @brief Get field chan12_raw from hil_rc_inputs_raw message + * + * @return RC channel 12 value, in microseconds + */ +static inline uint16_t mavlink_msg_hil_rc_inputs_raw_get_chan12_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 30); +} + +/** + * @brief Get field rssi from hil_rc_inputs_raw message + * + * @return Receive signal strength indicator, 0: 0%, 255: 100% + */ +static inline uint8_t mavlink_msg_hil_rc_inputs_raw_get_rssi(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 32); +} + +/** + * @brief Decode a hil_rc_inputs_raw message into a struct + * + * @param msg The message to decode + * @param hil_rc_inputs_raw C-struct to decode the message contents into + */ +static inline void mavlink_msg_hil_rc_inputs_raw_decode(const mavlink_message_t *msg, mavlink_hil_rc_inputs_raw_t *hil_rc_inputs_raw) +{ +#if MAVLINK_NEED_BYTE_SWAP + hil_rc_inputs_raw->time_usec = mavlink_msg_hil_rc_inputs_raw_get_time_usec(msg); + hil_rc_inputs_raw->chan1_raw = mavlink_msg_hil_rc_inputs_raw_get_chan1_raw(msg); + hil_rc_inputs_raw->chan2_raw = mavlink_msg_hil_rc_inputs_raw_get_chan2_raw(msg); + hil_rc_inputs_raw->chan3_raw = mavlink_msg_hil_rc_inputs_raw_get_chan3_raw(msg); + hil_rc_inputs_raw->chan4_raw = mavlink_msg_hil_rc_inputs_raw_get_chan4_raw(msg); + hil_rc_inputs_raw->chan5_raw = mavlink_msg_hil_rc_inputs_raw_get_chan5_raw(msg); + hil_rc_inputs_raw->chan6_raw = mavlink_msg_hil_rc_inputs_raw_get_chan6_raw(msg); + hil_rc_inputs_raw->chan7_raw = mavlink_msg_hil_rc_inputs_raw_get_chan7_raw(msg); + hil_rc_inputs_raw->chan8_raw = mavlink_msg_hil_rc_inputs_raw_get_chan8_raw(msg); + hil_rc_inputs_raw->chan9_raw = mavlink_msg_hil_rc_inputs_raw_get_chan9_raw(msg); + hil_rc_inputs_raw->chan10_raw = mavlink_msg_hil_rc_inputs_raw_get_chan10_raw(msg); + hil_rc_inputs_raw->chan11_raw = mavlink_msg_hil_rc_inputs_raw_get_chan11_raw(msg); + hil_rc_inputs_raw->chan12_raw = mavlink_msg_hil_rc_inputs_raw_get_chan12_raw(msg); + hil_rc_inputs_raw->rssi = mavlink_msg_hil_rc_inputs_raw_get_rssi(msg); +#else + memcpy(hil_rc_inputs_raw, _MAV_PAYLOAD(msg), 33); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_hil_state.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_hil_state.h new file mode 100644 index 000000000..58036037d --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_hil_state.h @@ -0,0 +1,474 @@ +// MESSAGE HIL_STATE PACKING + +#define MAVLINK_MSG_ID_HIL_STATE 90 + +typedef struct __mavlink_hil_state_t { + uint64_t time_usec; ///< Timestamp (microseconds since UNIX epoch or microseconds since system boot) + float roll; ///< Roll angle (rad) + float pitch; ///< Pitch angle (rad) + float yaw; ///< Yaw angle (rad) + float rollspeed; ///< Roll angular speed (rad/s) + float pitchspeed; ///< Pitch angular speed (rad/s) + float yawspeed; ///< Yaw angular speed (rad/s) + int32_t lat; ///< Latitude, expressed as * 1E7 + int32_t lon; ///< Longitude, expressed as * 1E7 + int32_t alt; ///< Altitude in meters, expressed as * 1000 (millimeters) + int16_t vx; ///< Ground X Speed (Latitude), expressed as m/s * 100 + int16_t vy; ///< Ground Y Speed (Longitude), expressed as m/s * 100 + int16_t vz; ///< Ground Z Speed (Altitude), expressed as m/s * 100 + int16_t xacc; ///< X acceleration (mg) + int16_t yacc; ///< Y acceleration (mg) + int16_t zacc; ///< Z acceleration (mg) +} mavlink_hil_state_t; + +#define MAVLINK_MSG_ID_HIL_STATE_LEN 56 +#define MAVLINK_MSG_ID_90_LEN 56 + + +#define MAVLINK_MESSAGE_INFO_HIL_STATE \ + { \ + "HIL_STATE", \ + 16, \ + { \ + { "time_usec", NULL, MAVLINK_TYPE_UINT64_T, 0, 0, offsetof(mavlink_hil_state_t, time_usec) }, \ + { "roll", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_hil_state_t, roll) }, \ + { "pitch", NULL, MAVLINK_TYPE_FLOAT, 0, 12, offsetof(mavlink_hil_state_t, pitch) }, \ + { "yaw", NULL, MAVLINK_TYPE_FLOAT, 0, 16, offsetof(mavlink_hil_state_t, yaw) }, \ + { "rollspeed", NULL, MAVLINK_TYPE_FLOAT, 0, 20, offsetof(mavlink_hil_state_t, rollspeed) }, \ + { "pitchspeed", NULL, MAVLINK_TYPE_FLOAT, 0, 24, offsetof(mavlink_hil_state_t, pitchspeed) }, \ + { "yawspeed", NULL, MAVLINK_TYPE_FLOAT, 0, 28, offsetof(mavlink_hil_state_t, yawspeed) }, \ + { "lat", NULL, MAVLINK_TYPE_INT32_T, 0, 32, offsetof(mavlink_hil_state_t, lat) }, \ + { "lon", NULL, MAVLINK_TYPE_INT32_T, 0, 36, offsetof(mavlink_hil_state_t, lon) }, \ + { "alt", NULL, MAVLINK_TYPE_INT32_T, 0, 40, offsetof(mavlink_hil_state_t, alt) }, \ + { "vx", NULL, MAVLINK_TYPE_INT16_T, 0, 44, offsetof(mavlink_hil_state_t, vx) }, \ + { "vy", NULL, MAVLINK_TYPE_INT16_T, 0, 46, offsetof(mavlink_hil_state_t, vy) }, \ + { "vz", NULL, MAVLINK_TYPE_INT16_T, 0, 48, offsetof(mavlink_hil_state_t, vz) }, \ + { "xacc", NULL, MAVLINK_TYPE_INT16_T, 0, 50, offsetof(mavlink_hil_state_t, xacc) }, \ + { "yacc", NULL, MAVLINK_TYPE_INT16_T, 0, 52, offsetof(mavlink_hil_state_t, yacc) }, \ + { "zacc", NULL, MAVLINK_TYPE_INT16_T, 0, 54, offsetof(mavlink_hil_state_t, zacc) }, \ + } \ + } + + +/** + * @brief Pack a hil_state message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param time_usec Timestamp (microseconds since UNIX epoch or microseconds since system boot) + * @param roll Roll angle (rad) + * @param pitch Pitch angle (rad) + * @param yaw Yaw angle (rad) + * @param rollspeed Roll angular speed (rad/s) + * @param pitchspeed Pitch angular speed (rad/s) + * @param yawspeed Yaw angular speed (rad/s) + * @param lat Latitude, expressed as * 1E7 + * @param lon Longitude, expressed as * 1E7 + * @param alt Altitude in meters, expressed as * 1000 (millimeters) + * @param vx Ground X Speed (Latitude), expressed as m/s * 100 + * @param vy Ground Y Speed (Longitude), expressed as m/s * 100 + * @param vz Ground Z Speed (Altitude), expressed as m/s * 100 + * @param xacc X acceleration (mg) + * @param yacc Y acceleration (mg) + * @param zacc Z acceleration (mg) + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_hil_state_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint64_t time_usec, float roll, float pitch, float yaw, float rollspeed, float pitchspeed, float yawspeed, int32_t lat, int32_t lon, int32_t alt, int16_t vx, int16_t vy, int16_t vz, int16_t xacc, int16_t yacc, int16_t zacc) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[56]; + _mav_put_uint64_t(buf, 0, time_usec); + _mav_put_float(buf, 8, roll); + _mav_put_float(buf, 12, pitch); + _mav_put_float(buf, 16, yaw); + _mav_put_float(buf, 20, rollspeed); + _mav_put_float(buf, 24, pitchspeed); + _mav_put_float(buf, 28, yawspeed); + _mav_put_int32_t(buf, 32, lat); + _mav_put_int32_t(buf, 36, lon); + _mav_put_int32_t(buf, 40, alt); + _mav_put_int16_t(buf, 44, vx); + _mav_put_int16_t(buf, 46, vy); + _mav_put_int16_t(buf, 48, vz); + _mav_put_int16_t(buf, 50, xacc); + _mav_put_int16_t(buf, 52, yacc); + _mav_put_int16_t(buf, 54, zacc); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 56); +#else + mavlink_hil_state_t packet; + packet.time_usec = time_usec; + packet.roll = roll; + packet.pitch = pitch; + packet.yaw = yaw; + packet.rollspeed = rollspeed; + packet.pitchspeed = pitchspeed; + packet.yawspeed = yawspeed; + packet.lat = lat; + packet.lon = lon; + packet.alt = alt; + packet.vx = vx; + packet.vy = vy; + packet.vz = vz; + packet.xacc = xacc; + packet.yacc = yacc; + packet.zacc = zacc; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 56); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_HIL_STATE; + return mavlink_finalize_message(msg, system_id, component_id, 56, 183); +} + +/** + * @brief Pack a hil_state message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param time_usec Timestamp (microseconds since UNIX epoch or microseconds since system boot) + * @param roll Roll angle (rad) + * @param pitch Pitch angle (rad) + * @param yaw Yaw angle (rad) + * @param rollspeed Roll angular speed (rad/s) + * @param pitchspeed Pitch angular speed (rad/s) + * @param yawspeed Yaw angular speed (rad/s) + * @param lat Latitude, expressed as * 1E7 + * @param lon Longitude, expressed as * 1E7 + * @param alt Altitude in meters, expressed as * 1000 (millimeters) + * @param vx Ground X Speed (Latitude), expressed as m/s * 100 + * @param vy Ground Y Speed (Longitude), expressed as m/s * 100 + * @param vz Ground Z Speed (Altitude), expressed as m/s * 100 + * @param xacc X acceleration (mg) + * @param yacc Y acceleration (mg) + * @param zacc Z acceleration (mg) + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_hil_state_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint64_t time_usec, float roll, float pitch, float yaw, float rollspeed, float pitchspeed, float yawspeed, int32_t lat, int32_t lon, int32_t alt, int16_t vx, int16_t vy, int16_t vz, int16_t xacc, int16_t yacc, int16_t zacc) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[56]; + _mav_put_uint64_t(buf, 0, time_usec); + _mav_put_float(buf, 8, roll); + _mav_put_float(buf, 12, pitch); + _mav_put_float(buf, 16, yaw); + _mav_put_float(buf, 20, rollspeed); + _mav_put_float(buf, 24, pitchspeed); + _mav_put_float(buf, 28, yawspeed); + _mav_put_int32_t(buf, 32, lat); + _mav_put_int32_t(buf, 36, lon); + _mav_put_int32_t(buf, 40, alt); + _mav_put_int16_t(buf, 44, vx); + _mav_put_int16_t(buf, 46, vy); + _mav_put_int16_t(buf, 48, vz); + _mav_put_int16_t(buf, 50, xacc); + _mav_put_int16_t(buf, 52, yacc); + _mav_put_int16_t(buf, 54, zacc); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 56); +#else + mavlink_hil_state_t packet; + packet.time_usec = time_usec; + packet.roll = roll; + packet.pitch = pitch; + packet.yaw = yaw; + packet.rollspeed = rollspeed; + packet.pitchspeed = pitchspeed; + packet.yawspeed = yawspeed; + packet.lat = lat; + packet.lon = lon; + packet.alt = alt; + packet.vx = vx; + packet.vy = vy; + packet.vz = vz; + packet.xacc = xacc; + packet.yacc = yacc; + packet.zacc = zacc; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 56); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_HIL_STATE; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 56, 183); +} + +/** + * @brief Encode a hil_state struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param hil_state C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_hil_state_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_hil_state_t *hil_state) +{ + return mavlink_msg_hil_state_pack(system_id, component_id, msg, hil_state->time_usec, hil_state->roll, hil_state->pitch, hil_state->yaw, hil_state->rollspeed, hil_state->pitchspeed, hil_state->yawspeed, hil_state->lat, hil_state->lon, hil_state->alt, hil_state->vx, hil_state->vy, hil_state->vz, hil_state->xacc, hil_state->yacc, hil_state->zacc); +} + +/** + * @brief Send a hil_state message + * @param chan MAVLink channel to send the message + * + * @param time_usec Timestamp (microseconds since UNIX epoch or microseconds since system boot) + * @param roll Roll angle (rad) + * @param pitch Pitch angle (rad) + * @param yaw Yaw angle (rad) + * @param rollspeed Roll angular speed (rad/s) + * @param pitchspeed Pitch angular speed (rad/s) + * @param yawspeed Yaw angular speed (rad/s) + * @param lat Latitude, expressed as * 1E7 + * @param lon Longitude, expressed as * 1E7 + * @param alt Altitude in meters, expressed as * 1000 (millimeters) + * @param vx Ground X Speed (Latitude), expressed as m/s * 100 + * @param vy Ground Y Speed (Longitude), expressed as m/s * 100 + * @param vz Ground Z Speed (Altitude), expressed as m/s * 100 + * @param xacc X acceleration (mg) + * @param yacc Y acceleration (mg) + * @param zacc Z acceleration (mg) + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_hil_state_send(mavlink_channel_t chan, uint64_t time_usec, float roll, float pitch, float yaw, float rollspeed, float pitchspeed, float yawspeed, int32_t lat, int32_t lon, int32_t alt, int16_t vx, int16_t vy, int16_t vz, int16_t xacc, int16_t yacc, int16_t zacc) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[56]; + _mav_put_uint64_t(buf, 0, time_usec); + _mav_put_float(buf, 8, roll); + _mav_put_float(buf, 12, pitch); + _mav_put_float(buf, 16, yaw); + _mav_put_float(buf, 20, rollspeed); + _mav_put_float(buf, 24, pitchspeed); + _mav_put_float(buf, 28, yawspeed); + _mav_put_int32_t(buf, 32, lat); + _mav_put_int32_t(buf, 36, lon); + _mav_put_int32_t(buf, 40, alt); + _mav_put_int16_t(buf, 44, vx); + _mav_put_int16_t(buf, 46, vy); + _mav_put_int16_t(buf, 48, vz); + _mav_put_int16_t(buf, 50, xacc); + _mav_put_int16_t(buf, 52, yacc); + _mav_put_int16_t(buf, 54, zacc); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_HIL_STATE, buf, 56, 183); +#else + mavlink_hil_state_t packet; + packet.time_usec = time_usec; + packet.roll = roll; + packet.pitch = pitch; + packet.yaw = yaw; + packet.rollspeed = rollspeed; + packet.pitchspeed = pitchspeed; + packet.yawspeed = yawspeed; + packet.lat = lat; + packet.lon = lon; + packet.alt = alt; + packet.vx = vx; + packet.vy = vy; + packet.vz = vz; + packet.xacc = xacc; + packet.yacc = yacc; + packet.zacc = zacc; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_HIL_STATE, (const char *)&packet, 56, 183); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE HIL_STATE UNPACKING + + +/** + * @brief Get field time_usec from hil_state message + * + * @return Timestamp (microseconds since UNIX epoch or microseconds since system boot) + */ +static inline uint64_t mavlink_msg_hil_state_get_time_usec(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint64_t(msg, 0); +} + +/** + * @brief Get field roll from hil_state message + * + * @return Roll angle (rad) + */ +static inline float mavlink_msg_hil_state_get_roll(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 8); +} + +/** + * @brief Get field pitch from hil_state message + * + * @return Pitch angle (rad) + */ +static inline float mavlink_msg_hil_state_get_pitch(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 12); +} + +/** + * @brief Get field yaw from hil_state message + * + * @return Yaw angle (rad) + */ +static inline float mavlink_msg_hil_state_get_yaw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 16); +} + +/** + * @brief Get field rollspeed from hil_state message + * + * @return Roll angular speed (rad/s) + */ +static inline float mavlink_msg_hil_state_get_rollspeed(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 20); +} + +/** + * @brief Get field pitchspeed from hil_state message + * + * @return Pitch angular speed (rad/s) + */ +static inline float mavlink_msg_hil_state_get_pitchspeed(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 24); +} + +/** + * @brief Get field yawspeed from hil_state message + * + * @return Yaw angular speed (rad/s) + */ +static inline float mavlink_msg_hil_state_get_yawspeed(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 28); +} + +/** + * @brief Get field lat from hil_state message + * + * @return Latitude, expressed as * 1E7 + */ +static inline int32_t mavlink_msg_hil_state_get_lat(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int32_t(msg, 32); +} + +/** + * @brief Get field lon from hil_state message + * + * @return Longitude, expressed as * 1E7 + */ +static inline int32_t mavlink_msg_hil_state_get_lon(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int32_t(msg, 36); +} + +/** + * @brief Get field alt from hil_state message + * + * @return Altitude in meters, expressed as * 1000 (millimeters) + */ +static inline int32_t mavlink_msg_hil_state_get_alt(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int32_t(msg, 40); +} + +/** + * @brief Get field vx from hil_state message + * + * @return Ground X Speed (Latitude), expressed as m/s * 100 + */ +static inline int16_t mavlink_msg_hil_state_get_vx(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 44); +} + +/** + * @brief Get field vy from hil_state message + * + * @return Ground Y Speed (Longitude), expressed as m/s * 100 + */ +static inline int16_t mavlink_msg_hil_state_get_vy(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 46); +} + +/** + * @brief Get field vz from hil_state message + * + * @return Ground Z Speed (Altitude), expressed as m/s * 100 + */ +static inline int16_t mavlink_msg_hil_state_get_vz(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 48); +} + +/** + * @brief Get field xacc from hil_state message + * + * @return X acceleration (mg) + */ +static inline int16_t mavlink_msg_hil_state_get_xacc(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 50); +} + +/** + * @brief Get field yacc from hil_state message + * + * @return Y acceleration (mg) + */ +static inline int16_t mavlink_msg_hil_state_get_yacc(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 52); +} + +/** + * @brief Get field zacc from hil_state message + * + * @return Z acceleration (mg) + */ +static inline int16_t mavlink_msg_hil_state_get_zacc(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 54); +} + +/** + * @brief Decode a hil_state message into a struct + * + * @param msg The message to decode + * @param hil_state C-struct to decode the message contents into + */ +static inline void mavlink_msg_hil_state_decode(const mavlink_message_t *msg, mavlink_hil_state_t *hil_state) +{ +#if MAVLINK_NEED_BYTE_SWAP + hil_state->time_usec = mavlink_msg_hil_state_get_time_usec(msg); + hil_state->roll = mavlink_msg_hil_state_get_roll(msg); + hil_state->pitch = mavlink_msg_hil_state_get_pitch(msg); + hil_state->yaw = mavlink_msg_hil_state_get_yaw(msg); + hil_state->rollspeed = mavlink_msg_hil_state_get_rollspeed(msg); + hil_state->pitchspeed = mavlink_msg_hil_state_get_pitchspeed(msg); + hil_state->yawspeed = mavlink_msg_hil_state_get_yawspeed(msg); + hil_state->lat = mavlink_msg_hil_state_get_lat(msg); + hil_state->lon = mavlink_msg_hil_state_get_lon(msg); + hil_state->alt = mavlink_msg_hil_state_get_alt(msg); + hil_state->vx = mavlink_msg_hil_state_get_vx(msg); + hil_state->vy = mavlink_msg_hil_state_get_vy(msg); + hil_state->vz = mavlink_msg_hil_state_get_vz(msg); + hil_state->xacc = mavlink_msg_hil_state_get_xacc(msg); + hil_state->yacc = mavlink_msg_hil_state_get_yacc(msg); + hil_state->zacc = mavlink_msg_hil_state_get_zacc(msg); +#else + memcpy(hil_state, _MAV_PAYLOAD(msg), 56); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_local_position_ned.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_local_position_ned.h new file mode 100644 index 000000000..2f4224d08 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_local_position_ned.h @@ -0,0 +1,276 @@ +// MESSAGE LOCAL_POSITION_NED PACKING + +#define MAVLINK_MSG_ID_LOCAL_POSITION_NED 32 + +typedef struct __mavlink_local_position_ned_t { + uint32_t time_boot_ms; ///< Timestamp (milliseconds since system boot) + float x; ///< X Position + float y; ///< Y Position + float z; ///< Z Position + float vx; ///< X Speed + float vy; ///< Y Speed + float vz; ///< Z Speed +} mavlink_local_position_ned_t; + +#define MAVLINK_MSG_ID_LOCAL_POSITION_NED_LEN 28 +#define MAVLINK_MSG_ID_32_LEN 28 + + +#define MAVLINK_MESSAGE_INFO_LOCAL_POSITION_NED \ + { \ + "LOCAL_POSITION_NED", \ + 7, \ + { \ + { "time_boot_ms", NULL, MAVLINK_TYPE_UINT32_T, 0, 0, offsetof(mavlink_local_position_ned_t, time_boot_ms) }, \ + { "x", NULL, MAVLINK_TYPE_FLOAT, 0, 4, offsetof(mavlink_local_position_ned_t, x) }, \ + { "y", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_local_position_ned_t, y) }, \ + { "z", NULL, MAVLINK_TYPE_FLOAT, 0, 12, offsetof(mavlink_local_position_ned_t, z) }, \ + { "vx", NULL, MAVLINK_TYPE_FLOAT, 0, 16, offsetof(mavlink_local_position_ned_t, vx) }, \ + { "vy", NULL, MAVLINK_TYPE_FLOAT, 0, 20, offsetof(mavlink_local_position_ned_t, vy) }, \ + { "vz", NULL, MAVLINK_TYPE_FLOAT, 0, 24, offsetof(mavlink_local_position_ned_t, vz) }, \ + } \ + } + + +/** + * @brief Pack a local_position_ned message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param x X Position + * @param y Y Position + * @param z Z Position + * @param vx X Speed + * @param vy Y Speed + * @param vz Z Speed + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_local_position_ned_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint32_t time_boot_ms, float x, float y, float z, float vx, float vy, float vz) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[28]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_float(buf, 4, x); + _mav_put_float(buf, 8, y); + _mav_put_float(buf, 12, z); + _mav_put_float(buf, 16, vx); + _mav_put_float(buf, 20, vy); + _mav_put_float(buf, 24, vz); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 28); +#else + mavlink_local_position_ned_t packet; + packet.time_boot_ms = time_boot_ms; + packet.x = x; + packet.y = y; + packet.z = z; + packet.vx = vx; + packet.vy = vy; + packet.vz = vz; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 28); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_LOCAL_POSITION_NED; + return mavlink_finalize_message(msg, system_id, component_id, 28, 185); +} + +/** + * @brief Pack a local_position_ned message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param x X Position + * @param y Y Position + * @param z Z Position + * @param vx X Speed + * @param vy Y Speed + * @param vz Z Speed + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_local_position_ned_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint32_t time_boot_ms, float x, float y, float z, float vx, float vy, float vz) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[28]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_float(buf, 4, x); + _mav_put_float(buf, 8, y); + _mav_put_float(buf, 12, z); + _mav_put_float(buf, 16, vx); + _mav_put_float(buf, 20, vy); + _mav_put_float(buf, 24, vz); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 28); +#else + mavlink_local_position_ned_t packet; + packet.time_boot_ms = time_boot_ms; + packet.x = x; + packet.y = y; + packet.z = z; + packet.vx = vx; + packet.vy = vy; + packet.vz = vz; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 28); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_LOCAL_POSITION_NED; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 28, 185); +} + +/** + * @brief Encode a local_position_ned struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param local_position_ned C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_local_position_ned_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_local_position_ned_t *local_position_ned) +{ + return mavlink_msg_local_position_ned_pack(system_id, component_id, msg, local_position_ned->time_boot_ms, local_position_ned->x, local_position_ned->y, local_position_ned->z, local_position_ned->vx, local_position_ned->vy, local_position_ned->vz); +} + +/** + * @brief Send a local_position_ned message + * @param chan MAVLink channel to send the message + * + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param x X Position + * @param y Y Position + * @param z Z Position + * @param vx X Speed + * @param vy Y Speed + * @param vz Z Speed + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_local_position_ned_send(mavlink_channel_t chan, uint32_t time_boot_ms, float x, float y, float z, float vx, float vy, float vz) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[28]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_float(buf, 4, x); + _mav_put_float(buf, 8, y); + _mav_put_float(buf, 12, z); + _mav_put_float(buf, 16, vx); + _mav_put_float(buf, 20, vy); + _mav_put_float(buf, 24, vz); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_LOCAL_POSITION_NED, buf, 28, 185); +#else + mavlink_local_position_ned_t packet; + packet.time_boot_ms = time_boot_ms; + packet.x = x; + packet.y = y; + packet.z = z; + packet.vx = vx; + packet.vy = vy; + packet.vz = vz; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_LOCAL_POSITION_NED, (const char *)&packet, 28, 185); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE LOCAL_POSITION_NED UNPACKING + + +/** + * @brief Get field time_boot_ms from local_position_ned message + * + * @return Timestamp (milliseconds since system boot) + */ +static inline uint32_t mavlink_msg_local_position_ned_get_time_boot_ms(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint32_t(msg, 0); +} + +/** + * @brief Get field x from local_position_ned message + * + * @return X Position + */ +static inline float mavlink_msg_local_position_ned_get_x(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 4); +} + +/** + * @brief Get field y from local_position_ned message + * + * @return Y Position + */ +static inline float mavlink_msg_local_position_ned_get_y(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 8); +} + +/** + * @brief Get field z from local_position_ned message + * + * @return Z Position + */ +static inline float mavlink_msg_local_position_ned_get_z(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 12); +} + +/** + * @brief Get field vx from local_position_ned message + * + * @return X Speed + */ +static inline float mavlink_msg_local_position_ned_get_vx(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 16); +} + +/** + * @brief Get field vy from local_position_ned message + * + * @return Y Speed + */ +static inline float mavlink_msg_local_position_ned_get_vy(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 20); +} + +/** + * @brief Get field vz from local_position_ned message + * + * @return Z Speed + */ +static inline float mavlink_msg_local_position_ned_get_vz(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 24); +} + +/** + * @brief Decode a local_position_ned message into a struct + * + * @param msg The message to decode + * @param local_position_ned C-struct to decode the message contents into + */ +static inline void mavlink_msg_local_position_ned_decode(const mavlink_message_t *msg, mavlink_local_position_ned_t *local_position_ned) +{ +#if MAVLINK_NEED_BYTE_SWAP + local_position_ned->time_boot_ms = mavlink_msg_local_position_ned_get_time_boot_ms(msg); + local_position_ned->x = mavlink_msg_local_position_ned_get_x(msg); + local_position_ned->y = mavlink_msg_local_position_ned_get_y(msg); + local_position_ned->z = mavlink_msg_local_position_ned_get_z(msg); + local_position_ned->vx = mavlink_msg_local_position_ned_get_vx(msg); + local_position_ned->vy = mavlink_msg_local_position_ned_get_vy(msg); + local_position_ned->vz = mavlink_msg_local_position_ned_get_vz(msg); +#else + memcpy(local_position_ned, _MAV_PAYLOAD(msg), 28); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_local_position_ned_system_global_offset.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_local_position_ned_system_global_offset.h new file mode 100644 index 000000000..fdfaca245 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_local_position_ned_system_global_offset.h @@ -0,0 +1,276 @@ +// MESSAGE LOCAL_POSITION_NED_SYSTEM_GLOBAL_OFFSET PACKING + +#define MAVLINK_MSG_ID_LOCAL_POSITION_NED_SYSTEM_GLOBAL_OFFSET 89 + +typedef struct __mavlink_local_position_ned_system_global_offset_t { + uint32_t time_boot_ms; ///< Timestamp (milliseconds since system boot) + float x; ///< X Position + float y; ///< Y Position + float z; ///< Z Position + float roll; ///< Roll + float pitch; ///< Pitch + float yaw; ///< Yaw +} mavlink_local_position_ned_system_global_offset_t; + +#define MAVLINK_MSG_ID_LOCAL_POSITION_NED_SYSTEM_GLOBAL_OFFSET_LEN 28 +#define MAVLINK_MSG_ID_89_LEN 28 + + +#define MAVLINK_MESSAGE_INFO_LOCAL_POSITION_NED_SYSTEM_GLOBAL_OFFSET \ + { \ + "LOCAL_POSITION_NED_SYSTEM_GLOBAL_OFFSET", \ + 7, \ + { \ + { "time_boot_ms", NULL, MAVLINK_TYPE_UINT32_T, 0, 0, offsetof(mavlink_local_position_ned_system_global_offset_t, time_boot_ms) }, \ + { "x", NULL, MAVLINK_TYPE_FLOAT, 0, 4, offsetof(mavlink_local_position_ned_system_global_offset_t, x) }, \ + { "y", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_local_position_ned_system_global_offset_t, y) }, \ + { "z", NULL, MAVLINK_TYPE_FLOAT, 0, 12, offsetof(mavlink_local_position_ned_system_global_offset_t, z) }, \ + { "roll", NULL, MAVLINK_TYPE_FLOAT, 0, 16, offsetof(mavlink_local_position_ned_system_global_offset_t, roll) }, \ + { "pitch", NULL, MAVLINK_TYPE_FLOAT, 0, 20, offsetof(mavlink_local_position_ned_system_global_offset_t, pitch) }, \ + { "yaw", NULL, MAVLINK_TYPE_FLOAT, 0, 24, offsetof(mavlink_local_position_ned_system_global_offset_t, yaw) }, \ + } \ + } + + +/** + * @brief Pack a local_position_ned_system_global_offset message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param x X Position + * @param y Y Position + * @param z Z Position + * @param roll Roll + * @param pitch Pitch + * @param yaw Yaw + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_local_position_ned_system_global_offset_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint32_t time_boot_ms, float x, float y, float z, float roll, float pitch, float yaw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[28]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_float(buf, 4, x); + _mav_put_float(buf, 8, y); + _mav_put_float(buf, 12, z); + _mav_put_float(buf, 16, roll); + _mav_put_float(buf, 20, pitch); + _mav_put_float(buf, 24, yaw); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 28); +#else + mavlink_local_position_ned_system_global_offset_t packet; + packet.time_boot_ms = time_boot_ms; + packet.x = x; + packet.y = y; + packet.z = z; + packet.roll = roll; + packet.pitch = pitch; + packet.yaw = yaw; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 28); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_LOCAL_POSITION_NED_SYSTEM_GLOBAL_OFFSET; + return mavlink_finalize_message(msg, system_id, component_id, 28, 231); +} + +/** + * @brief Pack a local_position_ned_system_global_offset message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param x X Position + * @param y Y Position + * @param z Z Position + * @param roll Roll + * @param pitch Pitch + * @param yaw Yaw + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_local_position_ned_system_global_offset_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint32_t time_boot_ms, float x, float y, float z, float roll, float pitch, float yaw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[28]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_float(buf, 4, x); + _mav_put_float(buf, 8, y); + _mav_put_float(buf, 12, z); + _mav_put_float(buf, 16, roll); + _mav_put_float(buf, 20, pitch); + _mav_put_float(buf, 24, yaw); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 28); +#else + mavlink_local_position_ned_system_global_offset_t packet; + packet.time_boot_ms = time_boot_ms; + packet.x = x; + packet.y = y; + packet.z = z; + packet.roll = roll; + packet.pitch = pitch; + packet.yaw = yaw; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 28); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_LOCAL_POSITION_NED_SYSTEM_GLOBAL_OFFSET; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 28, 231); +} + +/** + * @brief Encode a local_position_ned_system_global_offset struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param local_position_ned_system_global_offset C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_local_position_ned_system_global_offset_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_local_position_ned_system_global_offset_t *local_position_ned_system_global_offset) +{ + return mavlink_msg_local_position_ned_system_global_offset_pack(system_id, component_id, msg, local_position_ned_system_global_offset->time_boot_ms, local_position_ned_system_global_offset->x, local_position_ned_system_global_offset->y, local_position_ned_system_global_offset->z, local_position_ned_system_global_offset->roll, local_position_ned_system_global_offset->pitch, local_position_ned_system_global_offset->yaw); +} + +/** + * @brief Send a local_position_ned_system_global_offset message + * @param chan MAVLink channel to send the message + * + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param x X Position + * @param y Y Position + * @param z Z Position + * @param roll Roll + * @param pitch Pitch + * @param yaw Yaw + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_local_position_ned_system_global_offset_send(mavlink_channel_t chan, uint32_t time_boot_ms, float x, float y, float z, float roll, float pitch, float yaw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[28]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_float(buf, 4, x); + _mav_put_float(buf, 8, y); + _mav_put_float(buf, 12, z); + _mav_put_float(buf, 16, roll); + _mav_put_float(buf, 20, pitch); + _mav_put_float(buf, 24, yaw); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_LOCAL_POSITION_NED_SYSTEM_GLOBAL_OFFSET, buf, 28, 231); +#else + mavlink_local_position_ned_system_global_offset_t packet; + packet.time_boot_ms = time_boot_ms; + packet.x = x; + packet.y = y; + packet.z = z; + packet.roll = roll; + packet.pitch = pitch; + packet.yaw = yaw; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_LOCAL_POSITION_NED_SYSTEM_GLOBAL_OFFSET, (const char *)&packet, 28, 231); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE LOCAL_POSITION_NED_SYSTEM_GLOBAL_OFFSET UNPACKING + + +/** + * @brief Get field time_boot_ms from local_position_ned_system_global_offset message + * + * @return Timestamp (milliseconds since system boot) + */ +static inline uint32_t mavlink_msg_local_position_ned_system_global_offset_get_time_boot_ms(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint32_t(msg, 0); +} + +/** + * @brief Get field x from local_position_ned_system_global_offset message + * + * @return X Position + */ +static inline float mavlink_msg_local_position_ned_system_global_offset_get_x(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 4); +} + +/** + * @brief Get field y from local_position_ned_system_global_offset message + * + * @return Y Position + */ +static inline float mavlink_msg_local_position_ned_system_global_offset_get_y(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 8); +} + +/** + * @brief Get field z from local_position_ned_system_global_offset message + * + * @return Z Position + */ +static inline float mavlink_msg_local_position_ned_system_global_offset_get_z(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 12); +} + +/** + * @brief Get field roll from local_position_ned_system_global_offset message + * + * @return Roll + */ +static inline float mavlink_msg_local_position_ned_system_global_offset_get_roll(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 16); +} + +/** + * @brief Get field pitch from local_position_ned_system_global_offset message + * + * @return Pitch + */ +static inline float mavlink_msg_local_position_ned_system_global_offset_get_pitch(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 20); +} + +/** + * @brief Get field yaw from local_position_ned_system_global_offset message + * + * @return Yaw + */ +static inline float mavlink_msg_local_position_ned_system_global_offset_get_yaw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 24); +} + +/** + * @brief Decode a local_position_ned_system_global_offset message into a struct + * + * @param msg The message to decode + * @param local_position_ned_system_global_offset C-struct to decode the message contents into + */ +static inline void mavlink_msg_local_position_ned_system_global_offset_decode(const mavlink_message_t *msg, mavlink_local_position_ned_system_global_offset_t *local_position_ned_system_global_offset) +{ +#if MAVLINK_NEED_BYTE_SWAP + local_position_ned_system_global_offset->time_boot_ms = mavlink_msg_local_position_ned_system_global_offset_get_time_boot_ms(msg); + local_position_ned_system_global_offset->x = mavlink_msg_local_position_ned_system_global_offset_get_x(msg); + local_position_ned_system_global_offset->y = mavlink_msg_local_position_ned_system_global_offset_get_y(msg); + local_position_ned_system_global_offset->z = mavlink_msg_local_position_ned_system_global_offset_get_z(msg); + local_position_ned_system_global_offset->roll = mavlink_msg_local_position_ned_system_global_offset_get_roll(msg); + local_position_ned_system_global_offset->pitch = mavlink_msg_local_position_ned_system_global_offset_get_pitch(msg); + local_position_ned_system_global_offset->yaw = mavlink_msg_local_position_ned_system_global_offset_get_yaw(msg); +#else + memcpy(local_position_ned_system_global_offset, _MAV_PAYLOAD(msg), 28); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_local_position_setpoint.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_local_position_setpoint.h new file mode 100644 index 000000000..24e315276 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_local_position_setpoint.h @@ -0,0 +1,232 @@ +// MESSAGE LOCAL_POSITION_SETPOINT PACKING + +#define MAVLINK_MSG_ID_LOCAL_POSITION_SETPOINT 51 + +typedef struct __mavlink_local_position_setpoint_t { + float x; ///< x position + float y; ///< y position + float z; ///< z position + float yaw; ///< Desired yaw angle + uint8_t coordinate_frame; ///< Coordinate frame - valid values are only MAV_FRAME_LOCAL_NED or MAV_FRAME_LOCAL_ENU +} mavlink_local_position_setpoint_t; + +#define MAVLINK_MSG_ID_LOCAL_POSITION_SETPOINT_LEN 17 +#define MAVLINK_MSG_ID_51_LEN 17 + + +#define MAVLINK_MESSAGE_INFO_LOCAL_POSITION_SETPOINT \ + { \ + "LOCAL_POSITION_SETPOINT", \ + 5, \ + { \ + { "x", NULL, MAVLINK_TYPE_FLOAT, 0, 0, offsetof(mavlink_local_position_setpoint_t, x) }, \ + { "y", NULL, MAVLINK_TYPE_FLOAT, 0, 4, offsetof(mavlink_local_position_setpoint_t, y) }, \ + { "z", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_local_position_setpoint_t, z) }, \ + { "yaw", NULL, MAVLINK_TYPE_FLOAT, 0, 12, offsetof(mavlink_local_position_setpoint_t, yaw) }, \ + { "coordinate_frame", NULL, MAVLINK_TYPE_UINT8_T, 0, 16, offsetof(mavlink_local_position_setpoint_t, coordinate_frame) }, \ + } \ + } + + +/** + * @brief Pack a local_position_setpoint message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param coordinate_frame Coordinate frame - valid values are only MAV_FRAME_LOCAL_NED or MAV_FRAME_LOCAL_ENU + * @param x x position + * @param y y position + * @param z z position + * @param yaw Desired yaw angle + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_local_position_setpoint_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t coordinate_frame, float x, float y, float z, float yaw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[17]; + _mav_put_float(buf, 0, x); + _mav_put_float(buf, 4, y); + _mav_put_float(buf, 8, z); + _mav_put_float(buf, 12, yaw); + _mav_put_uint8_t(buf, 16, coordinate_frame); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 17); +#else + mavlink_local_position_setpoint_t packet; + packet.x = x; + packet.y = y; + packet.z = z; + packet.yaw = yaw; + packet.coordinate_frame = coordinate_frame; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 17); +#endif + + msg->msgid = MAVLINK_MSG_ID_LOCAL_POSITION_SETPOINT; + return mavlink_finalize_message(msg, system_id, component_id, 17, 223); +} + +/** + * @brief Pack a local_position_setpoint message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param coordinate_frame Coordinate frame - valid values are only MAV_FRAME_LOCAL_NED or MAV_FRAME_LOCAL_ENU + * @param x x position + * @param y y position + * @param z z position + * @param yaw Desired yaw angle + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_local_position_setpoint_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t coordinate_frame, float x, float y, float z, float yaw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[17]; + _mav_put_float(buf, 0, x); + _mav_put_float(buf, 4, y); + _mav_put_float(buf, 8, z); + _mav_put_float(buf, 12, yaw); + _mav_put_uint8_t(buf, 16, coordinate_frame); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 17); +#else + mavlink_local_position_setpoint_t packet; + packet.x = x; + packet.y = y; + packet.z = z; + packet.yaw = yaw; + packet.coordinate_frame = coordinate_frame; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 17); +#endif + + msg->msgid = MAVLINK_MSG_ID_LOCAL_POSITION_SETPOINT; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 17, 223); +} + +/** + * @brief Encode a local_position_setpoint struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param local_position_setpoint C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_local_position_setpoint_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_local_position_setpoint_t *local_position_setpoint) +{ + return mavlink_msg_local_position_setpoint_pack(system_id, component_id, msg, local_position_setpoint->coordinate_frame, local_position_setpoint->x, local_position_setpoint->y, local_position_setpoint->z, local_position_setpoint->yaw); +} + +/** + * @brief Send a local_position_setpoint message + * @param chan MAVLink channel to send the message + * + * @param coordinate_frame Coordinate frame - valid values are only MAV_FRAME_LOCAL_NED or MAV_FRAME_LOCAL_ENU + * @param x x position + * @param y y position + * @param z z position + * @param yaw Desired yaw angle + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_local_position_setpoint_send(mavlink_channel_t chan, uint8_t coordinate_frame, float x, float y, float z, float yaw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[17]; + _mav_put_float(buf, 0, x); + _mav_put_float(buf, 4, y); + _mav_put_float(buf, 8, z); + _mav_put_float(buf, 12, yaw); + _mav_put_uint8_t(buf, 16, coordinate_frame); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_LOCAL_POSITION_SETPOINT, buf, 17, 223); +#else + mavlink_local_position_setpoint_t packet; + packet.x = x; + packet.y = y; + packet.z = z; + packet.yaw = yaw; + packet.coordinate_frame = coordinate_frame; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_LOCAL_POSITION_SETPOINT, (const char *)&packet, 17, 223); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE LOCAL_POSITION_SETPOINT UNPACKING + + +/** + * @brief Get field coordinate_frame from local_position_setpoint message + * + * @return Coordinate frame - valid values are only MAV_FRAME_LOCAL_NED or MAV_FRAME_LOCAL_ENU + */ +static inline uint8_t mavlink_msg_local_position_setpoint_get_coordinate_frame(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 16); +} + +/** + * @brief Get field x from local_position_setpoint message + * + * @return x position + */ +static inline float mavlink_msg_local_position_setpoint_get_x(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 0); +} + +/** + * @brief Get field y from local_position_setpoint message + * + * @return y position + */ +static inline float mavlink_msg_local_position_setpoint_get_y(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 4); +} + +/** + * @brief Get field z from local_position_setpoint message + * + * @return z position + */ +static inline float mavlink_msg_local_position_setpoint_get_z(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 8); +} + +/** + * @brief Get field yaw from local_position_setpoint message + * + * @return Desired yaw angle + */ +static inline float mavlink_msg_local_position_setpoint_get_yaw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 12); +} + +/** + * @brief Decode a local_position_setpoint message into a struct + * + * @param msg The message to decode + * @param local_position_setpoint C-struct to decode the message contents into + */ +static inline void mavlink_msg_local_position_setpoint_decode(const mavlink_message_t *msg, mavlink_local_position_setpoint_t *local_position_setpoint) +{ +#if MAVLINK_NEED_BYTE_SWAP + local_position_setpoint->x = mavlink_msg_local_position_setpoint_get_x(msg); + local_position_setpoint->y = mavlink_msg_local_position_setpoint_get_y(msg); + local_position_setpoint->z = mavlink_msg_local_position_setpoint_get_z(msg); + local_position_setpoint->yaw = mavlink_msg_local_position_setpoint_get_yaw(msg); + local_position_setpoint->coordinate_frame = mavlink_msg_local_position_setpoint_get_coordinate_frame(msg); +#else + memcpy(local_position_setpoint, _MAV_PAYLOAD(msg), 17); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_manual_control.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_manual_control.h new file mode 100644 index 000000000..f6b38ba20 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_manual_control.h @@ -0,0 +1,320 @@ +// MESSAGE MANUAL_CONTROL PACKING + +#define MAVLINK_MSG_ID_MANUAL_CONTROL 69 + +typedef struct __mavlink_manual_control_t { + float roll; ///< roll + float pitch; ///< pitch + float yaw; ///< yaw + float thrust; ///< thrust + uint8_t target; ///< The system to be controlled + uint8_t roll_manual; ///< roll control enabled auto:0, manual:1 + uint8_t pitch_manual; ///< pitch auto:0, manual:1 + uint8_t yaw_manual; ///< yaw auto:0, manual:1 + uint8_t thrust_manual; ///< thrust auto:0, manual:1 +} mavlink_manual_control_t; + +#define MAVLINK_MSG_ID_MANUAL_CONTROL_LEN 21 +#define MAVLINK_MSG_ID_69_LEN 21 + + +#define MAVLINK_MESSAGE_INFO_MANUAL_CONTROL \ + { \ + "MANUAL_CONTROL", \ + 9, \ + { \ + { "roll", NULL, MAVLINK_TYPE_FLOAT, 0, 0, offsetof(mavlink_manual_control_t, roll) }, \ + { "pitch", NULL, MAVLINK_TYPE_FLOAT, 0, 4, offsetof(mavlink_manual_control_t, pitch) }, \ + { "yaw", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_manual_control_t, yaw) }, \ + { "thrust", NULL, MAVLINK_TYPE_FLOAT, 0, 12, offsetof(mavlink_manual_control_t, thrust) }, \ + { "target", NULL, MAVLINK_TYPE_UINT8_T, 0, 16, offsetof(mavlink_manual_control_t, target) }, \ + { "roll_manual", NULL, MAVLINK_TYPE_UINT8_T, 0, 17, offsetof(mavlink_manual_control_t, roll_manual) }, \ + { "pitch_manual", NULL, MAVLINK_TYPE_UINT8_T, 0, 18, offsetof(mavlink_manual_control_t, pitch_manual) }, \ + { "yaw_manual", NULL, MAVLINK_TYPE_UINT8_T, 0, 19, offsetof(mavlink_manual_control_t, yaw_manual) }, \ + { "thrust_manual", NULL, MAVLINK_TYPE_UINT8_T, 0, 20, offsetof(mavlink_manual_control_t, thrust_manual) }, \ + } \ + } + + +/** + * @brief Pack a manual_control message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param target The system to be controlled + * @param roll roll + * @param pitch pitch + * @param yaw yaw + * @param thrust thrust + * @param roll_manual roll control enabled auto:0, manual:1 + * @param pitch_manual pitch auto:0, manual:1 + * @param yaw_manual yaw auto:0, manual:1 + * @param thrust_manual thrust auto:0, manual:1 + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_manual_control_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t target, float roll, float pitch, float yaw, float thrust, uint8_t roll_manual, uint8_t pitch_manual, uint8_t yaw_manual, uint8_t thrust_manual) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[21]; + _mav_put_float(buf, 0, roll); + _mav_put_float(buf, 4, pitch); + _mav_put_float(buf, 8, yaw); + _mav_put_float(buf, 12, thrust); + _mav_put_uint8_t(buf, 16, target); + _mav_put_uint8_t(buf, 17, roll_manual); + _mav_put_uint8_t(buf, 18, pitch_manual); + _mav_put_uint8_t(buf, 19, yaw_manual); + _mav_put_uint8_t(buf, 20, thrust_manual); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 21); +#else + mavlink_manual_control_t packet; + packet.roll = roll; + packet.pitch = pitch; + packet.yaw = yaw; + packet.thrust = thrust; + packet.target = target; + packet.roll_manual = roll_manual; + packet.pitch_manual = pitch_manual; + packet.yaw_manual = yaw_manual; + packet.thrust_manual = thrust_manual; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 21); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_MANUAL_CONTROL; + return mavlink_finalize_message(msg, system_id, component_id, 21, 52); +} + +/** + * @brief Pack a manual_control message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param target The system to be controlled + * @param roll roll + * @param pitch pitch + * @param yaw yaw + * @param thrust thrust + * @param roll_manual roll control enabled auto:0, manual:1 + * @param pitch_manual pitch auto:0, manual:1 + * @param yaw_manual yaw auto:0, manual:1 + * @param thrust_manual thrust auto:0, manual:1 + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_manual_control_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t target, float roll, float pitch, float yaw, float thrust, uint8_t roll_manual, uint8_t pitch_manual, uint8_t yaw_manual, uint8_t thrust_manual) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[21]; + _mav_put_float(buf, 0, roll); + _mav_put_float(buf, 4, pitch); + _mav_put_float(buf, 8, yaw); + _mav_put_float(buf, 12, thrust); + _mav_put_uint8_t(buf, 16, target); + _mav_put_uint8_t(buf, 17, roll_manual); + _mav_put_uint8_t(buf, 18, pitch_manual); + _mav_put_uint8_t(buf, 19, yaw_manual); + _mav_put_uint8_t(buf, 20, thrust_manual); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 21); +#else + mavlink_manual_control_t packet; + packet.roll = roll; + packet.pitch = pitch; + packet.yaw = yaw; + packet.thrust = thrust; + packet.target = target; + packet.roll_manual = roll_manual; + packet.pitch_manual = pitch_manual; + packet.yaw_manual = yaw_manual; + packet.thrust_manual = thrust_manual; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 21); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_MANUAL_CONTROL; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 21, 52); +} + +/** + * @brief Encode a manual_control struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param manual_control C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_manual_control_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_manual_control_t *manual_control) +{ + return mavlink_msg_manual_control_pack(system_id, component_id, msg, manual_control->target, manual_control->roll, manual_control->pitch, manual_control->yaw, manual_control->thrust, manual_control->roll_manual, manual_control->pitch_manual, manual_control->yaw_manual, manual_control->thrust_manual); +} + +/** + * @brief Send a manual_control message + * @param chan MAVLink channel to send the message + * + * @param target The system to be controlled + * @param roll roll + * @param pitch pitch + * @param yaw yaw + * @param thrust thrust + * @param roll_manual roll control enabled auto:0, manual:1 + * @param pitch_manual pitch auto:0, manual:1 + * @param yaw_manual yaw auto:0, manual:1 + * @param thrust_manual thrust auto:0, manual:1 + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_manual_control_send(mavlink_channel_t chan, uint8_t target, float roll, float pitch, float yaw, float thrust, uint8_t roll_manual, uint8_t pitch_manual, uint8_t yaw_manual, uint8_t thrust_manual) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[21]; + _mav_put_float(buf, 0, roll); + _mav_put_float(buf, 4, pitch); + _mav_put_float(buf, 8, yaw); + _mav_put_float(buf, 12, thrust); + _mav_put_uint8_t(buf, 16, target); + _mav_put_uint8_t(buf, 17, roll_manual); + _mav_put_uint8_t(buf, 18, pitch_manual); + _mav_put_uint8_t(buf, 19, yaw_manual); + _mav_put_uint8_t(buf, 20, thrust_manual); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_MANUAL_CONTROL, buf, 21, 52); +#else + mavlink_manual_control_t packet; + packet.roll = roll; + packet.pitch = pitch; + packet.yaw = yaw; + packet.thrust = thrust; + packet.target = target; + packet.roll_manual = roll_manual; + packet.pitch_manual = pitch_manual; + packet.yaw_manual = yaw_manual; + packet.thrust_manual = thrust_manual; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_MANUAL_CONTROL, (const char *)&packet, 21, 52); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE MANUAL_CONTROL UNPACKING + + +/** + * @brief Get field target from manual_control message + * + * @return The system to be controlled + */ +static inline uint8_t mavlink_msg_manual_control_get_target(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 16); +} + +/** + * @brief Get field roll from manual_control message + * + * @return roll + */ +static inline float mavlink_msg_manual_control_get_roll(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 0); +} + +/** + * @brief Get field pitch from manual_control message + * + * @return pitch + */ +static inline float mavlink_msg_manual_control_get_pitch(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 4); +} + +/** + * @brief Get field yaw from manual_control message + * + * @return yaw + */ +static inline float mavlink_msg_manual_control_get_yaw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 8); +} + +/** + * @brief Get field thrust from manual_control message + * + * @return thrust + */ +static inline float mavlink_msg_manual_control_get_thrust(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 12); +} + +/** + * @brief Get field roll_manual from manual_control message + * + * @return roll control enabled auto:0, manual:1 + */ +static inline uint8_t mavlink_msg_manual_control_get_roll_manual(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 17); +} + +/** + * @brief Get field pitch_manual from manual_control message + * + * @return pitch auto:0, manual:1 + */ +static inline uint8_t mavlink_msg_manual_control_get_pitch_manual(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 18); +} + +/** + * @brief Get field yaw_manual from manual_control message + * + * @return yaw auto:0, manual:1 + */ +static inline uint8_t mavlink_msg_manual_control_get_yaw_manual(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 19); +} + +/** + * @brief Get field thrust_manual from manual_control message + * + * @return thrust auto:0, manual:1 + */ +static inline uint8_t mavlink_msg_manual_control_get_thrust_manual(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 20); +} + +/** + * @brief Decode a manual_control message into a struct + * + * @param msg The message to decode + * @param manual_control C-struct to decode the message contents into + */ +static inline void mavlink_msg_manual_control_decode(const mavlink_message_t *msg, mavlink_manual_control_t *manual_control) +{ +#if MAVLINK_NEED_BYTE_SWAP + manual_control->roll = mavlink_msg_manual_control_get_roll(msg); + manual_control->pitch = mavlink_msg_manual_control_get_pitch(msg); + manual_control->yaw = mavlink_msg_manual_control_get_yaw(msg); + manual_control->thrust = mavlink_msg_manual_control_get_thrust(msg); + manual_control->target = mavlink_msg_manual_control_get_target(msg); + manual_control->roll_manual = mavlink_msg_manual_control_get_roll_manual(msg); + manual_control->pitch_manual = mavlink_msg_manual_control_get_pitch_manual(msg); + manual_control->yaw_manual = mavlink_msg_manual_control_get_yaw_manual(msg); + manual_control->thrust_manual = mavlink_msg_manual_control_get_thrust_manual(msg); +#else + memcpy(manual_control, _MAV_PAYLOAD(msg), 21); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_memory_vect.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_memory_vect.h new file mode 100644 index 000000000..3be09546c --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_memory_vect.h @@ -0,0 +1,205 @@ +// MESSAGE MEMORY_VECT PACKING + +#define MAVLINK_MSG_ID_MEMORY_VECT 249 + +typedef struct __mavlink_memory_vect_t { + uint16_t address; ///< Starting address of the debug variables + uint8_t ver; ///< Version code of the type variable. 0=unknown, type ignored and assumed int16_t. 1=as below + uint8_t type; ///< Type code of the memory variables. for ver = 1: 0=16 x int16_t, 1=16 x uint16_t, 2=16 x Q15, 3=16 x 1Q14 + int8_t value[32]; ///< Memory contents at specified address +} mavlink_memory_vect_t; + +#define MAVLINK_MSG_ID_MEMORY_VECT_LEN 36 +#define MAVLINK_MSG_ID_249_LEN 36 + +#define MAVLINK_MSG_MEMORY_VECT_FIELD_VALUE_LEN 32 + +#define MAVLINK_MESSAGE_INFO_MEMORY_VECT \ + { \ + "MEMORY_VECT", \ + 4, \ + { \ + { "address", NULL, MAVLINK_TYPE_UINT16_T, 0, 0, offsetof(mavlink_memory_vect_t, address) }, \ + { "ver", NULL, MAVLINK_TYPE_UINT8_T, 0, 2, offsetof(mavlink_memory_vect_t, ver) }, \ + { "type", NULL, MAVLINK_TYPE_UINT8_T, 0, 3, offsetof(mavlink_memory_vect_t, type) }, \ + { "value", NULL, MAVLINK_TYPE_INT8_T, 32, 4, offsetof(mavlink_memory_vect_t, value) }, \ + } \ + } + + +/** + * @brief Pack a memory_vect message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param address Starting address of the debug variables + * @param ver Version code of the type variable. 0=unknown, type ignored and assumed int16_t. 1=as below + * @param type Type code of the memory variables. for ver = 1: 0=16 x int16_t, 1=16 x uint16_t, 2=16 x Q15, 3=16 x 1Q14 + * @param value Memory contents at specified address + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_memory_vect_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint16_t address, uint8_t ver, uint8_t type, const int8_t *value) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[36]; + _mav_put_uint16_t(buf, 0, address); + _mav_put_uint8_t(buf, 2, ver); + _mav_put_uint8_t(buf, 3, type); + _mav_put_int8_t_array(buf, 4, value, 32); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 36); +#else + mavlink_memory_vect_t packet; + packet.address = address; + packet.ver = ver; + packet.type = type; + mav_array_memcpy(packet.value, value, sizeof(int8_t) * 32); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 36); +#endif + + msg->msgid = MAVLINK_MSG_ID_MEMORY_VECT; + return mavlink_finalize_message(msg, system_id, component_id, 36, 204); +} + +/** + * @brief Pack a memory_vect message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param address Starting address of the debug variables + * @param ver Version code of the type variable. 0=unknown, type ignored and assumed int16_t. 1=as below + * @param type Type code of the memory variables. for ver = 1: 0=16 x int16_t, 1=16 x uint16_t, 2=16 x Q15, 3=16 x 1Q14 + * @param value Memory contents at specified address + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_memory_vect_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint16_t address, uint8_t ver, uint8_t type, const int8_t *value) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[36]; + _mav_put_uint16_t(buf, 0, address); + _mav_put_uint8_t(buf, 2, ver); + _mav_put_uint8_t(buf, 3, type); + _mav_put_int8_t_array(buf, 4, value, 32); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 36); +#else + mavlink_memory_vect_t packet; + packet.address = address; + packet.ver = ver; + packet.type = type; + mav_array_memcpy(packet.value, value, sizeof(int8_t) * 32); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 36); +#endif + + msg->msgid = MAVLINK_MSG_ID_MEMORY_VECT; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 36, 204); +} + +/** + * @brief Encode a memory_vect struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param memory_vect C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_memory_vect_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_memory_vect_t *memory_vect) +{ + return mavlink_msg_memory_vect_pack(system_id, component_id, msg, memory_vect->address, memory_vect->ver, memory_vect->type, memory_vect->value); +} + +/** + * @brief Send a memory_vect message + * @param chan MAVLink channel to send the message + * + * @param address Starting address of the debug variables + * @param ver Version code of the type variable. 0=unknown, type ignored and assumed int16_t. 1=as below + * @param type Type code of the memory variables. for ver = 1: 0=16 x int16_t, 1=16 x uint16_t, 2=16 x Q15, 3=16 x 1Q14 + * @param value Memory contents at specified address + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_memory_vect_send(mavlink_channel_t chan, uint16_t address, uint8_t ver, uint8_t type, const int8_t *value) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[36]; + _mav_put_uint16_t(buf, 0, address); + _mav_put_uint8_t(buf, 2, ver); + _mav_put_uint8_t(buf, 3, type); + _mav_put_int8_t_array(buf, 4, value, 32); + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_MEMORY_VECT, buf, 36, 204); +#else + mavlink_memory_vect_t packet; + packet.address = address; + packet.ver = ver; + packet.type = type; + mav_array_memcpy(packet.value, value, sizeof(int8_t) * 32); + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_MEMORY_VECT, (const char *)&packet, 36, 204); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE MEMORY_VECT UNPACKING + + +/** + * @brief Get field address from memory_vect message + * + * @return Starting address of the debug variables + */ +static inline uint16_t mavlink_msg_memory_vect_get_address(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 0); +} + +/** + * @brief Get field ver from memory_vect message + * + * @return Version code of the type variable. 0=unknown, type ignored and assumed int16_t. 1=as below + */ +static inline uint8_t mavlink_msg_memory_vect_get_ver(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 2); +} + +/** + * @brief Get field type from memory_vect message + * + * @return Type code of the memory variables. for ver = 1: 0=16 x int16_t, 1=16 x uint16_t, 2=16 x Q15, 3=16 x 1Q14 + */ +static inline uint8_t mavlink_msg_memory_vect_get_type(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 3); +} + +/** + * @brief Get field value from memory_vect message + * + * @return Memory contents at specified address + */ +static inline uint16_t mavlink_msg_memory_vect_get_value(const mavlink_message_t *msg, int8_t *value) +{ + return _MAV_RETURN_int8_t_array(msg, value, 32, 4); +} + +/** + * @brief Decode a memory_vect message into a struct + * + * @param msg The message to decode + * @param memory_vect C-struct to decode the message contents into + */ +static inline void mavlink_msg_memory_vect_decode(const mavlink_message_t *msg, mavlink_memory_vect_t *memory_vect) +{ +#if MAVLINK_NEED_BYTE_SWAP + memory_vect->address = mavlink_msg_memory_vect_get_address(msg); + memory_vect->ver = mavlink_msg_memory_vect_get_ver(msg); + memory_vect->type = mavlink_msg_memory_vect_get_type(msg); + mavlink_msg_memory_vect_get_value(msg, memory_vect->value); +#else + memcpy(memory_vect, _MAV_PAYLOAD(msg), 36); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_ack.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_ack.h new file mode 100644 index 000000000..adc8b1406 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_ack.h @@ -0,0 +1,188 @@ +// MESSAGE MISSION_ACK PACKING + +#define MAVLINK_MSG_ID_MISSION_ACK 47 + +typedef struct __mavlink_mission_ack_t { + uint8_t target_system; ///< System ID + uint8_t target_component; ///< Component ID + uint8_t type; ///< See MAV_MISSION_RESULT enum +} mavlink_mission_ack_t; + +#define MAVLINK_MSG_ID_MISSION_ACK_LEN 3 +#define MAVLINK_MSG_ID_47_LEN 3 + + +#define MAVLINK_MESSAGE_INFO_MISSION_ACK \ + { \ + "MISSION_ACK", \ + 3, \ + { \ + { "target_system", NULL, MAVLINK_TYPE_UINT8_T, 0, 0, offsetof(mavlink_mission_ack_t, target_system) }, \ + { "target_component", NULL, MAVLINK_TYPE_UINT8_T, 0, 1, offsetof(mavlink_mission_ack_t, target_component) }, \ + { "type", NULL, MAVLINK_TYPE_UINT8_T, 0, 2, offsetof(mavlink_mission_ack_t, type) }, \ + } \ + } + + +/** + * @brief Pack a mission_ack message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param target_system System ID + * @param target_component Component ID + * @param type See MAV_MISSION_RESULT enum + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_mission_ack_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, uint8_t type) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[3]; + _mav_put_uint8_t(buf, 0, target_system); + _mav_put_uint8_t(buf, 1, target_component); + _mav_put_uint8_t(buf, 2, type); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 3); +#else + mavlink_mission_ack_t packet; + packet.target_system = target_system; + packet.target_component = target_component; + packet.type = type; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 3); +#endif + + msg->msgid = MAVLINK_MSG_ID_MISSION_ACK; + return mavlink_finalize_message(msg, system_id, component_id, 3, 153); +} + +/** + * @brief Pack a mission_ack message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param target_system System ID + * @param target_component Component ID + * @param type See MAV_MISSION_RESULT enum + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_mission_ack_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, uint8_t type) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[3]; + _mav_put_uint8_t(buf, 0, target_system); + _mav_put_uint8_t(buf, 1, target_component); + _mav_put_uint8_t(buf, 2, type); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 3); +#else + mavlink_mission_ack_t packet; + packet.target_system = target_system; + packet.target_component = target_component; + packet.type = type; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 3); +#endif + + msg->msgid = MAVLINK_MSG_ID_MISSION_ACK; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 3, 153); +} + +/** + * @brief Encode a mission_ack struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param mission_ack C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_mission_ack_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_mission_ack_t *mission_ack) +{ + return mavlink_msg_mission_ack_pack(system_id, component_id, msg, mission_ack->target_system, mission_ack->target_component, mission_ack->type); +} + +/** + * @brief Send a mission_ack message + * @param chan MAVLink channel to send the message + * + * @param target_system System ID + * @param target_component Component ID + * @param type See MAV_MISSION_RESULT enum + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_mission_ack_send(mavlink_channel_t chan, uint8_t target_system, uint8_t target_component, uint8_t type) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[3]; + _mav_put_uint8_t(buf, 0, target_system); + _mav_put_uint8_t(buf, 1, target_component); + _mav_put_uint8_t(buf, 2, type); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_MISSION_ACK, buf, 3, 153); +#else + mavlink_mission_ack_t packet; + packet.target_system = target_system; + packet.target_component = target_component; + packet.type = type; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_MISSION_ACK, (const char *)&packet, 3, 153); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE MISSION_ACK UNPACKING + + +/** + * @brief Get field target_system from mission_ack message + * + * @return System ID + */ +static inline uint8_t mavlink_msg_mission_ack_get_target_system(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 0); +} + +/** + * @brief Get field target_component from mission_ack message + * + * @return Component ID + */ +static inline uint8_t mavlink_msg_mission_ack_get_target_component(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 1); +} + +/** + * @brief Get field type from mission_ack message + * + * @return See MAV_MISSION_RESULT enum + */ +static inline uint8_t mavlink_msg_mission_ack_get_type(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 2); +} + +/** + * @brief Decode a mission_ack message into a struct + * + * @param msg The message to decode + * @param mission_ack C-struct to decode the message contents into + */ +static inline void mavlink_msg_mission_ack_decode(const mavlink_message_t *msg, mavlink_mission_ack_t *mission_ack) +{ +#if MAVLINK_NEED_BYTE_SWAP + mission_ack->target_system = mavlink_msg_mission_ack_get_target_system(msg); + mission_ack->target_component = mavlink_msg_mission_ack_get_target_component(msg); + mission_ack->type = mavlink_msg_mission_ack_get_type(msg); +#else + memcpy(mission_ack, _MAV_PAYLOAD(msg), 3); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_clear_all.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_clear_all.h new file mode 100644 index 000000000..31cd45923 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_clear_all.h @@ -0,0 +1,166 @@ +// MESSAGE MISSION_CLEAR_ALL PACKING + +#define MAVLINK_MSG_ID_MISSION_CLEAR_ALL 45 + +typedef struct __mavlink_mission_clear_all_t { + uint8_t target_system; ///< System ID + uint8_t target_component; ///< Component ID +} mavlink_mission_clear_all_t; + +#define MAVLINK_MSG_ID_MISSION_CLEAR_ALL_LEN 2 +#define MAVLINK_MSG_ID_45_LEN 2 + + +#define MAVLINK_MESSAGE_INFO_MISSION_CLEAR_ALL \ + { \ + "MISSION_CLEAR_ALL", \ + 2, \ + { \ + { "target_system", NULL, MAVLINK_TYPE_UINT8_T, 0, 0, offsetof(mavlink_mission_clear_all_t, target_system) }, \ + { "target_component", NULL, MAVLINK_TYPE_UINT8_T, 0, 1, offsetof(mavlink_mission_clear_all_t, target_component) }, \ + } \ + } + + +/** + * @brief Pack a mission_clear_all message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param target_system System ID + * @param target_component Component ID + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_mission_clear_all_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[2]; + _mav_put_uint8_t(buf, 0, target_system); + _mav_put_uint8_t(buf, 1, target_component); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 2); +#else + mavlink_mission_clear_all_t packet; + packet.target_system = target_system; + packet.target_component = target_component; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 2); +#endif + + msg->msgid = MAVLINK_MSG_ID_MISSION_CLEAR_ALL; + return mavlink_finalize_message(msg, system_id, component_id, 2, 232); +} + +/** + * @brief Pack a mission_clear_all message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param target_system System ID + * @param target_component Component ID + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_mission_clear_all_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[2]; + _mav_put_uint8_t(buf, 0, target_system); + _mav_put_uint8_t(buf, 1, target_component); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 2); +#else + mavlink_mission_clear_all_t packet; + packet.target_system = target_system; + packet.target_component = target_component; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 2); +#endif + + msg->msgid = MAVLINK_MSG_ID_MISSION_CLEAR_ALL; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 2, 232); +} + +/** + * @brief Encode a mission_clear_all struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param mission_clear_all C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_mission_clear_all_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_mission_clear_all_t *mission_clear_all) +{ + return mavlink_msg_mission_clear_all_pack(system_id, component_id, msg, mission_clear_all->target_system, mission_clear_all->target_component); +} + +/** + * @brief Send a mission_clear_all message + * @param chan MAVLink channel to send the message + * + * @param target_system System ID + * @param target_component Component ID + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_mission_clear_all_send(mavlink_channel_t chan, uint8_t target_system, uint8_t target_component) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[2]; + _mav_put_uint8_t(buf, 0, target_system); + _mav_put_uint8_t(buf, 1, target_component); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_MISSION_CLEAR_ALL, buf, 2, 232); +#else + mavlink_mission_clear_all_t packet; + packet.target_system = target_system; + packet.target_component = target_component; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_MISSION_CLEAR_ALL, (const char *)&packet, 2, 232); +#endif +} + +#endif + +// MESSAGE MISSION_CLEAR_ALL UNPACKING + + +/** + * @brief Get field target_system from mission_clear_all message + * + * @return System ID + */ +static inline uint8_t mavlink_msg_mission_clear_all_get_target_system(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 0); +} + +/** + * @brief Get field target_component from mission_clear_all message + * + * @return Component ID + */ +static inline uint8_t mavlink_msg_mission_clear_all_get_target_component(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 1); +} + +/** + * @brief Decode a mission_clear_all message into a struct + * + * @param msg The message to decode + * @param mission_clear_all C-struct to decode the message contents into + */ +static inline void mavlink_msg_mission_clear_all_decode(const mavlink_message_t *msg, mavlink_mission_clear_all_t *mission_clear_all) +{ +#if MAVLINK_NEED_BYTE_SWAP + mission_clear_all->target_system = mavlink_msg_mission_clear_all_get_target_system(msg); + mission_clear_all->target_component = mavlink_msg_mission_clear_all_get_target_component(msg); +#else + memcpy(mission_clear_all, _MAV_PAYLOAD(msg), 2); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_count.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_count.h new file mode 100644 index 000000000..1c230d72f --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_count.h @@ -0,0 +1,188 @@ +// MESSAGE MISSION_COUNT PACKING + +#define MAVLINK_MSG_ID_MISSION_COUNT 44 + +typedef struct __mavlink_mission_count_t { + uint16_t count; ///< Number of mission items in the sequence + uint8_t target_system; ///< System ID + uint8_t target_component; ///< Component ID +} mavlink_mission_count_t; + +#define MAVLINK_MSG_ID_MISSION_COUNT_LEN 4 +#define MAVLINK_MSG_ID_44_LEN 4 + + +#define MAVLINK_MESSAGE_INFO_MISSION_COUNT \ + { \ + "MISSION_COUNT", \ + 3, \ + { \ + { "count", NULL, MAVLINK_TYPE_UINT16_T, 0, 0, offsetof(mavlink_mission_count_t, count) }, \ + { "target_system", NULL, MAVLINK_TYPE_UINT8_T, 0, 2, offsetof(mavlink_mission_count_t, target_system) }, \ + { "target_component", NULL, MAVLINK_TYPE_UINT8_T, 0, 3, offsetof(mavlink_mission_count_t, target_component) }, \ + } \ + } + + +/** + * @brief Pack a mission_count message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param target_system System ID + * @param target_component Component ID + * @param count Number of mission items in the sequence + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_mission_count_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, uint16_t count) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[4]; + _mav_put_uint16_t(buf, 0, count); + _mav_put_uint8_t(buf, 2, target_system); + _mav_put_uint8_t(buf, 3, target_component); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 4); +#else + mavlink_mission_count_t packet; + packet.count = count; + packet.target_system = target_system; + packet.target_component = target_component; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 4); +#endif + + msg->msgid = MAVLINK_MSG_ID_MISSION_COUNT; + return mavlink_finalize_message(msg, system_id, component_id, 4, 221); +} + +/** + * @brief Pack a mission_count message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param target_system System ID + * @param target_component Component ID + * @param count Number of mission items in the sequence + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_mission_count_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, uint16_t count) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[4]; + _mav_put_uint16_t(buf, 0, count); + _mav_put_uint8_t(buf, 2, target_system); + _mav_put_uint8_t(buf, 3, target_component); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 4); +#else + mavlink_mission_count_t packet; + packet.count = count; + packet.target_system = target_system; + packet.target_component = target_component; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 4); +#endif + + msg->msgid = MAVLINK_MSG_ID_MISSION_COUNT; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 4, 221); +} + +/** + * @brief Encode a mission_count struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param mission_count C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_mission_count_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_mission_count_t *mission_count) +{ + return mavlink_msg_mission_count_pack(system_id, component_id, msg, mission_count->target_system, mission_count->target_component, mission_count->count); +} + +/** + * @brief Send a mission_count message + * @param chan MAVLink channel to send the message + * + * @param target_system System ID + * @param target_component Component ID + * @param count Number of mission items in the sequence + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_mission_count_send(mavlink_channel_t chan, uint8_t target_system, uint8_t target_component, uint16_t count) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[4]; + _mav_put_uint16_t(buf, 0, count); + _mav_put_uint8_t(buf, 2, target_system); + _mav_put_uint8_t(buf, 3, target_component); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_MISSION_COUNT, buf, 4, 221); +#else + mavlink_mission_count_t packet; + packet.count = count; + packet.target_system = target_system; + packet.target_component = target_component; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_MISSION_COUNT, (const char *)&packet, 4, 221); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE MISSION_COUNT UNPACKING + + +/** + * @brief Get field target_system from mission_count message + * + * @return System ID + */ +static inline uint8_t mavlink_msg_mission_count_get_target_system(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 2); +} + +/** + * @brief Get field target_component from mission_count message + * + * @return Component ID + */ +static inline uint8_t mavlink_msg_mission_count_get_target_component(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 3); +} + +/** + * @brief Get field count from mission_count message + * + * @return Number of mission items in the sequence + */ +static inline uint16_t mavlink_msg_mission_count_get_count(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 0); +} + +/** + * @brief Decode a mission_count message into a struct + * + * @param msg The message to decode + * @param mission_count C-struct to decode the message contents into + */ +static inline void mavlink_msg_mission_count_decode(const mavlink_message_t *msg, mavlink_mission_count_t *mission_count) +{ +#if MAVLINK_NEED_BYTE_SWAP + mission_count->count = mavlink_msg_mission_count_get_count(msg); + mission_count->target_system = mavlink_msg_mission_count_get_target_system(msg); + mission_count->target_component = mavlink_msg_mission_count_get_target_component(msg); +#else + memcpy(mission_count, _MAV_PAYLOAD(msg), 4); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_current.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_current.h new file mode 100644 index 000000000..4ebcd1998 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_current.h @@ -0,0 +1,144 @@ +// MESSAGE MISSION_CURRENT PACKING + +#define MAVLINK_MSG_ID_MISSION_CURRENT 42 + +typedef struct __mavlink_mission_current_t { + uint16_t seq; ///< Sequence +} mavlink_mission_current_t; + +#define MAVLINK_MSG_ID_MISSION_CURRENT_LEN 2 +#define MAVLINK_MSG_ID_42_LEN 2 + + +#define MAVLINK_MESSAGE_INFO_MISSION_CURRENT \ + { \ + "MISSION_CURRENT", \ + 1, \ + { \ + { "seq", NULL, MAVLINK_TYPE_UINT16_T, 0, 0, offsetof(mavlink_mission_current_t, seq) }, \ + } \ + } + + +/** + * @brief Pack a mission_current message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param seq Sequence + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_mission_current_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint16_t seq) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[2]; + _mav_put_uint16_t(buf, 0, seq); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 2); +#else + mavlink_mission_current_t packet; + packet.seq = seq; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 2); +#endif + + msg->msgid = MAVLINK_MSG_ID_MISSION_CURRENT; + return mavlink_finalize_message(msg, system_id, component_id, 2, 28); +} + +/** + * @brief Pack a mission_current message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param seq Sequence + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_mission_current_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint16_t seq) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[2]; + _mav_put_uint16_t(buf, 0, seq); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 2); +#else + mavlink_mission_current_t packet; + packet.seq = seq; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 2); +#endif + + msg->msgid = MAVLINK_MSG_ID_MISSION_CURRENT; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 2, 28); +} + +/** + * @brief Encode a mission_current struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param mission_current C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_mission_current_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_mission_current_t *mission_current) +{ + return mavlink_msg_mission_current_pack(system_id, component_id, msg, mission_current->seq); +} + +/** + * @brief Send a mission_current message + * @param chan MAVLink channel to send the message + * + * @param seq Sequence + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_mission_current_send(mavlink_channel_t chan, uint16_t seq) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[2]; + _mav_put_uint16_t(buf, 0, seq); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_MISSION_CURRENT, buf, 2, 28); +#else + mavlink_mission_current_t packet; + packet.seq = seq; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_MISSION_CURRENT, (const char *)&packet, 2, 28); +#endif +} + +#endif + +// MESSAGE MISSION_CURRENT UNPACKING + + +/** + * @brief Get field seq from mission_current message + * + * @return Sequence + */ +static inline uint16_t mavlink_msg_mission_current_get_seq(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 0); +} + +/** + * @brief Decode a mission_current message into a struct + * + * @param msg The message to decode + * @param mission_current C-struct to decode the message contents into + */ +static inline void mavlink_msg_mission_current_decode(const mavlink_message_t *msg, mavlink_mission_current_t *mission_current) +{ +#if MAVLINK_NEED_BYTE_SWAP + mission_current->seq = mavlink_msg_mission_current_get_seq(msg); +#else + memcpy(mission_current, _MAV_PAYLOAD(msg), 2); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_item.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_item.h new file mode 100644 index 000000000..d60bbfda5 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_item.h @@ -0,0 +1,430 @@ +// MESSAGE MISSION_ITEM PACKING + +#define MAVLINK_MSG_ID_MISSION_ITEM 39 + +typedef struct __mavlink_mission_item_t { + float param1; ///< PARAM1 / For NAV command MISSIONs: Radius in which the MISSION is accepted as reached, in meters + float param2; ///< PARAM2 / For NAV command MISSIONs: Time that the MAV should stay inside the PARAM1 radius before advancing, in milliseconds + float param3; ///< PARAM3 / For LOITER command MISSIONs: Orbit to circle around the MISSION, in meters. If positive the orbit direction should be clockwise, if negative the orbit direction should be counter-clockwise. + float param4; ///< PARAM4 / For NAV and LOITER command MISSIONs: Yaw orientation in degrees, [0..360] 0 = NORTH + float x; ///< PARAM5 / local: x position, global: latitude + float y; ///< PARAM6 / y position: global: longitude + float z; ///< PARAM7 / z position: global: altitude + uint16_t seq; ///< Sequence + uint16_t command; ///< The scheduled action for the MISSION. see MAV_CMD in common.xml MAVLink specs + uint8_t target_system; ///< System ID + uint8_t target_component; ///< Component ID + uint8_t frame; ///< The coordinate system of the MISSION. see MAV_FRAME in mavlink_types.h + uint8_t current; ///< false:0, true:1 + uint8_t autocontinue; ///< autocontinue to next wp +} mavlink_mission_item_t; + +#define MAVLINK_MSG_ID_MISSION_ITEM_LEN 37 +#define MAVLINK_MSG_ID_39_LEN 37 + + +#define MAVLINK_MESSAGE_INFO_MISSION_ITEM \ + { \ + "MISSION_ITEM", \ + 14, \ + { \ + { "param1", NULL, MAVLINK_TYPE_FLOAT, 0, 0, offsetof(mavlink_mission_item_t, param1) }, \ + { "param2", NULL, MAVLINK_TYPE_FLOAT, 0, 4, offsetof(mavlink_mission_item_t, param2) }, \ + { "param3", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_mission_item_t, param3) }, \ + { "param4", NULL, MAVLINK_TYPE_FLOAT, 0, 12, offsetof(mavlink_mission_item_t, param4) }, \ + { "x", NULL, MAVLINK_TYPE_FLOAT, 0, 16, offsetof(mavlink_mission_item_t, x) }, \ + { "y", NULL, MAVLINK_TYPE_FLOAT, 0, 20, offsetof(mavlink_mission_item_t, y) }, \ + { "z", NULL, MAVLINK_TYPE_FLOAT, 0, 24, offsetof(mavlink_mission_item_t, z) }, \ + { "seq", NULL, MAVLINK_TYPE_UINT16_T, 0, 28, offsetof(mavlink_mission_item_t, seq) }, \ + { "command", NULL, MAVLINK_TYPE_UINT16_T, 0, 30, offsetof(mavlink_mission_item_t, command) }, \ + { "target_system", NULL, MAVLINK_TYPE_UINT8_T, 0, 32, offsetof(mavlink_mission_item_t, target_system) }, \ + { "target_component", NULL, MAVLINK_TYPE_UINT8_T, 0, 33, offsetof(mavlink_mission_item_t, target_component) }, \ + { "frame", NULL, MAVLINK_TYPE_UINT8_T, 0, 34, offsetof(mavlink_mission_item_t, frame) }, \ + { "current", NULL, MAVLINK_TYPE_UINT8_T, 0, 35, offsetof(mavlink_mission_item_t, current) }, \ + { "autocontinue", NULL, MAVLINK_TYPE_UINT8_T, 0, 36, offsetof(mavlink_mission_item_t, autocontinue) }, \ + } \ + } + + +/** + * @brief Pack a mission_item message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param target_system System ID + * @param target_component Component ID + * @param seq Sequence + * @param frame The coordinate system of the MISSION. see MAV_FRAME in mavlink_types.h + * @param command The scheduled action for the MISSION. see MAV_CMD in common.xml MAVLink specs + * @param current false:0, true:1 + * @param autocontinue autocontinue to next wp + * @param param1 PARAM1 / For NAV command MISSIONs: Radius in which the MISSION is accepted as reached, in meters + * @param param2 PARAM2 / For NAV command MISSIONs: Time that the MAV should stay inside the PARAM1 radius before advancing, in milliseconds + * @param param3 PARAM3 / For LOITER command MISSIONs: Orbit to circle around the MISSION, in meters. If positive the orbit direction should be clockwise, if negative the orbit direction should be counter-clockwise. + * @param param4 PARAM4 / For NAV and LOITER command MISSIONs: Yaw orientation in degrees, [0..360] 0 = NORTH + * @param x PARAM5 / local: x position, global: latitude + * @param y PARAM6 / y position: global: longitude + * @param z PARAM7 / z position: global: altitude + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_mission_item_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, uint16_t seq, uint8_t frame, uint16_t command, uint8_t current, uint8_t autocontinue, float param1, float param2, float param3, float param4, float x, float y, float z) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[37]; + _mav_put_float(buf, 0, param1); + _mav_put_float(buf, 4, param2); + _mav_put_float(buf, 8, param3); + _mav_put_float(buf, 12, param4); + _mav_put_float(buf, 16, x); + _mav_put_float(buf, 20, y); + _mav_put_float(buf, 24, z); + _mav_put_uint16_t(buf, 28, seq); + _mav_put_uint16_t(buf, 30, command); + _mav_put_uint8_t(buf, 32, target_system); + _mav_put_uint8_t(buf, 33, target_component); + _mav_put_uint8_t(buf, 34, frame); + _mav_put_uint8_t(buf, 35, current); + _mav_put_uint8_t(buf, 36, autocontinue); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 37); +#else + mavlink_mission_item_t packet; + packet.param1 = param1; + packet.param2 = param2; + packet.param3 = param3; + packet.param4 = param4; + packet.x = x; + packet.y = y; + packet.z = z; + packet.seq = seq; + packet.command = command; + packet.target_system = target_system; + packet.target_component = target_component; + packet.frame = frame; + packet.current = current; + packet.autocontinue = autocontinue; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 37); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_MISSION_ITEM; + return mavlink_finalize_message(msg, system_id, component_id, 37, 254); +} + +/** + * @brief Pack a mission_item message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param target_system System ID + * @param target_component Component ID + * @param seq Sequence + * @param frame The coordinate system of the MISSION. see MAV_FRAME in mavlink_types.h + * @param command The scheduled action for the MISSION. see MAV_CMD in common.xml MAVLink specs + * @param current false:0, true:1 + * @param autocontinue autocontinue to next wp + * @param param1 PARAM1 / For NAV command MISSIONs: Radius in which the MISSION is accepted as reached, in meters + * @param param2 PARAM2 / For NAV command MISSIONs: Time that the MAV should stay inside the PARAM1 radius before advancing, in milliseconds + * @param param3 PARAM3 / For LOITER command MISSIONs: Orbit to circle around the MISSION, in meters. If positive the orbit direction should be clockwise, if negative the orbit direction should be counter-clockwise. + * @param param4 PARAM4 / For NAV and LOITER command MISSIONs: Yaw orientation in degrees, [0..360] 0 = NORTH + * @param x PARAM5 / local: x position, global: latitude + * @param y PARAM6 / y position: global: longitude + * @param z PARAM7 / z position: global: altitude + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_mission_item_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, uint16_t seq, uint8_t frame, uint16_t command, uint8_t current, uint8_t autocontinue, float param1, float param2, float param3, float param4, float x, float y, float z) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[37]; + _mav_put_float(buf, 0, param1); + _mav_put_float(buf, 4, param2); + _mav_put_float(buf, 8, param3); + _mav_put_float(buf, 12, param4); + _mav_put_float(buf, 16, x); + _mav_put_float(buf, 20, y); + _mav_put_float(buf, 24, z); + _mav_put_uint16_t(buf, 28, seq); + _mav_put_uint16_t(buf, 30, command); + _mav_put_uint8_t(buf, 32, target_system); + _mav_put_uint8_t(buf, 33, target_component); + _mav_put_uint8_t(buf, 34, frame); + _mav_put_uint8_t(buf, 35, current); + _mav_put_uint8_t(buf, 36, autocontinue); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 37); +#else + mavlink_mission_item_t packet; + packet.param1 = param1; + packet.param2 = param2; + packet.param3 = param3; + packet.param4 = param4; + packet.x = x; + packet.y = y; + packet.z = z; + packet.seq = seq; + packet.command = command; + packet.target_system = target_system; + packet.target_component = target_component; + packet.frame = frame; + packet.current = current; + packet.autocontinue = autocontinue; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 37); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_MISSION_ITEM; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 37, 254); +} + +/** + * @brief Encode a mission_item struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param mission_item C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_mission_item_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_mission_item_t *mission_item) +{ + return mavlink_msg_mission_item_pack(system_id, component_id, msg, mission_item->target_system, mission_item->target_component, mission_item->seq, mission_item->frame, mission_item->command, mission_item->current, mission_item->autocontinue, mission_item->param1, mission_item->param2, mission_item->param3, mission_item->param4, mission_item->x, mission_item->y, mission_item->z); +} + +/** + * @brief Send a mission_item message + * @param chan MAVLink channel to send the message + * + * @param target_system System ID + * @param target_component Component ID + * @param seq Sequence + * @param frame The coordinate system of the MISSION. see MAV_FRAME in mavlink_types.h + * @param command The scheduled action for the MISSION. see MAV_CMD in common.xml MAVLink specs + * @param current false:0, true:1 + * @param autocontinue autocontinue to next wp + * @param param1 PARAM1 / For NAV command MISSIONs: Radius in which the MISSION is accepted as reached, in meters + * @param param2 PARAM2 / For NAV command MISSIONs: Time that the MAV should stay inside the PARAM1 radius before advancing, in milliseconds + * @param param3 PARAM3 / For LOITER command MISSIONs: Orbit to circle around the MISSION, in meters. If positive the orbit direction should be clockwise, if negative the orbit direction should be counter-clockwise. + * @param param4 PARAM4 / For NAV and LOITER command MISSIONs: Yaw orientation in degrees, [0..360] 0 = NORTH + * @param x PARAM5 / local: x position, global: latitude + * @param y PARAM6 / y position: global: longitude + * @param z PARAM7 / z position: global: altitude + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_mission_item_send(mavlink_channel_t chan, uint8_t target_system, uint8_t target_component, uint16_t seq, uint8_t frame, uint16_t command, uint8_t current, uint8_t autocontinue, float param1, float param2, float param3, float param4, float x, float y, float z) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[37]; + _mav_put_float(buf, 0, param1); + _mav_put_float(buf, 4, param2); + _mav_put_float(buf, 8, param3); + _mav_put_float(buf, 12, param4); + _mav_put_float(buf, 16, x); + _mav_put_float(buf, 20, y); + _mav_put_float(buf, 24, z); + _mav_put_uint16_t(buf, 28, seq); + _mav_put_uint16_t(buf, 30, command); + _mav_put_uint8_t(buf, 32, target_system); + _mav_put_uint8_t(buf, 33, target_component); + _mav_put_uint8_t(buf, 34, frame); + _mav_put_uint8_t(buf, 35, current); + _mav_put_uint8_t(buf, 36, autocontinue); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_MISSION_ITEM, buf, 37, 254); +#else + mavlink_mission_item_t packet; + packet.param1 = param1; + packet.param2 = param2; + packet.param3 = param3; + packet.param4 = param4; + packet.x = x; + packet.y = y; + packet.z = z; + packet.seq = seq; + packet.command = command; + packet.target_system = target_system; + packet.target_component = target_component; + packet.frame = frame; + packet.current = current; + packet.autocontinue = autocontinue; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_MISSION_ITEM, (const char *)&packet, 37, 254); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE MISSION_ITEM UNPACKING + + +/** + * @brief Get field target_system from mission_item message + * + * @return System ID + */ +static inline uint8_t mavlink_msg_mission_item_get_target_system(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 32); +} + +/** + * @brief Get field target_component from mission_item message + * + * @return Component ID + */ +static inline uint8_t mavlink_msg_mission_item_get_target_component(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 33); +} + +/** + * @brief Get field seq from mission_item message + * + * @return Sequence + */ +static inline uint16_t mavlink_msg_mission_item_get_seq(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 28); +} + +/** + * @brief Get field frame from mission_item message + * + * @return The coordinate system of the MISSION. see MAV_FRAME in mavlink_types.h + */ +static inline uint8_t mavlink_msg_mission_item_get_frame(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 34); +} + +/** + * @brief Get field command from mission_item message + * + * @return The scheduled action for the MISSION. see MAV_CMD in common.xml MAVLink specs + */ +static inline uint16_t mavlink_msg_mission_item_get_command(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 30); +} + +/** + * @brief Get field current from mission_item message + * + * @return false:0, true:1 + */ +static inline uint8_t mavlink_msg_mission_item_get_current(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 35); +} + +/** + * @brief Get field autocontinue from mission_item message + * + * @return autocontinue to next wp + */ +static inline uint8_t mavlink_msg_mission_item_get_autocontinue(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 36); +} + +/** + * @brief Get field param1 from mission_item message + * + * @return PARAM1 / For NAV command MISSIONs: Radius in which the MISSION is accepted as reached, in meters + */ +static inline float mavlink_msg_mission_item_get_param1(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 0); +} + +/** + * @brief Get field param2 from mission_item message + * + * @return PARAM2 / For NAV command MISSIONs: Time that the MAV should stay inside the PARAM1 radius before advancing, in milliseconds + */ +static inline float mavlink_msg_mission_item_get_param2(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 4); +} + +/** + * @brief Get field param3 from mission_item message + * + * @return PARAM3 / For LOITER command MISSIONs: Orbit to circle around the MISSION, in meters. If positive the orbit direction should be clockwise, if negative the orbit direction should be counter-clockwise. + */ +static inline float mavlink_msg_mission_item_get_param3(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 8); +} + +/** + * @brief Get field param4 from mission_item message + * + * @return PARAM4 / For NAV and LOITER command MISSIONs: Yaw orientation in degrees, [0..360] 0 = NORTH + */ +static inline float mavlink_msg_mission_item_get_param4(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 12); +} + +/** + * @brief Get field x from mission_item message + * + * @return PARAM5 / local: x position, global: latitude + */ +static inline float mavlink_msg_mission_item_get_x(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 16); +} + +/** + * @brief Get field y from mission_item message + * + * @return PARAM6 / y position: global: longitude + */ +static inline float mavlink_msg_mission_item_get_y(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 20); +} + +/** + * @brief Get field z from mission_item message + * + * @return PARAM7 / z position: global: altitude + */ +static inline float mavlink_msg_mission_item_get_z(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 24); +} + +/** + * @brief Decode a mission_item message into a struct + * + * @param msg The message to decode + * @param mission_item C-struct to decode the message contents into + */ +static inline void mavlink_msg_mission_item_decode(const mavlink_message_t *msg, mavlink_mission_item_t *mission_item) +{ +#if MAVLINK_NEED_BYTE_SWAP + mission_item->param1 = mavlink_msg_mission_item_get_param1(msg); + mission_item->param2 = mavlink_msg_mission_item_get_param2(msg); + mission_item->param3 = mavlink_msg_mission_item_get_param3(msg); + mission_item->param4 = mavlink_msg_mission_item_get_param4(msg); + mission_item->x = mavlink_msg_mission_item_get_x(msg); + mission_item->y = mavlink_msg_mission_item_get_y(msg); + mission_item->z = mavlink_msg_mission_item_get_z(msg); + mission_item->seq = mavlink_msg_mission_item_get_seq(msg); + mission_item->command = mavlink_msg_mission_item_get_command(msg); + mission_item->target_system = mavlink_msg_mission_item_get_target_system(msg); + mission_item->target_component = mavlink_msg_mission_item_get_target_component(msg); + mission_item->frame = mavlink_msg_mission_item_get_frame(msg); + mission_item->current = mavlink_msg_mission_item_get_current(msg); + mission_item->autocontinue = mavlink_msg_mission_item_get_autocontinue(msg); +#else + memcpy(mission_item, _MAV_PAYLOAD(msg), 37); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_item_reached.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_item_reached.h new file mode 100644 index 000000000..a5b485f80 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_item_reached.h @@ -0,0 +1,144 @@ +// MESSAGE MISSION_ITEM_REACHED PACKING + +#define MAVLINK_MSG_ID_MISSION_ITEM_REACHED 46 + +typedef struct __mavlink_mission_item_reached_t { + uint16_t seq; ///< Sequence +} mavlink_mission_item_reached_t; + +#define MAVLINK_MSG_ID_MISSION_ITEM_REACHED_LEN 2 +#define MAVLINK_MSG_ID_46_LEN 2 + + +#define MAVLINK_MESSAGE_INFO_MISSION_ITEM_REACHED \ + { \ + "MISSION_ITEM_REACHED", \ + 1, \ + { \ + { "seq", NULL, MAVLINK_TYPE_UINT16_T, 0, 0, offsetof(mavlink_mission_item_reached_t, seq) }, \ + } \ + } + + +/** + * @brief Pack a mission_item_reached message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param seq Sequence + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_mission_item_reached_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint16_t seq) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[2]; + _mav_put_uint16_t(buf, 0, seq); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 2); +#else + mavlink_mission_item_reached_t packet; + packet.seq = seq; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 2); +#endif + + msg->msgid = MAVLINK_MSG_ID_MISSION_ITEM_REACHED; + return mavlink_finalize_message(msg, system_id, component_id, 2, 11); +} + +/** + * @brief Pack a mission_item_reached message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param seq Sequence + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_mission_item_reached_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint16_t seq) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[2]; + _mav_put_uint16_t(buf, 0, seq); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 2); +#else + mavlink_mission_item_reached_t packet; + packet.seq = seq; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 2); +#endif + + msg->msgid = MAVLINK_MSG_ID_MISSION_ITEM_REACHED; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 2, 11); +} + +/** + * @brief Encode a mission_item_reached struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param mission_item_reached C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_mission_item_reached_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_mission_item_reached_t *mission_item_reached) +{ + return mavlink_msg_mission_item_reached_pack(system_id, component_id, msg, mission_item_reached->seq); +} + +/** + * @brief Send a mission_item_reached message + * @param chan MAVLink channel to send the message + * + * @param seq Sequence + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_mission_item_reached_send(mavlink_channel_t chan, uint16_t seq) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[2]; + _mav_put_uint16_t(buf, 0, seq); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_MISSION_ITEM_REACHED, buf, 2, 11); +#else + mavlink_mission_item_reached_t packet; + packet.seq = seq; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_MISSION_ITEM_REACHED, (const char *)&packet, 2, 11); +#endif +} + +#endif + +// MESSAGE MISSION_ITEM_REACHED UNPACKING + + +/** + * @brief Get field seq from mission_item_reached message + * + * @return Sequence + */ +static inline uint16_t mavlink_msg_mission_item_reached_get_seq(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 0); +} + +/** + * @brief Decode a mission_item_reached message into a struct + * + * @param msg The message to decode + * @param mission_item_reached C-struct to decode the message contents into + */ +static inline void mavlink_msg_mission_item_reached_decode(const mavlink_message_t *msg, mavlink_mission_item_reached_t *mission_item_reached) +{ +#if MAVLINK_NEED_BYTE_SWAP + mission_item_reached->seq = mavlink_msg_mission_item_reached_get_seq(msg); +#else + memcpy(mission_item_reached, _MAV_PAYLOAD(msg), 2); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_request.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_request.h new file mode 100644 index 000000000..71aa7be26 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_request.h @@ -0,0 +1,188 @@ +// MESSAGE MISSION_REQUEST PACKING + +#define MAVLINK_MSG_ID_MISSION_REQUEST 40 + +typedef struct __mavlink_mission_request_t { + uint16_t seq; ///< Sequence + uint8_t target_system; ///< System ID + uint8_t target_component; ///< Component ID +} mavlink_mission_request_t; + +#define MAVLINK_MSG_ID_MISSION_REQUEST_LEN 4 +#define MAVLINK_MSG_ID_40_LEN 4 + + +#define MAVLINK_MESSAGE_INFO_MISSION_REQUEST \ + { \ + "MISSION_REQUEST", \ + 3, \ + { \ + { "seq", NULL, MAVLINK_TYPE_UINT16_T, 0, 0, offsetof(mavlink_mission_request_t, seq) }, \ + { "target_system", NULL, MAVLINK_TYPE_UINT8_T, 0, 2, offsetof(mavlink_mission_request_t, target_system) }, \ + { "target_component", NULL, MAVLINK_TYPE_UINT8_T, 0, 3, offsetof(mavlink_mission_request_t, target_component) }, \ + } \ + } + + +/** + * @brief Pack a mission_request message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param target_system System ID + * @param target_component Component ID + * @param seq Sequence + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_mission_request_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, uint16_t seq) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[4]; + _mav_put_uint16_t(buf, 0, seq); + _mav_put_uint8_t(buf, 2, target_system); + _mav_put_uint8_t(buf, 3, target_component); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 4); +#else + mavlink_mission_request_t packet; + packet.seq = seq; + packet.target_system = target_system; + packet.target_component = target_component; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 4); +#endif + + msg->msgid = MAVLINK_MSG_ID_MISSION_REQUEST; + return mavlink_finalize_message(msg, system_id, component_id, 4, 230); +} + +/** + * @brief Pack a mission_request message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param target_system System ID + * @param target_component Component ID + * @param seq Sequence + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_mission_request_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, uint16_t seq) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[4]; + _mav_put_uint16_t(buf, 0, seq); + _mav_put_uint8_t(buf, 2, target_system); + _mav_put_uint8_t(buf, 3, target_component); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 4); +#else + mavlink_mission_request_t packet; + packet.seq = seq; + packet.target_system = target_system; + packet.target_component = target_component; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 4); +#endif + + msg->msgid = MAVLINK_MSG_ID_MISSION_REQUEST; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 4, 230); +} + +/** + * @brief Encode a mission_request struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param mission_request C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_mission_request_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_mission_request_t *mission_request) +{ + return mavlink_msg_mission_request_pack(system_id, component_id, msg, mission_request->target_system, mission_request->target_component, mission_request->seq); +} + +/** + * @brief Send a mission_request message + * @param chan MAVLink channel to send the message + * + * @param target_system System ID + * @param target_component Component ID + * @param seq Sequence + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_mission_request_send(mavlink_channel_t chan, uint8_t target_system, uint8_t target_component, uint16_t seq) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[4]; + _mav_put_uint16_t(buf, 0, seq); + _mav_put_uint8_t(buf, 2, target_system); + _mav_put_uint8_t(buf, 3, target_component); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_MISSION_REQUEST, buf, 4, 230); +#else + mavlink_mission_request_t packet; + packet.seq = seq; + packet.target_system = target_system; + packet.target_component = target_component; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_MISSION_REQUEST, (const char *)&packet, 4, 230); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE MISSION_REQUEST UNPACKING + + +/** + * @brief Get field target_system from mission_request message + * + * @return System ID + */ +static inline uint8_t mavlink_msg_mission_request_get_target_system(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 2); +} + +/** + * @brief Get field target_component from mission_request message + * + * @return Component ID + */ +static inline uint8_t mavlink_msg_mission_request_get_target_component(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 3); +} + +/** + * @brief Get field seq from mission_request message + * + * @return Sequence + */ +static inline uint16_t mavlink_msg_mission_request_get_seq(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 0); +} + +/** + * @brief Decode a mission_request message into a struct + * + * @param msg The message to decode + * @param mission_request C-struct to decode the message contents into + */ +static inline void mavlink_msg_mission_request_decode(const mavlink_message_t *msg, mavlink_mission_request_t *mission_request) +{ +#if MAVLINK_NEED_BYTE_SWAP + mission_request->seq = mavlink_msg_mission_request_get_seq(msg); + mission_request->target_system = mavlink_msg_mission_request_get_target_system(msg); + mission_request->target_component = mavlink_msg_mission_request_get_target_component(msg); +#else + memcpy(mission_request, _MAV_PAYLOAD(msg), 4); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_request_list.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_request_list.h new file mode 100644 index 000000000..d7492f57b --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_request_list.h @@ -0,0 +1,166 @@ +// MESSAGE MISSION_REQUEST_LIST PACKING + +#define MAVLINK_MSG_ID_MISSION_REQUEST_LIST 43 + +typedef struct __mavlink_mission_request_list_t { + uint8_t target_system; ///< System ID + uint8_t target_component; ///< Component ID +} mavlink_mission_request_list_t; + +#define MAVLINK_MSG_ID_MISSION_REQUEST_LIST_LEN 2 +#define MAVLINK_MSG_ID_43_LEN 2 + + +#define MAVLINK_MESSAGE_INFO_MISSION_REQUEST_LIST \ + { \ + "MISSION_REQUEST_LIST", \ + 2, \ + { \ + { "target_system", NULL, MAVLINK_TYPE_UINT8_T, 0, 0, offsetof(mavlink_mission_request_list_t, target_system) }, \ + { "target_component", NULL, MAVLINK_TYPE_UINT8_T, 0, 1, offsetof(mavlink_mission_request_list_t, target_component) }, \ + } \ + } + + +/** + * @brief Pack a mission_request_list message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param target_system System ID + * @param target_component Component ID + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_mission_request_list_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[2]; + _mav_put_uint8_t(buf, 0, target_system); + _mav_put_uint8_t(buf, 1, target_component); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 2); +#else + mavlink_mission_request_list_t packet; + packet.target_system = target_system; + packet.target_component = target_component; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 2); +#endif + + msg->msgid = MAVLINK_MSG_ID_MISSION_REQUEST_LIST; + return mavlink_finalize_message(msg, system_id, component_id, 2, 132); +} + +/** + * @brief Pack a mission_request_list message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param target_system System ID + * @param target_component Component ID + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_mission_request_list_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[2]; + _mav_put_uint8_t(buf, 0, target_system); + _mav_put_uint8_t(buf, 1, target_component); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 2); +#else + mavlink_mission_request_list_t packet; + packet.target_system = target_system; + packet.target_component = target_component; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 2); +#endif + + msg->msgid = MAVLINK_MSG_ID_MISSION_REQUEST_LIST; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 2, 132); +} + +/** + * @brief Encode a mission_request_list struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param mission_request_list C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_mission_request_list_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_mission_request_list_t *mission_request_list) +{ + return mavlink_msg_mission_request_list_pack(system_id, component_id, msg, mission_request_list->target_system, mission_request_list->target_component); +} + +/** + * @brief Send a mission_request_list message + * @param chan MAVLink channel to send the message + * + * @param target_system System ID + * @param target_component Component ID + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_mission_request_list_send(mavlink_channel_t chan, uint8_t target_system, uint8_t target_component) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[2]; + _mav_put_uint8_t(buf, 0, target_system); + _mav_put_uint8_t(buf, 1, target_component); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_MISSION_REQUEST_LIST, buf, 2, 132); +#else + mavlink_mission_request_list_t packet; + packet.target_system = target_system; + packet.target_component = target_component; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_MISSION_REQUEST_LIST, (const char *)&packet, 2, 132); +#endif +} + +#endif + +// MESSAGE MISSION_REQUEST_LIST UNPACKING + + +/** + * @brief Get field target_system from mission_request_list message + * + * @return System ID + */ +static inline uint8_t mavlink_msg_mission_request_list_get_target_system(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 0); +} + +/** + * @brief Get field target_component from mission_request_list message + * + * @return Component ID + */ +static inline uint8_t mavlink_msg_mission_request_list_get_target_component(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 1); +} + +/** + * @brief Decode a mission_request_list message into a struct + * + * @param msg The message to decode + * @param mission_request_list C-struct to decode the message contents into + */ +static inline void mavlink_msg_mission_request_list_decode(const mavlink_message_t *msg, mavlink_mission_request_list_t *mission_request_list) +{ +#if MAVLINK_NEED_BYTE_SWAP + mission_request_list->target_system = mavlink_msg_mission_request_list_get_target_system(msg); + mission_request_list->target_component = mavlink_msg_mission_request_list_get_target_component(msg); +#else + memcpy(mission_request_list, _MAV_PAYLOAD(msg), 2); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_request_partial_list.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_request_partial_list.h new file mode 100644 index 000000000..6588109cc --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_request_partial_list.h @@ -0,0 +1,210 @@ +// MESSAGE MISSION_REQUEST_PARTIAL_LIST PACKING + +#define MAVLINK_MSG_ID_MISSION_REQUEST_PARTIAL_LIST 37 + +typedef struct __mavlink_mission_request_partial_list_t { + int16_t start_index; ///< Start index, 0 by default + int16_t end_index; ///< End index, -1 by default (-1: send list to end). Else a valid index of the list + uint8_t target_system; ///< System ID + uint8_t target_component; ///< Component ID +} mavlink_mission_request_partial_list_t; + +#define MAVLINK_MSG_ID_MISSION_REQUEST_PARTIAL_LIST_LEN 6 +#define MAVLINK_MSG_ID_37_LEN 6 + + +#define MAVLINK_MESSAGE_INFO_MISSION_REQUEST_PARTIAL_LIST \ + { \ + "MISSION_REQUEST_PARTIAL_LIST", \ + 4, \ + { \ + { "start_index", NULL, MAVLINK_TYPE_INT16_T, 0, 0, offsetof(mavlink_mission_request_partial_list_t, start_index) }, \ + { "end_index", NULL, MAVLINK_TYPE_INT16_T, 0, 2, offsetof(mavlink_mission_request_partial_list_t, end_index) }, \ + { "target_system", NULL, MAVLINK_TYPE_UINT8_T, 0, 4, offsetof(mavlink_mission_request_partial_list_t, target_system) }, \ + { "target_component", NULL, MAVLINK_TYPE_UINT8_T, 0, 5, offsetof(mavlink_mission_request_partial_list_t, target_component) }, \ + } \ + } + + +/** + * @brief Pack a mission_request_partial_list message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param target_system System ID + * @param target_component Component ID + * @param start_index Start index, 0 by default + * @param end_index End index, -1 by default (-1: send list to end). Else a valid index of the list + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_mission_request_partial_list_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, int16_t start_index, int16_t end_index) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[6]; + _mav_put_int16_t(buf, 0, start_index); + _mav_put_int16_t(buf, 2, end_index); + _mav_put_uint8_t(buf, 4, target_system); + _mav_put_uint8_t(buf, 5, target_component); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 6); +#else + mavlink_mission_request_partial_list_t packet; + packet.start_index = start_index; + packet.end_index = end_index; + packet.target_system = target_system; + packet.target_component = target_component; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 6); +#endif + + msg->msgid = MAVLINK_MSG_ID_MISSION_REQUEST_PARTIAL_LIST; + return mavlink_finalize_message(msg, system_id, component_id, 6, 212); +} + +/** + * @brief Pack a mission_request_partial_list message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param target_system System ID + * @param target_component Component ID + * @param start_index Start index, 0 by default + * @param end_index End index, -1 by default (-1: send list to end). Else a valid index of the list + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_mission_request_partial_list_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, int16_t start_index, int16_t end_index) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[6]; + _mav_put_int16_t(buf, 0, start_index); + _mav_put_int16_t(buf, 2, end_index); + _mav_put_uint8_t(buf, 4, target_system); + _mav_put_uint8_t(buf, 5, target_component); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 6); +#else + mavlink_mission_request_partial_list_t packet; + packet.start_index = start_index; + packet.end_index = end_index; + packet.target_system = target_system; + packet.target_component = target_component; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 6); +#endif + + msg->msgid = MAVLINK_MSG_ID_MISSION_REQUEST_PARTIAL_LIST; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 6, 212); +} + +/** + * @brief Encode a mission_request_partial_list struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param mission_request_partial_list C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_mission_request_partial_list_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_mission_request_partial_list_t *mission_request_partial_list) +{ + return mavlink_msg_mission_request_partial_list_pack(system_id, component_id, msg, mission_request_partial_list->target_system, mission_request_partial_list->target_component, mission_request_partial_list->start_index, mission_request_partial_list->end_index); +} + +/** + * @brief Send a mission_request_partial_list message + * @param chan MAVLink channel to send the message + * + * @param target_system System ID + * @param target_component Component ID + * @param start_index Start index, 0 by default + * @param end_index End index, -1 by default (-1: send list to end). Else a valid index of the list + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_mission_request_partial_list_send(mavlink_channel_t chan, uint8_t target_system, uint8_t target_component, int16_t start_index, int16_t end_index) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[6]; + _mav_put_int16_t(buf, 0, start_index); + _mav_put_int16_t(buf, 2, end_index); + _mav_put_uint8_t(buf, 4, target_system); + _mav_put_uint8_t(buf, 5, target_component); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_MISSION_REQUEST_PARTIAL_LIST, buf, 6, 212); +#else + mavlink_mission_request_partial_list_t packet; + packet.start_index = start_index; + packet.end_index = end_index; + packet.target_system = target_system; + packet.target_component = target_component; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_MISSION_REQUEST_PARTIAL_LIST, (const char *)&packet, 6, 212); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE MISSION_REQUEST_PARTIAL_LIST UNPACKING + + +/** + * @brief Get field target_system from mission_request_partial_list message + * + * @return System ID + */ +static inline uint8_t mavlink_msg_mission_request_partial_list_get_target_system(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 4); +} + +/** + * @brief Get field target_component from mission_request_partial_list message + * + * @return Component ID + */ +static inline uint8_t mavlink_msg_mission_request_partial_list_get_target_component(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 5); +} + +/** + * @brief Get field start_index from mission_request_partial_list message + * + * @return Start index, 0 by default + */ +static inline int16_t mavlink_msg_mission_request_partial_list_get_start_index(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 0); +} + +/** + * @brief Get field end_index from mission_request_partial_list message + * + * @return End index, -1 by default (-1: send list to end). Else a valid index of the list + */ +static inline int16_t mavlink_msg_mission_request_partial_list_get_end_index(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 2); +} + +/** + * @brief Decode a mission_request_partial_list message into a struct + * + * @param msg The message to decode + * @param mission_request_partial_list C-struct to decode the message contents into + */ +static inline void mavlink_msg_mission_request_partial_list_decode(const mavlink_message_t *msg, mavlink_mission_request_partial_list_t *mission_request_partial_list) +{ +#if MAVLINK_NEED_BYTE_SWAP + mission_request_partial_list->start_index = mavlink_msg_mission_request_partial_list_get_start_index(msg); + mission_request_partial_list->end_index = mavlink_msg_mission_request_partial_list_get_end_index(msg); + mission_request_partial_list->target_system = mavlink_msg_mission_request_partial_list_get_target_system(msg); + mission_request_partial_list->target_component = mavlink_msg_mission_request_partial_list_get_target_component(msg); +#else + memcpy(mission_request_partial_list, _MAV_PAYLOAD(msg), 6); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_set_current.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_set_current.h new file mode 100644 index 000000000..c45d7ae85 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_set_current.h @@ -0,0 +1,188 @@ +// MESSAGE MISSION_SET_CURRENT PACKING + +#define MAVLINK_MSG_ID_MISSION_SET_CURRENT 41 + +typedef struct __mavlink_mission_set_current_t { + uint16_t seq; ///< Sequence + uint8_t target_system; ///< System ID + uint8_t target_component; ///< Component ID +} mavlink_mission_set_current_t; + +#define MAVLINK_MSG_ID_MISSION_SET_CURRENT_LEN 4 +#define MAVLINK_MSG_ID_41_LEN 4 + + +#define MAVLINK_MESSAGE_INFO_MISSION_SET_CURRENT \ + { \ + "MISSION_SET_CURRENT", \ + 3, \ + { \ + { "seq", NULL, MAVLINK_TYPE_UINT16_T, 0, 0, offsetof(mavlink_mission_set_current_t, seq) }, \ + { "target_system", NULL, MAVLINK_TYPE_UINT8_T, 0, 2, offsetof(mavlink_mission_set_current_t, target_system) }, \ + { "target_component", NULL, MAVLINK_TYPE_UINT8_T, 0, 3, offsetof(mavlink_mission_set_current_t, target_component) }, \ + } \ + } + + +/** + * @brief Pack a mission_set_current message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param target_system System ID + * @param target_component Component ID + * @param seq Sequence + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_mission_set_current_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, uint16_t seq) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[4]; + _mav_put_uint16_t(buf, 0, seq); + _mav_put_uint8_t(buf, 2, target_system); + _mav_put_uint8_t(buf, 3, target_component); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 4); +#else + mavlink_mission_set_current_t packet; + packet.seq = seq; + packet.target_system = target_system; + packet.target_component = target_component; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 4); +#endif + + msg->msgid = MAVLINK_MSG_ID_MISSION_SET_CURRENT; + return mavlink_finalize_message(msg, system_id, component_id, 4, 28); +} + +/** + * @brief Pack a mission_set_current message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param target_system System ID + * @param target_component Component ID + * @param seq Sequence + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_mission_set_current_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, uint16_t seq) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[4]; + _mav_put_uint16_t(buf, 0, seq); + _mav_put_uint8_t(buf, 2, target_system); + _mav_put_uint8_t(buf, 3, target_component); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 4); +#else + mavlink_mission_set_current_t packet; + packet.seq = seq; + packet.target_system = target_system; + packet.target_component = target_component; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 4); +#endif + + msg->msgid = MAVLINK_MSG_ID_MISSION_SET_CURRENT; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 4, 28); +} + +/** + * @brief Encode a mission_set_current struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param mission_set_current C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_mission_set_current_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_mission_set_current_t *mission_set_current) +{ + return mavlink_msg_mission_set_current_pack(system_id, component_id, msg, mission_set_current->target_system, mission_set_current->target_component, mission_set_current->seq); +} + +/** + * @brief Send a mission_set_current message + * @param chan MAVLink channel to send the message + * + * @param target_system System ID + * @param target_component Component ID + * @param seq Sequence + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_mission_set_current_send(mavlink_channel_t chan, uint8_t target_system, uint8_t target_component, uint16_t seq) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[4]; + _mav_put_uint16_t(buf, 0, seq); + _mav_put_uint8_t(buf, 2, target_system); + _mav_put_uint8_t(buf, 3, target_component); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_MISSION_SET_CURRENT, buf, 4, 28); +#else + mavlink_mission_set_current_t packet; + packet.seq = seq; + packet.target_system = target_system; + packet.target_component = target_component; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_MISSION_SET_CURRENT, (const char *)&packet, 4, 28); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE MISSION_SET_CURRENT UNPACKING + + +/** + * @brief Get field target_system from mission_set_current message + * + * @return System ID + */ +static inline uint8_t mavlink_msg_mission_set_current_get_target_system(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 2); +} + +/** + * @brief Get field target_component from mission_set_current message + * + * @return Component ID + */ +static inline uint8_t mavlink_msg_mission_set_current_get_target_component(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 3); +} + +/** + * @brief Get field seq from mission_set_current message + * + * @return Sequence + */ +static inline uint16_t mavlink_msg_mission_set_current_get_seq(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 0); +} + +/** + * @brief Decode a mission_set_current message into a struct + * + * @param msg The message to decode + * @param mission_set_current C-struct to decode the message contents into + */ +static inline void mavlink_msg_mission_set_current_decode(const mavlink_message_t *msg, mavlink_mission_set_current_t *mission_set_current) +{ +#if MAVLINK_NEED_BYTE_SWAP + mission_set_current->seq = mavlink_msg_mission_set_current_get_seq(msg); + mission_set_current->target_system = mavlink_msg_mission_set_current_get_target_system(msg); + mission_set_current->target_component = mavlink_msg_mission_set_current_get_target_component(msg); +#else + memcpy(mission_set_current, _MAV_PAYLOAD(msg), 4); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_write_partial_list.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_write_partial_list.h new file mode 100644 index 000000000..dad0fb257 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_mission_write_partial_list.h @@ -0,0 +1,210 @@ +// MESSAGE MISSION_WRITE_PARTIAL_LIST PACKING + +#define MAVLINK_MSG_ID_MISSION_WRITE_PARTIAL_LIST 38 + +typedef struct __mavlink_mission_write_partial_list_t { + int16_t start_index; ///< Start index, 0 by default and smaller / equal to the largest index of the current onboard list. + int16_t end_index; ///< End index, equal or greater than start index. + uint8_t target_system; ///< System ID + uint8_t target_component; ///< Component ID +} mavlink_mission_write_partial_list_t; + +#define MAVLINK_MSG_ID_MISSION_WRITE_PARTIAL_LIST_LEN 6 +#define MAVLINK_MSG_ID_38_LEN 6 + + +#define MAVLINK_MESSAGE_INFO_MISSION_WRITE_PARTIAL_LIST \ + { \ + "MISSION_WRITE_PARTIAL_LIST", \ + 4, \ + { \ + { "start_index", NULL, MAVLINK_TYPE_INT16_T, 0, 0, offsetof(mavlink_mission_write_partial_list_t, start_index) }, \ + { "end_index", NULL, MAVLINK_TYPE_INT16_T, 0, 2, offsetof(mavlink_mission_write_partial_list_t, end_index) }, \ + { "target_system", NULL, MAVLINK_TYPE_UINT8_T, 0, 4, offsetof(mavlink_mission_write_partial_list_t, target_system) }, \ + { "target_component", NULL, MAVLINK_TYPE_UINT8_T, 0, 5, offsetof(mavlink_mission_write_partial_list_t, target_component) }, \ + } \ + } + + +/** + * @brief Pack a mission_write_partial_list message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param target_system System ID + * @param target_component Component ID + * @param start_index Start index, 0 by default and smaller / equal to the largest index of the current onboard list. + * @param end_index End index, equal or greater than start index. + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_mission_write_partial_list_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, int16_t start_index, int16_t end_index) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[6]; + _mav_put_int16_t(buf, 0, start_index); + _mav_put_int16_t(buf, 2, end_index); + _mav_put_uint8_t(buf, 4, target_system); + _mav_put_uint8_t(buf, 5, target_component); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 6); +#else + mavlink_mission_write_partial_list_t packet; + packet.start_index = start_index; + packet.end_index = end_index; + packet.target_system = target_system; + packet.target_component = target_component; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 6); +#endif + + msg->msgid = MAVLINK_MSG_ID_MISSION_WRITE_PARTIAL_LIST; + return mavlink_finalize_message(msg, system_id, component_id, 6, 9); +} + +/** + * @brief Pack a mission_write_partial_list message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param target_system System ID + * @param target_component Component ID + * @param start_index Start index, 0 by default and smaller / equal to the largest index of the current onboard list. + * @param end_index End index, equal or greater than start index. + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_mission_write_partial_list_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, int16_t start_index, int16_t end_index) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[6]; + _mav_put_int16_t(buf, 0, start_index); + _mav_put_int16_t(buf, 2, end_index); + _mav_put_uint8_t(buf, 4, target_system); + _mav_put_uint8_t(buf, 5, target_component); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 6); +#else + mavlink_mission_write_partial_list_t packet; + packet.start_index = start_index; + packet.end_index = end_index; + packet.target_system = target_system; + packet.target_component = target_component; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 6); +#endif + + msg->msgid = MAVLINK_MSG_ID_MISSION_WRITE_PARTIAL_LIST; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 6, 9); +} + +/** + * @brief Encode a mission_write_partial_list struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param mission_write_partial_list C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_mission_write_partial_list_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_mission_write_partial_list_t *mission_write_partial_list) +{ + return mavlink_msg_mission_write_partial_list_pack(system_id, component_id, msg, mission_write_partial_list->target_system, mission_write_partial_list->target_component, mission_write_partial_list->start_index, mission_write_partial_list->end_index); +} + +/** + * @brief Send a mission_write_partial_list message + * @param chan MAVLink channel to send the message + * + * @param target_system System ID + * @param target_component Component ID + * @param start_index Start index, 0 by default and smaller / equal to the largest index of the current onboard list. + * @param end_index End index, equal or greater than start index. + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_mission_write_partial_list_send(mavlink_channel_t chan, uint8_t target_system, uint8_t target_component, int16_t start_index, int16_t end_index) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[6]; + _mav_put_int16_t(buf, 0, start_index); + _mav_put_int16_t(buf, 2, end_index); + _mav_put_uint8_t(buf, 4, target_system); + _mav_put_uint8_t(buf, 5, target_component); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_MISSION_WRITE_PARTIAL_LIST, buf, 6, 9); +#else + mavlink_mission_write_partial_list_t packet; + packet.start_index = start_index; + packet.end_index = end_index; + packet.target_system = target_system; + packet.target_component = target_component; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_MISSION_WRITE_PARTIAL_LIST, (const char *)&packet, 6, 9); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE MISSION_WRITE_PARTIAL_LIST UNPACKING + + +/** + * @brief Get field target_system from mission_write_partial_list message + * + * @return System ID + */ +static inline uint8_t mavlink_msg_mission_write_partial_list_get_target_system(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 4); +} + +/** + * @brief Get field target_component from mission_write_partial_list message + * + * @return Component ID + */ +static inline uint8_t mavlink_msg_mission_write_partial_list_get_target_component(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 5); +} + +/** + * @brief Get field start_index from mission_write_partial_list message + * + * @return Start index, 0 by default and smaller / equal to the largest index of the current onboard list. + */ +static inline int16_t mavlink_msg_mission_write_partial_list_get_start_index(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 0); +} + +/** + * @brief Get field end_index from mission_write_partial_list message + * + * @return End index, equal or greater than start index. + */ +static inline int16_t mavlink_msg_mission_write_partial_list_get_end_index(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 2); +} + +/** + * @brief Decode a mission_write_partial_list message into a struct + * + * @param msg The message to decode + * @param mission_write_partial_list C-struct to decode the message contents into + */ +static inline void mavlink_msg_mission_write_partial_list_decode(const mavlink_message_t *msg, mavlink_mission_write_partial_list_t *mission_write_partial_list) +{ +#if MAVLINK_NEED_BYTE_SWAP + mission_write_partial_list->start_index = mavlink_msg_mission_write_partial_list_get_start_index(msg); + mission_write_partial_list->end_index = mavlink_msg_mission_write_partial_list_get_end_index(msg); + mission_write_partial_list->target_system = mavlink_msg_mission_write_partial_list_get_target_system(msg); + mission_write_partial_list->target_component = mavlink_msg_mission_write_partial_list_get_target_component(msg); +#else + memcpy(mission_write_partial_list, _MAV_PAYLOAD(msg), 6); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_named_value_float.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_named_value_float.h new file mode 100644 index 000000000..bc64526c3 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_named_value_float.h @@ -0,0 +1,183 @@ +// MESSAGE NAMED_VALUE_FLOAT PACKING + +#define MAVLINK_MSG_ID_NAMED_VALUE_FLOAT 251 + +typedef struct __mavlink_named_value_float_t { + uint32_t time_boot_ms; ///< Timestamp (milliseconds since system boot) + float value; ///< Floating point value + char name[10]; ///< Name of the debug variable +} mavlink_named_value_float_t; + +#define MAVLINK_MSG_ID_NAMED_VALUE_FLOAT_LEN 18 +#define MAVLINK_MSG_ID_251_LEN 18 + +#define MAVLINK_MSG_NAMED_VALUE_FLOAT_FIELD_NAME_LEN 10 + +#define MAVLINK_MESSAGE_INFO_NAMED_VALUE_FLOAT \ + { \ + "NAMED_VALUE_FLOAT", \ + 3, \ + { \ + { "time_boot_ms", NULL, MAVLINK_TYPE_UINT32_T, 0, 0, offsetof(mavlink_named_value_float_t, time_boot_ms) }, \ + { "value", NULL, MAVLINK_TYPE_FLOAT, 0, 4, offsetof(mavlink_named_value_float_t, value) }, \ + { "name", NULL, MAVLINK_TYPE_CHAR, 10, 8, offsetof(mavlink_named_value_float_t, name) }, \ + } \ + } + + +/** + * @brief Pack a named_value_float message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param name Name of the debug variable + * @param value Floating point value + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_named_value_float_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint32_t time_boot_ms, const char *name, float value) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[18]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_float(buf, 4, value); + _mav_put_char_array(buf, 8, name, 10); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 18); +#else + mavlink_named_value_float_t packet; + packet.time_boot_ms = time_boot_ms; + packet.value = value; + mav_array_memcpy(packet.name, name, sizeof(char) * 10); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 18); +#endif + + msg->msgid = MAVLINK_MSG_ID_NAMED_VALUE_FLOAT; + return mavlink_finalize_message(msg, system_id, component_id, 18, 170); +} + +/** + * @brief Pack a named_value_float message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param name Name of the debug variable + * @param value Floating point value + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_named_value_float_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint32_t time_boot_ms, const char *name, float value) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[18]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_float(buf, 4, value); + _mav_put_char_array(buf, 8, name, 10); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 18); +#else + mavlink_named_value_float_t packet; + packet.time_boot_ms = time_boot_ms; + packet.value = value; + mav_array_memcpy(packet.name, name, sizeof(char) * 10); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 18); +#endif + + msg->msgid = MAVLINK_MSG_ID_NAMED_VALUE_FLOAT; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 18, 170); +} + +/** + * @brief Encode a named_value_float struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param named_value_float C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_named_value_float_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_named_value_float_t *named_value_float) +{ + return mavlink_msg_named_value_float_pack(system_id, component_id, msg, named_value_float->time_boot_ms, named_value_float->name, named_value_float->value); +} + +/** + * @brief Send a named_value_float message + * @param chan MAVLink channel to send the message + * + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param name Name of the debug variable + * @param value Floating point value + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_named_value_float_send(mavlink_channel_t chan, uint32_t time_boot_ms, const char *name, float value) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[18]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_float(buf, 4, value); + _mav_put_char_array(buf, 8, name, 10); + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_NAMED_VALUE_FLOAT, buf, 18, 170); +#else + mavlink_named_value_float_t packet; + packet.time_boot_ms = time_boot_ms; + packet.value = value; + mav_array_memcpy(packet.name, name, sizeof(char) * 10); + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_NAMED_VALUE_FLOAT, (const char *)&packet, 18, 170); +#endif +} + +#endif + +// MESSAGE NAMED_VALUE_FLOAT UNPACKING + + +/** + * @brief Get field time_boot_ms from named_value_float message + * + * @return Timestamp (milliseconds since system boot) + */ +static inline uint32_t mavlink_msg_named_value_float_get_time_boot_ms(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint32_t(msg, 0); +} + +/** + * @brief Get field name from named_value_float message + * + * @return Name of the debug variable + */ +static inline uint16_t mavlink_msg_named_value_float_get_name(const mavlink_message_t *msg, char *name) +{ + return _MAV_RETURN_char_array(msg, name, 10, 8); +} + +/** + * @brief Get field value from named_value_float message + * + * @return Floating point value + */ +static inline float mavlink_msg_named_value_float_get_value(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 4); +} + +/** + * @brief Decode a named_value_float message into a struct + * + * @param msg The message to decode + * @param named_value_float C-struct to decode the message contents into + */ +static inline void mavlink_msg_named_value_float_decode(const mavlink_message_t *msg, mavlink_named_value_float_t *named_value_float) +{ +#if MAVLINK_NEED_BYTE_SWAP + named_value_float->time_boot_ms = mavlink_msg_named_value_float_get_time_boot_ms(msg); + named_value_float->value = mavlink_msg_named_value_float_get_value(msg); + mavlink_msg_named_value_float_get_name(msg, named_value_float->name); +#else + memcpy(named_value_float, _MAV_PAYLOAD(msg), 18); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_named_value_int.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_named_value_int.h new file mode 100644 index 000000000..b067f7a20 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_named_value_int.h @@ -0,0 +1,183 @@ +// MESSAGE NAMED_VALUE_INT PACKING + +#define MAVLINK_MSG_ID_NAMED_VALUE_INT 252 + +typedef struct __mavlink_named_value_int_t { + uint32_t time_boot_ms; ///< Timestamp (milliseconds since system boot) + int32_t value; ///< Signed integer value + char name[10]; ///< Name of the debug variable +} mavlink_named_value_int_t; + +#define MAVLINK_MSG_ID_NAMED_VALUE_INT_LEN 18 +#define MAVLINK_MSG_ID_252_LEN 18 + +#define MAVLINK_MSG_NAMED_VALUE_INT_FIELD_NAME_LEN 10 + +#define MAVLINK_MESSAGE_INFO_NAMED_VALUE_INT \ + { \ + "NAMED_VALUE_INT", \ + 3, \ + { \ + { "time_boot_ms", NULL, MAVLINK_TYPE_UINT32_T, 0, 0, offsetof(mavlink_named_value_int_t, time_boot_ms) }, \ + { "value", NULL, MAVLINK_TYPE_INT32_T, 0, 4, offsetof(mavlink_named_value_int_t, value) }, \ + { "name", NULL, MAVLINK_TYPE_CHAR, 10, 8, offsetof(mavlink_named_value_int_t, name) }, \ + } \ + } + + +/** + * @brief Pack a named_value_int message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param name Name of the debug variable + * @param value Signed integer value + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_named_value_int_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint32_t time_boot_ms, const char *name, int32_t value) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[18]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_int32_t(buf, 4, value); + _mav_put_char_array(buf, 8, name, 10); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 18); +#else + mavlink_named_value_int_t packet; + packet.time_boot_ms = time_boot_ms; + packet.value = value; + mav_array_memcpy(packet.name, name, sizeof(char) * 10); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 18); +#endif + + msg->msgid = MAVLINK_MSG_ID_NAMED_VALUE_INT; + return mavlink_finalize_message(msg, system_id, component_id, 18, 44); +} + +/** + * @brief Pack a named_value_int message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param name Name of the debug variable + * @param value Signed integer value + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_named_value_int_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint32_t time_boot_ms, const char *name, int32_t value) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[18]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_int32_t(buf, 4, value); + _mav_put_char_array(buf, 8, name, 10); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 18); +#else + mavlink_named_value_int_t packet; + packet.time_boot_ms = time_boot_ms; + packet.value = value; + mav_array_memcpy(packet.name, name, sizeof(char) * 10); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 18); +#endif + + msg->msgid = MAVLINK_MSG_ID_NAMED_VALUE_INT; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 18, 44); +} + +/** + * @brief Encode a named_value_int struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param named_value_int C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_named_value_int_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_named_value_int_t *named_value_int) +{ + return mavlink_msg_named_value_int_pack(system_id, component_id, msg, named_value_int->time_boot_ms, named_value_int->name, named_value_int->value); +} + +/** + * @brief Send a named_value_int message + * @param chan MAVLink channel to send the message + * + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param name Name of the debug variable + * @param value Signed integer value + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_named_value_int_send(mavlink_channel_t chan, uint32_t time_boot_ms, const char *name, int32_t value) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[18]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_int32_t(buf, 4, value); + _mav_put_char_array(buf, 8, name, 10); + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_NAMED_VALUE_INT, buf, 18, 44); +#else + mavlink_named_value_int_t packet; + packet.time_boot_ms = time_boot_ms; + packet.value = value; + mav_array_memcpy(packet.name, name, sizeof(char) * 10); + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_NAMED_VALUE_INT, (const char *)&packet, 18, 44); +#endif +} + +#endif + +// MESSAGE NAMED_VALUE_INT UNPACKING + + +/** + * @brief Get field time_boot_ms from named_value_int message + * + * @return Timestamp (milliseconds since system boot) + */ +static inline uint32_t mavlink_msg_named_value_int_get_time_boot_ms(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint32_t(msg, 0); +} + +/** + * @brief Get field name from named_value_int message + * + * @return Name of the debug variable + */ +static inline uint16_t mavlink_msg_named_value_int_get_name(const mavlink_message_t *msg, char *name) +{ + return _MAV_RETURN_char_array(msg, name, 10, 8); +} + +/** + * @brief Get field value from named_value_int message + * + * @return Signed integer value + */ +static inline int32_t mavlink_msg_named_value_int_get_value(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int32_t(msg, 4); +} + +/** + * @brief Decode a named_value_int message into a struct + * + * @param msg The message to decode + * @param named_value_int C-struct to decode the message contents into + */ +static inline void mavlink_msg_named_value_int_decode(const mavlink_message_t *msg, mavlink_named_value_int_t *named_value_int) +{ +#if MAVLINK_NEED_BYTE_SWAP + named_value_int->time_boot_ms = mavlink_msg_named_value_int_get_time_boot_ms(msg); + named_value_int->value = mavlink_msg_named_value_int_get_value(msg); + mavlink_msg_named_value_int_get_name(msg, named_value_int->name); +#else + memcpy(named_value_int, _MAV_PAYLOAD(msg), 18); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_nav_controller_output.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_nav_controller_output.h new file mode 100644 index 000000000..25fcce698 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_nav_controller_output.h @@ -0,0 +1,298 @@ +// MESSAGE NAV_CONTROLLER_OUTPUT PACKING + +#define MAVLINK_MSG_ID_NAV_CONTROLLER_OUTPUT 62 + +typedef struct __mavlink_nav_controller_output_t { + float nav_roll; ///< Current desired roll in degrees + float nav_pitch; ///< Current desired pitch in degrees + float alt_error; ///< Current altitude error in meters + float aspd_error; ///< Current airspeed error in meters/second + float xtrack_error; ///< Current crosstrack error on x-y plane in meters + int16_t nav_bearing; ///< Current desired heading in degrees + int16_t target_bearing; ///< Bearing to current MISSION/target in degrees + uint16_t wp_dist; ///< Distance to active MISSION in meters +} mavlink_nav_controller_output_t; + +#define MAVLINK_MSG_ID_NAV_CONTROLLER_OUTPUT_LEN 26 +#define MAVLINK_MSG_ID_62_LEN 26 + + +#define MAVLINK_MESSAGE_INFO_NAV_CONTROLLER_OUTPUT \ + { \ + "NAV_CONTROLLER_OUTPUT", \ + 8, \ + { \ + { "nav_roll", NULL, MAVLINK_TYPE_FLOAT, 0, 0, offsetof(mavlink_nav_controller_output_t, nav_roll) }, \ + { "nav_pitch", NULL, MAVLINK_TYPE_FLOAT, 0, 4, offsetof(mavlink_nav_controller_output_t, nav_pitch) }, \ + { "alt_error", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_nav_controller_output_t, alt_error) }, \ + { "aspd_error", NULL, MAVLINK_TYPE_FLOAT, 0, 12, offsetof(mavlink_nav_controller_output_t, aspd_error) }, \ + { "xtrack_error", NULL, MAVLINK_TYPE_FLOAT, 0, 16, offsetof(mavlink_nav_controller_output_t, xtrack_error) }, \ + { "nav_bearing", NULL, MAVLINK_TYPE_INT16_T, 0, 20, offsetof(mavlink_nav_controller_output_t, nav_bearing) }, \ + { "target_bearing", NULL, MAVLINK_TYPE_INT16_T, 0, 22, offsetof(mavlink_nav_controller_output_t, target_bearing) }, \ + { "wp_dist", NULL, MAVLINK_TYPE_UINT16_T, 0, 24, offsetof(mavlink_nav_controller_output_t, wp_dist) }, \ + } \ + } + + +/** + * @brief Pack a nav_controller_output message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param nav_roll Current desired roll in degrees + * @param nav_pitch Current desired pitch in degrees + * @param nav_bearing Current desired heading in degrees + * @param target_bearing Bearing to current MISSION/target in degrees + * @param wp_dist Distance to active MISSION in meters + * @param alt_error Current altitude error in meters + * @param aspd_error Current airspeed error in meters/second + * @param xtrack_error Current crosstrack error on x-y plane in meters + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_nav_controller_output_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + float nav_roll, float nav_pitch, int16_t nav_bearing, int16_t target_bearing, uint16_t wp_dist, float alt_error, float aspd_error, float xtrack_error) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[26]; + _mav_put_float(buf, 0, nav_roll); + _mav_put_float(buf, 4, nav_pitch); + _mav_put_float(buf, 8, alt_error); + _mav_put_float(buf, 12, aspd_error); + _mav_put_float(buf, 16, xtrack_error); + _mav_put_int16_t(buf, 20, nav_bearing); + _mav_put_int16_t(buf, 22, target_bearing); + _mav_put_uint16_t(buf, 24, wp_dist); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 26); +#else + mavlink_nav_controller_output_t packet; + packet.nav_roll = nav_roll; + packet.nav_pitch = nav_pitch; + packet.alt_error = alt_error; + packet.aspd_error = aspd_error; + packet.xtrack_error = xtrack_error; + packet.nav_bearing = nav_bearing; + packet.target_bearing = target_bearing; + packet.wp_dist = wp_dist; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 26); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_NAV_CONTROLLER_OUTPUT; + return mavlink_finalize_message(msg, system_id, component_id, 26, 183); +} + +/** + * @brief Pack a nav_controller_output message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param nav_roll Current desired roll in degrees + * @param nav_pitch Current desired pitch in degrees + * @param nav_bearing Current desired heading in degrees + * @param target_bearing Bearing to current MISSION/target in degrees + * @param wp_dist Distance to active MISSION in meters + * @param alt_error Current altitude error in meters + * @param aspd_error Current airspeed error in meters/second + * @param xtrack_error Current crosstrack error on x-y plane in meters + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_nav_controller_output_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + float nav_roll, float nav_pitch, int16_t nav_bearing, int16_t target_bearing, uint16_t wp_dist, float alt_error, float aspd_error, float xtrack_error) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[26]; + _mav_put_float(buf, 0, nav_roll); + _mav_put_float(buf, 4, nav_pitch); + _mav_put_float(buf, 8, alt_error); + _mav_put_float(buf, 12, aspd_error); + _mav_put_float(buf, 16, xtrack_error); + _mav_put_int16_t(buf, 20, nav_bearing); + _mav_put_int16_t(buf, 22, target_bearing); + _mav_put_uint16_t(buf, 24, wp_dist); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 26); +#else + mavlink_nav_controller_output_t packet; + packet.nav_roll = nav_roll; + packet.nav_pitch = nav_pitch; + packet.alt_error = alt_error; + packet.aspd_error = aspd_error; + packet.xtrack_error = xtrack_error; + packet.nav_bearing = nav_bearing; + packet.target_bearing = target_bearing; + packet.wp_dist = wp_dist; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 26); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_NAV_CONTROLLER_OUTPUT; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 26, 183); +} + +/** + * @brief Encode a nav_controller_output struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param nav_controller_output C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_nav_controller_output_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_nav_controller_output_t *nav_controller_output) +{ + return mavlink_msg_nav_controller_output_pack(system_id, component_id, msg, nav_controller_output->nav_roll, nav_controller_output->nav_pitch, nav_controller_output->nav_bearing, nav_controller_output->target_bearing, nav_controller_output->wp_dist, nav_controller_output->alt_error, nav_controller_output->aspd_error, nav_controller_output->xtrack_error); +} + +/** + * @brief Send a nav_controller_output message + * @param chan MAVLink channel to send the message + * + * @param nav_roll Current desired roll in degrees + * @param nav_pitch Current desired pitch in degrees + * @param nav_bearing Current desired heading in degrees + * @param target_bearing Bearing to current MISSION/target in degrees + * @param wp_dist Distance to active MISSION in meters + * @param alt_error Current altitude error in meters + * @param aspd_error Current airspeed error in meters/second + * @param xtrack_error Current crosstrack error on x-y plane in meters + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_nav_controller_output_send(mavlink_channel_t chan, float nav_roll, float nav_pitch, int16_t nav_bearing, int16_t target_bearing, uint16_t wp_dist, float alt_error, float aspd_error, float xtrack_error) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[26]; + _mav_put_float(buf, 0, nav_roll); + _mav_put_float(buf, 4, nav_pitch); + _mav_put_float(buf, 8, alt_error); + _mav_put_float(buf, 12, aspd_error); + _mav_put_float(buf, 16, xtrack_error); + _mav_put_int16_t(buf, 20, nav_bearing); + _mav_put_int16_t(buf, 22, target_bearing); + _mav_put_uint16_t(buf, 24, wp_dist); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_NAV_CONTROLLER_OUTPUT, buf, 26, 183); +#else + mavlink_nav_controller_output_t packet; + packet.nav_roll = nav_roll; + packet.nav_pitch = nav_pitch; + packet.alt_error = alt_error; + packet.aspd_error = aspd_error; + packet.xtrack_error = xtrack_error; + packet.nav_bearing = nav_bearing; + packet.target_bearing = target_bearing; + packet.wp_dist = wp_dist; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_NAV_CONTROLLER_OUTPUT, (const char *)&packet, 26, 183); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE NAV_CONTROLLER_OUTPUT UNPACKING + + +/** + * @brief Get field nav_roll from nav_controller_output message + * + * @return Current desired roll in degrees + */ +static inline float mavlink_msg_nav_controller_output_get_nav_roll(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 0); +} + +/** + * @brief Get field nav_pitch from nav_controller_output message + * + * @return Current desired pitch in degrees + */ +static inline float mavlink_msg_nav_controller_output_get_nav_pitch(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 4); +} + +/** + * @brief Get field nav_bearing from nav_controller_output message + * + * @return Current desired heading in degrees + */ +static inline int16_t mavlink_msg_nav_controller_output_get_nav_bearing(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 20); +} + +/** + * @brief Get field target_bearing from nav_controller_output message + * + * @return Bearing to current MISSION/target in degrees + */ +static inline int16_t mavlink_msg_nav_controller_output_get_target_bearing(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 22); +} + +/** + * @brief Get field wp_dist from nav_controller_output message + * + * @return Distance to active MISSION in meters + */ +static inline uint16_t mavlink_msg_nav_controller_output_get_wp_dist(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 24); +} + +/** + * @brief Get field alt_error from nav_controller_output message + * + * @return Current altitude error in meters + */ +static inline float mavlink_msg_nav_controller_output_get_alt_error(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 8); +} + +/** + * @brief Get field aspd_error from nav_controller_output message + * + * @return Current airspeed error in meters/second + */ +static inline float mavlink_msg_nav_controller_output_get_aspd_error(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 12); +} + +/** + * @brief Get field xtrack_error from nav_controller_output message + * + * @return Current crosstrack error on x-y plane in meters + */ +static inline float mavlink_msg_nav_controller_output_get_xtrack_error(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 16); +} + +/** + * @brief Decode a nav_controller_output message into a struct + * + * @param msg The message to decode + * @param nav_controller_output C-struct to decode the message contents into + */ +static inline void mavlink_msg_nav_controller_output_decode(const mavlink_message_t *msg, mavlink_nav_controller_output_t *nav_controller_output) +{ +#if MAVLINK_NEED_BYTE_SWAP + nav_controller_output->nav_roll = mavlink_msg_nav_controller_output_get_nav_roll(msg); + nav_controller_output->nav_pitch = mavlink_msg_nav_controller_output_get_nav_pitch(msg); + nav_controller_output->alt_error = mavlink_msg_nav_controller_output_get_alt_error(msg); + nav_controller_output->aspd_error = mavlink_msg_nav_controller_output_get_aspd_error(msg); + nav_controller_output->xtrack_error = mavlink_msg_nav_controller_output_get_xtrack_error(msg); + nav_controller_output->nav_bearing = mavlink_msg_nav_controller_output_get_nav_bearing(msg); + nav_controller_output->target_bearing = mavlink_msg_nav_controller_output_get_target_bearing(msg); + nav_controller_output->wp_dist = mavlink_msg_nav_controller_output_get_wp_dist(msg); +#else + memcpy(nav_controller_output, _MAV_PAYLOAD(msg), 26); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_optical_flow.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_optical_flow.h new file mode 100644 index 000000000..41d6345c0 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_optical_flow.h @@ -0,0 +1,298 @@ +// MESSAGE OPTICAL_FLOW PACKING + +#define MAVLINK_MSG_ID_OPTICAL_FLOW 100 + +typedef struct __mavlink_optical_flow_t { + uint64_t time_usec; ///< Timestamp (UNIX) + float flow_comp_m_x; ///< Flow in meters in x-sensor direction, angular-speed compensated + float flow_comp_m_y; ///< Flow in meters in y-sensor direction, angular-speed compensated + float ground_distance; ///< Ground distance in meters. Positive value: distance known. Negative value: Unknown distance + int16_t flow_x; ///< Flow in pixels in x-sensor direction + int16_t flow_y; ///< Flow in pixels in y-sensor direction + uint8_t sensor_id; ///< Sensor ID + uint8_t quality; ///< Optical flow quality / confidence. 0: bad, 255: maximum quality +} mavlink_optical_flow_t; + +#define MAVLINK_MSG_ID_OPTICAL_FLOW_LEN 26 +#define MAVLINK_MSG_ID_100_LEN 26 + + +#define MAVLINK_MESSAGE_INFO_OPTICAL_FLOW \ + { \ + "OPTICAL_FLOW", \ + 8, \ + { \ + { "time_usec", NULL, MAVLINK_TYPE_UINT64_T, 0, 0, offsetof(mavlink_optical_flow_t, time_usec) }, \ + { "flow_comp_m_x", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_optical_flow_t, flow_comp_m_x) }, \ + { "flow_comp_m_y", NULL, MAVLINK_TYPE_FLOAT, 0, 12, offsetof(mavlink_optical_flow_t, flow_comp_m_y) }, \ + { "ground_distance", NULL, MAVLINK_TYPE_FLOAT, 0, 16, offsetof(mavlink_optical_flow_t, ground_distance) }, \ + { "flow_x", NULL, MAVLINK_TYPE_INT16_T, 0, 20, offsetof(mavlink_optical_flow_t, flow_x) }, \ + { "flow_y", NULL, MAVLINK_TYPE_INT16_T, 0, 22, offsetof(mavlink_optical_flow_t, flow_y) }, \ + { "sensor_id", NULL, MAVLINK_TYPE_UINT8_T, 0, 24, offsetof(mavlink_optical_flow_t, sensor_id) }, \ + { "quality", NULL, MAVLINK_TYPE_UINT8_T, 0, 25, offsetof(mavlink_optical_flow_t, quality) }, \ + } \ + } + + +/** + * @brief Pack a optical_flow message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param time_usec Timestamp (UNIX) + * @param sensor_id Sensor ID + * @param flow_x Flow in pixels in x-sensor direction + * @param flow_y Flow in pixels in y-sensor direction + * @param flow_comp_m_x Flow in meters in x-sensor direction, angular-speed compensated + * @param flow_comp_m_y Flow in meters in y-sensor direction, angular-speed compensated + * @param quality Optical flow quality / confidence. 0: bad, 255: maximum quality + * @param ground_distance Ground distance in meters. Positive value: distance known. Negative value: Unknown distance + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_optical_flow_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint64_t time_usec, uint8_t sensor_id, int16_t flow_x, int16_t flow_y, float flow_comp_m_x, float flow_comp_m_y, uint8_t quality, float ground_distance) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[26]; + _mav_put_uint64_t(buf, 0, time_usec); + _mav_put_float(buf, 8, flow_comp_m_x); + _mav_put_float(buf, 12, flow_comp_m_y); + _mav_put_float(buf, 16, ground_distance); + _mav_put_int16_t(buf, 20, flow_x); + _mav_put_int16_t(buf, 22, flow_y); + _mav_put_uint8_t(buf, 24, sensor_id); + _mav_put_uint8_t(buf, 25, quality); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 26); +#else + mavlink_optical_flow_t packet; + packet.time_usec = time_usec; + packet.flow_comp_m_x = flow_comp_m_x; + packet.flow_comp_m_y = flow_comp_m_y; + packet.ground_distance = ground_distance; + packet.flow_x = flow_x; + packet.flow_y = flow_y; + packet.sensor_id = sensor_id; + packet.quality = quality; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 26); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_OPTICAL_FLOW; + return mavlink_finalize_message(msg, system_id, component_id, 26, 175); +} + +/** + * @brief Pack a optical_flow message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param time_usec Timestamp (UNIX) + * @param sensor_id Sensor ID + * @param flow_x Flow in pixels in x-sensor direction + * @param flow_y Flow in pixels in y-sensor direction + * @param flow_comp_m_x Flow in meters in x-sensor direction, angular-speed compensated + * @param flow_comp_m_y Flow in meters in y-sensor direction, angular-speed compensated + * @param quality Optical flow quality / confidence. 0: bad, 255: maximum quality + * @param ground_distance Ground distance in meters. Positive value: distance known. Negative value: Unknown distance + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_optical_flow_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint64_t time_usec, uint8_t sensor_id, int16_t flow_x, int16_t flow_y, float flow_comp_m_x, float flow_comp_m_y, uint8_t quality, float ground_distance) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[26]; + _mav_put_uint64_t(buf, 0, time_usec); + _mav_put_float(buf, 8, flow_comp_m_x); + _mav_put_float(buf, 12, flow_comp_m_y); + _mav_put_float(buf, 16, ground_distance); + _mav_put_int16_t(buf, 20, flow_x); + _mav_put_int16_t(buf, 22, flow_y); + _mav_put_uint8_t(buf, 24, sensor_id); + _mav_put_uint8_t(buf, 25, quality); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 26); +#else + mavlink_optical_flow_t packet; + packet.time_usec = time_usec; + packet.flow_comp_m_x = flow_comp_m_x; + packet.flow_comp_m_y = flow_comp_m_y; + packet.ground_distance = ground_distance; + packet.flow_x = flow_x; + packet.flow_y = flow_y; + packet.sensor_id = sensor_id; + packet.quality = quality; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 26); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_OPTICAL_FLOW; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 26, 175); +} + +/** + * @brief Encode a optical_flow struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param optical_flow C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_optical_flow_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_optical_flow_t *optical_flow) +{ + return mavlink_msg_optical_flow_pack(system_id, component_id, msg, optical_flow->time_usec, optical_flow->sensor_id, optical_flow->flow_x, optical_flow->flow_y, optical_flow->flow_comp_m_x, optical_flow->flow_comp_m_y, optical_flow->quality, optical_flow->ground_distance); +} + +/** + * @brief Send a optical_flow message + * @param chan MAVLink channel to send the message + * + * @param time_usec Timestamp (UNIX) + * @param sensor_id Sensor ID + * @param flow_x Flow in pixels in x-sensor direction + * @param flow_y Flow in pixels in y-sensor direction + * @param flow_comp_m_x Flow in meters in x-sensor direction, angular-speed compensated + * @param flow_comp_m_y Flow in meters in y-sensor direction, angular-speed compensated + * @param quality Optical flow quality / confidence. 0: bad, 255: maximum quality + * @param ground_distance Ground distance in meters. Positive value: distance known. Negative value: Unknown distance + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_optical_flow_send(mavlink_channel_t chan, uint64_t time_usec, uint8_t sensor_id, int16_t flow_x, int16_t flow_y, float flow_comp_m_x, float flow_comp_m_y, uint8_t quality, float ground_distance) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[26]; + _mav_put_uint64_t(buf, 0, time_usec); + _mav_put_float(buf, 8, flow_comp_m_x); + _mav_put_float(buf, 12, flow_comp_m_y); + _mav_put_float(buf, 16, ground_distance); + _mav_put_int16_t(buf, 20, flow_x); + _mav_put_int16_t(buf, 22, flow_y); + _mav_put_uint8_t(buf, 24, sensor_id); + _mav_put_uint8_t(buf, 25, quality); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_OPTICAL_FLOW, buf, 26, 175); +#else + mavlink_optical_flow_t packet; + packet.time_usec = time_usec; + packet.flow_comp_m_x = flow_comp_m_x; + packet.flow_comp_m_y = flow_comp_m_y; + packet.ground_distance = ground_distance; + packet.flow_x = flow_x; + packet.flow_y = flow_y; + packet.sensor_id = sensor_id; + packet.quality = quality; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_OPTICAL_FLOW, (const char *)&packet, 26, 175); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE OPTICAL_FLOW UNPACKING + + +/** + * @brief Get field time_usec from optical_flow message + * + * @return Timestamp (UNIX) + */ +static inline uint64_t mavlink_msg_optical_flow_get_time_usec(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint64_t(msg, 0); +} + +/** + * @brief Get field sensor_id from optical_flow message + * + * @return Sensor ID + */ +static inline uint8_t mavlink_msg_optical_flow_get_sensor_id(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 24); +} + +/** + * @brief Get field flow_x from optical_flow message + * + * @return Flow in pixels in x-sensor direction + */ +static inline int16_t mavlink_msg_optical_flow_get_flow_x(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 20); +} + +/** + * @brief Get field flow_y from optical_flow message + * + * @return Flow in pixels in y-sensor direction + */ +static inline int16_t mavlink_msg_optical_flow_get_flow_y(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 22); +} + +/** + * @brief Get field flow_comp_m_x from optical_flow message + * + * @return Flow in meters in x-sensor direction, angular-speed compensated + */ +static inline float mavlink_msg_optical_flow_get_flow_comp_m_x(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 8); +} + +/** + * @brief Get field flow_comp_m_y from optical_flow message + * + * @return Flow in meters in y-sensor direction, angular-speed compensated + */ +static inline float mavlink_msg_optical_flow_get_flow_comp_m_y(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 12); +} + +/** + * @brief Get field quality from optical_flow message + * + * @return Optical flow quality / confidence. 0: bad, 255: maximum quality + */ +static inline uint8_t mavlink_msg_optical_flow_get_quality(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 25); +} + +/** + * @brief Get field ground_distance from optical_flow message + * + * @return Ground distance in meters. Positive value: distance known. Negative value: Unknown distance + */ +static inline float mavlink_msg_optical_flow_get_ground_distance(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 16); +} + +/** + * @brief Decode a optical_flow message into a struct + * + * @param msg The message to decode + * @param optical_flow C-struct to decode the message contents into + */ +static inline void mavlink_msg_optical_flow_decode(const mavlink_message_t *msg, mavlink_optical_flow_t *optical_flow) +{ +#if MAVLINK_NEED_BYTE_SWAP + optical_flow->time_usec = mavlink_msg_optical_flow_get_time_usec(msg); + optical_flow->flow_comp_m_x = mavlink_msg_optical_flow_get_flow_comp_m_x(msg); + optical_flow->flow_comp_m_y = mavlink_msg_optical_flow_get_flow_comp_m_y(msg); + optical_flow->ground_distance = mavlink_msg_optical_flow_get_ground_distance(msg); + optical_flow->flow_x = mavlink_msg_optical_flow_get_flow_x(msg); + optical_flow->flow_y = mavlink_msg_optical_flow_get_flow_y(msg); + optical_flow->sensor_id = mavlink_msg_optical_flow_get_sensor_id(msg); + optical_flow->quality = mavlink_msg_optical_flow_get_quality(msg); +#else + memcpy(optical_flow, _MAV_PAYLOAD(msg), 26); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_param_request_list.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_param_request_list.h new file mode 100644 index 000000000..ebe30971f --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_param_request_list.h @@ -0,0 +1,166 @@ +// MESSAGE PARAM_REQUEST_LIST PACKING + +#define MAVLINK_MSG_ID_PARAM_REQUEST_LIST 21 + +typedef struct __mavlink_param_request_list_t { + uint8_t target_system; ///< System ID + uint8_t target_component; ///< Component ID +} mavlink_param_request_list_t; + +#define MAVLINK_MSG_ID_PARAM_REQUEST_LIST_LEN 2 +#define MAVLINK_MSG_ID_21_LEN 2 + + +#define MAVLINK_MESSAGE_INFO_PARAM_REQUEST_LIST \ + { \ + "PARAM_REQUEST_LIST", \ + 2, \ + { \ + { "target_system", NULL, MAVLINK_TYPE_UINT8_T, 0, 0, offsetof(mavlink_param_request_list_t, target_system) }, \ + { "target_component", NULL, MAVLINK_TYPE_UINT8_T, 0, 1, offsetof(mavlink_param_request_list_t, target_component) }, \ + } \ + } + + +/** + * @brief Pack a param_request_list message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param target_system System ID + * @param target_component Component ID + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_param_request_list_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[2]; + _mav_put_uint8_t(buf, 0, target_system); + _mav_put_uint8_t(buf, 1, target_component); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 2); +#else + mavlink_param_request_list_t packet; + packet.target_system = target_system; + packet.target_component = target_component; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 2); +#endif + + msg->msgid = MAVLINK_MSG_ID_PARAM_REQUEST_LIST; + return mavlink_finalize_message(msg, system_id, component_id, 2, 159); +} + +/** + * @brief Pack a param_request_list message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param target_system System ID + * @param target_component Component ID + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_param_request_list_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[2]; + _mav_put_uint8_t(buf, 0, target_system); + _mav_put_uint8_t(buf, 1, target_component); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 2); +#else + mavlink_param_request_list_t packet; + packet.target_system = target_system; + packet.target_component = target_component; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 2); +#endif + + msg->msgid = MAVLINK_MSG_ID_PARAM_REQUEST_LIST; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 2, 159); +} + +/** + * @brief Encode a param_request_list struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param param_request_list C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_param_request_list_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_param_request_list_t *param_request_list) +{ + return mavlink_msg_param_request_list_pack(system_id, component_id, msg, param_request_list->target_system, param_request_list->target_component); +} + +/** + * @brief Send a param_request_list message + * @param chan MAVLink channel to send the message + * + * @param target_system System ID + * @param target_component Component ID + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_param_request_list_send(mavlink_channel_t chan, uint8_t target_system, uint8_t target_component) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[2]; + _mav_put_uint8_t(buf, 0, target_system); + _mav_put_uint8_t(buf, 1, target_component); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_PARAM_REQUEST_LIST, buf, 2, 159); +#else + mavlink_param_request_list_t packet; + packet.target_system = target_system; + packet.target_component = target_component; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_PARAM_REQUEST_LIST, (const char *)&packet, 2, 159); +#endif +} + +#endif + +// MESSAGE PARAM_REQUEST_LIST UNPACKING + + +/** + * @brief Get field target_system from param_request_list message + * + * @return System ID + */ +static inline uint8_t mavlink_msg_param_request_list_get_target_system(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 0); +} + +/** + * @brief Get field target_component from param_request_list message + * + * @return Component ID + */ +static inline uint8_t mavlink_msg_param_request_list_get_target_component(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 1); +} + +/** + * @brief Decode a param_request_list message into a struct + * + * @param msg The message to decode + * @param param_request_list C-struct to decode the message contents into + */ +static inline void mavlink_msg_param_request_list_decode(const mavlink_message_t *msg, mavlink_param_request_list_t *param_request_list) +{ +#if MAVLINK_NEED_BYTE_SWAP + param_request_list->target_system = mavlink_msg_param_request_list_get_target_system(msg); + param_request_list->target_component = mavlink_msg_param_request_list_get_target_component(msg); +#else + memcpy(param_request_list, _MAV_PAYLOAD(msg), 2); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_param_request_read.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_param_request_read.h new file mode 100644 index 000000000..e144cf443 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_param_request_read.h @@ -0,0 +1,205 @@ +// MESSAGE PARAM_REQUEST_READ PACKING + +#define MAVLINK_MSG_ID_PARAM_REQUEST_READ 20 + +typedef struct __mavlink_param_request_read_t { + int16_t param_index; ///< Parameter index. Send -1 to use the param ID field as identifier (else the param id will be ignored) + uint8_t target_system; ///< System ID + uint8_t target_component; ///< Component ID + char param_id[16]; ///< Onboard parameter id, terminated by NULL if the length is less than 16 human-readable chars and WITHOUT null termination (NULL) byte if the length is exactly 16 chars - applications have to provide 16+1 bytes storage if the ID is stored as string +} mavlink_param_request_read_t; + +#define MAVLINK_MSG_ID_PARAM_REQUEST_READ_LEN 20 +#define MAVLINK_MSG_ID_20_LEN 20 + +#define MAVLINK_MSG_PARAM_REQUEST_READ_FIELD_PARAM_ID_LEN 16 + +#define MAVLINK_MESSAGE_INFO_PARAM_REQUEST_READ \ + { \ + "PARAM_REQUEST_READ", \ + 4, \ + { \ + { "param_index", NULL, MAVLINK_TYPE_INT16_T, 0, 0, offsetof(mavlink_param_request_read_t, param_index) }, \ + { "target_system", NULL, MAVLINK_TYPE_UINT8_T, 0, 2, offsetof(mavlink_param_request_read_t, target_system) }, \ + { "target_component", NULL, MAVLINK_TYPE_UINT8_T, 0, 3, offsetof(mavlink_param_request_read_t, target_component) }, \ + { "param_id", NULL, MAVLINK_TYPE_CHAR, 16, 4, offsetof(mavlink_param_request_read_t, param_id) }, \ + } \ + } + + +/** + * @brief Pack a param_request_read message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param target_system System ID + * @param target_component Component ID + * @param param_id Onboard parameter id, terminated by NULL if the length is less than 16 human-readable chars and WITHOUT null termination (NULL) byte if the length is exactly 16 chars - applications have to provide 16+1 bytes storage if the ID is stored as string + * @param param_index Parameter index. Send -1 to use the param ID field as identifier (else the param id will be ignored) + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_param_request_read_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, const char *param_id, int16_t param_index) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[20]; + _mav_put_int16_t(buf, 0, param_index); + _mav_put_uint8_t(buf, 2, target_system); + _mav_put_uint8_t(buf, 3, target_component); + _mav_put_char_array(buf, 4, param_id, 16); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 20); +#else + mavlink_param_request_read_t packet; + packet.param_index = param_index; + packet.target_system = target_system; + packet.target_component = target_component; + mav_array_memcpy(packet.param_id, param_id, sizeof(char) * 16); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 20); +#endif + + msg->msgid = MAVLINK_MSG_ID_PARAM_REQUEST_READ; + return mavlink_finalize_message(msg, system_id, component_id, 20, 214); +} + +/** + * @brief Pack a param_request_read message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param target_system System ID + * @param target_component Component ID + * @param param_id Onboard parameter id, terminated by NULL if the length is less than 16 human-readable chars and WITHOUT null termination (NULL) byte if the length is exactly 16 chars - applications have to provide 16+1 bytes storage if the ID is stored as string + * @param param_index Parameter index. Send -1 to use the param ID field as identifier (else the param id will be ignored) + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_param_request_read_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, const char *param_id, int16_t param_index) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[20]; + _mav_put_int16_t(buf, 0, param_index); + _mav_put_uint8_t(buf, 2, target_system); + _mav_put_uint8_t(buf, 3, target_component); + _mav_put_char_array(buf, 4, param_id, 16); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 20); +#else + mavlink_param_request_read_t packet; + packet.param_index = param_index; + packet.target_system = target_system; + packet.target_component = target_component; + mav_array_memcpy(packet.param_id, param_id, sizeof(char) * 16); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 20); +#endif + + msg->msgid = MAVLINK_MSG_ID_PARAM_REQUEST_READ; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 20, 214); +} + +/** + * @brief Encode a param_request_read struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param param_request_read C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_param_request_read_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_param_request_read_t *param_request_read) +{ + return mavlink_msg_param_request_read_pack(system_id, component_id, msg, param_request_read->target_system, param_request_read->target_component, param_request_read->param_id, param_request_read->param_index); +} + +/** + * @brief Send a param_request_read message + * @param chan MAVLink channel to send the message + * + * @param target_system System ID + * @param target_component Component ID + * @param param_id Onboard parameter id, terminated by NULL if the length is less than 16 human-readable chars and WITHOUT null termination (NULL) byte if the length is exactly 16 chars - applications have to provide 16+1 bytes storage if the ID is stored as string + * @param param_index Parameter index. Send -1 to use the param ID field as identifier (else the param id will be ignored) + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_param_request_read_send(mavlink_channel_t chan, uint8_t target_system, uint8_t target_component, const char *param_id, int16_t param_index) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[20]; + _mav_put_int16_t(buf, 0, param_index); + _mav_put_uint8_t(buf, 2, target_system); + _mav_put_uint8_t(buf, 3, target_component); + _mav_put_char_array(buf, 4, param_id, 16); + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_PARAM_REQUEST_READ, buf, 20, 214); +#else + mavlink_param_request_read_t packet; + packet.param_index = param_index; + packet.target_system = target_system; + packet.target_component = target_component; + mav_array_memcpy(packet.param_id, param_id, sizeof(char) * 16); + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_PARAM_REQUEST_READ, (const char *)&packet, 20, 214); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE PARAM_REQUEST_READ UNPACKING + + +/** + * @brief Get field target_system from param_request_read message + * + * @return System ID + */ +static inline uint8_t mavlink_msg_param_request_read_get_target_system(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 2); +} + +/** + * @brief Get field target_component from param_request_read message + * + * @return Component ID + */ +static inline uint8_t mavlink_msg_param_request_read_get_target_component(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 3); +} + +/** + * @brief Get field param_id from param_request_read message + * + * @return Onboard parameter id, terminated by NULL if the length is less than 16 human-readable chars and WITHOUT null termination (NULL) byte if the length is exactly 16 chars - applications have to provide 16+1 bytes storage if the ID is stored as string + */ +static inline uint16_t mavlink_msg_param_request_read_get_param_id(const mavlink_message_t *msg, char *param_id) +{ + return _MAV_RETURN_char_array(msg, param_id, 16, 4); +} + +/** + * @brief Get field param_index from param_request_read message + * + * @return Parameter index. Send -1 to use the param ID field as identifier (else the param id will be ignored) + */ +static inline int16_t mavlink_msg_param_request_read_get_param_index(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 0); +} + +/** + * @brief Decode a param_request_read message into a struct + * + * @param msg The message to decode + * @param param_request_read C-struct to decode the message contents into + */ +static inline void mavlink_msg_param_request_read_decode(const mavlink_message_t *msg, mavlink_param_request_read_t *param_request_read) +{ +#if MAVLINK_NEED_BYTE_SWAP + param_request_read->param_index = mavlink_msg_param_request_read_get_param_index(msg); + param_request_read->target_system = mavlink_msg_param_request_read_get_target_system(msg); + param_request_read->target_component = mavlink_msg_param_request_read_get_target_component(msg); + mavlink_msg_param_request_read_get_param_id(msg, param_request_read->param_id); +#else + memcpy(param_request_read, _MAV_PAYLOAD(msg), 20); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_param_set.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_param_set.h new file mode 100644 index 000000000..dc241f273 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_param_set.h @@ -0,0 +1,227 @@ +// MESSAGE PARAM_SET PACKING + +#define MAVLINK_MSG_ID_PARAM_SET 23 + +typedef struct __mavlink_param_set_t { + float param_value; ///< Onboard parameter value + uint8_t target_system; ///< System ID + uint8_t target_component; ///< Component ID + char param_id[16]; ///< Onboard parameter id, terminated by NULL if the length is less than 16 human-readable chars and WITHOUT null termination (NULL) byte if the length is exactly 16 chars - applications have to provide 16+1 bytes storage if the ID is stored as string + uint8_t param_type; ///< Onboard parameter type: see the MAV_PARAM_TYPE enum for supported data types. +} mavlink_param_set_t; + +#define MAVLINK_MSG_ID_PARAM_SET_LEN 23 +#define MAVLINK_MSG_ID_23_LEN 23 + +#define MAVLINK_MSG_PARAM_SET_FIELD_PARAM_ID_LEN 16 + +#define MAVLINK_MESSAGE_INFO_PARAM_SET \ + { \ + "PARAM_SET", \ + 5, \ + { \ + { "param_value", NULL, MAVLINK_TYPE_FLOAT, 0, 0, offsetof(mavlink_param_set_t, param_value) }, \ + { "target_system", NULL, MAVLINK_TYPE_UINT8_T, 0, 4, offsetof(mavlink_param_set_t, target_system) }, \ + { "target_component", NULL, MAVLINK_TYPE_UINT8_T, 0, 5, offsetof(mavlink_param_set_t, target_component) }, \ + { "param_id", NULL, MAVLINK_TYPE_CHAR, 16, 6, offsetof(mavlink_param_set_t, param_id) }, \ + { "param_type", NULL, MAVLINK_TYPE_UINT8_T, 0, 22, offsetof(mavlink_param_set_t, param_type) }, \ + } \ + } + + +/** + * @brief Pack a param_set message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param target_system System ID + * @param target_component Component ID + * @param param_id Onboard parameter id, terminated by NULL if the length is less than 16 human-readable chars and WITHOUT null termination (NULL) byte if the length is exactly 16 chars - applications have to provide 16+1 bytes storage if the ID is stored as string + * @param param_value Onboard parameter value + * @param param_type Onboard parameter type: see the MAV_PARAM_TYPE enum for supported data types. + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_param_set_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, const char *param_id, float param_value, uint8_t param_type) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[23]; + _mav_put_float(buf, 0, param_value); + _mav_put_uint8_t(buf, 4, target_system); + _mav_put_uint8_t(buf, 5, target_component); + _mav_put_uint8_t(buf, 22, param_type); + _mav_put_char_array(buf, 6, param_id, 16); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 23); +#else + mavlink_param_set_t packet; + packet.param_value = param_value; + packet.target_system = target_system; + packet.target_component = target_component; + packet.param_type = param_type; + mav_array_memcpy(packet.param_id, param_id, sizeof(char) * 16); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 23); +#endif + + msg->msgid = MAVLINK_MSG_ID_PARAM_SET; + return mavlink_finalize_message(msg, system_id, component_id, 23, 168); +} + +/** + * @brief Pack a param_set message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param target_system System ID + * @param target_component Component ID + * @param param_id Onboard parameter id, terminated by NULL if the length is less than 16 human-readable chars and WITHOUT null termination (NULL) byte if the length is exactly 16 chars - applications have to provide 16+1 bytes storage if the ID is stored as string + * @param param_value Onboard parameter value + * @param param_type Onboard parameter type: see the MAV_PARAM_TYPE enum for supported data types. + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_param_set_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, const char *param_id, float param_value, uint8_t param_type) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[23]; + _mav_put_float(buf, 0, param_value); + _mav_put_uint8_t(buf, 4, target_system); + _mav_put_uint8_t(buf, 5, target_component); + _mav_put_uint8_t(buf, 22, param_type); + _mav_put_char_array(buf, 6, param_id, 16); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 23); +#else + mavlink_param_set_t packet; + packet.param_value = param_value; + packet.target_system = target_system; + packet.target_component = target_component; + packet.param_type = param_type; + mav_array_memcpy(packet.param_id, param_id, sizeof(char) * 16); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 23); +#endif + + msg->msgid = MAVLINK_MSG_ID_PARAM_SET; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 23, 168); +} + +/** + * @brief Encode a param_set struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param param_set C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_param_set_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_param_set_t *param_set) +{ + return mavlink_msg_param_set_pack(system_id, component_id, msg, param_set->target_system, param_set->target_component, param_set->param_id, param_set->param_value, param_set->param_type); +} + +/** + * @brief Send a param_set message + * @param chan MAVLink channel to send the message + * + * @param target_system System ID + * @param target_component Component ID + * @param param_id Onboard parameter id, terminated by NULL if the length is less than 16 human-readable chars and WITHOUT null termination (NULL) byte if the length is exactly 16 chars - applications have to provide 16+1 bytes storage if the ID is stored as string + * @param param_value Onboard parameter value + * @param param_type Onboard parameter type: see the MAV_PARAM_TYPE enum for supported data types. + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_param_set_send(mavlink_channel_t chan, uint8_t target_system, uint8_t target_component, const char *param_id, float param_value, uint8_t param_type) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[23]; + _mav_put_float(buf, 0, param_value); + _mav_put_uint8_t(buf, 4, target_system); + _mav_put_uint8_t(buf, 5, target_component); + _mav_put_uint8_t(buf, 22, param_type); + _mav_put_char_array(buf, 6, param_id, 16); + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_PARAM_SET, buf, 23, 168); +#else + mavlink_param_set_t packet; + packet.param_value = param_value; + packet.target_system = target_system; + packet.target_component = target_component; + packet.param_type = param_type; + mav_array_memcpy(packet.param_id, param_id, sizeof(char) * 16); + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_PARAM_SET, (const char *)&packet, 23, 168); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE PARAM_SET UNPACKING + + +/** + * @brief Get field target_system from param_set message + * + * @return System ID + */ +static inline uint8_t mavlink_msg_param_set_get_target_system(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 4); +} + +/** + * @brief Get field target_component from param_set message + * + * @return Component ID + */ +static inline uint8_t mavlink_msg_param_set_get_target_component(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 5); +} + +/** + * @brief Get field param_id from param_set message + * + * @return Onboard parameter id, terminated by NULL if the length is less than 16 human-readable chars and WITHOUT null termination (NULL) byte if the length is exactly 16 chars - applications have to provide 16+1 bytes storage if the ID is stored as string + */ +static inline uint16_t mavlink_msg_param_set_get_param_id(const mavlink_message_t *msg, char *param_id) +{ + return _MAV_RETURN_char_array(msg, param_id, 16, 6); +} + +/** + * @brief Get field param_value from param_set message + * + * @return Onboard parameter value + */ +static inline float mavlink_msg_param_set_get_param_value(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 0); +} + +/** + * @brief Get field param_type from param_set message + * + * @return Onboard parameter type: see the MAV_PARAM_TYPE enum for supported data types. + */ +static inline uint8_t mavlink_msg_param_set_get_param_type(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 22); +} + +/** + * @brief Decode a param_set message into a struct + * + * @param msg The message to decode + * @param param_set C-struct to decode the message contents into + */ +static inline void mavlink_msg_param_set_decode(const mavlink_message_t *msg, mavlink_param_set_t *param_set) +{ +#if MAVLINK_NEED_BYTE_SWAP + param_set->param_value = mavlink_msg_param_set_get_param_value(msg); + param_set->target_system = mavlink_msg_param_set_get_target_system(msg); + param_set->target_component = mavlink_msg_param_set_get_target_component(msg); + mavlink_msg_param_set_get_param_id(msg, param_set->param_id); + param_set->param_type = mavlink_msg_param_set_get_param_type(msg); +#else + memcpy(param_set, _MAV_PAYLOAD(msg), 23); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_param_value.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_param_value.h new file mode 100644 index 000000000..2b96fb9fe --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_param_value.h @@ -0,0 +1,227 @@ +// MESSAGE PARAM_VALUE PACKING + +#define MAVLINK_MSG_ID_PARAM_VALUE 22 + +typedef struct __mavlink_param_value_t { + float param_value; ///< Onboard parameter value + uint16_t param_count; ///< Total number of onboard parameters + uint16_t param_index; ///< Index of this onboard parameter + char param_id[16]; ///< Onboard parameter id, terminated by NULL if the length is less than 16 human-readable chars and WITHOUT null termination (NULL) byte if the length is exactly 16 chars - applications have to provide 16+1 bytes storage if the ID is stored as string + uint8_t param_type; ///< Onboard parameter type: see the MAV_PARAM_TYPE enum for supported data types. +} mavlink_param_value_t; + +#define MAVLINK_MSG_ID_PARAM_VALUE_LEN 25 +#define MAVLINK_MSG_ID_22_LEN 25 + +#define MAVLINK_MSG_PARAM_VALUE_FIELD_PARAM_ID_LEN 16 + +#define MAVLINK_MESSAGE_INFO_PARAM_VALUE \ + { \ + "PARAM_VALUE", \ + 5, \ + { \ + { "param_value", NULL, MAVLINK_TYPE_FLOAT, 0, 0, offsetof(mavlink_param_value_t, param_value) }, \ + { "param_count", NULL, MAVLINK_TYPE_UINT16_T, 0, 4, offsetof(mavlink_param_value_t, param_count) }, \ + { "param_index", NULL, MAVLINK_TYPE_UINT16_T, 0, 6, offsetof(mavlink_param_value_t, param_index) }, \ + { "param_id", NULL, MAVLINK_TYPE_CHAR, 16, 8, offsetof(mavlink_param_value_t, param_id) }, \ + { "param_type", NULL, MAVLINK_TYPE_UINT8_T, 0, 24, offsetof(mavlink_param_value_t, param_type) }, \ + } \ + } + + +/** + * @brief Pack a param_value message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param param_id Onboard parameter id, terminated by NULL if the length is less than 16 human-readable chars and WITHOUT null termination (NULL) byte if the length is exactly 16 chars - applications have to provide 16+1 bytes storage if the ID is stored as string + * @param param_value Onboard parameter value + * @param param_type Onboard parameter type: see the MAV_PARAM_TYPE enum for supported data types. + * @param param_count Total number of onboard parameters + * @param param_index Index of this onboard parameter + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_param_value_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + const char *param_id, float param_value, uint8_t param_type, uint16_t param_count, uint16_t param_index) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[25]; + _mav_put_float(buf, 0, param_value); + _mav_put_uint16_t(buf, 4, param_count); + _mav_put_uint16_t(buf, 6, param_index); + _mav_put_uint8_t(buf, 24, param_type); + _mav_put_char_array(buf, 8, param_id, 16); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 25); +#else + mavlink_param_value_t packet; + packet.param_value = param_value; + packet.param_count = param_count; + packet.param_index = param_index; + packet.param_type = param_type; + mav_array_memcpy(packet.param_id, param_id, sizeof(char) * 16); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 25); +#endif + + msg->msgid = MAVLINK_MSG_ID_PARAM_VALUE; + return mavlink_finalize_message(msg, system_id, component_id, 25, 220); +} + +/** + * @brief Pack a param_value message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param param_id Onboard parameter id, terminated by NULL if the length is less than 16 human-readable chars and WITHOUT null termination (NULL) byte if the length is exactly 16 chars - applications have to provide 16+1 bytes storage if the ID is stored as string + * @param param_value Onboard parameter value + * @param param_type Onboard parameter type: see the MAV_PARAM_TYPE enum for supported data types. + * @param param_count Total number of onboard parameters + * @param param_index Index of this onboard parameter + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_param_value_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + const char *param_id, float param_value, uint8_t param_type, uint16_t param_count, uint16_t param_index) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[25]; + _mav_put_float(buf, 0, param_value); + _mav_put_uint16_t(buf, 4, param_count); + _mav_put_uint16_t(buf, 6, param_index); + _mav_put_uint8_t(buf, 24, param_type); + _mav_put_char_array(buf, 8, param_id, 16); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 25); +#else + mavlink_param_value_t packet; + packet.param_value = param_value; + packet.param_count = param_count; + packet.param_index = param_index; + packet.param_type = param_type; + mav_array_memcpy(packet.param_id, param_id, sizeof(char) * 16); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 25); +#endif + + msg->msgid = MAVLINK_MSG_ID_PARAM_VALUE; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 25, 220); +} + +/** + * @brief Encode a param_value struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param param_value C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_param_value_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_param_value_t *param_value) +{ + return mavlink_msg_param_value_pack(system_id, component_id, msg, param_value->param_id, param_value->param_value, param_value->param_type, param_value->param_count, param_value->param_index); +} + +/** + * @brief Send a param_value message + * @param chan MAVLink channel to send the message + * + * @param param_id Onboard parameter id, terminated by NULL if the length is less than 16 human-readable chars and WITHOUT null termination (NULL) byte if the length is exactly 16 chars - applications have to provide 16+1 bytes storage if the ID is stored as string + * @param param_value Onboard parameter value + * @param param_type Onboard parameter type: see the MAV_PARAM_TYPE enum for supported data types. + * @param param_count Total number of onboard parameters + * @param param_index Index of this onboard parameter + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_param_value_send(mavlink_channel_t chan, const char *param_id, float param_value, uint8_t param_type, uint16_t param_count, uint16_t param_index) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[25]; + _mav_put_float(buf, 0, param_value); + _mav_put_uint16_t(buf, 4, param_count); + _mav_put_uint16_t(buf, 6, param_index); + _mav_put_uint8_t(buf, 24, param_type); + _mav_put_char_array(buf, 8, param_id, 16); + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_PARAM_VALUE, buf, 25, 220); +#else + mavlink_param_value_t packet; + packet.param_value = param_value; + packet.param_count = param_count; + packet.param_index = param_index; + packet.param_type = param_type; + mav_array_memcpy(packet.param_id, param_id, sizeof(char) * 16); + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_PARAM_VALUE, (const char *)&packet, 25, 220); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE PARAM_VALUE UNPACKING + + +/** + * @brief Get field param_id from param_value message + * + * @return Onboard parameter id, terminated by NULL if the length is less than 16 human-readable chars and WITHOUT null termination (NULL) byte if the length is exactly 16 chars - applications have to provide 16+1 bytes storage if the ID is stored as string + */ +static inline uint16_t mavlink_msg_param_value_get_param_id(const mavlink_message_t *msg, char *param_id) +{ + return _MAV_RETURN_char_array(msg, param_id, 16, 8); +} + +/** + * @brief Get field param_value from param_value message + * + * @return Onboard parameter value + */ +static inline float mavlink_msg_param_value_get_param_value(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 0); +} + +/** + * @brief Get field param_type from param_value message + * + * @return Onboard parameter type: see the MAV_PARAM_TYPE enum for supported data types. + */ +static inline uint8_t mavlink_msg_param_value_get_param_type(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 24); +} + +/** + * @brief Get field param_count from param_value message + * + * @return Total number of onboard parameters + */ +static inline uint16_t mavlink_msg_param_value_get_param_count(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 4); +} + +/** + * @brief Get field param_index from param_value message + * + * @return Index of this onboard parameter + */ +static inline uint16_t mavlink_msg_param_value_get_param_index(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 6); +} + +/** + * @brief Decode a param_value message into a struct + * + * @param msg The message to decode + * @param param_value C-struct to decode the message contents into + */ +static inline void mavlink_msg_param_value_decode(const mavlink_message_t *msg, mavlink_param_value_t *param_value) +{ +#if MAVLINK_NEED_BYTE_SWAP + param_value->param_value = mavlink_msg_param_value_get_param_value(msg); + param_value->param_count = mavlink_msg_param_value_get_param_count(msg); + param_value->param_index = mavlink_msg_param_value_get_param_index(msg); + mavlink_msg_param_value_get_param_id(msg, param_value->param_id); + param_value->param_type = mavlink_msg_param_value_get_param_type(msg); +#else + memcpy(param_value, _MAV_PAYLOAD(msg), 25); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_ping.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_ping.h new file mode 100644 index 000000000..326311988 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_ping.h @@ -0,0 +1,210 @@ +// MESSAGE PING PACKING + +#define MAVLINK_MSG_ID_PING 4 + +typedef struct __mavlink_ping_t { + uint64_t time_usec; ///< Unix timestamp in microseconds + uint32_t seq; ///< PING sequence + uint8_t target_system; ///< 0: request ping from all receiving systems, if greater than 0: message is a ping response and number is the system id of the requesting system + uint8_t target_component; ///< 0: request ping from all receiving components, if greater than 0: message is a ping response and number is the system id of the requesting system +} mavlink_ping_t; + +#define MAVLINK_MSG_ID_PING_LEN 14 +#define MAVLINK_MSG_ID_4_LEN 14 + + +#define MAVLINK_MESSAGE_INFO_PING \ + { \ + "PING", \ + 4, \ + { \ + { "time_usec", NULL, MAVLINK_TYPE_UINT64_T, 0, 0, offsetof(mavlink_ping_t, time_usec) }, \ + { "seq", NULL, MAVLINK_TYPE_UINT32_T, 0, 8, offsetof(mavlink_ping_t, seq) }, \ + { "target_system", NULL, MAVLINK_TYPE_UINT8_T, 0, 12, offsetof(mavlink_ping_t, target_system) }, \ + { "target_component", NULL, MAVLINK_TYPE_UINT8_T, 0, 13, offsetof(mavlink_ping_t, target_component) }, \ + } \ + } + + +/** + * @brief Pack a ping message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param time_usec Unix timestamp in microseconds + * @param seq PING sequence + * @param target_system 0: request ping from all receiving systems, if greater than 0: message is a ping response and number is the system id of the requesting system + * @param target_component 0: request ping from all receiving components, if greater than 0: message is a ping response and number is the system id of the requesting system + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_ping_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint64_t time_usec, uint32_t seq, uint8_t target_system, uint8_t target_component) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[14]; + _mav_put_uint64_t(buf, 0, time_usec); + _mav_put_uint32_t(buf, 8, seq); + _mav_put_uint8_t(buf, 12, target_system); + _mav_put_uint8_t(buf, 13, target_component); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 14); +#else + mavlink_ping_t packet; + packet.time_usec = time_usec; + packet.seq = seq; + packet.target_system = target_system; + packet.target_component = target_component; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 14); +#endif + + msg->msgid = MAVLINK_MSG_ID_PING; + return mavlink_finalize_message(msg, system_id, component_id, 14, 237); +} + +/** + * @brief Pack a ping message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param time_usec Unix timestamp in microseconds + * @param seq PING sequence + * @param target_system 0: request ping from all receiving systems, if greater than 0: message is a ping response and number is the system id of the requesting system + * @param target_component 0: request ping from all receiving components, if greater than 0: message is a ping response and number is the system id of the requesting system + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_ping_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint64_t time_usec, uint32_t seq, uint8_t target_system, uint8_t target_component) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[14]; + _mav_put_uint64_t(buf, 0, time_usec); + _mav_put_uint32_t(buf, 8, seq); + _mav_put_uint8_t(buf, 12, target_system); + _mav_put_uint8_t(buf, 13, target_component); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 14); +#else + mavlink_ping_t packet; + packet.time_usec = time_usec; + packet.seq = seq; + packet.target_system = target_system; + packet.target_component = target_component; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 14); +#endif + + msg->msgid = MAVLINK_MSG_ID_PING; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 14, 237); +} + +/** + * @brief Encode a ping struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param ping C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_ping_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_ping_t *ping) +{ + return mavlink_msg_ping_pack(system_id, component_id, msg, ping->time_usec, ping->seq, ping->target_system, ping->target_component); +} + +/** + * @brief Send a ping message + * @param chan MAVLink channel to send the message + * + * @param time_usec Unix timestamp in microseconds + * @param seq PING sequence + * @param target_system 0: request ping from all receiving systems, if greater than 0: message is a ping response and number is the system id of the requesting system + * @param target_component 0: request ping from all receiving components, if greater than 0: message is a ping response and number is the system id of the requesting system + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_ping_send(mavlink_channel_t chan, uint64_t time_usec, uint32_t seq, uint8_t target_system, uint8_t target_component) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[14]; + _mav_put_uint64_t(buf, 0, time_usec); + _mav_put_uint32_t(buf, 8, seq); + _mav_put_uint8_t(buf, 12, target_system); + _mav_put_uint8_t(buf, 13, target_component); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_PING, buf, 14, 237); +#else + mavlink_ping_t packet; + packet.time_usec = time_usec; + packet.seq = seq; + packet.target_system = target_system; + packet.target_component = target_component; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_PING, (const char *)&packet, 14, 237); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE PING UNPACKING + + +/** + * @brief Get field time_usec from ping message + * + * @return Unix timestamp in microseconds + */ +static inline uint64_t mavlink_msg_ping_get_time_usec(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint64_t(msg, 0); +} + +/** + * @brief Get field seq from ping message + * + * @return PING sequence + */ +static inline uint32_t mavlink_msg_ping_get_seq(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint32_t(msg, 8); +} + +/** + * @brief Get field target_system from ping message + * + * @return 0: request ping from all receiving systems, if greater than 0: message is a ping response and number is the system id of the requesting system + */ +static inline uint8_t mavlink_msg_ping_get_target_system(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 12); +} + +/** + * @brief Get field target_component from ping message + * + * @return 0: request ping from all receiving components, if greater than 0: message is a ping response and number is the system id of the requesting system + */ +static inline uint8_t mavlink_msg_ping_get_target_component(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 13); +} + +/** + * @brief Decode a ping message into a struct + * + * @param msg The message to decode + * @param ping C-struct to decode the message contents into + */ +static inline void mavlink_msg_ping_decode(const mavlink_message_t *msg, mavlink_ping_t *ping) +{ +#if MAVLINK_NEED_BYTE_SWAP + ping->time_usec = mavlink_msg_ping_get_time_usec(msg); + ping->seq = mavlink_msg_ping_get_seq(msg); + ping->target_system = mavlink_msg_ping_get_target_system(msg); + ping->target_component = mavlink_msg_ping_get_target_component(msg); +#else + memcpy(ping, _MAV_PAYLOAD(msg), 14); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_raw_imu.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_raw_imu.h new file mode 100644 index 000000000..9cb8fd8dd --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_raw_imu.h @@ -0,0 +1,342 @@ +// MESSAGE RAW_IMU PACKING + +#define MAVLINK_MSG_ID_RAW_IMU 27 + +typedef struct __mavlink_raw_imu_t { + uint64_t time_usec; ///< Timestamp (microseconds since UNIX epoch or microseconds since system boot) + int16_t xacc; ///< X acceleration (raw) + int16_t yacc; ///< Y acceleration (raw) + int16_t zacc; ///< Z acceleration (raw) + int16_t xgyro; ///< Angular speed around X axis (raw) + int16_t ygyro; ///< Angular speed around Y axis (raw) + int16_t zgyro; ///< Angular speed around Z axis (raw) + int16_t xmag; ///< X Magnetic field (raw) + int16_t ymag; ///< Y Magnetic field (raw) + int16_t zmag; ///< Z Magnetic field (raw) +} mavlink_raw_imu_t; + +#define MAVLINK_MSG_ID_RAW_IMU_LEN 26 +#define MAVLINK_MSG_ID_27_LEN 26 + + +#define MAVLINK_MESSAGE_INFO_RAW_IMU \ + { \ + "RAW_IMU", \ + 10, \ + { \ + { "time_usec", NULL, MAVLINK_TYPE_UINT64_T, 0, 0, offsetof(mavlink_raw_imu_t, time_usec) }, \ + { "xacc", NULL, MAVLINK_TYPE_INT16_T, 0, 8, offsetof(mavlink_raw_imu_t, xacc) }, \ + { "yacc", NULL, MAVLINK_TYPE_INT16_T, 0, 10, offsetof(mavlink_raw_imu_t, yacc) }, \ + { "zacc", NULL, MAVLINK_TYPE_INT16_T, 0, 12, offsetof(mavlink_raw_imu_t, zacc) }, \ + { "xgyro", NULL, MAVLINK_TYPE_INT16_T, 0, 14, offsetof(mavlink_raw_imu_t, xgyro) }, \ + { "ygyro", NULL, MAVLINK_TYPE_INT16_T, 0, 16, offsetof(mavlink_raw_imu_t, ygyro) }, \ + { "zgyro", NULL, MAVLINK_TYPE_INT16_T, 0, 18, offsetof(mavlink_raw_imu_t, zgyro) }, \ + { "xmag", NULL, MAVLINK_TYPE_INT16_T, 0, 20, offsetof(mavlink_raw_imu_t, xmag) }, \ + { "ymag", NULL, MAVLINK_TYPE_INT16_T, 0, 22, offsetof(mavlink_raw_imu_t, ymag) }, \ + { "zmag", NULL, MAVLINK_TYPE_INT16_T, 0, 24, offsetof(mavlink_raw_imu_t, zmag) }, \ + } \ + } + + +/** + * @brief Pack a raw_imu message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param time_usec Timestamp (microseconds since UNIX epoch or microseconds since system boot) + * @param xacc X acceleration (raw) + * @param yacc Y acceleration (raw) + * @param zacc Z acceleration (raw) + * @param xgyro Angular speed around X axis (raw) + * @param ygyro Angular speed around Y axis (raw) + * @param zgyro Angular speed around Z axis (raw) + * @param xmag X Magnetic field (raw) + * @param ymag Y Magnetic field (raw) + * @param zmag Z Magnetic field (raw) + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_raw_imu_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint64_t time_usec, int16_t xacc, int16_t yacc, int16_t zacc, int16_t xgyro, int16_t ygyro, int16_t zgyro, int16_t xmag, int16_t ymag, int16_t zmag) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[26]; + _mav_put_uint64_t(buf, 0, time_usec); + _mav_put_int16_t(buf, 8, xacc); + _mav_put_int16_t(buf, 10, yacc); + _mav_put_int16_t(buf, 12, zacc); + _mav_put_int16_t(buf, 14, xgyro); + _mav_put_int16_t(buf, 16, ygyro); + _mav_put_int16_t(buf, 18, zgyro); + _mav_put_int16_t(buf, 20, xmag); + _mav_put_int16_t(buf, 22, ymag); + _mav_put_int16_t(buf, 24, zmag); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 26); +#else + mavlink_raw_imu_t packet; + packet.time_usec = time_usec; + packet.xacc = xacc; + packet.yacc = yacc; + packet.zacc = zacc; + packet.xgyro = xgyro; + packet.ygyro = ygyro; + packet.zgyro = zgyro; + packet.xmag = xmag; + packet.ymag = ymag; + packet.zmag = zmag; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 26); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_RAW_IMU; + return mavlink_finalize_message(msg, system_id, component_id, 26, 144); +} + +/** + * @brief Pack a raw_imu message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param time_usec Timestamp (microseconds since UNIX epoch or microseconds since system boot) + * @param xacc X acceleration (raw) + * @param yacc Y acceleration (raw) + * @param zacc Z acceleration (raw) + * @param xgyro Angular speed around X axis (raw) + * @param ygyro Angular speed around Y axis (raw) + * @param zgyro Angular speed around Z axis (raw) + * @param xmag X Magnetic field (raw) + * @param ymag Y Magnetic field (raw) + * @param zmag Z Magnetic field (raw) + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_raw_imu_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint64_t time_usec, int16_t xacc, int16_t yacc, int16_t zacc, int16_t xgyro, int16_t ygyro, int16_t zgyro, int16_t xmag, int16_t ymag, int16_t zmag) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[26]; + _mav_put_uint64_t(buf, 0, time_usec); + _mav_put_int16_t(buf, 8, xacc); + _mav_put_int16_t(buf, 10, yacc); + _mav_put_int16_t(buf, 12, zacc); + _mav_put_int16_t(buf, 14, xgyro); + _mav_put_int16_t(buf, 16, ygyro); + _mav_put_int16_t(buf, 18, zgyro); + _mav_put_int16_t(buf, 20, xmag); + _mav_put_int16_t(buf, 22, ymag); + _mav_put_int16_t(buf, 24, zmag); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 26); +#else + mavlink_raw_imu_t packet; + packet.time_usec = time_usec; + packet.xacc = xacc; + packet.yacc = yacc; + packet.zacc = zacc; + packet.xgyro = xgyro; + packet.ygyro = ygyro; + packet.zgyro = zgyro; + packet.xmag = xmag; + packet.ymag = ymag; + packet.zmag = zmag; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 26); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_RAW_IMU; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 26, 144); +} + +/** + * @brief Encode a raw_imu struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param raw_imu C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_raw_imu_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_raw_imu_t *raw_imu) +{ + return mavlink_msg_raw_imu_pack(system_id, component_id, msg, raw_imu->time_usec, raw_imu->xacc, raw_imu->yacc, raw_imu->zacc, raw_imu->xgyro, raw_imu->ygyro, raw_imu->zgyro, raw_imu->xmag, raw_imu->ymag, raw_imu->zmag); +} + +/** + * @brief Send a raw_imu message + * @param chan MAVLink channel to send the message + * + * @param time_usec Timestamp (microseconds since UNIX epoch or microseconds since system boot) + * @param xacc X acceleration (raw) + * @param yacc Y acceleration (raw) + * @param zacc Z acceleration (raw) + * @param xgyro Angular speed around X axis (raw) + * @param ygyro Angular speed around Y axis (raw) + * @param zgyro Angular speed around Z axis (raw) + * @param xmag X Magnetic field (raw) + * @param ymag Y Magnetic field (raw) + * @param zmag Z Magnetic field (raw) + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_raw_imu_send(mavlink_channel_t chan, uint64_t time_usec, int16_t xacc, int16_t yacc, int16_t zacc, int16_t xgyro, int16_t ygyro, int16_t zgyro, int16_t xmag, int16_t ymag, int16_t zmag) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[26]; + _mav_put_uint64_t(buf, 0, time_usec); + _mav_put_int16_t(buf, 8, xacc); + _mav_put_int16_t(buf, 10, yacc); + _mav_put_int16_t(buf, 12, zacc); + _mav_put_int16_t(buf, 14, xgyro); + _mav_put_int16_t(buf, 16, ygyro); + _mav_put_int16_t(buf, 18, zgyro); + _mav_put_int16_t(buf, 20, xmag); + _mav_put_int16_t(buf, 22, ymag); + _mav_put_int16_t(buf, 24, zmag); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_RAW_IMU, buf, 26, 144); +#else + mavlink_raw_imu_t packet; + packet.time_usec = time_usec; + packet.xacc = xacc; + packet.yacc = yacc; + packet.zacc = zacc; + packet.xgyro = xgyro; + packet.ygyro = ygyro; + packet.zgyro = zgyro; + packet.xmag = xmag; + packet.ymag = ymag; + packet.zmag = zmag; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_RAW_IMU, (const char *)&packet, 26, 144); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE RAW_IMU UNPACKING + + +/** + * @brief Get field time_usec from raw_imu message + * + * @return Timestamp (microseconds since UNIX epoch or microseconds since system boot) + */ +static inline uint64_t mavlink_msg_raw_imu_get_time_usec(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint64_t(msg, 0); +} + +/** + * @brief Get field xacc from raw_imu message + * + * @return X acceleration (raw) + */ +static inline int16_t mavlink_msg_raw_imu_get_xacc(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 8); +} + +/** + * @brief Get field yacc from raw_imu message + * + * @return Y acceleration (raw) + */ +static inline int16_t mavlink_msg_raw_imu_get_yacc(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 10); +} + +/** + * @brief Get field zacc from raw_imu message + * + * @return Z acceleration (raw) + */ +static inline int16_t mavlink_msg_raw_imu_get_zacc(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 12); +} + +/** + * @brief Get field xgyro from raw_imu message + * + * @return Angular speed around X axis (raw) + */ +static inline int16_t mavlink_msg_raw_imu_get_xgyro(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 14); +} + +/** + * @brief Get field ygyro from raw_imu message + * + * @return Angular speed around Y axis (raw) + */ +static inline int16_t mavlink_msg_raw_imu_get_ygyro(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 16); +} + +/** + * @brief Get field zgyro from raw_imu message + * + * @return Angular speed around Z axis (raw) + */ +static inline int16_t mavlink_msg_raw_imu_get_zgyro(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 18); +} + +/** + * @brief Get field xmag from raw_imu message + * + * @return X Magnetic field (raw) + */ +static inline int16_t mavlink_msg_raw_imu_get_xmag(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 20); +} + +/** + * @brief Get field ymag from raw_imu message + * + * @return Y Magnetic field (raw) + */ +static inline int16_t mavlink_msg_raw_imu_get_ymag(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 22); +} + +/** + * @brief Get field zmag from raw_imu message + * + * @return Z Magnetic field (raw) + */ +static inline int16_t mavlink_msg_raw_imu_get_zmag(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 24); +} + +/** + * @brief Decode a raw_imu message into a struct + * + * @param msg The message to decode + * @param raw_imu C-struct to decode the message contents into + */ +static inline void mavlink_msg_raw_imu_decode(const mavlink_message_t *msg, mavlink_raw_imu_t *raw_imu) +{ +#if MAVLINK_NEED_BYTE_SWAP + raw_imu->time_usec = mavlink_msg_raw_imu_get_time_usec(msg); + raw_imu->xacc = mavlink_msg_raw_imu_get_xacc(msg); + raw_imu->yacc = mavlink_msg_raw_imu_get_yacc(msg); + raw_imu->zacc = mavlink_msg_raw_imu_get_zacc(msg); + raw_imu->xgyro = mavlink_msg_raw_imu_get_xgyro(msg); + raw_imu->ygyro = mavlink_msg_raw_imu_get_ygyro(msg); + raw_imu->zgyro = mavlink_msg_raw_imu_get_zgyro(msg); + raw_imu->xmag = mavlink_msg_raw_imu_get_xmag(msg); + raw_imu->ymag = mavlink_msg_raw_imu_get_ymag(msg); + raw_imu->zmag = mavlink_msg_raw_imu_get_zmag(msg); +#else + memcpy(raw_imu, _MAV_PAYLOAD(msg), 26); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_raw_pressure.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_raw_pressure.h new file mode 100644 index 000000000..ca001b302 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_raw_pressure.h @@ -0,0 +1,232 @@ +// MESSAGE RAW_PRESSURE PACKING + +#define MAVLINK_MSG_ID_RAW_PRESSURE 28 + +typedef struct __mavlink_raw_pressure_t { + uint64_t time_usec; ///< Timestamp (microseconds since UNIX epoch or microseconds since system boot) + int16_t press_abs; ///< Absolute pressure (raw) + int16_t press_diff1; ///< Differential pressure 1 (raw) + int16_t press_diff2; ///< Differential pressure 2 (raw) + int16_t temperature; ///< Raw Temperature measurement (raw) +} mavlink_raw_pressure_t; + +#define MAVLINK_MSG_ID_RAW_PRESSURE_LEN 16 +#define MAVLINK_MSG_ID_28_LEN 16 + + +#define MAVLINK_MESSAGE_INFO_RAW_PRESSURE \ + { \ + "RAW_PRESSURE", \ + 5, \ + { \ + { "time_usec", NULL, MAVLINK_TYPE_UINT64_T, 0, 0, offsetof(mavlink_raw_pressure_t, time_usec) }, \ + { "press_abs", NULL, MAVLINK_TYPE_INT16_T, 0, 8, offsetof(mavlink_raw_pressure_t, press_abs) }, \ + { "press_diff1", NULL, MAVLINK_TYPE_INT16_T, 0, 10, offsetof(mavlink_raw_pressure_t, press_diff1) }, \ + { "press_diff2", NULL, MAVLINK_TYPE_INT16_T, 0, 12, offsetof(mavlink_raw_pressure_t, press_diff2) }, \ + { "temperature", NULL, MAVLINK_TYPE_INT16_T, 0, 14, offsetof(mavlink_raw_pressure_t, temperature) }, \ + } \ + } + + +/** + * @brief Pack a raw_pressure message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param time_usec Timestamp (microseconds since UNIX epoch or microseconds since system boot) + * @param press_abs Absolute pressure (raw) + * @param press_diff1 Differential pressure 1 (raw) + * @param press_diff2 Differential pressure 2 (raw) + * @param temperature Raw Temperature measurement (raw) + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_raw_pressure_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint64_t time_usec, int16_t press_abs, int16_t press_diff1, int16_t press_diff2, int16_t temperature) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[16]; + _mav_put_uint64_t(buf, 0, time_usec); + _mav_put_int16_t(buf, 8, press_abs); + _mav_put_int16_t(buf, 10, press_diff1); + _mav_put_int16_t(buf, 12, press_diff2); + _mav_put_int16_t(buf, 14, temperature); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 16); +#else + mavlink_raw_pressure_t packet; + packet.time_usec = time_usec; + packet.press_abs = press_abs; + packet.press_diff1 = press_diff1; + packet.press_diff2 = press_diff2; + packet.temperature = temperature; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 16); +#endif + + msg->msgid = MAVLINK_MSG_ID_RAW_PRESSURE; + return mavlink_finalize_message(msg, system_id, component_id, 16, 67); +} + +/** + * @brief Pack a raw_pressure message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param time_usec Timestamp (microseconds since UNIX epoch or microseconds since system boot) + * @param press_abs Absolute pressure (raw) + * @param press_diff1 Differential pressure 1 (raw) + * @param press_diff2 Differential pressure 2 (raw) + * @param temperature Raw Temperature measurement (raw) + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_raw_pressure_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint64_t time_usec, int16_t press_abs, int16_t press_diff1, int16_t press_diff2, int16_t temperature) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[16]; + _mav_put_uint64_t(buf, 0, time_usec); + _mav_put_int16_t(buf, 8, press_abs); + _mav_put_int16_t(buf, 10, press_diff1); + _mav_put_int16_t(buf, 12, press_diff2); + _mav_put_int16_t(buf, 14, temperature); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 16); +#else + mavlink_raw_pressure_t packet; + packet.time_usec = time_usec; + packet.press_abs = press_abs; + packet.press_diff1 = press_diff1; + packet.press_diff2 = press_diff2; + packet.temperature = temperature; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 16); +#endif + + msg->msgid = MAVLINK_MSG_ID_RAW_PRESSURE; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 16, 67); +} + +/** + * @brief Encode a raw_pressure struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param raw_pressure C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_raw_pressure_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_raw_pressure_t *raw_pressure) +{ + return mavlink_msg_raw_pressure_pack(system_id, component_id, msg, raw_pressure->time_usec, raw_pressure->press_abs, raw_pressure->press_diff1, raw_pressure->press_diff2, raw_pressure->temperature); +} + +/** + * @brief Send a raw_pressure message + * @param chan MAVLink channel to send the message + * + * @param time_usec Timestamp (microseconds since UNIX epoch or microseconds since system boot) + * @param press_abs Absolute pressure (raw) + * @param press_diff1 Differential pressure 1 (raw) + * @param press_diff2 Differential pressure 2 (raw) + * @param temperature Raw Temperature measurement (raw) + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_raw_pressure_send(mavlink_channel_t chan, uint64_t time_usec, int16_t press_abs, int16_t press_diff1, int16_t press_diff2, int16_t temperature) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[16]; + _mav_put_uint64_t(buf, 0, time_usec); + _mav_put_int16_t(buf, 8, press_abs); + _mav_put_int16_t(buf, 10, press_diff1); + _mav_put_int16_t(buf, 12, press_diff2); + _mav_put_int16_t(buf, 14, temperature); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_RAW_PRESSURE, buf, 16, 67); +#else + mavlink_raw_pressure_t packet; + packet.time_usec = time_usec; + packet.press_abs = press_abs; + packet.press_diff1 = press_diff1; + packet.press_diff2 = press_diff2; + packet.temperature = temperature; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_RAW_PRESSURE, (const char *)&packet, 16, 67); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE RAW_PRESSURE UNPACKING + + +/** + * @brief Get field time_usec from raw_pressure message + * + * @return Timestamp (microseconds since UNIX epoch or microseconds since system boot) + */ +static inline uint64_t mavlink_msg_raw_pressure_get_time_usec(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint64_t(msg, 0); +} + +/** + * @brief Get field press_abs from raw_pressure message + * + * @return Absolute pressure (raw) + */ +static inline int16_t mavlink_msg_raw_pressure_get_press_abs(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 8); +} + +/** + * @brief Get field press_diff1 from raw_pressure message + * + * @return Differential pressure 1 (raw) + */ +static inline int16_t mavlink_msg_raw_pressure_get_press_diff1(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 10); +} + +/** + * @brief Get field press_diff2 from raw_pressure message + * + * @return Differential pressure 2 (raw) + */ +static inline int16_t mavlink_msg_raw_pressure_get_press_diff2(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 12); +} + +/** + * @brief Get field temperature from raw_pressure message + * + * @return Raw Temperature measurement (raw) + */ +static inline int16_t mavlink_msg_raw_pressure_get_temperature(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 14); +} + +/** + * @brief Decode a raw_pressure message into a struct + * + * @param msg The message to decode + * @param raw_pressure C-struct to decode the message contents into + */ +static inline void mavlink_msg_raw_pressure_decode(const mavlink_message_t *msg, mavlink_raw_pressure_t *raw_pressure) +{ +#if MAVLINK_NEED_BYTE_SWAP + raw_pressure->time_usec = mavlink_msg_raw_pressure_get_time_usec(msg); + raw_pressure->press_abs = mavlink_msg_raw_pressure_get_press_abs(msg); + raw_pressure->press_diff1 = mavlink_msg_raw_pressure_get_press_diff1(msg); + raw_pressure->press_diff2 = mavlink_msg_raw_pressure_get_press_diff2(msg); + raw_pressure->temperature = mavlink_msg_raw_pressure_get_temperature(msg); +#else + memcpy(raw_pressure, _MAV_PAYLOAD(msg), 16); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_rc_channels_override.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_rc_channels_override.h new file mode 100644 index 000000000..6e41b75e3 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_rc_channels_override.h @@ -0,0 +1,342 @@ +// MESSAGE RC_CHANNELS_OVERRIDE PACKING + +#define MAVLINK_MSG_ID_RC_CHANNELS_OVERRIDE 70 + +typedef struct __mavlink_rc_channels_override_t { + uint16_t chan1_raw; ///< RC channel 1 value, in microseconds + uint16_t chan2_raw; ///< RC channel 2 value, in microseconds + uint16_t chan3_raw; ///< RC channel 3 value, in microseconds + uint16_t chan4_raw; ///< RC channel 4 value, in microseconds + uint16_t chan5_raw; ///< RC channel 5 value, in microseconds + uint16_t chan6_raw; ///< RC channel 6 value, in microseconds + uint16_t chan7_raw; ///< RC channel 7 value, in microseconds + uint16_t chan8_raw; ///< RC channel 8 value, in microseconds + uint8_t target_system; ///< System ID + uint8_t target_component; ///< Component ID +} mavlink_rc_channels_override_t; + +#define MAVLINK_MSG_ID_RC_CHANNELS_OVERRIDE_LEN 18 +#define MAVLINK_MSG_ID_70_LEN 18 + + +#define MAVLINK_MESSAGE_INFO_RC_CHANNELS_OVERRIDE \ + { \ + "RC_CHANNELS_OVERRIDE", \ + 10, \ + { \ + { "chan1_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 0, offsetof(mavlink_rc_channels_override_t, chan1_raw) }, \ + { "chan2_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 2, offsetof(mavlink_rc_channels_override_t, chan2_raw) }, \ + { "chan3_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 4, offsetof(mavlink_rc_channels_override_t, chan3_raw) }, \ + { "chan4_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 6, offsetof(mavlink_rc_channels_override_t, chan4_raw) }, \ + { "chan5_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 8, offsetof(mavlink_rc_channels_override_t, chan5_raw) }, \ + { "chan6_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 10, offsetof(mavlink_rc_channels_override_t, chan6_raw) }, \ + { "chan7_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 12, offsetof(mavlink_rc_channels_override_t, chan7_raw) }, \ + { "chan8_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 14, offsetof(mavlink_rc_channels_override_t, chan8_raw) }, \ + { "target_system", NULL, MAVLINK_TYPE_UINT8_T, 0, 16, offsetof(mavlink_rc_channels_override_t, target_system) }, \ + { "target_component", NULL, MAVLINK_TYPE_UINT8_T, 0, 17, offsetof(mavlink_rc_channels_override_t, target_component) }, \ + } \ + } + + +/** + * @brief Pack a rc_channels_override message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param target_system System ID + * @param target_component Component ID + * @param chan1_raw RC channel 1 value, in microseconds + * @param chan2_raw RC channel 2 value, in microseconds + * @param chan3_raw RC channel 3 value, in microseconds + * @param chan4_raw RC channel 4 value, in microseconds + * @param chan5_raw RC channel 5 value, in microseconds + * @param chan6_raw RC channel 6 value, in microseconds + * @param chan7_raw RC channel 7 value, in microseconds + * @param chan8_raw RC channel 8 value, in microseconds + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_rc_channels_override_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, uint16_t chan1_raw, uint16_t chan2_raw, uint16_t chan3_raw, uint16_t chan4_raw, uint16_t chan5_raw, uint16_t chan6_raw, uint16_t chan7_raw, uint16_t chan8_raw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[18]; + _mav_put_uint16_t(buf, 0, chan1_raw); + _mav_put_uint16_t(buf, 2, chan2_raw); + _mav_put_uint16_t(buf, 4, chan3_raw); + _mav_put_uint16_t(buf, 6, chan4_raw); + _mav_put_uint16_t(buf, 8, chan5_raw); + _mav_put_uint16_t(buf, 10, chan6_raw); + _mav_put_uint16_t(buf, 12, chan7_raw); + _mav_put_uint16_t(buf, 14, chan8_raw); + _mav_put_uint8_t(buf, 16, target_system); + _mav_put_uint8_t(buf, 17, target_component); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 18); +#else + mavlink_rc_channels_override_t packet; + packet.chan1_raw = chan1_raw; + packet.chan2_raw = chan2_raw; + packet.chan3_raw = chan3_raw; + packet.chan4_raw = chan4_raw; + packet.chan5_raw = chan5_raw; + packet.chan6_raw = chan6_raw; + packet.chan7_raw = chan7_raw; + packet.chan8_raw = chan8_raw; + packet.target_system = target_system; + packet.target_component = target_component; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 18); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_RC_CHANNELS_OVERRIDE; + return mavlink_finalize_message(msg, system_id, component_id, 18, 124); +} + +/** + * @brief Pack a rc_channels_override message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param target_system System ID + * @param target_component Component ID + * @param chan1_raw RC channel 1 value, in microseconds + * @param chan2_raw RC channel 2 value, in microseconds + * @param chan3_raw RC channel 3 value, in microseconds + * @param chan4_raw RC channel 4 value, in microseconds + * @param chan5_raw RC channel 5 value, in microseconds + * @param chan6_raw RC channel 6 value, in microseconds + * @param chan7_raw RC channel 7 value, in microseconds + * @param chan8_raw RC channel 8 value, in microseconds + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_rc_channels_override_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, uint16_t chan1_raw, uint16_t chan2_raw, uint16_t chan3_raw, uint16_t chan4_raw, uint16_t chan5_raw, uint16_t chan6_raw, uint16_t chan7_raw, uint16_t chan8_raw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[18]; + _mav_put_uint16_t(buf, 0, chan1_raw); + _mav_put_uint16_t(buf, 2, chan2_raw); + _mav_put_uint16_t(buf, 4, chan3_raw); + _mav_put_uint16_t(buf, 6, chan4_raw); + _mav_put_uint16_t(buf, 8, chan5_raw); + _mav_put_uint16_t(buf, 10, chan6_raw); + _mav_put_uint16_t(buf, 12, chan7_raw); + _mav_put_uint16_t(buf, 14, chan8_raw); + _mav_put_uint8_t(buf, 16, target_system); + _mav_put_uint8_t(buf, 17, target_component); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 18); +#else + mavlink_rc_channels_override_t packet; + packet.chan1_raw = chan1_raw; + packet.chan2_raw = chan2_raw; + packet.chan3_raw = chan3_raw; + packet.chan4_raw = chan4_raw; + packet.chan5_raw = chan5_raw; + packet.chan6_raw = chan6_raw; + packet.chan7_raw = chan7_raw; + packet.chan8_raw = chan8_raw; + packet.target_system = target_system; + packet.target_component = target_component; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 18); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_RC_CHANNELS_OVERRIDE; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 18, 124); +} + +/** + * @brief Encode a rc_channels_override struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param rc_channels_override C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_rc_channels_override_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_rc_channels_override_t *rc_channels_override) +{ + return mavlink_msg_rc_channels_override_pack(system_id, component_id, msg, rc_channels_override->target_system, rc_channels_override->target_component, rc_channels_override->chan1_raw, rc_channels_override->chan2_raw, rc_channels_override->chan3_raw, rc_channels_override->chan4_raw, rc_channels_override->chan5_raw, rc_channels_override->chan6_raw, rc_channels_override->chan7_raw, rc_channels_override->chan8_raw); +} + +/** + * @brief Send a rc_channels_override message + * @param chan MAVLink channel to send the message + * + * @param target_system System ID + * @param target_component Component ID + * @param chan1_raw RC channel 1 value, in microseconds + * @param chan2_raw RC channel 2 value, in microseconds + * @param chan3_raw RC channel 3 value, in microseconds + * @param chan4_raw RC channel 4 value, in microseconds + * @param chan5_raw RC channel 5 value, in microseconds + * @param chan6_raw RC channel 6 value, in microseconds + * @param chan7_raw RC channel 7 value, in microseconds + * @param chan8_raw RC channel 8 value, in microseconds + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_rc_channels_override_send(mavlink_channel_t chan, uint8_t target_system, uint8_t target_component, uint16_t chan1_raw, uint16_t chan2_raw, uint16_t chan3_raw, uint16_t chan4_raw, uint16_t chan5_raw, uint16_t chan6_raw, uint16_t chan7_raw, uint16_t chan8_raw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[18]; + _mav_put_uint16_t(buf, 0, chan1_raw); + _mav_put_uint16_t(buf, 2, chan2_raw); + _mav_put_uint16_t(buf, 4, chan3_raw); + _mav_put_uint16_t(buf, 6, chan4_raw); + _mav_put_uint16_t(buf, 8, chan5_raw); + _mav_put_uint16_t(buf, 10, chan6_raw); + _mav_put_uint16_t(buf, 12, chan7_raw); + _mav_put_uint16_t(buf, 14, chan8_raw); + _mav_put_uint8_t(buf, 16, target_system); + _mav_put_uint8_t(buf, 17, target_component); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_RC_CHANNELS_OVERRIDE, buf, 18, 124); +#else + mavlink_rc_channels_override_t packet; + packet.chan1_raw = chan1_raw; + packet.chan2_raw = chan2_raw; + packet.chan3_raw = chan3_raw; + packet.chan4_raw = chan4_raw; + packet.chan5_raw = chan5_raw; + packet.chan6_raw = chan6_raw; + packet.chan7_raw = chan7_raw; + packet.chan8_raw = chan8_raw; + packet.target_system = target_system; + packet.target_component = target_component; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_RC_CHANNELS_OVERRIDE, (const char *)&packet, 18, 124); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE RC_CHANNELS_OVERRIDE UNPACKING + + +/** + * @brief Get field target_system from rc_channels_override message + * + * @return System ID + */ +static inline uint8_t mavlink_msg_rc_channels_override_get_target_system(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 16); +} + +/** + * @brief Get field target_component from rc_channels_override message + * + * @return Component ID + */ +static inline uint8_t mavlink_msg_rc_channels_override_get_target_component(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 17); +} + +/** + * @brief Get field chan1_raw from rc_channels_override message + * + * @return RC channel 1 value, in microseconds + */ +static inline uint16_t mavlink_msg_rc_channels_override_get_chan1_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 0); +} + +/** + * @brief Get field chan2_raw from rc_channels_override message + * + * @return RC channel 2 value, in microseconds + */ +static inline uint16_t mavlink_msg_rc_channels_override_get_chan2_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 2); +} + +/** + * @brief Get field chan3_raw from rc_channels_override message + * + * @return RC channel 3 value, in microseconds + */ +static inline uint16_t mavlink_msg_rc_channels_override_get_chan3_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 4); +} + +/** + * @brief Get field chan4_raw from rc_channels_override message + * + * @return RC channel 4 value, in microseconds + */ +static inline uint16_t mavlink_msg_rc_channels_override_get_chan4_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 6); +} + +/** + * @brief Get field chan5_raw from rc_channels_override message + * + * @return RC channel 5 value, in microseconds + */ +static inline uint16_t mavlink_msg_rc_channels_override_get_chan5_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 8); +} + +/** + * @brief Get field chan6_raw from rc_channels_override message + * + * @return RC channel 6 value, in microseconds + */ +static inline uint16_t mavlink_msg_rc_channels_override_get_chan6_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 10); +} + +/** + * @brief Get field chan7_raw from rc_channels_override message + * + * @return RC channel 7 value, in microseconds + */ +static inline uint16_t mavlink_msg_rc_channels_override_get_chan7_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 12); +} + +/** + * @brief Get field chan8_raw from rc_channels_override message + * + * @return RC channel 8 value, in microseconds + */ +static inline uint16_t mavlink_msg_rc_channels_override_get_chan8_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 14); +} + +/** + * @brief Decode a rc_channels_override message into a struct + * + * @param msg The message to decode + * @param rc_channels_override C-struct to decode the message contents into + */ +static inline void mavlink_msg_rc_channels_override_decode(const mavlink_message_t *msg, mavlink_rc_channels_override_t *rc_channels_override) +{ +#if MAVLINK_NEED_BYTE_SWAP + rc_channels_override->chan1_raw = mavlink_msg_rc_channels_override_get_chan1_raw(msg); + rc_channels_override->chan2_raw = mavlink_msg_rc_channels_override_get_chan2_raw(msg); + rc_channels_override->chan3_raw = mavlink_msg_rc_channels_override_get_chan3_raw(msg); + rc_channels_override->chan4_raw = mavlink_msg_rc_channels_override_get_chan4_raw(msg); + rc_channels_override->chan5_raw = mavlink_msg_rc_channels_override_get_chan5_raw(msg); + rc_channels_override->chan6_raw = mavlink_msg_rc_channels_override_get_chan6_raw(msg); + rc_channels_override->chan7_raw = mavlink_msg_rc_channels_override_get_chan7_raw(msg); + rc_channels_override->chan8_raw = mavlink_msg_rc_channels_override_get_chan8_raw(msg); + rc_channels_override->target_system = mavlink_msg_rc_channels_override_get_target_system(msg); + rc_channels_override->target_component = mavlink_msg_rc_channels_override_get_target_component(msg); +#else + memcpy(rc_channels_override, _MAV_PAYLOAD(msg), 18); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_rc_channels_raw.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_rc_channels_raw.h new file mode 100644 index 000000000..f29581575 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_rc_channels_raw.h @@ -0,0 +1,364 @@ +// MESSAGE RC_CHANNELS_RAW PACKING + +#define MAVLINK_MSG_ID_RC_CHANNELS_RAW 35 + +typedef struct __mavlink_rc_channels_raw_t { + uint32_t time_boot_ms; ///< Timestamp (milliseconds since system boot) + uint16_t chan1_raw; ///< RC channel 1 value, in microseconds + uint16_t chan2_raw; ///< RC channel 2 value, in microseconds + uint16_t chan3_raw; ///< RC channel 3 value, in microseconds + uint16_t chan4_raw; ///< RC channel 4 value, in microseconds + uint16_t chan5_raw; ///< RC channel 5 value, in microseconds + uint16_t chan6_raw; ///< RC channel 6 value, in microseconds + uint16_t chan7_raw; ///< RC channel 7 value, in microseconds + uint16_t chan8_raw; ///< RC channel 8 value, in microseconds + uint8_t port; ///< Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows to encode more than 8 servos. + uint8_t rssi; ///< Receive signal strength indicator, 0: 0%, 255: 100% +} mavlink_rc_channels_raw_t; + +#define MAVLINK_MSG_ID_RC_CHANNELS_RAW_LEN 22 +#define MAVLINK_MSG_ID_35_LEN 22 + + +#define MAVLINK_MESSAGE_INFO_RC_CHANNELS_RAW \ + { \ + "RC_CHANNELS_RAW", \ + 11, \ + { \ + { "time_boot_ms", NULL, MAVLINK_TYPE_UINT32_T, 0, 0, offsetof(mavlink_rc_channels_raw_t, time_boot_ms) }, \ + { "chan1_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 4, offsetof(mavlink_rc_channels_raw_t, chan1_raw) }, \ + { "chan2_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 6, offsetof(mavlink_rc_channels_raw_t, chan2_raw) }, \ + { "chan3_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 8, offsetof(mavlink_rc_channels_raw_t, chan3_raw) }, \ + { "chan4_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 10, offsetof(mavlink_rc_channels_raw_t, chan4_raw) }, \ + { "chan5_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 12, offsetof(mavlink_rc_channels_raw_t, chan5_raw) }, \ + { "chan6_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 14, offsetof(mavlink_rc_channels_raw_t, chan6_raw) }, \ + { "chan7_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 16, offsetof(mavlink_rc_channels_raw_t, chan7_raw) }, \ + { "chan8_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 18, offsetof(mavlink_rc_channels_raw_t, chan8_raw) }, \ + { "port", NULL, MAVLINK_TYPE_UINT8_T, 0, 20, offsetof(mavlink_rc_channels_raw_t, port) }, \ + { "rssi", NULL, MAVLINK_TYPE_UINT8_T, 0, 21, offsetof(mavlink_rc_channels_raw_t, rssi) }, \ + } \ + } + + +/** + * @brief Pack a rc_channels_raw message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param port Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows to encode more than 8 servos. + * @param chan1_raw RC channel 1 value, in microseconds + * @param chan2_raw RC channel 2 value, in microseconds + * @param chan3_raw RC channel 3 value, in microseconds + * @param chan4_raw RC channel 4 value, in microseconds + * @param chan5_raw RC channel 5 value, in microseconds + * @param chan6_raw RC channel 6 value, in microseconds + * @param chan7_raw RC channel 7 value, in microseconds + * @param chan8_raw RC channel 8 value, in microseconds + * @param rssi Receive signal strength indicator, 0: 0%, 255: 100% + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_rc_channels_raw_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint32_t time_boot_ms, uint8_t port, uint16_t chan1_raw, uint16_t chan2_raw, uint16_t chan3_raw, uint16_t chan4_raw, uint16_t chan5_raw, uint16_t chan6_raw, uint16_t chan7_raw, uint16_t chan8_raw, uint8_t rssi) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[22]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_uint16_t(buf, 4, chan1_raw); + _mav_put_uint16_t(buf, 6, chan2_raw); + _mav_put_uint16_t(buf, 8, chan3_raw); + _mav_put_uint16_t(buf, 10, chan4_raw); + _mav_put_uint16_t(buf, 12, chan5_raw); + _mav_put_uint16_t(buf, 14, chan6_raw); + _mav_put_uint16_t(buf, 16, chan7_raw); + _mav_put_uint16_t(buf, 18, chan8_raw); + _mav_put_uint8_t(buf, 20, port); + _mav_put_uint8_t(buf, 21, rssi); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 22); +#else + mavlink_rc_channels_raw_t packet; + packet.time_boot_ms = time_boot_ms; + packet.chan1_raw = chan1_raw; + packet.chan2_raw = chan2_raw; + packet.chan3_raw = chan3_raw; + packet.chan4_raw = chan4_raw; + packet.chan5_raw = chan5_raw; + packet.chan6_raw = chan6_raw; + packet.chan7_raw = chan7_raw; + packet.chan8_raw = chan8_raw; + packet.port = port; + packet.rssi = rssi; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 22); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_RC_CHANNELS_RAW; + return mavlink_finalize_message(msg, system_id, component_id, 22, 244); +} + +/** + * @brief Pack a rc_channels_raw message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param port Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows to encode more than 8 servos. + * @param chan1_raw RC channel 1 value, in microseconds + * @param chan2_raw RC channel 2 value, in microseconds + * @param chan3_raw RC channel 3 value, in microseconds + * @param chan4_raw RC channel 4 value, in microseconds + * @param chan5_raw RC channel 5 value, in microseconds + * @param chan6_raw RC channel 6 value, in microseconds + * @param chan7_raw RC channel 7 value, in microseconds + * @param chan8_raw RC channel 8 value, in microseconds + * @param rssi Receive signal strength indicator, 0: 0%, 255: 100% + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_rc_channels_raw_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint32_t time_boot_ms, uint8_t port, uint16_t chan1_raw, uint16_t chan2_raw, uint16_t chan3_raw, uint16_t chan4_raw, uint16_t chan5_raw, uint16_t chan6_raw, uint16_t chan7_raw, uint16_t chan8_raw, uint8_t rssi) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[22]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_uint16_t(buf, 4, chan1_raw); + _mav_put_uint16_t(buf, 6, chan2_raw); + _mav_put_uint16_t(buf, 8, chan3_raw); + _mav_put_uint16_t(buf, 10, chan4_raw); + _mav_put_uint16_t(buf, 12, chan5_raw); + _mav_put_uint16_t(buf, 14, chan6_raw); + _mav_put_uint16_t(buf, 16, chan7_raw); + _mav_put_uint16_t(buf, 18, chan8_raw); + _mav_put_uint8_t(buf, 20, port); + _mav_put_uint8_t(buf, 21, rssi); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 22); +#else + mavlink_rc_channels_raw_t packet; + packet.time_boot_ms = time_boot_ms; + packet.chan1_raw = chan1_raw; + packet.chan2_raw = chan2_raw; + packet.chan3_raw = chan3_raw; + packet.chan4_raw = chan4_raw; + packet.chan5_raw = chan5_raw; + packet.chan6_raw = chan6_raw; + packet.chan7_raw = chan7_raw; + packet.chan8_raw = chan8_raw; + packet.port = port; + packet.rssi = rssi; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 22); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_RC_CHANNELS_RAW; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 22, 244); +} + +/** + * @brief Encode a rc_channels_raw struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param rc_channels_raw C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_rc_channels_raw_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_rc_channels_raw_t *rc_channels_raw) +{ + return mavlink_msg_rc_channels_raw_pack(system_id, component_id, msg, rc_channels_raw->time_boot_ms, rc_channels_raw->port, rc_channels_raw->chan1_raw, rc_channels_raw->chan2_raw, rc_channels_raw->chan3_raw, rc_channels_raw->chan4_raw, rc_channels_raw->chan5_raw, rc_channels_raw->chan6_raw, rc_channels_raw->chan7_raw, rc_channels_raw->chan8_raw, rc_channels_raw->rssi); +} + +/** + * @brief Send a rc_channels_raw message + * @param chan MAVLink channel to send the message + * + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param port Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows to encode more than 8 servos. + * @param chan1_raw RC channel 1 value, in microseconds + * @param chan2_raw RC channel 2 value, in microseconds + * @param chan3_raw RC channel 3 value, in microseconds + * @param chan4_raw RC channel 4 value, in microseconds + * @param chan5_raw RC channel 5 value, in microseconds + * @param chan6_raw RC channel 6 value, in microseconds + * @param chan7_raw RC channel 7 value, in microseconds + * @param chan8_raw RC channel 8 value, in microseconds + * @param rssi Receive signal strength indicator, 0: 0%, 255: 100% + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_rc_channels_raw_send(mavlink_channel_t chan, uint32_t time_boot_ms, uint8_t port, uint16_t chan1_raw, uint16_t chan2_raw, uint16_t chan3_raw, uint16_t chan4_raw, uint16_t chan5_raw, uint16_t chan6_raw, uint16_t chan7_raw, uint16_t chan8_raw, uint8_t rssi) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[22]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_uint16_t(buf, 4, chan1_raw); + _mav_put_uint16_t(buf, 6, chan2_raw); + _mav_put_uint16_t(buf, 8, chan3_raw); + _mav_put_uint16_t(buf, 10, chan4_raw); + _mav_put_uint16_t(buf, 12, chan5_raw); + _mav_put_uint16_t(buf, 14, chan6_raw); + _mav_put_uint16_t(buf, 16, chan7_raw); + _mav_put_uint16_t(buf, 18, chan8_raw); + _mav_put_uint8_t(buf, 20, port); + _mav_put_uint8_t(buf, 21, rssi); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_RC_CHANNELS_RAW, buf, 22, 244); +#else + mavlink_rc_channels_raw_t packet; + packet.time_boot_ms = time_boot_ms; + packet.chan1_raw = chan1_raw; + packet.chan2_raw = chan2_raw; + packet.chan3_raw = chan3_raw; + packet.chan4_raw = chan4_raw; + packet.chan5_raw = chan5_raw; + packet.chan6_raw = chan6_raw; + packet.chan7_raw = chan7_raw; + packet.chan8_raw = chan8_raw; + packet.port = port; + packet.rssi = rssi; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_RC_CHANNELS_RAW, (const char *)&packet, 22, 244); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE RC_CHANNELS_RAW UNPACKING + + +/** + * @brief Get field time_boot_ms from rc_channels_raw message + * + * @return Timestamp (milliseconds since system boot) + */ +static inline uint32_t mavlink_msg_rc_channels_raw_get_time_boot_ms(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint32_t(msg, 0); +} + +/** + * @brief Get field port from rc_channels_raw message + * + * @return Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows to encode more than 8 servos. + */ +static inline uint8_t mavlink_msg_rc_channels_raw_get_port(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 20); +} + +/** + * @brief Get field chan1_raw from rc_channels_raw message + * + * @return RC channel 1 value, in microseconds + */ +static inline uint16_t mavlink_msg_rc_channels_raw_get_chan1_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 4); +} + +/** + * @brief Get field chan2_raw from rc_channels_raw message + * + * @return RC channel 2 value, in microseconds + */ +static inline uint16_t mavlink_msg_rc_channels_raw_get_chan2_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 6); +} + +/** + * @brief Get field chan3_raw from rc_channels_raw message + * + * @return RC channel 3 value, in microseconds + */ +static inline uint16_t mavlink_msg_rc_channels_raw_get_chan3_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 8); +} + +/** + * @brief Get field chan4_raw from rc_channels_raw message + * + * @return RC channel 4 value, in microseconds + */ +static inline uint16_t mavlink_msg_rc_channels_raw_get_chan4_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 10); +} + +/** + * @brief Get field chan5_raw from rc_channels_raw message + * + * @return RC channel 5 value, in microseconds + */ +static inline uint16_t mavlink_msg_rc_channels_raw_get_chan5_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 12); +} + +/** + * @brief Get field chan6_raw from rc_channels_raw message + * + * @return RC channel 6 value, in microseconds + */ +static inline uint16_t mavlink_msg_rc_channels_raw_get_chan6_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 14); +} + +/** + * @brief Get field chan7_raw from rc_channels_raw message + * + * @return RC channel 7 value, in microseconds + */ +static inline uint16_t mavlink_msg_rc_channels_raw_get_chan7_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 16); +} + +/** + * @brief Get field chan8_raw from rc_channels_raw message + * + * @return RC channel 8 value, in microseconds + */ +static inline uint16_t mavlink_msg_rc_channels_raw_get_chan8_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 18); +} + +/** + * @brief Get field rssi from rc_channels_raw message + * + * @return Receive signal strength indicator, 0: 0%, 255: 100% + */ +static inline uint8_t mavlink_msg_rc_channels_raw_get_rssi(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 21); +} + +/** + * @brief Decode a rc_channels_raw message into a struct + * + * @param msg The message to decode + * @param rc_channels_raw C-struct to decode the message contents into + */ +static inline void mavlink_msg_rc_channels_raw_decode(const mavlink_message_t *msg, mavlink_rc_channels_raw_t *rc_channels_raw) +{ +#if MAVLINK_NEED_BYTE_SWAP + rc_channels_raw->time_boot_ms = mavlink_msg_rc_channels_raw_get_time_boot_ms(msg); + rc_channels_raw->chan1_raw = mavlink_msg_rc_channels_raw_get_chan1_raw(msg); + rc_channels_raw->chan2_raw = mavlink_msg_rc_channels_raw_get_chan2_raw(msg); + rc_channels_raw->chan3_raw = mavlink_msg_rc_channels_raw_get_chan3_raw(msg); + rc_channels_raw->chan4_raw = mavlink_msg_rc_channels_raw_get_chan4_raw(msg); + rc_channels_raw->chan5_raw = mavlink_msg_rc_channels_raw_get_chan5_raw(msg); + rc_channels_raw->chan6_raw = mavlink_msg_rc_channels_raw_get_chan6_raw(msg); + rc_channels_raw->chan7_raw = mavlink_msg_rc_channels_raw_get_chan7_raw(msg); + rc_channels_raw->chan8_raw = mavlink_msg_rc_channels_raw_get_chan8_raw(msg); + rc_channels_raw->port = mavlink_msg_rc_channels_raw_get_port(msg); + rc_channels_raw->rssi = mavlink_msg_rc_channels_raw_get_rssi(msg); +#else + memcpy(rc_channels_raw, _MAV_PAYLOAD(msg), 22); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_rc_channels_scaled.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_rc_channels_scaled.h new file mode 100644 index 000000000..55fcbfffd --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_rc_channels_scaled.h @@ -0,0 +1,364 @@ +// MESSAGE RC_CHANNELS_SCALED PACKING + +#define MAVLINK_MSG_ID_RC_CHANNELS_SCALED 34 + +typedef struct __mavlink_rc_channels_scaled_t { + uint32_t time_boot_ms; ///< Timestamp (milliseconds since system boot) + int16_t chan1_scaled; ///< RC channel 1 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + int16_t chan2_scaled; ///< RC channel 2 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + int16_t chan3_scaled; ///< RC channel 3 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + int16_t chan4_scaled; ///< RC channel 4 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + int16_t chan5_scaled; ///< RC channel 5 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + int16_t chan6_scaled; ///< RC channel 6 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + int16_t chan7_scaled; ///< RC channel 7 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + int16_t chan8_scaled; ///< RC channel 8 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + uint8_t port; ///< Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows to encode more than 8 servos. + uint8_t rssi; ///< Receive signal strength indicator, 0: 0%, 255: 100% +} mavlink_rc_channels_scaled_t; + +#define MAVLINK_MSG_ID_RC_CHANNELS_SCALED_LEN 22 +#define MAVLINK_MSG_ID_34_LEN 22 + + +#define MAVLINK_MESSAGE_INFO_RC_CHANNELS_SCALED \ + { \ + "RC_CHANNELS_SCALED", \ + 11, \ + { \ + { "time_boot_ms", NULL, MAVLINK_TYPE_UINT32_T, 0, 0, offsetof(mavlink_rc_channels_scaled_t, time_boot_ms) }, \ + { "chan1_scaled", NULL, MAVLINK_TYPE_INT16_T, 0, 4, offsetof(mavlink_rc_channels_scaled_t, chan1_scaled) }, \ + { "chan2_scaled", NULL, MAVLINK_TYPE_INT16_T, 0, 6, offsetof(mavlink_rc_channels_scaled_t, chan2_scaled) }, \ + { "chan3_scaled", NULL, MAVLINK_TYPE_INT16_T, 0, 8, offsetof(mavlink_rc_channels_scaled_t, chan3_scaled) }, \ + { "chan4_scaled", NULL, MAVLINK_TYPE_INT16_T, 0, 10, offsetof(mavlink_rc_channels_scaled_t, chan4_scaled) }, \ + { "chan5_scaled", NULL, MAVLINK_TYPE_INT16_T, 0, 12, offsetof(mavlink_rc_channels_scaled_t, chan5_scaled) }, \ + { "chan6_scaled", NULL, MAVLINK_TYPE_INT16_T, 0, 14, offsetof(mavlink_rc_channels_scaled_t, chan6_scaled) }, \ + { "chan7_scaled", NULL, MAVLINK_TYPE_INT16_T, 0, 16, offsetof(mavlink_rc_channels_scaled_t, chan7_scaled) }, \ + { "chan8_scaled", NULL, MAVLINK_TYPE_INT16_T, 0, 18, offsetof(mavlink_rc_channels_scaled_t, chan8_scaled) }, \ + { "port", NULL, MAVLINK_TYPE_UINT8_T, 0, 20, offsetof(mavlink_rc_channels_scaled_t, port) }, \ + { "rssi", NULL, MAVLINK_TYPE_UINT8_T, 0, 21, offsetof(mavlink_rc_channels_scaled_t, rssi) }, \ + } \ + } + + +/** + * @brief Pack a rc_channels_scaled message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param port Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows to encode more than 8 servos. + * @param chan1_scaled RC channel 1 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + * @param chan2_scaled RC channel 2 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + * @param chan3_scaled RC channel 3 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + * @param chan4_scaled RC channel 4 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + * @param chan5_scaled RC channel 5 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + * @param chan6_scaled RC channel 6 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + * @param chan7_scaled RC channel 7 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + * @param chan8_scaled RC channel 8 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + * @param rssi Receive signal strength indicator, 0: 0%, 255: 100% + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_rc_channels_scaled_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint32_t time_boot_ms, uint8_t port, int16_t chan1_scaled, int16_t chan2_scaled, int16_t chan3_scaled, int16_t chan4_scaled, int16_t chan5_scaled, int16_t chan6_scaled, int16_t chan7_scaled, int16_t chan8_scaled, uint8_t rssi) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[22]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_int16_t(buf, 4, chan1_scaled); + _mav_put_int16_t(buf, 6, chan2_scaled); + _mav_put_int16_t(buf, 8, chan3_scaled); + _mav_put_int16_t(buf, 10, chan4_scaled); + _mav_put_int16_t(buf, 12, chan5_scaled); + _mav_put_int16_t(buf, 14, chan6_scaled); + _mav_put_int16_t(buf, 16, chan7_scaled); + _mav_put_int16_t(buf, 18, chan8_scaled); + _mav_put_uint8_t(buf, 20, port); + _mav_put_uint8_t(buf, 21, rssi); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 22); +#else + mavlink_rc_channels_scaled_t packet; + packet.time_boot_ms = time_boot_ms; + packet.chan1_scaled = chan1_scaled; + packet.chan2_scaled = chan2_scaled; + packet.chan3_scaled = chan3_scaled; + packet.chan4_scaled = chan4_scaled; + packet.chan5_scaled = chan5_scaled; + packet.chan6_scaled = chan6_scaled; + packet.chan7_scaled = chan7_scaled; + packet.chan8_scaled = chan8_scaled; + packet.port = port; + packet.rssi = rssi; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 22); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_RC_CHANNELS_SCALED; + return mavlink_finalize_message(msg, system_id, component_id, 22, 237); +} + +/** + * @brief Pack a rc_channels_scaled message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param port Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows to encode more than 8 servos. + * @param chan1_scaled RC channel 1 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + * @param chan2_scaled RC channel 2 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + * @param chan3_scaled RC channel 3 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + * @param chan4_scaled RC channel 4 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + * @param chan5_scaled RC channel 5 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + * @param chan6_scaled RC channel 6 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + * @param chan7_scaled RC channel 7 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + * @param chan8_scaled RC channel 8 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + * @param rssi Receive signal strength indicator, 0: 0%, 255: 100% + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_rc_channels_scaled_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint32_t time_boot_ms, uint8_t port, int16_t chan1_scaled, int16_t chan2_scaled, int16_t chan3_scaled, int16_t chan4_scaled, int16_t chan5_scaled, int16_t chan6_scaled, int16_t chan7_scaled, int16_t chan8_scaled, uint8_t rssi) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[22]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_int16_t(buf, 4, chan1_scaled); + _mav_put_int16_t(buf, 6, chan2_scaled); + _mav_put_int16_t(buf, 8, chan3_scaled); + _mav_put_int16_t(buf, 10, chan4_scaled); + _mav_put_int16_t(buf, 12, chan5_scaled); + _mav_put_int16_t(buf, 14, chan6_scaled); + _mav_put_int16_t(buf, 16, chan7_scaled); + _mav_put_int16_t(buf, 18, chan8_scaled); + _mav_put_uint8_t(buf, 20, port); + _mav_put_uint8_t(buf, 21, rssi); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 22); +#else + mavlink_rc_channels_scaled_t packet; + packet.time_boot_ms = time_boot_ms; + packet.chan1_scaled = chan1_scaled; + packet.chan2_scaled = chan2_scaled; + packet.chan3_scaled = chan3_scaled; + packet.chan4_scaled = chan4_scaled; + packet.chan5_scaled = chan5_scaled; + packet.chan6_scaled = chan6_scaled; + packet.chan7_scaled = chan7_scaled; + packet.chan8_scaled = chan8_scaled; + packet.port = port; + packet.rssi = rssi; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 22); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_RC_CHANNELS_SCALED; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 22, 237); +} + +/** + * @brief Encode a rc_channels_scaled struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param rc_channels_scaled C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_rc_channels_scaled_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_rc_channels_scaled_t *rc_channels_scaled) +{ + return mavlink_msg_rc_channels_scaled_pack(system_id, component_id, msg, rc_channels_scaled->time_boot_ms, rc_channels_scaled->port, rc_channels_scaled->chan1_scaled, rc_channels_scaled->chan2_scaled, rc_channels_scaled->chan3_scaled, rc_channels_scaled->chan4_scaled, rc_channels_scaled->chan5_scaled, rc_channels_scaled->chan6_scaled, rc_channels_scaled->chan7_scaled, rc_channels_scaled->chan8_scaled, rc_channels_scaled->rssi); +} + +/** + * @brief Send a rc_channels_scaled message + * @param chan MAVLink channel to send the message + * + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param port Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows to encode more than 8 servos. + * @param chan1_scaled RC channel 1 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + * @param chan2_scaled RC channel 2 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + * @param chan3_scaled RC channel 3 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + * @param chan4_scaled RC channel 4 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + * @param chan5_scaled RC channel 5 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + * @param chan6_scaled RC channel 6 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + * @param chan7_scaled RC channel 7 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + * @param chan8_scaled RC channel 8 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + * @param rssi Receive signal strength indicator, 0: 0%, 255: 100% + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_rc_channels_scaled_send(mavlink_channel_t chan, uint32_t time_boot_ms, uint8_t port, int16_t chan1_scaled, int16_t chan2_scaled, int16_t chan3_scaled, int16_t chan4_scaled, int16_t chan5_scaled, int16_t chan6_scaled, int16_t chan7_scaled, int16_t chan8_scaled, uint8_t rssi) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[22]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_int16_t(buf, 4, chan1_scaled); + _mav_put_int16_t(buf, 6, chan2_scaled); + _mav_put_int16_t(buf, 8, chan3_scaled); + _mav_put_int16_t(buf, 10, chan4_scaled); + _mav_put_int16_t(buf, 12, chan5_scaled); + _mav_put_int16_t(buf, 14, chan6_scaled); + _mav_put_int16_t(buf, 16, chan7_scaled); + _mav_put_int16_t(buf, 18, chan8_scaled); + _mav_put_uint8_t(buf, 20, port); + _mav_put_uint8_t(buf, 21, rssi); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_RC_CHANNELS_SCALED, buf, 22, 237); +#else + mavlink_rc_channels_scaled_t packet; + packet.time_boot_ms = time_boot_ms; + packet.chan1_scaled = chan1_scaled; + packet.chan2_scaled = chan2_scaled; + packet.chan3_scaled = chan3_scaled; + packet.chan4_scaled = chan4_scaled; + packet.chan5_scaled = chan5_scaled; + packet.chan6_scaled = chan6_scaled; + packet.chan7_scaled = chan7_scaled; + packet.chan8_scaled = chan8_scaled; + packet.port = port; + packet.rssi = rssi; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_RC_CHANNELS_SCALED, (const char *)&packet, 22, 237); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE RC_CHANNELS_SCALED UNPACKING + + +/** + * @brief Get field time_boot_ms from rc_channels_scaled message + * + * @return Timestamp (milliseconds since system boot) + */ +static inline uint32_t mavlink_msg_rc_channels_scaled_get_time_boot_ms(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint32_t(msg, 0); +} + +/** + * @brief Get field port from rc_channels_scaled message + * + * @return Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows to encode more than 8 servos. + */ +static inline uint8_t mavlink_msg_rc_channels_scaled_get_port(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 20); +} + +/** + * @brief Get field chan1_scaled from rc_channels_scaled message + * + * @return RC channel 1 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + */ +static inline int16_t mavlink_msg_rc_channels_scaled_get_chan1_scaled(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 4); +} + +/** + * @brief Get field chan2_scaled from rc_channels_scaled message + * + * @return RC channel 2 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + */ +static inline int16_t mavlink_msg_rc_channels_scaled_get_chan2_scaled(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 6); +} + +/** + * @brief Get field chan3_scaled from rc_channels_scaled message + * + * @return RC channel 3 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + */ +static inline int16_t mavlink_msg_rc_channels_scaled_get_chan3_scaled(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 8); +} + +/** + * @brief Get field chan4_scaled from rc_channels_scaled message + * + * @return RC channel 4 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + */ +static inline int16_t mavlink_msg_rc_channels_scaled_get_chan4_scaled(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 10); +} + +/** + * @brief Get field chan5_scaled from rc_channels_scaled message + * + * @return RC channel 5 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + */ +static inline int16_t mavlink_msg_rc_channels_scaled_get_chan5_scaled(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 12); +} + +/** + * @brief Get field chan6_scaled from rc_channels_scaled message + * + * @return RC channel 6 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + */ +static inline int16_t mavlink_msg_rc_channels_scaled_get_chan6_scaled(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 14); +} + +/** + * @brief Get field chan7_scaled from rc_channels_scaled message + * + * @return RC channel 7 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + */ +static inline int16_t mavlink_msg_rc_channels_scaled_get_chan7_scaled(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 16); +} + +/** + * @brief Get field chan8_scaled from rc_channels_scaled message + * + * @return RC channel 8 value scaled, (-100%) -10000, (0%) 0, (100%) 10000 + */ +static inline int16_t mavlink_msg_rc_channels_scaled_get_chan8_scaled(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 18); +} + +/** + * @brief Get field rssi from rc_channels_scaled message + * + * @return Receive signal strength indicator, 0: 0%, 255: 100% + */ +static inline uint8_t mavlink_msg_rc_channels_scaled_get_rssi(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 21); +} + +/** + * @brief Decode a rc_channels_scaled message into a struct + * + * @param msg The message to decode + * @param rc_channels_scaled C-struct to decode the message contents into + */ +static inline void mavlink_msg_rc_channels_scaled_decode(const mavlink_message_t *msg, mavlink_rc_channels_scaled_t *rc_channels_scaled) +{ +#if MAVLINK_NEED_BYTE_SWAP + rc_channels_scaled->time_boot_ms = mavlink_msg_rc_channels_scaled_get_time_boot_ms(msg); + rc_channels_scaled->chan1_scaled = mavlink_msg_rc_channels_scaled_get_chan1_scaled(msg); + rc_channels_scaled->chan2_scaled = mavlink_msg_rc_channels_scaled_get_chan2_scaled(msg); + rc_channels_scaled->chan3_scaled = mavlink_msg_rc_channels_scaled_get_chan3_scaled(msg); + rc_channels_scaled->chan4_scaled = mavlink_msg_rc_channels_scaled_get_chan4_scaled(msg); + rc_channels_scaled->chan5_scaled = mavlink_msg_rc_channels_scaled_get_chan5_scaled(msg); + rc_channels_scaled->chan6_scaled = mavlink_msg_rc_channels_scaled_get_chan6_scaled(msg); + rc_channels_scaled->chan7_scaled = mavlink_msg_rc_channels_scaled_get_chan7_scaled(msg); + rc_channels_scaled->chan8_scaled = mavlink_msg_rc_channels_scaled_get_chan8_scaled(msg); + rc_channels_scaled->port = mavlink_msg_rc_channels_scaled_get_port(msg); + rc_channels_scaled->rssi = mavlink_msg_rc_channels_scaled_get_rssi(msg); +#else + memcpy(rc_channels_scaled, _MAV_PAYLOAD(msg), 22); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_request_data_stream.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_request_data_stream.h new file mode 100644 index 000000000..be4037df2 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_request_data_stream.h @@ -0,0 +1,232 @@ +// MESSAGE REQUEST_DATA_STREAM PACKING + +#define MAVLINK_MSG_ID_REQUEST_DATA_STREAM 66 + +typedef struct __mavlink_request_data_stream_t { + uint16_t req_message_rate; ///< The requested interval between two messages of this type + uint8_t target_system; ///< The target requested to send the message stream. + uint8_t target_component; ///< The target requested to send the message stream. + uint8_t req_stream_id; ///< The ID of the requested data stream + uint8_t start_stop; ///< 1 to start sending, 0 to stop sending. +} mavlink_request_data_stream_t; + +#define MAVLINK_MSG_ID_REQUEST_DATA_STREAM_LEN 6 +#define MAVLINK_MSG_ID_66_LEN 6 + + +#define MAVLINK_MESSAGE_INFO_REQUEST_DATA_STREAM \ + { \ + "REQUEST_DATA_STREAM", \ + 5, \ + { \ + { "req_message_rate", NULL, MAVLINK_TYPE_UINT16_T, 0, 0, offsetof(mavlink_request_data_stream_t, req_message_rate) }, \ + { "target_system", NULL, MAVLINK_TYPE_UINT8_T, 0, 2, offsetof(mavlink_request_data_stream_t, target_system) }, \ + { "target_component", NULL, MAVLINK_TYPE_UINT8_T, 0, 3, offsetof(mavlink_request_data_stream_t, target_component) }, \ + { "req_stream_id", NULL, MAVLINK_TYPE_UINT8_T, 0, 4, offsetof(mavlink_request_data_stream_t, req_stream_id) }, \ + { "start_stop", NULL, MAVLINK_TYPE_UINT8_T, 0, 5, offsetof(mavlink_request_data_stream_t, start_stop) }, \ + } \ + } + + +/** + * @brief Pack a request_data_stream message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param target_system The target requested to send the message stream. + * @param target_component The target requested to send the message stream. + * @param req_stream_id The ID of the requested data stream + * @param req_message_rate The requested interval between two messages of this type + * @param start_stop 1 to start sending, 0 to stop sending. + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_request_data_stream_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, uint8_t req_stream_id, uint16_t req_message_rate, uint8_t start_stop) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[6]; + _mav_put_uint16_t(buf, 0, req_message_rate); + _mav_put_uint8_t(buf, 2, target_system); + _mav_put_uint8_t(buf, 3, target_component); + _mav_put_uint8_t(buf, 4, req_stream_id); + _mav_put_uint8_t(buf, 5, start_stop); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 6); +#else + mavlink_request_data_stream_t packet; + packet.req_message_rate = req_message_rate; + packet.target_system = target_system; + packet.target_component = target_component; + packet.req_stream_id = req_stream_id; + packet.start_stop = start_stop; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 6); +#endif + + msg->msgid = MAVLINK_MSG_ID_REQUEST_DATA_STREAM; + return mavlink_finalize_message(msg, system_id, component_id, 6, 148); +} + +/** + * @brief Pack a request_data_stream message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param target_system The target requested to send the message stream. + * @param target_component The target requested to send the message stream. + * @param req_stream_id The ID of the requested data stream + * @param req_message_rate The requested interval between two messages of this type + * @param start_stop 1 to start sending, 0 to stop sending. + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_request_data_stream_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, uint8_t req_stream_id, uint16_t req_message_rate, uint8_t start_stop) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[6]; + _mav_put_uint16_t(buf, 0, req_message_rate); + _mav_put_uint8_t(buf, 2, target_system); + _mav_put_uint8_t(buf, 3, target_component); + _mav_put_uint8_t(buf, 4, req_stream_id); + _mav_put_uint8_t(buf, 5, start_stop); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 6); +#else + mavlink_request_data_stream_t packet; + packet.req_message_rate = req_message_rate; + packet.target_system = target_system; + packet.target_component = target_component; + packet.req_stream_id = req_stream_id; + packet.start_stop = start_stop; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 6); +#endif + + msg->msgid = MAVLINK_MSG_ID_REQUEST_DATA_STREAM; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 6, 148); +} + +/** + * @brief Encode a request_data_stream struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param request_data_stream C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_request_data_stream_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_request_data_stream_t *request_data_stream) +{ + return mavlink_msg_request_data_stream_pack(system_id, component_id, msg, request_data_stream->target_system, request_data_stream->target_component, request_data_stream->req_stream_id, request_data_stream->req_message_rate, request_data_stream->start_stop); +} + +/** + * @brief Send a request_data_stream message + * @param chan MAVLink channel to send the message + * + * @param target_system The target requested to send the message stream. + * @param target_component The target requested to send the message stream. + * @param req_stream_id The ID of the requested data stream + * @param req_message_rate The requested interval between two messages of this type + * @param start_stop 1 to start sending, 0 to stop sending. + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_request_data_stream_send(mavlink_channel_t chan, uint8_t target_system, uint8_t target_component, uint8_t req_stream_id, uint16_t req_message_rate, uint8_t start_stop) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[6]; + _mav_put_uint16_t(buf, 0, req_message_rate); + _mav_put_uint8_t(buf, 2, target_system); + _mav_put_uint8_t(buf, 3, target_component); + _mav_put_uint8_t(buf, 4, req_stream_id); + _mav_put_uint8_t(buf, 5, start_stop); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_REQUEST_DATA_STREAM, buf, 6, 148); +#else + mavlink_request_data_stream_t packet; + packet.req_message_rate = req_message_rate; + packet.target_system = target_system; + packet.target_component = target_component; + packet.req_stream_id = req_stream_id; + packet.start_stop = start_stop; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_REQUEST_DATA_STREAM, (const char *)&packet, 6, 148); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE REQUEST_DATA_STREAM UNPACKING + + +/** + * @brief Get field target_system from request_data_stream message + * + * @return The target requested to send the message stream. + */ +static inline uint8_t mavlink_msg_request_data_stream_get_target_system(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 2); +} + +/** + * @brief Get field target_component from request_data_stream message + * + * @return The target requested to send the message stream. + */ +static inline uint8_t mavlink_msg_request_data_stream_get_target_component(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 3); +} + +/** + * @brief Get field req_stream_id from request_data_stream message + * + * @return The ID of the requested data stream + */ +static inline uint8_t mavlink_msg_request_data_stream_get_req_stream_id(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 4); +} + +/** + * @brief Get field req_message_rate from request_data_stream message + * + * @return The requested interval between two messages of this type + */ +static inline uint16_t mavlink_msg_request_data_stream_get_req_message_rate(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 0); +} + +/** + * @brief Get field start_stop from request_data_stream message + * + * @return 1 to start sending, 0 to stop sending. + */ +static inline uint8_t mavlink_msg_request_data_stream_get_start_stop(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 5); +} + +/** + * @brief Decode a request_data_stream message into a struct + * + * @param msg The message to decode + * @param request_data_stream C-struct to decode the message contents into + */ +static inline void mavlink_msg_request_data_stream_decode(const mavlink_message_t *msg, mavlink_request_data_stream_t *request_data_stream) +{ +#if MAVLINK_NEED_BYTE_SWAP + request_data_stream->req_message_rate = mavlink_msg_request_data_stream_get_req_message_rate(msg); + request_data_stream->target_system = mavlink_msg_request_data_stream_get_target_system(msg); + request_data_stream->target_component = mavlink_msg_request_data_stream_get_target_component(msg); + request_data_stream->req_stream_id = mavlink_msg_request_data_stream_get_req_stream_id(msg); + request_data_stream->start_stop = mavlink_msg_request_data_stream_get_start_stop(msg); +#else + memcpy(request_data_stream, _MAV_PAYLOAD(msg), 6); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint.h new file mode 100644 index 000000000..7e1025bf1 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint.h @@ -0,0 +1,232 @@ +// MESSAGE ROLL_PITCH_YAW_SPEED_THRUST_SETPOINT PACKING + +#define MAVLINK_MSG_ID_ROLL_PITCH_YAW_SPEED_THRUST_SETPOINT 59 + +typedef struct __mavlink_roll_pitch_yaw_speed_thrust_setpoint_t { + uint32_t time_boot_ms; ///< Timestamp in milliseconds since system boot + float roll_speed; ///< Desired roll angular speed in rad/s + float pitch_speed; ///< Desired pitch angular speed in rad/s + float yaw_speed; ///< Desired yaw angular speed in rad/s + float thrust; ///< Collective thrust, normalized to 0 .. 1 +} mavlink_roll_pitch_yaw_speed_thrust_setpoint_t; + +#define MAVLINK_MSG_ID_ROLL_PITCH_YAW_SPEED_THRUST_SETPOINT_LEN 20 +#define MAVLINK_MSG_ID_59_LEN 20 + + +#define MAVLINK_MESSAGE_INFO_ROLL_PITCH_YAW_SPEED_THRUST_SETPOINT \ + { \ + "ROLL_PITCH_YAW_SPEED_THRUST_SETPOINT", \ + 5, \ + { \ + { "time_boot_ms", NULL, MAVLINK_TYPE_UINT32_T, 0, 0, offsetof(mavlink_roll_pitch_yaw_speed_thrust_setpoint_t, time_boot_ms) }, \ + { "roll_speed", NULL, MAVLINK_TYPE_FLOAT, 0, 4, offsetof(mavlink_roll_pitch_yaw_speed_thrust_setpoint_t, roll_speed) }, \ + { "pitch_speed", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_roll_pitch_yaw_speed_thrust_setpoint_t, pitch_speed) }, \ + { "yaw_speed", NULL, MAVLINK_TYPE_FLOAT, 0, 12, offsetof(mavlink_roll_pitch_yaw_speed_thrust_setpoint_t, yaw_speed) }, \ + { "thrust", NULL, MAVLINK_TYPE_FLOAT, 0, 16, offsetof(mavlink_roll_pitch_yaw_speed_thrust_setpoint_t, thrust) }, \ + } \ + } + + +/** + * @brief Pack a roll_pitch_yaw_speed_thrust_setpoint message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param time_boot_ms Timestamp in milliseconds since system boot + * @param roll_speed Desired roll angular speed in rad/s + * @param pitch_speed Desired pitch angular speed in rad/s + * @param yaw_speed Desired yaw angular speed in rad/s + * @param thrust Collective thrust, normalized to 0 .. 1 + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint32_t time_boot_ms, float roll_speed, float pitch_speed, float yaw_speed, float thrust) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[20]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_float(buf, 4, roll_speed); + _mav_put_float(buf, 8, pitch_speed); + _mav_put_float(buf, 12, yaw_speed); + _mav_put_float(buf, 16, thrust); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 20); +#else + mavlink_roll_pitch_yaw_speed_thrust_setpoint_t packet; + packet.time_boot_ms = time_boot_ms; + packet.roll_speed = roll_speed; + packet.pitch_speed = pitch_speed; + packet.yaw_speed = yaw_speed; + packet.thrust = thrust; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 20); +#endif + + msg->msgid = MAVLINK_MSG_ID_ROLL_PITCH_YAW_SPEED_THRUST_SETPOINT; + return mavlink_finalize_message(msg, system_id, component_id, 20, 238); +} + +/** + * @brief Pack a roll_pitch_yaw_speed_thrust_setpoint message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param time_boot_ms Timestamp in milliseconds since system boot + * @param roll_speed Desired roll angular speed in rad/s + * @param pitch_speed Desired pitch angular speed in rad/s + * @param yaw_speed Desired yaw angular speed in rad/s + * @param thrust Collective thrust, normalized to 0 .. 1 + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint32_t time_boot_ms, float roll_speed, float pitch_speed, float yaw_speed, float thrust) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[20]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_float(buf, 4, roll_speed); + _mav_put_float(buf, 8, pitch_speed); + _mav_put_float(buf, 12, yaw_speed); + _mav_put_float(buf, 16, thrust); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 20); +#else + mavlink_roll_pitch_yaw_speed_thrust_setpoint_t packet; + packet.time_boot_ms = time_boot_ms; + packet.roll_speed = roll_speed; + packet.pitch_speed = pitch_speed; + packet.yaw_speed = yaw_speed; + packet.thrust = thrust; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 20); +#endif + + msg->msgid = MAVLINK_MSG_ID_ROLL_PITCH_YAW_SPEED_THRUST_SETPOINT; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 20, 238); +} + +/** + * @brief Encode a roll_pitch_yaw_speed_thrust_setpoint struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param roll_pitch_yaw_speed_thrust_setpoint C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_roll_pitch_yaw_speed_thrust_setpoint_t *roll_pitch_yaw_speed_thrust_setpoint) +{ + return mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_pack(system_id, component_id, msg, roll_pitch_yaw_speed_thrust_setpoint->time_boot_ms, roll_pitch_yaw_speed_thrust_setpoint->roll_speed, roll_pitch_yaw_speed_thrust_setpoint->pitch_speed, roll_pitch_yaw_speed_thrust_setpoint->yaw_speed, roll_pitch_yaw_speed_thrust_setpoint->thrust); +} + +/** + * @brief Send a roll_pitch_yaw_speed_thrust_setpoint message + * @param chan MAVLink channel to send the message + * + * @param time_boot_ms Timestamp in milliseconds since system boot + * @param roll_speed Desired roll angular speed in rad/s + * @param pitch_speed Desired pitch angular speed in rad/s + * @param yaw_speed Desired yaw angular speed in rad/s + * @param thrust Collective thrust, normalized to 0 .. 1 + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_send(mavlink_channel_t chan, uint32_t time_boot_ms, float roll_speed, float pitch_speed, float yaw_speed, float thrust) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[20]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_float(buf, 4, roll_speed); + _mav_put_float(buf, 8, pitch_speed); + _mav_put_float(buf, 12, yaw_speed); + _mav_put_float(buf, 16, thrust); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_ROLL_PITCH_YAW_SPEED_THRUST_SETPOINT, buf, 20, 238); +#else + mavlink_roll_pitch_yaw_speed_thrust_setpoint_t packet; + packet.time_boot_ms = time_boot_ms; + packet.roll_speed = roll_speed; + packet.pitch_speed = pitch_speed; + packet.yaw_speed = yaw_speed; + packet.thrust = thrust; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_ROLL_PITCH_YAW_SPEED_THRUST_SETPOINT, (const char *)&packet, 20, 238); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE ROLL_PITCH_YAW_SPEED_THRUST_SETPOINT UNPACKING + + +/** + * @brief Get field time_boot_ms from roll_pitch_yaw_speed_thrust_setpoint message + * + * @return Timestamp in milliseconds since system boot + */ +static inline uint32_t mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_get_time_boot_ms(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint32_t(msg, 0); +} + +/** + * @brief Get field roll_speed from roll_pitch_yaw_speed_thrust_setpoint message + * + * @return Desired roll angular speed in rad/s + */ +static inline float mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_get_roll_speed(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 4); +} + +/** + * @brief Get field pitch_speed from roll_pitch_yaw_speed_thrust_setpoint message + * + * @return Desired pitch angular speed in rad/s + */ +static inline float mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_get_pitch_speed(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 8); +} + +/** + * @brief Get field yaw_speed from roll_pitch_yaw_speed_thrust_setpoint message + * + * @return Desired yaw angular speed in rad/s + */ +static inline float mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_get_yaw_speed(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 12); +} + +/** + * @brief Get field thrust from roll_pitch_yaw_speed_thrust_setpoint message + * + * @return Collective thrust, normalized to 0 .. 1 + */ +static inline float mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_get_thrust(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 16); +} + +/** + * @brief Decode a roll_pitch_yaw_speed_thrust_setpoint message into a struct + * + * @param msg The message to decode + * @param roll_pitch_yaw_speed_thrust_setpoint C-struct to decode the message contents into + */ +static inline void mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_decode(const mavlink_message_t *msg, mavlink_roll_pitch_yaw_speed_thrust_setpoint_t *roll_pitch_yaw_speed_thrust_setpoint) +{ +#if MAVLINK_NEED_BYTE_SWAP + roll_pitch_yaw_speed_thrust_setpoint->time_boot_ms = mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_get_time_boot_ms(msg); + roll_pitch_yaw_speed_thrust_setpoint->roll_speed = mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_get_roll_speed(msg); + roll_pitch_yaw_speed_thrust_setpoint->pitch_speed = mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_get_pitch_speed(msg); + roll_pitch_yaw_speed_thrust_setpoint->yaw_speed = mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_get_yaw_speed(msg); + roll_pitch_yaw_speed_thrust_setpoint->thrust = mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_get_thrust(msg); +#else + memcpy(roll_pitch_yaw_speed_thrust_setpoint, _MAV_PAYLOAD(msg), 20); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_roll_pitch_yaw_thrust_setpoint.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_roll_pitch_yaw_thrust_setpoint.h new file mode 100644 index 000000000..cde3f88db --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_roll_pitch_yaw_thrust_setpoint.h @@ -0,0 +1,232 @@ +// MESSAGE ROLL_PITCH_YAW_THRUST_SETPOINT PACKING + +#define MAVLINK_MSG_ID_ROLL_PITCH_YAW_THRUST_SETPOINT 58 + +typedef struct __mavlink_roll_pitch_yaw_thrust_setpoint_t { + uint32_t time_boot_ms; ///< Timestamp in milliseconds since system boot + float roll; ///< Desired roll angle in radians + float pitch; ///< Desired pitch angle in radians + float yaw; ///< Desired yaw angle in radians + float thrust; ///< Collective thrust, normalized to 0 .. 1 +} mavlink_roll_pitch_yaw_thrust_setpoint_t; + +#define MAVLINK_MSG_ID_ROLL_PITCH_YAW_THRUST_SETPOINT_LEN 20 +#define MAVLINK_MSG_ID_58_LEN 20 + + +#define MAVLINK_MESSAGE_INFO_ROLL_PITCH_YAW_THRUST_SETPOINT \ + { \ + "ROLL_PITCH_YAW_THRUST_SETPOINT", \ + 5, \ + { \ + { "time_boot_ms", NULL, MAVLINK_TYPE_UINT32_T, 0, 0, offsetof(mavlink_roll_pitch_yaw_thrust_setpoint_t, time_boot_ms) }, \ + { "roll", NULL, MAVLINK_TYPE_FLOAT, 0, 4, offsetof(mavlink_roll_pitch_yaw_thrust_setpoint_t, roll) }, \ + { "pitch", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_roll_pitch_yaw_thrust_setpoint_t, pitch) }, \ + { "yaw", NULL, MAVLINK_TYPE_FLOAT, 0, 12, offsetof(mavlink_roll_pitch_yaw_thrust_setpoint_t, yaw) }, \ + { "thrust", NULL, MAVLINK_TYPE_FLOAT, 0, 16, offsetof(mavlink_roll_pitch_yaw_thrust_setpoint_t, thrust) }, \ + } \ + } + + +/** + * @brief Pack a roll_pitch_yaw_thrust_setpoint message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param time_boot_ms Timestamp in milliseconds since system boot + * @param roll Desired roll angle in radians + * @param pitch Desired pitch angle in radians + * @param yaw Desired yaw angle in radians + * @param thrust Collective thrust, normalized to 0 .. 1 + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_roll_pitch_yaw_thrust_setpoint_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint32_t time_boot_ms, float roll, float pitch, float yaw, float thrust) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[20]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_float(buf, 4, roll); + _mav_put_float(buf, 8, pitch); + _mav_put_float(buf, 12, yaw); + _mav_put_float(buf, 16, thrust); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 20); +#else + mavlink_roll_pitch_yaw_thrust_setpoint_t packet; + packet.time_boot_ms = time_boot_ms; + packet.roll = roll; + packet.pitch = pitch; + packet.yaw = yaw; + packet.thrust = thrust; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 20); +#endif + + msg->msgid = MAVLINK_MSG_ID_ROLL_PITCH_YAW_THRUST_SETPOINT; + return mavlink_finalize_message(msg, system_id, component_id, 20, 239); +} + +/** + * @brief Pack a roll_pitch_yaw_thrust_setpoint message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param time_boot_ms Timestamp in milliseconds since system boot + * @param roll Desired roll angle in radians + * @param pitch Desired pitch angle in radians + * @param yaw Desired yaw angle in radians + * @param thrust Collective thrust, normalized to 0 .. 1 + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_roll_pitch_yaw_thrust_setpoint_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint32_t time_boot_ms, float roll, float pitch, float yaw, float thrust) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[20]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_float(buf, 4, roll); + _mav_put_float(buf, 8, pitch); + _mav_put_float(buf, 12, yaw); + _mav_put_float(buf, 16, thrust); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 20); +#else + mavlink_roll_pitch_yaw_thrust_setpoint_t packet; + packet.time_boot_ms = time_boot_ms; + packet.roll = roll; + packet.pitch = pitch; + packet.yaw = yaw; + packet.thrust = thrust; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 20); +#endif + + msg->msgid = MAVLINK_MSG_ID_ROLL_PITCH_YAW_THRUST_SETPOINT; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 20, 239); +} + +/** + * @brief Encode a roll_pitch_yaw_thrust_setpoint struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param roll_pitch_yaw_thrust_setpoint C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_roll_pitch_yaw_thrust_setpoint_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_roll_pitch_yaw_thrust_setpoint_t *roll_pitch_yaw_thrust_setpoint) +{ + return mavlink_msg_roll_pitch_yaw_thrust_setpoint_pack(system_id, component_id, msg, roll_pitch_yaw_thrust_setpoint->time_boot_ms, roll_pitch_yaw_thrust_setpoint->roll, roll_pitch_yaw_thrust_setpoint->pitch, roll_pitch_yaw_thrust_setpoint->yaw, roll_pitch_yaw_thrust_setpoint->thrust); +} + +/** + * @brief Send a roll_pitch_yaw_thrust_setpoint message + * @param chan MAVLink channel to send the message + * + * @param time_boot_ms Timestamp in milliseconds since system boot + * @param roll Desired roll angle in radians + * @param pitch Desired pitch angle in radians + * @param yaw Desired yaw angle in radians + * @param thrust Collective thrust, normalized to 0 .. 1 + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_roll_pitch_yaw_thrust_setpoint_send(mavlink_channel_t chan, uint32_t time_boot_ms, float roll, float pitch, float yaw, float thrust) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[20]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_float(buf, 4, roll); + _mav_put_float(buf, 8, pitch); + _mav_put_float(buf, 12, yaw); + _mav_put_float(buf, 16, thrust); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_ROLL_PITCH_YAW_THRUST_SETPOINT, buf, 20, 239); +#else + mavlink_roll_pitch_yaw_thrust_setpoint_t packet; + packet.time_boot_ms = time_boot_ms; + packet.roll = roll; + packet.pitch = pitch; + packet.yaw = yaw; + packet.thrust = thrust; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_ROLL_PITCH_YAW_THRUST_SETPOINT, (const char *)&packet, 20, 239); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE ROLL_PITCH_YAW_THRUST_SETPOINT UNPACKING + + +/** + * @brief Get field time_boot_ms from roll_pitch_yaw_thrust_setpoint message + * + * @return Timestamp in milliseconds since system boot + */ +static inline uint32_t mavlink_msg_roll_pitch_yaw_thrust_setpoint_get_time_boot_ms(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint32_t(msg, 0); +} + +/** + * @brief Get field roll from roll_pitch_yaw_thrust_setpoint message + * + * @return Desired roll angle in radians + */ +static inline float mavlink_msg_roll_pitch_yaw_thrust_setpoint_get_roll(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 4); +} + +/** + * @brief Get field pitch from roll_pitch_yaw_thrust_setpoint message + * + * @return Desired pitch angle in radians + */ +static inline float mavlink_msg_roll_pitch_yaw_thrust_setpoint_get_pitch(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 8); +} + +/** + * @brief Get field yaw from roll_pitch_yaw_thrust_setpoint message + * + * @return Desired yaw angle in radians + */ +static inline float mavlink_msg_roll_pitch_yaw_thrust_setpoint_get_yaw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 12); +} + +/** + * @brief Get field thrust from roll_pitch_yaw_thrust_setpoint message + * + * @return Collective thrust, normalized to 0 .. 1 + */ +static inline float mavlink_msg_roll_pitch_yaw_thrust_setpoint_get_thrust(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 16); +} + +/** + * @brief Decode a roll_pitch_yaw_thrust_setpoint message into a struct + * + * @param msg The message to decode + * @param roll_pitch_yaw_thrust_setpoint C-struct to decode the message contents into + */ +static inline void mavlink_msg_roll_pitch_yaw_thrust_setpoint_decode(const mavlink_message_t *msg, mavlink_roll_pitch_yaw_thrust_setpoint_t *roll_pitch_yaw_thrust_setpoint) +{ +#if MAVLINK_NEED_BYTE_SWAP + roll_pitch_yaw_thrust_setpoint->time_boot_ms = mavlink_msg_roll_pitch_yaw_thrust_setpoint_get_time_boot_ms(msg); + roll_pitch_yaw_thrust_setpoint->roll = mavlink_msg_roll_pitch_yaw_thrust_setpoint_get_roll(msg); + roll_pitch_yaw_thrust_setpoint->pitch = mavlink_msg_roll_pitch_yaw_thrust_setpoint_get_pitch(msg); + roll_pitch_yaw_thrust_setpoint->yaw = mavlink_msg_roll_pitch_yaw_thrust_setpoint_get_yaw(msg); + roll_pitch_yaw_thrust_setpoint->thrust = mavlink_msg_roll_pitch_yaw_thrust_setpoint_get_thrust(msg); +#else + memcpy(roll_pitch_yaw_thrust_setpoint, _MAV_PAYLOAD(msg), 20); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_safety_allowed_area.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_safety_allowed_area.h new file mode 100644 index 000000000..55d050af4 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_safety_allowed_area.h @@ -0,0 +1,276 @@ +// MESSAGE SAFETY_ALLOWED_AREA PACKING + +#define MAVLINK_MSG_ID_SAFETY_ALLOWED_AREA 55 + +typedef struct __mavlink_safety_allowed_area_t { + float p1x; ///< x position 1 / Latitude 1 + float p1y; ///< y position 1 / Longitude 1 + float p1z; ///< z position 1 / Altitude 1 + float p2x; ///< x position 2 / Latitude 2 + float p2y; ///< y position 2 / Longitude 2 + float p2z; ///< z position 2 / Altitude 2 + uint8_t frame; ///< Coordinate frame, as defined by MAV_FRAME enum in mavlink_types.h. Can be either global, GPS, right-handed with Z axis up or local, right handed, Z axis down. +} mavlink_safety_allowed_area_t; + +#define MAVLINK_MSG_ID_SAFETY_ALLOWED_AREA_LEN 25 +#define MAVLINK_MSG_ID_55_LEN 25 + + +#define MAVLINK_MESSAGE_INFO_SAFETY_ALLOWED_AREA \ + { \ + "SAFETY_ALLOWED_AREA", \ + 7, \ + { \ + { "p1x", NULL, MAVLINK_TYPE_FLOAT, 0, 0, offsetof(mavlink_safety_allowed_area_t, p1x) }, \ + { "p1y", NULL, MAVLINK_TYPE_FLOAT, 0, 4, offsetof(mavlink_safety_allowed_area_t, p1y) }, \ + { "p1z", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_safety_allowed_area_t, p1z) }, \ + { "p2x", NULL, MAVLINK_TYPE_FLOAT, 0, 12, offsetof(mavlink_safety_allowed_area_t, p2x) }, \ + { "p2y", NULL, MAVLINK_TYPE_FLOAT, 0, 16, offsetof(mavlink_safety_allowed_area_t, p2y) }, \ + { "p2z", NULL, MAVLINK_TYPE_FLOAT, 0, 20, offsetof(mavlink_safety_allowed_area_t, p2z) }, \ + { "frame", NULL, MAVLINK_TYPE_UINT8_T, 0, 24, offsetof(mavlink_safety_allowed_area_t, frame) }, \ + } \ + } + + +/** + * @brief Pack a safety_allowed_area message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param frame Coordinate frame, as defined by MAV_FRAME enum in mavlink_types.h. Can be either global, GPS, right-handed with Z axis up or local, right handed, Z axis down. + * @param p1x x position 1 / Latitude 1 + * @param p1y y position 1 / Longitude 1 + * @param p1z z position 1 / Altitude 1 + * @param p2x x position 2 / Latitude 2 + * @param p2y y position 2 / Longitude 2 + * @param p2z z position 2 / Altitude 2 + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_safety_allowed_area_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t frame, float p1x, float p1y, float p1z, float p2x, float p2y, float p2z) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[25]; + _mav_put_float(buf, 0, p1x); + _mav_put_float(buf, 4, p1y); + _mav_put_float(buf, 8, p1z); + _mav_put_float(buf, 12, p2x); + _mav_put_float(buf, 16, p2y); + _mav_put_float(buf, 20, p2z); + _mav_put_uint8_t(buf, 24, frame); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 25); +#else + mavlink_safety_allowed_area_t packet; + packet.p1x = p1x; + packet.p1y = p1y; + packet.p1z = p1z; + packet.p2x = p2x; + packet.p2y = p2y; + packet.p2z = p2z; + packet.frame = frame; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 25); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_SAFETY_ALLOWED_AREA; + return mavlink_finalize_message(msg, system_id, component_id, 25, 3); +} + +/** + * @brief Pack a safety_allowed_area message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param frame Coordinate frame, as defined by MAV_FRAME enum in mavlink_types.h. Can be either global, GPS, right-handed with Z axis up or local, right handed, Z axis down. + * @param p1x x position 1 / Latitude 1 + * @param p1y y position 1 / Longitude 1 + * @param p1z z position 1 / Altitude 1 + * @param p2x x position 2 / Latitude 2 + * @param p2y y position 2 / Longitude 2 + * @param p2z z position 2 / Altitude 2 + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_safety_allowed_area_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t frame, float p1x, float p1y, float p1z, float p2x, float p2y, float p2z) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[25]; + _mav_put_float(buf, 0, p1x); + _mav_put_float(buf, 4, p1y); + _mav_put_float(buf, 8, p1z); + _mav_put_float(buf, 12, p2x); + _mav_put_float(buf, 16, p2y); + _mav_put_float(buf, 20, p2z); + _mav_put_uint8_t(buf, 24, frame); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 25); +#else + mavlink_safety_allowed_area_t packet; + packet.p1x = p1x; + packet.p1y = p1y; + packet.p1z = p1z; + packet.p2x = p2x; + packet.p2y = p2y; + packet.p2z = p2z; + packet.frame = frame; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 25); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_SAFETY_ALLOWED_AREA; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 25, 3); +} + +/** + * @brief Encode a safety_allowed_area struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param safety_allowed_area C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_safety_allowed_area_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_safety_allowed_area_t *safety_allowed_area) +{ + return mavlink_msg_safety_allowed_area_pack(system_id, component_id, msg, safety_allowed_area->frame, safety_allowed_area->p1x, safety_allowed_area->p1y, safety_allowed_area->p1z, safety_allowed_area->p2x, safety_allowed_area->p2y, safety_allowed_area->p2z); +} + +/** + * @brief Send a safety_allowed_area message + * @param chan MAVLink channel to send the message + * + * @param frame Coordinate frame, as defined by MAV_FRAME enum in mavlink_types.h. Can be either global, GPS, right-handed with Z axis up or local, right handed, Z axis down. + * @param p1x x position 1 / Latitude 1 + * @param p1y y position 1 / Longitude 1 + * @param p1z z position 1 / Altitude 1 + * @param p2x x position 2 / Latitude 2 + * @param p2y y position 2 / Longitude 2 + * @param p2z z position 2 / Altitude 2 + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_safety_allowed_area_send(mavlink_channel_t chan, uint8_t frame, float p1x, float p1y, float p1z, float p2x, float p2y, float p2z) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[25]; + _mav_put_float(buf, 0, p1x); + _mav_put_float(buf, 4, p1y); + _mav_put_float(buf, 8, p1z); + _mav_put_float(buf, 12, p2x); + _mav_put_float(buf, 16, p2y); + _mav_put_float(buf, 20, p2z); + _mav_put_uint8_t(buf, 24, frame); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SAFETY_ALLOWED_AREA, buf, 25, 3); +#else + mavlink_safety_allowed_area_t packet; + packet.p1x = p1x; + packet.p1y = p1y; + packet.p1z = p1z; + packet.p2x = p2x; + packet.p2y = p2y; + packet.p2z = p2z; + packet.frame = frame; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SAFETY_ALLOWED_AREA, (const char *)&packet, 25, 3); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE SAFETY_ALLOWED_AREA UNPACKING + + +/** + * @brief Get field frame from safety_allowed_area message + * + * @return Coordinate frame, as defined by MAV_FRAME enum in mavlink_types.h. Can be either global, GPS, right-handed with Z axis up or local, right handed, Z axis down. + */ +static inline uint8_t mavlink_msg_safety_allowed_area_get_frame(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 24); +} + +/** + * @brief Get field p1x from safety_allowed_area message + * + * @return x position 1 / Latitude 1 + */ +static inline float mavlink_msg_safety_allowed_area_get_p1x(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 0); +} + +/** + * @brief Get field p1y from safety_allowed_area message + * + * @return y position 1 / Longitude 1 + */ +static inline float mavlink_msg_safety_allowed_area_get_p1y(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 4); +} + +/** + * @brief Get field p1z from safety_allowed_area message + * + * @return z position 1 / Altitude 1 + */ +static inline float mavlink_msg_safety_allowed_area_get_p1z(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 8); +} + +/** + * @brief Get field p2x from safety_allowed_area message + * + * @return x position 2 / Latitude 2 + */ +static inline float mavlink_msg_safety_allowed_area_get_p2x(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 12); +} + +/** + * @brief Get field p2y from safety_allowed_area message + * + * @return y position 2 / Longitude 2 + */ +static inline float mavlink_msg_safety_allowed_area_get_p2y(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 16); +} + +/** + * @brief Get field p2z from safety_allowed_area message + * + * @return z position 2 / Altitude 2 + */ +static inline float mavlink_msg_safety_allowed_area_get_p2z(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 20); +} + +/** + * @brief Decode a safety_allowed_area message into a struct + * + * @param msg The message to decode + * @param safety_allowed_area C-struct to decode the message contents into + */ +static inline void mavlink_msg_safety_allowed_area_decode(const mavlink_message_t *msg, mavlink_safety_allowed_area_t *safety_allowed_area) +{ +#if MAVLINK_NEED_BYTE_SWAP + safety_allowed_area->p1x = mavlink_msg_safety_allowed_area_get_p1x(msg); + safety_allowed_area->p1y = mavlink_msg_safety_allowed_area_get_p1y(msg); + safety_allowed_area->p1z = mavlink_msg_safety_allowed_area_get_p1z(msg); + safety_allowed_area->p2x = mavlink_msg_safety_allowed_area_get_p2x(msg); + safety_allowed_area->p2y = mavlink_msg_safety_allowed_area_get_p2y(msg); + safety_allowed_area->p2z = mavlink_msg_safety_allowed_area_get_p2z(msg); + safety_allowed_area->frame = mavlink_msg_safety_allowed_area_get_frame(msg); +#else + memcpy(safety_allowed_area, _MAV_PAYLOAD(msg), 25); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_safety_set_allowed_area.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_safety_set_allowed_area.h new file mode 100644 index 000000000..3e03e2a7c --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_safety_set_allowed_area.h @@ -0,0 +1,320 @@ +// MESSAGE SAFETY_SET_ALLOWED_AREA PACKING + +#define MAVLINK_MSG_ID_SAFETY_SET_ALLOWED_AREA 54 + +typedef struct __mavlink_safety_set_allowed_area_t { + float p1x; ///< x position 1 / Latitude 1 + float p1y; ///< y position 1 / Longitude 1 + float p1z; ///< z position 1 / Altitude 1 + float p2x; ///< x position 2 / Latitude 2 + float p2y; ///< y position 2 / Longitude 2 + float p2z; ///< z position 2 / Altitude 2 + uint8_t target_system; ///< System ID + uint8_t target_component; ///< Component ID + uint8_t frame; ///< Coordinate frame, as defined by MAV_FRAME enum in mavlink_types.h. Can be either global, GPS, right-handed with Z axis up or local, right handed, Z axis down. +} mavlink_safety_set_allowed_area_t; + +#define MAVLINK_MSG_ID_SAFETY_SET_ALLOWED_AREA_LEN 27 +#define MAVLINK_MSG_ID_54_LEN 27 + + +#define MAVLINK_MESSAGE_INFO_SAFETY_SET_ALLOWED_AREA \ + { \ + "SAFETY_SET_ALLOWED_AREA", \ + 9, \ + { \ + { "p1x", NULL, MAVLINK_TYPE_FLOAT, 0, 0, offsetof(mavlink_safety_set_allowed_area_t, p1x) }, \ + { "p1y", NULL, MAVLINK_TYPE_FLOAT, 0, 4, offsetof(mavlink_safety_set_allowed_area_t, p1y) }, \ + { "p1z", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_safety_set_allowed_area_t, p1z) }, \ + { "p2x", NULL, MAVLINK_TYPE_FLOAT, 0, 12, offsetof(mavlink_safety_set_allowed_area_t, p2x) }, \ + { "p2y", NULL, MAVLINK_TYPE_FLOAT, 0, 16, offsetof(mavlink_safety_set_allowed_area_t, p2y) }, \ + { "p2z", NULL, MAVLINK_TYPE_FLOAT, 0, 20, offsetof(mavlink_safety_set_allowed_area_t, p2z) }, \ + { "target_system", NULL, MAVLINK_TYPE_UINT8_T, 0, 24, offsetof(mavlink_safety_set_allowed_area_t, target_system) }, \ + { "target_component", NULL, MAVLINK_TYPE_UINT8_T, 0, 25, offsetof(mavlink_safety_set_allowed_area_t, target_component) }, \ + { "frame", NULL, MAVLINK_TYPE_UINT8_T, 0, 26, offsetof(mavlink_safety_set_allowed_area_t, frame) }, \ + } \ + } + + +/** + * @brief Pack a safety_set_allowed_area message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param target_system System ID + * @param target_component Component ID + * @param frame Coordinate frame, as defined by MAV_FRAME enum in mavlink_types.h. Can be either global, GPS, right-handed with Z axis up or local, right handed, Z axis down. + * @param p1x x position 1 / Latitude 1 + * @param p1y y position 1 / Longitude 1 + * @param p1z z position 1 / Altitude 1 + * @param p2x x position 2 / Latitude 2 + * @param p2y y position 2 / Longitude 2 + * @param p2z z position 2 / Altitude 2 + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_safety_set_allowed_area_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, uint8_t frame, float p1x, float p1y, float p1z, float p2x, float p2y, float p2z) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[27]; + _mav_put_float(buf, 0, p1x); + _mav_put_float(buf, 4, p1y); + _mav_put_float(buf, 8, p1z); + _mav_put_float(buf, 12, p2x); + _mav_put_float(buf, 16, p2y); + _mav_put_float(buf, 20, p2z); + _mav_put_uint8_t(buf, 24, target_system); + _mav_put_uint8_t(buf, 25, target_component); + _mav_put_uint8_t(buf, 26, frame); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 27); +#else + mavlink_safety_set_allowed_area_t packet; + packet.p1x = p1x; + packet.p1y = p1y; + packet.p1z = p1z; + packet.p2x = p2x; + packet.p2y = p2y; + packet.p2z = p2z; + packet.target_system = target_system; + packet.target_component = target_component; + packet.frame = frame; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 27); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_SAFETY_SET_ALLOWED_AREA; + return mavlink_finalize_message(msg, system_id, component_id, 27, 15); +} + +/** + * @brief Pack a safety_set_allowed_area message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param target_system System ID + * @param target_component Component ID + * @param frame Coordinate frame, as defined by MAV_FRAME enum in mavlink_types.h. Can be either global, GPS, right-handed with Z axis up or local, right handed, Z axis down. + * @param p1x x position 1 / Latitude 1 + * @param p1y y position 1 / Longitude 1 + * @param p1z z position 1 / Altitude 1 + * @param p2x x position 2 / Latitude 2 + * @param p2y y position 2 / Longitude 2 + * @param p2z z position 2 / Altitude 2 + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_safety_set_allowed_area_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, uint8_t frame, float p1x, float p1y, float p1z, float p2x, float p2y, float p2z) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[27]; + _mav_put_float(buf, 0, p1x); + _mav_put_float(buf, 4, p1y); + _mav_put_float(buf, 8, p1z); + _mav_put_float(buf, 12, p2x); + _mav_put_float(buf, 16, p2y); + _mav_put_float(buf, 20, p2z); + _mav_put_uint8_t(buf, 24, target_system); + _mav_put_uint8_t(buf, 25, target_component); + _mav_put_uint8_t(buf, 26, frame); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 27); +#else + mavlink_safety_set_allowed_area_t packet; + packet.p1x = p1x; + packet.p1y = p1y; + packet.p1z = p1z; + packet.p2x = p2x; + packet.p2y = p2y; + packet.p2z = p2z; + packet.target_system = target_system; + packet.target_component = target_component; + packet.frame = frame; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 27); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_SAFETY_SET_ALLOWED_AREA; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 27, 15); +} + +/** + * @brief Encode a safety_set_allowed_area struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param safety_set_allowed_area C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_safety_set_allowed_area_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_safety_set_allowed_area_t *safety_set_allowed_area) +{ + return mavlink_msg_safety_set_allowed_area_pack(system_id, component_id, msg, safety_set_allowed_area->target_system, safety_set_allowed_area->target_component, safety_set_allowed_area->frame, safety_set_allowed_area->p1x, safety_set_allowed_area->p1y, safety_set_allowed_area->p1z, safety_set_allowed_area->p2x, safety_set_allowed_area->p2y, safety_set_allowed_area->p2z); +} + +/** + * @brief Send a safety_set_allowed_area message + * @param chan MAVLink channel to send the message + * + * @param target_system System ID + * @param target_component Component ID + * @param frame Coordinate frame, as defined by MAV_FRAME enum in mavlink_types.h. Can be either global, GPS, right-handed with Z axis up or local, right handed, Z axis down. + * @param p1x x position 1 / Latitude 1 + * @param p1y y position 1 / Longitude 1 + * @param p1z z position 1 / Altitude 1 + * @param p2x x position 2 / Latitude 2 + * @param p2y y position 2 / Longitude 2 + * @param p2z z position 2 / Altitude 2 + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_safety_set_allowed_area_send(mavlink_channel_t chan, uint8_t target_system, uint8_t target_component, uint8_t frame, float p1x, float p1y, float p1z, float p2x, float p2y, float p2z) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[27]; + _mav_put_float(buf, 0, p1x); + _mav_put_float(buf, 4, p1y); + _mav_put_float(buf, 8, p1z); + _mav_put_float(buf, 12, p2x); + _mav_put_float(buf, 16, p2y); + _mav_put_float(buf, 20, p2z); + _mav_put_uint8_t(buf, 24, target_system); + _mav_put_uint8_t(buf, 25, target_component); + _mav_put_uint8_t(buf, 26, frame); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SAFETY_SET_ALLOWED_AREA, buf, 27, 15); +#else + mavlink_safety_set_allowed_area_t packet; + packet.p1x = p1x; + packet.p1y = p1y; + packet.p1z = p1z; + packet.p2x = p2x; + packet.p2y = p2y; + packet.p2z = p2z; + packet.target_system = target_system; + packet.target_component = target_component; + packet.frame = frame; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SAFETY_SET_ALLOWED_AREA, (const char *)&packet, 27, 15); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE SAFETY_SET_ALLOWED_AREA UNPACKING + + +/** + * @brief Get field target_system from safety_set_allowed_area message + * + * @return System ID + */ +static inline uint8_t mavlink_msg_safety_set_allowed_area_get_target_system(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 24); +} + +/** + * @brief Get field target_component from safety_set_allowed_area message + * + * @return Component ID + */ +static inline uint8_t mavlink_msg_safety_set_allowed_area_get_target_component(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 25); +} + +/** + * @brief Get field frame from safety_set_allowed_area message + * + * @return Coordinate frame, as defined by MAV_FRAME enum in mavlink_types.h. Can be either global, GPS, right-handed with Z axis up or local, right handed, Z axis down. + */ +static inline uint8_t mavlink_msg_safety_set_allowed_area_get_frame(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 26); +} + +/** + * @brief Get field p1x from safety_set_allowed_area message + * + * @return x position 1 / Latitude 1 + */ +static inline float mavlink_msg_safety_set_allowed_area_get_p1x(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 0); +} + +/** + * @brief Get field p1y from safety_set_allowed_area message + * + * @return y position 1 / Longitude 1 + */ +static inline float mavlink_msg_safety_set_allowed_area_get_p1y(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 4); +} + +/** + * @brief Get field p1z from safety_set_allowed_area message + * + * @return z position 1 / Altitude 1 + */ +static inline float mavlink_msg_safety_set_allowed_area_get_p1z(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 8); +} + +/** + * @brief Get field p2x from safety_set_allowed_area message + * + * @return x position 2 / Latitude 2 + */ +static inline float mavlink_msg_safety_set_allowed_area_get_p2x(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 12); +} + +/** + * @brief Get field p2y from safety_set_allowed_area message + * + * @return y position 2 / Longitude 2 + */ +static inline float mavlink_msg_safety_set_allowed_area_get_p2y(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 16); +} + +/** + * @brief Get field p2z from safety_set_allowed_area message + * + * @return z position 2 / Altitude 2 + */ +static inline float mavlink_msg_safety_set_allowed_area_get_p2z(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 20); +} + +/** + * @brief Decode a safety_set_allowed_area message into a struct + * + * @param msg The message to decode + * @param safety_set_allowed_area C-struct to decode the message contents into + */ +static inline void mavlink_msg_safety_set_allowed_area_decode(const mavlink_message_t *msg, mavlink_safety_set_allowed_area_t *safety_set_allowed_area) +{ +#if MAVLINK_NEED_BYTE_SWAP + safety_set_allowed_area->p1x = mavlink_msg_safety_set_allowed_area_get_p1x(msg); + safety_set_allowed_area->p1y = mavlink_msg_safety_set_allowed_area_get_p1y(msg); + safety_set_allowed_area->p1z = mavlink_msg_safety_set_allowed_area_get_p1z(msg); + safety_set_allowed_area->p2x = mavlink_msg_safety_set_allowed_area_get_p2x(msg); + safety_set_allowed_area->p2y = mavlink_msg_safety_set_allowed_area_get_p2y(msg); + safety_set_allowed_area->p2z = mavlink_msg_safety_set_allowed_area_get_p2z(msg); + safety_set_allowed_area->target_system = mavlink_msg_safety_set_allowed_area_get_target_system(msg); + safety_set_allowed_area->target_component = mavlink_msg_safety_set_allowed_area_get_target_component(msg); + safety_set_allowed_area->frame = mavlink_msg_safety_set_allowed_area_get_frame(msg); +#else + memcpy(safety_set_allowed_area, _MAV_PAYLOAD(msg), 27); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_scaled_imu.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_scaled_imu.h new file mode 100644 index 000000000..c508efd48 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_scaled_imu.h @@ -0,0 +1,342 @@ +// MESSAGE SCALED_IMU PACKING + +#define MAVLINK_MSG_ID_SCALED_IMU 26 + +typedef struct __mavlink_scaled_imu_t { + uint32_t time_boot_ms; ///< Timestamp (milliseconds since system boot) + int16_t xacc; ///< X acceleration (mg) + int16_t yacc; ///< Y acceleration (mg) + int16_t zacc; ///< Z acceleration (mg) + int16_t xgyro; ///< Angular speed around X axis (millirad /sec) + int16_t ygyro; ///< Angular speed around Y axis (millirad /sec) + int16_t zgyro; ///< Angular speed around Z axis (millirad /sec) + int16_t xmag; ///< X Magnetic field (milli tesla) + int16_t ymag; ///< Y Magnetic field (milli tesla) + int16_t zmag; ///< Z Magnetic field (milli tesla) +} mavlink_scaled_imu_t; + +#define MAVLINK_MSG_ID_SCALED_IMU_LEN 22 +#define MAVLINK_MSG_ID_26_LEN 22 + + +#define MAVLINK_MESSAGE_INFO_SCALED_IMU \ + { \ + "SCALED_IMU", \ + 10, \ + { \ + { "time_boot_ms", NULL, MAVLINK_TYPE_UINT32_T, 0, 0, offsetof(mavlink_scaled_imu_t, time_boot_ms) }, \ + { "xacc", NULL, MAVLINK_TYPE_INT16_T, 0, 4, offsetof(mavlink_scaled_imu_t, xacc) }, \ + { "yacc", NULL, MAVLINK_TYPE_INT16_T, 0, 6, offsetof(mavlink_scaled_imu_t, yacc) }, \ + { "zacc", NULL, MAVLINK_TYPE_INT16_T, 0, 8, offsetof(mavlink_scaled_imu_t, zacc) }, \ + { "xgyro", NULL, MAVLINK_TYPE_INT16_T, 0, 10, offsetof(mavlink_scaled_imu_t, xgyro) }, \ + { "ygyro", NULL, MAVLINK_TYPE_INT16_T, 0, 12, offsetof(mavlink_scaled_imu_t, ygyro) }, \ + { "zgyro", NULL, MAVLINK_TYPE_INT16_T, 0, 14, offsetof(mavlink_scaled_imu_t, zgyro) }, \ + { "xmag", NULL, MAVLINK_TYPE_INT16_T, 0, 16, offsetof(mavlink_scaled_imu_t, xmag) }, \ + { "ymag", NULL, MAVLINK_TYPE_INT16_T, 0, 18, offsetof(mavlink_scaled_imu_t, ymag) }, \ + { "zmag", NULL, MAVLINK_TYPE_INT16_T, 0, 20, offsetof(mavlink_scaled_imu_t, zmag) }, \ + } \ + } + + +/** + * @brief Pack a scaled_imu message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param xacc X acceleration (mg) + * @param yacc Y acceleration (mg) + * @param zacc Z acceleration (mg) + * @param xgyro Angular speed around X axis (millirad /sec) + * @param ygyro Angular speed around Y axis (millirad /sec) + * @param zgyro Angular speed around Z axis (millirad /sec) + * @param xmag X Magnetic field (milli tesla) + * @param ymag Y Magnetic field (milli tesla) + * @param zmag Z Magnetic field (milli tesla) + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_scaled_imu_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint32_t time_boot_ms, int16_t xacc, int16_t yacc, int16_t zacc, int16_t xgyro, int16_t ygyro, int16_t zgyro, int16_t xmag, int16_t ymag, int16_t zmag) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[22]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_int16_t(buf, 4, xacc); + _mav_put_int16_t(buf, 6, yacc); + _mav_put_int16_t(buf, 8, zacc); + _mav_put_int16_t(buf, 10, xgyro); + _mav_put_int16_t(buf, 12, ygyro); + _mav_put_int16_t(buf, 14, zgyro); + _mav_put_int16_t(buf, 16, xmag); + _mav_put_int16_t(buf, 18, ymag); + _mav_put_int16_t(buf, 20, zmag); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 22); +#else + mavlink_scaled_imu_t packet; + packet.time_boot_ms = time_boot_ms; + packet.xacc = xacc; + packet.yacc = yacc; + packet.zacc = zacc; + packet.xgyro = xgyro; + packet.ygyro = ygyro; + packet.zgyro = zgyro; + packet.xmag = xmag; + packet.ymag = ymag; + packet.zmag = zmag; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 22); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_SCALED_IMU; + return mavlink_finalize_message(msg, system_id, component_id, 22, 170); +} + +/** + * @brief Pack a scaled_imu message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param xacc X acceleration (mg) + * @param yacc Y acceleration (mg) + * @param zacc Z acceleration (mg) + * @param xgyro Angular speed around X axis (millirad /sec) + * @param ygyro Angular speed around Y axis (millirad /sec) + * @param zgyro Angular speed around Z axis (millirad /sec) + * @param xmag X Magnetic field (milli tesla) + * @param ymag Y Magnetic field (milli tesla) + * @param zmag Z Magnetic field (milli tesla) + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_scaled_imu_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint32_t time_boot_ms, int16_t xacc, int16_t yacc, int16_t zacc, int16_t xgyro, int16_t ygyro, int16_t zgyro, int16_t xmag, int16_t ymag, int16_t zmag) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[22]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_int16_t(buf, 4, xacc); + _mav_put_int16_t(buf, 6, yacc); + _mav_put_int16_t(buf, 8, zacc); + _mav_put_int16_t(buf, 10, xgyro); + _mav_put_int16_t(buf, 12, ygyro); + _mav_put_int16_t(buf, 14, zgyro); + _mav_put_int16_t(buf, 16, xmag); + _mav_put_int16_t(buf, 18, ymag); + _mav_put_int16_t(buf, 20, zmag); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 22); +#else + mavlink_scaled_imu_t packet; + packet.time_boot_ms = time_boot_ms; + packet.xacc = xacc; + packet.yacc = yacc; + packet.zacc = zacc; + packet.xgyro = xgyro; + packet.ygyro = ygyro; + packet.zgyro = zgyro; + packet.xmag = xmag; + packet.ymag = ymag; + packet.zmag = zmag; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 22); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_SCALED_IMU; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 22, 170); +} + +/** + * @brief Encode a scaled_imu struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param scaled_imu C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_scaled_imu_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_scaled_imu_t *scaled_imu) +{ + return mavlink_msg_scaled_imu_pack(system_id, component_id, msg, scaled_imu->time_boot_ms, scaled_imu->xacc, scaled_imu->yacc, scaled_imu->zacc, scaled_imu->xgyro, scaled_imu->ygyro, scaled_imu->zgyro, scaled_imu->xmag, scaled_imu->ymag, scaled_imu->zmag); +} + +/** + * @brief Send a scaled_imu message + * @param chan MAVLink channel to send the message + * + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param xacc X acceleration (mg) + * @param yacc Y acceleration (mg) + * @param zacc Z acceleration (mg) + * @param xgyro Angular speed around X axis (millirad /sec) + * @param ygyro Angular speed around Y axis (millirad /sec) + * @param zgyro Angular speed around Z axis (millirad /sec) + * @param xmag X Magnetic field (milli tesla) + * @param ymag Y Magnetic field (milli tesla) + * @param zmag Z Magnetic field (milli tesla) + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_scaled_imu_send(mavlink_channel_t chan, uint32_t time_boot_ms, int16_t xacc, int16_t yacc, int16_t zacc, int16_t xgyro, int16_t ygyro, int16_t zgyro, int16_t xmag, int16_t ymag, int16_t zmag) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[22]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_int16_t(buf, 4, xacc); + _mav_put_int16_t(buf, 6, yacc); + _mav_put_int16_t(buf, 8, zacc); + _mav_put_int16_t(buf, 10, xgyro); + _mav_put_int16_t(buf, 12, ygyro); + _mav_put_int16_t(buf, 14, zgyro); + _mav_put_int16_t(buf, 16, xmag); + _mav_put_int16_t(buf, 18, ymag); + _mav_put_int16_t(buf, 20, zmag); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SCALED_IMU, buf, 22, 170); +#else + mavlink_scaled_imu_t packet; + packet.time_boot_ms = time_boot_ms; + packet.xacc = xacc; + packet.yacc = yacc; + packet.zacc = zacc; + packet.xgyro = xgyro; + packet.ygyro = ygyro; + packet.zgyro = zgyro; + packet.xmag = xmag; + packet.ymag = ymag; + packet.zmag = zmag; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SCALED_IMU, (const char *)&packet, 22, 170); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE SCALED_IMU UNPACKING + + +/** + * @brief Get field time_boot_ms from scaled_imu message + * + * @return Timestamp (milliseconds since system boot) + */ +static inline uint32_t mavlink_msg_scaled_imu_get_time_boot_ms(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint32_t(msg, 0); +} + +/** + * @brief Get field xacc from scaled_imu message + * + * @return X acceleration (mg) + */ +static inline int16_t mavlink_msg_scaled_imu_get_xacc(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 4); +} + +/** + * @brief Get field yacc from scaled_imu message + * + * @return Y acceleration (mg) + */ +static inline int16_t mavlink_msg_scaled_imu_get_yacc(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 6); +} + +/** + * @brief Get field zacc from scaled_imu message + * + * @return Z acceleration (mg) + */ +static inline int16_t mavlink_msg_scaled_imu_get_zacc(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 8); +} + +/** + * @brief Get field xgyro from scaled_imu message + * + * @return Angular speed around X axis (millirad /sec) + */ +static inline int16_t mavlink_msg_scaled_imu_get_xgyro(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 10); +} + +/** + * @brief Get field ygyro from scaled_imu message + * + * @return Angular speed around Y axis (millirad /sec) + */ +static inline int16_t mavlink_msg_scaled_imu_get_ygyro(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 12); +} + +/** + * @brief Get field zgyro from scaled_imu message + * + * @return Angular speed around Z axis (millirad /sec) + */ +static inline int16_t mavlink_msg_scaled_imu_get_zgyro(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 14); +} + +/** + * @brief Get field xmag from scaled_imu message + * + * @return X Magnetic field (milli tesla) + */ +static inline int16_t mavlink_msg_scaled_imu_get_xmag(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 16); +} + +/** + * @brief Get field ymag from scaled_imu message + * + * @return Y Magnetic field (milli tesla) + */ +static inline int16_t mavlink_msg_scaled_imu_get_ymag(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 18); +} + +/** + * @brief Get field zmag from scaled_imu message + * + * @return Z Magnetic field (milli tesla) + */ +static inline int16_t mavlink_msg_scaled_imu_get_zmag(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 20); +} + +/** + * @brief Decode a scaled_imu message into a struct + * + * @param msg The message to decode + * @param scaled_imu C-struct to decode the message contents into + */ +static inline void mavlink_msg_scaled_imu_decode(const mavlink_message_t *msg, mavlink_scaled_imu_t *scaled_imu) +{ +#if MAVLINK_NEED_BYTE_SWAP + scaled_imu->time_boot_ms = mavlink_msg_scaled_imu_get_time_boot_ms(msg); + scaled_imu->xacc = mavlink_msg_scaled_imu_get_xacc(msg); + scaled_imu->yacc = mavlink_msg_scaled_imu_get_yacc(msg); + scaled_imu->zacc = mavlink_msg_scaled_imu_get_zacc(msg); + scaled_imu->xgyro = mavlink_msg_scaled_imu_get_xgyro(msg); + scaled_imu->ygyro = mavlink_msg_scaled_imu_get_ygyro(msg); + scaled_imu->zgyro = mavlink_msg_scaled_imu_get_zgyro(msg); + scaled_imu->xmag = mavlink_msg_scaled_imu_get_xmag(msg); + scaled_imu->ymag = mavlink_msg_scaled_imu_get_ymag(msg); + scaled_imu->zmag = mavlink_msg_scaled_imu_get_zmag(msg); +#else + memcpy(scaled_imu, _MAV_PAYLOAD(msg), 22); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_scaled_pressure.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_scaled_pressure.h new file mode 100644 index 000000000..46e808677 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_scaled_pressure.h @@ -0,0 +1,210 @@ +// MESSAGE SCALED_PRESSURE PACKING + +#define MAVLINK_MSG_ID_SCALED_PRESSURE 29 + +typedef struct __mavlink_scaled_pressure_t { + uint32_t time_boot_ms; ///< Timestamp (milliseconds since system boot) + float press_abs; ///< Absolute pressure (hectopascal) + float press_diff; ///< Differential pressure 1 (hectopascal) + int16_t temperature; ///< Temperature measurement (0.01 degrees celsius) +} mavlink_scaled_pressure_t; + +#define MAVLINK_MSG_ID_SCALED_PRESSURE_LEN 14 +#define MAVLINK_MSG_ID_29_LEN 14 + + +#define MAVLINK_MESSAGE_INFO_SCALED_PRESSURE \ + { \ + "SCALED_PRESSURE", \ + 4, \ + { \ + { "time_boot_ms", NULL, MAVLINK_TYPE_UINT32_T, 0, 0, offsetof(mavlink_scaled_pressure_t, time_boot_ms) }, \ + { "press_abs", NULL, MAVLINK_TYPE_FLOAT, 0, 4, offsetof(mavlink_scaled_pressure_t, press_abs) }, \ + { "press_diff", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_scaled_pressure_t, press_diff) }, \ + { "temperature", NULL, MAVLINK_TYPE_INT16_T, 0, 12, offsetof(mavlink_scaled_pressure_t, temperature) }, \ + } \ + } + + +/** + * @brief Pack a scaled_pressure message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param press_abs Absolute pressure (hectopascal) + * @param press_diff Differential pressure 1 (hectopascal) + * @param temperature Temperature measurement (0.01 degrees celsius) + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_scaled_pressure_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint32_t time_boot_ms, float press_abs, float press_diff, int16_t temperature) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[14]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_float(buf, 4, press_abs); + _mav_put_float(buf, 8, press_diff); + _mav_put_int16_t(buf, 12, temperature); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 14); +#else + mavlink_scaled_pressure_t packet; + packet.time_boot_ms = time_boot_ms; + packet.press_abs = press_abs; + packet.press_diff = press_diff; + packet.temperature = temperature; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 14); +#endif + + msg->msgid = MAVLINK_MSG_ID_SCALED_PRESSURE; + return mavlink_finalize_message(msg, system_id, component_id, 14, 115); +} + +/** + * @brief Pack a scaled_pressure message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param press_abs Absolute pressure (hectopascal) + * @param press_diff Differential pressure 1 (hectopascal) + * @param temperature Temperature measurement (0.01 degrees celsius) + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_scaled_pressure_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint32_t time_boot_ms, float press_abs, float press_diff, int16_t temperature) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[14]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_float(buf, 4, press_abs); + _mav_put_float(buf, 8, press_diff); + _mav_put_int16_t(buf, 12, temperature); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 14); +#else + mavlink_scaled_pressure_t packet; + packet.time_boot_ms = time_boot_ms; + packet.press_abs = press_abs; + packet.press_diff = press_diff; + packet.temperature = temperature; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 14); +#endif + + msg->msgid = MAVLINK_MSG_ID_SCALED_PRESSURE; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 14, 115); +} + +/** + * @brief Encode a scaled_pressure struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param scaled_pressure C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_scaled_pressure_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_scaled_pressure_t *scaled_pressure) +{ + return mavlink_msg_scaled_pressure_pack(system_id, component_id, msg, scaled_pressure->time_boot_ms, scaled_pressure->press_abs, scaled_pressure->press_diff, scaled_pressure->temperature); +} + +/** + * @brief Send a scaled_pressure message + * @param chan MAVLink channel to send the message + * + * @param time_boot_ms Timestamp (milliseconds since system boot) + * @param press_abs Absolute pressure (hectopascal) + * @param press_diff Differential pressure 1 (hectopascal) + * @param temperature Temperature measurement (0.01 degrees celsius) + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_scaled_pressure_send(mavlink_channel_t chan, uint32_t time_boot_ms, float press_abs, float press_diff, int16_t temperature) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[14]; + _mav_put_uint32_t(buf, 0, time_boot_ms); + _mav_put_float(buf, 4, press_abs); + _mav_put_float(buf, 8, press_diff); + _mav_put_int16_t(buf, 12, temperature); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SCALED_PRESSURE, buf, 14, 115); +#else + mavlink_scaled_pressure_t packet; + packet.time_boot_ms = time_boot_ms; + packet.press_abs = press_abs; + packet.press_diff = press_diff; + packet.temperature = temperature; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SCALED_PRESSURE, (const char *)&packet, 14, 115); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE SCALED_PRESSURE UNPACKING + + +/** + * @brief Get field time_boot_ms from scaled_pressure message + * + * @return Timestamp (milliseconds since system boot) + */ +static inline uint32_t mavlink_msg_scaled_pressure_get_time_boot_ms(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint32_t(msg, 0); +} + +/** + * @brief Get field press_abs from scaled_pressure message + * + * @return Absolute pressure (hectopascal) + */ +static inline float mavlink_msg_scaled_pressure_get_press_abs(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 4); +} + +/** + * @brief Get field press_diff from scaled_pressure message + * + * @return Differential pressure 1 (hectopascal) + */ +static inline float mavlink_msg_scaled_pressure_get_press_diff(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 8); +} + +/** + * @brief Get field temperature from scaled_pressure message + * + * @return Temperature measurement (0.01 degrees celsius) + */ +static inline int16_t mavlink_msg_scaled_pressure_get_temperature(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 12); +} + +/** + * @brief Decode a scaled_pressure message into a struct + * + * @param msg The message to decode + * @param scaled_pressure C-struct to decode the message contents into + */ +static inline void mavlink_msg_scaled_pressure_decode(const mavlink_message_t *msg, mavlink_scaled_pressure_t *scaled_pressure) +{ +#if MAVLINK_NEED_BYTE_SWAP + scaled_pressure->time_boot_ms = mavlink_msg_scaled_pressure_get_time_boot_ms(msg); + scaled_pressure->press_abs = mavlink_msg_scaled_pressure_get_press_abs(msg); + scaled_pressure->press_diff = mavlink_msg_scaled_pressure_get_press_diff(msg); + scaled_pressure->temperature = mavlink_msg_scaled_pressure_get_temperature(msg); +#else + memcpy(scaled_pressure, _MAV_PAYLOAD(msg), 14); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_servo_output_raw.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_servo_output_raw.h new file mode 100644 index 000000000..5290ae7ca --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_servo_output_raw.h @@ -0,0 +1,342 @@ +// MESSAGE SERVO_OUTPUT_RAW PACKING + +#define MAVLINK_MSG_ID_SERVO_OUTPUT_RAW 36 + +typedef struct __mavlink_servo_output_raw_t { + uint32_t time_usec; ///< Timestamp (microseconds since system boot) + uint16_t servo1_raw; ///< Servo output 1 value, in microseconds + uint16_t servo2_raw; ///< Servo output 2 value, in microseconds + uint16_t servo3_raw; ///< Servo output 3 value, in microseconds + uint16_t servo4_raw; ///< Servo output 4 value, in microseconds + uint16_t servo5_raw; ///< Servo output 5 value, in microseconds + uint16_t servo6_raw; ///< Servo output 6 value, in microseconds + uint16_t servo7_raw; ///< Servo output 7 value, in microseconds + uint16_t servo8_raw; ///< Servo output 8 value, in microseconds + uint8_t port; ///< Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows to encode more than 8 servos. +} mavlink_servo_output_raw_t; + +#define MAVLINK_MSG_ID_SERVO_OUTPUT_RAW_LEN 21 +#define MAVLINK_MSG_ID_36_LEN 21 + + +#define MAVLINK_MESSAGE_INFO_SERVO_OUTPUT_RAW \ + { \ + "SERVO_OUTPUT_RAW", \ + 10, \ + { \ + { "time_usec", NULL, MAVLINK_TYPE_UINT32_T, 0, 0, offsetof(mavlink_servo_output_raw_t, time_usec) }, \ + { "servo1_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 4, offsetof(mavlink_servo_output_raw_t, servo1_raw) }, \ + { "servo2_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 6, offsetof(mavlink_servo_output_raw_t, servo2_raw) }, \ + { "servo3_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 8, offsetof(mavlink_servo_output_raw_t, servo3_raw) }, \ + { "servo4_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 10, offsetof(mavlink_servo_output_raw_t, servo4_raw) }, \ + { "servo5_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 12, offsetof(mavlink_servo_output_raw_t, servo5_raw) }, \ + { "servo6_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 14, offsetof(mavlink_servo_output_raw_t, servo6_raw) }, \ + { "servo7_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 16, offsetof(mavlink_servo_output_raw_t, servo7_raw) }, \ + { "servo8_raw", NULL, MAVLINK_TYPE_UINT16_T, 0, 18, offsetof(mavlink_servo_output_raw_t, servo8_raw) }, \ + { "port", NULL, MAVLINK_TYPE_UINT8_T, 0, 20, offsetof(mavlink_servo_output_raw_t, port) }, \ + } \ + } + + +/** + * @brief Pack a servo_output_raw message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param time_usec Timestamp (microseconds since system boot) + * @param port Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows to encode more than 8 servos. + * @param servo1_raw Servo output 1 value, in microseconds + * @param servo2_raw Servo output 2 value, in microseconds + * @param servo3_raw Servo output 3 value, in microseconds + * @param servo4_raw Servo output 4 value, in microseconds + * @param servo5_raw Servo output 5 value, in microseconds + * @param servo6_raw Servo output 6 value, in microseconds + * @param servo7_raw Servo output 7 value, in microseconds + * @param servo8_raw Servo output 8 value, in microseconds + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_servo_output_raw_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint32_t time_usec, uint8_t port, uint16_t servo1_raw, uint16_t servo2_raw, uint16_t servo3_raw, uint16_t servo4_raw, uint16_t servo5_raw, uint16_t servo6_raw, uint16_t servo7_raw, uint16_t servo8_raw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[21]; + _mav_put_uint32_t(buf, 0, time_usec); + _mav_put_uint16_t(buf, 4, servo1_raw); + _mav_put_uint16_t(buf, 6, servo2_raw); + _mav_put_uint16_t(buf, 8, servo3_raw); + _mav_put_uint16_t(buf, 10, servo4_raw); + _mav_put_uint16_t(buf, 12, servo5_raw); + _mav_put_uint16_t(buf, 14, servo6_raw); + _mav_put_uint16_t(buf, 16, servo7_raw); + _mav_put_uint16_t(buf, 18, servo8_raw); + _mav_put_uint8_t(buf, 20, port); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 21); +#else + mavlink_servo_output_raw_t packet; + packet.time_usec = time_usec; + packet.servo1_raw = servo1_raw; + packet.servo2_raw = servo2_raw; + packet.servo3_raw = servo3_raw; + packet.servo4_raw = servo4_raw; + packet.servo5_raw = servo5_raw; + packet.servo6_raw = servo6_raw; + packet.servo7_raw = servo7_raw; + packet.servo8_raw = servo8_raw; + packet.port = port; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 21); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_SERVO_OUTPUT_RAW; + return mavlink_finalize_message(msg, system_id, component_id, 21, 222); +} + +/** + * @brief Pack a servo_output_raw message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param time_usec Timestamp (microseconds since system boot) + * @param port Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows to encode more than 8 servos. + * @param servo1_raw Servo output 1 value, in microseconds + * @param servo2_raw Servo output 2 value, in microseconds + * @param servo3_raw Servo output 3 value, in microseconds + * @param servo4_raw Servo output 4 value, in microseconds + * @param servo5_raw Servo output 5 value, in microseconds + * @param servo6_raw Servo output 6 value, in microseconds + * @param servo7_raw Servo output 7 value, in microseconds + * @param servo8_raw Servo output 8 value, in microseconds + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_servo_output_raw_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint32_t time_usec, uint8_t port, uint16_t servo1_raw, uint16_t servo2_raw, uint16_t servo3_raw, uint16_t servo4_raw, uint16_t servo5_raw, uint16_t servo6_raw, uint16_t servo7_raw, uint16_t servo8_raw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[21]; + _mav_put_uint32_t(buf, 0, time_usec); + _mav_put_uint16_t(buf, 4, servo1_raw); + _mav_put_uint16_t(buf, 6, servo2_raw); + _mav_put_uint16_t(buf, 8, servo3_raw); + _mav_put_uint16_t(buf, 10, servo4_raw); + _mav_put_uint16_t(buf, 12, servo5_raw); + _mav_put_uint16_t(buf, 14, servo6_raw); + _mav_put_uint16_t(buf, 16, servo7_raw); + _mav_put_uint16_t(buf, 18, servo8_raw); + _mav_put_uint8_t(buf, 20, port); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 21); +#else + mavlink_servo_output_raw_t packet; + packet.time_usec = time_usec; + packet.servo1_raw = servo1_raw; + packet.servo2_raw = servo2_raw; + packet.servo3_raw = servo3_raw; + packet.servo4_raw = servo4_raw; + packet.servo5_raw = servo5_raw; + packet.servo6_raw = servo6_raw; + packet.servo7_raw = servo7_raw; + packet.servo8_raw = servo8_raw; + packet.port = port; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 21); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_SERVO_OUTPUT_RAW; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 21, 222); +} + +/** + * @brief Encode a servo_output_raw struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param servo_output_raw C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_servo_output_raw_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_servo_output_raw_t *servo_output_raw) +{ + return mavlink_msg_servo_output_raw_pack(system_id, component_id, msg, servo_output_raw->time_usec, servo_output_raw->port, servo_output_raw->servo1_raw, servo_output_raw->servo2_raw, servo_output_raw->servo3_raw, servo_output_raw->servo4_raw, servo_output_raw->servo5_raw, servo_output_raw->servo6_raw, servo_output_raw->servo7_raw, servo_output_raw->servo8_raw); +} + +/** + * @brief Send a servo_output_raw message + * @param chan MAVLink channel to send the message + * + * @param time_usec Timestamp (microseconds since system boot) + * @param port Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows to encode more than 8 servos. + * @param servo1_raw Servo output 1 value, in microseconds + * @param servo2_raw Servo output 2 value, in microseconds + * @param servo3_raw Servo output 3 value, in microseconds + * @param servo4_raw Servo output 4 value, in microseconds + * @param servo5_raw Servo output 5 value, in microseconds + * @param servo6_raw Servo output 6 value, in microseconds + * @param servo7_raw Servo output 7 value, in microseconds + * @param servo8_raw Servo output 8 value, in microseconds + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_servo_output_raw_send(mavlink_channel_t chan, uint32_t time_usec, uint8_t port, uint16_t servo1_raw, uint16_t servo2_raw, uint16_t servo3_raw, uint16_t servo4_raw, uint16_t servo5_raw, uint16_t servo6_raw, uint16_t servo7_raw, uint16_t servo8_raw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[21]; + _mav_put_uint32_t(buf, 0, time_usec); + _mav_put_uint16_t(buf, 4, servo1_raw); + _mav_put_uint16_t(buf, 6, servo2_raw); + _mav_put_uint16_t(buf, 8, servo3_raw); + _mav_put_uint16_t(buf, 10, servo4_raw); + _mav_put_uint16_t(buf, 12, servo5_raw); + _mav_put_uint16_t(buf, 14, servo6_raw); + _mav_put_uint16_t(buf, 16, servo7_raw); + _mav_put_uint16_t(buf, 18, servo8_raw); + _mav_put_uint8_t(buf, 20, port); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SERVO_OUTPUT_RAW, buf, 21, 222); +#else + mavlink_servo_output_raw_t packet; + packet.time_usec = time_usec; + packet.servo1_raw = servo1_raw; + packet.servo2_raw = servo2_raw; + packet.servo3_raw = servo3_raw; + packet.servo4_raw = servo4_raw; + packet.servo5_raw = servo5_raw; + packet.servo6_raw = servo6_raw; + packet.servo7_raw = servo7_raw; + packet.servo8_raw = servo8_raw; + packet.port = port; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SERVO_OUTPUT_RAW, (const char *)&packet, 21, 222); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE SERVO_OUTPUT_RAW UNPACKING + + +/** + * @brief Get field time_usec from servo_output_raw message + * + * @return Timestamp (microseconds since system boot) + */ +static inline uint32_t mavlink_msg_servo_output_raw_get_time_usec(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint32_t(msg, 0); +} + +/** + * @brief Get field port from servo_output_raw message + * + * @return Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows to encode more than 8 servos. + */ +static inline uint8_t mavlink_msg_servo_output_raw_get_port(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 20); +} + +/** + * @brief Get field servo1_raw from servo_output_raw message + * + * @return Servo output 1 value, in microseconds + */ +static inline uint16_t mavlink_msg_servo_output_raw_get_servo1_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 4); +} + +/** + * @brief Get field servo2_raw from servo_output_raw message + * + * @return Servo output 2 value, in microseconds + */ +static inline uint16_t mavlink_msg_servo_output_raw_get_servo2_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 6); +} + +/** + * @brief Get field servo3_raw from servo_output_raw message + * + * @return Servo output 3 value, in microseconds + */ +static inline uint16_t mavlink_msg_servo_output_raw_get_servo3_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 8); +} + +/** + * @brief Get field servo4_raw from servo_output_raw message + * + * @return Servo output 4 value, in microseconds + */ +static inline uint16_t mavlink_msg_servo_output_raw_get_servo4_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 10); +} + +/** + * @brief Get field servo5_raw from servo_output_raw message + * + * @return Servo output 5 value, in microseconds + */ +static inline uint16_t mavlink_msg_servo_output_raw_get_servo5_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 12); +} + +/** + * @brief Get field servo6_raw from servo_output_raw message + * + * @return Servo output 6 value, in microseconds + */ +static inline uint16_t mavlink_msg_servo_output_raw_get_servo6_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 14); +} + +/** + * @brief Get field servo7_raw from servo_output_raw message + * + * @return Servo output 7 value, in microseconds + */ +static inline uint16_t mavlink_msg_servo_output_raw_get_servo7_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 16); +} + +/** + * @brief Get field servo8_raw from servo_output_raw message + * + * @return Servo output 8 value, in microseconds + */ +static inline uint16_t mavlink_msg_servo_output_raw_get_servo8_raw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 18); +} + +/** + * @brief Decode a servo_output_raw message into a struct + * + * @param msg The message to decode + * @param servo_output_raw C-struct to decode the message contents into + */ +static inline void mavlink_msg_servo_output_raw_decode(const mavlink_message_t *msg, mavlink_servo_output_raw_t *servo_output_raw) +{ +#if MAVLINK_NEED_BYTE_SWAP + servo_output_raw->time_usec = mavlink_msg_servo_output_raw_get_time_usec(msg); + servo_output_raw->servo1_raw = mavlink_msg_servo_output_raw_get_servo1_raw(msg); + servo_output_raw->servo2_raw = mavlink_msg_servo_output_raw_get_servo2_raw(msg); + servo_output_raw->servo3_raw = mavlink_msg_servo_output_raw_get_servo3_raw(msg); + servo_output_raw->servo4_raw = mavlink_msg_servo_output_raw_get_servo4_raw(msg); + servo_output_raw->servo5_raw = mavlink_msg_servo_output_raw_get_servo5_raw(msg); + servo_output_raw->servo6_raw = mavlink_msg_servo_output_raw_get_servo6_raw(msg); + servo_output_raw->servo7_raw = mavlink_msg_servo_output_raw_get_servo7_raw(msg); + servo_output_raw->servo8_raw = mavlink_msg_servo_output_raw_get_servo8_raw(msg); + servo_output_raw->port = mavlink_msg_servo_output_raw_get_port(msg); +#else + memcpy(servo_output_raw, _MAV_PAYLOAD(msg), 21); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_set_global_position_setpoint_int.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_set_global_position_setpoint_int.h new file mode 100644 index 000000000..ace180c04 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_set_global_position_setpoint_int.h @@ -0,0 +1,232 @@ +// MESSAGE SET_GLOBAL_POSITION_SETPOINT_INT PACKING + +#define MAVLINK_MSG_ID_SET_GLOBAL_POSITION_SETPOINT_INT 53 + +typedef struct __mavlink_set_global_position_setpoint_int_t { + int32_t latitude; ///< WGS84 Latitude position in degrees * 1E7 + int32_t longitude; ///< WGS84 Longitude position in degrees * 1E7 + int32_t altitude; ///< WGS84 Altitude in meters * 1000 (positive for up) + int16_t yaw; ///< Desired yaw angle in degrees * 100 + uint8_t coordinate_frame; ///< Coordinate frame - valid values are only MAV_FRAME_GLOBAL or MAV_FRAME_GLOBAL_RELATIVE_ALT +} mavlink_set_global_position_setpoint_int_t; + +#define MAVLINK_MSG_ID_SET_GLOBAL_POSITION_SETPOINT_INT_LEN 15 +#define MAVLINK_MSG_ID_53_LEN 15 + + +#define MAVLINK_MESSAGE_INFO_SET_GLOBAL_POSITION_SETPOINT_INT \ + { \ + "SET_GLOBAL_POSITION_SETPOINT_INT", \ + 5, \ + { \ + { "latitude", NULL, MAVLINK_TYPE_INT32_T, 0, 0, offsetof(mavlink_set_global_position_setpoint_int_t, latitude) }, \ + { "longitude", NULL, MAVLINK_TYPE_INT32_T, 0, 4, offsetof(mavlink_set_global_position_setpoint_int_t, longitude) }, \ + { "altitude", NULL, MAVLINK_TYPE_INT32_T, 0, 8, offsetof(mavlink_set_global_position_setpoint_int_t, altitude) }, \ + { "yaw", NULL, MAVLINK_TYPE_INT16_T, 0, 12, offsetof(mavlink_set_global_position_setpoint_int_t, yaw) }, \ + { "coordinate_frame", NULL, MAVLINK_TYPE_UINT8_T, 0, 14, offsetof(mavlink_set_global_position_setpoint_int_t, coordinate_frame) }, \ + } \ + } + + +/** + * @brief Pack a set_global_position_setpoint_int message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param coordinate_frame Coordinate frame - valid values are only MAV_FRAME_GLOBAL or MAV_FRAME_GLOBAL_RELATIVE_ALT + * @param latitude WGS84 Latitude position in degrees * 1E7 + * @param longitude WGS84 Longitude position in degrees * 1E7 + * @param altitude WGS84 Altitude in meters * 1000 (positive for up) + * @param yaw Desired yaw angle in degrees * 100 + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_set_global_position_setpoint_int_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t coordinate_frame, int32_t latitude, int32_t longitude, int32_t altitude, int16_t yaw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[15]; + _mav_put_int32_t(buf, 0, latitude); + _mav_put_int32_t(buf, 4, longitude); + _mav_put_int32_t(buf, 8, altitude); + _mav_put_int16_t(buf, 12, yaw); + _mav_put_uint8_t(buf, 14, coordinate_frame); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 15); +#else + mavlink_set_global_position_setpoint_int_t packet; + packet.latitude = latitude; + packet.longitude = longitude; + packet.altitude = altitude; + packet.yaw = yaw; + packet.coordinate_frame = coordinate_frame; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 15); +#endif + + msg->msgid = MAVLINK_MSG_ID_SET_GLOBAL_POSITION_SETPOINT_INT; + return mavlink_finalize_message(msg, system_id, component_id, 15, 33); +} + +/** + * @brief Pack a set_global_position_setpoint_int message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param coordinate_frame Coordinate frame - valid values are only MAV_FRAME_GLOBAL or MAV_FRAME_GLOBAL_RELATIVE_ALT + * @param latitude WGS84 Latitude position in degrees * 1E7 + * @param longitude WGS84 Longitude position in degrees * 1E7 + * @param altitude WGS84 Altitude in meters * 1000 (positive for up) + * @param yaw Desired yaw angle in degrees * 100 + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_set_global_position_setpoint_int_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t coordinate_frame, int32_t latitude, int32_t longitude, int32_t altitude, int16_t yaw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[15]; + _mav_put_int32_t(buf, 0, latitude); + _mav_put_int32_t(buf, 4, longitude); + _mav_put_int32_t(buf, 8, altitude); + _mav_put_int16_t(buf, 12, yaw); + _mav_put_uint8_t(buf, 14, coordinate_frame); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 15); +#else + mavlink_set_global_position_setpoint_int_t packet; + packet.latitude = latitude; + packet.longitude = longitude; + packet.altitude = altitude; + packet.yaw = yaw; + packet.coordinate_frame = coordinate_frame; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 15); +#endif + + msg->msgid = MAVLINK_MSG_ID_SET_GLOBAL_POSITION_SETPOINT_INT; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 15, 33); +} + +/** + * @brief Encode a set_global_position_setpoint_int struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param set_global_position_setpoint_int C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_set_global_position_setpoint_int_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_set_global_position_setpoint_int_t *set_global_position_setpoint_int) +{ + return mavlink_msg_set_global_position_setpoint_int_pack(system_id, component_id, msg, set_global_position_setpoint_int->coordinate_frame, set_global_position_setpoint_int->latitude, set_global_position_setpoint_int->longitude, set_global_position_setpoint_int->altitude, set_global_position_setpoint_int->yaw); +} + +/** + * @brief Send a set_global_position_setpoint_int message + * @param chan MAVLink channel to send the message + * + * @param coordinate_frame Coordinate frame - valid values are only MAV_FRAME_GLOBAL or MAV_FRAME_GLOBAL_RELATIVE_ALT + * @param latitude WGS84 Latitude position in degrees * 1E7 + * @param longitude WGS84 Longitude position in degrees * 1E7 + * @param altitude WGS84 Altitude in meters * 1000 (positive for up) + * @param yaw Desired yaw angle in degrees * 100 + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_set_global_position_setpoint_int_send(mavlink_channel_t chan, uint8_t coordinate_frame, int32_t latitude, int32_t longitude, int32_t altitude, int16_t yaw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[15]; + _mav_put_int32_t(buf, 0, latitude); + _mav_put_int32_t(buf, 4, longitude); + _mav_put_int32_t(buf, 8, altitude); + _mav_put_int16_t(buf, 12, yaw); + _mav_put_uint8_t(buf, 14, coordinate_frame); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SET_GLOBAL_POSITION_SETPOINT_INT, buf, 15, 33); +#else + mavlink_set_global_position_setpoint_int_t packet; + packet.latitude = latitude; + packet.longitude = longitude; + packet.altitude = altitude; + packet.yaw = yaw; + packet.coordinate_frame = coordinate_frame; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SET_GLOBAL_POSITION_SETPOINT_INT, (const char *)&packet, 15, 33); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE SET_GLOBAL_POSITION_SETPOINT_INT UNPACKING + + +/** + * @brief Get field coordinate_frame from set_global_position_setpoint_int message + * + * @return Coordinate frame - valid values are only MAV_FRAME_GLOBAL or MAV_FRAME_GLOBAL_RELATIVE_ALT + */ +static inline uint8_t mavlink_msg_set_global_position_setpoint_int_get_coordinate_frame(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 14); +} + +/** + * @brief Get field latitude from set_global_position_setpoint_int message + * + * @return WGS84 Latitude position in degrees * 1E7 + */ +static inline int32_t mavlink_msg_set_global_position_setpoint_int_get_latitude(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int32_t(msg, 0); +} + +/** + * @brief Get field longitude from set_global_position_setpoint_int message + * + * @return WGS84 Longitude position in degrees * 1E7 + */ +static inline int32_t mavlink_msg_set_global_position_setpoint_int_get_longitude(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int32_t(msg, 4); +} + +/** + * @brief Get field altitude from set_global_position_setpoint_int message + * + * @return WGS84 Altitude in meters * 1000 (positive for up) + */ +static inline int32_t mavlink_msg_set_global_position_setpoint_int_get_altitude(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int32_t(msg, 8); +} + +/** + * @brief Get field yaw from set_global_position_setpoint_int message + * + * @return Desired yaw angle in degrees * 100 + */ +static inline int16_t mavlink_msg_set_global_position_setpoint_int_get_yaw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 12); +} + +/** + * @brief Decode a set_global_position_setpoint_int message into a struct + * + * @param msg The message to decode + * @param set_global_position_setpoint_int C-struct to decode the message contents into + */ +static inline void mavlink_msg_set_global_position_setpoint_int_decode(const mavlink_message_t *msg, mavlink_set_global_position_setpoint_int_t *set_global_position_setpoint_int) +{ +#if MAVLINK_NEED_BYTE_SWAP + set_global_position_setpoint_int->latitude = mavlink_msg_set_global_position_setpoint_int_get_latitude(msg); + set_global_position_setpoint_int->longitude = mavlink_msg_set_global_position_setpoint_int_get_longitude(msg); + set_global_position_setpoint_int->altitude = mavlink_msg_set_global_position_setpoint_int_get_altitude(msg); + set_global_position_setpoint_int->yaw = mavlink_msg_set_global_position_setpoint_int_get_yaw(msg); + set_global_position_setpoint_int->coordinate_frame = mavlink_msg_set_global_position_setpoint_int_get_coordinate_frame(msg); +#else + memcpy(set_global_position_setpoint_int, _MAV_PAYLOAD(msg), 15); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_set_gps_global_origin.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_set_gps_global_origin.h new file mode 100644 index 000000000..caf072930 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_set_gps_global_origin.h @@ -0,0 +1,210 @@ +// MESSAGE SET_GPS_GLOBAL_ORIGIN PACKING + +#define MAVLINK_MSG_ID_SET_GPS_GLOBAL_ORIGIN 48 + +typedef struct __mavlink_set_gps_global_origin_t { + int32_t latitude; ///< global position * 1E7 + int32_t longitude; ///< global position * 1E7 + int32_t altitude; ///< global position * 1000 + uint8_t target_system; ///< System ID +} mavlink_set_gps_global_origin_t; + +#define MAVLINK_MSG_ID_SET_GPS_GLOBAL_ORIGIN_LEN 13 +#define MAVLINK_MSG_ID_48_LEN 13 + + +#define MAVLINK_MESSAGE_INFO_SET_GPS_GLOBAL_ORIGIN \ + { \ + "SET_GPS_GLOBAL_ORIGIN", \ + 4, \ + { \ + { "latitude", NULL, MAVLINK_TYPE_INT32_T, 0, 0, offsetof(mavlink_set_gps_global_origin_t, latitude) }, \ + { "longitude", NULL, MAVLINK_TYPE_INT32_T, 0, 4, offsetof(mavlink_set_gps_global_origin_t, longitude) }, \ + { "altitude", NULL, MAVLINK_TYPE_INT32_T, 0, 8, offsetof(mavlink_set_gps_global_origin_t, altitude) }, \ + { "target_system", NULL, MAVLINK_TYPE_UINT8_T, 0, 12, offsetof(mavlink_set_gps_global_origin_t, target_system) }, \ + } \ + } + + +/** + * @brief Pack a set_gps_global_origin message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param target_system System ID + * @param latitude global position * 1E7 + * @param longitude global position * 1E7 + * @param altitude global position * 1000 + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_set_gps_global_origin_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t target_system, int32_t latitude, int32_t longitude, int32_t altitude) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[13]; + _mav_put_int32_t(buf, 0, latitude); + _mav_put_int32_t(buf, 4, longitude); + _mav_put_int32_t(buf, 8, altitude); + _mav_put_uint8_t(buf, 12, target_system); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 13); +#else + mavlink_set_gps_global_origin_t packet; + packet.latitude = latitude; + packet.longitude = longitude; + packet.altitude = altitude; + packet.target_system = target_system; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 13); +#endif + + msg->msgid = MAVLINK_MSG_ID_SET_GPS_GLOBAL_ORIGIN; + return mavlink_finalize_message(msg, system_id, component_id, 13, 41); +} + +/** + * @brief Pack a set_gps_global_origin message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param target_system System ID + * @param latitude global position * 1E7 + * @param longitude global position * 1E7 + * @param altitude global position * 1000 + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_set_gps_global_origin_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t target_system, int32_t latitude, int32_t longitude, int32_t altitude) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[13]; + _mav_put_int32_t(buf, 0, latitude); + _mav_put_int32_t(buf, 4, longitude); + _mav_put_int32_t(buf, 8, altitude); + _mav_put_uint8_t(buf, 12, target_system); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 13); +#else + mavlink_set_gps_global_origin_t packet; + packet.latitude = latitude; + packet.longitude = longitude; + packet.altitude = altitude; + packet.target_system = target_system; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 13); +#endif + + msg->msgid = MAVLINK_MSG_ID_SET_GPS_GLOBAL_ORIGIN; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 13, 41); +} + +/** + * @brief Encode a set_gps_global_origin struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param set_gps_global_origin C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_set_gps_global_origin_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_set_gps_global_origin_t *set_gps_global_origin) +{ + return mavlink_msg_set_gps_global_origin_pack(system_id, component_id, msg, set_gps_global_origin->target_system, set_gps_global_origin->latitude, set_gps_global_origin->longitude, set_gps_global_origin->altitude); +} + +/** + * @brief Send a set_gps_global_origin message + * @param chan MAVLink channel to send the message + * + * @param target_system System ID + * @param latitude global position * 1E7 + * @param longitude global position * 1E7 + * @param altitude global position * 1000 + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_set_gps_global_origin_send(mavlink_channel_t chan, uint8_t target_system, int32_t latitude, int32_t longitude, int32_t altitude) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[13]; + _mav_put_int32_t(buf, 0, latitude); + _mav_put_int32_t(buf, 4, longitude); + _mav_put_int32_t(buf, 8, altitude); + _mav_put_uint8_t(buf, 12, target_system); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SET_GPS_GLOBAL_ORIGIN, buf, 13, 41); +#else + mavlink_set_gps_global_origin_t packet; + packet.latitude = latitude; + packet.longitude = longitude; + packet.altitude = altitude; + packet.target_system = target_system; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SET_GPS_GLOBAL_ORIGIN, (const char *)&packet, 13, 41); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE SET_GPS_GLOBAL_ORIGIN UNPACKING + + +/** + * @brief Get field target_system from set_gps_global_origin message + * + * @return System ID + */ +static inline uint8_t mavlink_msg_set_gps_global_origin_get_target_system(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 12); +} + +/** + * @brief Get field latitude from set_gps_global_origin message + * + * @return global position * 1E7 + */ +static inline int32_t mavlink_msg_set_gps_global_origin_get_latitude(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int32_t(msg, 0); +} + +/** + * @brief Get field longitude from set_gps_global_origin message + * + * @return global position * 1E7 + */ +static inline int32_t mavlink_msg_set_gps_global_origin_get_longitude(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int32_t(msg, 4); +} + +/** + * @brief Get field altitude from set_gps_global_origin message + * + * @return global position * 1000 + */ +static inline int32_t mavlink_msg_set_gps_global_origin_get_altitude(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int32_t(msg, 8); +} + +/** + * @brief Decode a set_gps_global_origin message into a struct + * + * @param msg The message to decode + * @param set_gps_global_origin C-struct to decode the message contents into + */ +static inline void mavlink_msg_set_gps_global_origin_decode(const mavlink_message_t *msg, mavlink_set_gps_global_origin_t *set_gps_global_origin) +{ +#if MAVLINK_NEED_BYTE_SWAP + set_gps_global_origin->latitude = mavlink_msg_set_gps_global_origin_get_latitude(msg); + set_gps_global_origin->longitude = mavlink_msg_set_gps_global_origin_get_longitude(msg); + set_gps_global_origin->altitude = mavlink_msg_set_gps_global_origin_get_altitude(msg); + set_gps_global_origin->target_system = mavlink_msg_set_gps_global_origin_get_target_system(msg); +#else + memcpy(set_gps_global_origin, _MAV_PAYLOAD(msg), 13); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_set_local_position_setpoint.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_set_local_position_setpoint.h new file mode 100644 index 000000000..420d0d1b8 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_set_local_position_setpoint.h @@ -0,0 +1,276 @@ +// MESSAGE SET_LOCAL_POSITION_SETPOINT PACKING + +#define MAVLINK_MSG_ID_SET_LOCAL_POSITION_SETPOINT 50 + +typedef struct __mavlink_set_local_position_setpoint_t { + float x; ///< x position + float y; ///< y position + float z; ///< z position + float yaw; ///< Desired yaw angle + uint8_t target_system; ///< System ID + uint8_t target_component; ///< Component ID + uint8_t coordinate_frame; ///< Coordinate frame - valid values are only MAV_FRAME_LOCAL_NED or MAV_FRAME_LOCAL_ENU +} mavlink_set_local_position_setpoint_t; + +#define MAVLINK_MSG_ID_SET_LOCAL_POSITION_SETPOINT_LEN 19 +#define MAVLINK_MSG_ID_50_LEN 19 + + +#define MAVLINK_MESSAGE_INFO_SET_LOCAL_POSITION_SETPOINT \ + { \ + "SET_LOCAL_POSITION_SETPOINT", \ + 7, \ + { \ + { "x", NULL, MAVLINK_TYPE_FLOAT, 0, 0, offsetof(mavlink_set_local_position_setpoint_t, x) }, \ + { "y", NULL, MAVLINK_TYPE_FLOAT, 0, 4, offsetof(mavlink_set_local_position_setpoint_t, y) }, \ + { "z", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_set_local_position_setpoint_t, z) }, \ + { "yaw", NULL, MAVLINK_TYPE_FLOAT, 0, 12, offsetof(mavlink_set_local_position_setpoint_t, yaw) }, \ + { "target_system", NULL, MAVLINK_TYPE_UINT8_T, 0, 16, offsetof(mavlink_set_local_position_setpoint_t, target_system) }, \ + { "target_component", NULL, MAVLINK_TYPE_UINT8_T, 0, 17, offsetof(mavlink_set_local_position_setpoint_t, target_component) }, \ + { "coordinate_frame", NULL, MAVLINK_TYPE_UINT8_T, 0, 18, offsetof(mavlink_set_local_position_setpoint_t, coordinate_frame) }, \ + } \ + } + + +/** + * @brief Pack a set_local_position_setpoint message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param target_system System ID + * @param target_component Component ID + * @param coordinate_frame Coordinate frame - valid values are only MAV_FRAME_LOCAL_NED or MAV_FRAME_LOCAL_ENU + * @param x x position + * @param y y position + * @param z z position + * @param yaw Desired yaw angle + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_set_local_position_setpoint_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, uint8_t coordinate_frame, float x, float y, float z, float yaw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[19]; + _mav_put_float(buf, 0, x); + _mav_put_float(buf, 4, y); + _mav_put_float(buf, 8, z); + _mav_put_float(buf, 12, yaw); + _mav_put_uint8_t(buf, 16, target_system); + _mav_put_uint8_t(buf, 17, target_component); + _mav_put_uint8_t(buf, 18, coordinate_frame); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 19); +#else + mavlink_set_local_position_setpoint_t packet; + packet.x = x; + packet.y = y; + packet.z = z; + packet.yaw = yaw; + packet.target_system = target_system; + packet.target_component = target_component; + packet.coordinate_frame = coordinate_frame; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 19); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_SET_LOCAL_POSITION_SETPOINT; + return mavlink_finalize_message(msg, system_id, component_id, 19, 214); +} + +/** + * @brief Pack a set_local_position_setpoint message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param target_system System ID + * @param target_component Component ID + * @param coordinate_frame Coordinate frame - valid values are only MAV_FRAME_LOCAL_NED or MAV_FRAME_LOCAL_ENU + * @param x x position + * @param y y position + * @param z z position + * @param yaw Desired yaw angle + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_set_local_position_setpoint_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, uint8_t coordinate_frame, float x, float y, float z, float yaw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[19]; + _mav_put_float(buf, 0, x); + _mav_put_float(buf, 4, y); + _mav_put_float(buf, 8, z); + _mav_put_float(buf, 12, yaw); + _mav_put_uint8_t(buf, 16, target_system); + _mav_put_uint8_t(buf, 17, target_component); + _mav_put_uint8_t(buf, 18, coordinate_frame); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 19); +#else + mavlink_set_local_position_setpoint_t packet; + packet.x = x; + packet.y = y; + packet.z = z; + packet.yaw = yaw; + packet.target_system = target_system; + packet.target_component = target_component; + packet.coordinate_frame = coordinate_frame; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 19); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_SET_LOCAL_POSITION_SETPOINT; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 19, 214); +} + +/** + * @brief Encode a set_local_position_setpoint struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param set_local_position_setpoint C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_set_local_position_setpoint_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_set_local_position_setpoint_t *set_local_position_setpoint) +{ + return mavlink_msg_set_local_position_setpoint_pack(system_id, component_id, msg, set_local_position_setpoint->target_system, set_local_position_setpoint->target_component, set_local_position_setpoint->coordinate_frame, set_local_position_setpoint->x, set_local_position_setpoint->y, set_local_position_setpoint->z, set_local_position_setpoint->yaw); +} + +/** + * @brief Send a set_local_position_setpoint message + * @param chan MAVLink channel to send the message + * + * @param target_system System ID + * @param target_component Component ID + * @param coordinate_frame Coordinate frame - valid values are only MAV_FRAME_LOCAL_NED or MAV_FRAME_LOCAL_ENU + * @param x x position + * @param y y position + * @param z z position + * @param yaw Desired yaw angle + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_set_local_position_setpoint_send(mavlink_channel_t chan, uint8_t target_system, uint8_t target_component, uint8_t coordinate_frame, float x, float y, float z, float yaw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[19]; + _mav_put_float(buf, 0, x); + _mav_put_float(buf, 4, y); + _mav_put_float(buf, 8, z); + _mav_put_float(buf, 12, yaw); + _mav_put_uint8_t(buf, 16, target_system); + _mav_put_uint8_t(buf, 17, target_component); + _mav_put_uint8_t(buf, 18, coordinate_frame); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SET_LOCAL_POSITION_SETPOINT, buf, 19, 214); +#else + mavlink_set_local_position_setpoint_t packet; + packet.x = x; + packet.y = y; + packet.z = z; + packet.yaw = yaw; + packet.target_system = target_system; + packet.target_component = target_component; + packet.coordinate_frame = coordinate_frame; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SET_LOCAL_POSITION_SETPOINT, (const char *)&packet, 19, 214); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE SET_LOCAL_POSITION_SETPOINT UNPACKING + + +/** + * @brief Get field target_system from set_local_position_setpoint message + * + * @return System ID + */ +static inline uint8_t mavlink_msg_set_local_position_setpoint_get_target_system(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 16); +} + +/** + * @brief Get field target_component from set_local_position_setpoint message + * + * @return Component ID + */ +static inline uint8_t mavlink_msg_set_local_position_setpoint_get_target_component(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 17); +} + +/** + * @brief Get field coordinate_frame from set_local_position_setpoint message + * + * @return Coordinate frame - valid values are only MAV_FRAME_LOCAL_NED or MAV_FRAME_LOCAL_ENU + */ +static inline uint8_t mavlink_msg_set_local_position_setpoint_get_coordinate_frame(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 18); +} + +/** + * @brief Get field x from set_local_position_setpoint message + * + * @return x position + */ +static inline float mavlink_msg_set_local_position_setpoint_get_x(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 0); +} + +/** + * @brief Get field y from set_local_position_setpoint message + * + * @return y position + */ +static inline float mavlink_msg_set_local_position_setpoint_get_y(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 4); +} + +/** + * @brief Get field z from set_local_position_setpoint message + * + * @return z position + */ +static inline float mavlink_msg_set_local_position_setpoint_get_z(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 8); +} + +/** + * @brief Get field yaw from set_local_position_setpoint message + * + * @return Desired yaw angle + */ +static inline float mavlink_msg_set_local_position_setpoint_get_yaw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 12); +} + +/** + * @brief Decode a set_local_position_setpoint message into a struct + * + * @param msg The message to decode + * @param set_local_position_setpoint C-struct to decode the message contents into + */ +static inline void mavlink_msg_set_local_position_setpoint_decode(const mavlink_message_t *msg, mavlink_set_local_position_setpoint_t *set_local_position_setpoint) +{ +#if MAVLINK_NEED_BYTE_SWAP + set_local_position_setpoint->x = mavlink_msg_set_local_position_setpoint_get_x(msg); + set_local_position_setpoint->y = mavlink_msg_set_local_position_setpoint_get_y(msg); + set_local_position_setpoint->z = mavlink_msg_set_local_position_setpoint_get_z(msg); + set_local_position_setpoint->yaw = mavlink_msg_set_local_position_setpoint_get_yaw(msg); + set_local_position_setpoint->target_system = mavlink_msg_set_local_position_setpoint_get_target_system(msg); + set_local_position_setpoint->target_component = mavlink_msg_set_local_position_setpoint_get_target_component(msg); + set_local_position_setpoint->coordinate_frame = mavlink_msg_set_local_position_setpoint_get_coordinate_frame(msg); +#else + memcpy(set_local_position_setpoint, _MAV_PAYLOAD(msg), 19); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_set_mode.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_set_mode.h new file mode 100644 index 000000000..6c6474801 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_set_mode.h @@ -0,0 +1,188 @@ +// MESSAGE SET_MODE PACKING + +#define MAVLINK_MSG_ID_SET_MODE 11 + +typedef struct __mavlink_set_mode_t { + uint32_t custom_mode; ///< The new autopilot-specific mode. This field can be ignored by an autopilot. + uint8_t target_system; ///< The system setting the mode + uint8_t base_mode; ///< The new base mode +} mavlink_set_mode_t; + +#define MAVLINK_MSG_ID_SET_MODE_LEN 6 +#define MAVLINK_MSG_ID_11_LEN 6 + + +#define MAVLINK_MESSAGE_INFO_SET_MODE \ + { \ + "SET_MODE", \ + 3, \ + { \ + { "custom_mode", NULL, MAVLINK_TYPE_UINT32_T, 0, 0, offsetof(mavlink_set_mode_t, custom_mode) }, \ + { "target_system", NULL, MAVLINK_TYPE_UINT8_T, 0, 4, offsetof(mavlink_set_mode_t, target_system) }, \ + { "base_mode", NULL, MAVLINK_TYPE_UINT8_T, 0, 5, offsetof(mavlink_set_mode_t, base_mode) }, \ + } \ + } + + +/** + * @brief Pack a set_mode message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param target_system The system setting the mode + * @param base_mode The new base mode + * @param custom_mode The new autopilot-specific mode. This field can be ignored by an autopilot. + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_set_mode_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t target_system, uint8_t base_mode, uint32_t custom_mode) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[6]; + _mav_put_uint32_t(buf, 0, custom_mode); + _mav_put_uint8_t(buf, 4, target_system); + _mav_put_uint8_t(buf, 5, base_mode); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 6); +#else + mavlink_set_mode_t packet; + packet.custom_mode = custom_mode; + packet.target_system = target_system; + packet.base_mode = base_mode; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 6); +#endif + + msg->msgid = MAVLINK_MSG_ID_SET_MODE; + return mavlink_finalize_message(msg, system_id, component_id, 6, 89); +} + +/** + * @brief Pack a set_mode message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param target_system The system setting the mode + * @param base_mode The new base mode + * @param custom_mode The new autopilot-specific mode. This field can be ignored by an autopilot. + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_set_mode_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t target_system, uint8_t base_mode, uint32_t custom_mode) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[6]; + _mav_put_uint32_t(buf, 0, custom_mode); + _mav_put_uint8_t(buf, 4, target_system); + _mav_put_uint8_t(buf, 5, base_mode); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 6); +#else + mavlink_set_mode_t packet; + packet.custom_mode = custom_mode; + packet.target_system = target_system; + packet.base_mode = base_mode; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 6); +#endif + + msg->msgid = MAVLINK_MSG_ID_SET_MODE; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 6, 89); +} + +/** + * @brief Encode a set_mode struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param set_mode C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_set_mode_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_set_mode_t *set_mode) +{ + return mavlink_msg_set_mode_pack(system_id, component_id, msg, set_mode->target_system, set_mode->base_mode, set_mode->custom_mode); +} + +/** + * @brief Send a set_mode message + * @param chan MAVLink channel to send the message + * + * @param target_system The system setting the mode + * @param base_mode The new base mode + * @param custom_mode The new autopilot-specific mode. This field can be ignored by an autopilot. + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_set_mode_send(mavlink_channel_t chan, uint8_t target_system, uint8_t base_mode, uint32_t custom_mode) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[6]; + _mav_put_uint32_t(buf, 0, custom_mode); + _mav_put_uint8_t(buf, 4, target_system); + _mav_put_uint8_t(buf, 5, base_mode); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SET_MODE, buf, 6, 89); +#else + mavlink_set_mode_t packet; + packet.custom_mode = custom_mode; + packet.target_system = target_system; + packet.base_mode = base_mode; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SET_MODE, (const char *)&packet, 6, 89); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE SET_MODE UNPACKING + + +/** + * @brief Get field target_system from set_mode message + * + * @return The system setting the mode + */ +static inline uint8_t mavlink_msg_set_mode_get_target_system(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 4); +} + +/** + * @brief Get field base_mode from set_mode message + * + * @return The new base mode + */ +static inline uint8_t mavlink_msg_set_mode_get_base_mode(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 5); +} + +/** + * @brief Get field custom_mode from set_mode message + * + * @return The new autopilot-specific mode. This field can be ignored by an autopilot. + */ +static inline uint32_t mavlink_msg_set_mode_get_custom_mode(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint32_t(msg, 0); +} + +/** + * @brief Decode a set_mode message into a struct + * + * @param msg The message to decode + * @param set_mode C-struct to decode the message contents into + */ +static inline void mavlink_msg_set_mode_decode(const mavlink_message_t *msg, mavlink_set_mode_t *set_mode) +{ +#if MAVLINK_NEED_BYTE_SWAP + set_mode->custom_mode = mavlink_msg_set_mode_get_custom_mode(msg); + set_mode->target_system = mavlink_msg_set_mode_get_target_system(msg); + set_mode->base_mode = mavlink_msg_set_mode_get_base_mode(msg); +#else + memcpy(set_mode, _MAV_PAYLOAD(msg), 6); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_set_quad_motors_setpoint.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_set_quad_motors_setpoint.h new file mode 100644 index 000000000..6fc2a9924 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_set_quad_motors_setpoint.h @@ -0,0 +1,232 @@ +// MESSAGE SET_QUAD_MOTORS_SETPOINT PACKING + +#define MAVLINK_MSG_ID_SET_QUAD_MOTORS_SETPOINT 60 + +typedef struct __mavlink_set_quad_motors_setpoint_t { + uint16_t motor_front_nw; ///< Front motor in + configuration, front left motor in x configuration + uint16_t motor_right_ne; ///< Right motor in + configuration, front right motor in x configuration + uint16_t motor_back_se; ///< Back motor in + configuration, back right motor in x configuration + uint16_t motor_left_sw; ///< Left motor in + configuration, back left motor in x configuration + uint8_t target_system; ///< System ID of the system that should set these motor commands +} mavlink_set_quad_motors_setpoint_t; + +#define MAVLINK_MSG_ID_SET_QUAD_MOTORS_SETPOINT_LEN 9 +#define MAVLINK_MSG_ID_60_LEN 9 + + +#define MAVLINK_MESSAGE_INFO_SET_QUAD_MOTORS_SETPOINT \ + { \ + "SET_QUAD_MOTORS_SETPOINT", \ + 5, \ + { \ + { "motor_front_nw", NULL, MAVLINK_TYPE_UINT16_T, 0, 0, offsetof(mavlink_set_quad_motors_setpoint_t, motor_front_nw) }, \ + { "motor_right_ne", NULL, MAVLINK_TYPE_UINT16_T, 0, 2, offsetof(mavlink_set_quad_motors_setpoint_t, motor_right_ne) }, \ + { "motor_back_se", NULL, MAVLINK_TYPE_UINT16_T, 0, 4, offsetof(mavlink_set_quad_motors_setpoint_t, motor_back_se) }, \ + { "motor_left_sw", NULL, MAVLINK_TYPE_UINT16_T, 0, 6, offsetof(mavlink_set_quad_motors_setpoint_t, motor_left_sw) }, \ + { "target_system", NULL, MAVLINK_TYPE_UINT8_T, 0, 8, offsetof(mavlink_set_quad_motors_setpoint_t, target_system) }, \ + } \ + } + + +/** + * @brief Pack a set_quad_motors_setpoint message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param target_system System ID of the system that should set these motor commands + * @param motor_front_nw Front motor in + configuration, front left motor in x configuration + * @param motor_right_ne Right motor in + configuration, front right motor in x configuration + * @param motor_back_se Back motor in + configuration, back right motor in x configuration + * @param motor_left_sw Left motor in + configuration, back left motor in x configuration + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_set_quad_motors_setpoint_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t target_system, uint16_t motor_front_nw, uint16_t motor_right_ne, uint16_t motor_back_se, uint16_t motor_left_sw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[9]; + _mav_put_uint16_t(buf, 0, motor_front_nw); + _mav_put_uint16_t(buf, 2, motor_right_ne); + _mav_put_uint16_t(buf, 4, motor_back_se); + _mav_put_uint16_t(buf, 6, motor_left_sw); + _mav_put_uint8_t(buf, 8, target_system); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 9); +#else + mavlink_set_quad_motors_setpoint_t packet; + packet.motor_front_nw = motor_front_nw; + packet.motor_right_ne = motor_right_ne; + packet.motor_back_se = motor_back_se; + packet.motor_left_sw = motor_left_sw; + packet.target_system = target_system; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 9); +#endif + + msg->msgid = MAVLINK_MSG_ID_SET_QUAD_MOTORS_SETPOINT; + return mavlink_finalize_message(msg, system_id, component_id, 9, 30); +} + +/** + * @brief Pack a set_quad_motors_setpoint message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param target_system System ID of the system that should set these motor commands + * @param motor_front_nw Front motor in + configuration, front left motor in x configuration + * @param motor_right_ne Right motor in + configuration, front right motor in x configuration + * @param motor_back_se Back motor in + configuration, back right motor in x configuration + * @param motor_left_sw Left motor in + configuration, back left motor in x configuration + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_set_quad_motors_setpoint_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t target_system, uint16_t motor_front_nw, uint16_t motor_right_ne, uint16_t motor_back_se, uint16_t motor_left_sw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[9]; + _mav_put_uint16_t(buf, 0, motor_front_nw); + _mav_put_uint16_t(buf, 2, motor_right_ne); + _mav_put_uint16_t(buf, 4, motor_back_se); + _mav_put_uint16_t(buf, 6, motor_left_sw); + _mav_put_uint8_t(buf, 8, target_system); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 9); +#else + mavlink_set_quad_motors_setpoint_t packet; + packet.motor_front_nw = motor_front_nw; + packet.motor_right_ne = motor_right_ne; + packet.motor_back_se = motor_back_se; + packet.motor_left_sw = motor_left_sw; + packet.target_system = target_system; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 9); +#endif + + msg->msgid = MAVLINK_MSG_ID_SET_QUAD_MOTORS_SETPOINT; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 9, 30); +} + +/** + * @brief Encode a set_quad_motors_setpoint struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param set_quad_motors_setpoint C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_set_quad_motors_setpoint_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_set_quad_motors_setpoint_t *set_quad_motors_setpoint) +{ + return mavlink_msg_set_quad_motors_setpoint_pack(system_id, component_id, msg, set_quad_motors_setpoint->target_system, set_quad_motors_setpoint->motor_front_nw, set_quad_motors_setpoint->motor_right_ne, set_quad_motors_setpoint->motor_back_se, set_quad_motors_setpoint->motor_left_sw); +} + +/** + * @brief Send a set_quad_motors_setpoint message + * @param chan MAVLink channel to send the message + * + * @param target_system System ID of the system that should set these motor commands + * @param motor_front_nw Front motor in + configuration, front left motor in x configuration + * @param motor_right_ne Right motor in + configuration, front right motor in x configuration + * @param motor_back_se Back motor in + configuration, back right motor in x configuration + * @param motor_left_sw Left motor in + configuration, back left motor in x configuration + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_set_quad_motors_setpoint_send(mavlink_channel_t chan, uint8_t target_system, uint16_t motor_front_nw, uint16_t motor_right_ne, uint16_t motor_back_se, uint16_t motor_left_sw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[9]; + _mav_put_uint16_t(buf, 0, motor_front_nw); + _mav_put_uint16_t(buf, 2, motor_right_ne); + _mav_put_uint16_t(buf, 4, motor_back_se); + _mav_put_uint16_t(buf, 6, motor_left_sw); + _mav_put_uint8_t(buf, 8, target_system); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SET_QUAD_MOTORS_SETPOINT, buf, 9, 30); +#else + mavlink_set_quad_motors_setpoint_t packet; + packet.motor_front_nw = motor_front_nw; + packet.motor_right_ne = motor_right_ne; + packet.motor_back_se = motor_back_se; + packet.motor_left_sw = motor_left_sw; + packet.target_system = target_system; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SET_QUAD_MOTORS_SETPOINT, (const char *)&packet, 9, 30); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE SET_QUAD_MOTORS_SETPOINT UNPACKING + + +/** + * @brief Get field target_system from set_quad_motors_setpoint message + * + * @return System ID of the system that should set these motor commands + */ +static inline uint8_t mavlink_msg_set_quad_motors_setpoint_get_target_system(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 8); +} + +/** + * @brief Get field motor_front_nw from set_quad_motors_setpoint message + * + * @return Front motor in + configuration, front left motor in x configuration + */ +static inline uint16_t mavlink_msg_set_quad_motors_setpoint_get_motor_front_nw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 0); +} + +/** + * @brief Get field motor_right_ne from set_quad_motors_setpoint message + * + * @return Right motor in + configuration, front right motor in x configuration + */ +static inline uint16_t mavlink_msg_set_quad_motors_setpoint_get_motor_right_ne(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 2); +} + +/** + * @brief Get field motor_back_se from set_quad_motors_setpoint message + * + * @return Back motor in + configuration, back right motor in x configuration + */ +static inline uint16_t mavlink_msg_set_quad_motors_setpoint_get_motor_back_se(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 4); +} + +/** + * @brief Get field motor_left_sw from set_quad_motors_setpoint message + * + * @return Left motor in + configuration, back left motor in x configuration + */ +static inline uint16_t mavlink_msg_set_quad_motors_setpoint_get_motor_left_sw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 6); +} + +/** + * @brief Decode a set_quad_motors_setpoint message into a struct + * + * @param msg The message to decode + * @param set_quad_motors_setpoint C-struct to decode the message contents into + */ +static inline void mavlink_msg_set_quad_motors_setpoint_decode(const mavlink_message_t *msg, mavlink_set_quad_motors_setpoint_t *set_quad_motors_setpoint) +{ +#if MAVLINK_NEED_BYTE_SWAP + set_quad_motors_setpoint->motor_front_nw = mavlink_msg_set_quad_motors_setpoint_get_motor_front_nw(msg); + set_quad_motors_setpoint->motor_right_ne = mavlink_msg_set_quad_motors_setpoint_get_motor_right_ne(msg); + set_quad_motors_setpoint->motor_back_se = mavlink_msg_set_quad_motors_setpoint_get_motor_back_se(msg); + set_quad_motors_setpoint->motor_left_sw = mavlink_msg_set_quad_motors_setpoint_get_motor_left_sw(msg); + set_quad_motors_setpoint->target_system = mavlink_msg_set_quad_motors_setpoint_get_target_system(msg); +#else + memcpy(set_quad_motors_setpoint, _MAV_PAYLOAD(msg), 9); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust.h new file mode 100644 index 000000000..78a890dd1 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust.h @@ -0,0 +1,321 @@ +// MESSAGE SET_QUAD_SWARM_LED_ROLL_PITCH_YAW_THRUST PACKING + +#define MAVLINK_MSG_ID_SET_QUAD_SWARM_LED_ROLL_PITCH_YAW_THRUST 63 + +typedef struct __mavlink_set_quad_swarm_led_roll_pitch_yaw_thrust_t { + int16_t roll[4]; ///< Desired roll angle in radians +-PI (+-32767) + int16_t pitch[4]; ///< Desired pitch angle in radians +-PI (+-32767) + int16_t yaw[4]; ///< Desired yaw angle in radians, scaled to int16 +-PI (+-32767) + uint16_t thrust[4]; ///< Collective thrust, scaled to uint16 (0..65535) + uint8_t group; ///< ID of the quadrotor group (0 - 255, up to 256 groups supported) + uint8_t mode; ///< ID of the flight mode (0 - 255, up to 256 modes supported) + uint8_t led_red[4]; ///< RGB red channel (0-255) + uint8_t led_blue[4]; ///< RGB green channel (0-255) + uint8_t led_green[4]; ///< RGB blue channel (0-255) +} mavlink_set_quad_swarm_led_roll_pitch_yaw_thrust_t; + +#define MAVLINK_MSG_ID_SET_QUAD_SWARM_LED_ROLL_PITCH_YAW_THRUST_LEN 46 +#define MAVLINK_MSG_ID_63_LEN 46 + +#define MAVLINK_MSG_SET_QUAD_SWARM_LED_ROLL_PITCH_YAW_THRUST_FIELD_ROLL_LEN 4 +#define MAVLINK_MSG_SET_QUAD_SWARM_LED_ROLL_PITCH_YAW_THRUST_FIELD_PITCH_LEN 4 +#define MAVLINK_MSG_SET_QUAD_SWARM_LED_ROLL_PITCH_YAW_THRUST_FIELD_YAW_LEN 4 +#define MAVLINK_MSG_SET_QUAD_SWARM_LED_ROLL_PITCH_YAW_THRUST_FIELD_THRUST_LEN 4 +#define MAVLINK_MSG_SET_QUAD_SWARM_LED_ROLL_PITCH_YAW_THRUST_FIELD_LED_RED_LEN 4 +#define MAVLINK_MSG_SET_QUAD_SWARM_LED_ROLL_PITCH_YAW_THRUST_FIELD_LED_BLUE_LEN 4 +#define MAVLINK_MSG_SET_QUAD_SWARM_LED_ROLL_PITCH_YAW_THRUST_FIELD_LED_GREEN_LEN 4 + +#define MAVLINK_MESSAGE_INFO_SET_QUAD_SWARM_LED_ROLL_PITCH_YAW_THRUST \ + { \ + "SET_QUAD_SWARM_LED_ROLL_PITCH_YAW_THRUST", \ + 9, \ + { \ + { "roll", NULL, MAVLINK_TYPE_INT16_T, 4, 0, offsetof(mavlink_set_quad_swarm_led_roll_pitch_yaw_thrust_t, roll) }, \ + { "pitch", NULL, MAVLINK_TYPE_INT16_T, 4, 8, offsetof(mavlink_set_quad_swarm_led_roll_pitch_yaw_thrust_t, pitch) }, \ + { "yaw", NULL, MAVLINK_TYPE_INT16_T, 4, 16, offsetof(mavlink_set_quad_swarm_led_roll_pitch_yaw_thrust_t, yaw) }, \ + { "thrust", NULL, MAVLINK_TYPE_UINT16_T, 4, 24, offsetof(mavlink_set_quad_swarm_led_roll_pitch_yaw_thrust_t, thrust) }, \ + { "group", NULL, MAVLINK_TYPE_UINT8_T, 0, 32, offsetof(mavlink_set_quad_swarm_led_roll_pitch_yaw_thrust_t, group) }, \ + { "mode", NULL, MAVLINK_TYPE_UINT8_T, 0, 33, offsetof(mavlink_set_quad_swarm_led_roll_pitch_yaw_thrust_t, mode) }, \ + { "led_red", NULL, MAVLINK_TYPE_UINT8_T, 4, 34, offsetof(mavlink_set_quad_swarm_led_roll_pitch_yaw_thrust_t, led_red) }, \ + { "led_blue", NULL, MAVLINK_TYPE_UINT8_T, 4, 38, offsetof(mavlink_set_quad_swarm_led_roll_pitch_yaw_thrust_t, led_blue) }, \ + { "led_green", NULL, MAVLINK_TYPE_UINT8_T, 4, 42, offsetof(mavlink_set_quad_swarm_led_roll_pitch_yaw_thrust_t, led_green) }, \ + } \ + } + + +/** + * @brief Pack a set_quad_swarm_led_roll_pitch_yaw_thrust message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param group ID of the quadrotor group (0 - 255, up to 256 groups supported) + * @param mode ID of the flight mode (0 - 255, up to 256 modes supported) + * @param led_red RGB red channel (0-255) + * @param led_blue RGB green channel (0-255) + * @param led_green RGB blue channel (0-255) + * @param roll Desired roll angle in radians +-PI (+-32767) + * @param pitch Desired pitch angle in radians +-PI (+-32767) + * @param yaw Desired yaw angle in radians, scaled to int16 +-PI (+-32767) + * @param thrust Collective thrust, scaled to uint16 (0..65535) + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t group, uint8_t mode, const uint8_t *led_red, const uint8_t *led_blue, const uint8_t *led_green, const int16_t *roll, const int16_t *pitch, const int16_t *yaw, const uint16_t *thrust) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[46]; + _mav_put_uint8_t(buf, 32, group); + _mav_put_uint8_t(buf, 33, mode); + _mav_put_int16_t_array(buf, 0, roll, 4); + _mav_put_int16_t_array(buf, 8, pitch, 4); + _mav_put_int16_t_array(buf, 16, yaw, 4); + _mav_put_uint16_t_array(buf, 24, thrust, 4); + _mav_put_uint8_t_array(buf, 34, led_red, 4); + _mav_put_uint8_t_array(buf, 38, led_blue, 4); + _mav_put_uint8_t_array(buf, 42, led_green, 4); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 46); +#else + mavlink_set_quad_swarm_led_roll_pitch_yaw_thrust_t packet; + packet.group = group; + packet.mode = mode; + mav_array_memcpy(packet.roll, roll, sizeof(int16_t) * 4); + mav_array_memcpy(packet.pitch, pitch, sizeof(int16_t) * 4); + mav_array_memcpy(packet.yaw, yaw, sizeof(int16_t) * 4); + mav_array_memcpy(packet.thrust, thrust, sizeof(uint16_t) * 4); + mav_array_memcpy(packet.led_red, led_red, sizeof(uint8_t) * 4); + mav_array_memcpy(packet.led_blue, led_blue, sizeof(uint8_t) * 4); + mav_array_memcpy(packet.led_green, led_green, sizeof(uint8_t) * 4); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 46); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_SET_QUAD_SWARM_LED_ROLL_PITCH_YAW_THRUST; + return mavlink_finalize_message(msg, system_id, component_id, 46, 130); +} + +/** + * @brief Pack a set_quad_swarm_led_roll_pitch_yaw_thrust message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param group ID of the quadrotor group (0 - 255, up to 256 groups supported) + * @param mode ID of the flight mode (0 - 255, up to 256 modes supported) + * @param led_red RGB red channel (0-255) + * @param led_blue RGB green channel (0-255) + * @param led_green RGB blue channel (0-255) + * @param roll Desired roll angle in radians +-PI (+-32767) + * @param pitch Desired pitch angle in radians +-PI (+-32767) + * @param yaw Desired yaw angle in radians, scaled to int16 +-PI (+-32767) + * @param thrust Collective thrust, scaled to uint16 (0..65535) + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t group, uint8_t mode, const uint8_t *led_red, const uint8_t *led_blue, const uint8_t *led_green, const int16_t *roll, const int16_t *pitch, const int16_t *yaw, const uint16_t *thrust) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[46]; + _mav_put_uint8_t(buf, 32, group); + _mav_put_uint8_t(buf, 33, mode); + _mav_put_int16_t_array(buf, 0, roll, 4); + _mav_put_int16_t_array(buf, 8, pitch, 4); + _mav_put_int16_t_array(buf, 16, yaw, 4); + _mav_put_uint16_t_array(buf, 24, thrust, 4); + _mav_put_uint8_t_array(buf, 34, led_red, 4); + _mav_put_uint8_t_array(buf, 38, led_blue, 4); + _mav_put_uint8_t_array(buf, 42, led_green, 4); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 46); +#else + mavlink_set_quad_swarm_led_roll_pitch_yaw_thrust_t packet; + packet.group = group; + packet.mode = mode; + mav_array_memcpy(packet.roll, roll, sizeof(int16_t) * 4); + mav_array_memcpy(packet.pitch, pitch, sizeof(int16_t) * 4); + mav_array_memcpy(packet.yaw, yaw, sizeof(int16_t) * 4); + mav_array_memcpy(packet.thrust, thrust, sizeof(uint16_t) * 4); + mav_array_memcpy(packet.led_red, led_red, sizeof(uint8_t) * 4); + mav_array_memcpy(packet.led_blue, led_blue, sizeof(uint8_t) * 4); + mav_array_memcpy(packet.led_green, led_green, sizeof(uint8_t) * 4); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 46); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_SET_QUAD_SWARM_LED_ROLL_PITCH_YAW_THRUST; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 46, 130); +} + +/** + * @brief Encode a set_quad_swarm_led_roll_pitch_yaw_thrust struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param set_quad_swarm_led_roll_pitch_yaw_thrust C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_set_quad_swarm_led_roll_pitch_yaw_thrust_t *set_quad_swarm_led_roll_pitch_yaw_thrust) +{ + return mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_pack(system_id, component_id, msg, set_quad_swarm_led_roll_pitch_yaw_thrust->group, set_quad_swarm_led_roll_pitch_yaw_thrust->mode, set_quad_swarm_led_roll_pitch_yaw_thrust->led_red, set_quad_swarm_led_roll_pitch_yaw_thrust->led_blue, set_quad_swarm_led_roll_pitch_yaw_thrust->led_green, set_quad_swarm_led_roll_pitch_yaw_thrust->roll, set_quad_swarm_led_roll_pitch_yaw_thrust->pitch, set_quad_swarm_led_roll_pitch_yaw_thrust->yaw, set_quad_swarm_led_roll_pitch_yaw_thrust->thrust); +} + +/** + * @brief Send a set_quad_swarm_led_roll_pitch_yaw_thrust message + * @param chan MAVLink channel to send the message + * + * @param group ID of the quadrotor group (0 - 255, up to 256 groups supported) + * @param mode ID of the flight mode (0 - 255, up to 256 modes supported) + * @param led_red RGB red channel (0-255) + * @param led_blue RGB green channel (0-255) + * @param led_green RGB blue channel (0-255) + * @param roll Desired roll angle in radians +-PI (+-32767) + * @param pitch Desired pitch angle in radians +-PI (+-32767) + * @param yaw Desired yaw angle in radians, scaled to int16 +-PI (+-32767) + * @param thrust Collective thrust, scaled to uint16 (0..65535) + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_send(mavlink_channel_t chan, uint8_t group, uint8_t mode, const uint8_t *led_red, const uint8_t *led_blue, const uint8_t *led_green, const int16_t *roll, const int16_t *pitch, const int16_t *yaw, const uint16_t *thrust) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[46]; + _mav_put_uint8_t(buf, 32, group); + _mav_put_uint8_t(buf, 33, mode); + _mav_put_int16_t_array(buf, 0, roll, 4); + _mav_put_int16_t_array(buf, 8, pitch, 4); + _mav_put_int16_t_array(buf, 16, yaw, 4); + _mav_put_uint16_t_array(buf, 24, thrust, 4); + _mav_put_uint8_t_array(buf, 34, led_red, 4); + _mav_put_uint8_t_array(buf, 38, led_blue, 4); + _mav_put_uint8_t_array(buf, 42, led_green, 4); + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SET_QUAD_SWARM_LED_ROLL_PITCH_YAW_THRUST, buf, 46, 130); +#else + mavlink_set_quad_swarm_led_roll_pitch_yaw_thrust_t packet; + packet.group = group; + packet.mode = mode; + mav_array_memcpy(packet.roll, roll, sizeof(int16_t) * 4); + mav_array_memcpy(packet.pitch, pitch, sizeof(int16_t) * 4); + mav_array_memcpy(packet.yaw, yaw, sizeof(int16_t) * 4); + mav_array_memcpy(packet.thrust, thrust, sizeof(uint16_t) * 4); + mav_array_memcpy(packet.led_red, led_red, sizeof(uint8_t) * 4); + mav_array_memcpy(packet.led_blue, led_blue, sizeof(uint8_t) * 4); + mav_array_memcpy(packet.led_green, led_green, sizeof(uint8_t) * 4); + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SET_QUAD_SWARM_LED_ROLL_PITCH_YAW_THRUST, (const char *)&packet, 46, 130); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE SET_QUAD_SWARM_LED_ROLL_PITCH_YAW_THRUST UNPACKING + + +/** + * @brief Get field group from set_quad_swarm_led_roll_pitch_yaw_thrust message + * + * @return ID of the quadrotor group (0 - 255, up to 256 groups supported) + */ +static inline uint8_t mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_get_group(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 32); +} + +/** + * @brief Get field mode from set_quad_swarm_led_roll_pitch_yaw_thrust message + * + * @return ID of the flight mode (0 - 255, up to 256 modes supported) + */ +static inline uint8_t mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_get_mode(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 33); +} + +/** + * @brief Get field led_red from set_quad_swarm_led_roll_pitch_yaw_thrust message + * + * @return RGB red channel (0-255) + */ +static inline uint16_t mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_get_led_red(const mavlink_message_t *msg, uint8_t *led_red) +{ + return _MAV_RETURN_uint8_t_array(msg, led_red, 4, 34); +} + +/** + * @brief Get field led_blue from set_quad_swarm_led_roll_pitch_yaw_thrust message + * + * @return RGB green channel (0-255) + */ +static inline uint16_t mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_get_led_blue(const mavlink_message_t *msg, uint8_t *led_blue) +{ + return _MAV_RETURN_uint8_t_array(msg, led_blue, 4, 38); +} + +/** + * @brief Get field led_green from set_quad_swarm_led_roll_pitch_yaw_thrust message + * + * @return RGB blue channel (0-255) + */ +static inline uint16_t mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_get_led_green(const mavlink_message_t *msg, uint8_t *led_green) +{ + return _MAV_RETURN_uint8_t_array(msg, led_green, 4, 42); +} + +/** + * @brief Get field roll from set_quad_swarm_led_roll_pitch_yaw_thrust message + * + * @return Desired roll angle in radians +-PI (+-32767) + */ +static inline uint16_t mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_get_roll(const mavlink_message_t *msg, int16_t *roll) +{ + return _MAV_RETURN_int16_t_array(msg, roll, 4, 0); +} + +/** + * @brief Get field pitch from set_quad_swarm_led_roll_pitch_yaw_thrust message + * + * @return Desired pitch angle in radians +-PI (+-32767) + */ +static inline uint16_t mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_get_pitch(const mavlink_message_t *msg, int16_t *pitch) +{ + return _MAV_RETURN_int16_t_array(msg, pitch, 4, 8); +} + +/** + * @brief Get field yaw from set_quad_swarm_led_roll_pitch_yaw_thrust message + * + * @return Desired yaw angle in radians, scaled to int16 +-PI (+-32767) + */ +static inline uint16_t mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_get_yaw(const mavlink_message_t *msg, int16_t *yaw) +{ + return _MAV_RETURN_int16_t_array(msg, yaw, 4, 16); +} + +/** + * @brief Get field thrust from set_quad_swarm_led_roll_pitch_yaw_thrust message + * + * @return Collective thrust, scaled to uint16 (0..65535) + */ +static inline uint16_t mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_get_thrust(const mavlink_message_t *msg, uint16_t *thrust) +{ + return _MAV_RETURN_uint16_t_array(msg, thrust, 4, 24); +} + +/** + * @brief Decode a set_quad_swarm_led_roll_pitch_yaw_thrust message into a struct + * + * @param msg The message to decode + * @param set_quad_swarm_led_roll_pitch_yaw_thrust C-struct to decode the message contents into + */ +static inline void mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_decode(const mavlink_message_t *msg, mavlink_set_quad_swarm_led_roll_pitch_yaw_thrust_t *set_quad_swarm_led_roll_pitch_yaw_thrust) +{ +#if MAVLINK_NEED_BYTE_SWAP + mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_get_roll(msg, set_quad_swarm_led_roll_pitch_yaw_thrust->roll); + mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_get_pitch(msg, set_quad_swarm_led_roll_pitch_yaw_thrust->pitch); + mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_get_yaw(msg, set_quad_swarm_led_roll_pitch_yaw_thrust->yaw); + mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_get_thrust(msg, set_quad_swarm_led_roll_pitch_yaw_thrust->thrust); + set_quad_swarm_led_roll_pitch_yaw_thrust->group = mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_get_group(msg); + set_quad_swarm_led_roll_pitch_yaw_thrust->mode = mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_get_mode(msg); + mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_get_led_red(msg, set_quad_swarm_led_roll_pitch_yaw_thrust->led_red); + mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_get_led_blue(msg, set_quad_swarm_led_roll_pitch_yaw_thrust->led_blue); + mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_get_led_green(msg, set_quad_swarm_led_roll_pitch_yaw_thrust->led_green); +#else + memcpy(set_quad_swarm_led_roll_pitch_yaw_thrust, _MAV_PAYLOAD(msg), 46); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust.h new file mode 100644 index 000000000..17bd7da8a --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust.h @@ -0,0 +1,252 @@ +// MESSAGE SET_QUAD_SWARM_ROLL_PITCH_YAW_THRUST PACKING + +#define MAVLINK_MSG_ID_SET_QUAD_SWARM_ROLL_PITCH_YAW_THRUST 61 + +typedef struct __mavlink_set_quad_swarm_roll_pitch_yaw_thrust_t { + int16_t roll[4]; ///< Desired roll angle in radians +-PI (+-32767) + int16_t pitch[4]; ///< Desired pitch angle in radians +-PI (+-32767) + int16_t yaw[4]; ///< Desired yaw angle in radians, scaled to int16 +-PI (+-32767) + uint16_t thrust[4]; ///< Collective thrust, scaled to uint16 (0..65535) + uint8_t group; ///< ID of the quadrotor group (0 - 255, up to 256 groups supported) + uint8_t mode; ///< ID of the flight mode (0 - 255, up to 256 modes supported) +} mavlink_set_quad_swarm_roll_pitch_yaw_thrust_t; + +#define MAVLINK_MSG_ID_SET_QUAD_SWARM_ROLL_PITCH_YAW_THRUST_LEN 34 +#define MAVLINK_MSG_ID_61_LEN 34 + +#define MAVLINK_MSG_SET_QUAD_SWARM_ROLL_PITCH_YAW_THRUST_FIELD_ROLL_LEN 4 +#define MAVLINK_MSG_SET_QUAD_SWARM_ROLL_PITCH_YAW_THRUST_FIELD_PITCH_LEN 4 +#define MAVLINK_MSG_SET_QUAD_SWARM_ROLL_PITCH_YAW_THRUST_FIELD_YAW_LEN 4 +#define MAVLINK_MSG_SET_QUAD_SWARM_ROLL_PITCH_YAW_THRUST_FIELD_THRUST_LEN 4 + +#define MAVLINK_MESSAGE_INFO_SET_QUAD_SWARM_ROLL_PITCH_YAW_THRUST \ + { \ + "SET_QUAD_SWARM_ROLL_PITCH_YAW_THRUST", \ + 6, \ + { \ + { "roll", NULL, MAVLINK_TYPE_INT16_T, 4, 0, offsetof(mavlink_set_quad_swarm_roll_pitch_yaw_thrust_t, roll) }, \ + { "pitch", NULL, MAVLINK_TYPE_INT16_T, 4, 8, offsetof(mavlink_set_quad_swarm_roll_pitch_yaw_thrust_t, pitch) }, \ + { "yaw", NULL, MAVLINK_TYPE_INT16_T, 4, 16, offsetof(mavlink_set_quad_swarm_roll_pitch_yaw_thrust_t, yaw) }, \ + { "thrust", NULL, MAVLINK_TYPE_UINT16_T, 4, 24, offsetof(mavlink_set_quad_swarm_roll_pitch_yaw_thrust_t, thrust) }, \ + { "group", NULL, MAVLINK_TYPE_UINT8_T, 0, 32, offsetof(mavlink_set_quad_swarm_roll_pitch_yaw_thrust_t, group) }, \ + { "mode", NULL, MAVLINK_TYPE_UINT8_T, 0, 33, offsetof(mavlink_set_quad_swarm_roll_pitch_yaw_thrust_t, mode) }, \ + } \ + } + + +/** + * @brief Pack a set_quad_swarm_roll_pitch_yaw_thrust message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param group ID of the quadrotor group (0 - 255, up to 256 groups supported) + * @param mode ID of the flight mode (0 - 255, up to 256 modes supported) + * @param roll Desired roll angle in radians +-PI (+-32767) + * @param pitch Desired pitch angle in radians +-PI (+-32767) + * @param yaw Desired yaw angle in radians, scaled to int16 +-PI (+-32767) + * @param thrust Collective thrust, scaled to uint16 (0..65535) + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t group, uint8_t mode, const int16_t *roll, const int16_t *pitch, const int16_t *yaw, const uint16_t *thrust) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[34]; + _mav_put_uint8_t(buf, 32, group); + _mav_put_uint8_t(buf, 33, mode); + _mav_put_int16_t_array(buf, 0, roll, 4); + _mav_put_int16_t_array(buf, 8, pitch, 4); + _mav_put_int16_t_array(buf, 16, yaw, 4); + _mav_put_uint16_t_array(buf, 24, thrust, 4); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 34); +#else + mavlink_set_quad_swarm_roll_pitch_yaw_thrust_t packet; + packet.group = group; + packet.mode = mode; + mav_array_memcpy(packet.roll, roll, sizeof(int16_t) * 4); + mav_array_memcpy(packet.pitch, pitch, sizeof(int16_t) * 4); + mav_array_memcpy(packet.yaw, yaw, sizeof(int16_t) * 4); + mav_array_memcpy(packet.thrust, thrust, sizeof(uint16_t) * 4); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 34); +#endif + + msg->msgid = MAVLINK_MSG_ID_SET_QUAD_SWARM_ROLL_PITCH_YAW_THRUST; + return mavlink_finalize_message(msg, system_id, component_id, 34, 240); +} + +/** + * @brief Pack a set_quad_swarm_roll_pitch_yaw_thrust message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param group ID of the quadrotor group (0 - 255, up to 256 groups supported) + * @param mode ID of the flight mode (0 - 255, up to 256 modes supported) + * @param roll Desired roll angle in radians +-PI (+-32767) + * @param pitch Desired pitch angle in radians +-PI (+-32767) + * @param yaw Desired yaw angle in radians, scaled to int16 +-PI (+-32767) + * @param thrust Collective thrust, scaled to uint16 (0..65535) + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t group, uint8_t mode, const int16_t *roll, const int16_t *pitch, const int16_t *yaw, const uint16_t *thrust) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[34]; + _mav_put_uint8_t(buf, 32, group); + _mav_put_uint8_t(buf, 33, mode); + _mav_put_int16_t_array(buf, 0, roll, 4); + _mav_put_int16_t_array(buf, 8, pitch, 4); + _mav_put_int16_t_array(buf, 16, yaw, 4); + _mav_put_uint16_t_array(buf, 24, thrust, 4); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 34); +#else + mavlink_set_quad_swarm_roll_pitch_yaw_thrust_t packet; + packet.group = group; + packet.mode = mode; + mav_array_memcpy(packet.roll, roll, sizeof(int16_t) * 4); + mav_array_memcpy(packet.pitch, pitch, sizeof(int16_t) * 4); + mav_array_memcpy(packet.yaw, yaw, sizeof(int16_t) * 4); + mav_array_memcpy(packet.thrust, thrust, sizeof(uint16_t) * 4); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 34); +#endif + + msg->msgid = MAVLINK_MSG_ID_SET_QUAD_SWARM_ROLL_PITCH_YAW_THRUST; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 34, 240); +} + +/** + * @brief Encode a set_quad_swarm_roll_pitch_yaw_thrust struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param set_quad_swarm_roll_pitch_yaw_thrust C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_set_quad_swarm_roll_pitch_yaw_thrust_t *set_quad_swarm_roll_pitch_yaw_thrust) +{ + return mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_pack(system_id, component_id, msg, set_quad_swarm_roll_pitch_yaw_thrust->group, set_quad_swarm_roll_pitch_yaw_thrust->mode, set_quad_swarm_roll_pitch_yaw_thrust->roll, set_quad_swarm_roll_pitch_yaw_thrust->pitch, set_quad_swarm_roll_pitch_yaw_thrust->yaw, set_quad_swarm_roll_pitch_yaw_thrust->thrust); +} + +/** + * @brief Send a set_quad_swarm_roll_pitch_yaw_thrust message + * @param chan MAVLink channel to send the message + * + * @param group ID of the quadrotor group (0 - 255, up to 256 groups supported) + * @param mode ID of the flight mode (0 - 255, up to 256 modes supported) + * @param roll Desired roll angle in radians +-PI (+-32767) + * @param pitch Desired pitch angle in radians +-PI (+-32767) + * @param yaw Desired yaw angle in radians, scaled to int16 +-PI (+-32767) + * @param thrust Collective thrust, scaled to uint16 (0..65535) + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_send(mavlink_channel_t chan, uint8_t group, uint8_t mode, const int16_t *roll, const int16_t *pitch, const int16_t *yaw, const uint16_t *thrust) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[34]; + _mav_put_uint8_t(buf, 32, group); + _mav_put_uint8_t(buf, 33, mode); + _mav_put_int16_t_array(buf, 0, roll, 4); + _mav_put_int16_t_array(buf, 8, pitch, 4); + _mav_put_int16_t_array(buf, 16, yaw, 4); + _mav_put_uint16_t_array(buf, 24, thrust, 4); + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SET_QUAD_SWARM_ROLL_PITCH_YAW_THRUST, buf, 34, 240); +#else + mavlink_set_quad_swarm_roll_pitch_yaw_thrust_t packet; + packet.group = group; + packet.mode = mode; + mav_array_memcpy(packet.roll, roll, sizeof(int16_t) * 4); + mav_array_memcpy(packet.pitch, pitch, sizeof(int16_t) * 4); + mav_array_memcpy(packet.yaw, yaw, sizeof(int16_t) * 4); + mav_array_memcpy(packet.thrust, thrust, sizeof(uint16_t) * 4); + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SET_QUAD_SWARM_ROLL_PITCH_YAW_THRUST, (const char *)&packet, 34, 240); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE SET_QUAD_SWARM_ROLL_PITCH_YAW_THRUST UNPACKING + + +/** + * @brief Get field group from set_quad_swarm_roll_pitch_yaw_thrust message + * + * @return ID of the quadrotor group (0 - 255, up to 256 groups supported) + */ +static inline uint8_t mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_get_group(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 32); +} + +/** + * @brief Get field mode from set_quad_swarm_roll_pitch_yaw_thrust message + * + * @return ID of the flight mode (0 - 255, up to 256 modes supported) + */ +static inline uint8_t mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_get_mode(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 33); +} + +/** + * @brief Get field roll from set_quad_swarm_roll_pitch_yaw_thrust message + * + * @return Desired roll angle in radians +-PI (+-32767) + */ +static inline uint16_t mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_get_roll(const mavlink_message_t *msg, int16_t *roll) +{ + return _MAV_RETURN_int16_t_array(msg, roll, 4, 0); +} + +/** + * @brief Get field pitch from set_quad_swarm_roll_pitch_yaw_thrust message + * + * @return Desired pitch angle in radians +-PI (+-32767) + */ +static inline uint16_t mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_get_pitch(const mavlink_message_t *msg, int16_t *pitch) +{ + return _MAV_RETURN_int16_t_array(msg, pitch, 4, 8); +} + +/** + * @brief Get field yaw from set_quad_swarm_roll_pitch_yaw_thrust message + * + * @return Desired yaw angle in radians, scaled to int16 +-PI (+-32767) + */ +static inline uint16_t mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_get_yaw(const mavlink_message_t *msg, int16_t *yaw) +{ + return _MAV_RETURN_int16_t_array(msg, yaw, 4, 16); +} + +/** + * @brief Get field thrust from set_quad_swarm_roll_pitch_yaw_thrust message + * + * @return Collective thrust, scaled to uint16 (0..65535) + */ +static inline uint16_t mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_get_thrust(const mavlink_message_t *msg, uint16_t *thrust) +{ + return _MAV_RETURN_uint16_t_array(msg, thrust, 4, 24); +} + +/** + * @brief Decode a set_quad_swarm_roll_pitch_yaw_thrust message into a struct + * + * @param msg The message to decode + * @param set_quad_swarm_roll_pitch_yaw_thrust C-struct to decode the message contents into + */ +static inline void mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_decode(const mavlink_message_t *msg, mavlink_set_quad_swarm_roll_pitch_yaw_thrust_t *set_quad_swarm_roll_pitch_yaw_thrust) +{ +#if MAVLINK_NEED_BYTE_SWAP + mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_get_roll(msg, set_quad_swarm_roll_pitch_yaw_thrust->roll); + mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_get_pitch(msg, set_quad_swarm_roll_pitch_yaw_thrust->pitch); + mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_get_yaw(msg, set_quad_swarm_roll_pitch_yaw_thrust->yaw); + mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_get_thrust(msg, set_quad_swarm_roll_pitch_yaw_thrust->thrust); + set_quad_swarm_roll_pitch_yaw_thrust->group = mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_get_group(msg); + set_quad_swarm_roll_pitch_yaw_thrust->mode = mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_get_mode(msg); +#else + memcpy(set_quad_swarm_roll_pitch_yaw_thrust, _MAV_PAYLOAD(msg), 34); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_set_roll_pitch_yaw_speed_thrust.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_set_roll_pitch_yaw_speed_thrust.h new file mode 100644 index 000000000..6778ee091 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_set_roll_pitch_yaw_speed_thrust.h @@ -0,0 +1,254 @@ +// MESSAGE SET_ROLL_PITCH_YAW_SPEED_THRUST PACKING + +#define MAVLINK_MSG_ID_SET_ROLL_PITCH_YAW_SPEED_THRUST 57 + +typedef struct __mavlink_set_roll_pitch_yaw_speed_thrust_t { + float roll_speed; ///< Desired roll angular speed in rad/s + float pitch_speed; ///< Desired pitch angular speed in rad/s + float yaw_speed; ///< Desired yaw angular speed in rad/s + float thrust; ///< Collective thrust, normalized to 0 .. 1 + uint8_t target_system; ///< System ID + uint8_t target_component; ///< Component ID +} mavlink_set_roll_pitch_yaw_speed_thrust_t; + +#define MAVLINK_MSG_ID_SET_ROLL_PITCH_YAW_SPEED_THRUST_LEN 18 +#define MAVLINK_MSG_ID_57_LEN 18 + + +#define MAVLINK_MESSAGE_INFO_SET_ROLL_PITCH_YAW_SPEED_THRUST \ + { \ + "SET_ROLL_PITCH_YAW_SPEED_THRUST", \ + 6, \ + { \ + { "roll_speed", NULL, MAVLINK_TYPE_FLOAT, 0, 0, offsetof(mavlink_set_roll_pitch_yaw_speed_thrust_t, roll_speed) }, \ + { "pitch_speed", NULL, MAVLINK_TYPE_FLOAT, 0, 4, offsetof(mavlink_set_roll_pitch_yaw_speed_thrust_t, pitch_speed) }, \ + { "yaw_speed", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_set_roll_pitch_yaw_speed_thrust_t, yaw_speed) }, \ + { "thrust", NULL, MAVLINK_TYPE_FLOAT, 0, 12, offsetof(mavlink_set_roll_pitch_yaw_speed_thrust_t, thrust) }, \ + { "target_system", NULL, MAVLINK_TYPE_UINT8_T, 0, 16, offsetof(mavlink_set_roll_pitch_yaw_speed_thrust_t, target_system) }, \ + { "target_component", NULL, MAVLINK_TYPE_UINT8_T, 0, 17, offsetof(mavlink_set_roll_pitch_yaw_speed_thrust_t, target_component) }, \ + } \ + } + + +/** + * @brief Pack a set_roll_pitch_yaw_speed_thrust message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param target_system System ID + * @param target_component Component ID + * @param roll_speed Desired roll angular speed in rad/s + * @param pitch_speed Desired pitch angular speed in rad/s + * @param yaw_speed Desired yaw angular speed in rad/s + * @param thrust Collective thrust, normalized to 0 .. 1 + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_set_roll_pitch_yaw_speed_thrust_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, float roll_speed, float pitch_speed, float yaw_speed, float thrust) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[18]; + _mav_put_float(buf, 0, roll_speed); + _mav_put_float(buf, 4, pitch_speed); + _mav_put_float(buf, 8, yaw_speed); + _mav_put_float(buf, 12, thrust); + _mav_put_uint8_t(buf, 16, target_system); + _mav_put_uint8_t(buf, 17, target_component); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 18); +#else + mavlink_set_roll_pitch_yaw_speed_thrust_t packet; + packet.roll_speed = roll_speed; + packet.pitch_speed = pitch_speed; + packet.yaw_speed = yaw_speed; + packet.thrust = thrust; + packet.target_system = target_system; + packet.target_component = target_component; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 18); +#endif + + msg->msgid = MAVLINK_MSG_ID_SET_ROLL_PITCH_YAW_SPEED_THRUST; + return mavlink_finalize_message(msg, system_id, component_id, 18, 24); +} + +/** + * @brief Pack a set_roll_pitch_yaw_speed_thrust message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param target_system System ID + * @param target_component Component ID + * @param roll_speed Desired roll angular speed in rad/s + * @param pitch_speed Desired pitch angular speed in rad/s + * @param yaw_speed Desired yaw angular speed in rad/s + * @param thrust Collective thrust, normalized to 0 .. 1 + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_set_roll_pitch_yaw_speed_thrust_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, float roll_speed, float pitch_speed, float yaw_speed, float thrust) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[18]; + _mav_put_float(buf, 0, roll_speed); + _mav_put_float(buf, 4, pitch_speed); + _mav_put_float(buf, 8, yaw_speed); + _mav_put_float(buf, 12, thrust); + _mav_put_uint8_t(buf, 16, target_system); + _mav_put_uint8_t(buf, 17, target_component); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 18); +#else + mavlink_set_roll_pitch_yaw_speed_thrust_t packet; + packet.roll_speed = roll_speed; + packet.pitch_speed = pitch_speed; + packet.yaw_speed = yaw_speed; + packet.thrust = thrust; + packet.target_system = target_system; + packet.target_component = target_component; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 18); +#endif + + msg->msgid = MAVLINK_MSG_ID_SET_ROLL_PITCH_YAW_SPEED_THRUST; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 18, 24); +} + +/** + * @brief Encode a set_roll_pitch_yaw_speed_thrust struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param set_roll_pitch_yaw_speed_thrust C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_set_roll_pitch_yaw_speed_thrust_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_set_roll_pitch_yaw_speed_thrust_t *set_roll_pitch_yaw_speed_thrust) +{ + return mavlink_msg_set_roll_pitch_yaw_speed_thrust_pack(system_id, component_id, msg, set_roll_pitch_yaw_speed_thrust->target_system, set_roll_pitch_yaw_speed_thrust->target_component, set_roll_pitch_yaw_speed_thrust->roll_speed, set_roll_pitch_yaw_speed_thrust->pitch_speed, set_roll_pitch_yaw_speed_thrust->yaw_speed, set_roll_pitch_yaw_speed_thrust->thrust); +} + +/** + * @brief Send a set_roll_pitch_yaw_speed_thrust message + * @param chan MAVLink channel to send the message + * + * @param target_system System ID + * @param target_component Component ID + * @param roll_speed Desired roll angular speed in rad/s + * @param pitch_speed Desired pitch angular speed in rad/s + * @param yaw_speed Desired yaw angular speed in rad/s + * @param thrust Collective thrust, normalized to 0 .. 1 + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_set_roll_pitch_yaw_speed_thrust_send(mavlink_channel_t chan, uint8_t target_system, uint8_t target_component, float roll_speed, float pitch_speed, float yaw_speed, float thrust) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[18]; + _mav_put_float(buf, 0, roll_speed); + _mav_put_float(buf, 4, pitch_speed); + _mav_put_float(buf, 8, yaw_speed); + _mav_put_float(buf, 12, thrust); + _mav_put_uint8_t(buf, 16, target_system); + _mav_put_uint8_t(buf, 17, target_component); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SET_ROLL_PITCH_YAW_SPEED_THRUST, buf, 18, 24); +#else + mavlink_set_roll_pitch_yaw_speed_thrust_t packet; + packet.roll_speed = roll_speed; + packet.pitch_speed = pitch_speed; + packet.yaw_speed = yaw_speed; + packet.thrust = thrust; + packet.target_system = target_system; + packet.target_component = target_component; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SET_ROLL_PITCH_YAW_SPEED_THRUST, (const char *)&packet, 18, 24); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE SET_ROLL_PITCH_YAW_SPEED_THRUST UNPACKING + + +/** + * @brief Get field target_system from set_roll_pitch_yaw_speed_thrust message + * + * @return System ID + */ +static inline uint8_t mavlink_msg_set_roll_pitch_yaw_speed_thrust_get_target_system(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 16); +} + +/** + * @brief Get field target_component from set_roll_pitch_yaw_speed_thrust message + * + * @return Component ID + */ +static inline uint8_t mavlink_msg_set_roll_pitch_yaw_speed_thrust_get_target_component(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 17); +} + +/** + * @brief Get field roll_speed from set_roll_pitch_yaw_speed_thrust message + * + * @return Desired roll angular speed in rad/s + */ +static inline float mavlink_msg_set_roll_pitch_yaw_speed_thrust_get_roll_speed(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 0); +} + +/** + * @brief Get field pitch_speed from set_roll_pitch_yaw_speed_thrust message + * + * @return Desired pitch angular speed in rad/s + */ +static inline float mavlink_msg_set_roll_pitch_yaw_speed_thrust_get_pitch_speed(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 4); +} + +/** + * @brief Get field yaw_speed from set_roll_pitch_yaw_speed_thrust message + * + * @return Desired yaw angular speed in rad/s + */ +static inline float mavlink_msg_set_roll_pitch_yaw_speed_thrust_get_yaw_speed(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 8); +} + +/** + * @brief Get field thrust from set_roll_pitch_yaw_speed_thrust message + * + * @return Collective thrust, normalized to 0 .. 1 + */ +static inline float mavlink_msg_set_roll_pitch_yaw_speed_thrust_get_thrust(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 12); +} + +/** + * @brief Decode a set_roll_pitch_yaw_speed_thrust message into a struct + * + * @param msg The message to decode + * @param set_roll_pitch_yaw_speed_thrust C-struct to decode the message contents into + */ +static inline void mavlink_msg_set_roll_pitch_yaw_speed_thrust_decode(const mavlink_message_t *msg, mavlink_set_roll_pitch_yaw_speed_thrust_t *set_roll_pitch_yaw_speed_thrust) +{ +#if MAVLINK_NEED_BYTE_SWAP + set_roll_pitch_yaw_speed_thrust->roll_speed = mavlink_msg_set_roll_pitch_yaw_speed_thrust_get_roll_speed(msg); + set_roll_pitch_yaw_speed_thrust->pitch_speed = mavlink_msg_set_roll_pitch_yaw_speed_thrust_get_pitch_speed(msg); + set_roll_pitch_yaw_speed_thrust->yaw_speed = mavlink_msg_set_roll_pitch_yaw_speed_thrust_get_yaw_speed(msg); + set_roll_pitch_yaw_speed_thrust->thrust = mavlink_msg_set_roll_pitch_yaw_speed_thrust_get_thrust(msg); + set_roll_pitch_yaw_speed_thrust->target_system = mavlink_msg_set_roll_pitch_yaw_speed_thrust_get_target_system(msg); + set_roll_pitch_yaw_speed_thrust->target_component = mavlink_msg_set_roll_pitch_yaw_speed_thrust_get_target_component(msg); +#else + memcpy(set_roll_pitch_yaw_speed_thrust, _MAV_PAYLOAD(msg), 18); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_set_roll_pitch_yaw_thrust.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_set_roll_pitch_yaw_thrust.h new file mode 100644 index 000000000..5aea49a99 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_set_roll_pitch_yaw_thrust.h @@ -0,0 +1,254 @@ +// MESSAGE SET_ROLL_PITCH_YAW_THRUST PACKING + +#define MAVLINK_MSG_ID_SET_ROLL_PITCH_YAW_THRUST 56 + +typedef struct __mavlink_set_roll_pitch_yaw_thrust_t { + float roll; ///< Desired roll angle in radians + float pitch; ///< Desired pitch angle in radians + float yaw; ///< Desired yaw angle in radians + float thrust; ///< Collective thrust, normalized to 0 .. 1 + uint8_t target_system; ///< System ID + uint8_t target_component; ///< Component ID +} mavlink_set_roll_pitch_yaw_thrust_t; + +#define MAVLINK_MSG_ID_SET_ROLL_PITCH_YAW_THRUST_LEN 18 +#define MAVLINK_MSG_ID_56_LEN 18 + + +#define MAVLINK_MESSAGE_INFO_SET_ROLL_PITCH_YAW_THRUST \ + { \ + "SET_ROLL_PITCH_YAW_THRUST", \ + 6, \ + { \ + { "roll", NULL, MAVLINK_TYPE_FLOAT, 0, 0, offsetof(mavlink_set_roll_pitch_yaw_thrust_t, roll) }, \ + { "pitch", NULL, MAVLINK_TYPE_FLOAT, 0, 4, offsetof(mavlink_set_roll_pitch_yaw_thrust_t, pitch) }, \ + { "yaw", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_set_roll_pitch_yaw_thrust_t, yaw) }, \ + { "thrust", NULL, MAVLINK_TYPE_FLOAT, 0, 12, offsetof(mavlink_set_roll_pitch_yaw_thrust_t, thrust) }, \ + { "target_system", NULL, MAVLINK_TYPE_UINT8_T, 0, 16, offsetof(mavlink_set_roll_pitch_yaw_thrust_t, target_system) }, \ + { "target_component", NULL, MAVLINK_TYPE_UINT8_T, 0, 17, offsetof(mavlink_set_roll_pitch_yaw_thrust_t, target_component) }, \ + } \ + } + + +/** + * @brief Pack a set_roll_pitch_yaw_thrust message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param target_system System ID + * @param target_component Component ID + * @param roll Desired roll angle in radians + * @param pitch Desired pitch angle in radians + * @param yaw Desired yaw angle in radians + * @param thrust Collective thrust, normalized to 0 .. 1 + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_set_roll_pitch_yaw_thrust_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, float roll, float pitch, float yaw, float thrust) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[18]; + _mav_put_float(buf, 0, roll); + _mav_put_float(buf, 4, pitch); + _mav_put_float(buf, 8, yaw); + _mav_put_float(buf, 12, thrust); + _mav_put_uint8_t(buf, 16, target_system); + _mav_put_uint8_t(buf, 17, target_component); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 18); +#else + mavlink_set_roll_pitch_yaw_thrust_t packet; + packet.roll = roll; + packet.pitch = pitch; + packet.yaw = yaw; + packet.thrust = thrust; + packet.target_system = target_system; + packet.target_component = target_component; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 18); +#endif + + msg->msgid = MAVLINK_MSG_ID_SET_ROLL_PITCH_YAW_THRUST; + return mavlink_finalize_message(msg, system_id, component_id, 18, 100); +} + +/** + * @brief Pack a set_roll_pitch_yaw_thrust message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param target_system System ID + * @param target_component Component ID + * @param roll Desired roll angle in radians + * @param pitch Desired pitch angle in radians + * @param yaw Desired yaw angle in radians + * @param thrust Collective thrust, normalized to 0 .. 1 + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_set_roll_pitch_yaw_thrust_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t target_system, uint8_t target_component, float roll, float pitch, float yaw, float thrust) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[18]; + _mav_put_float(buf, 0, roll); + _mav_put_float(buf, 4, pitch); + _mav_put_float(buf, 8, yaw); + _mav_put_float(buf, 12, thrust); + _mav_put_uint8_t(buf, 16, target_system); + _mav_put_uint8_t(buf, 17, target_component); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 18); +#else + mavlink_set_roll_pitch_yaw_thrust_t packet; + packet.roll = roll; + packet.pitch = pitch; + packet.yaw = yaw; + packet.thrust = thrust; + packet.target_system = target_system; + packet.target_component = target_component; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 18); +#endif + + msg->msgid = MAVLINK_MSG_ID_SET_ROLL_PITCH_YAW_THRUST; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 18, 100); +} + +/** + * @brief Encode a set_roll_pitch_yaw_thrust struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param set_roll_pitch_yaw_thrust C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_set_roll_pitch_yaw_thrust_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_set_roll_pitch_yaw_thrust_t *set_roll_pitch_yaw_thrust) +{ + return mavlink_msg_set_roll_pitch_yaw_thrust_pack(system_id, component_id, msg, set_roll_pitch_yaw_thrust->target_system, set_roll_pitch_yaw_thrust->target_component, set_roll_pitch_yaw_thrust->roll, set_roll_pitch_yaw_thrust->pitch, set_roll_pitch_yaw_thrust->yaw, set_roll_pitch_yaw_thrust->thrust); +} + +/** + * @brief Send a set_roll_pitch_yaw_thrust message + * @param chan MAVLink channel to send the message + * + * @param target_system System ID + * @param target_component Component ID + * @param roll Desired roll angle in radians + * @param pitch Desired pitch angle in radians + * @param yaw Desired yaw angle in radians + * @param thrust Collective thrust, normalized to 0 .. 1 + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_set_roll_pitch_yaw_thrust_send(mavlink_channel_t chan, uint8_t target_system, uint8_t target_component, float roll, float pitch, float yaw, float thrust) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[18]; + _mav_put_float(buf, 0, roll); + _mav_put_float(buf, 4, pitch); + _mav_put_float(buf, 8, yaw); + _mav_put_float(buf, 12, thrust); + _mav_put_uint8_t(buf, 16, target_system); + _mav_put_uint8_t(buf, 17, target_component); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SET_ROLL_PITCH_YAW_THRUST, buf, 18, 100); +#else + mavlink_set_roll_pitch_yaw_thrust_t packet; + packet.roll = roll; + packet.pitch = pitch; + packet.yaw = yaw; + packet.thrust = thrust; + packet.target_system = target_system; + packet.target_component = target_component; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SET_ROLL_PITCH_YAW_THRUST, (const char *)&packet, 18, 100); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE SET_ROLL_PITCH_YAW_THRUST UNPACKING + + +/** + * @brief Get field target_system from set_roll_pitch_yaw_thrust message + * + * @return System ID + */ +static inline uint8_t mavlink_msg_set_roll_pitch_yaw_thrust_get_target_system(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 16); +} + +/** + * @brief Get field target_component from set_roll_pitch_yaw_thrust message + * + * @return Component ID + */ +static inline uint8_t mavlink_msg_set_roll_pitch_yaw_thrust_get_target_component(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 17); +} + +/** + * @brief Get field roll from set_roll_pitch_yaw_thrust message + * + * @return Desired roll angle in radians + */ +static inline float mavlink_msg_set_roll_pitch_yaw_thrust_get_roll(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 0); +} + +/** + * @brief Get field pitch from set_roll_pitch_yaw_thrust message + * + * @return Desired pitch angle in radians + */ +static inline float mavlink_msg_set_roll_pitch_yaw_thrust_get_pitch(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 4); +} + +/** + * @brief Get field yaw from set_roll_pitch_yaw_thrust message + * + * @return Desired yaw angle in radians + */ +static inline float mavlink_msg_set_roll_pitch_yaw_thrust_get_yaw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 8); +} + +/** + * @brief Get field thrust from set_roll_pitch_yaw_thrust message + * + * @return Collective thrust, normalized to 0 .. 1 + */ +static inline float mavlink_msg_set_roll_pitch_yaw_thrust_get_thrust(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 12); +} + +/** + * @brief Decode a set_roll_pitch_yaw_thrust message into a struct + * + * @param msg The message to decode + * @param set_roll_pitch_yaw_thrust C-struct to decode the message contents into + */ +static inline void mavlink_msg_set_roll_pitch_yaw_thrust_decode(const mavlink_message_t *msg, mavlink_set_roll_pitch_yaw_thrust_t *set_roll_pitch_yaw_thrust) +{ +#if MAVLINK_NEED_BYTE_SWAP + set_roll_pitch_yaw_thrust->roll = mavlink_msg_set_roll_pitch_yaw_thrust_get_roll(msg); + set_roll_pitch_yaw_thrust->pitch = mavlink_msg_set_roll_pitch_yaw_thrust_get_pitch(msg); + set_roll_pitch_yaw_thrust->yaw = mavlink_msg_set_roll_pitch_yaw_thrust_get_yaw(msg); + set_roll_pitch_yaw_thrust->thrust = mavlink_msg_set_roll_pitch_yaw_thrust_get_thrust(msg); + set_roll_pitch_yaw_thrust->target_system = mavlink_msg_set_roll_pitch_yaw_thrust_get_target_system(msg); + set_roll_pitch_yaw_thrust->target_component = mavlink_msg_set_roll_pitch_yaw_thrust_get_target_component(msg); +#else + memcpy(set_roll_pitch_yaw_thrust, _MAV_PAYLOAD(msg), 18); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_state_correction.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_state_correction.h new file mode 100644 index 000000000..759dd1789 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_state_correction.h @@ -0,0 +1,320 @@ +// MESSAGE STATE_CORRECTION PACKING + +#define MAVLINK_MSG_ID_STATE_CORRECTION 64 + +typedef struct __mavlink_state_correction_t { + float xErr; ///< x position error + float yErr; ///< y position error + float zErr; ///< z position error + float rollErr; ///< roll error (radians) + float pitchErr; ///< pitch error (radians) + float yawErr; ///< yaw error (radians) + float vxErr; ///< x velocity + float vyErr; ///< y velocity + float vzErr; ///< z velocity +} mavlink_state_correction_t; + +#define MAVLINK_MSG_ID_STATE_CORRECTION_LEN 36 +#define MAVLINK_MSG_ID_64_LEN 36 + + +#define MAVLINK_MESSAGE_INFO_STATE_CORRECTION \ + { \ + "STATE_CORRECTION", \ + 9, \ + { \ + { "xErr", NULL, MAVLINK_TYPE_FLOAT, 0, 0, offsetof(mavlink_state_correction_t, xErr) }, \ + { "yErr", NULL, MAVLINK_TYPE_FLOAT, 0, 4, offsetof(mavlink_state_correction_t, yErr) }, \ + { "zErr", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_state_correction_t, zErr) }, \ + { "rollErr", NULL, MAVLINK_TYPE_FLOAT, 0, 12, offsetof(mavlink_state_correction_t, rollErr) }, \ + { "pitchErr", NULL, MAVLINK_TYPE_FLOAT, 0, 16, offsetof(mavlink_state_correction_t, pitchErr) }, \ + { "yawErr", NULL, MAVLINK_TYPE_FLOAT, 0, 20, offsetof(mavlink_state_correction_t, yawErr) }, \ + { "vxErr", NULL, MAVLINK_TYPE_FLOAT, 0, 24, offsetof(mavlink_state_correction_t, vxErr) }, \ + { "vyErr", NULL, MAVLINK_TYPE_FLOAT, 0, 28, offsetof(mavlink_state_correction_t, vyErr) }, \ + { "vzErr", NULL, MAVLINK_TYPE_FLOAT, 0, 32, offsetof(mavlink_state_correction_t, vzErr) }, \ + } \ + } + + +/** + * @brief Pack a state_correction message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param xErr x position error + * @param yErr y position error + * @param zErr z position error + * @param rollErr roll error (radians) + * @param pitchErr pitch error (radians) + * @param yawErr yaw error (radians) + * @param vxErr x velocity + * @param vyErr y velocity + * @param vzErr z velocity + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_state_correction_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + float xErr, float yErr, float zErr, float rollErr, float pitchErr, float yawErr, float vxErr, float vyErr, float vzErr) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[36]; + _mav_put_float(buf, 0, xErr); + _mav_put_float(buf, 4, yErr); + _mav_put_float(buf, 8, zErr); + _mav_put_float(buf, 12, rollErr); + _mav_put_float(buf, 16, pitchErr); + _mav_put_float(buf, 20, yawErr); + _mav_put_float(buf, 24, vxErr); + _mav_put_float(buf, 28, vyErr); + _mav_put_float(buf, 32, vzErr); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 36); +#else + mavlink_state_correction_t packet; + packet.xErr = xErr; + packet.yErr = yErr; + packet.zErr = zErr; + packet.rollErr = rollErr; + packet.pitchErr = pitchErr; + packet.yawErr = yawErr; + packet.vxErr = vxErr; + packet.vyErr = vyErr; + packet.vzErr = vzErr; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 36); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_STATE_CORRECTION; + return mavlink_finalize_message(msg, system_id, component_id, 36, 130); +} + +/** + * @brief Pack a state_correction message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param xErr x position error + * @param yErr y position error + * @param zErr z position error + * @param rollErr roll error (radians) + * @param pitchErr pitch error (radians) + * @param yawErr yaw error (radians) + * @param vxErr x velocity + * @param vyErr y velocity + * @param vzErr z velocity + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_state_correction_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + float xErr, float yErr, float zErr, float rollErr, float pitchErr, float yawErr, float vxErr, float vyErr, float vzErr) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[36]; + _mav_put_float(buf, 0, xErr); + _mav_put_float(buf, 4, yErr); + _mav_put_float(buf, 8, zErr); + _mav_put_float(buf, 12, rollErr); + _mav_put_float(buf, 16, pitchErr); + _mav_put_float(buf, 20, yawErr); + _mav_put_float(buf, 24, vxErr); + _mav_put_float(buf, 28, vyErr); + _mav_put_float(buf, 32, vzErr); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 36); +#else + mavlink_state_correction_t packet; + packet.xErr = xErr; + packet.yErr = yErr; + packet.zErr = zErr; + packet.rollErr = rollErr; + packet.pitchErr = pitchErr; + packet.yawErr = yawErr; + packet.vxErr = vxErr; + packet.vyErr = vyErr; + packet.vzErr = vzErr; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 36); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_STATE_CORRECTION; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 36, 130); +} + +/** + * @brief Encode a state_correction struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param state_correction C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_state_correction_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_state_correction_t *state_correction) +{ + return mavlink_msg_state_correction_pack(system_id, component_id, msg, state_correction->xErr, state_correction->yErr, state_correction->zErr, state_correction->rollErr, state_correction->pitchErr, state_correction->yawErr, state_correction->vxErr, state_correction->vyErr, state_correction->vzErr); +} + +/** + * @brief Send a state_correction message + * @param chan MAVLink channel to send the message + * + * @param xErr x position error + * @param yErr y position error + * @param zErr z position error + * @param rollErr roll error (radians) + * @param pitchErr pitch error (radians) + * @param yawErr yaw error (radians) + * @param vxErr x velocity + * @param vyErr y velocity + * @param vzErr z velocity + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_state_correction_send(mavlink_channel_t chan, float xErr, float yErr, float zErr, float rollErr, float pitchErr, float yawErr, float vxErr, float vyErr, float vzErr) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[36]; + _mav_put_float(buf, 0, xErr); + _mav_put_float(buf, 4, yErr); + _mav_put_float(buf, 8, zErr); + _mav_put_float(buf, 12, rollErr); + _mav_put_float(buf, 16, pitchErr); + _mav_put_float(buf, 20, yawErr); + _mav_put_float(buf, 24, vxErr); + _mav_put_float(buf, 28, vyErr); + _mav_put_float(buf, 32, vzErr); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_STATE_CORRECTION, buf, 36, 130); +#else + mavlink_state_correction_t packet; + packet.xErr = xErr; + packet.yErr = yErr; + packet.zErr = zErr; + packet.rollErr = rollErr; + packet.pitchErr = pitchErr; + packet.yawErr = yawErr; + packet.vxErr = vxErr; + packet.vyErr = vyErr; + packet.vzErr = vzErr; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_STATE_CORRECTION, (const char *)&packet, 36, 130); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE STATE_CORRECTION UNPACKING + + +/** + * @brief Get field xErr from state_correction message + * + * @return x position error + */ +static inline float mavlink_msg_state_correction_get_xErr(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 0); +} + +/** + * @brief Get field yErr from state_correction message + * + * @return y position error + */ +static inline float mavlink_msg_state_correction_get_yErr(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 4); +} + +/** + * @brief Get field zErr from state_correction message + * + * @return z position error + */ +static inline float mavlink_msg_state_correction_get_zErr(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 8); +} + +/** + * @brief Get field rollErr from state_correction message + * + * @return roll error (radians) + */ +static inline float mavlink_msg_state_correction_get_rollErr(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 12); +} + +/** + * @brief Get field pitchErr from state_correction message + * + * @return pitch error (radians) + */ +static inline float mavlink_msg_state_correction_get_pitchErr(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 16); +} + +/** + * @brief Get field yawErr from state_correction message + * + * @return yaw error (radians) + */ +static inline float mavlink_msg_state_correction_get_yawErr(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 20); +} + +/** + * @brief Get field vxErr from state_correction message + * + * @return x velocity + */ +static inline float mavlink_msg_state_correction_get_vxErr(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 24); +} + +/** + * @brief Get field vyErr from state_correction message + * + * @return y velocity + */ +static inline float mavlink_msg_state_correction_get_vyErr(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 28); +} + +/** + * @brief Get field vzErr from state_correction message + * + * @return z velocity + */ +static inline float mavlink_msg_state_correction_get_vzErr(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 32); +} + +/** + * @brief Decode a state_correction message into a struct + * + * @param msg The message to decode + * @param state_correction C-struct to decode the message contents into + */ +static inline void mavlink_msg_state_correction_decode(const mavlink_message_t *msg, mavlink_state_correction_t *state_correction) +{ +#if MAVLINK_NEED_BYTE_SWAP + state_correction->xErr = mavlink_msg_state_correction_get_xErr(msg); + state_correction->yErr = mavlink_msg_state_correction_get_yErr(msg); + state_correction->zErr = mavlink_msg_state_correction_get_zErr(msg); + state_correction->rollErr = mavlink_msg_state_correction_get_rollErr(msg); + state_correction->pitchErr = mavlink_msg_state_correction_get_pitchErr(msg); + state_correction->yawErr = mavlink_msg_state_correction_get_yawErr(msg); + state_correction->vxErr = mavlink_msg_state_correction_get_vxErr(msg); + state_correction->vyErr = mavlink_msg_state_correction_get_vyErr(msg); + state_correction->vzErr = mavlink_msg_state_correction_get_vzErr(msg); +#else + memcpy(state_correction, _MAV_PAYLOAD(msg), 36); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_statustext.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_statustext.h new file mode 100644 index 000000000..b75669d35 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_statustext.h @@ -0,0 +1,161 @@ +// MESSAGE STATUSTEXT PACKING + +#define MAVLINK_MSG_ID_STATUSTEXT 253 + +typedef struct __mavlink_statustext_t { + uint8_t severity; ///< Severity of status. Relies on the definitions within RFC-5424. See enum MAV_SEVERITY. + char text[50]; ///< Status text message, without null termination character +} mavlink_statustext_t; + +#define MAVLINK_MSG_ID_STATUSTEXT_LEN 51 +#define MAVLINK_MSG_ID_253_LEN 51 + +#define MAVLINK_MSG_STATUSTEXT_FIELD_TEXT_LEN 50 + +#define MAVLINK_MESSAGE_INFO_STATUSTEXT \ + { \ + "STATUSTEXT", \ + 2, \ + { \ + { "severity", NULL, MAVLINK_TYPE_UINT8_T, 0, 0, offsetof(mavlink_statustext_t, severity) }, \ + { "text", NULL, MAVLINK_TYPE_CHAR, 50, 1, offsetof(mavlink_statustext_t, text) }, \ + } \ + } + + +/** + * @brief Pack a statustext message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param severity Severity of status. Relies on the definitions within RFC-5424. See enum MAV_SEVERITY. + * @param text Status text message, without null termination character + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_statustext_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint8_t severity, const char *text) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[51]; + _mav_put_uint8_t(buf, 0, severity); + _mav_put_char_array(buf, 1, text, 50); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 51); +#else + mavlink_statustext_t packet; + packet.severity = severity; + mav_array_memcpy(packet.text, text, sizeof(char) * 50); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 51); +#endif + + msg->msgid = MAVLINK_MSG_ID_STATUSTEXT; + return mavlink_finalize_message(msg, system_id, component_id, 51, 83); +} + +/** + * @brief Pack a statustext message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param severity Severity of status. Relies on the definitions within RFC-5424. See enum MAV_SEVERITY. + * @param text Status text message, without null termination character + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_statustext_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint8_t severity, const char *text) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[51]; + _mav_put_uint8_t(buf, 0, severity); + _mav_put_char_array(buf, 1, text, 50); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 51); +#else + mavlink_statustext_t packet; + packet.severity = severity; + mav_array_memcpy(packet.text, text, sizeof(char) * 50); + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 51); +#endif + + msg->msgid = MAVLINK_MSG_ID_STATUSTEXT; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 51, 83); +} + +/** + * @brief Encode a statustext struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param statustext C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_statustext_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_statustext_t *statustext) +{ + return mavlink_msg_statustext_pack(system_id, component_id, msg, statustext->severity, statustext->text); +} + +/** + * @brief Send a statustext message + * @param chan MAVLink channel to send the message + * + * @param severity Severity of status. Relies on the definitions within RFC-5424. See enum MAV_SEVERITY. + * @param text Status text message, without null termination character + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_statustext_send(mavlink_channel_t chan, uint8_t severity, const char *text) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[51]; + _mav_put_uint8_t(buf, 0, severity); + _mav_put_char_array(buf, 1, text, 50); + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_STATUSTEXT, buf, 51, 83); +#else + mavlink_statustext_t packet; + packet.severity = severity; + mav_array_memcpy(packet.text, text, sizeof(char) * 50); + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_STATUSTEXT, (const char *)&packet, 51, 83); +#endif +} + +#endif + +// MESSAGE STATUSTEXT UNPACKING + + +/** + * @brief Get field severity from statustext message + * + * @return Severity of status. Relies on the definitions within RFC-5424. See enum MAV_SEVERITY. + */ +static inline uint8_t mavlink_msg_statustext_get_severity(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint8_t(msg, 0); +} + +/** + * @brief Get field text from statustext message + * + * @return Status text message, without null termination character + */ +static inline uint16_t mavlink_msg_statustext_get_text(const mavlink_message_t *msg, char *text) +{ + return _MAV_RETURN_char_array(msg, text, 50, 1); +} + +/** + * @brief Decode a statustext message into a struct + * + * @param msg The message to decode + * @param statustext C-struct to decode the message contents into + */ +static inline void mavlink_msg_statustext_decode(const mavlink_message_t *msg, mavlink_statustext_t *statustext) +{ +#if MAVLINK_NEED_BYTE_SWAP + statustext->severity = mavlink_msg_statustext_get_severity(msg); + mavlink_msg_statustext_get_text(msg, statustext->text); +#else + memcpy(statustext, _MAV_PAYLOAD(msg), 51); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_sys_status.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_sys_status.h new file mode 100644 index 000000000..481475749 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_sys_status.h @@ -0,0 +1,408 @@ +// MESSAGE SYS_STATUS PACKING + +#define MAVLINK_MSG_ID_SYS_STATUS 1 + +typedef struct __mavlink_sys_status_t { + uint32_t onboard_control_sensors_present; ///< Bitmask showing which onboard controllers and sensors are present. Value of 0: not present. Value of 1: present. Indices: 0: 3D gyro, 1: 3D acc, 2: 3D mag, 3: absolute pressure, 4: differential pressure, 5: GPS, 6: optical flow, 7: computer vision position, 8: laser based position, 9: external ground-truth (Vicon or Leica). Controllers: 10: 3D angular rate control 11: attitude stabilization, 12: yaw position, 13: z/altitude control, 14: x/y position control, 15: motor outputs / control + uint32_t onboard_control_sensors_enabled; ///< Bitmask showing which onboard controllers and sensors are enabled: Value of 0: not enabled. Value of 1: enabled. Indices: 0: 3D gyro, 1: 3D acc, 2: 3D mag, 3: absolute pressure, 4: differential pressure, 5: GPS, 6: optical flow, 7: computer vision position, 8: laser based position, 9: external ground-truth (Vicon or Leica). Controllers: 10: 3D angular rate control 11: attitude stabilization, 12: yaw position, 13: z/altitude control, 14: x/y position control, 15: motor outputs / control + uint32_t onboard_control_sensors_health; ///< Bitmask showing which onboard controllers and sensors are operational or have an error: Value of 0: not enabled. Value of 1: enabled. Indices: 0: 3D gyro, 1: 3D acc, 2: 3D mag, 3: absolute pressure, 4: differential pressure, 5: GPS, 6: optical flow, 7: computer vision position, 8: laser based position, 9: external ground-truth (Vicon or Leica). Controllers: 10: 3D angular rate control 11: attitude stabilization, 12: yaw position, 13: z/altitude control, 14: x/y position control, 15: motor outputs / control + uint16_t load; ///< Maximum usage in percent of the mainloop time, (0%: 0, 100%: 1000) should be always below 1000 + uint16_t voltage_battery; ///< Battery voltage, in millivolts (1 = 1 millivolt) + int16_t current_battery; ///< Battery current, in 10*milliamperes (1 = 10 milliampere), -1: autopilot does not measure the current + uint16_t drop_rate_comm; ///< Communication drops in percent, (0%: 0, 100%: 10'000), (UART, I2C, SPI, CAN), dropped packets on all links (packets that were corrupted on reception on the MAV) + uint16_t errors_comm; ///< Communication errors (UART, I2C, SPI, CAN), dropped packets on all links (packets that were corrupted on reception on the MAV) + uint16_t errors_count1; ///< Autopilot-specific errors + uint16_t errors_count2; ///< Autopilot-specific errors + uint16_t errors_count3; ///< Autopilot-specific errors + uint16_t errors_count4; ///< Autopilot-specific errors + int8_t battery_remaining; ///< Remaining battery energy: (0%: 0, 100%: 100), -1: autopilot estimate the remaining battery +} mavlink_sys_status_t; + +#define MAVLINK_MSG_ID_SYS_STATUS_LEN 31 +#define MAVLINK_MSG_ID_1_LEN 31 + + +#define MAVLINK_MESSAGE_INFO_SYS_STATUS \ + { \ + "SYS_STATUS", \ + 13, \ + { \ + { "onboard_control_sensors_present", "0x%04x", MAVLINK_TYPE_UINT32_T, 0, 0, offsetof(mavlink_sys_status_t, onboard_control_sensors_present) }, \ + { "onboard_control_sensors_enabled", "0x%04x", MAVLINK_TYPE_UINT32_T, 0, 4, offsetof(mavlink_sys_status_t, onboard_control_sensors_enabled) }, \ + { "onboard_control_sensors_health", "0x%04x", MAVLINK_TYPE_UINT32_T, 0, 8, offsetof(mavlink_sys_status_t, onboard_control_sensors_health) }, \ + { "load", NULL, MAVLINK_TYPE_UINT16_T, 0, 12, offsetof(mavlink_sys_status_t, load) }, \ + { "voltage_battery", NULL, MAVLINK_TYPE_UINT16_T, 0, 14, offsetof(mavlink_sys_status_t, voltage_battery) }, \ + { "current_battery", NULL, MAVLINK_TYPE_INT16_T, 0, 16, offsetof(mavlink_sys_status_t, current_battery) }, \ + { "drop_rate_comm", NULL, MAVLINK_TYPE_UINT16_T, 0, 18, offsetof(mavlink_sys_status_t, drop_rate_comm) }, \ + { "errors_comm", NULL, MAVLINK_TYPE_UINT16_T, 0, 20, offsetof(mavlink_sys_status_t, errors_comm) }, \ + { "errors_count1", NULL, MAVLINK_TYPE_UINT16_T, 0, 22, offsetof(mavlink_sys_status_t, errors_count1) }, \ + { "errors_count2", NULL, MAVLINK_TYPE_UINT16_T, 0, 24, offsetof(mavlink_sys_status_t, errors_count2) }, \ + { "errors_count3", NULL, MAVLINK_TYPE_UINT16_T, 0, 26, offsetof(mavlink_sys_status_t, errors_count3) }, \ + { "errors_count4", NULL, MAVLINK_TYPE_UINT16_T, 0, 28, offsetof(mavlink_sys_status_t, errors_count4) }, \ + { "battery_remaining", NULL, MAVLINK_TYPE_INT8_T, 0, 30, offsetof(mavlink_sys_status_t, battery_remaining) }, \ + } \ + } + + +/** + * @brief Pack a sys_status message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param onboard_control_sensors_present Bitmask showing which onboard controllers and sensors are present. Value of 0: not present. Value of 1: present. Indices: 0: 3D gyro, 1: 3D acc, 2: 3D mag, 3: absolute pressure, 4: differential pressure, 5: GPS, 6: optical flow, 7: computer vision position, 8: laser based position, 9: external ground-truth (Vicon or Leica). Controllers: 10: 3D angular rate control 11: attitude stabilization, 12: yaw position, 13: z/altitude control, 14: x/y position control, 15: motor outputs / control + * @param onboard_control_sensors_enabled Bitmask showing which onboard controllers and sensors are enabled: Value of 0: not enabled. Value of 1: enabled. Indices: 0: 3D gyro, 1: 3D acc, 2: 3D mag, 3: absolute pressure, 4: differential pressure, 5: GPS, 6: optical flow, 7: computer vision position, 8: laser based position, 9: external ground-truth (Vicon or Leica). Controllers: 10: 3D angular rate control 11: attitude stabilization, 12: yaw position, 13: z/altitude control, 14: x/y position control, 15: motor outputs / control + * @param onboard_control_sensors_health Bitmask showing which onboard controllers and sensors are operational or have an error: Value of 0: not enabled. Value of 1: enabled. Indices: 0: 3D gyro, 1: 3D acc, 2: 3D mag, 3: absolute pressure, 4: differential pressure, 5: GPS, 6: optical flow, 7: computer vision position, 8: laser based position, 9: external ground-truth (Vicon or Leica). Controllers: 10: 3D angular rate control 11: attitude stabilization, 12: yaw position, 13: z/altitude control, 14: x/y position control, 15: motor outputs / control + * @param load Maximum usage in percent of the mainloop time, (0%: 0, 100%: 1000) should be always below 1000 + * @param voltage_battery Battery voltage, in millivolts (1 = 1 millivolt) + * @param current_battery Battery current, in 10*milliamperes (1 = 10 milliampere), -1: autopilot does not measure the current + * @param battery_remaining Remaining battery energy: (0%: 0, 100%: 100), -1: autopilot estimate the remaining battery + * @param drop_rate_comm Communication drops in percent, (0%: 0, 100%: 10'000), (UART, I2C, SPI, CAN), dropped packets on all links (packets that were corrupted on reception on the MAV) + * @param errors_comm Communication errors (UART, I2C, SPI, CAN), dropped packets on all links (packets that were corrupted on reception on the MAV) + * @param errors_count1 Autopilot-specific errors + * @param errors_count2 Autopilot-specific errors + * @param errors_count3 Autopilot-specific errors + * @param errors_count4 Autopilot-specific errors + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_sys_status_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint32_t onboard_control_sensors_present, uint32_t onboard_control_sensors_enabled, uint32_t onboard_control_sensors_health, uint16_t load, uint16_t voltage_battery, int16_t current_battery, int8_t battery_remaining, uint16_t drop_rate_comm, uint16_t errors_comm, uint16_t errors_count1, uint16_t errors_count2, uint16_t errors_count3, uint16_t errors_count4) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[31]; + _mav_put_uint32_t(buf, 0, onboard_control_sensors_present); + _mav_put_uint32_t(buf, 4, onboard_control_sensors_enabled); + _mav_put_uint32_t(buf, 8, onboard_control_sensors_health); + _mav_put_uint16_t(buf, 12, load); + _mav_put_uint16_t(buf, 14, voltage_battery); + _mav_put_int16_t(buf, 16, current_battery); + _mav_put_uint16_t(buf, 18, drop_rate_comm); + _mav_put_uint16_t(buf, 20, errors_comm); + _mav_put_uint16_t(buf, 22, errors_count1); + _mav_put_uint16_t(buf, 24, errors_count2); + _mav_put_uint16_t(buf, 26, errors_count3); + _mav_put_uint16_t(buf, 28, errors_count4); + _mav_put_int8_t(buf, 30, battery_remaining); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 31); +#else + mavlink_sys_status_t packet; + packet.onboard_control_sensors_present = onboard_control_sensors_present; + packet.onboard_control_sensors_enabled = onboard_control_sensors_enabled; + packet.onboard_control_sensors_health = onboard_control_sensors_health; + packet.load = load; + packet.voltage_battery = voltage_battery; + packet.current_battery = current_battery; + packet.drop_rate_comm = drop_rate_comm; + packet.errors_comm = errors_comm; + packet.errors_count1 = errors_count1; + packet.errors_count2 = errors_count2; + packet.errors_count3 = errors_count3; + packet.errors_count4 = errors_count4; + packet.battery_remaining = battery_remaining; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 31); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_SYS_STATUS; + return mavlink_finalize_message(msg, system_id, component_id, 31, 124); +} + +/** + * @brief Pack a sys_status message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param onboard_control_sensors_present Bitmask showing which onboard controllers and sensors are present. Value of 0: not present. Value of 1: present. Indices: 0: 3D gyro, 1: 3D acc, 2: 3D mag, 3: absolute pressure, 4: differential pressure, 5: GPS, 6: optical flow, 7: computer vision position, 8: laser based position, 9: external ground-truth (Vicon or Leica). Controllers: 10: 3D angular rate control 11: attitude stabilization, 12: yaw position, 13: z/altitude control, 14: x/y position control, 15: motor outputs / control + * @param onboard_control_sensors_enabled Bitmask showing which onboard controllers and sensors are enabled: Value of 0: not enabled. Value of 1: enabled. Indices: 0: 3D gyro, 1: 3D acc, 2: 3D mag, 3: absolute pressure, 4: differential pressure, 5: GPS, 6: optical flow, 7: computer vision position, 8: laser based position, 9: external ground-truth (Vicon or Leica). Controllers: 10: 3D angular rate control 11: attitude stabilization, 12: yaw position, 13: z/altitude control, 14: x/y position control, 15: motor outputs / control + * @param onboard_control_sensors_health Bitmask showing which onboard controllers and sensors are operational or have an error: Value of 0: not enabled. Value of 1: enabled. Indices: 0: 3D gyro, 1: 3D acc, 2: 3D mag, 3: absolute pressure, 4: differential pressure, 5: GPS, 6: optical flow, 7: computer vision position, 8: laser based position, 9: external ground-truth (Vicon or Leica). Controllers: 10: 3D angular rate control 11: attitude stabilization, 12: yaw position, 13: z/altitude control, 14: x/y position control, 15: motor outputs / control + * @param load Maximum usage in percent of the mainloop time, (0%: 0, 100%: 1000) should be always below 1000 + * @param voltage_battery Battery voltage, in millivolts (1 = 1 millivolt) + * @param current_battery Battery current, in 10*milliamperes (1 = 10 milliampere), -1: autopilot does not measure the current + * @param battery_remaining Remaining battery energy: (0%: 0, 100%: 100), -1: autopilot estimate the remaining battery + * @param drop_rate_comm Communication drops in percent, (0%: 0, 100%: 10'000), (UART, I2C, SPI, CAN), dropped packets on all links (packets that were corrupted on reception on the MAV) + * @param errors_comm Communication errors (UART, I2C, SPI, CAN), dropped packets on all links (packets that were corrupted on reception on the MAV) + * @param errors_count1 Autopilot-specific errors + * @param errors_count2 Autopilot-specific errors + * @param errors_count3 Autopilot-specific errors + * @param errors_count4 Autopilot-specific errors + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_sys_status_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint32_t onboard_control_sensors_present, uint32_t onboard_control_sensors_enabled, uint32_t onboard_control_sensors_health, uint16_t load, uint16_t voltage_battery, int16_t current_battery, int8_t battery_remaining, uint16_t drop_rate_comm, uint16_t errors_comm, uint16_t errors_count1, uint16_t errors_count2, uint16_t errors_count3, uint16_t errors_count4) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[31]; + _mav_put_uint32_t(buf, 0, onboard_control_sensors_present); + _mav_put_uint32_t(buf, 4, onboard_control_sensors_enabled); + _mav_put_uint32_t(buf, 8, onboard_control_sensors_health); + _mav_put_uint16_t(buf, 12, load); + _mav_put_uint16_t(buf, 14, voltage_battery); + _mav_put_int16_t(buf, 16, current_battery); + _mav_put_uint16_t(buf, 18, drop_rate_comm); + _mav_put_uint16_t(buf, 20, errors_comm); + _mav_put_uint16_t(buf, 22, errors_count1); + _mav_put_uint16_t(buf, 24, errors_count2); + _mav_put_uint16_t(buf, 26, errors_count3); + _mav_put_uint16_t(buf, 28, errors_count4); + _mav_put_int8_t(buf, 30, battery_remaining); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 31); +#else + mavlink_sys_status_t packet; + packet.onboard_control_sensors_present = onboard_control_sensors_present; + packet.onboard_control_sensors_enabled = onboard_control_sensors_enabled; + packet.onboard_control_sensors_health = onboard_control_sensors_health; + packet.load = load; + packet.voltage_battery = voltage_battery; + packet.current_battery = current_battery; + packet.drop_rate_comm = drop_rate_comm; + packet.errors_comm = errors_comm; + packet.errors_count1 = errors_count1; + packet.errors_count2 = errors_count2; + packet.errors_count3 = errors_count3; + packet.errors_count4 = errors_count4; + packet.battery_remaining = battery_remaining; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 31); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_SYS_STATUS; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 31, 124); +} + +/** + * @brief Encode a sys_status struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param sys_status C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_sys_status_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_sys_status_t *sys_status) +{ + return mavlink_msg_sys_status_pack(system_id, component_id, msg, sys_status->onboard_control_sensors_present, sys_status->onboard_control_sensors_enabled, sys_status->onboard_control_sensors_health, sys_status->load, sys_status->voltage_battery, sys_status->current_battery, sys_status->battery_remaining, sys_status->drop_rate_comm, sys_status->errors_comm, sys_status->errors_count1, sys_status->errors_count2, sys_status->errors_count3, sys_status->errors_count4); +} + +/** + * @brief Send a sys_status message + * @param chan MAVLink channel to send the message + * + * @param onboard_control_sensors_present Bitmask showing which onboard controllers and sensors are present. Value of 0: not present. Value of 1: present. Indices: 0: 3D gyro, 1: 3D acc, 2: 3D mag, 3: absolute pressure, 4: differential pressure, 5: GPS, 6: optical flow, 7: computer vision position, 8: laser based position, 9: external ground-truth (Vicon or Leica). Controllers: 10: 3D angular rate control 11: attitude stabilization, 12: yaw position, 13: z/altitude control, 14: x/y position control, 15: motor outputs / control + * @param onboard_control_sensors_enabled Bitmask showing which onboard controllers and sensors are enabled: Value of 0: not enabled. Value of 1: enabled. Indices: 0: 3D gyro, 1: 3D acc, 2: 3D mag, 3: absolute pressure, 4: differential pressure, 5: GPS, 6: optical flow, 7: computer vision position, 8: laser based position, 9: external ground-truth (Vicon or Leica). Controllers: 10: 3D angular rate control 11: attitude stabilization, 12: yaw position, 13: z/altitude control, 14: x/y position control, 15: motor outputs / control + * @param onboard_control_sensors_health Bitmask showing which onboard controllers and sensors are operational or have an error: Value of 0: not enabled. Value of 1: enabled. Indices: 0: 3D gyro, 1: 3D acc, 2: 3D mag, 3: absolute pressure, 4: differential pressure, 5: GPS, 6: optical flow, 7: computer vision position, 8: laser based position, 9: external ground-truth (Vicon or Leica). Controllers: 10: 3D angular rate control 11: attitude stabilization, 12: yaw position, 13: z/altitude control, 14: x/y position control, 15: motor outputs / control + * @param load Maximum usage in percent of the mainloop time, (0%: 0, 100%: 1000) should be always below 1000 + * @param voltage_battery Battery voltage, in millivolts (1 = 1 millivolt) + * @param current_battery Battery current, in 10*milliamperes (1 = 10 milliampere), -1: autopilot does not measure the current + * @param battery_remaining Remaining battery energy: (0%: 0, 100%: 100), -1: autopilot estimate the remaining battery + * @param drop_rate_comm Communication drops in percent, (0%: 0, 100%: 10'000), (UART, I2C, SPI, CAN), dropped packets on all links (packets that were corrupted on reception on the MAV) + * @param errors_comm Communication errors (UART, I2C, SPI, CAN), dropped packets on all links (packets that were corrupted on reception on the MAV) + * @param errors_count1 Autopilot-specific errors + * @param errors_count2 Autopilot-specific errors + * @param errors_count3 Autopilot-specific errors + * @param errors_count4 Autopilot-specific errors + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_sys_status_send(mavlink_channel_t chan, uint32_t onboard_control_sensors_present, uint32_t onboard_control_sensors_enabled, uint32_t onboard_control_sensors_health, uint16_t load, uint16_t voltage_battery, int16_t current_battery, int8_t battery_remaining, uint16_t drop_rate_comm, uint16_t errors_comm, uint16_t errors_count1, uint16_t errors_count2, uint16_t errors_count3, uint16_t errors_count4) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[31]; + _mav_put_uint32_t(buf, 0, onboard_control_sensors_present); + _mav_put_uint32_t(buf, 4, onboard_control_sensors_enabled); + _mav_put_uint32_t(buf, 8, onboard_control_sensors_health); + _mav_put_uint16_t(buf, 12, load); + _mav_put_uint16_t(buf, 14, voltage_battery); + _mav_put_int16_t(buf, 16, current_battery); + _mav_put_uint16_t(buf, 18, drop_rate_comm); + _mav_put_uint16_t(buf, 20, errors_comm); + _mav_put_uint16_t(buf, 22, errors_count1); + _mav_put_uint16_t(buf, 24, errors_count2); + _mav_put_uint16_t(buf, 26, errors_count3); + _mav_put_uint16_t(buf, 28, errors_count4); + _mav_put_int8_t(buf, 30, battery_remaining); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SYS_STATUS, buf, 31, 124); +#else + mavlink_sys_status_t packet; + packet.onboard_control_sensors_present = onboard_control_sensors_present; + packet.onboard_control_sensors_enabled = onboard_control_sensors_enabled; + packet.onboard_control_sensors_health = onboard_control_sensors_health; + packet.load = load; + packet.voltage_battery = voltage_battery; + packet.current_battery = current_battery; + packet.drop_rate_comm = drop_rate_comm; + packet.errors_comm = errors_comm; + packet.errors_count1 = errors_count1; + packet.errors_count2 = errors_count2; + packet.errors_count3 = errors_count3; + packet.errors_count4 = errors_count4; + packet.battery_remaining = battery_remaining; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SYS_STATUS, (const char *)&packet, 31, 124); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE SYS_STATUS UNPACKING + + +/** + * @brief Get field onboard_control_sensors_present from sys_status message + * + * @return Bitmask showing which onboard controllers and sensors are present. Value of 0: not present. Value of 1: present. Indices: 0: 3D gyro, 1: 3D acc, 2: 3D mag, 3: absolute pressure, 4: differential pressure, 5: GPS, 6: optical flow, 7: computer vision position, 8: laser based position, 9: external ground-truth (Vicon or Leica). Controllers: 10: 3D angular rate control 11: attitude stabilization, 12: yaw position, 13: z/altitude control, 14: x/y position control, 15: motor outputs / control + */ +static inline uint32_t mavlink_msg_sys_status_get_onboard_control_sensors_present(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint32_t(msg, 0); +} + +/** + * @brief Get field onboard_control_sensors_enabled from sys_status message + * + * @return Bitmask showing which onboard controllers and sensors are enabled: Value of 0: not enabled. Value of 1: enabled. Indices: 0: 3D gyro, 1: 3D acc, 2: 3D mag, 3: absolute pressure, 4: differential pressure, 5: GPS, 6: optical flow, 7: computer vision position, 8: laser based position, 9: external ground-truth (Vicon or Leica). Controllers: 10: 3D angular rate control 11: attitude stabilization, 12: yaw position, 13: z/altitude control, 14: x/y position control, 15: motor outputs / control + */ +static inline uint32_t mavlink_msg_sys_status_get_onboard_control_sensors_enabled(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint32_t(msg, 4); +} + +/** + * @brief Get field onboard_control_sensors_health from sys_status message + * + * @return Bitmask showing which onboard controllers and sensors are operational or have an error: Value of 0: not enabled. Value of 1: enabled. Indices: 0: 3D gyro, 1: 3D acc, 2: 3D mag, 3: absolute pressure, 4: differential pressure, 5: GPS, 6: optical flow, 7: computer vision position, 8: laser based position, 9: external ground-truth (Vicon or Leica). Controllers: 10: 3D angular rate control 11: attitude stabilization, 12: yaw position, 13: z/altitude control, 14: x/y position control, 15: motor outputs / control + */ +static inline uint32_t mavlink_msg_sys_status_get_onboard_control_sensors_health(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint32_t(msg, 8); +} + +/** + * @brief Get field load from sys_status message + * + * @return Maximum usage in percent of the mainloop time, (0%: 0, 100%: 1000) should be always below 1000 + */ +static inline uint16_t mavlink_msg_sys_status_get_load(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 12); +} + +/** + * @brief Get field voltage_battery from sys_status message + * + * @return Battery voltage, in millivolts (1 = 1 millivolt) + */ +static inline uint16_t mavlink_msg_sys_status_get_voltage_battery(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 14); +} + +/** + * @brief Get field current_battery from sys_status message + * + * @return Battery current, in 10*milliamperes (1 = 10 milliampere), -1: autopilot does not measure the current + */ +static inline int16_t mavlink_msg_sys_status_get_current_battery(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 16); +} + +/** + * @brief Get field battery_remaining from sys_status message + * + * @return Remaining battery energy: (0%: 0, 100%: 100), -1: autopilot estimate the remaining battery + */ +static inline int8_t mavlink_msg_sys_status_get_battery_remaining(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int8_t(msg, 30); +} + +/** + * @brief Get field drop_rate_comm from sys_status message + * + * @return Communication drops in percent, (0%: 0, 100%: 10'000), (UART, I2C, SPI, CAN), dropped packets on all links (packets that were corrupted on reception on the MAV) + */ +static inline uint16_t mavlink_msg_sys_status_get_drop_rate_comm(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 18); +} + +/** + * @brief Get field errors_comm from sys_status message + * + * @return Communication errors (UART, I2C, SPI, CAN), dropped packets on all links (packets that were corrupted on reception on the MAV) + */ +static inline uint16_t mavlink_msg_sys_status_get_errors_comm(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 20); +} + +/** + * @brief Get field errors_count1 from sys_status message + * + * @return Autopilot-specific errors + */ +static inline uint16_t mavlink_msg_sys_status_get_errors_count1(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 22); +} + +/** + * @brief Get field errors_count2 from sys_status message + * + * @return Autopilot-specific errors + */ +static inline uint16_t mavlink_msg_sys_status_get_errors_count2(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 24); +} + +/** + * @brief Get field errors_count3 from sys_status message + * + * @return Autopilot-specific errors + */ +static inline uint16_t mavlink_msg_sys_status_get_errors_count3(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 26); +} + +/** + * @brief Get field errors_count4 from sys_status message + * + * @return Autopilot-specific errors + */ +static inline uint16_t mavlink_msg_sys_status_get_errors_count4(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 28); +} + +/** + * @brief Decode a sys_status message into a struct + * + * @param msg The message to decode + * @param sys_status C-struct to decode the message contents into + */ +static inline void mavlink_msg_sys_status_decode(const mavlink_message_t *msg, mavlink_sys_status_t *sys_status) +{ +#if MAVLINK_NEED_BYTE_SWAP + sys_status->onboard_control_sensors_present = mavlink_msg_sys_status_get_onboard_control_sensors_present(msg); + sys_status->onboard_control_sensors_enabled = mavlink_msg_sys_status_get_onboard_control_sensors_enabled(msg); + sys_status->onboard_control_sensors_health = mavlink_msg_sys_status_get_onboard_control_sensors_health(msg); + sys_status->load = mavlink_msg_sys_status_get_load(msg); + sys_status->voltage_battery = mavlink_msg_sys_status_get_voltage_battery(msg); + sys_status->current_battery = mavlink_msg_sys_status_get_current_battery(msg); + sys_status->drop_rate_comm = mavlink_msg_sys_status_get_drop_rate_comm(msg); + sys_status->errors_comm = mavlink_msg_sys_status_get_errors_comm(msg); + sys_status->errors_count1 = mavlink_msg_sys_status_get_errors_count1(msg); + sys_status->errors_count2 = mavlink_msg_sys_status_get_errors_count2(msg); + sys_status->errors_count3 = mavlink_msg_sys_status_get_errors_count3(msg); + sys_status->errors_count4 = mavlink_msg_sys_status_get_errors_count4(msg); + sys_status->battery_remaining = mavlink_msg_sys_status_get_battery_remaining(msg); +#else + memcpy(sys_status, _MAV_PAYLOAD(msg), 31); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_system_time.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_system_time.h new file mode 100644 index 000000000..cf213773b --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_system_time.h @@ -0,0 +1,166 @@ +// MESSAGE SYSTEM_TIME PACKING + +#define MAVLINK_MSG_ID_SYSTEM_TIME 2 + +typedef struct __mavlink_system_time_t { + uint64_t time_unix_usec; ///< Timestamp of the master clock in microseconds since UNIX epoch. + uint32_t time_boot_ms; ///< Timestamp of the component clock since boot time in milliseconds. +} mavlink_system_time_t; + +#define MAVLINK_MSG_ID_SYSTEM_TIME_LEN 12 +#define MAVLINK_MSG_ID_2_LEN 12 + + +#define MAVLINK_MESSAGE_INFO_SYSTEM_TIME \ + { \ + "SYSTEM_TIME", \ + 2, \ + { \ + { "time_unix_usec", NULL, MAVLINK_TYPE_UINT64_T, 0, 0, offsetof(mavlink_system_time_t, time_unix_usec) }, \ + { "time_boot_ms", NULL, MAVLINK_TYPE_UINT32_T, 0, 8, offsetof(mavlink_system_time_t, time_boot_ms) }, \ + } \ + } + + +/** + * @brief Pack a system_time message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param time_unix_usec Timestamp of the master clock in microseconds since UNIX epoch. + * @param time_boot_ms Timestamp of the component clock since boot time in milliseconds. + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_system_time_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint64_t time_unix_usec, uint32_t time_boot_ms) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[12]; + _mav_put_uint64_t(buf, 0, time_unix_usec); + _mav_put_uint32_t(buf, 8, time_boot_ms); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 12); +#else + mavlink_system_time_t packet; + packet.time_unix_usec = time_unix_usec; + packet.time_boot_ms = time_boot_ms; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 12); +#endif + + msg->msgid = MAVLINK_MSG_ID_SYSTEM_TIME; + return mavlink_finalize_message(msg, system_id, component_id, 12, 137); +} + +/** + * @brief Pack a system_time message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param time_unix_usec Timestamp of the master clock in microseconds since UNIX epoch. + * @param time_boot_ms Timestamp of the component clock since boot time in milliseconds. + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_system_time_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint64_t time_unix_usec, uint32_t time_boot_ms) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[12]; + _mav_put_uint64_t(buf, 0, time_unix_usec); + _mav_put_uint32_t(buf, 8, time_boot_ms); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 12); +#else + mavlink_system_time_t packet; + packet.time_unix_usec = time_unix_usec; + packet.time_boot_ms = time_boot_ms; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 12); +#endif + + msg->msgid = MAVLINK_MSG_ID_SYSTEM_TIME; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 12, 137); +} + +/** + * @brief Encode a system_time struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param system_time C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_system_time_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_system_time_t *system_time) +{ + return mavlink_msg_system_time_pack(system_id, component_id, msg, system_time->time_unix_usec, system_time->time_boot_ms); +} + +/** + * @brief Send a system_time message + * @param chan MAVLink channel to send the message + * + * @param time_unix_usec Timestamp of the master clock in microseconds since UNIX epoch. + * @param time_boot_ms Timestamp of the component clock since boot time in milliseconds. + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_system_time_send(mavlink_channel_t chan, uint64_t time_unix_usec, uint32_t time_boot_ms) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[12]; + _mav_put_uint64_t(buf, 0, time_unix_usec); + _mav_put_uint32_t(buf, 8, time_boot_ms); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SYSTEM_TIME, buf, 12, 137); +#else + mavlink_system_time_t packet; + packet.time_unix_usec = time_unix_usec; + packet.time_boot_ms = time_boot_ms; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_SYSTEM_TIME, (const char *)&packet, 12, 137); +#endif +} + +#endif + +// MESSAGE SYSTEM_TIME UNPACKING + + +/** + * @brief Get field time_unix_usec from system_time message + * + * @return Timestamp of the master clock in microseconds since UNIX epoch. + */ +static inline uint64_t mavlink_msg_system_time_get_time_unix_usec(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint64_t(msg, 0); +} + +/** + * @brief Get field time_boot_ms from system_time message + * + * @return Timestamp of the component clock since boot time in milliseconds. + */ +static inline uint32_t mavlink_msg_system_time_get_time_boot_ms(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint32_t(msg, 8); +} + +/** + * @brief Decode a system_time message into a struct + * + * @param msg The message to decode + * @param system_time C-struct to decode the message contents into + */ +static inline void mavlink_msg_system_time_decode(const mavlink_message_t *msg, mavlink_system_time_t *system_time) +{ +#if MAVLINK_NEED_BYTE_SWAP + system_time->time_unix_usec = mavlink_msg_system_time_get_time_unix_usec(msg); + system_time->time_boot_ms = mavlink_msg_system_time_get_time_boot_ms(msg); +#else + memcpy(system_time, _MAV_PAYLOAD(msg), 12); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_vfr_hud.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_vfr_hud.h new file mode 100644 index 000000000..918445424 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_vfr_hud.h @@ -0,0 +1,254 @@ +// MESSAGE VFR_HUD PACKING + +#define MAVLINK_MSG_ID_VFR_HUD 74 + +typedef struct __mavlink_vfr_hud_t { + float airspeed; ///< Current airspeed in m/s + float groundspeed; ///< Current ground speed in m/s + float alt; ///< Current altitude (MSL), in meters + float climb; ///< Current climb rate in meters/second + int16_t heading; ///< Current heading in degrees, in compass units (0..360, 0=north) + uint16_t throttle; ///< Current throttle setting in integer percent, 0 to 100 +} mavlink_vfr_hud_t; + +#define MAVLINK_MSG_ID_VFR_HUD_LEN 20 +#define MAVLINK_MSG_ID_74_LEN 20 + + +#define MAVLINK_MESSAGE_INFO_VFR_HUD \ + { \ + "VFR_HUD", \ + 6, \ + { \ + { "airspeed", NULL, MAVLINK_TYPE_FLOAT, 0, 0, offsetof(mavlink_vfr_hud_t, airspeed) }, \ + { "groundspeed", NULL, MAVLINK_TYPE_FLOAT, 0, 4, offsetof(mavlink_vfr_hud_t, groundspeed) }, \ + { "alt", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_vfr_hud_t, alt) }, \ + { "climb", NULL, MAVLINK_TYPE_FLOAT, 0, 12, offsetof(mavlink_vfr_hud_t, climb) }, \ + { "heading", NULL, MAVLINK_TYPE_INT16_T, 0, 16, offsetof(mavlink_vfr_hud_t, heading) }, \ + { "throttle", NULL, MAVLINK_TYPE_UINT16_T, 0, 18, offsetof(mavlink_vfr_hud_t, throttle) }, \ + } \ + } + + +/** + * @brief Pack a vfr_hud message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param airspeed Current airspeed in m/s + * @param groundspeed Current ground speed in m/s + * @param heading Current heading in degrees, in compass units (0..360, 0=north) + * @param throttle Current throttle setting in integer percent, 0 to 100 + * @param alt Current altitude (MSL), in meters + * @param climb Current climb rate in meters/second + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_vfr_hud_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + float airspeed, float groundspeed, int16_t heading, uint16_t throttle, float alt, float climb) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[20]; + _mav_put_float(buf, 0, airspeed); + _mav_put_float(buf, 4, groundspeed); + _mav_put_float(buf, 8, alt); + _mav_put_float(buf, 12, climb); + _mav_put_int16_t(buf, 16, heading); + _mav_put_uint16_t(buf, 18, throttle); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 20); +#else + mavlink_vfr_hud_t packet; + packet.airspeed = airspeed; + packet.groundspeed = groundspeed; + packet.alt = alt; + packet.climb = climb; + packet.heading = heading; + packet.throttle = throttle; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 20); +#endif + + msg->msgid = MAVLINK_MSG_ID_VFR_HUD; + return mavlink_finalize_message(msg, system_id, component_id, 20, 20); +} + +/** + * @brief Pack a vfr_hud message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param airspeed Current airspeed in m/s + * @param groundspeed Current ground speed in m/s + * @param heading Current heading in degrees, in compass units (0..360, 0=north) + * @param throttle Current throttle setting in integer percent, 0 to 100 + * @param alt Current altitude (MSL), in meters + * @param climb Current climb rate in meters/second + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_vfr_hud_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + float airspeed, float groundspeed, int16_t heading, uint16_t throttle, float alt, float climb) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[20]; + _mav_put_float(buf, 0, airspeed); + _mav_put_float(buf, 4, groundspeed); + _mav_put_float(buf, 8, alt); + _mav_put_float(buf, 12, climb); + _mav_put_int16_t(buf, 16, heading); + _mav_put_uint16_t(buf, 18, throttle); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 20); +#else + mavlink_vfr_hud_t packet; + packet.airspeed = airspeed; + packet.groundspeed = groundspeed; + packet.alt = alt; + packet.climb = climb; + packet.heading = heading; + packet.throttle = throttle; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 20); +#endif + + msg->msgid = MAVLINK_MSG_ID_VFR_HUD; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 20, 20); +} + +/** + * @brief Encode a vfr_hud struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param vfr_hud C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_vfr_hud_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_vfr_hud_t *vfr_hud) +{ + return mavlink_msg_vfr_hud_pack(system_id, component_id, msg, vfr_hud->airspeed, vfr_hud->groundspeed, vfr_hud->heading, vfr_hud->throttle, vfr_hud->alt, vfr_hud->climb); +} + +/** + * @brief Send a vfr_hud message + * @param chan MAVLink channel to send the message + * + * @param airspeed Current airspeed in m/s + * @param groundspeed Current ground speed in m/s + * @param heading Current heading in degrees, in compass units (0..360, 0=north) + * @param throttle Current throttle setting in integer percent, 0 to 100 + * @param alt Current altitude (MSL), in meters + * @param climb Current climb rate in meters/second + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_vfr_hud_send(mavlink_channel_t chan, float airspeed, float groundspeed, int16_t heading, uint16_t throttle, float alt, float climb) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[20]; + _mav_put_float(buf, 0, airspeed); + _mav_put_float(buf, 4, groundspeed); + _mav_put_float(buf, 8, alt); + _mav_put_float(buf, 12, climb); + _mav_put_int16_t(buf, 16, heading); + _mav_put_uint16_t(buf, 18, throttle); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_VFR_HUD, buf, 20, 20); +#else + mavlink_vfr_hud_t packet; + packet.airspeed = airspeed; + packet.groundspeed = groundspeed; + packet.alt = alt; + packet.climb = climb; + packet.heading = heading; + packet.throttle = throttle; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_VFR_HUD, (const char *)&packet, 20, 20); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE VFR_HUD UNPACKING + + +/** + * @brief Get field airspeed from vfr_hud message + * + * @return Current airspeed in m/s + */ +static inline float mavlink_msg_vfr_hud_get_airspeed(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 0); +} + +/** + * @brief Get field groundspeed from vfr_hud message + * + * @return Current ground speed in m/s + */ +static inline float mavlink_msg_vfr_hud_get_groundspeed(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 4); +} + +/** + * @brief Get field heading from vfr_hud message + * + * @return Current heading in degrees, in compass units (0..360, 0=north) + */ +static inline int16_t mavlink_msg_vfr_hud_get_heading(const mavlink_message_t *msg) +{ + return _MAV_RETURN_int16_t(msg, 16); +} + +/** + * @brief Get field throttle from vfr_hud message + * + * @return Current throttle setting in integer percent, 0 to 100 + */ +static inline uint16_t mavlink_msg_vfr_hud_get_throttle(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint16_t(msg, 18); +} + +/** + * @brief Get field alt from vfr_hud message + * + * @return Current altitude (MSL), in meters + */ +static inline float mavlink_msg_vfr_hud_get_alt(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 8); +} + +/** + * @brief Get field climb from vfr_hud message + * + * @return Current climb rate in meters/second + */ +static inline float mavlink_msg_vfr_hud_get_climb(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 12); +} + +/** + * @brief Decode a vfr_hud message into a struct + * + * @param msg The message to decode + * @param vfr_hud C-struct to decode the message contents into + */ +static inline void mavlink_msg_vfr_hud_decode(const mavlink_message_t *msg, mavlink_vfr_hud_t *vfr_hud) +{ +#if MAVLINK_NEED_BYTE_SWAP + vfr_hud->airspeed = mavlink_msg_vfr_hud_get_airspeed(msg); + vfr_hud->groundspeed = mavlink_msg_vfr_hud_get_groundspeed(msg); + vfr_hud->alt = mavlink_msg_vfr_hud_get_alt(msg); + vfr_hud->climb = mavlink_msg_vfr_hud_get_climb(msg); + vfr_hud->heading = mavlink_msg_vfr_hud_get_heading(msg); + vfr_hud->throttle = mavlink_msg_vfr_hud_get_throttle(msg); +#else + memcpy(vfr_hud, _MAV_PAYLOAD(msg), 20); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_vicon_position_estimate.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_vicon_position_estimate.h new file mode 100644 index 000000000..b4baca63d --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_vicon_position_estimate.h @@ -0,0 +1,276 @@ +// MESSAGE VICON_POSITION_ESTIMATE PACKING + +#define MAVLINK_MSG_ID_VICON_POSITION_ESTIMATE 104 + +typedef struct __mavlink_vicon_position_estimate_t { + uint64_t usec; ///< Timestamp (milliseconds) + float x; ///< Global X position + float y; ///< Global Y position + float z; ///< Global Z position + float roll; ///< Roll angle in rad + float pitch; ///< Pitch angle in rad + float yaw; ///< Yaw angle in rad +} mavlink_vicon_position_estimate_t; + +#define MAVLINK_MSG_ID_VICON_POSITION_ESTIMATE_LEN 32 +#define MAVLINK_MSG_ID_104_LEN 32 + + +#define MAVLINK_MESSAGE_INFO_VICON_POSITION_ESTIMATE \ + { \ + "VICON_POSITION_ESTIMATE", \ + 7, \ + { \ + { "usec", NULL, MAVLINK_TYPE_UINT64_T, 0, 0, offsetof(mavlink_vicon_position_estimate_t, usec) }, \ + { "x", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_vicon_position_estimate_t, x) }, \ + { "y", NULL, MAVLINK_TYPE_FLOAT, 0, 12, offsetof(mavlink_vicon_position_estimate_t, y) }, \ + { "z", NULL, MAVLINK_TYPE_FLOAT, 0, 16, offsetof(mavlink_vicon_position_estimate_t, z) }, \ + { "roll", NULL, MAVLINK_TYPE_FLOAT, 0, 20, offsetof(mavlink_vicon_position_estimate_t, roll) }, \ + { "pitch", NULL, MAVLINK_TYPE_FLOAT, 0, 24, offsetof(mavlink_vicon_position_estimate_t, pitch) }, \ + { "yaw", NULL, MAVLINK_TYPE_FLOAT, 0, 28, offsetof(mavlink_vicon_position_estimate_t, yaw) }, \ + } \ + } + + +/** + * @brief Pack a vicon_position_estimate message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param usec Timestamp (milliseconds) + * @param x Global X position + * @param y Global Y position + * @param z Global Z position + * @param roll Roll angle in rad + * @param pitch Pitch angle in rad + * @param yaw Yaw angle in rad + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_vicon_position_estimate_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint64_t usec, float x, float y, float z, float roll, float pitch, float yaw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[32]; + _mav_put_uint64_t(buf, 0, usec); + _mav_put_float(buf, 8, x); + _mav_put_float(buf, 12, y); + _mav_put_float(buf, 16, z); + _mav_put_float(buf, 20, roll); + _mav_put_float(buf, 24, pitch); + _mav_put_float(buf, 28, yaw); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 32); +#else + mavlink_vicon_position_estimate_t packet; + packet.usec = usec; + packet.x = x; + packet.y = y; + packet.z = z; + packet.roll = roll; + packet.pitch = pitch; + packet.yaw = yaw; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 32); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_VICON_POSITION_ESTIMATE; + return mavlink_finalize_message(msg, system_id, component_id, 32, 56); +} + +/** + * @brief Pack a vicon_position_estimate message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param usec Timestamp (milliseconds) + * @param x Global X position + * @param y Global Y position + * @param z Global Z position + * @param roll Roll angle in rad + * @param pitch Pitch angle in rad + * @param yaw Yaw angle in rad + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_vicon_position_estimate_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint64_t usec, float x, float y, float z, float roll, float pitch, float yaw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[32]; + _mav_put_uint64_t(buf, 0, usec); + _mav_put_float(buf, 8, x); + _mav_put_float(buf, 12, y); + _mav_put_float(buf, 16, z); + _mav_put_float(buf, 20, roll); + _mav_put_float(buf, 24, pitch); + _mav_put_float(buf, 28, yaw); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 32); +#else + mavlink_vicon_position_estimate_t packet; + packet.usec = usec; + packet.x = x; + packet.y = y; + packet.z = z; + packet.roll = roll; + packet.pitch = pitch; + packet.yaw = yaw; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 32); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_VICON_POSITION_ESTIMATE; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 32, 56); +} + +/** + * @brief Encode a vicon_position_estimate struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param vicon_position_estimate C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_vicon_position_estimate_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_vicon_position_estimate_t *vicon_position_estimate) +{ + return mavlink_msg_vicon_position_estimate_pack(system_id, component_id, msg, vicon_position_estimate->usec, vicon_position_estimate->x, vicon_position_estimate->y, vicon_position_estimate->z, vicon_position_estimate->roll, vicon_position_estimate->pitch, vicon_position_estimate->yaw); +} + +/** + * @brief Send a vicon_position_estimate message + * @param chan MAVLink channel to send the message + * + * @param usec Timestamp (milliseconds) + * @param x Global X position + * @param y Global Y position + * @param z Global Z position + * @param roll Roll angle in rad + * @param pitch Pitch angle in rad + * @param yaw Yaw angle in rad + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_vicon_position_estimate_send(mavlink_channel_t chan, uint64_t usec, float x, float y, float z, float roll, float pitch, float yaw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[32]; + _mav_put_uint64_t(buf, 0, usec); + _mav_put_float(buf, 8, x); + _mav_put_float(buf, 12, y); + _mav_put_float(buf, 16, z); + _mav_put_float(buf, 20, roll); + _mav_put_float(buf, 24, pitch); + _mav_put_float(buf, 28, yaw); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_VICON_POSITION_ESTIMATE, buf, 32, 56); +#else + mavlink_vicon_position_estimate_t packet; + packet.usec = usec; + packet.x = x; + packet.y = y; + packet.z = z; + packet.roll = roll; + packet.pitch = pitch; + packet.yaw = yaw; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_VICON_POSITION_ESTIMATE, (const char *)&packet, 32, 56); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE VICON_POSITION_ESTIMATE UNPACKING + + +/** + * @brief Get field usec from vicon_position_estimate message + * + * @return Timestamp (milliseconds) + */ +static inline uint64_t mavlink_msg_vicon_position_estimate_get_usec(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint64_t(msg, 0); +} + +/** + * @brief Get field x from vicon_position_estimate message + * + * @return Global X position + */ +static inline float mavlink_msg_vicon_position_estimate_get_x(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 8); +} + +/** + * @brief Get field y from vicon_position_estimate message + * + * @return Global Y position + */ +static inline float mavlink_msg_vicon_position_estimate_get_y(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 12); +} + +/** + * @brief Get field z from vicon_position_estimate message + * + * @return Global Z position + */ +static inline float mavlink_msg_vicon_position_estimate_get_z(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 16); +} + +/** + * @brief Get field roll from vicon_position_estimate message + * + * @return Roll angle in rad + */ +static inline float mavlink_msg_vicon_position_estimate_get_roll(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 20); +} + +/** + * @brief Get field pitch from vicon_position_estimate message + * + * @return Pitch angle in rad + */ +static inline float mavlink_msg_vicon_position_estimate_get_pitch(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 24); +} + +/** + * @brief Get field yaw from vicon_position_estimate message + * + * @return Yaw angle in rad + */ +static inline float mavlink_msg_vicon_position_estimate_get_yaw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 28); +} + +/** + * @brief Decode a vicon_position_estimate message into a struct + * + * @param msg The message to decode + * @param vicon_position_estimate C-struct to decode the message contents into + */ +static inline void mavlink_msg_vicon_position_estimate_decode(const mavlink_message_t *msg, mavlink_vicon_position_estimate_t *vicon_position_estimate) +{ +#if MAVLINK_NEED_BYTE_SWAP + vicon_position_estimate->usec = mavlink_msg_vicon_position_estimate_get_usec(msg); + vicon_position_estimate->x = mavlink_msg_vicon_position_estimate_get_x(msg); + vicon_position_estimate->y = mavlink_msg_vicon_position_estimate_get_y(msg); + vicon_position_estimate->z = mavlink_msg_vicon_position_estimate_get_z(msg); + vicon_position_estimate->roll = mavlink_msg_vicon_position_estimate_get_roll(msg); + vicon_position_estimate->pitch = mavlink_msg_vicon_position_estimate_get_pitch(msg); + vicon_position_estimate->yaw = mavlink_msg_vicon_position_estimate_get_yaw(msg); +#else + memcpy(vicon_position_estimate, _MAV_PAYLOAD(msg), 32); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_vision_position_estimate.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_vision_position_estimate.h new file mode 100644 index 000000000..e8c809aa4 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_vision_position_estimate.h @@ -0,0 +1,276 @@ +// MESSAGE VISION_POSITION_ESTIMATE PACKING + +#define MAVLINK_MSG_ID_VISION_POSITION_ESTIMATE 102 + +typedef struct __mavlink_vision_position_estimate_t { + uint64_t usec; ///< Timestamp (milliseconds) + float x; ///< Global X position + float y; ///< Global Y position + float z; ///< Global Z position + float roll; ///< Roll angle in rad + float pitch; ///< Pitch angle in rad + float yaw; ///< Yaw angle in rad +} mavlink_vision_position_estimate_t; + +#define MAVLINK_MSG_ID_VISION_POSITION_ESTIMATE_LEN 32 +#define MAVLINK_MSG_ID_102_LEN 32 + + +#define MAVLINK_MESSAGE_INFO_VISION_POSITION_ESTIMATE \ + { \ + "VISION_POSITION_ESTIMATE", \ + 7, \ + { \ + { "usec", NULL, MAVLINK_TYPE_UINT64_T, 0, 0, offsetof(mavlink_vision_position_estimate_t, usec) }, \ + { "x", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_vision_position_estimate_t, x) }, \ + { "y", NULL, MAVLINK_TYPE_FLOAT, 0, 12, offsetof(mavlink_vision_position_estimate_t, y) }, \ + { "z", NULL, MAVLINK_TYPE_FLOAT, 0, 16, offsetof(mavlink_vision_position_estimate_t, z) }, \ + { "roll", NULL, MAVLINK_TYPE_FLOAT, 0, 20, offsetof(mavlink_vision_position_estimate_t, roll) }, \ + { "pitch", NULL, MAVLINK_TYPE_FLOAT, 0, 24, offsetof(mavlink_vision_position_estimate_t, pitch) }, \ + { "yaw", NULL, MAVLINK_TYPE_FLOAT, 0, 28, offsetof(mavlink_vision_position_estimate_t, yaw) }, \ + } \ + } + + +/** + * @brief Pack a vision_position_estimate message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param usec Timestamp (milliseconds) + * @param x Global X position + * @param y Global Y position + * @param z Global Z position + * @param roll Roll angle in rad + * @param pitch Pitch angle in rad + * @param yaw Yaw angle in rad + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_vision_position_estimate_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint64_t usec, float x, float y, float z, float roll, float pitch, float yaw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[32]; + _mav_put_uint64_t(buf, 0, usec); + _mav_put_float(buf, 8, x); + _mav_put_float(buf, 12, y); + _mav_put_float(buf, 16, z); + _mav_put_float(buf, 20, roll); + _mav_put_float(buf, 24, pitch); + _mav_put_float(buf, 28, yaw); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 32); +#else + mavlink_vision_position_estimate_t packet; + packet.usec = usec; + packet.x = x; + packet.y = y; + packet.z = z; + packet.roll = roll; + packet.pitch = pitch; + packet.yaw = yaw; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 32); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_VISION_POSITION_ESTIMATE; + return mavlink_finalize_message(msg, system_id, component_id, 32, 158); +} + +/** + * @brief Pack a vision_position_estimate message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param usec Timestamp (milliseconds) + * @param x Global X position + * @param y Global Y position + * @param z Global Z position + * @param roll Roll angle in rad + * @param pitch Pitch angle in rad + * @param yaw Yaw angle in rad + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_vision_position_estimate_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint64_t usec, float x, float y, float z, float roll, float pitch, float yaw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[32]; + _mav_put_uint64_t(buf, 0, usec); + _mav_put_float(buf, 8, x); + _mav_put_float(buf, 12, y); + _mav_put_float(buf, 16, z); + _mav_put_float(buf, 20, roll); + _mav_put_float(buf, 24, pitch); + _mav_put_float(buf, 28, yaw); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 32); +#else + mavlink_vision_position_estimate_t packet; + packet.usec = usec; + packet.x = x; + packet.y = y; + packet.z = z; + packet.roll = roll; + packet.pitch = pitch; + packet.yaw = yaw; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 32); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + + msg->msgid = MAVLINK_MSG_ID_VISION_POSITION_ESTIMATE; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 32, 158); +} + +/** + * @brief Encode a vision_position_estimate struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param vision_position_estimate C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_vision_position_estimate_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_vision_position_estimate_t *vision_position_estimate) +{ + return mavlink_msg_vision_position_estimate_pack(system_id, component_id, msg, vision_position_estimate->usec, vision_position_estimate->x, vision_position_estimate->y, vision_position_estimate->z, vision_position_estimate->roll, vision_position_estimate->pitch, vision_position_estimate->yaw); +} + +/** + * @brief Send a vision_position_estimate message + * @param chan MAVLink channel to send the message + * + * @param usec Timestamp (milliseconds) + * @param x Global X position + * @param y Global Y position + * @param z Global Z position + * @param roll Roll angle in rad + * @param pitch Pitch angle in rad + * @param yaw Yaw angle in rad + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_vision_position_estimate_send(mavlink_channel_t chan, uint64_t usec, float x, float y, float z, float roll, float pitch, float yaw) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[32]; + _mav_put_uint64_t(buf, 0, usec); + _mav_put_float(buf, 8, x); + _mav_put_float(buf, 12, y); + _mav_put_float(buf, 16, z); + _mav_put_float(buf, 20, roll); + _mav_put_float(buf, 24, pitch); + _mav_put_float(buf, 28, yaw); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_VISION_POSITION_ESTIMATE, buf, 32, 158); +#else + mavlink_vision_position_estimate_t packet; + packet.usec = usec; + packet.x = x; + packet.y = y; + packet.z = z; + packet.roll = roll; + packet.pitch = pitch; + packet.yaw = yaw; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_VISION_POSITION_ESTIMATE, (const char *)&packet, 32, 158); +#endif // if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE VISION_POSITION_ESTIMATE UNPACKING + + +/** + * @brief Get field usec from vision_position_estimate message + * + * @return Timestamp (milliseconds) + */ +static inline uint64_t mavlink_msg_vision_position_estimate_get_usec(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint64_t(msg, 0); +} + +/** + * @brief Get field x from vision_position_estimate message + * + * @return Global X position + */ +static inline float mavlink_msg_vision_position_estimate_get_x(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 8); +} + +/** + * @brief Get field y from vision_position_estimate message + * + * @return Global Y position + */ +static inline float mavlink_msg_vision_position_estimate_get_y(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 12); +} + +/** + * @brief Get field z from vision_position_estimate message + * + * @return Global Z position + */ +static inline float mavlink_msg_vision_position_estimate_get_z(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 16); +} + +/** + * @brief Get field roll from vision_position_estimate message + * + * @return Roll angle in rad + */ +static inline float mavlink_msg_vision_position_estimate_get_roll(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 20); +} + +/** + * @brief Get field pitch from vision_position_estimate message + * + * @return Pitch angle in rad + */ +static inline float mavlink_msg_vision_position_estimate_get_pitch(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 24); +} + +/** + * @brief Get field yaw from vision_position_estimate message + * + * @return Yaw angle in rad + */ +static inline float mavlink_msg_vision_position_estimate_get_yaw(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 28); +} + +/** + * @brief Decode a vision_position_estimate message into a struct + * + * @param msg The message to decode + * @param vision_position_estimate C-struct to decode the message contents into + */ +static inline void mavlink_msg_vision_position_estimate_decode(const mavlink_message_t *msg, mavlink_vision_position_estimate_t *vision_position_estimate) +{ +#if MAVLINK_NEED_BYTE_SWAP + vision_position_estimate->usec = mavlink_msg_vision_position_estimate_get_usec(msg); + vision_position_estimate->x = mavlink_msg_vision_position_estimate_get_x(msg); + vision_position_estimate->y = mavlink_msg_vision_position_estimate_get_y(msg); + vision_position_estimate->z = mavlink_msg_vision_position_estimate_get_z(msg); + vision_position_estimate->roll = mavlink_msg_vision_position_estimate_get_roll(msg); + vision_position_estimate->pitch = mavlink_msg_vision_position_estimate_get_pitch(msg); + vision_position_estimate->yaw = mavlink_msg_vision_position_estimate_get_yaw(msg); +#else + memcpy(vision_position_estimate, _MAV_PAYLOAD(msg), 32); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/mavlink_msg_vision_speed_estimate.h b/flight/libraries/mavlink/v1.0/common/mavlink_msg_vision_speed_estimate.h new file mode 100644 index 000000000..3bdab7cf7 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/mavlink_msg_vision_speed_estimate.h @@ -0,0 +1,210 @@ +// MESSAGE VISION_SPEED_ESTIMATE PACKING + +#define MAVLINK_MSG_ID_VISION_SPEED_ESTIMATE 103 + +typedef struct __mavlink_vision_speed_estimate_t { + uint64_t usec; ///< Timestamp (milliseconds) + float x; ///< Global X speed + float y; ///< Global Y speed + float z; ///< Global Z speed +} mavlink_vision_speed_estimate_t; + +#define MAVLINK_MSG_ID_VISION_SPEED_ESTIMATE_LEN 20 +#define MAVLINK_MSG_ID_103_LEN 20 + + +#define MAVLINK_MESSAGE_INFO_VISION_SPEED_ESTIMATE \ + { \ + "VISION_SPEED_ESTIMATE", \ + 4, \ + { \ + { "usec", NULL, MAVLINK_TYPE_UINT64_T, 0, 0, offsetof(mavlink_vision_speed_estimate_t, usec) }, \ + { "x", NULL, MAVLINK_TYPE_FLOAT, 0, 8, offsetof(mavlink_vision_speed_estimate_t, x) }, \ + { "y", NULL, MAVLINK_TYPE_FLOAT, 0, 12, offsetof(mavlink_vision_speed_estimate_t, y) }, \ + { "z", NULL, MAVLINK_TYPE_FLOAT, 0, 16, offsetof(mavlink_vision_speed_estimate_t, z) }, \ + } \ + } + + +/** + * @brief Pack a vision_speed_estimate message + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * + * @param usec Timestamp (milliseconds) + * @param x Global X speed + * @param y Global Y speed + * @param z Global Z speed + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_vision_speed_estimate_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, + uint64_t usec, float x, float y, float z) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[20]; + _mav_put_uint64_t(buf, 0, usec); + _mav_put_float(buf, 8, x); + _mav_put_float(buf, 12, y); + _mav_put_float(buf, 16, z); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 20); +#else + mavlink_vision_speed_estimate_t packet; + packet.usec = usec; + packet.x = x; + packet.y = y; + packet.z = z; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 20); +#endif + + msg->msgid = MAVLINK_MSG_ID_VISION_SPEED_ESTIMATE; + return mavlink_finalize_message(msg, system_id, component_id, 20, 208); +} + +/** + * @brief Pack a vision_speed_estimate message on a channel + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param chan The MAVLink channel this message was sent over + * @param msg The MAVLink message to compress the data into + * @param usec Timestamp (milliseconds) + * @param x Global X speed + * @param y Global Y speed + * @param z Global Z speed + * @return length of the message in bytes (excluding serial stream start sign) + */ +static inline uint16_t mavlink_msg_vision_speed_estimate_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan, + mavlink_message_t *msg, + uint64_t usec, float x, float y, float z) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[20]; + _mav_put_uint64_t(buf, 0, usec); + _mav_put_float(buf, 8, x); + _mav_put_float(buf, 12, y); + _mav_put_float(buf, 16, z); + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, 20); +#else + mavlink_vision_speed_estimate_t packet; + packet.usec = usec; + packet.x = x; + packet.y = y; + packet.z = z; + + memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, 20); +#endif + + msg->msgid = MAVLINK_MSG_ID_VISION_SPEED_ESTIMATE; + return mavlink_finalize_message_chan(msg, system_id, component_id, chan, 20, 208); +} + +/** + * @brief Encode a vision_speed_estimate struct into a message + * + * @param system_id ID of this system + * @param component_id ID of this component (e.g. 200 for IMU) + * @param msg The MAVLink message to compress the data into + * @param vision_speed_estimate C-struct to read the message contents from + */ +static inline uint16_t mavlink_msg_vision_speed_estimate_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t *msg, const mavlink_vision_speed_estimate_t *vision_speed_estimate) +{ + return mavlink_msg_vision_speed_estimate_pack(system_id, component_id, msg, vision_speed_estimate->usec, vision_speed_estimate->x, vision_speed_estimate->y, vision_speed_estimate->z); +} + +/** + * @brief Send a vision_speed_estimate message + * @param chan MAVLink channel to send the message + * + * @param usec Timestamp (milliseconds) + * @param x Global X speed + * @param y Global Y speed + * @param z Global Z speed + */ +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +static inline void mavlink_msg_vision_speed_estimate_send(mavlink_channel_t chan, uint64_t usec, float x, float y, float z) +{ +#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS + char buf[20]; + _mav_put_uint64_t(buf, 0, usec); + _mav_put_float(buf, 8, x); + _mav_put_float(buf, 12, y); + _mav_put_float(buf, 16, z); + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_VISION_SPEED_ESTIMATE, buf, 20, 208); +#else + mavlink_vision_speed_estimate_t packet; + packet.usec = usec; + packet.x = x; + packet.y = y; + packet.z = z; + + _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_VISION_SPEED_ESTIMATE, (const char *)&packet, 20, 208); +#endif +} + +#endif // ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// MESSAGE VISION_SPEED_ESTIMATE UNPACKING + + +/** + * @brief Get field usec from vision_speed_estimate message + * + * @return Timestamp (milliseconds) + */ +static inline uint64_t mavlink_msg_vision_speed_estimate_get_usec(const mavlink_message_t *msg) +{ + return _MAV_RETURN_uint64_t(msg, 0); +} + +/** + * @brief Get field x from vision_speed_estimate message + * + * @return Global X speed + */ +static inline float mavlink_msg_vision_speed_estimate_get_x(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 8); +} + +/** + * @brief Get field y from vision_speed_estimate message + * + * @return Global Y speed + */ +static inline float mavlink_msg_vision_speed_estimate_get_y(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 12); +} + +/** + * @brief Get field z from vision_speed_estimate message + * + * @return Global Z speed + */ +static inline float mavlink_msg_vision_speed_estimate_get_z(const mavlink_message_t *msg) +{ + return _MAV_RETURN_float(msg, 16); +} + +/** + * @brief Decode a vision_speed_estimate message into a struct + * + * @param msg The message to decode + * @param vision_speed_estimate C-struct to decode the message contents into + */ +static inline void mavlink_msg_vision_speed_estimate_decode(const mavlink_message_t *msg, mavlink_vision_speed_estimate_t *vision_speed_estimate) +{ +#if MAVLINK_NEED_BYTE_SWAP + vision_speed_estimate->usec = mavlink_msg_vision_speed_estimate_get_usec(msg); + vision_speed_estimate->x = mavlink_msg_vision_speed_estimate_get_x(msg); + vision_speed_estimate->y = mavlink_msg_vision_speed_estimate_get_y(msg); + vision_speed_estimate->z = mavlink_msg_vision_speed_estimate_get_z(msg); +#else + memcpy(vision_speed_estimate, _MAV_PAYLOAD(msg), 20); +#endif +} diff --git a/flight/libraries/mavlink/v1.0/common/testsuite.h b/flight/libraries/mavlink/v1.0/common/testsuite.h new file mode 100644 index 000000000..a20937159 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/testsuite.h @@ -0,0 +1,4096 @@ +/** @file + * @brief MAVLink comm protocol testsuite generated from common.xml + * @see http://qgroundcontrol.org/mavlink/ + */ +#ifndef COMMON_TESTSUITE_H +#define COMMON_TESTSUITE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef MAVLINK_TEST_ALL +#define MAVLINK_TEST_ALL + +static void mavlink_test_common(uint8_t, uint8_t, mavlink_message_t * last_msg); + +static void mavlink_test_all(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_test_common(system_id, component_id, last_msg); +} +#endif + + +static void mavlink_test_heartbeat(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_heartbeat_t packet_in = { + 963497464, + 17, + 84, + 151, + 218, + 3, + }; + mavlink_heartbeat_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.custom_mode = packet_in.custom_mode; + packet1.type = packet_in.type; + packet1.autopilot = packet_in.autopilot; + packet1.base_mode = packet_in.base_mode; + packet1.system_status = packet_in.system_status; + packet1.mavlink_version = packet_in.mavlink_version; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_heartbeat_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_heartbeat_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_heartbeat_pack(system_id, component_id, &msg, packet1.type, packet1.autopilot, packet1.base_mode, packet1.custom_mode, packet1.system_status); + mavlink_msg_heartbeat_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_heartbeat_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.type, packet1.autopilot, packet1.base_mode, packet1.custom_mode, packet1.system_status); + mavlink_msg_heartbeat_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_heartbeat_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_heartbeat_send(MAVLINK_COMM_1, packet1.type, packet1.autopilot, packet1.base_mode, packet1.custom_mode, packet1.system_status); + mavlink_msg_heartbeat_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_sys_status(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_sys_status_t packet_in = { + 963497464, + 963497672, + 963497880, + 17859, + 17963, + 18067, + 18171, + 18275, + 18379, + 18483, + 18587, + 18691, + 223, + }; + mavlink_sys_status_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.onboard_control_sensors_present = packet_in.onboard_control_sensors_present; + packet1.onboard_control_sensors_enabled = packet_in.onboard_control_sensors_enabled; + packet1.onboard_control_sensors_health = packet_in.onboard_control_sensors_health; + packet1.load = packet_in.load; + packet1.voltage_battery = packet_in.voltage_battery; + packet1.current_battery = packet_in.current_battery; + packet1.drop_rate_comm = packet_in.drop_rate_comm; + packet1.errors_comm = packet_in.errors_comm; + packet1.errors_count1 = packet_in.errors_count1; + packet1.errors_count2 = packet_in.errors_count2; + packet1.errors_count3 = packet_in.errors_count3; + packet1.errors_count4 = packet_in.errors_count4; + packet1.battery_remaining = packet_in.battery_remaining; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_sys_status_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_sys_status_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_sys_status_pack(system_id, component_id, &msg, packet1.onboard_control_sensors_present, packet1.onboard_control_sensors_enabled, packet1.onboard_control_sensors_health, packet1.load, packet1.voltage_battery, packet1.current_battery, packet1.battery_remaining, packet1.drop_rate_comm, packet1.errors_comm, packet1.errors_count1, packet1.errors_count2, packet1.errors_count3, packet1.errors_count4); + mavlink_msg_sys_status_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_sys_status_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.onboard_control_sensors_present, packet1.onboard_control_sensors_enabled, packet1.onboard_control_sensors_health, packet1.load, packet1.voltage_battery, packet1.current_battery, packet1.battery_remaining, packet1.drop_rate_comm, packet1.errors_comm, packet1.errors_count1, packet1.errors_count2, packet1.errors_count3, packet1.errors_count4); + mavlink_msg_sys_status_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_sys_status_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_sys_status_send(MAVLINK_COMM_1, packet1.onboard_control_sensors_present, packet1.onboard_control_sensors_enabled, packet1.onboard_control_sensors_health, packet1.load, packet1.voltage_battery, packet1.current_battery, packet1.battery_remaining, packet1.drop_rate_comm, packet1.errors_comm, packet1.errors_count1, packet1.errors_count2, packet1.errors_count3, packet1.errors_count4); + mavlink_msg_sys_status_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_system_time(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_system_time_t packet_in = { + 93372036854775807ULL, + 963497880, + }; + mavlink_system_time_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.time_unix_usec = packet_in.time_unix_usec; + packet1.time_boot_ms = packet_in.time_boot_ms; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_system_time_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_system_time_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_system_time_pack(system_id, component_id, &msg, packet1.time_unix_usec, packet1.time_boot_ms); + mavlink_msg_system_time_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_system_time_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.time_unix_usec, packet1.time_boot_ms); + mavlink_msg_system_time_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_system_time_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_system_time_send(MAVLINK_COMM_1, packet1.time_unix_usec, packet1.time_boot_ms); + mavlink_msg_system_time_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_ping(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_ping_t packet_in = { + 93372036854775807ULL, + 963497880, + 41, + 108, + }; + mavlink_ping_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.time_usec = packet_in.time_usec; + packet1.seq = packet_in.seq; + packet1.target_system = packet_in.target_system; + packet1.target_component = packet_in.target_component; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_ping_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_ping_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_ping_pack(system_id, component_id, &msg, packet1.time_usec, packet1.seq, packet1.target_system, packet1.target_component); + mavlink_msg_ping_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_ping_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.time_usec, packet1.seq, packet1.target_system, packet1.target_component); + mavlink_msg_ping_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_ping_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_ping_send(MAVLINK_COMM_1, packet1.time_usec, packet1.seq, packet1.target_system, packet1.target_component); + mavlink_msg_ping_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_change_operator_control(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_change_operator_control_t packet_in = { + 5, + 72, + 139, + "DEFGHIJKLMNOPQRSTUVWXYZA", + }; + mavlink_change_operator_control_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.target_system = packet_in.target_system; + packet1.control_request = packet_in.control_request; + packet1.version = packet_in.version; + + mav_array_memcpy(packet1.passkey, packet_in.passkey, sizeof(char) * 25); + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_change_operator_control_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_change_operator_control_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_change_operator_control_pack(system_id, component_id, &msg, packet1.target_system, packet1.control_request, packet1.version, packet1.passkey); + mavlink_msg_change_operator_control_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_change_operator_control_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.target_system, packet1.control_request, packet1.version, packet1.passkey); + mavlink_msg_change_operator_control_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_change_operator_control_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_change_operator_control_send(MAVLINK_COMM_1, packet1.target_system, packet1.control_request, packet1.version, packet1.passkey); + mavlink_msg_change_operator_control_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_change_operator_control_ack(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_change_operator_control_ack_t packet_in = { + 5, + 72, + 139, + }; + mavlink_change_operator_control_ack_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.gcs_system_id = packet_in.gcs_system_id; + packet1.control_request = packet_in.control_request; + packet1.ack = packet_in.ack; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_change_operator_control_ack_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_change_operator_control_ack_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_change_operator_control_ack_pack(system_id, component_id, &msg, packet1.gcs_system_id, packet1.control_request, packet1.ack); + mavlink_msg_change_operator_control_ack_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_change_operator_control_ack_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.gcs_system_id, packet1.control_request, packet1.ack); + mavlink_msg_change_operator_control_ack_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_change_operator_control_ack_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_change_operator_control_ack_send(MAVLINK_COMM_1, packet1.gcs_system_id, packet1.control_request, packet1.ack); + mavlink_msg_change_operator_control_ack_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_auth_key(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_auth_key_t packet_in = { + "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDE", + }; + mavlink_auth_key_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + + mav_array_memcpy(packet1.key, packet_in.key, sizeof(char) * 32); + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_auth_key_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_auth_key_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_auth_key_pack(system_id, component_id, &msg, packet1.key); + mavlink_msg_auth_key_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_auth_key_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.key); + mavlink_msg_auth_key_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_auth_key_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_auth_key_send(MAVLINK_COMM_1, packet1.key); + mavlink_msg_auth_key_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_set_mode(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_set_mode_t packet_in = { + 963497464, + 17, + 84, + }; + mavlink_set_mode_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.custom_mode = packet_in.custom_mode; + packet1.target_system = packet_in.target_system; + packet1.base_mode = packet_in.base_mode; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_mode_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_set_mode_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_mode_pack(system_id, component_id, &msg, packet1.target_system, packet1.base_mode, packet1.custom_mode); + mavlink_msg_set_mode_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_mode_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.target_system, packet1.base_mode, packet1.custom_mode); + mavlink_msg_set_mode_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_set_mode_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_mode_send(MAVLINK_COMM_1, packet1.target_system, packet1.base_mode, packet1.custom_mode); + mavlink_msg_set_mode_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_param_request_read(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_param_request_read_t packet_in = { + 17235, + 139, + 206, + "EFGHIJKLMNOPQRS", + }; + mavlink_param_request_read_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.param_index = packet_in.param_index; + packet1.target_system = packet_in.target_system; + packet1.target_component = packet_in.target_component; + + mav_array_memcpy(packet1.param_id, packet_in.param_id, sizeof(char) * 16); + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_param_request_read_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_param_request_read_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_param_request_read_pack(system_id, component_id, &msg, packet1.target_system, packet1.target_component, packet1.param_id, packet1.param_index); + mavlink_msg_param_request_read_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_param_request_read_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.target_system, packet1.target_component, packet1.param_id, packet1.param_index); + mavlink_msg_param_request_read_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_param_request_read_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_param_request_read_send(MAVLINK_COMM_1, packet1.target_system, packet1.target_component, packet1.param_id, packet1.param_index); + mavlink_msg_param_request_read_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_param_request_list(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_param_request_list_t packet_in = { + 5, + 72, + }; + mavlink_param_request_list_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.target_system = packet_in.target_system; + packet1.target_component = packet_in.target_component; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_param_request_list_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_param_request_list_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_param_request_list_pack(system_id, component_id, &msg, packet1.target_system, packet1.target_component); + mavlink_msg_param_request_list_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_param_request_list_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.target_system, packet1.target_component); + mavlink_msg_param_request_list_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_param_request_list_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_param_request_list_send(MAVLINK_COMM_1, packet1.target_system, packet1.target_component); + mavlink_msg_param_request_list_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_param_value(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_param_value_t packet_in = { + 17.0, + 17443, + 17547, + "IJKLMNOPQRSTUVW", + 77, + }; + mavlink_param_value_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.param_value = packet_in.param_value; + packet1.param_count = packet_in.param_count; + packet1.param_index = packet_in.param_index; + packet1.param_type = packet_in.param_type; + + mav_array_memcpy(packet1.param_id, packet_in.param_id, sizeof(char) * 16); + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_param_value_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_param_value_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_param_value_pack(system_id, component_id, &msg, packet1.param_id, packet1.param_value, packet1.param_type, packet1.param_count, packet1.param_index); + mavlink_msg_param_value_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_param_value_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.param_id, packet1.param_value, packet1.param_type, packet1.param_count, packet1.param_index); + mavlink_msg_param_value_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_param_value_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_param_value_send(MAVLINK_COMM_1, packet1.param_id, packet1.param_value, packet1.param_type, packet1.param_count, packet1.param_index); + mavlink_msg_param_value_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_param_set(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_param_set_t packet_in = { + 17.0, + 17, + 84, + "GHIJKLMNOPQRSTU", + 199, + }; + mavlink_param_set_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.param_value = packet_in.param_value; + packet1.target_system = packet_in.target_system; + packet1.target_component = packet_in.target_component; + packet1.param_type = packet_in.param_type; + + mav_array_memcpy(packet1.param_id, packet_in.param_id, sizeof(char) * 16); + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_param_set_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_param_set_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_param_set_pack(system_id, component_id, &msg, packet1.target_system, packet1.target_component, packet1.param_id, packet1.param_value, packet1.param_type); + mavlink_msg_param_set_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_param_set_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.target_system, packet1.target_component, packet1.param_id, packet1.param_value, packet1.param_type); + mavlink_msg_param_set_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_param_set_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_param_set_send(MAVLINK_COMM_1, packet1.target_system, packet1.target_component, packet1.param_id, packet1.param_value, packet1.param_type); + mavlink_msg_param_set_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_gps_raw_int(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_gps_raw_int_t packet_in = { + 93372036854775807ULL, + 963497880, + 963498088, + 963498296, + 18275, + 18379, + 18483, + 18587, + 89, + 156, + }; + mavlink_gps_raw_int_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.time_usec = packet_in.time_usec; + packet1.lat = packet_in.lat; + packet1.lon = packet_in.lon; + packet1.alt = packet_in.alt; + packet1.eph = packet_in.eph; + packet1.epv = packet_in.epv; + packet1.vel = packet_in.vel; + packet1.cog = packet_in.cog; + packet1.fix_type = packet_in.fix_type; + packet1.satellites_visible = packet_in.satellites_visible; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_gps_raw_int_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_gps_raw_int_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_gps_raw_int_pack(system_id, component_id, &msg, packet1.time_usec, packet1.fix_type, packet1.lat, packet1.lon, packet1.alt, packet1.eph, packet1.epv, packet1.vel, packet1.cog, packet1.satellites_visible); + mavlink_msg_gps_raw_int_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_gps_raw_int_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.time_usec, packet1.fix_type, packet1.lat, packet1.lon, packet1.alt, packet1.eph, packet1.epv, packet1.vel, packet1.cog, packet1.satellites_visible); + mavlink_msg_gps_raw_int_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_gps_raw_int_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_gps_raw_int_send(MAVLINK_COMM_1, packet1.time_usec, packet1.fix_type, packet1.lat, packet1.lon, packet1.alt, packet1.eph, packet1.epv, packet1.vel, packet1.cog, packet1.satellites_visible); + mavlink_msg_gps_raw_int_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_gps_status(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_gps_status_t packet_in = { + 5, + { 72,73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91 }, + { 132,133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151 }, + { 192,193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211 }, + { 252,253, 254, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + { 56,57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75 }, + }; + mavlink_gps_status_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.satellites_visible = packet_in.satellites_visible; + + mav_array_memcpy(packet1.satellite_prn, packet_in.satellite_prn, sizeof(uint8_t) * 20); + mav_array_memcpy(packet1.satellite_used, packet_in.satellite_used, sizeof(uint8_t) * 20); + mav_array_memcpy(packet1.satellite_elevation, packet_in.satellite_elevation, sizeof(uint8_t) * 20); + mav_array_memcpy(packet1.satellite_azimuth, packet_in.satellite_azimuth, sizeof(uint8_t) * 20); + mav_array_memcpy(packet1.satellite_snr, packet_in.satellite_snr, sizeof(uint8_t) * 20); + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_gps_status_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_gps_status_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_gps_status_pack(system_id, component_id, &msg, packet1.satellites_visible, packet1.satellite_prn, packet1.satellite_used, packet1.satellite_elevation, packet1.satellite_azimuth, packet1.satellite_snr); + mavlink_msg_gps_status_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_gps_status_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.satellites_visible, packet1.satellite_prn, packet1.satellite_used, packet1.satellite_elevation, packet1.satellite_azimuth, packet1.satellite_snr); + mavlink_msg_gps_status_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_gps_status_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_gps_status_send(MAVLINK_COMM_1, packet1.satellites_visible, packet1.satellite_prn, packet1.satellite_used, packet1.satellite_elevation, packet1.satellite_azimuth, packet1.satellite_snr); + mavlink_msg_gps_status_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_scaled_imu(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_scaled_imu_t packet_in = { + 963497464, + 17443, + 17547, + 17651, + 17755, + 17859, + 17963, + 18067, + 18171, + 18275, + }; + mavlink_scaled_imu_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.time_boot_ms = packet_in.time_boot_ms; + packet1.xacc = packet_in.xacc; + packet1.yacc = packet_in.yacc; + packet1.zacc = packet_in.zacc; + packet1.xgyro = packet_in.xgyro; + packet1.ygyro = packet_in.ygyro; + packet1.zgyro = packet_in.zgyro; + packet1.xmag = packet_in.xmag; + packet1.ymag = packet_in.ymag; + packet1.zmag = packet_in.zmag; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_scaled_imu_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_scaled_imu_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_scaled_imu_pack(system_id, component_id, &msg, packet1.time_boot_ms, packet1.xacc, packet1.yacc, packet1.zacc, packet1.xgyro, packet1.ygyro, packet1.zgyro, packet1.xmag, packet1.ymag, packet1.zmag); + mavlink_msg_scaled_imu_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_scaled_imu_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.time_boot_ms, packet1.xacc, packet1.yacc, packet1.zacc, packet1.xgyro, packet1.ygyro, packet1.zgyro, packet1.xmag, packet1.ymag, packet1.zmag); + mavlink_msg_scaled_imu_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_scaled_imu_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_scaled_imu_send(MAVLINK_COMM_1, packet1.time_boot_ms, packet1.xacc, packet1.yacc, packet1.zacc, packet1.xgyro, packet1.ygyro, packet1.zgyro, packet1.xmag, packet1.ymag, packet1.zmag); + mavlink_msg_scaled_imu_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_raw_imu(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_raw_imu_t packet_in = { + 93372036854775807ULL, + 17651, + 17755, + 17859, + 17963, + 18067, + 18171, + 18275, + 18379, + 18483, + }; + mavlink_raw_imu_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.time_usec = packet_in.time_usec; + packet1.xacc = packet_in.xacc; + packet1.yacc = packet_in.yacc; + packet1.zacc = packet_in.zacc; + packet1.xgyro = packet_in.xgyro; + packet1.ygyro = packet_in.ygyro; + packet1.zgyro = packet_in.zgyro; + packet1.xmag = packet_in.xmag; + packet1.ymag = packet_in.ymag; + packet1.zmag = packet_in.zmag; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_raw_imu_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_raw_imu_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_raw_imu_pack(system_id, component_id, &msg, packet1.time_usec, packet1.xacc, packet1.yacc, packet1.zacc, packet1.xgyro, packet1.ygyro, packet1.zgyro, packet1.xmag, packet1.ymag, packet1.zmag); + mavlink_msg_raw_imu_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_raw_imu_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.time_usec, packet1.xacc, packet1.yacc, packet1.zacc, packet1.xgyro, packet1.ygyro, packet1.zgyro, packet1.xmag, packet1.ymag, packet1.zmag); + mavlink_msg_raw_imu_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_raw_imu_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_raw_imu_send(MAVLINK_COMM_1, packet1.time_usec, packet1.xacc, packet1.yacc, packet1.zacc, packet1.xgyro, packet1.ygyro, packet1.zgyro, packet1.xmag, packet1.ymag, packet1.zmag); + mavlink_msg_raw_imu_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_raw_pressure(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_raw_pressure_t packet_in = { + 93372036854775807ULL, + 17651, + 17755, + 17859, + 17963, + }; + mavlink_raw_pressure_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.time_usec = packet_in.time_usec; + packet1.press_abs = packet_in.press_abs; + packet1.press_diff1 = packet_in.press_diff1; + packet1.press_diff2 = packet_in.press_diff2; + packet1.temperature = packet_in.temperature; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_raw_pressure_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_raw_pressure_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_raw_pressure_pack(system_id, component_id, &msg, packet1.time_usec, packet1.press_abs, packet1.press_diff1, packet1.press_diff2, packet1.temperature); + mavlink_msg_raw_pressure_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_raw_pressure_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.time_usec, packet1.press_abs, packet1.press_diff1, packet1.press_diff2, packet1.temperature); + mavlink_msg_raw_pressure_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_raw_pressure_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_raw_pressure_send(MAVLINK_COMM_1, packet1.time_usec, packet1.press_abs, packet1.press_diff1, packet1.press_diff2, packet1.temperature); + mavlink_msg_raw_pressure_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_scaled_pressure(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_scaled_pressure_t packet_in = { + 963497464, + 45.0, + 73.0, + 17859, + }; + mavlink_scaled_pressure_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.time_boot_ms = packet_in.time_boot_ms; + packet1.press_abs = packet_in.press_abs; + packet1.press_diff = packet_in.press_diff; + packet1.temperature = packet_in.temperature; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_scaled_pressure_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_scaled_pressure_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_scaled_pressure_pack(system_id, component_id, &msg, packet1.time_boot_ms, packet1.press_abs, packet1.press_diff, packet1.temperature); + mavlink_msg_scaled_pressure_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_scaled_pressure_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.time_boot_ms, packet1.press_abs, packet1.press_diff, packet1.temperature); + mavlink_msg_scaled_pressure_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_scaled_pressure_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_scaled_pressure_send(MAVLINK_COMM_1, packet1.time_boot_ms, packet1.press_abs, packet1.press_diff, packet1.temperature); + mavlink_msg_scaled_pressure_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_attitude(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_attitude_t packet_in = { + 963497464, + 45.0, + 73.0, + 101.0, + 129.0, + 157.0, + 185.0, + }; + mavlink_attitude_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.time_boot_ms = packet_in.time_boot_ms; + packet1.roll = packet_in.roll; + packet1.pitch = packet_in.pitch; + packet1.yaw = packet_in.yaw; + packet1.rollspeed = packet_in.rollspeed; + packet1.pitchspeed = packet_in.pitchspeed; + packet1.yawspeed = packet_in.yawspeed; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_attitude_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_attitude_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_attitude_pack(system_id, component_id, &msg, packet1.time_boot_ms, packet1.roll, packet1.pitch, packet1.yaw, packet1.rollspeed, packet1.pitchspeed, packet1.yawspeed); + mavlink_msg_attitude_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_attitude_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.time_boot_ms, packet1.roll, packet1.pitch, packet1.yaw, packet1.rollspeed, packet1.pitchspeed, packet1.yawspeed); + mavlink_msg_attitude_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_attitude_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_attitude_send(MAVLINK_COMM_1, packet1.time_boot_ms, packet1.roll, packet1.pitch, packet1.yaw, packet1.rollspeed, packet1.pitchspeed, packet1.yawspeed); + mavlink_msg_attitude_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_attitude_quaternion(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_attitude_quaternion_t packet_in = { + 963497464, + 45.0, + 73.0, + 101.0, + 129.0, + 157.0, + 185.0, + 213.0, + }; + mavlink_attitude_quaternion_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.time_boot_ms = packet_in.time_boot_ms; + packet1.q1 = packet_in.q1; + packet1.q2 = packet_in.q2; + packet1.q3 = packet_in.q3; + packet1.q4 = packet_in.q4; + packet1.rollspeed = packet_in.rollspeed; + packet1.pitchspeed = packet_in.pitchspeed; + packet1.yawspeed = packet_in.yawspeed; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_attitude_quaternion_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_attitude_quaternion_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_attitude_quaternion_pack(system_id, component_id, &msg, packet1.time_boot_ms, packet1.q1, packet1.q2, packet1.q3, packet1.q4, packet1.rollspeed, packet1.pitchspeed, packet1.yawspeed); + mavlink_msg_attitude_quaternion_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_attitude_quaternion_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.time_boot_ms, packet1.q1, packet1.q2, packet1.q3, packet1.q4, packet1.rollspeed, packet1.pitchspeed, packet1.yawspeed); + mavlink_msg_attitude_quaternion_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_attitude_quaternion_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_attitude_quaternion_send(MAVLINK_COMM_1, packet1.time_boot_ms, packet1.q1, packet1.q2, packet1.q3, packet1.q4, packet1.rollspeed, packet1.pitchspeed, packet1.yawspeed); + mavlink_msg_attitude_quaternion_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_local_position_ned(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_local_position_ned_t packet_in = { + 963497464, + 45.0, + 73.0, + 101.0, + 129.0, + 157.0, + 185.0, + }; + mavlink_local_position_ned_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.time_boot_ms = packet_in.time_boot_ms; + packet1.x = packet_in.x; + packet1.y = packet_in.y; + packet1.z = packet_in.z; + packet1.vx = packet_in.vx; + packet1.vy = packet_in.vy; + packet1.vz = packet_in.vz; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_local_position_ned_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_local_position_ned_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_local_position_ned_pack(system_id, component_id, &msg, packet1.time_boot_ms, packet1.x, packet1.y, packet1.z, packet1.vx, packet1.vy, packet1.vz); + mavlink_msg_local_position_ned_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_local_position_ned_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.time_boot_ms, packet1.x, packet1.y, packet1.z, packet1.vx, packet1.vy, packet1.vz); + mavlink_msg_local_position_ned_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_local_position_ned_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_local_position_ned_send(MAVLINK_COMM_1, packet1.time_boot_ms, packet1.x, packet1.y, packet1.z, packet1.vx, packet1.vy, packet1.vz); + mavlink_msg_local_position_ned_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_global_position_int(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_global_position_int_t packet_in = { + 963497464, + 963497672, + 963497880, + 963498088, + 963498296, + 18275, + 18379, + 18483, + 18587, + }; + mavlink_global_position_int_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.time_boot_ms = packet_in.time_boot_ms; + packet1.lat = packet_in.lat; + packet1.lon = packet_in.lon; + packet1.alt = packet_in.alt; + packet1.relative_alt = packet_in.relative_alt; + packet1.vx = packet_in.vx; + packet1.vy = packet_in.vy; + packet1.vz = packet_in.vz; + packet1.hdg = packet_in.hdg; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_global_position_int_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_global_position_int_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_global_position_int_pack(system_id, component_id, &msg, packet1.time_boot_ms, packet1.lat, packet1.lon, packet1.alt, packet1.relative_alt, packet1.vx, packet1.vy, packet1.vz, packet1.hdg); + mavlink_msg_global_position_int_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_global_position_int_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.time_boot_ms, packet1.lat, packet1.lon, packet1.alt, packet1.relative_alt, packet1.vx, packet1.vy, packet1.vz, packet1.hdg); + mavlink_msg_global_position_int_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_global_position_int_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_global_position_int_send(MAVLINK_COMM_1, packet1.time_boot_ms, packet1.lat, packet1.lon, packet1.alt, packet1.relative_alt, packet1.vx, packet1.vy, packet1.vz, packet1.hdg); + mavlink_msg_global_position_int_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_rc_channels_scaled(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_rc_channels_scaled_t packet_in = { + 963497464, + 17443, + 17547, + 17651, + 17755, + 17859, + 17963, + 18067, + 18171, + 65, + 132, + }; + mavlink_rc_channels_scaled_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.time_boot_ms = packet_in.time_boot_ms; + packet1.chan1_scaled = packet_in.chan1_scaled; + packet1.chan2_scaled = packet_in.chan2_scaled; + packet1.chan3_scaled = packet_in.chan3_scaled; + packet1.chan4_scaled = packet_in.chan4_scaled; + packet1.chan5_scaled = packet_in.chan5_scaled; + packet1.chan6_scaled = packet_in.chan6_scaled; + packet1.chan7_scaled = packet_in.chan7_scaled; + packet1.chan8_scaled = packet_in.chan8_scaled; + packet1.port = packet_in.port; + packet1.rssi = packet_in.rssi; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_rc_channels_scaled_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_rc_channels_scaled_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_rc_channels_scaled_pack(system_id, component_id, &msg, packet1.time_boot_ms, packet1.port, packet1.chan1_scaled, packet1.chan2_scaled, packet1.chan3_scaled, packet1.chan4_scaled, packet1.chan5_scaled, packet1.chan6_scaled, packet1.chan7_scaled, packet1.chan8_scaled, packet1.rssi); + mavlink_msg_rc_channels_scaled_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_rc_channels_scaled_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.time_boot_ms, packet1.port, packet1.chan1_scaled, packet1.chan2_scaled, packet1.chan3_scaled, packet1.chan4_scaled, packet1.chan5_scaled, packet1.chan6_scaled, packet1.chan7_scaled, packet1.chan8_scaled, packet1.rssi); + mavlink_msg_rc_channels_scaled_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_rc_channels_scaled_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_rc_channels_scaled_send(MAVLINK_COMM_1, packet1.time_boot_ms, packet1.port, packet1.chan1_scaled, packet1.chan2_scaled, packet1.chan3_scaled, packet1.chan4_scaled, packet1.chan5_scaled, packet1.chan6_scaled, packet1.chan7_scaled, packet1.chan8_scaled, packet1.rssi); + mavlink_msg_rc_channels_scaled_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_rc_channels_raw(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_rc_channels_raw_t packet_in = { + 963497464, + 17443, + 17547, + 17651, + 17755, + 17859, + 17963, + 18067, + 18171, + 65, + 132, + }; + mavlink_rc_channels_raw_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.time_boot_ms = packet_in.time_boot_ms; + packet1.chan1_raw = packet_in.chan1_raw; + packet1.chan2_raw = packet_in.chan2_raw; + packet1.chan3_raw = packet_in.chan3_raw; + packet1.chan4_raw = packet_in.chan4_raw; + packet1.chan5_raw = packet_in.chan5_raw; + packet1.chan6_raw = packet_in.chan6_raw; + packet1.chan7_raw = packet_in.chan7_raw; + packet1.chan8_raw = packet_in.chan8_raw; + packet1.port = packet_in.port; + packet1.rssi = packet_in.rssi; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_rc_channels_raw_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_rc_channels_raw_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_rc_channels_raw_pack(system_id, component_id, &msg, packet1.time_boot_ms, packet1.port, packet1.chan1_raw, packet1.chan2_raw, packet1.chan3_raw, packet1.chan4_raw, packet1.chan5_raw, packet1.chan6_raw, packet1.chan7_raw, packet1.chan8_raw, packet1.rssi); + mavlink_msg_rc_channels_raw_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_rc_channels_raw_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.time_boot_ms, packet1.port, packet1.chan1_raw, packet1.chan2_raw, packet1.chan3_raw, packet1.chan4_raw, packet1.chan5_raw, packet1.chan6_raw, packet1.chan7_raw, packet1.chan8_raw, packet1.rssi); + mavlink_msg_rc_channels_raw_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_rc_channels_raw_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_rc_channels_raw_send(MAVLINK_COMM_1, packet1.time_boot_ms, packet1.port, packet1.chan1_raw, packet1.chan2_raw, packet1.chan3_raw, packet1.chan4_raw, packet1.chan5_raw, packet1.chan6_raw, packet1.chan7_raw, packet1.chan8_raw, packet1.rssi); + mavlink_msg_rc_channels_raw_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_servo_output_raw(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_servo_output_raw_t packet_in = { + 963497464, + 17443, + 17547, + 17651, + 17755, + 17859, + 17963, + 18067, + 18171, + 65, + }; + mavlink_servo_output_raw_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.time_usec = packet_in.time_usec; + packet1.servo1_raw = packet_in.servo1_raw; + packet1.servo2_raw = packet_in.servo2_raw; + packet1.servo3_raw = packet_in.servo3_raw; + packet1.servo4_raw = packet_in.servo4_raw; + packet1.servo5_raw = packet_in.servo5_raw; + packet1.servo6_raw = packet_in.servo6_raw; + packet1.servo7_raw = packet_in.servo7_raw; + packet1.servo8_raw = packet_in.servo8_raw; + packet1.port = packet_in.port; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_servo_output_raw_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_servo_output_raw_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_servo_output_raw_pack(system_id, component_id, &msg, packet1.time_usec, packet1.port, packet1.servo1_raw, packet1.servo2_raw, packet1.servo3_raw, packet1.servo4_raw, packet1.servo5_raw, packet1.servo6_raw, packet1.servo7_raw, packet1.servo8_raw); + mavlink_msg_servo_output_raw_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_servo_output_raw_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.time_usec, packet1.port, packet1.servo1_raw, packet1.servo2_raw, packet1.servo3_raw, packet1.servo4_raw, packet1.servo5_raw, packet1.servo6_raw, packet1.servo7_raw, packet1.servo8_raw); + mavlink_msg_servo_output_raw_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_servo_output_raw_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_servo_output_raw_send(MAVLINK_COMM_1, packet1.time_usec, packet1.port, packet1.servo1_raw, packet1.servo2_raw, packet1.servo3_raw, packet1.servo4_raw, packet1.servo5_raw, packet1.servo6_raw, packet1.servo7_raw, packet1.servo8_raw); + mavlink_msg_servo_output_raw_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_mission_request_partial_list(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_mission_request_partial_list_t packet_in = { + 17235, + 17339, + 17, + 84, + }; + mavlink_mission_request_partial_list_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.start_index = packet_in.start_index; + packet1.end_index = packet_in.end_index; + packet1.target_system = packet_in.target_system; + packet1.target_component = packet_in.target_component; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_request_partial_list_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_mission_request_partial_list_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_request_partial_list_pack(system_id, component_id, &msg, packet1.target_system, packet1.target_component, packet1.start_index, packet1.end_index); + mavlink_msg_mission_request_partial_list_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_request_partial_list_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.target_system, packet1.target_component, packet1.start_index, packet1.end_index); + mavlink_msg_mission_request_partial_list_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_mission_request_partial_list_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_request_partial_list_send(MAVLINK_COMM_1, packet1.target_system, packet1.target_component, packet1.start_index, packet1.end_index); + mavlink_msg_mission_request_partial_list_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_mission_write_partial_list(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_mission_write_partial_list_t packet_in = { + 17235, + 17339, + 17, + 84, + }; + mavlink_mission_write_partial_list_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.start_index = packet_in.start_index; + packet1.end_index = packet_in.end_index; + packet1.target_system = packet_in.target_system; + packet1.target_component = packet_in.target_component; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_write_partial_list_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_mission_write_partial_list_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_write_partial_list_pack(system_id, component_id, &msg, packet1.target_system, packet1.target_component, packet1.start_index, packet1.end_index); + mavlink_msg_mission_write_partial_list_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_write_partial_list_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.target_system, packet1.target_component, packet1.start_index, packet1.end_index); + mavlink_msg_mission_write_partial_list_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_mission_write_partial_list_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_write_partial_list_send(MAVLINK_COMM_1, packet1.target_system, packet1.target_component, packet1.start_index, packet1.end_index); + mavlink_msg_mission_write_partial_list_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_mission_item(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_mission_item_t packet_in = { + 17.0, + 45.0, + 73.0, + 101.0, + 129.0, + 157.0, + 185.0, + 18691, + 18795, + 101, + 168, + 235, + 46, + 113, + }; + mavlink_mission_item_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.param1 = packet_in.param1; + packet1.param2 = packet_in.param2; + packet1.param3 = packet_in.param3; + packet1.param4 = packet_in.param4; + packet1.x = packet_in.x; + packet1.y = packet_in.y; + packet1.z = packet_in.z; + packet1.seq = packet_in.seq; + packet1.command = packet_in.command; + packet1.target_system = packet_in.target_system; + packet1.target_component = packet_in.target_component; + packet1.frame = packet_in.frame; + packet1.current = packet_in.current; + packet1.autocontinue = packet_in.autocontinue; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_item_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_mission_item_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_item_pack(system_id, component_id, &msg, packet1.target_system, packet1.target_component, packet1.seq, packet1.frame, packet1.command, packet1.current, packet1.autocontinue, packet1.param1, packet1.param2, packet1.param3, packet1.param4, packet1.x, packet1.y, packet1.z); + mavlink_msg_mission_item_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_item_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.target_system, packet1.target_component, packet1.seq, packet1.frame, packet1.command, packet1.current, packet1.autocontinue, packet1.param1, packet1.param2, packet1.param3, packet1.param4, packet1.x, packet1.y, packet1.z); + mavlink_msg_mission_item_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_mission_item_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_item_send(MAVLINK_COMM_1, packet1.target_system, packet1.target_component, packet1.seq, packet1.frame, packet1.command, packet1.current, packet1.autocontinue, packet1.param1, packet1.param2, packet1.param3, packet1.param4, packet1.x, packet1.y, packet1.z); + mavlink_msg_mission_item_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_mission_request(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_mission_request_t packet_in = { + 17235, + 139, + 206, + }; + mavlink_mission_request_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.seq = packet_in.seq; + packet1.target_system = packet_in.target_system; + packet1.target_component = packet_in.target_component; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_request_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_mission_request_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_request_pack(system_id, component_id, &msg, packet1.target_system, packet1.target_component, packet1.seq); + mavlink_msg_mission_request_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_request_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.target_system, packet1.target_component, packet1.seq); + mavlink_msg_mission_request_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_mission_request_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_request_send(MAVLINK_COMM_1, packet1.target_system, packet1.target_component, packet1.seq); + mavlink_msg_mission_request_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_mission_set_current(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_mission_set_current_t packet_in = { + 17235, + 139, + 206, + }; + mavlink_mission_set_current_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.seq = packet_in.seq; + packet1.target_system = packet_in.target_system; + packet1.target_component = packet_in.target_component; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_set_current_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_mission_set_current_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_set_current_pack(system_id, component_id, &msg, packet1.target_system, packet1.target_component, packet1.seq); + mavlink_msg_mission_set_current_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_set_current_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.target_system, packet1.target_component, packet1.seq); + mavlink_msg_mission_set_current_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_mission_set_current_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_set_current_send(MAVLINK_COMM_1, packet1.target_system, packet1.target_component, packet1.seq); + mavlink_msg_mission_set_current_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_mission_current(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_mission_current_t packet_in = { + 17235, + }; + mavlink_mission_current_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.seq = packet_in.seq; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_current_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_mission_current_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_current_pack(system_id, component_id, &msg, packet1.seq); + mavlink_msg_mission_current_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_current_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.seq); + mavlink_msg_mission_current_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_mission_current_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_current_send(MAVLINK_COMM_1, packet1.seq); + mavlink_msg_mission_current_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_mission_request_list(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_mission_request_list_t packet_in = { + 5, + 72, + }; + mavlink_mission_request_list_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.target_system = packet_in.target_system; + packet1.target_component = packet_in.target_component; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_request_list_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_mission_request_list_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_request_list_pack(system_id, component_id, &msg, packet1.target_system, packet1.target_component); + mavlink_msg_mission_request_list_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_request_list_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.target_system, packet1.target_component); + mavlink_msg_mission_request_list_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_mission_request_list_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_request_list_send(MAVLINK_COMM_1, packet1.target_system, packet1.target_component); + mavlink_msg_mission_request_list_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_mission_count(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_mission_count_t packet_in = { + 17235, + 139, + 206, + }; + mavlink_mission_count_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.count = packet_in.count; + packet1.target_system = packet_in.target_system; + packet1.target_component = packet_in.target_component; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_count_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_mission_count_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_count_pack(system_id, component_id, &msg, packet1.target_system, packet1.target_component, packet1.count); + mavlink_msg_mission_count_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_count_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.target_system, packet1.target_component, packet1.count); + mavlink_msg_mission_count_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_mission_count_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_count_send(MAVLINK_COMM_1, packet1.target_system, packet1.target_component, packet1.count); + mavlink_msg_mission_count_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_mission_clear_all(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_mission_clear_all_t packet_in = { + 5, + 72, + }; + mavlink_mission_clear_all_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.target_system = packet_in.target_system; + packet1.target_component = packet_in.target_component; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_clear_all_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_mission_clear_all_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_clear_all_pack(system_id, component_id, &msg, packet1.target_system, packet1.target_component); + mavlink_msg_mission_clear_all_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_clear_all_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.target_system, packet1.target_component); + mavlink_msg_mission_clear_all_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_mission_clear_all_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_clear_all_send(MAVLINK_COMM_1, packet1.target_system, packet1.target_component); + mavlink_msg_mission_clear_all_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_mission_item_reached(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_mission_item_reached_t packet_in = { + 17235, + }; + mavlink_mission_item_reached_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.seq = packet_in.seq; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_item_reached_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_mission_item_reached_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_item_reached_pack(system_id, component_id, &msg, packet1.seq); + mavlink_msg_mission_item_reached_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_item_reached_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.seq); + mavlink_msg_mission_item_reached_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_mission_item_reached_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_item_reached_send(MAVLINK_COMM_1, packet1.seq); + mavlink_msg_mission_item_reached_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_mission_ack(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_mission_ack_t packet_in = { + 5, + 72, + 139, + }; + mavlink_mission_ack_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.target_system = packet_in.target_system; + packet1.target_component = packet_in.target_component; + packet1.type = packet_in.type; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_ack_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_mission_ack_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_ack_pack(system_id, component_id, &msg, packet1.target_system, packet1.target_component, packet1.type); + mavlink_msg_mission_ack_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_ack_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.target_system, packet1.target_component, packet1.type); + mavlink_msg_mission_ack_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_mission_ack_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_mission_ack_send(MAVLINK_COMM_1, packet1.target_system, packet1.target_component, packet1.type); + mavlink_msg_mission_ack_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_set_gps_global_origin(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_set_gps_global_origin_t packet_in = { + 963497464, + 963497672, + 963497880, + 41, + }; + mavlink_set_gps_global_origin_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.latitude = packet_in.latitude; + packet1.longitude = packet_in.longitude; + packet1.altitude = packet_in.altitude; + packet1.target_system = packet_in.target_system; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_gps_global_origin_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_set_gps_global_origin_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_gps_global_origin_pack(system_id, component_id, &msg, packet1.target_system, packet1.latitude, packet1.longitude, packet1.altitude); + mavlink_msg_set_gps_global_origin_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_gps_global_origin_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.target_system, packet1.latitude, packet1.longitude, packet1.altitude); + mavlink_msg_set_gps_global_origin_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_set_gps_global_origin_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_gps_global_origin_send(MAVLINK_COMM_1, packet1.target_system, packet1.latitude, packet1.longitude, packet1.altitude); + mavlink_msg_set_gps_global_origin_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_gps_global_origin(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_gps_global_origin_t packet_in = { + 963497464, + 963497672, + 963497880, + }; + mavlink_gps_global_origin_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.latitude = packet_in.latitude; + packet1.longitude = packet_in.longitude; + packet1.altitude = packet_in.altitude; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_gps_global_origin_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_gps_global_origin_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_gps_global_origin_pack(system_id, component_id, &msg, packet1.latitude, packet1.longitude, packet1.altitude); + mavlink_msg_gps_global_origin_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_gps_global_origin_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.latitude, packet1.longitude, packet1.altitude); + mavlink_msg_gps_global_origin_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_gps_global_origin_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_gps_global_origin_send(MAVLINK_COMM_1, packet1.latitude, packet1.longitude, packet1.altitude); + mavlink_msg_gps_global_origin_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_set_local_position_setpoint(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_set_local_position_setpoint_t packet_in = { + 17.0, + 45.0, + 73.0, + 101.0, + 53, + 120, + 187, + }; + mavlink_set_local_position_setpoint_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.x = packet_in.x; + packet1.y = packet_in.y; + packet1.z = packet_in.z; + packet1.yaw = packet_in.yaw; + packet1.target_system = packet_in.target_system; + packet1.target_component = packet_in.target_component; + packet1.coordinate_frame = packet_in.coordinate_frame; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_local_position_setpoint_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_set_local_position_setpoint_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_local_position_setpoint_pack(system_id, component_id, &msg, packet1.target_system, packet1.target_component, packet1.coordinate_frame, packet1.x, packet1.y, packet1.z, packet1.yaw); + mavlink_msg_set_local_position_setpoint_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_local_position_setpoint_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.target_system, packet1.target_component, packet1.coordinate_frame, packet1.x, packet1.y, packet1.z, packet1.yaw); + mavlink_msg_set_local_position_setpoint_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_set_local_position_setpoint_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_local_position_setpoint_send(MAVLINK_COMM_1, packet1.target_system, packet1.target_component, packet1.coordinate_frame, packet1.x, packet1.y, packet1.z, packet1.yaw); + mavlink_msg_set_local_position_setpoint_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_local_position_setpoint(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_local_position_setpoint_t packet_in = { + 17.0, + 45.0, + 73.0, + 101.0, + 53, + }; + mavlink_local_position_setpoint_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.x = packet_in.x; + packet1.y = packet_in.y; + packet1.z = packet_in.z; + packet1.yaw = packet_in.yaw; + packet1.coordinate_frame = packet_in.coordinate_frame; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_local_position_setpoint_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_local_position_setpoint_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_local_position_setpoint_pack(system_id, component_id, &msg, packet1.coordinate_frame, packet1.x, packet1.y, packet1.z, packet1.yaw); + mavlink_msg_local_position_setpoint_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_local_position_setpoint_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.coordinate_frame, packet1.x, packet1.y, packet1.z, packet1.yaw); + mavlink_msg_local_position_setpoint_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_local_position_setpoint_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_local_position_setpoint_send(MAVLINK_COMM_1, packet1.coordinate_frame, packet1.x, packet1.y, packet1.z, packet1.yaw); + mavlink_msg_local_position_setpoint_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_global_position_setpoint_int(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_global_position_setpoint_int_t packet_in = { + 963497464, + 963497672, + 963497880, + 17859, + 175, + }; + mavlink_global_position_setpoint_int_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.latitude = packet_in.latitude; + packet1.longitude = packet_in.longitude; + packet1.altitude = packet_in.altitude; + packet1.yaw = packet_in.yaw; + packet1.coordinate_frame = packet_in.coordinate_frame; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_global_position_setpoint_int_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_global_position_setpoint_int_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_global_position_setpoint_int_pack(system_id, component_id, &msg, packet1.coordinate_frame, packet1.latitude, packet1.longitude, packet1.altitude, packet1.yaw); + mavlink_msg_global_position_setpoint_int_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_global_position_setpoint_int_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.coordinate_frame, packet1.latitude, packet1.longitude, packet1.altitude, packet1.yaw); + mavlink_msg_global_position_setpoint_int_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_global_position_setpoint_int_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_global_position_setpoint_int_send(MAVLINK_COMM_1, packet1.coordinate_frame, packet1.latitude, packet1.longitude, packet1.altitude, packet1.yaw); + mavlink_msg_global_position_setpoint_int_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_set_global_position_setpoint_int(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_set_global_position_setpoint_int_t packet_in = { + 963497464, + 963497672, + 963497880, + 17859, + 175, + }; + mavlink_set_global_position_setpoint_int_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.latitude = packet_in.latitude; + packet1.longitude = packet_in.longitude; + packet1.altitude = packet_in.altitude; + packet1.yaw = packet_in.yaw; + packet1.coordinate_frame = packet_in.coordinate_frame; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_global_position_setpoint_int_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_set_global_position_setpoint_int_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_global_position_setpoint_int_pack(system_id, component_id, &msg, packet1.coordinate_frame, packet1.latitude, packet1.longitude, packet1.altitude, packet1.yaw); + mavlink_msg_set_global_position_setpoint_int_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_global_position_setpoint_int_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.coordinate_frame, packet1.latitude, packet1.longitude, packet1.altitude, packet1.yaw); + mavlink_msg_set_global_position_setpoint_int_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_set_global_position_setpoint_int_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_global_position_setpoint_int_send(MAVLINK_COMM_1, packet1.coordinate_frame, packet1.latitude, packet1.longitude, packet1.altitude, packet1.yaw); + mavlink_msg_set_global_position_setpoint_int_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_safety_set_allowed_area(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_safety_set_allowed_area_t packet_in = { + 17.0, + 45.0, + 73.0, + 101.0, + 129.0, + 157.0, + 77, + 144, + 211, + }; + mavlink_safety_set_allowed_area_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.p1x = packet_in.p1x; + packet1.p1y = packet_in.p1y; + packet1.p1z = packet_in.p1z; + packet1.p2x = packet_in.p2x; + packet1.p2y = packet_in.p2y; + packet1.p2z = packet_in.p2z; + packet1.target_system = packet_in.target_system; + packet1.target_component = packet_in.target_component; + packet1.frame = packet_in.frame; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_safety_set_allowed_area_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_safety_set_allowed_area_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_safety_set_allowed_area_pack(system_id, component_id, &msg, packet1.target_system, packet1.target_component, packet1.frame, packet1.p1x, packet1.p1y, packet1.p1z, packet1.p2x, packet1.p2y, packet1.p2z); + mavlink_msg_safety_set_allowed_area_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_safety_set_allowed_area_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.target_system, packet1.target_component, packet1.frame, packet1.p1x, packet1.p1y, packet1.p1z, packet1.p2x, packet1.p2y, packet1.p2z); + mavlink_msg_safety_set_allowed_area_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_safety_set_allowed_area_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_safety_set_allowed_area_send(MAVLINK_COMM_1, packet1.target_system, packet1.target_component, packet1.frame, packet1.p1x, packet1.p1y, packet1.p1z, packet1.p2x, packet1.p2y, packet1.p2z); + mavlink_msg_safety_set_allowed_area_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_safety_allowed_area(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_safety_allowed_area_t packet_in = { + 17.0, + 45.0, + 73.0, + 101.0, + 129.0, + 157.0, + 77, + }; + mavlink_safety_allowed_area_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.p1x = packet_in.p1x; + packet1.p1y = packet_in.p1y; + packet1.p1z = packet_in.p1z; + packet1.p2x = packet_in.p2x; + packet1.p2y = packet_in.p2y; + packet1.p2z = packet_in.p2z; + packet1.frame = packet_in.frame; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_safety_allowed_area_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_safety_allowed_area_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_safety_allowed_area_pack(system_id, component_id, &msg, packet1.frame, packet1.p1x, packet1.p1y, packet1.p1z, packet1.p2x, packet1.p2y, packet1.p2z); + mavlink_msg_safety_allowed_area_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_safety_allowed_area_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.frame, packet1.p1x, packet1.p1y, packet1.p1z, packet1.p2x, packet1.p2y, packet1.p2z); + mavlink_msg_safety_allowed_area_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_safety_allowed_area_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_safety_allowed_area_send(MAVLINK_COMM_1, packet1.frame, packet1.p1x, packet1.p1y, packet1.p1z, packet1.p2x, packet1.p2y, packet1.p2z); + mavlink_msg_safety_allowed_area_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_set_roll_pitch_yaw_thrust(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_set_roll_pitch_yaw_thrust_t packet_in = { + 17.0, + 45.0, + 73.0, + 101.0, + 53, + 120, + }; + mavlink_set_roll_pitch_yaw_thrust_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.roll = packet_in.roll; + packet1.pitch = packet_in.pitch; + packet1.yaw = packet_in.yaw; + packet1.thrust = packet_in.thrust; + packet1.target_system = packet_in.target_system; + packet1.target_component = packet_in.target_component; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_roll_pitch_yaw_thrust_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_set_roll_pitch_yaw_thrust_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_roll_pitch_yaw_thrust_pack(system_id, component_id, &msg, packet1.target_system, packet1.target_component, packet1.roll, packet1.pitch, packet1.yaw, packet1.thrust); + mavlink_msg_set_roll_pitch_yaw_thrust_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_roll_pitch_yaw_thrust_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.target_system, packet1.target_component, packet1.roll, packet1.pitch, packet1.yaw, packet1.thrust); + mavlink_msg_set_roll_pitch_yaw_thrust_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_set_roll_pitch_yaw_thrust_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_roll_pitch_yaw_thrust_send(MAVLINK_COMM_1, packet1.target_system, packet1.target_component, packet1.roll, packet1.pitch, packet1.yaw, packet1.thrust); + mavlink_msg_set_roll_pitch_yaw_thrust_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_set_roll_pitch_yaw_speed_thrust(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_set_roll_pitch_yaw_speed_thrust_t packet_in = { + 17.0, + 45.0, + 73.0, + 101.0, + 53, + 120, + }; + mavlink_set_roll_pitch_yaw_speed_thrust_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.roll_speed = packet_in.roll_speed; + packet1.pitch_speed = packet_in.pitch_speed; + packet1.yaw_speed = packet_in.yaw_speed; + packet1.thrust = packet_in.thrust; + packet1.target_system = packet_in.target_system; + packet1.target_component = packet_in.target_component; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_roll_pitch_yaw_speed_thrust_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_set_roll_pitch_yaw_speed_thrust_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_roll_pitch_yaw_speed_thrust_pack(system_id, component_id, &msg, packet1.target_system, packet1.target_component, packet1.roll_speed, packet1.pitch_speed, packet1.yaw_speed, packet1.thrust); + mavlink_msg_set_roll_pitch_yaw_speed_thrust_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_roll_pitch_yaw_speed_thrust_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.target_system, packet1.target_component, packet1.roll_speed, packet1.pitch_speed, packet1.yaw_speed, packet1.thrust); + mavlink_msg_set_roll_pitch_yaw_speed_thrust_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_set_roll_pitch_yaw_speed_thrust_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_roll_pitch_yaw_speed_thrust_send(MAVLINK_COMM_1, packet1.target_system, packet1.target_component, packet1.roll_speed, packet1.pitch_speed, packet1.yaw_speed, packet1.thrust); + mavlink_msg_set_roll_pitch_yaw_speed_thrust_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_roll_pitch_yaw_thrust_setpoint(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_roll_pitch_yaw_thrust_setpoint_t packet_in = { + 963497464, + 45.0, + 73.0, + 101.0, + 129.0, + }; + mavlink_roll_pitch_yaw_thrust_setpoint_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.time_boot_ms = packet_in.time_boot_ms; + packet1.roll = packet_in.roll; + packet1.pitch = packet_in.pitch; + packet1.yaw = packet_in.yaw; + packet1.thrust = packet_in.thrust; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_roll_pitch_yaw_thrust_setpoint_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_roll_pitch_yaw_thrust_setpoint_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_roll_pitch_yaw_thrust_setpoint_pack(system_id, component_id, &msg, packet1.time_boot_ms, packet1.roll, packet1.pitch, packet1.yaw, packet1.thrust); + mavlink_msg_roll_pitch_yaw_thrust_setpoint_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_roll_pitch_yaw_thrust_setpoint_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.time_boot_ms, packet1.roll, packet1.pitch, packet1.yaw, packet1.thrust); + mavlink_msg_roll_pitch_yaw_thrust_setpoint_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_roll_pitch_yaw_thrust_setpoint_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_roll_pitch_yaw_thrust_setpoint_send(MAVLINK_COMM_1, packet1.time_boot_ms, packet1.roll, packet1.pitch, packet1.yaw, packet1.thrust); + mavlink_msg_roll_pitch_yaw_thrust_setpoint_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_roll_pitch_yaw_speed_thrust_setpoint(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_roll_pitch_yaw_speed_thrust_setpoint_t packet_in = { + 963497464, + 45.0, + 73.0, + 101.0, + 129.0, + }; + mavlink_roll_pitch_yaw_speed_thrust_setpoint_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.time_boot_ms = packet_in.time_boot_ms; + packet1.roll_speed = packet_in.roll_speed; + packet1.pitch_speed = packet_in.pitch_speed; + packet1.yaw_speed = packet_in.yaw_speed; + packet1.thrust = packet_in.thrust; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_pack(system_id, component_id, &msg, packet1.time_boot_ms, packet1.roll_speed, packet1.pitch_speed, packet1.yaw_speed, packet1.thrust); + mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.time_boot_ms, packet1.roll_speed, packet1.pitch_speed, packet1.yaw_speed, packet1.thrust); + mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_send(MAVLINK_COMM_1, packet1.time_boot_ms, packet1.roll_speed, packet1.pitch_speed, packet1.yaw_speed, packet1.thrust); + mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_set_quad_motors_setpoint(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_set_quad_motors_setpoint_t packet_in = { + 17235, + 17339, + 17443, + 17547, + 29, + }; + mavlink_set_quad_motors_setpoint_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.motor_front_nw = packet_in.motor_front_nw; + packet1.motor_right_ne = packet_in.motor_right_ne; + packet1.motor_back_se = packet_in.motor_back_se; + packet1.motor_left_sw = packet_in.motor_left_sw; + packet1.target_system = packet_in.target_system; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_quad_motors_setpoint_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_set_quad_motors_setpoint_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_quad_motors_setpoint_pack(system_id, component_id, &msg, packet1.target_system, packet1.motor_front_nw, packet1.motor_right_ne, packet1.motor_back_se, packet1.motor_left_sw); + mavlink_msg_set_quad_motors_setpoint_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_quad_motors_setpoint_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.target_system, packet1.motor_front_nw, packet1.motor_right_ne, packet1.motor_back_se, packet1.motor_left_sw); + mavlink_msg_set_quad_motors_setpoint_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_set_quad_motors_setpoint_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_quad_motors_setpoint_send(MAVLINK_COMM_1, packet1.target_system, packet1.motor_front_nw, packet1.motor_right_ne, packet1.motor_back_se, packet1.motor_left_sw); + mavlink_msg_set_quad_motors_setpoint_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_set_quad_swarm_roll_pitch_yaw_thrust(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_set_quad_swarm_roll_pitch_yaw_thrust_t packet_in = { + { 17235, 17236, 17237, 17238 }, + { 17651, 17652, 17653, 17654 }, + { 18067, 18068, 18069, 18070 }, + { 18483, 18484, 18485, 18486 }, + 101, + 168, + }; + mavlink_set_quad_swarm_roll_pitch_yaw_thrust_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.group = packet_in.group; + packet1.mode = packet_in.mode; + + mav_array_memcpy(packet1.roll, packet_in.roll, sizeof(int16_t) * 4); + mav_array_memcpy(packet1.pitch, packet_in.pitch, sizeof(int16_t) * 4); + mav_array_memcpy(packet1.yaw, packet_in.yaw, sizeof(int16_t) * 4); + mav_array_memcpy(packet1.thrust, packet_in.thrust, sizeof(uint16_t) * 4); + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_pack(system_id, component_id, &msg, packet1.group, packet1.mode, packet1.roll, packet1.pitch, packet1.yaw, packet1.thrust); + mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.group, packet1.mode, packet1.roll, packet1.pitch, packet1.yaw, packet1.thrust); + mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_send(MAVLINK_COMM_1, packet1.group, packet1.mode, packet1.roll, packet1.pitch, packet1.yaw, packet1.thrust); + mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_nav_controller_output(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_nav_controller_output_t packet_in = { + 17.0, + 45.0, + 73.0, + 101.0, + 129.0, + 18275, + 18379, + 18483, + }; + mavlink_nav_controller_output_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.nav_roll = packet_in.nav_roll; + packet1.nav_pitch = packet_in.nav_pitch; + packet1.alt_error = packet_in.alt_error; + packet1.aspd_error = packet_in.aspd_error; + packet1.xtrack_error = packet_in.xtrack_error; + packet1.nav_bearing = packet_in.nav_bearing; + packet1.target_bearing = packet_in.target_bearing; + packet1.wp_dist = packet_in.wp_dist; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_nav_controller_output_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_nav_controller_output_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_nav_controller_output_pack(system_id, component_id, &msg, packet1.nav_roll, packet1.nav_pitch, packet1.nav_bearing, packet1.target_bearing, packet1.wp_dist, packet1.alt_error, packet1.aspd_error, packet1.xtrack_error); + mavlink_msg_nav_controller_output_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_nav_controller_output_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.nav_roll, packet1.nav_pitch, packet1.nav_bearing, packet1.target_bearing, packet1.wp_dist, packet1.alt_error, packet1.aspd_error, packet1.xtrack_error); + mavlink_msg_nav_controller_output_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_nav_controller_output_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_nav_controller_output_send(MAVLINK_COMM_1, packet1.nav_roll, packet1.nav_pitch, packet1.nav_bearing, packet1.target_bearing, packet1.wp_dist, packet1.alt_error, packet1.aspd_error, packet1.xtrack_error); + mavlink_msg_nav_controller_output_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_set_quad_swarm_led_roll_pitch_yaw_thrust(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_set_quad_swarm_led_roll_pitch_yaw_thrust_t packet_in = { + { 17235, 17236, 17237, 17238 }, + { 17651, 17652, 17653, 17654 }, + { 18067, 18068, 18069, 18070 }, + { 18483, 18484, 18485, 18486 }, + 101, + 168, + { 235, 236, 237, 238 }, + { 247, 248, 249, 250 }, + { 3, 4, 5, 6 }, + }; + mavlink_set_quad_swarm_led_roll_pitch_yaw_thrust_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.group = packet_in.group; + packet1.mode = packet_in.mode; + + mav_array_memcpy(packet1.roll, packet_in.roll, sizeof(int16_t) * 4); + mav_array_memcpy(packet1.pitch, packet_in.pitch, sizeof(int16_t) * 4); + mav_array_memcpy(packet1.yaw, packet_in.yaw, sizeof(int16_t) * 4); + mav_array_memcpy(packet1.thrust, packet_in.thrust, sizeof(uint16_t) * 4); + mav_array_memcpy(packet1.led_red, packet_in.led_red, sizeof(uint8_t) * 4); + mav_array_memcpy(packet1.led_blue, packet_in.led_blue, sizeof(uint8_t) * 4); + mav_array_memcpy(packet1.led_green, packet_in.led_green, sizeof(uint8_t) * 4); + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_pack(system_id, component_id, &msg, packet1.group, packet1.mode, packet1.led_red, packet1.led_blue, packet1.led_green, packet1.roll, packet1.pitch, packet1.yaw, packet1.thrust); + mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.group, packet1.mode, packet1.led_red, packet1.led_blue, packet1.led_green, packet1.roll, packet1.pitch, packet1.yaw, packet1.thrust); + mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_send(MAVLINK_COMM_1, packet1.group, packet1.mode, packet1.led_red, packet1.led_blue, packet1.led_green, packet1.roll, packet1.pitch, packet1.yaw, packet1.thrust); + mavlink_msg_set_quad_swarm_led_roll_pitch_yaw_thrust_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_state_correction(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_state_correction_t packet_in = { + 17.0, + 45.0, + 73.0, + 101.0, + 129.0, + 157.0, + 185.0, + 213.0, + 241.0, + }; + mavlink_state_correction_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.xErr = packet_in.xErr; + packet1.yErr = packet_in.yErr; + packet1.zErr = packet_in.zErr; + packet1.rollErr = packet_in.rollErr; + packet1.pitchErr = packet_in.pitchErr; + packet1.yawErr = packet_in.yawErr; + packet1.vxErr = packet_in.vxErr; + packet1.vyErr = packet_in.vyErr; + packet1.vzErr = packet_in.vzErr; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_state_correction_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_state_correction_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_state_correction_pack(system_id, component_id, &msg, packet1.xErr, packet1.yErr, packet1.zErr, packet1.rollErr, packet1.pitchErr, packet1.yawErr, packet1.vxErr, packet1.vyErr, packet1.vzErr); + mavlink_msg_state_correction_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_state_correction_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.xErr, packet1.yErr, packet1.zErr, packet1.rollErr, packet1.pitchErr, packet1.yawErr, packet1.vxErr, packet1.vyErr, packet1.vzErr); + mavlink_msg_state_correction_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_state_correction_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_state_correction_send(MAVLINK_COMM_1, packet1.xErr, packet1.yErr, packet1.zErr, packet1.rollErr, packet1.pitchErr, packet1.yawErr, packet1.vxErr, packet1.vyErr, packet1.vzErr); + mavlink_msg_state_correction_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_request_data_stream(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_request_data_stream_t packet_in = { + 17235, + 139, + 206, + 17, + 84, + }; + mavlink_request_data_stream_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.req_message_rate = packet_in.req_message_rate; + packet1.target_system = packet_in.target_system; + packet1.target_component = packet_in.target_component; + packet1.req_stream_id = packet_in.req_stream_id; + packet1.start_stop = packet_in.start_stop; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_request_data_stream_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_request_data_stream_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_request_data_stream_pack(system_id, component_id, &msg, packet1.target_system, packet1.target_component, packet1.req_stream_id, packet1.req_message_rate, packet1.start_stop); + mavlink_msg_request_data_stream_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_request_data_stream_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.target_system, packet1.target_component, packet1.req_stream_id, packet1.req_message_rate, packet1.start_stop); + mavlink_msg_request_data_stream_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_request_data_stream_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_request_data_stream_send(MAVLINK_COMM_1, packet1.target_system, packet1.target_component, packet1.req_stream_id, packet1.req_message_rate, packet1.start_stop); + mavlink_msg_request_data_stream_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_data_stream(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_data_stream_t packet_in = { + 17235, + 139, + 206, + }; + mavlink_data_stream_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.message_rate = packet_in.message_rate; + packet1.stream_id = packet_in.stream_id; + packet1.on_off = packet_in.on_off; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_data_stream_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_data_stream_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_data_stream_pack(system_id, component_id, &msg, packet1.stream_id, packet1.message_rate, packet1.on_off); + mavlink_msg_data_stream_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_data_stream_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.stream_id, packet1.message_rate, packet1.on_off); + mavlink_msg_data_stream_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_data_stream_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_data_stream_send(MAVLINK_COMM_1, packet1.stream_id, packet1.message_rate, packet1.on_off); + mavlink_msg_data_stream_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_manual_control(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_manual_control_t packet_in = { + 17.0, + 45.0, + 73.0, + 101.0, + 53, + 120, + 187, + 254, + 65, + }; + mavlink_manual_control_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.roll = packet_in.roll; + packet1.pitch = packet_in.pitch; + packet1.yaw = packet_in.yaw; + packet1.thrust = packet_in.thrust; + packet1.target = packet_in.target; + packet1.roll_manual = packet_in.roll_manual; + packet1.pitch_manual = packet_in.pitch_manual; + packet1.yaw_manual = packet_in.yaw_manual; + packet1.thrust_manual = packet_in.thrust_manual; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_manual_control_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_manual_control_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_manual_control_pack(system_id, component_id, &msg, packet1.target, packet1.roll, packet1.pitch, packet1.yaw, packet1.thrust, packet1.roll_manual, packet1.pitch_manual, packet1.yaw_manual, packet1.thrust_manual); + mavlink_msg_manual_control_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_manual_control_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.target, packet1.roll, packet1.pitch, packet1.yaw, packet1.thrust, packet1.roll_manual, packet1.pitch_manual, packet1.yaw_manual, packet1.thrust_manual); + mavlink_msg_manual_control_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_manual_control_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_manual_control_send(MAVLINK_COMM_1, packet1.target, packet1.roll, packet1.pitch, packet1.yaw, packet1.thrust, packet1.roll_manual, packet1.pitch_manual, packet1.yaw_manual, packet1.thrust_manual); + mavlink_msg_manual_control_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_rc_channels_override(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_rc_channels_override_t packet_in = { + 17235, + 17339, + 17443, + 17547, + 17651, + 17755, + 17859, + 17963, + 53, + 120, + }; + mavlink_rc_channels_override_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.chan1_raw = packet_in.chan1_raw; + packet1.chan2_raw = packet_in.chan2_raw; + packet1.chan3_raw = packet_in.chan3_raw; + packet1.chan4_raw = packet_in.chan4_raw; + packet1.chan5_raw = packet_in.chan5_raw; + packet1.chan6_raw = packet_in.chan6_raw; + packet1.chan7_raw = packet_in.chan7_raw; + packet1.chan8_raw = packet_in.chan8_raw; + packet1.target_system = packet_in.target_system; + packet1.target_component = packet_in.target_component; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_rc_channels_override_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_rc_channels_override_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_rc_channels_override_pack(system_id, component_id, &msg, packet1.target_system, packet1.target_component, packet1.chan1_raw, packet1.chan2_raw, packet1.chan3_raw, packet1.chan4_raw, packet1.chan5_raw, packet1.chan6_raw, packet1.chan7_raw, packet1.chan8_raw); + mavlink_msg_rc_channels_override_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_rc_channels_override_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.target_system, packet1.target_component, packet1.chan1_raw, packet1.chan2_raw, packet1.chan3_raw, packet1.chan4_raw, packet1.chan5_raw, packet1.chan6_raw, packet1.chan7_raw, packet1.chan8_raw); + mavlink_msg_rc_channels_override_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_rc_channels_override_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_rc_channels_override_send(MAVLINK_COMM_1, packet1.target_system, packet1.target_component, packet1.chan1_raw, packet1.chan2_raw, packet1.chan3_raw, packet1.chan4_raw, packet1.chan5_raw, packet1.chan6_raw, packet1.chan7_raw, packet1.chan8_raw); + mavlink_msg_rc_channels_override_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_vfr_hud(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_vfr_hud_t packet_in = { + 17.0, + 45.0, + 73.0, + 101.0, + 18067, + 18171, + }; + mavlink_vfr_hud_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.airspeed = packet_in.airspeed; + packet1.groundspeed = packet_in.groundspeed; + packet1.alt = packet_in.alt; + packet1.climb = packet_in.climb; + packet1.heading = packet_in.heading; + packet1.throttle = packet_in.throttle; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_vfr_hud_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_vfr_hud_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_vfr_hud_pack(system_id, component_id, &msg, packet1.airspeed, packet1.groundspeed, packet1.heading, packet1.throttle, packet1.alt, packet1.climb); + mavlink_msg_vfr_hud_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_vfr_hud_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.airspeed, packet1.groundspeed, packet1.heading, packet1.throttle, packet1.alt, packet1.climb); + mavlink_msg_vfr_hud_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_vfr_hud_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_vfr_hud_send(MAVLINK_COMM_1, packet1.airspeed, packet1.groundspeed, packet1.heading, packet1.throttle, packet1.alt, packet1.climb); + mavlink_msg_vfr_hud_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_command_long(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_command_long_t packet_in = { + 17.0, + 45.0, + 73.0, + 101.0, + 129.0, + 157.0, + 185.0, + 18691, + 223, + 34, + 101, + }; + mavlink_command_long_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.param1 = packet_in.param1; + packet1.param2 = packet_in.param2; + packet1.param3 = packet_in.param3; + packet1.param4 = packet_in.param4; + packet1.param5 = packet_in.param5; + packet1.param6 = packet_in.param6; + packet1.param7 = packet_in.param7; + packet1.command = packet_in.command; + packet1.target_system = packet_in.target_system; + packet1.target_component = packet_in.target_component; + packet1.confirmation = packet_in.confirmation; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_command_long_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_command_long_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_command_long_pack(system_id, component_id, &msg, packet1.target_system, packet1.target_component, packet1.command, packet1.confirmation, packet1.param1, packet1.param2, packet1.param3, packet1.param4, packet1.param5, packet1.param6, packet1.param7); + mavlink_msg_command_long_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_command_long_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.target_system, packet1.target_component, packet1.command, packet1.confirmation, packet1.param1, packet1.param2, packet1.param3, packet1.param4, packet1.param5, packet1.param6, packet1.param7); + mavlink_msg_command_long_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_command_long_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_command_long_send(MAVLINK_COMM_1, packet1.target_system, packet1.target_component, packet1.command, packet1.confirmation, packet1.param1, packet1.param2, packet1.param3, packet1.param4, packet1.param5, packet1.param6, packet1.param7); + mavlink_msg_command_long_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_command_ack(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_command_ack_t packet_in = { + 17235, + 139, + }; + mavlink_command_ack_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.command = packet_in.command; + packet1.result = packet_in.result; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_command_ack_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_command_ack_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_command_ack_pack(system_id, component_id, &msg, packet1.command, packet1.result); + mavlink_msg_command_ack_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_command_ack_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.command, packet1.result); + mavlink_msg_command_ack_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_command_ack_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_command_ack_send(MAVLINK_COMM_1, packet1.command, packet1.result); + mavlink_msg_command_ack_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_local_position_ned_system_global_offset(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_local_position_ned_system_global_offset_t packet_in = { + 963497464, + 45.0, + 73.0, + 101.0, + 129.0, + 157.0, + 185.0, + }; + mavlink_local_position_ned_system_global_offset_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.time_boot_ms = packet_in.time_boot_ms; + packet1.x = packet_in.x; + packet1.y = packet_in.y; + packet1.z = packet_in.z; + packet1.roll = packet_in.roll; + packet1.pitch = packet_in.pitch; + packet1.yaw = packet_in.yaw; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_local_position_ned_system_global_offset_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_local_position_ned_system_global_offset_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_local_position_ned_system_global_offset_pack(system_id, component_id, &msg, packet1.time_boot_ms, packet1.x, packet1.y, packet1.z, packet1.roll, packet1.pitch, packet1.yaw); + mavlink_msg_local_position_ned_system_global_offset_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_local_position_ned_system_global_offset_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.time_boot_ms, packet1.x, packet1.y, packet1.z, packet1.roll, packet1.pitch, packet1.yaw); + mavlink_msg_local_position_ned_system_global_offset_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_local_position_ned_system_global_offset_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_local_position_ned_system_global_offset_send(MAVLINK_COMM_1, packet1.time_boot_ms, packet1.x, packet1.y, packet1.z, packet1.roll, packet1.pitch, packet1.yaw); + mavlink_msg_local_position_ned_system_global_offset_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_hil_state(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_hil_state_t packet_in = { + 93372036854775807ULL, + 73.0, + 101.0, + 129.0, + 157.0, + 185.0, + 213.0, + 963499128, + 963499336, + 963499544, + 19523, + 19627, + 19731, + 19835, + 19939, + 20043, + }; + mavlink_hil_state_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.time_usec = packet_in.time_usec; + packet1.roll = packet_in.roll; + packet1.pitch = packet_in.pitch; + packet1.yaw = packet_in.yaw; + packet1.rollspeed = packet_in.rollspeed; + packet1.pitchspeed = packet_in.pitchspeed; + packet1.yawspeed = packet_in.yawspeed; + packet1.lat = packet_in.lat; + packet1.lon = packet_in.lon; + packet1.alt = packet_in.alt; + packet1.vx = packet_in.vx; + packet1.vy = packet_in.vy; + packet1.vz = packet_in.vz; + packet1.xacc = packet_in.xacc; + packet1.yacc = packet_in.yacc; + packet1.zacc = packet_in.zacc; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_hil_state_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_hil_state_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_hil_state_pack(system_id, component_id, &msg, packet1.time_usec, packet1.roll, packet1.pitch, packet1.yaw, packet1.rollspeed, packet1.pitchspeed, packet1.yawspeed, packet1.lat, packet1.lon, packet1.alt, packet1.vx, packet1.vy, packet1.vz, packet1.xacc, packet1.yacc, packet1.zacc); + mavlink_msg_hil_state_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_hil_state_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.time_usec, packet1.roll, packet1.pitch, packet1.yaw, packet1.rollspeed, packet1.pitchspeed, packet1.yawspeed, packet1.lat, packet1.lon, packet1.alt, packet1.vx, packet1.vy, packet1.vz, packet1.xacc, packet1.yacc, packet1.zacc); + mavlink_msg_hil_state_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_hil_state_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_hil_state_send(MAVLINK_COMM_1, packet1.time_usec, packet1.roll, packet1.pitch, packet1.yaw, packet1.rollspeed, packet1.pitchspeed, packet1.yawspeed, packet1.lat, packet1.lon, packet1.alt, packet1.vx, packet1.vy, packet1.vz, packet1.xacc, packet1.yacc, packet1.zacc); + mavlink_msg_hil_state_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_hil_controls(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_hil_controls_t packet_in = { + 93372036854775807ULL, + 73.0, + 101.0, + 129.0, + 157.0, + 185.0, + 213.0, + 241.0, + 269.0, + 125, + 192, + }; + mavlink_hil_controls_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.time_usec = packet_in.time_usec; + packet1.roll_ailerons = packet_in.roll_ailerons; + packet1.pitch_elevator = packet_in.pitch_elevator; + packet1.yaw_rudder = packet_in.yaw_rudder; + packet1.throttle = packet_in.throttle; + packet1.aux1 = packet_in.aux1; + packet1.aux2 = packet_in.aux2; + packet1.aux3 = packet_in.aux3; + packet1.aux4 = packet_in.aux4; + packet1.mode = packet_in.mode; + packet1.nav_mode = packet_in.nav_mode; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_hil_controls_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_hil_controls_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_hil_controls_pack(system_id, component_id, &msg, packet1.time_usec, packet1.roll_ailerons, packet1.pitch_elevator, packet1.yaw_rudder, packet1.throttle, packet1.aux1, packet1.aux2, packet1.aux3, packet1.aux4, packet1.mode, packet1.nav_mode); + mavlink_msg_hil_controls_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_hil_controls_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.time_usec, packet1.roll_ailerons, packet1.pitch_elevator, packet1.yaw_rudder, packet1.throttle, packet1.aux1, packet1.aux2, packet1.aux3, packet1.aux4, packet1.mode, packet1.nav_mode); + mavlink_msg_hil_controls_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_hil_controls_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_hil_controls_send(MAVLINK_COMM_1, packet1.time_usec, packet1.roll_ailerons, packet1.pitch_elevator, packet1.yaw_rudder, packet1.throttle, packet1.aux1, packet1.aux2, packet1.aux3, packet1.aux4, packet1.mode, packet1.nav_mode); + mavlink_msg_hil_controls_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_hil_rc_inputs_raw(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_hil_rc_inputs_raw_t packet_in = { + 93372036854775807ULL, + 17651, + 17755, + 17859, + 17963, + 18067, + 18171, + 18275, + 18379, + 18483, + 18587, + 18691, + 18795, + 101, + }; + mavlink_hil_rc_inputs_raw_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.time_usec = packet_in.time_usec; + packet1.chan1_raw = packet_in.chan1_raw; + packet1.chan2_raw = packet_in.chan2_raw; + packet1.chan3_raw = packet_in.chan3_raw; + packet1.chan4_raw = packet_in.chan4_raw; + packet1.chan5_raw = packet_in.chan5_raw; + packet1.chan6_raw = packet_in.chan6_raw; + packet1.chan7_raw = packet_in.chan7_raw; + packet1.chan8_raw = packet_in.chan8_raw; + packet1.chan9_raw = packet_in.chan9_raw; + packet1.chan10_raw = packet_in.chan10_raw; + packet1.chan11_raw = packet_in.chan11_raw; + packet1.chan12_raw = packet_in.chan12_raw; + packet1.rssi = packet_in.rssi; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_hil_rc_inputs_raw_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_hil_rc_inputs_raw_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_hil_rc_inputs_raw_pack(system_id, component_id, &msg, packet1.time_usec, packet1.chan1_raw, packet1.chan2_raw, packet1.chan3_raw, packet1.chan4_raw, packet1.chan5_raw, packet1.chan6_raw, packet1.chan7_raw, packet1.chan8_raw, packet1.chan9_raw, packet1.chan10_raw, packet1.chan11_raw, packet1.chan12_raw, packet1.rssi); + mavlink_msg_hil_rc_inputs_raw_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_hil_rc_inputs_raw_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.time_usec, packet1.chan1_raw, packet1.chan2_raw, packet1.chan3_raw, packet1.chan4_raw, packet1.chan5_raw, packet1.chan6_raw, packet1.chan7_raw, packet1.chan8_raw, packet1.chan9_raw, packet1.chan10_raw, packet1.chan11_raw, packet1.chan12_raw, packet1.rssi); + mavlink_msg_hil_rc_inputs_raw_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_hil_rc_inputs_raw_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_hil_rc_inputs_raw_send(MAVLINK_COMM_1, packet1.time_usec, packet1.chan1_raw, packet1.chan2_raw, packet1.chan3_raw, packet1.chan4_raw, packet1.chan5_raw, packet1.chan6_raw, packet1.chan7_raw, packet1.chan8_raw, packet1.chan9_raw, packet1.chan10_raw, packet1.chan11_raw, packet1.chan12_raw, packet1.rssi); + mavlink_msg_hil_rc_inputs_raw_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_optical_flow(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_optical_flow_t packet_in = { + 93372036854775807ULL, + 73.0, + 101.0, + 129.0, + 18275, + 18379, + 77, + 144, + }; + mavlink_optical_flow_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.time_usec = packet_in.time_usec; + packet1.flow_comp_m_x = packet_in.flow_comp_m_x; + packet1.flow_comp_m_y = packet_in.flow_comp_m_y; + packet1.ground_distance = packet_in.ground_distance; + packet1.flow_x = packet_in.flow_x; + packet1.flow_y = packet_in.flow_y; + packet1.sensor_id = packet_in.sensor_id; + packet1.quality = packet_in.quality; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_optical_flow_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_optical_flow_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_optical_flow_pack(system_id, component_id, &msg, packet1.time_usec, packet1.sensor_id, packet1.flow_x, packet1.flow_y, packet1.flow_comp_m_x, packet1.flow_comp_m_y, packet1.quality, packet1.ground_distance); + mavlink_msg_optical_flow_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_optical_flow_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.time_usec, packet1.sensor_id, packet1.flow_x, packet1.flow_y, packet1.flow_comp_m_x, packet1.flow_comp_m_y, packet1.quality, packet1.ground_distance); + mavlink_msg_optical_flow_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_optical_flow_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_optical_flow_send(MAVLINK_COMM_1, packet1.time_usec, packet1.sensor_id, packet1.flow_x, packet1.flow_y, packet1.flow_comp_m_x, packet1.flow_comp_m_y, packet1.quality, packet1.ground_distance); + mavlink_msg_optical_flow_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_global_vision_position_estimate(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_global_vision_position_estimate_t packet_in = { + 93372036854775807ULL, + 73.0, + 101.0, + 129.0, + 157.0, + 185.0, + 213.0, + }; + mavlink_global_vision_position_estimate_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.usec = packet_in.usec; + packet1.x = packet_in.x; + packet1.y = packet_in.y; + packet1.z = packet_in.z; + packet1.roll = packet_in.roll; + packet1.pitch = packet_in.pitch; + packet1.yaw = packet_in.yaw; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_global_vision_position_estimate_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_global_vision_position_estimate_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_global_vision_position_estimate_pack(system_id, component_id, &msg, packet1.usec, packet1.x, packet1.y, packet1.z, packet1.roll, packet1.pitch, packet1.yaw); + mavlink_msg_global_vision_position_estimate_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_global_vision_position_estimate_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.usec, packet1.x, packet1.y, packet1.z, packet1.roll, packet1.pitch, packet1.yaw); + mavlink_msg_global_vision_position_estimate_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_global_vision_position_estimate_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_global_vision_position_estimate_send(MAVLINK_COMM_1, packet1.usec, packet1.x, packet1.y, packet1.z, packet1.roll, packet1.pitch, packet1.yaw); + mavlink_msg_global_vision_position_estimate_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_vision_position_estimate(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_vision_position_estimate_t packet_in = { + 93372036854775807ULL, + 73.0, + 101.0, + 129.0, + 157.0, + 185.0, + 213.0, + }; + mavlink_vision_position_estimate_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.usec = packet_in.usec; + packet1.x = packet_in.x; + packet1.y = packet_in.y; + packet1.z = packet_in.z; + packet1.roll = packet_in.roll; + packet1.pitch = packet_in.pitch; + packet1.yaw = packet_in.yaw; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_vision_position_estimate_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_vision_position_estimate_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_vision_position_estimate_pack(system_id, component_id, &msg, packet1.usec, packet1.x, packet1.y, packet1.z, packet1.roll, packet1.pitch, packet1.yaw); + mavlink_msg_vision_position_estimate_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_vision_position_estimate_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.usec, packet1.x, packet1.y, packet1.z, packet1.roll, packet1.pitch, packet1.yaw); + mavlink_msg_vision_position_estimate_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_vision_position_estimate_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_vision_position_estimate_send(MAVLINK_COMM_1, packet1.usec, packet1.x, packet1.y, packet1.z, packet1.roll, packet1.pitch, packet1.yaw); + mavlink_msg_vision_position_estimate_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_vision_speed_estimate(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_vision_speed_estimate_t packet_in = { + 93372036854775807ULL, + 73.0, + 101.0, + 129.0, + }; + mavlink_vision_speed_estimate_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.usec = packet_in.usec; + packet1.x = packet_in.x; + packet1.y = packet_in.y; + packet1.z = packet_in.z; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_vision_speed_estimate_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_vision_speed_estimate_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_vision_speed_estimate_pack(system_id, component_id, &msg, packet1.usec, packet1.x, packet1.y, packet1.z); + mavlink_msg_vision_speed_estimate_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_vision_speed_estimate_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.usec, packet1.x, packet1.y, packet1.z); + mavlink_msg_vision_speed_estimate_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_vision_speed_estimate_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_vision_speed_estimate_send(MAVLINK_COMM_1, packet1.usec, packet1.x, packet1.y, packet1.z); + mavlink_msg_vision_speed_estimate_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_vicon_position_estimate(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_vicon_position_estimate_t packet_in = { + 93372036854775807ULL, + 73.0, + 101.0, + 129.0, + 157.0, + 185.0, + 213.0, + }; + mavlink_vicon_position_estimate_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.usec = packet_in.usec; + packet1.x = packet_in.x; + packet1.y = packet_in.y; + packet1.z = packet_in.z; + packet1.roll = packet_in.roll; + packet1.pitch = packet_in.pitch; + packet1.yaw = packet_in.yaw; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_vicon_position_estimate_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_vicon_position_estimate_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_vicon_position_estimate_pack(system_id, component_id, &msg, packet1.usec, packet1.x, packet1.y, packet1.z, packet1.roll, packet1.pitch, packet1.yaw); + mavlink_msg_vicon_position_estimate_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_vicon_position_estimate_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.usec, packet1.x, packet1.y, packet1.z, packet1.roll, packet1.pitch, packet1.yaw); + mavlink_msg_vicon_position_estimate_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_vicon_position_estimate_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_vicon_position_estimate_send(MAVLINK_COMM_1, packet1.usec, packet1.x, packet1.y, packet1.z, packet1.roll, packet1.pitch, packet1.yaw); + mavlink_msg_vicon_position_estimate_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_memory_vect(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_memory_vect_t packet_in = { + 17235, + 139, + 206, + { 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48 }, + }; + mavlink_memory_vect_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.address = packet_in.address; + packet1.ver = packet_in.ver; + packet1.type = packet_in.type; + + mav_array_memcpy(packet1.value, packet_in.value, sizeof(int8_t) * 32); + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_memory_vect_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_memory_vect_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_memory_vect_pack(system_id, component_id, &msg, packet1.address, packet1.ver, packet1.type, packet1.value); + mavlink_msg_memory_vect_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_memory_vect_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.address, packet1.ver, packet1.type, packet1.value); + mavlink_msg_memory_vect_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_memory_vect_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_memory_vect_send(MAVLINK_COMM_1, packet1.address, packet1.ver, packet1.type, packet1.value); + mavlink_msg_memory_vect_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_debug_vect(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_debug_vect_t packet_in = { + 93372036854775807ULL, + 73.0, + 101.0, + 129.0, + "UVWXYZABC", + }; + mavlink_debug_vect_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.time_usec = packet_in.time_usec; + packet1.x = packet_in.x; + packet1.y = packet_in.y; + packet1.z = packet_in.z; + + mav_array_memcpy(packet1.name, packet_in.name, sizeof(char) * 10); + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_debug_vect_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_debug_vect_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_debug_vect_pack(system_id, component_id, &msg, packet1.name, packet1.time_usec, packet1.x, packet1.y, packet1.z); + mavlink_msg_debug_vect_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_debug_vect_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.name, packet1.time_usec, packet1.x, packet1.y, packet1.z); + mavlink_msg_debug_vect_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_debug_vect_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_debug_vect_send(MAVLINK_COMM_1, packet1.name, packet1.time_usec, packet1.x, packet1.y, packet1.z); + mavlink_msg_debug_vect_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_named_value_float(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_named_value_float_t packet_in = { + 963497464, + 45.0, + "IJKLMNOPQ", + }; + mavlink_named_value_float_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.time_boot_ms = packet_in.time_boot_ms; + packet1.value = packet_in.value; + + mav_array_memcpy(packet1.name, packet_in.name, sizeof(char) * 10); + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_named_value_float_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_named_value_float_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_named_value_float_pack(system_id, component_id, &msg, packet1.time_boot_ms, packet1.name, packet1.value); + mavlink_msg_named_value_float_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_named_value_float_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.time_boot_ms, packet1.name, packet1.value); + mavlink_msg_named_value_float_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_named_value_float_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_named_value_float_send(MAVLINK_COMM_1, packet1.time_boot_ms, packet1.name, packet1.value); + mavlink_msg_named_value_float_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_named_value_int(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_named_value_int_t packet_in = { + 963497464, + 963497672, + "IJKLMNOPQ", + }; + mavlink_named_value_int_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.time_boot_ms = packet_in.time_boot_ms; + packet1.value = packet_in.value; + + mav_array_memcpy(packet1.name, packet_in.name, sizeof(char) * 10); + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_named_value_int_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_named_value_int_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_named_value_int_pack(system_id, component_id, &msg, packet1.time_boot_ms, packet1.name, packet1.value); + mavlink_msg_named_value_int_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_named_value_int_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.time_boot_ms, packet1.name, packet1.value); + mavlink_msg_named_value_int_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_named_value_int_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_named_value_int_send(MAVLINK_COMM_1, packet1.time_boot_ms, packet1.name, packet1.value); + mavlink_msg_named_value_int_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_statustext(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_statustext_t packet_in = { + 5, + "BCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWX", + }; + mavlink_statustext_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.severity = packet_in.severity; + + mav_array_memcpy(packet1.text, packet_in.text, sizeof(char) * 50); + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_statustext_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_statustext_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_statustext_pack(system_id, component_id, &msg, packet1.severity, packet1.text); + mavlink_msg_statustext_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_statustext_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.severity, packet1.text); + mavlink_msg_statustext_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_statustext_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_statustext_send(MAVLINK_COMM_1, packet1.severity, packet1.text); + mavlink_msg_statustext_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_debug(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_message_t msg; + uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; + uint16_t i; + mavlink_debug_t packet_in = { + 963497464, + 45.0, + 29, + }; + mavlink_debug_t packet1, packet2; + + memset(&packet1, 0, sizeof(packet1)); + packet1.time_boot_ms = packet_in.time_boot_ms; + packet1.value = packet_in.value; + packet1.ind = packet_in.ind; + + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_debug_encode(system_id, component_id, &msg, &packet1); + mavlink_msg_debug_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_debug_pack(system_id, component_id, &msg, packet1.time_boot_ms, packet1.ind, packet1.value); + mavlink_msg_debug_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_debug_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg, packet1.time_boot_ms, packet1.ind, packet1.value); + mavlink_msg_debug_decode(&msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_to_send_buffer(buffer, &msg); + for (i = 0; i < mavlink_msg_get_send_buffer_length(&msg); i++) { + comm_send_ch(MAVLINK_COMM_0, buffer[i]); + } + mavlink_msg_debug_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); + + memset(&packet2, 0, sizeof(packet2)); + mavlink_msg_debug_send(MAVLINK_COMM_1, packet1.time_boot_ms, packet1.ind, packet1.value); + mavlink_msg_debug_decode(last_msg, &packet2); + MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0); +} + +static void mavlink_test_common(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg) +{ + mavlink_test_heartbeat(system_id, component_id, last_msg); + mavlink_test_sys_status(system_id, component_id, last_msg); + mavlink_test_system_time(system_id, component_id, last_msg); + mavlink_test_ping(system_id, component_id, last_msg); + mavlink_test_change_operator_control(system_id, component_id, last_msg); + mavlink_test_change_operator_control_ack(system_id, component_id, last_msg); + mavlink_test_auth_key(system_id, component_id, last_msg); + mavlink_test_set_mode(system_id, component_id, last_msg); + mavlink_test_param_request_read(system_id, component_id, last_msg); + mavlink_test_param_request_list(system_id, component_id, last_msg); + mavlink_test_param_value(system_id, component_id, last_msg); + mavlink_test_param_set(system_id, component_id, last_msg); + mavlink_test_gps_raw_int(system_id, component_id, last_msg); + mavlink_test_gps_status(system_id, component_id, last_msg); + mavlink_test_scaled_imu(system_id, component_id, last_msg); + mavlink_test_raw_imu(system_id, component_id, last_msg); + mavlink_test_raw_pressure(system_id, component_id, last_msg); + mavlink_test_scaled_pressure(system_id, component_id, last_msg); + mavlink_test_attitude(system_id, component_id, last_msg); + mavlink_test_attitude_quaternion(system_id, component_id, last_msg); + mavlink_test_local_position_ned(system_id, component_id, last_msg); + mavlink_test_global_position_int(system_id, component_id, last_msg); + mavlink_test_rc_channels_scaled(system_id, component_id, last_msg); + mavlink_test_rc_channels_raw(system_id, component_id, last_msg); + mavlink_test_servo_output_raw(system_id, component_id, last_msg); + mavlink_test_mission_request_partial_list(system_id, component_id, last_msg); + mavlink_test_mission_write_partial_list(system_id, component_id, last_msg); + mavlink_test_mission_item(system_id, component_id, last_msg); + mavlink_test_mission_request(system_id, component_id, last_msg); + mavlink_test_mission_set_current(system_id, component_id, last_msg); + mavlink_test_mission_current(system_id, component_id, last_msg); + mavlink_test_mission_request_list(system_id, component_id, last_msg); + mavlink_test_mission_count(system_id, component_id, last_msg); + mavlink_test_mission_clear_all(system_id, component_id, last_msg); + mavlink_test_mission_item_reached(system_id, component_id, last_msg); + mavlink_test_mission_ack(system_id, component_id, last_msg); + mavlink_test_set_gps_global_origin(system_id, component_id, last_msg); + mavlink_test_gps_global_origin(system_id, component_id, last_msg); + mavlink_test_set_local_position_setpoint(system_id, component_id, last_msg); + mavlink_test_local_position_setpoint(system_id, component_id, last_msg); + mavlink_test_global_position_setpoint_int(system_id, component_id, last_msg); + mavlink_test_set_global_position_setpoint_int(system_id, component_id, last_msg); + mavlink_test_safety_set_allowed_area(system_id, component_id, last_msg); + mavlink_test_safety_allowed_area(system_id, component_id, last_msg); + mavlink_test_set_roll_pitch_yaw_thrust(system_id, component_id, last_msg); + mavlink_test_set_roll_pitch_yaw_speed_thrust(system_id, component_id, last_msg); + mavlink_test_roll_pitch_yaw_thrust_setpoint(system_id, component_id, last_msg); + mavlink_test_roll_pitch_yaw_speed_thrust_setpoint(system_id, component_id, last_msg); + mavlink_test_set_quad_motors_setpoint(system_id, component_id, last_msg); + mavlink_test_set_quad_swarm_roll_pitch_yaw_thrust(system_id, component_id, last_msg); + mavlink_test_nav_controller_output(system_id, component_id, last_msg); + mavlink_test_set_quad_swarm_led_roll_pitch_yaw_thrust(system_id, component_id, last_msg); + mavlink_test_state_correction(system_id, component_id, last_msg); + mavlink_test_request_data_stream(system_id, component_id, last_msg); + mavlink_test_data_stream(system_id, component_id, last_msg); + mavlink_test_manual_control(system_id, component_id, last_msg); + mavlink_test_rc_channels_override(system_id, component_id, last_msg); + mavlink_test_vfr_hud(system_id, component_id, last_msg); + mavlink_test_command_long(system_id, component_id, last_msg); + mavlink_test_command_ack(system_id, component_id, last_msg); + mavlink_test_local_position_ned_system_global_offset(system_id, component_id, last_msg); + mavlink_test_hil_state(system_id, component_id, last_msg); + mavlink_test_hil_controls(system_id, component_id, last_msg); + mavlink_test_hil_rc_inputs_raw(system_id, component_id, last_msg); + mavlink_test_optical_flow(system_id, component_id, last_msg); + mavlink_test_global_vision_position_estimate(system_id, component_id, last_msg); + mavlink_test_vision_position_estimate(system_id, component_id, last_msg); + mavlink_test_vision_speed_estimate(system_id, component_id, last_msg); + mavlink_test_vicon_position_estimate(system_id, component_id, last_msg); + mavlink_test_memory_vect(system_id, component_id, last_msg); + mavlink_test_debug_vect(system_id, component_id, last_msg); + mavlink_test_named_value_float(system_id, component_id, last_msg); + mavlink_test_named_value_int(system_id, component_id, last_msg); + mavlink_test_statustext(system_id, component_id, last_msg); + mavlink_test_debug(system_id, component_id, last_msg); +} + +#ifdef __cplusplus +} +#endif // __cplusplus +#endif // COMMON_TESTSUITE_H diff --git a/flight/libraries/mavlink/v1.0/common/version.h b/flight/libraries/mavlink/v1.0/common/version.h new file mode 100644 index 000000000..f58feb830 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/common/version.h @@ -0,0 +1,12 @@ +/** @file + * @brief MAVLink comm protocol built from common.xml + * @see http://pixhawk.ethz.ch/software/mavlink + */ +#ifndef MAVLINK_VERSION_H +#define MAVLINK_VERSION_H + +#define MAVLINK_BUILD_DATE "Thu Aug 23 16:39:58 2012" +#define MAVLINK_WIRE_PROTOCOL_VERSION "1.0" +#define MAVLINK_MAX_DIALECT_PAYLOAD_SIZE 101 + +#endif // MAVLINK_VERSION_H diff --git a/flight/libraries/mavlink/v1.0/mavlink_helpers.h b/flight/libraries/mavlink/v1.0/mavlink_helpers.h new file mode 100644 index 000000000..f9f02b69d --- /dev/null +++ b/flight/libraries/mavlink/v1.0/mavlink_helpers.h @@ -0,0 +1,534 @@ +#ifndef _MAVLINK_HELPERS_H_ +#define _MAVLINK_HELPERS_H_ + +#include "string.h" +#include "checksum.h" +#include "mavlink_types.h" + +#ifndef MAVLINK_HELPER +#define MAVLINK_HELPER +#endif + +/* + internal function to give access to the channel status for each channel + */ +MAVLINK_HELPER mavlink_status_t *mavlink_get_channel_status(uint8_t chan) +{ + static mavlink_status_t m_mavlink_status[MAVLINK_COMM_NUM_BUFFERS]; + + return &m_mavlink_status[chan]; +} + +/* + internal function to give access to the channel buffer for each channel + */ +MAVLINK_HELPER mavlink_message_t *mavlink_get_channel_buffer(uint8_t chan) +{ +#if MAVLINK_EXTERNAL_RX_BUFFER + // No m_mavlink_message array defined in function, + // has to be defined externally +#ifndef m_mavlink_message +#error ERROR: IF #define MAVLINK_EXTERNAL_RX_BUFFER IS SET, THE BUFFER HAS TO BE ALLOCATED OUTSIDE OF THIS FUNCTION (mavlink_message_t m_mavlink_buffer[MAVLINK_COMM_NUM_BUFFERS];) +#endif +#else + static mavlink_message_t m_mavlink_buffer[MAVLINK_COMM_NUM_BUFFERS]; +#endif + return &m_mavlink_buffer[chan]; +} + +/** + * @brief Finalize a MAVLink message with channel assignment + * + * This function calculates the checksum and sets length and aircraft id correctly. + * It assumes that the message id and the payload are already correctly set. This function + * can also be used if the message header has already been written before (as in mavlink_msg_xxx_pack + * instead of mavlink_msg_xxx_pack_headerless), it just introduces little extra overhead. + * + * @param msg Message to finalize + * @param system_id Id of the sending (this) system, 1-127 + * @param length Message length + */ +#if MAVLINK_CRC_EXTRA +MAVLINK_HELPER uint16_t mavlink_finalize_message_chan(mavlink_message_t *msg, uint8_t system_id, uint8_t component_id, + uint8_t chan, uint8_t length, uint8_t crc_extra) +#else +MAVLINK_HELPER uint16_t mavlink_finalize_message_chan(mavlink_message_t *msg, uint8_t system_id, uint8_t component_id, + uint8_t chan, uint8_t length) +#endif +{ + // This code part is the same for all messages; + uint16_t checksum; + + msg->magic = MAVLINK_STX; + msg->len = length; + msg->sysid = system_id; + msg->compid = component_id; + // One sequence number per component + msg->seq = mavlink_get_channel_status(chan)->current_tx_seq; + mavlink_get_channel_status(chan)->current_tx_seq = mavlink_get_channel_status(chan)->current_tx_seq + 1; + checksum = crc_calculate((uint8_t *)&msg->len, length + MAVLINK_CORE_HEADER_LEN); +#if MAVLINK_CRC_EXTRA + crc_accumulate(crc_extra, &checksum); +#endif + mavlink_ck_a(msg) = (uint8_t)(checksum & 0xFF); + mavlink_ck_b(msg) = (uint8_t)(checksum >> 8); + + return length + MAVLINK_NUM_NON_PAYLOAD_BYTES; +} + + +/** + * @brief Finalize a MAVLink message with MAVLINK_COMM_0 as default channel + */ +#if MAVLINK_CRC_EXTRA +MAVLINK_HELPER uint16_t mavlink_finalize_message(mavlink_message_t *msg, uint8_t system_id, uint8_t component_id, + uint8_t length, uint8_t crc_extra) +{ + return mavlink_finalize_message_chan(msg, system_id, component_id, MAVLINK_COMM_0, length, crc_extra); +} +#else +MAVLINK_HELPER uint16_t mavlink_finalize_message(mavlink_message_t *msg, uint8_t system_id, uint8_t component_id, + uint8_t length) +{ + return mavlink_finalize_message_chan(msg, system_id, component_id, MAVLINK_COMM_0, length); +} +#endif + +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS +MAVLINK_HELPER void _mavlink_send_uart(mavlink_channel_t chan, const char *buf, uint16_t len); + +/** + * @brief Finalize a MAVLink message with channel assignment and send + */ +#if MAVLINK_CRC_EXTRA +MAVLINK_HELPER void _mav_finalize_message_chan_send(mavlink_channel_t chan, uint8_t msgid, const char *packet, + uint8_t length, uint8_t crc_extra) +#else +MAVLINK_HELPER void _mav_finalize_message_chan_send(mavlink_channel_t chan, uint8_t msgid, const char *packet, uint8_t length) +#endif +{ + uint16_t checksum; + uint8_t buf[MAVLINK_NUM_HEADER_BYTES]; + uint8_t ck[2]; + mavlink_status_t *status = mavlink_get_channel_status(chan); + + buf[0] = MAVLINK_STX; + buf[1] = length; + buf[2] = status->current_tx_seq; + buf[3] = mavlink_system.sysid; + buf[4] = mavlink_system.compid; + buf[5] = msgid; + status->current_tx_seq++; + checksum = crc_calculate((uint8_t *)&buf[1], MAVLINK_CORE_HEADER_LEN); + crc_accumulate_buffer(&checksum, packet, length); +#if MAVLINK_CRC_EXTRA + crc_accumulate(crc_extra, &checksum); +#endif + ck[0] = (uint8_t)(checksum & 0xFF); + ck[1] = (uint8_t)(checksum >> 8); + + MAVLINK_START_UART_SEND(chan, MAVLINK_NUM_NON_PAYLOAD_BYTES + (uint16_t)length); + _mavlink_send_uart(chan, (const char *)buf, MAVLINK_NUM_HEADER_BYTES); + _mavlink_send_uart(chan, packet, length); + _mavlink_send_uart(chan, (const char *)ck, 2); + MAVLINK_END_UART_SEND(chan, MAVLINK_NUM_NON_PAYLOAD_BYTES + (uint16_t)length); +} + +/** + * @brief re-send a message over a uart channel + * this is more stack efficient than re-marshalling the message + */ +MAVLINK_HELPER void _mavlink_resend_uart(mavlink_channel_t chan, const mavlink_message_t *msg) +{ + uint8_t ck[2]; + + ck[0] = (uint8_t)(msg->checksum & 0xFF); + ck[1] = (uint8_t)(msg->checksum >> 8); + + MAVLINK_START_UART_SEND(chan, MAVLINK_NUM_NON_PAYLOAD_BYTES + msg->len); + _mavlink_send_uart(chan, (const char *)&msg->magic, MAVLINK_NUM_HEADER_BYTES); + _mavlink_send_uart(chan, _MAV_PAYLOAD(msg), msg->len); + _mavlink_send_uart(chan, (const char *)ck, 2); + MAVLINK_END_UART_SEND(chan, MAVLINK_NUM_NON_PAYLOAD_BYTES + msg->len); +} +#endif // MAVLINK_USE_CONVENIENCE_FUNCTIONS + +/** + * @brief Pack a message to send it over a serial byte stream + */ +MAVLINK_HELPER uint16_t mavlink_msg_to_send_buffer(uint8_t *buffer, const mavlink_message_t *msg) +{ + memcpy(buffer, (const uint8_t *)&msg->magic, MAVLINK_NUM_NON_PAYLOAD_BYTES + (uint16_t)msg->len); + return MAVLINK_NUM_NON_PAYLOAD_BYTES + (uint16_t)msg->len; +} + +union __mavlink_bitfield { + uint8_t uint8; + int8_t int8; + uint16_t uint16; + int16_t int16; + uint32_t uint32; + int32_t int32; +}; + + +MAVLINK_HELPER void mavlink_start_checksum(mavlink_message_t *msg) +{ + crc_init(&msg->checksum); +} + +MAVLINK_HELPER void mavlink_update_checksum(mavlink_message_t *msg, uint8_t c) +{ + crc_accumulate(c, &msg->checksum); +} + +/** + * This is a convenience function which handles the complete MAVLink parsing. + * the function will parse one byte at a time and return the complete packet once + * it could be successfully decoded. Checksum and other failures will be silently + * ignored. + * + * @param chan ID of the current channel. This allows to parse different channels with this function. + * a channel is not a physical message channel like a serial port, but a logic partition of + * the communication streams in this case. COMM_NB is the limit for the number of channels + * on MCU (e.g. ARM7), while COMM_NB_HIGH is the limit for the number of channels in Linux/Windows + * @param c The char to barse + * + * @param returnMsg NULL if no message could be decoded, the message data else + * @return 0 if no message could be decoded, 1 else + * + * A typical use scenario of this function call is: + * + * @code + * #include // For fixed-width uint8_t type + * + * mavlink_message_t msg; + * int chan = 0; + * + * + * while(serial.bytesAvailable > 0) + * { + * uint8_t byte = serial.getNextByte(); + * if (mavlink_parse_char(chan, byte, &msg)) + * { + * printf("Received message with ID %d, sequence: %d from component %d of system %d", msg.msgid, msg.seq, msg.compid, msg.sysid); + * } + * } + * + * + * @endcode + */ +MAVLINK_HELPER uint8_t mavlink_parse_char(uint8_t chan, uint8_t c, mavlink_message_t *r_message, mavlink_status_t *r_mavlink_status) +{ + /* + default message crc function. You can override this per-system to + put this data in a different memory segment + */ +#if MAVLINK_CRC_EXTRA +#ifndef MAVLINK_MESSAGE_CRC + static const uint8_t mavlink_message_crcs[256] = MAVLINK_MESSAGE_CRCS; +#define MAVLINK_MESSAGE_CRC(msgid) mavlink_message_crcs[msgid] +#endif +#endif + +/* Enable this option to check the length of each message. + This allows invalid messages to be caught much sooner. Use if the transmission + medium is prone to missing (or extra) characters (e.g. a radio that fades in + and out). Only use if the channel will only contain messages types listed in + the headers. + */ +#if MAVLINK_CHECK_MESSAGE_LENGTH +#ifndef MAVLINK_MESSAGE_LENGTH + static const uint8_t mavlink_message_lengths[256] = MAVLINK_MESSAGE_LENGTHS; +#define MAVLINK_MESSAGE_LENGTH(msgid) mavlink_message_lengths[msgid] +#endif +#endif + + mavlink_message_t *rxmsg = mavlink_get_channel_buffer(chan); ///< The currently decoded message + mavlink_status_t *status = mavlink_get_channel_status(chan); ///< The current decode status + int bufferIndex = 0; + + status->msg_received = 0; + + switch (status->parse_state) { + case MAVLINK_PARSE_STATE_UNINIT: + case MAVLINK_PARSE_STATE_IDLE: + if (c == MAVLINK_STX) { + status->parse_state = MAVLINK_PARSE_STATE_GOT_STX; + rxmsg->len = 0; + rxmsg->magic = c; + mavlink_start_checksum(rxmsg); + } + break; + + case MAVLINK_PARSE_STATE_GOT_STX: + if (status->msg_received +/* Support shorter buffers than the + default maximum packet size */ +#if (MAVLINK_MAX_PAYLOAD_LEN < 255) + || c > MAVLINK_MAX_PAYLOAD_LEN +#endif + ) { + status->buffer_overrun++; + status->parse_error++; + status->msg_received = 0; + status->parse_state = MAVLINK_PARSE_STATE_IDLE; + } else { + // NOT counting STX, LENGTH, SEQ, SYSID, COMPID, MSGID, CRC1 and CRC2 + rxmsg->len = c; + status->packet_idx = 0; + mavlink_update_checksum(rxmsg, c); + status->parse_state = MAVLINK_PARSE_STATE_GOT_LENGTH; + } + break; + + case MAVLINK_PARSE_STATE_GOT_LENGTH: + rxmsg->seq = c; + mavlink_update_checksum(rxmsg, c); + status->parse_state = MAVLINK_PARSE_STATE_GOT_SEQ; + break; + + case MAVLINK_PARSE_STATE_GOT_SEQ: + rxmsg->sysid = c; + mavlink_update_checksum(rxmsg, c); + status->parse_state = MAVLINK_PARSE_STATE_GOT_SYSID; + break; + + case MAVLINK_PARSE_STATE_GOT_SYSID: + rxmsg->compid = c; + mavlink_update_checksum(rxmsg, c); + status->parse_state = MAVLINK_PARSE_STATE_GOT_COMPID; + break; + + case MAVLINK_PARSE_STATE_GOT_COMPID: +#if MAVLINK_CHECK_MESSAGE_LENGTH + if (rxmsg->len != MAVLINK_MESSAGE_LENGTH(c)) { + status->parse_error++; + status->parse_state = MAVLINK_PARSE_STATE_IDLE; + break; + if (c == MAVLINK_STX) { + status->parse_state = MAVLINK_PARSE_STATE_GOT_STX; + mavlink_start_checksum(rxmsg); + } + } +#endif + rxmsg->msgid = c; + mavlink_update_checksum(rxmsg, c); + if (rxmsg->len == 0) { + status->parse_state = MAVLINK_PARSE_STATE_GOT_PAYLOAD; + } else { + status->parse_state = MAVLINK_PARSE_STATE_GOT_MSGID; + } + break; + + case MAVLINK_PARSE_STATE_GOT_MSGID: + _MAV_PAYLOAD_NON_CONST(rxmsg)[status->packet_idx++] = (char)c; + mavlink_update_checksum(rxmsg, c); + if (status->packet_idx == rxmsg->len) { + status->parse_state = MAVLINK_PARSE_STATE_GOT_PAYLOAD; + } + break; + + case MAVLINK_PARSE_STATE_GOT_PAYLOAD: +#if MAVLINK_CRC_EXTRA + mavlink_update_checksum(rxmsg, MAVLINK_MESSAGE_CRC(rxmsg->msgid)); +#endif + if (c != (rxmsg->checksum & 0xFF)) { + // Check first checksum byte + status->parse_error++; + status->msg_received = 0; + status->parse_state = MAVLINK_PARSE_STATE_IDLE; + if (c == MAVLINK_STX) { + status->parse_state = MAVLINK_PARSE_STATE_GOT_STX; + rxmsg->len = 0; + mavlink_start_checksum(rxmsg); + } + } else { + status->parse_state = MAVLINK_PARSE_STATE_GOT_CRC1; + _MAV_PAYLOAD_NON_CONST(rxmsg)[status->packet_idx] = (char)c; + } + break; + + case MAVLINK_PARSE_STATE_GOT_CRC1: + if (c != (rxmsg->checksum >> 8)) { + // Check second checksum byte + status->parse_error++; + status->msg_received = 0; + status->parse_state = MAVLINK_PARSE_STATE_IDLE; + if (c == MAVLINK_STX) { + status->parse_state = MAVLINK_PARSE_STATE_GOT_STX; + rxmsg->len = 0; + mavlink_start_checksum(rxmsg); + } + } else { + // Successfully got message + status->msg_received = 1; + status->parse_state = MAVLINK_PARSE_STATE_IDLE; + _MAV_PAYLOAD_NON_CONST(rxmsg)[status->packet_idx + 1] = (char)c; + memcpy(r_message, rxmsg, sizeof(mavlink_message_t)); + } + break; + } + + bufferIndex++; + // If a message has been sucessfully decoded, check index + if (status->msg_received == 1) { + // while(status->current_seq != rxmsg->seq) + // { + // status->packet_rx_drop_count++; + // status->current_seq++; + // } + status->current_rx_seq = rxmsg->seq; + // Initial condition: If no packet has been received so far, drop count is undefined + if (status->packet_rx_success_count == 0) { + status->packet_rx_drop_count = 0; + } + // Count this packet as received + status->packet_rx_success_count++; + } + + r_mavlink_status->current_rx_seq = status->current_rx_seq + 1; + r_mavlink_status->packet_rx_success_count = status->packet_rx_success_count; + r_mavlink_status->packet_rx_drop_count = status->parse_error; + status->parse_error = 0; + return status->msg_received; +} + +/** + * @brief Put a bitfield of length 1-32 bit into the buffer + * + * @param b the value to add, will be encoded in the bitfield + * @param bits number of bits to use to encode b, e.g. 1 for boolean, 2, 3, etc. + * @param packet_index the position in the packet (the index of the first byte to use) + * @param bit_index the position in the byte (the index of the first bit to use) + * @param buffer packet buffer to write into + * @return new position of the last used byte in the buffer + */ +MAVLINK_HELPER uint8_t put_bitfield_n_by_index(int32_t b, uint8_t bits, uint8_t packet_index, uint8_t bit_index, uint8_t *r_bit_index, uint8_t *buffer) +{ + uint16_t bits_remain = bits; + // Transform number into network order + int32_t v; + uint8_t i_bit_index, i_byte_index, curr_bits_n; + +#if MAVLINK_NEED_BYTE_SWAP + union { + int32_t i; + uint8_t b[4]; + } bin, bout; + bin.i = b; + bout.b[0] = bin.b[3]; + bout.b[1] = bin.b[2]; + bout.b[2] = bin.b[1]; + bout.b[3] = bin.b[0]; + v = bout.i; +#else + v = b; +#endif + + // buffer in + // 01100000 01000000 00000000 11110001 + // buffer out + // 11110001 00000000 01000000 01100000 + + // Existing partly filled byte (four free slots) + // 0111xxxx + + // Mask n free bits + // 00001111 = 2^0 + 2^1 + 2^2 + 2^3 = 2^n - 1 + // = ((uint32_t)(1 << n)) - 1; // = 2^n - 1 + + // Shift n bits into the right position + // out = in >> n; + + // Mask and shift bytes + i_bit_index = bit_index; + i_byte_index = packet_index; + if (bit_index > 0) { + // If bits were available at start, they were available + // in the byte before the current index + i_byte_index--; + } + + // While bits have not been packed yet + while (bits_remain > 0) { + // Bits still have to be packed + // there can be more than 8 bits, so + // we might have to pack them into more than one byte + + // First pack everything we can into the current 'open' byte + // curr_bits_n = bits_remain << 3; // Equals bits_remain mod 8 + // FIXME + if (bits_remain <= (uint8_t)(8 - i_bit_index)) { + // Enough space + curr_bits_n = (uint8_t)bits_remain; + } else { + curr_bits_n = (8 - i_bit_index); + } + + // Pack these n bits into the current byte + // Mask out whatever was at that position with ones (xxx11111) + buffer[i_byte_index] &= (0xFF >> (8 - curr_bits_n)); + // Put content to this position, by masking out the non-used part + buffer[i_byte_index] |= ((0x00 << curr_bits_n) & v); + + // Increment the bit index + i_bit_index += curr_bits_n; + + // Now proceed to the next byte, if necessary + bits_remain -= curr_bits_n; + if (bits_remain > 0) { + // Offer another 8 bits / one byte + i_byte_index++; + i_bit_index = 0; + } + } + + *r_bit_index = i_bit_index; + // If a partly filled byte is present, mark this as consumed + if (i_bit_index != 7) { + i_byte_index++; + } + return i_byte_index - packet_index; +} + +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS + +// To make MAVLink work on your MCU, define comm_send_ch() if you wish +// to send 1 byte at a time, or MAVLINK_SEND_UART_BYTES() to send a +// whole packet at a time + +/* + + #include "mavlink_types.h" + + void comm_send_ch(mavlink_channel_t chan, uint8_t ch) + { + if (chan == MAVLINK_COMM_0) + { + uart0_transmit(ch); + } + if (chan == MAVLINK_COMM_1) + { + uart1_transmit(ch); + } + } + */ + +MAVLINK_HELPER void _mavlink_send_uart(mavlink_channel_t chan, const char *buf, uint16_t len) +{ +#ifdef MAVLINK_SEND_UART_BYTES + /* this is the more efficient approach, if the platform + defines it */ + MAVLINK_SEND_UART_BYTES(chan, (uint8_t *)buf, len); +#else + /* fallback to one byte at a time */ + uint16_t i; + for (i = 0; i < len; i++) { + comm_send_ch(chan, (uint8_t)buf[i]); + } +#endif +} +#endif // MAVLINK_USE_CONVENIENCE_FUNCTIONS + +#endif /* _MAVLINK_HELPERS_H_ */ diff --git a/flight/libraries/mavlink/v1.0/mavlink_protobuf_manager.hpp b/flight/libraries/mavlink/v1.0/mavlink_protobuf_manager.hpp new file mode 100644 index 000000000..1126a9a88 --- /dev/null +++ b/flight/libraries/mavlink/v1.0/mavlink_protobuf_manager.hpp @@ -0,0 +1,336 @@ +#ifndef MAVLINKPROTOBUFMANAGER_HPP +#define MAVLINKPROTOBUFMANAGER_HPP + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace mavlink { +class ProtobufManager { +public: + ProtobufManager() + : mRegisteredTypeCount(0) + , mStreamID(0) + , mVerbose(false) + , kExtendedHeaderSize(MAVLINK_EXTENDED_HEADER_LEN) + , kExtendedPayloadMaxSize(MAVLINK_MAX_EXTENDED_PAYLOAD_LEN) + { + // register GLOverlay + { + std::tr1::shared_ptr msg(new px::GLOverlay); + registerType(msg); + } + + // register ObstacleList + { + std::tr1::shared_ptr msg(new px::ObstacleList); + registerType(msg); + } + + // register ObstacleMap + { + std::tr1::shared_ptr msg(new px::ObstacleMap); + registerType(msg); + } + + // register Path + { + std::tr1::shared_ptr msg(new px::Path); + registerType(msg); + } + + // register PointCloudXYZI + { + std::tr1::shared_ptr msg(new px::PointCloudXYZI); + registerType(msg); + } + + // register PointCloudXYZRGB + { + std::tr1::shared_ptr msg(new px::PointCloudXYZRGB); + registerType(msg); + } + + // register RGBDImage + { + std::tr1::shared_ptr msg(new px::RGBDImage); + registerType(msg); + } + + srand(time(NULL)); + mStreamID = rand() + 1; + } + + bool fragmentMessage(uint8_t system_id, uint8_t component_id, + uint8_t target_system, uint8_t target_component, + const google::protobuf::Message & protobuf_msg, + std::vector & fragments) const + { + TypeMap::const_iterator it = mTypeMap.find(protobuf_msg.GetTypeName()); + + if (it == mTypeMap.end()) { + std::cout << "# WARNING: Protobuf message with type " + << protobuf_msg.GetTypeName() << " is not registered." + << std::endl; + return false; + } + + uint8_t typecode = it->second; + + std::string data = protobuf_msg.SerializeAsString(); + + int fragmentCount = (protobuf_msg.ByteSize() + kExtendedPayloadMaxSize - 1) / kExtendedPayloadMaxSize; + unsigned int offset = 0; + + for (int i = 0; i < fragmentCount; ++i) { + mavlink_extended_message_t fragment; + + // write extended header data + uint8_t *payload = reinterpret_cast(fragment.base_msg.payload64); + unsigned int length = 0; + uint8_t flags = 0; + + if (i < fragmentCount - 1) { + length = kExtendedPayloadMaxSize; + flags |= 0x1; + } else { + length = protobuf_msg.ByteSize() - kExtendedPayloadMaxSize * (fragmentCount - 1); + } + + memcpy(payload, &target_system, 1); + memcpy(payload + 1, &target_component, 1); + memcpy(payload + 2, &typecode, 1); + memcpy(payload + 3, &length, 4); + memcpy(payload + 7, &mStreamID, 2); + memcpy(payload + 9, &offset, 4); + memcpy(payload + 13, &flags, 1); + + fragment.base_msg.msgid = MAVLINK_MSG_ID_EXTENDED_MESSAGE; + mavlink_finalize_message(&fragment.base_msg, system_id, component_id, kExtendedHeaderSize, 0); + + // write extended payload data + fragment.extended_payload_len = length; + memcpy(fragment.extended_payload, &data[offset], length); + + fragments.push_back(fragment); + offset += length; + } + + if (mVerbose) { + std::cerr << "# INFO: Split extended message with size " + << protobuf_msg.ByteSize() << " into " + << fragmentCount << " fragments." << std::endl; + } + + return true; + } + + bool cacheFragment(mavlink_extended_message_t & msg) + { + if (!validFragment(msg)) { + if (mVerbose) { + std::cerr << "# WARNING: Message is not a valid fragment. " + << "Dropping message..." << std::endl; + } + return false; + } + + // read extended header + uint8_t *payload = reinterpret_cast(msg.base_msg.payload64); + uint8_t typecode = 0; + unsigned int length = 0; + unsigned short streamID = 0; + unsigned int offset = 0; + uint8_t flags = 0; + + memcpy(&typecode, payload + 2, 1); + memcpy(&length, payload + 3, 4); + memcpy(&streamID, payload + 7, 2); + memcpy(&offset, payload + 9, 4); + memcpy(&flags, payload + 13, 1); + + if (typecode >= mTypeMap.size()) { + std::cout << "# WARNING: Protobuf message with type code " + << static_cast(typecode) << " is not registered." << std::endl; + return false; + } + + bool reassemble = false; + + FragmentQueue::iterator it = mFragmentQueue.find(streamID); + if (it == mFragmentQueue.end()) { + if (offset == 0) { + mFragmentQueue[streamID].push_back(msg); + + if ((flags & 0x1) != 0x1) { + reassemble = true; + } + + if (mVerbose) { + std::cerr << "# INFO: Added fragment to new queue." + << std::endl; + } + } else { + if (mVerbose) { + std::cerr << "# WARNING: Message is not a valid fragment. " + << "Dropping message..." << std::endl; + } + } + } else { + std::deque & queue = it->second; + + if (queue.empty()) { + if (offset == 0) { + queue.push_back(msg); + + if ((flags & 0x1) != 0x1) { + reassemble = true; + } + } else { + if (mVerbose) { + std::cerr << "# WARNING: Message is not a valid fragment. " + << "Dropping message..." << std::endl; + } + } + } else { + if (fragmentDataSize(queue.back()) + fragmentOffset(queue.back()) != offset) { + if (mVerbose) { + std::cerr << "# WARNING: Previous fragment(s) have been lost. " + << "Dropping message and clearing queue..." << std::endl; + } + queue.clear(); + } else { + queue.push_back(msg); + + if ((flags & 0x1) != 0x1) { + reassemble = true; + } + } + } + } + + if (reassemble) { + std::deque & queue = mFragmentQueue[streamID]; + + std::string data; + for (size_t i = 0; i < queue.size(); ++i) { + mavlink_extended_message_t & mavlink_msg = queue.at(i); + + data.append(reinterpret_cast(&mavlink_msg.extended_payload[0]), + static_cast(mavlink_msg.extended_payload_len)); + } + + mMessages.at(typecode)->ParseFromString(data); + + mMessageAvailable.at(typecode) = true; + + queue.clear(); + + if (mVerbose) { + std::cerr << "# INFO: Reassembled fragments for message with typename " + << mMessages.at(typecode)->GetTypeName() << " and size " + << mMessages.at(typecode)->ByteSize() + << "." << std::endl; + } + } + + return true; + } + + bool getMessage(std::tr1::shared_ptr & msg) + { + for (size_t i = 0; i < mMessageAvailable.size(); ++i) { + if (mMessageAvailable.at(i)) { + msg = mMessages.at(i); + mMessageAvailable.at(i) = false; + + return true; + } + } + + return false; + } + +private: + void registerType(const std::tr1::shared_ptr & msg) + { + mTypeMap[msg->GetTypeName()] = mRegisteredTypeCount; + ++mRegisteredTypeCount; + mMessages.push_back(msg); + mMessageAvailable.push_back(false); + } + + bool validFragment(const mavlink_extended_message_t & msg) const + { + if (msg.base_msg.magic != MAVLINK_STX || + msg.base_msg.len != kExtendedHeaderSize || + msg.base_msg.msgid != MAVLINK_MSG_ID_EXTENDED_MESSAGE) { + return false; + } + + uint16_t checksum; + checksum = crc_calculate(reinterpret_cast(&msg.base_msg.len), MAVLINK_CORE_HEADER_LEN); + crc_accumulate_buffer(&checksum, reinterpret_cast(&msg.base_msg.payload64), kExtendedHeaderSize); +#if MAVLINK_CRC_EXTRA + static const uint8_t mavlink_message_crcs[256] = MAVLINK_MESSAGE_CRCS; + crc_accumulate(mavlink_message_crcs[msg.base_msg.msgid], &checksum); +#endif + + if (mavlink_ck_a(&(msg.base_msg)) != (uint8_t)(checksum & 0xFF) && + mavlink_ck_b(&(msg.base_msg)) != (uint8_t)(checksum >> 8)) { + return false; + } + + return true; + } + + unsigned int fragmentDataSize(const mavlink_extended_message_t & msg) const + { + const uint8_t *payload = reinterpret_cast(msg.base_msg.payload64); + + return *(reinterpret_cast(payload + 3)); + } + + unsigned int fragmentOffset(const mavlink_extended_message_t & msg) const + { + const uint8_t *payload = reinterpret_cast(msg.base_msg.payload64); + + return *(reinterpret_cast(payload + 9)); + } + + int mRegisteredTypeCount; + unsigned short mStreamID; + bool mVerbose; + + typedef std::map TypeMap; + TypeMap mTypeMap; + std::vector< std::tr1::shared_ptr > mMessages; + std::vector mMessageAvailable; + + typedef std::map > FragmentQueue; + FragmentQueue mFragmentQueue; + + const int kExtendedHeaderSize; + /** + * Extended header structure + * ========================= + * byte 0 - target_system + * byte 1 - target_component + * byte 2 - extended message id (type code) + * bytes 3-6 - extended payload size in bytes + * byte 7-8 - stream ID + * byte 9-12 - fragment offset + * byte 13 - fragment flags (bit 0 - 1=more fragments, 0=last fragment) + */ + + const int kExtendedPayloadMaxSize; +}; +} + +#endif // ifndef MAVLINKPROTOBUFMANAGER_HPP diff --git a/flight/libraries/mavlink/v1.0/mavlink_types.h b/flight/libraries/mavlink/v1.0/mavlink_types.h new file mode 100644 index 000000000..3ac9977fb --- /dev/null +++ b/flight/libraries/mavlink/v1.0/mavlink_types.h @@ -0,0 +1,158 @@ +#ifndef MAVLINK_TYPES_H_ +#define MAVLINK_TYPES_H_ + +#include + +#ifndef MAVLINK_MAX_PAYLOAD_LEN +// it is possible to override this, but be careful! +#define MAVLINK_MAX_PAYLOAD_LEN 255 ///< Maximum payload length +#endif + +#define MAVLINK_CORE_HEADER_LEN 5 ///< Length of core header (of the comm. layer): message length (1 byte) + message sequence (1 byte) + message system id (1 byte) + message component id (1 byte) + message type id (1 byte) +#define MAVLINK_NUM_HEADER_BYTES (MAVLINK_CORE_HEADER_LEN + 1) ///< Length of all header bytes, including core and checksum +#define MAVLINK_NUM_CHECKSUM_BYTES 2 +#define MAVLINK_NUM_NON_PAYLOAD_BYTES (MAVLINK_NUM_HEADER_BYTES + MAVLINK_NUM_CHECKSUM_BYTES) + +#define MAVLINK_MAX_PACKET_LEN (MAVLINK_MAX_PAYLOAD_LEN + MAVLINK_NUM_NON_PAYLOAD_BYTES) ///< Maximum packet length + +#define MAVLINK_MSG_ID_EXTENDED_MESSAGE 255 +#define MAVLINK_EXTENDED_HEADER_LEN 14 + +#if (defined _MSC_VER) | ((defined __APPLE__) & (defined __MACH__)) | (defined __linux__) +/* full fledged 32bit++ OS */ + #define MAVLINK_MAX_EXTENDED_PACKET_LEN 65507 +#else +/* small microcontrollers */ + #define MAVLINK_MAX_EXTENDED_PACKET_LEN 2048 +#endif + +#define MAVLINK_MAX_EXTENDED_PAYLOAD_LEN (MAVLINK_MAX_EXTENDED_PACKET_LEN - MAVLINK_EXTENDED_HEADER_LEN - MAVLINK_NUM_NON_PAYLOAD_BYTES) + +typedef struct param_union { + union { + float param_float; + int32_t param_int32; + uint32_t param_uint32; + uint8_t param_uint8; + uint8_t bytes[4]; + }; + uint8_t type; +} mavlink_param_union_t; + +typedef struct __mavlink_system { + uint8_t sysid; ///< Used by the MAVLink message_xx_send() convenience function + uint8_t compid; ///< Used by the MAVLink message_xx_send() convenience function + uint8_t type; ///< Unused, can be used by user to store the system's type + uint8_t state; ///< Unused, can be used by user to store the system's state + uint8_t mode; ///< Unused, can be used by user to store the system's mode + uint8_t nav_mode; ///< Unused, can be used by user to store the system's navigation mode +} mavlink_system_t; + +typedef struct __mavlink_message { + uint16_t checksum; /// sent at end of packet + uint8_t magic; ///< protocol magic marker + uint8_t len; ///< Length of payload + uint8_t seq; ///< Sequence of packet + uint8_t sysid; ///< ID of message sender system/aircraft + uint8_t compid; ///< ID of the message sender component + uint8_t msgid; ///< ID of message in payload + uint64_t payload64[(MAVLINK_MAX_PAYLOAD_LEN + MAVLINK_NUM_CHECKSUM_BYTES + 7) / 8]; +} mavlink_message_t; + + +typedef struct __mavlink_extended_message { + mavlink_message_t base_msg; + int32_t extended_payload_len; ///< Length of extended payload if any + uint8_t extended_payload[MAVLINK_MAX_EXTENDED_PAYLOAD_LEN]; +} mavlink_extended_message_t; + + +typedef enum { + MAVLINK_TYPE_CHAR = 0, + MAVLINK_TYPE_UINT8_T = 1, + MAVLINK_TYPE_INT8_T = 2, + MAVLINK_TYPE_UINT16_T = 3, + MAVLINK_TYPE_INT16_T = 4, + MAVLINK_TYPE_UINT32_T = 5, + MAVLINK_TYPE_INT32_T = 6, + MAVLINK_TYPE_UINT64_T = 7, + MAVLINK_TYPE_INT64_T = 8, + MAVLINK_TYPE_FLOAT = 9, + MAVLINK_TYPE_DOUBLE = 10 +} mavlink_message_type_t; + +#define MAVLINK_MAX_FIELDS 64 + +typedef struct __mavlink_field_info { + const char *name; // name of this field + const char *print_format; // printing format hint, or NULL + mavlink_message_type_t type; // type of this field + unsigned int array_length; // if non-zero, field is an array + unsigned int wire_offset; // offset of each field in the payload + unsigned int structure_offset; // offset in a C structure +} mavlink_field_info_t; + +// note that in this structure the order of fields is the order +// in the XML file, not necessary the wire order +typedef struct __mavlink_message_info { + const char *name; // name of the message + unsigned num_fields; // how many fields in this message + mavlink_field_info_t fields[MAVLINK_MAX_FIELDS]; // field information +} mavlink_message_info_t; + +#define _MAV_PAYLOAD(msg) ((const char *)(&((msg)->payload64[0]))) +#define _MAV_PAYLOAD_NON_CONST(msg) ((char *)(&((msg)->payload64[0]))) + +// checksum is immediately after the payload bytes +#define mavlink_ck_a(msg) *((msg)->len + (uint8_t *)_MAV_PAYLOAD_NON_CONST(msg)) +#define mavlink_ck_b(msg) *(((msg)->len + (uint16_t)1) + (uint8_t *)_MAV_PAYLOAD_NON_CONST(msg)) + +typedef enum { + MAVLINK_COMM_0, + MAVLINK_COMM_1, + MAVLINK_COMM_2, + MAVLINK_COMM_3 +} mavlink_channel_t; + +/* + * applications can set MAVLINK_COMM_NUM_BUFFERS to the maximum number + * of buffers they will use. If more are used, then the result will be + * a stack overrun + */ +#ifndef MAVLINK_COMM_NUM_BUFFERS +#if (defined linux) | (defined __linux) | (defined __MACH__) | (defined _WIN32) +# define MAVLINK_COMM_NUM_BUFFERS 16 +#else +# define MAVLINK_COMM_NUM_BUFFERS 4 +#endif +#endif + +typedef enum { + MAVLINK_PARSE_STATE_UNINIT = 0, + MAVLINK_PARSE_STATE_IDLE, + MAVLINK_PARSE_STATE_GOT_STX, + MAVLINK_PARSE_STATE_GOT_SEQ, + MAVLINK_PARSE_STATE_GOT_LENGTH, + MAVLINK_PARSE_STATE_GOT_SYSID, + MAVLINK_PARSE_STATE_GOT_COMPID, + MAVLINK_PARSE_STATE_GOT_MSGID, + MAVLINK_PARSE_STATE_GOT_PAYLOAD, + MAVLINK_PARSE_STATE_GOT_CRC1 +} mavlink_parse_state_t; ///< The state machine for the comm parser + +typedef struct __mavlink_status { + uint8_t msg_received; ///< Number of received messages + uint8_t buffer_overrun; ///< Number of buffer overruns + uint8_t parse_error; ///< Number of parse errors + mavlink_parse_state_t parse_state; ///< Parsing state machine + uint8_t packet_idx; ///< Index in current packet + uint8_t current_rx_seq; ///< Sequence number of last packet received + uint8_t current_tx_seq; ///< Sequence number of last packet sent + uint16_t packet_rx_success_count; ///< Received packets + uint16_t packet_rx_drop_count; ///< Number of packet drops +} mavlink_status_t; + +#define MAVLINK_BIG_ENDIAN 0 +#define MAVLINK_LITTLE_ENDIAN 1 + +#endif /* MAVLINK_TYPES_H_ */ diff --git a/flight/libraries/mavlink/v1.0/protocol.h b/flight/libraries/mavlink/v1.0/protocol.h new file mode 100644 index 000000000..d482a9eaf --- /dev/null +++ b/flight/libraries/mavlink/v1.0/protocol.h @@ -0,0 +1,321 @@ +#ifndef _MAVLINK_PROTOCOL_H_ +#define _MAVLINK_PROTOCOL_H_ + +#include "string.h" +#include "mavlink_types.h" + +/* + If you want MAVLink on a system that is native big-endian, + you need to define NATIVE_BIG_ENDIAN + */ +#ifdef NATIVE_BIG_ENDIAN +# define MAVLINK_NEED_BYTE_SWAP (MAVLINK_ENDIAN == MAVLINK_LITTLE_ENDIAN) +#else +# define MAVLINK_NEED_BYTE_SWAP (MAVLINK_ENDIAN != MAVLINK_LITTLE_ENDIAN) +#endif + +#ifndef MAVLINK_STACK_BUFFER +#define MAVLINK_STACK_BUFFER 0 +#endif + +#ifndef MAVLINK_AVOID_GCC_STACK_BUG +# define MAVLINK_AVOID_GCC_STACK_BUG defined(__GNUC__) +#endif + +#ifndef MAVLINK_ASSERT +#define MAVLINK_ASSERT(x) +#endif + +#ifndef MAVLINK_START_UART_SEND +#define MAVLINK_START_UART_SEND(chan, length) +#endif + +#ifndef MAVLINK_END_UART_SEND +#define MAVLINK_END_UART_SEND(chan, length) +#endif + +#ifdef MAVLINK_SEPARATE_HELPERS +#define MAVLINK_HELPER +#else +#define MAVLINK_HELPER static inline +#include "mavlink_helpers.h" +#endif // MAVLINK_SEPARATE_HELPERS + +/* always include the prototypes to ensure we don't get out of sync */ +MAVLINK_HELPER mavlink_status_t *mavlink_get_channel_status(uint8_t chan); +#if MAVLINK_CRC_EXTRA +MAVLINK_HELPER uint16_t mavlink_finalize_message_chan(mavlink_message_t *msg, uint8_t system_id, uint8_t component_id, + uint8_t chan, uint8_t length, uint8_t crc_extra); +MAVLINK_HELPER uint16_t mavlink_finalize_message(mavlink_message_t *msg, uint8_t system_id, uint8_t component_id, + uint8_t length, uint8_t crc_extra); +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS +MAVLINK_HELPER void _mav_finalize_message_chan_send(mavlink_channel_t chan, uint8_t msgid, const char *packet, + uint8_t length, uint8_t crc_extra); +#endif +#else +MAVLINK_HELPER uint16_t mavlink_finalize_message_chan(mavlink_message_t *msg, uint8_t system_id, uint8_t component_id, + uint8_t chan, uint8_t length); +MAVLINK_HELPER uint16_t mavlink_finalize_message(mavlink_message_t *msg, uint8_t system_id, uint8_t component_id, + uint8_t length); +MAVLINK_HELPER void _mav_finalize_message_chan_send(mavlink_channel_t chan, uint8_t msgid, const char *packet, uint8_t length); +#endif // MAVLINK_CRC_EXTRA +MAVLINK_HELPER uint16_t mavlink_msg_to_send_buffer(uint8_t *buffer, const mavlink_message_t *msg); +MAVLINK_HELPER void mavlink_start_checksum(mavlink_message_t *msg); +MAVLINK_HELPER void mavlink_update_checksum(mavlink_message_t *msg, uint8_t c); +MAVLINK_HELPER uint8_t mavlink_parse_char(uint8_t chan, uint8_t c, mavlink_message_t *r_message, mavlink_status_t *r_mavlink_status); +MAVLINK_HELPER uint8_t put_bitfield_n_by_index(int32_t b, uint8_t bits, uint8_t packet_index, uint8_t bit_index, + uint8_t *r_bit_index, uint8_t *buffer); +#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS +MAVLINK_HELPER void _mavlink_send_uart(mavlink_channel_t chan, const char *buf, uint16_t len); +MAVLINK_HELPER void _mavlink_resend_uart(mavlink_channel_t chan, const mavlink_message_t *msg); +#endif + +/** + * @brief Get the required buffer size for this message + */ +static inline uint16_t mavlink_msg_get_send_buffer_length(const mavlink_message_t *msg) +{ + return msg->len + MAVLINK_NUM_NON_PAYLOAD_BYTES; +} + +#if MAVLINK_NEED_BYTE_SWAP +static inline void byte_swap_2(char *dst, const char *src) +{ + dst[0] = src[1]; + dst[1] = src[0]; +} +static inline void byte_swap_4(char *dst, const char *src) +{ + dst[0] = src[3]; + dst[1] = src[2]; + dst[2] = src[1]; + dst[3] = src[0]; +} +static inline void byte_swap_8(char *dst, const char *src) +{ + dst[0] = src[7]; + dst[1] = src[6]; + dst[2] = src[5]; + dst[3] = src[4]; + dst[4] = src[3]; + dst[5] = src[2]; + dst[6] = src[1]; + dst[7] = src[0]; +} +#elif !MAVLINK_ALIGNED_FIELDS +static inline void byte_copy_2(char *dst, const char *src) +{ + dst[0] = src[0]; + dst[1] = src[1]; +} +static inline void byte_copy_4(char *dst, const char *src) +{ + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst[3] = src[3]; +} +static inline void byte_copy_8(char *dst, const char *src) +{ + memcpy(dst, src, 8); +} +#endif // if MAVLINK_NEED_BYTE_SWAP + +#define _mav_put_uint8_t(buf, wire_offset, b) buf[wire_offset] = (uint8_t)b +#define _mav_put_int8_t(buf, wire_offset, b) buf[wire_offset] = (int8_t)b +#define _mav_put_char(buf, wire_offset, b) buf[wire_offset] = b + +#if MAVLINK_NEED_BYTE_SWAP +#define _mav_put_uint16_t(buf, wire_offset, b) byte_swap_2(&buf[wire_offset], (const char *)&b) +#define _mav_put_int16_t(buf, wire_offset, b) byte_swap_2(&buf[wire_offset], (const char *)&b) +#define _mav_put_uint32_t(buf, wire_offset, b) byte_swap_4(&buf[wire_offset], (const char *)&b) +#define _mav_put_int32_t(buf, wire_offset, b) byte_swap_4(&buf[wire_offset], (const char *)&b) +#define _mav_put_uint64_t(buf, wire_offset, b) byte_swap_8(&buf[wire_offset], (const char *)&b) +#define _mav_put_int64_t(buf, wire_offset, b) byte_swap_8(&buf[wire_offset], (const char *)&b) +#define _mav_put_float(buf, wire_offset, b) byte_swap_4(&buf[wire_offset], (const char *)&b) +#define _mav_put_double(buf, wire_offset, b) byte_swap_8(&buf[wire_offset], (const char *)&b) +#elif !MAVLINK_ALIGNED_FIELDS +#define _mav_put_uint16_t(buf, wire_offset, b) byte_copy_2(&buf[wire_offset], (const char *)&b) +#define _mav_put_int16_t(buf, wire_offset, b) byte_copy_2(&buf[wire_offset], (const char *)&b) +#define _mav_put_uint32_t(buf, wire_offset, b) byte_copy_4(&buf[wire_offset], (const char *)&b) +#define _mav_put_int32_t(buf, wire_offset, b) byte_copy_4(&buf[wire_offset], (const char *)&b) +#define _mav_put_uint64_t(buf, wire_offset, b) byte_copy_8(&buf[wire_offset], (const char *)&b) +#define _mav_put_int64_t(buf, wire_offset, b) byte_copy_8(&buf[wire_offset], (const char *)&b) +#define _mav_put_float(buf, wire_offset, b) byte_copy_4(&buf[wire_offset], (const char *)&b) +#define _mav_put_double(buf, wire_offset, b) byte_copy_8(&buf[wire_offset], (const char *)&b) +#else +#define _mav_put_uint16_t(buf, wire_offset, b) *(uint16_t *)&buf[wire_offset] = b +#define _mav_put_int16_t(buf, wire_offset, b) *(int16_t *)&buf[wire_offset] = b +#define _mav_put_uint32_t(buf, wire_offset, b) *(uint32_t *)&buf[wire_offset] = b +#define _mav_put_int32_t(buf, wire_offset, b) *(int32_t *)&buf[wire_offset] = b +#define _mav_put_uint64_t(buf, wire_offset, b) *(uint64_t *)&buf[wire_offset] = b +#define _mav_put_int64_t(buf, wire_offset, b) *(int64_t *)&buf[wire_offset] = b +#define _mav_put_float(buf, wire_offset, b) *(float *)&buf[wire_offset] = b +#define _mav_put_double(buf, wire_offset, b) *(double *)&buf[wire_offset] = b +#endif // if MAVLINK_NEED_BYTE_SWAP + +/* + like memcpy(), but if src is NULL, do a memset to zero + */ +static void mav_array_memcpy(void *dest, const void *src, size_t n) +{ + if (src == NULL) { + memset(dest, 0, n); + } else { + memcpy(dest, src, n); + } +} + +/* + * Place a char array into a buffer + */ +static inline void _mav_put_char_array(char *buf, uint8_t wire_offset, const char *b, uint8_t array_length) +{ + mav_array_memcpy(&buf[wire_offset], b, array_length); +} + +/* + * Place a uint8_t array into a buffer + */ +static inline void _mav_put_uint8_t_array(char *buf, uint8_t wire_offset, const uint8_t *b, uint8_t array_length) +{ + mav_array_memcpy(&buf[wire_offset], b, array_length); +} + +/* + * Place a int8_t array into a buffer + */ +static inline void _mav_put_int8_t_array(char *buf, uint8_t wire_offset, const int8_t *b, uint8_t array_length) +{ + mav_array_memcpy(&buf[wire_offset], b, array_length); +} + +#if MAVLINK_NEED_BYTE_SWAP +#define _MAV_PUT_ARRAY(TYPE, V) \ + static inline void _mav_put_##TYPE##_array(char *buf, uint8_t wire_offset, const TYPE * b, uint8_t array_length) \ + { \ + if (b == NULL) { \ + memset(&buf[wire_offset], 0, array_length * sizeof(TYPE)); \ + } \ + else { \ + uint16_t i; \ + for (i = 0; i < array_length; i++) { \ + _mav_put_##TYPE(buf, wire_offset + (i * sizeof(TYPE)), b[i]); \ + } \ + } \ + } +#else +#define _MAV_PUT_ARRAY(TYPE, V) \ + static inline void _mav_put_##TYPE##_array(char *buf, uint8_t wire_offset, const TYPE * b, uint8_t array_length) \ + { \ + mav_array_memcpy(&buf[wire_offset], b, array_length * sizeof(TYPE)); \ + } +#endif + +_MAV_PUT_ARRAY(uint16_t, u16) +_MAV_PUT_ARRAY(uint32_t, u32) +_MAV_PUT_ARRAY(uint64_t, u64) +_MAV_PUT_ARRAY(int16_t, i16) +_MAV_PUT_ARRAY(int32_t, i32) +_MAV_PUT_ARRAY(int64_t, i64) +_MAV_PUT_ARRAY(float, f) +_MAV_PUT_ARRAY(double, d) + +#define _MAV_RETURN_char(msg, wire_offset) (const char)_MAV_PAYLOAD(msg)[wire_offset] +#define _MAV_RETURN_int8_t(msg, wire_offset) (const int8_t)_MAV_PAYLOAD(msg)[wire_offset] +#define _MAV_RETURN_uint8_t(msg, wire_offset) (const uint8_t)_MAV_PAYLOAD(msg)[wire_offset] + +#if MAVLINK_NEED_BYTE_SWAP +#define _MAV_MSG_RETURN_TYPE(TYPE, SIZE) \ + static inline TYPE _MAV_RETURN_##TYPE(const mavlink_message_t * msg, uint8_t ofs) \ + { TYPE r; byte_swap_##SIZE((char *)&r, &_MAV_PAYLOAD(msg)[ofs]); return r; } + +_MAV_MSG_RETURN_TYPE(uint16_t, 2) +_MAV_MSG_RETURN_TYPE(int16_t, 2) +_MAV_MSG_RETURN_TYPE(uint32_t, 4) +_MAV_MSG_RETURN_TYPE(int32_t, 4) +_MAV_MSG_RETURN_TYPE(uint64_t, 8) +_MAV_MSG_RETURN_TYPE(int64_t, 8) +_MAV_MSG_RETURN_TYPE(float, 4) +_MAV_MSG_RETURN_TYPE(double, 8) + +#elif !MAVLINK_ALIGNED_FIELDS +#define _MAV_MSG_RETURN_TYPE(TYPE, SIZE) \ + static inline TYPE _MAV_RETURN_##TYPE(const mavlink_message_t * msg, uint8_t ofs) \ + { TYPE r; byte_copy_##SIZE((char *)&r, &_MAV_PAYLOAD(msg)[ofs]); return r; } + +_MAV_MSG_RETURN_TYPE(uint16_t, 2) +_MAV_MSG_RETURN_TYPE(int16_t, 2) +_MAV_MSG_RETURN_TYPE(uint32_t, 4) +_MAV_MSG_RETURN_TYPE(int32_t, 4) +_MAV_MSG_RETURN_TYPE(uint64_t, 8) +_MAV_MSG_RETURN_TYPE(int64_t, 8) +_MAV_MSG_RETURN_TYPE(float, 4) +_MAV_MSG_RETURN_TYPE(double, 8) +#else // nicely aligned, no swap +#define _MAV_MSG_RETURN_TYPE(TYPE) \ + static inline TYPE _MAV_RETURN_##TYPE(const mavlink_message_t * msg, uint8_t ofs) \ + { return *(const TYPE *)(&_MAV_PAYLOAD(msg)[ofs]); } + +_MAV_MSG_RETURN_TYPE(uint16_t) +_MAV_MSG_RETURN_TYPE(int16_t) +_MAV_MSG_RETURN_TYPE(uint32_t) +_MAV_MSG_RETURN_TYPE(int32_t) +_MAV_MSG_RETURN_TYPE(uint64_t) +_MAV_MSG_RETURN_TYPE(int64_t) +_MAV_MSG_RETURN_TYPE(float) +_MAV_MSG_RETURN_TYPE(double) +#endif // MAVLINK_NEED_BYTE_SWAP + +static inline uint16_t _MAV_RETURN_char_array(const mavlink_message_t *msg, char *value, + uint8_t array_length, uint8_t wire_offset) +{ + memcpy(value, &_MAV_PAYLOAD(msg)[wire_offset], array_length); + return array_length; +} + +static inline uint16_t _MAV_RETURN_uint8_t_array(const mavlink_message_t *msg, uint8_t *value, + uint8_t array_length, uint8_t wire_offset) +{ + memcpy(value, &_MAV_PAYLOAD(msg)[wire_offset], array_length); + return array_length; +} + +static inline uint16_t _MAV_RETURN_int8_t_array(const mavlink_message_t *msg, int8_t *value, + uint8_t array_length, uint8_t wire_offset) +{ + memcpy(value, &_MAV_PAYLOAD(msg)[wire_offset], array_length); + return array_length; +} + +#if MAVLINK_NEED_BYTE_SWAP +#define _MAV_RETURN_ARRAY(TYPE, V) \ + static inline uint16_t _MAV_RETURN_##TYPE##_array(const mavlink_message_t * msg, TYPE * value, \ + uint8_t array_length, uint8_t wire_offset) \ + { \ + uint16_t i; \ + for (i = 0; i < array_length; i++) { \ + value[i] = _MAV_RETURN_##TYPE(msg, wire_offset + (i * sizeof(value[0]))); \ + } \ + return array_length * sizeof(value[0]); \ + } +#else +#define _MAV_RETURN_ARRAY(TYPE, V) \ + static inline uint16_t _MAV_RETURN_##TYPE##_array(const mavlink_message_t * msg, TYPE * value, \ + uint8_t array_length, uint8_t wire_offset) \ + { \ + memcpy(value, &_MAV_PAYLOAD(msg)[wire_offset], array_length * sizeof(TYPE)); \ + return array_length * sizeof(TYPE); \ + } +#endif + +_MAV_RETURN_ARRAY(uint16_t, u16) +_MAV_RETURN_ARRAY(uint32_t, u32) +_MAV_RETURN_ARRAY(uint64_t, u64) +_MAV_RETURN_ARRAY(int16_t, i16) +_MAV_RETURN_ARRAY(int32_t, i32) +_MAV_RETURN_ARRAY(int64_t, i64) +_MAV_RETURN_ARRAY(float, f) +_MAV_RETURN_ARRAY(double, d) + +#endif // _MAVLINK_PROTOCOL_H_ diff --git a/flight/libraries/paths.c b/flight/libraries/paths.c index 8656b920a..c5d473d06 100644 --- a/flight/libraries/paths.c +++ b/flight/libraries/paths.c @@ -2,11 +2,14 @@ ****************************************************************************** * * @file paths.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2015. + * * @brief Library path manipulation * * @see The GNU Public License (GPL) Version 3 * + * @addtogroup LibrePilotLibraries LibrePilot Libraries Navigation *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify @@ -61,6 +64,7 @@ void path_progress(PathDesiredData *path, float *cur_point, struct path_status * break; case PATHDESIRED_MODE_GOTOENDPOINT: + case PATHDESIRED_MODE_AUTOTAKEOFF: // needed for pos hold at end of takeoff return path_endpoint(path, cur_point, status, mode3D); break; diff --git a/flight/libraries/plans.c b/flight/libraries/plans.c index a739c55bf..6e5db8442 100644 --- a/flight/libraries/plans.c +++ b/flight/libraries/plans.c @@ -1,16 +1,15 @@ /** ****************************************************************************** - * @addtogroup OpenPilotLibraries OpenPilot Libraries - * @{ - * @addtogroup Navigation - * @brief setups RTH/PH and other pathfollower/pathplanner status - * @{ * * @file plan.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2015. + * + * @brief setups RTH/PH and other pathfollower/pathplanner status * * @see The GNU Public License (GPL) Version 3 * + * @addtogroup LibrePilotLibraries LibrePilot Libraries Navigation ******************************************************************************/ /* * This program is free software; you can redistribute it and/or modify @@ -43,6 +42,7 @@ #include #include #include +#include #include #define UPDATE_EXPECTED 0.02f @@ -143,7 +143,9 @@ void plan_setup_returnToBase() // For a safer RTB destination altitude will be the higher between takeofflocation and current position (corrected with safety margin) float destDown; + float destVelocity; FlightModeSettingsReturnToBaseAltitudeOffsetGet(&destDown); + FlightModeSettingsReturnToBaseVelocityGet(&destVelocity); destDown = MIN(positionStateDown, takeoffLocation.Down) - destDown; FlightModeSettingsPositionHoldOffsetData offset; FlightModeSettingsPositionHoldOffsetGet(&offset); @@ -156,8 +158,8 @@ void plan_setup_returnToBase() pathDesired.Start.East = takeoffLocation.East; pathDesired.Start.Down = destDown; - pathDesired.StartingVelocity = 0.0f; - pathDesired.EndingVelocity = 0.0f; + pathDesired.StartingVelocity = destVelocity; + pathDesired.EndingVelocity = destVelocity; FlightModeSettingsReturnToBaseNextCommandOptions ReturnToBaseNextCommand; FlightModeSettingsReturnToBaseNextCommandGet(&ReturnToBaseNextCommand); @@ -170,158 +172,35 @@ void plan_setup_returnToBase() PathDesiredSet(&pathDesired); } - -// Vtol AutoTakeoff invocation from flight mode requires the following sequence: -// 1. Arming must be done whilst in the AutoTakeOff flight mode -// 2. If the AutoTakeoff flight mode is selected and already armed, requires disarming first -// 3. Wait for armed state -// 4. Once the user increases the throttle position to above 50%, then and only then initiate auto-takeoff. -// 5. Whilst the throttle is < 50% before takeoff, all stick inputs are being ignored. -// 6. If during the autotakeoff sequence, at any stage, if the throttle stick position reduces to less than 10%, landing is initiated. - -static StatusVtolAutoTakeoffControlStateOptions autotakeoffState = STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_WAITFORARMED; - -#define AUTOTAKEOFF_TO_INCREMENTAL_HEIGHT_MIN 2.0f -#define AUTOTAKEOFF_TO_INCREMENTAL_HEIGHT_MAX 50.0f -static void plan_setup_AutoTakeoff_helper(PathDesiredData *pathDesired) +void plan_setup_AutoTakeoff() { + PathDesiredData pathDesired; + + memset(&pathDesired, 0, sizeof(PathDesiredData)); PositionStateData positionState; PositionStateGet(&positionState); - float velocity_down; float autotakeoff_height; - FlightModeSettingsAutoTakeOffVelocityGet(&velocity_down); FlightModeSettingsAutoTakeOffHeightGet(&autotakeoff_height); - autotakeoff_height = fabsf(autotakeoff_height); - if (autotakeoff_height < AUTOTAKEOFF_TO_INCREMENTAL_HEIGHT_MIN) { - autotakeoff_height = AUTOTAKEOFF_TO_INCREMENTAL_HEIGHT_MIN; - } else if (autotakeoff_height > AUTOTAKEOFF_TO_INCREMENTAL_HEIGHT_MAX) { - autotakeoff_height = AUTOTAKEOFF_TO_INCREMENTAL_HEIGHT_MAX; - } + autotakeoff_height = fabsf(autotakeoff_height); + pathDesired.Start.North = positionState.North; + pathDesired.Start.East = positionState.East; + pathDesired.Start.Down = positionState.Down; + pathDesired.ModeParameters[PATHDESIRED_MODEPARAMETER_AUTOTAKEOFF_NORTH] = 0.0f; + pathDesired.ModeParameters[PATHDESIRED_MODEPARAMETER_AUTOTAKEOFF_EAST] = 0.0f; + pathDesired.ModeParameters[PATHDESIRED_MODEPARAMETER_AUTOTAKEOFF_DOWN] = 0.0f; + pathDesired.ModeParameters[PATHDESIRED_MODEPARAMETER_AUTOTAKEOFF_CONTROLSTATE] = 0.0f; - pathDesired->Start.North = positionState.North; - pathDesired->Start.East = positionState.East; - pathDesired->Start.Down = positionState.Down; - pathDesired->ModeParameters[PATHDESIRED_MODEPARAMETER_AUTOTAKEOFF_NORTH] = 0.0f; - pathDesired->ModeParameters[PATHDESIRED_MODEPARAMETER_AUTOTAKEOFF_EAST] = 0.0f; - pathDesired->ModeParameters[PATHDESIRED_MODEPARAMETER_AUTOTAKEOFF_DOWN] = -velocity_down; - pathDesired->ModeParameters[PATHDESIRED_MODEPARAMETER_AUTOTAKEOFF_CONTROLSTATE] = (float)autotakeoffState; + pathDesired.End.North = positionState.North; + pathDesired.End.East = positionState.East; + pathDesired.End.Down = positionState.Down - autotakeoff_height; - pathDesired->End.North = positionState.North; - pathDesired->End.East = positionState.East; - pathDesired->End.Down = positionState.Down - autotakeoff_height; - - pathDesired->StartingVelocity = 0.0f; - pathDesired->EndingVelocity = 0.0f; - pathDesired->Mode = PATHDESIRED_MODE_AUTOTAKEOFF; -} - -#define AUTOTAKEOFF_INFLIGHT_THROTTLE_CHECK_LIMIT 0.2f -void plan_setup_AutoTakeoff() -{ - autotakeoffState = STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_WAITFORARMED; - // We only allow takeoff if the state transition of disarmed to armed occurs - // whilst in the autotake flight mode - FlightStatusData flightStatus; - FlightStatusGet(&flightStatus); - StabilizationDesiredData stabiDesired; - StabilizationDesiredGet(&stabiDesired); - - // Are we inflight? - if (flightStatus.Armed && stabiDesired.Thrust > AUTOTAKEOFF_INFLIGHT_THROTTLE_CHECK_LIMIT) { - // ok assume already in flight and just enter position hold - // if we are not actually inflight this will just be a violent autotakeoff - autotakeoffState = STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_POSITIONHOLD; - plan_setup_positionHold(); - } else { - if (flightStatus.Armed) { - autotakeoffState = STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_REQUIREUNARMEDFIRST; - // Note that if this mode was invoked unintentionally whilst in flight, effectively - // all inputs get ignored and the vtol continues to fly to its previous - // stabi command. - } - PathDesiredData pathDesired; - // re-initialise in setup stage - memset(&pathDesired, 0, sizeof(PathDesiredData)); - plan_setup_AutoTakeoff_helper(&pathDesired); - PathDesiredSet(&pathDesired); - } -} - -#define AUTOTAKEOFF_THROTTLE_LIMIT_TO_ALLOW_TAKEOFF_START 0.3f -#define AUTOTAKEOFF_THROTTLE_ABORT_LIMIT 0.1f -void plan_run_AutoTakeoff() -{ - StatusVtolAutoTakeoffControlStateOptions priorState = autotakeoffState; - - switch (autotakeoffState) { - case STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_REQUIREUNARMEDFIRST: - { - FlightStatusData flightStatus; - FlightStatusGet(&flightStatus); - if (!flightStatus.Armed) { - autotakeoffState = STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_WAITFORMIDTHROTTLE; - } - } - break; - case STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_WAITFORARMED: - { - FlightStatusData flightStatus; - FlightStatusGet(&flightStatus); - if (flightStatus.Armed) { - autotakeoffState = STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_WAITFORMIDTHROTTLE; - } - } - break; - case STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_WAITFORMIDTHROTTLE: - { - ManualControlCommandData cmd; - ManualControlCommandGet(&cmd); - - if (cmd.Throttle > AUTOTAKEOFF_THROTTLE_LIMIT_TO_ALLOW_TAKEOFF_START) { - autotakeoffState = STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_INITIATE; - } - } - break; - case STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_INITIATE: - { - ManualControlCommandData cmd; - ManualControlCommandGet(&cmd); - - if (cmd.Throttle < AUTOTAKEOFF_THROTTLE_ABORT_LIMIT) { - autotakeoffState = STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_ABORT; - plan_setup_land(); - } - } - break; - - case STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_ABORT: - { - FlightStatusData flightStatus; - FlightStatusGet(&flightStatus); - if (!flightStatus.Armed) { - autotakeoffState = STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_WAITFORARMED; - } - } - break; - case STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_POSITIONHOLD: - // nothing to do. land has been requested. stay here for forever until mode change. - default: - break; - } - - if (autotakeoffState != STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_ABORT && - autotakeoffState != STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_POSITIONHOLD) { - if (priorState != autotakeoffState) { - PathDesiredData pathDesired; - // re-initialise in setup stage - memset(&pathDesired, 0, sizeof(PathDesiredData)); - plan_setup_AutoTakeoff_helper(&pathDesired); - PathDesiredSet(&pathDesired); - } - } + pathDesired.StartingVelocity = 0.0f; + pathDesired.EndingVelocity = 0.0f; + pathDesired.Mode = PATHDESIRED_MODE_AUTOTAKEOFF; + PathDesiredSet(&pathDesired); } static void plan_setup_land_helper(PathDesiredData *pathDesired) diff --git a/flight/libraries/sanitycheck.c b/flight/libraries/sanitycheck.c index bfb4b792b..8c019e38e 100644 --- a/flight/libraries/sanitycheck.c +++ b/flight/libraries/sanitycheck.c @@ -5,7 +5,8 @@ * @addtogroup OpenPilot Libraries OpenPilot System Libraries * @{ * @file sanitycheck.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. * @brief Utilities to validate a flight configuration * @see The GNU Public License (GPL) Version 3 * @@ -163,6 +164,14 @@ int32_t configuration_check() ADDSEVERITY(!coptercontrol); ADDSEVERITY(navCapableFusion); break; +#if !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) + case FLIGHTMODESETTINGS_FLIGHTMODEPOSITION_AUTOTUNE: + ADDSEVERITY(!gps_assisted); + // it would be fun to try autotune on a fixed wing + // but that should only be attempted by devs at first + ADDSEVERITY(multirotor); + break; +#endif /* !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) */ default: // Uncovered modes are automatically an error ADDSEVERITY(false); @@ -225,7 +234,7 @@ int32_t configuration_check() } /** - * Checks the stabiliation settings for a paritcular mode and makes + * Checks the stabilization settings for a particular mode and makes * sure it is appropriate for the airframe * @param[in] index Which stabilization mode to check * @returns true or false @@ -304,12 +313,11 @@ static bool check_stabilization_settings(int index, bool multirotor, bool copter return false; } - - // if cruise control, ensure rate or acro are not set + // if cruise control, ensure Acro+ is not set if (modes[FLIGHTMODESETTINGS_STABILIZATION1SETTINGS_THRUST] == FLIGHTMODESETTINGS_STABILIZATION1SETTINGS_CRUISECONTROL) { for (uint32_t i = 0; i < FLIGHTMODESETTINGS_STABILIZATION1SETTINGS_YAW; i++) { - if ((modes[i] == FLIGHTMODESETTINGS_STABILIZATION1SETTINGS_RATE || - modes[i] == FLIGHTMODESETTINGS_STABILIZATION1SETTINGS_ACRO)) { + // Do not allow Acro+, attitude estimation is not safe. + if (modes[i] == FLIGHTMODESETTINGS_STABILIZATION1SETTINGS_ACRO) { return false; } } diff --git a/flight/make/apps-defs.mk b/flight/make/apps-defs.mk index 45bdb0049..d4d89ce31 100644 --- a/flight/make/apps-defs.mk +++ b/flight/make/apps-defs.mk @@ -34,7 +34,11 @@ FLIGHTLIBINC = $(FLIGHTLIB)/inc OPUAVOBJINC = $(OPUAVOBJ)/inc OPUAVTALKINC = $(OPUAVTALK)/inc -## PID +## MAVLink +MAVLINKINC = $(FLIGHTLIB)/mavlink/v1.0/common + + +## PID PIDLIB =$(FLIGHTLIB)/pid PIDLIBINC =$(FLIGHTLIB)/pid @@ -86,9 +90,14 @@ SRC += $(PIOSCOMMON)/pios_rfm22b.c SRC += $(PIOSCOMMON)/pios_rfm22b_com.c SRC += $(PIOSCOMMON)/pios_rcvr.c SRC += $(PIOSCOMMON)/pios_sbus.c +SRC += $(PIOSCOMMON)/pios_hott.c SRC += $(PIOSCOMMON)/pios_srxl.c +SRC += $(PIOSCOMMON)/pios_exbus.c +SRC += $(PIOSCOMMON)/pios_ibus.c SRC += $(PIOSCOMMON)/pios_sdcard.c SRC += $(PIOSCOMMON)/pios_sensors.c +SRC += $(PIOSCOMMON)/pios_openlrs.c +SRC += $(PIOSCOMMON)/pios_openlrs_rcvr.c ## Misc library functions SRC += $(FLIGHTLIB)/sanitycheck.c @@ -109,6 +118,8 @@ SRC += $(PIOSCOMMON)/pios_com_msg.c SRC += $(PIOSCOMMON)/pios_crc.c SRC += $(PIOSCOMMON)/pios_deltatime.c SRC += $(PIOSCOMMON)/pios_led.c +SRC += $(PIOSCOMMON)/pios_semaphore.c +SRC += $(PIOSCOMMON)/pios_thread.c ifneq ($(PIOS_OMITS_USB),YES) ## PIOS USB related files @@ -130,6 +141,11 @@ SRC += $(MATHLIB)/butterworth.c SRC += $(FLIGHTLIB)/printf-stdarg.c SRC += $(FLIGHTLIB)/optypes.c +## CPP support +ifeq ($(USE_CXX),YES) +CPPSRC += $(FLIGHTLIB)/mini_cpp.cpp +endif + ## Modules SRC += $(foreach mod, $(MODULES), $(sort $(wildcard $(OPMODULEDIR)/$(mod)/*.c))) CPPSRC += $(foreach mod, $(MODULES), $(sort $(wildcard $(OPMODULEDIR)/$(mod)/*.cpp))) @@ -178,6 +194,7 @@ EXTRAINCDIRS += $(PIDLIBINC) EXTRAINCDIRS += $(OPUAVOBJINC) EXTRAINCDIRS += $(OPUAVTALKINC) EXTRAINCDIRS += $(FLIGHT_UAVOBJ_DIR) +EXTRAINCDIRS += $(MAVLINKINC) # Modules EXTRAINCDIRS += $(foreach mod, $(OPTMODULES) $(MODULES), $(OPMODULEDIR)/$(mod)/inc) $(OPMODULEDIR)/System/inc diff --git a/flight/make/boot-defs.mk b/flight/make/boot-defs.mk index b3d03a6ce..42629af9c 100644 --- a/flight/make/boot-defs.mk +++ b/flight/make/boot-defs.mk @@ -67,6 +67,11 @@ SRC += $(PIOSCOMMON)/pios_led.c SRC += $(FLIGHTLIB)/op_dfu.c SRC += $(FLIGHTLIB)/printf-stdarg.c +## CPP support +ifeq ($(USE_CXX),YES) +CPPSRC += $(FLIGHTLIB)/mini_cpp.cpp +endif + # List C source files here which must be compiled in ARM-Mode (no -mthumb). # Use file-extension c for "c-only"-files SRCARM += diff --git a/flight/make/common-defs.mk b/flight/make/common-defs.mk index db5e7a6c7..76b26e961 100644 --- a/flight/make/common-defs.mk +++ b/flight/make/common-defs.mk @@ -234,43 +234,43 @@ endif # Generate code for PyMite # $(OUTDIR)/pmlib_img.c $(OUTDIR)/pmlib_nat.c $(OUTDIR)/pmlibusr_img.c $(OUTDIR)/pmlibusr_nat.c $(OUTDIR)/pmfeatures.h: $(wildcard $(PYMITELIB)/*.py) $(wildcard $(PYMITEPLAT)/*.py) $(wildcard $(FLIGHTPLANLIB)/*.py) $(wildcard $(FLIGHTPLANS)/*.py) -# @echo $(MSG_PYMITEINIT) $(call toprel, $@) +# @echo $(MSG_PYMITEINIT) $(call toprel,$@) # @$(PYTHON) $(PYMITETOOLS)/pmImgCreator.py -f $(PYMITEPLAT)/pmfeatures.py -c -s --memspace=flash -o $(OUTDIR)/pmlib_img.c --native-file=$(OUTDIR)/pmlib_nat.c $(PYMITELIB)/list.py $(PYMITELIB)/dict.py $(PYMITELIB)/__bi.py $(PYMITELIB)/sys.py $(PYMITELIB)/string.py $(wildcard $(FLIGHTPLANLIB)/*.py) # @$(PYTHON) $(PYMITETOOLS)/pmGenPmFeatures.py $(PYMITEPLAT)/pmfeatures.py > $(OUTDIR)/pmfeatures.h # @$(PYTHON) $(PYMITETOOLS)/pmImgCreator.py -f $(PYMITEPLAT)/pmfeatures.py -c -u -o $(OUTDIR)/pmlibusr_img.c --native-file=$(OUTDIR)/pmlibusr_nat.c $(FLIGHTPLANS)/test.py # Link: create ELF output file from object files. ifeq ($(USE_CXX), YES) -$(eval $(call LINK_CXX_TEMPLATE, $(OUTDIR)/$(TARGET).elf, $(ALLOBJ), $(ALLLIB))) +$(eval $(call LINK_CXX_TEMPLATE,$(OUTDIR)/$(TARGET).elf,$(ALLOBJ),$(ALLLIB))) else -$(eval $(call LINK_TEMPLATE, $(OUTDIR)/$(TARGET).elf, $(ALLOBJ), $(ALLLIB))) +$(eval $(call LINK_TEMPLATE,$(OUTDIR)/$(TARGET).elf,$(ALLOBJ),$(ALLLIB))) endif # Assemble: create object files from assembler source files. -$(foreach src, $(ASRC), $(eval $(call ASSEMBLE_TEMPLATE, $(src)))) +$(foreach src, $(ASRC), $(eval $(call ASSEMBLE_TEMPLATE,$(src)))) # Assemble: create object files from assembler source files. ARM-only -$(foreach src, $(ASRCARM), $(eval $(call ASSEMBLE_ARM_TEMPLATE, $(src)))) +$(foreach src, $(ASRCARM), $(eval $(call ASSEMBLE_ARM_TEMPLATE,$(src)))) # Compile: create object files from C source files. -$(foreach src, $(SRC), $(eval $(call COMPILE_C_TEMPLATE, $(src)))) +$(foreach src, $(SRC), $(eval $(call COMPILE_C_TEMPLATE,$(src)))) # Compile: create object files from C source files. ARM-only -$(foreach src, $(SRCARM), $(eval $(call COMPILE_C_ARM_TEMPLATE, $(src)))) +$(foreach src, $(SRCARM), $(eval $(call COMPILE_C_ARM_TEMPLATE,$(src)))) ifeq ($(USE_CXX), YES) # Compile: create object files from C++ source files. -$(foreach src, $(CPPSRC), $(eval $(call COMPILE_CXX_TEMPLATE, $(src)))) +$(foreach src, $(CPPSRC), $(eval $(call COMPILE_CXX_TEMPLATE,$(src)))) # Compile: create object files from C++ source files. ARM-only -$(foreach src, $(CPPSRCARM), $(eval $(call COMPILE_CXX_ARM_TEMPLATE, $(src)))) +$(foreach src, $(CPPSRCARM), $(eval $(call COMPILE_CXX_ARM_TEMPLATE,$(src)))) endif # Compile: create assembler files from C source files. ARM/Thumb -$(eval $(call PARTIAL_COMPILE_TEMPLATE, SRC)) +$(eval $(call PARTIAL_COMPILE_TEMPLATE,SRC)) # Compile: create assembler files from C source files. ARM only -$(eval $(call PARTIAL_COMPILE_ARM_TEMPLATE, SRCARM)) +$(eval $(call PARTIAL_COMPILE_ARM_TEMPLATE,SRCARM)) # Add opfw target $(eval $(call OPFW_TEMPLATE,$(OUTDIR)/$(TARGET).bin,$(BOARD_TYPE),$(BOARD_REVISION))) @@ -287,7 +287,7 @@ bino: $(OUTDIR)/$(TARGET).bin.o opfw: $(OUTDIR)/$(TARGET).opfw # Display sizes of sections. -$(eval $(call SIZE_TEMPLATE, $(OUTDIR)/$(TARGET).elf)) +$(eval $(call SIZE_TEMPLATE,$(OUTDIR)/$(TARGET).elf)) # Target: clean project clean: diff --git a/flight/make/firmware-defs.mk b/flight/make/firmware-defs.mk index 48f65bb3c..14873835e 100644 --- a/flight/make/firmware-defs.mk +++ b/flight/make/firmware-defs.mk @@ -227,9 +227,14 @@ endef define LINK_TEMPLATE .SECONDARY : $(1) .PRECIOUS : $(2) $(3) -$(1): $(2) $(3) +$(1).input_files: $(2) $(3) + $(V1) rm -rf $(1).input_files + $(foreach file,$(2) $(3), + $(V1) echo $(file) >> $$@) + +$(1): $(1).input_files @echo $(MSG_LINKING) $$(call toprel, $$@) - $(V1) $(CC) $(THUMB) $$(CFLAGS) $$(CPPFLAGS) $(2) $(3) --output $$@ $$(LDFLAGS) + $(V1) $(CC) $(THUMB) $$(CFLAGS) $$(CPPFLAGS) @$(1).input_files --output $$@ $$(LDFLAGS) endef # Link: create ELF output file from object files. @@ -238,9 +243,14 @@ endef define LINK_CXX_TEMPLATE .SECONDARY : $(1) .PRECIOUS : $(2) $(3) -$(1): $(2) $(3) +$(1).input_files: $(2) $(3) + $(V1) rm -rf $(1).input_files + $(foreach file,$(2) $(3), + $(V1) echo $(file) >> $$@) + +$(1): $(1).input_files @echo $(MSG_LINKING) $$(call toprel, $$@) - $(V1) $(CXX) $(THUMB) $$(CFLAGS) $$(CPPFLAGS) $$(CXXFLAGS) $(2) $(3) --output $$@ $$(LDFLAGS) + $(V1) $(CXX) $(THUMB) $$(CFLAGS) $$(CPPFLAGS) $$(CXXFLAGS) @$(1).input_files --output $$@ $$(LDFLAGS) endef # Compile: create assembler files from C source files. ARM/Thumb diff --git a/make/unittest.mk b/flight/make/unittest.mk similarity index 90% rename from make/unittest.mk rename to flight/make/unittest.mk index 2190a6ab4..861d3ebf1 100644 --- a/make/unittest.mk +++ b/flight/make/unittest.mk @@ -28,9 +28,11 @@ override ARM_SDK_PREFIX := override THUMB := +GTEST_SRC_DIR := $(GTEST_DIR)/src + # Unit test source files ALLSRC := $(SRC) $(wildcard ./*.c) -ALLCPPSRC := $(wildcard ./*.cpp) $(GTEST_DIR)/src/gtest_main.cc +ALLCPPSRC := $(wildcard ./*.cpp) $(GTEST_SRC_DIR)/gtest_main.cc ALLSRCBASE := $(notdir $(basename $(ALLSRC) $(ALLCPPSRC))) ALLOBJ := $(addprefix $(OUTDIR)/, $(addsuffix .o, $(ALLSRCBASE))) @@ -38,16 +40,16 @@ $(foreach src,$(ALLSRC),$(eval $(call COMPILE_C_TEMPLATE,$(src)))) $(foreach src,$(ALLCPPSRC),$(eval $(call COMPILE_CXX_TEMPLATE,$(src)))) # Specific extensions to CPPFLAGS only for the google test library -$(OUTDIR)/gtest-all.o: CPPFLAGS += -I$(GTEST_DIR) +$(OUTDIR)/gtest-all.o: CPPFLAGS += -I$(GTEST_SRC_DIR)/.. -$(eval $(call COMPILE_CXX_TEMPLATE, $(GTEST_DIR)/src/gtest-all.cc)) +$(eval $(call COMPILE_CXX_TEMPLATE, $(GTEST_SRC_DIR)/gtest-all.cc)) $(eval $(call LINK_CXX_TEMPLATE,$(OUTDIR)/$(TARGET).elf,$(ALLOBJ) $(OUTDIR)/gtest-all.o)) # Flags passed to the preprocessor CPPFLAGS += -I$(GTEST_DIR)/include # Flags passed to the C++ compiler -CXXFLAGS += -g -Wall -Wextra +CXXFLAGS += -g -Wall -Wextra -Wno-missing-field-initializers # Flags passed to the C compiler CONLYFLAGS += -std=gnu99 diff --git a/flight/modules/Actuator/actuator.c b/flight/modules/Actuator/actuator.c index c0adc82f1..a2a66838f 100644 --- a/flight/modules/Actuator/actuator.c +++ b/flight/modules/Actuator/actuator.c @@ -45,6 +45,7 @@ #include "mixersettings.h" #include "mixerstatus.h" #include "cameradesired.h" +#include "hwsettings.h" #include "manualcontrolcommand.h" #include "taskinfo.h" #include @@ -60,23 +61,25 @@ 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 +#define ACTUATOR_ONESHOT_CLOCK 12000000 +#define ACTUATOR_ONESHOT125_PULSE_FACTOR 1.5f +#define ACTUATOR_ONESHOT42_PULSE_FACTOR 0.5f +#define ACTUATOR_MULTISHOT_PULSE_FACTOR 0.24f +#define ACTUATOR_PWM_CLOCK 1000000 // Private types @@ -85,6 +88,7 @@ static xQueueHandle queue; static xTaskHandle taskHandle; static FrameType_t frameType = FRAME_TYPE_MULTIROTOR; static SystemSettingsThrustControlOptions thrustType = SYSTEMSETTINGS_THRUSTCONTROL_THROTTLE; +static bool camStabEnabled; static uint8_t pinsMode[MAX_MIX_ACTUATORS]; // used to inform the actuator thread that actuator update rate is changed @@ -98,7 +102,7 @@ static int mixer_settings_count = 2; // Private functions static void actuatorTask(void *parameters); static int16_t scaleChannel(float value, int16_t max, int16_t min, int16_t neutral); -static int16_t scaleMotor(float value, int16_t max, int16_t min, int16_t neutral, float maxMotor, float minMotor, bool armed, bool AlwaysStabilizeWhenArmed, float throttleDesired); +static int16_t scaleMotor(float value, int16_t max, int16_t min, int16_t neutral, float maxMotor, float minMotor, bool armed, bool alwaysStabilizeWhenArmed, float throttleDesired); static void setFailsafe(); static float MixerCurveFullRangeProportional(const float input, const float *curve, uint8_t elements, bool multirotor); static float MixerCurveFullRangeAbsolute(const float input, const float *curve, uint8_t elements, bool multirotor); @@ -157,6 +161,12 @@ int32_t ActuatorInitialize() // Register AccessoryDesired (Secondary input to this module) AccessoryDesiredInitialize(); + // Check if CameraStab module is enabled + HwSettingsOptionalModulesData optionalModules; + HwSettingsInitialize(); + HwSettingsOptionalModulesGet(&optionalModules); + camStabEnabled = (optionalModules.CameraStab == HWSETTINGS_OPTIONALMODULES_ENABLED); + // Primary output of this module ActuatorCommandInitialize(); @@ -270,10 +280,10 @@ static void actuatorTask(__attribute__((unused)) void *parameters) bool multirotor = (GetCurrentFrameType() == FRAME_TYPE_MULTIROTOR); // check if frame is a multirotor. bool fixedwing = (GetCurrentFrameType() == FRAME_TYPE_FIXED_WING); // check if frame is a fixedwing. bool alwaysArmed = settings.Arming == FLIGHTMODESETTINGS_ARMING_ALWAYSARMED; - bool AlwaysStabilizeWhenArmed = settings.AlwaysStabilizeWhenArmed == FLIGHTMODESETTINGS_ALWAYSSTABILIZEWHENARMED_TRUE; + bool alwaysStabilizeWhenArmed = flightStatus.AlwaysStabilizeWhenArmed == FLIGHTSTATUS_ALWAYSSTABILIZEWHENARMED_TRUE; if (alwaysArmed) { - AlwaysStabilizeWhenArmed = false; // Do not allow always stabilize when alwaysArmed is active. This is dangerous. + alwaysStabilizeWhenArmed = false; // Do not allow always stabilize when alwaysArmed is active. This is dangerous. } // safety settings if (!armed) { @@ -284,7 +294,7 @@ static void actuatorTask(__attribute__((unused)) void *parameters) // throttleDesired should never be 0 or go below 0. // force set all other controls to zero if throttle is cut (previously set in Stabilization) // todo: can probably remove this - if (!(multirotor && AlwaysStabilizeWhenArmed && armed)) { // we don't do this if this is a multirotor AND AlwaysStabilizeWhenArmed is true and the model is armed + if (!(multirotor && alwaysStabilizeWhenArmed && armed)) { // we don't do this if this is a multirotor AND AlwaysStabilizeWhenArmed is true and the model is armed if (actuatorSettings.LowThrottleZeroAxis.Roll == ACTUATORSETTINGS_LOWTHROTTLEZEROAXIS_TRUE) { desired.Roll = 0.00f; } @@ -448,8 +458,9 @@ static void actuatorTask(__attribute__((unused)) void *parameters) if ((mixer_type >= MIXERSETTINGS_MIXER1TYPE_CAMERAROLLORSERVO1) && (mixer_type <= MIXERSETTINGS_MIXER1TYPE_CAMERAYAW)) { - CameraDesiredData cameraDesired; - if (CameraDesiredGet(&cameraDesired) == 0) { + if (camStabEnabled) { + CameraDesiredData cameraDesired; + CameraDesiredGet(&cameraDesired); switch (mixer_type) { case MIXERSETTINGS_MIXER1TYPE_CAMERAROLLORSERVO1: status[ct] = cameraDesired.RollOrServo1; @@ -498,7 +509,7 @@ static void actuatorTask(__attribute__((unused)) void *parameters) maxMotor, minMotor, armed, - AlwaysStabilizeWhenArmed, + alwaysStabilizeWhenArmed, throttleDesired); } else { // else we scale the channel command.Channel[i] = scaleChannel(status[i], @@ -746,7 +757,7 @@ static inline int16_t scaleMotorMoveAndCompress(float valueMotor, int16_t max, i /** * Constrain motor values to keep any one motor value from going too far out of range of another motor */ -static int16_t scaleMotor(float value, int16_t max, int16_t min, int16_t neutral, float maxMotor, float minMotor, bool armed, bool AlwaysStabilizeWhenArmed, float throttleDesired) +static int16_t scaleMotor(float value, int16_t max, int16_t min, int16_t neutral, float maxMotor, float minMotor, bool armed, bool alwaysStabilizeWhenArmed, float throttleDesired) { int16_t valueScaled; @@ -757,7 +768,7 @@ static int16_t scaleMotor(float value, int16_t max, int16_t min, int16_t neutral valueScaled = scaleChannel(value, max, min, neutral); } - // I've added the bool AlwaysStabilizeWhenArmed to this function. Right now we command the motors at min or a range between neutral and max. + // I've added the bool alwaysStabilizeWhenArmed to this function. Right now we command the motors at min or a range between neutral and max. // NEVER should a motor be command at between min and neutral. I don't like the idea of stabilization ever commanding a motor to min, but we give people the option // This prevents motors startup sync issues causing possible ESC failures. @@ -765,8 +776,8 @@ static int16_t scaleMotor(float value, int16_t max, int16_t min, int16_t neutral if (!armed) { // if not armed return min EVERYTIME! valueScaled = min; - } else if (!AlwaysStabilizeWhenArmed && (throttleDesired <= 0.0f) && spinWhileArmed) { - // all motors idle is AlwaysStabilizeWhenArmed is false, throttle is less than or equal to neutral and spin while armed + } else if (!alwaysStabilizeWhenArmed && (throttleDesired <= 0.0f) && spinWhileArmed) { + // all motors idle is alwaysStabilizeWhenArmed is false, throttle is less than or equal to neutral and spin while armed // stabilize when armed? valueScaled = neutral; } else if (!spinWhileArmed && (throttleDesired <= 0.0f)) { @@ -929,8 +940,16 @@ static bool set_channel(uint8_t mixer_channel, uint16_t 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); + // Remap 1000-2000 range to 125-250µs + PIOS_Servo_Set(actuatorSettings.ChannelAddr[mixer_channel], value * ACTUATOR_ONESHOT125_PULSE_FACTOR); + break; + case ACTUATORSETTINGS_BANKMODE_ONESHOT42: + // Remap 1000-2000 range to 41,666-83,333µs + PIOS_Servo_Set(actuatorSettings.ChannelAddr[mixer_channel], value * ACTUATOR_ONESHOT42_PULSE_FACTOR); + break; + case ACTUATORSETTINGS_BANKMODE_MULTISHOT: + // Remap 1000-2000 range to 5-25µs + PIOS_Servo_Set(actuatorSettings.ChannelAddr[mixer_channel], (value * ACTUATOR_MULTISHOT_PULSE_FACTOR) - 180); break; default: PIOS_Servo_Set(actuatorSettings.ChannelAddr[mixer_channel], value); @@ -982,8 +1001,10 @@ static void actuator_update_rate_if_changed(bool force_update) } switch (actuatorSettings.BankMode[i]) { case ACTUATORSETTINGS_BANKMODE_ONESHOT125: + case ACTUATORSETTINGS_BANKMODE_ONESHOT42: + case ACTUATORSETTINGS_BANKMODE_MULTISHOT: 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 2MHz timer clock + clock[i] = ACTUATOR_ONESHOT_CLOCK; // Setup an 12MHz timer clock break; case ACTUATORSETTINGS_BANKMODE_PWMSYNC: freq[i] = 100; diff --git a/flight/modules/Attitude/attitude.c b/flight/modules/Attitude/attitude.c index c9d5fd5f8..beed0308f 100644 --- a/flight/modules/Attitude/attitude.c +++ b/flight/modules/Attitude/attitude.c @@ -8,7 +8,8 @@ * @{ * * @file attitude.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @brief Module to handle all comms to the AHRS on a periodic basis. * * @see The GNU Public License (GPL) Version 3 @@ -83,25 +84,27 @@ PERF_DEFINE_COUNTER(counterAtt); // - 0xA7710004 number of accel samples read for each loop (cc only). // Private constants -#define STACK_SIZE_BYTES 540 -#define TASK_PRIORITY (tskIDLE_PRIORITY + 3) +#define STACK_SIZE_BYTES 540 +#define TASK_PRIORITY (tskIDLE_PRIORITY + 3) // Attitude module loop interval (defined by sensor rate in pios_config.h) static const uint32_t sensor_period_ms = ((uint32_t)1000.0f / PIOS_SENSOR_RATE); -#define UPDATE_RATE 25.0f +#define UPDATE_RATE 25.0f // Interval in number of sample to recalculate temp bias -#define TEMP_CALIB_INTERVAL 30 +#define TEMP_CALIB_INTERVAL 30 // LPF -#define TEMP_DT (1.0f / PIOS_SENSOR_RATE) -#define TEMP_LPF_FC 5.0f +#define TEMP_DT (1.0f / PIOS_SENSOR_RATE) +#define TEMP_LPF_FC 5.0f static const float temp_alpha = TEMP_DT / (TEMP_DT + 1.0f / (2.0f * M_PI_F * TEMP_LPF_FC)); -#define UPDATE_EXPECTED (1.0f / PIOS_SENSOR_RATE) -#define UPDATE_MIN 1.0e-6f -#define UPDATE_MAX 1.0f -#define UPDATE_ALPHA 1.0e-2f +#define UPDATE_EXPECTED (1.0f / PIOS_SENSOR_RATE) +#define UPDATE_MIN 1.0e-6f +#define UPDATE_MAX 1.0f +#define UPDATE_ALPHA 1.0e-2f + +#define VARIANCE_WINDOW_SIZE 40 // Private types @@ -152,6 +155,9 @@ static uint8_t temp_calibration_count = 0; static AccelGyroSettingsgyro_scaleData gyro_scale; static AccelGyroSettingsaccel_scaleData accel_scale; +static pw_variance_t gyro_var[3]; +static bool initialZeroWhenBoardSteady = true; +static float boardSteadyMaxVariance; // For running trim flights static volatile bool trim_requested = false; @@ -243,6 +249,14 @@ static void AttitudeTask(__attribute__((unused)) void *parameters) bool cc3d = BOARDISCC3D; + AccelStateData accelState; + GyroStateData gyros; + int32_t retval = 0; + + gyros.x = 0.0f; + gyros.y = 0.0f; + gyros.z = 0.0f; + if (cc3d) { #if defined(PIOS_INCLUDE_MPU6000) @@ -280,12 +294,31 @@ static void AttitudeTask(__attribute__((unused)) void *parameters) PIOS_DELTATIME_Init(&dtconfig, UPDATE_EXPECTED, UPDATE_MIN, UPDATE_MAX, UPDATE_ALPHA); portTickType lastSysTime = xTaskGetTickCount(); + portTickType startTime = xTaskGetTickCount(); + pseudo_windowed_variance_init(&gyro_var[0], VARIANCE_WINDOW_SIZE); + pseudo_windowed_variance_init(&gyro_var[1], VARIANCE_WINDOW_SIZE); + pseudo_windowed_variance_init(&gyro_var[2], VARIANCE_WINDOW_SIZE); + // Main task loop while (1) { FlightStatusData flightStatus; FlightStatusGet(&flightStatus); - if ((xTaskGetTickCount() < 7000) && (xTaskGetTickCount() > 1000)) { + if (init == 0 && initialZeroWhenBoardSteady) { + pseudo_windowed_variance_push_sample(&gyro_var[0], gyros.x); + pseudo_windowed_variance_push_sample(&gyro_var[1], gyros.y); + pseudo_windowed_variance_push_sample(&gyro_var[2], gyros.z); + float const gyrovarx = pseudo_windowed_variance_get(&gyro_var[0]); + float const gyrovary = pseudo_windowed_variance_get(&gyro_var[1]); + float const gyrovarz = pseudo_windowed_variance_get(&gyro_var[2]); + + if ((fabsf(gyrovarx) + fabsf(gyrovary) + fabsf(gyrovarz)) > boardSteadyMaxVariance) { + startTime = xTaskGetTickCount(); + } + } + if (xTaskGetTickCount() - startTime < 1000) { + PIOS_NOTIFY_StartNotification(NOTIFY_OK, NOTIFY_PRIORITY_REGULAR); + } else if ((xTaskGetTickCount() - startTime < 7000)) { // Use accels to initialise attitude and calculate gyro bias accelKp = 1.0f; accelKi = 0.0f; @@ -316,9 +349,6 @@ static void AttitudeTask(__attribute__((unused)) void *parameters) #ifdef PIOS_INCLUDE_WDG PIOS_WDG_UpdateFlag(PIOS_WDG_ATTITUDE); #endif - AccelStateData accelState; - GyroStateData gyros; - int32_t retval = 0; if (cc3d) { retval = updateSensorsCC3D(&accelState, &gyros); @@ -327,16 +357,14 @@ static void AttitudeTask(__attribute__((unused)) void *parameters) } // Only update attitude when sensor data is good - if (retval != 0) { + // raise alarm if gyro has not been yet calibrated to prevent arming + if (retval != 0 || init == 0) { AlarmsSet(SYSTEMALARMS_ALARM_ATTITUDE, SYSTEMALARMS_ALARM_ERROR); } else { // Do not update attitude data in simulation mode if (!AttitudeStateReadOnly()) { - PERF_TIMED_SECTION_START(counterAtt); updateAttitude(&accelState, &gyros); - PERF_TIMED_SECTION_END(counterAtt); } - PERF_MEASURE_PERIOD(counterPeriod); AlarmsClear(SYSTEMALARMS_ALARM_ATTITUDE); } vTaskDelayUntil(&lastSysTime, sensor_period_ms / portTICK_PERIOD_MS); @@ -606,17 +634,41 @@ static inline void apply_accel_filter(const float *raw, float *filtered) __attribute__((optimize("O3"))) static void updateAttitude(AccelStateData *accelStateData, GyroStateData *gyrosData) { - float dT = PIOS_DELTATIME_GetAverageSeconds(&dtconfig); + static uint32_t samples = 0; + static float gyros_accum[3]; + static float accels_accum[3]; + // Bad practice to assume structure order, but saves memory float *gyros = &gyrosData->x; float *accels = &accelStateData->x; + if (samples < ATTITUDE_SENSORS_DOWNSAMPLE - 1) { + gyros_accum[0] += gyros[0]; + gyros_accum[1] += gyros[1]; + gyros_accum[2] += gyros[2]; + accels_accum[0] += accels[0]; + accels_accum[1] += accels[1]; + accels_accum[2] += accels[2]; + samples++; + return; + } + float dT = PIOS_DELTATIME_GetAverageSeconds(&dtconfig); + PERF_TIMED_SECTION_START(counterAtt); + float inv_samples_count = 1.0f / (float)samples; + samples = 0; + gyros_accum[0] *= inv_samples_count; + gyros_accum[1] *= inv_samples_count; + gyros_accum[2] *= inv_samples_count; + accels_accum[0] *= inv_samples_count; + accels_accum[1] *= inv_samples_count; + accels_accum[2] *= inv_samples_count; + float grot[3]; float accel_err[3]; // Apply smoothing to accel values, to reduce vibration noise before main calculations. - apply_accel_filter(accels, accels_filtered); + apply_accel_filter(accels_accum, accels_filtered); // Rotate gravity unit vector to body frame, filter and cross with accels grot[0] = -(2 * (q[1] * q[3] - q[0] * q[2])); @@ -628,7 +680,7 @@ __attribute__((optimize("O3"))) static void updateAttitude(AccelStateData *accel CrossProduct((const float *)accels_filtered, (const float *)grot_filtered, accel_err); // Account for accel magnitude - float inv_accel_mag = fast_invsqrtf(accels_filtered[0] * accels_filtered[0] + accels_filtered[1] * accels_filtered[1] + accels_filtered[2] * accels_filtered[2]); + float inv_accel_mag = invsqrtf(accels_filtered[0] * accels_filtered[0] + accels_filtered[1] * accels_filtered[1] + accels_filtered[2] * accels_filtered[2]); if (inv_accel_mag > 1e3f) { return; } @@ -637,7 +689,7 @@ __attribute__((optimize("O3"))) static void updateAttitude(AccelStateData *accel float inv_grot_mag; if (accel_filter_enabled) { - inv_grot_mag = fast_invsqrtf(grot_filtered[0] * grot_filtered[0] + grot_filtered[1] * grot_filtered[1] + grot_filtered[2] * grot_filtered[2]); + inv_grot_mag = invsqrtf(grot_filtered[0] * grot_filtered[0] + grot_filtered[1] * grot_filtered[1] + grot_filtered[2] * grot_filtered[2]); } else { inv_grot_mag = 1.0f; } @@ -658,18 +710,18 @@ __attribute__((optimize("O3"))) static void updateAttitude(AccelStateData *accel // Correct rates based on error, integral component dealt with in updateSensors const float kpInvdT = accelKp / dT; - gyros[0] += accel_err[0] * kpInvdT; - gyros[1] += accel_err[1] * kpInvdT; - gyros[2] += accel_err[2] * kpInvdT; + gyros_accum[0] += accel_err[0] * kpInvdT; + gyros_accum[1] += accel_err[1] * kpInvdT; + gyros_accum[2] += accel_err[2] * kpInvdT; { // scoping variables to save memory // Work out time derivative from INSAlgo writeup // Also accounts for the fact that gyros are in deg/s float qdot[4]; - qdot[0] = (-q[1] * gyros[0] - q[2] * gyros[1] - q[3] * gyros[2]) * dT * (M_PI_F / 180.0f / 2.0f); - qdot[1] = (q[0] * gyros[0] - q[3] * gyros[1] + q[2] * gyros[2]) * dT * (M_PI_F / 180.0f / 2.0f); - qdot[2] = (q[3] * gyros[0] + q[0] * gyros[1] - q[1] * gyros[2]) * dT * (M_PI_F / 180.0f / 2.0f); - qdot[3] = (-q[2] * gyros[0] + q[1] * gyros[1] + q[0] * gyros[2]) * dT * (M_PI_F / 180.0f / 2.0f); + qdot[0] = (-q[1] * gyros_accum[0] - q[2] * gyros_accum[1] - q[3] * gyros_accum[2]) * dT * (M_PI_F / 180.0f / 2.0f); + qdot[1] = (q[0] * gyros_accum[0] - q[3] * gyros_accum[1] + q[2] * gyros_accum[2]) * dT * (M_PI_F / 180.0f / 2.0f); + qdot[2] = (q[3] * gyros_accum[0] + q[0] * gyros_accum[1] - q[1] * gyros_accum[2]) * dT * (M_PI_F / 180.0f / 2.0f); + qdot[3] = (-q[2] * gyros_accum[0] + q[1] * gyros_accum[1] + q[0] * gyros_accum[2]) * dT * (M_PI_F / 180.0f / 2.0f); // Take a time step q[0] = q[0] + qdot[0]; @@ -685,8 +737,8 @@ __attribute__((optimize("O3"))) static void updateAttitude(AccelStateData *accel } } - // Renomalize - float inv_qmag = fast_invsqrtf(q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]); + // Renormalize + float inv_qmag = invsqrtf(q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]); // If quaternion has become inappropriately short or is nan reinit. // THIS SHOULD NEVER ACTUALLY HAPPEN @@ -711,6 +763,10 @@ __attribute__((optimize("O3"))) static void updateAttitude(AccelStateData *accel Quaternion2RPY(&attitudeState.q1, &attitudeState.Roll); AttitudeStateSet(&attitudeState); + gyros_accum[0] = gyros_accum[1] = gyros_accum[2] = 0.0f; + accels_accum[0] = accels_accum[1] = accels_accum[2] = 0.0f; + PERF_TIMED_SECTION_END(counterAtt); + PERF_MEASURE_PERIOD(counterPeriod); } static void settingsUpdatedCb(__attribute__((unused)) UAVObjEvent *objEv) @@ -725,6 +781,9 @@ static void settingsUpdatedCb(__attribute__((unused)) UAVObjEvent *objEv) accelKi = attitudeSettings.AccelKi; yawBiasRate = attitudeSettings.YawBiasRate; + initialZeroWhenBoardSteady = (attitudeSettings.InitialZeroWhenBoardSteady == ATTITUDESETTINGS_INITIALZEROWHENBOARDSTEADY_TRUE); + boardSteadyMaxVariance = attitudeSettings.BoardSteadyMaxVariance; + // Calculate accel filter alpha, in the same way as for gyro data in stabilization module. const float fakeDt = 0.0025f; if (attitudeSettings.AccelTau < 0.0001f) { diff --git a/flight/modules/AutoTune/autotune.c b/flight/modules/AutoTune/autotune.c new file mode 100644 index 000000000..d84933c22 --- /dev/null +++ b/flight/modules/AutoTune/autotune.c @@ -0,0 +1,1479 @@ +/** + ****************************************************************************** + * @addtogroup OpenPilotModules OpenPilot Modules + * @{ + * @addtogroup StabilizationModule Stabilization Module + * @brief Stabilization PID loops in an airframe type independent manner + * @note This object updates the @ref ActuatorDesired "Actuator Desired" based on the + * PID loops on the @ref AttitudeDesired "Attitude Desired" and @ref AttitudeState "Attitude State" + * @{ + * + * @file AutoTune/autotune.c + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * dRonin, http://dRonin.org/, Copyright (C) 2015-2016 + * Tau Labs, http://taulabs.org, Copyright (C) 2013-2014 + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. + * @brief Automatic PID tuning module. + * + * @see The GNU Public License (GPL) Version 3 + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(PIOS_EXCLUDE_ADVANCED_FEATURES) +#define powapprox fastpow +#define expapprox fastexp +#else +#define powapprox powf +#define expapprox expf +#endif /* defined(PIOS_EXCLUDE_ADVANCED_FEATURES) */ + + +// Private constants +#undef STACK_SIZE_BYTES +// Pull Request version tested on Sparky2. 292 bytes of stack left when configured with 1340 +// Beware that Nano needs 156 bytes more stack than Sparky2 +#define STACK_SIZE_BYTES 1340 +#define TASK_PRIORITY (tskIDLE_PRIORITY + 1) + +#define AF_NUMX 13 +#define AF_NUMP 43 + +#if !defined(AT_QUEUE_NUMELEM) +#define AT_QUEUE_NUMELEM 18 +#endif + +#define TASK_STARTUP_DELAY_MS 250 /* delay task startup this much, waiting on accessory valid */ +#define NOT_AT_MODE_DELAY_MS 50 /* delay this many ms if not in autotune mode */ +#define NOT_AT_MODE_RATE (1000.0f / NOT_AT_MODE_DELAY_MS) /* this many loops per second if not in autotune mode */ +#define SMOOTH_QUICK_FLUSH_DELAY 0.5f /* wait this long after last change to flush to permanent storage */ +#define SMOOTH_QUICK_FLUSH_TICKS (SMOOTH_QUICK_FLUSH_DELAY * NOT_AT_MODE_RATE) /* this many ticks after last change to flush to permanent storage */ + +#define MAX_PTS_PER_CYCLE 4 /* max gyro updates to process per loop see YIELD_MS and consider gyro rate */ +#define INIT_TIME_DELAY_MS 100 /* delay to allow stab bank, etc. to be populated after flight mode switch change detection */ +#define SYSTEMIDENT_TIME_DELAY_MS 2000 /* delay before starting systemident (shaking) flight mode */ +#define INIT_TIME_DELAY2_MS 2500 /* delay before starting to capture data */ +#define YIELD_MS 2 /* delay this long between processing sessions see MAX_PTS_PER_CYCLE and consider gyro rate */ + +// CheckSettings() returned error bits +#define TAU_NAN 1 +#define BETA_NAN 2 +#define ROLL_BETA_LOW 4 +#define PITCH_BETA_LOW 8 +#define YAW_BETA_LOW 16 +#define TAU_TOO_LONG 32 +#define TAU_TOO_SHORT 64 +#define CPU_TOO_SLOW 128 + +// smooth-quick modes +#define SMOOTH_QUICK_DISABLED 0 +#define SMOOTH_QUICK_ACCESSORY_BASE 10 +#define SMOOTH_QUICK_TOGGLE_BASE 20 + + +// Private types +enum AUTOTUNE_STATE { AT_INIT, AT_INIT_DELAY, AT_INIT_DELAY2, AT_START, AT_RUN, AT_FINISHED, AT_WAITING }; +struct at_queued_data { + float y[3]; /* Gyro measurements */ + float u[3]; /* Actuator desired */ + float throttle; /* Throttle desired */ + uint32_t gyroStateCallbackTimestamp; /* PIOS_DELAY_GetRaw() time of GyroState callback */ + uint32_t sensorReadTimestamp; /* PIOS_DELAY_GetRaw() time of sensor read */ +}; + + +// Private variables +static SystemIdentSettingsData systemIdentSettings; +// save memory because metadata is only briefly accessed, when normal data struct is not being used +// unnamed union issues a warning +static union { + SystemIdentStateData systemIdentState; + UAVObjMetadata systemIdentStateMetaData; +} u; +static StabilizationBankManualRateData manualRate; +static xTaskHandle taskHandle; +static xQueueHandle atQueue; +static float gX[AF_NUMX] = { 0 }; +static float gP[AF_NUMP] = { 0 }; +static float gyroReadTimeAverage; +static float gyroReadTimeAverageAlpha; +static float gyroReadTimeAverageAlphaAlpha; +static float alpha; +static float smoothQuickValue; +static volatile uint32_t atPointsSpilled; +static uint32_t throttleAccumulator; +static uint8_t rollMax, pitchMax; +static int8_t accessoryToUse; +static int8_t flightModeSwitchTogglePosition; +static bool moduleEnabled; + + +// Private functions +static void AtNewGyroData(UAVObjEvent *ev); +static bool AutoTuneFoundInFMS(); +static void AutoTuneTask(void *parameters); +static void AfInit(float X[AF_NUMX], float P[AF_NUMP]); +static void AfPredict(float X[AF_NUMX], float P[AF_NUMP], const float u_in[3], const float gyro[3], const float dT_s, const float t_in); +static bool CheckFlightModeSwitchForPidRequest(uint8_t flightMode); +static uint8_t CheckSettings(); +static uint8_t CheckSettingsRaw(); +static void ComputeStabilizationAndSetPidsFromDampAndNoise(float damp, float noise); +static void FlightModeSettingsUpdatedCb(UAVObjEvent *ev); +static void InitSystemIdent(bool loadDefaults); +static void ProportionPidsSmoothToQuick(); +static void UpdateSystemIdentState(const float *X, const float *noise, float dT_s, uint32_t predicts, uint32_t spills, float hover_throttle); +static void UpdateStabilizationDesired(bool doingIdent); + + +/** + * Initialise the module, called on startup + * \returns 0 on success or -1 if initialisation failed + */ +int32_t AutoTuneInitialize(void) +{ + // do this here since module can become disabled for several reasons + // even for MODULE_AutoTune_BUILTIN + FlightModeSettingsInitialize(); + +#if defined(MODULE_AutoTune_BUILTIN) + moduleEnabled = true; +#else + // HwSettings is only used right here, so init here + HwSettingsInitialize(); + HwSettingsOptionalModulesData optionalModules; + HwSettingsOptionalModulesGet(&optionalModules); + if (optionalModules.AutoTune == HWSETTINGS_OPTIONALMODULES_ENABLED) { + // even though the AutoTune module is automatically enabled + // (below, when the flight mode switch is configured to use autotune) + // there are use cases where the user may even want it enabled without being on the FMS + // that allows PIDs to be adjusted in flight + moduleEnabled = true; + } else { + // if the user did not manually enable the autotune module + // do it for them if they have autotune on their flight mode switch + moduleEnabled = AutoTuneFoundInFMS(); + } +#endif /* defined(MODULE_AutoTune_BUILTIN) */ + + if (moduleEnabled) { + AccessoryDesiredInitialize(); + ActuatorDesiredInitialize(); + FlightStatusInitialize(); + GyroStateInitialize(); + ManualControlCommandInitialize(); + StabilizationBankInitialize(); + StabilizationSettingsBank1Initialize(); + StabilizationSettingsBank2Initialize(); + StabilizationSettingsBank3Initialize(); + SystemIdentSettingsInitialize(); + SystemIdentStateInitialize(); + + atQueue = xQueueCreate(AT_QUEUE_NUMELEM, sizeof(struct at_queued_data)); + if (!atQueue) { + moduleEnabled = false; + } + } + if (!moduleEnabled) { + // only need to watch for enabling AutoTune in FMS if AutoTune module is _not_ running + FlightModeSettingsConnectCallback(FlightModeSettingsUpdatedCb); + } + + return 0; +} + + +/** + * Initialise the module, called on startup + * \returns 0 on success or -1 if initialisation failed + */ +int32_t AutoTuneStart(void) +{ + // Start main task if it is enabled + if (moduleEnabled) { + GyroStateConnectCallback(AtNewGyroData); + xTaskCreate(AutoTuneTask, "AutoTune", STACK_SIZE_BYTES / 4, NULL, TASK_PRIORITY, &taskHandle); + PIOS_TASK_MONITOR_RegisterTask(TASKINFO_RUNNING_AUTOTUNE, taskHandle); + } + return 0; +} + + +MODULE_INITCALL(AutoTuneInitialize, AutoTuneStart); + + +/** + * Module thread, should not return. + */ +static void AutoTuneTask(__attribute__((unused)) void *parameters) +{ + float noise[3] = { 0 }; + float dT_s = 0.0f; + uint32_t lastUpdateTime = 0; // initialization is only for compiler warning + uint32_t lastTime = 0; + uint32_t measureTime = 0; + uint32_t updateCounter = 0; + enum AUTOTUNE_STATE state = AT_INIT; + bool saveSiNeeded = false; + bool savePidNeeded = false; + + // wait for the accessory values to stabilize + // otherwise they come up as zero, then change to their real value + // and that causes the PIDs to be re-exported (if smoothquick is active), which the user may not want + vTaskDelay(TASK_STARTUP_DELAY_MS / portTICK_RATE_MS); + + // get max attitude / max rate + // for use in generating Attitude mode commands from this module + // note that the values could change when they change flight mode (and the associated bank) + StabilizationBankRollMaxGet(&rollMax); + StabilizationBankPitchMaxGet(&pitchMax); + StabilizationBankManualRateGet(&manualRate); + // correctly set accessoryToUse and flightModeSwitchTogglePosition + // based on what is in SystemIdent + // so that the user can use the PID smooth->quick slider in flights following the autotune flight + InitSystemIdent(false); + smoothQuickValue = systemIdentSettings.SmoothQuickValue; + + while (1) { + uint32_t diffTime; + bool doingIdent = false; + bool canSleep = true; + FlightStatusData flightStatus; + FlightStatusGet(&flightStatus); + + if (flightStatus.Armed == FLIGHTSTATUS_ARMED_DISARMED) { + if (saveSiNeeded) { + saveSiNeeded = false; + // Save SystemIdentSettings to permanent settings + UAVObjSave(SystemIdentSettingsHandle(), 0); + } + if (savePidNeeded) { + savePidNeeded = false; + // Save PIDs to permanent settings + switch (systemIdentSettings.DestinationPidBank) { + case 1: + UAVObjSave(StabilizationSettingsBank1Handle(), 0); + break; + case 2: + UAVObjSave(StabilizationSettingsBank2Handle(), 0); + break; + case 3: + UAVObjSave(StabilizationSettingsBank3Handle(), 0); + break; + } + } + } + + // if using flight mode switch "quick toggle 3x" to "try smooth -> quick PIDs" is enabled + // and user toggled into and back out of AutoTune three times in the last two seconds + // and the autotune data gathering is complete + // and the autotune data gathered is good + // note: CheckFlightModeSwitchForPidRequest(mode) only returns true if current mode is not autotune + if (flightModeSwitchTogglePosition != -1 && CheckFlightModeSwitchForPidRequest(flightStatus.FlightMode) + && systemIdentSettings.Complete && !CheckSettings()) { + if (flightStatus.Armed == FLIGHTSTATUS_ARMED_ARMED) { + // if user toggled while armed set PID's to next in sequence + // if you assume that smoothest is -1 and quickest is +1 + // this corresponds to 0,+.50,+1.00,-1.00,-.50 (for 5 position toggle) + smoothQuickValue += 1.0f / (float)flightModeSwitchTogglePosition; + if (smoothQuickValue > 1.001f) { + smoothQuickValue = -1.0f; + } + } else { + // if they did the 3x FMS toggle while disarmed, set PID's back to the middle of smoothquick + smoothQuickValue = 0.0f; + } + // calculate PIDs based on new smoothQuickValue and save to the PID bank + ProportionPidsSmoothToQuick(); + // save new PIDs permanently when / if disarmed + savePidNeeded = true; + // we also save the new knob/toggle value for startup next time + // this keeps the PIDs in sync with the toggle position + saveSiNeeded = true; + } + + ////////////////////////////////////////////////////////////////////////////////////// + // if configured to use a slider for smooth-quick and the autotune module is running + // (note that the module can be automatically or manually enabled) + // then the smooth-quick slider is always active (when not actually in autotune mode) + // + // when the slider is active it will immediately change the PIDs + // and it will schedule the PIDs to be written to permanent storage + // + // if the FC is disarmed, the perm write will happen on next loop + // but if the FC is armed, the perm write will only occur when the FC goes disarmed + ////////////////////////////////////////////////////////////////////////////////////// + + // we don't want it saving to permanent storage many times + // while the user is moving the knob once, so wait till the knob stops moving + static uint8_t savePidDelay; + // any time we are not in AutoTune mode: + // - the user may be using the accessory0-3 knob/slider to request PID changes + // - the state machine needs to be reset + // - the local version of Attitude mode gets skipped + if (flightStatus.FlightMode != FLIGHTSTATUS_FLIGHTMODE_AUTOTUNE) { + // if accessory0-3 is configured as a PID changing slider/knob over the smooth to quick range + // and FC is not currently running autotune + // and accessory0-3 changed by at least 1/85 of full range (2) + // (don't bother checking to see if the requested accessory# is configured properly + // if it isn't, the value will be 0 which is the center of [-1,1] anyway) + if (accessoryToUse != -1 && systemIdentSettings.Complete && !CheckSettings()) { + AccessoryDesiredData accessoryValue; + AccessoryDesiredInstGet(accessoryToUse, &accessoryValue); + // if the accessory changed more than some percent of total range + // some old PPM receivers use a low resolution chip which only allows about 180 steps out of a range of 2.0 + // a test Taranis transmitter knob has about 0.0233 slop out of a range of 2.0 + // what we are doing here does not need any higher precision than that + // user must move the knob more than 1/85th of the total range (of 2.0) for it to register as changed + if (fabsf(smoothQuickValue - accessoryValue.AccessoryVal) > (2.0f / 85.0f)) { + smoothQuickValue = accessoryValue.AccessoryVal; + // calculate PIDs based on new smoothQuickValue and save to the PID bank + ProportionPidsSmoothToQuick(); + // this schedules the first possible write of the PIDs to occur a fraction of a second or so from now + // and changes the scheduled time if it is already scheduled + savePidDelay = SMOOTH_QUICK_FLUSH_TICKS; + } else if (savePidDelay && --savePidDelay == 0) { + // this flags that the PIDs can be written to permanent storage right now + // but they will only be written when the FC is disarmed + // so this means immediate (after NOT_AT_MODE_DELAY_MS) or wait till FC is disarmed + savePidNeeded = true; + // we also save the new knob/toggle value for startup next time + // this avoids rewriting the PIDs at each startup + // because knob is unknown / not where it is expected / looks like knob moved + saveSiNeeded = true; + } + } else { + savePidDelay = 0; + } + state = AT_INIT; + vTaskDelay(NOT_AT_MODE_DELAY_MS / portTICK_RATE_MS); + continue; + } else { + savePidDelay = 0; + } + + switch (state) { + case AT_INIT: + // beware that control comes here every time the user toggles the flight mode switch into AutoTune + // and it isn't appropriate to reset the main state here + // init must wait until after a delay has passed: + // - to make sure they intended to stay in this mode + // - to wait for the stab bank to get populated with the new bank info + // This is a race. It is possible that flightStatus.FlightMode has been changed, + // but the stab bank hasn't been changed yet. + state = AT_INIT_DELAY; + lastUpdateTime = xTaskGetTickCount(); + break; + + case AT_INIT_DELAY: + diffTime = xTaskGetTickCount() - lastUpdateTime; + // after a small delay, get the stab bank values and SystemIdentSettings in case they changed + // this is a very small delay (100ms), so "quick 3x fms toggle" gets in here + if (diffTime > INIT_TIME_DELAY_MS) { + // do these here so the user has at most a 1/10th second + // with controls that use the previous bank's rates + StabilizationBankRollMaxGet(&rollMax); + StabilizationBankPitchMaxGet(&pitchMax); + StabilizationBankManualRateGet(&manualRate); + // load SystemIdentSettings so that they can change it + // and do smooth-quick on changed values + InitSystemIdent(false); + // wait for FC to arm in case they are doing this without a flight mode switch + // that causes the 2+ second delay that follows to happen after arming + // which gives them a chance to take off before the shakes start + // the FC must be armed and if we check here it also allows switchless setup to use autotune + if (flightStatus.Armed == FLIGHTSTATUS_ARMED_ARMED) { + state = AT_INIT_DELAY2; + lastUpdateTime = xTaskGetTickCount(); + } + } + break; + + case AT_INIT_DELAY2: + // delay for 2 seconds before actually starting the SystemIdent flight mode and AutoTune. + // that allows the user to get his fingers on the sticks + // and avoids starting the AutoTune if the user is toggling the flight mode switch + // to select other PIDs on the "simulated Smooth Quick slider". + // or simply "passing through" this flight mode to get to another flight mode + diffTime = xTaskGetTickCount() - lastUpdateTime; + // after 2 seconds start systemident flight mode + if (diffTime > SYSTEMIDENT_TIME_DELAY_MS) { + // load default tune and clean up any NANs from previous tune + InitSystemIdent(true); + AfInit(gX, gP); + // and write it out to the UAVO so innerloop can see the default values + UpdateSystemIdentState(gX, NULL, 0.0f, 0, 0, 0.0f); + // before starting SystemIdent stabilization mode + doingIdent = true; + state = AT_START; + } + break; + + case AT_START: + diffTime = xTaskGetTickCount() - lastUpdateTime; + doingIdent = true; + // after an additional short delay, start capturing data + if (diffTime > INIT_TIME_DELAY2_MS) { + // Reset save status + // save SI data even if partial or bad, aids in diagnostics + saveSiNeeded = true; + // don't save PIDs until data gathering is complete + // and the complete data has been sanity checked + savePidNeeded = false; + // get the tuning duration in case the user just changed it + measureTime = (uint32_t)systemIdentSettings.TuningDuration * (uint32_t)1000; + // init the "previous packet timestamp" + lastTime = PIOS_DELAY_GetRaw(); + /* Drain the queue of all current data */ + xQueueReset(atQueue); + /* And reset the point spill counter */ + updateCounter = 0; + atPointsSpilled = 0; + throttleAccumulator = 0; + alpha = 0.0f; + state = AT_RUN; + lastUpdateTime = xTaskGetTickCount(); + } + break; + + case AT_RUN: + diffTime = xTaskGetTickCount() - lastUpdateTime; + doingIdent = true; + canSleep = false; + // 4 gyro samples per cycle + // 2ms cycle time + // that is 500 gyro samples per second if it sleeps each time + // actually less than 500 because it cycle time is processing time + 2ms + for (int i = 0; i < MAX_PTS_PER_CYCLE; i++) { + struct at_queued_data pt; + /* Grab an autotune point */ + if (xQueueReceive(atQueue, &pt, 0) != pdTRUE) { + /* We've drained the buffer fully */ + canSleep = true; + break; + } + /* calculate time between successive points */ + dT_s = PIOS_DELAY_DiffuS2(lastTime, pt.gyroStateCallbackTimestamp) * 1.0e-6f; + /* This is for the first point, but + * also if we have extended drops */ + if (dT_s > 5.0f / PIOS_SENSOR_RATE) { + dT_s = 5.0f / PIOS_SENSOR_RATE; + } + lastTime = pt.gyroStateCallbackTimestamp; + // original algorithm handles time from GyroStateGet() to detected motion + // this algorithm also includes the time from raw gyro read to GyroStateGet() + gyroReadTimeAverage = gyroReadTimeAverage * alpha + + PIOS_DELAY_DiffuS2(pt.sensorReadTimestamp, pt.gyroStateCallbackTimestamp) * 1.0e-6f * (1.0f - alpha); + alpha = alpha * gyroReadTimeAverageAlphaAlpha + gyroReadTimeAverageAlpha * (1.0f - gyroReadTimeAverageAlphaAlpha); + AfPredict(gX, gP, pt.u, pt.y, dT_s, pt.throttle); + for (int j = 0; j < 3; ++j) { + const float NOISE_ALPHA = 0.9997f; // 10 second time constant at 300 Hz + noise[j] = NOISE_ALPHA * noise[j] + (1 - NOISE_ALPHA) * (pt.y[j] - gX[j]) * (pt.y[j] - gX[j]); + } + // This will work up to 8kHz with an 89% throttle position before overflow + throttleAccumulator += 10000 * pt.throttle; + // Update uavo every 256 cycles to avoid + // telemetry spam + if (((++updateCounter) & 0xff) == 0) { + float hoverThrottle = ((float)(throttleAccumulator / updateCounter)) / 10000.0f; + UpdateSystemIdentState(gX, noise, dT_s, updateCounter, atPointsSpilled, hoverThrottle); + } + } + if (diffTime > measureTime) { // Move on to next state + // permanent flag that AT is complete and PIDs can be calculated + state = AT_FINISHED; + } + break; + + case AT_FINISHED: + // update with info from the last few data points + if ((updateCounter & 0xff) != 0) { + float hoverThrottle = ((float)(throttleAccumulator / updateCounter)) / 10000.0f; + UpdateSystemIdentState(gX, noise, dT_s, updateCounter, atPointsSpilled, hoverThrottle); + } + // data is automatically considered bad if FC was disarmed at the time AT completed + if (flightStatus.Armed == FLIGHTSTATUS_ARMED_ARMED) { + // always calculate and save PIDs if disabling sanity checks + if (!CheckSettings()) { + ProportionPidsSmoothToQuick(); + savePidNeeded = true; + // mark these results as good in the log settings so they can be viewed in playback + u.systemIdentState.Complete = true; + SystemIdentStateCompleteSet(&u.systemIdentState.Complete); + // mark these results as good in the permanent settings so they can be used next flight too + // this is written to the UAVO below, outside of the ARMED and CheckSettings() checks + systemIdentSettings.Complete = true; + } + // always raise an alarm if sanity checks failed + // even if disabling sanity checks + // that way user can still see that they failed + uint8_t failureBits = CheckSettingsRaw(); + if (failureBits) { + // raise a warning that includes failureBits to indicate what failed + ExtendedAlarmsSet(SYSTEMALARMS_ALARM_SYSTEMCONFIGURATION, SYSTEMALARMS_ALARM_WARNING, + SYSTEMALARMS_EXTENDEDALARMSTATUS_AUTOTUNE, failureBits); + } + } + // need to save UAVO after .Complete gets potentially set + // SystemIdentSettings needs the whole UAVO saved so it is saved outside the previous checks + SystemIdentSettingsSet(&systemIdentSettings); + state = AT_WAITING; + break; + + case AT_WAITING: + default: + // after tuning, wait here till user switches to another flight mode + // or disarms + break; + } + + // fly in Attitude mode or in SystemIdent mode + UpdateStabilizationDesired(doingIdent); + + if (canSleep) { + vTaskDelay(YIELD_MS / portTICK_RATE_MS); + } + } +} + + +// FlightModeSettings callback +// determine if autotune is enabled in the flight mode switch +static bool AutoTuneFoundInFMS() +{ + bool found = false; + FlightModeSettingsFlightModePositionOptions fms[FLIGHTMODESETTINGS_FLIGHTMODEPOSITION_NUMELEM]; + uint8_t num_flightMode; + + FlightModeSettingsFlightModePositionGet(fms); + ManualControlSettingsFlightModeNumberGet(&num_flightMode); + for (uint8_t i = 0; i < num_flightMode; ++i) { + if (fms[i] == FLIGHTMODESETTINGS_FLIGHTMODEPOSITION_AUTOTUNE) { + found = true; + break; + } + } + return found; +} + + +// gyro sensor callback +// get gyro data and actuatordesired into a packet +// and put it in the queue for later processing +static void AtNewGyroData(UAVObjEvent *ev) +{ + static struct at_queued_data q_item; + static bool last_sample_unpushed = false; + GyroStateData gyro; + ActuatorDesiredData actuators; + uint32_t timestamp; + + if (!ev || !ev->obj || ev->instId != 0 || ev->event != EV_UPDATED) { + return; + } + + // object will at times change asynchronously so must copy data here, with locking + // and do it as soon as possible + timestamp = PIOS_DELAY_GetRaw(); + GyroStateGet(&gyro); + ActuatorDesiredGet(&actuators); + + if (last_sample_unpushed) { + /* Last time we were unable to queue up the gyro data. + * Try again, last chance! */ + if (xQueueSend(atQueue, &q_item, 0) != pdTRUE) { + atPointsSpilled++; + } + } + + q_item.gyroStateCallbackTimestamp = timestamp; + q_item.y[0] = q_item.y[0] * stabSettings.gyro_alpha + gyro.x * (1 - stabSettings.gyro_alpha); + q_item.y[1] = q_item.y[1] * stabSettings.gyro_alpha + gyro.y * (1 - stabSettings.gyro_alpha); + q_item.y[2] = q_item.y[2] * stabSettings.gyro_alpha + gyro.z * (1 - stabSettings.gyro_alpha); + q_item.u[0] = actuators.Roll; + q_item.u[1] = actuators.Pitch; + q_item.u[2] = actuators.Yaw; + q_item.throttle = actuators.Thrust; + q_item.sensorReadTimestamp = gyro.SensorReadTimestamp; + + if (xQueueSend(atQueue, &q_item, 0) != pdTRUE) { + last_sample_unpushed = true; + } else { + last_sample_unpushed = false; + } +} + + +// this callback is only enabled if the AutoTune module is not running +// if it sees that AutoTune was added to the FMS it issues BOOT and ? alarms +static void FlightModeSettingsUpdatedCb(__attribute__((unused)) UAVObjEvent *ev) +{ + if (AutoTuneFoundInFMS()) { + ExtendedAlarmsSet(SYSTEMALARMS_ALARM_BOOTFAULT, SYSTEMALARMS_ALARM_CRITICAL, SYSTEMALARMS_EXTENDEDALARMSTATUS_REBOOTREQUIRED, 0); + } +} + + +// check for the user quickly toggling the flight mode switch +// into and out of AutoTune, 3 times +// that is a signal that the user wants to try the next PID settings +// on the scale from smooth to quick +// when it exceeds the quickest setting, it starts back at the smoothest setting +static bool CheckFlightModeSwitchForPidRequest(uint8_t flightMode) +{ + static uint32_t lastUpdateTime; + static uint8_t flightModePrev; + static uint8_t counter; + uint32_t updateTime; + + // only count transitions into and out of autotune + if ((flightModePrev == FLIGHTSTATUS_FLIGHTMODE_AUTOTUNE) ^ (flightMode == FLIGHTSTATUS_FLIGHTMODE_AUTOTUNE)) { + flightModePrev = flightMode; + updateTime = xTaskGetTickCount(); + // if it has been over 2 seconds, reset the counter + if (updateTime - lastUpdateTime > 2000) { + counter = 0; + } + // if the counter is reset, start a new time period + if (counter == 0) { + lastUpdateTime = updateTime; + } + // if flight mode has toggled into autotune 3 times but is currently not autotune + if (++counter >= 5 && flightMode != FLIGHTSTATUS_FLIGHTMODE_AUTOTUNE) { + counter = 0; + return true; + } + } + + return false; +} + + +// read SystemIdent uavos, update the local structures +// and set some flags based on the values +// it is used two ways: +// - on startup it reads settings so the user can reuse an old tune with smooth-quick +// - at tune time, it inits the state to default values of uavo xml file, in preparation for tuning +static void InitSystemIdent(bool loadDefaults) +{ + SystemIdentSettingsGet(&systemIdentSettings); + if (loadDefaults) { + // get these 10.0 10.0 7.0 -4.0 from default values of SystemIdent (.Beta and .Tau) + // so that if they are changed there (mainly for future code changes), they will be changed here too + // save metadata from being changed by the following SetDefaults() + SystemIdentStateGetMetadata(&u.systemIdentStateMetaData); + SystemIdentStateSetDefaults(SystemIdentStateHandle(), 0); + SystemIdentStateSetMetadata(&u.systemIdentStateMetaData); + SystemIdentStateGet(&u.systemIdentState); + // Tau, GyroReadTimeAverage, Beta, and the Complete flag get default values + // in preparation for running AutoTune + systemIdentSettings.Tau = u.systemIdentState.Tau; + systemIdentSettings.GyroReadTimeAverage = u.systemIdentState.GyroReadTimeAverage; + memcpy(&systemIdentSettings.Beta, &u.systemIdentState.Beta, sizeof(SystemIdentSettingsBetaData)); + systemIdentSettings.Complete = u.systemIdentState.Complete; + } else { + // Tau, GyroReadTimeAverage, Beta, and the Complete flag get stored values + // so the user can fly another battery to select and test PIDs with the slider/knob + u.systemIdentState.Tau = systemIdentSettings.Tau; + u.systemIdentState.GyroReadTimeAverage = systemIdentSettings.GyroReadTimeAverage; + memcpy(&u.systemIdentState.Beta, &systemIdentSettings.Beta, sizeof(SystemIdentStateBetaData)); + u.systemIdentState.Complete = systemIdentSettings.Complete; + } + SystemIdentStateSet(&u.systemIdentState); + + // (1.0f / PIOS_SENSOR_RATE) is gyro period + // the -1/10 makes it converge nicely, the other values make it converge the same way if the configuration is changed + // gyroReadTimeAverageAlphaAlpha is 0.9996 when the tuning duration is the default of 60 seconds + gyroReadTimeAverageAlphaAlpha = expapprox(-1.0f / PIOS_SENSOR_RATE / ((float)systemIdentSettings.TuningDuration / 10.0f)); + if (!IS_REAL(gyroReadTimeAverageAlphaAlpha)) { + gyroReadTimeAverageAlphaAlpha = expapprox(-1.0f / 500.0f / (60 / 10)); // basically 0.9996 + } + // 0.99999988f is as close to 1.0f as possible to make final average as smooth as possible + gyroReadTimeAverageAlpha = 0.99999988f; + gyroReadTimeAverage = u.systemIdentState.GyroReadTimeAverage; + + uint8_t SmoothQuickSource = systemIdentSettings.SmoothQuickSource; + switch (SmoothQuickSource) { + case SMOOTH_QUICK_ACCESSORY_BASE + 0: // use accessory0 + case SMOOTH_QUICK_ACCESSORY_BASE + 1: // use accessory1 + case SMOOTH_QUICK_ACCESSORY_BASE + 2: // use accessory2 + case SMOOTH_QUICK_ACCESSORY_BASE + 3: // use accessory3 + // leave smoothQuickValue alone since it is always controlled by knob + // disable PID changing with flight mode switch + flightModeSwitchTogglePosition = -1; + // enable PID changing with accessory0-3 + accessoryToUse = SmoothQuickSource - SMOOTH_QUICK_ACCESSORY_BASE; + break; + case SMOOTH_QUICK_TOGGLE_BASE + 3: // use flight mode switch toggle with 3 points + case SMOOTH_QUICK_TOGGLE_BASE + 5: // use flight mode switch toggle with 5 points + case SMOOTH_QUICK_TOGGLE_BASE + 7: // use flight mode switch toggle with 7 points + // don't allow init of current toggle position in the middle of 3x fms toggle + if (loadDefaults) { + // set toggle to middle of range + smoothQuickValue = 0.0f; + } + // enable PID changing with flight mode switch + flightModeSwitchTogglePosition = (SmoothQuickSource - 1 - SMOOTH_QUICK_TOGGLE_BASE) / 2; + // disable PID changing with accessory0-3 + accessoryToUse = -1; + break; + case SMOOTH_QUICK_DISABLED: + default: + // leave smoothQuickValue alone so user can set it to a different value and have it stay that value + // disable PID changing with flight mode switch + flightModeSwitchTogglePosition = -1; + // disable PID changing with accessory0-3 + accessoryToUse = -1; + break; + } +} + + +// update the gain and delay with current calculated value +// these are stored in the settings for use with next battery +// and also in the state for logging purposes +static void UpdateSystemIdentState(const float *X, const float *noise, + float dT_s, uint32_t predicts, uint32_t spills, float hover_throttle) +{ + u.systemIdentState.Beta.Roll = X[6]; + u.systemIdentState.Beta.Pitch = X[7]; + u.systemIdentState.Beta.Yaw = X[8]; + u.systemIdentState.Bias.Roll = X[10]; + u.systemIdentState.Bias.Pitch = X[11]; + u.systemIdentState.Bias.Yaw = X[12]; + u.systemIdentState.Tau = X[9]; + if (noise) { + u.systemIdentState.Noise.Roll = noise[0]; + u.systemIdentState.Noise.Pitch = noise[1]; + u.systemIdentState.Noise.Yaw = noise[2]; + } + u.systemIdentState.Period = dT_s * 1000.0f; + u.systemIdentState.NumAfPredicts = predicts; + u.systemIdentState.NumSpilledPts = spills; + u.systemIdentState.HoverThrottle = hover_throttle; + u.systemIdentState.GyroReadTimeAverage = gyroReadTimeAverage; + + // 'settings' tau, beta, and GyroReadTimeAverage have same value as 'state' versions + // the state version produces a GCS log + // the settings version is remembered after power off/on + systemIdentSettings.Tau = u.systemIdentState.Tau; + memcpy(&systemIdentSettings.Beta, &u.systemIdentState.Beta, sizeof(SystemIdentSettingsBetaData)); + systemIdentSettings.GyroReadTimeAverage = u.systemIdentState.GyroReadTimeAverage; + systemIdentSettings.SmoothQuickValue = smoothQuickValue; + + SystemIdentStateSet(&u.systemIdentState); +} + + +// when running AutoTune mode, this bypasses manualcontrol.c / stabilizedhandler.c +// to control whether the multicopter should be in Attitude mode vs. SystemIdent mode +static void UpdateStabilizationDesired(bool doingIdent) +{ + StabilizationDesiredData stabDesired; + ManualControlCommandData manualControlCommand; + + ManualControlCommandGet(&manualControlCommand); + + stabDesired.Roll = manualControlCommand.Roll * rollMax; + stabDesired.Pitch = manualControlCommand.Pitch * pitchMax; + stabDesired.Yaw = manualControlCommand.Yaw * manualRate.Yaw; + stabDesired.Thrust = manualControlCommand.Thrust; + + if (doingIdent) { + stabDesired.StabilizationMode.Roll = STABILIZATIONDESIRED_STABILIZATIONMODE_SYSTEMIDENT; + stabDesired.StabilizationMode.Pitch = STABILIZATIONDESIRED_STABILIZATIONMODE_SYSTEMIDENT; + stabDesired.StabilizationMode.Yaw = STABILIZATIONDESIRED_STABILIZATIONMODE_SYSTEMIDENT; + } else { + stabDesired.StabilizationMode.Roll = STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE; + stabDesired.StabilizationMode.Pitch = STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE; + stabDesired.StabilizationMode.Yaw = STABILIZATIONDESIRED_STABILIZATIONMODE_RATE; + } + stabDesired.StabilizationMode.Thrust = STABILIZATIONDESIRED_STABILIZATIONMODE_MANUAL; + + StabilizationDesiredSet(&stabDesired); +} + + +// check the completed autotune state (mainly gain and delay) +// to see if it is reasonable +// return a bit mask of errors detected +static uint8_t CheckSettingsRaw() +{ + uint8_t retVal = 0; + + // inverting the comparisons then negating the bool result should catch the nans but it doesn't + // so explictly check for nans + if (!IS_REAL(expapprox(u.systemIdentState.Tau))) { + retVal |= TAU_NAN; + } + if (!IS_REAL(expapprox(u.systemIdentState.Beta.Roll))) { + retVal |= BETA_NAN; + } + if (!IS_REAL(expapprox(u.systemIdentState.Beta.Pitch))) { + retVal |= BETA_NAN; + } + if (!IS_REAL(expapprox(u.systemIdentState.Beta.Yaw))) { + retVal |= BETA_NAN; + } + + // Check the axis gains + // Extreme values: Your roll or pitch gain was lower than expected. This will result in large PID values. + if (u.systemIdentState.Beta.Roll < 6) { + retVal |= ROLL_BETA_LOW; + } + if (u.systemIdentState.Beta.Pitch < 6) { + retVal |= PITCH_BETA_LOW; + } + // yaw gain is no longer checked, because the yaw options only include: + // - not calculating yaw + // - limiting yaw gain between two sane values (default) + // - ignoring errors and accepting the calculated yaw + + // Check the response speed + // Extreme values: Your estimated response speed (tau) is slower than normal. This will result in large PID values. + if (expapprox(u.systemIdentState.Tau) > 0.1f) { + retVal |= TAU_TOO_LONG; + } + // Extreme values: Your estimated response speed (tau) is faster than normal. This will result in large PID values. + else if (expapprox(u.systemIdentState.Tau) < 0.008f) { + retVal |= TAU_TOO_SHORT; + } + + // Sanity check: CPU is too slow compared to gyro rate + if (gyroReadTimeAverage > (1.0f / PIOS_SENSOR_RATE)) { + retVal |= CPU_TOO_SLOW; + } + + return retVal; +} + + +// check the completed autotune state (mainly gain and delay) +// to see if it is reasonable +// override bad yaw values if configured that way +// return a bit mask of errors detected +static uint8_t CheckSettings() +{ + uint8_t retVal = CheckSettingsRaw(); + + if (systemIdentSettings.DisableSanityChecks) { + retVal = 0; + } + return retVal; +} + + +// given Tau"+"GyroReadTimeAverage(delay) and Beta(gain) from the tune (and user selection of smooth to quick) calculate the PIDs +// this code came from dRonin GCS and has been converted from double precision math to single precision +static void ComputeStabilizationAndSetPidsFromDampAndNoise(float dampRate, float noiseRate) +{ + _Static_assert(sizeof(StabilizationSettingsBank1Data) == sizeof(StabilizationBankData), "sizeof(StabilizationSettingsBank1Data) != sizeof(StabilizationBankData)"); + StabilizationBankData volatile stabSettingsBank; + switch (systemIdentSettings.DestinationPidBank) { + case 1: + StabilizationSettingsBank1Get((void *)&stabSettingsBank); + break; + case 2: + StabilizationSettingsBank2Get((void *)&stabSettingsBank); + break; + case 3: + StabilizationSettingsBank3Get((void *)&stabSettingsBank); + break; + } + + // These three parameters define the desired response properties + // - rate scale in the fraction of the natural speed of the system + // to strive for. + // - damp is the amount of damping in the system. higher values + // make oscillations less likely + // - ghf is the amount of high frequency gain and limits the influence + // of noise + const float ghf = noiseRate / 1000.0f; + const float damp = dampRate / 100.0f; + + float tau = expapprox(u.systemIdentState.Tau) + systemIdentSettings.GyroReadTimeAverage; + float exp_beta_roll_times_ghf = expapprox(u.systemIdentState.Beta.Roll) * ghf; + float exp_beta_pitch_times_ghf = expapprox(u.systemIdentState.Beta.Pitch) * ghf; + + float wn = 1.0f / tau; + float tau_d = 0.0f; + for (int i = 0; i < 30; i++) { + float tau_d_roll = (2.0f * damp * tau * wn - 1.0f) / (4.0f * tau * damp * damp * wn * wn - 2.0f * damp * wn - tau * wn * wn + exp_beta_roll_times_ghf); + float tau_d_pitch = (2.0f * damp * tau * wn - 1.0f) / (4.0f * tau * damp * damp * wn * wn - 2.0f * damp * wn - tau * wn * wn + exp_beta_pitch_times_ghf); + // Select the slowest filter property + tau_d = (tau_d_roll > tau_d_pitch) ? tau_d_roll : tau_d_pitch; + wn = (tau + tau_d) / (tau * tau_d) / (2.0f * damp + 2.0f); + } + + // Set the real pole position. The first pole is quite slow, which + // prevents the integral being too snappy and driving too much + // overshoot. + const float a = ((tau + tau_d) / tau / tau_d - 2.0f * damp * wn) / 20.0f; + const float b = ((tau + tau_d) / tau / tau_d - 2.0f * damp * wn - a); + + // Calculate the gain for the outer loop by approximating the + // inner loop as a single order lpf. Set the outer loop to be + // critically damped; + const float zeta_o = 1.3f; + float kp_o = 1.0f / 4.0f / (zeta_o * zeta_o) / (1.0f / wn); + + // Except, if this is very high, we may be slew rate limited and pick + // up oscillation that way. Fix it with very soft clamping. + // (dRonin) MaximumRate defaults to 350, 6.5 corresponds to where we begin + // clamping rate ourselves. ESCs, etc, it depends upon gains + // and any pre-emphasis they do. Still give ourselves partial credit + // for inner loop bandwidth. + + // In dRonin, MaximumRate defaults to 350 and they begin clamping at outer Kp 6.5 + // To avoid oscillation, find the minimum rate, calculate the ratio of that to 350, + // and scale (linearly) with that. Skip yaw. There is no outer yaw in the GUI. + const uint16_t minRate = MIN(stabSettingsBank.MaximumRate.Roll, stabSettingsBank.MaximumRate.Pitch); + const float kp_o_clamp = systemIdentSettings.OuterLoopKpSoftClamp * ((float)minRate / 350.0f); + if (kp_o > kp_o_clamp) { + kp_o = kp_o_clamp - sqrtf(kp_o_clamp) + sqrtf(kp_o); + } + kp_o *= 0.95f; // Pick up some margin. + // Add a zero at 1/15th the innermost bandwidth. + const float ki_o = 0.75f * kp_o / (2.0f * M_PI_F * tau * 15.0f); + + float kpMax = 0.0f; + float betaMinLn = 1000.0f; + StabilizationBankRollRatePIDData volatile *rollPitchPid = NULL; // satisfy compiler warning only + + for (int i = 0; i < ((systemIdentSettings.CalculateYaw != SYSTEMIDENTSETTINGS_CALCULATEYAW_FALSE) ? 3 : 2); i++) { + float betaLn = SystemIdentStateBetaToArray(u.systemIdentState.Beta)[i]; + float beta = expapprox(betaLn); + float ki; + float kp; + float kd; + + switch (i) { + case 0: // Roll + case 1: // Pitch + ki = a * b * wn * wn * tau * tau_d / beta; + kp = tau * tau_d * ((a + b) * wn * wn + 2.0f * a * b * damp * wn) / beta - ki * tau_d; + kd = (tau * tau_d * (a * b + wn * wn + (a + b) * 2.0f * damp * wn) - 1.0f) / beta - kp * tau_d; + if (betaMinLn > betaLn) { + betaMinLn = betaLn; + // RollRatePID PitchRatePID YawRatePID + // form an array of structures + // point to one + // this pointer arithmetic no longer works as expected in a gcc 64 bit test program + // rollPitchPid = &(&stabSettingsBank.RollRatePID)[i]; + if (i == 0) { + rollPitchPid = &stabSettingsBank.RollRatePID; + } else { + rollPitchPid = (StabilizationBankRollRatePIDData *)&stabSettingsBank.PitchRatePID; + } + } + break; + case 2: // Yaw + // yaw uses a mixture of yaw and the slowest axis (pitch) for it's beta and thus PID calculation + // calculate the ratio to use when converting from the slowest axis (pitch) to the yaw axis + // as (e^(betaMinLn-betaYawLn))^0.6 + // which is (e^betaMinLn / e^betaYawLn)^0.6 + // which is (betaMin / betaYaw)^0.6 + // which is betaMin^0.6 / betaYaw^0.6 + // now given that kp for each axis can be written as kpaxis = xp / betaaxis + // for xp that is constant across all axes + // then kpmin (probably kppitch) was xp / betamin (probably betapitch) + // which we multiply by betaMin^0.6 / betaYaw^0.6 to get the new Yaw kp + // so the new kpyaw is (xp / betaMin) * (betaMin^0.6 / betaYaw^0.6) + // which is (xp / betaMin) * (betaMin^0.6 / betaYaw^0.6) + // which is (xp * betaMin^0.6) / (betaMin * betaYaw^0.6) + // which is xp / (betaMin * betaYaw^0.6 / betaMin^0.6) + // which is xp / (betaMin^0.4 * betaYaw^0.6) + // hence the new effective betaYaw for Yaw P is (betaMin^0.4)*(betaYaw^0.6) + beta = expapprox(0.6f * (betaMinLn - u.systemIdentState.Beta.Yaw)); + // this casting assumes that RollRatePID is the same as PitchRatePID + kp = rollPitchPid->Kp * beta; + ki = 0.8f * rollPitchPid->Ki * beta; + kd = 0.8f * rollPitchPid->Kd * beta; + break; + } + + if (i < 2) { + if (kpMax < kp) { + kpMax = kp; + } + } else { + // use the ratio with the largest roll/pitch kp to limit yaw kp to a reasonable value + // use largest roll/pitch kp because it is the axis most slowed by rotational inertia + // and yaw is also slowed maximally by rotational inertia + // note that kp, ki, kd are all proportional in beta + // so reducing them all proportionally is the same as changing beta + float min = 0.0f; + float max = 0.0f; + switch (systemIdentSettings.CalculateYaw) { + case SYSTEMIDENTSETTINGS_CALCULATEYAW_TRUELIMITTORATIO: + max = kpMax * systemIdentSettings.YawToRollPitchPIDRatioMax; + min = kpMax * systemIdentSettings.YawToRollPitchPIDRatioMin; + break; + case SYSTEMIDENTSETTINGS_CALCULATEYAW_TRUEIGNORELIMIT: + default: + max = 1000.0f; + min = 0.0f; + break; + } + + float ratio = 1.0f; + if (min > 0.0f && kp < min) { + ratio = kp / min; + } else if (max > 0.0f && kp > max) { + ratio = kp / max; + } + kp /= ratio; + ki /= ratio; + kd /= ratio; + } + + // reduce kd if so configured + // both of the quads tested for d term oscillation exhibit some degree of it with the stock autotune PIDs + // if may be that adjusting stabSettingsBank.DerivativeCutoff would have a similar affect + // reducing kd requires that kp and ki be reduced to avoid ringing + // the amount to reduce kp and ki is taken from ZN tuning + // specifically kp is parameterized based on the ratio between kp(PID) and kp(PI) as the D factor varies from 1 to 0 + // https://en.wikipedia.org/wiki/PID_controller + // Kp Ki Kd + // ----------------------------------- + // P 0.50*Ku - - + // PI 0.45*Ku 1.2*Kp/Tu - + // PID 0.60*Ku 2.0*Kp/Tu Kp*Tu/8 + // + // so Kp is multiplied by (.45/.60) if Kd is reduced to 0 + // and Ki is multiplied by (1.2/2.0) if Kd is reduced to 0 + #define KP_REDUCTION (.45f / .60f) + #define KI_REDUCTION (1.2f / 2.0f) + + // this link gives some additional ratios that are different + // the reduced overshoot ratios are invalid for this purpose + // https://en.wikipedia.org/wiki/Ziegler%E2%80%93Nichols_method + // Kp Ki Kd + // ------------------------------------------------ + // P 0.50*Ku - - + // PI 0.45*Ku Tu/1.2 - + // PD 0.80*Ku - Tu/8 + // classic PID 0.60*Ku Tu/2.0 Tu/8 #define KP_REDUCTION (.45f/.60f) #define KI_REDUCTION (1.2f/2.0f) + // Pessen Integral Rule 0.70*Ku Tu/2.5 3.0*Tu/20 #define KP_REDUCTION (.45f/.70f) #define KI_REDUCTION (1.2f/2.5f) + // some overshoot 0.33*Ku Tu/2.0 Tu/3 #define KP_REDUCTION (.45f/.33f) #define KI_REDUCTION (1.2f/2.0f) + // no overshoot 0.20*Ku Tu/2.0 Tu/3 #define KP_REDUCTION (.45f/.20f) #define KI_REDUCTION (1.2f/2.0f) + + // reduce roll and pitch, but not yaw + // yaw PID is entirely based on roll or pitch PIDs which have already been reduced + if (i < 2) { + kp = kp * KP_REDUCTION + kp * systemIdentSettings.DerivativeFactor * (1.0f - KP_REDUCTION); + ki = ki * KI_REDUCTION + ki * systemIdentSettings.DerivativeFactor * (1.0f - KI_REDUCTION); + kd *= systemIdentSettings.DerivativeFactor; + } + + switch (i) { + case 0: // Roll + stabSettingsBank.RollRatePID.Kp = kp; + stabSettingsBank.RollRatePID.Ki = ki; + stabSettingsBank.RollRatePID.Kd = kd; + stabSettingsBank.RollPI.Kp = kp_o; + stabSettingsBank.RollPI.Ki = ki_o; + break; + case 1: // Pitch + stabSettingsBank.PitchRatePID.Kp = kp; + stabSettingsBank.PitchRatePID.Ki = ki; + stabSettingsBank.PitchRatePID.Kd = kd; + stabSettingsBank.PitchPI.Kp = kp_o; + stabSettingsBank.PitchPI.Ki = ki_o; + break; + case 2: // Yaw + stabSettingsBank.YawRatePID.Kp = kp; + stabSettingsBank.YawRatePID.Ki = ki; + stabSettingsBank.YawRatePID.Kd = kd; +#if 0 + // if we ever choose to use these + // (e.g. mag yaw attitude) + // here they are + stabSettingsBank.YawPI.Kp = kp_o; + stabSettingsBank.YawPI.Ki = ki_o; +#endif + break; + } + } + + // Librepilot might do something more with this some time + // stabSettingsBank.DerivativeCutoff = 1.0f / (2.0f*M_PI_F*tau_d); + // SystemIdentSettingsDerivativeCutoffSet(&systemIdentSettings.DerivativeCutoff); + // then something to schedule saving this permanently to flash when disarmed + + // Save PIDs to UAVO RAM (not permanently yet) + switch (systemIdentSettings.DestinationPidBank) { + case 1: + StabilizationSettingsBank1Set((void *)&stabSettingsBank); + break; + case 2: + StabilizationSettingsBank2Set((void *)&stabSettingsBank); + break; + case 3: + StabilizationSettingsBank3Set((void *)&stabSettingsBank); + break; + } +} + + +// scale the damp and the noise to generate PIDs according to how a slider or other user specified ratio is set +// +// when val is half way between min and max, it generates the default PIDs +// when val is min, it generates the smoothest configured PIDs +// when val is max, it generates the quickest configured PIDs +// +// when val is between min and (min+max)/2, it scales val over the range [min, (min+max)/2] to generate PIDs between smoothest and default +// when val is between (min+max)/2 and max, it scales val over the range [(min+max)/2, max] to generate PIDs between default and quickest +// +// this is done piecewise because we are not guaranteed that default-min == max-default +// but we are given that [smoothDamp,smoothNoise] [defaultDamp,defaultNoise] [quickDamp,quickNoise] are all good parameterizations +// this code guarantees that we will get those exact parameterizations at (val =) min, (max+min)/2, and max +static void ProportionPidsSmoothToQuick() +{ + float ratio, damp, noise; + float min = -1.0f; + float val = smoothQuickValue; + float max = 1.0f; + + // translate from range [min, max] to range [0, max-min] + // that takes care of min < 0 case too + val -= min; + max -= min; + ratio = val / max; + + if (ratio <= 0.5f) { + // scale ratio in [0,0.5] to produce PIDs in [smoothest,default] + ratio *= 2.0f; + damp = (systemIdentSettings.DampMax * (1.0f - ratio)) + (systemIdentSettings.DampRate * ratio); + noise = (systemIdentSettings.NoiseMin * (1.0f - ratio)) + (systemIdentSettings.NoiseRate * ratio); + } else { + // scale ratio in [0.5,1.0] to produce PIDs in [default,quickest] + ratio = (ratio - 0.5f) * 2.0f; + damp = (systemIdentSettings.DampRate * (1.0f - ratio)) + (systemIdentSettings.DampMin * ratio); + noise = (systemIdentSettings.NoiseRate * (1.0f - ratio)) + (systemIdentSettings.NoiseMax * ratio); + } + + ComputeStabilizationAndSetPidsFromDampAndNoise(damp, noise); + // save it to the system, but not yet written to flash + SystemIdentSettingsSmoothQuickValueSet(&smoothQuickValue); +} + + +/** + * Prediction step for EKF on control inputs to quad that + * learns the system properties + * @param X the current state estimate which is updated in place + * @param P the current covariance matrix, updated in place + * @param[in] the current control inputs (roll, pitch, yaw) + * @param[in] the gyro measurements + */ +__attribute__((always_inline)) static inline void AfPredict(float X[AF_NUMX], float P[AF_NUMP], const float u_in[3], const float gyro[3], const float dT_s, const float t_in) +{ + const float Ts = dT_s; + const float Tsq = Ts * Ts; + const float Tsq3 = Tsq * Ts; + const float Tsq4 = Tsq * Tsq; + + // for convenience and clarity code below uses the named versions of + // the state variables + float w1 = X[0]; // roll rate estimate + float w2 = X[1]; // pitch rate estimate + float w3 = X[2]; // yaw rate estimate + float u1 = X[3]; // scaled roll torque + float u2 = X[4]; // scaled pitch torque + float u3 = X[5]; // scaled yaw torque + const float e_b1 = expapprox(X[6]); // roll torque scale + const float b1 = X[6]; + const float e_b2 = expapprox(X[7]); // pitch torque scale + const float b2 = X[7]; + const float e_b3 = expapprox(X[8]); // yaw torque scale + const float b3 = X[8]; + const float e_tau = expapprox(X[9]); // time response of the motors + const float tau = X[9]; + const float bias1 = X[10]; // bias in the roll torque + const float bias2 = X[11]; // bias in the pitch torque + const float bias3 = X[12]; // bias in the yaw torque + + // inputs to the system (roll, pitch, yaw) + const float u1_in = 4 * t_in * u_in[0]; + const float u2_in = 4 * t_in * u_in[1]; + const float u3_in = 4 * t_in * u_in[2]; + + // measurements from gyro + const float gyro_x = gyro[0]; + const float gyro_y = gyro[1]; + const float gyro_z = gyro[2]; + + // update named variables because we want to use predicted + // values below + w1 = X[0] = w1 - Ts * bias1 * e_b1 + Ts * u1 * e_b1; + w2 = X[1] = w2 - Ts * bias2 * e_b2 + Ts * u2 * e_b2; + w3 = X[2] = w3 - Ts * bias3 * e_b3 + Ts * u3 * e_b3; + u1 = X[3] = (Ts * u1_in) / (Ts + e_tau) + (u1 * e_tau) / (Ts + e_tau); + u2 = X[4] = (Ts * u2_in) / (Ts + e_tau) + (u2 * e_tau) / (Ts + e_tau); + u3 = X[5] = (Ts * u3_in) / (Ts + e_tau) + (u3 * e_tau) / (Ts + e_tau); + // X[6] to X[12] unchanged + + /**** filter parameters ****/ + const float q_w = 1e-3f; + const float q_ud = 1e-3f; + const float q_B = 1e-6f; + const float q_tau = 1e-6f; + const float q_bias = 1e-19f; + const float s_a = 150.0f; // expected gyro measurment noise + + const float Q[AF_NUMX] = { q_w, q_w, q_w, q_ud, q_ud, q_ud, q_B, q_B, q_B, q_tau, q_bias, q_bias, q_bias }; + + float D[AF_NUMP]; + for (uint32_t i = 0; i < AF_NUMP; i++) { + D[i] = P[i]; + } + + const float e_tau2 = e_tau * e_tau; + const float e_tau3 = e_tau * e_tau2; + const float e_tau4 = e_tau2 * e_tau2; + const float Ts_e_tau2 = (Ts + e_tau) * (Ts + e_tau); + const float Ts_e_tau4 = Ts_e_tau2 * Ts_e_tau2; + + // covariance propagation - D is stored copy of covariance + P[0] = D[0] + Q[0] + 2 * Ts * e_b1 * (D[3] - D[28] - D[9] * bias1 + D[9] * u1) + + Tsq * (e_b1 * e_b1) * (D[4] - 2 * D[29] + D[32] - 2 * D[10] * bias1 + 2 * D[30] * bias1 + 2 * D[10] * u1 - 2 * D[30] * u1 + + D[11] * (bias1 * bias1) + D[11] * (u1 * u1) - 2 * D[11] * bias1 * u1); + P[1] = D[1] + Q[1] + 2 * Ts * e_b2 * (D[5] - D[33] - D[12] * bias2 + D[12] * u2) + + Tsq * (e_b2 * e_b2) * (D[6] - 2 * D[34] + D[37] - 2 * D[13] * bias2 + 2 * D[35] * bias2 + 2 * D[13] * u2 - 2 * D[35] * u2 + + D[14] * (bias2 * bias2) + D[14] * (u2 * u2) - 2 * D[14] * bias2 * u2); + P[2] = D[2] + Q[2] + 2 * Ts * e_b3 * (D[7] - D[38] - D[15] * bias3 + D[15] * u3) + + Tsq * (e_b3 * e_b3) * (D[8] - 2 * D[39] + D[42] - 2 * D[16] * bias3 + 2 * D[40] * bias3 + 2 * D[16] * u3 - 2 * D[40] * u3 + + D[17] * (bias3 * bias3) + D[17] * (u3 * u3) - 2 * D[17] * bias3 * u3); + P[3] = (D[3] * (e_tau2 + Ts * e_tau) + Ts * e_b1 * e_tau2 * (D[4] - D[29]) + Tsq * e_b1 * e_tau * (D[4] - D[29]) + + D[18] * Ts * e_tau * (u1 - u1_in) + D[10] * e_b1 * (u1 * (Ts * e_tau2 + Tsq * e_tau) - bias1 * (Ts * e_tau2 + Tsq * e_tau)) + + D[21] * Tsq * e_b1 * e_tau * (u1 - u1_in) + D[31] * Tsq * e_b1 * e_tau * (u1_in - u1) + + D[24] * Tsq * e_b1 * e_tau * (u1 * (u1 - bias1) + u1_in * (bias1 - u1))) / Ts_e_tau2; + P[4] = (Q[3] * Tsq4 + e_tau4 * (D[4] + Q[3]) + 2 * Ts * e_tau3 * (D[4] + 2 * Q[3]) + 4 * Q[3] * Tsq3 * e_tau + + Tsq * e_tau2 * (D[4] + 6 * Q[3] + u1 * (D[27] * u1 + 2 * D[21]) + u1_in * (D[27] * u1_in - 2 * D[21])) + + 2 * D[21] * Ts * e_tau3 * (u1 - u1_in) - 2 * D[27] * Tsq * u1 * u1_in * e_tau2) / Ts_e_tau4; + P[5] = (D[5] * (e_tau2 + Ts * e_tau) + Ts * e_b2 * e_tau2 * (D[6] - D[34]) + + Tsq * e_b2 * e_tau * (D[6] - D[34]) + D[19] * Ts * e_tau * (u2 - u2_in) + + D[13] * e_b2 * (u2 * (Ts * e_tau2 + Tsq * e_tau) - bias2 * (Ts * e_tau2 + Tsq * e_tau)) + + D[22] * Tsq * e_b2 * e_tau * (u2 - u2_in) + D[36] * Tsq * e_b2 * e_tau * (u2_in - u2) + + D[25] * Tsq * e_b2 * e_tau * (u2 * (u2 - bias2) + u2_in * (bias2 - u2))) / Ts_e_tau2; + P[6] = (Q[4] * Tsq4 + e_tau4 * (D[6] + Q[4]) + 2 * Ts * e_tau3 * (D[6] + 2 * Q[4]) + 4 * Q[4] * Tsq3 * e_tau + + Tsq * e_tau2 * (D[6] + 6 * Q[4] + u2 * (D[27] * u2 + 2 * D[22]) + u2_in * (D[27] * u2_in - 2 * D[22])) + + 2 * D[22] * Ts * e_tau3 * (u2 - u2_in) - 2 * D[27] * Tsq * u2 * u2_in * e_tau2) / Ts_e_tau4; + P[7] = (D[7] * (e_tau2 + Ts * e_tau) + Ts * e_b3 * e_tau2 * (D[8] - D[39]) + + Tsq * e_b3 * e_tau * (D[8] - D[39]) + D[20] * Ts * e_tau * (u3 - u3_in) + + D[16] * e_b3 * (u3 * (Ts * e_tau2 + Tsq * e_tau) - bias3 * (Ts * e_tau2 + Tsq * e_tau)) + + D[23] * Tsq * e_b3 * e_tau * (u3 - u3_in) + D[41] * Tsq * e_b3 * e_tau * (u3_in - u3) + + D[26] * Tsq * e_b3 * e_tau * (u3 * (u3 - bias3) + u3_in * (bias3 - u3))) / Ts_e_tau2; + P[8] = (Q[5] * Tsq4 + e_tau4 * (D[8] + Q[5]) + 2 * Ts * e_tau3 * (D[8] + 2 * Q[5]) + 4 * Q[5] * Tsq3 * e_tau + + Tsq * e_tau2 * (D[8] + 6 * Q[5] + u3 * (D[27] * u3 + 2 * D[23]) + u3_in * (D[27] * u3_in - 2 * D[23])) + + 2 * D[23] * Ts * e_tau3 * (u3 - u3_in) - 2 * D[27] * Tsq * u3 * u3_in * e_tau2) / Ts_e_tau4; + P[9] = D[9] - Ts * e_b1 * (D[30] - D[10] + D[11] * (bias1 - u1)); + P[10] = (D[10] * (Ts + e_tau) + D[24] * Ts * (u1 - u1_in)) * (e_tau / Ts_e_tau2); + P[11] = D[11] + Q[6]; + P[12] = D[12] - Ts * e_b2 * (D[35] - D[13] + D[14] * (bias2 - u2)); + P[13] = (D[13] * (Ts + e_tau) + D[25] * Ts * (u2 - u2_in)) * (e_tau / Ts_e_tau2); + P[14] = D[14] + Q[7]; + P[15] = D[15] - Ts * e_b3 * (D[40] - D[16] + D[17] * (bias3 - u3)); + P[16] = (D[16] * (Ts + e_tau) + D[26] * Ts * (u3 - u3_in)) * (e_tau / Ts_e_tau2); + P[17] = D[17] + Q[8]; + P[18] = D[18] - Ts * e_b1 * (D[31] - D[21] + D[24] * (bias1 - u1)); + P[19] = D[19] - Ts * e_b2 * (D[36] - D[22] + D[25] * (bias2 - u2)); + P[20] = D[20] - Ts * e_b3 * (D[41] - D[23] + D[26] * (bias3 - u3)); + P[21] = (D[21] * (Ts + e_tau) + D[27] * Ts * (u1 - u1_in)) * (e_tau / Ts_e_tau2); + P[22] = (D[22] * (Ts + e_tau) + D[27] * Ts * (u2 - u2_in)) * (e_tau / Ts_e_tau2); + P[23] = (D[23] * (Ts + e_tau) + D[27] * Ts * (u3 - u3_in)) * (e_tau / Ts_e_tau2); + P[24] = D[24]; + P[25] = D[25]; + P[26] = D[26]; + P[27] = D[27] + Q[9]; + P[28] = D[28] - Ts * e_b1 * (D[32] - D[29] + D[30] * (bias1 - u1)); + P[29] = (D[29] * (Ts + e_tau) + D[31] * Ts * (u1 - u1_in)) * (e_tau / Ts_e_tau2); + P[30] = D[30]; + P[31] = D[31]; + P[32] = D[32] + Q[10]; + P[33] = D[33] - Ts * e_b2 * (D[37] - D[34] + D[35] * (bias2 - u2)); + P[34] = (D[34] * (Ts + e_tau) + D[36] * Ts * (u2 - u2_in)) * (e_tau / Ts_e_tau2); + P[35] = D[35]; + P[36] = D[36]; + P[37] = D[37] + Q[11]; + P[38] = D[38] - Ts * e_b3 * (D[42] - D[39] + D[40] * (bias3 - u3)); + P[39] = (D[39] * (Ts + e_tau) + D[41] * Ts * (u3 - u3_in)) * (e_tau / Ts_e_tau2); + P[40] = D[40]; + P[41] = D[41]; + P[42] = D[42] + Q[12]; + + /********* this is the update part of the equation ***********/ + float S[3] = { P[0] + s_a, P[1] + s_a, P[2] + s_a }; + X[0] = w1 + P[0] * ((gyro_x - w1) / S[0]); + X[1] = w2 + P[1] * ((gyro_y - w2) / S[1]); + X[2] = w3 + P[2] * ((gyro_z - w3) / S[2]); + X[3] = u1 + P[3] * ((gyro_x - w1) / S[0]); + X[4] = u2 + P[5] * ((gyro_y - w2) / S[1]); + X[5] = u3 + P[7] * ((gyro_z - w3) / S[2]); + X[6] = b1 + P[9] * ((gyro_x - w1) / S[0]); + X[7] = b2 + P[12] * ((gyro_y - w2) / S[1]); + X[8] = b3 + P[15] * ((gyro_z - w3) / S[2]); + X[9] = tau + P[18] * ((gyro_x - w1) / S[0]) + P[19] * ((gyro_y - w2) / S[1]) + P[20] * ((gyro_z - w3) / S[2]); + X[10] = bias1 + P[28] * ((gyro_x - w1) / S[0]); + X[11] = bias2 + P[33] * ((gyro_y - w2) / S[1]); + X[12] = bias3 + P[38] * ((gyro_z - w3) / S[2]); + + // update the duplicate cache + for (uint32_t i = 0; i < AF_NUMP; i++) { + D[i] = P[i]; + } + + // This is an approximation that removes some cross axis uncertainty but + // substantially reduces the number of calculations + P[0] = -D[0] * (D[0] / S[0] - 1); + P[1] = -D[1] * (D[1] / S[1] - 1); + P[2] = -D[2] * (D[2] / S[2] - 1); + P[3] = -D[3] * (D[0] / S[0] - 1); + P[4] = D[4] - D[3] * (D[3] / S[0]); + P[5] = -D[5] * (D[1] / S[1] - 1); + P[6] = D[6] - D[5] * (D[5] / S[1]); + P[7] = -D[7] * (D[2] / S[2] - 1); + P[8] = D[8] - D[7] * (D[7] / S[2]); + P[9] = -D[9] * (D[0] / S[0] - 1); + P[10] = D[10] - D[3] * (D[9] / S[0]); + P[11] = D[11] - D[9] * (D[9] / S[0]); + P[12] = -D[12] * (D[1] / S[1] - 1); + P[13] = D[13] - D[5] * (D[12] / S[1]); + P[14] = D[14] - D[12] * (D[12] / S[1]); + P[15] = -D[15] * (D[2] / S[2] - 1); + P[16] = D[16] - D[7] * (D[15] / S[2]); + P[17] = D[17] - D[15] * (D[15] / S[2]); + P[18] = -D[18] * (D[0] / S[0] - 1); + P[19] = -D[19] * (D[1] / S[1] - 1); + P[20] = -D[20] * (D[2] / S[2] - 1); + P[21] = D[21] - D[3] * (D[18] / S[0]); + P[22] = D[22] - D[5] * (D[19] / S[1]); + P[23] = D[23] - D[7] * (D[20] / S[2]); + P[24] = D[24] - D[9] * (D[18] / S[0]); + P[25] = D[25] - D[12] * (D[19] / S[1]); + P[26] = D[26] - D[15] * (D[20] / S[2]); + P[27] = D[27] - D[18] * (D[18] / S[0]) - D[19] * (D[19] / S[1]) - D[20] * (D[20] / S[2]); + P[28] = -D[28] * (D[0] / S[0] - 1); + P[29] = D[29] - D[3] * (D[28] / S[0]); + P[30] = D[30] - D[9] * (D[28] / S[0]); + P[31] = D[31] - D[18] * (D[28] / S[0]); + P[32] = D[32] - D[28] * (D[28] / S[0]); + P[33] = -D[33] * (D[1] / S[1] - 1); + P[34] = D[34] - D[5] * (D[33] / S[1]); + P[35] = D[35] - D[12] * (D[33] / S[1]); + P[36] = D[36] - D[19] * (D[33] / S[1]); + P[37] = D[37] - D[33] * (D[33] / S[1]); + P[38] = -D[38] * (D[2] / S[2] - 1); + P[39] = D[39] - D[7] * (D[38] / S[2]); + P[40] = D[40] - D[15] * (D[38] / S[2]); + P[41] = D[41] - D[20] * (D[38] / S[2]); + P[42] = D[42] - D[38] * (D[38] / S[2]); + + // apply limits to some of the state variables + if (X[9] > -1.5f) { + X[9] = -1.5f; + } else if (X[9] < -5.5f) { /* 4ms */ + X[9] = -5.5f; + } + if (X[10] > 0.5f) { + X[10] = 0.5f; + } else if (X[10] < -0.5f) { + X[10] = -0.5f; + } + if (X[11] > 0.5f) { + X[11] = 0.5f; + } else if (X[11] < -0.5f) { + X[11] = -0.5f; + } + if (X[12] > 0.5f) { + X[12] = 0.5f; + } else if (X[12] < -0.5f) { + X[12] = -0.5f; + } +} + + +/** + * Initialize the state variable and covariance matrix + * for the system identification EKF + */ +static void AfInit(float X[AF_NUMX], float P[AF_NUMP]) +{ + static const float qInit[AF_NUMX] = { + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + 0.05f, 0.05f, 0.005f, + 0.05f, + 0.05f, 0.05f, 0.05f + }; + + // X[0] = X[1] = X[2] = 0.0f; // assume no rotation + // X[3] = X[4] = X[5] = 0.0f; // and no net torque + // X[6] = X[7] = 10.0f; // roll and pitch medium amount of strength + // X[8] = 7.0f; // yaw strength + // X[9] = -4.0f; // and 50 (18?) ms time scale + // X[10] = X[11] = X[12] = 0.0f; // zero bias + + memset(X, 0, AF_NUMX * sizeof(X[0])); + // get these 10.0 10.0 7.0 -4.0 from default values of SystemIdent (.Beta and .Tau) + // so that if they are changed there (mainly for future code changes), they will be changed here too + memcpy(&X[6], &u.systemIdentState.Beta, sizeof(u.systemIdentState.Beta)); + X[9] = u.systemIdentState.Tau; + + // P initialization + memset(P, 0, AF_NUMP * sizeof(P[0])); + P[0] = qInit[0]; + P[1] = qInit[1]; + P[2] = qInit[2]; + P[4] = qInit[3]; + P[6] = qInit[4]; + P[8] = qInit[5]; + P[11] = qInit[6]; + P[14] = qInit[7]; + P[17] = qInit[8]; + P[27] = qInit[9]; + P[32] = qInit[10]; + P[37] = qInit[11]; + P[42] = qInit[12]; +} + +/** + * @} + * @} + */ diff --git a/flight/modules/Autotune/autotune.c b/flight/modules/Autotune/autotune.c deleted file mode 100644 index 60166dede..000000000 --- a/flight/modules/Autotune/autotune.c +++ /dev/null @@ -1,337 +0,0 @@ -/** - ****************************************************************************** - * @addtogroup OpenPilotModules OpenPilot Modules - * @{ - * @addtogroup Autotuning module - * @brief Reads from @ref ManualControlCommand and fakes a rate mode while - * toggling the channels to relay mode - * @{ - * - * @file autotune.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. - * @brief Module to handle all comms to the AHRS on a periodic basis. - * - * @see The GNU Public License (GPL) Version 3 - * - ******************************************************************************/ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/** - * Input objects: None, takes sensor data via pios - * Output objects: @ref AttitudeRaw @ref AttitudeActual - * - * This module computes an attitude estimate from the sensor data - * - * The module executes in its own thread. - * - * UAVObjects are automatically generated by the UAVObjectGenerator from - * the object definition XML file. - * - * Modules have no API, all communication to other modules is done through UAVObjects. - * However modules may use the API exposed by shared libraries. - * See the OpenPilot wiki for more details. - * http://www.openpilot.org/OpenPilot_Application_Architecture - * - */ - -#include - -#include "flightstatus.h" -#include "hwsettings.h" -#include "manualcontrolcommand.h" -#include "manualcontrolsettings.h" -#include "relaytuning.h" -#include "relaytuningsettings.h" -#include "stabilizationdesired.h" -#include "stabilizationsettings.h" -#include "taskinfo.h" - -// Private constants -#define STACK_SIZE_BYTES 1024 -#define TASK_PRIORITY (tskIDLE_PRIORITY + 2) - -// Private types -enum AUTOTUNE_STATE { AT_INIT, AT_START, AT_ROLL, AT_PITCH, AT_FINISHED, AT_SET }; - -// Private variables -static xTaskHandle taskHandle; -static bool autotuneEnabled; - -// Private functions -static void AutotuneTask(void *parameters); -static void update_stabilization_settings(); - -/** - * Initialise the module, called on startup - * \returns 0 on success or -1 if initialisation failed - */ -int32_t AutotuneInitialize(void) -{ - // Create a queue, connect to manual control command and flightstatus -#ifdef MODULE_AUTOTUNE_BUILTIN - autotuneEnabled = true; -#else - HwSettingsInitialize(); - uint8_t optionalModules[HWSETTINGS_OPTIONALMODULES_NUMELEM]; - - HwSettingsOptionalModulesGet(optionalModules); - - if (optionalModules[HWSETTINGS_OPTIONALMODULES_AUTOTUNE] == HWSETTINGS_OPTIONALMODULES_ENABLED) { - autotuneEnabled = true; - } else { - autotuneEnabled = false; - } -#endif - - return 0; -} - -/** - * Initialise the module, called on startup - * \returns 0 on success or -1 if initialisation failed - */ -int32_t AutotuneStart(void) -{ - // Start main task if it is enabled - if (autotuneEnabled) { - xTaskCreate(AutotuneTask, (signed char *)"Autotune", STACK_SIZE_BYTES / 4, NULL, TASK_PRIORITY, &taskHandle); - - PIOS_TASK_MONITOR_RegisterTask(TASKINFO_RUNNING_AUTOTUNE, taskHandle); - PIOS_WDG_RegisterFlag(PIOS_WDG_AUTOTUNE); - } - return 0; -} - -MODULE_INITCALL(AutotuneInitialize, AutotuneStart); - -/** - * Module thread, should not return. - */ -static void AutotuneTask(__attribute__((unused)) void *parameters) -{ - // AlarmsClear(SYSTEMALARMS_ALARM_ATTITUDE); - - enum AUTOTUNE_STATE state = AT_INIT; - - portTickType lastUpdateTime = xTaskGetTickCount(); - - while (1) { - PIOS_WDG_UpdateFlag(PIOS_WDG_AUTOTUNE); - // TODO: - // 1. get from queue - // 2. based on whether it is flightstatus or manualcontrol - - portTickType diffTime; - - const uint32_t PREPARE_TIME = 2000; - const uint32_t MEAURE_TIME = 30000; - - FlightStatusData flightStatus; - FlightStatusGet(&flightStatus); - - // Only allow this module to run when autotuning - if (flightStatus.FlightMode != FLIGHTSTATUS_FLIGHTMODE_AUTOTUNE) { - state = AT_INIT; - vTaskDelay(50); - continue; - } - - StabilizationDesiredData stabDesired; - StabilizationDesiredGet(&stabDesired); - - StabilizationSettingsData stabSettings; - StabilizationSettingsGet(&stabSettings); - - ManualControlSettingsData manualSettings; - ManualControlSettingsGet(&manualSettings); - - ManualControlCommandData manualControl; - ManualControlCommandGet(&manualControl); - - RelayTuningSettingsData relaySettings; - RelayTuningSettingsGet(&relaySettings); - - bool rate = relaySettings.Mode == RELAYTUNINGSETTINGS_MODE_RATE; - - if (rate) { // rate mode - stabDesired.StabilizationMode[STABILIZATIONDESIRED_STABILIZATIONMODE_ROLL] = STABILIZATIONDESIRED_STABILIZATIONMODE_RATE; - stabDesired.StabilizationMode[STABILIZATIONDESIRED_STABILIZATIONMODE_PITCH] = STABILIZATIONDESIRED_STABILIZATIONMODE_RATE; - - stabDesired.Roll = manualControl.Roll * stabSettings.ManualRate[STABILIZATIONSETTINGS_MANUALRATE_ROLL]; - stabDesired.Pitch = manualControl.Pitch * stabSettings.ManualRate[STABILIZATIONSETTINGS_MANUALRATE_PITCH]; - } else { - stabDesired.StabilizationMode[STABILIZATIONDESIRED_STABILIZATIONMODE_ROLL] = STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE; - stabDesired.StabilizationMode[STABILIZATIONDESIRED_STABILIZATIONMODE_PITCH] = STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE; - - stabDesired.Roll = manualControl.Roll * stabSettings.RollMax; - stabDesired.Pitch = manualControl.Pitch * stabSettings.PitchMax; - } - - stabDesired.StabilizationMode[STABILIZATIONDESIRED_STABILIZATIONMODE_YAW] = STABILIZATIONDESIRED_STABILIZATIONMODE_RATE; - stabDesired.Yaw = manualControl.Yaw * stabSettings.ManualRate[STABILIZATIONSETTINGS_MANUALRATE_YAW]; - stabDesired.StabilizationMode[STABILIZATIONDESIRED_STABILIZATIONMODE_THRUST] = STABILIZATIONDESIRED_STABILIZATIONMODE_MANUAL; - stabDesired.Thrust = manualControl.Thrust; - - switch (state) { - case AT_INIT: - - lastUpdateTime = xTaskGetTickCount(); - - // Only start when armed and flying - if (flightStatus.Armed == FLIGHTSTATUS_ARMED_ARMED && stabDesired.Thrust > 0) { - state = AT_START; - } - break; - - case AT_START: - - diffTime = xTaskGetTickCount() - lastUpdateTime; - - // Spend the first block of time in normal rate mode to get airborne - if (diffTime > PREPARE_TIME) { - state = AT_ROLL; - lastUpdateTime = xTaskGetTickCount(); - } - break; - - case AT_ROLL: - - diffTime = xTaskGetTickCount() - lastUpdateTime; - - // Run relay mode on the roll axis for the measurement time - stabDesired.StabilizationMode[STABILIZATIONDESIRED_STABILIZATIONMODE_ROLL] = rate ? STABILIZATIONDESIRED_STABILIZATIONMODE_RELAYRATE : - STABILIZATIONDESIRED_STABILIZATIONMODE_RELAYATTITUDE; - if (diffTime > MEAURE_TIME) { // Move on to next state - state = AT_PITCH; - lastUpdateTime = xTaskGetTickCount(); - } - break; - - case AT_PITCH: - - diffTime = xTaskGetTickCount() - lastUpdateTime; - - // Run relay mode on the pitch axis for the measurement time - stabDesired.StabilizationMode[STABILIZATIONDESIRED_STABILIZATIONMODE_PITCH] = rate ? STABILIZATIONDESIRED_STABILIZATIONMODE_RELAYRATE : - STABILIZATIONDESIRED_STABILIZATIONMODE_RELAYATTITUDE; - if (diffTime > MEAURE_TIME) { // Move on to next state - state = AT_FINISHED; - lastUpdateTime = xTaskGetTickCount(); - } - break; - - case AT_FINISHED: - - // Wait until disarmed and landed before updating the settings - if (flightStatus.Armed == FLIGHTSTATUS_ARMED_DISARMED && stabDesired.Thrust <= 0) { - state = AT_SET; - } - - break; - - case AT_SET: - update_stabilization_settings(); - state = AT_INIT; - break; - - default: - // Set an alarm or some shit like that - break; - } - - StabilizationDesiredSet(&stabDesired); - - vTaskDelay(10); - } -} - -/** - * Called after measuring roll and pitch to update the - * stabilization settings - * - * takes in @ref RelayTuning and outputs @ref StabilizationSettings - */ -static void update_stabilization_settings() -{ - RelayTuningData relayTuning; - - RelayTuningGet(&relayTuning); - - RelayTuningSettingsData relaySettings; - RelayTuningSettingsGet(&relaySettings); - - StabilizationSettingsData stabSettings; - StabilizationSettingsGet(&stabSettings); - - // Eventually get these settings from RelayTuningSettings - const float gain_ratio_r = 1.0f / 3.0f; - const float zero_ratio_r = 1.0f / 3.0f; - const float gain_ratio_p = 1.0f / 5.0f; - const float zero_ratio_p = 1.0f / 5.0f; - - // For now just run over roll and pitch - for (uint i = 0; i < 2; i++) { - float wu = 1000.0f * 2 * M_PI / relayTuning.Period[i]; // ultimate freq = output osc freq (rad/s) - - float wc = wu * gain_ratio_r; // target openloop crossover frequency (rad/s) - float zc = wc * zero_ratio_r; // controller zero location (rad/s) - float kpu = 4.0f / M_PI / relayTuning.Gain[i]; // ultimate gain, i.e. the proportional gain for instablity - float kp = kpu * gain_ratio_r; // proportional gain - float ki = zc * kp; // integral gain - - // Now calculate gains for the next loop out knowing it is the integral of - // the inner loop -- the plant is position/velocity = scale*1/s - float wc2 = wc * gain_ratio_p; // crossover of the attitude loop - float kp2 = wc2; // kp of attitude - float ki2 = wc2 * zero_ratio_p * kp2; // ki of attitude - - switch (i) { - case 0: // roll - stabSettings.RollRatePID[STABILIZATIONSETTINGS_ROLLRATEPID_KP] = kp; - stabSettings.RollRatePID[STABILIZATIONSETTINGS_ROLLRATEPID_KI] = ki; - stabSettings.RollPI[STABILIZATIONSETTINGS_ROLLPI_KP] = kp2; - stabSettings.RollPI[STABILIZATIONSETTINGS_ROLLPI_KI] = ki2; - break; - case 1: // Pitch - stabSettings.PitchRatePID[STABILIZATIONSETTINGS_ROLLRATEPID_KP] = kp; - stabSettings.PitchRatePID[STABILIZATIONSETTINGS_ROLLRATEPID_KI] = ki; - stabSettings.PitchPI[STABILIZATIONSETTINGS_ROLLPI_KP] = kp2; - stabSettings.PitchPI[STABILIZATIONSETTINGS_ROLLPI_KI] = ki2; - break; - default: - // Oh shit oh shit oh shit - break; - } - } - switch (relaySettings.Behavior) { - case RELAYTUNINGSETTINGS_BEHAVIOR_MEASURE: - // Just measure, don't update the stab settings - break; - case RELAYTUNINGSETTINGS_BEHAVIOR_COMPUTE: - StabilizationSettingsSet(&stabSettings); - break; - case RELAYTUNINGSETTINGS_BEHAVIOR_SAVE: - StabilizationSettingsSet(&stabSettings); - UAVObjSave(StabilizationSettingsHandle(), 0); - break; - } -} - -/** - * @} - * @} - */ diff --git a/flight/modules/ComUsbBridge/ComUsbBridge.c b/flight/modules/ComUsbBridge/ComUsbBridge.c index 400b921ac..15f9f5db9 100644 --- a/flight/modules/ComUsbBridge/ComUsbBridge.c +++ b/flight/modules/ComUsbBridge/ComUsbBridge.c @@ -32,7 +32,6 @@ #include -#include "hwsettings.h" #include "taskinfo.h" #include @@ -42,8 +41,9 @@ static void com2UsbBridgeTask(void *parameters); static void usb2ComBridgeTask(void *parameters); -static void updateSettings(UAVObjEvent *ev); static void usb2ComBridgeSetCtrlLine(uint32_t com_id, uint32_t mask, uint32_t state); +static void usb2ComBridgeSetBaudRate(uint32_t com_id, uint32_t baud); + // **************** // Private constants @@ -105,15 +105,14 @@ static int32_t comUsbBridgeInitialize(void) PIOS_COM_RegisterCtrlLineCallback(vcp_port, usb2ComBridgeSetCtrlLine, usart_port); + PIOS_COM_RegisterBaudRateCallback(vcp_port, + usb2ComBridgeSetBaudRate, + usart_port); } #ifdef MODULE_COMUSBBRIDGE_BUILTIN bridge_enabled = true; #else - HwSettingsInitialize(); - HwSettingsOptionalModulesData optionalModules; - - HwSettingsOptionalModulesGet(&optionalModules); if (usart_port && vcp_port) { bridge_enabled = true; @@ -127,8 +126,6 @@ static int32_t comUsbBridgeInitialize(void) PIOS_Assert(com2usb_buf); usb2com_buf = pios_malloc(BRIDGE_BUF_LEN); PIOS_Assert(usb2com_buf); - HwSettingsConnectCallback(&updateSettings); - updateSettings(0); } return 0; @@ -186,36 +183,7 @@ static void usb2ComBridgeSetCtrlLine(uint32_t com_id, uint32_t mask, uint32_t st PIOS_COM_SetCtrlLine(com_id, mask, state); } -static void updateSettings(__attribute__((unused)) UAVObjEvent *ev) +static void usb2ComBridgeSetBaudRate(uint32_t com_id, uint32_t baud) { - if (usart_port) { - // Retrieve settings - uint8_t speed; - HwSettingsComUsbBridgeSpeedGet(&speed); - - // Set port speed - switch (speed) { - case HWSETTINGS_COMUSBBRIDGESPEED_2400: - PIOS_COM_ChangeBaud(usart_port, 2400); - break; - case HWSETTINGS_COMUSBBRIDGESPEED_4800: - PIOS_COM_ChangeBaud(usart_port, 4800); - break; - case HWSETTINGS_COMUSBBRIDGESPEED_9600: - PIOS_COM_ChangeBaud(usart_port, 9600); - break; - case HWSETTINGS_COMUSBBRIDGESPEED_19200: - PIOS_COM_ChangeBaud(usart_port, 19200); - break; - case HWSETTINGS_COMUSBBRIDGESPEED_38400: - PIOS_COM_ChangeBaud(usart_port, 38400); - break; - case HWSETTINGS_COMUSBBRIDGESPEED_57600: - PIOS_COM_ChangeBaud(usart_port, 57600); - break; - case HWSETTINGS_COMUSBBRIDGESPEED_115200: - PIOS_COM_ChangeBaud(usart_port, 115200); - break; - } - } + PIOS_COM_ChangeBaud(com_id, baud); } diff --git a/flight/modules/GPS/DJI.c b/flight/modules/GPS/DJI.c new file mode 100644 index 000000000..a178e1cf2 --- /dev/null +++ b/flight/modules/GPS/DJI.c @@ -0,0 +1,408 @@ +/** + ****************************************************************************** + * @addtogroup OpenPilotModules OpenPilot Modules + * @{ + * @addtogroup GPSModule GPS Module + * @brief Process GPS information (DJI-Naza binary format) + * @{ + * + * @file DJI.c + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * @brief GPS module, handles DJI stream + * @see The GNU Public License (GPL) Version 3 + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "openpilot.h" +#include "pios.h" +#include "pios_math.h" +#include +#include + +#if defined(PIOS_INCLUDE_GPS_DJI_PARSER) + +#include "inc/DJI.h" +#include "inc/GPS.h" +#include +#include + +// parsing functions +static void parse_dji_gps(struct DJIPacket *dji, GPSPositionSensorData *gpsPosition); +#if !defined(PIOS_GPS_MINIMAL) +static void parse_dji_mag(struct DJIPacket *dji, GPSPositionSensorData *gpsPosition); +static void parse_dji_ver(struct DJIPacket *dji, GPSPositionSensorData *gpsPosition); +#endif /* !defined(PIOS_GPS_MINIMAL) */ + +static bool checksum_dji_message(struct DJIPacket *dji); +static uint32_t parse_dji_message(struct DJIPacket *dji, GPSPositionSensorData *gpsPosition); + +// parse table item +typedef struct { + uint8_t msgId; + void (*handler)(struct DJIPacket *dji, GPSPositionSensorData *gpsPosition); +} djiMessageHandler; + +const djiMessageHandler djiHandlerTable[] = { + { .msgId = DJI_ID_GPS, .handler = &parse_dji_gps }, +#if !defined(PIOS_GPS_MINIMAL) + { .msgId = DJI_ID_MAG, .handler = &parse_dji_mag }, + { .msgId = DJI_ID_VER, .handler = &parse_dji_ver }, +#endif /* !defined(PIOS_GPS_MINIMAL) */ +}; +#define DJI_HANDLER_TABLE_SIZE NELEMENTS(djiHandlerTable) + +#if !defined(PIOS_GPS_MINIMAL) +static bool useMag = false; + +// detected hw version +uint32_t djiHwVersion = -1; +uint32_t djiSwVersion = -1; +#endif /* !defined(PIOS_GPS_MINIMAL) */ + + +// parse incoming character stream for messages in DJI binary format +#define djiPacket ((struct DJIPacket *)parsedDjiStruct) +int parse_dji_stream(uint8_t *inputBuffer, uint16_t inputBufferLength, char *parsedDjiStruct, GPSPositionSensorData *gpsPosition, struct GPS_RX_STATS *gpsRxStats) +{ + enum ProtocolStates { + START, + DJI_SY2, + DJI_ID, + DJI_LEN, + DJI_PAYLOAD, + DJI_CHK1, + DJI_CHK2, + FINISHED + }; + enum RestartStates { + RESTART_WITH_ERROR, + RESTART_NO_ERROR + }; + static uint16_t payloadCount = 0; + static enum ProtocolStates protocolState = START; + static bool previousPacketGood = true; + int ret = PARSER_INCOMPLETE; // message not (yet) complete + uint16_t inputBufferIndex = 0; + uint16_t restartIndex = 0; // input buffer location to restart from + enum RestartStates restartState; + uint8_t inputByte; + bool currentPacketGood; + + // switch continue is the normal condition and comes back to here for another byte + // switch break is the error state that branches to the end and restarts the scan at the byte after the first sync byte + while (inputBufferIndex < inputBufferLength) { + inputByte = inputBuffer[inputBufferIndex++]; + switch (protocolState) { + case START: // detect protocol + if (inputByte == DJI_SYNC1) { // first DJI sync char found + protocolState = DJI_SY2; + // restart here, at byte after SYNC1, if we fail to parse + restartIndex = inputBufferIndex; + } + continue; + case DJI_SY2: + if (inputByte == DJI_SYNC2) { // second DJI sync char found + protocolState = DJI_ID; + } else { + restartState = RESTART_NO_ERROR; + break; + } + continue; + case DJI_ID: + djiPacket->header.id = inputByte; + protocolState = DJI_LEN; + continue; + case DJI_LEN: + if (inputByte > sizeof(DJIPayload)) { + gpsRxStats->gpsRxOverflow++; + restartState = RESTART_WITH_ERROR; + break; + } else { + djiPacket->header.len = inputByte; + if (inputByte == 0) { + protocolState = DJI_CHK1; + } else { + payloadCount = 0; + protocolState = DJI_PAYLOAD; + } + } + continue; + case DJI_PAYLOAD: + if (payloadCount < djiPacket->header.len) { + djiPacket->payload.payload[payloadCount] = inputByte; + if (++payloadCount == djiPacket->header.len) { + protocolState = DJI_CHK1; + } + } + continue; + case DJI_CHK1: + djiPacket->header.checksumA = inputByte; + protocolState = DJI_CHK2; + continue; + case DJI_CHK2: + djiPacket->header.checksumB = inputByte; + // ignore checksum errors on correct mag packets that nonetheless have checksum errors + // these checksum errors happen very often on clone DJI GPS (never on real DJI GPS) + // and are caused by a clone DJI GPS firmware error + // the errors happen when it is time to send a non-mag packet (4 or 5 per second) + // instead of a mag packet (30 per second) + currentPacketGood = checksum_dji_message(djiPacket); + // message complete and valid or (it's a mag packet and the previous "any" packet was good) + if (currentPacketGood || (djiPacket->header.id == DJI_ID_MAG && previousPacketGood)) { + parse_dji_message(djiPacket, gpsPosition); + gpsRxStats->gpsRxReceived++; + protocolState = START; + // overwrite PARSER_INCOMPLETE with PARSER_COMPLETE + // but don't overwrite PARSER_ERROR with PARSER_COMPLETE + // pass PARSER_ERROR to caller if it happens even once + // only pass PARSER_COMPLETE back to caller if we parsed a full set of GPS data + // that allows the caller to know if we are parsing GPS data + // or just other packets for some reason (DJI clone firmware bug that happens sometimes) + if (djiPacket->header.id == DJI_ID_GPS && ret == PARSER_INCOMPLETE) { + ret = PARSER_COMPLETE; // message complete & processed + } + } else { + gpsRxStats->gpsRxChkSumError++; + restartState = RESTART_WITH_ERROR; + previousPacketGood = false; + break; + } + previousPacketGood = currentPacketGood; + continue; + default: + continue; + } + + // this simple restart doesn't work across calls + // but it does work within a single call + // and it does the expected thing across calls + // if restarting due to error detected in 2nd call to this function (on split packet) + // then we just restart at index 0, which is mid-packet, not the second byte + if (restartState == RESTART_WITH_ERROR) { + ret = PARSER_ERROR; // inform caller that we found at least one error (along with 0 or more good packets) + } + inputBuffer += restartIndex; // restart parsing just past the most recent SYNC1 + inputBufferLength -= restartIndex; + inputBufferIndex = 0; + protocolState = START; + } + + return ret; +} + + +bool checksum_dji_message(struct DJIPacket *dji) +{ + int i; + uint8_t checksumA, checksumB; + + checksumA = dji->header.id; + checksumB = checksumA; + + checksumA += dji->header.len; + checksumB += checksumA; + + for (i = 0; i < dji->header.len; i++) { + checksumA += dji->payload.payload[i]; + checksumB += checksumA; + } + + if (dji->header.checksumA == checksumA && + dji->header.checksumB == checksumB) { + return true; + } else { + return false; + } +} + + +static void parse_dji_gps(struct DJIPacket *dji, GPSPositionSensorData *gpsPosition) +{ + GPSVelocitySensorData gpsVelocity; + struct DjiGps *djiGps = &dji->payload.gps; + + // decode with xor mask + uint8_t mask = djiGps->unused5; + + // some bytes at the end are not xored + // some bytes in the middle are not xored + for (uint8_t i = 0; i < GPS_DECODED_LENGTH; ++i) { + if (i != GPS_NOT_XORED_BYTE_1 && i != GPS_NOT_XORED_BYTE_2) { + dji->payload.payload[i] ^= mask; + } + } + + gpsVelocity.North = (float)djiGps->velN * 0.01f; + gpsVelocity.East = (float)djiGps->velE * 0.01f; + gpsVelocity.Down = (float)djiGps->velD * 0.01f; + GPSVelocitySensorSet(&gpsVelocity); + +#if !defined(PIOS_GPS_MINIMAL) + gpsPosition->Groundspeed = sqrtf(gpsVelocity.North * gpsVelocity.North + gpsVelocity.East * gpsVelocity.East); +#else + gpsPosition->Groundspeed = fmaxf(gpsVelocity.North, gpsVelocity.East) * 1.2f; // within 20% or so +#endif /* !defined(PIOS_GPS_MINIMAL) */ + // don't allow a funny number like 4.87416e-06 to show up in Uavo Browser for Heading + // smallest groundspeed is 0.01f from (int)1 * (float)0.01 + // so this is saying if groundspeed is zero + if (gpsPosition->Groundspeed < 0.009f) { + gpsPosition->Heading = 0.0f; + } else { + gpsPosition->Heading = RAD2DEG(atan2f(-gpsVelocity.East, -gpsVelocity.North)) + 180.0f; + } + gpsPosition->Altitude = (float)djiGps->hMSL * 0.001f; + // there is no source of geoid separation data in the DJI protocol + // Is there a reasonable world model calculation we can do to get a value for geoid separation? + gpsPosition->GeoidSeparation = 0.0f; + gpsPosition->Latitude = djiGps->lat; + gpsPosition->Longitude = djiGps->lon; + gpsPosition->Satellites = djiGps->numSV; + gpsPosition->PDOP = djiGps->pDOP * 0.01f; +#if !defined(PIOS_GPS_MINIMAL) + gpsPosition->HDOP = sqrtf((float)djiGps->nDOP * (float)djiGps->nDOP + (float)djiGps->eDOP * (float)djiGps->eDOP) * 0.01f; + if (gpsPosition->HDOP > 99.99f) { + gpsPosition->HDOP = 99.99f; + } +#else + gpsPosition->HDOP = MAX(djiGps->nDOP, djiGps->eDOP) * 0.01f; +#endif + gpsPosition->VDOP = djiGps->vDOP * 0.01f; + if (djiGps->flags & FLAGS_GPSFIX_OK) { + gpsPosition->Status = djiGps->fixType == FIXTYPE_3D ? + GPSPOSITIONSENSOR_STATUS_FIX3D : GPSPOSITIONSENSOR_STATUS_FIX2D; + } else { + gpsPosition->Status = GPSPOSITIONSENSOR_STATUS_NOFIX; + } + gpsPosition->SensorType = GPSPOSITIONSENSOR_SENSORTYPE_DJI; + gpsPosition->AutoConfigStatus = GPSPOSITIONSENSOR_AUTOCONFIGSTATUS_DISABLED; + GPSPositionSensorSet(gpsPosition); + +#if !defined(PIOS_GPS_MINIMAL) + // Time is valid, set GpsTime + GPSTimeData gpsTime; + // the lowest bit of day and the highest bit of hour overlap (xored? no, stranger than that) + // this causes strange day/hour changes + // we could track it here and even if we guess wrong initially + // we can massage the data so that time doesn't jump at least + // and maybe make the assumption that most people will fly at 5pm, not 1am + // this is part of the DJI protocol + // see DJI.h for further info + gpsTime.Year = (int16_t)djiGps->year + 2000; + gpsTime.Month = djiGps->month; + gpsTime.Day = djiGps->day; + gpsTime.Hour = djiGps->hour; + gpsTime.Minute = djiGps->min; + gpsTime.Second = djiGps->sec; + GPSTimeSet(&gpsTime); +#endif /* !defined(PIOS_GPS_MINIMAL) */ +} + + +#if !defined(PIOS_GPS_MINIMAL) +void dji_load_mag_settings() +{ + if (auxmagsupport_get_type() == AUXMAGSETTINGS_TYPE_DJI) { + useMag = true; + } else { + useMag = false; + } +} + + +static void parse_dji_mag(struct DJIPacket *dji, __attribute__((unused)) GPSPositionSensorData *gpsPosition) +{ + if (!useMag) { + return; + } + struct DjiMag *mag = &dji->payload.mag; + union { + struct { + int8_t mask; + int8_t mask2; + }; + int16_t maskmask; + } u; + u.mask = (int8_t)(dji->payload.payload[4]); + u.mask = u.mask2 = (((u.mask ^ (u.mask >> 4)) & 0x0F) | ((u.mask << 3) & 0xF0)) ^ (((u.mask & 0x01) << 3) | ((u.mask & 0x01) << 7)); + // yes, z is only xored by mask<<8, not maskmask + float mags[3] = { mag->x ^ u.maskmask, mag->y ^ u.maskmask, mag->z ^ ((int16_t)u.mask << 8) }; + auxmagsupport_publish_samples(mags, AUXMAGSENSOR_STATUS_OK); +} + + +static void parse_dji_ver(struct DJIPacket *dji, __attribute__((unused)) GPSPositionSensorData *gpsPosition) +{ + { + struct DjiVer *ver = &dji->payload.ver; + // decode with xor mask + uint8_t mask = (uint8_t)(ver->unused1); + + // first 4 bytes are unused and 0 before the encryption + // so any one of them can be used for the decrypting xor mask + for (uint8_t i = VER_FIRST_DECODED_BYTE; i < sizeof(struct DjiVer); ++i) { + dji->payload.payload[i] ^= mask; + } + + djiHwVersion = ver->hwVersion; + djiSwVersion = ver->swVersion; + } + { + GPSPositionSensorSensorTypeOptions sensorType; + sensorType = GPSPOSITIONSENSOR_SENSORTYPE_DJI; + GPSPositionSensorSensorTypeSet((uint8_t *)&sensorType); + } +} +#endif /* !defined(PIOS_GPS_MINIMAL) */ + + +// DJI message parser +// returns UAVObjectID if a UAVObject structure is ready for further processing +uint32_t parse_dji_message(struct DJIPacket *dji, GPSPositionSensorData *gpsPosition) +{ + static bool djiInitialized = false; + uint32_t id = 0; + + if (!djiInitialized) { + // initialize dop values. If no DOP sentence is received it is safer to initialize them to a high value rather than 0. + gpsPosition->HDOP = 99.99f; + gpsPosition->PDOP = 99.99f; + gpsPosition->VDOP = 99.99f; + djiInitialized = true; + } + + for (uint8_t i = 0; i < DJI_HANDLER_TABLE_SIZE; i++) { + const djiMessageHandler *handler = &djiHandlerTable[i]; + if (handler->msgId == dji->header.id) { + handler->handler(dji, gpsPosition); + break; + } + } + + { + uint8_t status; + GPSPositionSensorStatusGet(&status); + if (status == GPSPOSITIONSENSOR_STATUS_NOGPS) { + // Some dji thing has been received so GPS is there + status = GPSPOSITIONSENSOR_STATUS_NOFIX; + GPSPositionSensorStatusSet(&status); + } + } + + return id; +} +#endif // PIOS_INCLUDE_GPS_DJI_PARSER diff --git a/flight/modules/GPS/GPS.c b/flight/modules/GPS/GPS.c index 74166d6cf..305fb7148 100644 --- a/flight/modules/GPS/GPS.c +++ b/flight/modules/GPS/GPS.c @@ -2,13 +2,14 @@ ****************************************************************************** * @addtogroup OpenPilotModules OpenPilot Modules * @{ - * @addtogroup GSPModule GPS Module + * @addtogroup GPSModule GPS Module * @brief Process GPS information * @{ * * @file GPS.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @brief GPS module, handles GPS and NMEA stream + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @brief GPS module, handles GPS and various streams * @see The GNU Public License (GPL) Version 3 * *****************************************************************************/ @@ -48,36 +49,56 @@ #include "GPS.h" #include "NMEA.h" #include "UBX.h" +#include "DJI.h" #if defined(PIOS_INCLUDE_GPS_UBX_PARSER) && !defined(PIOS_GPS_MINIMAL) #include "inc/ubx_autoconfig.h" +#define FULL_UBX_PARSER #endif +#include #include PERF_DEFINE_COUNTER(counterBytesIn); PERF_DEFINE_COUNTER(counterRate); PERF_DEFINE_COUNTER(counterParse); + +#if defined(ANY_GPS_PARSER) || defined(ANY_FULL_GPS_PARSER) || defined(ANY_FULL_MAG_PARSER) +#error ANY_GPS_PARSER ANY_FULL_GPS_PARSER and ANY_FULL_MAG_PARSER should all be undefined at this point. +#endif + +#if defined(PIOS_INCLUDE_GPS_NMEA_PARSER) || defined(PIOS_INCLUDE_GPS_UBX_PARSER) || defined(PIOS_INCLUDE_GPS_DJI_PARSER) +#define ANY_GPS_PARSER +#endif +#if defined(ANY_GPS_PARSER) && !defined(PIOS_GPS_MINIMAL) +#define ANY_FULL_GPS_PARSER +#endif +#if (defined(PIOS_INCLUDE_HMC5X83) || defined(PIOS_INCLUDE_GPS_UBX_PARSER) || defined(PIOS_INCLUDE_GPS_DJI_PARSER)) && !defined(PIOS_GPS_MINIMAL) +#define ANY_FULL_MAG_PARSER +#endif + // **************** // Private functions static void gpsTask(__attribute__((unused)) void *parameters); static void updateHwSettings(__attribute__((unused)) UAVObjEvent *ev); -#ifdef PIOS_GPS_SETS_HOMELOCATION +#if defined(PIOS_GPS_SETS_HOMELOCATION) static void setHomeLocation(GPSPositionSensorData *gpsData); static float GravityAccel(float latitude, float longitude, float altitude); #endif -#ifdef PIOS_INCLUDE_GPS_UBX_PARSER +#if defined(ANY_FULL_MAG_PARSER) void AuxMagSettingsUpdatedCb(__attribute__((unused)) UAVObjEvent *ev); -#ifndef PIOS_GPS_MINIMAL -void updateGpsSettings(__attribute__((unused)) UAVObjEvent *ev); #endif +#if defined(ANY_FULL_GPS_PARSER) +void updateGpsSettings(__attribute__((unused)) UAVObjEvent *ev); #endif // **************** // Private constants -#define GPS_TIMEOUT_MS 500 +// GPS timeout is greater than 1000ms so that a stock GPS configuration can be used without timeout errors +#define GPS_TIMEOUT_MS 1250 + // delay from detecting HomeLocation.Set == False before setting new homelocation // this prevent that a save with homelocation.Set = false triggered by gps ends saving // the new location with Set = true. @@ -120,10 +141,9 @@ static xTaskHandle gpsTaskHandle; static char *gps_rx_buffer; -static uint32_t timeOfLastCommandMs; static uint32_t timeOfLastUpdateMs; -#if defined(PIOS_INCLUDE_GPS_NMEA_PARSER) || defined(PIOS_INCLUDE_GPS_UBX_PARSER) +#if defined(ANY_GPS_PARSER) static struct GPS_RX_STATS gpsRxStats; #endif @@ -177,7 +197,7 @@ int32_t GPSInitialize(void) GPSTimeInitialize(); GPSSatellitesInitialize(); HomeLocationInitialize(); -#ifdef PIOS_INCLUDE_GPS_UBX_PARSER +#if defined(ANY_FULL_MAG_PARSER) AuxMagSensorInitialize(); AuxMagSettingsInitialize(); GPSExtendedStatusInitialize(); @@ -211,19 +231,40 @@ int32_t GPSInitialize(void) #endif /* if defined(REVOLUTION) */ if (gpsEnabled) { -#if defined(PIOS_INCLUDE_GPS_NMEA_PARSER) && defined(PIOS_INCLUDE_GPS_UBX_PARSER) - gps_rx_buffer = pios_malloc((sizeof(struct UBXPacket) > NMEA_MAX_PACKET_LENGTH) ? sizeof(struct UBXPacket) : NMEA_MAX_PACKET_LENGTH); -#elif defined(PIOS_INCLUDE_GPS_UBX_PARSER) +#if defined(PIOS_GPS_MINIMAL) +#if defined(PIOS_INCLUDE_GPS_UBX_PARSER) gps_rx_buffer = pios_malloc(sizeof(struct UBXPacket)); -#elif defined(PIOS_INCLUDE_GPS_NMEA_PARSER) - gps_rx_buffer = pios_malloc(NMEA_MAX_PACKET_LENGTH); +#elif defined(PIOS_INCLUDE_GPS_DJI_PARSER) + gps_rx_buffer = pios_malloc(sizeof(struct DJIPacket)); #else gps_rx_buffer = NULL; #endif -#if defined(PIOS_INCLUDE_GPS_NMEA_PARSER) || defined(PIOS_INCLUDE_GPS_UBX_PARSER) +#else /* defined(PIOS_GPS_MINIMAL) */ +#if defined(ANY_GPS_PARSER) +#if defined(PIOS_INCLUDE_GPS_NMEA_PARSER) + size_t bufSize = NMEA_MAX_PACKET_LENGTH; +#else + size_t bufSize = 0; +#endif +#if defined(PIOS_INCLUDE_GPS_UBX_PARSER) + if (bufSize < sizeof(struct UBXPacket)) { + bufSize = sizeof(struct UBXPacket); + } +#endif +#if defined(PIOS_INCLUDE_GPS_DJI_PARSER) + if (bufSize < sizeof(struct DJIPacket)) { + bufSize = sizeof(struct DJIPacket); + } +#endif + gps_rx_buffer = pios_malloc(bufSize); +#else /* defined(ANY_GPS_PARSER) */ + gps_rx_buffer = NULL; +#endif /* defined(ANY_GPS_PARSER) */ +#endif /* defined(PIOS_GPS_MINIMAL) */ +#if defined(ANY_GPS_PARSER) PIOS_Assert(gps_rx_buffer); #endif -#if defined(PIOS_INCLUDE_GPS_UBX_PARSER) && !defined(PIOS_GPS_MINIMAL) +#if defined(ANY_FULL_GPS_PARSER) HwSettingsConnectCallback(updateHwSettings); // allow changing baud rate even after startup GPSSettingsConnectCallback(updateGpsSettings); #endif @@ -256,12 +297,10 @@ static void gpsTask(__attribute__((unused)) void *parameters) #endif GPSPositionSensorData gpspositionsensor; - timeOfLastUpdateMs = timeNowMs; - timeOfLastCommandMs = timeNowMs; - + timeOfLastUpdateMs = timeNowMs; GPSPositionSensorGet(&gpspositionsensor); -#if defined(PIOS_INCLUDE_GPS_UBX_PARSER) && !defined(PIOS_GPS_MINIMAL) - // this should be done in the task because it calls out to actually start the GPS serial reads +#if defined(ANY_FULL_GPS_PARSER) + // this should be done in the task because it calls out to actually start the ubx GPS serial reads updateGpsSettings(0); #endif @@ -275,7 +314,7 @@ static void gpsTask(__attribute__((unused)) void *parameters) // Loop forever while (1) { if (gpsPort) { -#if defined(PIOS_INCLUDE_GPS_UBX_PARSER) && !defined(PIOS_GPS_MINIMAL) +#if defined(FULL_UBX_PARSER) // do autoconfig stuff for UBX GPS's if (gpsSettings.DataProtocol == GPSSETTINGS_DATAPROTOCOL_UBX) { char *buffer = 0; @@ -309,16 +348,17 @@ static void gpsTask(__attribute__((unused)) void *parameters) GPSPositionSensorAutoConfigStatusSet(&gpspositionsensor.AutoConfigStatus); lastStatus = gpspositionsensor.AutoConfigStatus; } -#endif /* if defined(PIOS_INCLUDE_GPS_UBX_PARSER) && !defined(PIOS_GPS_MINIMAL) */ +#endif /* if defined(FULL_UBX_PARSER) */ uint16_t cnt; + int res; // This blocks the task until there is something on the buffer (or 100ms? passes) cnt = PIOS_COM_ReceiveBuffer(gpsPort, c, GPS_READ_BUFFER, xDelay); + res = PARSER_INCOMPLETE; if (cnt > 0) { PERF_TIMED_SECTION_START(counterParse); PERF_TRACK_VALUE(counterBytesIn, cnt); PERF_MEASURE_PERIOD(counterRate); - int res; switch (gpsSettings.DataProtocol) { #if defined(PIOS_INCLUDE_GPS_NMEA_PARSER) case GPSSETTINGS_DATAPROTOCOL_NMEA: @@ -329,6 +369,11 @@ static void gpsTask(__attribute__((unused)) void *parameters) case GPSSETTINGS_DATAPROTOCOL_UBX: res = parse_ubx_stream(c, cnt, gps_rx_buffer, &gpspositionsensor, &gpsRxStats); break; +#endif +#if defined(PIOS_INCLUDE_GPS_DJI_PARSER) + case GPSSETTINGS_DATAPROTOCOL_DJI: + res = parse_dji_stream(c, cnt, gps_rx_buffer, &gpspositionsensor, &gpsRxStats); + break; #endif default: res = NO_PARSER; // this should not happen @@ -339,23 +384,36 @@ static void gpsTask(__attribute__((unused)) void *parameters) if (res == PARSER_COMPLETE) { timeNowMs = xTaskGetTickCount() * portTICK_RATE_MS; timeOfLastUpdateMs = timeNowMs; - timeOfLastCommandMs = timeNowMs; } } - // Check for GPS timeout + // if there is a protocol error or communication error, or timeout error, + // generally, if there is an error that is due to configuration or bad hardware, set status to NOGPS + // poor GPS signal gets a different error/alarm (below) + // + // should this be expanded to include aux mag status as well? currently the aux mag + // attached to a GPS protocol (OPV9 and DJI) still says OK after the GPS/mag goes down + // (data cable unplugged or flight battery removed with USB still powering the FC) timeNowMs = xTaskGetTickCount() * portTICK_RATE_MS; - if ((timeNowMs - timeOfLastUpdateMs) >= GPS_TIMEOUT_MS || + if ((res == PARSER_ERROR) || + (timeNowMs - timeOfLastUpdateMs) >= GPS_TIMEOUT_MS || (gpsSettings.DataProtocol == GPSSETTINGS_DATAPROTOCOL_UBX && gpspositionsensor.AutoConfigStatus == GPSPOSITIONSENSOR_AUTOCONFIGSTATUS_ERROR)) { // we have not received any valid GPS sentences for a while. // either the GPS is not plugged in or a hardware problem or the GPS has locked up. GPSPositionSensorStatusOptions status = GPSPOSITIONSENSOR_STATUS_NOGPS; GPSPositionSensorStatusSet(&status); AlarmsSet(SYSTEMALARMS_ALARM_GPS, SYSTEMALARMS_ALARM_ERROR); - } else { - // we appear to be receiving GPS sentences OK, we've had an update + } + // if we parsed at least one packet successfully + // we aren't offline, but we still may not have a good enough fix to fly + // or we might not even be receiving all necessary GPS packets (NMEA) + else if (res == PARSER_COMPLETE) { + // we appear to be receiving packets OK // criteria for GPS-OK taken from this post... // http://forums.openpilot.org/topic/1523-professors-insgps-in-svn/page__view__findpost__p__5220 + // NMEA doesn't verify that all necessary packet types for an update have been received + // + // if (the fix is good) { if ((gpspositionsensor.PDOP < gpsSettings.MaxPDOP) && (gpspositionsensor.Satellites >= gpsSettings.MinSatellites) && (gpspositionsensor.Status == GPSPOSITIONSENSOR_STATUS_FIX3D) && (gpspositionsensor.Latitude != 0 || gpspositionsensor.Longitude != 0)) { @@ -376,9 +434,11 @@ static void gpsTask(__attribute__((unused)) void *parameters) homelocationSetDelay = 0; } #endif + // else if (we are at least getting what might be usable GPS data to finish a flight with) { } else if ((gpspositionsensor.Status == GPSPOSITIONSENSOR_STATUS_FIX3D) && (gpspositionsensor.Latitude != 0 || gpspositionsensor.Longitude != 0)) { AlarmsSet(SYSTEMALARMS_ALARM_GPS, SYSTEMALARMS_ALARM_WARNING); + // else data is probably not good enough to fly } else { AlarmsSet(SYSTEMALARMS_ALARM_GPS, SYSTEMALARMS_ALARM_CRITICAL); } @@ -494,73 +554,122 @@ void gps_set_fc_baud_from_arg(uint8_t baud) } +// set the FC port baud rate +// from HwSettings or override with 115200 if DJI +static void gps_set_fc_baud_from_settings() +{ + uint8_t speed; + + // Retrieve settings +#if defined(PIOS_INCLUDE_GPS_DJI_PARSER) && !defined(PIOS_GPS_MINIMAL) + if (gpsSettings.DataProtocol == GPSSETTINGS_DATAPROTOCOL_DJI) { + speed = HWSETTINGS_GPSSPEED_115200; + } else { +#endif + HwSettingsGPSSpeedGet(&speed); +#if defined(PIOS_INCLUDE_GPS_DJI_PARSER) && !defined(PIOS_GPS_MINIMAL) +} +#endif + // set fc baud + gps_set_fc_baud_from_arg(speed); +} + + /** - * Update the GPS settings, called on startup. - * FIXME: This should be in the GPSSettings object. But objects have - * too much overhead yet. Also the GPS has no any specific settings - * like protocol, etc. Thus the HwSettings object which contains the - * GPS port speed is used for now. + * HwSettings callback + * Generally speaking, set the FC baud rate + * and for UBX, if it is safe, start the auto config process + * this allows the user to change the baud rate and see if it works without rebooting */ // must updateHwSettings() before updateGpsSettings() so baud rate is set before GPS serial code starts running static void updateHwSettings(UAVObjEvent __attribute__((unused)) *ev) { -#if defined(PIOS_INCLUDE_GPS_UBX_PARSER) && !defined(PIOS_GPS_MINIMAL) +#if defined(ANY_FULL_GPS_PARSER) static uint32_t previousGpsPort = 0xf0f0f0f0; // = doesn't match gpsport #endif // if GPS (UBX or NMEA) is enabled at all if (gpsPort && gpsEnabled) { +// if we have ubx auto config then sometimes we don't set the baud rate +#if defined(FULL_UBX_PARSER) + // just for UBX, because it has autoconfig + // if in startup, or not configured to do ubx and ubx auto config + // // on first use of this port (previousGpsPort != gpsPort) we must set the Revo port baud rate // after startup (previousGpsPort == gpsPort) we must set the Revo port baud rate only if autoconfig is disabled // always we must set the Revo port baud rate if not using UBX -#if defined(PIOS_INCLUDE_GPS_UBX_PARSER) && !defined(PIOS_GPS_MINIMAL) if (ev == NULL || previousGpsPort != gpsPort || gpsSettings.UbxAutoConfig == GPSSETTINGS_UBXAUTOCONFIG_DISABLED || gpsSettings.DataProtocol != GPSSETTINGS_DATAPROTOCOL_UBX) -#endif +#endif /* defined(FULL_UBX_PARSER) */ { - uint8_t speed; - // Retrieve settings - HwSettingsGPSSpeedGet(&speed); - // set fc baud - gps_set_fc_baud_from_arg(speed); -#if defined(PIOS_INCLUDE_GPS_UBX_PARSER) && !defined(PIOS_GPS_MINIMAL) - // even changing the baud rate will make it re-verify the sensor type - // that way the user can just try some baud rates and when the sensor type is valid, the baud rate is correct + // always set the baud rate + gps_set_fc_baud_from_settings(); +#if defined(FULL_UBX_PARSER) + // just for UBX, because it has subtypes UBX(6), UBX7 and UBX8 + // changing anything in HwSettings will make it re-verify the sensor type (including auto-baud if not completely disabled) + // for auto baud disabled, the user can just try some baud rates and when the baud rate is correct, the sensor type becomes valid gps_ubx_reset_sensor_type(); -#endif +#endif /* defined(FULL_UBX_PARSER) */ } -#if defined(PIOS_INCLUDE_GPS_UBX_PARSER) && !defined(PIOS_GPS_MINIMAL) +#if defined(FULL_UBX_PARSER) else { - // it will never do this during startup because ev == NULL + // else: + // - we are past startup + // - we are running uxb protocol + // - and some form of ubx auto config is enabled + // + // it will never do this during startup because ev == NULL during startup + // + // this is here so that runtime (not startup) user changes to HwSettings will restart auto-config gps_ubx_autoconfig_set(NULL); } -#endif +#endif /* defined(FULL_UBX_PARSER) */ } -#if defined(PIOS_INCLUDE_GPS_UBX_PARSER) && !defined(PIOS_GPS_MINIMAL) +#if defined(ANY_FULL_GPS_PARSER) previousGpsPort = gpsPort; #endif } -#if defined(PIOS_INCLUDE_GPS_UBX_PARSER) && !defined(PIOS_GPS_MINIMAL) +#if defined(ANY_FULL_MAG_PARSER) void AuxMagSettingsUpdatedCb(__attribute__((unused)) UAVObjEvent *ev) { - load_mag_settings(); + auxmagsupport_reload_settings(); +#if defined(PIOS_INCLUDE_GPS_UBX_PARSER) + op_gpsv9_load_mag_settings(); +#endif +#if defined(PIOS_INCLUDE_GPS_DJI_PARSER) + dji_load_mag_settings(); +#endif +#if defined(PIOS_INCLUDE_HMC5X83) + aux_hmc5x83_load_mag_settings(); +#endif } +#endif /* defined(ANY_FULL_MAG_PARSER) */ +#if defined(ANY_FULL_GPS_PARSER) void updateGpsSettings(__attribute__((unused)) UAVObjEvent *ev) { ubx_autoconfig_settings_t newconfig; GPSSettingsGet(&gpsSettings); - // it's OK that ubx auto config is inited and ready to go, when GPS is disabled or running NMEA +#if defined(PIOS_INCLUDE_GPS_DJI_PARSER) + // each time there is a protocol change, set the baud rate + // so that DJI can be forced to 115200, but changing to another protocol will change the baud rate to the user specified value + // note that changes to HwSettings GPS baud rate are detected in the HwSettings callback, + // but changing to/from DJI is effectively a baud rate change because DJI is forced to be 115200 + gps_set_fc_baud_from_settings(); // knows to force 115200 for DJI +#endif + + // it's OK that ubx auto config is inited and ready to go, when GPS is disabled or running another protocol // because ubx auto config never gets called - // setting it up completely means that if we switch from initial NMEA to UBX or disabled to enabled, that it will start normally + // setting it up completely means that if we switch from the other protocol to UBX or disabled to enabled, that it will start normally newconfig.UbxAutoConfig = gpsSettings.UbxAutoConfig; + newconfig.AssistNowAutonomous = gpsSettings.UbxAssistNowAutonomous; newconfig.navRate = gpsSettings.UbxRate; newconfig.dynamicModel = gpsSettings.UbxDynamicModel == GPSSETTINGS_UBXDYNAMICMODEL_PORTABLE ? UBX_DYNMODEL_PORTABLE : gpsSettings.UbxDynamicModel == GPSSETTINGS_UBXDYNAMICMODEL_STATIONARY ? UBX_DYNMODEL_STATIONARY : @@ -646,9 +755,22 @@ void updateGpsSettings(__attribute__((unused)) UAVObjEvent *ev) break; } - gps_ubx_autoconfig_set(&newconfig); +// handle protocol changes and devices that have just been powered up +#if defined(PIOS_INCLUDE_GPS_UBX_PARSER) + if (gpsSettings.DataProtocol == GPSSETTINGS_DATAPROTOCOL_UBX) { + // do whatever the user has configured for power on startup + // even autoconfig disabled still gets the ubx version + gps_ubx_autoconfig_set(&newconfig); + } +#endif +#if defined(PIOS_INCLUDE_GPS_DJI_PARSER) + if (gpsSettings.DataProtocol == GPSSETTINGS_DATAPROTOCOL_DJI) { + // clear out satellite data because DJI doesn't provide it + GPSSatellitesSetDefaults(GPSSatellitesHandle(), 0); + } +#endif } -#endif /* if defined(PIOS_INCLUDE_GPS_UBX_PARSER) && !defined(PIOS_GPS_MINIMAL) */ +#endif /* defined(ANY_FULL_GPS_PARSER) */ /** * @} * @} diff --git a/flight/modules/GPS/NMEA.c b/flight/modules/GPS/NMEA.c index ab4733a83..1173bdae2 100644 --- a/flight/modules/GPS/NMEA.c +++ b/flight/modules/GPS/NMEA.c @@ -2,12 +2,13 @@ ****************************************************************************** * @addtogroup OpenPilotModules OpenPilot Modules * @{ - * @addtogroup GSPModule GPS Module - * @brief Process GPS information + * @addtogroup GPSModule GPS Module + * @brief Process GPS information (NMEA format) * @{ * * @file NMEA.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @brief GPS module, handles GPS and NMEA stream * @see The GNU Public License (GPL) Version 3 * @@ -107,7 +108,6 @@ static const struct nmea_parser nmea_parsers[] = { int parse_nmea_stream(uint8_t *rx, uint8_t len, char *gps_rx_buffer, GPSPositionSensorData *GpsData, struct GPS_RX_STATS *gpsRxStats) { - int ret = PARSER_INCOMPLETE; static uint8_t rx_count = 0; static bool start_flag = false; static bool found_cr = false; @@ -139,8 +139,6 @@ int parse_nmea_stream(uint8_t *rx, uint8_t len, char *gps_rx_buffer, GPSPosition } else { i = len; } - // if no more data, we can return an error - ret = PARSER_ERROR; // loop to restart at the $ if there is one continue; } @@ -150,7 +148,6 @@ int parse_nmea_stream(uint8_t *rx, uint8_t len, char *gps_rx_buffer, GPSPosition // Flush the buffer and note the overflow event. gpsRxStats->gpsRxOverflow++; start_flag = false; - ret = PARSER_OVERRUN; continue; } else { gps_rx_buffer[rx_count++] = c; @@ -182,13 +179,11 @@ int parse_nmea_stream(uint8_t *rx, uint8_t len, char *gps_rx_buffer, GPSPosition // PIOS_DEBUG_PinHigh(2); gpsRxStats->gpsRxChkSumError++; // PIOS_DEBUG_PinLow(2); - ret = PARSER_ERROR; } else { // Valid checksum, use this packet to update the GPS position if (!NMEA_update_position(&gps_rx_buffer[1], GpsData)) { // PIOS_DEBUG_PinHigh(2); gpsRxStats->gpsRxParserError++; // PIOS_DEBUG_PinLow(2); - ret = PARSER_ERROR; } else { gpsRxStats->gpsRxReceived++; goodParse = true; @@ -205,7 +200,7 @@ int parse_nmea_stream(uint8_t *rx, uint8_t len, char *gps_rx_buffer, GPSPosition // might think the GPS was offline return PARSER_COMPLETE; } else { - return ret; + return PARSER_INCOMPLETE; } } diff --git a/flight/modules/GPS/UBX.c b/flight/modules/GPS/UBX.c index d34a59195..19ad46127 100644 --- a/flight/modules/GPS/UBX.c +++ b/flight/modules/GPS/UBX.c @@ -2,13 +2,14 @@ ****************************************************************************** * @addtogroup OpenPilotModules OpenPilot Modules * @{ - * @addtogroup GSPModule GPS Module + * @addtogroup GPSModule GPS Module * @brief Process GPS information (UBX binary format) * @{ * * @file UBX.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. - * @brief GPS module, handles GPS and NMEA stream + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. + * @brief GPS module, handles GPS and UBX stream * @see The GNU Public License (GPL) Version 3 * *****************************************************************************/ @@ -33,22 +34,25 @@ #include "pios_math.h" #include #include + #if defined(PIOS_INCLUDE_GPS_UBX_PARSER) + #include "inc/UBX.h" #include "inc/GPS.h" #include -#ifndef PIOS_GPS_MINIMAL +#if !defined(PIOS_GPS_MINIMAL) #include - static bool useMag = false; -#endif -GPSPositionSensorSensorTypeOptions sensorType = GPSPOSITIONSENSOR_SENSORTYPE_UNKNOWN; +#endif /* !defined(PIOS_GPS_MINIMAL) */ + +// this is set and used by this low level ubx code +// it is also reset by the ubx configuration code (UBX6 vs. UBX7) in ubx_autoconfig.c +GPSPositionSensorSensorTypeOptions ubxSensorType = GPSPOSITIONSENSOR_SENSORTYPE_UNKNOWN; static bool usePvt = false; static uint32_t lastPvtTime = 0; - // parse table item typedef struct { uint8_t msgClass; @@ -57,31 +61,27 @@ typedef struct { } ubx_message_handler; // parsing functions, roughly ordered by reception rate (higher rate messages on top) - static void parse_ubx_nav_posllh(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosition); static void parse_ubx_nav_velned(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosition); static void parse_ubx_nav_sol(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosition); static void parse_ubx_nav_dop(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosition); -#ifndef PIOS_GPS_MINIMAL +#if !defined(PIOS_GPS_MINIMAL) static void parse_ubx_nav_pvt(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosition); static void parse_ubx_nav_timeutc(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosition); static void parse_ubx_nav_svinfo(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosition); - static void parse_ubx_op_sys(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosition); static void parse_ubx_op_mag(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosition); - static void parse_ubx_ack_ack(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosition); static void parse_ubx_ack_nak(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosition); - static void parse_ubx_mon_ver(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosition); -#endif +#endif /* !defined(PIOS_GPS_MINIMAL) */ const ubx_message_handler ubx_handler_table[] = { { .msgClass = UBX_CLASS_NAV, .msgID = UBX_ID_NAV_POSLLH, .handler = &parse_ubx_nav_posllh }, { .msgClass = UBX_CLASS_NAV, .msgID = UBX_ID_NAV_VELNED, .handler = &parse_ubx_nav_velned }, { .msgClass = UBX_CLASS_NAV, .msgID = UBX_ID_NAV_SOL, .handler = &parse_ubx_nav_sol }, { .msgClass = UBX_CLASS_NAV, .msgID = UBX_ID_NAV_DOP, .handler = &parse_ubx_nav_dop }, -#ifndef PIOS_GPS_MINIMAL +#if !defined(PIOS_GPS_MINIMAL) { .msgClass = UBX_CLASS_NAV, .msgID = UBX_ID_NAV_PVT, .handler = &parse_ubx_nav_pvt }, { .msgClass = UBX_CLASS_OP_CUST, .msgID = UBX_ID_OP_MAG, .handler = &parse_ubx_op_mag }, { .msgClass = UBX_CLASS_NAV, .msgID = UBX_ID_NAV_SVINFO, .handler = &parse_ubx_nav_svinfo }, @@ -92,7 +92,7 @@ const ubx_message_handler ubx_handler_table[] = { { .msgClass = UBX_CLASS_ACK, .msgID = UBX_ID_ACK_NAK, .handler = &parse_ubx_ack_nak }, { .msgClass = UBX_CLASS_MON, .msgID = UBX_ID_MON_VER, .handler = &parse_ubx_mon_ver }, -#endif +#endif /* !defined(PIOS_GPS_MINIMAL) */ }; #define UBX_HANDLER_TABLE_SIZE NELEMENTS(ubx_handler_table) @@ -105,11 +105,10 @@ struct UBX_ACK_NAK ubxLastNak; // If a PVT sentence is received in the last UBX_PVT_TIMEOUT (ms) timeframe it disables VELNED/POSLLH/SOL/TIMEUTC #define UBX_PVT_TIMEOUT (1000) -// parse incoming character stream for messages in UBX binary format +// parse incoming character stream for messages in UBX binary format int parse_ubx_stream(uint8_t *rx, uint16_t len, char *gps_rx_buffer, GPSPositionSensorData *GpsData, struct GPS_RX_STATS *gpsRxStats) { - int ret = PARSER_INCOMPLETE; // message not (yet) complete enum proto_states { START, UBX_SY2, @@ -122,49 +121,70 @@ int parse_ubx_stream(uint8_t *rx, uint16_t len, char *gps_rx_buffer, GPSPosition UBX_CHK2, FINISHED }; - uint8_t c; - static enum proto_states proto_state = START; + enum restart_states { + RESTART_WITH_ERROR, + RESTART_NO_ERROR + }; static uint16_t rx_count = 0; + static enum proto_states proto_state = START; struct UBXPacket *ubx = (struct UBXPacket *)gps_rx_buffer; - int i = 0; + int ret = PARSER_INCOMPLETE; // message not (yet) complete + uint16_t i = 0; + uint16_t restart_index = 0; + enum restart_states restart_state; + uint8_t c; + // switch continue is the normal condition and comes back to here for another byte + // switch break is the error state that branches to the end and restarts the scan at the byte after the first sync byte while (i < len) { c = rx[i++]; switch (proto_state) { case START: // detect protocol if (c == UBX_SYNC1) { // first UBX sync char found - proto_state = UBX_SY2; + proto_state = UBX_SY2; + // restart here, at byte after SYNC1, if we fail to parse + restart_index = i; } - break; + continue; case UBX_SY2: if (c == UBX_SYNC2) { // second UBX sync char found proto_state = UBX_CLASS; } else { - proto_state = START; // reset state + restart_state = RESTART_NO_ERROR; + break; } - break; + continue; case UBX_CLASS: ubx->header.class = c; proto_state = UBX_ID; - break; + continue; case UBX_ID: ubx->header.id = c; proto_state = UBX_LEN1; - break; + continue; case UBX_LEN1: ubx->header.len = c; proto_state = UBX_LEN2; - break; + continue; case UBX_LEN2: ubx->header.len += (c << 8); if (ubx->header.len > sizeof(UBXPayload)) { gpsRxStats->gpsRxOverflow++; - proto_state = START; +#if defined(PIOS_GPS_MINIMAL) + restart_state = RESTART_NO_ERROR; +#else + restart_state = RESTART_WITH_ERROR; +#endif + break; } else { - rx_count = 0; - proto_state = UBX_PAYLOAD; + if (ubx->header.len == 0) { + proto_state = UBX_CHK1; + } else { + proto_state = UBX_PAYLOAD; + rx_count = 0; + } } - break; + continue; case UBX_PAYLOAD: if (rx_count < ubx->header.len) { ubx->payload.payload[rx_count] = c; @@ -172,41 +192,61 @@ int parse_ubx_stream(uint8_t *rx, uint16_t len, char *gps_rx_buffer, GPSPosition proto_state = UBX_CHK1; } } - break; + continue; case UBX_CHK1: ubx->header.ck_a = c; proto_state = UBX_CHK2; - break; + continue; case UBX_CHK2: ubx->header.ck_b = c; - if (checksum_ubx_message(ubx)) { // message complete and valid - parse_ubx_message(ubx, GpsData); - proto_state = FINISHED; + // OP GPSV9 sends data with bad checksums this appears to happen because it drops data + // this has been proven by running it without autoconfig and testing: + // data coming from OPV9 "GPS+MCU" port the checksum errors happen roughly every 5 to 30 seconds + // same data coming from OPV9 "GPS Only" port the checksums are always good + // this also occasionally causes parse_ubx_message() to issue alarms because not all the messages were received + // see OP GPSV9 comment in parse_ubx_message() for further information + if (checksum_ubx_message(ubx)) { + gpsRxStats->gpsRxReceived++; + proto_state = START; + // overwrite PARSER_INCOMPLETE with PARSER_COMPLETE + // but don't overwrite PARSER_ERROR with PARSER_COMPLETE + // pass PARSER_ERROR to caller if it happens even once + // only pass PARSER_COMPLETE back to caller if we parsed a full set of GPS data + // that allows the caller to know if we are parsing GPS data + // or just other packets for some reason (mis-configuration) + if (parse_ubx_message(ubx, GpsData) == GPSPOSITIONSENSOR_OBJID + && ret == PARSER_INCOMPLETE) { + ret = PARSER_COMPLETE; + } } else { gpsRxStats->gpsRxChkSumError++; - proto_state = START; + restart_state = RESTART_WITH_ERROR; + break; } - break; + continue; default: - break; + continue; } - if (proto_state == START) { - ret = (ret != PARSER_COMPLETE) ? PARSER_ERROR : PARSER_COMPLETE; // parser couldn't use this byte - } else if (proto_state == FINISHED) { - gpsRxStats->gpsRxReceived++; - proto_state = START; - ret = PARSER_COMPLETE; // message complete & processed + // this simple restart doesn't work across calls + // but it does work within a single call + // and it does the expected thing across calls + // if restarting due to error detected in 2nd call to this function (on split packet) + // then we just restart at index 0, which is mid-packet, not the second byte + if (restart_state == RESTART_WITH_ERROR) { + ret = PARSER_ERROR; // inform caller that we found at least one error (along with 0 or more good packets) } + rx += restart_index; // restart parsing just past the most recent SYNC1 + len -= restart_index; + i = 0; + proto_state = START; } return ret; } - // Keep track of various GPS messages needed to make up a single UAVO update // time-of-week timestamp is used to correlate matching messages - #define POSLLH_RECEIVED (1 << 0) #define STATUS_RECEIVED (1 << 1) #define DOP_RECEIVED (1 << 2) @@ -336,6 +376,7 @@ static void parse_ubx_nav_velned(struct UBXPacket *ubx, GPSPositionSensorData *G } } } + #if !defined(PIOS_GPS_MINIMAL) static void parse_ubx_nav_pvt(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosition) { @@ -465,12 +506,12 @@ static void parse_ubx_mon_ver(struct UBXPacket *ubx, __attribute__((unused)) GPS { struct UBX_MON_VER *mon_ver = &ubx->payload.mon_ver; - ubxHwVersion = atoi(mon_ver->hwVersion); - sensorType = (ubxHwVersion >= 80000) ? GPSPOSITIONSENSOR_SENSORTYPE_UBX8 : - ((ubxHwVersion >= 70000) ? GPSPOSITIONSENSOR_SENSORTYPE_UBX7 : GPSPOSITIONSENSOR_SENSORTYPE_UBX); + ubxHwVersion = atoi(mon_ver->hwVersion); + ubxSensorType = (ubxHwVersion >= UBX_HW_VERSION_8) ? GPSPOSITIONSENSOR_SENSORTYPE_UBX8 : + ((ubxHwVersion >= UBX_HW_VERSION_7) ? GPSPOSITIONSENSOR_SENSORTYPE_UBX7 : GPSPOSITIONSENSOR_SENSORTYPE_UBX); // send sensor type right now because on UBX NEMA we don't get a full set of messages // and we want to be able to see sensor type even on UBX NEMA GPS's - GPSPositionSensorSensorTypeSet((uint8_t *)&sensorType); + GPSPositionSensorSensorTypeSet((uint8_t *)&ubxSensorType); } static void parse_ubx_op_sys(struct UBXPacket *ubx, __attribute__((unused)) GPSPositionSensorData *GpsPosition) @@ -499,10 +540,8 @@ static void parse_ubx_op_mag(struct UBXPacket *ubx, __attribute__((unused)) GPSP } #endif /* if !defined(PIOS_GPS_MINIMAL) */ - // UBX message parser // returns UAVObjectID if a UAVObject structure is ready for further processing - uint32_t parse_ubx_message(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosition) { uint32_t id = 0; @@ -525,10 +564,10 @@ uint32_t parse_ubx_message(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosi } } - GpsPosition->SensorType = sensorType; + GpsPosition->SensorType = ubxSensorType; if (msgtracker.msg_received == ALL_RECEIVED) { - // leave my new field alone! + // leave BaudRate field alone! GPSPositionSensorBaudRateGet(&GpsPosition->BaudRate); GPSPositionSensorSet(GpsPosition); msgtracker.msg_received = NONE_RECEIVED; @@ -538,6 +577,10 @@ uint32_t parse_ubx_message(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosi GPSPositionSensorStatusGet(&status); if (status == GPSPOSITIONSENSOR_STATUS_NOGPS) { // Some ubx thing has been received so GPS is there + // + // OP GPSV9 will sometimes cause this NOFIX + // because GPSV9 drops data which causes checksum errors which causes GPS.c to set the status to NOGPS + // see OP GPSV9 comment in parse_ubx_stream() for further information status = GPSPOSITIONSENSOR_STATUS_NOFIX; GPSPositionSensorStatusSet(&status); } @@ -546,19 +589,13 @@ uint32_t parse_ubx_message(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosi } #if !defined(PIOS_GPS_MINIMAL) - -void load_mag_settings() +void op_gpsv9_load_mag_settings() { - auxmagsupport_reload_settings(); - - if (auxmagsupport_get_type() != AUXMAGSETTINGS_TYPE_GPSV9) { - useMag = false; - const uint8_t status = AUXMAGSENSOR_STATUS_NONE; - // next sample from other external mags will provide the right status if present - AuxMagSensorStatusSet((uint8_t *)&status); - } else { + if (auxmagsupport_get_type() == AUXMAGSETTINGS_TYPE_GPSV9) { useMag = true; + } else { + useMag = false; } } -#endif -#endif // PIOS_INCLUDE_GPS_UBX_PARSER +#endif // !defined(PIOS_GPS_MINIMAL) +#endif // defined(PIOS_INCLUDE_GPS_UBX_PARSER) diff --git a/flight/modules/GPS/inc/DJI.h b/flight/modules/GPS/inc/DJI.h new file mode 100644 index 000000000..47ad02472 --- /dev/null +++ b/flight/modules/GPS/inc/DJI.h @@ -0,0 +1,332 @@ +/** + ****************************************************************************** + * @addtogroup OpenPilotModules OpenPilot Modules + * @{ + * @addtogroup GPSModule GPS Module + * @brief Process GPS information (DJI-Naza binary format) + * @{ + * + * @file DJI.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * @brief GPS module, handles DJI stream + * @see The GNU Public License (GPL) Version 3 + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef DJI_H +#define DJI_H +#include "openpilot.h" +#include "gpspositionsensor.h" +#include "gpsextendedstatus.h" +#ifndef PIOS_GPS_MINIMAL +#include "auxmagsensor.h" +#endif + +#include "GPS.h" + +#define DJI_SYNC1 0x55 // DJI protocol synchronization characters +#define DJI_SYNC2 0xaa + +// Message IDs +typedef enum { + DJI_ID_GPS = 0x10, + DJI_ID_MAG = 0x20, + DJI_ID_VER = 0x30, +} dji_msg_id; + +// private structures + +/* + GPS protocol info from + http://www.rcgroups.com/forums/showpost.php?p=26210591&postcount=15 + + The 0x10 message contains GPS data. Here is the structure of the message, + fields marked with XX I'm not sure about yet. The others will be described below. + + 55 AA 10 3A DT DT DT DT LO LO LO LO LA LA LA LA AL AL AL AL HA HA HA HA VA VA VA VA XX XX XX XX + NV NV NV NV EV EV EV EV DV DV DV DV PD PD VD VD ND ND ED ED NS XX FT XX SF XX XX XM SN SN CS CS + + The payload is XORed with a mask that changes over time (see below for more details). + + Values in the message are stored in little endian. + + HEADER + ------------- + BYTE 1-2: message header - always 55 AA + BYTE 3: message id (0x10 for GPS message) + BYTE 4: lenght of the payload (0x3A or 58 decimal for 0x10 message) + + PAYLOAD + -------------- + BYTE 5-8 (DT) : date and time, see details below + BYTE 9-12 (LO) : longitude (x10^7, degree decimal) + BYTE 13-16 (LA): latitude (x10^7, degree decimal) + BYTE 17-20 (AL): altitude (in milimeters) + BYTE 21-24 (HA): horizontal accuracy estimate (see uBlox NAV-POSLLH message for details) + BYTE 25-28 (VA): vertical accuracy estimate (see uBlox NAV-POSLLH message for details) + BYTE 29-32 : ??? (seems to be always 0) + BYTE 33-36 (NV): NED north velocity (see uBlox NAV-VELNED message for details) + BYTE 37-40 (EV): NED east velocity (see uBlox NAV-VELNED message for details) + BYTE 41-44 (DV): NED down velocity (see uBlox NAV-VELNED message for details) + BYTE 45-46 (PD): position DOP (see uBlox NAV-DOP message for details) + BYTE 47-48 (VD): vertical DOP (see uBlox NAV-DOP message for details) + BYTE 49-50 (ND): northing DOP (see uBlox NAV-DOP message for details) + BYTE 51-52 (ED): easting DOP (see uBlox NAV-DOP message for details) + BYTE 53 (NS) : number of satellites (not XORed) + BYTE 54 : ??? (not XORed, seems to be always 0) + BYTE 55 (FT) : fix type (0 - no lock, 2 - 2D lock, 3 - 3D lock, not sure if other values can be expected + : see uBlox NAV-SOL message for details) + BYTE 56 : ??? (seems to be always 0) + BYTE 57 (SF) : fix status flags (see uBlox NAV-SOL message for details) + BYTE 58-59 : ??? (seems to be always 0) + BYTE 60 (XM) : not sure yet, but I use it as the XOR mask + BYTE 61-62 (SN): sequence number (not XORed), once there is a lock - increases with every message. + When the lock is lost later LSB and MSB are swapped with every message. + + CHECKSUM + ----------------- + BYTE 63-64 (CS): checksum, calculated the same way as for uBlox binary messages + + + XOR mask + --------------- + All bytes of the payload except 53rd (NS), 54th, 61st (SN LSB) and 62nd (SN MSB) are XORed with a mask. + Mask is calculated based on the value of byte 53rd (NS) and 61st (SN LSB). + + If we index bits from LSB to MSB as 0-7 we have: + mask[0] = 53rdByte[0] xor 61stByte[4] + mask[1] = 53rdByte[1] xor 61stByte[5] + mask[2] = 53rdByte[2] xor 61stByte[6] + mask[3] = 53rdByte[3] xor 61stByte[7] xor 53rdByte[0]; + mask[4] = 53rdByte[1]; + mask[5] = 53rdByte[2]; + mask[6] = 53rdByte[3]; + mask[7] = 53rdByte[0] xor 61stByte[4]; + + To simplify calculations any of the unknown bytes that when XORer seem to be always 0 (29-32, 56, 58-60) + can be used as XOR mask (based on the fact that 0 XOR mask == mask). In the library I use byte 60. + + Date and time format + ---------------------------- + Date (Year, Month, Day) and time (Hour, Minute, Second) are stored as little endian 32bit unsigned integer, + the meaning of particular bits is as follows: + + YYYYYYYMMMMDDDDDHHHHMMMMMMSSSSSS + + NOTE 1: to get the day value correct you must add 1 when hour is > 7 + NOTE 2: for the time between 16:00 and 23:59 the hour will be returned as 0-7 + and there seems to be no way to differentiate between 00:00 - 07:59 and 16:00 - 23:59. + + From further discussion in the thread, it sounds like the day is written into the buffer + (buffer initially zero bits) and then the hour is xored into the buffer + with the bottom bit of day and top bit of hour mapped to the same buffer bit? + Is that even correct? Or could we have a correct hour and the day is just wrong? + + http://www.rcgroups.com/forums/showpost.php?p=28158918&postcount=180 + Midnight between 13th and 14th of March + 0001110 0011 01110 0000 000000 000000 -> 14.3.14 00:00:00 -> 0 + identical with + 4PM, 14th of March + 0001110 0011 01110 0000 000000 000000 -> 14.3.14 00:00:00 -> 0 + + Midnight between 14th and 15th of March + 0001110 0011 01111 0000 000000 000000 -> 14.3.15 00:00:00 -> 16 + identical with + 4PM, 15th of March + 0001110 0011 01111 0000 000000 000000 -> 14.3.15 00:00:00 -> 16 + + So as you can see even if we take 5 bits the hour is not correct either + Are they are xored? If we knew the date from a different source we would know the time. + Maybe the xor mask itself contains the bit. Does the mask change? and how? across the transitions. + + http://www.rcgroups.com/forums/showpost.php?p=28168741&postcount=182 + Originally Posted by gwouite View Post + Question, are you sure that at 4PM, you're day value doesn't increase of 1 ? + It does, but it also does decrease by 1 at 8am so you have: + 00:00 - 07:59 => day = X, hour = 0 - 7 + 08:00 - 15:59 => day = X - 1, hour = 8 - 15 + 16:00 - 23:59 => day = X, hour = 0 - 7 + + http://www.rcgroups.com/forums/showpost.php?p=28782603&postcount=218 + Here is the SBAS config from the Naza GPS + CFG-SBAS - 06 16 08 00 01 03 03 00 51 62 06 00 + If I read it correctly EGNOS (PRN 124/124/126), MSAS (PRN 129/137) and WAAS (PRN 133/134/135/138) are enabled. + */ + +// DJI GPS packet +struct DjiGps { // byte offset from beginning of packet, subtract 5 for struct offset + struct { // YYYYYYYMMMMDDDDDHHHHMMMMMMSSSSSS + uint32_t sec : 6; + uint32_t min : 6; + uint32_t hour : 4; + uint32_t day : 5; + uint32_t month : 4; + uint32_t year : 7; + }; // BYTE 5-8 (DT): date and time, see details above + int32_t lon; // BYTE 9-12 (LO): longitude (x10^7, degree decimal) + int32_t lat; // BYTE 13-16 (LA): latitude (x10^7, degree decimal) + int32_t hMSL; // BYTE 17-20 (AL): altitude (in millimeters) (is this MSL or geoid?) + uint32_t hAcc; // BYTE 21-24 (HA): horizontal accuracy estimate (see uBlox NAV-POSLLH message for details) + uint32_t vAcc; // BYTE 25-28 (VA): vertical accuracy estimate (see uBlox NAV-POSLLH message for details) + uint32_t unused1; // BYTE 29-32: ??? (seems to be always 0) + int32_t velN; // BYTE 33-36 (NV): NED north velocity (see uBlox NAV-VELNED message for details) + int32_t velE; // BYTE 37-40 (EV): NED east velocity (see uBlox NAV-VELNED message for details) + int32_t velD; // BYTE 41-44 (DV): NED down velocity (see uBlox NAV-VELNED message for details) + uint16_t pDOP; // BYTE 45-46 (PD): position DOP (see uBlox NAV-DOP message for details) + uint16_t vDOP; // BYTE 47-48 (VD): vertical DOP (see uBlox NAV-DOP message for details) + uint16_t nDOP; // BYTE 49-50 (ND): northing DOP (see uBlox NAV-DOP message for details) + uint16_t eDOP; // BYTE 51-52 (ED): easting DOP (see uBlox NAV-DOP message for details) + uint8_t numSV; // BYTE 53 (NS): number of satellites (not XORed) + uint8_t unused2; // BYTE 54: ??? (not XORed, seems to be always 0) + uint8_t fixType; // BYTE 55 (FT): fix type (0 - no lock, 2 - 2D lock, 3 - 3D lock, not sure if other values can be expected + // see uBlox NAV-SOL message for details) + uint8_t unused3; // BYTE 56: ??? (seems to be always 0) + uint8_t flags; // BYTE 57 (SF): fix status flags (see uBlox NAV-SOL message for details) + uint16_t unused4; // BYTE 58-59: ??? (seems to be always 0) + uint8_t unused5; // BYTE 60 (XM): not sure yet, but I use it as the XOR mask + uint16_t seqNo; // BYTE 61-62 (SN): sequence number (not XORed), once there is a lock + // increases with every message. When the lock is lost later LSB and MSB are swapped (in all messages where lock is lost). +} __attribute__((packed)); + +#define FLAGS_GPSFIX_OK (1 << 0) +#define FLAGS_DIFFSOLN (1 << 1) +#define FLAGS_WKNSET (1 << 2) +#define FLAGS_TOWSET (1 << 3) + +#define FIXTYPE_NO_FIX 0x00 /* No Fix */ +#define FIXTYPE_DEAD_RECKON 0x01 /* Dead Reckoning only */ +#define FIXTYPE_2D 0x02 /* 2D-Fix */ +#define FIXTYPE_3D 0x03 /* 3D-Fix */ +#define FIXTYPE_GNSS_DEAD_RECKON 0x04 /* GNSS + dead reckoning combined */ +#define FIXTYPE_TIME_ONLY 0x05 /* Time only fix */ + +#define GPS_DECODED_LENGTH offsetof(struct DjiGps, seqNo) +#define GPS_NOT_XORED_BYTE_1 offsetof(struct DjiGps, numSV) +#define GPS_NOT_XORED_BYTE_2 offsetof(struct DjiGps, unused2) + + +/* + mag protocol info from + http://www.rcgroups.com/forums/showpost.php?p=26248426&postcount=62 + + The 0x20 message contains compass data. Here is the structure of the message, + fields marked with XX I'm not sure about yet. The others will be described below. + + 55 AA 20 06 CX CX CY CY CZ CZ CS CS + + Values in the message are stored in little endian. + + HEADER + ------------- + BYTE 1-2: message header - always 55 AA + BYTE 3: message id (0x20 for compass message) + BYTE 4: length of the payload (0x06 or 6 decimal for 0x20 message) + + PAYLOAD + -------------- + BYTE 5-6 (CX): compass X axis data (signed) - see comments below + BYTE 7-8 (CY): compass Y axis data (signed) - see comments below + BYTE 9-10 (CZ): compass Z axis data (signed) - see comments below + + CHECKSUM + ----------------- + BYTE 11-12 (CS): checksum, calculated the same way as for uBlox binary messages + + All the bytes of the payload except 9th are XORed with a mask. + Mask is calculated based on the value of the 9th byte. + + If we index bits from LSB to MSB as 0-7 we have: + mask[0] = 9thByte[0] xor 9thByte[4] + mask[1] = 9thByte[1] xor 9thByte[5] + mask[2] = 9thByte[2] xor 9thByte[6] + mask[3] = 9thByte[3] xor 9thByte[7] xor 9thByte[0]; + mask[4] = 9thByte[1]; + mask[5] = 9thByte[2]; + mask[6] = 9thByte[3]; + mask[7] = 9thByte[4] xor 9thByte[0]; + + To calculate the heading (not tilt compensated) you need to do atan2 on the resulting + y any a (y and x?) values, convert radians to degrees and add 360 if the result is negative. + */ + +struct DjiMag { // byte offset from beginning of packet, subtract 5 for struct offset + int16_t x; // BYTE 5-6 (CX): compass X axis data (signed) - see comments below + int16_t y; // BYTE 7-8 (CY): compass Y axis data (signed) - see comments below + int16_t z; // BYTE 9-10 (CZ): compass Z axis data (signed) - see comments below +} __attribute__((packed)); + + +/* + version info from + http://www.rcgroups.com/forums/showpost.php?p=27058649&postcount=120 + + This is still to be confirmed but I believe the 0x30 message carries the GPS module hardware id and firmware version. + + 55 AA 30 0C XX XX XX XX FW FW FW FW HW HW HW HW CS CS + + Note that you need to read version numbers backwards (02 01 00 06 means v6.0.1.2) + + HEADER + ------------- + BYTE 1-2: message header - always 55 AA + BYTE 3: message id (0x30 for GPS module versions message) + BYTE 4: length of the payload (0x0C or 12 decimal for 0x30 message) + + PAYLOAD + -------------- + BYTE 5-8" ??? (seems to be always 0) + BYTE 9-12 (FW): firmware version + BYTE 13-16 (HW): hardware id + + CHECKSUM + ----------------- + BYTE 17-18 (CS): checksum, calculated the same way as for uBlox binary messages + */ + +struct DjiVer { // byte offset from beginning of packet, subtract 5 for struct offset + uint32_t unused1; // BYTE 5-8" ??? (seems to be always 0) + uint32_t swVersion; // BYTE 9-12 (FW): firmware version + uint32_t hwVersion; // BYTE 13-16 (HW): hardware id +} __attribute__((packed)); +#define VER_FIRST_DECODED_BYTE offsetof(struct DjiVer, swVersion) + + +typedef union { + uint8_t payload[0]; + // Nav Class + struct DjiGps gps; + struct DjiMag mag; + struct DjiVer ver; +} DJIPayload; + +struct DJIHeader { + uint8_t id; + uint8_t len; + uint8_t checksumA; // these are not part of the dji header, they are actually in the trailer + uint8_t checksumB; // but they are kept here for parsing ease +} __attribute__((packed)); + +struct DJIPacket { + struct DJIHeader header; + DJIPayload payload; +} __attribute__((packed)); + +int parse_dji_stream(uint8_t *inputBuffer, uint16_t inputBufferLength, char *parsedDjiStruct, GPSPositionSensorData *GpsData, struct GPS_RX_STATS *GpsRxStats); +void dji_load_mag_settings(); + +#endif /* DJI_H */ diff --git a/flight/modules/GPS/inc/GPS.h b/flight/modules/GPS/inc/GPS.h index 4722e1100..764f4597e 100644 --- a/flight/modules/GPS/inc/GPS.h +++ b/flight/modules/GPS/inc/GPS.h @@ -2,7 +2,7 @@ ****************************************************************************** * @addtogroup OpenPilotModules OpenPilot Modules * @{ - * @addtogroup GSPModule GPS Module + * @addtogroup GPSModule GPS Module * @brief Process GPS information * @{ * diff --git a/flight/modules/GPS/inc/NMEA.h b/flight/modules/GPS/inc/NMEA.h index c337abb07..720e21290 100644 --- a/flight/modules/GPS/inc/NMEA.h +++ b/flight/modules/GPS/inc/NMEA.h @@ -2,8 +2,8 @@ ****************************************************************************** * @addtogroup OpenPilotModules OpenPilot Modules * @{ - * @addtogroup GSPModule GPS Module - * @brief Process GPS information + * @addtogroup GPSModule GPS Module + * @brief Process GPS information (NMEA format) * @{ * * @file NMEA.h diff --git a/flight/modules/GPS/inc/UBX.h b/flight/modules/GPS/inc/UBX.h index c4ea60357..4615a4a15 100644 --- a/flight/modules/GPS/inc/UBX.h +++ b/flight/modules/GPS/inc/UBX.h @@ -2,13 +2,14 @@ ****************************************************************************** * @addtogroup OpenPilotModules OpenPilot Modules * @{ - * @addtogroup GSPModule GPS Module - * @brief Process GPS information + * @addtogroup GPSModule GPS Module + * @brief Process GPS information (UBX binary format) * @{ * * @file UBX.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @brief GPS module, handles GPS and NMEA stream + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @brief GPS module, handles GPS and UBX stream * @see The GNU Public License (GPL) Version 3 * *****************************************************************************/ @@ -41,6 +42,8 @@ #define UBX_HW_VERSION_8 80000 #define UBX_HW_VERSION_7 70000 +#define UBX_HW_VERSION_6 60000 +#define UBX_HW_VERSION_5 50000 #define UBX_SYNC1 0xb5 // UBX protocol synchronization characters #define UBX_SYNC2 0x62 @@ -97,13 +100,14 @@ typedef enum { } ubx_class_mon_id; typedef enum { - UBX_ID_CFG_NAV5 = 0x24, - UBX_ID_CFG_RATE = 0x08, - UBX_ID_CFG_MSG = 0x01, - UBX_ID_CFG_CFG = 0x09, - UBX_ID_CFG_SBAS = 0x16, - UBX_ID_CFG_GNSS = 0x3E, - UBX_ID_CFG_PRT = 0x00 + UBX_ID_CFG_NAV5 = 0x24, + UBX_ID_CFG_NAVX5 = 0x23, + UBX_ID_CFG_RATE = 0x08, + UBX_ID_CFG_MSG = 0x01, + UBX_ID_CFG_CFG = 0x09, + UBX_ID_CFG_SBAS = 0x16, + UBX_ID_CFG_GNSS = 0x3E, + UBX_ID_CFG_PRT = 0x00 } ubx_class_cfg_id; typedef enum { @@ -501,6 +505,21 @@ struct UBX_CFG_GNSS { struct UBX_CFG_GNSS_CFGBLOCK cfgBlocks[UBX_GNSS_ID_MAX]; } __attribute__((packed)); +// CFG-NAV5: Position Fixing Mode +#define UBX_CFG_NAV5_FIXMODE_2D_ONLY 0x01 +#define UBX_CFG_NAV5_FIXMODE_3D_ONLY 0x02 +#define UBX_CFG_NAV5_FIXMODE_AUTO_2D3D 0x03 + +// CFG-NAV5: Bitfield mask +#define UBX_CFG_NAV5_DYNMODEL (1 << 0) // Apply dynamic model settings +#define UBX_CFG_NAV5_MINELEV (1 << 1) // Apply minimum elevation settings +#define UBX_CFG_NAV5_FIXMODE (1 << 2) // Apply fix mode settings +#define UBX_CFG_NAV5_DRLIMIT (1 << 3) // Reserved +#define UBX_CFG_NAV5_POSITION (1 << 4) // Apply position mask settings +#define UBX_CFG_NAV5_TIME (1 << 5) // Apply time mask settings +#define UBX_CFG_NAV5_STATICHOLD (1 << 6) // Apply static hold settings +#define UBX_CFG_NAV5_DGPS (1 << 7) // Reserved + struct UBX_CFG_NAV5 { uint16_t mask; uint8_t dynModel; @@ -522,6 +541,41 @@ struct UBX_CFG_NAV5 { uint32_t reserved4; } __attribute__((packed)); +// CFG-NAVX5: Bitfield mask1 +#define UBX_CFG_NAVX5_MIN_MAX (1 << 2) // Apply min/max SVs settings +#define UBX_CFG_NAVX5_MIN_CNO (1 << 3) // Apply minimum C/N0 setting +#define UBX_CFG_NAVX5_INIT_3DFIX (1 << 6) // Apply initial 3D fix settings +#define UBX_CFG_NAVX5_WKN_ROLL (1 << 9) // Apply GPS weeknumber rollover settings +#define UBX_CFG_NAVX5_PPP (1 << 13) // Apply PPP flag, only supported on certain product variants +#define UBX_CFG_NAVX5_AOP (1 << 14) // Apply useAOP flag and aopOrbMaxErr setting (AssistNow Autonomous) + +struct UBX_CFG_NAVX5 { + uint16_t version; + uint16_t mask1; + uint32_t reserved0; + uint8_t reserved1; + uint8_t reserved2; + uint8_t minSVs; + uint8_t maxSVs; + uint8_t minCN0; + uint8_t reserved5; + uint8_t iniFix3D; + uint8_t reserved6; + uint8_t reserved7; + uint8_t reserved8; + uint16_t wknRollover; + uint32_t reserved9; + uint8_t reserved10; + uint8_t reserved11; + uint8_t usePPP; + uint8_t useAOP; + uint8_t reserved12; + uint8_t reserved13; + uint16_t aopOrbMaxErr; + uint32_t reserved3; + uint32_t reserved4; +} __attribute__((packed)); + // MON message Class #define UBX_MON_MAX_EXT 5 struct UBX_MON_VER { @@ -598,13 +652,14 @@ union UBXSENTPACKET { struct { struct UBXSENTHEADER header; union { - struct UBX_CFG_CFG cfg_cfg; - struct UBX_CFG_MSG cfg_msg; - struct UBX_CFG_NAV5 cfg_nav5; - struct UBX_CFG_PRT cfg_prt; - struct UBX_CFG_RATE cfg_rate; - struct UBX_CFG_SBAS cfg_sbas; - struct UBX_CFG_GNSS cfg_gnss; + struct UBX_CFG_CFG cfg_cfg; + struct UBX_CFG_MSG cfg_msg; + struct UBX_CFG_NAV5 cfg_nav5; + struct UBX_CFG_NAVX5 cfg_navx5; + struct UBX_CFG_PRT cfg_prt; + struct UBX_CFG_RATE cfg_rate; + struct UBX_CFG_SBAS cfg_sbas; + struct UBX_CFG_GNSS cfg_gnss; } payload; uint8_t resvd[2]; // added space for checksum bytes } message; @@ -612,7 +667,7 @@ union UBXSENTPACKET { // Used by AutoConfig code extern int32_t ubxHwVersion; -extern GPSPositionSensorSensorTypeOptions sensorType; +extern GPSPositionSensorSensorTypeOptions ubxSensorType; extern struct UBX_ACK_ACK ubxLastAck; extern struct UBX_ACK_NAK ubxLastNak; @@ -620,6 +675,7 @@ bool checksum_ubx_message(struct UBXPacket *); uint32_t parse_ubx_message(struct UBXPacket *, GPSPositionSensorData *); int parse_ubx_stream(uint8_t *rx, uint16_t len, char *, GPSPositionSensorData *, struct GPS_RX_STATS *); -void load_mag_settings(); +void op_gpsv9_load_mag_settings(); +void aux_hmc5x83_load_mag_settings(); #endif /* UBX_H */ diff --git a/flight/modules/GPS/inc/ubx_autoconfig.h b/flight/modules/GPS/inc/ubx_autoconfig.h index f24bc48a7..8578f1d6b 100644 --- a/flight/modules/GPS/inc/ubx_autoconfig.h +++ b/flight/modules/GPS/inc/ubx_autoconfig.h @@ -1,13 +1,17 @@ /** ****************************************************************************** + * @addtogroup OpenPilotModules OpenPilot Modules + * @{ + * @addtogroup GPSModule GPS Module + * @brief Support code for UBX AutoConfig + * @{ + * + * @file ubx_autoconfig.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014. + * @brief Support code for UBX AutoConfig + * @see The GNU Public License (GPL) Version 3 * - * @file %FILENAME% - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014. - * @addtogroup [Group] - * @{ - * @addtogroup %CLASS% - * @{ - * @brief [Brief] *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify @@ -85,6 +89,7 @@ typedef enum { #define UBX_ typedef struct { GPSSettingsUbxAutoConfigOptions UbxAutoConfig; + GPSSettingsUbxAssistNowAutonomousOptions AssistNowAutonomous; bool SBASRanging; bool SBASCorrection; bool SBASIntegrity; @@ -102,6 +107,7 @@ typedef struct { // Sent messages for configuration support typedef struct UBX_CFG_CFG ubx_cfg_cfg_t; typedef struct UBX_CFG_NAV5 ubx_cfg_nav5_t; +typedef struct UBX_CFG_NAVX5 ubx_cfg_navx5_t; typedef struct UBX_CFG_RATE ubx_cfg_rate_t; typedef struct UBX_CFG_MSG ubx_cfg_msg_t; typedef struct UBX_CFG_PRT ubx_cfg_prt_t; diff --git a/flight/modules/GPS/ubx_autoconfig.c b/flight/modules/GPS/ubx_autoconfig.c index 3e0adf012..9cfb079d3 100644 --- a/flight/modules/GPS/ubx_autoconfig.c +++ b/flight/modules/GPS/ubx_autoconfig.c @@ -2,12 +2,13 @@ ****************************************************************************** * @addtogroup OpenPilotModules OpenPilot Modules * @{ - * @addtogroup GSPModule GPS Module + * @addtogroup GPSModule GPS Module * @brief Support code for UBX AutoConfig * @{ * * @file ubx_autoconfig.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014. * @brief Support code for UBX AutoConfig * @see The GNU Public License (GPL) Version 3 * @@ -238,10 +239,10 @@ void gps_ubx_reset_sensor_type() // is this needed? // what happens if two tasks / threads try to do an XyzSet() at the same time? if (__sync_fetch_and_add(&mutex, 1) == 0) { - ubxHwVersion = -1; + ubxHwVersion = -1; baud_to_try_index -= 1; // undo postincrement and start with the one that was most recently successful - sensorType = GPSPOSITIONSENSOR_SENSORTYPE_UNKNOWN; - GPSPositionSensorSensorTypeSet(&sensorType); + ubxSensorType = GPSPOSITIONSENSOR_SENSORTYPE_UNKNOWN; + GPSPositionSensorSensorTypeSet(&ubxSensorType); // make the sensor type / autobaud code time out immediately to send the request immediately status->lastStepTimestampRaw += 0x8000000UL; } @@ -309,13 +310,22 @@ static void config_nav(uint16_t *bytes_to_send) { memset((uint8_t *)status->working_packet.buffer, 0, sizeof(UBXSentHeader_t) + sizeof(ubx_cfg_nav5_t)); status->working_packet.message.payload.cfg_nav5.dynModel = status->currentSettings.dynamicModel; - status->working_packet.message.payload.cfg_nav5.fixMode = 2; // 1=2D only, 2=3D only, 3=Auto 2D/3D + status->working_packet.message.payload.cfg_nav5.fixMode = UBX_CFG_NAV5_FIXMODE_3D_ONLY; // mask LSB=dyn|minEl|posFixMode|drLim|posMask|statisticHoldMask|dgpsMask|......|reservedBit0 = MSB - status->working_packet.message.payload.cfg_nav5.mask = 0x01 + 0x04; // Dyn Model | posFixMode configuration + status->working_packet.message.payload.cfg_nav5.mask = UBX_CFG_NAV5_DYNMODEL + UBX_CFG_NAV5_FIXMODE; *bytes_to_send = prepare_packet((UBXSentPacket_t *)&status->working_packet, UBX_CLASS_CFG, UBX_ID_CFG_NAV5, sizeof(ubx_cfg_nav5_t)); } +static void config_navx(uint16_t *bytes_to_send) +{ + memset((uint8_t *)status->working_packet.buffer, 0, sizeof(UBXSentHeader_t) + sizeof(ubx_cfg_navx5_t)); + status->working_packet.message.payload.cfg_navx5.useAOP = status->currentSettings.AssistNowAutonomous; + status->working_packet.message.payload.cfg_navx5.mask1 = UBX_CFG_NAVX5_AOP; + + *bytes_to_send = prepare_packet((UBXSentPacket_t *)&status->working_packet, UBX_CLASS_CFG, UBX_ID_CFG_NAVX5, sizeof(ubx_cfg_navx5_t)); +} + static void config_sbas(uint16_t *bytes_to_send) { @@ -408,7 +418,6 @@ static void config_save(uint16_t *bytes_to_send) *bytes_to_send = prepare_packet((UBXSentPacket_t *)&status->working_packet, UBX_CLASS_CFG, UBX_ID_CFG_CFG, sizeof(ubx_cfg_cfg_t)); } - static void configure(uint16_t *bytes_to_send) { switch (status->lastConfigSent) { @@ -422,6 +431,15 @@ static void configure(uint16_t *bytes_to_send) break; case LAST_CONFIG_SENT_START + 2: + if (ubxHwVersion > UBX_HW_VERSION_5) { + config_navx(bytes_to_send); + break; + } else { + // Skip and fall through to next step + status->lastConfigSent++; + } + + case LAST_CONFIG_SENT_START + 3: if (status->currentSettings.enableGLONASS || status->currentSettings.enableGPS) { config_gnss(bytes_to_send); break; @@ -431,7 +449,7 @@ static void configure(uint16_t *bytes_to_send) } // in the else case we must fall through because we must send something each time because successful send is tested externally - case LAST_CONFIG_SENT_START + 3: + case LAST_CONFIG_SENT_START + 4: config_sbas(bytes_to_send); break; @@ -849,6 +867,8 @@ void gps_ubx_autoconfig_run(char * *buffer, uint16_t *bytes_to_send) } +// (re)init the autoconfig stuff so that it will run if called +// // this can be called from a different thread // so everything it touches must be declared volatile void gps_ubx_autoconfig_set(ubx_autoconfig_settings_t *config) @@ -883,17 +903,17 @@ void gps_ubx_autoconfig_set(ubx_autoconfig_settings_t *config) status->currentStep = new_step; status->currentStepSave = new_step; + // this forces the sensor type detection to occur outside the FSM + // and _can_ also engage the autobaud detection that is outside the FSM + // don't do it if FSM is enabled as FSM can change the baud itself + // (don't do it because the baud rates are already in sync) + gps_ubx_reset_sensor_type(); + if (status->currentSettings.UbxAutoConfig >= GPSSETTINGS_UBXAUTOCONFIG_AUTOBAUDANDCONFIGURE) { // enabled refers to autoconfigure // note that sensor type (gps type) detection happens even if completely disabled - // also note that AutoBaud is less than Configure + // also note that AutoBaud is less than AutoBaudAndConfigure enabled = true; - } else { - // this forces the sensor type detection to occur outside the FSM - // and _can_ also engage the autobaud detection that is outside the FSM - // don't do it if FSM is enabled as FSM can change the baud itself - // (don't do it because the baud rates are already in sync) - gps_ubx_reset_sensor_type(); } } diff --git a/flight/modules/ManualControl/armhandler.c b/flight/modules/ManualControl/armhandler.c index dedd4b03c..a93586da4 100644 --- a/flight/modules/ManualControl/armhandler.c +++ b/flight/modules/ManualControl/armhandler.c @@ -7,7 +7,8 @@ * @{ * * @file armhandler.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014. * * @see The GNU Public License (GPL) Version 3 * @@ -40,7 +41,7 @@ #endif // Private constants -#define ARMED_THRESHOLD 0.50f +#define ARMED_THRESHOLD 0.20f #define GROUND_LOW_THROTTLE 0.01f // Private types @@ -106,6 +107,10 @@ void armHandler(bool newinit, FrameType_t frameType) AccessoryDesiredInstGet(2, &acc); armSwitch = true; break; + case FLIGHTMODESETTINGS_ARMING_ACCESSORY3: + AccessoryDesiredInstGet(3, &acc); + armSwitch = true; + break; default: break; } @@ -181,6 +186,7 @@ void armHandler(bool newinit, FrameType_t frameType) case FLIGHTMODESETTINGS_ARMING_ACCESSORY0: case FLIGHTMODESETTINGS_ARMING_ACCESSORY1: case FLIGHTMODESETTINGS_ARMING_ACCESSORY2: + case FLIGHTMODESETTINGS_ARMING_ACCESSORY3: armingInputLevel = -1.0f * acc.AccessoryVal; break; default: @@ -190,12 +196,27 @@ void armHandler(bool newinit, FrameType_t frameType) bool manualArm = false; bool manualDisarm = false; - if (armingInputLevel <= -ARMED_THRESHOLD) { + static FlightModeSettingsArmingOptions previousArmingSettings = -1; + static float previousArmingInputLevel = 0.0f; + + if (previousArmingSettings != settings.Arming) { + previousArmingSettings = settings.Arming; + previousArmingInputLevel = 0.0f; + } + + // ignore previous arming input level if not transitioning from fully ARMED/DISARMED states. + if ((armState != ARM_STATE_DISARMED) && (armState != ARM_STATE_ARMED)) { + previousArmingInputLevel = 0.0f; + } + + if ((armingInputLevel <= -ARMED_THRESHOLD) && (previousArmingInputLevel > -ARMED_THRESHOLD)) { manualArm = true; - } else if (armingInputLevel >= +ARMED_THRESHOLD) { + } else if ((armingInputLevel >= +ARMED_THRESHOLD) && (previousArmingInputLevel < +ARMED_THRESHOLD)) { manualDisarm = true; } + previousArmingInputLevel = armingInputLevel; + switch (armState) { case ARM_STATE_DISARMED: setArmedIfChanged(FLIGHTSTATUS_ARMED_DISARMED); @@ -313,14 +334,26 @@ static bool okToArm(void) return false; } + // Avoid arming while AlwaysStabilizeWhenArmed is active + if (flightStatus.AlwaysStabilizeWhenArmed == FLIGHTSTATUS_ALWAYSSTABILIZEWHENARMED_TRUE) { + return false; + } + return true; break; case FLIGHTSTATUS_FLIGHTMODE_LAND: +#if !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) + case FLIGHTSTATUS_FLIGHTMODE_AUTOTUNE: +#endif /* !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) */ return false; case FLIGHTSTATUS_FLIGHTMODE_AUTOTAKEOFF: case FLIGHTSTATUS_FLIGHTMODE_PATHPLANNER: + // Avoid arming while AlwaysStabilizeWhenArmed is active + if (flightStatus.AlwaysStabilizeWhenArmed == FLIGHTSTATUS_ALWAYSSTABILIZEWHENARMED_TRUE) { + return false; + } return true; default: diff --git a/flight/modules/ManualControl/manualcontrol.c b/flight/modules/ManualControl/manualcontrol.c index 56247e836..b18f8d8cb 100644 --- a/flight/modules/ManualControl/manualcontrol.c +++ b/flight/modules/ManualControl/manualcontrol.c @@ -11,7 +11,8 @@ * AttitudeDesired object (stabilized mode) * * @file manualcontrol.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014. * @brief ManualControl module. Handles safety R/C link and flight mode. * * @see The GNU Public License (GPL) Version 3 @@ -37,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -46,7 +48,7 @@ #include #ifndef PIOS_EXCLUDE_ADVANCED_FEATURES #include -#endif +#endif /* ifndef PIOS_EXCLUDE_ADVANCED_FEATURES */ // Private constants #if defined(PIOS_MANUAL_STACK_SIZE) @@ -62,6 +64,7 @@ #define ASSISTEDCONTROL_BRAKETHRUST_DEADBAND_FACTOR_LO 0.96f #define ASSISTEDCONTROL_BRAKETHRUST_DEADBAND_FACTOR_HI 1.04f +#define ALWAYSTABILIZEACCESSORY_THRESHOLD 0.05f // defined handlers @@ -116,7 +119,7 @@ static void commandUpdatedCb(UAVObjEvent *ev); static void manualControlTask(void); #ifndef PIOS_EXCLUDE_ADVANCED_FEATURES static uint8_t isAssistedFlightMode(uint8_t position, uint8_t flightMode, FlightModeSettingsData *modeSettings); -#endif +#endif /* ifndef PIOS_EXCLUDE_ADVANCED_FEATURES */ static void SettingsUpdatedCb(UAVObjEvent *ev); #define assumptions (assumptions1 && assumptions2 && assumptions3 && assumptions4 && assumptions5 && assumptions6 && assumptions7 && assumptions_flightmode) @@ -126,14 +129,15 @@ static void SettingsUpdatedCb(UAVObjEvent *ev); */ int32_t ManualControlStart() { - // Run this initially to make sure the configuration is checked - configuration_check(); - // Whenever the configuration changes, make sure it is safe to fly SystemSettingsConnectCallback(configurationUpdatedCb); ManualControlSettingsConnectCallback(configurationUpdatedCb); + FlightModeSettingsConnectCallback(configurationUpdatedCb); ManualControlCommandConnectCallback(commandUpdatedCb); + // Run this initially to make sure the configuration is checked + configuration_check(); + // clear alarms AlarmsClear(SYSTEMALARMS_ALARM_MANUALCONTROL); @@ -144,8 +148,8 @@ int32_t ManualControlStart() #ifndef PIOS_EXCLUDE_ADVANCED_FEATURES takeOffLocationHandlerInit(); +#endif /* ifndef PIOS_EXCLUDE_ADVANCED_FEATURES */ -#endif // Start main task PIOS_CALLBACKSCHEDULER_Dispatch(callbackHandle); @@ -166,12 +170,13 @@ int32_t ManualControlInitialize() FlightModeSettingsInitialize(); SystemSettingsInitialize(); StabilizationSettingsInitialize(); + AccessoryDesiredInitialize(); #ifndef PIOS_EXCLUDE_ADVANCED_FEATURES VtolSelfTuningStatsInitialize(); VtolPathFollowerSettingsInitialize(); VtolPathFollowerSettingsConnectCallback(&SettingsUpdatedCb); SystemSettingsConnectCallback(&SettingsUpdatedCb); -#endif +#endif /* ifndef PIOS_EXCLUDE_ADVANCED_FEATURES */ callbackHandle = PIOS_CALLBACKSCHEDULER_Create(&manualControlTask, CALLBACK_PRIORITY, CBTASK_PRIORITY, CALLBACKINFO_RUNNING_MANUALCONTROL, STACK_SIZE_BYTES); return 0; @@ -199,7 +204,7 @@ static void SettingsUpdatedCb(__attribute__((unused)) UAVObjEvent *ev) break; } } -#endif +#endif /* ifndef PIOS_EXCLUDE_ADVANCED_FEATURES */ } /** @@ -211,23 +216,26 @@ static void manualControlTask(void) armHandler(false, frameType); #ifndef PIOS_EXCLUDE_ADVANCED_FEATURES takeOffLocationHandler(); -#endif +#endif /* ifndef PIOS_EXCLUDE_ADVANCED_FEATURES */ // Process flight mode FlightStatusData flightStatus; FlightStatusGet(&flightStatus); ManualControlCommandData cmd; ManualControlCommandGet(&cmd); + AccessoryDesiredData acc; #ifndef PIOS_EXCLUDE_ADVANCED_FEATURES VtolPathFollowerSettingsThrustLimitsData thrustLimits; VtolPathFollowerSettingsThrustLimitsGet(&thrustLimits); -#endif +#endif /* ifndef PIOS_EXCLUDE_ADVANCED_FEATURES */ FlightModeSettingsData modeSettings; FlightModeSettingsGet(&modeSettings); + static uint8_t lastPosition = 0; uint8_t position = cmd.FlightModeSwitchPosition; - uint8_t newMode = flightStatus.FlightMode; + uint8_t newMode = flightStatus.FlightMode; + uint8_t newAlwaysStabilized = flightStatus.AlwaysStabilizeWhenArmed; uint8_t newFlightModeAssist = flightStatus.FlightModeAssist; uint8_t newAssistedControlState = flightStatus.AssistedControlState; uint8_t newAssistedThrottleState = flightStatus.AssistedThrottleState; @@ -235,6 +243,13 @@ static void manualControlTask(void) newMode = modeSettings.FlightModePosition[position]; } + // Ignore change to AutoTakeOff and keep last flight mode position + // if vehicle is already armed and maybe in air... + if ((newMode == FLIGHTSTATUS_FLIGHTMODE_AUTOTAKEOFF) && flightStatus.Armed) { + newMode = flightStatus.FlightMode; + position = lastPosition; + } + // if a mode change occurs we default the assist mode and states here // to avoid having to add it to all of the below modes that are // otherwise unrelated @@ -260,6 +275,9 @@ static void manualControlTask(void) case FLIGHTSTATUS_FLIGHTMODE_STABILIZED4: case FLIGHTSTATUS_FLIGHTMODE_STABILIZED5: case FLIGHTSTATUS_FLIGHTMODE_STABILIZED6: +#if !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) + case FLIGHTSTATUS_FLIGHTMODE_AUTOTUNE: +#endif /* ifndef PIOS_EXCLUDE_ADVANCED_FEATURES */ handler = &handler_STABILIZED; #ifndef PIOS_EXCLUDE_ADVANCED_FEATURES @@ -273,7 +291,6 @@ static void manualControlTask(void) newAssistedThrottleState = FLIGHTSTATUS_ASSISTEDTHROTTLESTATE_MANUAL; } - if (newFlightModeAssist) { // assess roll/pitch state bool flagRollPitchHasInput = (fabsf(cmd.Roll) > 0.0f || fabsf(cmd.Pitch) > 0.0f); @@ -449,23 +466,60 @@ static void manualControlTask(void) // There is no default, so if a flightmode is forgotten the compiler can throw a warning! } + bool alwaysStabilizedSwitch = false; + + // Check for a AlwaysStabilizeWhenArmed accessory switch + switch (modeSettings.AlwaysStabilizeWhenArmedSwitch) { + case FLIGHTMODESETTINGS_ALWAYSSTABILIZEWHENARMEDSWITCH_ACCESSORY0: + AccessoryDesiredInstGet(0, &acc); + alwaysStabilizedSwitch = true; + break; + case FLIGHTMODESETTINGS_ALWAYSSTABILIZEWHENARMEDSWITCH_ACCESSORY1: + AccessoryDesiredInstGet(1, &acc); + alwaysStabilizedSwitch = true; + break; + case FLIGHTMODESETTINGS_ALWAYSSTABILIZEWHENARMEDSWITCH_ACCESSORY2: + AccessoryDesiredInstGet(2, &acc); + alwaysStabilizedSwitch = true; + break; + case FLIGHTMODESETTINGS_ALWAYSSTABILIZEWHENARMEDSWITCH_ACCESSORY3: + AccessoryDesiredInstGet(3, &acc); + alwaysStabilizedSwitch = true; + break; + default: + break; + } + + if (alwaysStabilizedSwitch) { + if (acc.AccessoryVal <= -ALWAYSTABILIZEACCESSORY_THRESHOLD) { + newAlwaysStabilized = FLIGHTSTATUS_ALWAYSSTABILIZEWHENARMED_FALSE; + } else if (acc.AccessoryVal >= ALWAYSTABILIZEACCESSORY_THRESHOLD) { + newAlwaysStabilized = FLIGHTSTATUS_ALWAYSSTABILIZEWHENARMED_TRUE; + } + } else { + newAlwaysStabilized = FLIGHTSTATUS_ALWAYSSTABILIZEWHENARMED_FALSE; + } + bool newinit = false; // FlightMode needs to be set correctly on first run (otherwise ControlChain is invalid) static bool firstRun = true; - if (flightStatus.FlightMode != newMode || firstRun || + if (flightStatus.AlwaysStabilizeWhenArmed != newAlwaysStabilized || + flightStatus.FlightMode != newMode || firstRun || newFlightModeAssist != flightStatus.FlightModeAssist || newAssistedControlState != flightStatus.AssistedControlState || flightStatus.AssistedThrottleState != newAssistedThrottleState) { firstRun = false; - flightStatus.ControlChain = handler->controlChain; - flightStatus.FlightMode = newMode; - flightStatus.FlightModeAssist = newFlightModeAssist; - flightStatus.AssistedControlState = newAssistedControlState; - flightStatus.AssistedThrottleState = newAssistedThrottleState; + flightStatus.ControlChain = handler->controlChain; + flightStatus.FlightMode = newMode; + flightStatus.AlwaysStabilizeWhenArmed = newAlwaysStabilized; + flightStatus.FlightModeAssist = newFlightModeAssist; + flightStatus.AssistedControlState = newAssistedControlState; + flightStatus.AssistedThrottleState = newAssistedThrottleState; FlightStatusSet(&flightStatus); newinit = true; + lastPosition = position; } if (handler->handler) { handler->handler(newinit); @@ -489,22 +543,21 @@ static void commandUpdatedCb(__attribute__((unused)) UAVObjEvent *ev) } +#if !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) /** * Check and set modes for gps assisted stablised flight modes */ -#ifndef PIOS_EXCLUDE_ADVANCED_FEATURES static uint8_t isAssistedFlightMode(uint8_t position, uint8_t flightMode, FlightModeSettingsData *modeSettings) { - uint8_t flightModeAssistOption = STABILIZATIONSETTINGS_FLIGHTMODEASSISTMAP_NONE; - uint8_t isAssistedFlag = FLIGHTSTATUS_FLIGHTMODEASSIST_NONE; StabilizationSettingsFlightModeAssistMapOptions FlightModeAssistMap[STABILIZATIONSETTINGS_FLIGHTMODEASSISTMAP_NUMELEM]; StabilizationSettingsFlightModeAssistMapGet(FlightModeAssistMap); - if (position < STABILIZATIONSETTINGS_FLIGHTMODEASSISTMAP_NUMELEM) { - flightModeAssistOption = FlightModeAssistMap[position]; + if (flightMode == FLIGHTSTATUS_FLIGHTMODE_AUTOTUNE + || position >= STABILIZATIONSETTINGS_FLIGHTMODEASSISTMAP_NUMELEM) { + return FLIGHTSTATUS_FLIGHTMODEASSIST_NONE; } - switch (flightModeAssistOption) { + switch (FlightModeAssistMap[position]) { case STABILIZATIONSETTINGS_FLIGHTMODEASSISTMAP_NONE: break; case STABILIZATIONSETTINGS_FLIGHTMODEASSISTMAP_GPSASSIST: @@ -551,22 +604,22 @@ static uint8_t isAssistedFlightMode(uint8_t position, uint8_t flightMode, Flight case FLIGHTMODESETTINGS_STABILIZATION1SETTINGS_ALTITUDEHOLD: case FLIGHTMODESETTINGS_STABILIZATION1SETTINGS_ALTITUDEVARIO: // this is only for use with stabi mods with althold/vario. - isAssistedFlag = FLIGHTSTATUS_FLIGHTMODEASSIST_GPSASSIST_PRIMARYTHRUST; - break; + return FLIGHTSTATUS_FLIGHTMODEASSIST_GPSASSIST_PRIMARYTHRUST; + case FLIGHTMODESETTINGS_STABILIZATION1SETTINGS_MANUAL: case FLIGHTMODESETTINGS_STABILIZATION1SETTINGS_CRUISECONTROL: default: // this is the default for non stabi modes also - isAssistedFlag = FLIGHTSTATUS_FLIGHTMODEASSIST_GPSASSIST; - break; + return FLIGHTSTATUS_FLIGHTMODEASSIST_GPSASSIST; } } break; } - return isAssistedFlag; + // return isAssistedFlag; + return FLIGHTSTATUS_FLIGHTMODEASSIST_NONE; } -#endif /* ifndef PIOS_EXCLUDE_ADVANCED_FEATURES */ +#endif /* !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) */ /** * @} diff --git a/flight/modules/ManualControl/pathfollowerhandler.c b/flight/modules/ManualControl/pathfollowerhandler.c index 202c833b8..a48a754ce 100644 --- a/flight/modules/ManualControl/pathfollowerhandler.c +++ b/flight/modules/ManualControl/pathfollowerhandler.c @@ -1,16 +1,14 @@ /** ****************************************************************************** - * @addtogroup OpenPilotModules OpenPilot Modules - * @{ - * @addtogroup ManualControl - * @brief Interpretes the control input in ManualControlCommand - * @{ - * * @file pathfollowerhandler.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2015. + * + * @brief Interpretes the control input in ManualControlCommand * * @see The GNU Public License (GPL) Version 3 * + * @addtogroup LibrePilotModules LibrePilot Modules ManualControl ******************************************************************************/ /* * This program is free software; you can redistribute it and/or modify @@ -140,9 +138,6 @@ void pathFollowerHandler(bool newinit) plan_run_VelocityRoam(); } break; - case FLIGHTSTATUS_FLIGHTMODE_AUTOTAKEOFF: - plan_run_AutoTakeoff(); - break; case FLIGHTSTATUS_FLIGHTMODE_AUTOCRUISE: plan_run_AutoCruise(); break; diff --git a/flight/modules/ManualControl/stabilizedhandler.c b/flight/modules/ManualControl/stabilizedhandler.c index e2361b1f9..7de4ae24d 100644 --- a/flight/modules/ManualControl/stabilizedhandler.c +++ b/flight/modules/ManualControl/stabilizedhandler.c @@ -7,7 +7,8 @@ * @{ * * @file stabilizedhandler.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014. * * @see The GNU Public License (GPL) Version 3 * @@ -30,10 +31,12 @@ #include "inc/manualcontrol.h" #include +#include #include #include #include #include +#include // Private constants @@ -42,18 +45,23 @@ // Private functions static float applyExpo(float value, float expo); +// Private variables +static uint8_t currentFpvTiltAngle = 0; +static float cosAngle = 0.0f; +static float sinAngle = 0.0f; + static float applyExpo(float value, float expo) { // note: fastPow makes a small error, therefore result needs to be bound - float exp = boundf(fastPow(1.00695f, expo), 0.5f, 2.0f); + float exp = boundf(fastPow(1.01395948f, expo), 0.25f, 4.0f); // magic number scales expo // so that // expo=100 yields value**10 // expo=0 yields value**1 // expo=-100 yields value**(1/10) - // (pow(2.0,1/100)~=1.00695) + // (pow(4.0,1/100)~=1.01395948) if (value > 0.0f) { return boundf(fastPow(value, exp), 0.0f, 1.0f); } else if (value < -0.0f) { @@ -69,12 +77,16 @@ static float applyExpo(float value, float expo) * @input: ManualControlCommand * @output: StabilizationDesired */ -void stabilizedHandler(bool newinit) +void stabilizedHandler(__attribute__((unused)) bool newinit) { - if (newinit) { + static bool inited = false; + + if (!inited) { + inited = true; StabilizationDesiredInitialize(); StabilizationBankInitialize(); } + ManualControlCommandData cmd; ManualControlCommandGet(&cmd); @@ -90,10 +102,27 @@ void stabilizedHandler(bool newinit) cmd.Roll = applyExpo(cmd.Roll, stabSettings.StickExpo.Roll); cmd.Pitch = applyExpo(cmd.Pitch, stabSettings.StickExpo.Pitch); cmd.Yaw = applyExpo(cmd.Yaw, stabSettings.StickExpo.Yaw); + + if (stabSettings.FpvCamTiltCompensation > 0) { + // Reduce Cpu load + if (currentFpvTiltAngle != stabSettings.FpvCamTiltCompensation) { + cosAngle = cos_lookup_deg((float)stabSettings.FpvCamTiltCompensation); + sinAngle = sin_lookup_deg((float)stabSettings.FpvCamTiltCompensation); + currentFpvTiltAngle = stabSettings.FpvCamTiltCompensation; + } + float rollCommand = cmd.Roll; + float yawCommand = cmd.Yaw; + + // http://shrediquette.blogspot.de/2016/01/some-thoughts-on-camera-tilt.html + // When Roll right, add negative Yaw. + // When Yaw left, add negative Roll. + cmd.Roll = boundf((cosAngle * rollCommand) + (sinAngle * yawCommand), -1.0f, 1.0f); + cmd.Yaw = boundf((cosAngle * yawCommand) - (sinAngle * rollCommand), -1.0f, 1.0f); + } + uint8_t *stab_settings; FlightStatusData flightStatus; FlightStatusGet(&flightStatus); - switch (flightStatus.FlightMode) { case FLIGHTSTATUS_FLIGHTMODE_STABILIZED1: stab_settings = (uint8_t *)FlightModeSettingsStabilization1SettingsToArray(settings.Stabilization1Settings); @@ -113,6 +142,13 @@ void stabilizedHandler(bool newinit) case FLIGHTSTATUS_FLIGHTMODE_STABILIZED6: stab_settings = (uint8_t *)FlightModeSettingsStabilization6SettingsToArray(settings.Stabilization6Settings); break; +#if !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) + case FLIGHTSTATUS_FLIGHTMODE_AUTOTUNE: + // let autotune.c handle it + // because it must switch to Attitude after seconds + return; + +#endif /* !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) */ default: // Major error, this should not occur because only enter this block when one of these is true AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_CRITICAL); @@ -130,6 +166,9 @@ void stabilizedHandler(bool newinit) (stab_settings[0] == STABILIZATIONDESIRED_STABILIZATIONMODE_VIRTUALBAR) ? cmd.Roll : (stab_settings[0] == STABILIZATIONDESIRED_STABILIZATIONMODE_ACRO) ? cmd.Roll * stabSettings.ManualRate.Roll : (stab_settings[0] == STABILIZATIONDESIRED_STABILIZATIONMODE_RATTITUDE) ? cmd.Roll * stabSettings.RollMax : +#if !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) + (stab_settings[0] == STABILIZATIONDESIRED_STABILIZATIONMODE_SYSTEMIDENT) ? cmd.Roll * stabSettings.RollMax : +#endif /* !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) */ 0; // this is an invalid mode stabilization.Pitch = @@ -142,6 +181,9 @@ void stabilizedHandler(bool newinit) (stab_settings[1] == STABILIZATIONDESIRED_STABILIZATIONMODE_VIRTUALBAR) ? cmd.Pitch : (stab_settings[1] == STABILIZATIONDESIRED_STABILIZATIONMODE_ACRO) ? cmd.Pitch * stabSettings.ManualRate.Pitch : (stab_settings[1] == STABILIZATIONDESIRED_STABILIZATIONMODE_RATTITUDE) ? cmd.Pitch * stabSettings.PitchMax : +#if !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) + (stab_settings[1] == STABILIZATIONDESIRED_STABILIZATIONMODE_SYSTEMIDENT) ? cmd.Pitch * stabSettings.PitchMax : +#endif /* !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) */ 0; // this is an invalid mode // TOOD: Add assumption about order of stabilization desired and manual control stabilization mode fields having same order @@ -164,6 +206,9 @@ void stabilizedHandler(bool newinit) (stab_settings[2] == STABILIZATIONDESIRED_STABILIZATIONMODE_VIRTUALBAR) ? cmd.Yaw : (stab_settings[2] == STABILIZATIONDESIRED_STABILIZATIONMODE_ACRO) ? cmd.Yaw * stabSettings.ManualRate.Yaw : (stab_settings[2] == STABILIZATIONDESIRED_STABILIZATIONMODE_RATTITUDE) ? cmd.Yaw * stabSettings.YawMax : +#if !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) + (stab_settings[2] == STABILIZATIONDESIRED_STABILIZATIONMODE_SYSTEMIDENT) ? cmd.Yaw * stabSettings.ManualRate.Yaw : +#endif /* !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) */ 0; // this is an invalid mode } diff --git a/flight/modules/Notify/inc/sequences.h b/flight/modules/Notify/inc/sequences.h index 3cf46d832..72e99203a 100644 --- a/flight/modules/Notify/inc/sequences.h +++ b/flight/modules/Notify/inc/sequences.h @@ -2,7 +2,8 @@ ****************************************************************************** * * @file sequences.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @brief Notify module, sequences configuration. * * @see The GNU Public License (GPL) Version 3 @@ -34,25 +35,26 @@ // This represent the list of basic light sequences, defined later typedef enum { NOTIFY_SEQUENCE_ARMED_FM_MANUAL = 0, - NOTIFY_SEQUENCE_ARMED_FM_STABILIZED1 = 1, - NOTIFY_SEQUENCE_ARMED_FM_STABILIZED2 = 2, - NOTIFY_SEQUENCE_ARMED_FM_STABILIZED3 = 3, - NOTIFY_SEQUENCE_ARMED_FM_STABILIZED4 = 4, - NOTIFY_SEQUENCE_ARMED_FM_STABILIZED5 = 5, - NOTIFY_SEQUENCE_ARMED_FM_STABILIZED6 = 6, - NOTIFY_SEQUENCE_ARMED_FM_GPS = 8, - NOTIFY_SEQUENCE_ARMED_FM_RTH = 9, - NOTIFY_SEQUENCE_ARMED_FM_LAND = 10, - NOTIFY_SEQUENCE_ARMED_FM_AUTO = 11, - NOTIFY_SEQUENCE_ALM_WARN_GPS = 12, - NOTIFY_SEQUENCE_ALM_ERROR_GPS = 13, - NOTIFY_SEQUENCE_ALM_WARN_BATTERY = 14, - NOTIFY_SEQUENCE_ALM_ERROR_BATTERY = 15, - NOTIFY_SEQUENCE_ALM_MAG = 16, - NOTIFY_SEQUENCE_ALM_CONFIG = 17, - NOTIFY_SEQUENCE_ALM_RECEIVER = 18, - NOTIFY_SEQUENCE_DISARMED = 19, - NOTIFY_SEQUENCE_ALM_ATTITUDE = 20, + NOTIFY_SEQUENCE_ARMED_FM_STABILIZED1, + NOTIFY_SEQUENCE_ARMED_FM_STABILIZED2, + NOTIFY_SEQUENCE_ARMED_FM_STABILIZED3, + NOTIFY_SEQUENCE_ARMED_FM_STABILIZED4, + NOTIFY_SEQUENCE_ARMED_FM_STABILIZED5, + NOTIFY_SEQUENCE_ARMED_FM_STABILIZED6, + NOTIFY_SEQUENCE_ARMED_FM_GPS, + NOTIFY_SEQUENCE_ARMED_FM_RTH, + NOTIFY_SEQUENCE_ARMED_FM_LAND, + NOTIFY_SEQUENCE_ARMED_FM_AUTO, + NOTIFY_SEQUENCE_ALM_WARN_GPS, + NOTIFY_SEQUENCE_ALM_ERROR_GPS, + NOTIFY_SEQUENCE_ALM_WARN_BATTERY, + NOTIFY_SEQUENCE_ALM_ERROR_BATTERY, + NOTIFY_SEQUENCE_ALM_WARN_MAG, + NOTIFY_SEQUENCE_ALM_ERROR_MAG, + NOTIFY_SEQUENCE_ALM_CONFIG, + NOTIFY_SEQUENCE_ALM_RECEIVER, + NOTIFY_SEQUENCE_DISARMED, + NOTIFY_SEQUENCE_ALM_ATTITUDE, NOTIFY_SEQUENCE_NULL = 255, // skips any signalling for this condition } NotifySequences; @@ -65,6 +67,21 @@ typedef struct { uint8_t errorNotification; // index of the sequence to be used when alarm is in error status(pick one from NotifySequences enum) } AlarmDefinition_t; +#define STANDARD_ERROR_SEQUENCE(alarm_color, alarm_repeats) \ + { .repeats = alarm_repeats, .steps = { \ + { .time_off = 200, .time_on = 10, .color = COLOR_BLACK, .repeats = 1, }, \ + { .time_off = 100, .time_on = 300, .color = COLOR_DARKRED, .repeats = 1, }, \ + { .time_off = 100, .time_on = 300, .color = alarm_color, .repeats = 2, }, \ + { .time_off = 100, .time_on = 10, .color = COLOR_BLACK, .repeats = 1, }, \ + }, } + +#define STANDARD_WARN_SEQUENCE(alarm_color, alarm_repeats) \ + { .repeats = alarm_repeats, .steps = { \ + { .time_off = 200, .time_on = 10, .color = COLOR_BLACK, .repeats = 1, }, \ + { .time_off = 100, .time_on = 300, .color = COLOR_ORANGE, .repeats = 1, }, \ + { .time_off = 100, .time_on = 300, .color = alarm_color, .repeats = 1, }, \ + { .time_off = 200, .time_on = 10, .color = COLOR_BLACK, .repeats = 1, }, \ + }, } // This is the list of defined light sequences /* how each sequence is defined @@ -89,10 +106,12 @@ typedef struct { */ const LedSequence_t notifications[] = { [NOTIFY_SEQUENCE_DISARMED] = { .repeats = -1, .steps = { - { .time_off = 500, .time_on = 500, .color = COLOR_TEAL, .repeats = 1, }, + { .time_off = 200, .time_on = 10, .color = COLOR_BLACK, .repeats = 1, }, + { .time_off = 100, .time_on = 100, .color = COLOR_WHITE, .repeats = 1, }, + { .time_off = 200, .time_on = 10, .color = COLOR_BLACK, .repeats = 1, }, }, }, [NOTIFY_SEQUENCE_ARMED_FM_MANUAL] = { .repeats = -1, .steps = { - { .time_off = 900, .time_on = 100, .color = COLOR_YELLOW, .repeats = 1, }, + { .time_off = 900, .time_on = 100, .color = COLOR_BLUE, .repeats = 1, }, }, }, [NOTIFY_SEQUENCE_ARMED_FM_STABILIZED1] = { .repeats = -1, .steps = { { .time_off = 900, .time_on = 100, .color = COLOR_BLUE, .repeats = 1, }, @@ -131,34 +150,19 @@ const LedSequence_t notifications[] = { { .time_off = 100, .time_on = 200, .color = COLOR_GREEN, .repeats = 2, }, { .time_off = 500, .time_on = 200, .color = COLOR_GREEN, .repeats = 1, }, }, }, - - [NOTIFY_SEQUENCE_ALM_WARN_GPS] = { .repeats = 2, .steps = { - { .time_off = 300, .time_on = 300, .color = COLOR_ORANGE, .repeats = 2, }, - { .time_off = 300, .time_on = 300, .color = COLOR_GREEN, .repeats = 1, }, - }, }, - [NOTIFY_SEQUENCE_ALM_ERROR_GPS] = { .repeats = 2, .steps = { - { .time_off = 300, .time_on = 300, .color = COLOR_RED, .repeats = 2, }, - { .time_off = 300, .time_on = 300, .color = COLOR_GREEN, .repeats = 1, }, - }, }, + [NOTIFY_SEQUENCE_ALM_WARN_GPS] = STANDARD_WARN_SEQUENCE(COLOR_GREEN, 1), + [NOTIFY_SEQUENCE_ALM_ERROR_GPS] = STANDARD_ERROR_SEQUENCE(COLOR_GREEN, 1), [NOTIFY_SEQUENCE_ALM_WARN_BATTERY] = { .repeats = 1, .steps = { - { .time_off = 100, .time_on = 100, .color = COLOR_ORANGE, .repeats = 10, }, + { .time_off = 100, .time_on = 100, .color = COLOR_ORANGE, .repeats = 5, }, }, }, [NOTIFY_SEQUENCE_ALM_ERROR_BATTERY] = { .repeats = 1, .steps = { - { .time_off = 100, .time_on = 100, .color = COLOR_RED, .repeats = 10, }, + { .time_off = 100, .time_on = 100, .color = COLOR_RED, .repeats = 5, }, }, }, - [NOTIFY_SEQUENCE_ALM_MAG] = { .repeats = 1, .steps = { - { .time_off = 300, .time_on = 300, .color = COLOR_RED, .repeats = 2, }, - { .time_off = 300, .time_on = 300, .color = COLOR_PURPLE, .repeats = 1, }, - }, }, - [NOTIFY_SEQUENCE_ALM_CONFIG] = { .repeats = 1, .steps = { - { .time_off = 50, .time_on = 50, .color = COLOR_RED, .repeats = 9, }, - { .time_off = 500, .time_on = 50, .color = COLOR_RED, .repeats = 1, }, - }, }, - [NOTIFY_SEQUENCE_ALM_RECEIVER] = { .repeats = 1, .steps = { - { .time_off = 50, .time_on = 50, .color = COLOR_ORANGE, .repeats = 9, }, - { .time_off = 500, .time_on = 50, .color = COLOR_ORANGE, .repeats = 1, }, - }, }, - [NOTIFY_SEQUENCE_ALM_ATTITUDE] = { .repeats = 10, .steps = { + [NOTIFY_SEQUENCE_ALM_ERROR_MAG] = STANDARD_ERROR_SEQUENCE(COLOR_PURPLE, 1), + [NOTIFY_SEQUENCE_ALM_WARN_MAG] = STANDARD_WARN_SEQUENCE(COLOR_PURPLE, 1), + [NOTIFY_SEQUENCE_ALM_CONFIG] = STANDARD_ERROR_SEQUENCE(COLOR_RED, 2), + [NOTIFY_SEQUENCE_ALM_RECEIVER] = STANDARD_ERROR_SEQUENCE(COLOR_YELLOW, 1), + [NOTIFY_SEQUENCE_ALM_ATTITUDE] = { .repeats = 10, .steps = { { .time_off = 0, .time_on = 50, .color = COLOR_RED, .repeats = 1, }, { .time_off = 0, .time_on = 50, .color = COLOR_BLUE, .repeats = 1, }, }, }, @@ -184,12 +188,15 @@ const LedSequence_t *flightModeMap[] = { [FLIGHTSTATUS_FLIGHTMODE_POI] = ¬ifications[NOTIFY_SEQUENCE_ARMED_FM_GPS], [FLIGHTSTATUS_FLIGHTMODE_AUTOCRUISE] = ¬ifications[NOTIFY_SEQUENCE_ARMED_FM_GPS], [FLIGHTSTATUS_FLIGHTMODE_AUTOTAKEOFF] = ¬ifications[NOTIFY_SEQUENCE_ARMED_FM_LAND], +#if !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) + [FLIGHTSTATUS_FLIGHTMODE_AUTOTUNE] = ¬ifications[NOTIFY_SEQUENCE_ARMED_FM_MANUAL], +#endif /* !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) */ }; // List of alarms to show with attached sequences for each status const AlarmDefinition_t alarmsMap[] = { { - .timeBetweenNotifications = 10000, + .timeBetweenNotifications = 5000, .alarmIndex = SYSTEMALARMS_ALARM_GPS, .warnNotification = NOTIFY_SEQUENCE_ALM_WARN_GPS, .criticalNotification = NOTIFY_SEQUENCE_ALM_ERROR_GPS, @@ -198,9 +205,9 @@ const AlarmDefinition_t alarmsMap[] = { { .timeBetweenNotifications = 5000, .alarmIndex = SYSTEMALARMS_ALARM_MAGNETOMETER, - .warnNotification = NOTIFY_SEQUENCE_NULL, - .criticalNotification = NOTIFY_SEQUENCE_ALM_MAG, - .errorNotification = NOTIFY_SEQUENCE_ALM_MAG, + .warnNotification = NOTIFY_SEQUENCE_ALM_WARN_MAG, + .criticalNotification = NOTIFY_SEQUENCE_ALM_ERROR_MAG, + .errorNotification = NOTIFY_SEQUENCE_ALM_ERROR_MAG, }, { .timeBetweenNotifications = 15000, @@ -217,7 +224,7 @@ const AlarmDefinition_t alarmsMap[] = { .errorNotification = NOTIFY_SEQUENCE_ALM_CONFIG, }, { - .timeBetweenNotifications = 2000, + .timeBetweenNotifications = 5000, .alarmIndex = SYSTEMALARMS_ALARM_RECEIVER, .warnNotification = NOTIFY_SEQUENCE_ALM_RECEIVER, .criticalNotification = NOTIFY_SEQUENCE_ALM_RECEIVER, diff --git a/flight/modules/Notify/notify.c b/flight/modules/Notify/notify.c index ef6aee552..ed3f7ded2 100644 --- a/flight/modules/Notify/notify.c +++ b/flight/modules/Notify/notify.c @@ -106,7 +106,7 @@ void onTimerCb(__attribute__((unused)) UAVObjEvent *ev) SystemAlarmsAlarmGet(&alarms); for (uint8_t i = 0; i < alarmsMapSize; i++) { - uint8_t alarm = ((uint8_t *)&alarms)[alarmsMap[i].alarmIndex]; + uint8_t alarm = SystemAlarmsAlarmToArray(alarms)[alarmsMap[i].alarmIndex]; checkAlarm(alarm, &alarmStatus[i].lastAlarm, &alarmStatus[i].lastAlarmTime, @@ -121,16 +121,23 @@ void checkAlarm(uint8_t alarm, uint8_t *last_alarm, uint32_t *last_alm_time, uin { if (alarm > SYSTEMALARMS_ALARM_OK) { uint32_t current_time = PIOS_DELAY_GetuS(); - if (*last_alarm < alarm || *last_alm_time + timeBetweenNotifications * 1000 > current_time) { + if (*last_alarm < alarm || (*last_alm_time + timeBetweenNotifications * 1000) < current_time) { uint8_t sequence = (alarm == SYSTEMALARMS_ALARM_WARNING) ? warn_sequence : ((alarm == SYSTEMALARMS_ALARM_CRITICAL) ? critical_sequence : error_sequence); + bool updated = true; if (sequence != NOTIFY_SEQUENCE_NULL) { - PIOS_NOTIFICATION_Default_Ext_Led_Play( + updated = PIOS_NOTIFICATION_Default_Ext_Led_Play( ¬ifications[sequence], alarm == SYSTEMALARMS_ALARM_WARNING ? NOTIFY_PRIORITY_REGULAR : NOTIFY_PRIORITY_CRITICAL); } - *last_alarm = alarm; - *last_alm_time = current_time; + if (updated) { + *last_alarm = alarm; + *last_alm_time = current_time; + } + } + // workaround timer overflow + if (*last_alm_time > current_time) { + *last_alm_time = 0; } } else { *last_alarm = SYSTEMALARMS_ALARM_OK; diff --git a/flight/modules/OPLink/oplinkmod.c b/flight/modules/OPLink/oplinkmod.c index 770f70bb9..6727cdde3 100644 --- a/flight/modules/OPLink/oplinkmod.c +++ b/flight/modules/OPLink/oplinkmod.c @@ -112,6 +112,8 @@ static void systemTask(__attribute__((unused)) void *parameters) portTickType lastSysTime; uint16_t prev_tx_count = 0; uint16_t prev_rx_count = 0; + uint16_t prev_tx_seq = 0; + uint16_t prev_rx_seq = 0; bool first_time = true; while (!initTaskDone) { @@ -136,60 +138,60 @@ static void systemTask(__attribute__((unused)) void *parameters) // Main system loop while (1) { - // Flash the heartbeat LED -#if defined(PIOS_LED_HEARTBEAT) - PIOS_LED_Toggle(PIOS_LED_HEARTBEAT); -#endif /* PIOS_LED_HEARTBEAT */ - // Update the OPLinkStatus UAVO OPLinkStatusData oplinkStatus; OPLinkStatusGet(&oplinkStatus); // Get the other device stats. - PIOS_RFM2B_GetPairStats(pios_rfm22b_id, oplinkStatus.PairIDs, oplinkStatus.PairSignalStrengths, OPLINKSTATUS_PAIRIDS_NUMELEM); + PIOS_RFM22B_GetPairStats(pios_rfm22b_id, oplinkStatus.PairIDs, oplinkStatus.PairSignalStrengths, OPLINKSTATUS_PAIRIDS_NUMELEM); // Get the stats from the radio device struct rfm22b_stats radio_stats; PIOS_RFM22B_GetStats(pios_rfm22b_id, &radio_stats); + oplinkStatus.HeapRemaining = xPortGetFreeHeapSize(); if (pios_rfm22b_id) { // Update the status - oplinkStatus.HeapRemaining = xPortGetFreeHeapSize(); - oplinkStatus.DeviceID = PIOS_RFM22B_DeviceID(pios_rfm22b_id); - oplinkStatus.RxGood = radio_stats.rx_good; - oplinkStatus.RxCorrected = radio_stats.rx_corrected; - oplinkStatus.RxErrors = radio_stats.rx_error; - oplinkStatus.RxMissed = radio_stats.rx_missed; - oplinkStatus.RxFailure = radio_stats.rx_failure; - oplinkStatus.TxDropped = radio_stats.tx_dropped; - oplinkStatus.TxFailure = radio_stats.tx_failure; + oplinkStatus.DeviceID = PIOS_RFM22B_DeviceID(pios_rfm22b_id); + oplinkStatus.RxGood = radio_stats.rx_good; + oplinkStatus.RxCorrected = radio_stats.rx_corrected; + oplinkStatus.RxErrors = radio_stats.rx_error; + oplinkStatus.RxMissed = radio_stats.rx_missed; + oplinkStatus.RxFailure = radio_stats.rx_failure; + oplinkStatus.TxDropped = radio_stats.tx_dropped; + oplinkStatus.TxFailure = radio_stats.tx_failure; oplinkStatus.Resets = radio_stats.resets; oplinkStatus.Timeouts = radio_stats.timeouts; - oplinkStatus.RSSI = radio_stats.rssi; + oplinkStatus.RSSI = radio_stats.rssi; oplinkStatus.LinkQuality = radio_stats.link_quality; if (first_time) { first_time = false; } else { - uint16_t tx_count = radio_stats.tx_byte_count; - uint16_t rx_count = radio_stats.rx_byte_count; - uint16_t tx_bytes = (tx_count < prev_tx_count) ? (0xffff - prev_tx_count + tx_count) : (tx_count - prev_tx_count); - uint16_t rx_bytes = (rx_count < prev_rx_count) ? (0xffff - prev_rx_count + rx_count) : (rx_count - prev_rx_count); + uint16_t tx_count = radio_stats.tx_byte_count; + uint16_t rx_count = radio_stats.rx_byte_count; + uint16_t tx_packets = radio_stats.tx_seq - prev_tx_seq; + uint16_t rx_packets = radio_stats.rx_seq - prev_rx_seq; + uint16_t tx_bytes = (tx_count < prev_tx_count) ? (0xffff - prev_tx_count + tx_count) : (tx_count - prev_tx_count); + uint16_t rx_bytes = (rx_count < prev_rx_count) ? (0xffff - prev_rx_count + rx_count) : (rx_count - prev_rx_count); oplinkStatus.TXRate = (uint16_t)((float)(tx_bytes * 1000) / SYSTEM_UPDATE_PERIOD_MS); oplinkStatus.RXRate = (uint16_t)((float)(rx_bytes * 1000) / SYSTEM_UPDATE_PERIOD_MS); + oplinkStatus.TXPacketRate = (uint16_t)((float)(tx_packets * 1000) / SYSTEM_UPDATE_PERIOD_MS); + oplinkStatus.RXPacketRate = (uint16_t)((float)(rx_packets * 1000) / SYSTEM_UPDATE_PERIOD_MS); prev_tx_count = tx_count; prev_rx_count = rx_count; + prev_tx_seq = radio_stats.tx_seq; + prev_rx_seq = radio_stats.rx_seq; } oplinkStatus.TXSeq = radio_stats.tx_seq; oplinkStatus.RXSeq = radio_stats.rx_seq; oplinkStatus.LinkState = radio_stats.link_state; - } else { - oplinkStatus.LinkState = OPLINKSTATUS_LINKSTATE_DISABLED; } + // Turn on the link/heartbeat ID if we're connected, otherwise flash it. if (radio_stats.link_state == OPLINKSTATUS_LINKSTATE_CONNECTED) { LINK_LED_ON; } else { - LINK_LED_OFF; + LINK_LED_TOGGLE; } // Update the object diff --git a/flight/modules/PathFollower/fixedwingautotakeoffcontroller.cpp b/flight/modules/PathFollower/fixedwingautotakeoffcontroller.cpp new file mode 100644 index 000000000..656a5b631 --- /dev/null +++ b/flight/modules/PathFollower/fixedwingautotakeoffcontroller.cpp @@ -0,0 +1,280 @@ +/* + ****************************************************************************** + * + * @file FixedWingAutoTakeoffController.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2015. + * @brief Fixed wing fly controller implementation + * @see The GNU Public License (GPL) Version 3 + * + * @addtogroup LibrePilot LibrePilotModules Modules PathFollower Navigation + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +extern "C" { +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +} + +// C++ includes +#include "fixedwingautotakeoffcontroller.h" + +// Private constants + +// pointer to a singleton instance +FixedWingAutoTakeoffController *FixedWingAutoTakeoffController::p_inst = 0; + + +// Called when mode first engaged +void FixedWingAutoTakeoffController::Activate(void) +{ + if (!mActive) { + setState(FW_AUTOTAKEOFF_STATE_LAUNCH); + } + FixedWingFlyController::Activate(); +} + +/** + * fixed wing autopilot + * use fixed attitude heading towards destination waypoint + */ +void FixedWingAutoTakeoffController::UpdateAutoPilot() +{ + if (state < FW_AUTOTAKEOFF_STATE_SIZE) { + (this->*runFunctionTable[state])(); + } else { + setState(FW_AUTOTAKEOFF_STATE_LAUNCH); + } +} + +/** + * getAirspeed helper function + */ +float FixedWingAutoTakeoffController::getAirspeed(void) +{ + VelocityStateData v; + float yaw; + + VelocityStateGet(&v); + AttitudeStateYawGet(&yaw); + + // current ground speed projected in forward direction + float groundspeedProjection = v.North * cos_lookup_deg(yaw) + v.East * sin_lookup_deg(yaw); + + // note that airspeedStateBias is ( calibratedAirspeed - groundspeedProjection ) at the time of measurement, + // but thanks to accelerometers, groundspeedProjection reacts faster to changes in direction + // than airspeed and gps sensors alone + return groundspeedProjection + indicatedAirspeedStateBias; +} + + +/** + * setState - state transition including initialization + */ +void FixedWingAutoTakeoffController::setState(FixedWingAutoTakeoffControllerState_T setstate) +{ + if (state < FW_AUTOTAKEOFF_STATE_SIZE && setstate != state) { + state = setstate; + (this->*initFunctionTable[state])(); + } +} + +/** + * setAttitude - output function to steer plane + */ +void FixedWingAutoTakeoffController::setAttitude(bool unsafe) +{ + StabilizationDesiredData stabDesired; + + stabDesired.Roll = 0.0f; + stabDesired.Yaw = initYaw; + if (unsafe) { + stabDesired.Pitch = fixedWingSettings->LandingPitch; + stabDesired.Thrust = 0.0f; + } else { + stabDesired.Pitch = fixedWingSettings->TakeOffPitch; + stabDesired.Thrust = fixedWingSettings->ThrustLimit.Max; + } + stabDesired.StabilizationMode.Roll = STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE; + stabDesired.StabilizationMode.Pitch = STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE; + stabDesired.StabilizationMode.Yaw = STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE; + stabDesired.StabilizationMode.Thrust = STABILIZATIONDESIRED_STABILIZATIONMODE_MANUAL; + + StabilizationDesiredSet(&stabDesired); + if (unsafe) { + AlarmsSet(SYSTEMALARMS_ALARM_GUIDANCE, SYSTEMALARMS_ALARM_WARNING); + pathStatus->Status = PATHSTATUS_STATUS_CRITICAL; + } else { + AlarmsSet(SYSTEMALARMS_ALARM_GUIDANCE, SYSTEMALARMS_ALARM_OK); + } + + // calculate fractional progress based on altitude + float downPos; + PositionStateDownGet(&downPos); + if (fabsf(pathDesired->End.Down - pathDesired->Start.Down) < 1e-3f) { + pathStatus->fractional_progress = 1.0f; + pathStatus->error = 0.0f; + } else { + pathStatus->fractional_progress = (downPos - pathDesired->Start.Down) / (pathDesired->End.Down - pathDesired->Start.Down); + } + pathStatus->error = fabsf(downPos - pathDesired->End.Down); + + PathStatusSet(pathStatus); +} + +/** + * check if situation is unsafe + */ +bool FixedWingAutoTakeoffController::isUnsafe(void) +{ + bool abort = false; + float speed = getAirspeed(); + + if (speed > maxVelocity) { + maxVelocity = speed; + } + // too much total deceleration (crash, insufficient climbing power, ...) + if (speed < maxVelocity - fixedWingSettings->SafetyCutoffLimits.MaxDecelerationDeltaMPS) { + abort = true; + } + AttitudeStateData attitude; + AttitudeStateGet(&attitude); + // too much bank angle + if (fabsf(attitude.Roll) > fixedWingSettings->SafetyCutoffLimits.RollDeg) { + abort = true; + } + if (fabsf(attitude.Pitch - fixedWingSettings->TakeOffPitch) > fixedWingSettings->SafetyCutoffLimits.PitchDeg) { + abort = true; + } + float deltayaw = attitude.Yaw - initYaw; + if (deltayaw > 180.0f) { + deltayaw -= 360.0f; + } + if (deltayaw < -180.0f) { + deltayaw += 360.0f; + } + if (fabsf(deltayaw) > fixedWingSettings->SafetyCutoffLimits.YawDeg) { + abort = true; + } + return abort; +} + + +// init inactive does nothing +void FixedWingAutoTakeoffController::init_inactive(void) {} + +// init launch resets private variables to start values +void FixedWingAutoTakeoffController::init_launch(void) +{ + // find out vector direction of *runway* (if any) + // and align, otherwise just stay straight ahead + pathStatus->path_direction_north = 0.0f; + pathStatus->path_direction_east = 0.0f; + pathStatus->path_direction_down = 0.0f; + pathStatus->correction_direction_north = 0.0f; + pathStatus->correction_direction_east = 0.0f; + pathStatus->correction_direction_down = 0.0f; + if (fabsf(pathDesired->Start.North - pathDesired->End.North) < 1e-3f && + fabsf(pathDesired->Start.East - pathDesired->End.East) < 1e-3f) { + AttitudeStateYawGet(&initYaw); + } else { + initYaw = RAD2DEG(atan2f(pathDesired->End.East - pathDesired->Start.East, pathDesired->End.North - pathDesired->Start.North)); + if (initYaw < -180.0f) { + initYaw += 360.0f; + } + if (initYaw > 180.0f) { + initYaw -= 360.0f; + } + } + + maxVelocity = getAirspeed(); +} + +// init climb does nothing +void FixedWingAutoTakeoffController::init_climb(void) {} + +// init hold does nothing +void FixedWingAutoTakeoffController::init_hold(void) {} + +// init abort does nothing +void FixedWingAutoTakeoffController::init_abort(void) {} + + +// run inactive does nothing +// no state transitions +void FixedWingAutoTakeoffController::run_inactive(void) {} + +// run launch tries to takeoff - indicates safe situation with engine power (for hand launch) +// run launch checks for: +// 1. min velocity for climb +void FixedWingAutoTakeoffController::run_launch(void) +{ + // state transition + if (maxVelocity > fixedWingSettings->SafetyCutoffLimits.MaxDecelerationDeltaMPS) { + setState(FW_AUTOTAKEOFF_STATE_CLIMB); + } + + setAttitude(isUnsafe()); +} + +// run climb climbs with max power +// run climb checks for: +// 1. min altitude for hold +// 2. critical situation for abort (different than launch) +void FixedWingAutoTakeoffController::run_climb(void) +{ + bool unsafe = isUnsafe(); + float downPos; + + PositionStateDownGet(&downPos); + + if (unsafe) { + // state transition 2 + setState(FW_AUTOTAKEOFF_STATE_ABORT); + } else if (downPos < pathDesired->End.Down) { + // state transition 1 + setState(FW_AUTOTAKEOFF_STATE_HOLD); + } + + setAttitude(unsafe); +} + +// run hold loiters like in position hold +// no state transitions (FlyController does exception handling) +void FixedWingAutoTakeoffController::run_hold(void) +{ + // parent controller will do perfect position hold in autotakeoff mode + FixedWingFlyController::UpdateAutoPilot(); +} + +// run abort descends with wings level, engine off (like land) +// no state transitions +void FixedWingAutoTakeoffController::run_abort(void) +{ + setAttitude(true); +} diff --git a/flight/modules/PathFollower/fixedwingflycontroller.cpp b/flight/modules/PathFollower/fixedwingflycontroller.cpp index ed47d0069..1dcbd08d9 100644 --- a/flight/modules/PathFollower/fixedwingflycontroller.cpp +++ b/flight/modules/PathFollower/fixedwingflycontroller.cpp @@ -2,10 +2,13 @@ ****************************************************************************** * * @file FixedWingFlyController.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2015. * @brief Fixed wing fly controller implementation * @see The GNU Public License (GPL) Version 3 * + * @addtogroup LibrePilot LibrePilotModules Modules PathFollower Navigation + * *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify @@ -26,23 +29,13 @@ extern "C" { #include -#include - -#include #include -#include #include #include #include -#include "plans.h" -#include - -#include -#include #include #include #include -#include #include #include #include @@ -50,14 +43,7 @@ extern "C" { #include #include #include -#include -#include -#include #include -#include -#include -#include -#include } // C++ includes @@ -80,6 +66,7 @@ void FixedWingFlyController::Activate(void) SettingsUpdated(); resetGlobals(); mMode = pathDesired->Mode; + lastAirspeedUpdate = 0; } } @@ -244,9 +231,11 @@ void FixedWingFlyController::updatePathVelocity(float kFF, bool limited) */ uint8_t FixedWingFlyController::updateFixedDesiredAttitude() { - uint8_t result = 1; + uint8_t result = 1; + bool cutThrust = false; + bool hasAirspeed = true; - const float dT = fixedWingSettings->UpdatePeriod / 1000.0f; + const float dT = fixedWingSettings->UpdatePeriod / 1000.0f; VelocityDesiredData velocityDesired; VelocityStateData velocityState; @@ -259,7 +248,7 @@ uint8_t FixedWingFlyController::updateFixedDesiredAttitude() float groundspeedProjection; float indicatedAirspeedState; float indicatedAirspeedDesired; - float airspeedError; + float airspeedError = 0.0f; float pitchCommand; @@ -282,56 +271,99 @@ uint8_t FixedWingFlyController::updateFixedDesiredAttitude() AirspeedStateGet(&airspeedState); SystemSettingsGet(&systemSettings); + /** * Compute speed error and course */ - // missing sensors for airspeed-direction we have to assume within - // reasonable error that measured airspeed is actually the airspeed - // component in forward pointing direction - // airspeedVector is normalized - airspeedVector[0] = cos_lookup_deg(attitudeState.Yaw); - airspeedVector[1] = sin_lookup_deg(attitudeState.Yaw); - // current ground speed projected in forward direction - groundspeedProjection = velocityState.North * airspeedVector[0] + velocityState.East * airspeedVector[1]; - - // note that airspeedStateBias is ( calibratedAirspeed - groundspeedProjection ) at the time of measurement, - // but thanks to accelerometers, groundspeedProjection reacts faster to changes in direction - // than airspeed and gps sensors alone - indicatedAirspeedState = groundspeedProjection + indicatedAirspeedStateBias; - - // fluidMovement is a vector describing the aproximate movement vector of - // the surrounding fluid in 2d space (aka wind vector) - fluidMovement[0] = velocityState.North - (indicatedAirspeedState * airspeedVector[0]); - fluidMovement[1] = velocityState.East - (indicatedAirspeedState * airspeedVector[1]); - - // calculate the movement vector we need to fly to reach velocityDesired - - // taking fluidMovement into account - courseComponent[0] = velocityDesired.North - fluidMovement[0]; - courseComponent[1] = velocityDesired.East - fluidMovement[1]; - - indicatedAirspeedDesired = boundf(sqrtf(courseComponent[0] * courseComponent[0] + courseComponent[1] * courseComponent[1]), - fixedWingSettings->HorizontalVelMin, - fixedWingSettings->HorizontalVelMax); - - // if we could fly at arbitrary speeds, we'd just have to move towards the - // courseComponent vector as previously calculated and we'd be fine - // unfortunately however we are bound by min and max air speed limits, so - // we need to recalculate the correct course to meet at least the - // velocityDesired vector direction at our current speed - // this overwrites courseComponent - bool valid = correctCourse(courseComponent, (float *)&velocityDesired.North, fluidMovement, indicatedAirspeedDesired); - - // Error condition: wind speed too high, we can't go where we want anymore - fixedWingPathFollowerStatus.Errors.Wind = 0; - if ((!valid) && - fixedWingSettings->Safetymargins.Wind > 0.5f) { // alarm switched on - fixedWingPathFollowerStatus.Errors.Wind = 1; + // check for airspeed sensor + fixedWingPathFollowerStatus.Errors.AirspeedSensor = 0; + if (fixedWingSettings->UseAirspeedSensor == FIXEDWINGPATHFOLLOWERSETTINGS_USEAIRSPEEDSENSOR_FALSE) { + // fallback algo triggered voluntarily + hasAirspeed = false; + fixedWingPathFollowerStatus.Errors.AirspeedSensor = 1; + } else if (PIOS_DELAY_GetuSSince(lastAirspeedUpdate) > 1000000) { + // no airspeed update in one second, assume airspeed sensor failure + hasAirspeed = false; result = 0; + fixedWingPathFollowerStatus.Errors.AirspeedSensor = 1; } - // Airspeed error - airspeedError = indicatedAirspeedDesired - indicatedAirspeedState; + + if (hasAirspeed) { + // missing sensors for airspeed-direction we have to assume within + // reasonable error that measured airspeed is actually the airspeed + // component in forward pointing direction + // airspeedVector is normalized + airspeedVector[0] = cos_lookup_deg(attitudeState.Yaw); + airspeedVector[1] = sin_lookup_deg(attitudeState.Yaw); + + // current ground speed projected in forward direction + groundspeedProjection = velocityState.North * airspeedVector[0] + velocityState.East * airspeedVector[1]; + + // note that airspeedStateBias is ( calibratedAirspeed - groundspeedProjection ) at the time of measurement, + // but thanks to accelerometers, groundspeedProjection reacts faster to changes in direction + // than airspeed and gps sensors alone + indicatedAirspeedState = groundspeedProjection + indicatedAirspeedStateBias; + + // fluidMovement is a vector describing the aproximate movement vector of + // the surrounding fluid in 2d space (aka wind vector) + fluidMovement[0] = velocityState.North - (indicatedAirspeedState * airspeedVector[0]); + fluidMovement[1] = velocityState.East - (indicatedAirspeedState * airspeedVector[1]); + + // calculate the movement vector we need to fly to reach velocityDesired - + // taking fluidMovement into account + courseComponent[0] = velocityDesired.North - fluidMovement[0]; + courseComponent[1] = velocityDesired.East - fluidMovement[1]; + + indicatedAirspeedDesired = boundf(sqrtf(courseComponent[0] * courseComponent[0] + courseComponent[1] * courseComponent[1]), + fixedWingSettings->HorizontalVelMin, + fixedWingSettings->HorizontalVelMax); + + // if we could fly at arbitrary speeds, we'd just have to move towards the + // courseComponent vector as previously calculated and we'd be fine + // unfortunately however we are bound by min and max air speed limits, so + // we need to recalculate the correct course to meet at least the + // velocityDesired vector direction at our current speed + // this overwrites courseComponent + bool valid = correctCourse(courseComponent, (float *)&velocityDesired.North, fluidMovement, indicatedAirspeedDesired); + + // Error condition: wind speed too high, we can't go where we want anymore + fixedWingPathFollowerStatus.Errors.Wind = 0; + if ((!valid) && + fixedWingSettings->Safetymargins.Wind > 0.5f) { // alarm switched on + fixedWingPathFollowerStatus.Errors.Wind = 1; + result = 0; + } + + // Airspeed error + airspeedError = indicatedAirspeedDesired - indicatedAirspeedState; + + // Error condition: plane too slow or too fast + fixedWingPathFollowerStatus.Errors.Highspeed = 0; + fixedWingPathFollowerStatus.Errors.Lowspeed = 0; + if (indicatedAirspeedState > systemSettings.AirSpeedMax * fixedWingSettings->Safetymargins.Overspeed) { + fixedWingPathFollowerStatus.Errors.Overspeed = 1; + result = 0; + } + if (indicatedAirspeedState > fixedWingSettings->HorizontalVelMax * fixedWingSettings->Safetymargins.Highspeed) { + fixedWingPathFollowerStatus.Errors.Highspeed = 1; + result = 0; + cutThrust = true; + } + if (indicatedAirspeedState < fixedWingSettings->HorizontalVelMin * fixedWingSettings->Safetymargins.Lowspeed) { + fixedWingPathFollowerStatus.Errors.Lowspeed = 1; + result = 0; + } + if (indicatedAirspeedState < systemSettings.AirSpeedMin * fixedWingSettings->Safetymargins.Stallspeed) { + fixedWingPathFollowerStatus.Errors.Stallspeed = 1; + result = 0; + } + if (indicatedAirspeedState < fixedWingSettings->HorizontalVelMin * fixedWingSettings->Safetymargins.Lowspeed - fixedWingSettings->SafetyCutoffLimits.MaxDecelerationDeltaMPS) { + cutThrust = true; + result = 0; + } + } // Vertical speed error descentspeedDesired = boundf( @@ -340,36 +372,19 @@ uint8_t FixedWingFlyController::updateFixedDesiredAttitude() fixedWingSettings->VerticalVelMax); descentspeedError = descentspeedDesired - velocityState.Down; - // Error condition: plane too slow or too fast - fixedWingPathFollowerStatus.Errors.Highspeed = 0; - fixedWingPathFollowerStatus.Errors.Lowspeed = 0; - if (indicatedAirspeedState > systemSettings.AirSpeedMax * fixedWingSettings->Safetymargins.Overspeed) { - fixedWingPathFollowerStatus.Errors.Overspeed = 1; - result = 0; - } - if (indicatedAirspeedState > fixedWingSettings->HorizontalVelMax * fixedWingSettings->Safetymargins.Highspeed) { - fixedWingPathFollowerStatus.Errors.Highspeed = 1; - result = 0; - } - if (indicatedAirspeedState < fixedWingSettings->HorizontalVelMin * fixedWingSettings->Safetymargins.Lowspeed) { - fixedWingPathFollowerStatus.Errors.Lowspeed = 1; - result = 0; - } - if (indicatedAirspeedState < systemSettings.AirSpeedMin * fixedWingSettings->Safetymargins.Stallspeed) { - fixedWingPathFollowerStatus.Errors.Stallspeed = 1; - result = 0; - } - /** * Compute desired thrust command */ // Compute the cross feed from vertical speed to pitch, with saturation - float speedErrorToPowerCommandComponent = boundf( - (airspeedError / fixedWingSettings->HorizontalVelMin) * fixedWingSettings->AirspeedToPowerCrossFeed.Kp, - -fixedWingSettings->AirspeedToPowerCrossFeed.Max, - fixedWingSettings->AirspeedToPowerCrossFeed.Max - ); + float speedErrorToPowerCommandComponent = 0.0f; + if (hasAirspeed) { + speedErrorToPowerCommandComponent = boundf( + (airspeedError / fixedWingSettings->HorizontalVelMin) * fixedWingSettings->AirspeedToPowerCrossFeed.Kp, + -fixedWingSettings->AirspeedToPowerCrossFeed.Max, + fixedWingSettings->AirspeedToPowerCrossFeed.Max + ); + } // Compute final thrust response powerCommand = pid_apply(&PIDpower, -descentspeedError, dT) + @@ -390,57 +405,84 @@ uint8_t FixedWingFlyController::updateFixedDesiredAttitude() if (fixedWingSettings->ThrustLimit.Neutral + powerCommand >= fixedWingSettings->ThrustLimit.Max && // thrust at maximum velocityState.Down > 0.0f && // we ARE going down descentspeedDesired < 0.0f && // we WANT to go up - airspeedError > 0.0f && // we are too slow already - fixedWingSettings->Safetymargins.Lowpower > 0.5f) { // alarm switched on + airspeedError > 0.0f) { // we are too slow already fixedWingPathFollowerStatus.Errors.Lowpower = 1; - result = 0; + + if (fixedWingSettings->Safetymargins.Lowpower > 0.5f) { // alarm switched on + result = 0; + } } // Error condition: plane keeps climbing despite minimum thrust (opposite of above) fixedWingPathFollowerStatus.Errors.Highpower = 0; if (fixedWingSettings->ThrustLimit.Neutral + powerCommand <= fixedWingSettings->ThrustLimit.Min && // thrust at minimum velocityState.Down < 0.0f && // we ARE going up descentspeedDesired > 0.0f && // we WANT to go down - airspeedError < 0.0f && // we are too fast already - fixedWingSettings->Safetymargins.Highpower > 0.5f) { // alarm switched on + airspeedError < 0.0f) { // we are too fast already + // this alarm is often switched off because of false positives, however we still want to cut throttle if it happens + cutThrust = true; fixedWingPathFollowerStatus.Errors.Highpower = 1; - result = 0; + + if (fixedWingSettings->Safetymargins.Highpower > 0.5f) { // alarm switched on + result = 0; + } } /** * Compute desired pitch command */ - // Compute the cross feed from vertical speed to pitch, with saturation - float verticalSpeedToPitchCommandComponent = boundf(-descentspeedError * fixedWingSettings->VerticalToPitchCrossFeed.Kp, - -fixedWingSettings->VerticalToPitchCrossFeed.Max, - fixedWingSettings->VerticalToPitchCrossFeed.Max - ); + if (hasAirspeed) { + // Compute the cross feed from vertical speed to pitch, with saturation + float verticalSpeedToPitchCommandComponent = boundf(-descentspeedError * fixedWingSettings->VerticalToPitchCrossFeed.Kp, + -fixedWingSettings->VerticalToPitchCrossFeed.Max, + fixedWingSettings->VerticalToPitchCrossFeed.Max + ); - // Compute the pitch command as err*Kp + errInt*Ki + X_feed. - pitchCommand = -pid_apply(&PIDspeed, airspeedError, dT) + verticalSpeedToPitchCommandComponent; + // Compute the pitch command as err*Kp + errInt*Ki + X_feed. + pitchCommand = -pid_apply(&PIDspeed, airspeedError, dT) + verticalSpeedToPitchCommandComponent; - fixedWingPathFollowerStatus.Error.Speed = airspeedError; - fixedWingPathFollowerStatus.ErrorInt.Speed = PIDspeed.iAccumulator; - fixedWingPathFollowerStatus.Command.Speed = pitchCommand; + fixedWingPathFollowerStatus.Error.Speed = airspeedError; + fixedWingPathFollowerStatus.ErrorInt.Speed = PIDspeed.iAccumulator; + fixedWingPathFollowerStatus.Command.Speed = pitchCommand; - stabDesired.Pitch = boundf(fixedWingSettings->PitchLimit.Neutral + pitchCommand, - fixedWingSettings->PitchLimit.Min, - fixedWingSettings->PitchLimit.Max); + stabDesired.Pitch = boundf(fixedWingSettings->PitchLimit.Neutral + pitchCommand, + fixedWingSettings->PitchLimit.Min, + fixedWingSettings->PitchLimit.Max); - // Error condition: high speed dive - fixedWingPathFollowerStatus.Errors.Pitchcontrol = 0; - if (fixedWingSettings->PitchLimit.Neutral + pitchCommand >= fixedWingSettings->PitchLimit.Max && // pitch demand is full up - velocityState.Down > 0.0f && // we ARE going down - descentspeedDesired < 0.0f && // we WANT to go up - airspeedError < 0.0f && // we are too fast already - fixedWingSettings->Safetymargins.Pitchcontrol > 0.5f) { // alarm switched on + // Error condition: high speed dive + fixedWingPathFollowerStatus.Errors.Pitchcontrol = 0; + if (fixedWingSettings->PitchLimit.Neutral + pitchCommand >= fixedWingSettings->PitchLimit.Max && // pitch demand is full up + velocityState.Down > 0.0f && // we ARE going down + descentspeedDesired < 0.0f && // we WANT to go up + airspeedError < 0.0f && // we are too fast already + fixedWingSettings->Safetymargins.Pitchcontrol > 0.5f) { // alarm switched on + fixedWingPathFollowerStatus.Errors.Pitchcontrol = 1; + result = 0; + cutThrust = true; + } + } else { + // no airspeed sensor means we fly with constant pitch, like for landing pathfollower + stabDesired.Pitch = fixedWingSettings->LandingPitch; + } + + // Error condition: pitch way out of wack + if (fixedWingSettings->Safetymargins.Pitchcontrol > 0.5f && + (attitudeState.Pitch < fixedWingSettings->PitchLimit.Min - fixedWingSettings->SafetyCutoffLimits.PitchDeg || + attitudeState.Pitch > fixedWingSettings->PitchLimit.Max + fixedWingSettings->SafetyCutoffLimits.PitchDeg)) { fixedWingPathFollowerStatus.Errors.Pitchcontrol = 1; result = 0; + cutThrust = true; } + /** * Compute desired roll command */ - courseError = RAD2DEG(atan2f(courseComponent[1], courseComponent[0])) - attitudeState.Yaw; + if (hasAirspeed) { + courseError = RAD2DEG(atan2f(courseComponent[1], courseComponent[0])) - attitudeState.Yaw; + } else { + // fallback based on effective movement direction when in fallback mode, hope that airspeed > wind velocity, or we will never get home + courseError = RAD2DEG(atan2f(velocityDesired.East, velocityDesired.North)) - RAD2DEG(atan2f(velocityState.East, velocityState.North)); + } if (courseError < -180.0f) { courseError += 360.0f; @@ -473,7 +515,15 @@ uint8_t FixedWingFlyController::updateFixedDesiredAttitude() fixedWingSettings->RollLimit.Min, fixedWingSettings->RollLimit.Max); - // TODO: find a check to determine loss of directional control. Likely needs some check of derivative + // Error condition: roll way out of wack + fixedWingPathFollowerStatus.Errors.Rollcontrol = 0; + if (fixedWingSettings->Safetymargins.Rollcontrol > 0.5f && + (attitudeState.Roll < fixedWingSettings->RollLimit.Min - fixedWingSettings->SafetyCutoffLimits.RollDeg || + attitudeState.Roll > fixedWingSettings->RollLimit.Max + fixedWingSettings->SafetyCutoffLimits.RollDeg)) { + fixedWingPathFollowerStatus.Errors.Rollcontrol = 1; + result = 0; + cutThrust = true; + } /** @@ -482,6 +532,10 @@ uint8_t FixedWingFlyController::updateFixedDesiredAttitude() // TODO implement raw control mode for yaw and base on Accels.Y stabDesired.Yaw = 0.0f; + // safety cutoff condition + if (cutThrust) { + stabDesired.Thrust = 0.0f; + } stabDesired.StabilizationMode.Roll = STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE; stabDesired.StabilizationMode.Pitch = STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE; @@ -615,4 +669,6 @@ void FixedWingFlyController::AirspeedStateUpdatedCb(__attribute__((unused)) UAVO // changes to groundspeed to offset the airspeed by the same measurement. // This has a side effect that in the absence of any airspeed updates, the // pathfollower will fly using groundspeed. + + lastAirspeedUpdate = PIOS_DELAY_GetuS(); } diff --git a/flight/modules/PathFollower/fixedwinglandcontroller.cpp b/flight/modules/PathFollower/fixedwinglandcontroller.cpp new file mode 100644 index 000000000..c4b427c67 --- /dev/null +++ b/flight/modules/PathFollower/fixedwinglandcontroller.cpp @@ -0,0 +1,154 @@ +/* + ****************************************************************************** + * + * @file FixedWingLandController.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2015. + * @brief Fixed wing fly controller implementation + * @see The GNU Public License (GPL) Version 3 + * + * @addtogroup LibrePilot LibrePilotModules Modules PathFollower Navigation + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +extern "C" { +#include + +#include +#include +#include +#include +#include +} + +// C++ includes +#include "fixedwinglandcontroller.h" + +// Private constants + +// pointer to a singleton instance +FixedWingLandController *FixedWingLandController::p_inst = 0; + +FixedWingLandController::FixedWingLandController() + : fixedWingSettings(NULL), mActive(false), mMode(0) +{} + +// Called when mode first engaged +void FixedWingLandController::Activate(void) +{ + if (!mActive) { + mActive = true; + SettingsUpdated(); + resetGlobals(); + mMode = pathDesired->Mode; + } +} + +uint8_t FixedWingLandController::IsActive(void) +{ + return mActive; +} + +uint8_t FixedWingLandController::Mode(void) +{ + return mMode; +} + +// Objective updated in pathdesired +void FixedWingLandController::ObjectiveUpdated(void) +{} + +void FixedWingLandController::Deactivate(void) +{ + if (mActive) { + mActive = false; + resetGlobals(); + } +} + + +void FixedWingLandController::SettingsUpdated(void) +{} + +/** + * Initialise the module, called on startup + * \returns 0 on success or -1 if initialisation failed + */ +int32_t FixedWingLandController::Initialize(FixedWingPathFollowerSettingsData *ptr_fixedWingSettings) +{ + PIOS_Assert(ptr_fixedWingSettings); + + fixedWingSettings = ptr_fixedWingSettings; + + resetGlobals(); + + return 0; +} + +/** + * reset globals, (integrals, accumulated errors and timers) + */ +void FixedWingLandController::resetGlobals() +{ + pathStatus->path_time = 0.0f; + pathStatus->path_direction_north = 0.0f; + pathStatus->path_direction_east = 0.0f; + pathStatus->path_direction_down = 0.0f; + pathStatus->correction_direction_north = 0.0f; + pathStatus->correction_direction_east = 0.0f; + pathStatus->correction_direction_down = 0.0f; + pathStatus->error = 0.0f; + pathStatus->fractional_progress = 0.0f; +} + +/** + * fixed wing autopilot + * use fixed attitude heading towards destination waypoint + */ +void FixedWingLandController::UpdateAutoPilot() +{ + StabilizationDesiredData stabDesired; + + stabDesired.Roll = 0.0f; + stabDesired.Pitch = fixedWingSettings->LandingPitch; + stabDesired.Thrust = 0.0f; + stabDesired.StabilizationMode.Roll = STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE; + stabDesired.StabilizationMode.Pitch = STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE; + stabDesired.StabilizationMode.Thrust = STABILIZATIONDESIRED_STABILIZATIONMODE_MANUAL; + + // find out vector direction of *runway* (if any) + // and align, otherwise just stay straight ahead + if (fabsf(pathDesired->Start.North - pathDesired->End.North) < 1e-3f && + fabsf(pathDesired->Start.East - pathDesired->End.East) < 1e-3f) { + stabDesired.Yaw = 0.0f; + stabDesired.StabilizationMode.Yaw = STABILIZATIONDESIRED_STABILIZATIONMODE_RATE; + } else { + stabDesired.Yaw = RAD2DEG(atan2f(pathDesired->End.East - pathDesired->Start.East, pathDesired->End.North - pathDesired->Start.North)); + if (stabDesired.Yaw < -180.0f) { + stabDesired.Yaw += 360.0f; + } + if (stabDesired.Yaw > 180.0f) { + stabDesired.Yaw -= 360.0f; + } + stabDesired.StabilizationMode.Yaw = STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE; + } + StabilizationDesiredSet(&stabDesired); + AlarmsSet(SYSTEMALARMS_ALARM_GUIDANCE, SYSTEMALARMS_ALARM_OK); + + PathStatusSet(pathStatus); +} diff --git a/flight/modules/PathFollower/inc/fixedwingautotakeoffcontroller.h b/flight/modules/PathFollower/inc/fixedwingautotakeoffcontroller.h new file mode 100644 index 000000000..6930bd7db --- /dev/null +++ b/flight/modules/PathFollower/inc/fixedwingautotakeoffcontroller.h @@ -0,0 +1,98 @@ +/** + ****************************************************************************** + * @addtogroup LibrePilotModules LibrePilot Modules + * @{ + * @addtogroup FixedWing CONTROL interface class + * @brief CONTROL interface class for pathfollower fixed wing fly controller + * @{ + * + * @file fixedwingautotakeoffcontroller.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2015. + * @brief Executes CONTROL for fixed wing fly objectives + * + * @see The GNU Public License (GPL) Version 3 + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef FIXEDWINGAUTOTAKEOFFCONTROLLER_H +#define FIXEDWINGAUTOTAKEOFFCONTROLLER_H +#include "fixedwingflycontroller.h" + +// AutoTakeoff state machine +typedef enum { + FW_AUTOTAKEOFF_STATE_INACTIVE = 0, + FW_AUTOTAKEOFF_STATE_LAUNCH, + FW_AUTOTAKEOFF_STATE_CLIMB, + FW_AUTOTAKEOFF_STATE_HOLD, + FW_AUTOTAKEOFF_STATE_ABORT, + FW_AUTOTAKEOFF_STATE_SIZE +} FixedWingAutoTakeoffControllerState_T; + +class FixedWingAutoTakeoffController : public FixedWingFlyController { +protected: + static FixedWingAutoTakeoffController *p_inst; + +public: + static FixedWingFlyController *instance() + { + if (!p_inst) { + p_inst = new FixedWingAutoTakeoffController(); + } + return p_inst; + } + void Activate(void); + void UpdateAutoPilot(void); + +private: + // variables + FixedWingAutoTakeoffControllerState_T state; + float initYaw; + float maxVelocity; + + // functions + void setState(FixedWingAutoTakeoffControllerState_T setstate); + void setAttitude(bool unsafe); + float getAirspeed(void); + bool isUnsafe(void); + void run_inactive(void); + void run_launch(void); + void run_climb(void); + void run_hold(void); + void run_abort(void); + void init_inactive(void); + void init_launch(void); + void init_climb(void); + void init_hold(void); + void init_abort(void); + void(FixedWingAutoTakeoffController::*const runFunctionTable[FW_AUTOTAKEOFF_STATE_SIZE]) (void) = { + &FixedWingAutoTakeoffController::run_inactive, + &FixedWingAutoTakeoffController::run_launch, + &FixedWingAutoTakeoffController::run_climb, + &FixedWingAutoTakeoffController::run_hold, + &FixedWingAutoTakeoffController::run_abort + }; + void(FixedWingAutoTakeoffController::*const initFunctionTable[FW_AUTOTAKEOFF_STATE_SIZE]) (void) = { + &FixedWingAutoTakeoffController::init_inactive, + &FixedWingAutoTakeoffController::init_launch, + &FixedWingAutoTakeoffController::init_climb, + &FixedWingAutoTakeoffController::init_hold, + &FixedWingAutoTakeoffController::init_abort + }; +}; + +#endif // FIXEDWINGAUTOTAKEOFFCONTROLLER_H diff --git a/flight/modules/PathFollower/inc/fixedwingflycontroller.h b/flight/modules/PathFollower/inc/fixedwingflycontroller.h index 19dcf4003..14c5e490c 100644 --- a/flight/modules/PathFollower/inc/fixedwingflycontroller.h +++ b/flight/modules/PathFollower/inc/fixedwingflycontroller.h @@ -1,13 +1,14 @@ /** ****************************************************************************** - * @addtogroup OpenPilotModules OpenPilot Modules + * @addtogroup LibrePilotModules LibrePilot Modules * @{ * @addtogroup FixedWing CONTROL interface class * @brief CONTROL interface class for pathfollower fixed wing fly controller * @{ * - * @file FixedWingCONTROL.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2015. + * @file fixedwingflycontroller.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2015. * @brief Executes CONTROL for fixed wing fly objectives * * @see The GNU Public License (GPL) Version 3 @@ -33,7 +34,7 @@ #include "pathfollowercontrol.h" class FixedWingFlyController : public PathFollowerControl { -private: +protected: static FixedWingFlyController *p_inst; FixedWingFlyController(); @@ -57,24 +58,26 @@ public: uint8_t Mode(void); void AirspeedStateUpdatedCb(__attribute__((unused)) UAVObjEvent * ev); +protected: + FixedWingPathFollowerSettingsData *fixedWingSettings; + + uint8_t mActive; + uint8_t mMode; + // correct speed by measured airspeed + float indicatedAirspeedStateBias; private: void resetGlobals(); uint8_t updateAutoPilotFixedWing(); void updatePathVelocity(float kFF, bool limited); uint8_t updateFixedDesiredAttitude(); bool correctCourse(float *C, float *V, float *F, float s); - - FixedWingPathFollowerSettingsData *fixedWingSettings; - uint8_t mActive; - uint8_t mMode; + int32_t lastAirspeedUpdate; struct pid PIDposH[2]; struct pid PIDposV; struct pid PIDcourse; struct pid PIDspeed; struct pid PIDpower; - // correct speed by measured airspeed - float indicatedAirspeedStateBias; }; #endif // FIXEDWINGFLYCONTROLLER_H diff --git a/flight/modules/PathFollower/inc/fixedwinglandcontroller.h b/flight/modules/PathFollower/inc/fixedwinglandcontroller.h new file mode 100644 index 000000000..5e0dab889 --- /dev/null +++ b/flight/modules/PathFollower/inc/fixedwinglandcontroller.h @@ -0,0 +1,67 @@ +/** + ****************************************************************************** + * @addtogroup LibrePilotModules LibrePilot Modules + * @{ + * @addtogroup FixedWing CONTROL interface class + * @brief CONTROL interface class for pathfollower fixed wing fly controller + * @{ + * + * @file fixedwinglandcontroller.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2015. + * @brief Executes CONTROL for fixed wing fly objectives + * + * @see The GNU Public License (GPL) Version 3 + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef FIXEDWINGLANDCONTROLLER_H +#define FIXEDWINGLANDCONTROLLER_H +#include "pathfollowercontrol.h" + +class FixedWingLandController : public PathFollowerControl { +private: + static FixedWingLandController *p_inst; + FixedWingLandController(); + + +public: + static FixedWingLandController *instance() + { + if (!p_inst) { + p_inst = new FixedWingLandController(); + } + return p_inst; + } + + int32_t Initialize(FixedWingPathFollowerSettingsData *fixedWingSettings); + void Activate(void); + void Deactivate(void); + void SettingsUpdated(void); + void UpdateAutoPilot(void); + void ObjectiveUpdated(void); + uint8_t IsActive(void); + uint8_t Mode(void); + +private: + void resetGlobals(); + FixedWingPathFollowerSettingsData *fixedWingSettings; + uint8_t mActive; + uint8_t mMode; +}; + +#endif // FIXEDWINGLANDCONTROLLER_H diff --git a/flight/modules/PathFollower/inc/vtolautotakeoffcontroller.h b/flight/modules/PathFollower/inc/vtolautotakeoffcontroller.h index 4b52bfa9c..a7617d09c 100644 --- a/flight/modules/PathFollower/inc/vtolautotakeoffcontroller.h +++ b/flight/modules/PathFollower/inc/vtolautotakeoffcontroller.h @@ -1,13 +1,14 @@ /** ****************************************************************************** - * @addtogroup OpenPilotModules OpenPilot Modules + * @addtogroup LibrePilotModules LibrePilot Modules * @{ * @addtogroup PathFollower CONTROL interface class * @brief vtol land controller class * @{ * * @file vtollandcontroller.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2015. * @brief Executes CONTROL for landing sequence * * @see The GNU Public License (GPL) Version 3 @@ -70,6 +71,8 @@ private: PIDControlDown controlDown; PIDControlNE controlNE; uint8_t mActive; + uint8_t mOverride; + StatusVtolAutoTakeoffControlStateOptions autotakeoffState; }; #endif // VTOLAUTOTAKEOFFCONTROLLER_H diff --git a/flight/modules/PathFollower/inc/vtolautotakeofffsm.h b/flight/modules/PathFollower/inc/vtolautotakeofffsm.h index 6c912baec..3f8badb70 100644 --- a/flight/modules/PathFollower/inc/vtolautotakeofffsm.h +++ b/flight/modules/PathFollower/inc/vtolautotakeofffsm.h @@ -1,13 +1,14 @@ /** ****************************************************************************** - * @addtogroup OpenPilotModules OpenPilot Modules + * @addtogroup LibrePilotModules LibrePilot Modules * @{ * @addtogroup PathFollower FSM * @brief Executes landing sequence via an FSM * @{ * * @file vtollandfsm.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2015. * @brief Executes FSM for landing sequence * * @see The GNU Public License (GPL) Version 3 @@ -47,7 +48,7 @@ typedef enum { AUTOTAKEOFF_STATE_THRUSTDOWN, // Thrust down sequence AUTOTAKEOFF_STATE_THRUSTOFF, // Thrust is now off AUTOTAKEOFF_STATE_DISARMED, // Disarmed - AUTOTAKEOFF_STATE_ABORT, // Abort on error triggerig fallback to hold + AUTOTAKEOFF_STATE_ABORT, // Abort on error triggers fallback to land AUTOTAKEOFF_STATE_SIZE } PathFollowerFSM_AutoTakeoffState_T; diff --git a/flight/modules/PathFollower/inc/vtollandcontroller.h b/flight/modules/PathFollower/inc/vtollandcontroller.h index c770df0b3..21712345f 100644 --- a/flight/modules/PathFollower/inc/vtollandcontroller.h +++ b/flight/modules/PathFollower/inc/vtollandcontroller.h @@ -1,13 +1,14 @@ /** ****************************************************************************** - * @addtogroup OpenPilotModules OpenPilot Modules + * @addtogroup LibrePilotModules LibrePilot Modules * @{ * @addtogroup PathFollower CONTROL interface class * @brief vtol land controller class * @{ * * @file vtollandcontroller.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2015. * @brief Executes CONTROL for landing sequence * * @see The GNU Public License (GPL) Version 3 @@ -71,6 +72,7 @@ private: PIDControlDown controlDown; PIDControlNE controlNE; uint8_t mActive; + uint8_t mOverride; }; #endif // VTOLLANDCONTROLLER_H diff --git a/flight/modules/PathFollower/pathfollower.cpp b/flight/modules/PathFollower/pathfollower.cpp index f96328965..562b2e9b3 100644 --- a/flight/modules/PathFollower/pathfollower.cpp +++ b/flight/modules/PathFollower/pathfollower.cpp @@ -2,12 +2,14 @@ ****************************************************************************** * * @file pathfollower.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2015. * @brief This module compared @ref PositionActuatl to @ref ActiveWaypoint * and sets @ref AttitudeDesired. It only does this when the FlightMode field * of @ref ManualControlCommand is Auto. * * @see The GNU Public License (GPL) Version 3 + * @addtogroup LibrePilot LibrePilotModules Modules PathFollower Navigation * *****************************************************************************/ /* @@ -93,6 +95,8 @@ extern "C" { #include "vtolbrakecontroller.h" #include "vtolflycontroller.h" #include "fixedwingflycontroller.h" +#include "fixedwingautotakeoffcontroller.h" +#include "fixedwinglandcontroller.h" #include "grounddrivecontroller.h" // Private constants @@ -220,6 +224,8 @@ void pathFollowerInitializeControllersForFrameType() case FRAME_TYPE_FIXED_WING: if (!fixedwing_initialised) { FixedWingFlyController::instance()->Initialize(&fixedWingPathFollowerSettings); + FixedWingAutoTakeoffController::instance()->Initialize(&fixedWingPathFollowerSettings); + FixedWingLandController::instance()->Initialize(&fixedWingPathFollowerSettings); fixedwing_initialised = 1; } break; @@ -289,6 +295,14 @@ static void pathFollowerSetActiveController(void) activeController = FixedWingFlyController::instance(); activeController->Activate(); break; + case PATHDESIRED_MODE_LAND: // land with optional velocity roam option + activeController = FixedWingLandController::instance(); + activeController->Activate(); + break; + case PATHDESIRED_MODE_AUTOTAKEOFF: + activeController = FixedWingAutoTakeoffController::instance(); + activeController->Activate(); + break; default: activeController = 0; AlarmsSet(SYSTEMALARMS_ALARM_GUIDANCE, SYSTEMALARMS_ALARM_UNINITIALISED); @@ -451,6 +465,7 @@ static void SettingsUpdatedCb(__attribute__((unused)) UAVObjEvent *ev) static void airspeedStateUpdatedCb(__attribute__((unused)) UAVObjEvent *ev) { FixedWingFlyController::instance()->AirspeedStateUpdatedCb(ev); + FixedWingAutoTakeoffController::instance()->AirspeedStateUpdatedCb(ev); } diff --git a/flight/modules/PathFollower/vtolautotakeoffcontroller.cpp b/flight/modules/PathFollower/vtolautotakeoffcontroller.cpp index afac9e7e5..0c0bc6490 100644 --- a/flight/modules/PathFollower/vtolautotakeoffcontroller.cpp +++ b/flight/modules/PathFollower/vtolautotakeoffcontroller.cpp @@ -2,9 +2,11 @@ ****************************************************************************** * * @file vtollandcontroller.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2015. * @brief Vtol landing controller loop * @see The GNU Public License (GPL) Version 3 + * @addtogroup LibrePilot LibrePilotModules Modules PathFollower Navigation * *****************************************************************************/ /* @@ -57,6 +59,7 @@ extern "C" { #include #include #include +#include #include } @@ -67,6 +70,11 @@ extern "C" { #include "pidcontroldown.h" // Private constants +#define AUTOTAKEOFF_TO_INCREMENTAL_HEIGHT_MIN 2.0f +#define AUTOTAKEOFF_TO_INCREMENTAL_HEIGHT_MAX 50.0f +#define AUTOTAKEOFF_INFLIGHT_THROTTLE_CHECK_LIMIT 0.2f +#define AUTOTAKEOFF_THROTTLE_LIMIT_TO_ALLOW_TAKEOFF_START 0.3f +#define AUTOTAKEOFF_THROTTLE_ABORT_LIMIT 0.1f // pointer to a singleton instance VtolAutoTakeoffController *VtolAutoTakeoffController::p_inst = 0; @@ -79,11 +87,34 @@ VtolAutoTakeoffController::VtolAutoTakeoffController() void VtolAutoTakeoffController::Activate(void) { if (!mActive) { - mActive = true; + mActive = true; + mOverride = true; SettingsUpdated(); fsm->Activate(); controlDown.Activate(); controlNE.Activate(); + autotakeoffState = STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_WAITFORARMED; + // We only allow takeoff if the state transition of disarmed to armed occurs + // whilst in the autotake flight mode + FlightStatusData flightStatus; + FlightStatusGet(&flightStatus); + StabilizationDesiredData stabiDesired; + StabilizationDesiredGet(&stabiDesired); + + if (flightStatus.Armed) { + // Are we inflight? + if (stabiDesired.Thrust > AUTOTAKEOFF_INFLIGHT_THROTTLE_CHECK_LIMIT || flightStatus.ControlChain.PathPlanner == FLIGHTSTATUS_CONTROLCHAIN_TRUE) { + // ok assume already in flight and just enter position hold + // if we are not actually inflight this will just be a violent autotakeoff + autotakeoffState = STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_POSITIONHOLD; + } else { + autotakeoffState = STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_REQUIREUNARMEDFIRST; + // Note that if this mode was invoked unintentionally whilst in flight, effectively + // all inputs get ignored and the vtol continues to fly to its previous + // stabi command. + } + } + fsm->setControlState(autotakeoffState); } } @@ -100,15 +131,40 @@ uint8_t VtolAutoTakeoffController::Mode(void) // Objective updated in pathdesired, e.g. same flight mode but new target velocity void VtolAutoTakeoffController::ObjectiveUpdated(void) { - // Set the objective's target velocity + if (mOverride) { + // override pathDesired from PathPlanner with current position, + // as we deliberately don't care about the location of the waypoints on the map + float velocity_down; + float autotakeoff_height; + PositionStateData positionState; + PositionStateGet(&positionState); + FlightModeSettingsAutoTakeOffVelocityGet(&velocity_down); + FlightModeSettingsAutoTakeOffHeightGet(&autotakeoff_height); + autotakeoff_height = fabsf(autotakeoff_height); + if (autotakeoff_height < AUTOTAKEOFF_TO_INCREMENTAL_HEIGHT_MIN) { + autotakeoff_height = AUTOTAKEOFF_TO_INCREMENTAL_HEIGHT_MIN; + } else if (autotakeoff_height > AUTOTAKEOFF_TO_INCREMENTAL_HEIGHT_MAX) { + autotakeoff_height = AUTOTAKEOFF_TO_INCREMENTAL_HEIGHT_MAX; + } + controlDown.UpdateVelocitySetpoint(velocity_down); + controlNE.UpdateVelocitySetpoint(0.0f, 0.0f); + controlNE.UpdatePositionSetpoint(positionState.North, positionState.East); - controlDown.UpdateVelocitySetpoint(pathDesired->ModeParameters[PATHDESIRED_MODEPARAMETER_AUTOTAKEOFF_DOWN]); - controlNE.UpdateVelocitySetpoint(pathDesired->ModeParameters[PATHDESIRED_MODEPARAMETER_AUTOTAKEOFF_NORTH], - pathDesired->ModeParameters[PATHDESIRED_MODEPARAMETER_AUTOTAKEOFF_EAST]); - controlNE.UpdatePositionSetpoint(pathDesired->End.North, pathDesired->End.East); - controlDown.UpdatePositionSetpoint(pathDesired->End.Down); - fsm->setControlState((StatusVtolAutoTakeoffControlStateOptions)pathDesired->ModeParameters[PATHDESIRED_MODEPARAMETER_AUTOTAKEOFF_CONTROLSTATE]); + + controlDown.UpdatePositionSetpoint(positionState.Down - autotakeoff_height); + mOverride = false; // further updates always come from ManualControl and will control horizontal position + } else { + // Set the objective's target velocity + + controlDown.UpdateVelocitySetpoint(pathDesired->ModeParameters[PATHDESIRED_MODEPARAMETER_AUTOTAKEOFF_DOWN]); + controlNE.UpdateVelocitySetpoint(pathDesired->ModeParameters[PATHDESIRED_MODEPARAMETER_AUTOTAKEOFF_NORTH], + pathDesired->ModeParameters[PATHDESIRED_MODEPARAMETER_AUTOTAKEOFF_EAST]); + controlNE.UpdatePositionSetpoint(pathDesired->End.North, pathDesired->End.East); + controlDown.UpdatePositionSetpoint(pathDesired->End.Down); + } } + +// Controller deactivated void VtolAutoTakeoffController::Deactivate(void) { if (mActive) { @@ -224,6 +280,16 @@ int8_t VtolAutoTakeoffController::UpdateStabilizationDesired() controlNE.GetNECommand(&northCommand, &eastCommand); stabDesired.Thrust = controlDown.GetDownCommand(); + switch (autotakeoffState) { + case STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_WAITFORARMED: + case STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_WAITFORMIDTHROTTLE: + case STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_REQUIREUNARMEDFIRST: + case STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_ABORT: + stabDesired.Thrust = 0.0f; + break; + default: + break; + } float angle_radians = DEG2RAD(attitudeState.Yaw); float cos_angle = cosf(angle_radians); @@ -251,6 +317,78 @@ int8_t VtolAutoTakeoffController::UpdateStabilizationDesired() void VtolAutoTakeoffController::UpdateAutoPilot() { + // state machine updates: + // Vtol AutoTakeoff invocation from flight mode requires the following sequence: + // 1. Arming must be done whilst in the AutoTakeOff flight mode + // 2. If the AutoTakeoff flight mode is selected and already armed, requires disarming first + // 3. Wait for armed state + // 4. Once the user increases the throttle position to above 50%, then and only then initiate auto-takeoff. + // 5. Whilst the throttle is < 50% before takeoff, all stick inputs are being ignored. + // 6. If during the autotakeoff sequence, at any stage, if the throttle stick position reduces to less than 10%, landing is initiated. + + switch (autotakeoffState) { + case STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_REQUIREUNARMEDFIRST: + { + FlightStatusData flightStatus; + FlightStatusGet(&flightStatus); + if (!flightStatus.Armed) { + autotakeoffState = STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_WAITFORARMED; + fsm->setControlState(autotakeoffState); + } + } + break; + case STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_WAITFORARMED: + { + FlightStatusData flightStatus; + FlightStatusGet(&flightStatus); + if (flightStatus.Armed) { + autotakeoffState = STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_WAITFORMIDTHROTTLE; + fsm->setControlState(autotakeoffState); + } + } + break; + case STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_WAITFORMIDTHROTTLE: + { + ManualControlCommandData cmd; + ManualControlCommandGet(&cmd); + + if (cmd.Throttle > AUTOTAKEOFF_THROTTLE_LIMIT_TO_ALLOW_TAKEOFF_START) { + autotakeoffState = STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_INITIATE; + fsm->setControlState(autotakeoffState); + } + } + break; + case STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_INITIATE: + { + ManualControlCommandData cmd; + ManualControlCommandGet(&cmd); + FlightStatusData flightStatus; + FlightStatusGet(&flightStatus); + + // we do not do a takeoff abort in pathplanner mode + if (flightStatus.ControlChain.PathPlanner != FLIGHTSTATUS_CONTROLCHAIN_TRUE && + cmd.Throttle < AUTOTAKEOFF_THROTTLE_ABORT_LIMIT) { + autotakeoffState = STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_ABORT; + fsm->setControlState(autotakeoffState); + } + } + break; + case STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_ABORT: + { + FlightStatusData flightStatus; + FlightStatusGet(&flightStatus); + if (!flightStatus.Armed) { + autotakeoffState = STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_WAITFORARMED; + fsm->setControlState(autotakeoffState); + } + } + break; + case STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_POSITIONHOLD: + // nothing to do. land has been requested. stay here for forever until mode change. + default: + break; + } + fsm->Update(); UpdateVelocityDesired(); diff --git a/flight/modules/PathFollower/vtollandcontroller.cpp b/flight/modules/PathFollower/vtollandcontroller.cpp index c2546ed37..7362526bf 100644 --- a/flight/modules/PathFollower/vtollandcontroller.cpp +++ b/flight/modules/PathFollower/vtollandcontroller.cpp @@ -2,9 +2,11 @@ ****************************************************************************** * * @file vtollandcontroller.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2015. * @brief Vtol landing controller loop * @see The GNU Public License (GPL) Version 3 + * @addtogroup LibrePilot LibrePilotModules Modules PathFollower Navigation * *****************************************************************************/ /* @@ -76,7 +78,8 @@ VtolLandController::VtolLandController() void VtolLandController::Activate(void) { if (!mActive) { - mActive = true; + mActive = true; + mOverride = true; SettingsUpdated(); fsm->Activate(); controlDown.Activate(); @@ -97,11 +100,24 @@ uint8_t VtolLandController::Mode(void) // Objective updated in pathdesired, e.g. same flight mode but new target velocity void VtolLandController::ObjectiveUpdated(void) { - // Set the objective's target velocity - controlDown.UpdateVelocitySetpoint(pathDesired->ModeParameters[PATHDESIRED_MODEPARAMETER_VELOCITY_VELOCITYVECTOR_DOWN]); - controlNE.UpdateVelocitySetpoint(pathDesired->ModeParameters[PATHDESIRED_MODEPARAMETER_VELOCITY_VELOCITYVECTOR_NORTH], - pathDesired->ModeParameters[PATHDESIRED_MODEPARAMETER_VELOCITY_VELOCITYVECTOR_EAST]); - controlNE.UpdatePositionSetpoint(pathDesired->End.North, pathDesired->End.East); + if (mOverride) { + // override pathDesired from PathPLanner with current position, + // as we deliberately don' not care about the location of the waypoints on the map + float velocity_down; + PositionStateData positionState; + PositionStateGet(&positionState); + FlightModeSettingsLandingVelocityGet(&velocity_down); + controlDown.UpdateVelocitySetpoint(velocity_down); + controlNE.UpdateVelocitySetpoint(0.0f, 0.0f); + controlNE.UpdatePositionSetpoint(positionState.North, positionState.East); + mOverride = false; // further updates always come from ManualControl and will control horizontal position + } else { + // Set the objective's target velocity + controlDown.UpdateVelocitySetpoint(pathDesired->ModeParameters[PATHDESIRED_MODEPARAMETER_VELOCITY_VELOCITYVECTOR_DOWN]); + controlNE.UpdateVelocitySetpoint(pathDesired->ModeParameters[PATHDESIRED_MODEPARAMETER_VELOCITY_VELOCITYVECTOR_NORTH], + pathDesired->ModeParameters[PATHDESIRED_MODEPARAMETER_VELOCITY_VELOCITYVECTOR_EAST]); + controlNE.UpdatePositionSetpoint(pathDesired->End.North, pathDesired->End.East); + } } void VtolLandController::Deactivate(void) { diff --git a/flight/modules/PathPlanner/pathplanner.c b/flight/modules/PathPlanner/pathplanner.c index c22c816bc..0faeeafe2 100644 --- a/flight/modules/PathPlanner/pathplanner.c +++ b/flight/modules/PathPlanner/pathplanner.c @@ -1,13 +1,14 @@ /** ****************************************************************************** - * @addtogroup OpenPilotModules OpenPilot Modules + * @addtogroup LibrePilotModules LibrePilot Modules * @{ * @addtogroup PathPlanner Path Planner Module * @brief Executes a series of waypoints * @{ * * @file pathplanner.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2015. * @brief Executes a series of waypoints * * @see The GNU Public License (GPL) Version 3 @@ -48,8 +49,6 @@ #include "plans.h" #include #include -#include -#include #include // Private constants @@ -80,9 +79,6 @@ static uint8_t conditionPointingTowardsNext(); static uint8_t conditionPythonScript(); static uint8_t conditionImmediate(); static void SettingsUpdatedCb(__attribute__((unused)) UAVObjEvent *ev); -static void planner_setup_pathdesired_land(PathDesiredData *pathDesired); -static void planner_setup_pathdesired_takeoff(PathDesiredData *pathDesired); -static void planner_setup_pathdesired(PathDesiredData *pathDesired, bool overwrite_start_position); // Private variables @@ -132,8 +128,6 @@ int32_t PathPlannerInitialize() VelocityStateInitialize(); WaypointInitialize(); WaypointActiveInitialize(); - StatusVtolAutoTakeoffInitialize(); - StatusVtolLandInitialize(); pathPlannerHandle = PIOS_CALLBACKSCHEDULER_Create(&pathPlannerTask, CALLBACK_PRIORITY_REGULAR, TASK_PRIORITY, CALLBACKINFO_RUNNING_PATHPLANNER0, STACK_SIZE_BYTES); pathDesiredUpdaterHandle = PIOS_CALLBACKSCHEDULER_Create(&updatePathDesired, CALLBACK_PRIORITY_CRITICAL, TASK_PRIORITY, CALLBACKINFO_RUNNING_PATHPLANNER1, STACK_SIZE_BYTES); @@ -194,16 +188,7 @@ static void pathPlannerTask() FlightStatusGet(&flightStatus); if (flightStatus.ControlChain.PathPlanner != FLIGHTSTATUS_CONTROLCHAIN_TRUE) { pathplanner_active = false; - if (!validPathPlan) { - // unverified path plans are only a warning while we are not in pathplanner mode - // so it does not prevent arming. However manualcontrols safety check - // shall test for this warning when pathplan is on the flight mode selector - // thus a valid flight plan is a prerequirement for arming - AlarmsSet(SYSTEMALARMS_ALARM_PATHPLAN, SYSTEMALARMS_ALARM_WARNING); - } else { - AlarmsClear(SYSTEMALARMS_ALARM_PATHPLAN); - } - + AlarmsClear(SYSTEMALARMS_ALARM_PATHPLAN); return; } @@ -236,17 +221,17 @@ static void pathPlannerTask() return; } - // the transition from pathplanner to another flightmode back to pathplanner // triggers a reset back to 0 index in the waypoint list if (pathplanner_active == false) { - pathplanner_active = true; + pathplanner_active = true; - // This triggers callback to update variable - waypointActive.Index = 0; - WaypointActiveSet(&waypointActive); - - return; + FlightModeSettingsFlightModeChangeRestartsPathPlanOptions restart; + FlightModeSettingsFlightModeChangeRestartsPathPlanGet(&restart); + if (restart == FLIGHTMODESETTINGS_FLIGHTMODECHANGERESTARTSPATHPLAN_TRUE) { + setWaypoint(0); + return; + } } WaypointInstGet(waypointActive.Index, &waypoint); @@ -265,21 +250,6 @@ static void pathPlannerTask() return; } - // check start conditions - // autotakeoff requires midpoint thrust if we are in a pending takeoff situation - if (pathAction.Mode == PATHACTION_MODE_AUTOTAKEOFF) { - pathAction.EndCondition = PATHACTION_ENDCONDITION_LEGREMAINING; - if ((uint8_t)pathDesired.ModeParameters[PATHDESIRED_MODEPARAMETER_AUTOTAKEOFF_CONTROLSTATE] == STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_WAITFORMIDTHROTTLE) { - ManualControlCommandData cmd; - ManualControlCommandGet(&cmd); - if (cmd.Throttle > AUTOTAKEOFF_THROTTLE_LIMIT_TO_ALLOW_TAKEOFF_START) { - pathDesired.ModeParameters[PATHDESIRED_MODEPARAMETER_AUTOTAKEOFF_CONTROLSTATE] = (float)STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_INITIATE; - PathDesiredSet(&pathDesired); - } - return; - } - } - // check if condition has been met endCondition = pathConditionCheck(); @@ -331,22 +301,45 @@ void updatePathDesired() WaypointActiveGet(&waypointActive); WaypointInstGet(waypointActive.Index, &waypoint); - // Capture if current mode is takeoff - bool autotakeoff = (pathAction.Mode == PATHACTION_MODE_AUTOTAKEOFF); - PathActionInstGet(waypoint.Action, &pathAction); PathDesiredData pathDesired; - switch (pathAction.Mode) { - case PATHACTION_MODE_AUTOTAKEOFF: - planner_setup_pathdesired_takeoff(&pathDesired); - break; - case PATHACTION_MODE_LAND: - planner_setup_pathdesired_land(&pathDesired); - break; - default: - planner_setup_pathdesired(&pathDesired, autotakeoff); - break; + + pathDesired.End.North = waypoint.Position.North; + pathDesired.End.East = waypoint.Position.East; + pathDesired.End.Down = waypoint.Position.Down; + pathDesired.EndingVelocity = waypoint.Velocity; + pathDesired.Mode = pathAction.Mode; + pathDesired.ModeParameters[0] = pathAction.ModeParameters[0]; + pathDesired.ModeParameters[1] = pathAction.ModeParameters[1]; + pathDesired.ModeParameters[2] = pathAction.ModeParameters[2]; + pathDesired.ModeParameters[3] = pathAction.ModeParameters[3]; + pathDesired.UID = waypointActive.Index; + + + if (waypointActive.Index == 0) { + PositionStateData positionState; + PositionStateGet(&positionState); + // First waypoint has itself as start point (used to be home position but that proved dangerous when looping) + + /*pathDesired.Start[PATHDESIRED_START_NORTH] = waypoint.Position[WAYPOINT_POSITION_NORTH]; + pathDesired.Start[PATHDESIRED_START_EAST] = waypoint.Position[WAYPOINT_POSITION_EAST]; + pathDesired.Start[PATHDESIRED_START_DOWN] = waypoint.Position[WAYPOINT_POSITION_DOWN];*/ + // note: if certain flightmodes need to override Start, End or mode parameters, that should happen within + // the pathfollower as needed. This also holds if Start is replaced by current position for takeoff and landing + pathDesired.Start.North = positionState.North; + pathDesired.Start.East = positionState.East; + pathDesired.Start.Down = positionState.Down; + pathDesired.StartingVelocity = pathDesired.EndingVelocity; + } else { + // Get previous waypoint as start point + WaypointData waypointPrev; + WaypointInstGet(waypointActive.Index - 1, &waypointPrev); + + pathDesired.Start.North = waypointPrev.Position.North; + pathDesired.Start.East = waypointPrev.Position.East; + pathDesired.Start.Down = waypointPrev.Position.Down; + pathDesired.StartingVelocity = waypointPrev.Velocity; } PathDesiredSet(&pathDesired); @@ -437,112 +430,6 @@ void statusUpdated(__attribute__((unused)) UAVObjEvent *ev) PIOS_CALLBACKSCHEDULER_Dispatch(pathPlannerHandle); } -// Standard setup of a pathDesired command from the waypoint path plan -static void planner_setup_pathdesired(PathDesiredData *pathDesired, bool overwrite_start_position) -{ - pathDesired->End.North = waypoint.Position.North; - pathDesired->End.East = waypoint.Position.East; - pathDesired->End.Down = waypoint.Position.Down; - pathDesired->EndingVelocity = waypoint.Velocity; - pathDesired->Mode = pathAction.Mode; - pathDesired->ModeParameters[0] = pathAction.ModeParameters[0]; - pathDesired->ModeParameters[1] = pathAction.ModeParameters[1]; - pathDesired->ModeParameters[2] = pathAction.ModeParameters[2]; - pathDesired->ModeParameters[3] = pathAction.ModeParameters[3]; - pathDesired->UID = waypointActive.Index; - - - if (waypointActive.Index == 0 || overwrite_start_position) { - PositionStateData positionState; - PositionStateGet(&positionState); - // First waypoint has itself as start point (used to be home position but that proved dangerous when looping) - - /*pathDesired.Start[PATHDESIRED_START_NORTH] = waypoint.Position[WAYPOINT_POSITION_NORTH]; - pathDesired.Start[PATHDESIRED_START_EAST] = waypoint.Position[WAYPOINT_POSITION_EAST]; - pathDesired.Start[PATHDESIRED_START_DOWN] = waypoint.Position[WAYPOINT_POSITION_DOWN];*/ - // note takeoff relies on the start being the current location as it merely ascends and using - // the start as assumption current NE location - pathDesired->Start.North = positionState.North; - pathDesired->Start.East = positionState.East; - pathDesired->Start.Down = positionState.Down; - pathDesired->StartingVelocity = pathDesired->EndingVelocity; - } else { - // Get previous waypoint as start point - WaypointData waypointPrev; - WaypointInstGet(waypointActive.Index - 1, &waypointPrev); - - pathDesired->Start.North = waypointPrev.Position.North; - pathDesired->Start.East = waypointPrev.Position.East; - pathDesired->Start.Down = waypointPrev.Position.Down; - pathDesired->StartingVelocity = waypointPrev.Velocity; - } -} - -#define AUTOTAKEOFF_TO_INCREMENTAL_HEIGHT_MIN 2.0f -#define AUTOTAKEOFF_TO_INCREMENTAL_HEIGHT_MAX 50.0f -static void planner_setup_pathdesired_takeoff(PathDesiredData *pathDesired) -{ - PositionStateData positionState; - - PositionStateGet(&positionState); - float velocity_down; - float autotakeoff_height; - FlightModeSettingsAutoTakeOffVelocityGet(&velocity_down); - FlightModeSettingsAutoTakeOffHeightGet(&autotakeoff_height); - autotakeoff_height = fabsf(autotakeoff_height); - if (autotakeoff_height < AUTOTAKEOFF_TO_INCREMENTAL_HEIGHT_MIN) { - autotakeoff_height = AUTOTAKEOFF_TO_INCREMENTAL_HEIGHT_MIN; - } else if (autotakeoff_height > AUTOTAKEOFF_TO_INCREMENTAL_HEIGHT_MAX) { - autotakeoff_height = AUTOTAKEOFF_TO_INCREMENTAL_HEIGHT_MAX; - } - - - pathDesired->Start.North = positionState.North; - pathDesired->Start.East = positionState.East; - pathDesired->Start.Down = positionState.Down; - pathDesired->ModeParameters[PATHDESIRED_MODEPARAMETER_AUTOTAKEOFF_NORTH] = 0.0f; - pathDesired->ModeParameters[PATHDESIRED_MODEPARAMETER_AUTOTAKEOFF_EAST] = 0.0f; - pathDesired->ModeParameters[PATHDESIRED_MODEPARAMETER_AUTOTAKEOFF_DOWN] = -velocity_down; - // initially halt takeoff. - pathDesired->ModeParameters[PATHDESIRED_MODEPARAMETER_AUTOTAKEOFF_CONTROLSTATE] = (float)STATUSVTOLAUTOTAKEOFF_CONTROLSTATE_WAITFORMIDTHROTTLE; - - pathDesired->End.North = positionState.North; - pathDesired->End.East = positionState.East; - pathDesired->End.Down = positionState.Down - autotakeoff_height; - - pathDesired->StartingVelocity = 0.0f; - pathDesired->EndingVelocity = 0.0f; - pathDesired->Mode = PATHDESIRED_MODE_AUTOTAKEOFF; - - pathDesired->UID = waypointActive.Index; -} - -static void planner_setup_pathdesired_land(PathDesiredData *pathDesired) -{ - PositionStateData positionState; - - PositionStateGet(&positionState); - float velocity_down; - - FlightModeSettingsLandingVelocityGet(&velocity_down); - - pathDesired->Start.North = positionState.North; - pathDesired->Start.East = positionState.East; - pathDesired->Start.Down = positionState.Down; - pathDesired->ModeParameters[PATHDESIRED_MODEPARAMETER_LAND_VELOCITYVECTOR_NORTH] = 0.0f; - pathDesired->ModeParameters[PATHDESIRED_MODEPARAMETER_LAND_VELOCITYVECTOR_EAST] = 0.0f; - pathDesired->ModeParameters[PATHDESIRED_MODEPARAMETER_LAND_VELOCITYVECTOR_DOWN] = velocity_down; - - pathDesired->End.North = positionState.North; - pathDesired->End.East = positionState.East; - pathDesired->End.Down = positionState.Down; - - pathDesired->StartingVelocity = 0.0f; - pathDesired->EndingVelocity = 0.0f; - pathDesired->Mode = PATHDESIRED_MODE_LAND; - pathDesired->ModeParameters[PATHDESIRED_MODEPARAMETER_LAND_OPTIONS] = (float)PATHDESIRED_MODEPARAMETER_LAND_OPTION_HORIZONTAL_PH; -} - // helper function to go to a specific waypoint static void setWaypoint(uint16_t num) diff --git a/flight/modules/RadioComBridge/RadioComBridge.c b/flight/modules/RadioComBridge/RadioComBridge.c index a1146f75e..a9b4c70ae 100644 --- a/flight/modules/RadioComBridge/RadioComBridge.c +++ b/flight/modules/RadioComBridge/RadioComBridge.c @@ -131,7 +131,7 @@ static int32_t RadioComBridgeStart(void) OPLinkSettingsGet(&oplinkSettings); // Check if this is the coordinator modem - data->isCoordinator = (oplinkSettings.Coordinator == OPLINKSETTINGS_COORDINATOR_TRUE); + data->isCoordinator = (oplinkSettings.Protocol == OPLINKSETTINGS_PROTOCOL_OPLINKCOORDINATOR); // We will not parse/send UAVTalk if any ports are configured as Serial (except for over the USB HID port). data->parseUAVTalk = ((oplinkSettings.MainPort != OPLINKSETTINGS_MAINPORT_SERIAL) && @@ -170,13 +170,13 @@ static int32_t RadioComBridgeStart(void) } // Configure our UAVObjects for updates. - UAVObjConnectQueue(UAVObjGetByID(OPLINKSTATUS_OBJID), data->uavtalkEventQueue, EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ); UAVObjConnectQueue(UAVObjGetByID(OBJECTPERSISTENCE_OBJID), data->uavtalkEventQueue, EV_UPDATED | EV_UPDATED_MANUAL); if (data->isCoordinator) { UAVObjConnectQueue(UAVObjGetByID(OPLINKRECEIVER_OBJID), data->radioEventQueue, EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ); } else { UAVObjConnectQueue(UAVObjGetByID(OPLINKRECEIVER_OBJID), data->uavtalkEventQueue, EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ); } + registerObject(OPLinkStatusHandle()); if (data->isCoordinator) { registerObject(RadioComBridgeStatsHandle()); @@ -475,18 +475,18 @@ static void PPMInputTask(__attribute__((unused)) void *parameters) // Wait for the receiver semaphore. if (xSemaphoreTake(sem, PPM_INPUT_TIMEOUT) == pdTRUE) { // Read the receiver inputs. - for (uint8_t i = 0; i < OPLINKRECEIVER_CHANNEL_NUMELEM; ++i) { + for (uint8_t i = 0; i < RFM22B_PPM_NUM_CHANNELS; ++i) { channels[i] = PIOS_RCVR_Read(PIOS_PPM_RECEIVER, i + 1); } } else { // Failsafe - for (uint8_t i = 0; i < OPLINKRECEIVER_CHANNEL_NUMELEM; ++i) { + for (uint8_t i = 0; i < RFM22B_PPM_NUM_CHANNELS; ++i) { channels[i] = PIOS_RCVR_INVALID; } } // Pass the channel values to the radio device. - PIOS_RFM22B_PPMSet(pios_rfm22b_id, channels); + PIOS_RFM22B_PPMSet(pios_rfm22b_id, channels, RFM22B_PPM_NUM_CHANNELS); } } diff --git a/flight/modules/Receiver/receiver.c b/flight/modules/Receiver/receiver.c index 4dfd26770..900e1194c 100644 --- a/flight/modules/Receiver/receiver.c +++ b/flight/modules/Receiver/receiver.c @@ -99,8 +99,8 @@ static uint8_t isAssistedFlightMode(uint8_t position); static void applyLPF(float *value, ManualControlSettingsResponseTimeElem channel, ManualControlSettingsResponseTimeData *responseTime, uint8_t deadband, float dT); #endif -#define RCVR_ACTIVITY_MONITOR_CHANNELS_PER_GROUP 12 -#define RCVR_ACTIVITY_MONITOR_MIN_RANGE 10 +#define RCVR_ACTIVITY_MONITOR_CHANNELS_PER_GROUP 18 // Sbus max channel +#define RCVR_ACTIVITY_MONITOR_MIN_RANGE 15 struct rcvr_activity_fsm { ManualControlSettingsChannelGroupsOptions group; uint16_t prev[RCVR_ACTIVITY_MONITOR_CHANNELS_PER_GROUP]; @@ -655,18 +655,33 @@ static bool updateRcvrActivityCompare(uint32_t rcvr_id, struct rcvr_activity_fsm case MANUALCONTROLSETTINGS_CHANNELGROUPS_DSMFLEXIPORT: group = RECEIVERACTIVITY_ACTIVEGROUP_DSMFLEXIPORT; break; + case MANUALCONTROLSETTINGS_CHANNELGROUPS_DSMRCVRPORT: + group = RECEIVERACTIVITY_ACTIVEGROUP_DSMRCVRPORT; + break; + case MANUALCONTROLSETTINGS_CHANNELGROUPS_EXBUS: + group = RECEIVERACTIVITY_ACTIVEGROUP_EXBUS; + break; case MANUALCONTROLSETTINGS_CHANNELGROUPS_SBUS: group = RECEIVERACTIVITY_ACTIVEGROUP_SBUS; break; + case MANUALCONTROLSETTINGS_CHANNELGROUPS_HOTT: + group = RECEIVERACTIVITY_ACTIVEGROUP_HOTT; + break; case MANUALCONTROLSETTINGS_CHANNELGROUPS_SRXL: group = RECEIVERACTIVITY_ACTIVEGROUP_SRXL; break; + case MANUALCONTROLSETTINGS_CHANNELGROUPS_IBUS: + group = RECEIVERACTIVITY_ACTIVEGROUP_IBUS; + break; case MANUALCONTROLSETTINGS_CHANNELGROUPS_GCS: group = RECEIVERACTIVITY_ACTIVEGROUP_GCS; break; case MANUALCONTROLSETTINGS_CHANNELGROUPS_OPLINK: group = RECEIVERACTIVITY_ACTIVEGROUP_OPLINK; break; + case MANUALCONTROLSETTINGS_CHANNELGROUPS_OPENLRS: + group = RECEIVERACTIVITY_ACTIVEGROUP_OPENLRS; + break; default: PIOS_Assert(0); break; diff --git a/flight/modules/Sensors/sensors.c b/flight/modules/Sensors/sensors.c index 800d8a94c..a08e74b64 100644 --- a/flight/modules/Sensors/sensors.c +++ b/flight/modules/Sensors/sensors.c @@ -7,7 +7,8 @@ * @{ * * @file sensors.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2015. * @brief Module to handle fetch and preprocessing of sensor data * * @see The GNU Public License (GPL) Version 3 @@ -57,8 +58,12 @@ #include #include +#include +#include +#include #include #include +#include #include #include @@ -81,7 +86,7 @@ #define REGISTER_WDG() #endif -static const TickType_t sensor_period_ticks = ((uint32_t)1000.0f / PIOS_SENSOR_RATE) / portTICK_RATE_MS; +static const TickType_t sensor_period_ticks = ((uint32_t)(1000.0f / PIOS_SENSOR_RATE / (float)portTICK_RATE_MS)); // Interval in number of sample to recalculate temp bias #define TEMP_CALIB_INTERVAL 30 @@ -99,14 +104,16 @@ static const float temp_alpha_gyro_accel = LPF_ALPHA(TEMP_DT_GYRO_ACCEL, TEMP_LP #define TEMP_LPF_FC_BARO 5.0f static const float temp_alpha_baro = TEMP_DT_BARO / (TEMP_DT_BARO + 1.0f / (2.0f * M_PI_F * TEMP_LPF_FC_BARO)); - #define ZERO_ROT_ANGLE 0.00001f + // Private types typedef struct { // used to accumulate all samples in a task iteration - Vector3i32 accum[2]; - int32_t temperature; - uint32_t count; + uint64_t timestamp; // sum of "PIOS_DELAY_GetRaw() times of sensor read" in this averaged set + Vector3i32 accum[2]; // summed 16 bit sensor values in this averaged set + int32_t temperature; // sum of 16 bit temperatures in this averaged set + uint32_t prev_timestamp; // to detect timer wrap around + uint16_t count; // number of sensor reads in this averaged set } sensor_fetch_context; #define MAX_SENSOR_DATA_SIZE (sizeof(PIOS_SENSORS_3Axis_SensorsWithTemp) + MAX_SENSORS_PER_INSTANCE * sizeof(Vector3i16)) @@ -125,6 +132,10 @@ PERF_DEFINE_COUNTER(counterBaroPeriod); PERF_DEFINE_COUNTER(counterSensorPeriod); PERF_DEFINE_COUNTER(counterSensorResets); +#if defined(PIOS_INCLUDE_HMC5X83) +void aux_hmc5x83_load_settings(); +#endif + // Private functions static void SensorsTask(void *parameters); static void settingsUpdatedCb(UAVObjEvent *objEv); @@ -136,8 +147,11 @@ static void processSamples1d(PIOS_SENSORS_1Axis_SensorsWithTemp *sample, const P static void clearContext(sensor_fetch_context *sensor_context); static void handleAccel(float *samples, float temperature); -static void handleGyro(float *samples, float temperature); +static void handleGyro(float *samples, float temperature, uint32_t timestamp); static void handleMag(float *samples, float temperature); +#if defined(PIOS_INCLUDE_HMC5X83) +static void handleAuxMag(float *samples); +#endif static void handleBaro(float sample, float temperature); static void updateAccelTempBias(float temperature); @@ -151,7 +165,6 @@ RevoCalibrationData cal; AccelGyroSettingsData agcal; // These values are initialized by settings but can be updated by the attitude algorithm - static float mag_bias[3] = { 0, 0, 0 }; static float mag_transform[3][3] = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } @@ -168,9 +181,11 @@ static float gyro_temp_bias[3] = { 0 }; static uint8_t accel_temp_calibration_count = 0; static uint8_t gyro_temp_calibration_count = 0; +// The user specified "Rotate virtual attitude relative to board" static float R[3][3] = { { 0 } }; + // Variables used to handle baro temperature bias static RevoSettingsBaroTempCorrectionPolynomialData baroCorrection; static RevoSettingsBaroTempCorrectionExtentData baroCorrectionExtent; @@ -179,7 +194,11 @@ static float baro_temp_bias = 0; static float baro_temperature = NAN; static uint8_t baro_temp_calibration_count = 0; -static int8_t rotate = 0; +#if defined(PIOS_INCLUDE_HMC5X83) +// Allow AuxMag to be disabled without reboot +// because the other mags are that way +static bool useAuxMag = false; +#endif /** * Initialise the module. Called before the start function @@ -197,7 +216,11 @@ int32_t SensorsInitialize(void) AttitudeSettingsInitialize(); AccelGyroSettingsInitialize(); - rotate = 0; +#if defined(PIOS_INCLUDE_HMC5X83) + // for auxmagsupport.c helpers + AuxMagSettingsInitialize(); + AuxMagSensorInitialize(); +#endif RevoSettingsConnectCallback(&settingsUpdatedCb); RevoCalibrationConnectCallback(&settingsUpdatedCb); @@ -233,8 +256,6 @@ int32_t mag_test; * stabilization and to the attitude loop * */ - -uint32_t sensor_dt_us; static void SensorsTask(__attribute__((unused)) void *parameters) { portTickType lastSysTime; @@ -258,6 +279,7 @@ static void SensorsTask(__attribute__((unused)) void *parameters) bool sensors_test = true; uint8_t count = 0; LL_FOREACH((PIOS_SENSORS_Instance *)sensors_list, sensor) { + RELOAD_WDG(); // mag tests on I2C have 200+(7x10)ms delay calls in them sensors_test &= PIOS_SENSORS_Test(sensor); count++; } @@ -337,8 +359,10 @@ static void clearContext(sensor_fetch_context *sensor_context) sensor_context->accum[i].y = 0; sensor_context->accum[i].z = 0; } - sensor_context->temperature = 0; - sensor_context->count = 0; + sensor_context->temperature = 0; + sensor_context->prev_timestamp = 0; + sensor_context->timestamp = 0LL; + sensor_context->count = 0; } static void accumulateSamples(sensor_fetch_context *sensor_context, sensor_data *sample) @@ -349,6 +373,14 @@ static void accumulateSamples(sensor_fetch_context *sensor_context, sensor_data sensor_context->accum[i].z += sample->sensorSample3Axis.sample[i].z; } sensor_context->temperature += sample->sensorSample3Axis.temperature; + sensor_context->timestamp += sample->sensorSample3Axis.timestamp; + if (sensor_context->prev_timestamp > sample->sensorSample3Axis.timestamp) { + // we've wrapped so add the dropped top bit + // this makes the average come out correct instead of (0xfd+0x01)/2 = 0x7f or such + sensor_context->timestamp += 0x100000000LL; + } else { + sensor_context->prev_timestamp = sample->sensorSample3Axis.timestamp; + } sensor_context->count++; } @@ -360,26 +392,41 @@ static void processSamples3d(sensor_fetch_context *sensor_context, const PIOS_SE PIOS_SENSORS_GetScales(sensor, scales, MAX_SENSORS_PER_INSTANCE); float inv_count = 1.0f / (float)sensor_context->count; - if ((sensor->type & PIOS_SENSORS_TYPE_3AXIS_ACCEL) || - (sensor->type == PIOS_SENSORS_TYPE_3AXIS_MAG)) { + if ((sensor->type & PIOS_SENSORS_TYPE_3AXIS_ACCEL) + || (sensor->type == PIOS_SENSORS_TYPE_3AXIS_MAG) +#if defined(PIOS_INCLUDE_HMC5X83) + || (sensor->type == PIOS_SENSORS_TYPE_3AXIS_AUXMAG) +#endif + ) { float t = inv_count * scales[0]; samples[0] = ((float)sensor_context->accum[0].x * t); samples[1] = ((float)sensor_context->accum[0].y * t); samples[2] = ((float)sensor_context->accum[0].z * t); temperature = (float)sensor_context->temperature * inv_count * 0.01f; - if (sensor->type == PIOS_SENSORS_TYPE_3AXIS_MAG) { + switch (sensor->type) { + case PIOS_SENSORS_TYPE_3AXIS_MAG: handleMag(samples, temperature); PERF_MEASURE_PERIOD(counterMagPeriod); return; - } else { + +#if defined(PIOS_INCLUDE_HMC5X83) + case PIOS_SENSORS_TYPE_3AXIS_AUXMAG: + handleAuxMag(samples); + PERF_MEASURE_PERIOD(counterMagPeriod); + return; + +#endif + default: PERF_TRACK_VALUE(counterAccelSamples, sensor_context->count); PERF_MEASURE_PERIOD(counterAccelPeriod); handleAccel(samples, temperature); + break; } } if (sensor->type & PIOS_SENSORS_TYPE_3AXIS_GYRO) { uint8_t index = 0; + uint32_t timestamp; if (sensor->type == PIOS_SENSORS_TYPE_3AXIS_GYRO_ACCEL) { index = 1; } @@ -388,7 +435,8 @@ static void processSamples3d(sensor_fetch_context *sensor_context, const PIOS_SE samples[1] = ((float)sensor_context->accum[index].y * t); samples[2] = ((float)sensor_context->accum[index].z * t); temperature = (float)sensor_context->temperature * inv_count * 0.01f; - handleGyro(samples, temperature); + timestamp = (uint32_t)(sensor_context->timestamp / sensor_context->count); + handleGyro(samples, temperature, timestamp); return; } } @@ -420,10 +468,11 @@ static void handleAccel(float *samples, float temperature) accelSensorData.y = samples[1]; accelSensorData.z = samples[2]; accelSensorData.temperature = temperature; + AccelSensorSet(&accelSensorData); } -static void handleGyro(float *samples, float temperature) +static void handleGyro(float *samples, float temperature, uint32_t timestamp) { GyroSensorData gyroSensorData; @@ -433,10 +482,11 @@ static void handleGyro(float *samples, float temperature) samples[2] * agcal.gyro_scale.Z - agcal.gyro_bias.Z - gyro_temp_bias[2] }; rot_mult(R, gyros_out, samples); - gyroSensorData.temperature = temperature; gyroSensorData.x = samples[0]; gyroSensorData.y = samples[1]; gyroSensorData.z = samples[2]; + gyroSensorData.temperature = temperature; + gyroSensorData.SensorReadTimestamp = timestamp; GyroSensorSet(&gyroSensorData); } @@ -458,6 +508,15 @@ static void handleMag(float *samples, float temperature) MagSensorSet(&mag); } +#if defined(PIOS_INCLUDE_HMC5X83) +static void handleAuxMag(float *samples) +{ + if (useAuxMag) { + auxmagsupport_publish_samples(samples, AUXMAGSENSOR_STATUS_OK); + } +} +#endif + static void handleBaro(float sample, float temperature) { updateBaroTempBias(temperature); @@ -535,58 +594,47 @@ static void updateBaroTempBias(float temperature) } baro_temp_calibration_count--; } + /** - * Locally cache some variables from the AtttitudeSettings object + * Locally cache some variables from the AttitudeSettings object */ static void settingsUpdatedCb(__attribute__((unused)) UAVObjEvent *objEv) { RevoCalibrationGet(&cal); - AccelGyroSettingsGet(&agcal); mag_bias[0] = cal.mag_bias.X; mag_bias[1] = cal.mag_bias.Y; mag_bias[2] = cal.mag_bias.Z; + AccelGyroSettingsGet(&agcal); accel_temp_calibrated = (agcal.temp_calibrated_extent.max - agcal.temp_calibrated_extent.min > .1f) && (fabsf(agcal.accel_temp_coeff.X) > 1e-9f || fabsf(agcal.accel_temp_coeff.Y) > 1e-9f || fabsf(agcal.accel_temp_coeff.Z) > 1e-9f); - gyro_temp_calibrated = (agcal.temp_calibrated_extent.max - agcal.temp_calibrated_extent.min > .1f) && (fabsf(agcal.gyro_temp_coeff.X) > 1e-9f || fabsf(agcal.gyro_temp_coeff.Y) > 1e-9f || fabsf(agcal.gyro_temp_coeff.Z) > 1e-9f || fabsf(agcal.gyro_temp_coeff.Z2) > 1e-9f); - + // convert BoardRotation ("rotate virtual") into a quaternion AttitudeSettingsData attitudeSettings; AttitudeSettingsGet(&attitudeSettings); - - // Indicates not to expend cycles on rotation - if (fabsf(attitudeSettings.BoardRotation.Roll) < ZERO_ROT_ANGLE - && fabsf(attitudeSettings.BoardRotation.Pitch) < ZERO_ROT_ANGLE && - fabsf(attitudeSettings.BoardRotation.Yaw) < ZERO_ROT_ANGLE) { - rotate = 0; - } else { - rotate = 1; - } - const float rpy[3] = { attitudeSettings.BoardRotation.Roll, attitudeSettings.BoardRotation.Pitch, attitudeSettings.BoardRotation.Yaw }; - float rotationQuat[4]; RPY2Quaternion(rpy, rotationQuat); - if (fabsf(attitudeSettings.BoardLevelTrim.Roll) > ZERO_ROT_ANGLE || - fabsf(attitudeSettings.BoardLevelTrim.Pitch) > ZERO_ROT_ANGLE) { - float trimQuat[4]; - float sumQuat[4]; - rotate = 1; + // convert BoardLevelTrim ("board level calibration") into a quaternion + float trimQuat[4]; + float sumQuat[4]; + const float trimRpy[3] = { attitudeSettings.BoardLevelTrim.Roll, attitudeSettings.BoardLevelTrim.Pitch, 0.0f }; + // do we actually want to include BoardLevelTrim in the mag rotation? BoardRotation yes, but BoardLevelTrim? + // and is BoardLevelTrim done at the correct point in the sequence of rotations? + RPY2Quaternion(trimRpy, trimQuat); - const float trimRpy[3] = { attitudeSettings.BoardLevelTrim.Roll, attitudeSettings.BoardLevelTrim.Pitch, 0.0f }; - RPY2Quaternion(trimRpy, trimQuat); + // add the boardrotation and boardtrim rotations and put them into a rotation matrix + quat_mult(rotationQuat, trimQuat, sumQuat); + Quaternion2R(sumQuat, R); - quat_mult(rotationQuat, trimQuat, sumQuat); - Quaternion2R(sumQuat, R); - } else { - Quaternion2R(rotationQuat, R); - } + // mag_transform is only a scaling + // so add the scaling, and store the result in mag_transform for run time use matrix_mult_3x3f((float(*)[3])RevoCalibrationmag_transformToArray(cal.mag_transform), R, mag_transform); RevoSettingsBaroTempCorrectionPolynomialGet(&baroCorrection); @@ -598,6 +646,19 @@ static void settingsUpdatedCb(__attribute__((unused)) UAVObjEvent *objEv) fabsf(baroCorrection.c) > 1e-9f || fabsf(baroCorrection.d) > 1e-9f)); } + +#if defined(PIOS_INCLUDE_HMC5X83) +void aux_hmc5x83_load_mag_settings() +{ + uint8_t magType = auxmagsupport_get_type(); + + if (magType == AUXMAGSETTINGS_TYPE_I2C || magType == AUXMAGSETTINGS_TYPE_FLEXI) { + useAuxMag = true; + } else { + useAuxMag = false; + } +} +#endif /** * @} * @} diff --git a/flight/modules/Stabilization/inc/stabilization.h b/flight/modules/Stabilization/inc/stabilization.h index b1ff2fc13..fbf8dbf9b 100644 --- a/flight/modules/Stabilization/inc/stabilization.h +++ b/flight/modules/Stabilization/inc/stabilization.h @@ -80,9 +80,12 @@ extern StabilizationData stabSettings; // must be same as eventdispatcher to avoid needing additional mutexes #define CBTASK_PRIORITY CALLBACK_TASK_FLIGHTCONTROL +#ifndef STABILIZATION_ATTITUDE_DOWNSAMPLED // outer loop only executes every 4th uavobject update to save CPU #define OUTERLOOP_SKIPCOUNT 4 - +#else +#define OUTERLOOP_SKIPCOUNT ATTITUDE_SENSORS_DOWNSAMPLE +#endif // STABILIZATION_ATTITUDE_DOWNSAMPLED #endif // STABILIZATION_H /** diff --git a/flight/modules/Stabilization/innerloop.c b/flight/modules/Stabilization/innerloop.c index 3786b62f4..a50e6e6ec 100644 --- a/flight/modules/Stabilization/innerloop.c +++ b/flight/modules/Stabilization/innerloop.c @@ -9,7 +9,7 @@ * @{ * * @file innerloop.c - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2016. * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014. * @brief Attitude stabilization module. * @@ -51,14 +51,28 @@ #include #include #include +#if !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) +#include +#endif /* !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) */ + // Private constants -#define CALLBACK_PRIORITY CALLBACK_PRIORITY_CRITICAL +#define CALLBACK_PRIORITY CALLBACK_PRIORITY_CRITICAL -#define UPDATE_EXPECTED (1.0f / PIOS_SENSOR_RATE) -#define UPDATE_MIN 1.0e-6f -#define UPDATE_MAX 1.0f -#define UPDATE_ALPHA 1.0e-2f +#define UPDATE_EXPECTED (1.0f / PIOS_SENSOR_RATE) +#define UPDATE_MIN 1.0e-6f +#define UPDATE_MAX 1.0f +#define UPDATE_ALPHA 1.0e-2f + +#define SYSTEM_IDENT_PERIOD ((uint32_t)75) + +#if defined(PIOS_EXCLUDE_ADVANCED_FEATURES) +#define powapprox fastpow +#define expapprox fastexp +#else +#define powapprox powf +#define expapprox expf +#endif /* !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) */ // Private variables static DelayedCallbackInfo *callbackHandle; @@ -68,6 +82,10 @@ static uint8_t previous_mode[AXES] = { 255, 255, 255, 255 }; static PiOSDeltatimeConfig timeval; static float speedScaleFactor = 1.0f; static bool frame_is_multirotor; +static bool measuredDterm_enabled; +#if !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) +static uint32_t systemIdentTimeVal = 0; +#endif /* !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) */ // Private functions static void stabilizationInnerloopTask(); @@ -86,6 +104,9 @@ void stabilizationInnerloopInit() ManualControlCommandInitialize(); StabilizationDesiredInitialize(); ActuatorDesiredInitialize(); +#if !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) + SystemIdentStateInitialize(); +#endif /* !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) */ #ifdef REVOLUTION AirspeedStateInitialize(); AirspeedStateConnectCallback(AirSpeedUpdatedCb); @@ -98,7 +119,12 @@ void stabilizationInnerloopInit() // schedule dead calls every FAILSAFE_TIMEOUT_MS to have the watchdog cleared PIOS_CALLBACKSCHEDULER_Schedule(callbackHandle, FAILSAFE_TIMEOUT_MS, CALLBACK_UPDATEMODE_LATER); - frame_is_multirotor = (GetCurrentFrameType() == FRAME_TYPE_MULTIROTOR); + frame_is_multirotor = (GetCurrentFrameType() == FRAME_TYPE_MULTIROTOR); + measuredDterm_enabled = (stabSettings.settings.MeasureBasedDTerm == STABILIZATIONSETTINGS_MEASUREBASEDDTERM_TRUE); +#if !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) + // Settings for system identification + systemIdentTimeVal = PIOS_DELAY_GetRaw(); +#endif /* !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) */ } static float get_pid_scale_source_value() @@ -229,7 +255,6 @@ static void stabilizationInnerloopTask() } } - RateDesiredData rateDesired; ActuatorDesiredData actuator; StabilizationStatusInnerLoopData enabled; @@ -250,6 +275,7 @@ static void stabilizationInnerloopTask() StabilizationStatusOuterLoopGet(&outerLoop); bool allowPiroComp = true; + for (t = 0; t < AXES; t++) { bool reinit = (StabilizationStatusInnerLoopToArray(enabled)[t] != previous_mode[t]); previous_mode[t] = StabilizationStatusInnerLoopToArray(enabled)[t]; @@ -284,14 +310,16 @@ static void stabilizationInnerloopTask() // IMPORTANT: deliberately no "break;" here, execution continues with regular RATE control loop to avoid code duplication! // keep order as it is, RATE must follow! case STABILIZATIONSTATUS_INNERLOOP_RATE: + { // limit rate to maximum configured limits (once here instead of 5 times in outer loop) rate[t] = boundf(rate[t], -StabilizationBankMaximumRateToArray(stabSettings.stabBank.MaximumRate)[t], StabilizationBankMaximumRateToArray(stabSettings.stabBank.MaximumRate)[t] ); pid_scaler scaler = create_pid_scaler(t); - actuatorDesiredAxis[t] = pid_apply_setpoint(&stabSettings.innerPids[t], &scaler, rate[t], gyro_filtered[t], dT); - break; + actuatorDesiredAxis[t] = pid_apply_setpoint(&stabSettings.innerPids[t], &scaler, rate[t], gyro_filtered[t], dT, measuredDterm_enabled); + } + break; case STABILIZATIONSTATUS_INNERLOOP_ACRO: { float stickinput[3]; @@ -305,11 +333,72 @@ static void stabilizationInnerloopTask() pid_scaler ascaler = create_pid_scaler(t); ascaler.i *= boundf(1.0f - (1.5f * fabsf(stickinput[t])), 0.0f, 1.0f); // this prevents Integral from getting too high while controlled manually - float arate = pid_apply_setpoint(&stabSettings.innerPids[t], &ascaler, rate[t], gyro_filtered[t], dT); + float arate = pid_apply_setpoint(&stabSettings.innerPids[t], &ascaler, rate[t], gyro_filtered[t], dT, measuredDterm_enabled); float factor = fabsf(stickinput[t]) * stabSettings.acroInsanityFactors[t]; actuatorDesiredAxis[t] = factor * stickinput[t] + (1.0f - factor) * arate; } break; + +#if !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) + case STABILIZATIONSTATUS_INNERLOOP_SYSTEMIDENT: + { + static int8_t identIteration = 0; + static float identOffsets[3] = { 0 }; + + if (PIOS_DELAY_DiffuS(systemIdentTimeVal) / 1000.0f > SYSTEM_IDENT_PERIOD) { + const float SCALE_BIAS = 7.1f; + SystemIdentStateBetaData systemIdentBeta; + + SystemIdentStateBetaGet(&systemIdentBeta); + systemIdentTimeVal = PIOS_DELAY_GetRaw(); + identOffsets[0] = 0.0f; + identOffsets[1] = 0.0f; + identOffsets[2] = 0.0f; + identIteration = (identIteration + 1) & 7; + // why does yaw change twice a cycle and roll/pitch change only once? + uint8_t index = ((uint8_t[]) { '\2', '\0', '\2', '\0', '\2', '\1', '\2', '\1' } + )[identIteration]; + float scale = expapprox(SCALE_BIAS - SystemIdentStateBetaToArray(systemIdentBeta)[index]); + // if roll or pitch limit to 25% of range + if (identIteration & 1) { + if (scale > 0.25f) { + scale = 0.25f; + } + } + // else it is yaw that can be a little more radical + else { + if (scale > 0.45f) { + scale = 0.45f; + } + } + if (identIteration & 2) { + scale = -scale; + } + identOffsets[index] = scale; + // this results in: + // when identIteration==0: identOffsets[2] = yaw_scale; + // when identIteration==1: identOffsets[0] = roll_scale; + // when identIteration==2: identOffsets[2] = -yaw_scale; + // when identIteration==3: identOffsets[0] = -roll_scale; + // when identIteration==4: identOffsets[2] = yaw_scale; + // when identIteration==5: identOffsets[1] = pitch_scale; + // when identIteration==6: identOffsets[2] = -yaw_scale; + // when identIteration==7: identOffsets[1] = -pitch_scale; + // each change has one axis with an offset + // and another axis coming back to zero from having an offset + } + + rate[t] = boundf(rate[t], + -StabilizationBankMaximumRateToArray(stabSettings.stabBank.MaximumRate)[t], + StabilizationBankMaximumRateToArray(stabSettings.stabBank.MaximumRate)[t] + ); + pid_scaler scaler = create_pid_scaler(t); + actuatorDesiredAxis[t] = pid_apply_setpoint(&stabSettings.innerPids[t], &scaler, rate[t], gyro_filtered[t], dT, measuredDterm_enabled); + actuatorDesiredAxis[t] += identOffsets[t]; + } + break; +#endif /* !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) */ + case STABILIZATIONSTATUS_INNERLOOP_DIRECT: default: actuatorDesiredAxis[t] = rate[t]; diff --git a/flight/modules/Stabilization/outerloop.c b/flight/modules/Stabilization/outerloop.c index bb44b70b2..9fc3c6e4a 100644 --- a/flight/modules/Stabilization/outerloop.c +++ b/flight/modules/Stabilization/outerloop.c @@ -64,6 +64,10 @@ static AttitudeStateData attitude; static uint8_t previous_mode[AXES] = { 255, 255, 255, 255 }; static PiOSDeltatimeConfig timeval; +static bool pitchMin = false; +static bool pitchMax = false; +static bool rollMin = false; +static bool rollMax = false; // Private functions static void stabilizationOuterloopTask(); @@ -281,31 +285,51 @@ static void stabilizationOuterloopTask() rateDesiredAxis[t] = stabilizationDesiredAxis[t]; // default for all axes // now test limits for pitch and/or roll if (t == 1) { // pitch - if (attitudeState.Pitch < -stabSettings.stabBank.PitchMax) { - // attitude exceeds pitch max. - // zero rate desired if also -ve - if (rateDesiredAxis[t] < 0.0f) { - rateDesiredAxis[t] = 0.0f; + if ((attitudeState.Pitch < -stabSettings.stabBank.PitchMax) || pitchMin) { + pitchMin = true; + // Attitude exceeds pitch min, + // Do Attitude stabilisation at min pitch angle while user still maintain negative pitch + if (stabilizationDesiredAxis[t] < 0.0f) { + local_error[t] = -stabSettings.stabBank.PitchMax - attitudeState.Pitch; + rateDesiredAxis[t] = pid_apply(&stabSettings.outerPids[t], local_error[t], dT); + } else { + // Stop Attitude stabilization and return to Rate + pitchMin = false; } - } else if (attitudeState.Pitch > stabSettings.stabBank.PitchMax) { - // attitude exceeds pitch max - // zero rate desired if also +ve - if (rateDesiredAxis[t] > 0.0f) { - rateDesiredAxis[t] = 0.0f; + } else if ((attitudeState.Pitch > stabSettings.stabBank.PitchMax) || pitchMax) { + pitchMax = true; + // Attitude exceeds pitch max + // Do Attitude stabilisation at max pitch angle while user still maintain positive pitch + if (stabilizationDesiredAxis[t] > 0.0f) { + local_error[t] = stabSettings.stabBank.PitchMax - attitudeState.Pitch; + rateDesiredAxis[t] = pid_apply(&stabSettings.outerPids[t], local_error[t], dT); + } else { + // Stop Attitude stabilization and return to Rate + pitchMax = false; } } } else if (t == 0) { // roll - if (attitudeState.Roll < -stabSettings.stabBank.RollMax) { - // attitude exceeds roll max. - // zero rate desired if also -ve - if (rateDesiredAxis[t] < 0.0f) { - rateDesiredAxis[t] = 0.0f; + if ((attitudeState.Roll < -stabSettings.stabBank.RollMax) || rollMin) { + rollMin = true; + // Attitude exceeds roll min, + // Do Attitude stabilisation at min roll angle while user still maintain negative roll + if (stabilizationDesiredAxis[t] < 0.0f) { + local_error[t] = -stabSettings.stabBank.RollMax - attitudeState.Roll; + rateDesiredAxis[t] = pid_apply(&stabSettings.outerPids[t], local_error[t], dT); + } else { + // Stop Attitude stabilization and return to Rate + rollMin = false; } - } else if (attitudeState.Roll > stabSettings.stabBank.RollMax) { - // attitude exceeds roll max - // zero rate desired if also +ve - if (rateDesiredAxis[t] > 0.0f) { - rateDesiredAxis[t] = 0.0f; + } else if ((attitudeState.Roll > stabSettings.stabBank.RollMax) || rollMax) { + rollMax = true; + // Attitude exceeds roll max + // Do Attitude stabilisation at max roll angle while user still maintain positive roll + if (stabilizationDesiredAxis[t] > 0.0f) { + local_error[t] = stabSettings.stabBank.RollMax - attitudeState.Roll; + rateDesiredAxis[t] = pid_apply(&stabSettings.outerPids[t], local_error[t], dT); + } else { + // Stop Attitude stabilization and return to Rate + rollMax = false; } } } @@ -341,14 +365,19 @@ static void stabilizationOuterloopTask() static void AttitudeStateUpdatedCb(__attribute__((unused)) UAVObjEvent *ev) { +#ifndef STABILIZATION_ATTITUDE_DOWNSAMPLED // to reduce CPU utilization, outer loop is not executed on every state update static uint8_t cpusaver = 0; if ((cpusaver++ % OUTERLOOP_SKIPCOUNT) == 0) { - // this does not need mutex protection as both eventdispatcher and stabi run in same callback task! - AttitudeStateGet(&attitude); - PIOS_CALLBACKSCHEDULER_Dispatch(callbackHandle); - } +#endif + // this does not need mutex protection as both eventdispatcher and stabi run in same callback task! + AttitudeStateGet(&attitude); + PIOS_CALLBACKSCHEDULER_Dispatch(callbackHandle); + +#ifndef STABILIZATION_ATTITUDE_DOWNSAMPLED +} +#endif } /** diff --git a/flight/modules/Stabilization/stabilization.c b/flight/modules/Stabilization/stabilization.c index d9c3c01cb..24f257d12 100644 --- a/flight/modules/Stabilization/stabilization.c +++ b/flight/modules/Stabilization/stabilization.c @@ -9,7 +9,8 @@ * @{ * * @file stabilization.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @brief Attitude stabilization module. * * @see The GNU Public License (GPL) Version 3 @@ -141,6 +142,24 @@ static void StabilizationDesiredUpdatedCb(__attribute__((unused)) UAVObjEvent *e StabilizationStatusOuterLoopToArray(status.OuterLoop)[t] = STABILIZATIONSTATUS_OUTERLOOP_DIRECTWITHLIMITS; StabilizationStatusInnerLoopToArray(status.InnerLoop)[t] = STABILIZATIONSTATUS_INNERLOOP_RATE; break; + case STABILIZATIONDESIRED_STABILIZATIONMODE_SYSTEMIDENT: +#if !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) + // roll or pitch + if (t <= 1) { + StabilizationStatusOuterLoopToArray(status.OuterLoop)[t] = STABILIZATIONSTATUS_OUTERLOOP_ATTITUDE; + } + // else yaw (other modes don't worry about invalid thrust mode either) + else { + StabilizationStatusOuterLoopToArray(status.OuterLoop)[t] = STABILIZATIONSTATUS_OUTERLOOP_DIRECT; + } + StabilizationStatusInnerLoopToArray(status.InnerLoop)[t] = STABILIZATIONSTATUS_INNERLOOP_SYSTEMIDENT; + break; +#else /* !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) */ + // no break, do not reorder this code + // for low power FCs just fall through to Attitude mode + // that means Yaw will be Attitude, but at least it is safe and creates no/minimal extra code +#endif /* !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) */ +// do not reorder this code case STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE: StabilizationStatusOuterLoopToArray(status.OuterLoop)[t] = STABILIZATIONSTATUS_OUTERLOOP_ATTITUDE; StabilizationStatusInnerLoopToArray(status.InnerLoop)[t] = STABILIZATIONSTATUS_INNERLOOP_RATE; diff --git a/flight/modules/StateEstimation/filtercf.c b/flight/modules/StateEstimation/filtercf.c index 9d5ad1374..fae8d1f8c 100644 --- a/flight/modules/StateEstimation/filtercf.c +++ b/flight/modules/StateEstimation/filtercf.c @@ -40,7 +40,7 @@ #include #include #include - +#include #include #include // Private constants @@ -49,7 +49,7 @@ #define CALIBRATION_DELAY_MS 4000 #define CALIBRATION_DURATION_MS 6000 - +#define VARIANCE_WINDOW_SIZE 40 // Private types struct data { AttitudeSettingsData attitudeSettings; @@ -70,6 +70,7 @@ struct data { int32_t starttime; uint8_t init; bool magCalibrated; + pw_variance_t gyro_var[3]; }; // Private variables @@ -158,7 +159,6 @@ static int32_t maininit(stateFilter *self) this->gyroBias[0] = 0.0f; this->gyroBias[1] = 0.0f; this->gyroBias[2] = 0.0f; - return 0; } @@ -231,6 +231,11 @@ static filterResult complementaryFilter(struct data *this, float gyro[3], float mag[1] = 0.0f; mag[2] = 0.0f; #endif + + pseudo_windowed_variance_init(&this->gyro_var[0], VARIANCE_WINDOW_SIZE); + pseudo_windowed_variance_init(&this->gyro_var[1], VARIANCE_WINDOW_SIZE); + pseudo_windowed_variance_init(&this->gyro_var[2], VARIANCE_WINDOW_SIZE); + float magBias[3]; RevoCalibrationmag_biasArrayGet(magBias); // don't trust Mag for initial orientation if it has not been calibrated @@ -282,6 +287,22 @@ static filterResult complementaryFilter(struct data *this, float gyro[3], float return FILTERRESULT_OK; // must return OK on initial initialization, so attitude will init with a valid quaternion } + // check whether copter is steady + if (this->init == 0 && this->attitudeSettings.InitialZeroWhenBoardSteady == ATTITUDESETTINGS_INITIALZEROWHENBOARDSTEADY_TRUE) { + pseudo_windowed_variance_push_sample(&this->gyro_var[0], gyro[0]); + pseudo_windowed_variance_push_sample(&this->gyro_var[1], gyro[1]); + pseudo_windowed_variance_push_sample(&this->gyro_var[2], gyro[2]); + float const gyrovarx = pseudo_windowed_variance_get(&this->gyro_var[0]); + float const gyrovary = pseudo_windowed_variance_get(&this->gyro_var[1]); + float const gyrovarz = pseudo_windowed_variance_get(&this->gyro_var[2]); + + if ((fabsf(gyrovarx) + fabsf(gyrovary) + fabsf(gyrovarz)) > this->attitudeSettings.BoardSteadyMaxVariance) { + this->starttime = xTaskGetTickCount(); + this->first_run = 1; + return FILTERRESULT_WARNING; + } + } + if (this->init == 0 && xTaskGetTickCount() - this->starttime < CALIBRATION_DELAY_MS / portTICK_RATE_MS) { // wait 4 seconds for the user to get his hands off in case the board was just powered @@ -438,16 +459,16 @@ static filterResult complementaryFilter(struct data *this, float gyro[3], float attitude[3] = -attitude[3]; } - // Renomalize - float qmag = sqrtf(attitude[0] * attitude[0] + attitude[1] * attitude[1] + attitude[2] * attitude[2] + attitude[3] * attitude[3]); - attitude[0] = attitude[0] / qmag; - attitude[1] = attitude[1] / qmag; - attitude[2] = attitude[2] / qmag; - attitude[3] = attitude[3] / qmag; + // Renormalize + float inv_qmag = invsqrtf(attitude[0] * attitude[0] + attitude[1] * attitude[1] + attitude[2] * attitude[2] + attitude[3] * attitude[3]); + attitude[0] = attitude[0] * inv_qmag; + attitude[1] = attitude[1] * inv_qmag; + attitude[2] = attitude[2] * inv_qmag; + attitude[3] = attitude[3] * inv_qmag; // If quaternion has become inappropriately short or is nan reinit. // THIS SHOULD NEVER ACTUALLY HAPPEN - if ((fabsf(qmag) < 1.0e-3f) || isnan(qmag)) { + if ((fabsf(inv_qmag) > 1e3f) || isnan(inv_qmag)) { this->first_run = 1; return FILTERRESULT_WARNING; } diff --git a/flight/modules/StateEstimation/stateestimation.c b/flight/modules/StateEstimation/stateestimation.c index 60ed1149b..72d28fb00 100644 --- a/flight/modules/StateEstimation/stateestimation.c +++ b/flight/modules/StateEstimation/stateestimation.c @@ -383,6 +383,8 @@ static void StateEstimationCb(void) switch ((RevoSettingsFusionAlgorithmOptions)revoSettings.FusionAlgorithm) { case REVOSETTINGS_FUSIONALGORITHM_BASICCOMPLEMENTARY: newFilterChain = cfQueue; + // reinit Mag alarm + AlarmsSet(SYSTEMALARMS_ALARM_MAGNETOMETER, SYSTEMALARMS_ALARM_UNINITIALISED); break; case REVOSETTINGS_FUSIONALGORITHM_COMPLEMENTARYMAG: newFilterChain = cfmiQueue; @@ -414,7 +416,7 @@ static void StateEstimationCb(void) AlarmsSet(SYSTEMALARMS_ALARM_ATTITUDE, SYSTEMALARMS_ALARM_ERROR); return; } else { - // set new fusion algortithm + // set new fusion algorithm filterChain = newFilterChain; fusionAlgorithm = revoSettings.FusionAlgorithm; } @@ -570,6 +572,7 @@ static void sensorUpdatedCb(UAVObjEvent *ev) t.x = s.x + gyroDelta[0]; t.y = s.y + gyroDelta[1]; t.z = s.z + gyroDelta[2]; + t.SensorReadTimestamp = s.SensorReadTimestamp; GyroStateSet(&t); } diff --git a/flight/modules/System/inc/systemmod.h b/flight/modules/System/inc/systemmod.h index bd709f404..5abf10d05 100644 --- a/flight/modules/System/inc/systemmod.h +++ b/flight/modules/System/inc/systemmod.h @@ -1,12 +1,13 @@ /** ****************************************************************************** - * @addtogroup OpenPilotModules OpenPilot Modules + * @addtogroup LibrePilotModules LibrePilot Modules * @{ * @addtogroup SystemModule System Module * @{ * * @file systemmod.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @brief System module * * @see The GNU Public License (GPL) Version 3 @@ -30,6 +31,6 @@ #ifndef SYSTEMMOD_H #define SYSTEMMOD_H -int32_t SystemModInitialize(void); +int32_t SystemModStart(void); #endif // SYSTEMMOD_H diff --git a/flight/modules/System/systemmod.c b/flight/modules/System/systemmod.c index 8c94ec1b1..2cf86e751 100644 --- a/flight/modules/System/systemmod.c +++ b/flight/modules/System/systemmod.c @@ -1,7 +1,7 @@ /** ****************************************************************************** - * @addtogroup OpenPilotModules OpenPilot Modules - * @brief The OpenPilot Modules do the majority of the control in OpenPilot. The + * @addtogroup LibrePilotModules LibrePilot Modules + * @brief The LibrePilot Modules do the majority of the control in LibrePilot. The * @ref SystemModule "System Module" starts all the other modules that then take care * of all the telemetry and control algorithms and such. This is done through the @ref PIOS * "PIOS Hardware abstraction layer" which then contains hardware specific implementations @@ -16,7 +16,8 @@ * @{ * * @file systemmod.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2015. * @brief System module * * @see The GNU Public License (GPL) Version 3 @@ -59,6 +60,9 @@ #include #include #include +#include +#include + #ifdef PIOS_INCLUDE_INSTRUMENTATION #include @@ -114,11 +118,17 @@ static void callbackSchedulerForEachCallback(int16_t callback_id, const struct p static void updateStats(); static void updateSystemAlarms(); static void systemTask(void *parameters); -#ifdef DIAG_I2C_WDG_STATS static void updateI2Cstats(); +#ifdef DIAG_I2C_WDG_STATS static void updateWDGstats(); #endif +#ifdef PIOS_INCLUDE_I2C +#define I2C_ERROR_ACTIVITY_TIMEOUT_SECONDS 2 +#define I2C_ERROR_ACTIVITY_TIMEOUT (I2C_ERROR_ACTIVITY_TIMEOUT_SECONDS * 1000 / SYSTEM_UPDATE_PERIOD_MS) +static uint8_t i2c_error_activity[PIOS_I2C_ERROR_COUNT_NUMELEM]; +#endif + extern uintptr_t pios_uavo_settings_fs_id; extern uintptr_t pios_user_fs_id; @@ -133,8 +143,6 @@ int32_t SystemModStart(void) mallocFailed = false; // Create system task xTaskCreate(systemTask, "System", STACK_SIZE_BYTES / 4, NULL, TASK_PRIORITY, &systemTaskHandle); - // Register task - PIOS_TASK_MONITOR_RegisterTask(TASKINFO_RUNNING_SYSTEM, systemTaskHandle); return 0; } @@ -168,8 +176,6 @@ int32_t SystemModInitialize(void) return -1; } - SystemModStart(); - return 0; } @@ -179,16 +185,31 @@ MODULE_INITCALL(SystemModInitialize, 0); */ static void systemTask(__attribute__((unused)) void *parameters) { + /* calibrate the cpu usage monitor */ + PIOS_TASK_MONITOR_CalibrateIdleCounter(); + /* board driver init */ + PIOS_Board_Init(); + + /* Initialize all modules */ + MODULE_INITIALISE_ALL; + while (!initTaskDone) { vTaskDelay(10); } +#ifndef PIOS_INCLUDE_WDG +// if no watchdog is enabled, don't reset watchdog in MODULE_TASKCREATE_ALL loop +#define PIOS_WDG_Clear() +#endif /* create all modules thread */ MODULE_TASKCREATE_ALL; /* start the delayed callback scheduler */ PIOS_CALLBACKSCHEDULER_Start(); + // Register task + PIOS_TASK_MONITOR_RegisterTask(TASKINFO_RUNNING_SYSTEM, systemTaskHandle); + if (mallocFailed) { /* We failed to malloc during task creation, * system behaviour is undefined. Reset and let @@ -219,10 +240,13 @@ static void systemTask(__attribute__((unused)) void *parameters) NotificationUpdateStatus(); // Update the system statistics updateStats(); + + // Update I2C stats + updateI2Cstats(); + // Update the system alarms updateSystemAlarms(); #ifdef DIAG_I2C_WDG_STATS - updateI2Cstats(); updateWDGstats(); #endif @@ -251,10 +275,11 @@ static void systemTask(__attribute__((unused)) void *parameters) // Update the OPLinkStatus UAVO OPLinkStatusData oplinkStatus; OPLinkStatusGet(&oplinkStatus); + oplinkStatus.HeapRemaining = xPortGetFreeHeapSize(); if (pios_rfm22b_id) { // Get the other device stats. - PIOS_RFM2B_GetPairStats(pios_rfm22b_id, oplinkStatus.PairIDs, oplinkStatus.PairSignalStrengths, OPLINKSTATUS_PAIRIDS_NUMELEM); + PIOS_RFM22B_GetPairStats(pios_rfm22b_id, oplinkStatus.PairIDs, oplinkStatus.PairSignalStrengths, OPLINKSTATUS_PAIRIDS_NUMELEM); // Get the stats from the radio device struct rfm22b_stats radio_stats; @@ -264,30 +289,38 @@ static void systemTask(__attribute__((unused)) void *parameters) static bool first_time = true; static uint16_t prev_tx_count = 0; static uint16_t prev_rx_count = 0; - oplinkStatus.HeapRemaining = xPortGetFreeHeapSize(); - oplinkStatus.DeviceID = PIOS_RFM22B_DeviceID(pios_rfm22b_id); - oplinkStatus.RxGood = radio_stats.rx_good; - oplinkStatus.RxCorrected = radio_stats.rx_corrected; - oplinkStatus.RxErrors = radio_stats.rx_error; - oplinkStatus.RxMissed = radio_stats.rx_missed; - oplinkStatus.RxFailure = radio_stats.rx_failure; - oplinkStatus.TxDropped = radio_stats.tx_dropped; - oplinkStatus.TxFailure = radio_stats.tx_failure; + static uint16_t prev_tx_seq = 0; + static uint16_t prev_rx_seq = 0; + + oplinkStatus.DeviceID = PIOS_RFM22B_DeviceID(pios_rfm22b_id); + oplinkStatus.RxGood = radio_stats.rx_good; + oplinkStatus.RxCorrected = radio_stats.rx_corrected; + oplinkStatus.RxErrors = radio_stats.rx_error; + oplinkStatus.RxMissed = radio_stats.rx_missed; + oplinkStatus.RxFailure = radio_stats.rx_failure; + oplinkStatus.TxDropped = radio_stats.tx_dropped; + oplinkStatus.TxFailure = radio_stats.tx_failure; oplinkStatus.Resets = radio_stats.resets; oplinkStatus.Timeouts = radio_stats.timeouts; - oplinkStatus.RSSI = radio_stats.rssi; + oplinkStatus.RSSI = radio_stats.rssi; oplinkStatus.LinkQuality = radio_stats.link_quality; if (first_time) { first_time = false; } else { - uint16_t tx_count = radio_stats.tx_byte_count; - uint16_t rx_count = radio_stats.rx_byte_count; - uint16_t tx_bytes = (tx_count < prev_tx_count) ? (0xffff - prev_tx_count + tx_count) : (tx_count - prev_tx_count); - uint16_t rx_bytes = (rx_count < prev_rx_count) ? (0xffff - prev_rx_count + rx_count) : (rx_count - prev_rx_count); + uint16_t tx_count = radio_stats.tx_byte_count; + uint16_t rx_count = radio_stats.rx_byte_count; + uint16_t tx_packets = radio_stats.tx_seq - prev_tx_seq; + uint16_t rx_packets = radio_stats.rx_seq - prev_rx_seq; + uint16_t tx_bytes = (tx_count < prev_tx_count) ? (0xffff - prev_tx_count + tx_count) : (tx_count - prev_tx_count); + uint16_t rx_bytes = (rx_count < prev_rx_count) ? (0xffff - prev_rx_count + rx_count) : (rx_count - prev_rx_count); oplinkStatus.TXRate = (uint16_t)((float)(tx_bytes * 1000) / SYSTEM_UPDATE_PERIOD_MS); oplinkStatus.RXRate = (uint16_t)((float)(rx_bytes * 1000) / SYSTEM_UPDATE_PERIOD_MS); + oplinkStatus.TXPacketRate = (uint16_t)((float)(tx_packets * 1000) / SYSTEM_UPDATE_PERIOD_MS); + oplinkStatus.RXPacketRate = (uint16_t)((float)(rx_packets * 1000) / SYSTEM_UPDATE_PERIOD_MS); prev_tx_count = tx_count; prev_rx_count = rx_count; + prev_tx_seq = radio_stats.tx_seq; + prev_rx_seq = radio_stats.rx_seq; } oplinkStatus.TXSeq = radio_stats.tx_seq; oplinkStatus.RXSeq = radio_stats.rx_seq; @@ -441,9 +474,11 @@ static void callbackSchedulerForEachCallback(int16_t callback_id, const struct p return; } // delayed callback scheduler reports callback stack overflows as remaininng: -1 +#if !defined(ARCH_POSIX) && !defined(ARCH_WIN32) if (callback_info->stack_remaining < 0 && stackOverflow == STACKOVERFLOW_NONE) { stackOverflow = STACKOVERFLOW_WARNING; } +#endif // By convention, there is a direct mapping between (not negative) callback scheduler callback_id's and members // of the CallbackInfoXXXXElem enums PIOS_DEBUG_Assert(callback_id < CALLBACKINFO_RUNNING_NUMELEM); @@ -454,17 +489,36 @@ static void callbackSchedulerForEachCallback(int16_t callback_id, const struct p #endif /* ifdef DIAG_TASKS */ /** - * Called periodically to update the I2C statistics + * Called periodically (every SYSTEM_UPDATE_PERIOD_MS milliseconds) to update the I2C statistics */ -#ifdef DIAG_I2C_WDG_STATS static void updateI2Cstats() { #if defined(PIOS_INCLUDE_I2C) + static uint8_t previous_error_counts[PIOS_I2C_ERROR_COUNT_NUMELEM]; + + struct pios_i2c_fault_history history; + uint8_t error_counts[PIOS_I2C_ERROR_COUNT_NUMELEM]; + + PIOS_I2C_GetDiagnostics(&history, error_counts); + + // every time a counter changes, set activity timeout counter to ( I2C_ERROR_ACTIVITY_TIMEOUT ). + // every time a counter does not change, decrease activity counter. + + for (uint8_t i = 0; i < PIOS_I2C_ERROR_COUNT_NUMELEM; i++) { + if (error_counts[i] != previous_error_counts[i]) { + i2c_error_activity[i] = I2C_ERROR_ACTIVITY_TIMEOUT; + } else if (i2c_error_activity[i] > 0) { + i2c_error_activity[i]--; + } + + previous_error_counts[i] = error_counts[i]; + } + +#ifdef DIAG_I2C_WDG_STATS I2CStatsData i2cStats; I2CStatsGet(&i2cStats); - struct pios_i2c_fault_history history; - PIOS_I2C_GetDiagnostics(&history, &i2cStats.event_errors); + memcpy(&i2cStats.event_errors, &error_counts, sizeof(error_counts)); for (uint8_t i = 0; (i < I2C_LOG_DEPTH) && (i < I2CSTATS_EVENT_LOG_NUMELEM); i++) { i2cStats.evirq_log[i] = history.evirq[i]; @@ -474,9 +528,11 @@ static void updateI2Cstats() } i2cStats.last_error_type = history.type; I2CStatsSet(&i2cStats); -#endif +#endif /* DIAG_I2C_WDG_STATS */ +#endif /* PIOS_INCLUDE_I2C */ } +#ifdef DIAG_I2C_WDG_STATS static void updateWDGstats() { WatchdogStatusData watchdogStatus; @@ -558,7 +614,9 @@ static void updateStats() stats.UsrSlotsActive = fsStats.num_active_slots; } #endif - stats.CPULoad = 100 - PIOS_TASK_MONITOR_GetIdlePercentage(); + stats.CPUIdleTicks = PIOS_TASK_MONITOR_GetIdleTicksCount(); + stats.CPUZeroLoadTicks = PIOS_TASK_MONITOR_GetZeroLoadTicksCount(); + stats.CPULoad = 100 - (uint8_t)((100 * stats.CPUIdleTicks) / stats.CPUZeroLoadTicks); #if defined(PIOS_INCLUDE_ADC) && defined(PIOS_ADC_USE_TEMP_SENSOR) float temp_voltage = PIOS_ADC_PinGetVolt(PIOS_ADC_TEMPERATURE_PIN); @@ -635,6 +693,28 @@ static void updateSystemAlarms() sysStats.ObjectManagerQueueID = objStats.lastQueueErrorID; SystemStatsSet(&sysStats); } + +#ifdef PIOS_INCLUDE_I2C + if (AlarmsGet(SYSTEMALARMS_ALARM_I2C) != SYSTEMALARMS_ALARM_UNINITIALISED) { + static const SystemAlarmsAlarmOptions i2c_alarm_by_error[] = { + [PIOS_I2C_BAD_EVENT_COUNTER] = SYSTEMALARMS_ALARM_ERROR, + [PIOS_I2C_FSM_FAULT_COUNT] = SYSTEMALARMS_ALARM_ERROR, + [PIOS_I2C_ERROR_INTERRUPT_COUNTER] = SYSTEMALARMS_ALARM_ERROR, + [PIOS_I2C_NACK_COUNTER] = SYSTEMALARMS_ALARM_CRITICAL, + [PIOS_I2C_TIMEOUT_COUNTER] = SYSTEMALARMS_ALARM_ERROR, + }; + + SystemAlarmsAlarmOptions i2c_alarm = SYSTEMALARMS_ALARM_OK; + + for (uint8_t i = 0; i < PIOS_I2C_ERROR_COUNT_NUMELEM; i++) { + if ((i2c_error_activity[i] > 0) && (i2c_alarm < i2c_alarm_by_error[i])) { + i2c_alarm = i2c_alarm_by_error[i]; + } + } + + AlarmsSet(SYSTEMALARMS_ALARM_I2C, i2c_alarm); + } +#endif /* PIOS_INCLUDE_I2C */ } /** @@ -642,6 +722,7 @@ static void updateSystemAlarms() */ void vApplicationIdleHook(void) { + PIOS_TASK_MONITOR_IdleHook(); NotificationOnboardLedsRun(); #ifdef PIOS_INCLUDE_WS2811 LedNotificationExtLedsRun(); @@ -654,6 +735,7 @@ void vApplicationIdleHook(void) void vApplicationStackOverflowHook(__attribute__((unused)) xTaskHandle *pxTask, __attribute__((unused)) signed portCHAR *pcTaskName) { +#if !defined(ARCH_POSIX) && !defined(ARCH_WIN32) stackOverflow = STACKOVERFLOW_CRITICAL; #if DEBUG_STACK_OVERFLOW static volatile bool wait_here = true; @@ -662,6 +744,7 @@ void vApplicationStackOverflowHook(__attribute__((unused)) xTaskHandle *pxTask, } wait_here = true; #endif +#endif } /** diff --git a/flight/modules/Telemetry/telemetry.c b/flight/modules/Telemetry/telemetry.c index f7839427f..9796e8f59 100644 --- a/flight/modules/Telemetry/telemetry.c +++ b/flight/modules/Telemetry/telemetry.c @@ -100,30 +100,35 @@ #ifdef PIOS_INCLUDE_RFM22B #define HAS_RADIO #endif + // Private types typedef struct { // Determine port on which to communicate telemetry information uint32_t (*getPort)(); // Main telemetry queue xQueueHandle queue; + #ifdef PIOS_TELEM_PRIORITY_QUEUE // Priority telemetry queue xQueueHandle priorityQueue; #endif /* PIOS_TELEM_PRIORITY_QUEUE */ + // Transmit/receive task handles - xTaskHandle txTaskHandle; - xTaskHandle rxTaskHandle; + xTaskHandle txTaskHandle; + xTaskHandle rxTaskHandle; // Telemetry stream UAVTalkConnection uavTalkCon; } channelContext; + #ifdef HAS_RADIO // Main telemetry channel static channelContext localChannel; static int32_t transmitLocalData(uint8_t *data, int32_t length); static void registerLocalObject(UAVObjHandle obj); static uint32_t localPort(); +#endif /* ifdef HAS_RADIO */ + static void updateSettings(channelContext *channel); -#endif // OPLink telemetry channel static channelContext radioChannel; @@ -195,6 +200,7 @@ int32_t TelemetryStart(void) localChannel.rxTaskHandle); } #endif /* ifdef HAS_RADIO */ + // Start the telemetry tasks associated with Radio/USB UAVObjIterate(®isterRadioObject); @@ -231,6 +237,7 @@ void TelemetryInitializeChannel(channelContext *channel) // Create object queues channel->queue = xQueueCreate(MAX_QUEUE_SIZE, sizeof(UAVObjEvent)); + #if defined(PIOS_TELEM_PRIORITY_QUEUE) channel->priorityQueue = xQueueCreate(MAX_QUEUE_SIZE, sizeof(UAVObjEvent)); @@ -265,7 +272,8 @@ int32_t TelemetryInitialize(void) OPLinkSettingsData data; OPLinkSettingsGet(&data); - if (data.PPMOnly) { + bool ppm_only = (data.LinkType == OPLINKSETTINGS_LINKTYPE_CONTROL); + if (ppm_only) { radio_port = 0; } else { radio_port = PIOS_COM_RF; @@ -283,6 +291,7 @@ int32_t TelemetryInitialize(void) // Reset link stats txErrors = 0; txRetries = 0; + #ifdef HAS_RADIO // Set channel port handlers localChannel.getPort = localPort; @@ -297,10 +306,14 @@ int32_t TelemetryInitialize(void) // Initialise UAVTalk localChannel.uavTalkCon = UAVTalkInitialize(&transmitLocalData); } +#endif /* ifdef HAS_RADIO */ -#endif // Set channel port handlers radioChannel.getPort = radioPort; + + // Set the channel port baud rate + updateSettings(&radioChannel); + // Initialise channel TelemetryInitializeChannel(&radioChannel); // Initialise UAVTalk @@ -310,6 +323,7 @@ int32_t TelemetryInitialize(void) } MODULE_INITCALL(TelemetryInitialize, TelemetryStart); + #ifdef HAS_RADIO /** * Register a new object, adds object to local list and connects the queue depending on the object's @@ -333,7 +347,8 @@ static void registerLocalObject(UAVObjHandle obj) EV_NONE); } } -#endif +#endif /* ifdef HAS_RADIO */ + static void registerRadioObject(UAVObjHandle obj) { if (UAVObjIsMetaobject(obj)) { @@ -459,6 +474,7 @@ static void updateObject( UAVObjConnectQueue(obj, channel->priorityQueue, eventMask); } else #endif /* PIOS_TELEM_PRIORITY_QUEUE */ + UAVObjConnectQueue(obj, channel->queue, eventMask); } @@ -584,6 +600,7 @@ static void telemetryTxTask(void *parameters) /** * Tries to empty the high priority queue before handling any standard priority item */ + #ifdef PIOS_TELEM_PRIORITY_QUEUE // empty priority queue, non-blocking while (xQueueReceive(channel->priorityQueue, &ev, 0) == pdTRUE) { @@ -650,7 +667,8 @@ static uint32_t localPort() { return PIOS_COM_TELEM_RF; } -#endif + +#endif /* ifdef HAS_RADIO */ /** * Determine the port to be used for communication on the radio channel @@ -688,7 +706,7 @@ static int32_t transmitLocalData(uint8_t *data, int32_t length) return -1; } -#endif +#endif /* ifdef HAS_RADIO */ /** * Transmit data buffer to the radioport. @@ -811,9 +829,11 @@ static void updateTelemetryStats() // Get stats UAVTalkGetStats(radioChannel.uavTalkCon, &utalkStats, true); + #ifdef HAS_RADIO UAVTalkAddStats(localChannel.uavTalkCon, &utalkStats, true); #endif + // Get object data FlightTelemetryStatsGet(&flightStats); GCSTelemetryStatsGet(&gcsStats); @@ -895,7 +915,6 @@ static void updateTelemetryStats() } } -#ifdef HAS_RADIO /** * Update the telemetry settings, called on startup. * FIXME: This should be in the TelemetrySettings object. But objects @@ -939,7 +958,6 @@ static void updateSettings(channelContext *channel) } } -#endif /* ifdef HAS_RADIO */ /** * @} * @} diff --git a/flight/modules/UAVOMSPBridge/UAVOMSPBridge.c b/flight/modules/UAVOMSPBridge/UAVOMSPBridge.c new file mode 100644 index 000000000..cb0c3fb14 --- /dev/null +++ b/flight/modules/UAVOMSPBridge/UAVOMSPBridge.c @@ -0,0 +1,1124 @@ +/** + ****************************************************************************** + * @addtogroup OpenPilotModules OpenPilot Modules + * @{ + * @addtogroup UAVOMSPBridge UAVO to MSP Bridge Module + * @{ + * + * @file uavomspbridge.c + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * Tau Labs, http://taulabs.org, Copyright (C) 2015 + * dRonin, http://dronin.org Copyright (C) 2015-2016 + * @brief Bridges selected UAVObjects to MSP for MWOSD and the like. + * + * @see The GNU Public License (GPL) Version 3 + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Additional note on redistribution: The copyright and license notices above + * must be maintained in each individual source file that is a derivative work + * of this source file; otherwise redistribution is prohibited. + */ + +#include "openpilot.h" +#include "receiverstatus.h" +#include "hwsettings.h" +#include "flightmodesettings.h" +#include "flightbatterysettings.h" +#include "flightbatterystate.h" +#include "gpspositionsensor.h" +#include "manualcontrolcommand.h" +#include "manualcontrolsettings.h" +#include "oplinkstatus.h" +#include "accessorydesired.h" +#include "attitudestate.h" +#include "airspeedstate.h" +#include "actuatorsettings.h" +#include "actuatordesired.h" +#include "flightstatus.h" +#include "systemstats.h" +#include "systemalarms.h" +#include "takeofflocation.h" +#include "homelocation.h" +#include "positionstate.h" +#include "velocitystate.h" +#include "stabilizationdesired.h" +#include "taskinfo.h" +#include "stabilizationsettings.h" +#include "stabilizationbank.h" +#include "stabilizationsettingsbank1.h" +#include "stabilizationsettingsbank2.h" +#include "stabilizationsettingsbank3.h" +#include "magstate.h" +#include "objectpersistence.h" + +#include "pios_sensors.h" + + +#define PIOS_INCLUDE_MSP_BRIDGE + +#if defined(PIOS_INCLUDE_MSP_BRIDGE) + +// oplink rssi - absolute low : -127 dBm noise floor (set by software when link is completely lost) +// in reality : around -110 dBm +// max: various articles found on web quote -10 dBm as maximum received signal power. + +#define OPLINK_LOW_RSSI -110 +#define OPLINK_HIGH_RSSI -10 + +#define MSP_SENSOR_ACC (1 << 0) +#define MSP_SENSOR_BARO (1 << 1) +#define MSP_SENSOR_MAG (1 << 2) +#define MSP_SENSOR_GPS (1 << 3) +#define MSP_SENSOR_SONAR (1 << 4) + +// Magic numbers copied from mwosd +#define MSP_IDENT 100 // multitype + multiwii version + protocol version + capability variable +#define MSP_STATUS 101 // cycletime & errors_count & sensor present & box activation & current setting number +#define MSP_RAW_IMU 102 // 9 DOF +#define MSP_SERVO 103 // 8 servos +#define MSP_MOTOR 104 // 8 motors +#define MSP_RC 105 // 8 rc chan and more +#define MSP_RAW_GPS 106 // fix, numsat, lat, lon, alt, speed, ground course +#define MSP_COMP_GPS 107 // distance home, direction home +#define MSP_ATTITUDE 108 // 2 angles 1 heading +#define MSP_ALTITUDE 109 // altitude, variometer +#define MSP_ANALOG 110 // vbat, powermetersum, rssi if available on RX +#define MSP_RC_TUNING 111 // rc rate, rc expo, rollpitch rate, yaw rate, dyn throttle PID +#define MSP_PID 112 // P I D coeff (10 are used currently) +#define MSP_BOX 113 // BOX setup (number is dependant of your setup) +#define MSP_MISC 114 // powermeter trig +#define MSP_MOTOR_PINS 115 // which pins are in use for motors & servos, for GUI +#define MSP_BOXNAMES 116 // the aux switch names +#define MSP_PIDNAMES 117 // the PID names +#define MSP_BOXIDS 119 // get the permanent IDs associated to BOXes +#define MSP_NAV_STATUS 121 // Returns navigation status +#define MSP_CELLS 130 // FrSky SPort Telemtry +#define MSP_ALARMS 242 // Alarm request + +#define MSP_SET_PID 202 // set P I D coeff + +typedef enum { + MSP_BOX_ID_ARM, + MSP_BOX_ID_ANGLE, // mode.stable (attitude??) - [sensor icon] [ fligth mode icon ] + MSP_BOX_ID_HORIZON, // [sensor icon] [ flight mode icon ] + MSP_BOX_ID_BARO, // [sensor icon] + MSP_BOX_ID_VARIO, + MSP_BOX_ID_MAG, // [sensor icon] + MSP_BOX_ID_HEADFREE, + MSP_BOX_ID_HEADADJ, + MSP_BOX_ID_CAMSTAB, // [gimbal icon] + MSP_BOX_ID_CAMTRIG, + MSP_BOX_ID_GPSHOME, // [ flight mode icon ] + MSP_BOX_ID_GPSHOLD, // [ flight mode icon ] + MSP_BOX_ID_PASSTHRU, // [ flight mode icon ] + MSP_BOX_ID_BEEPER, + MSP_BOX_ID_LEDMAX, + MSP_BOX_ID_LEDLOW, + MSP_BOX_ID_LLIGHTS, // landing lights + MSP_BOX_ID_CALIB, + MSP_BOX_ID_GOVERNOR, + MSP_BOX_ID_OSD_SWITCH, // OSD on or off, maybe. + MSP_BOX_ID_GPSMISSION, // [ flight mode icon ] + MSP_BOX_ID_GPSLAND, // [ flight mode icon ] + + MSP_BOX_ID_AIR = 28, // this box will add AIRMODE icon to flight mode. + MSP_BOX_ID_ACROPLUS = 29, // this will add PLUS icon to ACRO. ACRO = !ANGLE && !HORIZON +} msp_boxid_t; + +enum { + MSP_STATUS_ARMED, + MSP_STATUS_FLIGHTMODE_STABILIZED, + MSP_STATUS_FLIGHTMODE_HORIZON, + MSP_STATUS_SENSOR_BARO, + MSP_STATUS_SENSOR_MAG, + MSP_STATUS_MISC_GIMBAL, + MSP_STATUS_FLIGHTMODE_GPSHOME, + MSP_STATUS_FLIGHTMODE_GPSHOLD, + MSP_STATUS_FLIGHTMODE_GPSMISSION, + MSP_STATUS_FLIGHTMODE_GPSLAND, + MSP_STATUS_FLIGHTMODE_PASSTHRU, + MSP_STATUS_OSD_SWITCH, + MSP_STATUS_ICON_AIRMODE, + MSP_STATUS_ICON_ACROPLUS, +}; + +static const uint8_t msp_boxes[] = { + [MSP_STATUS_ARMED] = MSP_BOX_ID_ARM, + [MSP_STATUS_FLIGHTMODE_STABILIZED] = MSP_BOX_ID_ANGLE, // flight mode + [MSP_STATUS_FLIGHTMODE_HORIZON] = MSP_BOX_ID_HORIZON, // flight mode + [MSP_STATUS_SENSOR_BARO] = MSP_BOX_ID_BARO, // sensor icon only + [MSP_STATUS_SENSOR_MAG] = MSP_BOX_ID_MAG, // sensor icon only + [MSP_STATUS_MISC_GIMBAL] = MSP_BOX_ID_CAMSTAB, // gimbal icon only + [MSP_STATUS_FLIGHTMODE_GPSHOME] = MSP_BOX_ID_GPSHOME, // flight mode + [MSP_STATUS_FLIGHTMODE_GPSHOLD] = MSP_BOX_ID_GPSHOLD, // flight mode + [MSP_STATUS_FLIGHTMODE_GPSMISSION] = MSP_BOX_ID_GPSMISSION, // flight mode + [MSP_STATUS_FLIGHTMODE_GPSLAND] = MSP_BOX_ID_GPSLAND, // flight mode + [MSP_STATUS_FLIGHTMODE_PASSTHRU] = MSP_BOX_ID_PASSTHRU, // flight mode + [MSP_STATUS_OSD_SWITCH] = MSP_BOX_ID_OSD_SWITCH, // switch OSD mode + [MSP_STATUS_ICON_AIRMODE] = MSP_BOX_ID_AIR, + [MSP_STATUS_ICON_ACROPLUS] = MSP_BOX_ID_ACROPLUS, +}; + +typedef enum { + MSP_IDLE, + MSP_HEADER_START, + MSP_HEADER_M, + MSP_HEADER_SIZE, + MSP_HEADER_CMD, + MSP_FILLBUF, + MSP_CHECKSUM, + MSP_DISCARD, + MSP_MAYBE_UAVTALK2, + MSP_MAYBE_UAVTALK3, + MSP_MAYBE_UAVTALK4, + MSP_MAYBE_UAVTALK_SLOW2, + MSP_MAYBE_UAVTALK_SLOW3, + MSP_MAYBE_UAVTALK_SLOW4, + MSP_MAYBE_UAVTALK_SLOW5, + MSP_MAYBE_UAVTALK_SLOW6 +} msp_state; + + +typedef struct __attribute__((packed)) { + uint8_t values[3]; +} +msp_pid_t; + +typedef enum { + PIDROLL, + PIDPITCH, + PIDYAW, + PIDAROLL, // (PIDALT) use this for Attitude ROLL + PIDAPITCH, // (PIDPOS) use this for Attitude PITCH + PIDPOSR, // skipped by MWOSD + PIDNAVR, // skipped by MWOSD + PIDAYAW, // (PIDLEVEL) use this for Attitude YAW + PIDMAG, // unused for now + PIDVEL, // skipped by MWOSD + PID_ITEM_COUNT +} pidIndex_e; + +static const char msp_pidnames[] = "ROLL;" + "PITCH;" + "YAW;" + "A.ROLL;" + "A.PITCH;" + "PosR;" + "NavR;" + "A.YAW;" + "MAG;" + "VEL;"; + +#define MSP_ANALOG_VOLTAGE (1 << 0) +#define MSP_ANALOG_CURRENT (1 << 1) + +struct msp_bridge { + uintptr_t com; + + uint8_t sensors; + uint8_t analog; + + UAVObjHandle current_pid_bank; + + msp_state state; + uint8_t cmd_size; + uint8_t cmd_id; + uint8_t cmd_i; + uint8_t checksum; + union { + uint8_t data[0]; + // Specific packed data structures go here. + msp_pid_t piditems[PID_ITEM_COUNT]; + } cmd_data; +}; + +#if defined(PIOS_MSP_STACK_SIZE) +#define STACK_SIZE_BYTES PIOS_MSP_STACK_SIZE +#else +#define STACK_SIZE_BYTES 768 +#endif +#define TASK_PRIORITY (tskIDLE_PRIORITY) + +#define MAX_ALARM_LEN 30 + +#define BOOT_DISPLAY_TIME_MS (10 * 1000) + +static bool module_enabled = false; +static struct msp_bridge *msp; +static int32_t uavoMSPBridgeInitialize(void); +static void uavoMSPBridgeTask(void *parameters); + +static void msp_send(struct msp_bridge *m, uint8_t cmd, const uint8_t *data, size_t len) +{ + uint8_t buf[5]; + uint8_t cs = (uint8_t)(len) ^ cmd; + + buf[0] = '$'; + buf[1] = 'M'; + buf[2] = '>'; + buf[3] = (uint8_t)(len); + buf[4] = cmd; + + PIOS_COM_SendBuffer(m->com, buf, sizeof(buf)); + + if (len > 0) { + PIOS_COM_SendBuffer(m->com, data, len); + + for (unsigned i = 0; i < len; i++) { + cs ^= data[i]; + } + } + + cs ^= 0; + + buf[0] = cs; + PIOS_COM_SendBuffer(m->com, buf, 1); +} + +static msp_state msp_state_size(struct msp_bridge *m, uint8_t b) +{ + m->cmd_size = b; + m->checksum = b; + return MSP_HEADER_CMD; +} + +static msp_state msp_state_cmd(struct msp_bridge *m, uint8_t b) +{ + m->cmd_i = 0; + m->cmd_id = b; + m->checksum ^= m->cmd_id; + + if (m->cmd_size > sizeof(m->cmd_data)) { + // Too large a body. Let's ignore it. + return MSP_DISCARD; + } + + return m->cmd_size == 0 ? MSP_CHECKSUM : MSP_FILLBUF; +} + +static msp_state msp_state_fill_buf(struct msp_bridge *m, uint8_t b) +{ + m->cmd_data.data[m->cmd_i++] = b; + m->checksum ^= b; + return m->cmd_i == m->cmd_size ? MSP_CHECKSUM : MSP_FILLBUF; +} + +static void msp_send_attitude(struct msp_bridge *m) +{ + union { + uint8_t buf[0]; + struct { + int16_t x; + int16_t y; + int16_t h; + } att; + } data; + AttitudeStateData attState; + + AttitudeStateGet(&attState); + + // Roll and Pitch are in 10ths of a degree. + data.att.x = attState.Roll * 10; + data.att.y = attState.Pitch * -10; + // Yaw is just -180 -> 180 + data.att.h = attState.Yaw; + + msp_send(m, MSP_ATTITUDE, data.buf, sizeof(data)); +} + +#define IS_STAB_MODE(d, m) (((d).Roll == (m)) && ((d).Pitch == (m))) + +static void msp_send_status(struct msp_bridge *m) +{ + union { + uint8_t buf[0]; + struct { + uint16_t cycleTime; + uint16_t i2cErrors; + uint16_t sensors; + uint32_t flags; + uint8_t setting; + } __attribute__((packed)) status; + } data; + // TODO: https://github.com/TauLabs/TauLabs/blob/next/shared/uavobjectdefinition/actuatordesired.xml#L8 + data.status.cycleTime = 0; + data.status.i2cErrors = 0; + + data.status.sensors = m->sensors; + + if (GPSPositionSensorHandle() != NULL) { + GPSPositionSensorStatusOptions gpsStatus; + GPSPositionSensorStatusGet(&gpsStatus); + + if (gpsStatus != GPSPOSITIONSENSOR_STATUS_NOGPS) { + data.status.sensors |= MSP_SENSOR_GPS; + } + } + + data.status.flags = 0; + data.status.setting = 0; + + FlightStatusData flightStatus; + FlightStatusGet(&flightStatus); + + StabilizationDesiredStabilizationModeData stabModeData; + StabilizationDesiredStabilizationModeGet(&stabModeData); + + if (flightStatus.Armed == FLIGHTSTATUS_ARMED_ARMED) { + data.status.flags |= (1 << MSP_STATUS_ARMED); + } + + // flightmode + + if (flightStatus.FlightMode == FLIGHTSTATUS_FLIGHTMODE_POSITIONHOLD) { + data.status.flags |= (1 << MSP_STATUS_FLIGHTMODE_GPSHOLD); + } else if (flightStatus.FlightMode == FLIGHTSTATUS_FLIGHTMODE_RETURNTOBASE) { + data.status.flags |= (1 << MSP_STATUS_FLIGHTMODE_GPSHOME); + } else if (flightStatus.FlightMode == FLIGHTSTATUS_FLIGHTMODE_PATHPLANNER) { + data.status.flags |= (1 << MSP_STATUS_FLIGHTMODE_GPSMISSION); + } else if (flightStatus.FlightMode == FLIGHTSTATUS_FLIGHTMODE_LAND) { + data.status.flags |= (1 << MSP_STATUS_FLIGHTMODE_GPSLAND); + } else if (flightStatus.FlightMode == FLIGHTSTATUS_FLIGHTMODE_MANUAL) { + data.status.flags |= (1 << MSP_STATUS_FLIGHTMODE_PASSTHRU); + } else { // + // if Roll(Rate) && Pitch(Rate) => Acro + // if Roll(Acro+) && Pitch(Acro+) => Acro+ + // if Roll(Rattitude) && Pitch(Rattitude) => Horizon + // else => Stabilized + + if (IS_STAB_MODE(stabModeData, STABILIZATIONDESIRED_STABILIZATIONMODE_RATE) + || IS_STAB_MODE(stabModeData, STABILIZATIONDESIRED_STABILIZATIONMODE_RATETRAINER)) { + // data.status.flags should not set any mode flags + } else if (IS_STAB_MODE(stabModeData, STABILIZATIONDESIRED_STABILIZATIONMODE_ACRO)) { // this is Acro+ mode + data.status.flags |= (1 << MSP_STATUS_ICON_ACROPLUS); + } else if (IS_STAB_MODE(stabModeData, STABILIZATIONDESIRED_STABILIZATIONMODE_RATTITUDE)) { + data.status.flags |= (1 << MSP_STATUS_FLIGHTMODE_HORIZON); + } else { // looks like stabilized mode, whichever it is.. + data.status.flags |= (1 << MSP_STATUS_FLIGHTMODE_STABILIZED); + } + } + + // sensors in use? + // flight mode HORIZON or STABILIZED will turn on Accelerometer icon. + // Barometer? + + if ((stabModeData.Thrust == STABILIZATIONDESIRED_STABILIZATIONMODE_ALTITUDEHOLD) + || (stabModeData.Thrust == STABILIZATIONDESIRED_STABILIZATIONMODE_ALTITUDEVARIO)) { + data.status.flags |= (1 << MSP_STATUS_SENSOR_BARO); + } + +#ifndef PIOS_EXCLUDE_ADVANCED_FEATURES + if (MagStateHandle() != NULL) { + MagStateSourceOptions magSource; + MagStateSourceGet(&magSource); + + if (magSource != MAGSTATE_SOURCE_INVALID) { + data.status.flags |= (1 << MSP_STATUS_SENSOR_MAG); + } + } +#endif /* PIOS_EXCLUDE_ADVANCED_FEATURES */ + + if (flightStatus.AlwaysStabilizeWhenArmed == FLIGHTSTATUS_ALWAYSSTABILIZEWHENARMED_TRUE) { + data.status.flags |= (1 << MSP_STATUS_ICON_AIRMODE); + } + + msp_send(m, MSP_STATUS, data.buf, sizeof(data)); +} + +static void msp_send_analog(struct msp_bridge *m) +{ + union { + uint8_t buf[0]; + struct { + uint8_t vbat; + uint16_t powerMeterSum; + uint16_t rssi; + uint16_t current; + } __attribute__((packed)) status; + } data; + + memset(&data, 0, sizeof(data)); + +#ifndef PIOS_EXCLUDE_ADVANCED_FEATURES + if (FlightBatteryStateHandle() != NULL) { + FlightBatteryStateData batState; + FlightBatteryStateGet(&batState); + + if (m->analog & MSP_ANALOG_VOLTAGE) { + data.status.vbat = (uint8_t)lroundf(batState.Voltage * 10); + } + if (m->analog & MSP_ANALOG_CURRENT) { + data.status.current = lroundf(batState.Current * 100); + data.status.powerMeterSum = lroundf(batState.ConsumedEnergy); + } + } +#endif + // OPLink supports RSSI reported in dBm, but updates different value in ReceiverStatus.Quality (link_quality - function of lost, repaired and good packet count). + // We use same method as in Receiver module to decide if oplink is used for control: + // Check for Throttle channel group, if this belongs to oplink, we will use oplink rssi instead of ReceiverStatus.Quality. + + ManualControlSettingsChannelGroupsData channelGroups; + ManualControlSettingsChannelGroupsGet(&channelGroups); + +#ifdef PIOS_INCLUDE_OPLINKRCVR + if (channelGroups.Throttle == MANUALCONTROLSETTINGS_CHANNELGROUPS_OPLINK) { + int8_t rssi; + OPLinkStatusRSSIGet(&rssi); + + // MSP values have no units, and OSD rssi display requires calibration anyway, so we will translate OPLINK_LOW_RSSI to OPLINK_HIGH_RSSI -> 0-1023 + if (rssi < OPLINK_LOW_RSSI) { + rssi = OPLINK_LOW_RSSI; + } else if (rssi > OPLINK_HIGH_RSSI) { + rssi = OPLINK_HIGH_RSSI; + } + + data.status.rssi = ((rssi - OPLINK_LOW_RSSI) * 1023) / (OPLINK_HIGH_RSSI - OPLINK_LOW_RSSI); + } else { +#endif /* PIOS_INCLUDE_OPLINKRCVR */ + uint8_t quality; + ReceiverStatusQualityGet(&quality); + + // MSP RSSI's range is 0-1023 + data.status.rssi = (quality * 1023) / 100; +#ifdef PIOS_INCLUDE_OPLINKRCVR +} +#endif /* PIOS_INCLUDE_OPLINKRCVR */ + + if (data.status.rssi > 1023) { + data.status.rssi = 1023; + } + + msp_send(m, MSP_ANALOG, data.buf, sizeof(data)); +} + +static void msp_send_raw_gps(struct msp_bridge *m) +{ + union { + uint8_t buf[0]; + struct { + uint8_t fix; // 0 or 1 + uint8_t num_sat; + int32_t lat; // 1 / 10 000 000 deg + int32_t lon; // 1 / 10 000 000 deg + uint16_t alt; // meter + uint16_t speed; // cm/s + int16_t ground_course; // degree * 10 + } __attribute__((packed)) raw_gps; + } data; + + GPSPositionSensorData gps_data; + + if (GPSPositionSensorHandle() != NULL) { + GPSPositionSensorGet(&gps_data); + + data.raw_gps.fix = (gps_data.Status >= GPSPOSITIONSENSOR_STATUS_FIX2D ? 1 : 0); // Data will display on OSD if 2D fix or better + data.raw_gps.num_sat = gps_data.Satellites; + data.raw_gps.lat = gps_data.Latitude; + data.raw_gps.lon = gps_data.Longitude; + data.raw_gps.alt = (uint16_t)gps_data.Altitude; + data.raw_gps.speed = (uint16_t)gps_data.Groundspeed; + data.raw_gps.ground_course = (int16_t)(gps_data.Heading * 10.0f); + + msp_send(m, MSP_RAW_GPS, data.buf, sizeof(data)); + } +} + +#ifndef PIOS_EXCLUDE_ADVANCED_FEATURES + +static inline float Sq(float x) +{ + return x * x; +} + +static void msp_send_comp_gps(struct msp_bridge *m) +{ + union { + uint8_t buf[0]; + struct { + uint16_t distance_to_home; // meter + int16_t direction_to_home; // degree [-180:180] + uint8_t home_position_valid; // 0 = Invalid, Dronin MSP specific + } __attribute__((packed)) comp_gps; + } data; + + data.comp_gps.distance_to_home = 0; + data.comp_gps.direction_to_home = 0; + data.comp_gps.home_position_valid = 0; // Home distance and direction will not display on OSD + + if (PositionStateHandle() && TakeOffLocationHandle()) { + TakeOffLocationData takeOffLocation; + TakeOffLocationGet(&takeOffLocation); + + if (takeOffLocation.Status == TAKEOFFLOCATION_STATUS_VALID) { + PositionStateData positionState; + PositionStateGet(&positionState); + + data.comp_gps.distance_to_home = (uint16_t)sqrtf(Sq(takeOffLocation.East - positionState.East) + Sq(takeOffLocation.North - positionState.North)); + data.comp_gps.direction_to_home = RAD2DEG(atan2f(takeOffLocation.East - positionState.East, takeOffLocation.North - positionState.North)); + + data.comp_gps.home_position_valid = 1; + } + } + + // here, CC3D implementation could use raw gps data (GPSPositionSensorData) and locally cached GPSPositionSensorData at arming time as TakeOffLocation. + + + msp_send(m, MSP_COMP_GPS, data.buf, sizeof(data)); +} + +static void msp_send_altitude(struct msp_bridge *m) +{ + union { + uint8_t buf[0]; + struct { + int32_t estimatedAltitude; // cm + int16_t vario; // cm/s + } __attribute__((packed)) altitude; + } data; + + + if (PositionStateHandle() != NULL) { + PositionStateData positionState; + PositionStateGet(&positionState); + + data.altitude.estimatedAltitude = (int32_t)roundf(positionState.Down * -100.0f); + } else { + data.altitude.estimatedAltitude = 0; + } + + if (VelocityStateHandle() != NULL) { + VelocityStateData velocityState; + VelocityStateGet(&velocityState); + + data.altitude.vario = (int16_t)roundf(velocityState.Down * -100.0f); + } else { + data.altitude.vario = 0; + } + + msp_send(m, MSP_ALTITUDE, data.buf, sizeof(data)); +} +#endif /* PIOS_EXCLUDE_ADVANCED_FEATURES */ + + +// Scale stick values whose input range is -1 to 1 to MSP's expected +// PWM range of 1000-2000. +static uint16_t msp_scale_rc(float percent) +{ + return percent * 500 + 1500; +} + +// Throttle maps to 1100-1900 and a bit differently as -1 == 1000 and +// then jumps immediately to 0 -> 1 for the rest of the range. MWOSD +// can learn ranges as wide as they are sent, but defaults to +// 1100-1900 so the throttle indicator will vary for the same stick +// position unless we send it what it wants right away. +static uint16_t msp_scale_rc_thr(float percent) +{ + return percent <= 0 ? 1100 : percent * 800 + 1100; +} + +// MSP RC order is Roll/Pitch/Yaw/Throttle/AUX1/AUX2/AUX3/AUX4 +static void msp_send_channels(struct msp_bridge *m) +{ + AccessoryDesiredData acc0, acc1, acc2, acc3; + ManualControlCommandData manualState; + + ManualControlCommandGet(&manualState); + AccessoryDesiredInstGet(0, &acc0); + AccessoryDesiredInstGet(1, &acc1); + AccessoryDesiredInstGet(2, &acc2); + AccessoryDesiredInstGet(3, &acc3); + + union { + uint8_t buf[0]; + uint16_t channels[8]; + } data = { + .channels = { + msp_scale_rc(manualState.Roll), + msp_scale_rc(manualState.Pitch * -1), // TL pitch is backwards + msp_scale_rc(manualState.Yaw), + msp_scale_rc_thr(manualState.Throttle), + msp_scale_rc(acc0.AccessoryVal), + msp_scale_rc(acc1.AccessoryVal), + msp_scale_rc(acc2.AccessoryVal), + msp_scale_rc(acc3.AccessoryVal), + } + }; + + msp_send(m, MSP_RC, data.buf, sizeof(data)); +} + +static void msp_send_boxids(struct msp_bridge *m) // This is actually sending a map of MSP_STATUS.flag bits to BOX ids. +{ + msp_send(m, MSP_BOXIDS, msp_boxes, sizeof(msp_boxes)); +} + +static void msp_send_pidnames(struct msp_bridge *m) +{ + msp_send(m, MSP_PIDNAMES, (const uint8_t *)msp_pidnames, sizeof(msp_pidnames) - 1); // without terminating 0 +} + +static void pid_native2msp(const float *native, msp_pid_t *piditem, float scale, unsigned numelem) +{ + for (unsigned i = 0; i < numelem; ++i) { + piditem->values[i] = lroundf(native[i] * scale); + } +} + +static void pid_msp2native(const msp_pid_t *piditem, float *native, float scale, unsigned numelem) +{ + for (unsigned i = 0; i < numelem; ++i) { + native[i] = (float)piditem->values[i] / scale; + } +} + +static UAVObjHandle get_current_pid_bank_handle() +{ + uint8_t fm; + + ManualControlCommandFlightModeSwitchPositionGet(&fm); + + if (fm >= FLIGHTMODESETTINGS_FLIGHTMODEPOSITION_NUMELEM) { + return STABILIZATIONSETTINGS_FLIGHTMODEMAP_BANK1; + } + + StabilizationSettingsFlightModeMapOptions flightModeMap[STABILIZATIONSETTINGS_FLIGHTMODEMAP_NUMELEM]; + StabilizationSettingsFlightModeMapGet(flightModeMap); + + switch (flightModeMap[fm]) { + case STABILIZATIONSETTINGS_FLIGHTMODEMAP_BANK1: + return StabilizationSettingsBank1Handle(); + + case STABILIZATIONSETTINGS_FLIGHTMODEMAP_BANK2: + return StabilizationSettingsBank2Handle(); + + case STABILIZATIONSETTINGS_FLIGHTMODEMAP_BANK3: + return StabilizationSettingsBank3Handle(); + } + + return 0; +} + +static void msp_send_pid(struct msp_bridge *m) +{ + m->current_pid_bank = get_current_pid_bank_handle(); + + StabilizationBankData bankData; + UAVObjGetData(m->current_pid_bank, &bankData); + + msp_pid_t piditems[PID_ITEM_COUNT]; + + memset(piditems, 0, sizeof(piditems)); + + pid_native2msp((float *)&bankData.RollRatePID, &piditems[PIDROLL], 10000, 3); + pid_native2msp((float *)&bankData.PitchRatePID, &piditems[PIDPITCH], 10000, 3); + pid_native2msp((float *)&bankData.YawRatePID, &piditems[PIDYAW], 10000, 3); + + pid_native2msp((float *)&bankData.RollPI, &piditems[PIDAROLL], 10, 2); + pid_native2msp((float *)&bankData.PitchPI, &piditems[PIDAPITCH], 10, 2); + pid_native2msp((float *)&bankData.YawPI, &piditems[PIDAYAW], 10, 2); + + msp_send(m, MSP_PID, (const uint8_t *)piditems, sizeof(piditems)); +} + +static void msp_set_pid(struct msp_bridge *m) +{ + if (m->current_pid_bank == 0) { + return; + } + + StabilizationBankData bankData; + UAVObjGetData(m->current_pid_bank, &bankData); + + pid_msp2native(&m->cmd_data.piditems[PIDROLL], (float *)&bankData.RollRatePID, 10000, 3); + pid_msp2native(&m->cmd_data.piditems[PIDPITCH], (float *)&bankData.PitchRatePID, 10000, 3); + pid_msp2native(&m->cmd_data.piditems[PIDYAW], (float *)&bankData.YawRatePID, 10000, 3); + + pid_msp2native(&m->cmd_data.piditems[PIDAROLL], (float *)&bankData.RollPI, 10, 2); + pid_msp2native(&m->cmd_data.piditems[PIDAPITCH], (float *)&bankData.PitchPI, 10, 2); + pid_msp2native(&m->cmd_data.piditems[PIDAYAW], (float *)&bankData.YawPI, 10, 2); + + UAVObjSetData(m->current_pid_bank, &bankData); + + bool needSave = true; + + if (needSave) { + FlightStatusArmedOptions armed; + FlightStatusArmedGet(&armed); + + if (armed == FLIGHTSTATUS_ARMED_DISARMED) { + ObjectPersistenceData op; + + op.ObjectID = UAVObjGetID(m->current_pid_bank); + op.InstanceID = 0; + op.Selection = OBJECTPERSISTENCE_SELECTION_SINGLEOBJECT; + op.Operation = OBJECTPERSISTENCE_OPERATION_SAVE; + + ObjectPersistenceSet(&op); + } + } + + msp_send(m, MSP_SET_PID, 0, 0); // send ack. +} + +#define ALARM_OK 0 +#define ALARM_WARN 1 +#define ALARM_ERROR 2 +#define ALARM_CRIT 3 + +#define MS2TICKS(m) ((m) / (portTICK_RATE_MS)) + +static void msp_send_alarms(__attribute__((unused)) struct msp_bridge *m) +{ + union { + uint8_t buf[0]; + struct { + uint8_t state; + char msg[MAX_ALARM_LEN]; + } __attribute__((packed)) alarm; + } data; + + SystemAlarmsData alarm; + SystemAlarmsGet(&alarm); + + // Special case early boot times -- just report boot reason + +#if 0 + if (xTaskGetTickCount() < MS2TICKS(10 * 1000)) { + data.alarm.state = ALARM_CRIT; + const char *boot_reason = AlarmBootReason(alarm.RebootCause); + strncpy((char *)data.alarm.msg, boot_reason, MAX_ALARM_LEN); + data.alarm.msg[MAX_ALARM_LEN - 1] = '\0'; + msp_send(m, MSP_ALARMS, data.buf, strlen((char *)data.alarm.msg) + 1); + return; + } +#endif + + uint8_t state; + data.alarm.state = ALARM_OK; + int32_t len = AlarmString(&alarm, data.alarm.msg, + sizeof(data.alarm.msg), SYSTEMALARMS_ALARM_CRITICAL, &state); // Include only CRITICAL and ERROR + + // NOTE: LP alarm severity levels and MSP levels do not match. ERROR and CRITICAL are swapped. + // So far, MW-OSD code (MSP consumer) does not make difference between ALARM_ERROR and ALARM_CRITICAL. + // ALARM_WARN should be blinking if thats the highest severity level at the moment. + // There might be other types of MSP consumers. + + switch (state) { + case SYSTEMALARMS_ALARM_WARNING: + data.alarm.state = ALARM_WARN; + break; + case SYSTEMALARMS_ALARM_ERROR: + data.alarm.state = ALARM_CRIT; + break; + case SYSTEMALARMS_ALARM_CRITICAL: + data.alarm.state = ALARM_ERROR; + break; + } + + msp_send(m, MSP_ALARMS, data.buf, len + 1); +} + +static msp_state msp_state_checksum(struct msp_bridge *m, uint8_t b) +{ + if ((m->checksum ^ b) != 0) { + return MSP_IDLE; + } + + // Respond to interesting things. + switch (m->cmd_id) { + case MSP_RAW_GPS: + msp_send_raw_gps(m); + break; +#ifndef PIOS_EXCLUDE_ADVANCED_FEATURES + case MSP_COMP_GPS: + msp_send_comp_gps(m); + break; + case MSP_ALTITUDE: + msp_send_altitude(m); + break; +#endif /* PIOS_EXCLUDE_ADVANCED_FEATURES */ + case MSP_ATTITUDE: + msp_send_attitude(m); + break; + case MSP_STATUS: + msp_send_status(m); + break; + case MSP_ANALOG: + msp_send_analog(m); + break; + case MSP_RC: + msp_send_channels(m); + break; + case MSP_BOXIDS: + msp_send_boxids(m); + break; + case MSP_ALARMS: + msp_send_alarms(m); + break; + case MSP_PID: + msp_send_pid(m); + break; + case MSP_SET_PID: + msp_set_pid(m); + break; + case MSP_PIDNAMES: + msp_send_pidnames(m); + break; + } + + return MSP_IDLE; +} + +static msp_state msp_state_discard(struct msp_bridge *m, __attribute__((unused)) uint8_t b) +{ + return m->cmd_i++ == m->cmd_size ? MSP_IDLE : MSP_DISCARD; +} + +/** + * Process incoming bytes from an MSP query thing. + * @param[in] b received byte + * @return true if we should continue processing bytes + */ +static bool msp_receive_byte(struct msp_bridge *m, uint8_t b) +{ + switch (m->state) { + case MSP_IDLE: + switch (b) { + case 0xe0: // uavtalk matching first part of 0x3c @ 57600 baud + m->state = MSP_MAYBE_UAVTALK_SLOW2; + break; + case '<': // uavtalk matching with 0x3c 0x2x 0xxx 0x0x + m->state = MSP_MAYBE_UAVTALK2; + break; + case '$': + m->state = MSP_HEADER_START; + break; + default: + m->state = MSP_IDLE; + } + break; + case MSP_HEADER_START: + m->state = b == 'M' ? MSP_HEADER_M : MSP_IDLE; + break; + case MSP_HEADER_M: + m->state = b == '<' ? MSP_HEADER_SIZE : MSP_IDLE; + break; + case MSP_HEADER_SIZE: + m->state = msp_state_size(m, b); + break; + case MSP_HEADER_CMD: + m->state = msp_state_cmd(m, b); + break; + case MSP_FILLBUF: + m->state = msp_state_fill_buf(m, b); + break; + case MSP_CHECKSUM: + m->state = msp_state_checksum(m, b); + break; + case MSP_DISCARD: + m->state = msp_state_discard(m, b); + break; + case MSP_MAYBE_UAVTALK2: + // e.g. 3c 20 1d 00 + // second possible uavtalk byte + m->state = (b & 0xf0) == 0x20 ? MSP_MAYBE_UAVTALK3 : MSP_IDLE; + break; + case MSP_MAYBE_UAVTALK3: + // third possible uavtalk byte can be anything + m->state = MSP_MAYBE_UAVTALK4; + break; + case MSP_MAYBE_UAVTALK4: + m->state = MSP_IDLE; + // If this looks like the fourth possible uavtalk byte, we're done + if ((b & 0xf0) == 0) { + PIOS_COM_TELEM_RF = m->com; + return false; + } + break; + case MSP_MAYBE_UAVTALK_SLOW2: + m->state = b == 0x18 ? MSP_MAYBE_UAVTALK_SLOW3 : MSP_IDLE; + break; + case MSP_MAYBE_UAVTALK_SLOW3: + m->state = b == 0x98 ? MSP_MAYBE_UAVTALK_SLOW4 : MSP_IDLE; + break; + case MSP_MAYBE_UAVTALK_SLOW4: + m->state = b == 0x7e ? MSP_MAYBE_UAVTALK_SLOW5 : MSP_IDLE; + break; + case MSP_MAYBE_UAVTALK_SLOW5: + m->state = b == 0x00 ? MSP_MAYBE_UAVTALK_SLOW6 : MSP_IDLE; + break; + case MSP_MAYBE_UAVTALK_SLOW6: + m->state = MSP_IDLE; + // If this looks like the sixth possible 57600 baud uavtalk byte, we're done + if (b == 0x60) { + PIOS_COM_ChangeBaud(m->com, 57600); + PIOS_COM_TELEM_RF = m->com; + return false; + } + break; + } + + return true; +} + +/** + * Module start routine automatically called after initialization routine + * @return 0 when was successful + */ +static int32_t uavoMSPBridgeStart(void) +{ + if (!module_enabled) { + // give port to telemetry if it doesn't have one + // stops board getting stuck in condition where it can't be connected to gcs + if (!PIOS_COM_TELEM_RF) { + PIOS_COM_TELEM_RF = pios_com_msp_id; + } + + return -1; + } + + xTaskHandle taskHandle; + + xTaskCreate(uavoMSPBridgeTask, "uavoMSPBridge", STACK_SIZE_BYTES / 4, NULL, TASK_PRIORITY, &taskHandle); + PIOS_TASK_MONITOR_RegisterTask(TASKINFO_RUNNING_UAVOMSPBRIDGE, taskHandle); + + return 0; +} + +static uint32_t hwsettings_mspspeed_enum_to_baud(uint8_t baud) +{ + switch (baud) { + case HWSETTINGS_MSPSPEED_2400: + return 2400; + + case HWSETTINGS_MSPSPEED_4800: + return 4800; + + case HWSETTINGS_MSPSPEED_9600: + return 9600; + + case HWSETTINGS_MSPSPEED_19200: + return 19200; + + case HWSETTINGS_MSPSPEED_38400: + return 38400; + + case HWSETTINGS_MSPSPEED_57600: + return 57600; + + default: + case HWSETTINGS_MSPSPEED_115200: + return 115200; + } +} + + +/** + * Module initialization routine + * @return 0 when initialization was successful + */ +static int32_t uavoMSPBridgeInitialize(void) +{ + if (pios_com_msp_id) { + msp = pios_malloc(sizeof(*msp)); + if (msp != NULL) { + memset(msp, 0x00, sizeof(*msp)); + + msp->com = pios_com_msp_id; + + // now figure out enabled features: registered sensors, ADC routing, GPS + +#ifdef PIOS_EXCLUDE_ADVANCED_FEATURES + msp->sensors |= MSP_SENSOR_ACC; +#else + + if (PIOS_SENSORS_GetInstanceByType(0, PIOS_SENSORS_TYPE_3AXIS_ACCEL)) { + msp->sensors |= MSP_SENSOR_ACC; + } + if (PIOS_SENSORS_GetInstanceByType(0, PIOS_SENSORS_TYPE_1AXIS_BARO)) { + msp->sensors |= MSP_SENSOR_BARO; + } + if (PIOS_SENSORS_GetInstanceByType(0, PIOS_SENSORS_TYPE_3AXIS_MAG | PIOS_SENSORS_TYPE_3AXIS_AUXMAG)) { + msp->sensors |= MSP_SENSOR_MAG; + } +#ifdef PIOS_SENSORS_TYPE_1AXIS_SONAR + if (PIOS_SENSORS_GetInstanceByType(0, PIOS_SENSORS_TYPE_1AXIS_SONAR)) { + msp->sensors |= MSP_SENSOR_SONAR; + } +#endif /* PIOS_SENSORS_TYPE_1AXIS_SONAR */ +#endif /* PIOS_EXCLUDE_ADVANCED_FEATURES */ + + // MAP_SENSOR_GPS is hot-pluggable type + + HwSettingsADCRoutingDataArray adcRoutingDataArray; + HwSettingsADCRoutingArrayGet(adcRoutingDataArray.array); + + for (unsigned i = 0; i < sizeof(adcRoutingDataArray.array) / sizeof(adcRoutingDataArray.array[0]); ++i) { + switch (adcRoutingDataArray.array[i]) { + case HWSETTINGS_ADCROUTING_BATTERYVOLTAGE: + msp->analog |= MSP_ANALOG_VOLTAGE; + break; + case HWSETTINGS_ADCROUTING_BATTERYCURRENT: + msp->analog |= MSP_ANALOG_CURRENT; + break; + default:; + } + } + + + HwSettingsMSPSpeedOptions mspSpeed; + HwSettingsMSPSpeedGet(&mspSpeed); + + PIOS_COM_ChangeBaud(pios_com_msp_id, hwsettings_mspspeed_enum_to_baud(mspSpeed)); + + module_enabled = true; + return 0; + } + } + + return -1; +} +MODULE_INITCALL(uavoMSPBridgeInitialize, uavoMSPBridgeStart); + +/** + * Main task routine + * @param[in] parameters parameter given by PIOS_Thread_Create() + */ +static void uavoMSPBridgeTask(__attribute__((unused)) void *parameters) +{ + while (1) { + uint8_t b = 0; + uint16_t count = PIOS_COM_ReceiveBuffer(msp->com, &b, 1, ~0); + if (count) { + if (!msp_receive_byte(msp, b)) { + // Returning is considered risky here as + // that's unusual and this is an edge case. + while (1) { + PIOS_DELAY_WaitmS(60 * 1000); + } + } + } + } +} + +#endif // PIOS_INCLUDE_MSP_BRIDGE +/** + * @} + * @} + */ diff --git a/flight/modules/UAVOMavlinkBridge/UAVOMavlinkBridge.c b/flight/modules/UAVOMavlinkBridge/UAVOMavlinkBridge.c new file mode 100644 index 000000000..bca1ab6fa --- /dev/null +++ b/flight/modules/UAVOMavlinkBridge/UAVOMavlinkBridge.c @@ -0,0 +1,627 @@ +/** + ****************************************************************************** + * @addtogroup OpenPilotModules OpenPilot Modules + * @{ + * @addtogroup UAVOMavlinkBridge UAVO to Mavlink Bridge Module + * @{ + * + * @file UAVOMavlinkBridge.c + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * dRonin, http://dRonin.org/, Copyright (C) 2015-2016 + * Tau Labs, http://taulabs.org, Copyright (C) 2013-2014 + * @brief Bridges selected UAVObjects to Mavlink + * + * @see The GNU Public License (GPL) Version 3 + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Additional note on redistribution: The copyright and license notices above + * must be maintained in each individual source file that is a derivative work + * of this source file; otherwise redistribution is prohibited. + */ + +// **************** +#include "openpilot.h" +#include "stabilizationdesired.h" +#include "flightbatterysettings.h" +#include "flightbatterystate.h" +#include "gpspositionsensor.h" +#include "manualcontrolcommand.h" +#include "attitudestate.h" +#include "airspeedstate.h" +#include "actuatordesired.h" +#include "flightstatus.h" +#include "systemstats.h" +#include "homelocation.h" +#include "positionstate.h" +#include "velocitystate.h" +#include "taskinfo.h" +#include "mavlink.h" +#include "hwsettings.h" +#include "oplinkstatus.h" +#include "receiverstatus.h" +#include "manualcontrolsettings.h" + +#include "custom_types.h" + +#define OPLINK_LOW_RSSI -110 +#define OPLINK_HIGH_RSSI -10 + +// **************** +// Private functions + +static void uavoMavlinkBridgeTask(void *parameters); + +// **************** +// Private constants + +#if defined(PIOS_MAVLINK_STACK_SIZE) +#define STACK_SIZE_BYTES PIOS_MAVLINK_STACK_SIZE +#else +#define STACK_SIZE_BYTES 696 +#endif + +#define TASK_PRIORITY (tskIDLE_PRIORITY) +#define TASK_RATE_HZ 10 + +static void mavlink_send_extended_status(); +static void mavlink_send_rc_channels(); +static void mavlink_send_position(); +static void mavlink_send_extra1(); +static void mavlink_send_extra2(); + +static const struct { + uint8_t rate; + void (*handler)(); +} mav_rates[] = { + [MAV_DATA_STREAM_EXTENDED_STATUS] = { + .rate = 2, // Hz + .handler = mavlink_send_extended_status, + }, + [MAV_DATA_STREAM_RC_CHANNELS] = { + .rate = 5, // Hz + .handler = mavlink_send_rc_channels, + }, + [MAV_DATA_STREAM_POSITION] = { + .rate = 2, // Hz + .handler = mavlink_send_position, + }, + [MAV_DATA_STREAM_EXTRA1] = { + .rate = 10, // Hz + .handler = mavlink_send_extra1, + }, + [MAV_DATA_STREAM_EXTRA2] = { + .rate = 2, // Hz + .handler = mavlink_send_extra2, + }, +}; + +#define MAXSTREAMS NELEMENTS(mav_rates) + +// **************** +// Private variables + +static bool module_enabled = false; + +static uint8_t *stream_ticks; + +static mavlink_message_t *mav_msg; + +static void updateSettings(); + +/** + * Initialise the module + * \return -1 if initialisation failed + * \return 0 on success + */ +static int32_t uavoMavlinkBridgeStart(void) +{ + if (module_enabled) { + // Start tasks + xTaskHandle taskHandle; + xTaskCreate(uavoMavlinkBridgeTask, "uavoMavlinkBridge", STACK_SIZE_BYTES / 4, NULL, TASK_PRIORITY, &taskHandle); + PIOS_TASK_MONITOR_RegisterTask(TASKINFO_RUNNING_UAVOMAVLINKBRIDGE, taskHandle); + return 0; + } + return -1; +} +/** + * Initialise the module + * \return -1 if initialisation failed + * \return 0 on success + */ +static int32_t uavoMavlinkBridgeInitialize(void) +{ + if (PIOS_COM_MAVLINK) { + updateSettings(); + + mav_msg = pios_malloc(sizeof(*mav_msg)); + stream_ticks = pios_malloc(MAXSTREAMS); + + if (mav_msg && stream_ticks) { + for (unsigned x = 0; x < MAXSTREAMS; ++x) { + stream_ticks[x] = (TASK_RATE_HZ / mav_rates[x].rate); + } + + module_enabled = true; + } + } + + return 0; +} +MODULE_INITCALL(uavoMavlinkBridgeInitialize, uavoMavlinkBridgeStart); + +static void send_message() +{ + uint16_t msg_length = MAVLINK_NUM_NON_PAYLOAD_BYTES + + mav_msg->len; + + PIOS_COM_SendBuffer(PIOS_COM_MAVLINK, &mav_msg->magic, msg_length); +} + +static void mavlink_send_extended_status() +{ +#ifndef PIOS_EXCLUDE_ADVANCED_FEATURES + FlightBatteryStateData batState; + SystemStatsData systemStats; + + if (FlightBatteryStateHandle() != NULL) { + FlightBatteryStateGet(&batState); + } + + SystemStatsGet(&systemStats); + + uint32_t battery_capacity = 0; + if (FlightBatterySettingsHandle() != NULL) { + FlightBatterySettingsCapacityGet(&battery_capacity); + } + + int8_t battery_remaining = 0; + if (battery_capacity != 0) { + if (batState.ConsumedEnergy < battery_capacity) { + battery_remaining = 100 - lroundf(batState.ConsumedEnergy / battery_capacity * 100); + } + } + + mavlink_msg_sys_status_pack(0, 200, mav_msg, + // onboard_control_sensors_present Bitmask showing which onboard controllers and sensors are present. Value of 0: not present. Value of 1: present. Indices: 0: 3D gyro, 1: 3D acc, 2: 3D mag, 3: absolute pressure, 4: differential pressure, 5: GPS, 6: optical flow, 7: computer vision position, 8: laser based position, 9: external ground-truth (Vicon or Leica). Controllers: 10: 3D angular rate control 11: attitude stabilization, 12: yaw position, 13: z/altitude control, 14: x/y position control, 15: motor outputs / control + 0, + // onboard_control_sensors_enabled Bitmask showing which onboard controllers and sensors are enabled: Value of 0: not enabled. Value of 1: enabled. Indices: 0: 3D gyro, 1: 3D acc, 2: 3D mag, 3: absolute pressure, 4: differential pressure, 5: GPS, 6: optical flow, 7: computer vision position, 8: laser based position, 9: external ground-truth (Vicon or Leica). Controllers: 10: 3D angular rate control 11: attitude stabilization, 12: yaw position, 13: z/altitude control, 14: x/y position control, 15: motor outputs / control + 0, + // onboard_control_sensors_health Bitmask showing which onboard controllers and sensors are operational or have an error: Value of 0: not enabled. Value of 1: enabled. Indices: 0: 3D gyro, 1: 3D acc, 2: 3D mag, 3: absolute pressure, 4: differential pressure, 5: GPS, 6: optical flow, 7: computer vision position, 8: laser based position, 9: external ground-truth (Vicon or Leica). Controllers: 10: 3D angular rate control 11: attitude stabilization, 12: yaw position, 13: z/altitude control, 14: x/y position control, 15: motor outputs / control + 0, + // load Maximum usage in percent of the mainloop time, (0%: 0, 100%: 1000) should be always below 1000 + (uint16_t)systemStats.CPULoad * 10, + // voltage_battery Battery voltage, in millivolts (1 = 1 millivolt) + lroundf(batState.Voltage * 1000), // No need to check for validity, Voltage reads 0.0 when measurement is not configured, + // current_battery Battery current, in 10*milliamperes (1 = 10 milliampere), -1: autopilot does not measure the current + lroundf(batState.Current * 100), // Same as for Voltage. 0 means no measurement + // battery_remaining Remaining battery energy: (0%: 0, 100%: 100), -1: autopilot estimate the remaining battery + battery_remaining, + // drop_rate_comm Communication drops in percent, (0%: 0, 100%: 10'000), (UART, I2C, SPI, CAN), dropped packets on all links (packets that were corrupted on reception on the MAV) + 0, + // errors_comm Communication errors (UART, I2C, SPI, CAN), dropped packets on all links (packets that were corrupted on reception on the MAV) + 0, + // errors_count1 Autopilot-specific errors + 0, + // errors_count2 Autopilot-specific errors + 0, + // errors_count3 Autopilot-specific errors + 0, + // errors_count4 Autopilot-specific errors + 0); + + send_message(); +#endif /* PIOS_EXCLUDE_ADVANCED_FEATURES */ +} + +static void mavlink_send_rc_channels() +{ + ManualControlCommandData manualState; + FlightStatusData flightStatus; + SystemStatsData systemStats; + + ManualControlCommandGet(&manualState); + FlightStatusGet(&flightStatus); + SystemStatsGet(&systemStats); + + uint8_t mavlinkRssi; + + ManualControlSettingsChannelGroupsData channelGroups; + ManualControlSettingsChannelGroupsGet(&channelGroups); + +#ifdef PIOS_INCLUDE_OPLINKRCVR + if (channelGroups.Throttle == MANUALCONTROLSETTINGS_CHANNELGROUPS_OPLINK) { + int8_t rssi; + OPLinkStatusRSSIGet(&rssi); + + if (rssi < OPLINK_LOW_RSSI) { + rssi = OPLINK_LOW_RSSI; + } else if (rssi > OPLINK_HIGH_RSSI) { + rssi = OPLINK_HIGH_RSSI; + } + + mavlinkRssi = ((rssi - OPLINK_LOW_RSSI) * 255) / (OPLINK_HIGH_RSSI - OPLINK_LOW_RSSI); + } else { +#endif /* PIOS_INCLUDE_OPLINKRCVR */ + uint8_t quality; + ReceiverStatusQualityGet(&quality); + + // MAVLink RSSI's range is 0-255 + mavlinkRssi = (quality * 255) / 100; +#ifdef PIOS_INCLUDE_OPLINKRCVR +} +#endif + + mavlink_msg_rc_channels_raw_pack(0, 200, mav_msg, + // time_boot_ms Timestamp (milliseconds since system boot) + systemStats.FlightTime, + // port Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows to encode more than 8 servos. + 0, + // chan1_raw RC channel 1 value, in microseconds + manualState.Channel[0], + // chan2_raw RC channel 2 value, in microseconds + manualState.Channel[1], + // chan3_raw RC channel 3 value, in microseconds + manualState.Channel[2], + // chan4_raw RC channel 4 value, in microseconds + manualState.Channel[3], + // chan5_raw RC channel 5 value, in microseconds + manualState.Channel[4], + // chan6_raw RC channel 6 value, in microseconds + manualState.Channel[5], + // chan7_raw RC channel 7 value, in microseconds + manualState.Channel[6], + // chan8_raw RC channel 8 value, in microseconds + manualState.Channel[7], + // rssi Receive signal strength indicator, 0: 0%, 255: 100% + mavlinkRssi); + + send_message(); +} + +static void mavlink_send_position() +{ + SystemStatsData systemStats; + + SystemStatsGet(&systemStats); + + if (GPSPositionSensorHandle() != NULL) { + GPSPositionSensorData gpsPosData; + GPSPositionSensorGet(&gpsPosData); + + uint8_t gps_fix_type = 0; + + switch (gpsPosData.Status) { + case GPSPOSITIONSENSOR_STATUS_NOGPS: + gps_fix_type = 0; + break; + case GPSPOSITIONSENSOR_STATUS_NOFIX: + gps_fix_type = 1; + break; + case GPSPOSITIONSENSOR_STATUS_FIX2D: + gps_fix_type = 2; + break; + case GPSPOSITIONSENSOR_STATUS_FIX3D: + gps_fix_type = 3; + break; + } + + mavlink_msg_gps_raw_int_pack(0, 200, mav_msg, + // time_usec Timestamp (microseconds since UNIX epoch or microseconds since system boot) + (uint64_t)systemStats.FlightTime * 1000, + // fix_type 0-1: no fix, 2: 2D fix, 3: 3D fix. Some applications will not use the value of this field unless it is at least two, so always correctly fill in the fix. + gps_fix_type, + // lat Latitude in 1E7 degrees + gpsPosData.Latitude, + // lon Longitude in 1E7 degrees + gpsPosData.Longitude, + // alt Altitude in 1E3 meters (millimeters) above MSL + gpsPosData.Altitude * 1000, + // eph GPS HDOP horizontal dilution of position in cm (m*100). If unknown, set to: 65535 + gpsPosData.HDOP * 100, + // epv GPS VDOP horizontal dilution of position in cm (m*100). If unknown, set to: 65535 + gpsPosData.VDOP * 100, + // vel GPS ground speed (m/s * 100). If unknown, set to: 65535 + gpsPosData.Groundspeed * 100, + // cog Course over ground (NOT heading, but direction of movement) in degrees * 100, 0.0..359.99 degrees. If unknown, set to: 65535 + gpsPosData.Heading * 100, + // satellites_visible Number of satellites visible. If unknown, set to 255 + gpsPosData.Satellites); + + send_message(); + } + +#ifndef PIOS_EXCLUDE_ADVANCED_FEATURES + if (HomeLocationHandle() != NULL) { + HomeLocationData homeLocation; + HomeLocationGet(&homeLocation); + + mavlink_msg_gps_global_origin_pack(0, 200, mav_msg, + // latitude Latitude (WGS84), expressed as * 1E7 + homeLocation.Latitude, + // longitude Longitude (WGS84), expressed as * 1E7 + homeLocation.Longitude, + // altitude Altitude(WGS84), expressed as * 1000 + homeLocation.Altitude * 1000); + + send_message(); + } +#endif /* PIOS_EXCLUDE_ADVANCED_FEATURES */ + + // TODO add waypoint nav stuff + // wp_target_bearing + // wp_dist = mavlink_msg_nav_controller_output_get_wp_dist(&msg); + // alt_error = mavlink_msg_nav_controller_output_get_alt_error(&msg); + // aspd_error = mavlink_msg_nav_controller_output_get_aspd_error(&msg); + // xtrack_error = mavlink_msg_nav_controller_output_get_xtrack_error(&msg); + // mavlink_msg_nav_controller_output_pack + // wp_number + // mavlink_msg_mission_current_pack +} + +static void mavlink_send_extra1() +{ + AttitudeStateData attState; + SystemStatsData systemStats; + + AttitudeStateGet(&attState); + SystemStatsGet(&systemStats); + + mavlink_msg_attitude_pack(0, 200, mav_msg, + // time_boot_ms Timestamp (milliseconds since system boot) + systemStats.FlightTime, + // roll Roll angle (rad) + DEG2RAD(attState.Roll), + // pitch Pitch angle (rad) + DEG2RAD(attState.Pitch), + // yaw Yaw angle (rad) + DEG2RAD(attState.Yaw), + // rollspeed Roll angular speed (rad/s) + 0, + // pitchspeed Pitch angular speed (rad/s) + 0, + // yawspeed Yaw angular speed (rad/s) + 0); + + send_message(); +} + +static inline float Sq(float x) +{ + return x * x; +} + +#define IS_STAB_MODE(d, m) (((d).Roll == (m)) && ((d).Pitch == (m))) + +static void mavlink_send_extra2() +{ + float airspeed = 0; + float altitude = 0; + float groundspeed = 0; + float climbrate = 0; + + +#ifndef PIOS_EXCLUDE_ADVANCED_FEATURES + if (AirspeedStateHandle() != NULL) { + AirspeedStateTrueAirspeedGet(&airspeed); + } + + if (PositionStateHandle() != NULL) { + PositionStateDownGet(&altitude); + altitude *= -1; + } + + if (VelocityStateHandle() != NULL) { + VelocityStateData velocityState; + VelocityStateGet(&velocityState); + + groundspeed = sqrtf(Sq(velocityState.North) + Sq(velocityState.East)); + climbrate = velocityState.Down * -1; + } +#endif + + float attitudeYaw = 0; + + AttitudeStateYawGet(&attitudeYaw); + // round attState.Yaw to nearest int and transfer from (-180 ... 180) to (0 ... 360) + int16_t heading = lroundf(attitudeYaw); + if (heading < 0) { + heading += 360; + } + + + float thrust; + ActuatorDesiredThrustGet(&thrust); + + mavlink_msg_vfr_hud_pack(0, 200, mav_msg, + // airspeed Current airspeed in m/s + airspeed, + // groundspeed Current ground speed in m/s + groundspeed, + // heading Current heading in degrees, in compass units (0..360, 0=north) + heading, + // throttle Current throttle setting in integer percent, 0 to 100 + thrust * 100, + // alt Current altitude (MSL), in meters + altitude, + // climb Current climb rate in meters/second + climbrate); + + send_message(); + + FlightStatusData flightStatus; + FlightStatusGet(&flightStatus); + + StabilizationDesiredStabilizationModeData stabModeData; + StabilizationDesiredStabilizationModeGet(&stabModeData); + + uint8_t armed_mode = 0; + if (flightStatus.Armed == FLIGHTSTATUS_ARMED_ARMED) { + armed_mode |= MAV_MODE_FLAG_SAFETY_ARMED; + } + + uint8_t custom_mode = CUSTOM_MODE_STAB; + + switch (flightStatus.FlightMode) { + case FLIGHTSTATUS_FLIGHTMODE_POSITIONHOLD: + custom_mode = CUSTOM_MODE_PHLD; + break; + + case FLIGHTSTATUS_FLIGHTMODE_RETURNTOBASE: + custom_mode = CUSTOM_MODE_RTL; + break; + + case FLIGHTSTATUS_FLIGHTMODE_AUTOCRUISE: + case FLIGHTSTATUS_FLIGHTMODE_AUTOTAKEOFF: + case FLIGHTSTATUS_FLIGHTMODE_PATHPLANNER: + custom_mode = CUSTOM_MODE_AUTO; + break; + + case FLIGHTSTATUS_FLIGHTMODE_LAND: + custom_mode = CUSTOM_MODE_LAND; + break; + + case FLIGHTSTATUS_FLIGHTMODE_MANUAL: + custom_mode = CUSTOM_MODE_ACRO; // or + break; + case FLIGHTSTATUS_FLIGHTMODE_AUTOTUNE: + custom_mode = CUSTOM_MODE_ATUN; + break; + case FLIGHTSTATUS_FLIGHTMODE_STABILIZED1: + case FLIGHTSTATUS_FLIGHTMODE_STABILIZED2: + case FLIGHTSTATUS_FLIGHTMODE_STABILIZED3: + case FLIGHTSTATUS_FLIGHTMODE_STABILIZED4: + case FLIGHTSTATUS_FLIGHTMODE_STABILIZED5: + case FLIGHTSTATUS_FLIGHTMODE_STABILIZED6: + + if (IS_STAB_MODE(stabModeData, STABILIZATIONDESIRED_STABILIZATIONMODE_RATE) + || IS_STAB_MODE(stabModeData, STABILIZATIONDESIRED_STABILIZATIONMODE_RATETRAINER)) { + custom_mode = CUSTOM_MODE_ACRO; + } else if (IS_STAB_MODE(stabModeData, STABILIZATIONDESIRED_STABILIZATIONMODE_ACRO)) { // this is Acro+ mode + custom_mode = CUSTOM_MODE_ACRO; + } else if (IS_STAB_MODE(stabModeData, STABILIZATIONDESIRED_STABILIZATIONMODE_RATTITUDE)) { + custom_mode = CUSTOM_MODE_SPORT; + } else if ((stabModeData.Thrust == STABILIZATIONDESIRED_STABILIZATIONMODE_ALTITUDEHOLD) + || (stabModeData.Thrust == STABILIZATIONDESIRED_STABILIZATIONMODE_ALTITUDEVARIO)) { + custom_mode = CUSTOM_MODE_ALTH; + } else { // looks like stabilized mode, whichever it is.. + custom_mode = CUSTOM_MODE_STAB; + } + + break; + case FLIGHTSTATUS_FLIGHTMODE_COURSELOCK: + case FLIGHTSTATUS_FLIGHTMODE_VELOCITYROAM: + case FLIGHTSTATUS_FLIGHTMODE_HOMELEASH: + case FLIGHTSTATUS_FLIGHTMODE_ABSOLUTEPOSITION: + case FLIGHTSTATUS_FLIGHTMODE_POI: + custom_mode = CUSTOM_MODE_STAB; // Don't know any better + break; + } + + mavlink_msg_heartbeat_pack(0, 200, mav_msg, + // type Type of the MAV (quadrotor, helicopter, etc., up to 15 types, defined in MAV_TYPE ENUM) + MAV_TYPE_GENERIC, + // autopilot Autopilot type / class. defined in MAV_AUTOPILOT ENUM + MAV_AUTOPILOT_GENERIC, // or MAV_AUTOPILOT_OPENPILOT + // base_mode System mode bitfield, see MAV_MODE_FLAGS ENUM in mavlink/include/mavlink_types.h + armed_mode, + // custom_mode A bitfield for use for autopilot-specific flags. + custom_mode, + // system_status System status flag, see MAV_STATE ENUM + 0); + + send_message(); +} + +/** + * Main task. It does not return. + */ + +static void uavoMavlinkBridgeTask(__attribute__((unused)) void *parameters) +{ + uint32_t lastSysTime; + + // Main task loop + lastSysTime = xTaskGetTickCount(); // portTICK_RATE_MS; + + while (1) { + vTaskDelayUntil(&lastSysTime, (1000 / TASK_RATE_HZ) / portTICK_RATE_MS); + + for (unsigned i = 0; i < MAXSTREAMS; ++i) { + if (!mav_rates[i].rate || !mav_rates[i].handler) { + continue; + } + + if (stream_ticks[i] == 0) { + // trigger now + uint8_t rate = mav_rates[i].rate; + if (rate > TASK_RATE_HZ) { + rate = TASK_RATE_HZ; + } + stream_ticks[i] = TASK_RATE_HZ / rate; + + mav_rates[i].handler(); + } + + --stream_ticks[i]; + } + } +} + +static uint32_t hwsettings_mavlinkspeed_enum_to_baud(uint8_t baud) +{ + switch (baud) { + case HWSETTINGS_MAVLINKSPEED_2400: + return 2400; + + case HWSETTINGS_MAVLINKSPEED_4800: + return 4800; + + case HWSETTINGS_MAVLINKSPEED_9600: + return 9600; + + case HWSETTINGS_MAVLINKSPEED_19200: + return 19200; + + case HWSETTINGS_MAVLINKSPEED_38400: + return 38400; + + case HWSETTINGS_MAVLINKSPEED_57600: + return 57600; + + default: + case HWSETTINGS_MAVLINKSPEED_115200: + return 115200; + } +} + + +static void updateSettings() +{ + if (PIOS_COM_MAVLINK) { + // Retrieve settings + HwSettingsMAVLinkSpeedOptions mavlinkSpeed; + HwSettingsMAVLinkSpeedGet(&mavlinkSpeed); + + PIOS_COM_ChangeBaud(PIOS_COM_MAVLINK, hwsettings_mavlinkspeed_enum_to_baud(mavlinkSpeed)); + } +} +/** + * @} + * @} + */ diff --git a/flight/modules/gpsp/gps9gpshandler.c b/flight/modules/gpsp/gps9gpshandler.c index 13f64ede2..8e0e82ccc 100644 --- a/flight/modules/gpsp/gps9gpshandler.c +++ b/flight/modules/gpsp/gps9gpshandler.c @@ -34,41 +34,42 @@ #include "gps9protocol.h" uint32_t lastUnsentData = 0; -uint8_t buffer[BUFFER_SIZE]; +uint8_t gpsBuffer[GPS_BUFFER_SIZE]; +uint8_t fcBuffer[FC_BUFFER_SIZE]; void handleGPS() { - bool completeSentenceSent = false; + bool completeSentenceInBuffer = false; int8_t maxCount = 2; do { int32_t datacounter = PIOS_UBX_DDC_GetAvailableBytes(PIOS_I2C_GPS); if (datacounter > 0) { - uint8_t toRead = (uint32_t)datacounter > BUFFER_SIZE - lastUnsentData ? BUFFER_SIZE - lastUnsentData : (uint8_t)datacounter; - uint8_t toSend = toRead; - PIOS_UBX_DDC_ReadData(PIOS_I2C_GPS, buffer, toRead); + uint8_t toRead = (uint32_t)datacounter > GPS_BUFFER_SIZE - lastUnsentData ? GPS_BUFFER_SIZE - lastUnsentData : (uint8_t)datacounter; + uint8_t toSend = toRead + lastUnsentData; + PIOS_UBX_DDC_ReadData(PIOS_I2C_GPS, gpsBuffer + lastUnsentData, toRead); uint8_t *lastSentence; uint16_t lastSentenceLength; - completeSentenceSent = ubx_getLastSentence(buffer, toRead, &lastSentence, &lastSentenceLength); - if (completeSentenceSent) { - toSend = (uint8_t)(lastSentence - buffer + lastSentenceLength); + completeSentenceInBuffer = ubx_getLastSentence(gpsBuffer, toSend, &lastSentence, &lastSentenceLength); + if (completeSentenceInBuffer) { + toSend = (uint8_t)(lastSentence - gpsBuffer + lastSentenceLength); + PIOS_COM_SendBuffer(pios_com_main_id, gpsBuffer, toSend); + // move unsent data to the beginning of gpsBuffer to be sent next time + lastUnsentData = lastUnsentData > toSend ? lastUnsentData - toSend : 0; + if (lastUnsentData > 0) { + memcpy(gpsBuffer, (gpsBuffer + toSend), lastUnsentData); + } } else { - lastUnsentData = 0; - } - - PIOS_COM_SendBuffer(pios_com_main_id, buffer, toSend); - - if (toRead > toSend) { - // move unsent data at the beginning of buffer to be sent next time - lastUnsentData = toRead - toSend; - memcpy(buffer, (buffer + toSend), lastUnsentData); + // toss the buffer contents if it's full and there are no complete + // ublox sentences in it. This happens if the module is sending NMEA + lastUnsentData = toSend < GPS_BUFFER_SIZE ? toSend : 0; } } - datacounter = PIOS_COM_ReceiveBuffer(pios_com_main_id, buffer, BUFFER_SIZE, 0); + datacounter = PIOS_COM_ReceiveBuffer(pios_com_main_id, fcBuffer, FC_BUFFER_SIZE, 0); if (datacounter > 0) { - PIOS_UBX_DDC_WriteData(PIOS_I2C_GPS, buffer, datacounter); + PIOS_UBX_DDC_WriteData(PIOS_I2C_GPS, fcBuffer, datacounter); } if (maxCount) { // Note: this delay is needed as querying too quickly the UBX module's I2C(DDC) diff --git a/flight/modules/gpsp/gpsdsysmod.c b/flight/modules/gpsp/gpsdsysmod.c index fe81e72fa..d7f009658 100644 --- a/flight/modules/gpsp/gpsdsysmod.c +++ b/flight/modules/gpsp/gpsdsysmod.c @@ -110,6 +110,10 @@ static void gpspSystemTask(__attribute__((unused)) void *parameters) while (!initTaskDone) { vTaskDelay(10); } +#ifndef PIOS_INCLUDE_WDG +// if no watchdog is enabled, don't reset watchdog in MODULE_TASKCREATE_ALL loop +#define PIOS_WDG_Clear() +#endif /* create all modules thread */ MODULE_TASKCREATE_ALL; diff --git a/flight/modules/gpsp/inc/gps9gpshandler.h b/flight/modules/gpsp/inc/gps9gpshandler.h index 078c2d7d1..d216e0d19 100644 --- a/flight/modules/gpsp/inc/gps9gpshandler.h +++ b/flight/modules/gpsp/inc/gps9gpshandler.h @@ -26,7 +26,8 @@ #ifndef GPS9GPSHANDLER_H_ #define GPS9GPSHANDLER_H_ -#define BUFFER_SIZE 200 +#define GPS_BUFFER_SIZE 250 +#define FC_BUFFER_SIZE 120 void handleGPS(); void setupGPS(); diff --git a/flight/pios/common/libraries/msheap/pios_msheap.c b/flight/pios/common/libraries/msheap/pios_msheap.c index 9ce9f7b8a..e7e03f8c6 100644 --- a/flight/pios/common/libraries/msheap/pios_msheap.c +++ b/flight/pios/common/libraries/msheap/pios_msheap.c @@ -62,7 +62,7 @@ extern char _efastheap; #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE heap_handle_t sram_heap; -#if PIOS_TARGET_PROVIDES_FAST_HEAP +#ifdef PIOS_TARGET_PROVIDES_FAST_HEAP heap_handle_t fast_heap; #else #define fast_heap sram_heap @@ -131,7 +131,7 @@ void vPortInitialiseBlocks(void) { msheap_init(&sram_heap, &_sheap, &_eheap); -#if PIOS_TARGET_PROVIDES_FAST_HEAP +#ifdef PIOS_TARGET_PROVIDES_FAST_HEAP msheap_init(&fast_heap, &_sfastheap, &_efastheap); #endif } diff --git a/flight/pios/common/pios_com.c b/flight/pios/common/pios_com.c index 9a4b83f60..b0a394b6c 100644 --- a/flight/pios/common/pios_com.c +++ b/flight/pios/common/pios_com.c @@ -333,12 +333,36 @@ int32_t PIOS_COM_RegisterCtrlLineCallback(uint32_t com_id, pios_com_callback_ctr return 0; } +/** + * Set baud rate callback associated with the port + * \param[in] port COM port + * \param[in] baud_rate_cb Callback function + * \param[in] context context to pass to the callback function + * \return -1 if port not available + * \return 0 on success + */ +int32_t PIOS_COM_RegisterBaudRateCallback(uint32_t com_id, pios_com_callback_baud_rate baud_rate_cb, uint32_t context) +{ + struct pios_com_dev *com_dev = (struct pios_com_dev *)com_id; + + if (!PIOS_COM_validate(com_dev)) { + /* Undefined COM port for this board (see pios_board.c) */ + return -1; + } + + /* Invoke the driver function if it exists */ + if (com_dev->driver->bind_baud_rate_cb) { + com_dev->driver->bind_baud_rate_cb(com_dev->lower_id, baud_rate_cb, context); + } + + return 0; +} static int32_t PIOS_COM_SendBufferNonBlockingInternal(struct pios_com_dev *com_dev, const uint8_t *buffer, uint16_t len) { PIOS_Assert(com_dev); PIOS_Assert(com_dev->has_tx); - if (com_dev->driver->available && !com_dev->driver->available(com_dev->lower_id)) { + if (com_dev->driver->available && !(com_dev->driver->available(com_dev->lower_id) & COM_AVAILABLE_TX)) { /* * Underlying device is down/unconnected. * Dump our fifo contents and act like an infinite data sink. @@ -625,18 +649,26 @@ check_again: * used to check a link is established even if the device * is valid. */ -bool PIOS_COM_Available(uint32_t com_id) +uint32_t PIOS_COM_Available(uint32_t com_id) { struct pios_com_dev *com_dev = (struct pios_com_dev *)com_id; if (!PIOS_COM_validate(com_dev)) { - return false; + return COM_AVAILABLE_NONE; } // If a driver does not provide a query method assume always // available if valid if (com_dev->driver->available == NULL) { - return true; + if (com_dev->has_rx && com_dev->has_tx) { + return COM_AVAILABLE_RXTX; + } else if (com_dev->has_rx) { + return COM_AVAILABLE_RX; + } else if (com_dev->has_tx) { + return COM_AVAILABLE_TX; + } + + return COM_AVAILABLE_NONE; /* can this really happen? */ } return (com_dev->driver->available)(com_dev->lower_id); diff --git a/flight/pios/common/pios_debuglog.c b/flight/pios/common/pios_debuglog.c index 8f400ec59..e688674bb 100644 --- a/flight/pios/common/pios_debuglog.c +++ b/flight/pios/common/pios_debuglog.c @@ -32,6 +32,7 @@ #include "pios.h" #include "uavobjectmanager.h" #include "debuglogentry.h" +#include "callbackinfo.h" // global definitions #ifdef PIOS_INCLUDE_DEBUGLOG @@ -39,14 +40,9 @@ // Global variables extern uintptr_t pios_user_fs_id; // flash filesystem for logging -#if defined(PIOS_INCLUDE_FREERTOS) static xSemaphoreHandle mutex = 0; #define mutexlock() xSemaphoreTakeRecursive(mutex, portMAX_DELAY) #define mutexunlock() xSemaphoreGiveRecursive(mutex) -#else -#define mutexlock() -#define mutexunlock() -#endif static bool logging_enabled = false; #define MAX_CONSECUTIVE_FAILS_COUNT 10 @@ -54,10 +50,12 @@ static bool log_is_full = false; static uint8_t fails_count = 0; static uint16_t flightnum = 0; static uint16_t lognum = 0; -static DebugLogEntryData *buffer = 0; -#if !defined(PIOS_INCLUDE_FREERTOS) -static DebugLogEntryData staticbuffer; -#endif + +#define BUFFERS_COUNT 2 +static DebugLogEntryData *current_buffer = 0; +static DebugLogEntryData *buffers[BUFFERS_COUNT] = { 0, 0 }; +static uint8_t current_write_buffer_index; +static uint8_t next_read_buffer_index; #define LOG_ENTRY_MAX_DATA_SIZE (sizeof(((DebugLogEntryData *)0)->Data)) #define LOG_ENTRY_HEADER_SIZE (sizeof(DebugLogEntryData) - LOG_ENTRY_MAX_DATA_SIZE) @@ -66,23 +64,33 @@ static DebugLogEntryData staticbuffer; static uint32_t used_buffer_space = 0; +#define CBTASK_PRIORITY CALLBACK_TASK_AUXILIARY +#define CALLBACK_PRIORITY CALLBACK_PRIORITY_LOW +#define CB_TIMEOUT 100 +#define STACK_SIZE_BYTES 512 +static DelayedCallbackInfo *callbackHandle; + /* Private Function Prototypes */ static void enqueue_data(uint32_t objid, uint16_t instid, size_t size, uint8_t *data); static bool write_current_buffer(); +static void writeTask(); +static uint8_t get_blocks_free(); /** * @brief Initialize the log facility */ void PIOS_DEBUGLOG_Initialize() { -#if defined(PIOS_INCLUDE_FREERTOS) if (!mutex) { - mutex = xSemaphoreCreateRecursiveMutex(); - buffer = pios_malloc(sizeof(DebugLogEntryData)); + mutex = xSemaphoreCreateRecursiveMutex(); + for (uint32_t i = 0; i < BUFFERS_COUNT; i++) { + buffers[i] = pios_malloc(sizeof(DebugLogEntryData)); + } + current_write_buffer_index = 0; + next_read_buffer_index = 0; + current_buffer = buffers[current_write_buffer_index]; } -#else - buffer = &staticbuffer; -#endif - if (!buffer) { + + if (!current_buffer) { return; } mutexlock(); @@ -91,10 +99,12 @@ void PIOS_DEBUGLOG_Initialize() fails_count = 0; used_buffer_space = 0; log_is_full = false; - while (PIOS_FLASHFS_ObjLoad(pios_user_fs_id, LOG_GET_FLIGHT_OBJID(flightnum), lognum, (uint8_t *)buffer, sizeof(DebugLogEntryData)) == 0) { + while (PIOS_FLASHFS_ObjLoad(pios_user_fs_id, LOG_GET_FLIGHT_OBJID(flightnum), lognum, (uint8_t *)current_buffer, sizeof(DebugLogEntryData)) == 0) { flightnum++; } mutexunlock(); + callbackHandle = PIOS_CALLBACKSCHEDULER_Create(&writeTask, CALLBACK_PRIORITY, CBTASK_PRIORITY, CALLBACKINFO_RUNNING_DEBUGLOG, STACK_SIZE_BYTES); + PIOS_CALLBACKSCHEDULER_Schedule(callbackHandle, CB_TIMEOUT, CALLBACK_UPDATEMODE_LATER); } @@ -122,7 +132,7 @@ void PIOS_DEBUGLOG_Enable(uint8_t enabled) */ void PIOS_DEBUGLOG_UAVObject(uint32_t objid, uint16_t instid, size_t size, uint8_t *data) { - if (!logging_enabled || !buffer || log_is_full) { + if (!logging_enabled || !current_buffer || log_is_full) { return; } mutexlock(); @@ -139,7 +149,7 @@ void PIOS_DEBUGLOG_UAVObject(uint32_t objid, uint16_t instid, size_t size, uint8 */ void PIOS_DEBUGLOG_Printf(char *format, ...) { - if (!logging_enabled || !buffer || log_is_full) { + if (!logging_enabled || !current_buffer || log_is_full) { return; } @@ -150,19 +160,19 @@ void PIOS_DEBUGLOG_Printf(char *format, ...) if (used_buffer_space) { write_current_buffer(); } - memset(buffer->Data, 0xff, sizeof(buffer->Data)); - vsnprintf((char *)buffer->Data, sizeof(buffer->Data), (char *)format, args); - buffer->Flight = flightnum; + memset(current_buffer->Data, 0xff, sizeof(current_buffer->Data)); + vsnprintf((char *)current_buffer->Data, sizeof(current_buffer->Data), (char *)format, args); + current_buffer->Flight = flightnum; - buffer->FlightTime = PIOS_DELAY_GetuS(); + current_buffer->FlightTime = PIOS_DELAY_GetuS(); - buffer->Entry = lognum; - buffer->Type = DEBUGLOGENTRY_TYPE_TEXT; - buffer->ObjectID = 0; - buffer->InstanceID = 0; - buffer->Size = strlen((const char *)buffer->Data); + current_buffer->Entry = lognum; + current_buffer->Type = DEBUGLOGENTRY_TYPE_TEXT; + current_buffer->ObjectID = 0; + current_buffer->InstanceID = 0; + current_buffer->Size = strlen((const char *)current_buffer->Data); - if (PIOS_FLASHFS_ObjSave(pios_user_fs_id, LOG_GET_FLIGHT_OBJID(flightnum), lognum, (uint8_t *)buffer, sizeof(DebugLogEntryData)) == 0) { + if (PIOS_FLASHFS_ObjSave(pios_user_fs_id, LOG_GET_FLIGHT_OBJID(flightnum), lognum, (uint8_t *)current_buffer, sizeof(DebugLogEntryData)) == 0) { lognum++; } mutexunlock(); @@ -233,21 +243,21 @@ void enqueue_data(uint32_t objid, uint16_t instid, size_t size, uint8_t *data) // start a new block if (!used_buffer_space) { - entry = buffer; - memset(buffer->Data, 0xff, sizeof(buffer->Data)); + entry = current_buffer; + memset(current_buffer->Data, 0xff, sizeof(current_buffer->Data)); used_buffer_space += size; } else { // if an instance is being filled and there is enough space, does enqueues new data. if (used_buffer_space + size + LOG_ENTRY_HEADER_SIZE > LOG_ENTRY_MAX_DATA_SIZE) { - buffer->Type = DEBUGLOGENTRY_TYPE_MULTIPLEUAVOBJECTS; + current_buffer->Type = DEBUGLOGENTRY_TYPE_MULTIPLEUAVOBJECTS; if (!write_current_buffer()) { return; } - entry = buffer; - memset(buffer->Data, 0xff, sizeof(buffer->Data)); + entry = current_buffer; + memset(current_buffer->Data, 0xff, sizeof(current_buffer->Data)); used_buffer_space += size; } else { - entry = (DebugLogEntryData *)&buffer->Data[used_buffer_space]; + entry = (DebugLogEntryData *)¤t_buffer->Data[used_buffer_space]; used_buffer_space += size + LOG_ENTRY_HEADER_SIZE; } } @@ -258,8 +268,8 @@ void enqueue_data(uint32_t objid, uint16_t instid, size_t size, uint8_t *data) entry->Type = DEBUGLOGENTRY_TYPE_UAVOBJECT; entry->ObjectID = objid; entry->InstanceID = instid; - if (size > sizeof(buffer->Data)) { - size = sizeof(buffer->Data); + if (size > sizeof(current_buffer->Data)) { + size = sizeof(current_buffer->Data); } entry->Size = size; @@ -268,18 +278,46 @@ void enqueue_data(uint32_t objid, uint16_t instid, size_t size, uint8_t *data) bool write_current_buffer() { - // not enough space, write the block and start a new one - if (PIOS_FLASHFS_ObjSave(pios_user_fs_id, LOG_GET_FLIGHT_OBJID(flightnum), lognum, (uint8_t *)buffer, sizeof(DebugLogEntryData)) == 0) { - lognum++; - fails_count = 0; + PIOS_CALLBACKSCHEDULER_Dispatch(callbackHandle); + // Check if queue is full + + if (get_blocks_free() > 0) { + current_write_buffer_index = (current_write_buffer_index + 1) % BUFFERS_COUNT; + current_buffer = buffers[current_write_buffer_index]; used_buffer_space = 0; + return true; } else { - if (fails_count++ > MAX_CONSECUTIVE_FAILS_COUNT) { - log_is_full = true; - } return false; } - return true; +} + +static uint8_t get_blocks_free() +{ + uint8_t used_blocks = current_write_buffer_index - next_read_buffer_index; + + if (current_write_buffer_index < next_read_buffer_index) { + used_blocks = (BUFFERS_COUNT - next_read_buffer_index) + current_write_buffer_index; + } + return (BUFFERS_COUNT - used_blocks) - 1; +} + +static void writeTask() +{ + if (current_write_buffer_index != next_read_buffer_index) { + // not enough space, write the block and start a new one + if (PIOS_FLASHFS_ObjSave(pios_user_fs_id, + LOG_GET_FLIGHT_OBJID(flightnum), lognum, + (uint8_t *)buffers[next_read_buffer_index], + sizeof(DebugLogEntryData)) == 0) { + next_read_buffer_index = (next_read_buffer_index + 1) % BUFFERS_COUNT; + lognum++; + fails_count = 0; + } else { + if (fails_count++ > MAX_CONSECUTIVE_FAILS_COUNT) { + log_is_full = true; + } + } + } } #endif /* ifdef PIOS_INCLUDE_DEBUGLOG */ /** diff --git a/flight/pios/common/pios_exbus.c b/flight/pios/common/pios_exbus.c new file mode 100644 index 000000000..a65333ea0 --- /dev/null +++ b/flight/pios/common/pios_exbus.c @@ -0,0 +1,457 @@ +/** + ****************************************************************************** + * @file pios_exbus.c + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * Tau Labs, http://taulabs.org, Copyright (C) 2013 + * @addtogroup PIOS PIOS Core hardware abstraction layer + * @{ + * @addtogroup PIOS_EXBUS Jeti EX Bus receiver functions + * @{ + * @brief Jeti EX Bus receiver functions + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +/* Project Includes */ +#include "pios_exbus_priv.h" + +#if defined(PIOS_INCLUDE_EXBUS) + +#if !defined(PIOS_INCLUDE_RTC) +#error PIOS_INCLUDE_RTC must be used to use EXBUS +#endif + +/** + * Based on Jeti EX Bus protocol version 1.21 + * Available at http://www.jetimodel.com/en/Telemetry-Protocol/ + */ + +/* EXBUS frame size and contents definitions */ +#define EXBUS_HEADER_LENGTH 4 +#define EXBUS_CRC_LENGTH 2 +#define EXBUS_MAX_CHANNELS 16 +#define EXBUS_OVERHEAD_LENGTH (EXBUS_HEADER_LENGTH + EXBUS_CRC_LENGTH) +#define EXBUS_MAX_FRAME_LENGTH (EXBUS_MAX_CHANNELS * 2 + 10 + EXBUS_OVERHEAD_LENGTH) + +#define EXBUS_SYNC_CHANNEL 0x3E +#define EXBUS_SYNC_TELEMETRY 0x3D +#define EXBUS_BYTE_REQ 0x01 +#define EXBUS_BYTE_NOREQ 0x03 + +#define EXBUS_DATA_CHANNEL 0x31 +#define EXBUS_DATA_TELEMETRY 0x3A +#define EXBUS_DATA_JETIBOX 0x3B + +#define EXBUS_LOW_BAUD_RATE 125000 +#define EXBUS_HIGH_BAUD_RATE 250000 +#define EXBUS_BAUD_RATE_LIMIT 64 +#define EXBUS_FRAME_TIMEOUT 4 +#define EXBUS_FAILSAFE_TIMEOUT 64 + +/* With an Ex.Bus frame rate of 10ms (100Hz) averaging over 20 samples + * gives about a 200ms response. + */ +#define EXBUS_FL_WEIGHTED_AVERAGE 20 + +/* Forward Declarations */ +static int32_t PIOS_EXBUS_Get(uint32_t rcvr_id, uint8_t channel); +static uint16_t PIOS_EXBUS_RxInCallback(uint32_t context, + uint8_t *buf, + uint16_t buf_len, + uint16_t *headroom, + bool *need_yield); +static void PIOS_EXBUS_Supervisor(uint32_t exbus_id); +static uint16_t PIOS_EXBUS_CRC_Update(uint16_t crc, uint8_t data); +static uint8_t PIOS_EXBUS_Quality_Get(uint32_t rcvr_id); + +/* Local Variables */ +const struct pios_rcvr_driver pios_exbus_rcvr_driver = { + .read = PIOS_EXBUS_Get, + .get_quality = PIOS_EXBUS_Quality_Get, +}; + +enum pios_exbus_dev_magic { + PIOS_EXBUS_DEV_MAGIC = 0x485355FF, +}; + +enum pios_exbus_frame_state { + EXBUS_STATE_SYNC, + EXBUS_STATE_REQ, + EXBUS_STATE_LEN, + EXBUS_STATE_PACKET_ID, + EXBUS_STATE_DATA_ID, + EXBUS_STATE_SUBLEN, + EXBUS_STATE_DATA +}; + +struct pios_exbus_state { + uint16_t channel_data[PIOS_EXBUS_NUM_INPUTS]; + uint8_t received_data[EXBUS_MAX_FRAME_LENGTH]; + uint8_t receive_timer; + uint8_t failsafe_timer; + uint8_t failsafe_count; + uint8_t byte_count; + uint8_t frame_length; + uint16_t crc; + bool high_baud_rate; + bool frame_found; + float quality; +}; + +struct pios_exbus_dev { + enum pios_exbus_dev_magic magic; + uint32_t com_port_id; + const struct pios_com_driver *driver; + struct pios_exbus_state state; +}; + +/* Allocate EXBUS device descriptor */ +static struct pios_exbus_dev *PIOS_EXBUS_Alloc(void) +{ + struct pios_exbus_dev *exbus_dev; + + exbus_dev = (struct pios_exbus_dev *)pios_malloc(sizeof(*exbus_dev)); + if (!exbus_dev) { + return NULL; + } + + exbus_dev->magic = PIOS_EXBUS_DEV_MAGIC; + return exbus_dev; +} + +/* Validate EXBUS device descriptor */ +static bool PIOS_EXBUS_Validate(struct pios_exbus_dev *exbus_dev) +{ + return exbus_dev->magic == PIOS_EXBUS_DEV_MAGIC; +} + +/* Reset channels in case of lost signal or explicit failsafe receiver flag */ +static void PIOS_EXBUS_ResetChannels(struct pios_exbus_dev *exbus_dev) +{ + struct pios_exbus_state *state = &(exbus_dev->state); + + for (int i = 0; i < PIOS_EXBUS_NUM_INPUTS; i++) { + state->channel_data[i] = PIOS_RCVR_TIMEOUT; + } +} + +/* Reset EXBUS receiver state */ +static void PIOS_EXBUS_ResetState(struct pios_exbus_dev *exbus_dev) +{ + struct pios_exbus_state *state = &(exbus_dev->state); + + state->receive_timer = 0; + state->failsafe_timer = 0; + state->failsafe_count = 0; + state->high_baud_rate = false; + state->frame_found = false; + state->quality = 0.0f; + PIOS_EXBUS_ResetChannels(exbus_dev); +} + +/** + * Check and unroll complete frame data. + * \output 0 frame data accepted + * \output -1 frame error found + */ +static int PIOS_EXBUS_UnrollChannels(struct pios_exbus_dev *exbus_dev) +{ + struct pios_exbus_state *state = &(exbus_dev->state); + + if (state->crc != 0) { + /* crc failed */ + return -1; + } + + enum pios_exbus_frame_state exbus_state = EXBUS_STATE_SYNC; + uint8_t *byte = state->received_data; + uint8_t sub_length; + uint8_t n_channels = 0; + uint8_t channel = 0; + + while ((byte - state->received_data) < state->frame_length) { + switch (exbus_state) { + case EXBUS_STATE_SYNC: + /* sync byte */ + if (*byte == EXBUS_SYNC_CHANNEL) { + exbus_state = EXBUS_STATE_REQ; + } else { + return -1; + } + byte += sizeof(uint8_t); + break; + + case EXBUS_STATE_REQ: + /* + * tells us whether the rx is requesting a reply or not, + * currently nothing is actually done with this information... + */ + if (*byte == EXBUS_BYTE_REQ) { + exbus_state = EXBUS_STATE_LEN; + } else if (*byte == EXBUS_BYTE_NOREQ) { + exbus_state = EXBUS_STATE_LEN; + } else { + return -1; + } + byte += sizeof(uint8_t); + break; + + case EXBUS_STATE_LEN: + /* total frame length */ + exbus_state = EXBUS_STATE_PACKET_ID; + byte += sizeof(uint8_t); + break; + + case EXBUS_STATE_PACKET_ID: + /* packet id */ + exbus_state = EXBUS_STATE_DATA_ID; + byte += sizeof(uint8_t); + break; + + case EXBUS_STATE_DATA_ID: + /* checks the type of data, ignore non-rc data */ + if (*byte == EXBUS_DATA_CHANNEL) { + exbus_state = EXBUS_STATE_SUBLEN; + } else { + return -1; + } + byte += sizeof(uint8_t); + break; + + case EXBUS_STATE_SUBLEN: + sub_length = *byte; + n_channels = sub_length / 2; + exbus_state = EXBUS_STATE_DATA; + byte += sizeof(uint8_t); + break; + + case EXBUS_STATE_DATA: + if (channel < n_channels) { + /* 1 lsb = 1/8 us */ + state->channel_data[channel++] = (byte[1] << 8 | byte[0]) / 8; + } + byte += sizeof(uint16_t); + break; + } + } + return 0; +} + +/* Update decoder state processing input byte from the stream */ +static void PIOS_EXBUS_UpdateState(struct pios_exbus_dev *exbus_dev, uint8_t byte) +{ + struct pios_exbus_state *state = &(exbus_dev->state); + + if (!state->frame_found) { + if (byte == EXBUS_SYNC_CHANNEL) { + state->frame_found = true; + state->byte_count = 0; + state->frame_length = EXBUS_MAX_FRAME_LENGTH; + state->crc = PIOS_EXBUS_CRC_Update(0, byte); + state->received_data[state->byte_count++] = byte; + } + } else if (state->byte_count < EXBUS_MAX_FRAME_LENGTH) { + state->crc = PIOS_EXBUS_CRC_Update(state->crc, byte); + state->received_data[state->byte_count++] = byte; + + if (state->byte_count == 3) { + state->frame_length = byte; + } + if (state->byte_count == state->frame_length) { + uint8_t quality_trend = 0; + if (!PIOS_EXBUS_UnrollChannels(exbus_dev)) { + /* data looking good */ + state->failsafe_timer = 0; + state->failsafe_count = 0; + quality_trend = 100; + } + // Calculate quality trend using weighted average of good frames + state->quality = ((state->quality * (EXBUS_FL_WEIGHTED_AVERAGE - 1)) + + quality_trend) / EXBUS_FL_WEIGHTED_AVERAGE; + /* get ready for the next frame */ + state->frame_found = false; + } + } else { + state->frame_found = false; + } +} + +/* Initialise EX Bus receiver interface */ +int32_t PIOS_EXBUS_Init(uint32_t *exbus_id, + const struct pios_com_driver *driver, + uint32_t lower_id) +{ + PIOS_DEBUG_Assert(exbus_id); + PIOS_DEBUG_Assert(driver); + + struct pios_exbus_dev *exbus_dev; + + exbus_dev = (struct pios_exbus_dev *)PIOS_EXBUS_Alloc(); + if (!exbus_dev) { + return -1; + } + + PIOS_EXBUS_ResetState(exbus_dev); + + *exbus_id = (uint32_t)exbus_dev; + + /* Set comm driver callback */ + (driver->bind_rx_cb)(lower_id, PIOS_EXBUS_RxInCallback, *exbus_id); + + if (!PIOS_RTC_RegisterTickCallback(PIOS_EXBUS_Supervisor, *exbus_id)) { + PIOS_DEBUG_Assert(0); + } + + exbus_dev->driver = driver; + exbus_dev->com_port_id = lower_id; + + return 0; +} + +/* Comm byte received callback */ +static uint16_t PIOS_EXBUS_RxInCallback(uint32_t context, + uint8_t *buf, + uint16_t buf_len, + uint16_t *headroom, + bool *need_yield) +{ + struct pios_exbus_dev *exbus_dev = (struct pios_exbus_dev *)context; + + bool valid = PIOS_EXBUS_Validate(exbus_dev); + + PIOS_Assert(valid); + + /* process byte(s) and clear receive timer */ + for (uint8_t i = 0; i < buf_len; i++) { + PIOS_EXBUS_UpdateState(exbus_dev, buf[i]); + exbus_dev->state.receive_timer = 0; + } + + /* Always signal that we can accept more data */ + if (headroom) { + *headroom = EXBUS_MAX_FRAME_LENGTH; + } + + /* We never need a yield */ + *need_yield = false; + + /* Always indicate that all bytes were consumed */ + return buf_len; +} + +/** + * Get the value of an input channel + * \param[in] channel Number of the channel desired (zero based) + * \output PIOS_RCVR_INVALID channel not available + * \output PIOS_RCVR_TIMEOUT failsafe condition or missing receiver + * \output >=0 channel value + */ +static int32_t PIOS_EXBUS_Get(uint32_t rcvr_id, uint8_t channel) +{ + struct pios_exbus_dev *exbus_dev = (struct pios_exbus_dev *)rcvr_id; + + if (!PIOS_EXBUS_Validate(exbus_dev)) { + return PIOS_RCVR_INVALID; + } + + /* return error if channel is not available */ + if (channel >= PIOS_EXBUS_NUM_INPUTS) { + return PIOS_RCVR_INVALID; + } + + /* may also be PIOS_RCVR_TIMEOUT set by other function */ + return exbus_dev->state.channel_data[channel]; +} + +static void PIOS_EXBUS_Change_BaudRate(struct pios_exbus_dev *device) +{ + struct pios_exbus_state *state = &(device->state); + + if (++state->failsafe_count >= EXBUS_BAUD_RATE_LIMIT) { + state->high_baud_rate = !state->high_baud_rate; + (device->driver->set_baud)(device->com_port_id, + state->high_baud_rate ? EXBUS_HIGH_BAUD_RATE : EXBUS_LOW_BAUD_RATE); + state->failsafe_count = 0; + } +} + +/** + * Input data supervisor is called periodically and provides + * two functions: frame syncing and failsafe triggering. + * + * EX.Bus frames come at 20ms or 10ms rate at 125 or 250 kbaud. + * RTC timer is running at 625Hz (1.6ms). So with divider 5 it gives + * 8ms pause between frames which is good for both EX.Bus frame rates. + * + * Data receive function must clear the receive_timer to confirm new + * data reception. If no new data received in 100ms, we must call the + * failsafe function which clears all channels. + */ +static void PIOS_EXBUS_Supervisor(uint32_t exbus_id) +{ + struct pios_exbus_dev *exbus_dev = (struct pios_exbus_dev *)exbus_id; + + bool valid = PIOS_EXBUS_Validate(exbus_dev); + + PIOS_Assert(valid); + + struct pios_exbus_state *state = &(exbus_dev->state); + + /* waiting for new frame if no bytes were received in 8ms */ + if (++state->receive_timer > EXBUS_FRAME_TIMEOUT) { + state->frame_found = false; + state->byte_count = 0; + state->receive_timer = 0; + state->frame_length = EXBUS_MAX_FRAME_LENGTH; + } + + /* activate failsafe if no frames have arrived in 102.4ms */ + if (++state->failsafe_timer > EXBUS_FAILSAFE_TIMEOUT) { + PIOS_EXBUS_ResetChannels(exbus_dev); + state->failsafe_timer = 0; + state->quality = 0.0f; + PIOS_EXBUS_Change_BaudRate(exbus_dev); + } +} + +static uint8_t PIOS_EXBUS_Quality_Get(uint32_t exbus_id) +{ + struct pios_exbus_dev *exbus_dev = (struct pios_exbus_dev *)exbus_id; + + bool valid = PIOS_EXBUS_Validate(exbus_dev); + + PIOS_Assert(valid); + + struct pios_exbus_state *state = &(exbus_dev->state); + + return (uint8_t)(state->quality + 0.5f); +} + +static uint16_t PIOS_EXBUS_CRC_Update(uint16_t crc, uint8_t data) +{ + data ^= (uint8_t)crc & (uint8_t)0xFF; + data ^= data << 4; + crc = ((((uint16_t)data << 8) | ((crc & 0xFF00) >> 8)) + ^ (uint8_t)(data >> 4) ^ ((uint16_t)data << 3)); + + return crc; +} + +#endif /* PIOS_INCLUDE_EXBUS */ + +/** + * @} + * @} + */ diff --git a/flight/pios/common/pios_flash_jedec.c b/flight/pios/common/pios_flash_jedec.c index 74a768184..1ebde0836 100644 --- a/flight/pios/common/pios_flash_jedec.c +++ b/flight/pios/common/pios_flash_jedec.c @@ -372,6 +372,9 @@ static int32_t PIOS_Flash_Jedec_EraseSector(uintptr_t flash_id, uint32_t addr) while (PIOS_Flash_Jedec_Busy(flash_dev) != 0) { #if defined(FLASH_FREERTOS) vTaskDelay(2); +#endif +#ifdef PIOS_INCLUDE_WDG + PIOS_WDG_Clear(); #endif } diff --git a/flight/pios/common/pios_flashfs_logfs.c b/flight/pios/common/pios_flashfs_logfs.c index a479160eb..849e38a70 100644 --- a/flight/pios/common/pios_flashfs_logfs.c +++ b/flight/pios/common/pios_flashfs_logfs.c @@ -123,6 +123,9 @@ static int32_t logfs_erase_arena(const struct logfs_state *logfs, uint8_t arena_ for (uint8_t sector_id = 0; sector_id < (logfs->cfg->arena_size / logfs->cfg->sector_size); sector_id++) { +#ifdef PIOS_INCLUDE_WDG + PIOS_WDG_Clear(); +#endif if (logfs->driver->erase_sector(logfs->flash_id, arena_addr + (sector_id * logfs->cfg->sector_size))) { return -1; @@ -197,9 +200,6 @@ static int32_t logfs_erase_all_arenas(const struct logfs_state *logfs) for (uint16_t arena = 0; arena < num_arenas; arena++) { #ifdef PIOS_LED_HEARTBEAT PIOS_LED_Toggle(PIOS_LED_HEARTBEAT); -#endif -#ifdef PIOS_INCLUDE_WDG - PIOS_WDG_Clear(); #endif if (logfs_erase_arena(logfs, arena) != 0) { return -1; @@ -445,6 +445,7 @@ static int32_t logfs_mount_log(struct logfs_state *logfs, uint8_t arena_id) slot_addr, (uint8_t *)&slot_hdr, sizeof(slot_hdr)) != 0) { + /* Abort the mount (format and retry mount if called from init) */ return -1; } @@ -452,8 +453,13 @@ static int32_t logfs_mount_log(struct logfs_state *logfs, uint8_t arena_id) * Empty slots must be in a continguous block at the * end of the arena. */ - PIOS_Assert(slot_hdr.state == SLOT_STATE_EMPTY || - logfs->num_free_slots == 0); + if (slot_hdr.state != SLOT_STATE_EMPTY && logfs->num_free_slots != 0) { + /* + * Once a free slot is found, the rest of the slots must be free + * else about the mount (format and retry mount if called from init) + */ + return -2; + } switch (slot_hdr.state) { case SLOT_STATE_EMPTY: @@ -465,6 +471,12 @@ static int32_t logfs_mount_log(struct logfs_state *logfs, uint8_t arena_id) case SLOT_STATE_RESERVED: case SLOT_STATE_OBSOLETE: break; + default: + /* + * If any slot header is unrecognized abort the mount + * (format and retry mount if called from init) + */ + return -3; } } @@ -530,6 +542,10 @@ static void PIOS_FLASHFS_Logfs_free(struct logfs_state *logfs) */ int32_t PIOS_FLASHFS_Logfs_Init(uintptr_t *fs_id, const struct flashfs_logfs_cfg *cfg, const struct pios_flash_driver *driver, uintptr_t flash_id) { +#ifdef PIOS_INCLUDE_WDG + PIOS_WDG_Clear(); +#endif + PIOS_Assert(cfg); PIOS_Assert(fs_id); PIOS_Assert(driver); @@ -544,69 +560,64 @@ int32_t PIOS_FLASHFS_Logfs_Init(uintptr_t *fs_id, const struct flashfs_logfs_cfg PIOS_Assert(driver->write_data); PIOS_Assert(driver->read_data); - int8_t rc; + int8_t rc = -1; // assume failure + int8_t count = 0; struct logfs_state *logfs; logfs = (struct logfs_state *)PIOS_FLASHFS_Logfs_alloc(); - if (!logfs) { - rc = -1; - goto out_exit; - } + if (logfs) { + while (rc && count++ < 2) { + /* Bind configuration parameters to this filesystem instance */ + logfs->cfg = cfg; /* filesystem configuration */ + logfs->driver = driver; /* lower-level flash driver */ + logfs->flash_id = flash_id; /* lower-level flash device id */ + logfs->mounted = false; - /* Bind configuration parameters to this filesystem instance */ - logfs->cfg = cfg; /* filesystem configuration */ - logfs->driver = driver; /* lower-level flash driver */ - logfs->flash_id = flash_id; /* lower-level flash device id */ - logfs->mounted = false; + if (logfs->driver->start_transaction(logfs->flash_id) == 0) { + bool found = false; + int32_t arena_id; + for (uint8_t try = 0; !found && try < 2; try++) { + /* Find the active arena */ + arena_id = logfs_find_active_arena(logfs); + if (arena_id >= 0) { + /* Found the active arena */ + found = true; + break; + } else { + /* No active arena found, erase and activate arena 0 */ + if (logfs_erase_arena(logfs, 0) != 0) { + break; + } + if (logfs_activate_arena(logfs, 0) != 0) { + break; + } + } + } - if (logfs->driver->start_transaction(logfs->flash_id) != 0) { - rc = -1; - goto out_exit; - } + if (!found) { + /* Still no active arena, something is broken */ + rc = -2; + goto out_end_trans; + } - bool found = false; - int32_t arena_id; - for (uint8_t try = 0; !found && try < 2; try++) { - /* Find the active arena */ - arena_id = logfs_find_active_arena(logfs); - if (arena_id >= 0) { - /* Found the active arena */ - found = true; - break; - } else { - /* No active arena found, erase and activate arena 0 */ - if (logfs_erase_arena(logfs, 0) != 0) { - break; - } - if (logfs_activate_arena(logfs, 0) != 0) { - break; + /* We've found an active arena, mount it */ + rc = logfs_mount_log(logfs, arena_id); + if (rc != 0) { + /* Failed to mount the log, something is broken */ + PIOS_FLASHFS_Format((uintptr_t)logfs); + rc -= 3; + goto out_end_trans; + } + + *fs_id = (uintptr_t)logfs; + +out_end_trans: + logfs->driver->end_transaction(logfs->flash_id); } } } - if (!found) { - /* Still no active arena, something is broken */ - rc = -2; - goto out_end_trans; - } - - /* We've found an active arena, mount it */ - if (logfs_mount_log(logfs, arena_id) != 0) { - /* Failed to mount the log, something is broken */ - rc = -3; - goto out_end_trans; - } - - /* Log has been mounted */ - rc = 0; - - *fs_id = (uintptr_t)logfs; - -out_end_trans: - logfs->driver->end_transaction(logfs->flash_id); - -out_exit: return rc; } diff --git a/flight/pios/common/pios_hmc5x83.c b/flight/pios/common/pios_hmc5x83.c index 0a16c4d64..5962395c1 100644 --- a/flight/pios/common/pios_hmc5x83.c +++ b/flight/pios/common/pios_hmc5x83.c @@ -45,7 +45,12 @@ typedef struct { uint32_t port_id; uint8_t slave_num; uint8_t CTRLB; + uint16_t magCountMax; + uint16_t magCount; volatile bool data_ready; + int16_t magData[3]; + bool hw_error; + uint32_t lastConfigTime; } pios_hmc5x83_dev_data_t; static int32_t PIOS_HMC5x83_Config(pios_hmc5x83_dev_data_t *dev); @@ -66,6 +71,7 @@ const PIOS_SENSORS_Driver PIOS_HMC5x83_Driver = { .get_scale = PIOS_HMC5x83_driver_get_scale, .is_polled = true, }; + /** * Allocate the device setting structure * @return pios_hmc5x83_dev_data_t pointer to newly created structure @@ -104,20 +110,73 @@ pios_hmc5x83_dev_t PIOS_HMC5x83_Init(const struct pios_hmc5x83_cfg *cfg, uint32_ dev->cfg = cfg; // store config before enabling interrupt dev->port_id = port_id; dev->slave_num = slave_num; -#ifdef PIOS_HMC5X83_HAS_GPIOS - PIOS_EXTI_Init(cfg->exti_cfg); -#endif - int32_t val = PIOS_HMC5x83_Config(dev); - PIOS_Assert(val == 0); +#ifdef PIOS_HMC5X83_HAS_GPIOS + if (cfg->exti_cfg) { + PIOS_EXTI_Init(cfg->exti_cfg); + } else +#endif /* PIOS_HMC5X83_HAS_GPIOS */ + { +// if PIOS_SENSOR_RATE is defined, there is a sensor loop that is called at that frequency +// and "is data available" can simply return false a few times to save some CPU +#ifdef PIOS_SENSOR_RATE + // for external mags that have no interrupt line, just poll them with a timer + // use the configured Output Data Rate to calculate the number of interations (of the main sensor task loop) + // to return false, before returning true + uint16_t rate100; + switch (cfg->M_ODR) { + case PIOS_HMC5x83_ODR_0_75: + rate100 = 75; + break; + case PIOS_HMC5x83_ODR_1_5: + rate100 = 150; + break; + case PIOS_HMC5x83_ODR_3: + rate100 = 300; + break; + case PIOS_HMC5x83_ODR_7_5: + rate100 = 750; + break; + case PIOS_HMC5x83_ODR_15: + rate100 = 1500; + break; + case PIOS_HMC5x83_ODR_30: + rate100 = 3000; + break; + default: + case PIOS_HMC5x83_ODR_75: + rate100 = 7500; + break; + } + // if the application sensor rate is fast enough to warrant skipping some slow hardware sensor reads + if ((PIOS_SENSOR_RATE * 100.0f / 3.0f) > rate100) { + // count the number of "return false" up to this number + dev->magCountMax = ((uint16_t)PIOS_SENSOR_RATE * 100 / rate100) + 1; + } else { + // return true every time (do a hardware sensor poll every time) + dev->magCountMax = 1; + } +#else /* PIOS_SENSOR_RATE */ + // return true every time (do a hardware sensor poll every time) + dev->magCountMax = 1; +#endif /* PIOS_SENSOR_RATE */ + // with this counter + dev->magCount = 0; + } + + if (PIOS_HMC5x83_Config(dev) != 0) { + dev->hw_error = true; + } dev->data_ready = false; return (pios_hmc5x83_dev_t)dev; } -void PIOS_HMC5x83_Register(pios_hmc5x83_dev_t handler) +void PIOS_HMC5x83_Register(pios_hmc5x83_dev_t handler, PIOS_SENSORS_TYPE sensortype) { - PIOS_SENSORS_Register(&PIOS_HMC5x83_Driver, PIOS_SENSORS_TYPE_3AXIS_MAG, handler); + if (handler) { + PIOS_SENSORS_Register(&PIOS_HMC5x83_Driver, sensortype, handler); + } } /** @@ -185,6 +244,8 @@ static int32_t PIOS_HMC5x83_Config(pios_hmc5x83_dev_data_t *dev) uint8_t CTRLA = 0x00; uint8_t MODE = 0x00; + dev->lastConfigTime = PIOS_DELAY_GetRaw(); + const struct pios_hmc5x83_cfg *cfg = dev->cfg; dev->CTRLB = 0; @@ -209,9 +270,64 @@ static int32_t PIOS_HMC5x83_Config(pios_hmc5x83_dev_data_t *dev) return -1; } +#ifdef PIOS_INCLUDE_WDG + // give HMC5x83 on I2C some extra time + PIOS_WDG_Clear(); +#endif /* PIOS_INCLUDE_WDG */ + + if (PIOS_HMC5x83_Test((pios_hmc5x83_dev_t)dev) != 0) { + return -1; + } + return 0; } +static void PIOS_HMC5x83_Orient(enum PIOS_HMC5X83_ORIENTATION orientation, int16_t in[3], int16_t out[3]) +{ + switch (orientation) { + case PIOS_HMC5X83_ORIENTATION_EAST_NORTH_UP: + out[0] = in[2]; + out[1] = in[0]; + out[2] = -in[1]; + break; + case PIOS_HMC5X83_ORIENTATION_SOUTH_EAST_UP: + out[0] = -in[0]; + out[1] = in[2]; + out[2] = -in[1]; + break; + case PIOS_HMC5X83_ORIENTATION_WEST_SOUTH_UP: + out[0] = -in[2]; + out[1] = -in[0]; + out[2] = -in[1]; + break; + case PIOS_HMC5X83_ORIENTATION_NORTH_WEST_UP: + out[0] = in[0]; + out[1] = -in[2]; + out[2] = -in[1]; + break; + case PIOS_HMC5X83_ORIENTATION_EAST_SOUTH_DOWN: + out[0] = in[2]; + out[1] = -in[0]; + out[2] = in[1]; + break; + case PIOS_HMC5X83_ORIENTATION_SOUTH_WEST_DOWN: + out[0] = -in[0]; + out[1] = -in[2]; + out[2] = in[1]; + break; + case PIOS_HMC5X83_ORIENTATION_WEST_NORTH_DOWN: + out[0] = -in[2]; + out[1] = in[0]; + out[2] = in[1]; + break; + case PIOS_HMC5X83_ORIENTATION_NORTH_EAST_DOWN: + out[0] = in[0]; + out[1] = in[2]; + out[2] = in[1]; + break; + } +} + /** * @brief Read current X, Z, Y values (in that order) * \param[in] dev device handler @@ -265,50 +381,14 @@ int32_t PIOS_HMC5x83_ReadMag(pios_hmc5x83_dev_t handler, int16_t out[3]) temp[i] = v; } - switch (dev->cfg->Orientation) { - case PIOS_HMC5X83_ORIENTATION_EAST_NORTH_UP: - out[0] = temp[2]; - out[1] = temp[0]; - out[2] = -temp[1]; - break; - case PIOS_HMC5X83_ORIENTATION_SOUTH_EAST_UP: - out[0] = -temp[0]; - out[1] = temp[2]; - out[2] = -temp[1]; - break; - case PIOS_HMC5X83_ORIENTATION_WEST_SOUTH_UP: - out[0] = -temp[2]; - out[1] = -temp[0]; - out[2] = -temp[1]; - break; - case PIOS_HMC5X83_ORIENTATION_NORTH_WEST_UP: - out[0] = temp[0]; - out[1] = -temp[2]; - out[2] = -temp[1]; - break; - case PIOS_HMC5X83_ORIENTATION_EAST_SOUTH_DOWN: - out[0] = temp[2]; - out[1] = -temp[0]; - out[2] = temp[1]; - break; - case PIOS_HMC5X83_ORIENTATION_SOUTH_WEST_DOWN: - out[0] = -temp[0]; - out[1] = -temp[2]; - out[2] = temp[1]; - break; - case PIOS_HMC5X83_ORIENTATION_WEST_NORTH_DOWN: - out[0] = -temp[2]; - out[1] = temp[0]; - out[2] = temp[1]; - break; - case PIOS_HMC5X83_ORIENTATION_NORTH_EAST_DOWN: - out[0] = temp[0]; - out[1] = temp[2]; - out[2] = temp[1]; - break; - } + PIOS_HMC5x83_Orient(dev->cfg->Orientation, temp, out); - // This should not be necessary but for some reason it is coming out of continuous conversion mode + // "This should not be necessary but for some reason it is coming out of continuous conversion mode" + // + // By default the chip is in single read mode meaning after reading from it once, it will go idle to save power. + // Once idle, we have write to it to turn it on before we can read from it again. + // To conserve current between measurements, the device is placed in a state similar to idle mode, but the + // Mode Register is not changed to Idle Mode. That is, MD[n] bits are unchanged. dev->cfg->Driver->Write(handler, PIOS_HMC5x83_MODE_REG, PIOS_HMC5x83_MODE_CONTINUOUS); return 0; @@ -334,11 +414,23 @@ uint8_t PIOS_HMC5x83_ReadID(pios_hmc5x83_dev_t handler, uint8_t out[4]) * \return true if new data is available * \return false if new data is not available */ -bool PIOS_HMC5x83_NewDataAvailable(pios_hmc5x83_dev_t handler) +bool PIOS_HMC5x83_NewDataAvailable(__attribute__((unused)) pios_hmc5x83_dev_t handler) { pios_hmc5x83_dev_data_t *dev = dev_validate(handler); - return dev->data_ready; +#ifdef PIOS_HMC5X83_HAS_GPIOS + if (dev->cfg->exti_cfg) { // if this device has an interrupt line attached, then wait for interrupt to say data is ready + return dev->data_ready; + } else +#endif /* PIOS_HMC5X83_HAS_GPIOS */ + { // else poll to see if data is ready or just say "true" and set polling interval elsewhere + if (++(dev->magCount) >= dev->magCountMax) { + dev->magCount = 0; + return true; + } else { + return false; + } + } } /** @@ -356,6 +448,12 @@ int32_t PIOS_HMC5x83_Test(pios_hmc5x83_dev_t handler) int16_t values[3]; pios_hmc5x83_dev_data_t *dev = dev_validate(handler); +#ifdef PIOS_INCLUDE_WDG + // give HMC5x83 on I2C some extra time to allow for reset, etc. if needed + // this is not in a loop, so it is safe + PIOS_WDG_Clear(); +#endif /* PIOS_INCLUDE_WDG */ + /* Verify that ID matches (HMC5x83 ID is null-terminated ASCII string "H43") */ char id[4]; @@ -435,16 +533,22 @@ int32_t PIOS_HMC5x83_Test(pios_hmc5x83_dev_t handler) return failed; } +#ifdef PIOS_HMC5X83_HAS_GPIOS /** * @brief IRQ Handler */ bool PIOS_HMC5x83_IRQHandler(pios_hmc5x83_dev_t handler) { + if (!handler) { // handler is not set on first call + return false; + } pios_hmc5x83_dev_data_t *dev = dev_validate(handler); dev->data_ready = true; + return false; } +#endif /* PIOS_HMC5X83_HAS_GPIOS */ #ifdef PIOS_INCLUDE_SPI int32_t PIOS_HMC5x83_SPI_Read(pios_hmc5x83_dev_t handler, uint8_t address, uint8_t *buffer, uint8_t len); @@ -529,8 +633,8 @@ int32_t PIOS_HMC5x83_SPI_Write(pios_hmc5x83_dev_t handler, uint8_t address, uint return 0; } #endif /* PIOS_INCLUDE_SPI */ -#ifdef PIOS_INCLUDE_I2C +#ifdef PIOS_INCLUDE_I2C int32_t PIOS_HMC5x83_I2C_Read(pios_hmc5x83_dev_t handler, uint8_t address, uint8_t *buffer, uint8_t len); int32_t PIOS_HMC5x83_I2C_Write(pios_hmc5x83_dev_t handler, uint8_t address, uint8_t buffer); @@ -609,9 +713,9 @@ int32_t PIOS_HMC5x83_I2C_Write(pios_hmc5x83_dev_t handler, uint8_t address, uint #endif /* PIOS_INCLUDE_I2C */ /* PIOS sensor driver implementation */ -bool PIOS_HMC5x83_driver_Test(uintptr_t context) +bool PIOS_HMC5x83_driver_Test(__attribute__((unused)) uintptr_t context) { - return !PIOS_HMC5x83_Test((pios_hmc5x83_dev_t)context); + return true; // Do not do tests now, Sensors module takes this rather too seriously. } void PIOS_HMC5x83_driver_Reset(__attribute__((unused)) uintptr_t context) {} @@ -625,19 +729,51 @@ void PIOS_HMC5x83_driver_get_scale(float *scales, uint8_t size, __attribute__((u void PIOS_HMC5x83_driver_fetch(void *data, uint8_t size, uintptr_t context) { PIOS_Assert(size > 0); - int16_t mag[3]; - PIOS_HMC5x83_ReadMag((pios_hmc5x83_dev_t)context, mag); + pios_hmc5x83_dev_data_t *dev = dev_validate((pios_hmc5x83_dev_t)context); + PIOS_SENSORS_3Axis_SensorsWithTemp *tmp = data; + tmp->count = 1; - tmp->sample[0].x = mag[0]; - tmp->sample[0].y = mag[1]; - tmp->sample[0].z = mag[2]; + tmp->sample[0].x = dev->magData[0]; + tmp->sample[0].y = dev->magData[1]; + tmp->sample[0].z = dev->magData[2]; tmp->temperature = 0; } + bool PIOS_HMC5x83_driver_poll(uintptr_t context) { - return PIOS_HMC5x83_NewDataAvailable((pios_hmc5x83_dev_t)context); + pios_hmc5x83_dev_data_t *dev = dev_validate((pios_hmc5x83_dev_t)context); + + if (dev->hw_error) { + if (PIOS_DELAY_DiffuS(dev->lastConfigTime) < 1000000) { + return false; + } + +#ifdef PIOS_INCLUDE_WDG + // give HMC5x83 on I2C some extra time + PIOS_WDG_Clear(); +#endif /* PIOS_INCLUDE_WDG */ + + if (PIOS_HMC5x83_Config(dev) == 0) { + dev->hw_error = false; + } + } + + if (dev->hw_error) { + return false; + } + + if (!PIOS_HMC5x83_NewDataAvailable((pios_hmc5x83_dev_t)context)) { + return false; + } + + if (PIOS_HMC5x83_ReadMag((pios_hmc5x83_dev_t)context, dev->magData) != 0) { + dev->hw_error = true; + return false; + } + + return true; } #endif /* PIOS_INCLUDE_HMC5x83 */ diff --git a/flight/pios/common/pios_hott.c b/flight/pios/common/pios_hott.c new file mode 100644 index 000000000..a3106edc4 --- /dev/null +++ b/flight/pios/common/pios_hott.c @@ -0,0 +1,450 @@ +/** + ****************************************************************************** + * @file pios_hott.c + * @author The LibrePilot Project, http://www.librepilot.org, Copyright (c) 2015 + * @author Tau Labs, http://taulabs.org, Copyright (C) 2013-2014 + * @addtogroup PIOS PIOS Core hardware abstraction layer + * @{ + * @addtogroup PIOS_HOTT Graupner HoTT receiver functions + * @{ + * @brief Graupner HoTT receiver functions for SUMD/H + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +/* Project Includes */ +#include "pios_hott_priv.h" + +#if defined(PIOS_INCLUDE_HOTT) + +#if !defined(PIOS_INCLUDE_RTC) +#error PIOS_INCLUDE_RTC must be used to use HOTT +#endif + +/** + * HOTT protocol documentation + * + * Currently known Graupner HoTT serial port settings: + * 115200bps serial stream, 8 bits, no parity, 1 stop bit + * size of each frame: 11..37 bytes + * data resolution: 14 bit + * frame period: 11ms or 22ms + * + * Currently known SUMD/SUMH frame structure: + * Section Byte_Number Byte_Name Byte_Value Remark + * Header 0 Vendor_ID 0xA8 Graupner + * Header 1 Status 0x00 valid and live SUMH data frame + * 0x01 valid and live SUMD data frame + * 0x81 valid SUMD/H data frame with + * transmitter in fail safe condition + * others invalid frame + * Header 2 N_Channels 0x02..0x20 number of transmitted channels + * Data n*2+1 Channel n MSB 0x00..0xff High Byte of channel n data + * Data n*2+2 Channel n LSB 0x00..0xff Low Byte of channel n data + * SUMD_CRC (N_Channels+1)*2+1 CRC High Byte 0x00..0xff High Byte of 16 Bit CRC + * SUMD_CRC (N_Channels+1)*2+2 CRC Low Byte 0x00..0xff Low Byte of 16 Bit CRC + * SUMH_Telemetry (N_Channels+1)*2+1 Telemetry_Req 0x00..0xff 0x00 no telemetry request + * SUMH_CRC (N_Channels+1)*2+2 CRC Byte 0x00..0xff Low Byte of all added data bytes + + * Channel Data Interpretation + * Stick Positon Channel Data Remark + * ext. low (-150%) 0x1c20 900µs + * low (-100%) 0x2260 1100µs + * neutral (0%) 0x2ee0 1500µs + * high (100%) 0x3b60 1900µs + * ext. high(150%) 0x41a0 2100µs + + * Channel Mapping (not sure) + * 1 Pitch + * 2 Aileron + * 3 Elevator + * 4 Yaw + * 5 Aux/Gyro on MX-12 + * 6 ESC + * 7 Aux/Gyr + */ + +/* HOTT frame size and contents definitions */ +#define HOTT_HEADER_LENGTH 3 +#define HOTT_CRC_LENGTH 2 +#define HOTT_MAX_CHANNELS_PER_FRAME 32 +#define HOTT_OVERHEAD_LENGTH (HOTT_HEADER_LENGTH + HOTT_CRC_LENGTH) +#define HOTT_MAX_FRAME_LENGTH (HOTT_MAX_CHANNELS_PER_FRAME * 2 + HOTT_OVERHEAD_LENGTH) + +#define HOTT_GRAUPNER_ID 0xA8 +#define HOTT_STATUS_LIVING_SUMH 0x00 +#define HOTT_STATUS_LIVING_SUMD 0x01 +#define HOTT_STATUS_FAILSAFE 0x81 +#define HOTT_FRAME_TIMEOUT 4 +#define HOTT_FAILSAFE_TIMEOUT 64 + +/* With an Ex.Bus frame rate of 11/22ms (90/45Hz) averaging over 15 samples + * gives about a 165/330ms response. + */ +#define HOTT_FL_WEIGHTED_AVERAGE 20 + + +/* Forward Declarations */ +static int32_t PIOS_HOTT_Get(uint32_t rcvr_id, uint8_t channel); +static uint16_t PIOS_HOTT_RxInCallback(uint32_t context, + uint8_t *buf, + uint16_t buf_len, + uint16_t *headroom, + bool *need_yield); +static void PIOS_HOTT_Supervisor(uint32_t hott_id); +static uint8_t PIOS_HOTT_Quality_Get(uint32_t rcvr_id); + +/* Local Variables */ +const struct pios_rcvr_driver pios_hott_rcvr_driver = { + .read = PIOS_HOTT_Get, + .get_quality = PIOS_HOTT_Quality_Get, +}; + +enum pios_hott_dev_magic { + PIOS_HOTT_DEV_MAGIC = 0x4853554D, +}; + +struct pios_hott_state { + uint16_t channel_data[PIOS_HOTT_NUM_INPUTS]; + uint8_t received_data[HOTT_MAX_FRAME_LENGTH]; + uint8_t receive_timer; + uint8_t failsafe_timer; + uint8_t frame_found; + uint8_t tx_connected; + uint8_t byte_count; + uint8_t frame_length; + float quality; +}; + +struct pios_hott_dev { + enum pios_hott_dev_magic magic; + const struct pios_hott_cfg *cfg; + enum pios_hott_proto proto; + struct pios_hott_state state; +}; + +/* Allocate HOTT device descriptor */ +static struct pios_hott_dev *PIOS_HOTT_Alloc(void) +{ + struct pios_hott_dev *hott_dev; + + hott_dev = (struct pios_hott_dev *)pios_malloc(sizeof(*hott_dev)); + if (!hott_dev) { + return NULL; + } + + hott_dev->magic = PIOS_HOTT_DEV_MAGIC; + return hott_dev; +} + +/* Validate HOTT device descriptor */ +static bool PIOS_HOTT_Validate(struct pios_hott_dev *hott_dev) +{ + return hott_dev->magic == PIOS_HOTT_DEV_MAGIC; +} + +/* Reset channels in case of lost signal or explicit failsafe receiver flag */ +static void PIOS_HOTT_ResetChannels(struct pios_hott_state *state) +{ + for (int i = 0; i < PIOS_HOTT_NUM_INPUTS; i++) { + state->channel_data[i] = PIOS_RCVR_TIMEOUT; + } +} + +/* Reset HOTT receiver state */ +static void PIOS_HOTT_ResetState(struct pios_hott_state *state) +{ + state->receive_timer = 0; + state->failsafe_timer = 0; + state->frame_found = 0; + state->tx_connected = 0; + state->quality = 0.0f; + PIOS_HOTT_ResetChannels(state); +} + +/** + * Check and unroll complete frame data. + * \output 0 frame data accepted + * \output -1 frame error found + */ +static int PIOS_HOTT_UnrollChannels(struct pios_hott_dev *hott_dev) +{ + struct pios_hott_state *state = &(hott_dev->state); + + /* check the header and crc for a valid HoTT SUM stream */ + uint8_t vendor = state->received_data[0]; + uint8_t status = state->received_data[1]; + + if (vendor != HOTT_GRAUPNER_ID) { + /* Graupner ID was expected */ + goto stream_error; + } + + switch (status) { + case HOTT_STATUS_LIVING_SUMH: + case HOTT_STATUS_LIVING_SUMD: + case HOTT_STATUS_FAILSAFE: + /* check crc before processing */ + if (hott_dev->proto == PIOS_HOTT_PROTO_SUMD) { + /* SUMD has 16 bit CCITT CRC */ + uint16_t crc = 0; + uint8_t *s = &(state->received_data[0]); + int len = state->byte_count - 2; + for (int n = 0; n < len; n++) { + crc ^= (uint16_t)s[n] << 8; + for (int i = 0; i < 8; i++) { + crc = (crc & 0x8000) ? (crc << 1) ^ 0x1021 : (crc << 1); + } + } + if (crc ^ (((uint16_t)s[len] << 8) | s[len + 1])) { + /* wrong crc checksum found */ + goto stream_error; + } + } + if (hott_dev->proto == PIOS_HOTT_PROTO_SUMH) { + /* SUMH has only 8 bit added CRC */ + uint8_t crc = 0; + uint8_t *s = &(state->received_data[0]); + int len = state->byte_count - 1; + for (int n = 0; n < len; n++) { + crc += s[n]; + } + if (crc ^ s[len]) { + /* wrong crc checksum found */ + goto stream_error; + } + } + /* check for a living connect */ + state->tx_connected |= (status != HOTT_STATUS_FAILSAFE); + break; + default: + /* wrong header format */ + goto stream_error; + } + + /* check initial connection since reset or timeout */ + if (!(state->tx_connected)) { + /* these are failsafe data without a first connect. ignore it */ + PIOS_HOTT_ResetChannels(state); + return 0; + } + + /* unroll channels */ + uint8_t n_channels = state->received_data[2]; + uint8_t *s = &(state->received_data[3]); + uint16_t word; + + for (int i = 0; i < HOTT_MAX_CHANNELS_PER_FRAME; i++) { + if (i < n_channels) { + word = ((uint16_t)s[0] << 8) | s[1]; + s += sizeof(uint16_t); + /* save the channel value */ + if (i < PIOS_HOTT_NUM_INPUTS) { + /* floating version. channel limits from -100..+100% are mapped to 1000..2000 */ + state->channel_data[i] = (uint16_t)(word / 6.4f - 375); + } + } else { + /* this channel was not received */ + state->channel_data[i] = PIOS_RCVR_INVALID; + } + } + + /* all channels processed */ + return 0; + +stream_error: + /* either SUMD selected with SUMH stream found, or vice-versa */ + return -1; +} + +/* Update decoder state processing input byte from the HoTT stream */ +static void PIOS_HOTT_UpdateState(struct pios_hott_dev *hott_dev, uint8_t byte) +{ + struct pios_hott_state *state = &(hott_dev->state); + + if (state->frame_found) { + /* receiving the data frame */ + if (state->byte_count < HOTT_MAX_FRAME_LENGTH) { + /* store next byte */ + state->received_data[state->byte_count++] = byte; + if (state->byte_count == HOTT_HEADER_LENGTH) { + /* 3rd byte contains the number of channels. calculate frame size */ + state->frame_length = HOTT_OVERHEAD_LENGTH + 2 * byte; + } + if (state->byte_count == state->frame_length) { + uint8_t quality_trend = 0; + /* full frame received - process and wait for new one */ + if (!PIOS_HOTT_UnrollChannels(hott_dev)) { + /* data looking good */ + state->failsafe_timer = 0; + quality_trend = 100; + } + // Calculate quality trend using weighted average of good frames + state->quality = ((state->quality * (HOTT_FL_WEIGHTED_AVERAGE - 1)) + + quality_trend) / HOTT_FL_WEIGHTED_AVERAGE; + + /* prepare for the next frame */ + state->frame_found = 0; + } + } + } +} + +/* Initialise HoTT receiver interface */ +int32_t PIOS_HOTT_Init(uint32_t *hott_id, + const struct pios_com_driver *driver, + uint32_t lower_id, + enum pios_hott_proto proto) +{ + PIOS_DEBUG_Assert(hott_id); + PIOS_DEBUG_Assert(driver); + + struct pios_hott_dev *hott_dev; + + hott_dev = (struct pios_hott_dev *)PIOS_HOTT_Alloc(); + if (!hott_dev) { + return -1; + } + + /* Bind the configuration to the device instance */ + hott_dev->proto = proto; + + PIOS_HOTT_ResetState(&(hott_dev->state)); + + *hott_id = (uint32_t)hott_dev; + + /* Set comm driver callback */ + (driver->bind_rx_cb)(lower_id, PIOS_HOTT_RxInCallback, *hott_id); + + if (!PIOS_RTC_RegisterTickCallback(PIOS_HOTT_Supervisor, *hott_id)) { + PIOS_DEBUG_Assert(0); + } + + return 0; +} + +/* Comm byte received callback */ +static uint16_t PIOS_HOTT_RxInCallback(uint32_t context, + uint8_t *buf, + uint16_t buf_len, + uint16_t *headroom, + bool *need_yield) +{ + struct pios_hott_dev *hott_dev = (struct pios_hott_dev *)context; + + bool valid = PIOS_HOTT_Validate(hott_dev); + + PIOS_Assert(valid); + + /* process byte(s) and clear receive timer */ + for (uint8_t i = 0; i < buf_len; i++) { + PIOS_HOTT_UpdateState(hott_dev, buf[i]); + hott_dev->state.receive_timer = 0; + } + + /* Always signal that we can accept more data */ + if (headroom) { + *headroom = HOTT_MAX_FRAME_LENGTH; + } + + /* We never need a yield */ + *need_yield = false; + + /* Always indicate that all bytes were consumed */ + return buf_len; +} + +/** + * Get the value of an input channel + * \param[in] channel Number of the channel desired (zero based) + * \output PIOS_RCVR_INVALID channel not available + * \output PIOS_RCVR_TIMEOUT failsafe condition or missing receiver + * \output >=0 channel value + */ +static int32_t PIOS_HOTT_Get(uint32_t rcvr_id, uint8_t channel) +{ + struct pios_hott_dev *hott_dev = (struct pios_hott_dev *)rcvr_id; + + if (!PIOS_HOTT_Validate(hott_dev)) { + return PIOS_RCVR_INVALID; + } + + /* return error if channel is not available */ + if (channel >= PIOS_HOTT_NUM_INPUTS) { + return PIOS_RCVR_INVALID; + } + + /* may also be PIOS_RCVR_TIMEOUT set by other function */ + return hott_dev->state.channel_data[channel]; +} + +static uint8_t PIOS_HOTT_Quality_Get(uint32_t hott_id) +{ + struct pios_hott_dev *hott_dev = (struct pios_hott_dev *)hott_id; + + bool valid = PIOS_HOTT_Validate(hott_dev); + + PIOS_Assert(valid); + + struct pios_hott_state *state = &(hott_dev->state); + + return (uint8_t)(state->quality + 0.5f); +} + +/** + * Input data supervisor is called periodically and provides + * two functions: frame syncing and failsafe triggering. + * + * HOTT frames come at 11ms or 22ms rate at 115200bps. + * RTC timer is running at 625Hz (1.6ms). So with divider 5 it gives + * 8ms pause between frames which is good for both HOTT frame rates. + * + * Data receive function must clear the receive_timer to confirm new + * data reception. If no new data received in 100ms, we must call the + * failsafe function which clears all channels. + */ +static void PIOS_HOTT_Supervisor(uint32_t hott_id) +{ + struct pios_hott_dev *hott_dev = (struct pios_hott_dev *)hott_id; + + bool valid = PIOS_HOTT_Validate(hott_dev); + + PIOS_Assert(valid); + + struct pios_hott_state *state = &(hott_dev->state); + + /* waiting for new frame if no bytes were received in 8ms */ + if (++state->receive_timer > HOTT_FRAME_TIMEOUT) { + state->frame_found = 1; + state->byte_count = 0; + state->receive_timer = 0; + state->frame_length = HOTT_MAX_FRAME_LENGTH; + } + + /* activate failsafe if no frames have arrived in 102.4ms */ + if (++state->failsafe_timer > HOTT_FAILSAFE_TIMEOUT) { + PIOS_HOTT_ResetChannels(state); + state->failsafe_timer = 0; + state->tx_connected = 0; + state->quality = 0.0f; + } +} + +#endif /* PIOS_INCLUDE_HOTT */ + +/** + * @} + * @} + */ diff --git a/flight/pios/common/pios_ibus.c b/flight/pios/common/pios_ibus.c new file mode 100644 index 000000000..4ba74fcf2 --- /dev/null +++ b/flight/pios/common/pios_ibus.c @@ -0,0 +1,255 @@ +/** + ****************************************************************************** + * @file pios_ibus.c + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * dRonin, http://dRonin.org/, Copyright (C) 2016 + * @addtogroup PIOS PIOS Core hardware abstraction layer + * @{ + * @addtogroup PIOS_IBus PiOS IBus receiver driver + * @{ + * @brief Receives and decodes IBus protocol reciever packets + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Additional note on redistribution: The copyright and license notices above + * must be maintained in each individual source file that is a derivative work + * of this source file; otherwise redistribution is prohibited. + */ + +#include "pios_ibus_priv.h" + +#ifdef PIOS_INCLUDE_IBUS + +// 1 sync byte, 1 unknown byte, 10x channels (uint16_t), 8 unknown bytes, 2 crc bytes +#define PIOS_IBUS_BUFLEN (1 + 1 + PIOS_IBUS_NUM_INPUTS * 2 + 8 + 2) +#define PIOS_IBUS_SYNCBYTE 0x20 +#define PIOS_IBUS_MAGIC 0x84fd9a39 + +/** + * @brief IBus receiver driver internal state data + */ +struct pios_ibus_dev { + uint32_t magic; + int buf_pos; + int rx_timer; + int failsafe_timer; + uint16_t checksum; + uint16_t channel_data[PIOS_IBUS_NUM_INPUTS]; + uint8_t rx_buf[PIOS_IBUS_BUFLEN]; +}; + +/** + * @brief Allocates a driver instance + * @retval pios_ibus_dev pointer on success, NULL on failure + */ +static struct pios_ibus_dev *PIOS_IBUS_Alloc(void); +/** + * @brief Validate a driver instance + * @param[in] dev device driver instance pointer + * @retval true on success, false on failure + */ +static bool PIOS_IBUS_Validate(const struct pios_ibus_dev *ibus_dev); +/** + * @brief Read a channel from the last received frame + * @param[in] id Driver instance + * @param[in] channel 0-based channel index + * @retval raw channel value, or error value (see pios_rcvr.h) + */ +static int32_t PIOS_IBUS_Read(uint32_t id, uint8_t channel); +/** + * @brief Set all channels in the last frame buffer to a given value + * @param[in] dev Driver instance + * @param[in] value channel value + */ +static void PIOS_IBUS_SetAllChannels(struct pios_ibus_dev *ibus_dev, uint16_t value); +/** + * @brief Serial receive callback + * @param[in] context Driver instance handle + * @param[in] buf Receive buffer + * @param[in] buf_len Number of bytes available + * @param[out] headroom Number of bytes remaining in internal buffer + * @param[out] task_woken Did we awake a task? + * @retval Number of bytes consumed from the buffer + */ +static uint16_t PIOS_IBUS_Receive(uint32_t context, uint8_t *buf, uint16_t buf_len, + uint16_t *headroom, bool *task_woken); +/** + * @brief Reset the internal receive buffer state + * @param[in] ibus_dev device driver instance pointer + */ +static void PIOS_IBUS_ResetBuffer(struct pios_ibus_dev *ibus_dev); +/** + * @brief Unpack a frame from the internal receive buffer to the channel buffer + * @param[in] ibus_dev device driver instance pointer + */ +static void PIOS_IBUS_UnpackFrame(struct pios_ibus_dev *ibus_dev); +/** + * @brief RTC tick callback + * @param[in] context Driver instance handle + */ +static void PIOS_IBUS_Supervisor(uint32_t context); + +// public +const struct pios_rcvr_driver pios_ibus_rcvr_driver = { + .read = PIOS_IBUS_Read, +}; + + +static struct pios_ibus_dev *PIOS_IBUS_Alloc(void) +{ + struct pios_ibus_dev *ibus_dev; + + ibus_dev = (struct pios_ibus_dev *)pios_malloc(sizeof(*ibus_dev)); + + if (!ibus_dev) { + return NULL; + } + + memset(ibus_dev, 0, sizeof(*ibus_dev)); + ibus_dev->magic = PIOS_IBUS_MAGIC; + + return ibus_dev; +} + +static bool PIOS_IBUS_Validate(const struct pios_ibus_dev *ibus_dev) +{ + return ibus_dev && ibus_dev->magic == PIOS_IBUS_MAGIC; +} + +int32_t PIOS_IBUS_Init(uint32_t *ibus_id, const struct pios_com_driver *driver, + uint32_t lower_id) +{ + struct pios_ibus_dev *ibus_dev = PIOS_IBUS_Alloc(); + + if (!ibus_dev) { + return -1; + } + + *ibus_id = (uint32_t)ibus_dev; + + PIOS_IBUS_SetAllChannels(ibus_dev, PIOS_RCVR_INVALID); + + if (!PIOS_RTC_RegisterTickCallback(PIOS_IBUS_Supervisor, *ibus_id)) { + PIOS_Assert(0); + } + + (driver->bind_rx_cb)(lower_id, PIOS_IBUS_Receive, *ibus_id); + + return 0; +} + +static int32_t PIOS_IBUS_Read(uint32_t context, uint8_t channel) +{ + if (channel > PIOS_IBUS_NUM_INPUTS) { + return PIOS_RCVR_INVALID; + } + + struct pios_ibus_dev *ibus_dev = (struct pios_ibus_dev *)context; + if (!PIOS_IBUS_Validate(ibus_dev)) { + return PIOS_RCVR_NODRIVER; + } + + return ibus_dev->channel_data[channel]; +} + +static void PIOS_IBUS_SetAllChannels(struct pios_ibus_dev *ibus_dev, uint16_t value) +{ + for (int i = 0; i < PIOS_IBUS_NUM_INPUTS; i++) { + ibus_dev->channel_data[i] = value; + } +} + +static uint16_t PIOS_IBUS_Receive(uint32_t context, uint8_t *buf, uint16_t buf_len, + uint16_t *headroom, bool *task_woken) +{ + struct pios_ibus_dev *ibus_dev = (struct pios_ibus_dev *)context; + + if (!PIOS_IBUS_Validate(ibus_dev)) { + goto out_fail; + } + + for (int i = 0; i < buf_len; i++) { + if (ibus_dev->buf_pos == 0 && buf[i] != PIOS_IBUS_SYNCBYTE) { + continue; + } + + ibus_dev->rx_buf[ibus_dev->buf_pos++] = buf[i]; + if (ibus_dev->buf_pos <= PIOS_IBUS_BUFLEN - 2) { + ibus_dev->checksum -= buf[i]; + } else if (ibus_dev->buf_pos == PIOS_IBUS_BUFLEN) { + PIOS_IBUS_UnpackFrame(ibus_dev); + } + } + + ibus_dev->rx_timer = 0; + + *headroom = PIOS_IBUS_BUFLEN - ibus_dev->buf_pos; + *task_woken = false; + return buf_len; + +out_fail: + *headroom = 0; + *task_woken = false; + return 0; +} + +static void PIOS_IBUS_ResetBuffer(struct pios_ibus_dev *ibus_dev) +{ + ibus_dev->checksum = 0xffff; + ibus_dev->buf_pos = 0; +} + +static void PIOS_IBUS_UnpackFrame(struct pios_ibus_dev *ibus_dev) +{ + uint16_t rxsum = ibus_dev->rx_buf[PIOS_IBUS_BUFLEN - 1] << 8 | + ibus_dev->rx_buf[PIOS_IBUS_BUFLEN - 2]; + + if (ibus_dev->checksum != rxsum) { + goto out_fail; + } + + uint16_t *chan = (uint16_t *)&ibus_dev->rx_buf[2]; + for (int i = 0; i < PIOS_IBUS_NUM_INPUTS; i++) { + ibus_dev->channel_data[i] = *chan++; + } + + ibus_dev->failsafe_timer = 0; + +out_fail: + PIOS_IBUS_ResetBuffer(ibus_dev); +} + +static void PIOS_IBUS_Supervisor(uint32_t context) +{ + struct pios_ibus_dev *ibus_dev = (struct pios_ibus_dev *)context; + + PIOS_Assert(PIOS_IBUS_Validate(ibus_dev)); + + if (++ibus_dev->rx_timer > 3) { + PIOS_IBUS_ResetBuffer(ibus_dev); + } + + if (++ibus_dev->failsafe_timer > 32) { + PIOS_IBUS_SetAllChannels(ibus_dev, PIOS_RCVR_TIMEOUT); + } +} + +#endif // PIOS_INCLUDE_IBUS + +/** + * @} + * @} + */ diff --git a/flight/pios/common/pios_mpu6000.c b/flight/pios/common/pios_mpu6000.c index 92a4054b0..97daddd68 100644 --- a/flight/pios/common/pios_mpu6000.c +++ b/flight/pios/common/pios_mpu6000.c @@ -104,6 +104,7 @@ static mpu6000_data_t mpu6000_data; static PIOS_SENSORS_3Axis_SensorsWithTemp *queue_data = 0; #define SENSOR_COUNT 2 #define SENSOR_DATA_SIZE (sizeof(PIOS_SENSORS_3Axis_SensorsWithTemp) + sizeof(Vector3i16) * SENSOR_COUNT) + // ! Private functions static struct mpu6000_dev *PIOS_MPU6000_alloc(const struct pios_mpu6000_cfg *cfg); static int32_t PIOS_MPU6000_Validate(struct mpu6000_dev *dev); @@ -111,7 +112,7 @@ static void PIOS_MPU6000_Config(struct pios_mpu6000_cfg const *cfg); static int32_t PIOS_MPU6000_SetReg(uint8_t address, uint8_t buffer); static int32_t PIOS_MPU6000_GetReg(uint8_t address); static void PIOS_MPU6000_SetSpeed(const bool fast); -static bool PIOS_MPU6000_HandleData(); +static bool PIOS_MPU6000_HandleData(uint32_t gyro_read_timestamp); static bool PIOS_MPU6000_ReadSensor(bool *woken); static int32_t PIOS_MPU6000_Test(void); @@ -540,24 +541,21 @@ static int32_t PIOS_MPU6000_Test(void) bool PIOS_MPU6000_IRQHandler(void) { + uint32_t gyro_read_timestamp = PIOS_DELAY_GetRaw(); bool woken = false; if (!mpu6000_configured) { return false; } - bool read_ok = false; - read_ok = PIOS_MPU6000_ReadSensor(&woken); - - if (read_ok) { - bool woken2 = PIOS_MPU6000_HandleData(); - woken |= woken2; + if (PIOS_MPU6000_ReadSensor(&woken)) { + woken |= PIOS_MPU6000_HandleData(gyro_read_timestamp); } return woken; } -static bool PIOS_MPU6000_HandleData() +static bool PIOS_MPU6000_HandleData(uint32_t gyro_read_timestamp) { if (!queue_data) { return false; @@ -600,6 +598,7 @@ static bool PIOS_MPU6000_HandleData() const int16_t temp = GET_SENSOR_DATA(mpu6000_data, Temperature); // Temperature in degrees C = (TEMP_OUT Register Value as a signed quantity)/340 + 36.53 queue_data->temperature = 3653 + (temp * 100) / 340; + queue_data->timestamp = gyro_read_timestamp; BaseType_t higherPriorityTaskWoken; xQueueSendToBackFromISR(dev->queue, (void *)queue_data, &higherPriorityTaskWoken); diff --git a/flight/pios/common/pios_mpu9250.c b/flight/pios/common/pios_mpu9250.c index 6fd4ba824..cdf11c259 100644 --- a/flight/pios/common/pios_mpu9250.c +++ b/flight/pios/common/pios_mpu9250.c @@ -137,7 +137,7 @@ static void PIOS_MPU9250_Config(struct pios_mpu9250_cfg const *cfg); static int32_t PIOS_MPU9250_SetReg(uint8_t address, uint8_t buffer); static int32_t PIOS_MPU9250_GetReg(uint8_t address); static void PIOS_MPU9250_SetSpeed(const bool fast); -static bool PIOS_MPU9250_HandleData(); +static bool PIOS_MPU9250_HandleData(uint32_t gyro_read_timestamp); static bool PIOS_MPU9250_ReadSensor(bool *woken); static int32_t PIOS_MPU9250_Test(void); #if defined(PIOS_MPU9250_MAG) @@ -812,9 +812,9 @@ static bool PIOS_MPU9250_ReadMag(bool *woken) * @return a boolean to the EXTI IRQ Handler wrapper indicating if a * higher priority task is now eligible to run */ - bool PIOS_MPU9250_IRQHandler(void) { + uint32_t gyro_read_timestamp = PIOS_DELAY_GetRaw(); bool woken = false; if (!mpu9250_configured) { @@ -825,18 +825,14 @@ bool PIOS_MPU9250_IRQHandler(void) PIOS_MPU9250_ReadMag(&woken); #endif - bool read_ok = false; - read_ok = PIOS_MPU9250_ReadSensor(&woken); - - if (read_ok) { - bool woken2 = PIOS_MPU9250_HandleData(); - woken |= woken2; + if (PIOS_MPU9250_ReadSensor(&woken)) { + woken |= PIOS_MPU9250_HandleData(gyro_read_timestamp); } return woken; } -static bool PIOS_MPU9250_HandleData() +static bool PIOS_MPU9250_HandleData(uint32_t gyro_read_timestamp) { // Rotate the sensor to OP convention. The datasheet defines X as towards the right // and Y as forward. OP convention transposes this. Also the Z is defined negatively @@ -916,6 +912,7 @@ static bool PIOS_MPU9250_HandleData() queue_data->sample[1].z = -1 - (GET_SENSOR_DATA(mpu9250_data, Gyro_Z)); const int16_t temp = GET_SENSOR_DATA(mpu9250_data, Temperature); queue_data->temperature = 2100 + ((float)(temp - PIOS_MPU9250_TEMP_OFFSET)) * (100.0f / PIOS_MPU9250_TEMP_SENSITIVITY); + queue_data->timestamp = gyro_read_timestamp; mag_data->temperature = queue_data->temperature; #ifdef PIOS_MPU9250_MAG if (mag_valid) { diff --git a/flight/pios/common/pios_ms5611.c b/flight/pios/common/pios_ms5611.c index 6a9c70879..d52675079 100644 --- a/flight/pios/common/pios_ms5611.c +++ b/flight/pios/common/pios_ms5611.c @@ -45,6 +45,9 @@ // Running moving average smoothing factor #define PIOS_MS5611_TEMP_SMOOTHING 10 // + +#define PIOS_MS5611_I2C_RETRIES 5 + /* Local Types */ typedef struct { uint16_t C[6]; @@ -94,6 +97,8 @@ static const struct pios_ms5611_cfg *dev_cfg; static int32_t i2c_id; static PIOS_SENSORS_1Axis_SensorsWithTemp results; +static bool sensorIsAlive = false; + // sensor driver interface bool PIOS_MS5611_driver_Test(uintptr_t context); void PIOS_MS5611_driver_Reset(uintptr_t context); @@ -116,13 +121,21 @@ const PIOS_SENSORS_Driver PIOS_MS5611_Driver = { int32_t ms5611_read_flag; void PIOS_MS5611_Init(const struct pios_ms5611_cfg *cfg, int32_t i2c_device) { - i2c_id = i2c_device; + static uint32_t initTime; - oversampling = cfg->oversampling; - conversionDelayMs = PIOS_MS5611_GetDelay(); - conversionDelayUs = PIOS_MS5611_GetDelayUs(); + if (cfg) { + i2c_id = i2c_device; - dev_cfg = cfg; // Store cfg before enabling interrupt + oversampling = cfg->oversampling; + conversionDelayMs = PIOS_MS5611_GetDelay(); + conversionDelayUs = PIOS_MS5611_GetDelayUs(); + + dev_cfg = cfg; // Store cfg before enabling interrupt + } else if (PIOS_DELAY_DiffuS(initTime) < 1000000) { // Do not reinitialize too often + return; + } + + initTime = PIOS_DELAY_GetRaw(); PIOS_MS5611_WriteCommand(MS5611_RESET); PIOS_DELAY_WaitmS(20); @@ -133,27 +146,35 @@ void PIOS_MS5611_Init(const struct pios_ms5611_cfg *cfg, int32_t i2c_device) compensation_t2 = 0; /* Calibration parameters */ for (int i = 0; i < 6; i++) { - while (PIOS_MS5611_Read(MS5611_CALIB_ADDR + i * 2, data, 2)) {} - ; + if (PIOS_MS5611_Read(MS5611_CALIB_ADDR + i * 2, data, 2) != 0) { + return; + } CalibData.C[i] = (data[0] << 8) | data[1]; } + + sensorIsAlive = true; } /** * Start the ADC conversion * \param[in] PresOrTemp BMP085_PRES_ADDR or BMP085_TEMP_ADDR - * \return 0 for success, -1 for failure (conversion completed and not read) + * \return 0 for success, -1 for failure (conversion completed and not read), -2 if failure occurred */ int32_t PIOS_MS5611_StartADC(ConversionTypeTypeDef Type) { + if (!sensorIsAlive) { /* if sensor is not alive, don't bother, wait for next poll to try to reinitialize */ + return -2; + } + /* Start the conversion */ + if (Type == MS5611_CONVERSION_TYPE_TemperatureConv) { - while (PIOS_MS5611_WriteCommand(MS5611_TEMP_ADDR + oversampling) != 0) { - continue; + if (PIOS_MS5611_WriteCommand(MS5611_TEMP_ADDR + oversampling) != 0) { + return -2; } } else if (Type == MS5611_CONVERSION_TYPE_PressureConv) { - while (PIOS_MS5611_WriteCommand(MS5611_PRES_ADDR + oversampling) != 0) { - continue; + if (PIOS_MS5611_WriteCommand(MS5611_PRES_ADDR + oversampling) != 0) { + return -2; } } lastConversionStart = PIOS_DELAY_GetRaw(); @@ -222,6 +243,10 @@ static uint32_t PIOS_MS5611_GetDelayUs() */ int32_t PIOS_MS5611_ReadADC(void) { + if (!sensorIsAlive) { /* if sensor is not alive, don't bother, wait for next poll to try to reinitialize */ + return -2; + } + uint8_t Data[3]; Data[0] = 0; @@ -350,7 +375,15 @@ static int32_t PIOS_MS5611_Read(uint8_t address, uint8_t *buffer, uint8_t len) } }; - return PIOS_I2C_Transfer(i2c_id, txn_list, NELEMENTS(txn_list)); + for (uint8_t retry = PIOS_MS5611_I2C_RETRIES; retry > 0; --retry) { + if (PIOS_I2C_Transfer(i2c_id, txn_list, NELEMENTS(txn_list)) == 0) { + return 0; + } + } + + sensorIsAlive = false; + + return -1; } /** @@ -373,7 +406,15 @@ static int32_t PIOS_MS5611_WriteCommand(uint8_t command) , }; - return PIOS_I2C_Transfer(i2c_id, txn_list, NELEMENTS(txn_list)); + for (uint8_t retry = PIOS_MS5611_I2C_RETRIES; retry > 0; --retry) { + if (PIOS_I2C_Transfer(i2c_id, txn_list, NELEMENTS(txn_list)) == 0) { + return 0; + } + } + + sensorIsAlive = false; + + return -1; } /** @@ -435,6 +476,10 @@ bool PIOS_MS5611_driver_poll(__attribute__((unused)) uintptr_t context) static uint8_t temp_press_interleave_count = 1; static MS5611_FSM_State next_state = MS5611_FSM_INIT; + if (!sensorIsAlive) { // try to reinit + PIOS_MS5611_Init(0, 0); + } + int32_t conversionResult = PIOS_MS5611_ReadADC(); if (__builtin_expect(conversionResult == -1, 1)) { diff --git a/flight/pios/common/pios_notify.c b/flight/pios/common/pios_notify.c index 9b0a1fc67..1cf86a00d 100644 --- a/flight/pios/common/pios_notify.c +++ b/flight/pios/common/pios_notify.c @@ -56,18 +56,19 @@ pios_notify_notification PIOS_NOTIFY_GetActiveNotification(bool clear) * @param sequence Sequence to be played * @param priority Priority of the sequence being played */ -void PIOS_NOTIFICATION_Default_Ext_Led_Play(const LedSequence_t *sequence, pios_notify_priority priority) +bool PIOS_NOTIFICATION_Default_Ext_Led_Play(const LedSequence_t *sequence, pios_notify_priority priority) { - // alert and alarms are repeated if condition persists. bacground notification instead are set once, so try to prevent loosing any update + // alert and alarms are repeated if condition persists. background notification instead are set once, so try to prevent loosing any update if (newNotification && priority != NOTIFY_PRIORITY_BACKGROUND) { // prevent overwriting higher priority or background notifications - if (extLedNotification.priority == NOTIFY_PRIORITY_BACKGROUND || extLedNotification.priority > priority) { - return; + if (extLedNotification.priority == NOTIFY_PRIORITY_BACKGROUND || extLedNotification.priority >= priority) { + return false; } } extLedNotification.priority = priority; extLedNotification.sequence = *sequence; newNotification = true; + return true; } diff --git a/flight/pios/common/pios_openlrs.c b/flight/pios/common/pios_openlrs.c new file mode 100644 index 000000000..bab86b19e --- /dev/null +++ b/flight/pios/common/pios_openlrs.c @@ -0,0 +1,1513 @@ +/** + ****************************************************************************** + * @addtogroup PIOS PIOS Core hardware abstraction layer + * @{ + * @addtogroup PIOS_RFM22B Radio Functions + * @brief PIOS OpenLRS interface for for the RFM22B radio + * @{ + * + * @file pios_openlrs.c + * @author Tau Labs, http://taulabs.org, Copyright (C) 2015 + * @author dRonin, http://dronin.org Copyright (C) 2015 + * @author LibrePilot, http://librepilot.org Copyright (C) 2016 + * @brief Implements an OpenLRS driver for the RFM22B + * @see The GNU Public License (GPL) Version 3 + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "pios.h" + +#ifdef PIOS_INCLUDE_OPENLRS + +#include +#include +#include +#include +#include +#include + +#include "flightstatus.h" +#include "flightbatterystate.h" +#include "oplinksettings.h" +#include "oplinkstatus.h" + +#include "pios_rfm22b_regs.h" + +#define STACK_SIZE_BYTES 800 +#define TASK_PRIORITY PIOS_THREAD_PRIO_NORMAL + + +static void rx_reset(struct pios_openlrs_dev *openlrs_dev); +static void rfmSetCarrierFrequency(struct pios_openlrs_dev *openlrs_dev, uint32_t f); +static uint8_t rfmGetRSSI(struct pios_openlrs_dev *openlrs_dev); +static void to_rx_mode(struct pios_openlrs_dev *openlrs_dev); +static void tx_packet(struct pios_openlrs_dev *openlrs_dev, uint8_t *pkt, uint8_t size); + +static struct pios_openlrs_dev *pios_openlrs_alloc(); +static bool pios_openlrs_validate(struct pios_openlrs_dev *openlrs_dev); + +// SPI read/write functions +static void rfm22_assertCs(struct pios_openlrs_dev *openlrs_dev); +static void rfm22_deassertCs(struct pios_openlrs_dev *openlrs_dev); +static void rfm22_claimBus(struct pios_openlrs_dev *openlrs_dev); +static void rfm22_releaseBus(struct pios_openlrs_dev *openlrs_dev); +static void rfm22_write_claim(struct pios_openlrs_dev *openlrs_dev, + uint8_t addr, uint8_t data); +static void rfm22_write(struct pios_openlrs_dev *openlrs_dev, uint8_t addr, + uint8_t data); +static uint8_t rfm22_read_claim(struct pios_openlrs_dev *openlrs_dev, + uint8_t addr); +static uint8_t rfm22_read(struct pios_openlrs_dev *openlrs_dev, + uint8_t addr); + +// Private constants +const struct rfm22_modem_regs { + uint32_t bps; + uint8_t r_1c, r_1d, r_1e, r_20, r_21, r_22, r_23, r_24, r_25, r_2a, r_6e, r_6f, r_70, r_71, r_72; +} modem_params[] = { + { 4800, 0x1a, 0x40, 0x0a, 0xa1, 0x20, 0x4e, 0xa5, 0x00, 0x1b, 0x1e, 0x27, 0x52, 0x2c, 0x23, 0x30 }, // 50000 0x00 + { 9600, 0x05, 0x40, 0x0a, 0xa1, 0x20, 0x4e, 0xa5, 0x00, 0x20, 0x24, 0x4e, 0xa5, 0x2c, 0x23, 0x30 }, // 25000 0x00 + { 19200, 0x06, 0x40, 0x0a, 0xd0, 0x00, 0x9d, 0x49, 0x00, 0x7b, 0x28, 0x9d, 0x49, 0x2c, 0x23, 0x30 }, // 25000 0x01 + { 57600, 0x05, 0x40, 0x0a, 0x45, 0x01, 0xd7, 0xdc, 0x03, 0xb8, 0x1e, 0x0e, 0xbf, 0x00, 0x23, 0x2e }, + { 125000, 0x8a, 0x40, 0x0a, 0x60, 0x01, 0x55, 0x55, 0x02, 0xad, 0x1e, 0x20, 0x00, 0x00, 0x23, 0xc8 }, +}; + +static const uint8_t pktsizes[8] = { 0, 7, 11, 12, 16, 17, 21, 0 }; + +static const uint8_t OUT_FF[64] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +const uint8_t default_hop_list[] = { DEFAULT_HOPLIST }; + +const uint32_t packet_advance_time_us = 1500; +const uint32_t packet_timeout_us = 1000; + +const struct rfm22_modem_regs bind_params = +{ 9600, 0x05, 0x40, 0x0a, 0xa1, 0x20, 0x4e, 0xa5, 0x00, 0x20, 0x24, 0x4e, 0xa5, 0x2c, 0x23, 0x30 }; + +static uint32_t minFreq() +{ + return MIN_RFM_FREQUENCY_433; +} + +static uint32_t maxFreq() +{ + return MAX_RFM_FREQUENCY_433; +} + +static uint32_t defCarrierFreq() +{ + return DEFAULT_CARRIER_FREQUENCY_433; +} + +static uint32_t bindingFreq() +{ + return BINDING_FREQUENCY_433; +} + +/***************************************************************************** +* OpenLRS data formatting utilities +*****************************************************************************/ + +static uint8_t getPacketSize(struct bind_data *bd) +{ + return pktsizes[(bd->flags & 0x07)]; +} + +static uint32_t getInterval(struct bind_data *bd) +{ + uint32_t ret; + + // Sending a x byte packet on bps y takes about (emperical) + // usec = (x + 15) * 8200000 / baudrate +#define BYTES_AT_BAUD_TO_USEC(bytes, bps, div) ((uint32_t)((bytes) + (div ? 20 : 15)) * 8200000L / (uint32_t)(bps)) + + ret = (BYTES_AT_BAUD_TO_USEC(getPacketSize(bd), modem_params[bd->modem_params].bps, bd->flags & DIVERSITY_ENABLED) + 2000); + + if (bd->flags & TELEMETRY_MASK) { + ret += (BYTES_AT_BAUD_TO_USEC(TELEMETRY_PACKETSIZE, modem_params[bd->modem_params].bps, bd->flags & DIVERSITY_ENABLED) + 1000); + } + + // round up to ms + ret = ((ret + 999) / 1000) * 1000; + + // enable following to limit packet rate to 50Hz at most +#ifdef LIMIT_RATE_TO_50HZ + if (ret < 20000) { + ret = 20000; + } +#endif + + return ret; +} + +static void unpackChannels(uint8_t config, int16_t PPM[], uint8_t *p) +{ + uint8_t i; + + for (i = 0; i <= (config / 2); i++) { // 4ch packed in 5 bytes + PPM[0] = (((uint16_t)p[4] & 0x03) << 8) + p[0]; + PPM[1] = (((uint16_t)p[4] & 0x0c) << 6) + p[1]; + PPM[2] = (((uint16_t)p[4] & 0x30) << 4) + p[2]; + PPM[3] = (((uint16_t)p[4] & 0xc0) << 2) + p[3]; + p += 5; + PPM += 4; + } + if (config & 1) { // 4ch packed in 1 byte; + PPM[0] = (((uint16_t)p[0] >> 6) & 3) * 333 + 12; + PPM[1] = (((uint16_t)p[0] >> 4) & 3) * 333 + 12; + PPM[2] = (((uint16_t)p[0] >> 2) & 3) * 333 + 12; + PPM[3] = (((uint16_t)p[0] >> 0) & 3) * 333 + 12; + } +} + +// ! Apply the OpenLRS rescaling to the channels +static void rescaleChannels(int16_t PPM[]) +{ + for (uint32_t i = 0; i < OPENLRS_PPM_NUM_CHANNELS; i++) { + int16_t x = PPM[i]; + int16_t ret; + + if (x < 12) { + ret = 808 + x * 16; + } else if (x < 1012) { + ret = x + 988; + } else if (x < 1024) { + ret = 2000 + (x - 1011) * 16; + } else { + ret = 2192; + } + + PPM[i] = ret; + } +} + +static uint8_t countSetBits(uint16_t x) +{ + x = x - ((x >> 1) & 0x5555); + x = (x & 0x3333) + ((x >> 2) & 0x3333); + x = x + (x >> 4); + x &= 0x0F0F; + return (x * 0x0101) >> 8; +} + +/***************************************************************************** +* OpenLRS hardware access +*****************************************************************************/ + +#define NOP() __asm__ __volatile__ ("nop") + +#define RF22B_PWRSTATE_POWERDOWN 0x00 +#define RF22B_PWRSTATE_READY RFM22_opfc1_xton +#define RF22B_PWRSTATE_RX (RFM22_opfc1_rxon | RFM22_opfc1_xton) +#define RF22B_PWRSTATE_TX (RFM22_opfc1_txon | RFM22_opfc1_xton) + +#define RF22B_PACKET_SENT_INTERRUPT RFM22_ie1_enpksent +#define RF22B_RX_PACKET_RECEIVED_IRQ RFM22_ie1_enpkvalid + +static void rfmSetChannel(struct pios_openlrs_dev *openlrs_dev, uint8_t ch) +{ + // DEBUG_PRINTF(3,"rfmSetChannel %d\r\n", ch); + uint8_t magicLSB = (openlrs_dev->bind_data.rf_magic & 0xff) ^ ch; + + rfm22_claimBus(openlrs_dev); + rfm22_write(openlrs_dev, RFM22_frequency_hopping_channel_select, openlrs_dev->bind_data.hopchannel[ch]); + rfm22_write(openlrs_dev, RFM22_transmit_header3 + 3, magicLSB); + rfm22_write(openlrs_dev, RFM22_check_header3 + 3, magicLSB); + rfm22_releaseBus(openlrs_dev); +} + +static uint8_t rfmGetRSSI(struct pios_openlrs_dev *openlrs_dev) +{ + return rfm22_read_claim(openlrs_dev, 0x26); +} + +static uint16_t rfmGetAFCC(struct pios_openlrs_dev *openlrs_dev) +{ + return ((uint16_t)rfm22_read_claim(openlrs_dev, 0x2B) << 2) | ((uint16_t)rfm22_read_claim(openlrs_dev, 0x2C) >> 6); +} + +static void setModemRegs(struct pios_openlrs_dev *openlrs_dev, const struct rfm22_modem_regs *r) +{ + DEBUG_PRINTF(3, "setModemRegs\r\n"); + rfm22_claimBus(openlrs_dev); + rfm22_write(openlrs_dev, RFM22_if_filter_bandwidth, r->r_1c); + rfm22_write(openlrs_dev, RFM22_afc_loop_gearshift_override, r->r_1d); + rfm22_write(openlrs_dev, RFM22_afc_timing_control, r->r_1e); + rfm22_write(openlrs_dev, RFM22_clk_recovery_oversampling_ratio, r->r_20); + rfm22_write(openlrs_dev, RFM22_clk_recovery_offset2, r->r_21); + rfm22_write(openlrs_dev, RFM22_clk_recovery_offset1, r->r_22); + rfm22_write(openlrs_dev, RFM22_clk_recovery_offset0, r->r_23); + rfm22_write(openlrs_dev, RFM22_clk_recovery_timing_loop_gain1, r->r_24); + rfm22_write(openlrs_dev, RFM22_clk_recovery_timing_loop_gain0, r->r_25); + rfm22_write(openlrs_dev, RFM22_afc_limiter, r->r_2a); + rfm22_write(openlrs_dev, RFM22_tx_data_rate1, r->r_6e); + rfm22_write(openlrs_dev, RFM22_tx_data_rate0, r->r_6f); + rfm22_write(openlrs_dev, RFM22_modulation_mode_control1, r->r_70); + rfm22_write(openlrs_dev, RFM22_modulation_mode_control2, r->r_71); + rfm22_write(openlrs_dev, RFM22_frequency_deviation, r->r_72); + rfm22_releaseBus(openlrs_dev); +} + +static void rfmSetCarrierFrequency(struct pios_openlrs_dev *openlrs_dev, uint32_t f) +{ + /* Protect ourselves from out-of-band frequencies. Ideally we'd latch + * an error here and prevent tx, but this is good enough to protect + * the hardware. */ + if ((f < minFreq(openlrs_dev->band)) || + (f > maxFreq(openlrs_dev->band))) { + f = defCarrierFreq(openlrs_dev->band); + } + + // DEBUG_PRINTF(3,"rfmSetCarrierFrequency %d\r\n", f); + uint16_t fb, fc, hbsel; + if (f < 480000000) { + hbsel = 0; + fb = f / 10000000 - 24; + fc = (f - (fb + 24) * 10000000) * 4 / 625; + } else { + hbsel = 1; + fb = f / 20000000 - 24; + fc = (f - (fb + 24) * 20000000) * 2 / 625; + } + rfm22_claimBus(openlrs_dev); + rfm22_write(openlrs_dev, RFM22_frequency_band_select, RFM22_fbs_sbse + (hbsel ? RFM22_fbs_hbsel : 0) + (fb & RFM22_fb_mask)); + rfm22_write(openlrs_dev, RFM22_nominal_carrier_frequency1, (fc >> 8)); + rfm22_write(openlrs_dev, RFM22_nominal_carrier_frequency0, (fc & 0xff)); + rfm22_releaseBus(openlrs_dev); +} + +static void init_rfm(struct pios_openlrs_dev *openlrs_dev, uint8_t isbind) +{ + DEBUG_PRINTF(2, "init_rfm %d\r\n", isbind); + + if (!isbind) { + DEBUG_PRINTF(2, "Binding settings:\r\n"); + PIOS_Thread_Sleep(10); + DEBUG_PRINTF(2, " version: %d\r\n", openlrs_dev->bind_data.version); + PIOS_Thread_Sleep(10); + DEBUG_PRINTF(2, " serial_baudrate: %d\r\n", openlrs_dev->bind_data.serial_baudrate); + PIOS_Thread_Sleep(10); + DEBUG_PRINTF(2, " rf_frequency: %d\r\n", openlrs_dev->bind_data.rf_frequency); + PIOS_Thread_Sleep(10); + DEBUG_PRINTF(2, " rf_power: %d\r\n", openlrs_dev->bind_data.rf_power); + PIOS_Thread_Sleep(10); + DEBUG_PRINTF(2, " rf_channel_spacing: %d\r\n", openlrs_dev->bind_data.rf_channel_spacing); + PIOS_Thread_Sleep(10); + DEBUG_PRINTF(2, " modem_params: %d\r\n", openlrs_dev->bind_data.modem_params); + PIOS_Thread_Sleep(10); + DEBUG_PRINTF(2, " flags: %d\r\n", openlrs_dev->bind_data.flags); + PIOS_Thread_Sleep(10); + } + + rfm22_claimBus(openlrs_dev); + openlrs_dev->it_status1 = rfm22_read(openlrs_dev, RFM22_interrupt_status1); // read status, clear interrupt + openlrs_dev->it_status2 = rfm22_read(openlrs_dev, RFM22_interrupt_status2); + rfm22_write(openlrs_dev, RFM22_interrupt_enable2, 0x00); // disable interrupts + rfm22_write(openlrs_dev, RFM22_op_and_func_ctrl1, RF22B_PWRSTATE_READY); // disable lbd, wakeup timer, use internal 32768,xton = 1; in ready mode + rfm22_write(openlrs_dev, RFM22_xtal_osc_load_cap, 0x7f); // c = 12.5p + rfm22_write(openlrs_dev, RFM22_cpu_output_clk, 0x05); + switch (openlrs_dev->cfg.gpio_direction) { + case GPIO0_TX_GPIO1_RX: + rfm22_write(openlrs_dev, RFM22_gpio0_config, RFM22_gpio0_config_txstate); // gpio0 TX State + rfm22_write(openlrs_dev, RFM22_gpio1_config, RFM22_gpio1_config_rxstate); // gpio1 RX State + break; + case GPIO0_RX_GPIO1_TX: + rfm22_write(openlrs_dev, RFM22_gpio0_config, RFM22_gpio0_config_rxstate); // gpio0 RX State + rfm22_write(openlrs_dev, RFM22_gpio1_config, RFM22_gpio1_config_txstate); // gpio1 TX State + break; + } + rfm22_write(openlrs_dev, RFM22_gpio2_config, 0xfd); // gpio 2 VDD + rfm22_write(openlrs_dev, RFM22_io_port_config, RFM22_io_port_default); // gpio 0, 1,2 NO OTHER FUNCTION. + rfm22_releaseBus(openlrs_dev); + + if (isbind) { + setModemRegs(openlrs_dev, &bind_params); + } else { + setModemRegs(openlrs_dev, &modem_params[openlrs_dev->bind_data.modem_params]); + } + + // Packet settings + rfm22_claimBus(openlrs_dev); + rfm22_write(openlrs_dev, RFM22_data_access_control, 0x8c); // enable packet handler, msb first, enable crc, + rfm22_write(openlrs_dev, RFM22_header_control1, 0x0f); // no broadcast, check header bytes 3,2,1,0 + rfm22_write(openlrs_dev, RFM22_header_control2, 0x42); // 4 byte header, 2 byte synch, variable pkt size + rfm22_write(openlrs_dev, RFM22_preamble_length, (openlrs_dev->bind_data.flags & DIVERSITY_ENABLED) ? 0x14 : 0x0a); // 40 bit preamble, 80 with diversity + rfm22_write(openlrs_dev, RFM22_preamble_detection_ctrl1, 0x2a); // preath = 5 (20bits), rssioff = 2 + rfm22_write(openlrs_dev, RFM22_sync_word3, 0x2d); // synchronize word 3 + rfm22_write(openlrs_dev, RFM22_sync_word2, 0xd4); // synchronize word 2 + rfm22_write(openlrs_dev, RFM22_sync_word1, 0x00); // synch word 1 (not used) + rfm22_write(openlrs_dev, RFM22_sync_word0, 0x00); // synch word 0 (not used) + + uint32_t magic = isbind ? BIND_MAGIC : openlrs_dev->bind_data.rf_magic; + for (uint8_t i = 0; i < 4; i++) { + rfm22_write(openlrs_dev, RFM22_transmit_header3 + i, (magic >> 24) & 0xff); // tx header + rfm22_write(openlrs_dev, RFM22_check_header3 + i, (magic >> 24) & 0xff); // rx header + magic = magic << 8; // advance to next byte + } + + rfm22_write(openlrs_dev, RFM22_header_enable3, 0xff); // all the bit to be checked + rfm22_write(openlrs_dev, RFM22_header_enable2, 0xff); // all the bit to be checked + rfm22_write(openlrs_dev, RFM22_header_enable1, 0xff); // all the bit to be checked + rfm22_write(openlrs_dev, RFM22_header_enable0, 0xff); // all the bit to be checked + + if (isbind) { + rfm22_write(openlrs_dev, RFM22_tx_power, BINDING_POWER); + } else { + rfm22_write(openlrs_dev, RFM22_tx_power, openlrs_dev->bind_data.rf_power); + } + + rfm22_write(openlrs_dev, RFM22_frequency_hopping_channel_select, 0); + rfm22_write(openlrs_dev, RFM22_frequency_hopping_step_size, openlrs_dev->bind_data.rf_channel_spacing); // channel spacing + + rfm22_write(openlrs_dev, RFM22_frequency_offset1, 0x00); + rfm22_write(openlrs_dev, RFM22_frequency_offset2, 0x00); // no offset + + rfm22_releaseBus(openlrs_dev); + + rfmSetCarrierFrequency(openlrs_dev, isbind ? bindingFreq(openlrs_dev->band) : openlrs_dev->bind_data.rf_frequency); +} + +static void to_rx_mode(struct pios_openlrs_dev *openlrs_dev) +{ + // DEBUG_PRINTF(3,"to_rx_mode\r\n"); + rfm22_claimBus(openlrs_dev); + openlrs_dev->it_status1 = rfm22_read(openlrs_dev, RFM22_interrupt_status1); + openlrs_dev->it_status2 = rfm22_read(openlrs_dev, RFM22_interrupt_status2); + rfm22_write(openlrs_dev, RFM22_op_and_func_ctrl1, RF22B_PWRSTATE_READY); + rfm22_releaseBus(openlrs_dev); + PIOS_Thread_Sleep(10); + rx_reset(openlrs_dev); + NOP(); +} + +static void clearFIFO(struct pios_openlrs_dev *openlrs_dev) +{ + // DEBUG_PRINTF(3,"clearFIFO\r\n"); + rfm22_claimBus(openlrs_dev); + rfm22_write(openlrs_dev, RFM22_op_and_func_ctrl2, 0x03); + rfm22_write(openlrs_dev, RFM22_op_and_func_ctrl2, 0x00); + rfm22_releaseBus(openlrs_dev); +} + +static void rx_reset(struct pios_openlrs_dev *openlrs_dev) +{ + // DEBUG_PRINTF(3,"rx_reset\r\n"); + rfm22_write_claim(openlrs_dev, RFM22_op_and_func_ctrl1, RF22B_PWRSTATE_READY); + rfm22_write_claim(openlrs_dev, RFM22_rx_fifo_control, 36); // threshold for rx almost full, interrupt when 1 byte received + clearFIFO(openlrs_dev); + rfm22_claimBus(openlrs_dev); + rfm22_write(openlrs_dev, RFM22_op_and_func_ctrl1, RF22B_PWRSTATE_RX); // to rx mode + rfm22_write(openlrs_dev, RFM22_interrupt_enable1, RF22B_RX_PACKET_RECEIVED_IRQ); + openlrs_dev->it_status1 = rfm22_read(openlrs_dev, RFM22_interrupt_status1); // read the Interrupt Status1 register + openlrs_dev->it_status2 = rfm22_read(openlrs_dev, RFM22_interrupt_status2); + rfm22_releaseBus(openlrs_dev); +} + +// TODO: move into dev structure +uint32_t tx_start = 0; + +static void tx_packet_async(struct pios_openlrs_dev *openlrs_dev, uint8_t *pkt, uint8_t size) +{ + rfm22_claimBus(openlrs_dev); + rfm22_write(openlrs_dev, RFM22_transmit_packet_length, size); // total tx size + + for (uint8_t i = 0; i < size; i++) { + rfm22_write(openlrs_dev, RFM22_fifo_access, pkt[i]); + } + + rfm22_write(openlrs_dev, RFM22_interrupt_enable1, RF22B_PACKET_SENT_INTERRUPT); + openlrs_dev->it_status1 = rfm22_read(openlrs_dev, RFM22_interrupt_status1); // read the Interrupt Status1 register + openlrs_dev->it_status2 = rfm22_read(openlrs_dev, RFM22_interrupt_status2); + tx_start = PIOS_DELAY_GetuS(); + rfm22_write(openlrs_dev, RFM22_op_and_func_ctrl1, RF22B_PWRSTATE_TX); // to tx mode + rfm22_releaseBus(openlrs_dev); + + openlrs_dev->rf_mode = Transmit; +} + +static void tx_packet(struct pios_openlrs_dev *openlrs_dev, uint8_t *pkt, uint8_t size) +{ + tx_packet_async(openlrs_dev, pkt, size); + PIOS_Semaphore_Take(openlrs_dev->sema_isr, 25); + +#if defined(PIOS_INCLUDE_WDG) && defined(PIOS_WDG_RFM22B) + // Update the watchdog timer + PIOS_WDG_UpdateFlag(PIOS_WDG_RFM22B); +#endif /* PIOS_WDG_RFM22B */ + + if (openlrs_dev->rf_mode == Transmit) { + DEBUG_PRINTF(2, "OLRS ERR: tx_packet timeout\r\n"); + init_rfm(openlrs_dev, false); // reset modem + } +} + +static void beacon_tone(struct pios_openlrs_dev *openlrs_dev, int16_t hz, int16_t len __attribute__((unused))) // duration is now in half seconds. +{ + DEBUG_PRINTF(2, "beacon_tone: %d %d\r\n", hz, len * 2); + int16_t d = 500000 / hz; // better resolution + +#if defined(PIOS_LED_LINK) + PIOS_LED_On(PIOS_LED_LINK); +#endif /* PIOS_LED_LINK */ + + if (d < 1) { + d = 1; + } + + rfm22_claimBus(openlrs_dev); + + // This need fixed for F1 +#ifdef GPIO_Mode_OUT + GPIO_TypeDef *gpio = openlrs_dev->cfg.spi_cfg->mosi.gpio; + uint16_t pin_source = openlrs_dev->cfg.spi_cfg->mosi.init.GPIO_Pin; + uint8_t remap = openlrs_dev->cfg.spi_cfg->remap; + + GPIO_InitTypeDef init = { + .GPIO_Speed = GPIO_Speed_50MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }; + init.GPIO_Pin = pin_source; + + // Set MOSI to digital out for bit banging + GPIO_PinAFConfig(gpio, pin_source, 0); + GPIO_Init(gpio, &init); + + uint32_t raw_time = PIOS_DELAY_GetRaw(); + int16_t cycles = (len * 500000 / d); + for (int16_t i = 0; i < cycles; i++) { + GPIO_SetBits(gpio, pin_source); + PIOS_DELAY_WaituS(d); + GPIO_ResetBits(gpio, pin_source); + PIOS_DELAY_WaituS(d); + + // Make sure to give other tasks time to do things + if (PIOS_DELAY_DiffuS(raw_time) > 10000) { + PIOS_Thread_Sleep(1); + raw_time = PIOS_DELAY_GetRaw(); + } + } + + GPIO_Init(gpio, (GPIO_InitTypeDef *)&openlrs_dev->cfg.spi_cfg->mosi.init); + GPIO_PinAFConfig(gpio, pin_source, remap); +#endif /* ifdef GPIO_Mode_OUT */ + rfm22_releaseBus(openlrs_dev); + +#if defined(PIOS_LED_LINK) + PIOS_LED_Off(PIOS_LED_LINK); +#endif /* PIOS_LED_LINK */ + +#if defined(PIOS_INCLUDE_WDG) && defined(PIOS_WDG_RFM22B) + // Update the watchdog timer + PIOS_WDG_UpdateFlag(PIOS_WDG_RFM22B); +#endif /* PIOS_WDG_RFM22B */ +} + + +static uint8_t beaconGetRSSI(struct pios_openlrs_dev *openlrs_dev) +{ + uint16_t rssiSUM = 0; + + rfmSetCarrierFrequency(openlrs_dev, openlrs_dev->beacon_frequency); + rfm22_write_claim(openlrs_dev, RFM22_frequency_hopping_channel_select, 0); // ch 0 to avoid offset + PIOS_Thread_Sleep(1); + rssiSUM += rfmGetRSSI(openlrs_dev); + PIOS_Thread_Sleep(1); + rssiSUM += rfmGetRSSI(openlrs_dev); + PIOS_Thread_Sleep(1); + rssiSUM += rfmGetRSSI(openlrs_dev); + PIOS_Thread_Sleep(1); + rssiSUM += rfmGetRSSI(openlrs_dev); + + return rssiSUM >> 2; +} + +static void beacon_send(struct pios_openlrs_dev *openlrs_dev, bool static_tone) +{ + DEBUG_PRINTF(2, "beacon_send\r\n"); + rfm22_claimBus(openlrs_dev); + openlrs_dev->it_status1 = rfm22_read(openlrs_dev, 0x03); // read status, clear interrupt + openlrs_dev->it_status2 = rfm22_read(openlrs_dev, 0x04); + rfm22_write(openlrs_dev, 0x06, 0x00); // no wakeup up, lbd, + rfm22_write(openlrs_dev, 0x07, RF22B_PWRSTATE_READY); // disable lbd, wakeup timer, use internal 32768,xton = 1; in ready mode + rfm22_write(openlrs_dev, 0x09, 0x7f); // (default) c = 12.5p + rfm22_write(openlrs_dev, 0x0a, 0x05); + rfm22_write(openlrs_dev, 0x0b, 0x12); // gpio0 TX State + rfm22_write(openlrs_dev, 0x0c, 0x15); // gpio1 RX State + rfm22_write(openlrs_dev, 0x0d, 0xfd); // gpio 2 micro-controller clk output + rfm22_write(openlrs_dev, 0x0e, 0x00); // gpio 0, 1,2 NO OTHER FUNCTION. + + rfm22_write(openlrs_dev, 0x70, 0x2C); // disable manchest + + rfm22_write(openlrs_dev, 0x30, 0x00); // disable packet handling + + rfm22_write(openlrs_dev, 0x79, 0); // start channel + + rfm22_write(openlrs_dev, 0x7a, 0x05); // 50khz step size (10khz x value) // no hopping + + rfm22_write(openlrs_dev, 0x71, 0x12); // trclk=[00] no clock, dtmod=[01] direct using SPI, fd8=0 eninv=0 modtyp=[10] FSK + rfm22_write(openlrs_dev, 0x72, 0x02); // fd (frequency deviation) 2*625Hz == 1.25kHz + + rfm22_write(openlrs_dev, 0x73, 0x00); + rfm22_write(openlrs_dev, 0x74, 0x00); // no offset + rfm22_releaseBus(openlrs_dev); + + rfmSetCarrierFrequency(openlrs_dev, openlrs_dev->beacon_frequency); + + rfm22_write_claim(openlrs_dev, 0x6d, 0x07); // 7 set max power 100mW + + PIOS_Thread_Sleep(10); + rfm22_write_claim(openlrs_dev, 0x07, RF22B_PWRSTATE_TX); // to tx mode + PIOS_Thread_Sleep(10); + + if (static_tone) { + uint8_t i = 0; + while (i++ < 20) { + beacon_tone(openlrs_dev, 440, 1); + } + } else { + // close encounters tune + // G, A, F, F(lower octave), C + // octave 3: 392 440 349 175 261 + + beacon_tone(openlrs_dev, 392, 1); + + rfm22_write(openlrs_dev, 0x6d, 0x05); // 5 set mid power 25mW + PIOS_Thread_Sleep(10); + beacon_tone(openlrs_dev, 440, 1); + + rfm22_write(openlrs_dev, 0x6d, 0x04); // 4 set mid power 13mW + PIOS_Thread_Sleep(10); + beacon_tone(openlrs_dev, 349, 1); + + rfm22_write(openlrs_dev, 0x6d, 0x02); // 2 set min power 3mW + PIOS_Thread_Sleep(10); + beacon_tone(openlrs_dev, 175, 1); + + rfm22_write(openlrs_dev, 0x6d, 0x00); // 0 set min power 1.3mW + PIOS_Thread_Sleep(10); + beacon_tone(openlrs_dev, 261, 2); + } + rfm22_write_claim(openlrs_dev, 0x07, RF22B_PWRSTATE_READY); +} + + +/***************************************************************************** +* High level OpenLRS functions +*****************************************************************************/ + +// TODO: these should move into device structure, or deleted +// if not useful to be reported via GCS + +#define ntohl(v) \ + ( \ + (((v) & 0xFF000000) >> 24) | \ + (((v) & 0x00FF0000) >> 8) | \ + (((v) & 0x0000FF00) << 8) | \ + (((v) & 0x000000FF) << 24)) + +static uint8_t pios_openlrs_bind_receive(struct pios_openlrs_dev *openlrs_dev, uint32_t timeout) +{ + uint32_t start = PIOS_Thread_Systime(); + uint8_t rxb; + + init_rfm(openlrs_dev, true); + // TODO: move openlrs_dev->rf_mode into dev structure + openlrs_dev->rf_mode = Receive; + to_rx_mode(openlrs_dev); + DEBUG_PRINTF(2, "Waiting bind\r\n"); + DEBUG_PRINTF(2, "timeout: %d\r\n", timeout); + DEBUG_PRINTF(2, "start: %d\r\n", start); + + uint32_t i = 0; + + while ((!timeout) || ((PIOS_Thread_Systime() - start) < timeout)) { + PIOS_Thread_Sleep(1); +#if defined(PIOS_INCLUDE_WDG) && defined(PIOS_WDG_RFM22B) + // Update the watchdog timer + PIOS_WDG_UpdateFlag(PIOS_WDG_RFM22B); +#endif /* PIOS_WDG_RFM22B */ + + if (i++ % 100 == 0) { + // DEBUG_PRINTF(2,"Waiting bind\r\n"); + +#if defined(PIOS_LED_LINK) + PIOS_LED_Toggle(PIOS_LED_LINK); +#endif /* PIOS_LED_LINK */ + } + if (openlrs_dev->rf_mode == Received) { + DEBUG_PRINTF(2, "Got pkt\r\n"); + + // TODO: parse data packet (write command for that) + rfm22_claimBus(openlrs_dev); + rfm22_assertCs(openlrs_dev); + PIOS_SPI_TransferByte(openlrs_dev->spi_id, 0x7f); + rxb = PIOS_SPI_TransferByte(openlrs_dev->spi_id, 0x00); + if (rxb == 'b') { + PIOS_SPI_TransferBlock(openlrs_dev->spi_id, OUT_FF, + (uint8_t *)&openlrs_dev->bind_data, sizeof(struct bind_data), NULL); + rfm22_deassertCs(openlrs_dev); + rfm22_releaseBus(openlrs_dev); + +#if defined(PIOS_INCLUDE_DEBUG_CONSOLE) + if (2 <= DEBUG_LEVEL && pios_com_debug_id > 0) { + DEBUG_PRINTF(2, "Binding settings:\r\n"); + PIOS_Thread_Sleep(10); + DEBUG_PRINTF(2, " version: %d\r\n", openlrs_dev->bind_data.version); + PIOS_Thread_Sleep(10); + DEBUG_PRINTF(2, " serial_baudrate: %d\r\n", openlrs_dev->bind_data.serial_baudrate); + PIOS_Thread_Sleep(10); + DEBUG_PRINTF(2, " rf_frequency: %d\r\n", openlrs_dev->bind_data.rf_frequency); + PIOS_Thread_Sleep(10); + DEBUG_PRINTF(2, " rf_power: %d\r\n", openlrs_dev->bind_data.rf_power); + PIOS_Thread_Sleep(10); + DEBUG_PRINTF(2, " rf_channel_spacing: %d\r\n", openlrs_dev->bind_data.rf_channel_spacing); + PIOS_Thread_Sleep(10); + DEBUG_PRINTF(2, " modem_params: %d\r\n", openlrs_dev->bind_data.modem_params); + PIOS_Thread_Sleep(10); + DEBUG_PRINTF(2, " flags: %d\r\n", openlrs_dev->bind_data.flags); + PIOS_Thread_Sleep(10); + + for (uint32_t j = 0; j < MAXHOPS; j++) { + DEBUG_PRINTF(2, " hop channel: %d\r\n", openlrs_dev->bind_data.hopchannel[j]); + PIOS_Thread_Sleep(10); + } + } +#endif /* PIOS_INCLUDE_DEBUG_CONSOLE */ + + if (openlrs_dev->bind_data.version == BINDING_VERSION) { + DEBUG_PRINTF(2, "data good\r\n"); + rxb = 'B'; + tx_packet(openlrs_dev, &rxb, 1); // ACK that we got bound + + OPLinkSettingsData binding; + OPLinkSettingsGet(&binding); + binding.Version = openlrs_dev->bind_data.version; + binding.SerialBaudrate = openlrs_dev->bind_data.serial_baudrate; + binding.RFFrequency = openlrs_dev->bind_data.rf_frequency; + binding.CoordID = openlrs_dev->bind_data.rf_magic; + binding.RFPower = openlrs_dev->bind_data.rf_power; + binding.RFChannelSpacing = openlrs_dev->bind_data.rf_channel_spacing; + binding.ModemParams = openlrs_dev->bind_data.modem_params; + binding.Flags = openlrs_dev->bind_data.flags; + for (uint32_t j = 0; j < OPLINKSETTINGS_HOPCHANNEL_NUMELEM; j++) { + binding.HopChannel[j] = openlrs_dev->bind_data.hopchannel[j]; + } + binding.BeaconFrequency = openlrs_dev->beacon_frequency; + binding.BeaconDelay = openlrs_dev->beacon_delay; + binding.BeaconPeriod = openlrs_dev->beacon_period; + OPLinkSettingsSet(&binding); + UAVObjSave(OPLinkSettingsHandle(), 0); + +#if defined(PIOS_LED_LINK) + PIOS_LED_Toggle(PIOS_LED_LINK); +#endif /* PIOS_LED_LINK */ + + return 1; + } + } else { + rfm22_deassertCs(openlrs_dev); + rfm22_releaseBus(openlrs_dev); + } + + openlrs_dev->rf_mode = Receive; + rx_reset(openlrs_dev); + } + } + return 0; +} + +#if defined(PIOS_INCLUDE_DEBUG_CONSOLE) +static void printVersion(uint16_t v) +{ + char ver[8]; + + ver[0] = '0' + ((v >> 8) & 0x0f); + ver[1] = '.'; + ver[2] = '0' + ((v >> 4) & 0x0f); + if (v & 0x0f) { + ver[3] = '.'; + ver[4] = '0' + (v & 0x0f); + ver[5] = '\r'; + ver[6] = '\n'; + ver[7] = '\0'; + } else { + ver[3] = '\r'; + ver[4] = '\n'; + ver[5] = '\0'; + } + DEBUG_PRINTF(2, ver); +} +#endif /* if defined(PIOS_INCLUDE_DEBUG_CONSOLE) */ + +static void pios_openlrs_setup(struct pios_openlrs_dev *openlrs_dev, bool bind) +{ + DEBUG_PRINTF(2, "OpenLRSng RX setup starting. Binding: %e\r\n", bind); + PIOS_Thread_Sleep(5); +#if defined(PIOS_INCLUDE_DEBUG_CONSOLE) + printVersion(OPENLRSNG_VERSION); +#endif + + // Get the OPLinkStatus UAVO + OPLinkStatusData oplink_status; + OPLinkStatusGet(&oplink_status); + if (bind) { + oplink_status.LinkState = OPLINKSTATUS_LINKSTATE_BINDING; + if (pios_openlrs_bind_receive(openlrs_dev, 0)) { + // TODO: save binding settings bindWriteEeprom(); + DEBUG_PRINTF(2, "Saved bind data to EEPROM (not really yet -- TODO)\r\n"); + } + } + oplink_status.LinkState = OPLINKSTATUS_LINKSTATE_BOUND; + + DEBUG_PRINTF(2, "Entering normal mode\r\n"); + + init_rfm(openlrs_dev, 0); // Configure the RFM22B's registers for normal operation + openlrs_dev->rf_channel = 0; + rfmSetChannel(openlrs_dev, openlrs_dev->rf_channel); + + // Count hopchannels as we need it later + openlrs_dev->hopcount = 0; + while ((openlrs_dev->hopcount < MAXHOPS) && (openlrs_dev->bind_data.hopchannel[openlrs_dev->hopcount] != 0)) { + openlrs_dev->hopcount++; + } + + // ################### RX SYNC AT STARTUP ################# + openlrs_dev->rf_mode = Receive; + to_rx_mode(openlrs_dev); + + openlrs_dev->link_acquired = 0; + openlrs_dev->lastPacketTimeUs = PIOS_DELAY_GetuS(); + + // Update the OPLinkStatus UAVO + OPLinkStatusSet(&oplink_status); + + DEBUG_PRINTF(2, "OpenLRSng RX setup complete\r\n"); +} + +static void pios_openlrs_rx_loop(struct pios_openlrs_dev *openlrs_dev) +{ + uint32_t timeUs, timeMs; + +#if defined(PIOS_INCLUDE_WDG) && defined(PIOS_WDG_RFM22B) + // Update the watchdog timer + PIOS_WDG_UpdateFlag(PIOS_WDG_RFM22B); +#endif /* PIOS_WDG_RFM22B */ + + if (rfm22_read_claim(openlrs_dev, 0x0C) == 0) { // detect the locked module and reboot + DEBUG_PRINTF(2, "OLRS ERR: RX hang\r\n"); + init_rfm(openlrs_dev, 0); + to_rx_mode(openlrs_dev); + } + + // Get the OPLinkStatus UAVO + OPLinkStatusData oplink_status; + OPLinkStatusGet(&oplink_status); + + // Update the RSSI + oplink_status.RSSI = openlrs_dev->rssi; + + timeUs = PIOS_DELAY_GetuS(); + timeMs = PIOS_Thread_Systime(); + + // DEBUG_PRINTF(2,"Time: %d\r\n", timeUs); + + uint8_t *tx_buf = openlrs_dev->tx_buf; // convenient variable + + if (openlrs_dev->rf_mode == Received) { + DEBUG_PRINTF(2, "Packet Received. Dt=%d\r\n", timeUs - openlrs_dev->lastPacketTimeUs); + + // Read the packet from RFM22b + rfm22_claimBus(openlrs_dev); + rfm22_assertCs(openlrs_dev); + PIOS_SPI_TransferByte(openlrs_dev->spi_id, 0x7F); + uint32_t packet_size = getPacketSize(&openlrs_dev->bind_data); + PIOS_SPI_TransferBlock(openlrs_dev->spi_id, OUT_FF, + openlrs_dev->rx_buf, packet_size, NULL); + rfm22_deassertCs(openlrs_dev); + rfm22_releaseBus(openlrs_dev); + + openlrs_dev->lastAFCCvalue = rfmGetAFCC(openlrs_dev); + +#if defined(PIOS_LED_LINK) + PIOS_LED_Toggle(PIOS_LED_LINK); +#endif /* PIOS_LED_LINK */ + + openlrs_dev->lastPacketTimeUs = timeUs; + openlrs_dev->numberOfLostPackets = 0; + oplink_status.LinkQuality <<= 1; + oplink_status.LinkQuality |= 1; + + if ((openlrs_dev->rx_buf[0] & 0x3e) == 0x00) { + // This flag indicates receiving PPM data + + unpackChannels(openlrs_dev->bind_data.flags & 7, openlrs_dev->ppm, openlrs_dev->rx_buf + 1); + rescaleChannels(openlrs_dev->ppm); + + // Call the PPM received callback if it's available. + if (openlrs_dev->openlrs_rcvr_id) { +#if defined(PIOS_INCLUDE_OPENLRS_RCVR) + PIOS_OpenLRS_Rcvr_UpdateChannels(openlrs_dev->openlrs_rcvr_id, openlrs_dev->ppm); +#endif + } + if (openlrs_dev->ppm_callback) { + openlrs_dev->ppm_callback(openlrs_dev->ppm); + } + } else { + // Not PPM data. Push into serial RX buffer. + if ((openlrs_dev->rx_buf[0] & 0x38) == 0x38) { + if ((openlrs_dev->rx_buf[0] ^ tx_buf[0]) & 0x80) { + // We got new data... (not retransmission) + tx_buf[0] ^= 0x80; // signal that we got it + bool rx_need_yield; + uint8_t data_len = openlrs_dev->rx_buf[0] & 7; + if (openlrs_dev->rx_in_cb && (data_len > 0)) { + (openlrs_dev->rx_in_cb)(openlrs_dev->rx_in_context, &openlrs_dev->rx_buf[1], data_len, NULL, &rx_need_yield); + } + } + } + } + + // Flag to indicate ever got a link + openlrs_dev->link_acquired |= true; + oplink_status.LinkState = OPLINKSTATUS_LINKSTATE_CONNECTED; + openlrs_dev->beacon_armed = false; // when receiving packets make sure beacon cannot emit + + // When telemetry is enabled we ack packets and send info about FC back + if (openlrs_dev->bind_data.flags & TELEMETRY_MASK) { + if ((tx_buf[0] ^ openlrs_dev->rx_buf[0]) & 0x40) { + // resend last message + } else { + tx_buf[0] &= 0xc0; + tx_buf[0] ^= 0x40; // swap sequence as we have new data + + // Check for data on serial link + uint8_t bytes = 0; + // Append data from the com interface if applicable. + if (openlrs_dev->tx_out_cb) { + // Try to get some data to send + bool need_yield = false; + bytes = (openlrs_dev->tx_out_cb)(openlrs_dev->tx_out_context, &tx_buf[1], 8, NULL, &need_yield); + } + + if (bytes > 0) { + tx_buf[0] |= (0x37 + bytes); + } else { + // tx_buf[0] lowest 6 bits left at 0 + tx_buf[1] = openlrs_dev->rssi; + if (FlightBatteryStateHandle()) { + FlightBatteryStateData bat; + FlightBatteryStateGet(&bat); + // FrSky protocol normally uses 3.3V at 255 but + // divider from display can be set internally + tx_buf[2] = (uint8_t)bat.Voltage / 25.0f * 255; + tx_buf[3] = (uint8_t)bat.Current / 60.0f * 255; + } else { + tx_buf[2] = 0; // these bytes carry analog info. package + tx_buf[3] = 0; // battery here + } + tx_buf[4] = (openlrs_dev->lastAFCCvalue >> 8); + tx_buf[5] = openlrs_dev->lastAFCCvalue & 0xff; + tx_buf[6] = countSetBits(oplink_status.LinkQuality & 0x7fff); + } + } + + // This will block until sent + tx_packet(openlrs_dev, tx_buf, 9); + } + + // Once a packet has been processed, flip back into receiving mode + openlrs_dev->rf_mode = Receive; + rx_reset(openlrs_dev); + + openlrs_dev->willhop = 1; + } + + if (openlrs_dev->link_acquired) { + // For missing packets to be properly trigger a well timed channel hop, this method should be called fairly close (but not sooner) + // than 1ms after the packet was expected to trigger this path + if ((openlrs_dev->numberOfLostPackets < openlrs_dev->hopcount) && (PIOS_DELAY_GetuSSince(openlrs_dev->lastPacketTimeUs) > (getInterval(&openlrs_dev->bind_data) + packet_timeout_us))) { + DEBUG_PRINTF(2, "OLRS WARN: Lost packet: %d\r\n", openlrs_dev->numberOfLostPackets); + // we lost packet, hop to next channel + oplink_status.LinkQuality <<= 1; + openlrs_dev->willhop = 1; + if (openlrs_dev->numberOfLostPackets == 0) { + openlrs_dev->linkLossTimeMs = timeMs; + openlrs_dev->nextBeaconTimeMs = 0; + } + openlrs_dev->numberOfLostPackets++; + openlrs_dev->lastPacketTimeUs += getInterval(&openlrs_dev->bind_data); + openlrs_dev->willhop = 1; + } else if ((openlrs_dev->numberOfLostPackets >= openlrs_dev->hopcount) && (PIOS_DELAY_GetuSSince(openlrs_dev->lastPacketTimeUs) > (getInterval(&openlrs_dev->bind_data) * openlrs_dev->hopcount))) { + DEBUG_PRINTF(2, "ORLS WARN: Trying to resync\r\n"); + // hop slowly to allow resync with TX + oplink_status.LinkQuality = 0; + openlrs_dev->willhop = 1; + openlrs_dev->lastPacketTimeUs = timeUs; + } + + if (openlrs_dev->numberOfLostPackets) { +#if defined(PIOS_LED_LINK) + PIOS_LED_Off(PIOS_LED_LINK); +#endif /* PIOS_LED_LINK */ + + if (openlrs_dev->failsafeDelay && + (oplink_status.LinkState == OPLINKSTATUS_LINKSTATE_CONNECTED) && + ((timeMs - openlrs_dev->linkLossTimeMs) > ((uint32_t)openlrs_dev->failsafeDelay))) { + DEBUG_PRINTF(2, "Failsafe activated: %d %d\r\n", timeMs, openlrs_dev->linkLossTimeMs); + oplink_status.LinkState = OPLINKSTATUS_LINKSTATE_DISCONNECTED; + // failsafeApply(); + openlrs_dev->nextBeaconTimeMs = (timeMs + 1000UL * openlrs_dev->beacon_period) | 1; // beacon activating... + } + + if ((openlrs_dev->beacon_frequency) && (openlrs_dev->nextBeaconTimeMs) && + ((timeMs - openlrs_dev->nextBeaconTimeMs) < 0x80000000)) { + // Indicate that the beacon is now active so we can trigger extra ones below + openlrs_dev->beacon_armed = true; + + DEBUG_PRINTF(2, "Beacon time: %d\r\n", openlrs_dev->nextBeaconTimeMs); + // Only beacon when disarmed + uint8_t armed; + FlightStatusArmedGet(&armed); + if (armed == FLIGHTSTATUS_ARMED_DISARMED) { + beacon_send(openlrs_dev, false); // play cool tune + init_rfm(openlrs_dev, 0); // go back to normal RX + rx_reset(openlrs_dev); + openlrs_dev->nextBeaconTimeMs = (timeMs + 1000UL * openlrs_dev->beacon_period) | 1; // avoid 0 in time + } + } + } + } else { + // Waiting for first packet, hop slowly + if (PIOS_DELAY_GetuSSince(openlrs_dev->lastPacketTimeUs) > (getInterval(&openlrs_dev->bind_data) * openlrs_dev->hopcount)) { + // DEBUG_PRINTF(3,"Trying to get first packet\r\n"); + openlrs_dev->lastPacketTimeUs = timeUs; + openlrs_dev->willhop = 1; + } + } + + if (openlrs_dev->willhop == 1) { + openlrs_dev->rf_channel++; + + if ((openlrs_dev->rf_channel == MAXHOPS) || (openlrs_dev->bind_data.hopchannel[openlrs_dev->rf_channel] == 0)) { + openlrs_dev->rf_channel = 0; + } + + if ((openlrs_dev->beacon_frequency) && (openlrs_dev->nextBeaconTimeMs) && openlrs_dev->beacon_armed) { + // Listen for RSSI on beacon channel briefly for 'trigger' + uint8_t brssi = beaconGetRSSI(openlrs_dev); + if (brssi > ((openlrs_dev->beacon_rssi_avg >> 2) + 20)) { + openlrs_dev->nextBeaconTimeMs = timeMs + 1000L; + } + openlrs_dev->beacon_rssi_avg = (openlrs_dev->beacon_rssi_avg * 3 + brssi * 4) >> 2; + + rfmSetCarrierFrequency(openlrs_dev, openlrs_dev->bind_data.rf_frequency); + } + + rfmSetChannel(openlrs_dev, openlrs_dev->rf_channel); + rx_reset(openlrs_dev); + openlrs_dev->willhop = 0; + } + + // Update UAVO + OPLinkStatusSet(&oplink_status); +} + +uint8_t PIOS_OpenLRS_RSSI_Get(void) +{ + // Get the OPLinkStatus UAVO + OPLinkStatusData oplink_status; + + OPLinkStatusGet(&oplink_status); + + if (oplink_status.LinkState != OPLINKSTATUS_LINKSTATE_CONNECTED) { + return 0; + } else { + OPLinkStatusData openlrs_status; + OPLinkStatusGet(&openlrs_status); + OPLinkSettingsData openlrs_data; + OPLinkSettingsGet(&openlrs_data); + + uint16_t LQ = oplink_status.LinkQuality & 0x7fff; + // count number of 1s in LinkQuality + LQ = LQ - ((LQ >> 1) & 0x5555); + LQ = (LQ & 0x3333) + ((LQ >> 2) & 0x3333); + LQ = LQ + (LQ >> 4); + LQ &= 0x0F0F; + LQ = (LQ * 0x0101) >> 8; + + switch (openlrs_data.RSSIType) { + case OPLINKSETTINGS_RSSITYPE_COMBINED: + if ((uint8_t)LQ == 15) { + return (uint8_t)((oplink_status.RSSI >> 1) + 128); + } else { + return LQ * 9; + } + case OPLINKSETTINGS_RSSITYPE_RSSI: + return openlrs_status.RSSI; + + case OPLINKSETTINGS_RSSITYPE_LINKQUALITY: + return (uint8_t)(LQ << 4); + + default: + return 0; + } + } +} + +/***************************************************************************** +* PPM Code +*****************************************************************************/ + +/** + * Register a OpenLRS_Rcvr interface to inform of PPM packets + * + * @param[in] rfm22b_dev The RFM22B device ID. + * @param[in] rfm22b_rcvr_id The receiver device to inform of PPM packets + */ +void PIOS_OpenLRS_RegisterRcvr(uint32_t openlrs_id, uint32_t openlrs_rcvr_id) +{ + struct pios_openlrs_dev *openlrs_dev = + (struct pios_openlrs_dev *)openlrs_id; + + if (!pios_openlrs_validate(openlrs_dev)) { + return; + } + + openlrs_dev->openlrs_rcvr_id = openlrs_rcvr_id; +} + +/** + * Register a OpenLRS_Rcvr interface to inform of PPM packets using a generic callback. + * + * @param[in] openlrs_id The OpenLRS device ID. + * @param[in] callback The callback function. + */ +void PIOS_OpenLRS_RegisterPPMCallback(uint32_t openlrs_id, PIOS_OpenLRS_PPMReceivedCallback callback) +{ + struct pios_openlrs_dev *openlrs_dev = + (struct pios_openlrs_dev *)openlrs_id; + + if (!pios_openlrs_validate(openlrs_dev)) { + return; + } + + openlrs_dev->ppm_callback = callback; +} + +/***************************************************************************** +* Task and device setup +*****************************************************************************/ + +static void pios_openlrs_task(void *parameters); + +// ! Global device handle, required for IRQ handler +static struct pios_openlrs_dev *g_openlrs_dev; + +/** + * Initialise an OPENLRS device + * + * @param[out] openlrs_id A pointer to store the device ID in. + * @param[in] spi_id The SPI bus index. + * @param[in] slave_num The SPI bus slave number. + * @param[in] cfg The device configuration. + */ +int32_t PIOS_OpenLRS_Init(uint32_t *openlrs_id, uint32_t spi_id, + uint32_t slave_num, + const struct pios_openlrs_cfg *cfg) +{ + PIOS_DEBUG_Assert(openlrs_id); + PIOS_DEBUG_Assert(cfg); + + // Allocate the device structure. + struct pios_openlrs_dev *openlrs_dev = pios_openlrs_alloc(); + if (!openlrs_dev) { + return -1; + } + *openlrs_id = (uint32_t)openlrs_dev; + g_openlrs_dev = openlrs_dev; + + // Hardcode the band for now. + openlrs_dev->band = 430000000; + + // Store the SPI handle + openlrs_dev->slave_num = slave_num; + openlrs_dev->spi_id = spi_id; + + // Before initializing everything, make sure device found + uint8_t device_type = rfm22_read(openlrs_dev, RFM22_DEVICE_TYPE) & RFM22_DT_MASK; + if (device_type != 0x08) { + return -1; + } + + // Initialize the com callbacks. + openlrs_dev->rx_in_cb = NULL; + openlrs_dev->tx_out_cb = NULL; + + // Initialize the "PPM" callback. + openlrs_dev->openlrs_rcvr_id = 0; + openlrs_dev->ppm_callback = 0; + + OPLinkSettingsInitialize(); + OPLinkStatusInitialize(); + DEBUG_PRINTF(2, "OpenLRS UAVOs Initialized\r\n"); + OPLinkSettingsData binding; + OPLinkSettingsGet(&binding); + if (binding.Version == BINDING_VERSION) { + openlrs_dev->bind_data.version = binding.Version; + openlrs_dev->bind_data.serial_baudrate = binding.SerialBaudrate; + openlrs_dev->bind_data.rf_frequency = binding.RFFrequency; + openlrs_dev->bind_data.rf_magic = binding.CoordID; + openlrs_dev->bind_data.rf_power = binding.RFPower; + openlrs_dev->bind_data.rf_channel_spacing = binding.RFChannelSpacing; + openlrs_dev->bind_data.modem_params = binding.ModemParams; + openlrs_dev->bind_data.flags = binding.Flags; + for (uint32_t i = 0; i < OPLINKSETTINGS_HOPCHANNEL_NUMELEM; i++) { + openlrs_dev->bind_data.hopchannel[i] = binding.HopChannel[i]; + } + } + + // Copy beacon settings over + openlrs_dev->beacon_frequency = binding.BeaconFrequency; + openlrs_dev->beacon_delay = binding.BeaconDelay; + openlrs_dev->beacon_period = binding.BeaconPeriod; + + openlrs_dev->failsafeDelay = binding.FailsafeDelay; + + // Bind the configuration to the device instance + openlrs_dev->cfg = *cfg; + + // Initialize the external interrupt. + PIOS_EXTI_Init(cfg->exti_cfg); + + // Register the watchdog timer for the radio driver task +#if defined(PIOS_INCLUDE_WDG) && defined(PIOS_WDG_RFM22B) + PIOS_WDG_RegisterFlag(PIOS_WDG_RFM22B); +#endif /* PIOS_WDG_RFM22B */ + + // Start the driver task. This task controls the radio state machine and removed all of the IO from the IRQ handler. + openlrs_dev->taskHandle = PIOS_Thread_Create(pios_openlrs_task, "PIOS_OpenLRS_Task", STACK_SIZE_BYTES, (void *)openlrs_dev, TASK_PRIORITY); + + // TaskMonitorAdd(TASKINFO_RUNNING_MODEMRX, openlrs_dev->taskHandle); + + return 0; +} + +/** + * The task that controls the radio state machine. + * + * @param[in] paramters The task parameters. + */ +static void pios_openlrs_task(void *parameters) +{ + struct pios_openlrs_dev *openlrs_dev = (struct pios_openlrs_dev *)parameters; + + if (!pios_openlrs_validate(openlrs_dev)) { + return; + } + + DEBUG_PRINTF(2, "Setup started\r\n"); + + if (openlrs_dev->bind_data.version == BINDING_VERSION) { + pios_openlrs_setup(openlrs_dev, false); + } else { + pios_openlrs_setup(openlrs_dev, true); + } + + DEBUG_PRINTF(2, "Setup complete\r\n"); + + bool rssi_sampled = false; + while (1) { +#if defined(PIOS_INCLUDE_WDG) && defined(PIOS_WDG_RFM22B) + // Update the watchdog timer + PIOS_WDG_UpdateFlag(PIOS_WDG_RFM22B); +#endif /* PIOS_WDG_RFM22B */ + + + /* This block of code determines the timing of when to call the loop method. It reaches a bit into + * the internal state of that method to get the optimal timings. This is to keep the loop method as + * similar as possible to the openLRSng implementation (for easier maintenance of compatibility) + * while minimizing overhead spinning in a while loop. + * + * There are three reasons to go into loop: + * 1. the ISR was triggered (packet was received) + * 2. a little before the expected packet (to sample the RSSI while receiving packet) + * 3. a little after expected packet (to channel hop when a packet was missing) + */ + + + uint32_t delay_ms = 0; + + uint32_t time_since_packet_us = PIOS_DELAY_GetuSSince(openlrs_dev->lastPacketTimeUs); + + if (!rssi_sampled) { + // If we had not sampled RSSI yet, schedule a bit early to try and catch while "packet is in the air" + uint32_t time_till_measure_rssi_us = (getInterval(&openlrs_dev->bind_data) - packet_advance_time_us) - time_since_packet_us; + delay_ms = (time_till_measure_rssi_us + 999) / 1000; + // DEBUG_PRINTF(3, "T1: %d\r\n", delay_ms); + } else { + // If we have sampled RSSI we want to schedule to hop when a packet has been missed + uint32_t time_till_timeout_us = (getInterval(&openlrs_dev->bind_data) + packet_timeout_us) - time_since_packet_us; + delay_ms = (time_till_timeout_us + 999) / 1000; + // DEBUG_PRINTF(3, "T2: %d %d\r\n", time_till_timeout_us,delay_ms, time_since_packet_us); + } + + // Maximum delay based on packet time + const uint32_t max_delay = (getInterval(&openlrs_dev->bind_data) + packet_timeout_us) / 1000; + if (delay_ms > max_delay) { + delay_ms = max_delay; + } + + if (PIOS_Semaphore_Take(openlrs_dev->sema_isr, delay_ms) == false) { + if (!rssi_sampled) { + // We timed out to sample RSSI + if (openlrs_dev->numberOfLostPackets < 2) { + openlrs_dev->lastRSSITimeUs = openlrs_dev->lastPacketTimeUs; + openlrs_dev->rssi = rfmGetRSSI(openlrs_dev); // Read the RSSI value + + // DEBUG_PRINTF(3, "Sampled RSSI: %d %d\r\n", openlrs_dev->RSSI, delay); + } + } else { + // We timed out because packet was missed + DEBUG_PRINTF(3, "ISR Timeout. Missed packet: %d %d %d\r\n", delay, getInterval(&openlrs_dev->bind_data), time_since_packet_us); + pios_openlrs_rx_loop(openlrs_dev); + } + + rssi_sampled = true; + } else { + // DEBUG_PRINTF(3, "ISR %d %d %d\r\n", delay, getInterval(&openlrs_dev->bind_data), time_since_packet_us); + + // Process incoming data + pios_openlrs_rx_loop(openlrs_dev); + + // When a packet has been received (processed below) indicate we need to sample a new RSSI + rssi_sampled = false; + } + + + // DEBUG_PRINTF(3, "Processing time %d\r\n", PIOS_DELAY_GetuSSince(openlrs_dev->lastPacketTimeUs)); + } +} + +bool PIOS_OpenLRS_EXT_Int(void) +{ + struct pios_openlrs_dev *openlrs_dev = g_openlrs_dev; + + if (!pios_openlrs_validate(openlrs_dev)) { + return false; + } + + if (openlrs_dev->rf_mode == Transmit) { + openlrs_dev->rf_mode = Transmitted; + } else if (openlrs_dev->rf_mode == Receive) { + openlrs_dev->rf_mode = Received; + } + + // Indicate to main task that an ISR occurred + bool woken = false; + PIOS_Semaphore_Give_FromISR(openlrs_dev->sema_isr, &woken); + + return woken; +} + + +/** + * Allocate the device structure + */ +static struct pios_openlrs_dev *pios_openlrs_alloc(void) +{ + struct pios_openlrs_dev *openlrs_dev; + + openlrs_dev = (struct pios_openlrs_dev *)pios_malloc(sizeof(*openlrs_dev)); + if (!openlrs_dev) { + return NULL; + } + + openlrs_dev->spi_id = 0; + + // Create the ISR signal + openlrs_dev->sema_isr = PIOS_Semaphore_Create(); + if (!openlrs_dev->sema_isr) { + pios_free(openlrs_dev); + return NULL; + } + + openlrs_dev->magic = PIOS_OPENLRS_DEV_MAGIC; + return openlrs_dev; +} + + +/** + * Validate that the device structure is valid. + * + * @param[in] openlrs_dev The OpenLRS device structure pointer. + */ +static bool pios_openlrs_validate(struct pios_openlrs_dev *openlrs_dev) +{ + return openlrs_dev != NULL + && openlrs_dev->magic == PIOS_OPENLRS_DEV_MAGIC; +} + +/***************************************************************************** +* SPI Read/Write Functions +*****************************************************************************/ + +/** + * Assert the chip select line. + * + * @param[in] rfm22b_dev The RFM22B device. + */ +static void rfm22_assertCs(struct pios_openlrs_dev *openlrs_dev) +{ + PIOS_DELAY_WaituS(1); + if (openlrs_dev->spi_id != 0) { + PIOS_SPI_RC_PinSet(openlrs_dev->spi_id, + openlrs_dev->slave_num, 0); + } +} + +/** + * Deassert the chip select line. + * + * @param[in] rfm22b_dev The RFM22B device structure pointer. + */ +static void rfm22_deassertCs(struct pios_openlrs_dev *openlrs_dev) +{ + if (openlrs_dev->spi_id != 0) { + PIOS_SPI_RC_PinSet(openlrs_dev->spi_id, + openlrs_dev->slave_num, 1); + } +} + +/** + * Claim the SPI bus. + * + * @param[in] rfm22b_dev The RFM22B device structure pointer. + */ +static void rfm22_claimBus(struct pios_openlrs_dev *openlrs_dev) +{ + if (openlrs_dev->spi_id != 0) { + PIOS_SPI_ClaimBus(openlrs_dev->spi_id); + } +} + +/** + * Release the SPI bus. + * + * @param[in] rfm22b_dev The RFM22B device structure pointer. + */ +static void rfm22_releaseBus(struct pios_openlrs_dev *openlrs_dev) +{ + if (openlrs_dev->spi_id != 0) { + PIOS_SPI_ReleaseBus(openlrs_dev->spi_id); + } +} + +/** + * Claim the semaphore and write a byte to a register + * + * @param[in] rfm22b_dev The RFM22B device. + * @param[in] addr The address to write to + * @param[in] data The datat to write to that address + */ +static void rfm22_write_claim(struct pios_openlrs_dev *openlrs_dev, + uint8_t addr, uint8_t data) +{ + rfm22_claimBus(openlrs_dev); + rfm22_assertCs(openlrs_dev); + uint8_t buf[2] = { addr | 0x80, data }; + PIOS_SPI_TransferBlock(openlrs_dev->spi_id, buf, NULL, sizeof(buf), + NULL); + rfm22_deassertCs(openlrs_dev); + rfm22_releaseBus(openlrs_dev); +} + +/** + * Claim the semaphore and write a byte to a register + * + * @param[in] rfm22b_dev The RFM22B device. + * @param[in] addr The address to write to + * @param[in] data The datat to write to that address + */ +static uint8_t rfm22_read_claim(struct pios_openlrs_dev *openlrs_dev, + uint8_t addr) +{ + uint8_t out[2] = { addr &0x7F, 0xFF }; + uint8_t in[2]; + + rfm22_claimBus(openlrs_dev); + rfm22_assertCs(openlrs_dev); + PIOS_SPI_TransferBlock(openlrs_dev->spi_id, out, in, sizeof(out), + NULL); + rfm22_deassertCs(openlrs_dev); + rfm22_releaseBus(openlrs_dev); + return in[1]; +} + +/** + * Write a byte to a register without claiming the semaphore + * + * @param[in] rfm22b_dev The RFM22B device. + * @param[in] addr The address to write to + * @param[in] data The datat to write to that address + */ +static void rfm22_write(struct pios_openlrs_dev *openlrs_dev, uint8_t addr, + uint8_t data) +{ + rfm22_assertCs(openlrs_dev); + uint8_t buf[2] = { addr | 0x80, data }; + PIOS_SPI_TransferBlock(openlrs_dev->spi_id, buf, NULL, sizeof(buf), + NULL); + rfm22_deassertCs(openlrs_dev); +} + +/** + * Read a byte from an RFM22b register without claiming the bus + * + * @param[in] rfm22b_dev The RFM22B device structure pointer. + * @param[in] addr The address to read from + * @return Returns the result of the register read + */ +static uint8_t rfm22_read(struct pios_openlrs_dev *openlrs_dev, uint8_t addr) +{ + uint8_t out[2] = { addr &0x7F, 0xFF }; + uint8_t in[2]; + + rfm22_assertCs(openlrs_dev); + PIOS_SPI_TransferBlock(openlrs_dev->spi_id, out, in, sizeof(out), + NULL); + rfm22_deassertCs(openlrs_dev); + return in[1]; +} + +#endif /* PIOS_INCLUDE_OPENLRS */ + +/** + * @} + * @} + */ diff --git a/flight/pios/common/pios_openlrs_rcvr.c b/flight/pios/common/pios_openlrs_rcvr.c new file mode 100644 index 000000000..3ffc73464 --- /dev/null +++ b/flight/pios/common/pios_openlrs_rcvr.c @@ -0,0 +1,223 @@ +/** + ****************************************************************************** + * @addtogroup PIOS PIOS Core hardware abstraction layer + * @{ + * @addtogroup PIOS_RFM22B Radio Functions + * @brief PIOS OpenLRS interface for for the RFM22B radio + * @{ + * + * @file pios_openlrs_rcvr.c + * @author Tau Labs, http://taulabs.org, Copyright (C) 2015 + * @brief Implements an OpenLRS driver for the RFM22B + * @see The GNU Public License (GPL) Version 3 + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "pios.h" + +#ifdef PIOS_INCLUDE_OPENLRS + +#include "pios_openlrs_priv.h" + +#include +#include +#include +#include + +#define PIOS_OPENLRS_RCVR_TIMEOUT_MS 100 + +/* Provide a RCVR driver */ +static int32_t PIOS_OpenLRS_Rcvr_Get(uint32_t rcvr_id, uint8_t channel); +static void PIOS_OpenLRS_Rcvr_Supervisor(uint32_t ppm_id); + +const struct pios_rcvr_driver pios_openlrs_rcvr_driver = { + .read = PIOS_OpenLRS_Rcvr_Get, +}; + +/* Local Variables */ +enum pios_openlrs_rcvr_dev_magic { + PIOS_OPENLRS_RCVR_DEV_MAGIC = 0x07ac9e2144ff5329, +}; + +struct pios_openlrs_rcvr_dev { + enum pios_openlrs_rcvr_dev_magic magic; + int16_t channels[OPENLRS_PPM_NUM_CHANNELS]; + uint8_t supv_timer; + bool fresh; +}; + +static void openlrs_rcvr_update_uavo(struct pios_openlrs_rcvr_dev *pios_rfm22b_rcvr_dev); + +static bool PIOS_OpenLRS_Rcvr_Validate(struct pios_openlrs_rcvr_dev + *openlrs_rcvr_dev) +{ + return openlrs_rcvr_dev->magic == PIOS_OPENLRS_RCVR_DEV_MAGIC; +} + +static struct pios_openlrs_rcvr_dev *PIOS_OpenLRS_Rcvr_alloc(void) +{ + struct pios_openlrs_rcvr_dev *openlrs_rcvr_dev; + + openlrs_rcvr_dev = + (struct pios_openlrs_rcvr_dev *) + pios_malloc(sizeof(*openlrs_rcvr_dev)); + if (!openlrs_rcvr_dev) { + return NULL; + } + + openlrs_rcvr_dev->magic = PIOS_OPENLRS_RCVR_DEV_MAGIC; + openlrs_rcvr_dev->fresh = false; + openlrs_rcvr_dev->supv_timer = 0; + + return openlrs_rcvr_dev; +} + +extern int32_t PIOS_OpenLRS_Rcvr_Init(uint32_t *openlrs_rcvr_id, uintptr_t openlrs_id) +{ + struct pios_openlrs_rcvr_dev *openlrs_rcvr_dev; + + /* Allocate the device structure */ + openlrs_rcvr_dev = + (struct pios_openlrs_rcvr_dev *)PIOS_OpenLRS_Rcvr_alloc(); + if (!openlrs_rcvr_dev) { + return -1; + } + + /* Register uavobj callback */ + OPLinkReceiverInitialize(); + + *openlrs_rcvr_id = (uintptr_t)openlrs_rcvr_dev; + PIOS_OpenLRS_RegisterRcvr(openlrs_id, *openlrs_rcvr_id); + + /* Register the failsafe timer callback. */ + if (!PIOS_RTC_RegisterTickCallback + (PIOS_OpenLRS_Rcvr_Supervisor, *openlrs_rcvr_id)) { + PIOS_DEBUG_Assert(0); + } + + return 0; +} + +/** + * Called from the core driver to set the channel values whenever a + * PPM packet is received. This method stores the data locally as well + * as sets the data into the OPLinkReceiver UAVO for visibility + */ +int32_t PIOS_OpenLRS_Rcvr_UpdateChannels(uint32_t openlrs_rcvr_id, int16_t *channels) +{ + /* Recover our device context */ + struct pios_openlrs_rcvr_dev *openlrs_rcvr_dev = + (struct pios_openlrs_rcvr_dev *)openlrs_rcvr_id; + + if (!PIOS_OpenLRS_Rcvr_Validate(openlrs_rcvr_dev)) { + /* Invalid device specified */ + return -1; + } + + for (uint32_t i = 0; i < OPENLRS_PPM_NUM_CHANNELS; i++) { + openlrs_rcvr_dev->channels[i] = channels[i]; + } + + openlrs_rcvr_update_uavo(openlrs_rcvr_dev); + + // let supervisor know we have new data + openlrs_rcvr_dev->fresh = true; + + return 0; +} + +/** + * Get the value of an input channel + * \param[in] channel Number of the channel desired (zero based) + * \output PIOS_RCVR_INVALID channel not available + * \output PIOS_RCVR_TIMEOUT failsafe condition or missing receiver + * \output >=0 channel value + */ +static int32_t PIOS_OpenLRS_Rcvr_Get(uint32_t openlrs_rcvr_id, uint8_t channel) +{ + if (channel >= OPENLRS_PPM_NUM_CHANNELS) { + /* channel is out of range */ + return PIOS_RCVR_INVALID; + } + + /* Recover our device context */ + struct pios_openlrs_rcvr_dev *openlrs_rcvr_dev = + (struct pios_openlrs_rcvr_dev *)openlrs_rcvr_id; + + if (!PIOS_OpenLRS_Rcvr_Validate(openlrs_rcvr_dev)) { + /* Invalid device specified */ + return PIOS_RCVR_INVALID; + } + + return openlrs_rcvr_dev->channels[channel]; +} + +static void PIOS_OpenLRS_Rcvr_Supervisor(uint32_t openlrs_rcvr_id) +{ + /* Recover our device context */ + struct pios_openlrs_rcvr_dev *openlrs_rcvr_dev = + (struct pios_openlrs_rcvr_dev *)openlrs_rcvr_id; + + if (!PIOS_OpenLRS_Rcvr_Validate(openlrs_rcvr_dev)) { + /* Invalid device specified */ + return; + } + + /* + * RTC runs at 625Hz. + */ + if (++(openlrs_rcvr_dev->supv_timer) < + (PIOS_OPENLRS_RCVR_TIMEOUT_MS * 1000 / 625)) { + return; + } + openlrs_rcvr_dev->supv_timer = 0; + + if (!openlrs_rcvr_dev->fresh) { + for (int32_t i = 0; i < OPLINKRECEIVER_CHANNEL_NUMELEM; + i++) { + openlrs_rcvr_dev->channels[i] = PIOS_RCVR_TIMEOUT; + } + } + + openlrs_rcvr_dev->fresh = false; +} + +static void openlrs_rcvr_update_uavo(struct pios_openlrs_rcvr_dev *rcvr_dev) +{ + // Also store the received data in a UAVO for easy + // debugging. However this is not what is used in + // ManualControl (it fetches directly from this driver) + OPLinkReceiverData rcvr; + + for (uint8_t i = 0; i < OPENLRS_PPM_NUM_CHANNELS; i++) { + if (i < OPLINKRECEIVER_CHANNEL_NUMELEM) { + rcvr.Channel[i] = rcvr_dev->channels[i]; + } + } + for (int i = OPENLRS_PPM_NUM_CHANNELS - 1; i < OPLINKRECEIVER_CHANNEL_NUMELEM; i++) { + rcvr.Channel[i] = PIOS_RCVR_INVALID; + } + OPLinkReceiverSet(&rcvr); +} + +#endif /* PIOS_INCLUDE_OPENLRS */ + +/** + * @} + * @} + */ diff --git a/flight/pios/common/pios_oplinkrcvr.c b/flight/pios/common/pios_oplinkrcvr.c index 5c967c105..1896a572e 100644 --- a/flight/pios/common/pios_oplinkrcvr.c +++ b/flight/pios/common/pios_oplinkrcvr.c @@ -191,7 +191,7 @@ static void PIOS_oplinkrcvr_Supervisor(uint32_t oplinkrcvr_id) static uint8_t PIOS_OPLinkRCVR_Quality_Get(__attribute__((unused)) uint32_t oplinkrcvr_id) { - uint8_t oplink_quality; + uint16_t oplink_quality; OPLinkStatusLinkQualityGet(&oplink_quality); diff --git a/flight/pios/common/pios_rfm22b.c b/flight/pios/common/pios_rfm22b.c index 35fe19ce1..1bc83015a 100644 --- a/flight/pios/common/pios_rfm22b.c +++ b/flight/pios/common/pios_rfm22b.c @@ -7,7 +7,8 @@ * @{ * * @file pios_rfm22b.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. * @brief Implements a driver the the RFM22B driver * @see The GNU Public License (GPL) Version 3 * @@ -39,7 +40,7 @@ // 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) -// 0 to 255 user data bytes +// 0 to 251 user data bytes // 4 byte ECC // // OR in PPM only mode: @@ -58,6 +59,7 @@ #ifdef PIOS_INCLUDE_RFM22B #include +#include #include #include #include @@ -187,8 +189,10 @@ static enum pios_radio_event rfm22_fatal_error(struct pios_rfm22b_dev *rfm22b_de static void rfm22b_add_rx_status(struct pios_rfm22b_dev *rfm22b_dev, enum pios_rfm22b_rx_packet_status status); static void rfm22_setNominalCarrierFrequency(struct pios_rfm22b_dev *rfm22b_dev, uint8_t init_chan); static bool rfm22_setFreqHopChannel(struct pios_rfm22b_dev *rfm22b_dev, uint8_t channel); +static void rfm22_generateDeviceID(struct pios_rfm22b_dev *rfm22b_dev); static void rfm22_updatePairStatus(struct pios_rfm22b_dev *radio_dev); -static void rfm22_calculateLinkQuality(struct pios_rfm22b_dev *rfm22b_dev); +static void rfm22_updateStats(struct pios_rfm22b_dev *rfm22b_dev); +static bool rfm22_checkTimeOut(struct pios_rfm22b_dev *rfm22b_dev); static bool rfm22_isConnected(struct pios_rfm22b_dev *rfm22b_dev); static bool rfm22_isCoordinator(struct pios_rfm22b_dev *rfm22b_dev); static uint32_t rfm22_destinationID(struct pios_rfm22b_dev *rfm22b_dev); @@ -414,7 +418,7 @@ int32_t PIOS_RFM22B_Init(uint32_t *rfm22b_id, uint32_t spi_id, uint32_t slave_nu rfm22b_dev->rx_in_cb = NULL; rfm22b_dev->tx_out_cb = NULL; - // Initialzie the PPM callback. + // Initialize the PPM callback. rfm22b_dev->ppm_callback = NULL; // Initialize the stats. @@ -434,7 +438,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, false, false, false, false); + RFM22B_DEFAULT_MAX_CHANNEL, false, true, false); // Create the event queue rfm22b_dev->eventQueue = xQueueCreate(EVENT_QUEUE_SIZE, sizeof(enum pios_radio_event)); @@ -445,18 +449,8 @@ int32_t PIOS_RFM22B_Init(uint32_t *rfm22b_id, uint32_t spi_id, uint32_t slave_nu // Create a semaphore to know if an ISR needs responding to vSemaphoreCreateBinary(rfm22b_dev->isrPending); - // Create our (hopefully) unique 32 bit id from the processor serial number. - uint8_t crcs[] = { 0, 0, 0, 0 }; - { - char serial_no_str[33]; - PIOS_SYS_SerialNumberGet(serial_no_str); - // Create a 32 bit value using 4 8 bit CRC values. - for (uint8_t i = 0; serial_no_str[i] != 0; ++i) { - crcs[i % 4] = PIOS_CRC_updateByte(crcs[i % 4], serial_no_str[i]); - } - } - rfm22b_dev->deviceID = crcs[0] | crcs[1] << 8 | crcs[2] << 16 | crcs[3] << 24; - DEBUG_PRINTF(2, "RF device ID: %x\n\r", rfm22b_dev->deviceID); + // Create default (hopefully) unique 32 bit id from the processor serial number. + rfm22_generateDeviceID(rfm22b_dev); // Initialize the external interrupt. PIOS_EXTI_Init(cfg->exti_cfg); @@ -509,6 +503,26 @@ bool PIOS_RFM22_EXT_Int(void) return false; } + +/** + * Set the device ID for the RFM22B device. + * + * @param[in] rfm22b_id The RFM22B device index. + * + */ +void PIOS_RFM22B_SetDeviceID(uint32_t rfm22b_id, uint32_t custom_device_id) +{ + struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id; + + if (custom_device_id > 0) { + rfm22b_dev->deviceID = custom_device_id; + } else { + rfm22_generateDeviceID(rfm22b_dev); + } + + DEBUG_PRINTF(2, "RF device ID: %x\n\r", rfm22b_dev->deviceID); +} + /** * Returns the unique device ID for the RFM22B device. * @@ -578,18 +592,17 @@ void PIOS_RFM22B_SetTxPower(uint32_t rfm22b_id, enum rfm22b_tx_power tx_pwr) * @param[in] min_chan The minimum channel. * @param[in] max_chan The maximum channel. * @param[in] coordinator Is this modem an coordinator. + * @param[in] data_mode Should this modem send/receive data packets? * @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, 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 data_mode, bool ppm_mode) { struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id; + bool ppm_only = ppm_mode && !data_mode; if (!PIOS_RFM22B_Validate(rfm22b_dev)) { return; } - ppm_mode = ppm_mode || ppm_only; rfm22b_dev->coordinator = coordinator; rfm22b_dev->ppm_send_mode = ppm_mode && coordinator; rfm22b_dev->ppm_recv_mode = ppm_mode && !coordinator; @@ -602,7 +615,7 @@ void PIOS_RFM22B_SetChannelConfig(uint32_t rfm22b_id, enum rfm22b_datarate datar datarate = RFM22B_PPM_ONLY_DATARATE; rfm22b_dev->datarate = RFM22B_PPM_ONLY_DATARATE; } else { - rfm22b_dev->one_way_link = oneway; + rfm22b_dev->one_way_link = false; rfm22b_dev->datarate = datarate; } rfm22b_dev->packet_time = (ppm_mode ? packet_time_ppm[datarate] : packet_time[datarate]); @@ -666,8 +679,8 @@ void PIOS_RFM22B_GetStats(uint32_t rfm22b_id, struct rfm22b_stats *stats) return; } - // Calculate the current link quality - rfm22_calculateLinkQuality(rfm22b_dev); + // Update the current stats + rfm22_updateStats(rfm22b_dev); // Return the stats. *stats = rfm22b_dev->stats; @@ -681,7 +694,7 @@ void PIOS_RFM22B_GetStats(uint32_t rfm22b_id, struct rfm22b_stats *stats) * @param[in] mx_pairs The length of the pdevice_ids and RSSIs arrays. * @return The number of pair stats returned. */ -uint8_t PIOS_RFM2B_GetPairStats(uint32_t rfm22b_id, uint32_t *device_ids, int8_t *RSSIs, uint8_t max_pairs) +uint8_t PIOS_RFM22B_GetPairStats(uint32_t rfm22b_id, uint32_t *device_ids, int8_t *RSSIs, uint8_t max_pairs) { struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id; @@ -1092,8 +1105,9 @@ void PIOS_RFM22B_SetPPMCallback(uint32_t rfm22b_id, PPMReceivedCallback cb) * * @param[in] rfm22b_dev The RFM22B device ID. * @param[in] channels The PPM channel values. + * @param[out] nchan The number of channels to set. */ -extern void PIOS_RFM22B_PPMSet(uint32_t rfm22b_id, int16_t *channels) +extern void PIOS_RFM22B_PPMSet(uint32_t rfm22b_id, int16_t *channels, uint8_t nchan) { struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id; @@ -1102,7 +1116,7 @@ extern void PIOS_RFM22B_PPMSet(uint32_t rfm22b_id, int16_t *channels) } for (uint8_t i = 0; i < RFM22B_PPM_NUM_CHANNELS; ++i) { - rfm22b_dev->ppm[i] = channels[i]; + rfm22b_dev->ppm[i] = (i < nchan) ? channels[i] : PIOS_RCVR_INVALID; } } @@ -1111,8 +1125,9 @@ extern void PIOS_RFM22B_PPMSet(uint32_t rfm22b_id, int16_t *channels) * * @param[in] rfm22b_dev The RFM22B device structure pointer. * @param[out] channels The PPM channel values. + * @param[out] nchan The number of channels to get. */ -extern void PIOS_RFM22B_PPMGet(uint32_t rfm22b_id, int16_t *channels) +extern void PIOS_RFM22B_PPMGet(uint32_t rfm22b_id, int16_t *channels, uint8_t nchan) { struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id; @@ -1120,8 +1135,16 @@ extern void PIOS_RFM22B_PPMGet(uint32_t rfm22b_id, int16_t *channels) return; } - for (uint8_t i = 0; i < RFM22B_PPM_NUM_CHANNELS; ++i) { - channels[i] = rfm22b_dev->ppm[i]; + if (!rfm22_isCoordinator(rfm22b_dev) && !rfm22_isConnected(rfm22b_dev)) { + // Set the PPM channels values to INVALID + for (uint8_t i = 0; i < RFM22B_PPM_NUM_CHANNELS; ++i) { + channels[i] = PIOS_RCVR_INVALID; + } + return; + } + + for (uint8_t i = 0; i < nchan; ++i) { + channels[i] = (i < RFM22B_PPM_NUM_CHANNELS) ? rfm22b_dev->ppm[i] : PIOS_RCVR_INVALID; } } @@ -1702,6 +1725,29 @@ static bool rfm22_setFreqHopChannel(struct pios_rfm22b_dev *rfm22b_dev, uint8_t return true; } +/** + * Generate the unique device ID for the RFM22B device. + * + * @param[in] rfm22b_id The RFM22B device index. + * + */ +void rfm22_generateDeviceID(struct pios_rfm22b_dev *rfm22b_dev) +{ + // Create our (hopefully) unique 32 bit id from the processor serial number. + uint8_t crcs[] = { 0, 0, 0, 0 }; + { + char serial_no_str[33]; + PIOS_SYS_SerialNumberGet(serial_no_str); + // Create a 32 bit value using 4 8 bit CRC values. + for (uint8_t i = 0; serial_no_str[i] != 0; ++i) { + crcs[i % 4] = PIOS_CRC_updateByte(crcs[i % 4], serial_no_str[i]); + } + } + + rfm22b_dev->deviceID = crcs[0] | crcs[1] << 8 | crcs[2] << 16 | crcs[3] << 24; + DEBUG_PRINTF(2, "Generated RF device ID: %x\n\r", rfm22b_dev->deviceID); +} + /** * Read the RFM22B interrupt and device status registers * @@ -1959,7 +2005,8 @@ static enum pios_radio_event radio_receivePacket(struct pios_rfm22b_dev *radio_d 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; + // Set failsafe value + radio_dev->ppm[i] = PIOS_RCVR_TIMEOUT; } } @@ -1984,6 +2031,9 @@ static enum pios_radio_event radio_receivePacket(struct pios_rfm22b_dev *radio_d rfm22b_add_rx_status(radio_dev, RADIO_ERROR_RX_PACKET); } + // Increment the packet sequence number. + radio_dev->stats.rx_seq++; + enum pios_radio_event ret_event = RADIO_EVENT_RX_COMPLETE; if (good_packet || corrected_packet) { // Send the data to the com port @@ -1998,10 +2048,10 @@ static enum pios_radio_event radio_receivePacket(struct pios_rfm22b_dev *radio_d 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->last_contact = xTaskGetTickCount(); + radio_dev->stats.link_state = OPLINKSTATUS_LINKSTATE_CONNECTED; + radio_dev->last_contact = xTaskGetTickCount(); + radio_dev->stats.rssi = radio_dev->rssi_dBm; } else { ret_event = RADIO_EVENT_RX_COMPLETE; } @@ -2096,17 +2146,31 @@ static void rfm22_updatePairStatus(struct pios_rfm22b_dev *radio_dev) } /** - * Calculate the link quality from the packet receipt, tranmittion statistics. + * Calculate stats from the packet receipt, transmission statistics. * * @param[in] rfm22b_dev The device structure */ -static void rfm22_calculateLinkQuality(struct pios_rfm22b_dev *rfm22b_dev) +static void rfm22_updateStats(struct pios_rfm22b_dev *rfm22b_dev) { // Add the RX packet statistics rfm22b_dev->stats.rx_good = 0; rfm22b_dev->stats.rx_corrected = 0; rfm22b_dev->stats.rx_error = 0; rfm22b_dev->stats.rx_failure = 0; + + if (!rfm22_isConnected(rfm22b_dev)) { + // Set link_quality to 0 and Rssi to noise floor if disconnected + rfm22b_dev->stats.link_quality = 0; + rfm22b_dev->stats.rssi = -127; + return; + } + + // Check if connection is timed out + if (rfm22_checkTimeOut(rfm22b_dev)) { + // Set the link state to disconnected. + rfm22b_dev->stats.link_state = OPLINKSTATUS_LINKSTATE_DISCONNECTED; + } + 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) { @@ -2134,6 +2198,16 @@ static void rfm22_calculateLinkQuality(struct pios_rfm22b_dev *rfm22b_dev) rfm22b_dev->stats.link_quality = 64 + rfm22b_dev->stats.rx_good - rfm22b_dev->stats.rx_error - rfm22b_dev->stats.rx_failure; } +/** + * A timeout occured ? + * + * @param[in] rfm22b_dev The device structure + */ +static bool rfm22_checkTimeOut(struct pios_rfm22b_dev *rfm22b_dev) +{ + return pios_rfm22_time_difference_ms(rfm22b_dev->last_contact, xTaskGetTickCount()) >= CONNECTED_TIMEOUT; +} + /** * Add a status value to the RX packet status array. * @@ -2262,26 +2336,17 @@ static uint8_t rfm22_calcChannel(struct pios_rfm22b_dev *rfm22b_dev, uint8_t ind uint8_t idx = index % rfm22b_dev->num_channels; // Are we switching to a new channel? - if (idx != rfm22b_dev->channel_index) { - 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; - // Set the PPM outputs to INVALID - for (uint8_t i = 0; i < RFM22B_PPM_NUM_CHANNELS; ++i) { - rfm22b_dev->ppm[i] = PIOS_RCVR_INVALID; - } - } - - // Stay on first channel. - idx = 0; - } - - rfm22b_dev->channel_index = idx; + if ((idx != rfm22b_dev->channel_index) && !rfm22_isCoordinator(rfm22b_dev) && rfm22_checkTimeOut(rfm22b_dev)) { + // Set the link state to disconnected. + rfm22b_dev->stats.link_state = OPLINKSTATUS_LINKSTATE_DISCONNECTED; + // Update stats + rfm22_updateStats(rfm22b_dev); + // Stay on first channel. + idx = 0; } + rfm22b_dev->channel_index = idx; + return rfm22b_dev->channels[idx]; } diff --git a/flight/pios/common/pios_rfm22b_com.c b/flight/pios/common/pios_rfm22b_com.c index 964cee585..1669e1095 100644 --- a/flight/pios/common/pios_rfm22b_com.c +++ b/flight/pios/common/pios_rfm22b_com.c @@ -40,7 +40,7 @@ static void PIOS_RFM22B_COM_RegisterRxCallback(uint32_t rfm22b_id, pios_com_call static void PIOS_RFM22B_COM_RegisterTxCallback(uint32_t rfm22b_id, pios_com_callback tx_out_cb, uint32_t context); static void PIOS_RFM22B_COM_TxStart(uint32_t rfm22b_id, uint16_t tx_bytes_avail); static void PIOS_RFM22B_COM_RxStart(uint32_t rfm22b_id, uint16_t rx_bytes_avail); -static bool PIOS_RFM22B_COM_Available(uint32_t rfm22b_com_id); +static uint32_t PIOS_RFM22B_COM_Available(uint32_t rfm22b_com_id); /* Local variables */ const struct pios_com_driver pios_rfm22b_com_driver = { @@ -135,9 +135,9 @@ static void PIOS_RFM22B_COM_RegisterTxCallback(uint32_t rfm22b_id, pios_com_call * @param[in] rfm22b_dev The device ID. * @return True of the device is available. */ -static bool PIOS_RFM22B_COM_Available(uint32_t rfm22b_id) +static uint32_t PIOS_RFM22B_COM_Available(uint32_t rfm22b_id) { - return PIOS_RFM22B_LinkStatus(rfm22b_id); + return PIOS_RFM22B_LinkStatus(rfm22b_id) ? COM_AVAILABLE_RXTX : COM_AVAILABLE_NONE; } #endif /* PIOS_INCLUDE_RFM22B_COM */ diff --git a/flight/pios/common/pios_semaphore.c b/flight/pios/common/pios_semaphore.c new file mode 100644 index 000000000..c10925731 --- /dev/null +++ b/flight/pios/common/pios_semaphore.c @@ -0,0 +1,411 @@ +/** + ****************************************************************************** + * @file pios_semaphore.c + * @author Tau Labs, http://taulabs.org, Copyright (C) 2013-2014 + * @addtogroup PIOS PIOS Core hardware abstraction layer + * @{ + * @addtogroup PIOS_Semaphore Semaphore Abstraction + * @{ + * @brief Abstracts the concept of a binary semaphore to hide different implementations + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "pios.h" +#include "pios_semaphore.h" + +#if !defined(PIOS_INCLUDE_FREERTOS) && !defined(PIOS_INCLUDE_CHIBIOS) && !defined(PIOS_INCLUDE_IRQ) +#error "pios_semaphore.c requires either PIOS_INCLUDE_FREERTOS, PIOS_INCLUDE_CHIBIOS or PIOS_INCLUDE_IRQ to be defined" +#endif + +#if defined(PIOS_INCLUDE_FREERTOS) + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +// portTICK_RATE_MS is in [ms/tick]. +// See http://sourceforge.net/tracker/?func=detail&aid=3498382&group_id=111543&atid=659636 +#define TICKS2MS(t) ((t) * (portTICK_RATE_MS)) +#define MS2TICKS(m) ((m) / (portTICK_RATE_MS)) + +/** + * + * @brief Creates a binary semaphore. + * + * @returns instance of @p struct pios_semaphore or NULL on failure + * + */ +struct pios_semaphore *PIOS_Semaphore_Create(void) +{ + struct pios_semaphore *sema = pios_malloc(sizeof(struct pios_semaphore)); + + if (sema == NULL) { + return NULL; + } + + /* + * The initial state of a binary semaphore is "given". + * FreeRTOS executes a "give" upon creation. + */ + xSemaphoreHandle temp; + vSemaphoreCreateBinary(temp); + sema->sema_handle = (uintptr_t)temp; + + return sema; +} + +/** + * + * @brief Takes binary semaphore. + * + * @param[in] sema pointer to instance of @p struct pios_semaphore + * @param[in] timeout_ms timeout for acquiring the lock in milliseconds + * + * @returns true on success or false on timeout or failure + * + */ +bool PIOS_Semaphore_Take(struct pios_semaphore *sema, uint32_t timeout_ms) +{ + PIOS_Assert(sema != NULL); + + portTickType timeout_ticks; + if (timeout_ms == PIOS_SEMAPHORE_TIMEOUT_MAX) { + timeout_ticks = portMAX_DELAY; + } else { + timeout_ticks = MS2TICKS(timeout_ms); + } + + return xSemaphoreTake(sema->sema_handle, timeout_ticks) == pdTRUE; +} + +/** + * + * @brief Gives binary semaphore. + * + * @param[in] sema pointer to instance of @p struct pios_semaphore + * + * @returns true on success or false on timeout or failure + * + */ +bool PIOS_Semaphore_Give(struct pios_semaphore *sema) +{ + PIOS_Assert(sema != NULL); + + return xSemaphoreGive(sema->sema_handle) == pdTRUE; +} + +/* Workaround for simulator version of FreeRTOS. */ +#if !defined(SIM_POSIX) +/** + * + * @brief Takes binary semaphore from ISR context. + * + * @param[in] sema pointer to instance of @p struct pios_semaphore + * @param[out] woken pointer to bool which will be set true if a context switch is required + * + * @returns true on success or false on timeout or failure + * + */ +bool PIOS_Semaphore_Take_FromISR(struct pios_semaphore *sema, bool *woken) +{ + PIOS_Assert(sema != NULL); + PIOS_Assert(woken != NULL); + + signed portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + + bool result = xSemaphoreTakeFromISR(sema->sema_handle, &xHigherPriorityTaskWoken) == pdTRUE; + + *woken = *woken || xHigherPriorityTaskWoken == pdTRUE; + + return result; +} + +/** + * + * @brief Gives binary semaphore from ISR context. + * + * @param[in] sema pointer to instance of @p struct pios_semaphore + * @param[out] woken pointer to bool which will be set true if a context switch is required + * + * @returns true on success or false on timeout or failure + * + */ +bool PIOS_Semaphore_Give_FromISR(struct pios_semaphore *sema, bool *woken) +{ + PIOS_Assert(sema != NULL); + PIOS_Assert(woken != NULL); + + signed portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + + bool result = xSemaphoreGiveFromISR(sema->sema_handle, &xHigherPriorityTaskWoken) == pdTRUE; + + *woken = *woken || xHigherPriorityTaskWoken == pdTRUE; + + return result; +} +#endif /* !defined(SIM_POSIX) */ + +#elif defined(PIOS_INCLUDE_CHIBIOS) + +/** + * + * @brief Creates a binary semaphore. + * + * @returns instance of @p struct pios_semaphore or NULL on failure + * + */ +struct pios_semaphore *PIOS_Semaphore_Create(void) +{ + struct pios_semaphore *sema = PIOS_malloc(sizeof(struct pios_semaphore)); + + if (sema == NULL) { + return NULL; + } + + /* + * The initial state of a binary semaphore is "given". + */ + chBSemInit(&sema->sema, false); + + return sema; +} + +/** + * + * @brief Takes binary semaphore. + * + * @param[in] sema pointer to instance of @p struct pios_semaphore + * @param[in] timeout_ms timeout for acquiring the lock in milliseconds + * + * @returns true on success or false on timeout or failure + * + */ +bool PIOS_Semaphore_Take(struct pios_semaphore *sema, uint32_t timeout_ms) +{ + PIOS_Assert(sema != NULL); + + if (timeout_ms == PIOS_SEMAPHORE_TIMEOUT_MAX) { + return chBSemWait(&sema->sema) == RDY_OK; + } else if (timeout_ms == 0) { + return chBSemWaitTimeout(&sema->sema, TIME_IMMEDIATE) == RDY_OK; + } else { + return chBSemWaitTimeout(&sema->sema, MS2ST(timeout_ms)) == RDY_OK; + } +} + +/** + * + * @brief Gives binary semaphore. + * + * @param[in] sema pointer to instance of @p struct pios_semaphore + * + * @returns true on success or false on timeout or failure + * + */ +bool PIOS_Semaphore_Give(struct pios_semaphore *sema) +{ + PIOS_Assert(sema != NULL); + + chBSemSignal(&sema->sema); + + return true; +} + +/** + * + * @brief Takes binary semaphore from ISR context. + * + * @param[in] sema pointer to instance of @p struct pios_semaphore + * @param[out] woken pointer to bool which will be set true if a context switch is required + * + * @returns true on success or false on timeout or failure + * + */ +bool PIOS_Semaphore_Take_FromISR(struct pios_semaphore *sema, bool *woken) +{ + /* Waiting on a semaphore within an interrupt is not supported by ChibiOS. */ + PIOS_Assert(false); + return false; +} + +/** + * + * @brief Gives binary semaphore from ISR context. + * + * @param[in] sema pointer to instance of @p struct pios_semaphore + * @param[out] woken pointer to bool which will be set true if a context switch is required + * + * @returns true on success or false on timeout or failure + * + */ +bool PIOS_Semaphore_Give_FromISR(struct pios_semaphore *sema, bool *woken) +{ + PIOS_Assert(sema != NULL); + PIOS_Assert(woken != NULL); + + chSysLockFromIsr(); + chBSemSignalI(&sema->sema); + chSysUnlockFromIsr(); + + return true; +} + +#elif defined(PIOS_INCLUDE_IRQ) + +/** + * + * @brief Creates a binary semaphore. + * + * @returns instance of @p struct pios_semaphore or NULL on failure + * + */ +struct pios_semaphore *PIOS_Semaphore_Create(void) +{ + struct pios_semaphore *sema = PIOS_malloc_no_dma(sizeof(struct pios_semaphore)); + + if (sema == NULL) { + return NULL; + } + + /* + * The initial state of a binary semaphore is "given". + */ + sema->sema_count = 1; + + return sema; +} + +/** + * + * @brief Takes binary semaphore. + * + * @param[in] sema pointer to instance of @p struct pios_semaphore + * @param[in] timeout_ms timeout for acquiring the lock in milliseconds + * + * @returns true on success or false on timeout or failure + * + */ +bool PIOS_Semaphore_Take(struct pios_semaphore *sema, uint32_t timeout_ms) +{ + PIOS_Assert(sema != NULL); + + uint32_t start = PIOS_DELAY_GetRaw(); + + uint32_t temp_sema_count; + do { + PIOS_IRQ_Disable(); + if ((temp_sema_count = sema->sema_count) != 0) { + --sema->sema_count; + } + PIOS_IRQ_Enable(); + } while (temp_sema_count == 0 && + PIOS_DELAY_DiffuS(start) < timeout_ms * 1000); + + return temp_sema_count != 0; +} + +/** + * + * @brief Gives binary semaphore. + * + * @param[in] sema pointer to instance of @p struct pios_semaphore + * + * @returns true on success or false on timeout or failure + * + */ +bool PIOS_Semaphore_Give(struct pios_semaphore *sema) +{ + PIOS_Assert(sema != NULL); + + bool result = true; + + PIOS_IRQ_Disable(); + + if (sema->sema_count == 0) { + ++sema->sema_count; + } else { + result = false; + } + + PIOS_IRQ_Enable(); + + return result; +} + +/* Workaround for simulator version of FreeRTOS. */ +#if !defined(SIM_POSIX) +/** + * + * @brief Takes binary semaphore from ISR context. + * + * @param[in] sema pointer to instance of @p struct pios_semaphore + * @param[out] woken pointer to bool which will be set true if a context switch is required + * + * @returns true on success or false on timeout or failure + * + */ +bool PIOS_Semaphore_Take_FromISR(struct pios_semaphore *sema, bool *woken) +{ + PIOS_Assert(sema != NULL); + + bool result = true; + + PIOS_IRQ_Disable(); + + if (sema->sema_count != 0) { + --sema->sema_count; + } else { + result = false; + } + + PIOS_IRQ_Enable(); + + return result; +} + +/** + * + * @brief Gives binary semaphore from ISR context. + * + * @param[in] sema pointer to instance of @p struct pios_semaphore + * @param[out] woken pointer to bool which will be set true if a context switch is required + * + * @returns true on success or false on timeout or failure + * + */ +bool PIOS_Semaphore_Give_FromISR(struct pios_semaphore *sema, bool *woken) +{ + PIOS_Assert(sema != NULL); + + bool result = true; + + PIOS_IRQ_Disable(); + + if (sema->sema_count == 0) { + ++sema->sema_count; + } else { + result = false; + } + + PIOS_IRQ_Enable(); + + return result; +} +#endif /* !defined(SIM_POSIX) */ + +#endif /* defined(PIOS_INCLUDE_IRQ) */ diff --git a/flight/pios/common/pios_sensors.c b/flight/pios/common/pios_sensors.c index 0275287e1..b2cbb4c48 100644 --- a/flight/pios/common/pios_sensors.c +++ b/flight/pios/common/pios_sensors.c @@ -57,7 +57,7 @@ PIOS_SENSORS_Instance *PIOS_SENSORS_GetInstanceByType(const PIOS_SENSORS_Instanc PIOS_SENSORS_Instance *sensor; LL_FOREACH((PIOS_SENSORS_Instance *)previous_instance, sensor) { - if (sensor->type && type) { + if (sensor->type & type) { return sensor; } } diff --git a/flight/pios/common/pios_task_monitor.c b/flight/pios/common/pios_task_monitor.c index 958a744a6..c6616b503 100644 --- a/flight/pios/common/pios_task_monitor.c +++ b/flight/pios/common/pios_task_monitor.c @@ -1,11 +1,12 @@ /** ****************************************************************************** - * @addtogroup OpenPilotSystem OpenPilot System + * @addtogroup LibrePilotSystem LibrePilot System * @{ - * @addtogroup OpenPilotLibraries OpenPilot System Libraries + * @addtogroup LibrePilotLibraries LibrePilot System Libraries * @{ - * @file pios_task_monitor.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @file pios_task_monitor.c + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2015. * @brief Task monitoring functions * @see The GNU Public License (GPL) Version 3 * @@ -36,6 +37,9 @@ static uint32_t mLastMonitorTime; static uint32_t mLastIdleMonitorTime; static uint16_t mMaxTasks; +volatile uint32_t idleCounter; +uint32_t zeroLoadIdleCounterPerSec = UINT32_MAX; +volatile bool idleCounterClear; /** * Initialize the Task Monitor */ @@ -149,31 +153,44 @@ void PIOS_TASK_MONITOR_ForEachTask(TaskMonitorTaskInfoCallback callback, void *c xSemaphoreGiveRecursive(mLock); } + uint8_t PIOS_TASK_MONITOR_GetIdlePercentage() { -#if defined(ARCH_POSIX) || defined(ARCH_WIN32) - return 50; + uint32_t ticks = PIOS_TASK_MONITOR_GetIdleTicksCount(); -#elif (configGENERATE_RUN_TIME_STATS == 1) - xSemaphoreTakeRecursive(mLock, portMAX_DELAY); - - uint32_t currentTime = portGET_RUN_TIME_COUNTER_VALUE(); - - /* avoid divide-by-zero if the interval is too small */ - uint32_t deltaTime = ((currentTime - mLastIdleMonitorTime) / 100) ? : 1; - mLastIdleMonitorTime = currentTime; - uint8_t running_time_percentage = 0; - - /* Generate idle time percentage stats */ - running_time_percentage = uxTaskGetRunTime(xTaskGetIdleTaskHandle()) / deltaTime; - xSemaphoreGiveRecursive(mLock); - return running_time_percentage; - -#else - return 0; - -#endif + return (uint8_t)((100 * ticks) / zeroLoadIdleCounterPerSec); } +uint32_t PIOS_TASK_MONITOR_GetIdleTicksCount() +{ + static portTickType lastTickCount = 0; + uint32_t ticks = 0; + portTickType now = xTaskGetTickCount(); + + if (idleCounterClear) { + idleCounter = 0; + } + + if (now > lastTickCount) { + uint32_t dT = (xTaskGetTickCount() - lastTickCount) * portTICK_RATE_MS; // in ms + ticks = (1000 * idleCounter) / dT; + } // else: TickCount has wrapped, do not calc now + lastTickCount = now; + idleCounterClear = true; + return ticks; +} + +void PIOS_TASK_MONITOR_CalibrateIdleCounter() +{ + idleCounterClear = true; + PIOS_TASK_MONITOR_GetIdleTicksCount(); + vTaskDelay(20); + zeroLoadIdleCounterPerSec = PIOS_TASK_MONITOR_GetIdleTicksCount(); +} + +uint32_t PIOS_TASK_MONITOR_GetZeroLoadTicksCount() +{ + return zeroLoadIdleCounterPerSec; +} #endif // PIOS_INCLUDE_TASK_MONITOR diff --git a/flight/pios/common/pios_thread.c b/flight/pios/common/pios_thread.c new file mode 100644 index 000000000..32f71f0b0 --- /dev/null +++ b/flight/pios/common/pios_thread.c @@ -0,0 +1,441 @@ +/** + ****************************************************************************** + * @file pios_thread.c + * @author Tau Labs, http://taulabs.org, Copyright (C) 2014 + * @addtogroup PIOS PIOS Core hardware abstraction layer + * @{ + * @addtogroup PIOS_Thread Thread Abstraction + * @{ + * @brief Abstracts the concept of a thread to hide different implementations + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "pios.h" +#include "pios_thread.h" + +#if !defined(PIOS_INCLUDE_FREERTOS) && !defined(PIOS_INCLUDE_CHIBIOS) +#error "pios_thread.c requires PIOS_INCLUDE_FREERTOS or PIOS_INCLUDE_CHIBIOS" +#endif + +#if defined(PIOS_INCLUDE_FREERTOS) + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +// portTICK_RATE_MS is in [ms/tick]. +// See http://sourceforge.net/tracker/?func=detail&aid=3498382&group_id=111543&atid=659636 +#define TICKS2MS(t) ((t) * (portTICK_RATE_MS)) +#define MS2TICKS(m) ((m) / (portTICK_RATE_MS)) + +/** + * + * @brief Creates a thread. + * + * @param[in] fp pointer to thread function + * @param[in] namep pointer to thread name + * @param[in] stack_bytes stack size in bytes + * @param[in] argp pointer to argument which will be passed to thread function + * @param[in] prio thread priority + * + * @returns instance of @p struct pios_thread or NULL on failure + * + */ +struct pios_thread *PIOS_Thread_Create(void (*fp)(void *), const char *namep, size_t stack_bytes, void *argp, enum pios_thread_prio_e prio) +{ + struct pios_thread *thread = pios_malloc(sizeof(struct pios_thread)); + + if (thread == NULL) { + return NULL; + } + + thread->task_handle = (uintptr_t)NULL; + + if (xTaskCreate(fp, (const char *)namep, stack_bytes / 4, argp, prio, (xTaskHandle *)&thread->task_handle) != pdPASS) { + pios_free(thread); + return NULL; + } + + return thread; +} + +#if (INCLUDE_vTaskDelete == 1) +/** + * + * @brief Destroys an instance of @p struct pios_thread. + * + * @param[in] threadp pointer to instance of @p struct pios_thread + * + */ +void PIOS_Thread_Delete(struct pios_thread *threadp) +{ + if (threadp == NULL) { + vTaskDelete(NULL); + } else { + vTaskDelete((xTaskHandle)threadp->task_handle); + } +} +#else +#error "PIOS_Thread_Delete requires INCLUDE_vTaskDelete to be defined 1" +#endif /* (INCLUDE_vTaskDelete == 1) */ + +/** + * + * @brief Returns the current system time. + * + * @returns current system time + * + */ +uint32_t PIOS_Thread_Systime(void) +{ + return (uint32_t)TICKS2MS(xTaskGetTickCount()); +} + +#if (INCLUDE_vTaskDelay == 1) +/** + * + * @brief Suspends execution of current thread at least for specified time. + * + * @param[in] time_ms time in milliseconds to suspend thread execution + * + */ +void PIOS_Thread_Sleep(uint32_t time_ms) +{ + if (time_ms == PIOS_THREAD_TIMEOUT_MAX) { + vTaskDelay(portMAX_DELAY); + } else { + vTaskDelay((portTickType)MS2TICKS(time_ms)); + } +} +#else +#error "PIOS_Thread_Sleep requires INCLUDE_vTaskDelay to be defined 1" +#endif /* (INCLUDE_vTaskDelay == 1) */ + +#if (INCLUDE_vTaskDelayUntil == 1) +/** + * + * @brief Suspends execution of current thread for a regular interval. + * + * @param[in] previous_ms pointer to system time of last execution, + * must have been initialized with PIOS_Thread_Systime() on first invocation + * @param[in] increment_ms time of regular interval in milliseconds + * + */ +void PIOS_Thread_Sleep_Until(uint32_t *previous_ms, uint32_t increment_ms) +{ + portTickType temp = MS2TICKS(*previous_ms); + + vTaskDelayUntil(&temp, (portTickType)MS2TICKS(increment_ms)); + *previous_ms = TICKS2MS(temp); +} +#else +#error "PIOS_Thread_Sleep requires INCLUDE_vTaskDelayUntil to be defined 1" +#endif /* (INCLUDE_vTaskDelayUntil == 1) */ + +/** + * + * @brief Returns stack usage of a thread. + * + * @param[in] threadp pointer to instance of @p struct pios_thread + * + * @return stack usage in bytes + * + */ +uint32_t PIOS_Thread_Get_Stack_Usage(struct pios_thread *threadp) +{ +#if (INCLUDE_uxTaskGetStackHighWaterMark == 1) + /* @note: This will fail when FreeRTOS TCB structure changes. */ + return uxTaskGetStackHighWaterMark((xTaskHandle)threadp->task_handle) * 4; + +#else + return 1024; + +#endif /* (INCLUDE_uxTaskGetStackHighWaterMark == 1) */ +} + +/** + * + * @brief Returns runtime of a thread. + * + * @param[in] threadp pointer to instance of @p struct pios_thread + * + * @return runtime in milliseconds + * + */ +uint32_t PIOS_Thread_Get_Runtime(struct pios_thread *threadp) +{ +#if (INCLUDE_uxTaskGetRunTime == 1) + return uxTaskGetRunTime((xTaskHandle)threadp->task_handle); + +#else + (void)threadp; + return 0; + +#endif /* (INCLUDE_uxTaskGetRunTime == 1) */ +} + +/** + * + * @brief Suspends execution of all threads. + * + */ +void PIOS_Thread_Scheduler_Suspend(void) +{ + vTaskSuspendAll(); +} + +/** + * + * @brief Resumes execution of all threads. + * + */ +void PIOS_Thread_Scheduler_Resume(void) +{ + xTaskResumeAll(); +} + +#elif defined(PIOS_INCLUDE_CHIBIOS) + +#define ST2MS(n) (((((n) - 1UL) * 1000UL) / CH_FREQUENCY) + 1UL) + +/** + * Compute size that is at rounded up to the nearest + * multiple of 8 + */ +static uint32_t ceil_size(uint32_t size) +{ + const uint32_t a = sizeof(stkalign_t); + + size = size + (a - size % a); + return size; +} +/** + * ChibiOS stack expects alignment (both start and end) + * to 8 byte boundaries. This makes sure to allocate enough + * memory and return an address that has the requested size + * or more with these constraints. + */ +static uint8_t *align8_alloc(uint32_t size) +{ + // round size up to at nearest multiple of 8 + 4 bytes to guarantee + // sufficient size within. This is because PIOS_malloc only guarantees + // uintptr_t alignment which is 4 bytes. + size = size + sizeof(uintptr_t); + uint8_t *wap = PIOS_malloc(size); + + // shift start point to nearest 8 byte boundary. + uint32_t pad = ((uint32_t)wap) % sizeof(stkalign_t); + wap = wap + pad; + + return wap; +} + +/** + * + * @brief Creates a thread. + * + * @param[in] fp pointer to thread function + * @param[in] namep pointer to thread name + * @param[in] stack_bytes stack size in bytes + * @param[in] argp pointer to argument which will be passed to thread function + * @param[in] prio thread priority + * + * @returns instance of @p struct pios_thread or NULL on failure + * + */ +struct pios_thread *PIOS_Thread_Create(void (*fp)(void *), const char *namep, size_t stack_bytes, void *argp, enum pios_thread_prio_e prio) +{ + struct pios_thread *thread = PIOS_malloc_no_dma(sizeof(struct pios_thread)); + + if (thread == NULL) { + return NULL; + } + +#ifdef SIM_POSIX + if (stack_bytes < PIOS_THREAD_STACK_SIZE_MIN) { + stack_bytes = PIOS_THREAD_STACK_SIZE_MIN; + } +#endif + + // Use special functions to ensure ChibiOS stack requirements + stack_bytes = ceil_size(stack_bytes); + uint8_t *wap = align8_alloc(stack_bytes); + if (wap == NULL) { + PIOS_free(thread); + return NULL; + } + + thread->threadp = chThdCreateStatic(wap, stack_bytes, prio, (msg_t (*)(void *))fp, argp); + if (thread->threadp == NULL) { + PIOS_free(thread); + PIOS_free(wap); + return NULL; + } + +#if CH_USE_REGISTRY + thread->threadp->p_name = namep; +#endif /* CH_USE_REGISTRY */ + + return thread; +} + +#if (CH_USE_WAITEXIT == TRUE) +/** + * + * @brief Destroys an instance of @p struct pios_thread. + * + * @param[in] threadp pointer to instance of @p struct pios_thread + * + */ +void PIOS_Thread_Delete(struct pios_thread *threadp) +{ + if (threadp == NULL) { + chThdExit(0); + } else { + chThdTerminate(threadp->threadp); + chThdWait(threadp->threadp); + } +} +#else +#error "PIOS_Thread_Delete requires CH_USE_WAITEXIT to be defined TRUE" +#endif /* (CH_USE_WAITEXIT == TRUE) */ + +/** + * + * @brief Returns the current system time. + * + * @returns current system time + * + */ +uint32_t PIOS_Thread_Systime(void) +{ + return (uint32_t)ST2MS(chTimeNow()); +} + +/** + * + * @brief Suspends execution of current thread at least for specified time. + * + * @param[in] time_ms time in milliseconds to suspend thread execution + * + */ +void PIOS_Thread_Sleep(uint32_t time_ms) +{ + if (time_ms == PIOS_THREAD_TIMEOUT_MAX) { + chThdSleep(TIME_INFINITE); + } else { + chThdSleep(MS2ST(time_ms)); + } +} + +/** + * + * @brief Suspends execution of current thread for a regular interval. + * + * @param[in] previous_ms pointer to system time of last execution, + * must have been initialized with PIOS_Thread_Systime() on first invocation + * @param[in] increment_ms time of regular interval in milliseconds + * + */ +void PIOS_Thread_Sleep_Until(uint32_t *previous_ms, uint32_t increment_ms) +{ + systime_t future = MS2ST(*previous_ms) + MS2ST(increment_ms); + + chSysLock(); + systime_t now = chTimeNow(); + int mustDelay = + now < MS2ST(*previous_ms) ? + (now < future && future < MS2ST(*previous_ms)) : + (now < future || future < MS2ST(*previous_ms)); + if (mustDelay) { + chThdSleepS(future - now); + } + chSysUnlock(); + *previous_ms = ST2MS(future); +} + +/** + * + * @brief Returns stack usage of a thread. + * + * @param[in] threadp pointer to instance of @p struct pios_thread + * + * @return stack usage in bytes + */ +uint32_t PIOS_Thread_Get_Stack_Usage(struct pios_thread *threadp) +{ +#if CH_DBG_FILL_THREADS + uint32_t *stack = (uint32_t *)((size_t)threadp->threadp + sizeof(*threadp->threadp)); + uint32_t *stklimit = stack; + while (*stack == + ((CH_STACK_FILL_VALUE << 24) | + (CH_STACK_FILL_VALUE << 16) | + (CH_STACK_FILL_VALUE << 8) | + (CH_STACK_FILL_VALUE << 0))) { + ++stack; + } + return (stack - stklimit) * 4; + +#else + return 0; + +#endif /* CH_DBG_FILL_THREADS */ +} + +/** + * + * @brief Returns runtime of a thread. + * + * @param[in] threadp pointer to instance of @p struct pios_thread + * + * @return runtime in milliseconds + * + */ +uint32_t PIOS_Thread_Get_Runtime(struct pios_thread *threadp) +{ + chSysLock(); + + uint32_t result = threadp->threadp->ticks_total; + threadp->threadp->ticks_total = 0; + + chSysUnlock(); + + return result; +} + +/** + * + * @brief Suspends execution of all threads. + * + */ +void PIOS_Thread_Scheduler_Suspend(void) +{ + chSysLock(); +} + +/** + * + * @brief Resumes execution of all threads. + * + */ +void PIOS_Thread_Scheduler_Resume(void) +{ + chSysUnlock(); +} + +#endif /* defined(PIOS_INCLUDE_CHIBIOS) */ diff --git a/flight/pios/common/pios_wavplay.c b/flight/pios/common/pios_wavplay.c index 564e7b859..c5352b99d 100644 --- a/flight/pios/common/pios_wavplay.c +++ b/flight/pios/common/pios_wavplay.c @@ -77,12 +77,12 @@ typedef enum { Unvalid_RIFF_ID, Unvalid_WAVE_Format, Unvalid_FormatChunk_ID, - Unsupporetd_FormatTag, - Unsupporetd_Number_Of_Channel, - Unsupporetd_Sample_Rate, - Unsupporetd_Bits_Per_Sample, + Unsupported_FormatTag, + Unsupported_Number_Of_Channel, + Unsupported_Sample_Rate, + Unsupported_Bits_Per_Sample, Unvalid_DataChunk_ID, - Unsupporetd_ExtraFormatBytes, + Unsupported_ExtraFormatBytes, Unvalid_FactChunk_ID } ErrorCode; @@ -256,13 +256,13 @@ static ErrorCode WavePlayer_WaveParsing(uint8_t *DirName, uint8_t *FileName, uin /* Read the audio format, must be 0x01 (PCM) -------------------------------*/ WAVE_Format.FormatTag = ReadUnit(buffer1, 20, 2, LittleEndian); if (WAVE_Format.FormatTag != WAVE_FORMAT_PCM) { - return Unsupporetd_FormatTag; + return Unsupported_FormatTag; } /* Read the number of channels, must be 0x01 (Mono) ------------------------*/ WAVE_Format.NumChannels = ReadUnit(buffer1, 22, 2, LittleEndian); if (WAVE_Format.NumChannels != CHANNEL_MONO) { - return Unsupporetd_Number_Of_Channel; + return Unsupported_Number_Of_Channel; } /* Read the Sample Rate ----------------------------------------------------*/ @@ -282,7 +282,7 @@ static ErrorCode WavePlayer_WaveParsing(uint8_t *DirName, uint8_t *FileName, uin TIM6ARRValue = (PIOS_PERIPHERAL_APB1_CLOCK) / 44100; break; /* 44.1KHz = 24MHz / 544 */ default: - return Unsupporetd_Sample_Rate; + return Unsupported_Sample_Rate; } /* Read the Byte Rate ------------------------------------------------------*/ @@ -294,7 +294,7 @@ static ErrorCode WavePlayer_WaveParsing(uint8_t *DirName, uint8_t *FileName, uin /* Read the number of bits per sample --------------------------------------*/ WAVE_Format.BitsPerSample = ReadUnit(buffer1, 34, 2, LittleEndian); if (WAVE_Format.BitsPerSample != BITS_PER_SAMPLE_8) { - return Unsupporetd_Bits_Per_Sample; + return Unsupported_Bits_Per_Sample; } SpeechDataOffset = 36; /* If there is Extra format bytes, these bytes will be defined in "Fact Chunk" */ @@ -302,7 +302,7 @@ static ErrorCode WavePlayer_WaveParsing(uint8_t *DirName, uint8_t *FileName, uin /* Read th Extra format bytes, must be 0x00 ------------------------------*/ Temp = ReadUnit(buffer1, 36, 2, LittleEndian); if (Temp != 0x00) { - return Unsupporetd_ExtraFormatBytes; + return Unsupported_ExtraFormatBytes; } /* Read the Fact chunk, must be 'fact' -----------------------------------*/ Temp = ReadUnit(buffer1, 38, 4, BigEndian); diff --git a/flight/modules/Autotune/inc/autotune.h b/flight/pios/inc/pios_board_init.h similarity index 69% rename from flight/modules/Autotune/inc/autotune.h rename to flight/pios/inc/pios_board_init.h index 64c556a8e..27b26a23a 100644 --- a/flight/modules/Autotune/inc/autotune.h +++ b/flight/pios/inc/pios_board_init.h @@ -1,14 +1,10 @@ /** ****************************************************************************** - * @addtogroup OpenPilotModules OpenPilot Modules - * @{ - * @addtogroup Attitude Attitude Module - * @{ - * - * @file attitude.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2011. - * @brief Acquires sensor data and fuses it into attitude estimate for CC * + * @file pios_board_init.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @brief board initialization prototypes + * -- * @see The GNU Public License (GPL) Version 3 * *****************************************************************************/ @@ -27,11 +23,9 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef ATTITUDE_H -#define ATTITUDE_H +#ifndef PIOS_BOARD_INIT_H +#define PIOS_BOARD_INIT_H -#include "openpilot.h" +extern void PIOS_Board_Init(void); -int32_t AttitudeInitialize(void); - -#endif // ATTITUDE_H +#endif /* PIOS_BOARD_INIT_H */ diff --git a/flight/pios/inc/pios_com.h b/flight/pios/inc/pios_com.h index b2591e4f0..53b2ed079 100644 --- a/flight/pios/inc/pios_com.h +++ b/flight/pios/inc/pios_com.h @@ -37,17 +37,19 @@ typedef uint16_t (*pios_com_callback)(uint32_t context, uint8_t *buf, uint16_t buf_len, uint16_t *headroom, bool *task_woken); typedef void (*pios_com_callback_ctrl_line)(uint32_t context, uint32_t mask, uint32_t state); +typedef void (*pios_com_callback_baud_rate)(uint32_t context, uint32_t baud); struct pios_com_driver { - void (*init)(uint32_t id); - void (*set_baud)(uint32_t id, uint32_t baud); - void (*set_ctrl_line)(uint32_t id, uint32_t mask, uint32_t state); - void (*tx_start)(uint32_t id, uint16_t tx_bytes_avail); - void (*rx_start)(uint32_t id, uint16_t rx_bytes_avail); - void (*bind_rx_cb)(uint32_t id, pios_com_callback rx_in_cb, uint32_t context); - void (*bind_tx_cb)(uint32_t id, pios_com_callback tx_out_cb, uint32_t context); - void (*bind_ctrl_line_cb)(uint32_t id, pios_com_callback_ctrl_line ctrl_line_cb, uint32_t context); - bool (*available)(uint32_t id); + void (*init)(uint32_t id); + void (*set_baud)(uint32_t id, uint32_t baud); + void (*set_ctrl_line)(uint32_t id, uint32_t mask, uint32_t state); + void (*tx_start)(uint32_t id, uint16_t tx_bytes_avail); + void (*rx_start)(uint32_t id, uint16_t rx_bytes_avail); + void (*bind_rx_cb)(uint32_t id, pios_com_callback rx_in_cb, uint32_t context); + void (*bind_tx_cb)(uint32_t id, pios_com_callback tx_out_cb, uint32_t context); + void (*bind_ctrl_line_cb)(uint32_t id, pios_com_callback_ctrl_line ctrl_line_cb, uint32_t context); + void (*bind_baud_rate_cb)(uint32_t id, pios_com_callback_baud_rate baud_rate_cb, uint32_t context); + uint32_t (*available)(uint32_t id); }; /* Control line definitions */ @@ -59,6 +61,7 @@ extern int32_t PIOS_COM_Init(uint32_t *com_id, const struct pios_com_driver *dri extern int32_t PIOS_COM_ChangeBaud(uint32_t com_id, uint32_t baud); extern int32_t PIOS_COM_SetCtrlLine(uint32_t com_id, uint32_t mask, uint32_t state); extern int32_t PIOS_COM_RegisterCtrlLineCallback(uint32_t usart_id, pios_com_callback_ctrl_line ctrl_line_cb, uint32_t context); +extern int32_t PIOS_COM_RegisterBaudRateCallback(uint32_t usart_id, pios_com_callback_baud_rate baud_rate_cb, uint32_t context); extern int32_t PIOS_COM_SendCharNonBlocking(uint32_t com_id, char c); extern int32_t PIOS_COM_SendChar(uint32_t com_id, char c); extern int32_t PIOS_COM_SendBufferNonBlocking(uint32_t com_id, const uint8_t *buffer, uint16_t len); @@ -68,7 +71,12 @@ extern int32_t PIOS_COM_SendString(uint32_t com_id, const char *str); extern int32_t PIOS_COM_SendFormattedStringNonBlocking(uint32_t com_id, const char *format, ...); extern int32_t PIOS_COM_SendFormattedString(uint32_t com_id, const char *format, ...); extern uint16_t PIOS_COM_ReceiveBuffer(uint32_t com_id, uint8_t *buf, uint16_t buf_len, uint32_t timeout_ms); -extern bool PIOS_COM_Available(uint32_t com_id); +extern uint32_t PIOS_COM_Available(uint32_t com_id); + +#define COM_AVAILABLE_NONE (0) +#define COM_AVAILABLE_RX (1 << 0) +#define COM_AVAILABLE_TX (1 << 1) +#define COM_AVAILABLE_RXTX (COM_AVAILABLE_RX | COM_AVAILABLE_TX) #endif /* PIOS_COM_H */ diff --git a/flight/pios/inc/pios_com_priv.h b/flight/pios/inc/pios_com_priv.h index 565dae3ef..b18128563 100644 --- a/flight/pios/inc/pios_com_priv.h +++ b/flight/pios/inc/pios_com_priv.h @@ -31,7 +31,6 @@ #ifndef PIOS_COM_PRIV_H #define PIOS_COM_PRIV_H -extern int32_t PIOS_COM_Init(uint32_t *com_id, const struct pios_com_driver *driver, uint32_t lower_id, uint8_t *rx_buffer, uint16_t rx_buffer_len, uint8_t *tx_buffer, uint16_t tx_buffer_len); #endif /* PIOS_COM_PRIV_H */ diff --git a/flight/pios/inc/pios_delay.h b/flight/pios/inc/pios_delay.h index 4a2da6347..63546d75d 100644 --- a/flight/pios/inc/pios_delay.h +++ b/flight/pios/inc/pios_delay.h @@ -7,7 +7,8 @@ * @{ * * @file pios_settings.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @brief Settings functions header * @see The GNU Public License (GPL) Version 3 * @@ -39,6 +40,7 @@ extern uint32_t PIOS_DELAY_GetuS(); extern uint32_t PIOS_DELAY_GetuSSince(uint32_t t); extern uint32_t PIOS_DELAY_GetRaw(); extern uint32_t PIOS_DELAY_DiffuS(uint32_t raw); +extern uint32_t PIOS_DELAY_DiffuS2(uint32_t raw, uint32_t later); #endif /* PIOS_DELAY_H */ diff --git a/flight/pios/inc/pios_exbus.h b/flight/pios/inc/pios_exbus.h new file mode 100644 index 000000000..0e2cbf88c --- /dev/null +++ b/flight/pios/inc/pios_exbus.h @@ -0,0 +1,38 @@ +/** + ****************************************************************************** + * + * @file pios_exbus.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * Tau Labs, http://taulabs.org, Copyright (C) 2013 + * @brief Futaba S.Bus functions header. + * @see The GNU Public License (GPL) Version 3 + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PIOS_EXBUS_H +#define PIOS_EXBUS_H + +/* Global Types */ + +/* Public Functions */ + +#endif /* PIOS_EXBUS_H */ + +/** + * @} + * @} + */ diff --git a/flight/pios/inc/pios_exbus_priv.h b/flight/pios/inc/pios_exbus_priv.h new file mode 100644 index 000000000..ace74e615 --- /dev/null +++ b/flight/pios/inc/pios_exbus_priv.h @@ -0,0 +1,47 @@ +/** + ****************************************************************************** + * @file pios_exbus_priv.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * Tau Labs, http://taulabs.org, Copyright (C) 2013 + * @addtogroup PIOS PIOS Core hardware abstraction layer + * @{ + * @addtogroup PIOS_EXBUS Jeti EX Bus receiver functions + * @{ + * @brief Jeti EX Bus receiver functions + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PIOS_EXBUS_PRIV_H +#define PIOS_EXBUS_PRIV_H + +#include +#include + + +/* EXBUS receiver instance configuration */ +extern const struct pios_rcvr_driver pios_exbus_rcvr_driver; + +extern int32_t PIOS_EXBUS_Init(uint32_t *exbus_id, + const struct pios_com_driver *driver, + uint32_t lower_id); + +#endif /* PIOS_EXBUS_PRIV_H */ + +/** + * @} + * @} + */ diff --git a/flight/pios/inc/pios_exti.h b/flight/pios/inc/pios_exti.h index 529e8ee2c..081271b66 100644 --- a/flight/pios/inc/pios_exti.h +++ b/flight/pios/inc/pios_exti.h @@ -35,18 +35,23 @@ #include +typedef bool (*pios_exti_vector_t)(void); + struct pios_exti_cfg { - bool (*vector)(void); + pios_exti_vector_t vector; uint32_t line; /* use EXTI_LineN macros */ - struct stm32_gpio pin; - struct stm32_irq irq; - struct stm32_exti exti; + struct stm32_gpio pin; + struct stm32_irq irq; + struct stm32_exti exti; }; /* must be added to any pios_exti_cfg definition for it to be valid */ -#define __exti_config __attribute__((section("_exti"))) +// #define __exti_config __attribute__((section("_exti"))) + +#define __exti_config extern int32_t PIOS_EXTI_Init(const struct pios_exti_cfg *cfg); +extern int32_t PIOS_EXTI_DeInit(const struct pios_exti_cfg *cfg); #endif /* PIOS_EXTI_H */ diff --git a/flight/pios/inc/pios_hmc5x83.h b/flight/pios/inc/pios_hmc5x83.h index 490168017..02206ed66 100644 --- a/flight/pios/inc/pios_hmc5x83.h +++ b/flight/pios/inc/pios_hmc5x83.h @@ -95,6 +95,9 @@ #define PIOS_HMC5x83_Sensitivity_5_6Ga 330 // LSB/Ga #define PIOS_HMC5x83_Sensitivity_8_1Ga 230 // LSB/Ga --> NOT RECOMMENDED +/* Status Register */ +#define PIOS_HMC5x83_DATAOUT_STATUS_RDY 0x01 + typedef uintptr_t pios_hmc5x83_dev_t; struct pios_hmc5x83_io_driver { @@ -137,7 +140,7 @@ struct pios_hmc5x83_cfg { /* Public Functions */ extern pios_hmc5x83_dev_t PIOS_HMC5x83_Init(const struct pios_hmc5x83_cfg *cfg, uint32_t port_id, uint8_t device_num); -extern void PIOS_HMC5x83_Register(pios_hmc5x83_dev_t handler); +extern void PIOS_HMC5x83_Register(pios_hmc5x83_dev_t handler, PIOS_SENSORS_TYPE sensortype); extern bool PIOS_HMC5x83_NewDataAvailable(pios_hmc5x83_dev_t handler); extern int32_t PIOS_HMC5x83_ReadMag(pios_hmc5x83_dev_t handler, int16_t out[3]); diff --git a/flight/pios/inc/pios_hott.h b/flight/pios/inc/pios_hott.h new file mode 100644 index 000000000..e63fcceec --- /dev/null +++ b/flight/pios/inc/pios_hott.h @@ -0,0 +1,36 @@ +/** + ****************************************************************************** + * @file pios_hott.h + * @author The LibrePilot Project, http://www.librepilot.org, Copyright (C) 2015 + * Tau Labs, http://taulabs.org, Copyright (C) 2013 + * @addtogroup PIOS PIOS Core hardware abstraction layer + * @{ + * @addtogroup PIOS_HOTT Graupner HoTT receiver functions + * @{ + * @brief Graupner HoTT receiver functions for SUMD/H + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PIOS_HOTT_H +#define PIOS_HOTT_H + +#endif /* PIOS_HOTT_H */ + +/** + * @} + * @} + */ diff --git a/flight/pios/inc/pios_hott_priv.h b/flight/pios/inc/pios_hott_priv.h new file mode 100644 index 000000000..b31bb3b9f --- /dev/null +++ b/flight/pios/inc/pios_hott_priv.h @@ -0,0 +1,53 @@ +/** + ****************************************************************************** + * @file pios_hott_private.h + * @author The LibrePilot Project, http://www.librepilot.org, Copyright (C) 2015 + * @author Tau Labs, http://taulabs.org, Copyright (C) 2013 + * @addtogroup PIOS PIOS Core hardware abstraction layer + * @{ + * @addtogroup PIOS_HOTT Graupner HoTT receiver functions + * @{ + * @brief Graupner HoTT receiver functions for SUMD/H + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PIOS_HOTT_PRIV_H +#define PIOS_HOTT_PRIV_H + +#include +#include + +/* HOTT protocol variations */ +enum pios_hott_proto { + PIOS_HOTT_PROTO_SUMD, + PIOS_HOTT_PROTO_SUMH, +}; + +/* HOTT receiver instance configuration */ +extern const struct pios_rcvr_driver pios_hott_rcvr_driver; + +extern int32_t PIOS_HOTT_Init(uint32_t *hott_id, + const struct pios_com_driver *driver, + uint32_t lower_id, + enum pios_hott_proto proto); + +#endif /* PIOS_HOTT_PRIV_H */ + +/** + * @} + * @} + */ diff --git a/flight/pios/inc/pios_i2c.h b/flight/pios/inc/pios_i2c.h index d3c7ceb67..0c4c71431 100644 --- a/flight/pios/inc/pios_i2c.h +++ b/flight/pios/inc/pios_i2c.h @@ -63,6 +63,16 @@ struct pios_i2c_fault_history { uint8_t state[I2C_LOG_DEPTH]; }; +enum pios_i2c_error_count { + PIOS_I2C_BAD_EVENT_COUNTER, + PIOS_I2C_FSM_FAULT_COUNT, + PIOS_I2C_ERROR_INTERRUPT_COUNTER, + PIOS_I2C_NACK_COUNTER, + PIOS_I2C_TIMEOUT_COUNTER, + + PIOS_I2C_ERROR_COUNT_NUMELEM, +}; + /* Public Functions */ extern int32_t PIOS_I2C_Transfer(uint32_t i2c_id, const struct pios_i2c_txn txn_list[], uint32_t num_txns); extern int32_t PIOS_I2C_Transfer_Callback(uint32_t i2c_id, const struct pios_i2c_txn txn_list[], uint32_t num_txns, void *callback); diff --git a/flight/pios/inc/pios_ibus.h b/flight/pios/inc/pios_ibus.h new file mode 100644 index 000000000..7c27d26d2 --- /dev/null +++ b/flight/pios/inc/pios_ibus.h @@ -0,0 +1,38 @@ +/** + ****************************************************************************** + * + * @file pios_ibus.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * dRonin, http://dRonin.org/, Copyright (C) 2016 + * @brief FlySky IBus functions header. + * @see The GNU Public License (GPL) Version 3 + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PIOS_IBUS_H +#define PIOS_IBUS_H + +/* Global Types */ + +/* Public Functions */ + +#endif /* PIOS_IBUS_H */ + +/** + * @} + * @} + */ diff --git a/flight/pios/inc/pios_ibus_priv.h b/flight/pios/inc/pios_ibus_priv.h new file mode 100644 index 000000000..d0a9146f6 --- /dev/null +++ b/flight/pios/inc/pios_ibus_priv.h @@ -0,0 +1,51 @@ +/** + ****************************************************************************** + * @file pios_ibus_priv.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * dRonin, http://dRonin.org/, Copyright (C) 2016 + * @addtogroup PIOS PIOS Core hardware abstraction layer + * @{ + * @addtogroup PIOS_IBus IBus receiver functions + * @{ + * @brief Receives and decodes IBus protocol receiver packets + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Additional note on redistribution: The copyright and license notices above + * must be maintained in each individual source file that is a derivative work + * of this source file; otherwise redistribution is prohibited. + */ + + +#ifndef PIOS_IBUS_PRIV_H +#define PIOS_IBUS_PRIV_H + +#include +#include + +/* IBUS receiver instance configuration */ +extern const struct pios_rcvr_driver pios_ibus_rcvr_driver; + +extern int32_t PIOS_IBUS_Init(uint32_t *ibus_id, + const struct pios_com_driver *driver, + uint32_t lower_id); + +#endif // PIOS_IBUS_PRIV_H + +/** + * @} + * @} + */ diff --git a/flight/pios/inc/pios_initcall.h b/flight/pios/inc/pios_initcall.h index 55b3e15f9..f98b5b628 100644 --- a/flight/pios/inc/pios_initcall.h +++ b/flight/pios/inc/pios_initcall.h @@ -7,7 +7,8 @@ * @{ * * @file pios_initcall.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2011. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2015 * @brief Initcall header * @see The GNU Public License (GPL) Version 3 * @@ -55,6 +56,7 @@ extern volatile int initTaskDone; extern void InitModules(); extern void StartModules(); +extern int32_t SystemModInitialize(void); #define MODULE_INITCALL(ifn, sfn) @@ -100,10 +102,12 @@ extern void StartModules(); initTaskDone = 1; \ } -#define MODULE_TASKCREATE_ALL \ +#define MODULE_TASKCREATE_ALL \ { for (initmodule_t *fn = __module_initcall_start; fn < __module_initcall_end; fn++) { \ - if (fn->fn_tinit) { \ - (fn->fn_tinit)(); } \ + if (fn->fn_tinit) { \ + (fn->fn_tinit)(); \ + PIOS_WDG_Clear(); \ + } \ } \ } diff --git a/flight/pios/inc/pios_instrumentation_helper.h b/flight/pios/inc/pios_instrumentation_helper.h index 819a88aaa..f7e0df94c 100644 --- a/flight/pios/inc/pios_instrumentation_helper.h +++ b/flight/pios/inc/pios_instrumentation_helper.h @@ -2,7 +2,8 @@ ****************************************************************************** * * @file pios_instrumentation_helper.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014. + * @author The LibrePilot Project, http://www.librepilot.org, Copyright (C) 2016 + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014. * @brief Macros to easily add optional performance monitoring to a module * * @see The GNU Public License (GPL) Version 3 @@ -51,10 +52,16 @@ * The following code needs to be added to a function called at module initialization. * the second parameter is a unique counter Id. * A good pracice is to use the upper half word as module id and lower as counter id - *
PERF_INIT_COUNTER(counterUpd, 0xA7710001);
- * PERF_INIT_COUNTER(counterAtt, 0xA7710002);
- * PERF_INIT_COUNTER(counterPeriod, 0xA7710003);
- * PERF_INIT_COUNTER(counterAccelSamples, 0xA7710004);
+ * Optionally three strings containing Module Name, Counter description and unit of measure can be passed. + * Those strings will be used in future to automatically extract the list of counters from code to managed + * by GCS or some other custom tool. + * + * PERF_INIT_COUNTER(counterVariable, id, "MODULE NAME","COUNTER DESCRIPTION","UNIT OF MEASURE"); + * + *
PERF_INIT_COUNTER(counterUpd, 0xA7710001, "ATTITUDE", "Sensor update execution time", "us");
+ * PERF_INIT_COUNTER(counterAtt, 0xA7710002, "ATTITUDE", "Attitude estimation execution time", "us");
+ * PERF_INIT_COUNTER(counterPeriod, 0xA7710003, "ATTITUDE", "Sensor update period", "us");
+ * PERF_INIT_COUNTER(counterAccelSamples, 0xA7710004, "ATTITUDE", "Samples for each sensor cycle", "count");
* * At this point you can start using the counters as in the following samples * @@ -84,31 +91,31 @@ /** * include the following macro together with modules variable declaration */ -#define PERF_DEFINE_COUNTER(x) pios_counter_t x +#define PERF_DEFINE_COUNTER(x) static pios_counter_t x /** * this mast be called at some module init code */ -#define PERF_INIT_COUNTER(x, id) x = PIOS_Instrumentation_CreateCounter(id) +#define PERF_INIT_COUNTER(x, id, ...) x = PIOS_Instrumentation_CreateCounter(id) /** * those are the monitoring macros */ -#define PERF_TIMED_SECTION_START(x) PIOS_Instrumentation_TimeStart(x) -#define PERF_TIMED_SECTION_END(x) PIOS_Instrumentation_TimeEnd(x) -#define PERF_MEASURE_PERIOD(x) PIOS_Instrumentation_TrackPeriod(x) -#define PERF_TRACK_VALUE(x, y) PIOS_Instrumentation_updateCounter(x, y) -#define PERF_INCREMENT_VALUE(x) PIOS_Instrumentation_incrementCounter(x, 1) -#define PERF_DECREMENT_VALUE(x) PIOS_Instrumentation_incrementCounter(x, -1) +#define PERF_TIMED_SECTION_START(x) PIOS_Instrumentation_TimeStart(x) +#define PERF_TIMED_SECTION_END(x) PIOS_Instrumentation_TimeEnd(x) +#define PERF_MEASURE_PERIOD(x) PIOS_Instrumentation_TrackPeriod(x) +#define PERF_TRACK_VALUE(x, y) PIOS_Instrumentation_updateCounter(x, y) +#define PERF_INCREMENT_VALUE(x) PIOS_Instrumentation_incrementCounter(x, 1) +#define PERF_DECREMENT_VALUE(x) PIOS_Instrumentation_incrementCounter(x, -1) #else #define PERF_DEFINE_COUNTER(x) -#define PERF_INIT_COUNTER(x, id) +#define PERF_INIT_COUNTER(x, id, ...) #define PERF_TIMED_SECTION_START(x) #define PERF_TIMED_SECTION_END(x) #define PERF_MEASURE_PERIOD(x) -#define PERF_TRACK_VALUE(x, y) +#define PERF_TRACK_VALUE(x, y) (void)y #define PERF_INCREMENT_VALUE(x) #define PERF_DECREMENT_VALUE(x) #endif /* PIOS_INCLUDE_INSTRUMENTATION */ diff --git a/flight/pios/inc/pios_notify.h b/flight/pios/inc/pios_notify.h index 12daefdc2..3ee6a3dec 100644 --- a/flight/pios/inc/pios_notify.h +++ b/flight/pios/inc/pios_notify.h @@ -84,8 +84,9 @@ pios_notify_notification PIOS_NOTIFY_GetActiveNotification(bool clear); * are repeated only once if repeat = -1 * @param sequence Sequence to be played * @param priority Priority of the sequence being played + * @return true if sequence is enqueued, false otherwise */ -void PIOS_NOTIFICATION_Default_Ext_Led_Play(const LedSequence_t *sequence, pios_notify_priority priority); +bool PIOS_NOTIFICATION_Default_Ext_Led_Play(const LedSequence_t *sequence, pios_notify_priority priority); /* * Play a sequence on an external rgb led. Sequences with priority higher than NOTIFY_PRIORITY_LOW diff --git a/flight/pios/inc/pios_openlrs.h b/flight/pios/inc/pios_openlrs.h new file mode 100644 index 000000000..865e81ccf --- /dev/null +++ b/flight/pios/inc/pios_openlrs.h @@ -0,0 +1,54 @@ +/** + ****************************************************************************** + * @addtogroup PIOS PIOS Core hardware abstraction layer + * @{ + * @addtogroup PIOS_RFM22B Radio Functions + * @brief PIOS OpenLRS interface for for the RFM22B radio + * @{ + * + * @file pios_openlrs.h + * @author Tau Labs, http://taulabs.org, Copyright (C) 2015 + * @author dRonin, http://dronin.org Copyright (C) 2015 + * @brief Implements an OpenLRS driver for the RFM22B + * @see The GNU Public License (GPL) Version 3 + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PIOS_OPENLRS_H +#define PIOS_OPENLRS_H + +/* Global Types */ +struct pios_openlrs_cfg { + const struct pios_spi_cfg *spi_cfg; /* Pointer to SPI interface configuration */ + const struct pios_exti_cfg *exti_cfg; /* Pointer to the EXTI configuration */ + enum gpio_direction gpio_direction; /* Definition comes from pios_rfm22b.h */ +}; + +typedef void (*PIOS_OpenLRS_PPMReceivedCallback)(const int16_t *channels); + +extern int32_t PIOS_OpenLRS_Init(uint32_t *openlrs_id, uint32_t spi_id, + uint32_t slave_num, const struct pios_openlrs_cfg *cfg); + +extern void PIOS_OpenLRS_RegisterRcvr(uint32_t openlrs_id, uint32_t rfm22b_rcvr_id); +extern void PIOS_OpenLRS_RegisterPPMCallback(uint32_t openlrs_id, PIOS_OpenLRS_PPMReceivedCallback callback); +extern uint8_t PIOS_OpenLRS_RSSI_Get(void); +#endif /* PIOS_OPENLRS_H */ +/** + * @} + * @} + */ diff --git a/flight/pios/inc/pios_openlrs_priv.h b/flight/pios/inc/pios_openlrs_priv.h new file mode 100644 index 000000000..c4ec33a26 --- /dev/null +++ b/flight/pios/inc/pios_openlrs_priv.h @@ -0,0 +1,208 @@ +/** + ****************************************************************************** + * @addtogroup PIOS PIOS Core hardware abstraction layer + * @{ + * @addtogroup PIOS_RFM22B Radio Functions + * @brief PIOS OpenLRS interface for for the RFM22B radio + * @{ + * + * @file pios_openlrs_priv.h + * @author Tau Labs, http://taulabs.org, Copyright (C) 2015 + * @author dRonin, http://dronin.org Copyright (C) 2015 + * @brief Implements an OpenLRS driver for the RFM22B + * @see The GNU Public License (GPL) Version 3 + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PIOS_OPENLRS_PRIV_H +#define PIOS_OPENLRS_PRIV_H + +#include "pios_openlrs.h" + +#define OPENLRSNG_VERSION 0x0382 + +#define MAXHOPS 24 +#define OPENLRS_PPM_NUM_CHANNELS 16 + +// Factory setting values, modify via the CLI + +// ####### RADIOLINK RF POWER (beacon is always 100/13/1.3mW) ####### +// 7 == 100mW (or 1000mW with M3) +// 6 == 50mW (use this when using booster amp), (800mW with M3) +// 5 == 25mW +// 4 == 13mW +// 3 == 6mW +// 2 == 3mW +// 1 == 1.6mW +// 0 == 1.3mW +#define DEFAULT_RF_POWER 7 + +#define DEFAULT_CHANNEL_SPACING 5 // 50kHz +#define DEFAULT_HOPLIST 22, 10, 19, 34, 49, 41 +#define DEFAULT_RF_MAGIC 0xDEADFEED + +// 0 -- 4800bps, best range +// 1 -- 9600bps, medium range +// 2 -- 19200bps, medium range +#define DEFAULT_DATARATE 2 + +// BIND_DATA flag masks +#define TELEMETRY_OFF 0x00 +#define TELEMETRY_PASSTHRU 0x08 +#define TELEMETRY_FRSKY 0x10 // covers smartport if used with & +#define TELEMETRY_SMARTPORT 0x18 +#define TELEMETRY_MASK 0x18 +#define CHANNELS_4_4 0x01 +#define CHANNELS_8 0x02 +#define CHANNELS_8_4 0x03 +#define CHANNELS_12 0x04 +#define CHANNELS_12_4 0x05 +#define CHANNELS_16 0x06 +#define DIVERSITY_ENABLED 0x80 +#define DEFAULT_FLAGS (CHANNELS_8 | TELEMETRY_PASSTHRU) + +// helper macro for European PMR channels +#define EU_PMR_CH(x) (445993750L + 12500L * (x)) // valid for ch1-ch8 + +// helper macro for US FRS channels 1-7 +#define US_FRS_CH(x) (462537500L + 25000L * (x)) // valid for ch1-ch7 + +#define DEFAULT_BEACON_FREQUENCY 0 // disable beacon +#define DEFAULT_BEACON_DEADTIME 30 // time to wait until go into beacon mode (30s) +#define DEFAULT_BEACON_INTERVAL 10 // interval between beacon transmits (10s) + +#define BINDING_POWER 0x06 // not lowest since may result fail with RFM23BP + +#define TELEMETRY_PACKETSIZE 9 + +#define BIND_MAGIC (0xDEC1BE15 + (OPENLRSNG_VERSION & 0xfff0)) +#define BINDING_VERSION ((OPENLRSNG_VERSION & 0x0ff0) >> 4) + +// HW frequency limits +#define MIN_RFM_FREQUENCY_868 848000000 +#define MAX_RFM_FREQUENCY_868 888000000 +#define DEFAULT_CARRIER_FREQUENCY_868 868000000 // Hz (ch 0) +#define BINDING_FREQUENCY_868 868000000 // Hz + +#define MIN_RFM_FREQUENCY_915 895000000 +#define MAX_RFM_FREQUENCY_915 935000000 +#define DEFAULT_CARRIER_FREQUENCY_915 915000000 // Hz (ch 0) +#define BINDING_FREQUENCY_915 915000000 // Hz + +#define MIN_RFM_FREQUENCY_433 413000000 +#define MAX_RFM_FREQUENCY_433 463000000 +#define DEFAULT_CARRIER_FREQUENCY_433 435000000 // Hz (ch 0) +#define BINDING_FREQUENCY_433 435000000 // Hz + +#define RFM22_DEVICE_TYPE 0x00 // R +#define RFM22_DT_MASK 0x1F + +struct bind_data { + uint8_t version; + uint32_t serial_baudrate; + uint32_t rf_frequency; + uint32_t rf_magic; + uint8_t rf_power; + uint8_t rf_channel_spacing; + uint8_t hopchannel[MAXHOPS]; + uint8_t modem_params; + uint8_t flags; +} __attribute__((packed)); + +enum RF_MODE { + Available, Transmit, Receive, Transmitted, Received, +}; + +enum pios_openlrs_dev_magic { + PIOS_OPENLRS_DEV_MAGIC = 0x18c97ab6, +}; + +struct pios_openlrs_dev { + enum pios_openlrs_dev_magic magic; + struct pios_openlrs_cfg cfg; + + // The SPI bus information + uint32_t spi_id; + uint32_t slave_num; + + double band; + + // The task handle + struct pios_thread *taskHandle; + + // The COM callback functions. + pios_com_callback rx_in_cb; + uint32_t rx_in_context; + pios_com_callback tx_out_cb; + uint32_t tx_out_context; + + // The event queue handle + struct pios_semaphore *sema_isr; + + // The PPM buffer + int16_t ppm[OPENLRS_PPM_NUM_CHANNELS]; + + // RFM22B RCVR interface + uintptr_t openlrs_rcvr_id; + + // PPM callback. + PIOS_OpenLRS_PPMReceivedCallback ppm_callback; + + // Flag to indicate if link every acquired + bool link_acquired; + + // Active bound information data + struct bind_data bind_data; + + // Beacon settings + uint32_t beacon_frequency; + uint8_t beacon_delay; + uint8_t beacon_period; + bool beacon_armed; + + enum RF_MODE rf_mode; + uint32_t rf_channel; + + uint8_t it_status1; + uint8_t it_status2; + + uint8_t rx_buf[64]; + uint8_t tx_buf[9]; + + int8_t rssi; + + // Variables from OpenLRS for radio control + uint8_t hopcount; + uint32_t lastPacketTimeUs; + uint32_t numberOfLostPackets; + uint16_t lastAFCCvalue; + uint32_t lastRSSITimeUs; + bool willhop; + uint32_t nextBeaconTimeMs; + uint32_t linkLossTimeMs; + uint32_t failsafeDelay; + uint32_t beacon_rssi_avg; +}; + +bool PIOS_OpenLRS_EXT_Int(void); + +#endif /* PIOS_OPENLRS_PRIV_H */ +/** + * @} + * @} + */ diff --git a/ground/gcs/src/plugins/modelview/modelviewplugin.h b/flight/pios/inc/pios_openlrs_rcvr_priv.h similarity index 55% rename from ground/gcs/src/plugins/modelview/modelviewplugin.h rename to flight/pios/inc/pios_openlrs_rcvr_priv.h index 72c9760d5..2997fb1a5 100644 --- a/ground/gcs/src/plugins/modelview/modelviewplugin.h +++ b/flight/pios/inc/pios_openlrs_rcvr_priv.h @@ -1,13 +1,17 @@ /** ****************************************************************************** + * @addtogroup PIOS PIOS Core hardware abstraction layer + * @{ + * @addtogroup PIOS_RFM22b RFM22b receiver functions + * @brief Deals with the RFM22b module + * @{ + * + * @file pios_rfm22b_rcvr_priv.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2013. + * @author Tau Labs, http://taulabs.org, Copyright (C) 2014 + * @brief TauLabs Link receiver private functions + * @see The GNU Public License (GPL) Version 3 * - * @file modelviewplugin.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @addtogroup GCSPlugins GCS Plugins - * @{ - * @addtogroup ModelViewPlugin ModelView Plugin - * @{ - * @brief A gadget that displays a 3D representation of the UAV *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify @@ -25,26 +29,19 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef MODELVIEWPLUGIN_H_ -#define MODELVIEWPLUGIN_H_ +#ifndef PIOS_OPENLRS_RCVR_PRIV_H +#define PIOS_OPENLRS_RCVR_PRIV_H -#include +#include -class ModelViewGadgetFactory; +extern const struct pios_rcvr_driver pios_openlrs_rcvr_driver; -class ModelViewPlugin : public ExtensionSystem::IPlugin { - Q_OBJECT - Q_PLUGIN_METADATA(IID "Openpilot.ModelView") +extern int32_t PIOS_OpenLRS_Rcvr_Init(uint32_t *openlrs_rcvr_id, uintptr_t openlrs_id); +extern int32_t PIOS_OpenLRS_Rcvr_UpdateChannels(uint32_t openlrs_rcvr_id, int16_t *channels); -public: - ModelViewPlugin(); - ~ModelViewPlugin(); +#endif /* PIOS_OPENLRS_RCVR_PRIV_H */ - void extensionsInitialized(); - bool initialize(const QStringList & arguments, QString *errorString); - void shutdown(); -private: - ModelViewGadgetFactory *mvf; -}; - -#endif /* MODELVIEWPLUGIN_H_ */ +/** + * @} + * @} + */ diff --git a/flight/pios/inc/pios_posix.h b/flight/pios/inc/pios_posix.h index aaf3cdc95..466082cfe 100644 --- a/flight/pios/inc/pios_posix.h +++ b/flight/pios/inc/pios_posix.h @@ -29,14 +29,16 @@ #include #ifndef __cplusplus + typedef enum { FALSE = 0, TRUE = !FALSE } bool; -#endif #ifndef false #define false FALSE #define true TRUE #endif +#endif + // #define FILEINFO FILE* // #define PIOS_SERVO_NUM_OUTPUTS 8 diff --git a/flight/pios/inc/pios_rfm22b.h b/flight/pios/inc/pios_rfm22b.h index 49af876b0..16dd460b2 100644 --- a/flight/pios/inc/pios_rfm22b.h +++ b/flight/pios/inc/pios_rfm22b.h @@ -7,7 +7,8 @@ * @{ * * @file pios_rfm22b.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. * @brief RFM22B functions header. * @see The GNU Public License (GPL) Version 3 * @@ -103,11 +104,12 @@ 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, 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 ppm_mode, bool ppm_only); extern void PIOS_RFM22B_SetCoordinatorID(uint32_t rfm22b_id, uint32_t coord_id); +extern void PIOS_RFM22B_SetDeviceID(uint32_t rfm22b_id, uint32_t device_id); extern uint32_t PIOS_RFM22B_DeviceID(uint32_t rfb22b_id); extern void PIOS_RFM22B_GetStats(uint32_t rfm22b_id, struct rfm22b_stats *stats); -extern uint8_t PIOS_RFM2B_GetPairStats(uint32_t rfm22b_id, uint32_t *device_ids, int8_t *RSSIs, uint8_t max_pairs); +extern uint8_t PIOS_RFM22B_GetPairStats(uint32_t rfm22b_id, uint32_t *device_ids, int8_t *RSSIs, uint8_t max_pairs); extern bool PIOS_RFM22B_InRxWait(uint32_t rfb22b_id); extern bool PIOS_RFM22B_LinkStatus(uint32_t rfm22b_id); extern bool PIOS_RFM22B_ReceivePacket(uint32_t rfm22b_id, uint8_t *p); @@ -115,8 +117,8 @@ extern bool PIOS_RFM22B_TransmitPacket(uint32_t rfm22b_id, uint8_t *p, uint8_t l extern pios_rfm22b_int_result PIOS_RFM22B_ProcessTx(uint32_t rfm22b_id); extern pios_rfm22b_int_result PIOS_RFM22B_ProcessRx(uint32_t rfm22b_id); extern void PIOS_RFM22B_SetPPMCallback(uint32_t rfm22b_id, PPMReceivedCallback cb); -extern void PIOS_RFM22B_PPMSet(uint32_t rfm22b_id, int16_t *channels); -extern void PIOS_RFM22B_PPMGet(uint32_t rfm22b_id, int16_t *channels); +extern void PIOS_RFM22B_PPMSet(uint32_t rfm22b_id, int16_t *channels, uint8_t nchan); +extern void PIOS_RFM22B_PPMGet(uint32_t rfm22b_id, int16_t *channels, uint8_t nchan); /* Global Variables */ extern const struct pios_com_driver pios_rfm22b_com_driver; diff --git a/flight/pios/inc/pios_rfm22b_priv.h b/flight/pios/inc/pios_rfm22b_priv.h index 47cf9d5c0..953c90fc0 100644 --- a/flight/pios/inc/pios_rfm22b_priv.h +++ b/flight/pios/inc/pios_rfm22b_priv.h @@ -39,488 +39,8 @@ // ************************************ -#define RFM22B_MAX_PACKET_LEN 64 -#define RFM22B_NUM_CHANNELS 251 - -// ************************************ - -#define RFM22_DEVICE_VERSION_V2 0x02 -#define RFM22_DEVICE_VERSION_A0 0x04 -#define RFM22_DEVICE_VERSION_B1 0x06 - -// ************************************ - -#define BIT0 (1u << 0) -#define BIT1 (1u << 1) -#define BIT2 (1u << 2) -#define BIT3 (1u << 3) -#define BIT4 (1u << 4) -#define BIT5 (1u << 5) -#define BIT6 (1u << 6) -#define BIT7 (1u << 7) - -// ************************************ - -#define RFM22_DEVICE_TYPE 0x00 // R -#define RFM22_DT_MASK 0x1F - -#define RFM22_DEVICE_VERSION 0x01 // R -#define RFM22_DV_MASK 0x1F - -#define RFM22_device_status 0x02 // R -#define RFM22_ds_cps_mask 0x03 // Chip Power State mask -#define RFM22_ds_cps_idle 0x00 // IDLE Chip Power State -#define RFM22_ds_cps_rx 0x01 // RX Chip Power State -#define RFM22_ds_cps_tx 0x02 // TX Chip Power State -// #define RFM22_ds_lockdet 0x04 // -// #define RFM22_ds_freqerr 0x08 // -#define RFM22_ds_headerr 0x10 // Header Error Status. Indicates if the received packet has a header check error -#define RFM22_ds_rxffem 0x20 // RX FIFO Empty Status -#define RFM22_ds_ffunfl 0x40 // RX/TX FIFO Underflow Status -#define RFM22_ds_ffovfl 0x80 // RX/TX FIFO Overflow Status - -#define RFM22_interrupt_status1 0x03 // R -#define RFM22_is1_icrerror BIT0 // CRC Error. When set to 1 the cyclic redundancy check is failed. -#define RFM22_is1_ipkvalid BIT1 // Valid Packet Received.When set to 1 a valid packet has been received. -#define RFM22_is1_ipksent BIT2 // Packet Sent Interrupt. When set to1 a valid packet has been transmitted. -#define RFM22_is1_iext BIT3 // External Interrupt. When set to 1 an interrupt occurred on one of the GPIO�s if it is programmed so. The status can be checked in register 0Eh. See GPIOx Configuration section for the details. -#define RFM22_is1_irxffafull BIT4 // RX FIFO Almost Full.When set to 1 the RX FIFO has met its almost full threshold and needs to be read by the microcontroller. -#define RFM22_is1_ixtffaem BIT5 // TX FIFO Almost Empty. When set to 1 the TX FIFO is almost empty and needs to be filled. -#define RFM22_is1_itxffafull BIT6 // TX FIFO Almost Full. When set to 1 the TX FIFO has met its almost full threshold and needs to be transmitted. -#define RFM22_is1_ifferr BIT7 // FIFO Underflow/Overflow Error. When set to 1 the TX or RX FIFO has overflowed or underflowed. - -#define RFM22_interrupt_status2 0x04 // R -#define RFM22_is2_ipor BIT0 // Power-on-Reset (POR). When the chip detects a Power on Reset above the desired setting this bit will be set to 1. -#define RFM22_is2_ichiprdy BIT1 // Chip Ready (XTAL). When a chip ready event has been detected this bit will be set to 1. -#define RFM22_is2_ilbd BIT2 // Low Battery Detect. When a low battery event is been detected this bit will be set to 1. This interrupt event is saved even if it is not enabled by the mask register bit and causes an interrupt after it is enabled. -#define RFM22_is2_iwut BIT3 // Wake-Up-Timer. On the expiration of programmed wake-up timer this bit will be set to 1. -#define RFM22_is2_irssi BIT4 // RSSI. When RSSI level exceeds the programmed threshold this bit will be set to 1. -#define RFM22_is2_ipreainval BIT5 // Invalid Preamble Detected. When the preamble is not found within a period of time set by the invalid preamble detection threshold in Register 54h, this bit will be set to 1. -#define RFM22_is2_ipreaval BIT6 // Valid Preamble Detected. When a preamble is detected this bit will be set to 1. -#define RFM22_is2_iswdet BIT7 // Sync Word Detected. When a sync word is detected this bit will be set to 1. - -#define RFM22_interrupt_enable1 0x05 // R/W -#define RFM22_ie1_encrcerror BIT0 // Enable CRC Error. When set to 1 the CRC Error interrupt will be enabled. -#define RFM22_ie1_enpkvalid BIT1 // Enable Valid Packet Received. When ipkvalid = 1 the Valid Packet Received Interrupt will be enabled. -#define RFM22_ie1_enpksent BIT2 // Enable Packet Sent. When ipksent =1 the Packet Sense Interrupt will be enabled. -#define RFM22_ie1_enext BIT3 // Enable External Interrupt. When set to 1 the External Interrupt will be enabled. -#define RFM22_ie1_enrxffafull BIT4 // Enable RX FIFO Almost Full. When set to 1 the RX FIFO Almost Full interrupt will be enabled. -#define RFM22_ie1_entxffaem BIT5 // Enable TX FIFO Almost Empty. When set to 1 the TX FIFO Almost Empty interrupt will be enabled. -#define RFM22_ie1_entxffafull BIT6 // Enable TX FIFO Almost Full. When set to 1 the TX FIFO Almost Full interrupt will be enabled. -#define RFM22_ie1_enfferr BIT7 // Enable FIFO Underflow/Overflow. When set to 1 the FIFO Underflow/Overflow interrupt will be enabled. - -#define RFM22_interrupt_enable2 0x06 // R/W -#define RFM22_ie2_enpor BIT0 // Enable POR. When set to 1 the POR interrupt will be enabled. -#define RFM22_ie2_enchiprdy BIT1 // Enable Chip Ready (XTAL). When set to 1 the Chip Ready interrupt will be enabled. -#define RFM22_ie2_enlbd BIT2 // Enable Low Battery Detect. When set to 1 the Low Battery Detect interrupt will be enabled. -#define RFM22_ie2_enwut BIT3 // Enable Wake-Up Timer. When set to 1 the Wake-Up Timer interrupt will be enabled. -#define RFM22_ie2_enrssi BIT4 // Enable RSSI. When set to 1 the RSSI Interrupt will be enabled. -#define RFM22_ie2_enpreainval BIT5 // Enable Invalid Preamble Detected. When mpreadet =1 the Invalid Preamble Detected Interrupt will be enabled. -#define RFM22_ie2_enpreaval BIT6 // Enable Valid Preamble Detected. When mpreadet =1 the Valid Preamble Detected Interrupt will be enabled. -#define RFM22_ie2_enswdet BIT7 // Enable Sync Word Detected. When mpreadet =1 the Preamble Detected Interrupt will be enabled. - -#define RFM22_op_and_func_ctrl1 0x07 // R/W -#define RFM22_opfc1_xton 0x01 // READY Mode (Xtal is ON). -#define RFM22_opfc1_pllon 0x02 // TUNE Mode (PLL is ON). When pllon = 1 the PLL will remain enabled in Idle State. This will for faster turn-around time at the cost of increased current consumption in Idle State. -#define RFM22_opfc1_rxon 0x04 // RX on in Manual Receiver Mode. Automatically cleared if Multiple Packets config. is disabled and a valid packet received. -#define RFM22_opfc1_txon 0x08 // TX on in Manual Transmit Mode. Automatically cleared in FIFO mode once the packet is sent. Transmission can be aborted during packet transmission, however, when no data has been sent yet, transmission can only be aborted after the device is programmed to �unmodulated carrier� ("Register 71h. Modulation Mode Control 2"). -#define RFM22_opfc1_x32ksel 0x10 // 32,768 kHz Crystal Oscillator Select. 0: RC oscillator 1: 32 kHz crystal -#define RFM22_opfc1_enwt 0x20 // Enable Wake-Up-Timer. Enabled when enwt = 1. If the Wake-up-Timer function is enabled it will operate in any mode and notify the microcontroller through the GPIO interrupt when the timer expires. -#define RFM22_opfc1_enlbd 0x40 // Enable Low Battery Detect. When this bit is set to 1 the Low Battery Detector circuit and threshold comparison will be enabled. -#define RFM22_opfc1_swres 0x80 // Software Register Reset Bit. This bit may be used to reset all registers simultaneously to a DEFAULT state, without the need for sequentially writing to each individual register. The RESET is accomplished by setting swres = 1. This bit will be automatically cleared. - -#define RFM22_op_and_func_ctrl2 0x08 // R/W -#define RFM22_opfc2_ffclrtx 0x01 // TX FIFO Reset/Clear. This has to be a two writes operation: Setting ffclrtx =1 followed by ffclrtx = 0 will clear the contents of the TX FIFO. -#define RFM22_opfc2_ffclrrx 0x02 // RX FIFO Reset/Clear. This has to be a two writes operation: Setting ffclrrx =1 followed by ffclrrx = 0 will clear the contents of the RX FIFO. -#define RFM22_opfc2_enldm 0x04 // Enable Low Duty Cycle Mode. If this bit is set to 1 then the chip turns on the RX regularly. The frequency should be set in the Wake-Up Timer Period register, while the minimum ON time should be set in the Low-Duty Cycle Mode Duration register. The FIFO mode should be enabled also. -#define RFM22_opfc2_autotx 0x08 // Automatic Transmission. When autotx = 1 the transceiver will enter automatically TX State when the FIFO is almost full. When the FIFO is empty it will automatically return to the Idle State. -#define RFM22_opfc2_rxmpk 0x10 // RX Multi Packet. When the chip is selected to use FIFO Mode (dtmod[1:0]) and RX Packet Handling (enpacrx) then it will fill up the FIFO with multiple valid packets if this bit is set, otherwise the transceiver will automatically leave the RX State after the first valid packet has been received. -#define RFM22_opfc2_antdiv_mask 0xE0 // Enable Antenna Diversity. The GPIO must be configured for Antenna Diversity for the algorithm to work properly. - -#define RFM22_xtal_osc_load_cap 0x09 // R/W -#define RFM22_xolc_xlc_mask 0x7F // Tuning Capacitance for the 30 MHz XTAL. -#define RFM22_xolc_xtalshft 0x80 // Additional capacitance to course shift the frequency if xlc[6:0] is not sufficient. Not binary with xlc[6:0]. - -#define RFM22_cpu_output_clk 0x0A // R/W -#define RFM22_coc_30MHz 0x00 -#define RFM22_coc_15MHz 0x01 -#define RFM22_coc_10MHz 0x02 -#define RFM22_coc_4MHz 0x03 -#define RFM22_coc_3MHz 0x04 -#define RFM22_coc_2MHz 0x05 -#define RFM22_coc_1MHz 0x06 -#define RFM22_coc_32768Hz 0x07 -#define RFM22_coc_enlfc 0x08 -#define RFM22_coc_0cycle 0x00 -#define RFM22_coc_128cycles 0x10 -#define RFM22_coc_256cycles 0x20 -#define RFM22_coc_512cycles 0x30 - -#define RFM22_gpio0_config 0x0B // R/W -#define RFM22_gpio0_config_por 0x00 // Power-On-Reset (output) -#define RFM22_gpio0_config_wut 0x01 // Wake-Up Timer: 1 when WUT has expired (output) -#define RFM22_gpio0_config_lbd 0x02 // Low Battery Detect: 1 when battery is below threshold setting (output) -#define RFM22_gpio0_config_ddi 0x03 // Direct Digital Input -#define RFM22_gpio0_config_eife 0x04 // External Interrupt, falling edge (input) -#define RFM22_gpio0_config_eire 0x05 // External Interrupt, rising edge (input) -#define RFM22_gpio0_config_eisc 0x06 // External Interrupt, state change (input) -#define RFM22_gpio0_config_ai 0x07 // ADC Analog Input -#define RFM22_gpio0_config_atni 0x08 // Reserved (Analog Test N Input) -#define RFM22_gpio0_config_atpi 0x09 // Reserved (Analog Test P Input) -#define RFM22_gpio0_config_ddo 0x0A // Direct Digital Output -#define RFM22_gpio0_config_dto 0x0B // Reserved (Digital Test Output) -#define RFM22_gpio0_config_atno 0x0C // Reserved (Analog Test N Output) -#define RFM22_gpio0_config_atpo 0x0D // Reserved (Analog Test P Output) -#define RFM22_gpio0_config_rv 0xOE // Reference Voltage (output) -#define RFM22_gpio0_config_dclk 0x0F // TX/RX Data CLK output to be used in conjunction with TX/RX Data pin (output) -#define RFM22_gpio0_config_txd 0x10 // TX Data input for direct modulation (input) -#define RFM22_gpio0_config_err 0x11 // External Retransmission Request (input) -#define RFM22_gpio0_config_txstate 0x12 // TX State (output) -#define RFM22_gpio0_config_txfifoaf 0x13 // TX FIFO Almost Full (output) -#define RFM22_gpio0_config_rxd 0x14 // RX Data (output) -#define RFM22_gpio0_config_rxstate 0x15 // RX State (output) -#define RFM22_gpio0_config_rxfifoaf 0x16 // RX FIFO Almost Full (output) -#define RFM22_gpio0_config_antswt1 0x17 // Antenna 1 Switch used for antenna diversity (output) -#define RFM22_gpio0_config_antswt2 0x18 // Antenna 2 Switch used for antenna diversity (output) -#define RFM22_gpio0_config_vpd 0x19 // Valid Preamble Detected (output) -#define RFM22_gpio0_config_ipd 0x1A // Invalid Preamble Detected (output) -#define RFM22_gpio0_config_swd 0x1B // Sync Word Detected (output) -#define RFM22_gpio0_config_cca 0x1C // Clear Channel Assessment (output) -#define RFM22_gpio0_config_vdd 0x1D // VDD -#define RFM22_gpio0_config_pup 0x20 -#define RFM22_gpio0_config_drv0 0x00 // output drive level -#define RFM22_gpio0_config_drv1 0x40 // output drive level -#define RFM22_gpio0_config_drv2 0x80 // output drive level -#define RFM22_gpio0_config_drv3 0xC0 // output drive level - -#define RFM22_gpio1_config 0x0C // R/W -#define RFM22_gpio1_config_ipor 0x00 // Inverted Power-On-Reset (output) -#define RFM22_gpio1_config_wut 0x01 // Wake-Up Timer: 1 when WUT has expired (output) -#define RFM22_gpio1_config_lbd 0x02 // Low Battery Detect: 1 when battery is below threshold setting (output) -#define RFM22_gpio1_config_ddi 0x03 // Direct Digital Input -#define RFM22_gpio1_config_eife 0x04 // External Interrupt, falling edge (input) -#define RFM22_gpio1_config_eire 0x05 // External Interrupt, rising edge (input) -#define RFM22_gpio1_config_eisc 0x06 // External Interrupt, state change (input) -#define RFM22_gpio1_config_ai 0x07 // ADC Analog Input -#define RFM22_gpio1_config_atni 0x08 // Reserved (Analog Test N Input) -#define RFM22_gpio1_config_atpi 0x09 // Reserved (Analog Test P Input) -#define RFM22_gpio1_config_ddo 0x0A // Direct Digital Output -#define RFM22_gpio1_config_dto 0x0B // Reserved (Digital Test Output) -#define RFM22_gpio1_config_atno 0x0C // Reserved (Analog Test N Output) -#define RFM22_gpio1_config_atpo 0x0D // Reserved (Analog Test P Output) -#define RFM22_gpio1_config_rv 0xOE // Reference Voltage (output) -#define RFM22_gpio1_config_dclk 0x0F // TX/RX Data CLK output to be used in conjunction with TX/RX Data pin (output) -#define RFM22_gpio1_config_txd 0x10 // TX Data input for direct modulation (input) -#define RFM22_gpio1_config_err 0x11 // External Retransmission Request (input) -#define RFM22_gpio1_config_txstate 0x12 // TX State (output) -#define RFM22_gpio1_config_txfifoaf 0x13 // TX FIFO Almost Full (output) -#define RFM22_gpio1_config_rxd 0x14 // RX Data (output) -#define RFM22_gpio1_config_rxstate 0x15 // RX State (output) -#define RFM22_gpio1_config_rxfifoaf 0x16 // RX FIFO Almost Full (output) -#define RFM22_gpio1_config_antswt1 0x17 // Antenna 1 Switch used for antenna diversity (output) -#define RFM22_gpio1_config_antswt2 0x18 // Antenna 2 Switch used for antenna diversity (output) -#define RFM22_gpio1_config_vpd 0x19 // Valid Preamble Detected (output) -#define RFM22_gpio1_config_ipd 0x1A // Invalid Preamble Detected (output) -#define RFM22_gpio1_config_swd 0x1B // Sync Word Detected (output) -#define RFM22_gpio1_config_cca 0x1C // Clear Channel Assessment (output) -#define RFM22_gpio1_config_vdd 0x1D // VDD -#define RFM22_gpio1_config_pup 0x20 -#define RFM22_gpio1_config_drv0 0x00 // output drive level -#define RFM22_gpio1_config_drv1 0x40 // output drive level -#define RFM22_gpio1_config_drv2 0x80 // output drive level -#define RFM22_gpio1_config_drv3 0xC0 // output drive level - -#define RFM22_gpio2_config 0x0D // R/W -#define RFM22_gpio2_config_mc 0x00 // Microcontroller Clock (output) -#define RFM22_gpio2_config_wut 0x01 // Wake-Up Timer: 1 when WUT has expired (output) -#define RFM22_gpio2_config_lbd 0x02 // Low Battery Detect: 1 when battery is below threshold setting (output) -#define RFM22_gpio2_config_ddi 0x03 // Direct Digital Input -#define RFM22_gpio2_config_eife 0x04 // External Interrupt, falling edge (input) -#define RFM22_gpio2_config_eire 0x05 // External Interrupt, rising edge (input) -#define RFM22_gpio2_config_eisc 0x06 // External Interrupt, state change (input) -#define RFM22_gpio2_config_ai 0x07 // ADC Analog Input -#define RFM22_gpio2_config_atni 0x08 // Reserved (Analog Test N Input) -#define RFM22_gpio2_config_atpi 0x09 // Reserved (Analog Test P Input) -#define RFM22_gpio2_config_ddo 0x0A // Direct Digital Output -#define RFM22_gpio2_config_dto 0x0B // Reserved (Digital Test Output) -#define RFM22_gpio2_config_atno 0x0C // Reserved (Analog Test N Output) -#define RFM22_gpio2_config_atpo 0x0D // Reserved (Analog Test P Output) -#define RFM22_gpio2_config_rv 0xOE // Reference Voltage (output) -#define RFM22_gpio2_config_dclk 0x0F // TX/RX Data CLK output to be used in conjunction with TX/RX Data pin (output) -#define RFM22_gpio2_config_txd 0x10 // TX Data input for direct modulation (input) -#define RFM22_gpio2_config_err 0x11 // External Retransmission Request (input) -#define RFM22_gpio2_config_txstate 0x12 // TX State (output) -#define RFM22_gpio2_config_txfifoaf 0x13 // TX FIFO Almost Full (output) -#define RFM22_gpio2_config_rxd 0x14 // RX Data (output) -#define RFM22_gpio2_config_rxstate 0x15 // RX State (output) -#define RFM22_gpio2_config_rxfifoaf 0x16 // RX FIFO Almost Full (output) -#define RFM22_gpio2_config_antswt1 0x17 // Antenna 1 Switch used for antenna diversity (output) -#define RFM22_gpio2_config_antswt2 0x18 // Antenna 2 Switch used for antenna diversity (output) -#define RFM22_gpio2_config_vpd 0x19 // Valid Preamble Detected (output) -#define RFM22_gpio2_config_ipd 0x1A // Invalid Preamble Detected (output) -#define RFM22_gpio2_config_swd 0x1B // Sync Word Detected (output) -#define RFM22_gpio2_config_cca 0x1C // Clear Channel Assessment (output) -#define RFM22_gpio2_config_vdd 0x1D // VDD -#define RFM22_gpio2_config_pup 0x20 -#define RFM22_gpio2_config_drv0 0x00 // output drive level -#define RFM22_gpio2_config_drv1 0x40 // output drive level -#define RFM22_gpio2_config_drv2 0x80 // output drive level -#define RFM22_gpio2_config_drv3 0xC0 // output drive level - -#define RFM22_io_port_config 0x0E // R/W -#define RFM22_io_port_extitst2 0x40 // External Interrupt Status. If the GPIO2 is programmed to be external interrupt sources then the status can be read here. -#define RFM22_io_port_extitst1 0x20 // External Interrupt Status. If the GPIO1 is programmed to be external interrupt sources then the status can be read here. -#define RFM22_io_port_extitst0 0x10 // External Interrupt Status. If the GPIO0 is programmed to be external interrupt sources then the status can be read here. -#define RFM22_io_port_itsdo 0x08 // Interrupt Request Output on the SDO Pin. nIRQ output is present on the SDO pin if this bit is set and the nSEL input is inactive (high). -#define RFM22_io_port_dio2 0x04 // Direct I/O for GPIO2. If the GPIO2 is configured to be a direct output then the value on the GPIO pin can be set here. If the GPIO2 is configured to be a direct input then the value of the pin can be read here. -#define RFM22_io_port_dio1 0x02 // Direct I/O for GPIO1. If the GPIO1 is configured to be a direct output then the value on the GPIO pin can be set here. If the GPIO1 is configured to be a direct input then the value of the pin can be read here. -#define RFM22_io_port_dio0 0x01 // Direct I/O for GPIO0. If the GPIO0 is configured to be a direct output then the value on the GPIO pin can be set here. If the GPIO0 is configured to be a direct input then the value of the pin can be read here. -#define RFM22_io_port_default 0x00 // GPIO pins are default - -#define RFM22_adc_config 0x0F // R/W -#define RFM22_ac_adcgain0 0x00 -#define RFM22_ac_adcgain1 0x01 -#define RFM22_ac_adcgain2 0x02 -#define RFM22_ac_adcgain3 0x03 -#define RFM22_ac_adcref_bg 0x00 -#define RFM22_ac_adcref_vdd3 0x08 -#define RFM22_ac_adcref_vdd2 0x0C -#define RFM22_ac_adcsel_temp_sensor 0x00 -#define RFM22_ac_adcsel_gpio0 0x10 -#define RFM22_ac_adcsel_gpio1 0x20 -#define RFM22_ac_adcsel_gpio2 0x30 -#define RFM22_ac_adcsel_gpio01 0x40 -#define RFM22_ac_adcsel_gpio12 0x50 -#define RFM22_ac_adcsel_gpio02 0x60 -#define RFM22_ac_adcsel_gpio_gnd 0x70 -#define RFM22_ac_adcstartbusy 0x80 - -#define RFM22_adc_sensor_amp_offset 0x10 // R/W -#define RFM22_asao_adcoffs_mask 0x0F // ADC Sensor Amplifier Offset. The offset can be calculated as Offset = adcoffs[2:0] x VDD/1000; MSB = adcoffs[3] = Sign bit. - -#define RFM22_adc_value 0x11 // R .. Internal 8 bit ADC Output Value. - -#define RFM22_temp_sensor_calib 0x12 // R/W -#define RFM22_tsc_tstrim_mask 0x0F // Temperature Sensor Trim Value. -#define RFM22_tsc_entstrim 0x10 // Temperature Sensor Trim Enable. -#define RFM22_tsc_entsoffs 0x20 // Temperature Sensor Offset to Convert from K to �C. -#define RFM22_tsc_tsrange0 0x00 // Temperature Sensor Range Selection. �64C to +64C 0.5C resolution -#define RFM22_tsc_tsrange1 0x40 // -40 to +85C with 1.0C resolution -#define RFM22_tsc_tsrange2 0x80 // 0C to 85C with 0.5C resolution -#define RFM22_tsc_tsrange3 0xC0 // -40F to 216F with 1.0F resolution - -#define RFM22_temp_value_offset 0x13 // R/W - -#define RFM22_wakeup_timer_period1 0x14 // R/W -#define RFM22_wakeup_timer_period2 0x15 // R/W -#define RFM22_wakeup_timer_period3 0x16 // R/W - -#define RFM22_wakeup_timer_value1 0x17 // R -#define RFM22_wakeup_timer_value2 0x18 // R - -#define RFM22_low_dutycycle_mode_duration 0x19 // R/W -#define RFM22_low_battery_detector_threshold 0x1A // R/W - -#define RFM22_battery_volateg_level 0x1B // R - -#define RFM22_if_filter_bandwidth 0x1C // R/W -#define RFM22_iffbw_filset_mask 0x0F -#define RFM22_iffbw_ndec_exp_mask 0x70 -#define RFM22_iffbw_dwn3_bypass 0x80 - -#define RFM22_afc_loop_gearshift_override 0x1D // R/W -#define RFM22_afc_lp_gs_ovrd_afcgearl_mask 0x07 // AFC Low Gear Setting. -#define RFM22_afc_lp_gs_ovrd_afcgearh_mask 0x38 // AFC High Gear Setting. -#define RFM22_afc_lp_gs_ovrd_enafc 0x40 // AFC Enable. -#define RFM22_afc_lp_gs_ovrd_afcbd 0x80 // If set, the tolerated AFC frequency error will be halved. - -#define RFM22_afc_timing_control 0x1E // R/W - -#define RFM22_clk_recovery_gearshift_override 0x1F // R/W -#define RFM22_clk_recovery_oversampling_ratio 0x20 // R/W -#define RFM22_clk_recovery_offset2 0x21 // R/W -#define RFM22_clk_recovery_offset1 0x22 // R/W -#define RFM22_clk_recovery_offset0 0x23 // R/W -#define RFM22_clk_recovery_timing_loop_gain1 0x24 // R/W -#define RFM22_clk_recovery_timing_loop_gain0 0x25 // R/W - -#define RFM22_rssi 0x26 // R -#define RFM22_rssi_threshold_clear_chan_indicator 0x27 // R/W - -#define RFM22_antenna_diversity_register1 0x28 // R -#define RFM22_antenna_diversity_register2 0x29 // R - -#define RFM22_afc_limiter 0x2A // R/W .. AFC_pull_in_range = �AFCLimiter[7:0] x (hbsel+1) x 625 Hz - -#define RFM22_afc_correction_read 0x2B // R - -#define RFM22_ook_counter_value1 0x2C // R/W -#define RFM22_ook_counter_value2 0x2D // R/W - -#define RFM22_slicer_peak_hold 0x2E // R/W - -#define RFM22_data_access_control 0x30 // R/W -#define RFM22_dac_crc_ccitt 0x00 // -#define RFM22_dac_crc_crc16 0x01 // -#define RFM22_dac_crc_iec16 0x02 // -#define RFM22_dac_crc_biacheva 0x03 // -#define RFM22_dac_encrc 0x04 // CRC Enable. Cyclic Redundancy Check generation is enabled if this bit is set. -#define RFM22_dac_enpactx 0x08 // Enable Packet TX Handling. If FIFO Mode (dtmod = 10) is being used automatic packet handling may be enabled. Setting enpactx = 1 will enable automatic packet handling in the TX path. Register 30�4D allow for various configurations of the packet structure. Setting enpactx = 0 will not do any packet handling in the TX path. It will only transmit what is loaded to the FIFO. -#define RFM22_dac_skip2ph 0x10 // Skip 2nd Phase of Preamble Detection. If set, we skip the second phase of the preamble detection (under certain conditions) if antenna diversity is enabled. -#define RFM22_dac_crcdonly 0x20 // CRC Data Only Enable. When this bit is set to 1 the CRC is calculated on and checked against the packet data fields only. -#define RFM22_dac_lsbfrst 0x40 // LSB First Enable. The LSB of the data will be transmitted/received first if this bit is set. -#define RFM22_dac_enpacrx 0x80 // Enable Packet RX Handling. If FIFO Mode (dtmod = 10) is being used automatic packet handling may be enabled. Setting enpacrx = 1 will enable automatic packet handling in the RX path. Register 30�4D allow for various configurations of the packet structure. Setting enpacrx = 0 will not do any packet handling in the RX path. It will only receive everything after the sync word and fill up the RX FIFO. - -#define RFM22_ezmac_status 0x31 // R -#define RFM22_ezmac_status_pksent 0x01 // Packet Sent. A 1 a packet has been sent by the radio. (Same bit as in register 03, but reading it does not reset the IRQ) -#define RFM22_ezmac_status_pktx 0x02 // Packet Transmitting. When 1 the radio is currently transmitting a packet. -#define RFM22_ezmac_status_crcerror 0x04 // CRC Error. When 1 a Cyclic Redundancy Check error has been detected. (Same bit as in register 03, but reading it does not reset the IRQ) -#define RFM22_ezmac_status_pkvalid 0x08 // Valid Packet Received. When a 1 a valid packet has been received by the receiver. (Same bit as in register 03, but reading it does not reset the IRQ) -#define RFM22_ezmac_status_pkrx 0x10 // Packet Receiving. When 1 the radio is currently receiving a valid packet. -#define RFM22_ezmac_status_pksrch 0x20 // Packet Searching. When 1 the radio is searching for a valid packet. -#define RFM22_ezmac_status_rxcrc1 0x40 // If high, it indicates the last CRC received is all one�s. May indicated Transmitter underflow in case of CRC error. - -#define RFM22_header_control1 0x32 // R/W -#define RFM22_header_cntl1_bcen_none 0x00 // No broadcast address enable. -#define RFM22_header_cntl1_bcen_0 0x10 // Broadcast address enable for header byte 0. -#define RFM22_header_cntl1_bcen_1 0x20 // Broadcast address enable for header byte 1. -#define RFM22_header_cntl1_bcen_2 0x40 // Broadcast address enable for header byte 2. -#define RFM22_header_cntl1_bcen_3 0x80 // Broadcast address enable for header byte 3. -#define RFM22_header_cntl1_hdch_none 0x00 // No Received Header check -#define RFM22_header_cntl1_hdch_0 0x01 // Received Header check for byte 0. -#define RFM22_header_cntl1_hdch_1 0x02 // Received Header check for byte 1. -#define RFM22_header_cntl1_hdch_2 0x04 // Received Header check for byte 2. -#define RFM22_header_cntl1_hdch_3 0x08 // Received Header check for byte 3. - -#define RFM22_header_control2 0x33 // R/W -#define RFM22_header_cntl2_prealen 0x01 // MSB of Preamble Length. See register Preamble Length. -#define RFM22_header_cntl2_synclen_3 0x00 // Synchronization Word 3 -#define RFM22_header_cntl2_synclen_32 0x02 // Synchronization Word 3 followed by 2 -#define RFM22_header_cntl2_synclen_321 0x04 // Synchronization Word 3 followed by 2 followed by 1 -#define RFM22_header_cntl2_synclen_3210 0x06 // Synchronization Word 3 followed by 2 followed by 1 followed by 0 -#define RFM22_header_cntl2_fixpklen 0x08 // Fix Packet Length. When fixpklen = 1 the packet length (pklen[7:0]) is not included in the header. When fixpklen = 0 the packet length is included in the header. -#define RFM22_header_cntl2_hdlen_none 0x00 // no header -#define RFM22_header_cntl2_hdlen_3 0x10 // header 3 -#define RFM22_header_cntl2_hdlen_32 0x20 // header 3 and 2 -#define RFM22_header_cntl2_hdlen_321 0x30 // header 3 and 2 and 1 -#define RFM22_header_cntl2_hdlen_3210 0x40 // header 3 and 2 and 1 and 0 -#define RFM22_header_cntl2_skipsyn 0x80 // If high, the system will ignore the syncword search timeout reset. The chip will not return to searching for Preamble, but instead will remain searching for Sync word. - -#define RFM22_preamble_length 0x34 // R/W - -#define RFM22_preamble_detection_ctrl1 0x35 // R/W -#define RFM22_pre_det_ctrl1_preath_mask 0xF8 // Number of nibbles processed during detection. -#define RFM22_pre_det_ctrl1_rssi_offset_mask 0x07 // Value added as offset to RSSI calculation. Every increment in this register results in an increment of +4 dB in the RSSI. - -#define RFM22_sync_word3 0x36 // R/W -#define RFM22_sync_word2 0x37 // R/W -#define RFM22_sync_word1 0x38 // R/W -#define RFM22_sync_word0 0x39 // R/W - -#define RFM22_transmit_header3 0x3A // R/W -#define RFM22_transmit_header2 0x3B // R/W -#define RFM22_transmit_header1 0x3C // R/W -#define RFM22_transmit_header0 0x3D // R/W - -#define RFM22_transmit_packet_length 0x3E // R/W - -#define RFM22_check_header3 0x3F // R/W -#define RFM22_check_header2 0x40 // R/W -#define RFM22_check_header1 0x41 // R/W -#define RFM22_check_header0 0x42 // R/W - -#define RFM22_header_enable3 0x43 // R/W -#define RFM22_header_enable2 0x44 // R/W -#define RFM22_header_enable1 0x45 // R/W -#define RFM22_header_enable0 0x46 // R/W - -#define RFM22_received_header3 0x47 // R -#define RFM22_received_header2 0x48 // R -#define RFM22_received_header1 0x49 // R -#define RFM22_received_header0 0x4A // R - -#define RFM22_received_packet_length 0x4B // R - -#define RFM22_adc8_control 0x4F // R/W - -#define RFM22_channel_filter_coeff_addr 0x60 // R/W -#define RFM22_ch_fil_coeff_ad_inv_pre_th_mask 0xF0 // -#define RFM22_ch_fil_coeff_ad_chfiladd_mask 0x0F // Channel Filter Coefficient Look-up Table Address. The address for channel filter coefficients used in the RX path. - -#define RFM22_xtal_osc_por_ctrl 0x62 // R/W -#define RFM22_xtal_osc_por_ctrl_pwst_mask 0xE0 // Internal Power States of the Chip. -#define RFM22_xtal_osc_por_ctrl_clkhyst 0x10 // Clock Hysteresis Setting. -#define RFM22_xtal_osc_por_ctrl_enbias2x 0x08 // 2 Times Higher Bias Current Enable. -#define RFM22_xtal_osc_por_ctrl_enamp2x 0x04 // 2 Times Higher Amplification Enable. -#define RFM22_xtal_osc_por_ctrl_bufovr 0x02 // Output Buffer Enable Override. -#define RFM22_xtal_osc_por_ctrl_enbuf 0x01 // Output Buffer Enable. - -#define RFM22_agc_override1 0x69 // R/W -#define RFM22_agc_ovr1_sgi 0x40 // AGC Loop, Set Gain Increase. If set to 0 then gain increasing will not be allowed. If set to 1 then gain increasing is allowed, default is 0. -#define RFM22_agc_ovr1_agcen 0x20 // Automatic Gain Control Enable. When this bit is set then the result of the control can be read out from bits [4:0], otherwise the gain can be controlled manually by writing into bits [4:0]. -#define RFM22_agc_ovr1_lnagain 0x10 // LNA Gain Select. 0 = min gain = 5dB, 1 = max gain = 25 dB. -#define RFM22_agc_ovr1_pga_mask 0x0F // PGA Gain Override Value. - -#define RFM22_tx_power 0x6D // R/W -#define RFM22_tx_pwr_lna_sw 0x08 // LNA Switch Controller. If set, lna_sw control from the digital will go high during TX modes, and low during other times. If reset, the digital control signal is low at all times. - -#define RFM22_tx_data_rate1 0x6E // R/W -#define RFM22_tx_data_rate0 0x6F // R/W - -#define RFM22_modulation_mode_control1 0x70 // R/W -#define RFM22_mmc1_enwhite 0x01 // Data Whitening is Enabled if this bit is set. -#define RFM22_mmc1_enmanch 0x02 // Manchester Coding is Enabled if this bit is set. -#define RFM22_mmc1_enmaninv 0x04 // Manchester Data Inversion is Enabled if this bit is set. -#define RFM22_mmc1_manppol 0x08 // Manchester Preamble Polarity (will transmit a series of 1 if set, or series of 0 if reset). -#define RFM22_mmc1_enphpwdn 0x10 // If set, the Packet Handler will be powered down when chip is in low power mode. -#define RFM22_mmc1_txdtrtscale 0x20 // This bit should be set for Data Rates below 30 kbps. - -#define RFM22_modulation_mode_control2 0x71 // R/W -#define RFM22_mmc2_modtyp_mask 0x03 // Modulation type. -#define RFM22_mmc2_modtyp_none 0x00 // -#define RFM22_mmc2_modtyp_ook 0x01 // -#define RFM22_mmc2_modtyp_fsk 0x02 // -#define RFM22_mmc2_modtyp_gfsk 0x03 // -#define RFM22_mmc2_fd 0x04 // MSB of Frequency Deviation Setting, see "Register 72h. Frequency Deviation". -#define RFM22_mmc2_eninv 0x08 // Invert TX and RX Data. -#define RFM22_mmc2_dtmod_mask 0x30 // Modulation source. -#define RFM22_mmc2_dtmod_dm_gpio 0x00 // -#define RFM22_mmc2_dtmod_dm_sdi 0x10 // -#define RFM22_mmc2_dtmod_fifo 0x20 // -#define RFM22_mmc2_dtmod_pn9 0x30 // -#define RFM22_mmc2_trclk_mask 0xC0 // TX Data Clock Configuration. -#define RFM22_mmc2_trclk_clk_none 0x00 // -#define RFM22_mmc2_trclk_clk_gpio 0x40 // -#define RFM22_mmc2_trclk_clk_sdo 0x80 // -#define RFM22_mmc2_trclk_clk_nirq 0xC0 // - -#define RFM22_frequency_deviation 0x72 // R/W - -#define RFM22_frequency_offset1 0x73 // R/W -#define RFM22_frequency_offset2 0x74 // R/W - -#define RFM22_frequency_band_select 0x75 // R/W -#define RFM22_fb_mask 0x1F -#define RFM22_fbs_hbsel 0x20 -#define RFM22_fbs_sbse 0x40 - -#define RFM22_nominal_carrier_frequency1 0x76 // R/W -#define RFM22_nominal_carrier_frequency0 0x77 // R/W - -#define RFM22_frequency_hopping_channel_select 0x79 // R/W -#define RFM22_frequency_hopping_step_size 0x7A // R/W - -#define RFM22_tx_fifo_control1 0x7C // R/W .. TX FIFO Almost Full Threshold (0 - 63) -#define RFM22_tx_fifo_control1_mask 0x3F - -#define RFM22_tx_fifo_control2 0x7D // R/W .. TX FIFO Almost Empty Threshold (0 - 63) -#define RFM22_tx_fifo_control2_mask 0x3F - -#define RFM22_rx_fifo_control 0x7E // R/W .. RX FIFO Almost Full Threshold (0 - 63) -#define RFM22_rx_fifo_control_mask 0x3F - -#define RFM22_fifo_access 0x7F // R/W - +#define RFM22B_MAX_PACKET_LEN 64 +#define RFM22B_NUM_CHANNELS 251 // External type definitions @@ -674,7 +194,7 @@ struct pios_rfm22b_dev { // The device ID uint32_t deviceID; - // The coodinator ID (0 if this modem is a coordinator). + // The coordinator ID (0 if this modem is a coordinator). uint32_t coordinatorID; // The task handle diff --git a/flight/pios/inc/pios_rfm22b_regs.h b/flight/pios/inc/pios_rfm22b_regs.h new file mode 100644 index 000000000..b1ff3d259 --- /dev/null +++ b/flight/pios/inc/pios_rfm22b_regs.h @@ -0,0 +1,521 @@ +/** + ****************************************************************************** + * @addtogroup PIOS PIOS Core hardware abstraction layer + * @{ + * @addtogroup PIOS_RFM22B Radio Functions + * @brief PIOS interface for RFM22B Radio + * @{ + * + * @file pios_rfm22b_regs.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. + * @author Tau Labs, http://taulabs.org, Copyright (C) 2014 + * @author LibrePilot, http://librepilot.org, Copyright (C) 2016 + * @brief RFM22B private definitions. + * @see The GNU Public License (GPL) Version 3 + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PIOS_RFM22B_REGS_H +#define PIOS_RFM22B_REGS_H + +// ************************************ + +#define RFM22_DEVICE_VERSION_V2 0x02 +#define RFM22_DEVICE_VERSION_A0 0x04 +#define RFM22_DEVICE_VERSION_B1 0x06 + +// ************************************ + +#define BIT0 (1u << 0) +#define BIT1 (1u << 1) +#define BIT2 (1u << 2) +#define BIT3 (1u << 3) +#define BIT4 (1u << 4) +#define BIT5 (1u << 5) +#define BIT6 (1u << 6) +#define BIT7 (1u << 7) + +// ************************************ + +#define RFM22_DEVICE_TYPE 0x00 // R +#define RFM22_DT_MASK 0x1F + +#define RFM22_DEVICE_VERSION 0x01 // R +#define RFM22_DV_MASK 0x1F + +#define RFM22_device_status 0x02 // R +#define RFM22_ds_cps_mask 0x03 // Chip Power State mask +#define RFM22_ds_cps_idle 0x00 // IDLE Chip Power State +#define RFM22_ds_cps_rx 0x01 // RX Chip Power State +#define RFM22_ds_cps_tx 0x02 // TX Chip Power State +// #define RFM22_ds_lockdet 0x04 // +// #define RFM22_ds_freqerr 0x08 // +#define RFM22_ds_headerr 0x10 // Header Error Status. Indicates if the received packet has a header check error +#define RFM22_ds_rxffem 0x20 // RX FIFO Empty Status +#define RFM22_ds_ffunfl 0x40 // RX/TX FIFO Underflow Status +#define RFM22_ds_ffovfl 0x80 // RX/TX FIFO Overflow Status + +#define RFM22_interrupt_status1 0x03 // R +#define RFM22_is1_icrerror BIT0 // CRC Error. When set to 1 the cyclic redundancy check is failed. +#define RFM22_is1_ipkvalid BIT1 // Valid Packet Received.When set to 1 a valid packet has been received. +#define RFM22_is1_ipksent BIT2 // Packet Sent Interrupt. When set to1 a valid packet has been transmitted. +#define RFM22_is1_iext BIT3 // External Interrupt. When set to 1 an interrupt occurred on one of the GPIO�s if it is programmed so. The status can be checked in register 0Eh. See GPIOx Configuration section for the details. +#define RFM22_is1_irxffafull BIT4 // RX FIFO Almost Full.When set to 1 the RX FIFO has met its almost full threshold and needs to be read by the microcontroller. +#define RFM22_is1_ixtffaem BIT5 // TX FIFO Almost Empty. When set to 1 the TX FIFO is almost empty and needs to be filled. +#define RFM22_is1_itxffafull BIT6 // TX FIFO Almost Full. When set to 1 the TX FIFO has met its almost full threshold and needs to be transmitted. +#define RFM22_is1_ifferr BIT7 // FIFO Underflow/Overflow Error. When set to 1 the TX or RX FIFO has overflowed or underflowed. + +#define RFM22_interrupt_status2 0x04 // R +#define RFM22_is2_ipor BIT0 // Power-on-Reset (POR). When the chip detects a Power on Reset above the desired setting this bit will be set to 1. +#define RFM22_is2_ichiprdy BIT1 // Chip Ready (XTAL). When a chip ready event has been detected this bit will be set to 1. +#define RFM22_is2_ilbd BIT2 // Low Battery Detect. When a low battery event is been detected this bit will be set to 1. This interrupt event is saved even if it is not enabled by the mask register bit and causes an interrupt after it is enabled. +#define RFM22_is2_iwut BIT3 // Wake-Up-Timer. On the expiration of programmed wake-up timer this bit will be set to 1. +#define RFM22_is2_irssi BIT4 // RSSI. When RSSI level exceeds the programmed threshold this bit will be set to 1. +#define RFM22_is2_ipreainval BIT5 // Invalid Preamble Detected. When the preamble is not found within a period of time set by the invalid preamble detection threshold in Register 54h, this bit will be set to 1. +#define RFM22_is2_ipreaval BIT6 // Valid Preamble Detected. When a preamble is detected this bit will be set to 1. +#define RFM22_is2_iswdet BIT7 // Sync Word Detected. When a sync word is detected this bit will be set to 1. + +#define RFM22_interrupt_enable1 0x05 // R/W +#define RFM22_ie1_encrcerror BIT0 // Enable CRC Error. When set to 1 the CRC Error interrupt will be enabled. +#define RFM22_ie1_enpkvalid BIT1 // Enable Valid Packet Received. When ipkvalid = 1 the Valid Packet Received Interrupt will be enabled. +#define RFM22_ie1_enpksent BIT2 // Enable Packet Sent. When ipksent =1 the Packet Sense Interrupt will be enabled. +#define RFM22_ie1_enext BIT3 // Enable External Interrupt. When set to 1 the External Interrupt will be enabled. +#define RFM22_ie1_enrxffafull BIT4 // Enable RX FIFO Almost Full. When set to 1 the RX FIFO Almost Full interrupt will be enabled. +#define RFM22_ie1_entxffaem BIT5 // Enable TX FIFO Almost Empty. When set to 1 the TX FIFO Almost Empty interrupt will be enabled. +#define RFM22_ie1_entxffafull BIT6 // Enable TX FIFO Almost Full. When set to 1 the TX FIFO Almost Full interrupt will be enabled. +#define RFM22_ie1_enfferr BIT7 // Enable FIFO Underflow/Overflow. When set to 1 the FIFO Underflow/Overflow interrupt will be enabled. + +#define RFM22_interrupt_enable2 0x06 // R/W +#define RFM22_ie2_enpor BIT0 // Enable POR. When set to 1 the POR interrupt will be enabled. +#define RFM22_ie2_enchiprdy BIT1 // Enable Chip Ready (XTAL). When set to 1 the Chip Ready interrupt will be enabled. +#define RFM22_ie2_enlbd BIT2 // Enable Low Battery Detect. When set to 1 the Low Battery Detect interrupt will be enabled. +#define RFM22_ie2_enwut BIT3 // Enable Wake-Up Timer. When set to 1 the Wake-Up Timer interrupt will be enabled. +#define RFM22_ie2_enrssi BIT4 // Enable RSSI. When set to 1 the RSSI Interrupt will be enabled. +#define RFM22_ie2_enpreainval BIT5 // Enable Invalid Preamble Detected. When mpreadet =1 the Invalid Preamble Detected Interrupt will be enabled. +#define RFM22_ie2_enpreaval BIT6 // Enable Valid Preamble Detected. When mpreadet =1 the Valid Preamble Detected Interrupt will be enabled. +#define RFM22_ie2_enswdet BIT7 // Enable Sync Word Detected. When mpreadet =1 the Preamble Detected Interrupt will be enabled. + +#define RFM22_op_and_func_ctrl1 0x07 // R/W +#define RFM22_opfc1_xton 0x01 // READY Mode (Xtal is ON). +#define RFM22_opfc1_pllon 0x02 // TUNE Mode (PLL is ON). When pllon = 1 the PLL will remain enabled in Idle State. This will for faster turn-around time at the cost of increased current consumption in Idle State. +#define RFM22_opfc1_rxon 0x04 // RX on in Manual Receiver Mode. Automatically cleared if Multiple Packets config. is disabled and a valid packet received. +#define RFM22_opfc1_txon 0x08 // TX on in Manual Transmit Mode. Automatically cleared in FIFO mode once the packet is sent. Transmission can be aborted during packet transmission, however, when no data has been sent yet, transmission can only be aborted after the device is programmed to �unmodulated carrier� ("Register 71h. Modulation Mode Control 2"). +#define RFM22_opfc1_x32ksel 0x10 // 32,768 kHz Crystal Oscillator Select. 0: RC oscillator 1: 32 kHz crystal +#define RFM22_opfc1_enwt 0x20 // Enable Wake-Up-Timer. Enabled when enwt = 1. If the Wake-up-Timer function is enabled it will operate in any mode and notify the microcontroller through the GPIO interrupt when the timer expires. +#define RFM22_opfc1_enlbd 0x40 // Enable Low Battery Detect. When this bit is set to 1 the Low Battery Detector circuit and threshold comparison will be enabled. +#define RFM22_opfc1_swres 0x80 // Software Register Reset Bit. This bit may be used to reset all registers simultaneously to a DEFAULT state, without the need for sequentially writing to each individual register. The RESET is accomplished by setting swres = 1. This bit will be automatically cleared. + +#define RFM22_op_and_func_ctrl2 0x08 // R/W +#define RFM22_opfc2_ffclrtx 0x01 // TX FIFO Reset/Clear. This has to be a two writes operation: Setting ffclrtx =1 followed by ffclrtx = 0 will clear the contents of the TX FIFO. +#define RFM22_opfc2_ffclrrx 0x02 // RX FIFO Reset/Clear. This has to be a two writes operation: Setting ffclrrx =1 followed by ffclrrx = 0 will clear the contents of the RX FIFO. +#define RFM22_opfc2_enldm 0x04 // Enable Low Duty Cycle Mode. If this bit is set to 1 then the chip turns on the RX regularly. The frequency should be set in the Wake-Up Timer Period register, while the minimum ON time should be set in the Low-Duty Cycle Mode Duration register. The FIFO mode should be enabled also. +#define RFM22_opfc2_autotx 0x08 // Automatic Transmission. When autotx = 1 the transceiver will enter automatically TX State when the FIFO is almost full. When the FIFO is empty it will automatically return to the Idle State. +#define RFM22_opfc2_rxmpk 0x10 // RX Multi Packet. When the chip is selected to use FIFO Mode (dtmod[1:0]) and RX Packet Handling (enpacrx) then it will fill up the FIFO with multiple valid packets if this bit is set, otherwise the transceiver will automatically leave the RX State after the first valid packet has been received. +#define RFM22_opfc2_antdiv_mask 0xE0 // Enable Antenna Diversity. The GPIO must be configured for Antenna Diversity for the algorithm to work properly. + +#define RFM22_xtal_osc_load_cap 0x09 // R/W +#define RFM22_xolc_xlc_mask 0x7F // Tuning Capacitance for the 30 MHz XTAL. +#define RFM22_xolc_xtalshft 0x80 // Additional capacitance to course shift the frequency if xlc[6:0] is not sufficient. Not binary with xlc[6:0]. + +#define RFM22_cpu_output_clk 0x0A // R/W +#define RFM22_coc_30MHz 0x00 +#define RFM22_coc_15MHz 0x01 +#define RFM22_coc_10MHz 0x02 +#define RFM22_coc_4MHz 0x03 +#define RFM22_coc_3MHz 0x04 +#define RFM22_coc_2MHz 0x05 +#define RFM22_coc_1MHz 0x06 +#define RFM22_coc_32768Hz 0x07 +#define RFM22_coc_enlfc 0x08 +#define RFM22_coc_0cycle 0x00 +#define RFM22_coc_128cycles 0x10 +#define RFM22_coc_256cycles 0x20 +#define RFM22_coc_512cycles 0x30 + +#define RFM22_gpio0_config 0x0B // R/W +#define RFM22_gpio0_config_por 0x00 // Power-On-Reset (output) +#define RFM22_gpio0_config_wut 0x01 // Wake-Up Timer: 1 when WUT has expired (output) +#define RFM22_gpio0_config_lbd 0x02 // Low Battery Detect: 1 when battery is below threshold setting (output) +#define RFM22_gpio0_config_ddi 0x03 // Direct Digital Input +#define RFM22_gpio0_config_eife 0x04 // External Interrupt, falling edge (input) +#define RFM22_gpio0_config_eire 0x05 // External Interrupt, rising edge (input) +#define RFM22_gpio0_config_eisc 0x06 // External Interrupt, state change (input) +#define RFM22_gpio0_config_ai 0x07 // ADC Analog Input +#define RFM22_gpio0_config_atni 0x08 // Reserved (Analog Test N Input) +#define RFM22_gpio0_config_atpi 0x09 // Reserved (Analog Test P Input) +#define RFM22_gpio0_config_ddo 0x0A // Direct Digital Output +#define RFM22_gpio0_config_dto 0x0B // Reserved (Digital Test Output) +#define RFM22_gpio0_config_atno 0x0C // Reserved (Analog Test N Output) +#define RFM22_gpio0_config_atpo 0x0D // Reserved (Analog Test P Output) +#define RFM22_gpio0_config_rv 0xOE // Reference Voltage (output) +#define RFM22_gpio0_config_dclk 0x0F // TX/RX Data CLK output to be used in conjunction with TX/RX Data pin (output) +#define RFM22_gpio0_config_txd 0x10 // TX Data input for direct modulation (input) +#define RFM22_gpio0_config_err 0x11 // External Retransmission Request (input) +#define RFM22_gpio0_config_txstate 0x12 // TX State (output) +#define RFM22_gpio0_config_txfifoaf 0x13 // TX FIFO Almost Full (output) +#define RFM22_gpio0_config_rxd 0x14 // RX Data (output) +#define RFM22_gpio0_config_rxstate 0x15 // RX State (output) +#define RFM22_gpio0_config_rxfifoaf 0x16 // RX FIFO Almost Full (output) +#define RFM22_gpio0_config_antswt1 0x17 // Antenna 1 Switch used for antenna diversity (output) +#define RFM22_gpio0_config_antswt2 0x18 // Antenna 2 Switch used for antenna diversity (output) +#define RFM22_gpio0_config_vpd 0x19 // Valid Preamble Detected (output) +#define RFM22_gpio0_config_ipd 0x1A // Invalid Preamble Detected (output) +#define RFM22_gpio0_config_swd 0x1B // Sync Word Detected (output) +#define RFM22_gpio0_config_cca 0x1C // Clear Channel Assessment (output) +#define RFM22_gpio0_config_vdd 0x1D // VDD +#define RFM22_gpio0_config_pup 0x20 +#define RFM22_gpio0_config_drv0 0x00 // output drive level +#define RFM22_gpio0_config_drv1 0x40 // output drive level +#define RFM22_gpio0_config_drv2 0x80 // output drive level +#define RFM22_gpio0_config_drv3 0xC0 // output drive level + +#define RFM22_gpio1_config 0x0C // R/W +#define RFM22_gpio1_config_ipor 0x00 // Inverted Power-On-Reset (output) +#define RFM22_gpio1_config_wut 0x01 // Wake-Up Timer: 1 when WUT has expired (output) +#define RFM22_gpio1_config_lbd 0x02 // Low Battery Detect: 1 when battery is below threshold setting (output) +#define RFM22_gpio1_config_ddi 0x03 // Direct Digital Input +#define RFM22_gpio1_config_eife 0x04 // External Interrupt, falling edge (input) +#define RFM22_gpio1_config_eire 0x05 // External Interrupt, rising edge (input) +#define RFM22_gpio1_config_eisc 0x06 // External Interrupt, state change (input) +#define RFM22_gpio1_config_ai 0x07 // ADC Analog Input +#define RFM22_gpio1_config_atni 0x08 // Reserved (Analog Test N Input) +#define RFM22_gpio1_config_atpi 0x09 // Reserved (Analog Test P Input) +#define RFM22_gpio1_config_ddo 0x0A // Direct Digital Output +#define RFM22_gpio1_config_dto 0x0B // Reserved (Digital Test Output) +#define RFM22_gpio1_config_atno 0x0C // Reserved (Analog Test N Output) +#define RFM22_gpio1_config_atpo 0x0D // Reserved (Analog Test P Output) +#define RFM22_gpio1_config_rv 0xOE // Reference Voltage (output) +#define RFM22_gpio1_config_dclk 0x0F // TX/RX Data CLK output to be used in conjunction with TX/RX Data pin (output) +#define RFM22_gpio1_config_txd 0x10 // TX Data input for direct modulation (input) +#define RFM22_gpio1_config_err 0x11 // External Retransmission Request (input) +#define RFM22_gpio1_config_txstate 0x12 // TX State (output) +#define RFM22_gpio1_config_txfifoaf 0x13 // TX FIFO Almost Full (output) +#define RFM22_gpio1_config_rxd 0x14 // RX Data (output) +#define RFM22_gpio1_config_rxstate 0x15 // RX State (output) +#define RFM22_gpio1_config_rxfifoaf 0x16 // RX FIFO Almost Full (output) +#define RFM22_gpio1_config_antswt1 0x17 // Antenna 1 Switch used for antenna diversity (output) +#define RFM22_gpio1_config_antswt2 0x18 // Antenna 2 Switch used for antenna diversity (output) +#define RFM22_gpio1_config_vpd 0x19 // Valid Preamble Detected (output) +#define RFM22_gpio1_config_ipd 0x1A // Invalid Preamble Detected (output) +#define RFM22_gpio1_config_swd 0x1B // Sync Word Detected (output) +#define RFM22_gpio1_config_cca 0x1C // Clear Channel Assessment (output) +#define RFM22_gpio1_config_vdd 0x1D // VDD +#define RFM22_gpio1_config_pup 0x20 +#define RFM22_gpio1_config_drv0 0x00 // output drive level +#define RFM22_gpio1_config_drv1 0x40 // output drive level +#define RFM22_gpio1_config_drv2 0x80 // output drive level +#define RFM22_gpio1_config_drv3 0xC0 // output drive level + +#define RFM22_gpio2_config 0x0D // R/W +#define RFM22_gpio2_config_mc 0x00 // Microcontroller Clock (output) +#define RFM22_gpio2_config_wut 0x01 // Wake-Up Timer: 1 when WUT has expired (output) +#define RFM22_gpio2_config_lbd 0x02 // Low Battery Detect: 1 when battery is below threshold setting (output) +#define RFM22_gpio2_config_ddi 0x03 // Direct Digital Input +#define RFM22_gpio2_config_eife 0x04 // External Interrupt, falling edge (input) +#define RFM22_gpio2_config_eire 0x05 // External Interrupt, rising edge (input) +#define RFM22_gpio2_config_eisc 0x06 // External Interrupt, state change (input) +#define RFM22_gpio2_config_ai 0x07 // ADC Analog Input +#define RFM22_gpio2_config_atni 0x08 // Reserved (Analog Test N Input) +#define RFM22_gpio2_config_atpi 0x09 // Reserved (Analog Test P Input) +#define RFM22_gpio2_config_ddo 0x0A // Direct Digital Output +#define RFM22_gpio2_config_dto 0x0B // Reserved (Digital Test Output) +#define RFM22_gpio2_config_atno 0x0C // Reserved (Analog Test N Output) +#define RFM22_gpio2_config_atpo 0x0D // Reserved (Analog Test P Output) +#define RFM22_gpio2_config_rv 0xOE // Reference Voltage (output) +#define RFM22_gpio2_config_dclk 0x0F // TX/RX Data CLK output to be used in conjunction with TX/RX Data pin (output) +#define RFM22_gpio2_config_txd 0x10 // TX Data input for direct modulation (input) +#define RFM22_gpio2_config_err 0x11 // External Retransmission Request (input) +#define RFM22_gpio2_config_txstate 0x12 // TX State (output) +#define RFM22_gpio2_config_txfifoaf 0x13 // TX FIFO Almost Full (output) +#define RFM22_gpio2_config_rxd 0x14 // RX Data (output) +#define RFM22_gpio2_config_rxstate 0x15 // RX State (output) +#define RFM22_gpio2_config_rxfifoaf 0x16 // RX FIFO Almost Full (output) +#define RFM22_gpio2_config_antswt1 0x17 // Antenna 1 Switch used for antenna diversity (output) +#define RFM22_gpio2_config_antswt2 0x18 // Antenna 2 Switch used for antenna diversity (output) +#define RFM22_gpio2_config_vpd 0x19 // Valid Preamble Detected (output) +#define RFM22_gpio2_config_ipd 0x1A // Invalid Preamble Detected (output) +#define RFM22_gpio2_config_swd 0x1B // Sync Word Detected (output) +#define RFM22_gpio2_config_cca 0x1C // Clear Channel Assessment (output) +#define RFM22_gpio2_config_vdd 0x1D // VDD +#define RFM22_gpio2_config_pup 0x20 +#define RFM22_gpio2_config_drv0 0x00 // output drive level +#define RFM22_gpio2_config_drv1 0x40 // output drive level +#define RFM22_gpio2_config_drv2 0x80 // output drive level +#define RFM22_gpio2_config_drv3 0xC0 // output drive level + +#define RFM22_io_port_config 0x0E // R/W +#define RFM22_io_port_extitst2 0x40 // External Interrupt Status. If the GPIO2 is programmed to be external interrupt sources then the status can be read here. +#define RFM22_io_port_extitst1 0x20 // External Interrupt Status. If the GPIO1 is programmed to be external interrupt sources then the status can be read here. +#define RFM22_io_port_extitst0 0x10 // External Interrupt Status. If the GPIO0 is programmed to be external interrupt sources then the status can be read here. +#define RFM22_io_port_itsdo 0x08 // Interrupt Request Output on the SDO Pin. nIRQ output is present on the SDO pin if this bit is set and the nSEL input is inactive (high). +#define RFM22_io_port_dio2 0x04 // Direct I/O for GPIO2. If the GPIO2 is configured to be a direct output then the value on the GPIO pin can be set here. If the GPIO2 is configured to be a direct input then the value of the pin can be read here. +#define RFM22_io_port_dio1 0x02 // Direct I/O for GPIO1. If the GPIO1 is configured to be a direct output then the value on the GPIO pin can be set here. If the GPIO1 is configured to be a direct input then the value of the pin can be read here. +#define RFM22_io_port_dio0 0x01 // Direct I/O for GPIO0. If the GPIO0 is configured to be a direct output then the value on the GPIO pin can be set here. If the GPIO0 is configured to be a direct input then the value of the pin can be read here. +#define RFM22_io_port_default 0x00 // GPIO pins are default + +#define RFM22_adc_config 0x0F // R/W +#define RFM22_ac_adcgain0 0x00 +#define RFM22_ac_adcgain1 0x01 +#define RFM22_ac_adcgain2 0x02 +#define RFM22_ac_adcgain3 0x03 +#define RFM22_ac_adcref_bg 0x00 +#define RFM22_ac_adcref_vdd3 0x08 +#define RFM22_ac_adcref_vdd2 0x0C +#define RFM22_ac_adcsel_temp_sensor 0x00 +#define RFM22_ac_adcsel_gpio0 0x10 +#define RFM22_ac_adcsel_gpio1 0x20 +#define RFM22_ac_adcsel_gpio2 0x30 +#define RFM22_ac_adcsel_gpio01 0x40 +#define RFM22_ac_adcsel_gpio12 0x50 +#define RFM22_ac_adcsel_gpio02 0x60 +#define RFM22_ac_adcsel_gpio_gnd 0x70 +#define RFM22_ac_adcstartbusy 0x80 + +#define RFM22_adc_sensor_amp_offset 0x10 // R/W +#define RFM22_asao_adcoffs_mask 0x0F // ADC Sensor Amplifier Offset. The offset can be calculated as Offset = adcoffs[2:0] x VDD/1000; MSB = adcoffs[3] = Sign bit. + +#define RFM22_adc_value 0x11 // R .. Internal 8 bit ADC Output Value. + +#define RFM22_temp_sensor_calib 0x12 // R/W +#define RFM22_tsc_tstrim_mask 0x0F // Temperature Sensor Trim Value. +#define RFM22_tsc_entstrim 0x10 // Temperature Sensor Trim Enable. +#define RFM22_tsc_entsoffs 0x20 // Temperature Sensor Offset to Convert from K to C. +#define RFM22_tsc_tsrange0 0x00 // Temperature Sensor Range Selection. -40C to +64C 0.5C resolution +#define RFM22_tsc_tsrange1 0x40 // -40 to +85C with 1.0C resolution +#define RFM22_tsc_tsrange2 0x80 // 0C to 85C with 0.5C resolution +#define RFM22_tsc_tsrange3 0xC0 // -40F to 216F with 1.0F resolution + +#define RFM22_temp_value_offset 0x13 // R/W + +#define RFM22_wakeup_timer_period1 0x14 // R/W +#define RFM22_wakeup_timer_period2 0x15 // R/W +#define RFM22_wakeup_timer_period3 0x16 // R/W + +#define RFM22_wakeup_timer_value1 0x17 // R +#define RFM22_wakeup_timer_value2 0x18 // R + +#define RFM22_low_dutycycle_mode_duration 0x19 // R/W +#define RFM22_low_battery_detector_threshold 0x1A // R/W + +#define RFM22_battery_volateg_level 0x1B // R + +#define RFM22_if_filter_bandwidth 0x1C // R/W +#define RFM22_iffbw_filset_mask 0x0F +#define RFM22_iffbw_ndec_exp_mask 0x70 +#define RFM22_iffbw_dwn3_bypass 0x80 + +#define RFM22_afc_loop_gearshift_override 0x1D // R/W +#define RFM22_afc_lp_gs_ovrd_afcgearl_mask 0x07 // AFC Low Gear Setting. +#define RFM22_afc_lp_gs_ovrd_afcgearh_mask 0x38 // AFC High Gear Setting. +#define RFM22_afc_lp_gs_ovrd_enafc 0x40 // AFC Enable. +#define RFM22_afc_lp_gs_ovrd_afcbd 0x80 // If set, the tolerated AFC frequency error will be halved. + +#define RFM22_afc_timing_control 0x1E // R/W + +#define RFM22_clk_recovery_gearshift_override 0x1F // R/W +#define RFM22_clk_recovery_oversampling_ratio 0x20 // R/W +#define RFM22_clk_recovery_offset2 0x21 // R/W +#define RFM22_clk_recovery_offset1 0x22 // R/W +#define RFM22_clk_recovery_offset0 0x23 // R/W +#define RFM22_clk_recovery_timing_loop_gain1 0x24 // R/W +#define RFM22_clk_recovery_timing_loop_gain0 0x25 // R/W + +#define RFM22_rssi 0x26 // R +#define RFM22_rssi_threshold_clear_chan_indicator 0x27 // R/W + +#define RFM22_antenna_diversity_register1 0x28 // R +#define RFM22_antenna_diversity_register2 0x29 // R + +#define RFM22_afc_limiter 0x2A // R/W .. AFC_pull_in_range = �AFCLimiter[7:0] x (hbsel+1) x 625 Hz + +#define RFM22_afc_correction_read 0x2B // R + +#define RFM22_ook_counter_value1 0x2C // R/W +#define RFM22_ook_counter_value2 0x2D // R/W + +#define RFM22_slicer_peak_hold 0x2E // R/W + +#define RFM22_data_access_control 0x30 // R/W +#define RFM22_dac_crc_ccitt 0x00 // +#define RFM22_dac_crc_crc16 0x01 // +#define RFM22_dac_crc_iec16 0x02 // +#define RFM22_dac_crc_biacheva 0x03 // +#define RFM22_dac_encrc 0x04 // CRC Enable. Cyclic Redundancy Check generation is enabled if this bit is set. +#define RFM22_dac_enpactx 0x08 // Enable Packet TX Handling. If FIFO Mode (dtmod = 10) is being used automatic packet handling may be enabled. Setting enpactx = 1 will enable automatic packet handling in the TX path. Register 30�4D allow for various configurations of the packet structure. Setting enpactx = 0 will not do any packet handling in the TX path. It will only transmit what is loaded to the FIFO. +#define RFM22_dac_skip2ph 0x10 // Skip 2nd Phase of Preamble Detection. If set, we skip the second phase of the preamble detection (under certain conditions) if antenna diversity is enabled. +#define RFM22_dac_crcdonly 0x20 // CRC Data Only Enable. When this bit is set to 1 the CRC is calculated on and checked against the packet data fields only. +#define RFM22_dac_lsbfrst 0x40 // LSB First Enable. The LSB of the data will be transmitted/received first if this bit is set. +#define RFM22_dac_enpacrx 0x80 // Enable Packet RX Handling. If FIFO Mode (dtmod = 10) is being used automatic packet handling may be enabled. Setting enpacrx = 1 will enable automatic packet handling in the RX path. Register 30�4D allow for various configurations of the packet structure. Setting enpacrx = 0 will not do any packet handling in the RX path. It will only receive everything after the sync word and fill up the RX FIFO. + +#define RFM22_ezmac_status 0x31 // R +#define RFM22_ezmac_status_pksent 0x01 // Packet Sent. A 1 a packet has been sent by the radio. (Same bit as in register 03, but reading it does not reset the IRQ) +#define RFM22_ezmac_status_pktx 0x02 // Packet Transmitting. When 1 the radio is currently transmitting a packet. +#define RFM22_ezmac_status_crcerror 0x04 // CRC Error. When 1 a Cyclic Redundancy Check error has been detected. (Same bit as in register 03, but reading it does not reset the IRQ) +#define RFM22_ezmac_status_pkvalid 0x08 // Valid Packet Received. When a 1 a valid packet has been received by the receiver. (Same bit as in register 03, but reading it does not reset the IRQ) +#define RFM22_ezmac_status_pkrx 0x10 // Packet Receiving. When 1 the radio is currently receiving a valid packet. +#define RFM22_ezmac_status_pksrch 0x20 // Packet Searching. When 1 the radio is searching for a valid packet. +#define RFM22_ezmac_status_rxcrc1 0x40 // If high, it indicates the last CRC received is all one�s. May indicated Transmitter underflow in case of CRC error. + +#define RFM22_header_control1 0x32 // R/W +#define RFM22_header_cntl1_bcen_none 0x00 // No broadcast address enable. +#define RFM22_header_cntl1_bcen_0 0x10 // Broadcast address enable for header byte 0. +#define RFM22_header_cntl1_bcen_1 0x20 // Broadcast address enable for header byte 1. +#define RFM22_header_cntl1_bcen_2 0x40 // Broadcast address enable for header byte 2. +#define RFM22_header_cntl1_bcen_3 0x80 // Broadcast address enable for header byte 3. +#define RFM22_header_cntl1_hdch_none 0x00 // No Received Header check +#define RFM22_header_cntl1_hdch_0 0x01 // Received Header check for byte 0. +#define RFM22_header_cntl1_hdch_1 0x02 // Received Header check for byte 1. +#define RFM22_header_cntl1_hdch_2 0x04 // Received Header check for byte 2. +#define RFM22_header_cntl1_hdch_3 0x08 // Received Header check for byte 3. + +#define RFM22_header_control2 0x33 // R/W +#define RFM22_header_cntl2_prealen 0x01 // MSB of Preamble Length. See register Preamble Length. +#define RFM22_header_cntl2_synclen_3 0x00 // Synchronization Word 3 +#define RFM22_header_cntl2_synclen_32 0x02 // Synchronization Word 3 followed by 2 +#define RFM22_header_cntl2_synclen_321 0x04 // Synchronization Word 3 followed by 2 followed by 1 +#define RFM22_header_cntl2_synclen_3210 0x06 // Synchronization Word 3 followed by 2 followed by 1 followed by 0 +#define RFM22_header_cntl2_fixpklen 0x08 // Fix Packet Length. When fixpklen = 1 the packet length (pklen[7:0]) is not included in the header. When fixpklen = 0 the packet length is included in the header. +#define RFM22_header_cntl2_hdlen_none 0x00 // no header +#define RFM22_header_cntl2_hdlen_3 0x10 // header 3 +#define RFM22_header_cntl2_hdlen_32 0x20 // header 3 and 2 +#define RFM22_header_cntl2_hdlen_321 0x30 // header 3 and 2 and 1 +#define RFM22_header_cntl2_hdlen_3210 0x40 // header 3 and 2 and 1 and 0 +#define RFM22_header_cntl2_skipsyn 0x80 // If high, the system will ignore the syncword search timeout reset. The chip will not return to searching for Preamble, but instead will remain searching for Sync word. + +#define RFM22_preamble_length 0x34 // R/W + +#define RFM22_preamble_detection_ctrl1 0x35 // R/W +#define RFM22_pre_det_ctrl1_preath_mask 0xF8 // Number of nibbles processed during detection. +#define RFM22_pre_det_ctrl1_rssi_offset_mask 0x07 // Value added as offset to RSSI calculation. Every increment in this register results in an increment of +4 dB in the RSSI. + +#define RFM22_sync_word3 0x36 // R/W +#define RFM22_sync_word2 0x37 // R/W +#define RFM22_sync_word1 0x38 // R/W +#define RFM22_sync_word0 0x39 // R/W + +#define RFM22_transmit_header3 0x3A // R/W +#define RFM22_transmit_header2 0x3B // R/W +#define RFM22_transmit_header1 0x3C // R/W +#define RFM22_transmit_header0 0x3D // R/W + +#define RFM22_transmit_packet_length 0x3E // R/W + +#define RFM22_check_header3 0x3F // R/W +#define RFM22_check_header2 0x40 // R/W +#define RFM22_check_header1 0x41 // R/W +#define RFM22_check_header0 0x42 // R/W + +#define RFM22_header_enable3 0x43 // R/W +#define RFM22_header_enable2 0x44 // R/W +#define RFM22_header_enable1 0x45 // R/W +#define RFM22_header_enable0 0x46 // R/W + +#define RFM22_received_header3 0x47 // R +#define RFM22_received_header2 0x48 // R +#define RFM22_received_header1 0x49 // R +#define RFM22_received_header0 0x4A // R + +#define RFM22_received_packet_length 0x4B // R + +#define RFM22_adc8_control 0x4F // R/W + +#define RFM22_channel_filter_coeff_addr 0x60 // R/W +#define RFM22_ch_fil_coeff_ad_inv_pre_th_mask 0xF0 // +#define RFM22_ch_fil_coeff_ad_chfiladd_mask 0x0F // Channel Filter Coefficient Look-up Table Address. The address for channel filter coefficients used in the RX path. + +#define RFM22_xtal_osc_por_ctrl 0x62 // R/W +#define RFM22_xtal_osc_por_ctrl_pwst_mask 0xE0 // Internal Power States of the Chip. +#define RFM22_xtal_osc_por_ctrl_clkhyst 0x10 // Clock Hysteresis Setting. +#define RFM22_xtal_osc_por_ctrl_enbias2x 0x08 // 2 Times Higher Bias Current Enable. +#define RFM22_xtal_osc_por_ctrl_enamp2x 0x04 // 2 Times Higher Amplification Enable. +#define RFM22_xtal_osc_por_ctrl_bufovr 0x02 // Output Buffer Enable Override. +#define RFM22_xtal_osc_por_ctrl_enbuf 0x01 // Output Buffer Enable. + +#define RFM22_agc_override1 0x69 // R/W +#define RFM22_agc_ovr1_sgi 0x40 // AGC Loop, Set Gain Increase. If set to 0 then gain increasing will not be allowed. If set to 1 then gain increasing is allowed, default is 0. +#define RFM22_agc_ovr1_agcen 0x20 // Automatic Gain Control Enable. When this bit is set then the result of the control can be read out from bits [4:0], otherwise the gain can be controlled manually by writing into bits [4:0]. +#define RFM22_agc_ovr1_lnagain 0x10 // LNA Gain Select. 0 = min gain = 5dB, 1 = max gain = 25 dB. +#define RFM22_agc_ovr1_pga_mask 0x0F // PGA Gain Override Value. + +#define RFM22_tx_power 0x6D // R/W +#define RFM22_tx_pwr_lna_sw 0x08 // LNA Switch Controller. If set, lna_sw control from the digital will go high during TX modes, and low during other times. If reset, the digital control signal is low at all times. + +#define RFM22_tx_data_rate1 0x6E // R/W +#define RFM22_tx_data_rate0 0x6F // R/W + +#define RFM22_modulation_mode_control1 0x70 // R/W +#define RFM22_mmc1_enwhite 0x01 // Data Whitening is Enabled if this bit is set. +#define RFM22_mmc1_enmanch 0x02 // Manchester Coding is Enabled if this bit is set. +#define RFM22_mmc1_enmaninv 0x04 // Manchester Data Inversion is Enabled if this bit is set. +#define RFM22_mmc1_manppol 0x08 // Manchester Preamble Polarity (will transmit a series of 1 if set, or series of 0 if reset). +#define RFM22_mmc1_enphpwdn 0x10 // If set, the Packet Handler will be powered down when chip is in low power mode. +#define RFM22_mmc1_txdtrtscale 0x20 // This bit should be set for Data Rates below 30 kbps. + +#define RFM22_modulation_mode_control2 0x71 // R/W +#define RFM22_mmc2_modtyp_mask 0x03 // Modulation type. +#define RFM22_mmc2_modtyp_none 0x00 // +#define RFM22_mmc2_modtyp_ook 0x01 // +#define RFM22_mmc2_modtyp_fsk 0x02 // +#define RFM22_mmc2_modtyp_gfsk 0x03 // +#define RFM22_mmc2_fd 0x04 // MSB of Frequency Deviation Setting, see "Register 72h. Frequency Deviation". +#define RFM22_mmc2_eninv 0x08 // Invert TX and RX Data. +#define RFM22_mmc2_dtmod_mask 0x30 // Modulation source. +#define RFM22_mmc2_dtmod_dm_gpio 0x00 // +#define RFM22_mmc2_dtmod_dm_sdi 0x10 // +#define RFM22_mmc2_dtmod_fifo 0x20 // +#define RFM22_mmc2_dtmod_pn9 0x30 // +#define RFM22_mmc2_trclk_mask 0xC0 // TX Data Clock Configuration. +#define RFM22_mmc2_trclk_clk_none 0x00 // +#define RFM22_mmc2_trclk_clk_gpio 0x40 // +#define RFM22_mmc2_trclk_clk_sdo 0x80 // +#define RFM22_mmc2_trclk_clk_nirq 0xC0 // + +#define RFM22_frequency_deviation 0x72 // R/W + +#define RFM22_frequency_offset1 0x73 // R/W +#define RFM22_frequency_offset2 0x74 // R/W + +#define RFM22_frequency_band_select 0x75 // R/W +#define RFM22_fb_mask 0x1F +#define RFM22_fbs_hbsel 0x20 +#define RFM22_fbs_sbse 0x40 + +#define RFM22_nominal_carrier_frequency1 0x76 // R/W +#define RFM22_nominal_carrier_frequency0 0x77 // R/W + +#define RFM22_frequency_hopping_channel_select 0x79 // R/W +#define RFM22_frequency_hopping_step_size 0x7A // R/W + +#define RFM22_tx_fifo_control1 0x7C // R/W .. TX FIFO Almost Full Threshold (0 - 63) +#define RFM22_tx_fifo_control1_mask 0x3F + +#define RFM22_tx_fifo_control2 0x7D // R/W .. TX FIFO Almost Empty Threshold (0 - 63) +#define RFM22_tx_fifo_control2_mask 0x3F + +#define RFM22_rx_fifo_control 0x7E // R/W .. RX FIFO Almost Full Threshold (0 - 63) +#define RFM22_rx_fifo_control_mask 0x3F + +#define RFM22_fifo_access 0x7F // R/W + + +#endif /* PIOS_RFM22B_REGS_H */ + +/** + * @} + * @} + */ diff --git a/flight/pios/inc/pios_semaphore.h b/flight/pios/inc/pios_semaphore.h new file mode 100644 index 000000000..c0468e1cc --- /dev/null +++ b/flight/pios/inc/pios_semaphore.h @@ -0,0 +1,71 @@ +/** + ****************************************************************************** + * @file pios_semaphore.h + * @author Tau Labs, http://taulabs.org, Copyright (C) 2013-2014 + * @addtogroup PIOS PIOS Core hardware abstraction layer + * @{ + * @addtogroup PIOS_Semaphore Semaphore Abstraction + * @{ + * @brief Abstracts the concept of a binary semaphore to hide different implementations + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef PIOS_SEMAPHORE_H_ +#define PIOS_SEMAPHORE_H_ + +#define PIOS_SEMAPHORE_TIMEOUT_MAX 0xffffffff + +#include +#include + +struct pios_semaphore { +#if defined(PIOS_INCLUDE_FREERTOS) + uintptr_t sema_handle; +#elif defined(PIOS_INCLUDE_CHIBIOS) + BinarySemaphore sema; +#elif defined(PIOS_INCLUDE_IRQ) + uint32_t sema_count; +#endif /* defined(PIOS_INCLUDE_IRQ) */ +}; + +/* + * The following functions implement the concept of a binary semaphore usable + * with PIOS_INCLUDE_FREERTOS, PIOS_INCLUDE_CHIBIOS or PIOS_INCLUDE_IRQ. + * + * Note that this is not the same as: + * - counting semaphore + * - mutex + * - recursive mutex + * + * see FreeRTOS documentation for details: http://www.freertos.org/a00113.html + * see ChibiOS documentation for details: http://chibios.sourceforge.net/html/group__synchronization.html + */ + +struct pios_semaphore *PIOS_Semaphore_Create(void); +bool PIOS_Semaphore_Take(struct pios_semaphore *sema, uint32_t timeout_ms); +bool PIOS_Semaphore_Give(struct pios_semaphore *sema); + +bool PIOS_Semaphore_Take_FromISR(struct pios_semaphore *sema, bool *woken); +bool PIOS_Semaphore_Give_FromISR(struct pios_semaphore *sema, bool *woken); + +#endif /* PIOS_SEMAPHORE_H_ */ + +/** + * @} + * @} + */ diff --git a/flight/pios/inc/pios_sensors.h b/flight/pios/inc/pios_sensors.h index eb565c14a..46789cfa5 100644 --- a/flight/pios/inc/pios_sensors.h +++ b/flight/pios/inc/pios_sensors.h @@ -54,15 +54,16 @@ typedef struct PIOS_SENSORS_Driver { } PIOS_SENSORS_Driver; typedef enum PIOS_SENSORS_TYPE { - PIOS_SENSORS_TYPE_3AXIS_ACCEL = 0x01, - PIOS_SENSORS_TYPE_3AXIS_GYRO = 0x02, + PIOS_SENSORS_TYPE_3AXIS_ACCEL = 0x01, + PIOS_SENSORS_TYPE_3AXIS_GYRO = 0x02, PIOS_SENSORS_TYPE_3AXIS_GYRO_ACCEL = 0x03, - PIOS_SENSORS_TYPE_3AXIS_MAG = 0x04, - PIOS_SENSORS_TYPE_1AXIS_BARO = 0x08, + PIOS_SENSORS_TYPE_3AXIS_MAG = 0x04, + PIOS_SENSORS_TYPE_3AXIS_AUXMAG = 0x08, + PIOS_SENSORS_TYPE_1AXIS_BARO = 0x10, } PIOS_SENSORS_TYPE; #define PIOS_SENSORS_TYPE_1D (PIOS_SENSORS_TYPE_1AXIS_BARO) -#define PIOS_SENSORS_TYPE_3D (PIOS_SENSORS_TYPE_3AXIS_ACCEL | PIOS_SENSORS_TYPE_3AXIS_GYRO | PIOS_SENSORS_TYPE_3AXIS_MAG) +#define PIOS_SENSORS_TYPE_3D (PIOS_SENSORS_TYPE_3AXIS_ACCEL | PIOS_SENSORS_TYPE_3AXIS_GYRO | PIOS_SENSORS_TYPE_3AXIS_MAG | PIOS_SENSORS_TYPE_3AXIS_AUXMAG) typedef struct PIOS_SENSORS_Instance { const PIOS_SENSORS_Driver *driver; @@ -75,14 +76,15 @@ typedef struct PIOS_SENSORS_Instance { * A 3d Accel sample with temperature */ typedef struct PIOS_SENSORS_3Axis_SensorsWithTemp { - uint16_t count; // number of sensor instances + uint32_t timestamp; // PIOS_DELAY_GetRaw() time of sensor read + uint16_t count; // number of sensor instances int16_t temperature; // Degrees Celsius * 100 Vector3i16 sample[]; } PIOS_SENSORS_3Axis_SensorsWithTemp; typedef struct PIOS_SENSORS_1Axis_SensorsWithTemp { - float temperature; // Degrees Celsius float sample; // sample + float temperature; // Degrees Celsius } PIOS_SENSORS_1Axis_SensorsWithTemp; /** diff --git a/flight/pios/inc/pios_task_monitor.h b/flight/pios/inc/pios_task_monitor.h index 42edc104f..17306ba5f 100644 --- a/flight/pios/inc/pios_task_monitor.h +++ b/flight/pios/inc/pios_task_monitor.h @@ -1,15 +1,17 @@ /** ****************************************************************************** - * @addtogroup OpenPilotSystem OpenPilot System + * @addtogroup LibrePilotSystem LibrePilot System * @{ - * @addtogroup OpenPilotLibraries OpenPilot System Libraries + * @addtogroup LibrePilotLibraries LibrePilot System Libraries * @{ - * @file task_monitor.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2013. + * @file pios_task_monitor.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2015. * @brief Task monitoring functions * @see The GNU Public License (GPL) Version 3 * *****************************************************************************/ + /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,7 +31,8 @@ #define PIOS_TASK_MONITOR_H #include - +extern volatile uint32_t idleCounter; +extern volatile bool idleCounterClear; /** * Initializes the Task Monitor. * @@ -109,4 +112,26 @@ extern void PIOS_TASK_MONITOR_ForEachTask(TaskMonitorTaskInfoCallback callback, */ extern uint8_t PIOS_TASK_MONITOR_GetIdlePercentage(); +static inline void PIOS_TASK_MONITOR_IdleHook() +{ + if (!idleCounterClear) { + ++idleCounter; + } else { + idleCounter = 0; + idleCounterClear = false; + } +} + +/** + * Calibrate the idle counter. it should be run with a single task (caller) created + */ +extern void PIOS_TASK_MONITOR_CalibrateIdleCounter(); +/** + * return the number of idle hook execution per second + * @return number of idle hook execution per second + */ +extern uint32_t PIOS_TASK_MONITOR_GetIdleTicksCount(); + +extern uint32_t PIOS_TASK_MONITOR_GetZeroLoadTicksCount(); + #endif // PIOS_TASK_MONITOR_H diff --git a/flight/pios/inc/pios_thread.h b/flight/pios/inc/pios_thread.h new file mode 100644 index 000000000..f52ff2d70 --- /dev/null +++ b/flight/pios/inc/pios_thread.h @@ -0,0 +1,93 @@ +/** + ****************************************************************************** + * @file pios_thread.h + * @author Tau Labs, http://taulabs.org, Copyright (C) 2014 + * @addtogroup PIOS PIOS Core hardware abstraction layer + * @{ + * @addtogroup PIOS_Thread Thread Abstraction + * @{ + * @brief Abstracts the concept of a thread to hide different implementations + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PIOS_THREAD_H_ +#define PIOS_THREAD_H_ + +#define PIOS_THREAD_TIMEOUT_MAX 0xffffffff + +#include +#include + +#if defined(PIOS_INCLUDE_FREERTOS) + +#include "FreeRTOSConfig.h" + +enum pios_thread_prio_e { + PIOS_THREAD_PRIO_LOW = 1, + PIOS_THREAD_PRIO_NORMAL = 2, + PIOS_THREAD_PRIO_HIGH = 3, + PIOS_THREAD_PRIO_HIGHEST = 4, /* @note: this has to match (configMAX_PRIORITIES - 1) */ +}; + +#define PIOS_THREAD_STACK_SIZE_MIN (configMINIMAL_STACK_SIZE * 4) + +struct pios_thread { + uintptr_t task_handle; +}; + +#elif defined(PIOS_INCLUDE_CHIBIOS) + +#include "ch.h" + +enum pios_thread_prio_e { + PIOS_THREAD_PRIO_LOW = LOWPRIO, + PIOS_THREAD_PRIO_NORMAL = NORMALPRIO, + PIOS_THREAD_PRIO_HIGH = NORMALPRIO + 32, + PIOS_THREAD_PRIO_HIGHEST = HIGHPRIO, +}; + +#define PIOS_THREAD_STACK_SIZE_MIN THD_WA_SIZE(4096 + PORT_INT_REQUIRED_STACK) + +struct pios_thread { + Thread *threadp; +}; + +#endif /* defined(PIOS_INCLUDE_CHIBIOS) */ + +/* + * The following functions implement the concept of a thread usable + * with PIOS_INCLUDE_FREERTOS. + * + * see FreeRTOS documentation for details: http://www.freertos.org/a00019.html + */ + +struct pios_thread *PIOS_Thread_Create(void (*fp)(void *), const char *namep, size_t stack_bytes, void *argp, enum pios_thread_prio_e prio); +void PIOS_Thread_Delete(struct pios_thread *threadp); +uint32_t PIOS_Thread_Systime(void); +void PIOS_Thread_Sleep(uint32_t time_ms); +void PIOS_Thread_Sleep_Until(uint32_t *previous_ms, uint32_t increment_ms); +uint32_t PIOS_Thread_Get_Stack_Usage(struct pios_thread *threadp); +uint32_t PIOS_Thread_Get_Runtime(struct pios_thread *threadp); +void PIOS_Thread_Scheduler_Suspend(void); +void PIOS_Thread_Scheduler_Resume(void); + +#endif /* PIOS_THREAD_H_ */ + +/** + * @} + * @} + */ diff --git a/flight/pios/inc/pios_usb_defs.h b/flight/pios/inc/pios_usb_defs.h index 289a96439..cca131e85 100644 --- a/flight/pios/inc/pios_usb_defs.h +++ b/flight/pios/inc/pios_usb_defs.h @@ -1,5 +1,5 @@ /** - ****************************************************************************** + **************************************************************************************** * @addtogroup PIOS PIOS Core hardware abstraction layer * @{ * @addtogroup PIOS_USB_DEFS USB standard types and definitions @@ -7,12 +7,12 @@ * @{ * * @file pios_usb_defs.h - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2016. * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @brief USB Standard types and definitions * @see The GNU Public License (GPL) Version 3 * - *****************************************************************************/ + ***************************************************************************************/ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -83,6 +83,9 @@ enum usb_ep_attr { #define htousbl(v) (v) #endif +#define usbstoh(v) htousbs(v) +#define usbltoh(v) htousbl(v) + #define USB_EP_IN(ep) ((uint8_t)(0x80 | ((ep) & 0xF))) #define USB_EP_OUT(ep) ((uint8_t)(0x00 | ((ep) & 0xF))) @@ -358,8 +361,9 @@ enum usb_product_ids { USB_PRODUCT_ID_OPLINK = 0x415C, USB_PRODUCT_ID_CC3D = 0x415D, USB_PRODUCT_ID_REVOLUTION = 0x415E, - USB_PRODUCT_ID_OSD = 0x4194, - USB_PRODUCT_ID_SPARE = 0x4195, + USB_PRODUCT_ID_SPARKY2 = 0x41D0, // was 0x415E during LP testing + USB_PRODUCT_ID_OSD = 0x4194, + USB_PRODUCT_ID_SPARE = 0x4195, } __attribute__((packed)); enum usb_op_board_ids { @@ -368,7 +372,8 @@ enum usb_op_board_ids { USB_OP_BOARD_ID_OPLINK = 3, USB_OP_BOARD_ID_COPTERCONTROL = 4, USB_OP_BOARD_ID_REVOLUTION = 5, - USB_OP_BOARD_ID_OSD = 6, + USB_OP_BOARD_ID_SPARKY2 = 5, + USB_OP_BOARD_ID_OSD = 6, } __attribute__((packed)); enum usb_op_board_modes { diff --git a/flight/pios/osx/inc/pios_com.h b/flight/pios/osx/inc/pios_com.h index edac1e181..e10247bd4 100644 --- a/flight/pios/osx/inc/pios_com.h +++ b/flight/pios/osx/inc/pios_com.h @@ -35,13 +35,13 @@ typedef uint16_t (*pios_com_callback)(uint32_t context, uint8_t *buf, uint16_t buf_len, uint16_t *headroom, bool *task_woken); struct pios_com_driver { - void (*init)(uint32_t id); - void (*set_baud)(uint32_t id, uint32_t baud); - void (*tx_start)(uint32_t id, uint16_t tx_bytes_avail); - void (*rx_start)(uint32_t id, uint16_t rx_bytes_avail); - void (*bind_rx_cb)(uint32_t id, pios_com_callback rx_in_cb, uint32_t context); - void (*bind_tx_cb)(uint32_t id, pios_com_callback tx_out_cb, uint32_t context); - bool (*available)(uint32_t id); + void (*init)(uint32_t id); + void (*set_baud)(uint32_t id, uint32_t baud); + void (*tx_start)(uint32_t id, uint16_t tx_bytes_avail); + void (*rx_start)(uint32_t id, uint16_t rx_bytes_avail); + void (*bind_rx_cb)(uint32_t id, pios_com_callback rx_in_cb, uint32_t context); + void (*bind_tx_cb)(uint32_t id, pios_com_callback tx_out_cb, uint32_t context); + uint32_t (*available)(uint32_t id); }; /* Public Functions */ @@ -56,7 +56,12 @@ extern int32_t PIOS_COM_SendString(uint32_t com_id, const char *str); extern int32_t PIOS_COM_SendFormattedStringNonBlocking(uint32_t com_id, const char *format, ...); extern int32_t PIOS_COM_SendFormattedString(uint32_t com_id, const char *format, ...); extern uint16_t PIOS_COM_ReceiveBuffer(uint32_t com_id, uint8_t *buf, uint16_t buf_len, uint32_t timeout_ms); -extern bool PIOS_COM_Available(uint32_t com_id); +extern uint32_t PIOS_COM_Available(uint32_t com_id); + +#define COM_AVAILABLE_NONE (0) +#define COM_AVAILABLE_RX (1 << 0) +#define COM_AVAILABLE_TX (1 << 1) +#define COM_AVAILABLE_RXTX (COM_AVAILABLE_RX | COM_AVAILABLE_TX) #endif /* PIOS_COM_H */ diff --git a/flight/pios/osx/osx/pios_com.c b/flight/pios/osx/osx/pios_com.c index 8eab84a4e..8cd754055 100644 --- a/flight/pios/osx/osx/pios_com.c +++ b/flight/pios/osx/osx/pios_com.c @@ -509,18 +509,26 @@ check_again: * used to check a link is established even if the device * is valid. */ -bool PIOS_COM_Available(uint32_t com_id) +uint32_t PIOS_COM_Available(uint32_t com_id) { struct pios_com_dev *com_dev = PIOS_COM_find_dev(com_id); if (!PIOS_COM_validate(com_dev)) { - return false; + return COM_AVAILABLE_NONE; } // If a driver does not provide a query method assume always // available if valid if (com_dev->driver->available == NULL) { - return true; + if (com_dev->has_rx && com_dev->has_tx) { + return COM_AVAILABLE_RXTX; + } else if (com_dev->has_rx) { + return COM_AVAILABLE_RX; + } else if (com_dev->has_tx) { + return COM_AVAILABLE_TX; + } + + return COM_AVAILABLE_NONE; /* can this really happen? */ } return (com_dev->driver->available)(com_dev->lower_id); diff --git a/flight/pios/pios.h b/flight/pios/pios.h index ed3e8fd52..1baab4ac0 100644 --- a/flight/pios/pios.h +++ b/flight/pios/pios.h @@ -1,8 +1,9 @@ /** ****************************************************************************** * @file pios.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2013 - * @author PhoenixPilot, http://github.com/PhoenixPilot, Copyright (C) 2012 + * @author The LibrePilot Project, http://www.librepilot.org, Copyright (C) 2015 + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2013 + * PhoenixPilot, http://github.com/PhoenixPilot, Copyright (C) 2012 * @brief Main PiOS header. * @see The GNU Public License (GPL) Version 3 *****************************************************************************/ @@ -228,10 +229,22 @@ extern "C" { #include #endif +#ifdef PIOS_INCLUDE_HOTT +#include +#endif + +#ifdef PIOS_INCLUDE_EXBUS +#include +#endif + #ifdef PIOS_INCLUDE_SRXL #include #endif +#ifdef PIOS_INCLUDE_IBUS +#include +#endif + /* PIOS abstract receiver interface */ #ifdef PIOS_INCLUDE_RCVR #include diff --git a/flight/pios/posix/pios_com.c b/flight/pios/posix/pios_com.c index 8eab84a4e..8cd754055 100644 --- a/flight/pios/posix/pios_com.c +++ b/flight/pios/posix/pios_com.c @@ -509,18 +509,26 @@ check_again: * used to check a link is established even if the device * is valid. */ -bool PIOS_COM_Available(uint32_t com_id) +uint32_t PIOS_COM_Available(uint32_t com_id) { struct pios_com_dev *com_dev = PIOS_COM_find_dev(com_id); if (!PIOS_COM_validate(com_dev)) { - return false; + return COM_AVAILABLE_NONE; } // If a driver does not provide a query method assume always // available if valid if (com_dev->driver->available == NULL) { - return true; + if (com_dev->has_rx && com_dev->has_tx) { + return COM_AVAILABLE_RXTX; + } else if (com_dev->has_rx) { + return COM_AVAILABLE_RX; + } else if (com_dev->has_tx) { + return COM_AVAILABLE_TX; + } + + return COM_AVAILABLE_NONE; /* can this really happen? */ } return (com_dev->driver->available)(com_dev->lower_id); diff --git a/flight/pios/stm32f0x/pios_exti.c b/flight/pios/stm32f0x/pios_exti.c index 863f88a92..8abf9e0f9 100644 --- a/flight/pios/stm32f0x/pios_exti.c +++ b/flight/pios/stm32f0x/pios_exti.c @@ -34,15 +34,9 @@ #ifdef PIOS_INCLUDE_EXTI /* Map EXTI line to full config */ -#define EXTI_MAX_LINES 16 -#define PIOS_EXTI_INVALID 0xFF -static uint8_t pios_exti_line_to_cfg_map[EXTI_MAX_LINES] = { - [0 ... EXTI_MAX_LINES - 1] = PIOS_EXTI_INVALID, -}; +#define EXTI_MAX_LINES 16 -/* Table of exti configs registered at compile time */ -extern struct pios_exti_cfg __start__exti __attribute__((weak)); -extern struct pios_exti_cfg __stop__exti __attribute__((weak)); +static pios_exti_vector_t pios_exti_vector[EXTI_MAX_LINES]; static uint8_t PIOS_EXTI_line_to_index(uint32_t line) { @@ -147,57 +141,62 @@ uint8_t PIOS_EXTI_gpio_pin_to_exti_source_pin(uint32_t gpio_pin) int32_t PIOS_EXTI_Init(const struct pios_exti_cfg *cfg) { PIOS_Assert(cfg); - PIOS_Assert(&__start__exti); - PIOS_Assert(cfg >= &__start__exti); - PIOS_Assert(cfg < &__stop__exti); - - uint8_t cfg_index = cfg - &__start__exti; /* Connect this config to the requested vector */ uint8_t line_index = PIOS_EXTI_line_to_index(cfg->line); - if (pios_exti_line_to_cfg_map[line_index] != PIOS_EXTI_INVALID) { + if (pios_exti_vector[line_index]) { /* Someone else already has this mapped */ - goto out_fail; + return -1; } - /* Bind the config to the exti line */ - pios_exti_line_to_cfg_map[line_index] = cfg_index; + /* Bind the vector to the exti line */ + pios_exti_vector[line_index] = cfg->vector; /* Initialize the GPIO pin */ - GPIO_Init(cfg->pin.gpio, (GPIO_InitTypeDef *)&cfg->pin.init); + GPIO_Init(cfg->pin.gpio, &cfg->pin.init); /* Set up the EXTI interrupt source */ uint8_t exti_source_port = PIOS_EXTI_gpio_port_to_exti_source_port(cfg->pin.gpio); + /* Following is not entirely correct! There is cfg->pin.pin_source to serve this purpose, and GPIO_Pin can also contain more than one bit set */ uint8_t exti_source_pin = PIOS_EXTI_gpio_pin_to_exti_source_pin(cfg->pin.init.GPIO_Pin); SYSCFG_EXTILineConfig(exti_source_port, exti_source_pin); EXTI_Init((EXTI_InitTypeDef *)&cfg->exti.init); /* Enable the interrupt channel */ - NVIC_Init((NVIC_InitTypeDef *)&cfg->irq.init); + NVIC_Init(&cfg->irq.init); return 0; +} + +int32_t PIOS_EXTI_DeInit(const struct pios_exti_cfg *cfg) +{ + uint8_t line_index = PIOS_EXTI_line_to_index(cfg->line); + + if (pios_exti_vector[line_index] == cfg->vector) { + EXTI_InitTypeDef disable = cfg->exti.init; + disable.EXTI_LineCmd = DISABLE; + + EXTI_Init(&disable); + pios_exti_vector[line_index] = 0; + + return 0; + } -out_fail: return -1; } static bool PIOS_EXTI_generic_irq_handler(uint8_t line_index) { - uint8_t cfg_index = pios_exti_line_to_cfg_map[line_index]; - - PIOS_Assert(&__start__exti); - - if (cfg_index > NELEMENTS(pios_exti_line_to_cfg_map) || - cfg_index == PIOS_EXTI_INVALID) { - /* Unconfigured interrupt just fired! */ - return false; + if (pios_exti_vector[line_index]) { + return pios_exti_vector[line_index](); } - struct pios_exti_cfg *cfg = &__start__exti + cfg_index; - return cfg->vector(); + /* Unconfigured interrupt just fired! */ + return false; } + /* Bind Interrupt Handlers */ #ifdef PIOS_INCLUDE_FREERTOS diff --git a/flight/pios/stm32f0x/pios_i2c.c b/flight/pios/stm32f0x/pios_i2c.c index b73355262..385c5295e 100644 --- a/flight/pios/stm32f0x/pios_i2c.c +++ b/flight/pios/stm32f0x/pios_i2c.c @@ -458,17 +458,17 @@ void PIOS_I2C_GetDiagnostics(struct pios_i2c_fault_history *data, uint8_t *count { #if defined(PIOS_I2C_DIAGNOSTICS) memcpy(data, &i2c_adapter_fault_history, sizeof(i2c_adapter_fault_history)); - counts[0] = i2c_bad_event_counter; - counts[1] = i2c_fsm_fault_count; - counts[2] = i2c_error_interrupt_counter; - counts[3] = i2c_nack_counter; - counts[4] = i2c_timeout_counter; + counts[PIOS_I2C_BAD_EVENT_COUNTER] = i2c_bad_event_counter; + counts[PIOS_I2C_FSM_FAULT_COUNT] = i2c_fsm_fault_count; + counts[PIOS_I2C_ERROR_INTERRUPT_COUNTER] = i2c_error_interrupt_counter; + counts[PIOS_I2C_NACK_COUNTER] = i2c_nack_counter; + counts[PIOS_I2C_TIMEOUT_COUNTER] = i2c_timeout_counter; #else struct pios_i2c_fault_history i2c_adapter_fault_history; - i2c_adapter_fault_history.type = PIOS_I2C_ERROR_EVENT; + i2c_adapter_fault_history.type = PIOS_I2C_ERROR_EVENT; memcpy(data, &i2c_adapter_fault_history, sizeof(i2c_adapter_fault_history)); - counts[0] = counts[1] = counts[2] = 0; + memset(counts, 0, sizeof(*counts) * PIOS_I2C_ERROR_COUNT_NUMELEM); #endif } diff --git a/flight/pios/stm32f10x/link_STM3210E_OP_BL_sections.ld b/flight/pios/stm32f10x/link_STM3210E_OP_BL_sections.ld deleted file mode 100644 index eabe17a83..000000000 --- a/flight/pios/stm32f10x/link_STM3210E_OP_BL_sections.ld +++ /dev/null @@ -1,356 +0,0 @@ -/* This is the size of the stack for early init and for all FreeRTOS IRQs */ -_irq_stack_size = 0x800; - -/* Check valid alignment for VTOR */ -ASSERT(ORIGIN(BL_FLASH) == ALIGN(ORIGIN(BL_FLASH), 0x80), "Start of memory region flash not aligned for startup vector table"); - -/* -this sends all unreferenced IRQHandlers to reset -*/ - - -PROVIDE ( Undefined_Handler = 0 ) ; -PROVIDE ( SWI_Handler = 0 ) ; -PROVIDE ( IRQ_Handler = 0 ) ; -PROVIDE ( Prefetch_Handler = 0 ) ; -PROVIDE ( Abort_Handler = 0 ) ; -PROVIDE ( FIQ_Handler = 0 ) ; - -PROVIDE ( NMI_Handler = 0 ) ; -PROVIDE ( HardFault_Handler = 0 ) ; -PROVIDE ( MemManage_Handler = 0 ) ; -PROVIDE ( BusFault_Handler = 0 ) ; -PROVIDE ( UsageFault_Handler = 0 ) ; -PROVIDE ( vPortSVCHandler = 0 ) ; -PROVIDE ( DebugMon_Handler = 0 ) ; -PROVIDE ( xPortPendSVHandler = 0 ) ; -PROVIDE ( xPortSysTickHandler = 0 ) ; - -PROVIDE ( WWDG_IRQHandler = 0 ) ; -PROVIDE ( PVD_IRQHandler = 0 ) ; -PROVIDE ( TAMPER_IRQHandler = 0 ) ; -PROVIDE ( RTC_IRQHandler = 0 ) ; -PROVIDE ( FLASH_IRQHandler = 0 ) ; -PROVIDE ( RCC_IRQHandler = 0 ) ; -PROVIDE ( EXTI0_IRQHandler = 0 ) ; -PROVIDE ( EXTI1_IRQHandler = 0 ) ; -PROVIDE ( EXTI2_IRQHandler = 0 ) ; -PROVIDE ( EXTI3_IRQHandler = 0 ) ; -PROVIDE ( EXTI4_IRQHandler = 0 ) ; -PROVIDE ( DMAChannel1_IRQHandler = 0 ) ; -PROVIDE ( DMAChannel2_IRQHandler = 0 ) ; -PROVIDE ( DMAChannel3_IRQHandler = 0 ) ; -PROVIDE ( DMAChannel4_IRQHandler = 0 ) ; -PROVIDE ( DMAChannel5_IRQHandler = 0 ) ; -PROVIDE ( DMAChannel6_IRQHandler = 0 ) ; -PROVIDE ( DMAChannel7_IRQHandler = 0 ) ; -PROVIDE ( ADC_IRQHandler = 0 ) ; -PROVIDE ( USB_HP_CAN1_TX_IRQHandler = 0 ) ; -PROVIDE ( USB_LP_CAN1_RX0_IRQHandler = 0 ) ; -PROVIDE ( CAN1_RX1_IRQHandler = 0 ) ; -PROVIDE ( CAN1_SCE_IRQHandler = 0 ) ; -PROVIDE ( EXTI9_5_IRQHandler = 0 ) ; -PROVIDE ( TIM1_BRK_IRQHandler = 0 ) ; -PROVIDE ( TIM1_UP_IRQHandler = 0 ) ; -PROVIDE ( TIM1_TRG_COM_IRQHandler = 0 ) ; -PROVIDE ( TIM1_CC_IRQHandler = 0 ) ; -PROVIDE ( TIM2_IRQHandler = 0 ) ; -PROVIDE ( TIM3_IRQHandler = 0 ) ; -PROVIDE ( TIM4_IRQHandler = 0 ) ; -PROVIDE ( I2C1_EV_IRQHandler = 0 ) ; -PROVIDE ( I2C1_ER_IRQHandler = 0 ) ; -PROVIDE ( I2C2_EV_IRQHandler = 0 ) ; -PROVIDE ( I2C2_ER_IRQHandler = 0 ) ; -PROVIDE ( SPI1_IRQHandler = 0 ) ; -PROVIDE ( SPI2_IRQHandler = 0 ) ; -PROVIDE ( USART1_IRQHandler = 0 ) ; -PROVIDE ( USART2_IRQHandler = 0 ) ; -PROVIDE ( USART3_IRQHandler = 0 ) ; -PROVIDE ( EXTI15_10_IRQHandler = 0 ) ; -PROVIDE ( RTCAlarm_IRQHandler = 0 ) ; -PROVIDE ( USBWakeUp_IRQHandler = 0 ) ; -PROVIDE ( TIM8_BRK_IRQHandler = 0 ) ; -PROVIDE ( TIM8_UP_IRQHandler = 0 ) ; -PROVIDE ( TIM8_TRG_COM_IRQHandler = 0 ) ; -PROVIDE ( TIM8_CC_IRQHandler = 0 ) ; -PROVIDE ( ADC3_IRQHandler = 0 ) ; -PROVIDE ( FSMC_IRQHandler = 0 ) ; -PROVIDE ( SDIO_IRQHandler = 0 ) ; -PROVIDE ( TIM5_IRQHandler = 0 ) ; -PROVIDE ( SPI3_IRQHandler = 0 ) ; -PROVIDE ( UART4_IRQHandler = 0 ) ; -PROVIDE ( UART5_IRQHandler = 0 ) ; -PROVIDE ( TIM6_IRQHandler = 0 ) ; -PROVIDE ( TIM7_IRQHandler = 0 ) ; -PROVIDE ( DMA2_Channel1_IRQHandler = 0 ) ; -PROVIDE ( DMA2_Channel2_IRQHandler = 0 ) ; -PROVIDE ( DMA2_Channel3_IRQHandler = 0 ) ; -PROVIDE ( DMA2_Channel4_5_IRQHandler = 0 ) ; - - - -/******************************************************************************/ -/* Peripheral memory map */ -/******************************************************************************/ -/*this allows to compile the ST lib in "non-debug" mode*/ - - -/* Peripheral and SRAM base address in the alias region */ -PERIPH_BB_BASE = 0x42000000; -SRAM_BB_BASE = 0x22000000; - -/* Peripheral and SRAM base address in the bit-band region */ -SRAM_BASE = 0x20000000; -PERIPH_BASE = 0x40000000; - -/* Flash registers base address */ -PROVIDE ( FLASH_BASE = 0x40022000); -/* Flash Option Bytes base address */ -PROVIDE ( OB_BASE = 0x1FFFF800); - -/* Peripheral memory map */ -APB1PERIPH_BASE = PERIPH_BASE ; -APB2PERIPH_BASE = (PERIPH_BASE + 0x10000) ; -AHBPERIPH_BASE = (PERIPH_BASE + 0x20000) ; - -PROVIDE ( TIM2 = (APB1PERIPH_BASE + 0x0000) ) ; -PROVIDE ( TIM3 = (APB1PERIPH_BASE + 0x0400) ) ; -PROVIDE ( TIM4 = (APB1PERIPH_BASE + 0x0800) ) ; -PROVIDE ( RTC = (APB1PERIPH_BASE + 0x2800) ) ; -PROVIDE ( WWDG = (APB1PERIPH_BASE + 0x2C00) ) ; -PROVIDE ( IWDG = (APB1PERIPH_BASE + 0x3000) ) ; -PROVIDE ( SPI2 = (APB1PERIPH_BASE + 0x3800) ) ; -PROVIDE ( USART2 = (APB1PERIPH_BASE + 0x4400) ) ; -PROVIDE ( USART3 = (APB1PERIPH_BASE + 0x4800) ) ; -PROVIDE ( I2C1 = (APB1PERIPH_BASE + 0x5400) ) ; -PROVIDE ( I2C2 = (APB1PERIPH_BASE + 0x5800) ) ; -PROVIDE ( CAN = (APB1PERIPH_BASE + 0x6400) ) ; -PROVIDE ( BKP = (APB1PERIPH_BASE + 0x6C00) ) ; -PROVIDE ( PWR = (APB1PERIPH_BASE + 0x7000) ) ; - -PROVIDE ( AFIO = (APB2PERIPH_BASE + 0x0000) ) ; -PROVIDE ( EXTI = (APB2PERIPH_BASE + 0x0400) ) ; -PROVIDE ( GPIOA = (APB2PERIPH_BASE + 0x0800) ) ; -PROVIDE ( GPIOB = (APB2PERIPH_BASE + 0x0C00) ) ; -PROVIDE ( GPIOC = (APB2PERIPH_BASE + 0x1000) ) ; -PROVIDE ( GPIOD = (APB2PERIPH_BASE + 0x1400) ) ; -PROVIDE ( GPIOE = (APB2PERIPH_BASE + 0x1800) ) ; -PROVIDE ( ADC1 = (APB2PERIPH_BASE + 0x2400) ) ; -PROVIDE ( ADC2 = (APB2PERIPH_BASE + 0x2800) ) ; -PROVIDE ( TIM1 = (APB2PERIPH_BASE + 0x2C00) ) ; -PROVIDE ( SPI1 = (APB2PERIPH_BASE + 0x3000) ) ; -PROVIDE ( USART1 = (APB2PERIPH_BASE + 0x3800) ) ; - -PROVIDE ( DMA = (AHBPERIPH_BASE + 0x0000) ) ; -PROVIDE ( DMA_Channel1 = (AHBPERIPH_BASE + 0x0008) ) ; -PROVIDE ( DMA_Channel2 = (AHBPERIPH_BASE + 0x001C) ) ; -PROVIDE ( DMA_Channel3 = (AHBPERIPH_BASE + 0x0030) ) ; -PROVIDE ( DMA_Channel4 = (AHBPERIPH_BASE + 0x0044) ) ; -PROVIDE ( DMA_Channel5 = (AHBPERIPH_BASE + 0x0058) ) ; -PROVIDE ( DMA_Channel6 = (AHBPERIPH_BASE + 0x006C) ) ; -PROVIDE ( DMA_Channel7 = (AHBPERIPH_BASE + 0x0080) ) ; -PROVIDE ( RCC = (AHBPERIPH_BASE + 0x1000) ) ; - -/* System Control Space memory map */ -SCS_BASE = 0xE000E000; - -PROVIDE ( SysTick = (SCS_BASE + 0x0010) ) ; -PROVIDE ( NVIC = (SCS_BASE + 0x0100) ) ; -PROVIDE ( SCB = (SCS_BASE + 0x0D00) ) ; - - -/* Sections Definitions */ - -SECTIONS -{ - /* for Cortex devices, the beginning of the startup code is stored in the .isr_vector section, which goes to FLASH */ - .isr_vector : - { - PROVIDE (pios_isr_vector_table_base = .); - KEEP(*(.isr_vector)) /* Startup code */ - . = ALIGN(4); - } > BL_FLASH - - /* for some STRx devices, the beginning of the startup code is stored in the .flashtext section, which goes to FLASH */ - .flashtext : - { - . = ALIGN(4); - *(.flashtext) /* Startup code */ - . = ALIGN(4); - } > BL_FLASH - - /* the program code is stored in the .text section, which goes to Flash */ - .text : - { - . = ALIGN(4); - - *(.text) /* remaining code */ - *(.text.*) /* remaining code */ - *(.rodata) /* read-only data (constants) */ - *(.rodata*) - *(.glue_7) - *(.glue_7t) - - . = ALIGN(4); - _etext = .; - /* This is used by the startup in order to initialize the .data secion */ - _sidata = _etext; - } > BL_FLASH - - - /* - * This stack is used both as the initial sp during early init as well as ultimately - * being used as the STM32's MSP (Main Stack Pointer) which is the same stack that - * is used for _all_ interrupt handlers. The end of this stack should be placed - * against the lowest address in RAM so that a stack overrun results in a hard fault - * at the first access beyond the end of the stack. - */ - .irq_stack : - { - . = ALIGN(4); - _irq_stack_end = . ; - . = . + _irq_stack_size ; - . = ALIGN(4); - _irq_stack_top = . - 4 ; - _init_stack_top = _irq_stack_top; - . = ALIGN(4); - } >RAM - - - /* This is the initialized data section - The program executes knowing that the data is in the RAM - but the loader puts the initial values in the FLASH (inidata). - It is one task of the startup to copy the initial values from FLASH to RAM. */ - .data : AT ( _sidata ) - { - . = ALIGN(4); - /* This is used by the startup in order to initialize the .data secion */ - _sdata = . ; - - *(.data) - *(.data.*) - . = ALIGN(4); - /* This is used by the startup in order to initialize the .data secion */ - _edata = . ; - } >RAM - - - - /* This is the uninitialized data section */ - .bss : - { - . = ALIGN(4); - /* This is used by the startup in order to initialize the .bss secion */ - _sbss = .; - - *(.bss) - *(COMMON) - - . = ALIGN(4); - /* This is used by the startup in order to initialize the .bss secion */ - _ebss = . ; - } >RAM - - PROVIDE ( end = _ebss ); - PROVIDE ( _end = _ebss ); - - /* this is the FLASH Bank1 */ - /* the C or assembly source must explicitly place the code or data there - using the "section" attribute */ - .b1text : - { - *(.b1text) /* remaining code */ - *(.b1rodata) /* read-only data (constants) */ - *(.b1rodata*) - } >FLASHB1 - - /* this is the EXTMEM */ - /* the C or assembly source must explicitly place the code or data there - using the "section" attribute */ - - /* EXTMEM Bank0 */ - .eb0text : - { - *(.eb0text) /* remaining code */ - *(.eb0rodata) /* read-only data (constants) */ - *(.eb0rodata*) - } >EXTMEMB0 - - /* EXTMEM Bank1 */ - .eb1text : - { - *(.eb1text) /* remaining code */ - *(.eb1rodata) /* read-only data (constants) */ - *(.eb1rodata*) - } >EXTMEMB1 - - /* EXTMEM Bank2 */ - .eb2text : - { - *(.eb2text) /* remaining code */ - *(.eb2rodata) /* read-only data (constants) */ - *(.eb2rodata*) - } >EXTMEMB2 - - /* EXTMEM Bank0 */ - .eb3text : - { - *(.eb3text) /* remaining code */ - *(.eb3rodata) /* read-only data (constants) */ - *(.eb3rodata*) - } >EXTMEMB3 - - __exidx_start = .; - __exidx_end = .; - - .boardinfo : - { - . = ALIGN(4); - KEEP(*(.boardinfo)) - . = ALIGN(4); - } > BD_INFO - - /* after that it's only debugging information. */ - - /* remove the debugging information from the standard libraries */ - /DISCARD/ : - { - libc.a ( * ) - libm.a ( * ) - libgcc.a ( * ) - } - - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - /* DWARF debug sections. - Symbols in the DWARF debugging sections are relative to the beginning - of the section so we begin them at 0. */ - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } -} diff --git a/flight/pios/stm32f10x/link_STM3210E_OP_memory.ld b/flight/pios/stm32f10x/link_STM3210E_OP_memory.ld deleted file mode 100644 index 3aa69dc5e..000000000 --- a/flight/pios/stm32f10x/link_STM3210E_OP_memory.ld +++ /dev/null @@ -1,12 +0,0 @@ -MEMORY -{ - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 0x10000 - BL_FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 0x05000 - 0x00080 - BD_INFO (r) : ORIGIN = 0x08005000 - 0x80, LENGTH = 0x00080 - FLASH (rx) : ORIGIN = 0x08005000, LENGTH = 0x80000 - 0x05000 - FLASHB1 (rx) : ORIGIN = 0x00000000, LENGTH = 0 - EXTMEMB0 (rx) : ORIGIN = 0x00000000, LENGTH = 0 - EXTMEMB1 (rx) : ORIGIN = 0x00000000, LENGTH = 0 - EXTMEMB2 (rx) : ORIGIN = 0x00000000, LENGTH = 0 - EXTMEMB3 (rx) : ORIGIN = 0x00000000, LENGTH = 0 -} diff --git a/flight/pios/stm32f10x/link_STM3210E_OP_sections.ld b/flight/pios/stm32f10x/link_STM3210E_OP_sections.ld deleted file mode 100644 index a71ed73c8..000000000 --- a/flight/pios/stm32f10x/link_STM3210E_OP_sections.ld +++ /dev/null @@ -1,383 +0,0 @@ -/* This is the size of the stack for early init and for all FreeRTOS IRQs */ -_irq_stack_size = 0x800; -/* This is the size of the stack for early init: life span is until scheduler starts */ -_init_stack_size = 0x800; - -/* Check valid alignment for VTOR */ -ASSERT(ORIGIN(FLASH) == ALIGN(ORIGIN(FLASH), 0x80), "Start of memory region flash not aligned for startup vector table"); - -/* -this sends all unreferenced IRQHandlers to reset -*/ - - -PROVIDE ( Undefined_Handler = 0 ) ; -PROVIDE ( SWI_Handler = 0 ) ; -PROVIDE ( IRQ_Handler = 0 ) ; -PROVIDE ( Prefetch_Handler = 0 ) ; -PROVIDE ( Abort_Handler = 0 ) ; -PROVIDE ( FIQ_Handler = 0 ) ; - -PROVIDE ( NMI_Handler = 0 ) ; -PROVIDE ( HardFault_Handler = 0 ) ; -PROVIDE ( MemManage_Handler = 0 ) ; -PROVIDE ( BusFault_Handler = 0 ) ; -PROVIDE ( UsageFault_Handler = 0 ) ; -PROVIDE ( vPortSVCHandler = 0 ) ; -PROVIDE ( DebugMon_Handler = 0 ) ; -PROVIDE ( xPortPendSVHandler = 0 ) ; -PROVIDE ( xPortSysTickHandler = 0 ) ; - -PROVIDE ( WWDG_IRQHandler = 0 ) ; -PROVIDE ( PVD_IRQHandler = 0 ) ; -PROVIDE ( TAMPER_IRQHandler = 0 ) ; -PROVIDE ( RTC_IRQHandler = 0 ) ; -PROVIDE ( FLASH_IRQHandler = 0 ) ; -PROVIDE ( RCC_IRQHandler = 0 ) ; -PROVIDE ( EXTI0_IRQHandler = 0 ) ; -PROVIDE ( EXTI1_IRQHandler = 0 ) ; -PROVIDE ( EXTI2_IRQHandler = 0 ) ; -PROVIDE ( EXTI3_IRQHandler = 0 ) ; -PROVIDE ( EXTI4_IRQHandler = 0 ) ; -PROVIDE ( DMAChannel1_IRQHandler = 0 ) ; -PROVIDE ( DMAChannel2_IRQHandler = 0 ) ; -PROVIDE ( DMAChannel3_IRQHandler = 0 ) ; -PROVIDE ( DMAChannel4_IRQHandler = 0 ) ; -PROVIDE ( DMAChannel5_IRQHandler = 0 ) ; -PROVIDE ( DMAChannel6_IRQHandler = 0 ) ; -PROVIDE ( DMAChannel7_IRQHandler = 0 ) ; -PROVIDE ( ADC_IRQHandler = 0 ) ; -PROVIDE ( USB_HP_CAN1_TX_IRQHandler = 0 ) ; -PROVIDE ( USB_LP_CAN1_RX0_IRQHandler = 0 ) ; -PROVIDE ( CAN1_RX1_IRQHandler = 0 ) ; -PROVIDE ( CAN1_SCE_IRQHandler = 0 ) ; -PROVIDE ( EXTI9_5_IRQHandler = 0 ) ; -PROVIDE ( TIM1_BRK_IRQHandler = 0 ) ; -PROVIDE ( TIM1_UP_IRQHandler = 0 ) ; -PROVIDE ( TIM1_TRG_COM_IRQHandler = 0 ) ; -PROVIDE ( TIM1_CC_IRQHandler = 0 ) ; -PROVIDE ( TIM2_IRQHandler = 0 ) ; -PROVIDE ( TIM3_IRQHandler = 0 ) ; -PROVIDE ( TIM4_IRQHandler = 0 ) ; -PROVIDE ( I2C1_EV_IRQHandler = 0 ) ; -PROVIDE ( I2C1_ER_IRQHandler = 0 ) ; -PROVIDE ( I2C2_EV_IRQHandler = 0 ) ; -PROVIDE ( I2C2_ER_IRQHandler = 0 ) ; -PROVIDE ( SPI1_IRQHandler = 0 ) ; -PROVIDE ( SPI2_IRQHandler = 0 ) ; -PROVIDE ( USART1_IRQHandler = 0 ) ; -PROVIDE ( USART2_IRQHandler = 0 ) ; -PROVIDE ( USART3_IRQHandler = 0 ) ; -PROVIDE ( EXTI15_10_IRQHandler = 0 ) ; -PROVIDE ( RTCAlarm_IRQHandler = 0 ) ; -PROVIDE ( USBWakeUp_IRQHandler = 0 ) ; -PROVIDE ( TIM8_BRK_IRQHandler = 0 ) ; -PROVIDE ( TIM8_UP_IRQHandler = 0 ) ; -PROVIDE ( TIM8_TRG_COM_IRQHandler = 0 ) ; -PROVIDE ( TIM8_CC_IRQHandler = 0 ) ; -PROVIDE ( ADC3_IRQHandler = 0 ) ; -PROVIDE ( FSMC_IRQHandler = 0 ) ; -PROVIDE ( SDIO_IRQHandler = 0 ) ; -PROVIDE ( TIM5_IRQHandler = 0 ) ; -PROVIDE ( SPI3_IRQHandler = 0 ) ; -PROVIDE ( UART4_IRQHandler = 0 ) ; -PROVIDE ( UART5_IRQHandler = 0 ) ; -PROVIDE ( TIM6_IRQHandler = 0 ) ; -PROVIDE ( TIM7_IRQHandler = 0 ) ; -PROVIDE ( DMA2_Channel1_IRQHandler = 0 ) ; -PROVIDE ( DMA2_Channel2_IRQHandler = 0 ) ; -PROVIDE ( DMA2_Channel3_IRQHandler = 0 ) ; -PROVIDE ( DMA2_Channel4_5_IRQHandler = 0 ) ; - - - -/******************************************************************************/ -/* Peripheral memory map */ -/******************************************************************************/ -/*this allows to compile the ST lib in "non-debug" mode*/ - - -/* Peripheral and SRAM base address in the alias region */ -PERIPH_BB_BASE = 0x42000000; -SRAM_BB_BASE = 0x22000000; - -/* Peripheral and SRAM base address in the bit-band region */ -SRAM_BASE = 0x20000000; -PERIPH_BASE = 0x40000000; - -/* Flash registers base address */ -PROVIDE ( FLASH_BASE = 0x40022000); -/* Flash Option Bytes base address */ -PROVIDE ( OB_BASE = 0x1FFFF800); - -/* Peripheral memory map */ -APB1PERIPH_BASE = PERIPH_BASE ; -APB2PERIPH_BASE = (PERIPH_BASE + 0x10000) ; -AHBPERIPH_BASE = (PERIPH_BASE + 0x20000) ; - -PROVIDE ( TIM2 = (APB1PERIPH_BASE + 0x0000) ) ; -PROVIDE ( TIM3 = (APB1PERIPH_BASE + 0x0400) ) ; -PROVIDE ( TIM4 = (APB1PERIPH_BASE + 0x0800) ) ; -PROVIDE ( RTC = (APB1PERIPH_BASE + 0x2800) ) ; -PROVIDE ( WWDG = (APB1PERIPH_BASE + 0x2C00) ) ; -PROVIDE ( IWDG = (APB1PERIPH_BASE + 0x3000) ) ; -PROVIDE ( SPI2 = (APB1PERIPH_BASE + 0x3800) ) ; -PROVIDE ( USART2 = (APB1PERIPH_BASE + 0x4400) ) ; -PROVIDE ( USART3 = (APB1PERIPH_BASE + 0x4800) ) ; -PROVIDE ( I2C1 = (APB1PERIPH_BASE + 0x5400) ) ; -PROVIDE ( I2C2 = (APB1PERIPH_BASE + 0x5800) ) ; -PROVIDE ( CAN = (APB1PERIPH_BASE + 0x6400) ) ; -PROVIDE ( BKP = (APB1PERIPH_BASE + 0x6C00) ) ; -PROVIDE ( PWR = (APB1PERIPH_BASE + 0x7000) ) ; - -PROVIDE ( AFIO = (APB2PERIPH_BASE + 0x0000) ) ; -PROVIDE ( EXTI = (APB2PERIPH_BASE + 0x0400) ) ; -PROVIDE ( GPIOA = (APB2PERIPH_BASE + 0x0800) ) ; -PROVIDE ( GPIOB = (APB2PERIPH_BASE + 0x0C00) ) ; -PROVIDE ( GPIOC = (APB2PERIPH_BASE + 0x1000) ) ; -PROVIDE ( GPIOD = (APB2PERIPH_BASE + 0x1400) ) ; -PROVIDE ( GPIOE = (APB2PERIPH_BASE + 0x1800) ) ; -PROVIDE ( ADC1 = (APB2PERIPH_BASE + 0x2400) ) ; -PROVIDE ( ADC2 = (APB2PERIPH_BASE + 0x2800) ) ; -PROVIDE ( TIM1 = (APB2PERIPH_BASE + 0x2C00) ) ; -PROVIDE ( SPI1 = (APB2PERIPH_BASE + 0x3000) ) ; -PROVIDE ( USART1 = (APB2PERIPH_BASE + 0x3800) ) ; - -PROVIDE ( DMA = (AHBPERIPH_BASE + 0x0000) ) ; -PROVIDE ( DMA_Channel1 = (AHBPERIPH_BASE + 0x0008) ) ; -PROVIDE ( DMA_Channel2 = (AHBPERIPH_BASE + 0x001C) ) ; -PROVIDE ( DMA_Channel3 = (AHBPERIPH_BASE + 0x0030) ) ; -PROVIDE ( DMA_Channel4 = (AHBPERIPH_BASE + 0x0044) ) ; -PROVIDE ( DMA_Channel5 = (AHBPERIPH_BASE + 0x0058) ) ; -PROVIDE ( DMA_Channel6 = (AHBPERIPH_BASE + 0x006C) ) ; -PROVIDE ( DMA_Channel7 = (AHBPERIPH_BASE + 0x0080) ) ; -PROVIDE ( RCC = (AHBPERIPH_BASE + 0x1000) ) ; - -/* System Control Space memory map */ -SCS_BASE = 0xE000E000; - -PROVIDE ( SysTick = (SCS_BASE + 0x0010) ) ; -PROVIDE ( NVIC = (SCS_BASE + 0x0100) ) ; -PROVIDE ( SCB = (SCS_BASE + 0x0D00) ) ; - -PROVIDE(pios_board_info_blob = ORIGIN(BD_INFO)); - -/* Sections Definitions */ - -SECTIONS -{ - /* for Cortex devices, the beginning of the startup code is stored in the .isr_vector section, which goes to FLASH */ - .isr_vector : - { - PROVIDE (pios_isr_vector_table_base = .); - KEEP(*(.isr_vector)) /* Startup code */ - . = ALIGN(4); - } >FLASH - - /* for some STRx devices, the beginning of the startup code is stored in the .flashtext section, which goes to FLASH */ - .flashtext : - { - . = ALIGN(4); - *(.flashtext) /* Startup code */ - . = ALIGN(4); - } >FLASH - - /* module sections */ - .initcallmodule.init : - { - . = ALIGN(4); - __module_initcall_start = .; - KEEP(*(.initcallmodule.init)) - . = ALIGN(4); - __module_initcall_end = .; - } >FLASH - - /* the program code is stored in the .text section, which goes to Flash */ - .text : - { - . = ALIGN(4); - - *(.text) /* remaining code */ - *(.text.*) /* remaining code */ - *(.rodata) /* read-only data (constants) */ - *(.rodata*) - *(.glue_7) - *(.glue_7t) - - . = ALIGN(4); - _etext = .; - /* This is used by the startup in order to initialize the .data secion */ - _sidata = _etext; - } >FLASH - - /* - * This stack is used both as the initial sp during early init as well as ultimately - * being used as the STM32's MSP (Main Stack Pointer) which is the same stack that - * is used for _all_ interrupt handlers. The end of this stack should be placed - * against the lowest address in RAM so that a stack overrun results in a hard fault - * at the first access beyond the end of the stack. - */ - .irq_stack : - { - . = ALIGN(4); - _irq_stack_end = . ; - . = . + _irq_stack_size ; - . = ALIGN(4); - _irq_stack_top = . - 4 ; - . = ALIGN(4); - } >RAM - - - /* This is the initialized data section - The program executes knowing that the data is in the RAM - but the loader puts the initial values in the FLASH (inidata). - It is one task of the startup to copy the initial values from FLASH to RAM. */ - .data : AT ( _sidata ) - { - . = ALIGN(4); - /* This is used by the startup in order to initialize the .data secion */ - _sdata = . ; - - *(.data) - *(.data.*) - . = ALIGN(4); - /* This is used by the startup in order to initialize the .data secion */ - _edata = . ; - } >RAM - - - - /* This is the uninitialized data section */ - .bss : - { - . = ALIGN(4); - /* This is used by the startup in order to initialize the .bss section */ - _sbss = .; - - *(.bss) - *(COMMON) - } >RAM - - .heap (NOLOAD) : - { - . = ALIGN(4); - _sheap = . ; - _sheap_pre_rtos = . ; - *(.heap) - . = ALIGN(4); - _eheap = . ; - _eheap_pre_rtos = . ; - _init_stack_end = . ; - _sheap_post_rtos = . ; - . = . + _init_stack_size ; - . = ALIGN(4); - _eheap_post_rtos = . ; - _init_stack_top = . - 4 ; - } > RAM - - _eram = ORIGIN(RAM) + LENGTH(RAM) ; - _ebss = _eram ; - - /* keep the heap section at the end of the SRAM - * this will allow to claim the remaining bytes not used - * at run time! (done by the reset vector). - */ - - PROVIDE ( end = _ebss ); - PROVIDE ( _end = _ebss ); - - /* this is the FLASH Bank1 */ - /* the C or assembly source must explicitly place the code or data there - using the "section" attribute */ - .b1text : - { - *(.b1text) /* remaining code */ - *(.b1rodata) /* read-only data (constants) */ - *(.b1rodata*) - } >FLASHB1 - - /* this is the EXTMEM */ - /* the C or assembly source must explicitly place the code or data there - using the "section" attribute */ - - /* EXTMEM Bank0 */ - .eb0text : - { - *(.eb0text) /* remaining code */ - *(.eb0rodata) /* read-only data (constants) */ - *(.eb0rodata*) - } >EXTMEMB0 - - /* EXTMEM Bank1 */ - .eb1text : - { - *(.eb1text) /* remaining code */ - *(.eb1rodata) /* read-only data (constants) */ - *(.eb1rodata*) - } >EXTMEMB1 - - /* EXTMEM Bank2 */ - .eb2text : - { - *(.eb2text) /* remaining code */ - *(.eb2rodata) /* read-only data (constants) */ - *(.eb2rodata*) - } >EXTMEMB2 - - /* EXTMEM Bank0 */ - .eb3text : - { - *(.eb3text) /* remaining code */ - *(.eb3rodata) /* read-only data (constants) */ - *(.eb3rodata*) - } >EXTMEMB3 - - __exidx_start = .; - __exidx_end = .; - - /* after that it's only debugging information. */ - - /* remove the debugging information from the standard libraries */ - /DISCARD/ : - { - libc.a ( * ) - libm.a ( * ) - libgcc.a ( * ) - } - - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - /* DWARF debug sections. - Symbols in the DWARF debugging sections are relative to the beginning - of the section so we begin them at 0. */ - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } -} - - diff --git a/flight/pios/stm32f10x/pios_exti.c b/flight/pios/stm32f10x/pios_exti.c index efdda068e..f1a3693d8 100644 --- a/flight/pios/stm32f10x/pios_exti.c +++ b/flight/pios/stm32f10x/pios_exti.c @@ -34,15 +34,9 @@ #ifdef PIOS_INCLUDE_EXTI /* Map EXTI line to full config */ -#define EXTI_MAX_LINES 16 -#define PIOS_EXTI_INVALID 0xFF -static uint8_t pios_exti_line_to_cfg_map[EXTI_MAX_LINES] = { - [0 ... EXTI_MAX_LINES - 1] = PIOS_EXTI_INVALID, -}; +#define EXTI_MAX_LINES 16 -/* Table of exti configs registered at compile time */ -extern struct pios_exti_cfg __start__exti __attribute__((weak)); -extern struct pios_exti_cfg __stop__exti __attribute__((weak)); +static pios_exti_vector_t pios_exti_vector[EXTI_MAX_LINES]; static uint8_t PIOS_EXTI_line_to_index(uint32_t line) { @@ -149,22 +143,17 @@ uint8_t PIOS_EXTI_gpio_pin_to_exti_source_pin(uint32_t gpio_pin) int32_t PIOS_EXTI_Init(const struct pios_exti_cfg *cfg) { PIOS_Assert(cfg); - PIOS_Assert(&__start__exti); - PIOS_Assert(cfg >= &__start__exti); - PIOS_Assert(cfg < &__stop__exti); - - uint8_t cfg_index = cfg - &__start__exti; /* Connect this config to the requested vector */ uint8_t line_index = PIOS_EXTI_line_to_index(cfg->line); - if (pios_exti_line_to_cfg_map[line_index] != PIOS_EXTI_INVALID) { + if (pios_exti_vector[line_index]) { /* Someone else already has this mapped */ - goto out_fail; + return -1; } - /* Bind the config to the exti line */ - pios_exti_line_to_cfg_map[line_index] = cfg_index; + /* Bind the vector to the exti line */ + pios_exti_vector[line_index] = cfg->vector; /* Initialize the GPIO pin */ GPIO_Init(cfg->pin.gpio, &cfg->pin.init); @@ -179,25 +168,33 @@ int32_t PIOS_EXTI_Init(const struct pios_exti_cfg *cfg) NVIC_Init(&cfg->irq.init); return 0; +} + +int32_t PIOS_EXTI_DeInit(const struct pios_exti_cfg *cfg) +{ + uint8_t line_index = PIOS_EXTI_line_to_index(cfg->line); + + if (pios_exti_vector[line_index] == cfg->vector) { + EXTI_InitTypeDef disable = cfg->exti.init; + disable.EXTI_LineCmd = DISABLE; + + EXTI_Init(&disable); + pios_exti_vector[line_index] = 0; + + return 0; + } -out_fail: return -1; } static bool PIOS_EXTI_generic_irq_handler(uint8_t line_index) { - uint8_t cfg_index = pios_exti_line_to_cfg_map[line_index]; - - PIOS_Assert(&__start__exti); - - if (cfg_index > NELEMENTS(pios_exti_line_to_cfg_map) || - cfg_index == PIOS_EXTI_INVALID) { - /* Unconfigured interrupt just fired! */ - return false; + if (pios_exti_vector[line_index]) { + return pios_exti_vector[line_index](); } - struct pios_exti_cfg *cfg = &__start__exti + cfg_index; - return cfg->vector(); + /* Unconfigured interrupt just fired! */ + return false; } #ifdef PIOS_INCLUDE_FREERTOS diff --git a/flight/pios/stm32f10x/pios_i2c.c b/flight/pios/stm32f10x/pios_i2c.c index d68f5d071..e18edc2fe 100644 --- a/flight/pios/stm32f10x/pios_i2c.c +++ b/flight/pios/stm32f10x/pios_i2c.c @@ -711,6 +711,12 @@ static bool i2c_adapter_wait_for_stopped(struct pios_i2c_adapter *i2c_adapter) static void i2c_adapter_reset_bus(struct pios_i2c_adapter *i2c_adapter) { + // retry with wait code from + // TauLabs 20150718 - Prevent F3 I2C Init Lockup #1728 + uint8_t retry_count; + uint8_t retry_count_clk; + static const uint8_t MAX_I2C_RETRY_COUNT = 10; + /* Reset the I2C block */ I2C_DeInit(i2c_adapter->cfg->regs); @@ -731,11 +737,13 @@ static void i2c_adapter_reset_bus(struct pios_i2c_adapter *i2c_adapter) /* have to be repeated (due to futher bus errors) but better than clocking 0xFF into an */ /* ESC */ // bool sda_hung = GPIO_ReadInputDataBit(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin) == Bit_RESET; - while (GPIO_ReadInputDataBit(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin) == Bit_RESET) { + retry_count_clk = 0; + while (GPIO_ReadInputDataBit(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin) == Bit_RESET && (retry_count_clk++ < MAX_I2C_RETRY_COUNT)) { + retry_count = 0; /* Set clock high and wait for any clock stretching to finish. */ GPIO_SetBits(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin); - while (GPIO_ReadInputDataBit(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin) == Bit_RESET) { - ; + while (GPIO_ReadInputDataBit(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin) == Bit_RESET && (retry_count++ < MAX_I2C_RETRY_COUNT)) { + PIOS_DELAY_WaituS(1); } PIOS_DELAY_WaituS(2); @@ -759,12 +767,14 @@ static void i2c_adapter_reset_bus(struct pios_i2c_adapter *i2c_adapter) /* Set data and clock high and wait for any clock stretching to finish. */ GPIO_SetBits(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin); GPIO_SetBits(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin); - while (GPIO_ReadInputDataBit(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin) == Bit_RESET) { - ; + retry_count = 0; + while (GPIO_ReadInputDataBit(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin) == Bit_RESET && (retry_count++ < MAX_I2C_RETRY_COUNT)) { + PIOS_DELAY_WaituS(1); } /* Wait for data to be high */ - while (GPIO_ReadInputDataBit(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin) != Bit_SET) { - ; + retry_count = 0; + while (GPIO_ReadInputDataBit(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin) != Bit_SET && (retry_count++ < MAX_I2C_RETRY_COUNT)) { + PIOS_DELAY_WaituS(1); } @@ -847,17 +857,17 @@ void PIOS_I2C_GetDiagnostics(struct pios_i2c_fault_history *data, uint8_t *count { #if defined(PIOS_I2C_DIAGNOSTICS) memcpy(data, &i2c_adapter_fault_history, sizeof(i2c_adapter_fault_history)); - counts[0] = i2c_bad_event_counter; - counts[1] = i2c_fsm_fault_count; - counts[2] = i2c_error_interrupt_counter; - counts[3] = i2c_nack_counter; - counts[4] = i2c_timeout_counter; + counts[PIOS_I2C_BAD_EVENT_COUNTER] = i2c_bad_event_counter; + counts[PIOS_I2C_FSM_FAULT_COUNT] = i2c_fsm_fault_count; + counts[PIOS_I2C_ERROR_INTERRUPT_COUNTER] = i2c_error_interrupt_counter; + counts[PIOS_I2C_NACK_COUNTER] = i2c_nack_counter; + counts[PIOS_I2C_TIMEOUT_COUNTER] = i2c_timeout_counter; #else struct pios_i2c_fault_history i2c_adapter_fault_history; - i2c_adapter_fault_history.type = PIOS_I2C_ERROR_EVENT; + i2c_adapter_fault_history.type = PIOS_I2C_ERROR_EVENT; memcpy(data, &i2c_adapter_fault_history, sizeof(i2c_adapter_fault_history)); - counts[0] = counts[1] = counts[2] = 0; + memset(counts, 0, sizeof(*counts) * PIOS_I2C_ERROR_COUNT_NUMELEM); #endif } diff --git a/flight/pios/stm32f10x/pios_ppm.c b/flight/pios/stm32f10x/pios_ppm.c index 5016d6750..4983c116e 100644 --- a/flight/pios/stm32f10x/pios_ppm.c +++ b/flight/pios/stm32f10x/pios_ppm.c @@ -7,7 +7,8 @@ * @{ * * @file pios_ppm.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @brief PPM Input functions (STM32 dependent) * @see The GNU Public License (GPL) Version 3 * @@ -50,7 +51,7 @@ const struct pios_rcvr_driver pios_ppm_rcvr_driver = { #define PIOS_PPM_IN_MIN_NUM_CHANNELS 4 #define PIOS_PPM_IN_MAX_NUM_CHANNELS PIOS_PPM_NUM_INPUTS #define PIOS_PPM_STABLE_CHANNEL_COUNT 25 // frames -#define PIOS_PPM_IN_MIN_SYNC_PULSE_US 3000 // microseconds +#define PIOS_PPM_IN_MIN_SYNC_PULSE_US 2700 // microseconds #define PIOS_PPM_IN_MIN_CHANNEL_PULSE_US 750 // microseconds #define PIOS_PPM_IN_MAX_CHANNEL_PULSE_US 2250 // microseconds @@ -341,6 +342,11 @@ static void PIOS_PPM_tim_edge_cb(__attribute__((unused)) uint32_t tim_id, } } #endif /* USE_FREERTOS */ + } else { + for (uint32_t i = 0; + i < PIOS_PPM_IN_MAX_NUM_CHANNELS; i++) { + ppm_dev->CaptureValue[i] = PIOS_RCVR_TIMEOUT; + } } ppm_dev->Fresh = TRUE; diff --git a/flight/pios/stm32f10x/pios_usb_cdc.c b/flight/pios/stm32f10x/pios_usb_cdc.c index e7c3c1fda..84255191f 100644 --- a/flight/pios/stm32f10x/pios_usb_cdc.c +++ b/flight/pios/stm32f10x/pios_usb_cdc.c @@ -41,15 +41,17 @@ static void PIOS_USB_CDC_RegisterTxCallback(uint32_t usbcdc_id, pios_com_callback tx_out_cb, uint32_t context); static void PIOS_USB_CDC_RegisterRxCallback(uint32_t usbcdc_id, pios_com_callback rx_in_cb, uint32_t context); +static void PIOS_USB_CDC_RegisterBaudRateCallback(uint32_t usbcdc_id, pios_com_callback_baud_rate baud_rate_cb, uint32_t context); static void PIOS_USB_CDC_TxStart(uint32_t usbcdc_id, uint16_t tx_bytes_avail); static void PIOS_USB_CDC_RxStart(uint32_t usbcdc_id, uint16_t rx_bytes_avail); -static bool PIOS_USB_CDC_Available(uint32_t usbcdc_id); +static uint32_t PIOS_USB_CDC_Available(uint32_t usbcdc_id); const struct pios_com_driver pios_usb_cdc_com_driver = { .tx_start = PIOS_USB_CDC_TxStart, .rx_start = PIOS_USB_CDC_RxStart, .bind_tx_cb = PIOS_USB_CDC_RegisterTxCallback, .bind_rx_cb = PIOS_USB_CDC_RegisterRxCallback, + .bind_baud_rate_cb = PIOS_USB_CDC_RegisterBaudRateCallback, .available = PIOS_USB_CDC_Available, }; @@ -68,6 +70,9 @@ struct pios_usb_cdc_dev { pios_com_callback tx_out_cb; uint32_t tx_out_context; + pios_com_callback_baud_rate baud_rate_cb; + uint32_t baud_rate_context; + uint8_t rx_packet_buffer[PIOS_USB_BOARD_CDC_DATA_LENGTH]; /* * NOTE: This is -1 as somewhat of a hack. It ensures that we always send packets @@ -353,7 +358,7 @@ RESULT PIOS_USB_CDC_SetControlLineState(void) return USB_SUCCESS; } -static bool PIOS_USB_CDC_Available(uint32_t usbcdc_id) +static uint32_t PIOS_USB_CDC_Available(uint32_t usbcdc_id) { struct pios_usb_cdc_dev *usb_cdc_dev = (struct pios_usb_cdc_dev *)usbcdc_id; @@ -361,8 +366,8 @@ static bool PIOS_USB_CDC_Available(uint32_t usbcdc_id) PIOS_Assert(valid); - return PIOS_USB_CheckAvailable(usb_cdc_dev->lower_id) && - (control_line_state & USB_CDC_CONTROL_LINE_STATE_DTE_PRESENT); + return (PIOS_USB_CheckAvailable(usb_cdc_dev->lower_id) && + (control_line_state & USB_CDC_CONTROL_LINE_STATE_DTE_PRESENT)) ? COM_AVAILABLE_RXTX : COM_AVAILABLE_NONE; } static struct usb_cdc_line_coding line_coding = { @@ -450,4 +455,37 @@ static void PIOS_USB_CDC_CTRL_EP_IN_Callback(void) SetEPTxValid(usb_cdc_dev->cfg->ctrl_tx_ep); } +static void PIOS_USB_CDC_RegisterBaudRateCallback(uint32_t usbcdc_id, pios_com_callback_baud_rate baud_rate_cb, uint32_t context) +{ + struct pios_usb_cdc_dev *usb_cdc_dev = (struct pios_usb_cdc_dev *)usbcdc_id; + + bool valid = PIOS_USB_CDC_validate(usb_cdc_dev); + + PIOS_Assert(valid); + + /* + * Order is important in these assignments since ISR uses _cb + * field to determine if it's ok to dereference _cb and _context + */ + usb_cdc_dev->baud_rate_context = context; + usb_cdc_dev->baud_rate_cb = baud_rate_cb; +} + +void PIOS_USB_CDC_SetLineCoding_Completed() +{ + struct pios_usb_cdc_dev *usb_cdc_dev = (struct pios_usb_cdc_dev *)pios_usb_cdc_id; + + bool valid = PIOS_USB_CDC_validate(usb_cdc_dev); + + if (!valid) { + /* No CDC interface is configured */ + return; + } + + if (usb_cdc_dev->baud_rate_cb) { + usb_cdc_dev->baud_rate_cb(usb_cdc_dev->baud_rate_context, usbltoh(line_coding.dwDTERate)); + } +} + + #endif /* PIOS_INCLUDE_USB_CDC */ diff --git a/flight/pios/stm32f10x/pios_usb_hid.c b/flight/pios/stm32f10x/pios_usb_hid.c index 532a78a7c..6b1e9d81b 100644 --- a/flight/pios/stm32f10x/pios_usb_hid.c +++ b/flight/pios/stm32f10x/pios_usb_hid.c @@ -43,13 +43,14 @@ static void PIOS_USB_HID_RegisterTxCallback(uint32_t usbhid_id, pios_com_callbac static void PIOS_USB_HID_RegisterRxCallback(uint32_t usbhid_id, pios_com_callback rx_in_cb, uint32_t context); static void PIOS_USB_HID_TxStart(uint32_t usbhid_id, uint16_t tx_bytes_avail); static void PIOS_USB_HID_RxStart(uint32_t usbhid_id, uint16_t rx_bytes_avail); +static uint32_t PIOS_USB_HID_Available(uint32_t usbhid_id); const struct pios_com_driver pios_usb_hid_com_driver = { .tx_start = PIOS_USB_HID_TxStart, .rx_start = PIOS_USB_HID_RxStart, .bind_tx_cb = PIOS_USB_HID_RegisterTxCallback, .bind_rx_cb = PIOS_USB_HID_RegisterRxCallback, - .available = PIOS_USB_CheckAvailable, + .available = PIOS_USB_HID_Available, }; enum pios_usb_hid_dev_magic { @@ -370,4 +371,9 @@ static void PIOS_USB_HID_EP_OUT_Callback(void) #endif /* PIOS_INCLUDE_FREERTOS */ } +static uint32_t PIOS_USB_HID_Available(uint32_t usbhid_id) +{ + return PIOS_USB_CheckAvailable(usbhid_id) ? COM_AVAILABLE_RXTX : COM_AVAILABLE_NONE; +} + #endif /* PIOS_INCLUDE_USB_HID */ diff --git a/flight/pios/stm32f10x/pios_usbhook.c b/flight/pios/stm32f10x/pios_usbhook.c index c1173db7d..55e0e40e5 100644 --- a/flight/pios/stm32f10x/pios_usbhook.c +++ b/flight/pios/stm32f10x/pios_usbhook.c @@ -42,6 +42,8 @@ /* STM32 USB Library Definitions */ #include "usb_lib.h" +static void (*ep0_rxready_cb)(void) = 0; + static ONE_DESCRIPTOR Device_Descriptor; void PIOS_USBHOOK_RegisterDevice(const uint8_t *desc, uint16_t desc_size) @@ -275,7 +277,13 @@ static void PIOS_USBHOOK_SetDeviceAddress(void) * Return : None. *******************************************************************************/ static void PIOS_USBHOOK_Status_In(void) -{} +{ + /* this callback gets executed after sending ZLP and doing In0_Process(), to ack */ + if (ep0_rxready_cb) { + ep0_rxready_cb(); + ep0_rxready_cb = 0; + } +} /******************************************************************************* * Function Name : PIOS_USBHOOK_Status_Out @@ -296,6 +304,7 @@ static void PIOS_USBHOOK_Status_Out(void) *******************************************************************************/ extern uint8_t *PIOS_USB_CDC_SetLineCoding(uint16_t Length); extern const uint8_t *PIOS_USB_CDC_GetLineCoding(uint16_t Length); +extern void PIOS_USB_CDC_SetLineCoding_Completed(); static RESULT PIOS_USBHOOK_Data_Setup(uint8_t RequestNo) { @@ -305,6 +314,7 @@ static RESULT PIOS_USBHOOK_Data_Setup(uint8_t RequestNo) CopyInRoutine = NULL; CopyOutRoutine = NULL; + switch (Type_Recipient) { case (STANDARD_REQUEST | INTERFACE_RECIPIENT): switch (pInformation->USBwIndex0) { @@ -346,6 +356,7 @@ static RESULT PIOS_USBHOOK_Data_Setup(uint8_t RequestNo) switch (RequestNo) { case USB_CDC_REQ_SET_LINE_CODING: CopyOutRoutine = PIOS_USB_CDC_SetLineCoding; + ep0_rxready_cb = PIOS_USB_CDC_SetLineCoding_Completed; break; case USB_CDC_REQ_GET_LINE_CODING: CopyInRoutine = PIOS_USB_CDC_GetLineCoding; diff --git a/flight/pios/stm32f10x/startup_stm32f10x_HD.S b/flight/pios/stm32f10x/startup_stm32f10x_HD.S deleted file mode 100644 index afb4b5b0b..000000000 --- a/flight/pios/stm32f10x/startup_stm32f10x_HD.S +++ /dev/null @@ -1,477 +0,0 @@ -/** - ****************************************************************************** - * @file startup_stm32f10x_hd.s - * @author MCD Application Team / David Ankers: Vector table for FreeRTOS - * @version V3.1.2 - * @date 09/28/2009 - * @brief STM32F10x High Density Devices vector table for RIDE7 toolchain. - * This module performs: - * - Set the initial SP - * - Set the initial PC == Reset_Handler, - * - Set the vector table entries with the exceptions ISR address, - * - Configure external SRAM mounted on STM3210E-EVAL board - * to be used as data memory (optional, to be enabled by user) - * - Branches to main in the C library (which eventually - * calls main()). - * After Reset the Cortex-M3 processor is in Thread mode, - * priority is Privileged, and the Stack is set to Main. - ****************************************************************************** - * @copy - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2009 STMicroelectronics

- */ - - .syntax unified - .cpu cortex-m3 - .fpu softvfp - .thumb - -.global g_pfnVectors -.global SystemInit_ExtMemCtl_Dummy -.global Default_Handler - -/* start address for the initialization values of the .data section. -defined in linker script */ -.word _sidata -/* start address for the .data section. defined in linker script */ -.word _sdata -/* end address for the .data section. defined in linker script */ -.word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss -/* stack used for SystemInit_ExtMemCtl; always internal RAM used */ - -.equ Initial_spTop, 0x20000400 -.equ BootRAM, 0xF1E0F85F -/** - * @brief This is the code that gets called when the processor first - * starts execution following a reset event. Only the absolutely - * necessary set is performed, after which the application - * supplied main() routine is called. - * @param None - * @retval : None -*/ - - .section .text.Reset_Handler - .weak Reset_Handler - .type Reset_Handler, %function -Reset_Handler: - -/* Copy the data segment initializers from flash to SRAM */ - movs r1, #0 - b LoopCopyDataInit - -CopyDataInit: - ldr r3, =_sidata - ldr r3, [r3, r1] - str r3, [r0, r1] - adds r1, r1, #4 - -LoopCopyDataInit: - ldr r0, =_sdata - ldr r3, =_edata - adds r2, r0, r1 - cmp r2, r3 - bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss -/* Call the application's entry point.*/ - bl main - bx lr -.size Reset_Handler, .-Reset_Handler - -/** - * @brief Dummy SystemInit_ExtMemCtl function - * @param None - * @retval : None -*/ - .section .text.SystemInit_ExtMemCtl_Dummy,"ax",%progbits -SystemInit_ExtMemCtl_Dummy: - bx lr - .size SystemInit_ExtMemCtl_Dummy, .-SystemInit_ExtMemCtl_Dummy - -/** - * @brief This is the code that gets called when the processor receives an - * unexpected interrupt. This simply enters an infinite loop, preserving - * the system state for examination by a debugger. - * - * @param None - * @retval : None -*/ - .section .text.Default_Handler,"ax",%progbits -Default_Handler: -Infinite_Loop: - b Infinite_Loop - .size Default_Handler, .-Default_Handler -/****************************************************************************** -* -* The minimal vector table for a Cortex M3. Note that the proper constructs -* must be placed on this to ensure that it ends up at physical address -* 0x0000.0000. -* -******************************************************************************/ - .section .isr_vector,"a",%progbits - .type g_pfnVectors, %object - .size g_pfnVectors, .-g_pfnVectors - - -g_pfnVectors: - .word _estack - .word Reset_Handler - .word NMI_Handler - .word HardFault_Handler - .word MemManage_Handler - .word BusFault_Handler - .word UsageFault_Handler - .word 0 - .word 0 - .word 0 - .word 0 - .word SVC_Handler - .word DebugMon_Handler - .word 0 - .word PendSV_Handler - .word SysTick_Handler - .word WWDG_IRQHandler - .word PVD_IRQHandler - .word TAMPER_IRQHandler - .word RTC_IRQHandler - .word FLASH_IRQHandler - .word RCC_IRQHandler - .word EXTI0_IRQHandler - .word EXTI1_IRQHandler - .word EXTI2_IRQHandler - .word EXTI3_IRQHandler - .word EXTI4_IRQHandler - .word DMA1_Channel1_IRQHandler - .word DMA1_Channel2_IRQHandler - .word DMA1_Channel3_IRQHandler - .word DMA1_Channel4_IRQHandler - .word DMA1_Channel5_IRQHandler - .word DMA1_Channel6_IRQHandler - .word DMA1_Channel7_IRQHandler - .word ADC1_2_IRQHandler - .word USB_HP_CAN1_TX_IRQHandler - .word USB_LP_CAN1_RX0_IRQHandler - .word CAN1_RX1_IRQHandler - .word CAN1_SCE_IRQHandler - .word EXTI9_5_IRQHandler - .word TIM1_BRK_IRQHandler - .word TIM1_UP_IRQHandler - .word TIM1_TRG_COM_IRQHandler - .word TIM1_CC_IRQHandler - .word TIM2_IRQHandler - .word TIM3_IRQHandler - .word TIM4_IRQHandler - .word I2C1_EV_IRQHandler - .word I2C1_ER_IRQHandler - .word I2C2_EV_IRQHandler - .word I2C2_ER_IRQHandler - .word SPI1_IRQHandler - .word SPI2_IRQHandler - .word USART1_IRQHandler - .word USART2_IRQHandler - .word USART3_IRQHandler - .word EXTI15_10_IRQHandler - .word RTCAlarm_IRQHandler - .word USBWakeUp_IRQHandler - .word TIM8_BRK_IRQHandler - .word TIM8_UP_IRQHandler - .word TIM8_TRG_COM_IRQHandler - .word TIM8_CC_IRQHandler - .word ADC3_IRQHandler - .word FSMC_IRQHandler - .word SDIO_IRQHandler - .word TIM5_IRQHandler - .word SPI3_IRQHandler - .word UART4_IRQHandler - .word UART5_IRQHandler - .word TIM6_IRQHandler - .word TIM7_IRQHandler - .word DMA2_Channel1_IRQHandler - .word DMA2_Channel2_IRQHandler - .word DMA2_Channel3_IRQHandler - .word DMA2_Channel4_5_IRQHandler - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word BootRAM /* @0x1E0. This is for boot in RAM mode for - STM32F10x High Density devices. */ - -/******************************************************************************* -* -* Provide weak aliases for each Exception handler to the Default_Handler. -* As they are weak aliases, any function with the same name will override -* this definition. -* -*******************************************************************************/ - - .weak NMI_Handler - .thumb_set NMI_Handler,Default_Handler - - .weak HardFault_Handler - .thumb_set HardFault_Handler,Default_Handler - - .weak MemManage_Handler - .thumb_set MemManage_Handler,Default_Handler - - .weak BusFault_Handler - .thumb_set BusFault_Handler,Default_Handler - - .weak UsageFault_Handler - .thumb_set UsageFault_Handler,Default_Handler - - .weak SVC_Handler - .thumb_set SVC_Handler,Default_Handler - - .weak DebugMon_Handler - .thumb_set DebugMon_Handler,Default_Handler - - .weak PendSV_Handler - .thumb_set PendSV_Handler,Default_Handler - - .weak SysTick_Handler - .thumb_set SysTick_Handler,Default_Handler - - .weak WWDG_IRQHandler - .thumb_set WWDG_IRQHandler,Default_Handler - - .weak PVD_IRQHandler - .thumb_set PVD_IRQHandler,Default_Handler - - .weak TAMPER_IRQHandler - .thumb_set TAMPER_IRQHandler,Default_Handler - - .weak RTC_IRQHandler - .thumb_set RTC_IRQHandler,Default_Handler - - .weak FLASH_IRQHandler - .thumb_set FLASH_IRQHandler,Default_Handler - - .weak RCC_IRQHandler - .thumb_set RCC_IRQHandler,Default_Handler - - .weak EXTI0_IRQHandler - .thumb_set EXTI0_IRQHandler,Default_Handler - - .weak EXTI1_IRQHandler - .thumb_set EXTI1_IRQHandler,Default_Handler - - .weak EXTI2_IRQHandler - .thumb_set EXTI2_IRQHandler,Default_Handler - - .weak EXTI3_IRQHandler - .thumb_set EXTI3_IRQHandler,Default_Handler - - .weak EXTI4_IRQHandler - .thumb_set EXTI4_IRQHandler,Default_Handler - - .weak DMA1_Channel1_IRQHandler - .thumb_set DMA1_Channel1_IRQHandler,Default_Handler - - .weak DMA1_Channel2_IRQHandler - .thumb_set DMA1_Channel2_IRQHandler,Default_Handler - - .weak DMA1_Channel3_IRQHandler - .thumb_set DMA1_Channel3_IRQHandler,Default_Handler - - .weak DMA1_Channel4_IRQHandler - .thumb_set DMA1_Channel4_IRQHandler,Default_Handler - - .weak DMA1_Channel5_IRQHandler - .thumb_set DMA1_Channel5_IRQHandler,Default_Handler - - .weak DMA1_Channel6_IRQHandler - .thumb_set DMA1_Channel6_IRQHandler,Default_Handler - - .weak DMA1_Channel7_IRQHandler - .thumb_set DMA1_Channel7_IRQHandler,Default_Handler - - .weak ADC1_2_IRQHandler - .thumb_set ADC1_2_IRQHandler,Default_Handler - - .weak USB_HP_CAN1_TX_IRQHandler - .thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler - - .weak USB_LP_CAN1_RX0_IRQHandler - .thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler - - .weak CAN1_RX1_IRQHandler - .thumb_set CAN1_RX1_IRQHandler,Default_Handler - - .weak CAN1_SCE_IRQHandler - .thumb_set CAN1_SCE_IRQHandler,Default_Handler - - .weak EXTI9_5_IRQHandler - .thumb_set EXTI9_5_IRQHandler,Default_Handler - - .weak TIM1_BRK_IRQHandler - .thumb_set TIM1_BRK_IRQHandler,Default_Handler - - .weak TIM1_UP_IRQHandler - .thumb_set TIM1_UP_IRQHandler,Default_Handler - - .weak TIM1_TRG_COM_IRQHandler - .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler - - .weak TIM1_CC_IRQHandler - .thumb_set TIM1_CC_IRQHandler,Default_Handler - - .weak TIM2_IRQHandler - .thumb_set TIM2_IRQHandler,Default_Handler - - .weak TIM3_IRQHandler - .thumb_set TIM3_IRQHandler,Default_Handler - - .weak TIM4_IRQHandler - .thumb_set TIM4_IRQHandler,Default_Handler - - .weak I2C1_EV_IRQHandler - .thumb_set I2C1_EV_IRQHandler,Default_Handler - - .weak I2C1_ER_IRQHandler - .thumb_set I2C1_ER_IRQHandler,Default_Handler - - .weak I2C2_EV_IRQHandler - .thumb_set I2C2_EV_IRQHandler,Default_Handler - - .weak I2C2_ER_IRQHandler - .thumb_set I2C2_ER_IRQHandler,Default_Handler - - .weak SPI1_IRQHandler - .thumb_set SPI1_IRQHandler,Default_Handler - - .weak SPI2_IRQHandler - .thumb_set SPI2_IRQHandler,Default_Handler - - .weak USART1_IRQHandler - .thumb_set USART1_IRQHandler,Default_Handler - - .weak USART2_IRQHandler - .thumb_set USART2_IRQHandler,Default_Handler - - .weak USART3_IRQHandler - .thumb_set USART3_IRQHandler,Default_Handler - - .weak EXTI15_10_IRQHandler - .thumb_set EXTI15_10_IRQHandler,Default_Handler - - .weak RTCAlarm_IRQHandler - .thumb_set RTCAlarm_IRQHandler,Default_Handler - - .weak USBWakeUp_IRQHandler - .thumb_set USBWakeUp_IRQHandler,Default_Handler - - .weak TIM8_BRK_IRQHandler - .thumb_set TIM8_BRK_IRQHandler,Default_Handler - - .weak TIM8_UP_IRQHandler - .thumb_set TIM8_UP_IRQHandler,Default_Handler - - .weak TIM8_TRG_COM_IRQHandler - .thumb_set TIM8_TRG_COM_IRQHandler,Default_Handler - - .weak TIM8_CC_IRQHandler - .thumb_set TIM8_CC_IRQHandler,Default_Handler - - .weak ADC3_IRQHandler - .thumb_set ADC3_IRQHandler,Default_Handler - - .weak FSMC_IRQHandler - .thumb_set FSMC_IRQHandler,Default_Handler - - .weak SDIO_IRQHandler - .thumb_set SDIO_IRQHandler,Default_Handler - - .weak TIM5_IRQHandler - .thumb_set TIM5_IRQHandler,Default_Handler - - .weak SPI3_IRQHandler - .thumb_set SPI3_IRQHandler,Default_Handler - - .weak UART4_IRQHandler - .thumb_set UART4_IRQHandler,Default_Handler - - .weak UART5_IRQHandler - .thumb_set UART5_IRQHandler,Default_Handler - - .weak TIM6_IRQHandler - .thumb_set TIM6_IRQHandler,Default_Handler - - .weak TIM7_IRQHandler - .thumb_set TIM7_IRQHandler,Default_Handler - - .weak DMA2_Channel1_IRQHandler - .thumb_set DMA2_Channel1_IRQHandler,Default_Handler - - .weak DMA2_Channel2_IRQHandler - .thumb_set DMA2_Channel2_IRQHandler,Default_Handler - - .weak DMA2_Channel3_IRQHandler - .thumb_set DMA2_Channel3_IRQHandler,Default_Handler - - .weak DMA2_Channel4_5_IRQHandler - .thumb_set DMA2_Channel4_5_IRQHandler,Default_Handler - - .weak SystemInit_ExtMemCtl - .thumb_set SystemInit_ExtMemCtl,SystemInit_ExtMemCtl_Dummy - diff --git a/flight/pios/stm32f10x/startup_stm32f10x_HD_OP.S b/flight/pios/stm32f10x/startup_stm32f10x_HD_OP.S deleted file mode 100644 index a0826115e..000000000 --- a/flight/pios/stm32f10x/startup_stm32f10x_HD_OP.S +++ /dev/null @@ -1,541 +0,0 @@ -/** - ****************************************************************************** - * @file startup_stm32f10x_hd.s - * @author MCD Application Team / David Ankers: Vector table for FreeRTOS - * @version V3.1.2 - * @date 09/28/2009 - * @brief STM32F10x High Density Devices vector table for RIDE7 toolchain. - * This module performs: - * - Set the initial SP - * - Set the initial PC == Reset_Handler, - * - Set the vector table entries with the exceptions ISR address, - * - Configure external SRAM mounted on STM3210E-EVAL board - * to be used as data memory (optional, to be enabled by user) - * - Branches to main in the C library (which eventually - * calls main()). - * After Reset the Cortex-M3 processor is in Thread mode, - * priority is Privileged, and the Stack is set to Main. - ****************************************************************************** - * @copy - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2009 STMicroelectronics

- */ - - .syntax unified - .cpu cortex-m3 - .fpu softvfp - .thumb - -.global g_pfnVectors -.global SystemInit_ExtMemCtl_Dummy -.global Default_Handler -.global xPortIncreaseHeapSize -.global Stack_Change - -/* start address for the initialization values of the .data section. -defined in linker script */ -.word _sidata -/* start address for the .data section. defined in linker script */ -.word _sdata -/* end address for the .data section. defined in linker script */ -.word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss -/* stack used for SystemInit_ExtMemCtl; always internal RAM used */ - -.equ BootRAM, 0xF1E0F85F -/** - * @brief This is the code that gets called when the processor first - * starts execution following a reset event. Only the absolutely - * necessary set is performed, after which the application - * supplied main() routine is called. - * @param None - * @retval : None -*/ - - .section .text.Reset_Handler - .weak Reset_Handler - .type Reset_Handler, %function -Reset_Handler: - -/* FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is - required, then adjust the Register Addresses */ - bl SystemInit_ExtMemCtl -/* restore original stack pointer */ - LDR r0, =_irq_stack_top - MSR msp, r0 - LDR r2, =_init_stack_top - MSR psp, r2 - /* check if irq and init stack are the same */ - /* if they are, we don't do stack swap */ - /* and lets bypass the monitoring as well for now */ - cmp r0, r2 - beq SectionBssInit -/* DO - * - stay in thread process mode - * - stay in privilege level - * - use process stack - */ - movs r0, #2 - MSR control, r0 - ISB -/* Fill IRQ stack for watermark monitoring */ - ldr r2, =_irq_stack_end - b LoopFillIRQStack - -FillIRQStack: - movw r3, #0xA5A5 - str r3, [r2], #4 - -LoopFillIRQStack: - ldr r3, = _irq_stack_top - cmp r2, r3 - bcc FillIRQStack - -SectionBssInit: -/* Copy the data segment initializers from flash to SRAM */ - movs r1, #0 - b LoopCopyDataInit - -CopyDataInit: - ldr r3, =_sidata - ldr r3, [r3, r1] - str r3, [r0, r1] - adds r1, r1, #4 - -LoopCopyDataInit: - ldr r0, =_sdata - ldr r3, =_edata - adds r2, r0, r1 - cmp r2, r3 - bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss -/* Call the application's entry point.*/ - bl main -/* will never return here */ - bx lr -.size Reset_Handler, .-Reset_Handler - -/** - * @brief This is the code that swaps stack (from end of heap to irq_stack). - * Also reclaim the heap that was used as a stack. - * @param None - * @retval : None -*/ - .section .text.Stack_Change - .weak Stack_Change - .type Stack_Change, %function -Stack_Change: - mov r4, lr -/* Switches stack back momentarily to MSP */ - movs r0, #0 - msr control, r0 -Heap_Reclaim: -/* add heap_post_rtos to the heap (if the capability/function exist) */ -/* Also claim the unused memory (between end of heap to end of memory */ -/* CAREFULL: the heap section must be the last section in RAM in order this to work */ - ldr r0, = _init_stack_size - ldr r1, = _eheap_post_rtos - ldr r2, = _eram - subs r2, r2, r1 - adds r0, r0, r2 - bl xPortIncreaseHeapSize - bx r4 - .size Stack_Change, .-Stack_Change - -/** - * @brief Dummy SystemInit_ExtMemCtl function - * @param None - * @retval : None -*/ - .section .text.SystemInit_ExtMemCtl_Dummy,"ax",%progbits -SystemInit_ExtMemCtl_Dummy: - bx lr - .size SystemInit_ExtMemCtl_Dummy, .-SystemInit_ExtMemCtl_Dummy - -/** - * @brief This is the code that gets called when the processor receives an - * unexpected interrupt. This simply enters an infinite loop, preserving - * the system state for examination by a debugger. - * - * @param None - * @retval : None -*/ - .section .text.Default_Handler,"ax",%progbits -Default_Handler: -Infinite_Loop: - b Infinite_Loop - .size Default_Handler, .-Default_Handler -/****************************************************************************** -* -* The minimal vector table for a Cortex M3. Note that the proper constructs -* must be placed on this to ensure that it ends up at physical address -* 0x0000.0000. -* -******************************************************************************/ - .section .isr_vector,"a",%progbits - .type g_pfnVectors, %object - .size g_pfnVectors, .-g_pfnVectors - - -g_pfnVectors: - .word _irq_stack_top - .word Reset_Handler - .word NMI_Handler - .word HardFault_Handler - .word MemManage_Handler - .word BusFault_Handler - .word UsageFault_Handler - .word 0 - .word 0 - .word 0 - .word 0 - .word vPortSVCHandler - .word DebugMon_Handler - .word 0 - .word xPortPendSVHandler - .word xPortSysTickHandler - .word WWDG_IRQHandler - .word PVD_IRQHandler - .word TAMPER_IRQHandler - .word RTC_IRQHandler - .word FLASH_IRQHandler - .word RCC_IRQHandler - .word EXTI0_IRQHandler - .word EXTI1_IRQHandler - .word EXTI2_IRQHandler - .word EXTI3_IRQHandler - .word EXTI4_IRQHandler - .word DMA1_Channel1_IRQHandler - .word DMA1_Channel2_IRQHandler - .word DMA1_Channel3_IRQHandler - .word DMA1_Channel4_IRQHandler - .word DMA1_Channel5_IRQHandler - .word DMA1_Channel6_IRQHandler - .word DMA1_Channel7_IRQHandler - .word ADC1_2_IRQHandler - .word USB_HP_CAN1_TX_IRQHandler - .word USB_LP_CAN1_RX0_IRQHandler - .word CAN1_RX1_IRQHandler - .word CAN1_SCE_IRQHandler - .word EXTI9_5_IRQHandler - .word TIM1_BRK_IRQHandler - .word TIM1_UP_IRQHandler - .word TIM1_TRG_COM_IRQHandler - .word TIM1_CC_IRQHandler - .word TIM2_IRQHandler - .word TIM3_IRQHandler - .word TIM4_IRQHandler - .word I2C1_EV_IRQHandler - .word I2C1_ER_IRQHandler - .word I2C2_EV_IRQHandler - .word I2C2_ER_IRQHandler - .word SPI1_IRQHandler - .word SPI2_IRQHandler - .word USART1_IRQHandler - .word USART2_IRQHandler - .word USART3_IRQHandler - .word EXTI15_10_IRQHandler - .word RTCAlarm_IRQHandler - .word USBWakeUp_IRQHandler - .word TIM8_BRK_IRQHandler - .word TIM8_UP_IRQHandler - .word TIM8_TRG_COM_IRQHandler - .word TIM8_CC_IRQHandler - .word ADC3_IRQHandler - .word FSMC_IRQHandler - .word SDIO_IRQHandler - .word TIM5_IRQHandler - .word SPI3_IRQHandler - .word UART4_IRQHandler - .word UART5_IRQHandler - .word TIM6_IRQHandler - .word TIM7_IRQHandler - .word DMA2_Channel1_IRQHandler - .word DMA2_Channel2_IRQHandler - .word DMA2_Channel3_IRQHandler - .word DMA2_Channel4_5_IRQHandler - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word BootRAM /* @0x1E0. This is for boot in RAM mode for - STM32F10x High Density devices. */ - -/******************************************************************************* -* -* Provide weak aliases for each Exception handler to the Default_Handler. -* As they are weak aliases, any function with the same name will override -* this definition. -* -*******************************************************************************/ - - .weak NMI_Handler - .thumb_set NMI_Handler,Default_Handler - - .weak HardFault_Handler - .thumb_set HardFault_Handler,Default_Handler - - .weak MemManage_Handler - .thumb_set MemManage_Handler,Default_Handler - - .weak BusFault_Handler - .thumb_set BusFault_Handler,Default_Handler - - .weak UsageFault_Handler - .thumb_set UsageFault_Handler,Default_Handler - - .weak SVC_Handler - .thumb_set SVC_Handler,Default_Handler - - .weak DebugMon_Handler - .thumb_set DebugMon_Handler,Default_Handler - - .weak PendSV_Handler - .thumb_set PendSV_Handler,Default_Handler - - .weak SysTick_Handler - .thumb_set SysTick_Handler,Default_Handler - - .weak WWDG_IRQHandler - .thumb_set WWDG_IRQHandler,Default_Handler - - .weak PVD_IRQHandler - .thumb_set PVD_IRQHandler,Default_Handler - - .weak TAMPER_IRQHandler - .thumb_set TAMPER_IRQHandler,Default_Handler - - .weak RTC_IRQHandler - .thumb_set RTC_IRQHandler,Default_Handler - - .weak FLASH_IRQHandler - .thumb_set FLASH_IRQHandler,Default_Handler - - .weak RCC_IRQHandler - .thumb_set RCC_IRQHandler,Default_Handler - - .weak EXTI0_IRQHandler - .thumb_set EXTI0_IRQHandler,Default_Handler - - .weak EXTI1_IRQHandler - .thumb_set EXTI1_IRQHandler,Default_Handler - - .weak EXTI2_IRQHandler - .thumb_set EXTI2_IRQHandler,Default_Handler - - .weak EXTI3_IRQHandler - .thumb_set EXTI3_IRQHandler,Default_Handler - - .weak EXTI4_IRQHandler - .thumb_set EXTI4_IRQHandler,Default_Handler - - .weak DMA1_Channel1_IRQHandler - .thumb_set DMA1_Channel1_IRQHandler,Default_Handler - - .weak DMA1_Channel2_IRQHandler - .thumb_set DMA1_Channel2_IRQHandler,Default_Handler - - .weak DMA1_Channel3_IRQHandler - .thumb_set DMA1_Channel3_IRQHandler,Default_Handler - - .weak DMA1_Channel4_IRQHandler - .thumb_set DMA1_Channel4_IRQHandler,Default_Handler - - .weak DMA1_Channel5_IRQHandler - .thumb_set DMA1_Channel5_IRQHandler,Default_Handler - - .weak DMA1_Channel6_IRQHandler - .thumb_set DMA1_Channel6_IRQHandler,Default_Handler - - .weak DMA1_Channel7_IRQHandler - .thumb_set DMA1_Channel7_IRQHandler,Default_Handler - - .weak ADC1_2_IRQHandler - .thumb_set ADC1_2_IRQHandler,Default_Handler - - .weak USB_HP_CAN1_TX_IRQHandler - .thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler - - .weak USB_LP_CAN1_RX0_IRQHandler - .thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler - - .weak CAN1_RX1_IRQHandler - .thumb_set CAN1_RX1_IRQHandler,Default_Handler - - .weak CAN1_SCE_IRQHandler - .thumb_set CAN1_SCE_IRQHandler,Default_Handler - - .weak EXTI9_5_IRQHandler - .thumb_set EXTI9_5_IRQHandler,Default_Handler - - .weak TIM1_BRK_IRQHandler - .thumb_set TIM1_BRK_IRQHandler,Default_Handler - - .weak TIM1_UP_IRQHandler - .thumb_set TIM1_UP_IRQHandler,Default_Handler - - .weak TIM1_TRG_COM_IRQHandler - .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler - - .weak TIM1_CC_IRQHandler - .thumb_set TIM1_CC_IRQHandler,Default_Handler - - .weak TIM2_IRQHandler - .thumb_set TIM2_IRQHandler,Default_Handler - - .weak TIM3_IRQHandler - .thumb_set TIM3_IRQHandler,Default_Handler - - .weak TIM4_IRQHandler - .thumb_set TIM4_IRQHandler,Default_Handler - - .weak I2C1_EV_IRQHandler - .thumb_set I2C1_EV_IRQHandler,Default_Handler - - .weak I2C1_ER_IRQHandler - .thumb_set I2C1_ER_IRQHandler,Default_Handler - - .weak I2C2_EV_IRQHandler - .thumb_set I2C2_EV_IRQHandler,Default_Handler - - .weak I2C2_ER_IRQHandler - .thumb_set I2C2_ER_IRQHandler,Default_Handler - - .weak SPI1_IRQHandler - .thumb_set SPI1_IRQHandler,Default_Handler - - .weak SPI2_IRQHandler - .thumb_set SPI2_IRQHandler,Default_Handler - - .weak USART1_IRQHandler - .thumb_set USART1_IRQHandler,Default_Handler - - .weak USART2_IRQHandler - .thumb_set USART2_IRQHandler,Default_Handler - - .weak USART3_IRQHandler - .thumb_set USART3_IRQHandler,Default_Handler - - .weak EXTI15_10_IRQHandler - .thumb_set EXTI15_10_IRQHandler,Default_Handler - - .weak RTCAlarm_IRQHandler - .thumb_set RTCAlarm_IRQHandler,Default_Handler - - .weak USBWakeUp_IRQHandler - .thumb_set USBWakeUp_IRQHandler,Default_Handler - - .weak TIM8_BRK_IRQHandler - .thumb_set TIM8_BRK_IRQHandler,Default_Handler - - .weak TIM8_UP_IRQHandler - .thumb_set TIM8_UP_IRQHandler,Default_Handler - - .weak TIM8_TRG_COM_IRQHandler - .thumb_set TIM8_TRG_COM_IRQHandler,Default_Handler - - .weak TIM8_CC_IRQHandler - .thumb_set TIM8_CC_IRQHandler,Default_Handler - - .weak ADC3_IRQHandler - .thumb_set ADC3_IRQHandler,Default_Handler - - .weak FSMC_IRQHandler - .thumb_set FSMC_IRQHandler,Default_Handler - - .weak SDIO_IRQHandler - .thumb_set SDIO_IRQHandler,Default_Handler - - .weak TIM5_IRQHandler - .thumb_set TIM5_IRQHandler,Default_Handler - - .weak SPI3_IRQHandler - .thumb_set SPI3_IRQHandler,Default_Handler - - .weak UART4_IRQHandler - .thumb_set UART4_IRQHandler,Default_Handler - - .weak UART5_IRQHandler - .thumb_set UART5_IRQHandler,Default_Handler - - .weak TIM6_IRQHandler - .thumb_set TIM6_IRQHandler,Default_Handler - - .weak TIM7_IRQHandler - .thumb_set TIM7_IRQHandler,Default_Handler - - .weak DMA2_Channel1_IRQHandler - .thumb_set DMA2_Channel1_IRQHandler,Default_Handler - - .weak DMA2_Channel2_IRQHandler - .thumb_set DMA2_Channel2_IRQHandler,Default_Handler - - .weak DMA2_Channel3_IRQHandler - .thumb_set DMA2_Channel3_IRQHandler,Default_Handler - - .weak DMA2_Channel4_5_IRQHandler - .thumb_set DMA2_Channel4_5_IRQHandler,Default_Handler - - .weak SystemInit_ExtMemCtl - .thumb_set SystemInit_ExtMemCtl,SystemInit_ExtMemCtl_Dummy - diff --git a/flight/pios/stm32f10x/startup_stm32f10x_MD.S b/flight/pios/stm32f10x/startup_stm32f10x_MD.S deleted file mode 100644 index 101499ca5..000000000 --- a/flight/pios/stm32f10x/startup_stm32f10x_MD.S +++ /dev/null @@ -1,355 +0,0 @@ -/** - ****************************************************************************** - * @file startup_stm32f10x_md.s - * @author MCD Application Team / Angus Peart - * @version V3.1.2 - * @date 09/28/2009 - * @brief STM32F10x Medium Density Devices vector table for RIDE7 toolchain. - * This module performs: - * - Set the initial SP - * - Set the initial PC == Reset_Handler, - * - Set the vector table entries with the exceptions ISR address - * - Branches to main in the C library (which eventually - * calls main()). - * After Reset the Cortex-M3 processor is in Thread mode, - * priority is Privileged, and the Stack is set to Main. - ******************************************************************************* - * @copy - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2009 STMicroelectronics

- */ - - .syntax unified - .cpu cortex-m3 - .fpu softvfp - .thumb - -.global g_pfnVectors -.global Default_Handler - -/* start address for the initialization values of the .data section. -defined in linker script */ -.word _sidata -/* start address for the .data section. defined in linker script */ -.word _sdata -/* end address for the .data section. defined in linker script */ -.word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss - -.equ BootRAM, 0xF108F85F -/** - * @brief This is the code that gets called when the processor first - * starts execution following a reset event. Only the absolutely - * necessary set is performed, after which the application - * supplied main() routine is called. - * @param None - * @retval : None -*/ - - .section .text.Reset_Handler - .weak Reset_Handler - .type Reset_Handler, %function -Reset_Handler: - -/* Copy the data segment initializers from flash to SRAM */ - movs r1, #0 - b LoopCopyDataInit - -CopyDataInit: - ldr r3, =_sidata - ldr r3, [r3, r1] - str r3, [r0, r1] - adds r1, r1, #4 - -LoopCopyDataInit: - ldr r0, =_sdata - ldr r3, =_edata - adds r2, r0, r1 - cmp r2, r3 - bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss -/* Call the application's entry point.*/ - bl main - bx lr -.size Reset_Handler, .-Reset_Handler - -/** - * @brief This is the code that gets called when the processor receives an - * unexpected interrupt. This simply enters an infinite loop, preserving - * the system state for examination by a debugger. - * - * @param None - * @retval : None -*/ - .section .text.Default_Handler,"ax",%progbits -Default_Handler: -Infinite_Loop: - b Infinite_Loop - .size Default_Handler, .-Default_Handler -/****************************************************************************** -* -* The minimal vector table for a Cortex M3. Note that the proper constructs -* must be placed on this to ensure that it ends up at physical address -* 0x0000.0000. -* -******************************************************************************/ - .section .isr_vector,"a",%progbits - .type g_pfnVectors, %object - .size g_pfnVectors, .-g_pfnVectors - - -g_pfnVectors: - .word _estack - .word Reset_Handler - .word NMI_Handler - .word HardFault_Handler - .word MemManage_Handler - .word BusFault_Handler - .word UsageFault_Handler - .word 0 - .word 0 - .word 0 - .word 0 - .word SVC_Handler - .word DebugMon_Handler - .word 0 - .word PendSV_Handler - .word SysTick_Handler - .word WWDG_IRQHandler - .word PVD_IRQHandler - .word TAMPER_IRQHandler - .word RTC_IRQHandler - .word FLASH_IRQHandler - .word RCC_IRQHandler - .word EXTI0_IRQHandler - .word EXTI1_IRQHandler - .word EXTI2_IRQHandler - .word EXTI3_IRQHandler - .word EXTI4_IRQHandler - .word DMA1_Channel1_IRQHandler - .word DMA1_Channel2_IRQHandler - .word DMA1_Channel3_IRQHandler - .word DMA1_Channel4_IRQHandler - .word DMA1_Channel5_IRQHandler - .word DMA1_Channel6_IRQHandler - .word DMA1_Channel7_IRQHandler - .word ADC1_2_IRQHandler - .word USB_HP_CAN1_TX_IRQHandler - .word USB_LP_CAN1_RX0_IRQHandler - .word CAN1_RX1_IRQHandler - .word CAN1_SCE_IRQHandler - .word EXTI9_5_IRQHandler - .word TIM1_BRK_IRQHandler - .word TIM1_UP_IRQHandler - .word TIM1_TRG_COM_IRQHandler - .word TIM1_CC_IRQHandler - .word TIM2_IRQHandler - .word TIM3_IRQHandler - .word TIM4_IRQHandler - .word I2C1_EV_IRQHandler - .word I2C1_ER_IRQHandler - .word I2C2_EV_IRQHandler - .word I2C2_ER_IRQHandler - .word SPI1_IRQHandler - .word SPI2_IRQHandler - .word USART1_IRQHandler - .word USART2_IRQHandler - .word USART3_IRQHandler - .word EXTI15_10_IRQHandler - .word RTCAlarm_IRQHandler - .word USBWakeUp_IRQHandler - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word BootRAM /* @0x108. This is for boot in RAM mode for - STM32F10x Medium Density devices. */ - -/******************************************************************************* -* -* Provide weak aliases for each Exception handler to the Default_Handler. -* As they are weak aliases, any function with the same name will override -* this definition. -* -*******************************************************************************/ - - .weak NMI_Handler - .thumb_set NMI_Handler,Default_Handler - - .weak HardFault_Handler - .thumb_set HardFault_Handler,Default_Handler - - .weak MemManage_Handler - .thumb_set MemManage_Handler,Default_Handler - - .weak BusFault_Handler - .thumb_set BusFault_Handler,Default_Handler - - .weak UsageFault_Handler - .thumb_set UsageFault_Handler,Default_Handler - - .weak SVC_Handler - .thumb_set SVC_Handler,Default_Handler - - .weak DebugMon_Handler - .thumb_set DebugMon_Handler,Default_Handler - - .weak PendSV_Handler - .thumb_set PendSV_Handler,Default_Handler - - .weak SysTick_Handler - .thumb_set SysTick_Handler,Default_Handler - - .weak WWDG_IRQHandler - .thumb_set WWDG_IRQHandler,Default_Handler - - .weak PVD_IRQHandler - .thumb_set PVD_IRQHandler,Default_Handler - - .weak TAMPER_IRQHandler - .thumb_set TAMPER_IRQHandler,Default_Handler - - .weak RTC_IRQHandler - .thumb_set RTC_IRQHandler,Default_Handler - - .weak FLASH_IRQHandler - .thumb_set FLASH_IRQHandler,Default_Handler - - .weak RCC_IRQHandler - .thumb_set RCC_IRQHandler,Default_Handler - - .weak EXTI0_IRQHandler - .thumb_set EXTI0_IRQHandler,Default_Handler - - .weak EXTI1_IRQHandler - .thumb_set EXTI1_IRQHandler,Default_Handler - - .weak EXTI2_IRQHandler - .thumb_set EXTI2_IRQHandler,Default_Handler - - .weak EXTI3_IRQHandler - .thumb_set EXTI3_IRQHandler,Default_Handler - - .weak EXTI4_IRQHandler - .thumb_set EXTI4_IRQHandler,Default_Handler - - .weak DMA1_Channel1_IRQHandler - .thumb_set DMA1_Channel1_IRQHandler,Default_Handler - - .weak DMA1_Channel2_IRQHandler - .thumb_set DMA1_Channel2_IRQHandler,Default_Handler - - .weak DMA1_Channel3_IRQHandler - .thumb_set DMA1_Channel3_IRQHandler,Default_Handler - - .weak DMA1_Channel4_IRQHandler - .thumb_set DMA1_Channel4_IRQHandler,Default_Handler - - .weak DMA1_Channel5_IRQHandler - .thumb_set DMA1_Channel5_IRQHandler,Default_Handler - - .weak DMA1_Channel6_IRQHandler - .thumb_set DMA1_Channel6_IRQHandler,Default_Handler - - .weak DMA1_Channel7_IRQHandler - .thumb_set DMA1_Channel7_IRQHandler,Default_Handler - - .weak ADC1_2_IRQHandler - .thumb_set ADC1_2_IRQHandler,Default_Handler - - .weak USB_HP_CAN1_TX_IRQHandler - .thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler - - .weak USB_LP_CAN1_RX0_IRQHandler - .thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler - - .weak CAN1_RX1_IRQHandler - .thumb_set CAN1_RX1_IRQHandler,Default_Handler - - .weak CAN1_SCE_IRQHandler - .thumb_set CAN1_SCE_IRQHandler,Default_Handler - - .weak EXTI9_5_IRQHandler - .thumb_set EXTI9_5_IRQHandler,Default_Handler - - .weak TIM1_BRK_IRQHandler - .thumb_set TIM1_BRK_IRQHandler,Default_Handler - - .weak TIM1_UP_IRQHandler - .thumb_set TIM1_UP_IRQHandler,Default_Handler - - .weak TIM1_TRG_COM_IRQHandler - .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler - - .weak TIM1_CC_IRQHandler - .thumb_set TIM1_CC_IRQHandler,Default_Handler - - .weak TIM2_IRQHandler - .thumb_set TIM2_IRQHandler,Default_Handler - - .weak TIM3_IRQHandler - .thumb_set TIM3_IRQHandler,Default_Handler - - .weak TIM4_IRQHandler - .thumb_set TIM4_IRQHandler,Default_Handler - - .weak I2C1_EV_IRQHandler - .thumb_set I2C1_EV_IRQHandler,Default_Handler - - .weak I2C1_ER_IRQHandler - .thumb_set I2C1_ER_IRQHandler,Default_Handler - - .weak I2C2_EV_IRQHandler - .thumb_set I2C2_EV_IRQHandler,Default_Handler - - .weak I2C2_ER_IRQHandler - .thumb_set I2C2_ER_IRQHandler,Default_Handler - - .weak SPI1_IRQHandler - .thumb_set SPI1_IRQHandler,Default_Handler - - .weak SPI2_IRQHandler - .thumb_set SPI2_IRQHandler,Default_Handler - - .weak USART1_IRQHandler - .thumb_set USART1_IRQHandler,Default_Handler - - .weak USART2_IRQHandler - .thumb_set USART2_IRQHandler,Default_Handler - - .weak USART3_IRQHandler - .thumb_set USART3_IRQHandler,Default_Handler - - .weak EXTI15_10_IRQHandler - .thumb_set EXTI15_10_IRQHandler,Default_Handler - - .weak RTCAlarm_IRQHandler - .thumb_set RTCAlarm_IRQHandler,Default_Handler - - .weak USBWakeUp_IRQHandler - .thumb_set USBWakeUp_IRQHandler,Default_Handler - - diff --git a/flight/pios/stm32f4xx/libraries/CMSIS/Device/ST/STM32F4xx/Source/sparky2/system_stm32f4xx.c b/flight/pios/stm32f4xx/libraries/CMSIS/Device/ST/STM32F4xx/Source/sparky2/system_stm32f4xx.c new file mode 100644 index 000000000..e6ffcd777 --- /dev/null +++ b/flight/pios/stm32f4xx/libraries/CMSIS/Device/ST/STM32F4xx/Source/sparky2/system_stm32f4xx.c @@ -0,0 +1,560 @@ +/** + ****************************************************************************** + * @file system_stm32f4xx.c + * @author MCD Application Team + * @version V1.1.0 + * @date 11-January-2013 + * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File. + * This file contains the system clock configuration for STM32F4xx devices, + * and is generated by the clock configuration tool + * stm32f4xx_Clock_Configuration_V1.1.0.xls + * + * 1. This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier + * and Divider factors, AHB/APBx prescalers and Flash settings), + * depending on the configuration made in the clock xls tool. + * This function is called at startup just after reset and + * before branch to main program. This call is made inside + * the "startup_stm32f4xx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used + * by the user application to setup the SysTick + * timer or configure other parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * 2. After each device reset the HSI (16 MHz) is used as system clock source. + * Then SystemInit() function is called, in "startup_stm32f4xx.s" file, to + * configure the system clock before to branch to main program. + * + * 3. If the system clock source selected by user fails to startup, the SystemInit() + * function will do nothing and HSI still used as system clock source. User can + * add some code to deal with this issue inside the SetSysClock() function. + * + * 4. The default value of HSE crystal is set to 25MHz, refer to "HSE_VALUE" define + * in "stm32f4xx.h" file. When HSE is used as system clock source, directly or + * through PLL, and you are using different crystal you have to adapt the HSE + * value to your own configuration. + * + * 5. This file configures the system clock as follows: + *============================================================================= + *============================================================================= + * Supported STM32F40xx/41xx/427x/437x devices + *----------------------------------------------------------------------------- + * System Clock source | PLL (HSE) + *----------------------------------------------------------------------------- + * SYSCLK(Hz) | 168000000 + *----------------------------------------------------------------------------- + * HCLK(Hz) | 168000000 + *----------------------------------------------------------------------------- + * AHB Prescaler | 1 + *----------------------------------------------------------------------------- + * APB1 Prescaler | 4 + *----------------------------------------------------------------------------- + * APB2 Prescaler | 2 + *----------------------------------------------------------------------------- + * HSE Frequency(Hz) | 8000000 + *----------------------------------------------------------------------------- + * PLL_M | 10 + *----------------------------------------------------------------------------- + * PLL_N | 420 + *----------------------------------------------------------------------------- + * PLL_P | 2 + *----------------------------------------------------------------------------- + * PLL_Q | 7 + *----------------------------------------------------------------------------- + * PLLI2S_N | NA + *----------------------------------------------------------------------------- + * PLLI2S_R | NA + *----------------------------------------------------------------------------- + * I2S input clock | NA + *----------------------------------------------------------------------------- + * VDD(V) | 3.3 + *----------------------------------------------------------------------------- + * Main regulator output voltage | Scale1 mode + *----------------------------------------------------------------------------- + * Flash Latency(WS) | 5 + *----------------------------------------------------------------------------- + * Prefetch Buffer | ON + *----------------------------------------------------------------------------- + * Instruction cache | ON + *----------------------------------------------------------------------------- + * Data cache | ON + *----------------------------------------------------------------------------- + * Require 48MHz for USB OTG FS, | Enabled + * SDIO and RNG clock | + *----------------------------------------------------------------------------- + *============================================================================= + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f4xx_system + * @{ + */ + +/** @addtogroup STM32F4xx_System_Private_Includes + * @{ + */ + +#include "stm32f4xx.h" + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Defines + * @{ + */ + +/************************* Miscellaneous Configuration ************************/ +/*!< Uncomment the following line if you need to use external SRAM mounted + on STM324xG_EVAL/STM324x7I_EVAL boards as data memory */ +/* #define DATA_IN_ExtSRAM */ + +/*!< Uncomment the following line if you need to relocate your vector Table in + Internal SRAM. */ +/* #define VECT_TAB_SRAM */ +#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field. + This value must be a multiple of 0x200. */ +/******************************************************************************/ + +/************************* PLL Parameters *************************************/ +/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */ +#define PLL_M 10 +#define PLL_N 420 + +/* SYSCLK = PLL_VCO / PLL_P */ +#define PLL_P 2 + +/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */ +#define PLL_Q 7 + +/******************************************************************************/ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Variables + * @{ + */ + + uint32_t SystemCoreClock = 168000000; + + __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_FunctionPrototypes + * @{ + */ + +static void SetSysClock(void); +#ifdef DATA_IN_ExtSRAM + static void SystemInit_ExtMemCtl(void); +#endif /* DATA_IN_ExtSRAM */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system + * Initialize the Embedded Flash Interface, the PLL and update the + * SystemFrequency variable. + * @param None + * @retval None + */ +void SystemInit(void) +{ + /* FPU settings ------------------------------------------------------------*/ + #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ + #endif + /* Reset the RCC clock configuration to the default reset state ------------*/ + /* Set HSION bit */ + RCC->CR |= (uint32_t)0x00000001; + + /* Reset CFGR register */ + RCC->CFGR = 0x00000000; + + /* Reset HSEON, CSSON and PLLON bits */ + RCC->CR &= (uint32_t)0xFEF6FFFF; + + /* Reset PLLCFGR register */ + RCC->PLLCFGR = 0x24003010; + + /* Reset HSEBYP bit */ + RCC->CR &= (uint32_t)0xFFFBFFFF; + + /* Disable all interrupts */ + RCC->CIR = 0x00000000; + +#ifdef DATA_IN_ExtSRAM + SystemInit_ExtMemCtl(); +#endif /* DATA_IN_ExtSRAM */ + + /* Configure the System clock source, PLL Multiplier and Divider factors, + AHB/APBx prescalers and Flash settings ----------------------------------*/ + SetSysClock(); + + /* Configure the Vector Table location add offset address ------------------*/ +#ifdef VECT_TAB_SRAM + SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ +#else + SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ +#endif +} + +/** + * @brief Update SystemCoreClock variable according to Clock Register Values. + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note Each time the core clock (HCLK) changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any configuration + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) + * or HSI_VALUE(*) multiplied/divided by the PLL factors. + * + * (*) HSI_VALUE is a constant defined in stm32f4xx.h file (default value + * 16 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (**) HSE_VALUE is a constant defined in stm32f4xx.h file (default value + * 25 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * have wrong result. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @param None + * @retval None + */ +void SystemCoreClockUpdate(void) +{ + uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2; + + /* Get SYSCLK source -------------------------------------------------------*/ + tmp = RCC->CFGR & RCC_CFGR_SWS; + + switch (tmp) + { + case 0x00: /* HSI used as system clock source */ + SystemCoreClock = HSI_VALUE; + break; + case 0x04: /* HSE used as system clock source */ + SystemCoreClock = HSE_VALUE; + break; + case 0x08: /* PLL used as system clock source */ + + /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N + SYSCLK = PLL_VCO / PLL_P + */ + pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22; + pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; + + if (pllsource != 0) + { + /* HSE used as PLL clock source */ + pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } + else + { + /* HSI used as PLL clock source */ + pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } + + pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2; + SystemCoreClock = pllvco/pllp; + break; + default: + SystemCoreClock = HSI_VALUE; + break; + } + /* Compute HCLK frequency --------------------------------------------------*/ + /* Get HCLK prescaler */ + tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; + /* HCLK frequency */ + SystemCoreClock >>= tmp; +} + +/** + * @brief Configures the System clock source, PLL Multiplier and Divider factors, + * AHB/APBx prescalers and Flash settings + * @Note This function should be called only once the RCC clock configuration + * is reset to the default reset state (done in SystemInit() function). + * @param None + * @retval None + */ +static void SetSysClock(void) +{ +/******************************************************************************/ +/* PLL (clocked by HSE) used as System clock source */ +/******************************************************************************/ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + /* Enable HSE */ + RCC->CR |= ((uint32_t)RCC_CR_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CR & RCC_CR_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if ((RCC->CR & RCC_CR_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if (HSEStatus == (uint32_t)0x01) + { + /* Select regulator voltage output Scale 1 mode, System frequency up to 168 MHz */ + RCC->APB1ENR |= RCC_APB1ENR_PWREN; + PWR->CR |= PWR_CR_VOS; + + /* HCLK = SYSCLK / 1*/ + RCC->CFGR |= RCC_CFGR_HPRE_DIV1; + + /* PCLK2 = HCLK / 2*/ + RCC->CFGR |= RCC_CFGR_PPRE2_DIV2; + + /* PCLK1 = HCLK / 4*/ + RCC->CFGR |= RCC_CFGR_PPRE1_DIV4; + + /* Configure the main PLL */ + RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | + (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); + + /* Enable the main PLL */ + RCC->CR |= RCC_CR_PLLON; + + /* Wait till the main PLL is ready */ + while((RCC->CR & RCC_CR_PLLRDY) == 0) + { + } + + /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ + FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_5WS; + + /* Select the main PLL as system clock source */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); + RCC->CFGR |= RCC_CFGR_SW_PLL; + + /* Wait till the main PLL is used as system clock source */ + while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); + { + } + } + else + { /* If HSE fails to start-up, the application will have wrong clock + configuration. User can add here some code to deal with this error */ + } + +} + +/** + * @brief Setup the external memory controller. Called in startup_stm32f4xx.s + * before jump to __main + * @param None + * @retval None + */ +#ifdef DATA_IN_ExtSRAM +/** + * @brief Setup the external memory controller. + * Called in startup_stm32f4xx.s before jump to main. + * This function configures the external SRAM mounted on STM324xG_EVAL/STM324x7I boards + * This SRAM will be used as program data memory (including heap and stack). + * @param None + * @retval None + */ +void SystemInit_ExtMemCtl(void) +{ +/*-- GPIOs Configuration -----------------------------------------------------*/ +/* + +-------------------+--------------------+------------------+------------------+ + + SRAM pins assignment + + +-------------------+--------------------+------------------+------------------+ + | PD0 <-> FSMC_D2 | PE0 <-> FSMC_NBL0 | PF0 <-> FSMC_A0 | PG0 <-> FSMC_A10 | + | PD1 <-> FSMC_D3 | PE1 <-> FSMC_NBL1 | PF1 <-> FSMC_A1 | PG1 <-> FSMC_A11 | + | PD4 <-> FSMC_NOE | PE2 <-> FSMC_A23 | PF2 <-> FSMC_A2 | PG2 <-> FSMC_A12 | + | PD5 <-> FSMC_NWE | PE3 <-> FSMC_A19 | PF3 <-> FSMC_A3 | PG3 <-> FSMC_A13 | + | PD8 <-> FSMC_D13 | PE4 <-> FSMC_A20 | PF4 <-> FSMC_A4 | PG4 <-> FSMC_A14 | + | PD9 <-> FSMC_D14 | PE5 <-> FSMC_A21 | PF5 <-> FSMC_A5 | PG5 <-> FSMC_A15 | + | PD10 <-> FSMC_D15 | PE6 <-> FSMC_A22 | PF12 <-> FSMC_A6 | PG9 <-> FSMC_NE2 | + | PD11 <-> FSMC_A16 | PE7 <-> FSMC_D4 | PF13 <-> FSMC_A7 |------------------+ + | PD12 <-> FSMC_A17 | PE8 <-> FSMC_D5 | PF14 <-> FSMC_A8 | + | PD13 <-> FSMC_A18 | PE9 <-> FSMC_D6 | PF15 <-> FSMC_A9 | + | PD14 <-> FSMC_D0 | PE10 <-> FSMC_D7 |------------------+ + | PD15 <-> FSMC_D1 | PE11 <-> FSMC_D8 | + +-------------------| PE12 <-> FSMC_D9 | + | PE13 <-> FSMC_D10 | + | PE14 <-> FSMC_D11 | + | PE15 <-> FSMC_D12 | + +--------------------+ +*/ + /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */ + RCC->AHB1ENR |= 0x00000078; + + /* Connect PDx pins to FSMC Alternate function */ + GPIOD->AFR[0] = 0x00cc00cc; + GPIOD->AFR[1] = 0xcccccccc; + /* Configure PDx pins in Alternate function mode */ + GPIOD->MODER = 0xaaaa0a0a; + /* Configure PDx pins speed to 100 MHz */ + GPIOD->OSPEEDR = 0xffff0f0f; + /* Configure PDx pins Output type to push-pull */ + GPIOD->OTYPER = 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOD->PUPDR = 0x00000000; + + /* Connect PEx pins to FSMC Alternate function */ + GPIOE->AFR[0] = 0xcccccccc; + GPIOE->AFR[1] = 0xcccccccc; + /* Configure PEx pins in Alternate function mode */ + GPIOE->MODER = 0xaaaaaaaa; + /* Configure PEx pins speed to 100 MHz */ + GPIOE->OSPEEDR = 0xffffffff; + /* Configure PEx pins Output type to push-pull */ + GPIOE->OTYPER = 0x00000000; + /* No pull-up, pull-down for PEx pins */ + GPIOE->PUPDR = 0x00000000; + + /* Connect PFx pins to FSMC Alternate function */ + GPIOF->AFR[0] = 0x00cccccc; + GPIOF->AFR[1] = 0xcccc0000; + /* Configure PFx pins in Alternate function mode */ + GPIOF->MODER = 0xaa000aaa; + /* Configure PFx pins speed to 100 MHz */ + GPIOF->OSPEEDR = 0xff000fff; + /* Configure PFx pins Output type to push-pull */ + GPIOF->OTYPER = 0x00000000; + /* No pull-up, pull-down for PFx pins */ + GPIOF->PUPDR = 0x00000000; + + /* Connect PGx pins to FSMC Alternate function */ + GPIOG->AFR[0] = 0x00cccccc; + GPIOG->AFR[1] = 0x000000c0; + /* Configure PGx pins in Alternate function mode */ + GPIOG->MODER = 0x00080aaa; + /* Configure PGx pins speed to 100 MHz */ + GPIOG->OSPEEDR = 0x000c0fff; + /* Configure PGx pins Output type to push-pull */ + GPIOG->OTYPER = 0x00000000; + /* No pull-up, pull-down for PGx pins */ + GPIOG->PUPDR = 0x00000000; + +/*-- FSMC Configuration ------------------------------------------------------*/ + /* Enable the FSMC interface clock */ + RCC->AHB3ENR |= 0x00000001; + + /* Configure and enable Bank1_SRAM2 */ + FSMC_Bank1->BTCR[2] = 0x00001011; + FSMC_Bank1->BTCR[3] = 0x00000201; + FSMC_Bank1E->BWTR[2] = 0x0fffffff; +/* + Bank1_SRAM2 is configured as follow: + + p.FSMC_AddressSetupTime = 1; + p.FSMC_AddressHoldTime = 0; + p.FSMC_DataSetupTime = 2; + p.FSMC_BusTurnAroundDuration = 0; + p.FSMC_CLKDivision = 0; + p.FSMC_DataLatency = 0; + p.FSMC_AccessMode = FSMC_AccessMode_A; + + FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2; + FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; + FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM; + FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; + FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; + FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; + FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; + FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; + FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; + FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; + FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; + FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; + FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; + FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p; + FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p; +*/ +} +#endif /* DATA_IN_ExtSRAM */ + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/flight/pios/stm32f4xx/library.mk b/flight/pios/stm32f4xx/library.mk index 7094a2b3f..669c8c08a 100644 --- a/flight/pios/stm32f4xx/library.mk +++ b/flight/pios/stm32f4xx/library.mk @@ -16,12 +16,26 @@ LINKER_SCRIPTS_COMPAT = $(PIOS_DEVLIB)link_$(BOARD)_fw_memory.ld \ # Compiler options implied by the F4xx CDEFS += -DSTM32F4XX +ifeq ($(CHIPFAMILY),STM32F427_437xx) +CDEFS += -DPIOS_TARGET_PROVIDES_FAST_HEAP +#large heap support must be enabled if SRAM > 128K +CDEFS += -DHEAP_SUPPORT_LARGE +CDEFS += -DSTM32F427_437xx +else +ifeq ($(CHIPFAMILY),STM32F429_439xx) +CDEFS += -DPIOS_TARGET_PROVIDES_FAST_HEAP +#large heap support must be enabled if SRAM > 128K +CDEFS += -DHEAP_SUPPORT_LARGE +CDEFS += -DSTM32F429_439xx +else ifneq ($(CHIPFAMILY),STM32F411xx) CDEFS += -DPIOS_TARGET_PROVIDES_FAST_HEAP CDEFS += -DSTM32F40_41xxx else CDEFS += -DSTM32F411xE endif +endif #STM32F429_439xx +endif #STM32F427_437xx CDEFS += -DSYSCLK_FREQ=$(SYSCLK_FREQ) CDEFS += -DHSE_VALUE=$(OSCILLATOR_FREQ) CDEFS += -DUSE_STDPERIPH_DRIVER diff --git a/flight/pios/stm32f4xx/link_STM32F4xx_RQ_bl_memory.ld b/flight/pios/stm32f4xx/link_STM32F4xx_RQ_bl_memory.ld new file mode 100644 index 000000000..7aa493e0f --- /dev/null +++ b/flight/pios/stm32f4xx/link_STM32F4xx_RQ_bl_memory.ld @@ -0,0 +1,9 @@ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 0x008000 - 0x000080 + BD_INFO (r) : ORIGIN = 0x08008000 - 0x80, LENGTH = 0x000080 + RSVD (rx) : ORIGIN = 0x08008000, LENGTH = 0x020000 - 0x008000 + FW (rx) : ORIGIN = 0x08020000, LENGTH = 0x1e0000 + CCSRAM (rw) : ORIGIN = 0x10000000, LENGTH = 0x010000 + SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x030000 +} diff --git a/flight/pios/stm32f4xx/link_STM32F4xx_RQ_fw_memory.ld b/flight/pios/stm32f4xx/link_STM32F4xx_RQ_fw_memory.ld new file mode 100644 index 000000000..cb693c543 --- /dev/null +++ b/flight/pios/stm32f4xx/link_STM32F4xx_RQ_fw_memory.ld @@ -0,0 +1,9 @@ +MEMORY +{ + BL (rx) : ORIGIN = 0x08000000, LENGTH = 0x008000 - 0x000080 + BD_INFO (r) : ORIGIN = 0x08008000 - 0x80, LENGTH = 0x000080 + RSVD (rx) : ORIGIN = 0x08008000, LENGTH = 0x020000 - 0x008000 + FLASH (rx) : ORIGIN = 0x08020000, LENGTH = 0x1e0000 + CCSRAM (rw) : ORIGIN = 0x10000000, LENGTH = 0x010000 + SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x030000 +} diff --git a/flight/pios/stm32f4xx/link_STM32F4xx_RQ_sections.ld b/flight/pios/stm32f4xx/link_STM32F4xx_RQ_sections.ld new file mode 100644 index 000000000..41644bacb --- /dev/null +++ b/flight/pios/stm32f4xx/link_STM32F4xx_RQ_sections.ld @@ -0,0 +1,193 @@ + +/* Section Definitions */ +SECTIONS +{ + /* + * Vectors, code and constant data. + */ + .text : + { + PROVIDE (pios_isr_vector_table_base = .); + KEEP(*(.cpu_vectors)) /* CPU exception vectors */ + KEEP(*(.io_vectors)) /* I/O interrupt vectors */ + *(.text .text.* .gnu.linkonce.t.*) + *(.glue_7t) *(.glue_7) + *(.rodata .rodata* .gnu.linkonce.r.*) + } > FLASH + + /* + * Init section for UAVObjects. + */ + .initcalluavobj.init : + { + . = ALIGN(4); + __uavobj_initcall_start = .; + KEEP(*(.initcalluavobj.init)) + . = ALIGN(4); + __uavobj_initcall_end = .; + } >FLASH + + /* + * Module init section section + */ + .initcallmodule.init : + { + . = ALIGN(4); + __module_initcall_start = .; + KEEP(*(.initcallmodule.init)) + . = ALIGN(4); + __module_initcall_end = .; + } >FLASH + + /* + * C++ exception handling. + */ + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + .ARM.exidx : + { + __exidx_start = .; + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __exidx_end = .; + } > FLASH + + /* + * Markers for the end of the 'text' section and the in-flash start of + * non-constant data + */ + . = ALIGN(4); + _etext = .; + _sidata = .; + + /* + * Board info structure, normally only generated by the bootloader but can + * be read by the application. + */ + PROVIDE(pios_board_info_blob = ORIGIN(BD_INFO)); + .boardinfo : + { + . = ALIGN(4); + KEEP(*(.boardinfo)) + . = ALIGN(ORIGIN(BD_INFO)+LENGTH(BD_INFO)); + } > BD_INFO + + /* + * Place the IRQ/bootstrap stack at the bottom of SRAM so that an overflow + * results in a hard fault. + */ + .istack (NOLOAD) : + { + . = ALIGN(4); + _irq_stack_end = . ; + *(.irqstack) + _irq_stack_top = . ; + } > CCSRAM + + + /* + * Non-const initialised data. + */ + .data : AT (_sidata) + { + . = ALIGN(4); + _sdata = .; + *(.data .data.*) + . = ALIGN(4); + _edata = . ; + } > SRAM + + /* + * Uninitialised data (BSS + commons). + */ + .bss (NOLOAD) : + { + _sbss = . ; + *(.bss .bss.*) + *(COMMON) + _ebss = . ; + PROVIDE ( _end = _ebss ) ; + } > SRAM + + /* + * The heap consumes the remainder of the SRAM. + */ + .heap (NOLOAD) : + { + . = ALIGN(4); + _sheap = . ; + + /* + * This allows us to declare an object or objects up to the minimum acceptable + * heap size and receive a linker error if the space available for the heap is + * not sufficient. + */ + *(.heap) + + /* extend the heap up to the top of SRAM */ + . = ORIGIN(SRAM) + LENGTH(SRAM) - ABSOLUTE(_sheap); + _eheap = .; + } > SRAM + + /* + * 'Fast' memory goes in the CCM SRAM + */ + .fast (NOLOAD) : + { + _sfast = . ; + *(.fast) + _efast = . ; + } > CCSRAM + + .fastheap (NOLOAD) : + { + . = ALIGN(4); + _sfastheap = . ; + + /* + * This allows us to declare an object or objects up to the minimum acceptable + * heap size and receive a linker error if the space available for the heap is + * not sufficient. + */ + *(.fastheap) + + /* extend the fastheap up to the top of CCSRAM */ + . = ORIGIN(CCSRAM) + LENGTH(CCSRAM) - ABSOLUTE(_sfastheap); + _efastheap = .; + } > CCSRAM + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } +} diff --git a/flight/pios/stm32f4xx/link_STM32F4xx_RQ_sections_compat.ld b/flight/pios/stm32f4xx/link_STM32F4xx_RQ_sections_compat.ld new file mode 100644 index 000000000..2f4300f4b --- /dev/null +++ b/flight/pios/stm32f4xx/link_STM32F4xx_RQ_sections_compat.ld @@ -0,0 +1,176 @@ + +/* Section Definitions */ +SECTIONS +{ + /* + * Vectors, code and constant data. + */ + .text : + { + PROVIDE (pios_isr_vector_table_base = .); + KEEP(*(.cpu_vectors)) /* CPU exception vectors */ + KEEP(*(.io_vectors)) /* I/O interrupt vectors */ + *(.text .text.* .gnu.linkonce.t.*) + *(.glue_7t) *(.glue_7) + *(.rodata .rodata* .gnu.linkonce.r.*) + } > FLASH + + /* + * Init section for UAVObjects. + */ + .initcalluavobj.init : + { + . = ALIGN(4); + __uavobj_initcall_start = .; + KEEP(*(.initcalluavobj.init)) + . = ALIGN(4); + __uavobj_initcall_end = .; + } >FLASH + + /* + * Module init section section + */ + .initcallmodule.init : + { + . = ALIGN(4); + __module_initcall_start = .; + KEEP(*(.initcallmodule.init)) + . = ALIGN(4); + __module_initcall_end = .; + } >FLASH + + /* + * C++ exception handling. + */ + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + .ARM.exidx : + { + __exidx_start = .; + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __exidx_end = .; + } > FLASH + + /* + * Markers for the end of the 'text' section and the in-flash start of + * non-constant data + */ + . = ALIGN(4); + _etext = .; + _sidata = .; + + /* + * Board info structure, normally only generated by the bootloader but can + * be read by the application. + */ + PROVIDE(pios_board_info_blob = ORIGIN(BD_INFO)); + .boardinfo : + { + . = ALIGN(4); + KEEP(*(.boardinfo)) + . = ALIGN(ORIGIN(BD_INFO)+LENGTH(BD_INFO)); + } > BD_INFO + + /* + * Place the IRQ/bootstrap stack at the bottom of SRAM so that an overflow + * results in a hard fault. + */ + .istack (NOLOAD) : + { + . = ALIGN(4); + _irq_stack_end = . ; + *(.irqstack) + _irq_stack_top = . ; + } > SRAM + + + /* + * Non-const initialised data. + */ + .data : AT (_sidata) + { + . = ALIGN(4); + _sdata = .; + *(.data .data.*) + . = ALIGN(4); + _edata = . ; + } > SRAM + + /* + * Uninitialised data (BSS + commons). + */ + .bss (NOLOAD) : + { + _sbss = . ; + *(.bss .bss.*) + *(COMMON) + _ebss = . ; + PROVIDE ( _end = _ebss ) ; + } > SRAM + + /* + * The heap consumes the remainder of the SRAM. + */ + .heap (NOLOAD) : + { + . = ALIGN(4); + _sheap = . ; + + /* + * This allows us to declare an object or objects up to the minimum acceptable + * heap size and receive a linker error if the space available for the heap is + * not sufficient. + */ + *(.heap) + + /* extend the heap up to the top of SRAM */ + . = ORIGIN(SRAM) + LENGTH(SRAM) - ABSOLUTE(_sheap); + _eheap = .; + } > SRAM + + /* + * 'Fast' memory goes in the CCM SRAM + */ + .fast (NOLOAD) : + { + _sfast = . ; + *(.fast) + _efast = . ; + } > CCSRAM + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } +} diff --git a/flight/pios/stm32f4xx/pios_bl_helper.c b/flight/pios/stm32f4xx/pios_bl_helper.c index 045779245..8b2150450 100644 --- a/flight/pios/stm32f4xx/pios_bl_helper.c +++ b/flight/pios/stm32f4xx/pios_bl_helper.c @@ -119,6 +119,66 @@ static struct device_flash_sector flash_sectors[] = { .size = 128 * 1024, .st_sector = FLASH_Sector_11, }, + [12] = { + .start = 0x08100000, + .size = 16 * 1024, + .st_sector = FLASH_Sector_12, + }, + [13] = { + .start = 0x08104000, + .size = 16 * 1024, + .st_sector = FLASH_Sector_13, + }, + [14] = { + .start = 0x08108000, + .size = 16 * 1024, + .st_sector = FLASH_Sector_14, + }, + [15] = { + .start = 0x0810C000, + .size = 16 * 1024, + .st_sector = FLASH_Sector_15, + }, + [16] = { + .start = 0x08110000, + .size = 64 * 1024, + .st_sector = FLASH_Sector_16, + }, + [17] = { + .start = 0x08120000, + .size = 128 * 1024, + .st_sector = FLASH_Sector_17, + }, + [18] = { + .start = 0x08140000, + .size = 128 * 1024, + .st_sector = FLASH_Sector_18, + }, + [19] = { + .start = 0x08160000, + .size = 128 * 1024, + .st_sector = FLASH_Sector_19, + }, + [20] = { + .start = 0x08180000, + .size = 128 * 1024, + .st_sector = FLASH_Sector_20, + }, + [21] = { + .start = 0x081A0000, + .size = 128 * 1024, + .st_sector = FLASH_Sector_21, + }, + [22] = { + .start = 0x081C0000, + .size = 128 * 1024, + .st_sector = FLASH_Sector_22, + }, + [23] = { + .start = 0x081E0000, + .size = 128 * 1024, + .st_sector = FLASH_Sector_23, + }, }; static bool PIOS_BL_HELPER_FLASH_GetSectorInfo(uint32_t address, uint8_t *sector_number, uint32_t *sector_start, uint32_t *sector_size) @@ -178,7 +238,19 @@ static bool erase_flash(uint32_t startAddress, uint32_t endAddress) PIOS_Assert(0); } for (int retry = 0; retry < MAX_DEL_RETRYS; ++retry) { - if (FLASH_EraseSector(sector_number, VoltageRange_3) == FLASH_COMPLETE) { + // if erasing area contain whole bank2 area, using bank erase + // bank2: sector 12 to sector 23 + if (sector_start == flash_sectors[12].start && + endAddress >= (flash_sectors[23].start + flash_sectors[23].size)) { + if (FLASH_EraseAllBank2Sectors(VoltageRange_3) == FLASH_COMPLETE) { + fail = false; + // using bank2 total size substitute sector_size + sector_size = flash_sectors[23].start - flash_sectors[12].start + flash_sectors[23].size; + break; + } else { + fail = true; + } + } else if (FLASH_EraseSector(sector_number, VoltageRange_3) == FLASH_COMPLETE) { fail = false; break; } else { diff --git a/flight/pios/stm32f4xx/pios_delay.c b/flight/pios/stm32f4xx/pios_delay.c index 55970d203..f9c5d62b1 100644 --- a/flight/pios/stm32f4xx/pios_delay.c +++ b/flight/pios/stm32f4xx/pios_delay.c @@ -7,7 +7,8 @@ * @{ * * @file pios_delay.c - * @author Michael Smith Copyright (C) 2012 + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * Michael Smith Copyright (C) 2012 * @brief Delay Functions * - Provides a micro-second granular delay using the CPU * cycle counter. @@ -168,6 +169,17 @@ uint32_t PIOS_DELAY_DiffuS(uint32_t raw) return diff / us_ticks; } +#if !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) +/** + * @brief Subtract two raw times and convert to us. + * @return Interval between raw times in microseconds + */ +uint32_t PIOS_DELAY_DiffuS2(uint32_t raw, uint32_t later) +{ + return (later - raw) / us_ticks; +} +#endif /* !defined(PIOS_EXCLUDE_ADVANCED_FEATURES) */ + #endif /* PIOS_INCLUDE_DELAY */ /** diff --git a/flight/pios/stm32f4xx/pios_exti.c b/flight/pios/stm32f4xx/pios_exti.c index e32cc98b9..55f59a90e 100644 --- a/flight/pios/stm32f4xx/pios_exti.c +++ b/flight/pios/stm32f4xx/pios_exti.c @@ -33,16 +33,9 @@ #ifdef PIOS_INCLUDE_EXTI -/* Map EXTI line to full config */ -#define EXTI_MAX_LINES 16 -#define PIOS_EXTI_INVALID 0xFF -static uint8_t pios_exti_line_to_cfg_map[EXTI_MAX_LINES] = { - [0 ... EXTI_MAX_LINES - 1] = PIOS_EXTI_INVALID, -}; +#define EXTI_MAX_LINES 16 -/* Table of exti configs registered at compile time */ -extern struct pios_exti_cfg __start__exti __attribute__((weak)); -extern struct pios_exti_cfg __stop__exti __attribute__((weak)); +static pios_exti_vector_t pios_exti_vector[EXTI_MAX_LINES]; static uint8_t PIOS_EXTI_line_to_index(uint32_t line) { @@ -149,28 +142,24 @@ uint8_t PIOS_EXTI_gpio_pin_to_exti_source_pin(uint32_t gpio_pin) int32_t PIOS_EXTI_Init(const struct pios_exti_cfg *cfg) { PIOS_Assert(cfg); - PIOS_Assert(&__start__exti); - PIOS_Assert(cfg >= &__start__exti); - PIOS_Assert(cfg < &__stop__exti); - - uint8_t cfg_index = cfg - &__start__exti; /* Connect this config to the requested vector */ uint8_t line_index = PIOS_EXTI_line_to_index(cfg->line); - if (pios_exti_line_to_cfg_map[line_index] != PIOS_EXTI_INVALID) { + if (pios_exti_vector[line_index]) { /* Someone else already has this mapped */ - goto out_fail; + return -1; } - /* Bind the config to the exti line */ - pios_exti_line_to_cfg_map[line_index] = cfg_index; + /* Bind the vector to the exti line */ + pios_exti_vector[line_index] = cfg->vector; /* Initialize the GPIO pin */ GPIO_Init(cfg->pin.gpio, &cfg->pin.init); /* Set up the EXTI interrupt source */ uint8_t exti_source_port = PIOS_EXTI_gpio_port_to_exti_source_port(cfg->pin.gpio); + /* Following is not entirely correct! There is cfg->pin.pin_source to serve this purpose, and GPIO_Pin can also contain more than one bit set */ uint8_t exti_source_pin = PIOS_EXTI_gpio_pin_to_exti_source_pin(cfg->pin.init.GPIO_Pin); SYSCFG_EXTILineConfig(exti_source_port, exti_source_pin); EXTI_Init(&cfg->exti.init); @@ -179,25 +168,33 @@ int32_t PIOS_EXTI_Init(const struct pios_exti_cfg *cfg) NVIC_Init(&cfg->irq.init); return 0; +} + +int32_t PIOS_EXTI_DeInit(const struct pios_exti_cfg *cfg) +{ + uint8_t line_index = PIOS_EXTI_line_to_index(cfg->line); + + if (pios_exti_vector[line_index] == cfg->vector) { + EXTI_InitTypeDef disable = cfg->exti.init; + disable.EXTI_LineCmd = DISABLE; + + EXTI_Init(&disable); + pios_exti_vector[line_index] = 0; + + return 0; + } -out_fail: return -1; } static bool PIOS_EXTI_generic_irq_handler(uint8_t line_index) { - uint8_t cfg_index = pios_exti_line_to_cfg_map[line_index]; - - PIOS_Assert(&__start__exti); - - if (cfg_index > NELEMENTS(pios_exti_line_to_cfg_map) || - cfg_index == PIOS_EXTI_INVALID) { - /* Unconfigured interrupt just fired! */ - return false; + if (pios_exti_vector[line_index]) { + return pios_exti_vector[line_index](); } - struct pios_exti_cfg *cfg = &__start__exti + cfg_index; - return cfg->vector(); + /* Unconfigured interrupt just fired! */ + return false; } /* Bind Interrupt Handlers */ diff --git a/flight/pios/stm32f4xx/pios_flash_internal.c b/flight/pios/stm32f4xx/pios_flash_internal.c index 18e66bf17..2c65a3e7a 100644 --- a/flight/pios/stm32f4xx/pios_flash_internal.c +++ b/flight/pios/stm32f4xx/pios_flash_internal.c @@ -100,6 +100,66 @@ static struct device_flash_sector flash_sectors[] = { .size = 128 * 1024, .st_sector = FLASH_Sector_11, }, + [12] = { + .start = 0x08100000, + .size = 16 * 1024, + .st_sector = FLASH_Sector_12, + }, + [13] = { + .start = 0x08104000, + .size = 16 * 1024, + .st_sector = FLASH_Sector_13, + }, + [14] = { + .start = 0x08108000, + .size = 16 * 1024, + .st_sector = FLASH_Sector_14, + }, + [15] = { + .start = 0x0810C000, + .size = 16 * 1024, + .st_sector = FLASH_Sector_15, + }, + [16] = { + .start = 0x08110000, + .size = 64 * 1024, + .st_sector = FLASH_Sector_16, + }, + [17] = { + .start = 0x08120000, + .size = 128 * 1024, + .st_sector = FLASH_Sector_17, + }, + [18] = { + .start = 0x08140000, + .size = 128 * 1024, + .st_sector = FLASH_Sector_18, + }, + [19] = { + .start = 0x08160000, + .size = 128 * 1024, + .st_sector = FLASH_Sector_19, + }, + [20] = { + .start = 0x08180000, + .size = 128 * 1024, + .st_sector = FLASH_Sector_20, + }, + [21] = { + .start = 0x081A0000, + .size = 128 * 1024, + .st_sector = FLASH_Sector_21, + }, + [22] = { + .start = 0x081C0000, + .size = 128 * 1024, + .st_sector = FLASH_Sector_22, + }, + [23] = { + .start = 0x081E0000, + .size = 128 * 1024, + .st_sector = FLASH_Sector_23, + }, }; static bool PIOS_Flash_Internal_GetSectorInfo(uint32_t address, uint8_t *sector_number, uint32_t *sector_start, uint32_t *sector_size) diff --git a/flight/pios/stm32f4xx/pios_i2c.c b/flight/pios/stm32f4xx/pios_i2c.c index 171669ac4..2821f79be 100644 --- a/flight/pios/stm32f4xx/pios_i2c.c +++ b/flight/pios/stm32f4xx/pios_i2c.c @@ -390,6 +390,7 @@ static const struct i2c_adapter_transition i2c_adapter_transitions[I2C_STATE_NUM }, }; + static void go_fsm_fault(struct pios_i2c_adapter *i2c_adapter) { #if defined(I2C_HALT_ON_ERRORS) @@ -401,6 +402,7 @@ static void go_fsm_fault(struct pios_i2c_adapter *i2c_adapter) i2c_adapter_reset_bus(i2c_adapter); } + static void go_bus_error(struct pios_i2c_adapter *i2c_adapter) { /* Note that this transfer has hit a bus error */ @@ -409,6 +411,7 @@ static void go_bus_error(struct pios_i2c_adapter *i2c_adapter) i2c_adapter_reset_bus(i2c_adapter); } + static void go_stopping(struct pios_i2c_adapter *i2c_adapter) { #ifdef USE_FREERTOS @@ -431,12 +434,14 @@ static void go_stopping(struct pios_i2c_adapter *i2c_adapter) } } + static void go_stopped(struct pios_i2c_adapter *i2c_adapter) { I2C_ITConfig(i2c_adapter->cfg->regs, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR, DISABLE); I2C_AcknowledgeConfig(i2c_adapter->cfg->regs, ENABLE); } + static void go_starting(struct pios_i2c_adapter *i2c_adapter) { PIOS_DEBUG_Assert(i2c_adapter->active_txn); @@ -465,6 +470,7 @@ static void go_starting(struct pios_i2c_adapter *i2c_adapter) } } + /* Common to 'more' and 'last' transaction */ static void go_r_any_txn_addr(struct pios_i2c_adapter *i2c_adapter) { @@ -477,24 +483,28 @@ static void go_r_any_txn_addr(struct pios_i2c_adapter *i2c_adapter) I2C_Send7bitAddress(i2c_adapter->cfg->regs, (i2c_adapter->active_txn->addr) << 1, I2C_Direction_Receiver); } + static void go_r_more_txn_pre_one(struct pios_i2c_adapter *i2c_adapter) { I2C_AcknowledgeConfig(i2c_adapter->cfg->regs, DISABLE); I2C_GenerateSTART(i2c_adapter->cfg->regs, ENABLE); } + static void go_r_last_txn_pre_one(struct pios_i2c_adapter *i2c_adapter) { I2C_AcknowledgeConfig(i2c_adapter->cfg->regs, DISABLE); I2C_GenerateSTOP(i2c_adapter->cfg->regs, ENABLE); } + /* Common to 'more' and 'last' transaction */ static void go_r_any_txn_pre_first(struct pios_i2c_adapter *i2c_adapter) { I2C_AcknowledgeConfig(i2c_adapter->cfg->regs, ENABLE); } + /* Common to 'more' and 'last' transaction */ static void go_r_any_txn_pre_middle(struct pios_i2c_adapter *i2c_adapter) { @@ -508,6 +518,7 @@ static void go_r_any_txn_pre_middle(struct pios_i2c_adapter *i2c_adapter) PIOS_DEBUG_Assert(i2c_adapter->active_byte <= i2c_adapter->last_byte); } + static void go_r_more_txn_pre_last(struct pios_i2c_adapter *i2c_adapter) { PIOS_DEBUG_Assert(i2c_adapter->active_byte); @@ -526,6 +537,7 @@ static void go_r_more_txn_pre_last(struct pios_i2c_adapter *i2c_adapter) PIOS_DEBUG_Assert(i2c_adapter->active_byte <= i2c_adapter->last_byte); } + static void go_r_last_txn_pre_last(struct pios_i2c_adapter *i2c_adapter) { PIOS_DEBUG_Assert(i2c_adapter->active_byte); @@ -544,6 +556,7 @@ static void go_r_last_txn_pre_last(struct pios_i2c_adapter *i2c_adapter) PIOS_DEBUG_Assert(i2c_adapter->active_byte <= i2c_adapter->last_byte); } + /* Common to 'more' and 'last' transaction */ static void go_r_any_txn_post_last(struct pios_i2c_adapter *i2c_adapter) { @@ -562,6 +575,7 @@ static void go_r_any_txn_post_last(struct pios_i2c_adapter *i2c_adapter) i2c_adapter->active_txn++; } + /* Common to 'more' and 'last' transaction */ static void go_w_any_txn_addr(struct pios_i2c_adapter *i2c_adapter) { @@ -574,6 +588,7 @@ static void go_w_any_txn_addr(struct pios_i2c_adapter *i2c_adapter) I2C_Send7bitAddress(i2c_adapter->cfg->regs, (i2c_adapter->active_txn->addr) << 1, I2C_Direction_Transmitter); } + static void go_w_any_txn_middle(struct pios_i2c_adapter *i2c_adapter) { PIOS_DEBUG_Assert(i2c_adapter->active_byte); @@ -589,6 +604,7 @@ static void go_w_any_txn_middle(struct pios_i2c_adapter *i2c_adapter) PIOS_DEBUG_Assert(i2c_adapter->active_byte <= i2c_adapter->last_byte); } + static void go_w_more_txn_last(struct pios_i2c_adapter *i2c_adapter) { PIOS_DEBUG_Assert(i2c_adapter->active_byte); @@ -607,6 +623,7 @@ static void go_w_more_txn_last(struct pios_i2c_adapter *i2c_adapter) PIOS_DEBUG_Assert(i2c_adapter->active_txn <= i2c_adapter->last_txn); } + static void go_w_last_txn_last(struct pios_i2c_adapter *i2c_adapter) { PIOS_DEBUG_Assert(i2c_adapter->active_byte); @@ -625,6 +642,7 @@ static void go_w_last_txn_last(struct pios_i2c_adapter *i2c_adapter) i2c_adapter->active_byte++; } + static void go_nack(struct pios_i2c_adapter *i2c_adapter) { i2c_adapter->nack = true; @@ -633,6 +651,7 @@ static void go_nack(struct pios_i2c_adapter *i2c_adapter) I2C_GenerateSTOP(i2c_adapter->cfg->regs, ENABLE); } + static void i2c_adapter_inject_event(struct pios_i2c_adapter *i2c_adapter, enum i2c_adapter_event event) { PIOS_IRQ_Disable(); @@ -668,6 +687,7 @@ static void i2c_adapter_inject_event(struct pios_i2c_adapter *i2c_adapter, enum PIOS_IRQ_Enable(); } + static void i2c_adapter_process_auto(struct pios_i2c_adapter *i2c_adapter) { PIOS_IRQ_Disable(); @@ -684,12 +704,14 @@ static void i2c_adapter_process_auto(struct pios_i2c_adapter *i2c_adapter) PIOS_IRQ_Enable(); } + static void i2c_adapter_fsm_init(struct pios_i2c_adapter *i2c_adapter) { i2c_adapter_reset_bus(i2c_adapter); i2c_adapter->curr_state = I2C_STATE_STOPPED; } + static bool i2c_adapter_wait_for_stopped(struct pios_i2c_adapter *i2c_adapter) { uint32_t guard; @@ -712,8 +734,15 @@ static bool i2c_adapter_wait_for_stopped(struct pios_i2c_adapter *i2c_adapter) return true; } + static void i2c_adapter_reset_bus(struct pios_i2c_adapter *i2c_adapter) { + // retry with wait code from + // TauLabs 20150718 - Prevent F3 I2C Init Lockup #1728 + uint8_t retry_count; + uint8_t retry_count_clk; + static const uint8_t MAX_I2C_RETRY_COUNT = 10; + /* Reset the I2C block */ I2C_DeInit(i2c_adapter->cfg->regs); @@ -734,11 +763,13 @@ static void i2c_adapter_reset_bus(struct pios_i2c_adapter *i2c_adapter) /* have to be repeated (due to futher bus errors) but better than clocking 0xFF into an */ /* ESC */ // bool sda_hung = GPIO_ReadInputDataBit(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin) == Bit_RESET; - while (GPIO_ReadInputDataBit(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin) == Bit_RESET) { + retry_count_clk = 0; + while (GPIO_ReadInputDataBit(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin) == Bit_RESET && (retry_count_clk++ < MAX_I2C_RETRY_COUNT)) { + retry_count = 0; /* Set clock high and wait for any clock stretching to finish. */ GPIO_SetBits(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin); - while (GPIO_ReadInputDataBit(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin) == Bit_RESET) { - ; + while (GPIO_ReadInputDataBit(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin) == Bit_RESET && (retry_count++ < MAX_I2C_RETRY_COUNT)) { + PIOS_DELAY_WaituS(1); } PIOS_DELAY_WaituS(2); @@ -762,12 +793,14 @@ static void i2c_adapter_reset_bus(struct pios_i2c_adapter *i2c_adapter) /* Set data and clock high and wait for any clock stretching to finish. */ GPIO_SetBits(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin); GPIO_SetBits(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin); - while (GPIO_ReadInputDataBit(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin) == Bit_RESET) { - ; + retry_count = 0; + while (GPIO_ReadInputDataBit(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin) == Bit_RESET && (retry_count++ < MAX_I2C_RETRY_COUNT)) { + PIOS_DELAY_WaituS(1); } /* Wait for data to be high */ - while (GPIO_ReadInputDataBit(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin) != Bit_SET) { - ; + retry_count = 0; + while (GPIO_ReadInputDataBit(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin) != Bit_SET && (retry_count++ < MAX_I2C_RETRY_COUNT)) { + PIOS_DELAY_WaituS(1); } @@ -818,6 +851,7 @@ static bool i2c_adapter_fsm_terminated(struct pios_i2c_adapter *i2c_adapter) } } + uint32_t i2c_cb_count = 0; static bool i2c_adapter_callback_handler(struct pios_i2c_adapter *i2c_adapter) { @@ -872,6 +906,7 @@ static bool i2c_adapter_callback_handler(struct pios_i2c_adapter *i2c_adapter) return (!i2c_adapter->bus_error) && semaphore_success; } + /** * Logs the last N state transitions and N IRQ events due to * an error condition @@ -917,17 +952,17 @@ void PIOS_I2C_GetDiagnostics(struct pios_i2c_fault_history *data, uint8_t *count { #if defined(PIOS_I2C_DIAGNOSTICS) memcpy(data, &i2c_adapter_fault_history, sizeof(i2c_adapter_fault_history)); - counts[0] = i2c_bad_event_counter; - counts[1] = i2c_fsm_fault_count; - counts[2] = i2c_error_interrupt_counter; - counts[3] = i2c_nack_counter; - counts[4] = i2c_timeout_counter; + counts[PIOS_I2C_BAD_EVENT_COUNTER] = i2c_bad_event_counter; + counts[PIOS_I2C_FSM_FAULT_COUNT] = i2c_fsm_fault_count; + counts[PIOS_I2C_ERROR_INTERRUPT_COUNTER] = i2c_error_interrupt_counter; + counts[PIOS_I2C_NACK_COUNTER] = i2c_nack_counter; + counts[PIOS_I2C_TIMEOUT_COUNTER] = i2c_timeout_counter; #else struct pios_i2c_fault_history i2c_adapter_fault_history; - i2c_adapter_fault_history.type = PIOS_I2C_ERROR_EVENT; + i2c_adapter_fault_history.type = PIOS_I2C_ERROR_EVENT; memcpy(data, &i2c_adapter_fault_history, sizeof(i2c_adapter_fault_history)); - counts[0] = counts[1] = counts[2] = 0; + memset(counts, 0, sizeof(*counts) * PIOS_I2C_ERROR_COUNT_NUMELEM); #endif } @@ -936,6 +971,7 @@ static bool PIOS_I2C_validate(struct pios_i2c_adapter *i2c_adapter) return i2c_adapter->magic == PIOS_I2C_DEV_MAGIC; } + #if defined(PIOS_INCLUDE_FREERTOS) && 0 static struct pios_i2c_dev *PIOS_I2C_alloc(void) { diff --git a/flight/pios/stm32f4xx/pios_ppm.c b/flight/pios/stm32f4xx/pios_ppm.c index 9d1deeecd..9f1875a02 100644 --- a/flight/pios/stm32f4xx/pios_ppm.c +++ b/flight/pios/stm32f4xx/pios_ppm.c @@ -7,7 +7,8 @@ * @{ * * @file pios_ppm.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. * @brief PPM Input functions (STM32 dependent) * @see The GNU Public License (GPL) Version 3 * @@ -48,7 +49,7 @@ const struct pios_rcvr_driver pios_ppm_rcvr_driver = { #define PIOS_PPM_IN_MIN_NUM_CHANNELS 4 #define PIOS_PPM_IN_MAX_NUM_CHANNELS PIOS_PPM_NUM_INPUTS #define PIOS_PPM_STABLE_CHANNEL_COUNT 25 // frames -#define PIOS_PPM_IN_MIN_SYNC_PULSE_US 3800 // microseconds +#define PIOS_PPM_IN_MIN_SYNC_PULSE_US 2700 // microseconds #define PIOS_PPM_IN_MIN_CHANNEL_PULSE_US 750 // microseconds #define PIOS_PPM_IN_MAX_CHANNEL_PULSE_US 2250 // microseconds @@ -330,6 +331,11 @@ static void PIOS_PPM_tim_edge_cb(__attribute__((unused)) uint32_t tim_id, uint32 } } #endif /* USE_FREERTOS */ + } else { + for (uint32_t i = 0; + i < PIOS_PPM_IN_MAX_NUM_CHANNELS; i++) { + ppm_dev->CaptureValue[i] = PIOS_RCVR_TIMEOUT; + } } ppm_dev->Fresh = true; diff --git a/flight/pios/stm32f4xx/pios_sys.c b/flight/pios/stm32f4xx/pios_sys.c index 1572697aa..ab6759fe9 100644 --- a/flight/pios/stm32f4xx/pios_sys.c +++ b/flight/pios/stm32f4xx/pios_sys.c @@ -74,7 +74,7 @@ void PIOS_SYS_Init(void) RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE | -#ifdef STM32F40_41xxx +#if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_GPIOG | RCC_AHB1Periph_GPIOH | @@ -85,6 +85,9 @@ void PIOS_SYS_Init(void) RCC_AHB1Periph_SRAM1 | RCC_AHB1Periph_SRAM2 | RCC_AHB1Periph_BKPSRAM | +#if defined(STM32F427_437xx) || defined(STM32F429_439xx) + RCC_AHB1Periph_SRAM3 | +#endif RCC_AHB1Periph_DMA1 | RCC_AHB1Periph_DMA2 | // RCC_AHB1Periph_ETH_MAC | No ethernet @@ -171,7 +174,7 @@ void PIOS_SYS_Init(void) GPIO_Init(GPIOD, &GPIO_InitStructure); GPIO_Init(GPIOE, &GPIO_InitStructure); -#ifdef STM32F40_41xxx +#if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) GPIO_Init(GPIOF, &GPIO_InitStructure); GPIO_Init(GPIOG, &GPIO_InitStructure); GPIO_Init(GPIOH, &GPIO_InitStructure); diff --git a/flight/pios/stm32f4xx/pios_tim.c b/flight/pios/stm32f4xx/pios_tim.c index a5b114b0a..dee7c997f 100644 --- a/flight/pios/stm32f4xx/pios_tim.c +++ b/flight/pios/stm32f4xx/pios_tim.c @@ -129,6 +129,25 @@ int32_t PIOS_TIM_InitClock(const struct pios_tim_clock_cfg *cfg) /* Enable Interrupts */ NVIC_Init(&cfg->irq.init); + + // Advanced timers TIM1 & TIM8 need special handling: + // There are up to 4 separate interrupts handlers for each advanced timer, but + // pios_tim_clock_cfg has provision for only one irq init, so we take care here + // to enable additional irq channels that we intend to use. + + + if (cfg->timer == TIM1) { + NVIC_InitTypeDef init = cfg->irq.init; + init.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn; + NVIC_Init(&init); +#if !defined(STM32F401xx) && !defined(STM32F411xE) + } else if (cfg->timer == TIM8) { + NVIC_InitTypeDef init = cfg->irq.init; + init.NVIC_IRQChannel = TIM8_UP_TIM13_IRQn; + NVIC_Init(&init); +#endif + } + return 0; } @@ -376,12 +395,6 @@ static void PIOS_TIM_7_irq_handler(void) PIOS_TIM_generic_irq_handler(TIM7); } -void TIM8_UP_IRQHandler(void) __attribute__((alias("PIOS_TIM_8_UP_irq_handler"))); -static void PIOS_TIM_8_UP_irq_handler(void) -{ - PIOS_TIM_generic_irq_handler(TIM8); -} - void TIM8_CC_IRQHandler(void) __attribute__((alias("PIOS_TIM_8_CC_irq_handler"))); static void PIOS_TIM_8_CC_irq_handler(void) { diff --git a/flight/pios/stm32f4xx/pios_usb_cdc.c b/flight/pios/stm32f4xx/pios_usb_cdc.c index 277165af2..62349b1d9 100644 --- a/flight/pios/stm32f4xx/pios_usb_cdc.c +++ b/flight/pios/stm32f4xx/pios_usb_cdc.c @@ -41,9 +41,10 @@ static void PIOS_USB_CDC_RegisterTxCallback(uint32_t usbcdc_id, pios_com_callback tx_out_cb, uint32_t context); static void PIOS_USB_CDC_RegisterRxCallback(uint32_t usbcdc_id, pios_com_callback rx_in_cb, uint32_t context); static void PIOS_USB_CDC_RegisterCtrlLineCallback(uint32_t usbcdc_id, pios_com_callback_ctrl_line ctrl_line_cb, uint32_t context); +static void PIOS_USB_CDC_RegisterBaudRateCallback(uint32_t usbcdc_id, pios_com_callback_baud_rate baud_rate_cb, uint32_t context); static void PIOS_USB_CDC_TxStart(uint32_t usbcdc_id, uint16_t tx_bytes_avail); static void PIOS_USB_CDC_RxStart(uint32_t usbcdc_id, uint16_t rx_bytes_avail); -static bool PIOS_USB_CDC_Available(uint32_t usbcdc_id); +static uint32_t PIOS_USB_CDC_Available(uint32_t usbcdc_id); const struct pios_com_driver pios_usb_cdc_com_driver = { .tx_start = PIOS_USB_CDC_TxStart, @@ -51,6 +52,7 @@ const struct pios_com_driver pios_usb_cdc_com_driver = { .bind_tx_cb = PIOS_USB_CDC_RegisterTxCallback, .bind_rx_cb = PIOS_USB_CDC_RegisterRxCallback, .bind_ctrl_line_cb = PIOS_USB_CDC_RegisterCtrlLineCallback, + .bind_baud_rate_cb = PIOS_USB_CDC_RegisterBaudRateCallback, .available = PIOS_USB_CDC_Available, }; @@ -70,6 +72,8 @@ struct pios_usb_cdc_dev { uint32_t tx_out_context; pios_com_callback_ctrl_line ctrl_line_cb; uint32_t ctrl_line_context; + pios_com_callback_baud_rate baud_rate_cb; + uint32_t baud_rate_context; bool usb_ctrl_if_enabled; bool usb_data_if_enabled; @@ -343,6 +347,21 @@ static void PIOS_USB_CDC_RegisterCtrlLineCallback(uint32_t usbcdc_id, pios_com_c usb_cdc_dev->ctrl_line_cb = ctrl_line_cb; } +static void PIOS_USB_CDC_RegisterBaudRateCallback(uint32_t usbcdc_id, pios_com_callback_baud_rate baud_rate_cb, uint32_t context) +{ + struct pios_usb_cdc_dev *usb_cdc_dev = (struct pios_usb_cdc_dev *)usbcdc_id; + + bool valid = PIOS_USB_CDC_validate(usb_cdc_dev); + + PIOS_Assert(valid); + + /* + * Order is important in these assignments since ISR uses _cb + * field to determine if it's ok to dereference _cb and _context + */ + usb_cdc_dev->baud_rate_context = context; + usb_cdc_dev->baud_rate_cb = baud_rate_cb; +} static bool PIOS_USB_CDC_CTRL_EP_IN_Callback(uint32_t usb_cdc_id, uint8_t epnum, uint16_t len); @@ -445,7 +464,7 @@ static bool PIOS_USB_CDC_CTRL_IF_Setup(uint32_t usb_cdc_id, struct usb_setup_req return true; } -static bool PIOS_USB_CDC_Available(uint32_t usbcdc_id) +static uint32_t PIOS_USB_CDC_Available(uint32_t usbcdc_id) { struct pios_usb_cdc_dev *usb_cdc_dev = (struct pios_usb_cdc_dev *)usbcdc_id; @@ -453,8 +472,8 @@ static bool PIOS_USB_CDC_Available(uint32_t usbcdc_id) PIOS_Assert(valid); - return PIOS_USB_CheckAvailable(usb_cdc_dev->lower_id) && - (control_line_state & USB_CDC_CONTROL_LINE_STATE_DTE_PRESENT); + return (PIOS_USB_CheckAvailable(usb_cdc_dev->lower_id) && + (control_line_state & USB_CDC_CONTROL_LINE_STATE_DTE_PRESENT)) ? COM_AVAILABLE_RXTX : COM_AVAILABLE_NONE; } /** @@ -488,13 +507,9 @@ static void PIOS_USB_CDC_CTRL_IF_CtrlDataOut(uint32_t usb_cdc_id, const struct u case (USB_REQ_TYPE_CLASS | USB_REQ_RECIPIENT_INTERFACE): switch (req->bRequest) { case USB_CDC_REQ_SET_LINE_CODING: - /* - * If we cared to, this is where we would apply the new line coding - * that is now stored in the line_coding struct. This could be used - * to notify the upper COM layer that the baud rate has changed. This - * may be useful in the case of a COM USB bridge where we would - * auto-adjust the USART baud rate based on the line coding set here. - */ + if (usb_cdc_dev->baud_rate_cb) { + usb_cdc_dev->baud_rate_cb(usb_cdc_dev->baud_rate_context, usbltoh(line_coding.dwDTERate)); + } break; default: /* Unhandled class request */ diff --git a/flight/pios/stm32f4xx/pios_usb_hid.c b/flight/pios/stm32f4xx/pios_usb_hid.c index f80c3a567..0d1e7928c 100644 --- a/flight/pios/stm32f4xx/pios_usb_hid.c +++ b/flight/pios/stm32f4xx/pios_usb_hid.c @@ -41,13 +41,14 @@ static void PIOS_USB_HID_RegisterTxCallback(uint32_t usbhid_id, pios_com_callbac static void PIOS_USB_HID_RegisterRxCallback(uint32_t usbhid_id, pios_com_callback rx_in_cb, uint32_t context); static void PIOS_USB_HID_TxStart(uint32_t usbhid_id, uint16_t tx_bytes_avail); static void PIOS_USB_HID_RxStart(uint32_t usbhid_id, uint16_t rx_bytes_avail); +static uint32_t PIOS_USB_HID_Available(uint32_t usbhid_id); const struct pios_com_driver pios_usb_hid_com_driver = { .tx_start = PIOS_USB_HID_TxStart, .rx_start = PIOS_USB_HID_RxStart, .bind_tx_cb = PIOS_USB_HID_RegisterTxCallback, .bind_rx_cb = PIOS_USB_HID_RegisterRxCallback, - .available = PIOS_USB_CheckAvailable, + .available = PIOS_USB_HID_Available, }; enum pios_usb_hid_dev_magic { @@ -549,4 +550,9 @@ static bool PIOS_USB_HID_EP_OUT_Callback(uint32_t usb_hid_id, __attribute__((unu return rc; } +static uint32_t PIOS_USB_HID_Available(uint32_t usbhid_id) +{ + return PIOS_USB_CheckAvailable(usbhid_id) ? COM_AVAILABLE_RXTX : COM_AVAILABLE_NONE; +} + #endif /* PIOS_INCLUDE_USB_HID */ diff --git a/flight/targets/boards/coptercontrol/board_hw_defs.c b/flight/targets/boards/coptercontrol/board_hw_defs.c index 1e464899d..4222540ef 100644 --- a/flight/targets/boards/coptercontrol/board_hw_defs.c +++ b/flight/targets/boards/coptercontrol/board_hw_defs.c @@ -1021,6 +1021,92 @@ static const struct pios_dsm_cfg pios_dsm_flexi_cfg = { #endif /* PIOS_INCLUDE_DSM */ +#if defined(PIOS_INCLUDE_HOTT) +/* + * HOTT USART + */ +#include + +static const struct pios_usart_cfg pios_usart_hott_flexi_cfg = { + .regs = USART3, + .init = { + .USART_BaudRate = 115200, + .USART_WordLength = USART_WordLength_8b, + .USART_Parity = USART_Parity_No, + .USART_StopBits = USART_StopBits_1, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + .USART_Mode = USART_Mode_Rx, + }, + .irq = { + .init = { + .NVIC_IRQChannel = USART3_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .rx = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_11, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_IPU, + }, + }, + .tx = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_10, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_IN_FLOATING, + }, + }, +}; +#endif /* PIOS_INCLUDE_HOTT */ + +#if defined(PIOS_INCLUDE_EXBUS) +/* + * EXBUS USART + */ +#include + +static const struct pios_usart_cfg pios_usart_exbus_flexi_cfg = { + .regs = USART3, + .init = { + .USART_BaudRate = 125000, + .USART_WordLength = USART_WordLength_8b, + .USART_Parity = USART_Parity_No, + .USART_StopBits = USART_StopBits_1, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + .USART_Mode = USART_Mode_Rx, + }, + .irq = { + .init = { + .NVIC_IRQChannel = USART3_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .rx = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_11, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_IPU, + }, + }, + .tx = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_10, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_IN_FLOATING, + }, + }, +}; +#endif /* PIOS_INCLUDE_EXBUS */ + #if defined(PIOS_INCLUDE_SRXL) /* * SRXL USART @@ -1065,6 +1151,50 @@ static const struct pios_usart_cfg pios_usart_srxl_flexi_cfg = { #endif /* PIOS_INCLUDE_SRXL */ +#if defined(PIOS_INCLUDE_IBUS) +/* + * IBUS USART + */ +#include + +static const struct pios_usart_cfg pios_usart_ibus_flexi_cfg = { + .regs = USART3, + .init = { + .USART_BaudRate = 115200, + .USART_WordLength = USART_WordLength_8b, + .USART_Parity = USART_Parity_No, + .USART_StopBits = USART_StopBits_1, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + .USART_Mode = USART_Mode_Rx, + }, + .irq = { + .init = { + .NVIC_IRQChannel = USART3_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .rx = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_11, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_IPU, + }, + }, + .tx = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_10, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_IN_FLOATING, + }, + }, +}; + +#endif /* PIOS_INCLUDE_IBUS */ + #if defined(PIOS_INCLUDE_SBUS) /* * S.Bus USART diff --git a/flight/targets/boards/coptercontrol/bootloader/main.c b/flight/targets/boards/coptercontrol/bootloader/main.c index 15068627c..20549d1fa 100644 --- a/flight/targets/boards/coptercontrol/bootloader/main.c +++ b/flight/targets/boards/coptercontrol/bootloader/main.c @@ -33,9 +33,8 @@ #include #include #include +#include -/* Prototype of PIOS_Board_Init() function */ -extern void PIOS_Board_Init(void); extern void FLASH_Download(); #define BSL_HOLD_STATE ((PIOS_USB_DETECT_GPIO_PORT->IDR & PIOS_USB_DETECT_GPIO_PIN) ? 0 : 1) diff --git a/flight/targets/boards/coptercontrol/bootloader/pios_board.c b/flight/targets/boards/coptercontrol/bootloader/pios_board.c index e0a63193a..4fd27d5ee 100644 --- a/flight/targets/boards/coptercontrol/bootloader/pios_board.c +++ b/flight/targets/boards/coptercontrol/bootloader/pios_board.c @@ -56,9 +56,6 @@ void PIOS_Board_Init(void) /* Flash 2 wait state */ FLASH_SetLatency(FLASH_Latency_2); - /* Delay system */ - PIOS_DELAY_Init(); - const struct pios_board_info *bdinfo = &pios_board_info_blob; #if defined(PIOS_INCLUDE_LED) diff --git a/flight/targets/boards/coptercontrol/firmware/Makefile b/flight/targets/boards/coptercontrol/firmware/Makefile index 44aa5ee90..86539ebfd 100644 --- a/flight/targets/boards/coptercontrol/firmware/Makefile +++ b/flight/targets/boards/coptercontrol/firmware/Makefile @@ -54,6 +54,8 @@ OPTMODULES += TxPID OPTMODULES += Osd/osdoutput #OPTMODULES += Altitude #OPTMODULES += Fault +OPTMODULES += UAVOMSPBridge +OPTMODULES += UAVOMavlinkBridge SRC += $(FLIGHTLIB)/notification.c diff --git a/flight/targets/boards/coptercontrol/firmware/coptercontrol.c b/flight/targets/boards/coptercontrol/firmware/coptercontrol.c index e748f6317..5e82464f5 100644 --- a/flight/targets/boards/coptercontrol/firmware/coptercontrol.c +++ b/flight/targets/boards/coptercontrol/firmware/coptercontrol.c @@ -1,17 +1,18 @@ /** ****************************************************************************** - * @addtogroup OpenPilotSystem OpenPilot System - * @brief These files are the core system files of OpenPilot. - * They are the ground layer just above PiOS. In practice, OpenPilot actually starts - * in the main() function of openpilot.c + * @addtogroup LibrePilotSystem LibrePilot System + * @brief These files are the core system files for CopterControl. + * They are the ground layer just above PiOS. In practice, CopterControl actually starts + * in the main() function of coptercontrol.c * @{ - * @addtogroup OpenPilotCore OpenPilot Core - * @brief This is where the OP firmware starts. Those files also define the compile-time + * @addtogroup LibrePilotCore LibrePilot Core + * @brief This is where the LP firmware starts. Those files also define the compile-time * options of the firmware. * @{ - * @file openpilot.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @brief Sets up and runs main OpenPilot tasks. + * @file coptercontrol.c + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2015 + * @brief Sets up and runs main tasks. * @see The GNU Public License (GPL) Version 3 * *****************************************************************************/ @@ -32,18 +33,11 @@ */ #include "inc/openpilot.h" -#include -#include - +#include /* Task Priorities */ -#define PRIORITY_TASK_HOOKS (tskIDLE_PRIORITY + 3) /* Global Variables */ - -/* Prototype of PIOS_Board_Init() function */ -extern void PIOS_Board_Init(void); extern void Stack_Change(void); - /** * OpenPilot Main function: * @@ -61,24 +55,9 @@ int main() /* Brings up System using CMSIS functions, enables the LEDs. */ PIOS_SYS_Init(); - /* Architecture dependant Hardware and - * core subsystem initialisation - * (see pios_board.c for your arch) - * */ - PIOS_Board_Init(); -#ifdef ERASE_FLASH - PIOS_Flash_Jedec_EraseChip(); -#if defined(PIOS_LED_HEARTBEAT) - PIOS_LED_Off(PIOS_LED_HEARTBEAT); -#endif /* PIOS_LED_HEARTBEAT */ - while (1) { - ; - } -#endif + SystemModStart(); - /* Initialize modules */ - MODULE_INITIALISE_ALL /* swap the stack to use the IRQ stack */ Stack_Change(); diff --git a/flight/targets/boards/coptercontrol/firmware/inc/pios_config.h b/flight/targets/boards/coptercontrol/firmware/inc/pios_config.h index 02fcd4979..a6f521c81 100644 --- a/flight/targets/boards/coptercontrol/firmware/inc/pios_config.h +++ b/flight/targets/boards/coptercontrol/firmware/inc/pios_config.h @@ -93,7 +93,9 @@ /* #define PIOS_INCLUDE_ETASV3 */ /* #define PIOS_INCLUDE_HCSR04 */ -#define PIOS_SENSOR_RATE 500.0f +#define PIOS_SENSOR_RATE 500.0f +#define STABILIZATION_ATTITUDE_DOWNSAMPLED +#define ATTITUDE_SENSORS_DOWNSAMPLE 4 /* PIOS receiver drivers */ #define PIOS_INCLUDE_PWM @@ -101,7 +103,10 @@ #define PIOS_INCLUDE_PPM_FLEXI #define PIOS_INCLUDE_DSM #define PIOS_INCLUDE_SBUS +#define PIOS_INCLUDE_EXBUS #define PIOS_INCLUDE_SRXL +#define PIOS_INCLUDE_HOTT +#define PIOS_INCLUDE_IBUS /* #define PIOS_INCLUDE_GCSRCVR */ /* #define PIOS_INCLUDE_OPLINKRCVR */ @@ -146,6 +151,7 @@ #define PIOS_GPS_MINIMAL /* #define PIOS_INCLUDE_GPS_NMEA_PARSER */ #define PIOS_INCLUDE_GPS_UBX_PARSER +/* #define PIOS_INCLUDE_GPS_DJI_PARSER */ /* #define PIOS_GPS_SETS_HOMELOCATION */ /* Stabilization options */ @@ -165,7 +171,7 @@ /* Task stack sizes */ #define PIOS_ACTUATOR_STACK_SIZE 700 #define PIOS_MANUAL_STACK_SIZE 735 -#define PIOS_RECEIVER_STACK_SIZE 620 +#define PIOS_RECEIVER_STACK_SIZE 640 #define PIOS_STABILIZATION_STACK_SIZE 400 #ifdef DIAG_TASKS diff --git a/flight/targets/boards/coptercontrol/firmware/pios_board.c b/flight/targets/boards/coptercontrol/firmware/pios_board.c index 659980639..7556dff22 100644 --- a/flight/targets/boards/coptercontrol/firmware/pios_board.c +++ b/flight/targets/boards/coptercontrol/firmware/pios_board.c @@ -4,10 +4,9 @@ * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * PhoenixPilot, http://github.com/PhoenixPilot, Copyright (C) 2012 - * - * @addtogroup OpenPilotSystem OpenPilot System + * @addtogroup LibrePilotSystem LibrePilot System * @{ - * @addtogroup OpenPilotCore OpenPilot Core + * @addtogroup LibrePilotCore LibrePilot Core * @{ * @brief Defines board specific static initializers for hardware for the CopterControl board. *****************************************************************************/ @@ -76,6 +75,11 @@ static void ActuatorSettingsUpdatedCb(UAVObjEvent *ev); #define PIOS_COM_HKOSD_TX_BUF_LEN 22 +#define PIOS_COM_MSP_TX_BUF_LEN 128 +#define PIOS_COM_MSP_RX_BUF_LEN 64 + +#define PIOS_COM_MAVLINK_TX_BUF_LEN 128 + #if defined(PIOS_INCLUDE_DEBUG_CONSOLE) #define PIOS_COM_DEBUGCONSOLE_TX_BUF_LEN 40 uint32_t pios_com_debug_id; @@ -87,11 +91,92 @@ uint32_t pios_com_vcp_id; uint32_t pios_com_gps_id; uint32_t pios_com_bridge_id; uint32_t pios_com_hkosd_id; - +uint32_t pios_com_msp_id; +uint32_t pios_com_mavlink_id; uint32_t pios_usb_rctx_id; uintptr_t pios_uavo_settings_fs_id; uintptr_t pios_user_fs_id = 0; + + +/* + * Setup a com port based on the passed cfg, driver and buffer sizes. + * tx size = 0 make the port rx only + * rx size = 0 make the port tx only + * having both tx and rx size = 0 is not valid and will fail further down in PIOS_COM_Init() + */ +static void PIOS_Board_configure_com(const struct pios_usart_cfg *usart_port_cfg, uint16_t rx_buf_len, uint16_t tx_buf_len, + const struct pios_com_driver *com_driver, uint32_t *pios_com_id) +{ + uint32_t pios_usart_id; + + if (PIOS_USART_Init(&pios_usart_id, usart_port_cfg)) { + PIOS_Assert(0); + } + + uint8_t *rx_buffer = 0, *tx_buffer = 0; + + if (rx_buf_len > 0) { + rx_buffer = (uint8_t *)pios_malloc(rx_buf_len); + PIOS_Assert(rx_buffer); + } + + if (tx_buf_len > 0) { + tx_buffer = (uint8_t *)pios_malloc(tx_buf_len); + PIOS_Assert(tx_buffer); + } + + if (PIOS_COM_Init(pios_com_id, com_driver, pios_usart_id, + rx_buffer, rx_buf_len, + tx_buffer, tx_buf_len)) { + PIOS_Assert(0); + } +} + +static void PIOS_Board_configure_dsm(const struct pios_usart_cfg *pios_usart_dsm_cfg, const struct pios_dsm_cfg *pios_dsm_cfg, + const struct pios_com_driver *usart_com_driver, + ManualControlSettingsChannelGroupsOptions channelgroup, uint8_t *bind) +{ + uint32_t pios_usart_dsm_id; + + if (PIOS_USART_Init(&pios_usart_dsm_id, pios_usart_dsm_cfg)) { + PIOS_Assert(0); + } + + uint32_t pios_dsm_id; + if (PIOS_DSM_Init(&pios_dsm_id, pios_dsm_cfg, usart_com_driver, + pios_usart_dsm_id, *bind)) { + PIOS_Assert(0); + } + + uint32_t pios_dsm_rcvr_id; + if (PIOS_RCVR_Init(&pios_dsm_rcvr_id, &pios_dsm_rcvr_driver, pios_dsm_id)) { + PIOS_Assert(0); + } + pios_rcvr_group_map[channelgroup] = pios_dsm_rcvr_id; +} + +static void PIOS_Board_configure_ibus(const struct pios_usart_cfg *usart_cfg) +{ + uint32_t pios_usart_ibus_id; + + if (PIOS_USART_Init(&pios_usart_ibus_id, usart_cfg)) { + PIOS_Assert(0); + } + + uint32_t pios_ibus_id; + if (PIOS_IBUS_Init(&pios_ibus_id, &pios_usart_com_driver, pios_usart_ibus_id)) { + PIOS_Assert(0); + } + + uint32_t pios_ibus_rcvr_id; + if (PIOS_RCVR_Init(&pios_ibus_rcvr_id, &pios_ibus_rcvr_driver, pios_ibus_id)) { + PIOS_Assert(0); + } + + pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_IBUS] = pios_ibus_rcvr_id; +} + /** * Configuration for MPU6000 chip */ @@ -156,9 +241,6 @@ static const struct pios_mpu6000_cfg pios_mpu6000_cfg = { int32_t init_test; void PIOS_Board_Init(void) { - /* Delay system */ - PIOS_DELAY_Init(); - const struct pios_board_info *bdinfo = &pios_board_info_blob; #if defined(PIOS_INCLUDE_LED) @@ -436,22 +518,7 @@ void PIOS_Board_Init(void) break; case HWSETTINGS_CC_MAINPORT_TELEMETRY: #if defined(PIOS_INCLUDE_TELEMETRY_RF) - { - uint32_t pios_usart_generic_id; - if (PIOS_USART_Init(&pios_usart_generic_id, &pios_usart_generic_main_cfg)) { - PIOS_Assert(0); - } - - uint8_t *rx_buffer = (uint8_t *)pios_malloc(PIOS_COM_TELEM_RF_RX_BUF_LEN); - uint8_t *tx_buffer = (uint8_t *)pios_malloc(PIOS_COM_TELEM_RF_TX_BUF_LEN); - PIOS_Assert(rx_buffer); - PIOS_Assert(tx_buffer); - if (PIOS_COM_Init(&pios_com_telem_rf_id, &pios_usart_com_driver, pios_usart_generic_id, - rx_buffer, PIOS_COM_TELEM_RF_RX_BUF_LEN, - tx_buffer, PIOS_COM_TELEM_RF_TX_BUF_LEN)) { - PIOS_Assert(0); - } - } + PIOS_Board_configure_com(&pios_usart_generic_main_cfg, PIOS_COM_TELEM_RF_RX_BUF_LEN, PIOS_COM_TELEM_RF_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_telem_rf_id); #endif /* PIOS_INCLUDE_TELEMETRY_RF */ break; case HWSETTINGS_CC_MAINPORT_SBUS: @@ -477,101 +544,34 @@ void PIOS_Board_Init(void) break; case HWSETTINGS_CC_MAINPORT_GPS: #if defined(PIOS_INCLUDE_GPS) - { - uint32_t pios_usart_generic_id; - if (PIOS_USART_Init(&pios_usart_generic_id, &pios_usart_generic_main_cfg)) { - PIOS_Assert(0); - } - - uint8_t *rx_buffer = (uint8_t *)pios_malloc(PIOS_COM_GPS_RX_BUF_LEN); - PIOS_Assert(rx_buffer); - if (PIOS_COM_Init(&pios_com_gps_id, &pios_usart_com_driver, pios_usart_generic_id, - rx_buffer, PIOS_COM_GPS_RX_BUF_LEN, - NULL, 0)) { - PIOS_Assert(0); - } - } + PIOS_Board_configure_com(&pios_usart_generic_main_cfg, PIOS_COM_GPS_RX_BUF_LEN, 0, &pios_usart_com_driver, &pios_com_gps_id); #endif /* PIOS_INCLUDE_GPS */ break; case HWSETTINGS_CC_MAINPORT_DSM: #if defined(PIOS_INCLUDE_DSM) - { - uint32_t pios_usart_dsm_id; - if (PIOS_USART_Init(&pios_usart_dsm_id, &pios_usart_dsm_main_cfg)) { - PIOS_Assert(0); - } - - uint32_t pios_dsm_id; - if (PIOS_DSM_Init(&pios_dsm_id, - &pios_dsm_main_cfg, - &pios_usart_com_driver, - pios_usart_dsm_id, - 0)) { - PIOS_Assert(0); - } - - uint32_t pios_dsm_rcvr_id; - if (PIOS_RCVR_Init(&pios_dsm_rcvr_id, &pios_dsm_rcvr_driver, pios_dsm_id)) { - PIOS_Assert(0); - } - pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_DSMMAINPORT] = pios_dsm_rcvr_id; - } + PIOS_Board_configure_dsm(&pios_usart_dsm_main_cfg, &pios_dsm_main_cfg, + &pios_usart_com_driver, MANUALCONTROLSETTINGS_CHANNELGROUPS_DSMMAINPORT, &hwsettings_DSMxBind); #endif /* PIOS_INCLUDE_DSM */ break; case HWSETTINGS_CC_MAINPORT_DEBUGCONSOLE: #if defined(PIOS_INCLUDE_COM) #if defined(PIOS_INCLUDE_DEBUG_CONSOLE) - { - uint32_t pios_usart_generic_id; - if (PIOS_USART_Init(&pios_usart_generic_id, &pios_usart_generic_main_cfg)) { - PIOS_Assert(0); - } - - uint8_t *tx_buffer = (uint8_t *)pios_malloc(PIOS_COM_DEBUGCONSOLE_TX_BUF_LEN); - PIOS_Assert(tx_buffer); - if (PIOS_COM_Init(&pios_com_debug_id, &pios_usart_com_driver, pios_usart_generic_id, - NULL, 0, - tx_buffer, PIOS_COM_DEBUGCONSOLE_TX_BUF_LEN)) { - PIOS_Assert(0); - } - } + PIOS_Board_configure_com(&pios_usart_generic_main_cfg, 0, PIOS_COM_DEBUGCONSOLE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_debug_id); #endif /* PIOS_INCLUDE_DEBUG_CONSOLE */ #endif /* PIOS_INCLUDE_COM */ break; case HWSETTINGS_CC_MAINPORT_COMBRIDGE: - { - uint32_t pios_usart_generic_id; - if (PIOS_USART_Init(&pios_usart_generic_id, &pios_usart_generic_main_cfg)) { - PIOS_Assert(0); - } - - uint8_t *rx_buffer = (uint8_t *)pios_malloc(PIOS_COM_BRIDGE_RX_BUF_LEN); - PIOS_Assert(rx_buffer); - uint8_t *tx_buffer = (uint8_t *)pios_malloc(PIOS_COM_BRIDGE_TX_BUF_LEN); - PIOS_Assert(tx_buffer); - if (PIOS_COM_Init(&pios_com_bridge_id, &pios_usart_com_driver, pios_usart_generic_id, - rx_buffer, PIOS_COM_BRIDGE_RX_BUF_LEN, - tx_buffer, PIOS_COM_BRIDGE_TX_BUF_LEN)) { - PIOS_Assert(0); - } - } - break; + PIOS_Board_configure_com(&pios_usart_generic_main_cfg, PIOS_COM_BRIDGE_RX_BUF_LEN, PIOS_COM_BRIDGE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_bridge_id); + break; + case HWSETTINGS_CC_MAINPORT_MSP: + PIOS_Board_configure_com(&pios_usart_generic_main_cfg, PIOS_COM_MSP_RX_BUF_LEN, PIOS_COM_MSP_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_msp_id); + break; + case HWSETTINGS_CC_MAINPORT_MAVLINK: + PIOS_Board_configure_com(&pios_usart_generic_main_cfg, 0, PIOS_COM_MAVLINK_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_mavlink_id); + break; case HWSETTINGS_CC_MAINPORT_OSDHK: - { - uint32_t pios_usart_hkosd_id; - if (PIOS_USART_Init(&pios_usart_hkosd_id, &pios_usart_hkosd_main_cfg)) { - PIOS_Assert(0); - } - - uint8_t *tx_buffer = (uint8_t *)pios_malloc(PIOS_COM_HKOSD_TX_BUF_LEN); - PIOS_Assert(tx_buffer); - if (PIOS_COM_Init(&pios_com_hkosd_id, &pios_usart_com_driver, pios_usart_hkosd_id, - NULL, 0, - tx_buffer, PIOS_COM_HKOSD_TX_BUF_LEN)) { - PIOS_Assert(0); - } - } - break; + PIOS_Board_configure_com(&pios_usart_hkosd_main_cfg, 0, PIOS_COM_HKOSD_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_hkosd_id); + break; } /* Configure the flexi port */ @@ -583,56 +583,21 @@ void PIOS_Board_Init(void) break; case HWSETTINGS_CC_FLEXIPORT_TELEMETRY: #if defined(PIOS_INCLUDE_TELEMETRY_RF) - { - uint32_t pios_usart_generic_id; - if (PIOS_USART_Init(&pios_usart_generic_id, &pios_usart_generic_flexi_cfg)) { - PIOS_Assert(0); - } - uint8_t *rx_buffer = (uint8_t *)pios_malloc(PIOS_COM_TELEM_RF_RX_BUF_LEN); - uint8_t *tx_buffer = (uint8_t *)pios_malloc(PIOS_COM_TELEM_RF_TX_BUF_LEN); - PIOS_Assert(rx_buffer); - PIOS_Assert(tx_buffer); - if (PIOS_COM_Init(&pios_com_telem_rf_id, &pios_usart_com_driver, pios_usart_generic_id, - rx_buffer, PIOS_COM_TELEM_RF_RX_BUF_LEN, - tx_buffer, PIOS_COM_TELEM_RF_TX_BUF_LEN)) { - PIOS_Assert(0); - } - } + PIOS_Board_configure_com(&pios_usart_generic_flexi_cfg, PIOS_COM_TELEM_RF_RX_BUF_LEN, PIOS_COM_TELEM_RF_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_telem_rf_id); #endif /* PIOS_INCLUDE_TELEMETRY_RF */ break; case HWSETTINGS_CC_FLEXIPORT_COMBRIDGE: - { - uint32_t pios_usart_generic_id; - if (PIOS_USART_Init(&pios_usart_generic_id, &pios_usart_generic_flexi_cfg)) { - PIOS_Assert(0); - } - - uint8_t *rx_buffer = (uint8_t *)pios_malloc(PIOS_COM_BRIDGE_RX_BUF_LEN); - uint8_t *tx_buffer = (uint8_t *)pios_malloc(PIOS_COM_BRIDGE_TX_BUF_LEN); - PIOS_Assert(rx_buffer); - PIOS_Assert(tx_buffer); - if (PIOS_COM_Init(&pios_com_bridge_id, &pios_usart_com_driver, pios_usart_generic_id, - rx_buffer, PIOS_COM_BRIDGE_RX_BUF_LEN, - tx_buffer, PIOS_COM_BRIDGE_TX_BUF_LEN)) { - PIOS_Assert(0); - } - } - break; + PIOS_Board_configure_com(&pios_usart_generic_flexi_cfg, PIOS_COM_BRIDGE_RX_BUF_LEN, PIOS_COM_BRIDGE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_bridge_id); + break; + case HWSETTINGS_CC_FLEXIPORT_MSP: + PIOS_Board_configure_com(&pios_usart_generic_flexi_cfg, PIOS_COM_MSP_RX_BUF_LEN, PIOS_COM_MSP_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_msp_id); + break; + case HWSETTINGS_CC_FLEXIPORT_MAVLINK: + PIOS_Board_configure_com(&pios_usart_generic_flexi_cfg, 0, PIOS_COM_MAVLINK_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_mavlink_id); + break; case HWSETTINGS_CC_FLEXIPORT_GPS: #if defined(PIOS_INCLUDE_GPS) - { - uint32_t pios_usart_generic_id; - if (PIOS_USART_Init(&pios_usart_generic_id, &pios_usart_generic_flexi_cfg)) { - PIOS_Assert(0); - } - uint8_t *rx_buffer = (uint8_t *)pios_malloc(PIOS_COM_GPS_RX_BUF_LEN); - PIOS_Assert(rx_buffer); - if (PIOS_COM_Init(&pios_com_gps_id, &pios_usart_com_driver, pios_usart_generic_id, - rx_buffer, PIOS_COM_GPS_RX_BUF_LEN, - NULL, 0)) { - PIOS_Assert(0); - } - } + PIOS_Board_configure_com(&pios_usart_generic_flexi_cfg, PIOS_COM_GPS_RX_BUF_LEN, 0, &pios_usart_com_driver, &pios_com_gps_id); #endif /* PIOS_INCLUDE_GPS */ break; case HWSETTINGS_CC_FLEXIPORT_PPM: @@ -651,29 +616,57 @@ void PIOS_Board_Init(void) break; case HWSETTINGS_CC_FLEXIPORT_DSM: #if defined(PIOS_INCLUDE_DSM) - { - uint32_t pios_usart_dsm_id; - if (PIOS_USART_Init(&pios_usart_dsm_id, &pios_usart_dsm_flexi_cfg)) { - PIOS_Assert(0); - } - - uint32_t pios_dsm_id; - if (PIOS_DSM_Init(&pios_dsm_id, - &pios_dsm_flexi_cfg, - &pios_usart_com_driver, - pios_usart_dsm_id, - hwsettings_DSMxBind)) { - PIOS_Assert(0); - } - - uint32_t pios_dsm_rcvr_id; - if (PIOS_RCVR_Init(&pios_dsm_rcvr_id, &pios_dsm_rcvr_driver, pios_dsm_id)) { - PIOS_Assert(0); - } - pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_DSMFLEXIPORT] = pios_dsm_rcvr_id; - } + PIOS_Board_configure_dsm(&pios_usart_dsm_flexi_cfg, &pios_dsm_flexi_cfg, + &pios_usart_com_driver, MANUALCONTROLSETTINGS_CHANNELGROUPS_DSMFLEXIPORT, &hwsettings_DSMxBind); #endif /* PIOS_INCLUDE_DSM */ break; + + case HWSETTINGS_CC_FLEXIPORT_HOTTSUMD: + case HWSETTINGS_CC_FLEXIPORT_HOTTSUMH: +#if defined(PIOS_INCLUDE_HOTT) + { + uint32_t pios_usart_hott_id; + if (PIOS_USART_Init(&pios_usart_hott_id, &pios_usart_hott_flexi_cfg)) { + PIOS_Assert(0); + } + + uint32_t pios_hott_id; + if (PIOS_HOTT_Init(&pios_hott_id, &pios_usart_com_driver, pios_usart_hott_id, + hwsettings_cc_flexiport == HWSETTINGS_CC_FLEXIPORT_HOTTSUMD ? PIOS_HOTT_PROTO_SUMD : PIOS_HOTT_PROTO_SUMH)) { + PIOS_Assert(0); + } + + uint32_t pios_hott_rcvr_id; + if (PIOS_RCVR_Init(&pios_hott_rcvr_id, &pios_hott_rcvr_driver, pios_hott_id)) { + PIOS_Assert(0); + } + pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_HOTT] = pios_hott_rcvr_id; + } +#endif /* PIOS_INCLUDE_HOTT */ + break; + + case HWSETTINGS_CC_FLEXIPORT_EXBUS: +#if defined(PIOS_INCLUDE_EXBUS) + { + uint32_t pios_usart_exbus_id; + if (PIOS_USART_Init(&pios_usart_exbus_id, &pios_usart_exbus_flexi_cfg)) { + PIOS_Assert(0); + } + + uint32_t pios_exbus_id; + if (PIOS_EXBUS_Init(&pios_exbus_id, &pios_usart_com_driver, pios_usart_exbus_id)) { + PIOS_Assert(0); + } + + uint32_t pios_exbus_rcvr_id; + if (PIOS_RCVR_Init(&pios_exbus_rcvr_id, &pios_exbus_rcvr_driver, pios_exbus_id)) { + PIOS_Assert(0); + } + pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_EXBUS] = pios_exbus_rcvr_id; + } +#endif /* PIOS_INCLUDE_EXBUS */ + break; + case HWSETTINGS_CC_FLEXIPORT_SRXL: #if defined(PIOS_INCLUDE_SRXL) { @@ -696,23 +689,16 @@ void PIOS_Board_Init(void) #endif /* PIOS_INCLUDE_SRXL */ break; + case HWSETTINGS_CC_FLEXIPORT_IBUS: +#if defined(PIOS_INCLUDE_IBUS) + PIOS_Board_configure_ibus(&pios_usart_ibus_flexi_cfg); +#endif /* PIOS_INCLUDE_IBUS */ + break; + case HWSETTINGS_CC_FLEXIPORT_DEBUGCONSOLE: #if defined(PIOS_INCLUDE_COM) #if defined(PIOS_INCLUDE_DEBUG_CONSOLE) - { - uint32_t pios_usart_generic_id; - if (PIOS_USART_Init(&pios_usart_generic_id, &pios_usart_generic_flexi_cfg)) { - PIOS_Assert(0); - } - - uint8_t *tx_buffer = (uint8_t *)pios_malloc(PIOS_COM_DEBUGCONSOLE_TX_BUF_LEN); - PIOS_Assert(tx_buffer); - if (PIOS_COM_Init(&pios_com_debug_id, &pios_usart_com_driver, pios_usart_generic_id, - NULL, 0, - tx_buffer, PIOS_COM_DEBUGCONSOLE_TX_BUF_LEN)) { - PIOS_Assert(0); - } - } + PIOS_Board_configure_com(&pios_usart_generic_flexi_cfg, 0, PIOS_COM_DEBUGCONSOLE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_debug_id); #endif /* PIOS_INCLUDE_DEBUG_CONSOLE */ #endif /* PIOS_INCLUDE_COM */ break; @@ -726,21 +712,8 @@ void PIOS_Board_Init(void) #endif /* PIOS_INCLUDE_I2C */ break; case HWSETTINGS_CC_FLEXIPORT_OSDHK: - { - uint32_t pios_usart_hkosd_id; - if (PIOS_USART_Init(&pios_usart_hkosd_id, &pios_usart_hkosd_flexi_cfg)) { - PIOS_Assert(0); - } - - uint8_t *tx_buffer = (uint8_t *)pios_malloc(PIOS_COM_HKOSD_TX_BUF_LEN); - PIOS_Assert(tx_buffer); - if (PIOS_COM_Init(&pios_com_hkosd_id, &pios_usart_com_driver, pios_usart_hkosd_id, - NULL, 0, - tx_buffer, PIOS_COM_HKOSD_TX_BUF_LEN)) { - PIOS_Assert(0); - } - } - break; + PIOS_Board_configure_com(&pios_usart_hkosd_flexi_cfg, 0, PIOS_COM_HKOSD_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_hkosd_id); + break; } /* Configure the rcvr port */ @@ -911,7 +884,9 @@ SystemAlarmsExtendedAlarmStatusOptions CopterControlConfigHook() if ((recmode == HWSETTINGS_CC_RCVRPORT_PPM_PIN8ONESHOT || flexiMode == HWSETTINGS_CC_FLEXIPORT_PPM) && (modes[3] == ACTUATORSETTINGS_BANKMODE_PWMSYNC || - modes[3] == ACTUATORSETTINGS_BANKMODE_ONESHOT125)) { + modes[3] == ACTUATORSETTINGS_BANKMODE_ONESHOT125 || + modes[3] == ACTUATORSETTINGS_BANKMODE_ONESHOT42 || + modes[3] == ACTUATORSETTINGS_BANKMODE_MULTISHOT)) { return SYSTEMALARMS_EXTENDEDALARMSTATUS_UNSUPPORTEDCONFIG_ONESHOT; } else { return SYSTEMALARMS_EXTENDEDALARMSTATUS_NONE; @@ -924,7 +899,9 @@ SystemAlarmsExtendedAlarmStatusOptions CopterControlConfigHook() case HWSETTINGS_CC_RCVRPORT_PWMNOONESHOT: for (uint8_t i = 0; i < ACTUATORSETTINGS_BANKMODE_NUMELEM; i++) { if (modes[i] == ACTUATORSETTINGS_BANKMODE_PWMSYNC || - modes[i] == ACTUATORSETTINGS_BANKMODE_ONESHOT125) { + modes[i] == ACTUATORSETTINGS_BANKMODE_ONESHOT125 || + modes[i] == ACTUATORSETTINGS_BANKMODE_ONESHOT42 || + modes[i] == ACTUATORSETTINGS_BANKMODE_MULTISHOT) { return SYSTEMALARMS_EXTENDEDALARMSTATUS_UNSUPPORTEDCONFIG_ONESHOT;; } diff --git a/flight/targets/boards/coptercontrol/pios_board.h b/flight/targets/boards/coptercontrol/pios_board.h index 36e719378..1750b4d9a 100644 --- a/flight/targets/boards/coptercontrol/pios_board.h +++ b/flight/targets/boards/coptercontrol/pios_board.h @@ -156,6 +156,12 @@ extern uint32_t pios_com_debug_id; extern uint32_t pios_com_hkosd_id; #define PIOS_COM_OSDHK (pios_com_hkosd_id) +extern uint32_t pios_com_msp_id; +#define PIOS_COM_MSP (pios_com_msp_id) + +extern uint32_t pios_com_mavlink_id; +#define PIOS_COM_MAVLINK (pios_com_mavlink_id) + // ------------------------- // ADC // PIOS_ADC_PinGet(0) = Gyro Z @@ -228,7 +234,7 @@ extern uint32_t pios_com_hkosd_id; // Receiver PPM input // ------------------------- #define PIOS_PPM_MAX_DEVS 1 -#define PIOS_PPM_NUM_INPUTS 12 +#define PIOS_PPM_NUM_INPUTS 16 // ------------------------- // Receiver PWM input @@ -248,12 +254,30 @@ extern uint32_t pios_com_hkosd_id; #define PIOS_SBUS_MAX_DEVS 1 #define PIOS_SBUS_NUM_INPUTS (16 + 2) +// ------------------------- +// Receiver HOTT input +// ------------------------- +#define PIOS_HOTT_MAX_DEVS 1 +#define PIOS_HOTT_NUM_INPUTS 32 + +// ------------------------- +// Receiver EX.Bus input +// ------------------------- +#define PIOS_EXBUS_MAX_DEVS 1 +#define PIOS_EXBUS_NUM_INPUTS 16 + // ------------------------- // Receiver Multiplex SRXL input // ------------------------- #define PIOS_SRXL_MAX_DEVS 1 #define PIOS_SRXL_NUM_INPUTS 16 +// ------------------------- +// Receiver FlySky IBus input +// ------------------------- +#define PIOS_IBUS_MAX_DEVS 1 +#define PIOS_IBUS_NUM_INPUTS 10 + // ------------------------- // Servo outputs // ------------------------- diff --git a/flight/targets/boards/discoveryf4bare/board_hw_defs.c b/flight/targets/boards/discoveryf4bare/board_hw_defs.c index 345864847..0c833776b 100644 --- a/flight/targets/boards/discoveryf4bare/board_hw_defs.c +++ b/flight/targets/boards/discoveryf4bare/board_hw_defs.c @@ -973,6 +973,64 @@ static const struct pios_usart_cfg pios_usart_hkosd_flexi_cfg = { }, }; +static const struct pios_usart_cfg pios_usart_rcvrport_cfg = { + .regs = USART6, + .remap = GPIO_AF_USART6, + .init = { + .USART_BaudRate = 57600, + .USART_WordLength = USART_WordLength_8b, + .USART_Parity = USART_Parity_No, + .USART_StopBits = USART_StopBits_1, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + .USART_Mode = USART_Mode_Rx | USART_Mode_Tx, + }, + .irq = { + .init = { + .NVIC_IRQChannel = USART6_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + + .dtr = { + // FlexIO pin 9 + .gpio = GPIOC, + .init = { + .GPIO_Pin = GPIO_Pin_8, + .GPIO_Speed = GPIO_Speed_25MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + }, + }, + + .tx = { + // * 7: PC6 = TIM8 CH1, USART6 TX + .gpio = GPIOC, + .init = { + .GPIO_Pin = GPIO_Pin_6, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + .pin_source = GPIO_PinSource6, + }, + + .rx = { + // * 8: PC7 = TIM8 CH2, USART6 RX + .gpio = GPIOC, + .init = { + .GPIO_Pin = GPIO_Pin_7, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + .pin_source = GPIO_PinSource7, + } +}; + #if defined(PIOS_INCLUDE_COM) #include @@ -1085,7 +1143,7 @@ static const struct pios_i2c_adapter_cfg pios_i2c_flexiport_adapter_cfg = { .GPIO_Mode = GPIO_Mode_AF, .GPIO_Speed = GPIO_Speed_50MHz, .GPIO_OType = GPIO_OType_OD, - .GPIO_PuPd = GPIO_PuPd_NOPULL, + .GPIO_PuPd = GPIO_PuPd_UP, }, }, .sda = { @@ -1095,7 +1153,7 @@ static const struct pios_i2c_adapter_cfg pios_i2c_flexiport_adapter_cfg = { .GPIO_Mode = GPIO_Mode_AF, .GPIO_Speed = GPIO_Speed_50MHz, .GPIO_OType = GPIO_OType_OD, - .GPIO_PuPd = GPIO_PuPd_NOPULL, + .GPIO_PuPd = GPIO_PuPd_UP, }, }, .event = { diff --git a/flight/targets/boards/discoveryf4bare/bootloader/main.c b/flight/targets/boards/discoveryf4bare/bootloader/main.c index 5c6e08db7..09a54a094 100644 --- a/flight/targets/boards/discoveryf4bare/bootloader/main.c +++ b/flight/targets/boards/discoveryf4bare/bootloader/main.c @@ -34,9 +34,8 @@ #include #include /* PIOS_USBHOOK_* */ #include +#include -/* Prototype of PIOS_Board_Init() function */ -extern void PIOS_Board_Init(void); extern void FLASH_Download(); void check_bor(); #define BSL_HOLD_STATE ((PIOS_USB_DETECT_GPIO_PORT->IDR & PIOS_USB_DETECT_GPIO_PIN) ? 0 : 1) diff --git a/flight/targets/boards/discoveryf4bare/firmware/Makefile b/flight/targets/boards/discoveryf4bare/firmware/Makefile index d82ff41d6..d9e9c67f4 100644 --- a/flight/targets/boards/discoveryf4bare/firmware/Makefile +++ b/flight/targets/boards/discoveryf4bare/firmware/Makefile @@ -1,7 +1,7 @@ # -# Copyright (c) 2015, The LibrePilot Project, http://www.librepilot.org -# Copyright (c) 2009-2013, The OpenPilot Team, http://www.openpilot.org -# Copyright (c) 2012, PhoenixPilot, http://github.com/PhoenixPilot +# Copyright (C) 2015-2016, The LibrePilot Project, http://www.librepilot.org +# Copyright (C) 2009-2013, The OpenPilot Team, http://www.openpilot.org +# Copyright (C) 2012, PhoenixPilot, http://github.com/PhoenixPilot # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -32,7 +32,7 @@ USE_CXX = YES USE_DSP_LIB ?= NO # List of mandatory modules to include -#MODULES += Sensors +MODULES += Sensors #MODULES += Attitude/revolution #MODULES += StateEstimation # use instead of Attitude #MODULES += Altitude/revolution @@ -55,7 +55,10 @@ MODULES += Osd/osdoutout MODULES += Logging MODULES += Telemetry +OPTMODULES += AutoTune OPTMODULES += ComUsbBridge +OPTMODULES += UAVOMSPBridge +OPTMODULES += UAVOMavlinkBridge SRC += $(FLIGHTLIB)/notification.c @@ -97,7 +100,6 @@ ifndef TESTAPP SRC += $(FLIGHTLIB)/insgps13state.c SRC += $(FLIGHTLIB)/auxmagsupport.c SRC += $(FLIGHTLIB)/lednotification.c - CPPSRC += $(FLIGHTLIB)/mini_cpp.cpp ## UAVObjects include ./UAVObjects.inc diff --git a/flight/targets/boards/discoveryf4bare/firmware/UAVObjects.inc b/flight/targets/boards/discoveryf4bare/firmware/UAVObjects.inc index afc1c82d1..b704f4ab0 100644 --- a/flight/targets/boards/discoveryf4bare/firmware/UAVObjects.inc +++ b/flight/targets/boards/discoveryf4bare/firmware/UAVObjects.inc @@ -1,5 +1,6 @@ # -# Copyright (c) 2009-2013, The OpenPilot Team, http://www.openpilot.org +# Copyright (C) 2016, The LibrePilot Project, http://www.librepilot.org +# Copyright (C) 2009-2013, The OpenPilot Team, http://www.openpilot.org # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -125,6 +126,8 @@ UAVOBJSRCFILENAMES += txpidsettings UAVOBJSRCFILENAMES += txpidstatus UAVOBJSRCFILENAMES += takeofflocation UAVOBJSRCFILENAMES += perfcounter +UAVOBJSRCFILENAMES += systemidentsettings +UAVOBJSRCFILENAMES += systemidentstate UAVOBJSRC = $(foreach UAVOBJSRCFILE,$(UAVOBJSRCFILENAMES),$(FLIGHT_UAVOBJ_DIR)/$(UAVOBJSRCFILE).c ) UAVOBJDEFINE = $(foreach UAVOBJSRCFILE,$(UAVOBJSRCFILENAMES),-DUAVOBJ_INIT_$(UAVOBJSRCFILE) ) diff --git a/flight/targets/boards/discoveryf4bare/firmware/discoveryf4bare.cpp b/flight/targets/boards/discoveryf4bare/firmware/discoveryf4bare.cpp index 268325b26..9ba92a137 100644 --- a/flight/targets/boards/discoveryf4bare/firmware/discoveryf4bare.cpp +++ b/flight/targets/boards/discoveryf4bare/firmware/discoveryf4bare.cpp @@ -34,46 +34,12 @@ extern "C" { #include "inc/openpilot.h" #include +#include -/* Task Priorities */ -#define PRIORITY_TASK_HOOKS (tskIDLE_PRIORITY + 3) /* Global Variables */ /* Local Variables */ -#define INCLUDE_TEST_TASKS 0 -#if INCLUDE_TEST_TASKS -static uint8_t sdcard_available; -#endif -char Buffer[1024]; -uint32_t Cache; - -/* Function Prototypes */ -#if INCLUDE_TEST_TASKS -static void TaskTick(void *pvParameters); -static void TaskTesting(void *pvParameters); -static void TaskHIDTest(void *pvParameters); -static void TaskServos(void *pvParameters); -static void TaskSDCard(void *pvParameters); -#endif -int32_t CONSOLE_Parse(uint8_t port, char c); -void OP_ADC_NotifyChange(uint32_t pin, uint32_t pin_value); - -/* Prototype of PIOS_Board_Init() function */ -extern void PIOS_Board_Init(void); -extern void Stack_Change(void); -static void Stack_Change_Weak() __attribute__((weakref("Stack_Change"))); - -/* Local Variables */ -#define INIT_TASK_PRIORITY (tskIDLE_PRIORITY + configMAX_PRIORITIES - 1) // max priority -#define INIT_TASK_STACK (1024 / 4) // XXX this seems excessive -static xTaskHandle initTaskHandle; - -/* Function Prototypes */ -static void initTask(void *parameters); - -/* Prototype of generated InitModules() function */ -extern void InitModules(void); } /** @@ -87,8 +53,6 @@ extern void InitModules(void); */ int main() { - int result; - /* NOTE: Do NOT modify the following start-up sequence */ /* Any new initialization functions should be added in OpenPilotInit() */ vPortInitialiseBlocks(); @@ -96,12 +60,7 @@ int main() /* Brings up System using CMSIS functions, enables the LEDs. */ PIOS_SYS_Init(); - /* For Revolution we use a FreeRTOS task to bring up the system so we can */ - /* always rely on FreeRTOS primitive */ - result = xTaskCreate(initTask, "init", - INIT_TASK_STACK, NULL, INIT_TASK_PRIORITY, - &initTaskHandle); - PIOS_Assert(result == pdPASS); + SystemModStart(); /* Start the FreeRTOS scheduler */ vTaskStartScheduler(); @@ -117,22 +76,7 @@ int main() return 0; } -/** - * Initialisation task. - * - * Runs board and module initialisation, then terminates. - */ -void initTask(__attribute__((unused)) void *parameters) -{ - /* board driver init */ - PIOS_Board_Init(); - /* Initialize modules */ - MODULE_INITIALISE_ALL; - - /* terminate this task */ - vTaskDelete(NULL); -} /** * @} diff --git a/flight/targets/boards/discoveryf4bare/firmware/inc/pios_config.h b/flight/targets/boards/discoveryf4bare/firmware/inc/pios_config.h index 2bc9c11b9..47388c988 100644 --- a/flight/targets/boards/discoveryf4bare/firmware/inc/pios_config.h +++ b/flight/targets/boards/discoveryf4bare/firmware/inc/pios_config.h @@ -5,7 +5,8 @@ * @addtogroup OpenPilotCore OpenPilot Core * @{ * @file pios_config.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2013. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2013. * @brief PiOS configuration header, the compile time config file for the PIOS. * Defines which PiOS libraries and features are included in the firmware. * @see The GNU Public License (GPL) Version 3 @@ -84,7 +85,7 @@ // #define PIOS_INCLUDE_MPU6000 // #define PIOS_MPU6000_ACCEL /* #define PIOS_INCLUDE_HMC5843 */ -// #define PIOS_INCLUDE_HMC5X83 +#define PIOS_INCLUDE_HMC5X83 // #define PIOS_HMC5X83_HAS_GPIOS /* #define PIOS_INCLUDE_BMP085 */ // #define PIOS_INCLUDE_MS5611 @@ -149,6 +150,7 @@ /* #define PIOS_GPS_MINIMAL */ #define PIOS_INCLUDE_GPS_NMEA_PARSER #define PIOS_INCLUDE_GPS_UBX_PARSER +#define PIOS_INCLUDE_GPS_DJI_PARSER #define PIOS_GPS_SETS_HOMELOCATION /* Stabilization options */ diff --git a/flight/targets/boards/discoveryf4bare/firmware/pios_board.c b/flight/targets/boards/discoveryf4bare/firmware/pios_board.c index bb9f6c33d..a58fd1d31 100644 --- a/flight/targets/boards/discoveryf4bare/firmware/pios_board.c +++ b/flight/targets/boards/discoveryf4bare/firmware/pios_board.c @@ -1,8 +1,9 @@ /** ****************************************************************************** * @file pios_board.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2011. - * @author PhoenixPilot, http://github.com/PhoenixPilot, Copyright (C) 2012 + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2011. + * PhoenixPilot, http://github.com/PhoenixPilot, Copyright (C) 2012 * @addtogroup OpenPilotSystem OpenPilot System * @{ * @addtogroup OpenPilotCore OpenPilot Core @@ -36,6 +37,7 @@ #include #include #include +#include #ifdef PIOS_INCLUDE_INSTRUMENTATION #include @@ -92,8 +94,16 @@ void PIOS_ADC_DMC_irq_handler(void) #if defined(PIOS_INCLUDE_HMC5X83) #include "pios_hmc5x83.h" +pios_hmc5x83_dev_t onboard_mag = 0; +pios_hmc5x83_dev_t external_mag = 0; + +bool pios_board_internal_mag_handler() +{ + return PIOS_HMC5x83_IRQHandler(onboard_mag); +} + static const struct pios_exti_cfg pios_exti_hmc5x83_cfg __exti_config = { - .vector = PIOS_HMC5x83_IRQHandler, + .vector = pios_board_internal_mag_handler, .line = EXTI_Line7, .pin = { .gpio = GPIOB, @@ -123,14 +133,30 @@ static const struct pios_exti_cfg pios_exti_hmc5x83_cfg __exti_config = { }, }; -static const struct pios_hmc5x83_cfg pios_hmc5x83_cfg = { - .exti_cfg = &pios_exti_hmc5x83_cfg, - .M_ODR = PIOS_HMC5x83_ODR_75, - .Meas_Conf = PIOS_HMC5x83_MEASCONF_NORMAL, - .Gain = PIOS_HMC5x83_GAIN_1_9, - .Mode = PIOS_HMC5x83_MODE_CONTINUOUS, - .Driver = &PIOS_HMC5x83_I2C_DRIVER, - .Orientation = PIOS_HMC5X83_ORIENTATION_EAST_NORTH_UP, +static const struct pios_hmc5x83_cfg pios_hmc5x83_internal_cfg = { +#ifdef PIOS_HMC5X83_HAS_GPIOS + .exti_cfg = &pios_exti_hmc5x83_cfg, +#endif + .M_ODR = PIOS_HMC5x83_ODR_75, + .Meas_Conf = PIOS_HMC5x83_MEASCONF_NORMAL, + .Gain = PIOS_HMC5x83_GAIN_1_9, + .Mode = PIOS_HMC5x83_MODE_CONTINUOUS, + .TempCompensation = false, + .Driver = &PIOS_HMC5x83_I2C_DRIVER, + .Orientation = PIOS_HMC5X83_ORIENTATION_EAST_NORTH_UP, +}; + +static const struct pios_hmc5x83_cfg pios_hmc5x83_external_cfg = { +#ifdef PIOS_HMC5X83_HAS_GPIOS + .exti_cfg = NULL, +#endif + .M_ODR = PIOS_HMC5x83_ODR_75, // if you change this for auxmag, change AUX_MAG_SKIP in sensors.c + .Meas_Conf = PIOS_HMC5x83_MEASCONF_NORMAL, + .Gain = PIOS_HMC5x83_GAIN_1_9, + .Mode = PIOS_HMC5x83_MODE_CONTINUOUS, + .TempCompensation = false, + .Driver = &PIOS_HMC5x83_I2C_DRIVER, + .Orientation = PIOS_HMC5X83_ORIENTATION_EAST_NORTH_UP, // ENU for GPSV9, WND for typical I2C mag }; #endif /* PIOS_INCLUDE_HMC5X83 */ @@ -209,7 +235,8 @@ uint32_t pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_NONE]; #define PIOS_COM_TELEM_RF_RX_BUF_LEN 512 #define PIOS_COM_TELEM_RF_TX_BUF_LEN 512 -#define PIOS_COM_GPS_RX_BUF_LEN 32 +#define PIOS_COM_GPS_RX_BUF_LEN 128 +#define PIOS_COM_GPS_TX_BUF_LEN 32 #define PIOS_COM_TELEM_USB_RX_BUF_LEN 65 #define PIOS_COM_TELEM_USB_TX_BUF_LEN 65 @@ -223,6 +250,11 @@ uint32_t pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_NONE]; #define PIOS_COM_HKOSD_RX_BUF_LEN 22 #define PIOS_COM_HKOSD_TX_BUF_LEN 22 +#define PIOS_COM_MSP_TX_BUF_LEN 128 +#define PIOS_COM_MSP_RX_BUF_LEN 64 + +#define PIOS_COM_MAVLINK_TX_BUF_LEN 128 + #if defined(PIOS_INCLUDE_DEBUG_CONSOLE) #define PIOS_COM_DEBUGCONSOLE_TX_BUF_LEN 40 uint32_t pios_com_debug_id; @@ -234,7 +266,8 @@ uint32_t pios_com_telem_rf_id = 0; uint32_t pios_com_bridge_id = 0; uint32_t pios_com_overo_id = 0; uint32_t pios_com_hkosd_id = 0; - +uint32_t pios_com_msp_id = 0; +uint32_t pios_com_mavlink_id = 0; uint32_t pios_com_vcp_id = 0; #if defined(PIOS_INCLUDE_RFM22B) @@ -245,9 +278,12 @@ uintptr_t pios_uavo_settings_fs_id; uintptr_t pios_user_fs_id; /* - * Setup a com port based on the passed cfg, driver and buffer sizes. tx size of -1 make the port rx only + * Setup a com port based on the passed cfg, driver and buffer sizes. + * tx size = 0 make the port rx only + * rx size = 0 make the port tx only + * having both tx and rx size = 0 is not valid and will fail further down in PIOS_COM_Init() */ -static void PIOS_Board_configure_com(const struct pios_usart_cfg *usart_port_cfg, size_t rx_buf_len, size_t tx_buf_len, +static void PIOS_Board_configure_com(const struct pios_usart_cfg *usart_port_cfg, uint16_t rx_buf_len, uint16_t tx_buf_len, const struct pios_com_driver *com_driver, uint32_t *pios_com_id) { uint32_t pios_usart_id; @@ -256,23 +292,22 @@ static void PIOS_Board_configure_com(const struct pios_usart_cfg *usart_port_cfg PIOS_Assert(0); } - uint8_t *rx_buffer = (uint8_t *)pios_malloc(rx_buf_len); - PIOS_Assert(rx_buffer); - if (tx_buf_len != (size_t)-1) { // this is the case for rx/tx ports - uint8_t *tx_buffer = (uint8_t *)pios_malloc(tx_buf_len); - PIOS_Assert(tx_buffer); + uint8_t *rx_buffer = 0, *tx_buffer = 0; - if (PIOS_COM_Init(pios_com_id, com_driver, pios_usart_id, - rx_buffer, rx_buf_len, - tx_buffer, tx_buf_len)) { - PIOS_Assert(0); - } - } else { // rx only port - if (PIOS_COM_Init(pios_com_id, com_driver, pios_usart_id, - rx_buffer, rx_buf_len, - NULL, 0)) { - PIOS_Assert(0); - } + if (rx_buf_len > 0) { + rx_buffer = (uint8_t *)pios_malloc(rx_buf_len); + PIOS_Assert(rx_buffer); + } + + if (tx_buf_len > 0) { + tx_buffer = (uint8_t *)pios_malloc(tx_buf_len); + PIOS_Assert(tx_buffer); + } + + if (PIOS_COM_Init(pios_com_id, com_driver, pios_usart_id, + rx_buffer, rx_buf_len, + tx_buffer, tx_buf_len)) { + PIOS_Assert(0); } } @@ -592,7 +627,7 @@ void PIOS_Board_Init(void) PIOS_Board_configure_com(&pios_usart_main_cfg, PIOS_COM_TELEM_RF_RX_BUF_LEN, PIOS_COM_TELEM_RF_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_telem_rf_id); break; case HWSETTINGS_RM_MAINPORT_GPS: - PIOS_Board_configure_com(&pios_usart_main_cfg, PIOS_COM_GPS_RX_BUF_LEN, -1, &pios_usart_com_driver, &pios_com_gps_id); + PIOS_Board_configure_com(&pios_usart_main_cfg, PIOS_COM_GPS_RX_BUF_LEN, PIOS_COM_GPS_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_gps_id); break; case HWSETTINGS_RM_MAINPORT_SBUS: #if defined(PIOS_INCLUDE_SBUS) @@ -633,6 +668,12 @@ void PIOS_Board_Init(void) case HWSETTINGS_RM_MAINPORT_COMBRIDGE: PIOS_Board_configure_com(&pios_usart_main_cfg, PIOS_COM_BRIDGE_RX_BUF_LEN, PIOS_COM_BRIDGE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_bridge_id); break; + case HWSETTINGS_RM_MAINPORT_MSP: + PIOS_Board_configure_com(&pios_usart_main_cfg, PIOS_COM_MSP_RX_BUF_LEN, PIOS_COM_MSP_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_msp_id); + break; + case HWSETTINGS_RM_MAINPORT_MAVLINK: + PIOS_Board_configure_com(&pios_usart_main_cfg, 0, PIOS_COM_MAVLINK_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_mavlink_id); + break; case HWSETTINGS_RM_MAINPORT_OSDHK: PIOS_Board_configure_com(&pios_usart_hkosd_main_cfg, PIOS_COM_HKOSD_RX_BUF_LEN, PIOS_COM_HKOSD_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_hkosd_id); break; @@ -654,15 +695,44 @@ void PIOS_Board_Init(void) break; case HWSETTINGS_RM_FLEXIPORT_I2C: #if defined(PIOS_INCLUDE_I2C) - { - if (PIOS_I2C_Init(&pios_i2c_flexiport_adapter_id, &pios_i2c_flexiport_adapter_cfg)) { - PIOS_Assert(0); - } + if (PIOS_I2C_Init(&pios_i2c_flexiport_adapter_id, &pios_i2c_flexiport_adapter_cfg)) { + PIOS_Assert(0); } + PIOS_DELAY_WaitmS(50); // this was after the other PIOS_I2C_Init(), so I copied it here too +#ifdef PIOS_INCLUDE_WDG + // give HMC5x83 on I2C some extra time to allow for reset, etc. if needed + // this is not in a loop, so it is safe + // leave this here even if PIOS_INCLUDE_HMC5X83 is undefined + // to avoid making something else fail when HMC5X83 is removed + PIOS_WDG_Clear(); +#endif /* PIOS_INCLUDE_WDG */ +#if defined(PIOS_INCLUDE_HMC5X83) + // get auxmag type + AuxMagSettingsTypeOptions option; + AuxMagSettingsInitialize(); + AuxMagSettingsTypeGet(&option); + // if the aux mag type is FlexiPort then set it up + if (option == AUXMAGSETTINGS_TYPE_FLEXI) { + // attach the 5x83 mag to the previously inited I2C2 + external_mag = PIOS_HMC5x83_Init(&pios_hmc5x83_external_cfg, pios_i2c_flexiport_adapter_id, 0); +#ifdef PIOS_INCLUDE_WDG + // give HMC5x83 on I2C some extra time to allow for reset, etc. if needed + // this is not in a loop, so it is safe + PIOS_WDG_Clear(); +#endif /* PIOS_INCLUDE_WDG */ + // add this sensor to the sensor task's list + // be careful that you don't register a slow, unimportant sensor after registering the fastest sensor + // and before registering some other fast and important sensor + // as that would cause delay and time jitter for the second fast sensor + PIOS_HMC5x83_Register(external_mag, PIOS_SENSORS_TYPE_3AXIS_AUXMAG); + // mag alarm is cleared later, so use I2C + AlarmsSet(SYSTEMALARMS_ALARM_I2C, (external_mag) ? SYSTEMALARMS_ALARM_OK : SYSTEMALARMS_ALARM_WARNING); + } +#endif /* PIOS_INCLUDE_HMC5X83 */ #endif /* PIOS_INCLUDE_I2C */ break; case HWSETTINGS_RM_FLEXIPORT_GPS: - PIOS_Board_configure_com(&pios_usart_flexi_cfg, PIOS_COM_GPS_RX_BUF_LEN, -1, &pios_usart_com_driver, &pios_com_gps_id); + PIOS_Board_configure_com(&pios_usart_flexi_cfg, PIOS_COM_GPS_RX_BUF_LEN, PIOS_COM_GPS_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_gps_id); break; case HWSETTINGS_RM_FLEXIPORT_DSM: // TODO: Define the various Channelgroup for Revo dsm inputs and handle here @@ -672,13 +742,19 @@ void PIOS_Board_Init(void) case HWSETTINGS_RM_FLEXIPORT_DEBUGCONSOLE: #if defined(PIOS_INCLUDE_DEBUG_CONSOLE) { - PIOS_Board_configure_com(&pios_usart_main_cfg, 0, PIOS_COM_DEBUGCONSOLE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_debug_id); + PIOS_Board_configure_com(&pios_usart_flexi_cfg, 0, PIOS_COM_DEBUGCONSOLE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_debug_id); } #endif /* PIOS_INCLUDE_DEBUG_CONSOLE */ break; case HWSETTINGS_RM_FLEXIPORT_COMBRIDGE: PIOS_Board_configure_com(&pios_usart_flexi_cfg, PIOS_COM_BRIDGE_RX_BUF_LEN, PIOS_COM_BRIDGE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_bridge_id); break; + case HWSETTINGS_RM_FLEXIPORT_MSP: + PIOS_Board_configure_com(&pios_usart_flexi_cfg, PIOS_COM_MSP_RX_BUF_LEN, PIOS_COM_MSP_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_msp_id); + break; + case HWSETTINGS_RM_FLEXIPORT_MAVLINK: + PIOS_Board_configure_com(&pios_usart_flexi_cfg, 0, PIOS_COM_MAVLINK_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_mavlink_id); + break; case HWSETTINGS_RM_FLEXIPORT_OSDHK: PIOS_Board_configure_com(&pios_usart_hkosd_flexi_cfg, PIOS_COM_HKOSD_RX_BUF_LEN, PIOS_COM_HKOSD_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_hkosd_id); break; @@ -748,6 +824,7 @@ void PIOS_Board_Init(void) } /* Set the radio configuration parameters. */ + PIOS_RFM22B_SetDeviceID(pios_rfm22b_id, oplinkSettings.CustomDeviceID); 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); @@ -756,7 +833,7 @@ void PIOS_Board_Init(void) PIOS_RFM22B_SetPPMCallback(pios_rfm22b_id, PIOS_Board_PPM_callback); } - /* Set the modem Tx poer level */ + /* Set the modem Tx power level */ switch (oplinkSettings.MaxRFPower) { case OPLINKSETTINGS_MAXRFPOWER_125: PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_0); @@ -796,7 +873,7 @@ void PIOS_Board_Init(void) OPLinkStatusSet(&oplinkStatus); #endif /* PIOS_INCLUDE_RFM22B */ -#if defined(PIOS_INCLUDE_PWM) || defined(PIOS_INCLUDE_PWM) +#if defined(PIOS_INCLUDE_PWM) || defined(PIOS_INCLUDE_PPM) const struct pios_servo_cfg *pios_servo_cfg; // default to servo outputs only @@ -819,6 +896,12 @@ void PIOS_Board_Init(void) case HWSETTINGS_RM_RCVRPORT_PPM: case HWSETTINGS_RM_RCVRPORT_PPMOUTPUTS: case HWSETTINGS_RM_RCVRPORT_PPMPWM: + case HWSETTINGS_RM_RCVRPORT_PPMTELEMETRY: + case HWSETTINGS_RM_RCVRPORT_PPMDEBUGCONSOLE: + case HWSETTINGS_RM_RCVRPORT_PPMCOMBRIDGE: + case HWSETTINGS_RM_RCVRPORT_PPMMSP: + case HWSETTINGS_RM_RCVRPORT_PPMMAVLINK: + case HWSETTINGS_RM_RCVRPORT_PPMGPS: #if defined(PIOS_INCLUDE_PPM) if (hwsettings_rcvrport == HWSETTINGS_RM_RCVRPORT_PPMOUTPUTS) { // configure servo outputs and the remaining 5 inputs as outputs @@ -840,6 +923,35 @@ void PIOS_Board_Init(void) break; } + // Configure rcvrport usart + switch (hwsettings_rcvrport) { + case HWSETTINGS_RM_RCVRPORT_TELEMETRY: + case HWSETTINGS_RM_RCVRPORT_PPMTELEMETRY: + PIOS_Board_configure_com(&pios_usart_rcvrport_cfg, PIOS_COM_TELEM_RF_RX_BUF_LEN, PIOS_COM_TELEM_RF_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_telem_rf_id); + break; + case HWSETTINGS_RM_RCVRPORT_DEBUGCONSOLE: + case HWSETTINGS_RM_RCVRPORT_PPMDEBUGCONSOLE: +#if defined(PIOS_INCLUDE_DEBUG_CONSOLE) + PIOS_Board_configure_com(&pios_usart_rcvrport_cfg, 0, PIOS_COM_DEBUGCONSOLE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_debug_id); +#endif /* PIOS_INCLUDE_DEBUG_CONSOLE */ + break; + case HWSETTINGS_RM_RCVRPORT_COMBRIDGE: + case HWSETTINGS_RM_RCVRPORT_PPMCOMBRIDGE: + PIOS_Board_configure_com(&pios_usart_rcvrport_cfg, PIOS_COM_BRIDGE_RX_BUF_LEN, PIOS_COM_BRIDGE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_bridge_id); + break; + case HWSETTINGS_RM_RCVRPORT_MSP: + case HWSETTINGS_RM_RCVRPORT_PPMMSP: + PIOS_Board_configure_com(&pios_usart_rcvrport_cfg, PIOS_COM_MSP_RX_BUF_LEN, PIOS_COM_MSP_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_msp_id); + break; + case HWSETTINGS_RM_RCVRPORT_MAVLINK: + case HWSETTINGS_RM_RCVRPORT_PPMMAVLINK: + PIOS_Board_configure_com(&pios_usart_rcvrport_cfg, 0, PIOS_COM_MAVLINK_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_mavlink_id); + break; + case HWSETTINGS_RM_RCVRPORT_GPS: + case HWSETTINGS_RM_RCVRPORT_PPMGPS: + PIOS_Board_configure_com(&pios_usart_rcvrport_cfg, PIOS_COM_GPS_RX_BUF_LEN, PIOS_COM_GPS_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_gps_id); + break; + } #if defined(PIOS_INCLUDE_GCSRCVR) GCSReceiverInitialize(); @@ -882,6 +994,7 @@ void PIOS_Board_Init(void) }; GPIO_Init(GPIOA, &gpioA8); + // init I2C1 for use with the internal mag and baro if (PIOS_I2C_Init(&pios_i2c_mag_pressure_adapter_id, &pios_i2c_mag_pressure_adapter_cfg)) { PIOS_DEBUG_Assert(0); } @@ -892,8 +1005,24 @@ void PIOS_Board_Init(void) PIOS_ADC_Init(&pios_adc_cfg); #endif +#ifdef PIOS_INCLUDE_WDG + // give HMC5x83 on I2C some extra time to allow for reset, etc. if needed + // this is not in a loop, so it is safe + // leave this here even if PIOS_INCLUDE_HMC5X83 is undefined + // to avoid making something else fail when HMC5X83 is removed + PIOS_WDG_Clear(); +#endif /* PIOS_INCLUDE_WDG */ + #if defined(PIOS_INCLUDE_HMC5X83) - PIOS_HMC5x83_Init(&pios_hmc5x83_cfg, pios_i2c_mag_pressure_adapter_id, 0); + // attach the 5x83 mag to the previously inited I2C1 + onboard_mag = PIOS_HMC5x83_Init(&pios_hmc5x83_internal_cfg, pios_i2c_mag_pressure_adapter_id, 0); +#ifdef PIOS_INCLUDE_WDG + // give HMC5x83 on I2C some extra time to allow for reset, etc. if needed + // this is not in a loop, so it is safe + PIOS_WDG_Clear(); +#endif /* PIOS_INCLUDE_WDG */ + // add this sensor to the sensor task's list + PIOS_HMC5x83_Register(onboard_mag, PIOS_SENSORS_TYPE_3AXIS_MAG); #endif #if defined(PIOS_INCLUDE_MS5611) diff --git a/flight/targets/boards/discoveryf4bare/pios_board.h b/flight/targets/boards/discoveryf4bare/pios_board.h index d25c71d53..a6373ccd3 100644 --- a/flight/targets/boards/discoveryf4bare/pios_board.h +++ b/flight/targets/boards/discoveryf4bare/pios_board.h @@ -128,12 +128,17 @@ extern uint32_t pios_com_telem_usb_id; extern uint32_t pios_com_bridge_id; extern uint32_t pios_com_vcp_id; extern uint32_t pios_com_hkosd_id; +extern uint32_t pios_com_msp_id; +extern uint32_t pios_com_mavlink_id; + #define PIOS_COM_GPS (pios_com_gps_id) #define PIOS_COM_TELEM_USB (pios_com_telem_usb_id) #define PIOS_COM_TELEM_RF (pios_com_telem_rf_id) #define PIOS_COM_BRIDGE (pios_com_bridge_id) #define PIOS_COM_VCP (pios_com_vcp_id) #define PIOS_COM_OSDHK (pios_com_hkosd_id) +#define PIOS_COM_MSP (pios_com_msp_id) +#define PIOS_COM_MAVLINK (pios_com_mavlink_id) #if defined(PIOS_INCLUDE_DEBUG_CONSOLE) extern uint32_t pios_com_debug_id; @@ -217,7 +222,7 @@ extern uint32_t pios_packet_handler; // Receiver PPM input // ------------------------- #define PIOS_PPM_MAX_DEVS 1 -#define PIOS_PPM_NUM_INPUTS 12 +#define PIOS_PPM_NUM_INPUTS 16 // ------------------------- // Receiver PWM input diff --git a/flight/targets/boards/gpsplatinum/bootloader/main.c b/flight/targets/boards/gpsplatinum/bootloader/main.c index 2e2230847..a11fa2f3d 100644 --- a/flight/targets/boards/gpsplatinum/bootloader/main.c +++ b/flight/targets/boards/gpsplatinum/bootloader/main.c @@ -36,9 +36,8 @@ #include #include #include +#include -/* Prototype of PIOS_Board_Init() function */ -extern void PIOS_Board_Init(void); extern void FLASH_Download(); int32_t platform_senddata(const uint8_t *msg, uint16_t msg_len); /* Private typedef -----------------------------------------------------------*/ diff --git a/flight/targets/boards/gpsplatinum/firmware/gpsp.c b/flight/targets/boards/gpsplatinum/firmware/gpsp.c index b240febb2..0768c2a55 100644 --- a/flight/targets/boards/gpsplatinum/firmware/gpsp.c +++ b/flight/targets/boards/gpsplatinum/firmware/gpsp.c @@ -34,14 +34,13 @@ #include "inc/openpilot.h" #include #include +#include /* Task Priorities */ #define PRIORITY_TASK_HOOKS (tskIDLE_PRIORITY + 3) /* Global Variables */ -/* Prototype of PIOS_Board_Init() function */ -extern void PIOS_Board_Init(void); extern void Stack_Change(void); /** diff --git a/flight/targets/boards/oplinkmini/board_hw_defs.c b/flight/targets/boards/oplinkmini/board_hw_defs.c index da3d81b95..548f965dd 100644 --- a/flight/targets/boards/oplinkmini/board_hw_defs.c +++ b/flight/targets/boards/oplinkmini/board_hw_defs.c @@ -298,8 +298,6 @@ static const struct pios_exti_cfg pios_exti_rfm22b_cfg __exti_config = { }, }; -#include - struct pios_rfm22b_cfg pios_rfm22b_cfg = { .spi_cfg = &pios_spi_rfm22b_cfg, .exti_cfg = &pios_exti_rfm22b_cfg, @@ -314,6 +312,51 @@ const struct pios_rfm22b_cfg *PIOS_BOARD_HW_DEFS_GetRfm22Cfg(__attribute__((unus return &pios_rfm22b_cfg; } +#if defined(PIOS_INCLUDE_OPENLRS) + +#include + +static const struct pios_exti_cfg pios_exti_openlrs_cfg __exti_config = { + .vector = PIOS_OpenLRS_EXT_Int, + .line = EXTI_Line2, + .pin = { + .gpio = GPIOA, + .init = { + .GPIO_Pin = GPIO_Pin_2, + .GPIO_Mode = GPIO_Mode_IN_FLOATING, + }, + }, + .irq = { + .init = { + .NVIC_IRQChannel = EXTI2_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_LOW, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .exti = { + .init = { + .EXTI_Line = EXTI_Line2, + .EXTI_Mode = EXTI_Mode_Interrupt, + .EXTI_Trigger = EXTI_Trigger_Falling, + .EXTI_LineCmd = ENABLE, + }, + }, +}; + +struct pios_openlrs_cfg pios_openlrs_cfg = { + .spi_cfg = &pios_spi_rfm22b_cfg, + .exti_cfg = &pios_exti_openlrs_cfg, +}; + +// ! Compatibility layer for various hardware revisions +const struct pios_openlrs_cfg *PIOS_BOARD_HW_DEFS_GetOpenLRSCfg(__attribute__((unused)) uint32_t board_revision) +{ + return &pios_openlrs_cfg; +} + +#endif /* PIOS_INCLUDE_OpenLRS */ + #endif /* PIOS_INCLUDE_RFM22B */ #if defined(PIOS_INCLUDE_ADC) diff --git a/flight/targets/boards/oplinkmini/bootloader/main.c b/flight/targets/boards/oplinkmini/bootloader/main.c index 9135341af..28cfcc30b 100644 --- a/flight/targets/boards/oplinkmini/bootloader/main.c +++ b/flight/targets/boards/oplinkmini/bootloader/main.c @@ -33,9 +33,8 @@ #include #include #include +#include -/* Prototype of PIOS_Board_Init() function */ -extern void PIOS_Board_Init(void); extern void FLASH_Download(); #define BSL_HOLD_STATE ((PIOS_USB_DETECT_GPIO_PORT->IDR & PIOS_USB_DETECT_GPIO_PIN) ? 0 : 1) diff --git a/flight/targets/boards/oplinkmini/firmware/Makefile b/flight/targets/boards/oplinkmini/firmware/Makefile index 186de237e..bf7c50a12 100644 --- a/flight/targets/boards/oplinkmini/firmware/Makefile +++ b/flight/targets/boards/oplinkmini/firmware/Makefile @@ -29,6 +29,7 @@ override USE_DSP_LIB := NO # List of mandatory modules to include MODULES += RadioComBridge +MODULES += ComUsbBridge # List of optional modules to include OPTMODULES = @@ -59,6 +60,8 @@ ifndef TESTAPP SRC += $(FLIGHT_UAVOBJ_DIR)/objectpersistence.c SRC += $(FLIGHT_UAVOBJ_DIR)/oplinkreceiver.c SRC += $(FLIGHT_UAVOBJ_DIR)/radiocombridgestats.c + SRC += $(FLIGHT_UAVOBJ_DIR)/flightbatterystate.c + SRC += $(FLIGHT_UAVOBJ_DIR)/flightstatus.c else ## Test Code SRC += $(OPTESTS)/test_common.c diff --git a/flight/targets/boards/oplinkmini/firmware/inc/pios_config.h b/flight/targets/boards/oplinkmini/firmware/inc/pios_config.h index 7717beb52..074d87606 100644 --- a/flight/targets/boards/oplinkmini/firmware/inc/pios_config.h +++ b/flight/targets/boards/oplinkmini/firmware/inc/pios_config.h @@ -120,6 +120,7 @@ #define PIOS_INCLUDE_RFM22B #define PIOS_INCLUDE_RFM22B_COM #define PIOS_INCLUDE_PPM_OUT +#define PIOS_INCLUDE_OPENLRS /* #define PIOS_RFM22B_DEBUG_ON_TELEM */ /* PIOS misc peripherals */ diff --git a/flight/targets/boards/oplinkmini/firmware/oplink.c b/flight/targets/boards/oplinkmini/firmware/oplink.c index 07d4fa551..13b5e44b3 100644 --- a/flight/targets/boards/oplinkmini/firmware/oplink.c +++ b/flight/targets/boards/oplinkmini/firmware/oplink.c @@ -34,14 +34,13 @@ #include "inc/openpilot.h" #include #include +#include /* Task Priorities */ #define PRIORITY_TASK_HOOKS (tskIDLE_PRIORITY + 3) /* Global Variables */ -/* Prototype of PIOS_Board_Init() function */ -extern void PIOS_Board_Init(void); extern void Stack_Change(void); /** diff --git a/flight/targets/boards/oplinkmini/firmware/pios_board.c b/flight/targets/boards/oplinkmini/firmware/pios_board.c index 34d033db3..a6f7574ca 100644 --- a/flight/targets/boards/oplinkmini/firmware/pios_board.c +++ b/flight/targets/boards/oplinkmini/firmware/pios_board.c @@ -6,7 +6,8 @@ * @{ * * @file pios_board.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @brief Defines board specific static initializers for hardware for the OpenPilot board. * @see The GNU Public License (GPL) Version 3 * @@ -31,6 +32,7 @@ #include #include #include +#include #include #ifdef PIOS_INCLUDE_SERVO #include @@ -63,6 +65,8 @@ uint32_t pios_com_telem_vcp_id = 0; uint32_t pios_com_telem_uart_main_id = 0; uint32_t pios_com_telem_uart_flexi_id = 0; uint32_t pios_com_telemetry_id = 0; +uint32_t pios_com_bridge_id = 0; +uint32_t pios_com_vcp_id = 0; #if defined(PIOS_INCLUDE_PPM) uint32_t pios_ppm_rcvr_id = 0; #endif @@ -74,14 +78,47 @@ uint32_t pios_rfm22b_id = 0; uint32_t pios_com_rfm22b_id = 0; uint32_t pios_com_radio_id = 0; #endif -uint8_t *pios_uart_rx_buffer; -uint8_t *pios_uart_tx_buffer; uintptr_t pios_uavo_settings_fs_id; uintptr_t pios_user_fs_id = 0; uint8_t servo_count = 0; +/* + * Setup a com port based on the passed cfg, driver and buffer sizes. + * tx size of 0 make the port rx only + * rx size of 0 make the port tx only + * having both tx and rx size of 0 is not valid and will fail further down in PIOS_COM_Init() + */ +static void PIOS_Board_configure_com(const struct pios_usart_cfg *usart_port_cfg, uint16_t rx_buf_len, uint16_t tx_buf_len, + const struct pios_com_driver *com_driver, uint32_t *pios_com_id) +{ + uint32_t pios_usart_id; + + if (PIOS_USART_Init(&pios_usart_id, usart_port_cfg)) { + PIOS_Assert(0); + } + + uint8_t *rx_buffer = 0, *tx_buffer = 0; + + if (rx_buf_len > 0) { + rx_buffer = (uint8_t *)pios_malloc(rx_buf_len); + PIOS_Assert(rx_buffer); + } + + if (tx_buf_len > 0) { + tx_buffer = (uint8_t *)pios_malloc(tx_buf_len); + PIOS_Assert(tx_buffer); + } + + if (PIOS_COM_Init(pios_com_id, com_driver, pios_usart_id, + rx_buffer, rx_buf_len, + tx_buffer, tx_buf_len)) { + PIOS_Assert(0); + } +} + + // Forward definitions static void PIOS_Board_PPM_callback(const int16_t *channels); @@ -216,17 +253,18 @@ void PIOS_Board_Init(void) } #endif - /* Allocate the uart buffers. */ - pios_uart_rx_buffer = (uint8_t *)pios_malloc(PIOS_COM_TELEM_RX_BUF_LEN); - pios_uart_tx_buffer = (uint8_t *)pios_malloc(PIOS_COM_TELEM_TX_BUF_LEN); - // Configure the main port OPLinkSettingsData oplinkSettings; OPLinkSettingsGet(&oplinkSettings); - bool is_coordinator = (oplinkSettings.Coordinator == OPLINKSETTINGS_COORDINATOR_TRUE); - bool is_oneway = (oplinkSettings.OneWay == OPLINKSETTINGS_ONEWAY_TRUE); - bool ppm_only = (oplinkSettings.PPMOnly == OPLINKSETTINGS_PPMONLY_TRUE); - bool ppm_mode = false; + bool is_coordinator = (oplinkSettings.Protocol == OPLINKSETTINGS_PROTOCOL_OPLINKCOORDINATOR); + bool openlrs = (oplinkSettings.Protocol == OPLINKSETTINGS_PROTOCOL_OPENLRS); + bool ppm_only = (oplinkSettings.LinkType == OPLINKSETTINGS_LINKTYPE_CONTROL); + bool data_mode = ((oplinkSettings.LinkType == OPLINKSETTINGS_LINKTYPE_DATA) || + (oplinkSettings.LinkType == OPLINKSETTINGS_LINKTYPE_DATAANDCONTROL)); + bool is_enabled = ((oplinkSettings.Protocol != OPLINKSETTINGS_PROTOCOL_DISABLED) && + ((oplinkSettings.MaxRFPower != OPLINKSETTINGS_MAXRFPOWER_0) || openlrs)); + bool ppm_mode = ((oplinkSettings.LinkType == OPLINKSETTINGS_LINKTYPE_CONTROL) || + (oplinkSettings.LinkType == OPLINKSETTINGS_LINKTYPE_DATAANDCONTROL)); bool servo_main = false; bool servo_flexi = false; switch (oplinkSettings.MainPort) { @@ -235,21 +273,19 @@ void PIOS_Board_Init(void) { /* Configure the main port for uart serial */ #ifndef PIOS_RFM22B_DEBUG_ON_TELEM - uint32_t pios_usart1_id; - if (PIOS_USART_Init(&pios_usart1_id, &pios_usart_serial_cfg)) { - PIOS_Assert(0); - } - PIOS_Assert(pios_uart_rx_buffer); - PIOS_Assert(pios_uart_tx_buffer); - if (PIOS_COM_Init(&pios_com_telem_uart_main_id, &pios_usart_com_driver, pios_usart1_id, - pios_uart_rx_buffer, PIOS_COM_TELEM_RX_BUF_LEN, - pios_uart_tx_buffer, PIOS_COM_TELEM_TX_BUF_LEN)) { - PIOS_Assert(0); - } + PIOS_Board_configure_com(&pios_usart_serial_cfg, + PIOS_COM_TELEM_RX_BUF_LEN, PIOS_COM_TELEM_TX_BUF_LEN, + &pios_usart_com_driver, &pios_com_telem_uart_main_id); + PIOS_COM_TELEMETRY = PIOS_COM_TELEM_UART_MAIN; #endif break; } + case OPLINKSETTINGS_MAINPORT_COMBRIDGE: + PIOS_Board_configure_com(&pios_usart_serial_cfg, + PIOS_COM_TELEM_RX_BUF_LEN, PIOS_COM_TELEM_TX_BUF_LEN, + &pios_usart_com_driver, &pios_com_bridge_id); + break; case OPLINKSETTINGS_MAINPORT_PPM: { #if defined(PIOS_INCLUDE_PPM) @@ -268,7 +304,6 @@ void PIOS_Board_Init(void) PIOS_PPM_Out_Init(&pios_ppm_out_id, &pios_main_ppm_out_cfg); } #endif /* PIOS_INCLUDE_PPM_OUT */ - ppm_mode = true; #endif /* PIOS_INCLUDE_PPM */ break; } @@ -285,21 +320,19 @@ void PIOS_Board_Init(void) case OPLINKSETTINGS_FLEXIPORT_SERIAL: { /* Configure the flexi port as uart serial */ - uint32_t pios_usart3_id; - - if (PIOS_USART_Init(&pios_usart3_id, &pios_usart_telem_flexi_cfg)) { - PIOS_Assert(0); - } - PIOS_Assert(pios_uart_rx_buffer); - PIOS_Assert(pios_uart_tx_buffer); - if (PIOS_COM_Init(&pios_com_telem_uart_flexi_id, &pios_usart_com_driver, pios_usart3_id, - pios_uart_rx_buffer, PIOS_COM_TELEM_RX_BUF_LEN, - pios_uart_tx_buffer, PIOS_COM_TELEM_TX_BUF_LEN)) { - PIOS_Assert(0); - } + PIOS_Board_configure_com(&pios_usart_telem_flexi_cfg, + PIOS_COM_TELEM_RX_BUF_LEN, PIOS_COM_TELEM_TX_BUF_LEN, + &pios_usart_com_driver, + &pios_com_telem_uart_flexi_id); PIOS_COM_TELEMETRY = PIOS_COM_TELEM_UART_FLEXI; break; } + case OPLINKSETTINGS_FLEXIPORT_COMBRIDGE: + PIOS_Board_configure_com(&pios_usart_telem_flexi_cfg, + PIOS_COM_TELEM_RX_BUF_LEN, PIOS_COM_TELEM_TX_BUF_LEN, + &pios_usart_com_driver, + &pios_com_bridge_id); + break; case OPLINKSETTINGS_FLEXIPORT_PPM: { #if defined(PIOS_INCLUDE_PPM) @@ -315,7 +348,6 @@ void PIOS_Board_Init(void) PIOS_PPM_Out_Init(&pios_ppm_out_id, &pios_flexi_ppm_out_cfg); } #endif /* PIOS_INCLUDE_PPM */ - ppm_mode = true; break; } case OPLINKSETTINGS_FLEXIPORT_PWM: @@ -330,6 +362,9 @@ void PIOS_Board_Init(void) case OPLINKSETTINGS_VCPPORT_SERIAL: PIOS_COM_TELEMETRY = PIOS_COM_TELEM_USB_VCP; break; + case OPLINKSETTINGS_VCPPORT_COMBRIDGE: + PIOS_COM_VCP = PIOS_COM_TELEM_USB_VCP; + break; case OPLINKSETTINGS_VCPPORT_DISABLED: break; } @@ -347,7 +382,6 @@ void PIOS_Board_Init(void) servo_count = 2; PIOS_Servo_Init(&pios_servo_flexi_cfg); } - ppm_mode = ppm_mode || (servo_count > 0); #endif // Initialize out status object. @@ -363,91 +397,104 @@ void PIOS_Board_Init(void) oplinkStatus.BoardRevision = bdinfo->board_rev; /* Initalize the RFM22B radio COM device. */ - if (oplinkSettings.MaxRFPower != OPLINKSETTINGS_MAXRFPOWER_0) { - oplinkStatus.LinkState = OPLINKSTATUS_LINKSTATE_ENABLED; + if (is_enabled) { + if (openlrs) { +#if defined(PIOS_INCLUDE_OPENLRS) + const struct pios_openlrs_cfg *openlrs_cfg = PIOS_BOARD_HW_DEFS_GetOpenLRSCfg(bdinfo->board_rev); + uint32_t openlrs_id; - // Configure the RFM22B device - const struct pios_rfm22b_cfg *rfm22b_cfg = PIOS_BOARD_HW_DEFS_GetRfm22Cfg(bdinfo->board_rev); - if (PIOS_RFM22B_Init(&pios_rfm22b_id, PIOS_RFM22_SPI_PORT, rfm22b_cfg->slave_num, rfm22b_cfg)) { - PIOS_Assert(0); - } + oplinkStatus.LinkState = OPLINKSTATUS_LINKSTATE_ENABLED; - // Configure the radio com interface - uint8_t *rx_buffer = (uint8_t *)pios_malloc(PIOS_COM_RFM22B_RF_RX_BUF_LEN); - uint8_t *tx_buffer = (uint8_t *)pios_malloc(PIOS_COM_RFM22B_RF_TX_BUF_LEN); - PIOS_Assert(rx_buffer); - PIOS_Assert(tx_buffer); - if (PIOS_COM_Init(&pios_com_rfm22b_id, &pios_rfm22b_com_driver, pios_rfm22b_id, - rx_buffer, PIOS_COM_RFM22B_RF_RX_BUF_LEN, - tx_buffer, PIOS_COM_RFM22B_RF_TX_BUF_LEN)) { - PIOS_Assert(0); - } + PIOS_OpenLRS_Init(&openlrs_id, PIOS_RFM22_SPI_PORT, 0, openlrs_cfg); + PIOS_OpenLRS_RegisterPPMCallback(openlrs_id, PIOS_Board_PPM_callback); +#endif /* PIOS_INCLUDE_OPENLRS */ + } else { + oplinkStatus.LinkState = OPLINKSTATUS_LINKSTATE_ENABLED; - // Set the RF data rate on the modem to ~2X the selected buad rate because the modem is half duplex. - enum rfm22b_datarate datarate = RFM22_datarate_64000; - switch (oplinkSettings.ComSpeed) { - case OPLINKSETTINGS_COMSPEED_4800: - datarate = RFM22_datarate_9600; - break; - case OPLINKSETTINGS_COMSPEED_9600: - datarate = RFM22_datarate_19200; - break; - case OPLINKSETTINGS_COMSPEED_19200: - datarate = RFM22_datarate_32000; - break; - case OPLINKSETTINGS_COMSPEED_38400: - datarate = RFM22_datarate_64000; - break; - case OPLINKSETTINGS_COMSPEED_57600: - datarate = RFM22_datarate_100000; - break; - case OPLINKSETTINGS_COMSPEED_115200: - datarate = RFM22_datarate_192000; - break; - } + // Configure the RFM22B device + const struct pios_rfm22b_cfg *rfm22b_cfg = PIOS_BOARD_HW_DEFS_GetRfm22Cfg(bdinfo->board_rev); + if (PIOS_RFM22B_Init(&pios_rfm22b_id, PIOS_RFM22_SPI_PORT, rfm22b_cfg->slave_num, rfm22b_cfg)) { + PIOS_Assert(0); + } - /* Set the modem Tx poer level */ - switch (oplinkSettings.MaxRFPower) { - case OPLINKSETTINGS_MAXRFPOWER_125: - PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_0); - break; - case OPLINKSETTINGS_MAXRFPOWER_16: - PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_1); - break; - case OPLINKSETTINGS_MAXRFPOWER_316: - PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_2); - break; - case OPLINKSETTINGS_MAXRFPOWER_63: - PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_3); - break; - case OPLINKSETTINGS_MAXRFPOWER_126: - PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_4); - break; - case OPLINKSETTINGS_MAXRFPOWER_25: - PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_5); - break; - case OPLINKSETTINGS_MAXRFPOWER_50: - PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_6); - break; - case OPLINKSETTINGS_MAXRFPOWER_100: - PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_7); - break; - default: - // do nothing - break; - } + // Configure the radio com interface + uint8_t *rx_buffer = (uint8_t *)pios_malloc(PIOS_COM_RFM22B_RF_RX_BUF_LEN); + uint8_t *tx_buffer = (uint8_t *)pios_malloc(PIOS_COM_RFM22B_RF_TX_BUF_LEN); + PIOS_Assert(rx_buffer); + PIOS_Assert(tx_buffer); + if (PIOS_COM_Init(&pios_com_rfm22b_id, &pios_rfm22b_com_driver, pios_rfm22b_id, + rx_buffer, PIOS_COM_RFM22B_RF_RX_BUF_LEN, + tx_buffer, PIOS_COM_RFM22B_RF_TX_BUF_LEN)) { + PIOS_Assert(0); + } - // Set the radio configuration parameters. - 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 RF data rate on the modem to ~2X the selected buad rate because the modem is half duplex. + enum rfm22b_datarate datarate = RFM22_datarate_64000; + switch (oplinkSettings.ComSpeed) { + case OPLINKSETTINGS_COMSPEED_4800: + datarate = RFM22_datarate_9600; + break; + case OPLINKSETTINGS_COMSPEED_9600: + datarate = RFM22_datarate_19200; + break; + case OPLINKSETTINGS_COMSPEED_19200: + datarate = RFM22_datarate_32000; + break; + case OPLINKSETTINGS_COMSPEED_38400: + datarate = RFM22_datarate_64000; + break; + case OPLINKSETTINGS_COMSPEED_57600: + datarate = RFM22_datarate_100000; + break; + case OPLINKSETTINGS_COMSPEED_115200: + datarate = RFM22_datarate_192000; + break; + } - /* Set the PPM callback if we should be receiving PPM. */ - if (ppm_mode || (ppm_only && !is_coordinator)) { - PIOS_RFM22B_SetPPMCallback(pios_rfm22b_id, PIOS_Board_PPM_callback); - } + /* Set the modem Tx power level */ + switch (oplinkSettings.MaxRFPower) { + case OPLINKSETTINGS_MAXRFPOWER_125: + PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_0); + break; + case OPLINKSETTINGS_MAXRFPOWER_16: + PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_1); + break; + case OPLINKSETTINGS_MAXRFPOWER_316: + PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_2); + break; + case OPLINKSETTINGS_MAXRFPOWER_63: + PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_3); + break; + case OPLINKSETTINGS_MAXRFPOWER_126: + PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_4); + break; + case OPLINKSETTINGS_MAXRFPOWER_25: + PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_5); + break; + case OPLINKSETTINGS_MAXRFPOWER_50: + PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_6); + break; + case OPLINKSETTINGS_MAXRFPOWER_100: + PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_7); + break; + default: + // do nothing + break; + } - // Reinitilize the modem to affect te changes. - PIOS_RFM22B_Reinit(pios_rfm22b_id); + // Set the radio configuration parameters. + PIOS_RFM22B_SetDeviceID(pios_rfm22b_id, oplinkSettings.CustomDeviceID); + PIOS_RFM22B_SetCoordinatorID(pios_rfm22b_id, oplinkSettings.CoordID); + PIOS_RFM22B_SetChannelConfig(pios_rfm22b_id, datarate, oplinkSettings.MinChannel, oplinkSettings.MaxChannel, is_coordinator, data_mode, ppm_mode); + + /* Set the PPM callback if we should be receiving PPM. */ + if (ppm_mode || (ppm_only && !is_coordinator)) { + PIOS_RFM22B_SetPPMCallback(pios_rfm22b_id, PIOS_Board_PPM_callback); + } + + // Reinitialize the modem to affect the changes. + PIOS_RFM22B_Reinit(pios_rfm22b_id); + } // openlrs } else { oplinkStatus.LinkState = OPLINKSTATUS_LINKSTATE_DISABLED; } diff --git a/flight/targets/boards/oplinkmini/pios_board.h b/flight/targets/boards/oplinkmini/pios_board.h index b571a87d4..749657ea7 100644 --- a/flight/targets/boards/oplinkmini/pios_board.h +++ b/flight/targets/boards/oplinkmini/pios_board.h @@ -181,19 +181,22 @@ extern uint32_t pios_com_telem_uart_flexi_id; extern uint32_t pios_com_telemetry_id; extern uint32_t pios_com_rfm22b_id; extern uint32_t pios_com_radio_id; +extern uint32_t pios_com_bridge_id; +extern uint32_t pios_com_vcp_id; extern uint32_t pios_ppm_rcvr_id; extern uint32_t pios_ppm_out_id; #define PIOS_COM_TELEM_USB_HID (pios_com_telem_usb_id) #define PIOS_COM_TELEM_USB PIOS_COM_TELEM_USB_HID #define PIOS_COM_TELEM_USB_VCP (pios_com_telem_vcp_id) +#define PIOS_COM_VCP (pios_com_vcp_id) #define PIOS_COM_TELEM_UART_MAIN (pios_com_telem_uart_main_id) #define PIOS_COM_TELEM_UART_FLEXI (pios_com_telem_uart_flexi_id) #define PIOS_COM_TELEMETRY (pios_com_telemetry_id) #define PIOS_COM_RFM22B (pios_com_rfm22b_id) #define PIOS_COM_RADIO (pios_com_radio_id) +#define PIOS_COM_BRIDGE (pios_com_bridge_id) #define PIOS_PPM_RECEIVER (pios_ppm_rcvr_id) #define PIOS_PPM_OUTPUT (pios_ppm_out_id) - #define RFM22_DEBUG 1 // ------------------------- @@ -248,7 +251,7 @@ extern uint32_t pios_ppm_out_id; // Receiver PPM input // ------------------------- #define PIOS_PPM_MAX_DEVS 1 -#define PIOS_PPM_NUM_INPUTS 8 +#define PIOS_PPM_NUM_INPUTS 12 // ------------------------- // Receiver PWM inputs diff --git a/flight/targets/boards/osd/board_hw_defs.c b/flight/targets/boards/osd/board_hw_defs.c index 5ef3cc7b5..ed86e0915 100644 --- a/flight/targets/boards/osd/board_hw_defs.c +++ b/flight/targets/boards/osd/board_hw_defs.c @@ -407,7 +407,7 @@ static const struct pios_i2c_adapter_cfg pios_i2c_flexiport_adapter_cfg = { .GPIO_Mode = GPIO_Mode_AF, .GPIO_Speed = GPIO_Speed_50MHz, .GPIO_OType = GPIO_OType_OD, - .GPIO_PuPd = GPIO_PuPd_NOPULL, + .GPIO_PuPd = GPIO_PuPd_UP, }, }, .sda = { @@ -417,7 +417,7 @@ static const struct pios_i2c_adapter_cfg pios_i2c_flexiport_adapter_cfg = { .GPIO_Mode = GPIO_Mode_AF, .GPIO_Speed = GPIO_Speed_50MHz, .GPIO_OType = GPIO_OType_OD, - .GPIO_PuPd = GPIO_PuPd_NOPULL, + .GPIO_PuPd = GPIO_PuPd_UP, }, }, .event = { diff --git a/flight/targets/boards/osd/bootloader/main.c b/flight/targets/boards/osd/bootloader/main.c index 12f2a4c39..c333ab9af 100644 --- a/flight/targets/boards/osd/bootloader/main.c +++ b/flight/targets/boards/osd/bootloader/main.c @@ -34,9 +34,8 @@ #include #include /* PIOS_USBHOOK_* */ #include +#include -/* Prototype of PIOS_Board_Init() function */ -extern void PIOS_Board_Init(void); extern void FLASH_Download(); #define BSL_HOLD_STATE ((PIOS_USB_DETECT_GPIO_PORT->IDR & PIOS_USB_DETECT_GPIO_PIN) ? 0 : 1) diff --git a/flight/targets/boards/osd/firmware/Makefile b/flight/targets/boards/osd/firmware/Makefile index edc8b34af..74043edcc 100644 --- a/flight/targets/boards/osd/firmware/Makefile +++ b/flight/targets/boards/osd/firmware/Makefile @@ -24,6 +24,9 @@ endif include ../board-info.mk include $(FLIGHT_ROOT_DIR)/make/firmware-defs.mk +# REVO C++ support +USE_CXX = YES + # ARM DSP library override USE_DSP_LIB := NO @@ -52,7 +55,7 @@ ifndef TESTAPP ## Application Core SRC += ../pios_usb_board_data.c SRC += $(OPMODULEDIR)/System/systemmod.c - SRC += $(OPSYSTEM)/osd.c + CPPSRC += $(OPSYSTEM)/osd.cpp SRC += $(OPSYSTEM)/pios_board.c SRC += $(FLIGHTLIB)/alarms.c SRC += $(OPUAVTALK)/uavtalk.c diff --git a/flight/targets/boards/osd/firmware/inc/pios_config.h b/flight/targets/boards/osd/firmware/inc/pios_config.h index 98f7c22c0..75ef3286a 100644 --- a/flight/targets/boards/osd/firmware/inc/pios_config.h +++ b/flight/targets/boards/osd/firmware/inc/pios_config.h @@ -81,7 +81,7 @@ /* #define PIOS_INCLUDE_MPU6000 */ /* #define PIOS_MPU6000_ACCEL */ /* #define PIOS_INCLUDE_HMC5843 */ -#define PIOS_INCLUDE_HMC5X83 +/* #define PIOS_INCLUDE_HMC5X83 */ /* #define PIOS_HMC5X83_HAS_GPIOS */ #define PIOS_INCLUDE_BMP085 /* #define PIOS_INCLUDE_MS5611 */ @@ -141,6 +141,7 @@ /* #define PIOS_GPS_MINIMAL */ #define PIOS_INCLUDE_GPS_NMEA_PARSER #define PIOS_INCLUDE_GPS_UBX_PARSER +#define PIOS_INCLUDE_GPS_DJI_PARSER #define PIOS_GPS_SETS_HOMELOCATION /* Stabilization options */ diff --git a/flight/targets/boards/osd/firmware/osd.c b/flight/targets/boards/osd/firmware/osd.c deleted file mode 100644 index 041b42c00..000000000 --- a/flight/targets/boards/osd/firmware/osd.c +++ /dev/null @@ -1,229 +0,0 @@ -/** - ****************************************************************************** - * - * @file main.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @brief Main modem functions - * @see The GNU Public License (GPL) Version 3 - * - *****************************************************************************/ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -// ***************************************************************************** - -// #define USE_WATCHDOG // comment this out if you don't want to use the watchdog - -// ***************************************************************************** - -#include "inc/openpilot.h" -#include - -/* Task Priorities */ -#define PRIORITY_TASK_HOOKS (tskIDLE_PRIORITY + 3) - -/* Global Variables */ - -/* Prototype of PIOS_Board_Init() function */ -extern void PIOS_Board_Init(void); -extern void Stack_Change(void); -static void Stack_Change_Weak() __attribute__((weakref("Stack_Change"))); - - -/* Function Prototypes */ -static void initTask(void *parameters); -/* Local Variables */ -#define INIT_TASK_PRIORITY (tskIDLE_PRIORITY + configMAX_PRIORITIES - 1) // max priority -#define INIT_TASK_STACK (1024 / 4) // XXX this seems excessive -static xTaskHandle initTaskHandle; - -// ***************************************************************************** -// Global Variables - -// ***************************************************************************** -// Local Variables - -#if defined(USE_WATCHDOG) -volatile uint16_t watchdog_timer; -uint16_t watchdog_delay; -#endif - -// ***************************************************************************** - -#if defined(USE_WATCHDOG) - -void processWatchdog(void) -{ - // random32 = UpdateCRC32(random32, IWDG->SR); - - if (watchdog_timer < watchdog_delay) { - return; - } - - // the watchdog needs resetting - - watchdog_timer = 0; - - watchdog_Clear(); -} - -void enableWatchdog(void) -{ // enable a watchdog - watchdog_timer = 0; - watchdog_delay = watchdog_Init(1000); // 1 second watchdog timeout -} - -#endif /* if defined(USE_WATCHDOG) */ - -// ***************************************************************************** - -void sequenceLEDs(void) -{ - for (int i = 0; i < 2; i++) { - // USB_LED_ON; - PIOS_DELAY_WaitmS(100); - // USB_LED_OFF; - PIOS_DELAY_WaitmS(100); - - #if defined(USE_WATCHDOG) - processWatchdog(); // process the watchdog - #endif - } -} - -// ***************************************************************************** -// find out what caused our reset and act on it - -void processReset(void) -{ - if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET) { // Independant Watchdog Reset - #if defined(PIOS_COM_DEBUG_CONSOLE) - DEBUG_PRINTF(0, "\r\nINDEPENDANT WATCHDOG CAUSED A RESET\r\n"); - #endif - - // all led's ON - // USB_LED_ON; - - - PIOS_DELAY_WaitmS(500); // delay a bit - - // all led's OFF - // USB_LED_OFF; - } -/* - if (RCC_GetFlagStatus(RCC_FLAG_WWDGRST) != RESET) - { // Window Watchdog Reset - - DEBUG_PRINTF(0, "\r\nWINDOW WATCHDOG CAUSED A REBOOT\r\n"); - - // all led's ON - USB_LED_ON; - LINK_LED_ON; - RX_LED_ON; - TX_LED_ON; - - PIOS_DELAY_WaitmS(500); // delay a bit - - // all led's OFF - USB_LED_OFF; - LINK_LED_OFF; - RX_LED_OFF; - TX_LED_OFF; - } - */ - if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET) { // Power-On Reset - #if defined(PIOS_COM_DEBUG) - DEBUG_PRINTF(0, "\r\nPOWER-ON-RESET\r\n"); - #endif - } - - if (RCC_GetFlagStatus(RCC_FLAG_SFTRST) != RESET) { // Software Reset - #if defined(PIOS_COM_DEBUG) - DEBUG_PRINTF(0, "\r\nSOFTWARE RESET\r\n"); - #endif - } - - if (RCC_GetFlagStatus(RCC_FLAG_LPWRRST) != RESET) { // Low-Power Reset - #if defined(PIOS_COM_DEBUG) - DEBUG_PRINTF(0, "\r\nLOW POWER RESET\r\n"); - #endif - } - - if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET) { // Pin Reset - #if defined(PIOS_COM_DEBUG) - DEBUG_PRINTF("0, \r\nPIN RESET\r\n"); - #endif - } - - // Clear reset flags - // RCC_ClearFlag(); -} - -int main() -{ - int result; - - // ************* - // init various variables - // ************* - /* NOTE: Do NOT modify the following start-up sequence */ - /* Any new initialization functions should be added in OpenPilotInit() */ - vPortInitialiseBlocks(); - - // Bring up System using CMSIS functions, enables the LEDs. - PIOS_SYS_Init(); - - /* For Revolution we use a FreeRTOS task to bring up the system so we can */ - /* always rely on FreeRTOS primitive */ - result = xTaskCreate(initTask, "init", - INIT_TASK_STACK, NULL, INIT_TASK_PRIORITY, - &initTaskHandle); - PIOS_Assert(result == pdPASS); - - /* Start the FreeRTOS scheduler which should never returns.*/ - vTaskStartScheduler(); - - /* If all is well we will never reach here as the scheduler will now be running. */ - /* Do some indication to user that something bad just happened */ - PIOS_LED_Off(PIOS_LED_HEARTBEAT); \ - for (;;) { \ - PIOS_LED_Toggle(PIOS_LED_HEARTBEAT); \ - PIOS_DELAY_WaitmS(100); \ - } - ; - - return 0; -} - -/** - * Initialisation task. - * - * Runs board and module initialisation, then terminates. - */ -void initTask(__attribute__((unused)) void *parameters) -{ - /* board driver init */ - PIOS_Board_Init(); - - /* Initialize modules */ - MODULE_INITIALISE_ALL; - - /* terminate this task */ - vTaskDelete(NULL); -} - -// ***************************************************************************** diff --git a/flight/targets/boards/osd/firmware/osd.cpp b/flight/targets/boards/osd/firmware/osd.cpp new file mode 100644 index 000000000..417b6d7b2 --- /dev/null +++ b/flight/targets/boards/osd/firmware/osd.cpp @@ -0,0 +1,85 @@ +/** + ****************************************************************************** + * @addtogroup LibrePilotSystem LibrePilot System + * @brief These files are the core system files for Revolution. + * They are the ground layer just above PiOS. In practice, OSD actually starts + * in the main() function of osd.cpp + * @{ + * @addtogroup LibrePilotCore LibrePilot Core + * @brief This is where the LP firmware starts. Those files also define the compile-time + * options of the firmware. + * @{ + * @file osd.c + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2015 + * @brief Sets up and runs main tasks. + * @see The GNU Public License (GPL) Version 3 + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +extern "C" { +#include "inc/openpilot.h" +#include +#include + + +/* Global Variables */ + +/* Local Variables */ +} + +/** + * OpenPilot Main function: + * + * Initialize PiOS
+ * Create the "System" task (SystemModInitializein Modules/System/systemmod.c)
+ * Start FreeRTOS Scheduler (vTaskStartScheduler)
+ * If something goes wrong, blink LED1 and LED2 every 100ms + * + */ +int main() +{ + /* NOTE: Do NOT modify the following start-up sequence */ + /* Any new initialization functions should be added in OpenPilotInit() */ + vPortInitialiseBlocks(); + + /* Brings up System using CMSIS functions, enables the LEDs. */ + PIOS_SYS_Init(); + + SystemModStart(); + + /* Start the FreeRTOS scheduler */ + vTaskStartScheduler(); + + /* If all is well we will never reach here as the scheduler will now be running. */ + /* Do some PIOS_LED_HEARTBEAT to user that something bad just happened */ + PIOS_LED_Off(PIOS_LED_HEARTBEAT); \ + for (;;) { \ + PIOS_LED_Toggle(PIOS_LED_HEARTBEAT); \ + PIOS_DELAY_WaitmS(100); \ + } + ; + + return 0; +} + + +/** + * @} + * @} + */ diff --git a/flight/targets/boards/revolution/board_hw_defs.c b/flight/targets/boards/revolution/board_hw_defs.c index d77666147..74770d980 100644 --- a/flight/targets/boards/revolution/board_hw_defs.c +++ b/flight/targets/boards/revolution/board_hw_defs.c @@ -1,8 +1,9 @@ /** ****************************************************************************** * @file board_hw_defs.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. - * @author PhoenixPilot, http://github.com/PhoenixPilot, Copyright (C) 2012 + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. + * PhoenixPilot, http://github.com/PhoenixPilot, Copyright (C) 2012 * @addtogroup OpenPilotSystem OpenPilot System * @{ * @addtogroup OpenPilotCore OpenPilot Core @@ -674,6 +675,72 @@ const struct pios_rfm22b_cfg *PIOS_BOARD_HW_DEFS_GetRfm22Cfg(uint32_t board_revi #endif /* PIOS_INCLUDE_RFM22B */ +#if defined(PIOS_INCLUDE_OPENLRS) + +#include + +static const struct pios_exti_cfg pios_exti_openlrs_cfg __exti_config = { + .vector = PIOS_OpenLRS_EXT_Int, + .line = EXTI_Line2, + .pin = { + .gpio = GPIOD, + .init = { + .GPIO_Pin = GPIO_Pin_2, + .GPIO_Speed = GPIO_Speed_100MHz, + .GPIO_Mode = GPIO_Mode_IN, + .GPIO_OType = GPIO_OType_OD, + .GPIO_PuPd = GPIO_PuPd_NOPULL, + }, + }, + .irq = { + .init = { + .NVIC_IRQChannel = EXTI2_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_LOW, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .exti = { + .init = { + .EXTI_Line = EXTI_Line2, // matches above GPIO pin + .EXTI_Mode = EXTI_Mode_Interrupt, + .EXTI_Trigger = EXTI_Trigger_Falling, + .EXTI_LineCmd = ENABLE, + }, + }, +}; + +const struct pios_openlrs_cfg pios_openlrs_rm1_cfg = { + .spi_cfg = &pios_spi_telem_flash_cfg, + .exti_cfg = &pios_exti_openlrs_cfg, + .gpio_direction = GPIO0_RX_GPIO1_TX, +}; + +const struct pios_openlrs_cfg pios_openlrs_rm2_cfg = { + .spi_cfg = &pios_spi_telem_flash_cfg, + .exti_cfg = &pios_exti_openlrs_cfg, + .gpio_direction = GPIO0_TX_GPIO1_RX, +}; + +const struct pios_openlrs_cfg *PIOS_BOARD_HW_DEFS_GetOpenLRSCfg(uint32_t board_revision) +{ + switch (board_revision) { + case 2: + return &pios_openlrs_rm1_cfg; + + break; + case 3: + return &pios_openlrs_rm2_cfg; + + break; + default: + PIOS_DEBUG_Assert(0); + } + return NULL; +} + +#endif /* PIOS_INCLUDE_OPENLRS */ + #endif /* PIOS_INCLUDE_SPI */ #if defined(PIOS_INCLUDE_FLASH) @@ -1054,6 +1121,154 @@ static const struct pios_usart_cfg pios_usart_srxl_flexi_cfg = { }; #endif /* PIOS_INCLUDE_SRXL */ + +#if defined(PIOS_INCLUDE_HOTT) +/* + * HOTT USART + */ +#include + +static const struct pios_usart_cfg pios_usart_hott_flexi_cfg = { + .regs = USART3, + .remap = GPIO_AF_USART3, + .init = { + .USART_BaudRate = 115200, + .USART_WordLength = USART_WordLength_8b, + .USART_Parity = USART_Parity_No, + .USART_StopBits = USART_StopBits_1, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + .USART_Mode = USART_Mode_Rx, + }, + .irq = { + .init = { + .NVIC_IRQChannel = USART3_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .rx = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_11, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, + .tx = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_10, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, +}; + +#endif /* PIOS_INCLUDE_HOTT */ + +#if defined(PIOS_INCLUDE_IBUS) +/* + * IBUS USART + */ +#include + +static const struct pios_usart_cfg pios_usart_ibus_flexi_cfg = { + .regs = USART3, + .remap = GPIO_AF_USART3, + .init = { + .USART_BaudRate = 115200, + .USART_WordLength = USART_WordLength_8b, + .USART_Parity = USART_Parity_No, + .USART_StopBits = USART_StopBits_1, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + .USART_Mode = USART_Mode_Rx, + }, + .irq = { + .init = { + .NVIC_IRQChannel = USART3_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .rx = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_11, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, + .tx = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_10, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, +}; + +#endif /* PIOS_INCLUDE_IBUS */ + +#if defined(PIOS_INCLUDE_EXBUS) +/* + * EXBUS USART + */ +#include + +static const struct pios_usart_cfg pios_usart_exbus_flexi_cfg = { + .regs = USART3, + .remap = GPIO_AF_USART3, + .init = { + .USART_BaudRate = 125000, + .USART_WordLength = USART_WordLength_8b, + .USART_Parity = USART_Parity_No, + .USART_StopBits = USART_StopBits_1, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + .USART_Mode = USART_Mode_Rx, + }, + .irq = { + .init = { + .NVIC_IRQChannel = USART3_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .rx = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_11, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, + .tx = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_10, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, +}; + +#endif /* PIOS_INCLUDE_EXBUS */ + /* * HK OSD */ @@ -1309,7 +1524,7 @@ static const struct pios_i2c_adapter_cfg pios_i2c_flexiport_adapter_cfg = { .GPIO_Mode = GPIO_Mode_AF, .GPIO_Speed = GPIO_Speed_50MHz, .GPIO_OType = GPIO_OType_OD, - .GPIO_PuPd = GPIO_PuPd_NOPULL, + .GPIO_PuPd = GPIO_PuPd_UP, }, }, .sda = { @@ -1319,7 +1534,7 @@ static const struct pios_i2c_adapter_cfg pios_i2c_flexiport_adapter_cfg = { .GPIO_Mode = GPIO_Mode_AF, .GPIO_Speed = GPIO_Speed_50MHz, .GPIO_OType = GPIO_OType_OD, - .GPIO_PuPd = GPIO_PuPd_NOPULL, + .GPIO_PuPd = GPIO_PuPd_UP, }, }, .event = { diff --git a/flight/targets/boards/revolution/bootloader/main.c b/flight/targets/boards/revolution/bootloader/main.c index 5c6e08db7..09a54a094 100644 --- a/flight/targets/boards/revolution/bootloader/main.c +++ b/flight/targets/boards/revolution/bootloader/main.c @@ -34,9 +34,8 @@ #include #include /* PIOS_USBHOOK_* */ #include +#include -/* Prototype of PIOS_Board_Init() function */ -extern void PIOS_Board_Init(void); extern void FLASH_Download(); void check_bor(); #define BSL_HOLD_STATE ((PIOS_USB_DETECT_GPIO_PORT->IDR & PIOS_USB_DETECT_GPIO_PIN) ? 0 : 1) diff --git a/flight/targets/boards/revolution/firmware/Makefile b/flight/targets/boards/revolution/firmware/Makefile index 94126c63a..616f45953 100644 --- a/flight/targets/boards/revolution/firmware/Makefile +++ b/flight/targets/boards/revolution/firmware/Makefile @@ -1,7 +1,7 @@ # -# Copyright (c) 2015, The LibrePilot Project, http://www.librepilot.org -# Copyright (c) 2009-2013, The OpenPilot Team, http://www.openpilot.org -# Copyright (c) 2012, PhoenixPilot, http://github.com/PhoenixPilot +# Copyright (C) 2015-2016, The LibrePilot Project, http://www.librepilot.org +# Copyright (C) 2009-2013, The OpenPilot Team, http://www.openpilot.org +# Copyright (C) 2012, PhoenixPilot, http://github.com/PhoenixPilot # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -52,7 +52,10 @@ MODULES += Logging MODULES += Telemetry MODULES += Notify +OPTMODULES += AutoTune OPTMODULES += ComUsbBridge +OPTMODULES += UAVOMSPBridge +OPTMODULES += UAVOMavlinkBridge SRC += $(FLIGHTLIB)/notification.c @@ -95,7 +98,6 @@ ifndef TESTAPP SRC += $(FLIGHTLIB)/auxmagsupport.c SRC += $(FLIGHTLIB)/lednotification.c SRC += $(FLIGHTLIB)/sha1.c - CPPSRC += $(FLIGHTLIB)/mini_cpp.cpp ## UAVObjects include ./UAVObjects.inc diff --git a/flight/targets/boards/revolution/firmware/UAVObjects.inc b/flight/targets/boards/revolution/firmware/UAVObjects.inc index 0b751c1d0..6100c4750 100644 --- a/flight/targets/boards/revolution/firmware/UAVObjects.inc +++ b/flight/targets/boards/revolution/firmware/UAVObjects.inc @@ -1,5 +1,6 @@ # -# Copyright (c) 2009-2013, The OpenPilot Team, http://www.openpilot.org +# Copyright (C) 2016, The LibrePilot Project, http://www.librepilot.org +# Copyright (C) 2009-2013, The OpenPilot Team, http://www.openpilot.org # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -125,6 +126,8 @@ UAVOBJSRCFILENAMES += txpidsettings UAVOBJSRCFILENAMES += txpidstatus UAVOBJSRCFILENAMES += takeofflocation UAVOBJSRCFILENAMES += perfcounter +UAVOBJSRCFILENAMES += systemidentsettings +UAVOBJSRCFILENAMES += systemidentstate UAVOBJSRC = $(foreach UAVOBJSRCFILE,$(UAVOBJSRCFILENAMES),$(FLIGHT_UAVOBJ_DIR)/$(UAVOBJSRCFILE).c ) UAVOBJDEFINE = $(foreach UAVOBJSRCFILE,$(UAVOBJSRCFILENAMES),-DUAVOBJ_INIT_$(UAVOBJSRCFILE) ) diff --git a/flight/targets/boards/revolution/firmware/inc/pios_config.h b/flight/targets/boards/revolution/firmware/inc/pios_config.h index baa1680ba..efe32a4be 100644 --- a/flight/targets/boards/revolution/firmware/inc/pios_config.h +++ b/flight/targets/boards/revolution/firmware/inc/pios_config.h @@ -5,7 +5,8 @@ * @addtogroup OpenPilotCore OpenPilot Core * @{ * @file pios_config.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2013. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2013. * @brief PiOS configuration header, the compile time config file for the PIOS. * Defines which PiOS libraries and features are included in the firmware. * @see The GNU Public License (GPL) Version 3 @@ -104,8 +105,12 @@ #define PIOS_INCLUDE_DSM #define PIOS_INCLUDE_SBUS #define PIOS_INCLUDE_SRXL +#define PIOS_INCLUDE_HOTT +#define PIOS_INCLUDE_EXBUS +#define PIOS_INCLUDE_IBUS #define PIOS_INCLUDE_GCSRCVR #define PIOS_INCLUDE_OPLINKRCVR +#define PIOS_INCLUDE_OPENLRS_RCVR /* PIOS abstract receiver interface */ #define PIOS_INCLUDE_RCVR @@ -130,6 +135,7 @@ /* PIOS radio modules */ #define PIOS_INCLUDE_RFM22B #define PIOS_INCLUDE_RFM22B_COM +#define PIOS_INCLUDE_OPENLRS /* #define PIOS_INCLUDE_PPM_OUT */ /* #define PIOS_RFM22B_DEBUG_ON_TELEM */ @@ -150,6 +156,7 @@ /* #define PIOS_GPS_MINIMAL */ #define PIOS_INCLUDE_GPS_NMEA_PARSER #define PIOS_INCLUDE_GPS_UBX_PARSER +#define PIOS_INCLUDE_GPS_DJI_PARSER #define PIOS_GPS_SETS_HOMELOCATION /* Stabilization options */ @@ -169,7 +176,7 @@ /* Task stack sizes */ /* #define PIOS_ACTUATOR_STACK_SIZE 1020 */ /* #define PIOS_MANUAL_STACK_SIZE 800 */ -/* #define PIOS_SYSTEM_STACK_SIZE 660 */ +#define PIOS_SYSTEM_STACK_SIZE 1536 /* #define PIOS_STABILIZATION_STACK_SIZE 524 */ /* #define PIOS_TELEM_STACK_SIZE 500 */ /* #define PIOS_EVENTDISPATCHER_STACK_SIZE 130 */ diff --git a/flight/targets/boards/revolution/firmware/pios_board.c b/flight/targets/boards/revolution/firmware/pios_board.c index 5bfc0a16c..7f7ddee07 100644 --- a/flight/targets/boards/revolution/firmware/pios_board.c +++ b/flight/targets/boards/revolution/firmware/pios_board.c @@ -1,8 +1,9 @@ /** ****************************************************************************** * @file pios_board.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2011. - * @author PhoenixPilot, http://github.com/PhoenixPilot, Copyright (C) 2012 + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2011. + * PhoenixPilot, http://github.com/PhoenixPilot, Copyright (C) 2012 * @addtogroup OpenPilotSystem OpenPilot System * @{ * @addtogroup OpenPilotCore OpenPilot Core @@ -34,9 +35,11 @@ #include #include #include +#include +#include #include #include - +#include #ifdef PIOS_INCLUDE_INSTRUMENTATION #include @@ -55,12 +58,11 @@ /** * Sensor configurations */ - #if defined(PIOS_INCLUDE_ADC) - #include "pios_adc_priv.h" void PIOS_ADC_DMC_irq_handler(void); void DMA2_Stream4_IRQHandler(void) __attribute__((alias("PIOS_ADC_DMC_irq_handler"))); + struct pios_adc_cfg pios_adc_cfg = { .adc_dev = ADC1, .dma = { @@ -84,22 +86,25 @@ struct pios_adc_cfg pios_adc_cfg = { .half_flag = DMA_IT_HTIF4, .full_flag = DMA_IT_TCIF4, }; + void PIOS_ADC_DMC_irq_handler(void) { /* Call into the generic code to handle the IRQ for this specific device */ PIOS_ADC_DMA_Handler(); } - #endif /* if defined(PIOS_INCLUDE_ADC) */ #if defined(PIOS_INCLUDE_HMC5X83) #include "pios_hmc5x83.h" -pios_hmc5x83_dev_t onboard_mag = 0; +pios_hmc5x83_dev_t onboard_mag = 0; +pios_hmc5x83_dev_t external_mag = 0; +#ifdef PIOS_HMC5X83_HAS_GPIOS bool pios_board_internal_mag_handler() { return PIOS_HMC5x83_IRQHandler(onboard_mag); } + static const struct pios_exti_cfg pios_exti_hmc5x83_cfg __exti_config = { .vector = pios_board_internal_mag_handler, .line = EXTI_Line7, @@ -130,15 +135,32 @@ static const struct pios_exti_cfg pios_exti_hmc5x83_cfg __exti_config = { }, }, }; +#endif /* PIOS_HMC5X83_HAS_GPIOS */ -static const struct pios_hmc5x83_cfg pios_hmc5x83_cfg = { - .exti_cfg = &pios_exti_hmc5x83_cfg, - .M_ODR = PIOS_HMC5x83_ODR_75, - .Meas_Conf = PIOS_HMC5x83_MEASCONF_NORMAL, - .Gain = PIOS_HMC5x83_GAIN_1_9, - .Mode = PIOS_HMC5x83_MODE_CONTINUOUS, - .Driver = &PIOS_HMC5x83_I2C_DRIVER, - .Orientation = PIOS_HMC5X83_ORIENTATION_EAST_NORTH_UP, +static const struct pios_hmc5x83_cfg pios_hmc5x83_internal_cfg = { +#ifdef PIOS_HMC5X83_HAS_GPIOS + .exti_cfg = &pios_exti_hmc5x83_cfg, +#endif + .M_ODR = PIOS_HMC5x83_ODR_75, + .Meas_Conf = PIOS_HMC5x83_MEASCONF_NORMAL, + .Gain = PIOS_HMC5x83_GAIN_1_9, + .Mode = PIOS_HMC5x83_MODE_CONTINUOUS, + .TempCompensation = false, + .Driver = &PIOS_HMC5x83_I2C_DRIVER, + .Orientation = PIOS_HMC5X83_ORIENTATION_EAST_NORTH_UP, +}; + +static const struct pios_hmc5x83_cfg pios_hmc5x83_external_cfg = { +#ifdef PIOS_HMC5X83_HAS_GPIOS + .exti_cfg = NULL, +#endif + .M_ODR = PIOS_HMC5x83_ODR_75, // if you change this for auxmag, change AUX_MAG_SKIP in sensors.c + .Meas_Conf = PIOS_HMC5x83_MEASCONF_NORMAL, + .Gain = PIOS_HMC5x83_GAIN_1_9, + .Mode = PIOS_HMC5x83_MODE_CONTINUOUS, + .TempCompensation = false, + .Driver = &PIOS_HMC5x83_I2C_DRIVER, + .Orientation = PIOS_HMC5X83_ORIENTATION_EAST_NORTH_UP, // ENU for GPSV9, WND for typical I2C mag }; #endif /* PIOS_INCLUDE_HMC5X83 */ @@ -235,6 +257,10 @@ uint32_t pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_NONE]; #define PIOS_COM_HKOSD_RX_BUF_LEN 22 #define PIOS_COM_HKOSD_TX_BUF_LEN 22 +#define PIOS_COM_MSP_TX_BUF_LEN 128 +#define PIOS_COM_MSP_RX_BUF_LEN 64 +#define PIOS_COM_MAVLINK_TX_BUF_LEN 128 + #if defined(PIOS_INCLUDE_DEBUG_CONSOLE) #define PIOS_COM_DEBUGCONSOLE_TX_BUF_LEN 40 uint32_t pios_com_debug_id; @@ -247,8 +273,9 @@ uint32_t pios_com_rf_id = 0; uint32_t pios_com_bridge_id = 0; uint32_t pios_com_overo_id = 0; uint32_t pios_com_hkosd_id = 0; - uint32_t pios_com_vcp_id = 0; +uint32_t pios_com_msp_id = 0; +uint32_t pios_com_mavlink_id = 0; #if defined(PIOS_INCLUDE_RFM22B) uint32_t pios_rfm22b_id = 0; @@ -258,9 +285,12 @@ uintptr_t pios_uavo_settings_fs_id; uintptr_t pios_user_fs_id; /* - * Setup a com port based on the passed cfg, driver and buffer sizes. tx size of -1 make the port rx only + * Setup a com port based on the passed cfg, driver and buffer sizes. + * tx size = 0 make the port rx only + * rx size = 0 make the port tx only + * having both tx and rx size = 0 is not valid and will fail further down in PIOS_COM_Init() */ -static void PIOS_Board_configure_com(const struct pios_usart_cfg *usart_port_cfg, size_t rx_buf_len, size_t tx_buf_len, +static void PIOS_Board_configure_com(const struct pios_usart_cfg *usart_port_cfg, uint16_t rx_buf_len, uint16_t tx_buf_len, const struct pios_com_driver *com_driver, uint32_t *pios_com_id) { uint32_t pios_usart_id; @@ -269,23 +299,22 @@ static void PIOS_Board_configure_com(const struct pios_usart_cfg *usart_port_cfg PIOS_Assert(0); } - uint8_t *rx_buffer = (uint8_t *)pios_malloc(rx_buf_len); - PIOS_Assert(rx_buffer); - if (tx_buf_len != (size_t)-1) { // this is the case for rx/tx ports - uint8_t *tx_buffer = (uint8_t *)pios_malloc(tx_buf_len); - PIOS_Assert(tx_buffer); + uint8_t *rx_buffer = 0, *tx_buffer = 0; - if (PIOS_COM_Init(pios_com_id, com_driver, pios_usart_id, - rx_buffer, rx_buf_len, - tx_buffer, tx_buf_len)) { - PIOS_Assert(0); - } - } else { // rx only port - if (PIOS_COM_Init(pios_com_id, com_driver, pios_usart_id, - rx_buffer, rx_buf_len, - NULL, 0)) { - PIOS_Assert(0); - } + if (rx_buf_len > 0) { + rx_buffer = (uint8_t *)pios_malloc(rx_buf_len); + PIOS_Assert(rx_buffer); + } + + if (tx_buf_len > 0) { + tx_buffer = (uint8_t *)pios_malloc(tx_buf_len); + PIOS_Assert(tx_buffer); + } + + if (PIOS_COM_Init(pios_com_id, com_driver, pios_usart_id, + rx_buffer, rx_buf_len, + tx_buffer, tx_buf_len)) { + PIOS_Assert(0); } } @@ -312,6 +341,27 @@ static void PIOS_Board_configure_dsm(const struct pios_usart_cfg *pios_usart_dsm pios_rcvr_group_map[channelgroup] = pios_dsm_rcvr_id; } +static void PIOS_Board_configure_ibus(const struct pios_usart_cfg *usart_cfg) +{ + uint32_t pios_usart_ibus_id; + + if (PIOS_USART_Init(&pios_usart_ibus_id, usart_cfg)) { + PIOS_Assert(0); + } + + uint32_t pios_ibus_id; + if (PIOS_IBUS_Init(&pios_ibus_id, &pios_usart_com_driver, pios_usart_ibus_id)) { + PIOS_Assert(0); + } + + uint32_t pios_ibus_rcvr_id; + if (PIOS_RCVR_Init(&pios_ibus_rcvr_id, &pios_ibus_rcvr_driver, pios_ibus_id)) { + PIOS_Assert(0); + } + + pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_IBUS] = pios_ibus_rcvr_id; +} + static void PIOS_Board_configure_pwm(const struct pios_pwm_cfg *pwm_cfg) { /* Set up the receiver port. Later this should be optional */ @@ -341,11 +391,10 @@ static void PIOS_Board_configure_ppm(const struct pios_ppm_cfg *ppm_cfg) static void PIOS_Board_PPM_callback(const int16_t *channels) { - uint8_t max_chan = (RFM22B_PPM_NUM_CHANNELS < OPLINKRECEIVER_CHANNEL_NUMELEM) ? RFM22B_PPM_NUM_CHANNELS : OPLINKRECEIVER_CHANNEL_NUMELEM; OPLinkReceiverData opl_rcvr; - for (uint8_t i = 0; i < max_chan; ++i) { - opl_rcvr.Channel[i] = channels[i]; + for (uint8_t i = 0; i < OPLINKRECEIVER_CHANNEL_NUMELEM; ++i) { + opl_rcvr.Channel[i] = (i < RFM22B_PPM_NUM_CHANNELS) ? channels[i] : PIOS_RCVR_TIMEOUT; } OPLinkReceiverSet(&opl_rcvr); } @@ -368,7 +417,6 @@ void PIOS_Board_Init(void) PIOS_LED_Init(led_cfg); #endif /* PIOS_INCLUDE_LED */ - #ifdef PIOS_INCLUDE_INSTRUMENTATION PIOS_Instrumentation_Init(PIOS_INSTRUMENTATION_MAX_COUNTERS); #endif @@ -400,6 +448,7 @@ void PIOS_Board_Init(void) #if defined(PIOS_INCLUDE_RTC) PIOS_RTC_Init(&pios_rtc_main_cfg); #endif + /* IAP System Setup */ PIOS_IAP_Init(); // check for safe mode commands from gcs @@ -411,6 +460,7 @@ void PIOS_Board_Init(void) PIOS_IAP_WriteBootCmd(1, 0); PIOS_IAP_WriteBootCmd(2, 0); } + #ifdef PIOS_INCLUDE_WDG PIOS_WDG_Init(); #endif @@ -471,11 +521,40 @@ void PIOS_Board_Init(void) break; case HWSETTINGS_RM_FLEXIPORT_I2C: #if defined(PIOS_INCLUDE_I2C) - { - if (PIOS_I2C_Init(&pios_i2c_flexiport_adapter_id, &pios_i2c_flexiport_adapter_cfg)) { - PIOS_Assert(0); - } + if (PIOS_I2C_Init(&pios_i2c_flexiport_adapter_id, &pios_i2c_flexiport_adapter_cfg)) { + PIOS_Assert(0); } + PIOS_DELAY_WaitmS(50); // this was after the other PIOS_I2C_Init(), so I copied it here too +#ifdef PIOS_INCLUDE_WDG + // give HMC5x83 on I2C some extra time to allow for reset, etc. if needed + // this is not in a loop, so it is safe + // leave this here even if PIOS_INCLUDE_HMC5X83 is undefined + // to avoid making something else fail when HMC5X83 is removed + PIOS_WDG_Clear(); +#endif /* PIOS_INCLUDE_WDG */ +#if defined(PIOS_INCLUDE_HMC5X83) + // get auxmag type + AuxMagSettingsTypeOptions option; + AuxMagSettingsInitialize(); + AuxMagSettingsTypeGet(&option); + // if the aux mag type is FlexiPort then set it up + if (option == AUXMAGSETTINGS_TYPE_FLEXI) { + // attach the 5x83 mag to the previously inited I2C2 + external_mag = PIOS_HMC5x83_Init(&pios_hmc5x83_external_cfg, pios_i2c_flexiport_adapter_id, 0); +#ifdef PIOS_INCLUDE_WDG + // give HMC5x83 on I2C some extra time to allow for reset, etc. if needed + // this is not in a loop, so it is safe + PIOS_WDG_Clear(); +#endif /* PIOS_INCLUDE_WDG */ + // add this sensor to the sensor task's list + // be careful that you don't register a slow, unimportant sensor after registering the fastest sensor + // and before registering some other fast and important sensor + // as that would cause delay and time jitter for the second fast sensor + PIOS_HMC5x83_Register(external_mag, PIOS_SENSORS_TYPE_3AXIS_AUXMAG); + // mag alarm is cleared later, so use I2C + AlarmsSet(SYSTEMALARMS_ALARM_I2C, (external_mag) ? SYSTEMALARMS_ALARM_OK : SYSTEMALARMS_ALARM_WARNING); + } +#endif /* PIOS_INCLUDE_HMC5X83 */ #endif /* PIOS_INCLUDE_I2C */ break; case HWSETTINGS_RM_FLEXIPORT_GPS: @@ -489,16 +568,23 @@ void PIOS_Board_Init(void) case HWSETTINGS_RM_FLEXIPORT_DEBUGCONSOLE: #if defined(PIOS_INCLUDE_DEBUG_CONSOLE) { - PIOS_Board_configure_com(&pios_usart_main_cfg, 0, PIOS_COM_DEBUGCONSOLE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_debug_id); + PIOS_Board_configure_com(&pios_usart_flexi_cfg, 0, PIOS_COM_DEBUGCONSOLE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_debug_id); } #endif /* PIOS_INCLUDE_DEBUG_CONSOLE */ break; case HWSETTINGS_RM_FLEXIPORT_COMBRIDGE: PIOS_Board_configure_com(&pios_usart_flexi_cfg, PIOS_COM_BRIDGE_RX_BUF_LEN, PIOS_COM_BRIDGE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_bridge_id); break; + case HWSETTINGS_RM_FLEXIPORT_MSP: + PIOS_Board_configure_com(&pios_usart_flexi_cfg, PIOS_COM_MSP_RX_BUF_LEN, PIOS_COM_MSP_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_msp_id); + break; + case HWSETTINGS_RM_FLEXIPORT_MAVLINK: + PIOS_Board_configure_com(&pios_usart_flexi_cfg, 0, PIOS_COM_MAVLINK_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_mavlink_id); + break; case HWSETTINGS_RM_FLEXIPORT_OSDHK: PIOS_Board_configure_com(&pios_usart_hkosd_flexi_cfg, PIOS_COM_HKOSD_RX_BUF_LEN, PIOS_COM_HKOSD_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_hkosd_id); break; + case HWSETTINGS_RM_FLEXIPORT_SRXL: #if defined(PIOS_INCLUDE_SRXL) { @@ -518,7 +604,59 @@ void PIOS_Board_Init(void) } pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_SRXL] = pios_srxl_rcvr_id; } -#endif +#endif /* PIOS_INCLUDE_SRXL */ + break; + + case HWSETTINGS_RM_FLEXIPORT_IBUS: +#if defined(PIOS_INCLUDE_IBUS) + PIOS_Board_configure_ibus(&pios_usart_ibus_flexi_cfg); +#endif /* PIOS_INCLUDE_IBUS */ + break; + + case HWSETTINGS_RM_FLEXIPORT_HOTTSUMD: + case HWSETTINGS_RM_FLEXIPORT_HOTTSUMH: +#if defined(PIOS_INCLUDE_HOTT) + { + uint32_t pios_usart_hott_id; + if (PIOS_USART_Init(&pios_usart_hott_id, &pios_usart_hott_flexi_cfg)) { + PIOS_Assert(0); + } + + uint32_t pios_hott_id; + if (PIOS_HOTT_Init(&pios_hott_id, &pios_usart_com_driver, pios_usart_hott_id, + hwsettings_flexiport == HWSETTINGS_RM_FLEXIPORT_HOTTSUMD ? PIOS_HOTT_PROTO_SUMD : PIOS_HOTT_PROTO_SUMH)) { + PIOS_Assert(0); + } + + uint32_t pios_hott_rcvr_id; + if (PIOS_RCVR_Init(&pios_hott_rcvr_id, &pios_hott_rcvr_driver, pios_hott_id)) { + PIOS_Assert(0); + } + pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_HOTT] = pios_hott_rcvr_id; + } +#endif /* PIOS_INCLUDE_HOTT */ + break; + + case HWSETTINGS_RM_FLEXIPORT_EXBUS: +#if defined(PIOS_INCLUDE_EXBUS) + { + uint32_t pios_usart_exbus_id; + if (PIOS_USART_Init(&pios_usart_exbus_id, &pios_usart_exbus_flexi_cfg)) { + PIOS_Assert(0); + } + + uint32_t pios_exbus_id; + if (PIOS_EXBUS_Init(&pios_exbus_id, &pios_usart_com_driver, pios_usart_exbus_id)) { + PIOS_Assert(0); + } + + uint32_t pios_exbus_rcvr_id; + if (PIOS_RCVR_Init(&pios_exbus_rcvr_id, &pios_exbus_rcvr_driver, pios_exbus_id)) { + PIOS_Assert(0); + } + pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_EXBUS] = pios_exbus_rcvr_id; + } +#endif /* PIOS_INCLUDE_EXBUS */ break; } /* hwsettings_rm_flexiport */ @@ -662,7 +800,6 @@ void PIOS_Board_Init(void) } #endif /* PIOS_INCLUDE_USB */ - /* Configure main USART port */ uint8_t hwsettings_mainport; HwSettingsRM_MainPortGet(&hwsettings_mainport); @@ -714,6 +851,12 @@ void PIOS_Board_Init(void) case HWSETTINGS_RM_MAINPORT_COMBRIDGE: PIOS_Board_configure_com(&pios_usart_main_cfg, PIOS_COM_BRIDGE_RX_BUF_LEN, PIOS_COM_BRIDGE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_bridge_id); break; + case HWSETTINGS_RM_MAINPORT_MSP: + PIOS_Board_configure_com(&pios_usart_main_cfg, PIOS_COM_MSP_RX_BUF_LEN, PIOS_COM_MSP_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_msp_id); + break; + case HWSETTINGS_RM_MAINPORT_MAVLINK: + PIOS_Board_configure_com(&pios_usart_main_cfg, 0, PIOS_COM_MAVLINK_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_mavlink_id); + break; case HWSETTINGS_RM_MAINPORT_OSDHK: PIOS_Board_configure_com(&pios_usart_hkosd_main_cfg, PIOS_COM_HKOSD_RX_BUF_LEN, PIOS_COM_HKOSD_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_hkosd_id); break; @@ -724,7 +867,6 @@ void PIOS_Board_Init(void) GPIO_WriteBit(pios_sbus_cfg.inv.gpio, pios_sbus_cfg.inv.init.GPIO_Pin, pios_sbus_cfg.gpio_inv_disable); } - /* Initalize the RFM22B radio COM device. */ #if defined(PIOS_INCLUDE_RFM22B) @@ -741,95 +883,119 @@ void PIOS_Board_Init(void) oplinkStatus.BoardRevision = bdinfo->board_rev; /* Is the radio turned on? */ - bool is_coordinator = (oplinkSettings.Coordinator == OPLINKSETTINGS_COORDINATOR_TRUE); - bool is_oneway = (oplinkSettings.OneWay == OPLINKSETTINGS_ONEWAY_TRUE); - bool ppm_mode = (oplinkSettings.PPM == OPLINKSETTINGS_PPM_TRUE); - bool ppm_only = (oplinkSettings.PPMOnly == OPLINKSETTINGS_PPMONLY_TRUE); - if (oplinkSettings.MaxRFPower != OPLINKSETTINGS_MAXRFPOWER_0) { - /* Configure the RFM22B device. */ - const struct pios_rfm22b_cfg *rfm22b_cfg = PIOS_BOARD_HW_DEFS_GetRfm22Cfg(bdinfo->board_rev); - if (PIOS_RFM22B_Init(&pios_rfm22b_id, PIOS_RFM22_SPI_PORT, rfm22b_cfg->slave_num, rfm22b_cfg)) { - PIOS_Assert(0); + bool is_coordinator = (oplinkSettings.Protocol == OPLINKSETTINGS_PROTOCOL_OPLINKCOORDINATOR); + bool openlrs = (oplinkSettings.Protocol == OPLINKSETTINGS_PROTOCOL_OPENLRS); + bool data_mode = ((oplinkSettings.LinkType == OPLINKSETTINGS_LINKTYPE_DATA) || + (oplinkSettings.LinkType == OPLINKSETTINGS_LINKTYPE_DATAANDCONTROL)); + bool ppm_mode = ((oplinkSettings.LinkType == OPLINKSETTINGS_LINKTYPE_CONTROL) || + (oplinkSettings.LinkType == OPLINKSETTINGS_LINKTYPE_DATAANDCONTROL)); + bool ppm_only = (oplinkSettings.LinkType == OPLINKSETTINGS_LINKTYPE_CONTROL); + bool is_enabled = ((oplinkSettings.Protocol != OPLINKSETTINGS_PROTOCOL_DISABLED) && + ((oplinkSettings.MaxRFPower != OPLINKSETTINGS_MAXRFPOWER_0) || openlrs)); + if (is_enabled) { + if (openlrs) { +#if defined(PIOS_INCLUDE_OPENLRS_RCVR) + const struct pios_openlrs_cfg *openlrs_cfg = PIOS_BOARD_HW_DEFS_GetOpenLRSCfg(bdinfo->board_rev); + uint32_t openlrs_id; + + PIOS_OpenLRS_Init(&openlrs_id, PIOS_RFM22_SPI_PORT, 0, openlrs_cfg); + { + uint32_t openlrsrcvr_id; + PIOS_OpenLRS_Rcvr_Init(&openlrsrcvr_id, openlrs_id); + uint32_t openlrsrcvr_rcvr_id; + if (PIOS_RCVR_Init(&openlrsrcvr_rcvr_id, &pios_openlrs_rcvr_driver, openlrsrcvr_id)) { + PIOS_Assert(0); + } + pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_OPENLRS] = openlrsrcvr_rcvr_id; + } +#endif /* PIOS_INCLUDE_OPENLRS_RCVR */ + } else { + /* Configure the RFM22B device. */ + const struct pios_rfm22b_cfg *rfm22b_cfg = PIOS_BOARD_HW_DEFS_GetRfm22Cfg(bdinfo->board_rev); + if (PIOS_RFM22B_Init(&pios_rfm22b_id, PIOS_RFM22_SPI_PORT, rfm22b_cfg->slave_num, rfm22b_cfg)) { + PIOS_Assert(0); + } + + /* Configure the radio com interface */ + uint8_t *rx_buffer = (uint8_t *)pios_malloc(PIOS_COM_RFM22B_RF_RX_BUF_LEN); + uint8_t *tx_buffer = (uint8_t *)pios_malloc(PIOS_COM_RFM22B_RF_TX_BUF_LEN); + PIOS_Assert(rx_buffer); + PIOS_Assert(tx_buffer); + if (PIOS_COM_Init(&pios_com_rf_id, &pios_rfm22b_com_driver, pios_rfm22b_id, + rx_buffer, PIOS_COM_RFM22B_RF_RX_BUF_LEN, + tx_buffer, PIOS_COM_RFM22B_RF_TX_BUF_LEN)) { + PIOS_Assert(0); + } + + oplinkStatus.LinkState = OPLINKSTATUS_LINKSTATE_ENABLED; + + // Set the RF data rate on the modem to ~2X the selected buad rate because the modem is half duplex. + enum rfm22b_datarate datarate = RFM22_datarate_64000; + switch (oplinkSettings.ComSpeed) { + case OPLINKSETTINGS_COMSPEED_4800: + datarate = RFM22_datarate_9600; + break; + case OPLINKSETTINGS_COMSPEED_9600: + datarate = RFM22_datarate_19200; + break; + case OPLINKSETTINGS_COMSPEED_19200: + datarate = RFM22_datarate_32000; + break; + case OPLINKSETTINGS_COMSPEED_38400: + datarate = RFM22_datarate_64000; + break; + case OPLINKSETTINGS_COMSPEED_57600: + datarate = RFM22_datarate_100000; + break; + case OPLINKSETTINGS_COMSPEED_115200: + datarate = RFM22_datarate_192000; + break; + } + + /* Set the radio configuration parameters. */ + PIOS_RFM22B_SetDeviceID(pios_rfm22b_id, oplinkSettings.CustomDeviceID); + PIOS_RFM22B_SetCoordinatorID(pios_rfm22b_id, oplinkSettings.CoordID); + PIOS_RFM22B_SetChannelConfig(pios_rfm22b_id, datarate, oplinkSettings.MinChannel, oplinkSettings.MaxChannel, is_coordinator, data_mode, ppm_mode); + + /* Set the PPM callback if we should be receiving PPM. */ + if (ppm_mode || (ppm_only && !is_coordinator)) { + PIOS_RFM22B_SetPPMCallback(pios_rfm22b_id, PIOS_Board_PPM_callback); + } + + /* Set the modem Tx power level */ + switch (oplinkSettings.MaxRFPower) { + case OPLINKSETTINGS_MAXRFPOWER_125: + PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_0); + break; + case OPLINKSETTINGS_MAXRFPOWER_16: + PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_1); + break; + case OPLINKSETTINGS_MAXRFPOWER_316: + PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_2); + break; + case OPLINKSETTINGS_MAXRFPOWER_63: + PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_3); + break; + case OPLINKSETTINGS_MAXRFPOWER_126: + PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_4); + break; + case OPLINKSETTINGS_MAXRFPOWER_25: + PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_5); + break; + case OPLINKSETTINGS_MAXRFPOWER_50: + PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_6); + break; + case OPLINKSETTINGS_MAXRFPOWER_100: + PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_7); + break; + default: + // do nothing + break; + } + + /* Reinitialize the modem. */ + PIOS_RFM22B_Reinit(pios_rfm22b_id); } - - /* Configure the radio com interface */ - uint8_t *rx_buffer = (uint8_t *)pios_malloc(PIOS_COM_RFM22B_RF_RX_BUF_LEN); - uint8_t *tx_buffer = (uint8_t *)pios_malloc(PIOS_COM_RFM22B_RF_TX_BUF_LEN); - PIOS_Assert(rx_buffer); - PIOS_Assert(tx_buffer); - if (PIOS_COM_Init(&pios_com_rf_id, &pios_rfm22b_com_driver, pios_rfm22b_id, - rx_buffer, PIOS_COM_RFM22B_RF_RX_BUF_LEN, - tx_buffer, PIOS_COM_RFM22B_RF_TX_BUF_LEN)) { - PIOS_Assert(0); - } - - oplinkStatus.LinkState = OPLINKSTATUS_LINKSTATE_ENABLED; - - // Set the RF data rate on the modem to ~2X the selected buad rate because the modem is half duplex. - enum rfm22b_datarate datarate = RFM22_datarate_64000; - switch (oplinkSettings.ComSpeed) { - case OPLINKSETTINGS_COMSPEED_4800: - datarate = RFM22_datarate_9600; - break; - case OPLINKSETTINGS_COMSPEED_9600: - datarate = RFM22_datarate_19200; - break; - case OPLINKSETTINGS_COMSPEED_19200: - datarate = RFM22_datarate_32000; - break; - case OPLINKSETTINGS_COMSPEED_38400: - datarate = RFM22_datarate_64000; - break; - case OPLINKSETTINGS_COMSPEED_57600: - datarate = RFM22_datarate_100000; - break; - case OPLINKSETTINGS_COMSPEED_115200: - datarate = RFM22_datarate_192000; - break; - } - - /* Set the radio configuration parameters. */ - 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 || (ppm_only && !is_coordinator)) { - PIOS_RFM22B_SetPPMCallback(pios_rfm22b_id, PIOS_Board_PPM_callback); - } - - /* Set the modem Tx poer level */ - switch (oplinkSettings.MaxRFPower) { - case OPLINKSETTINGS_MAXRFPOWER_125: - PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_0); - break; - case OPLINKSETTINGS_MAXRFPOWER_16: - PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_1); - break; - case OPLINKSETTINGS_MAXRFPOWER_316: - PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_2); - break; - case OPLINKSETTINGS_MAXRFPOWER_63: - PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_3); - break; - case OPLINKSETTINGS_MAXRFPOWER_126: - PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_4); - break; - case OPLINKSETTINGS_MAXRFPOWER_25: - PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_5); - break; - case OPLINKSETTINGS_MAXRFPOWER_50: - PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_6); - break; - case OPLINKSETTINGS_MAXRFPOWER_100: - PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_7); - break; - default: - // do nothing - break; - } - - /* Reinitialize the modem. */ - PIOS_RFM22B_Reinit(pios_rfm22b_id); } else { oplinkStatus.LinkState = OPLINKSTATUS_LINKSTATE_DISABLED; } @@ -837,8 +1003,7 @@ void PIOS_Board_Init(void) OPLinkStatusSet(&oplinkStatus); #endif /* PIOS_INCLUDE_RFM22B */ -#if defined(PIOS_INCLUDE_PWM) || defined(PIOS_INCLUDE_PWM) - +#if defined(PIOS_INCLUDE_PWM) || defined(PIOS_INCLUDE_PPM) const struct pios_servo_cfg *pios_servo_cfg; // default to servo outputs only pios_servo_cfg = &pios_servo_cfg_out; @@ -847,10 +1012,9 @@ void PIOS_Board_Init(void) /* Configure the receiver port*/ uint8_t hwsettings_rcvrport; HwSettingsRM_RcvrPortGet(&hwsettings_rcvrport); - // + + // Configure rcvrport PPM/PWM/OUTPUTS switch (hwsettings_rcvrport) { - case HWSETTINGS_RM_RCVRPORT_DISABLED: - break; case HWSETTINGS_RM_RCVRPORT_PWM: #if defined(PIOS_INCLUDE_PWM) /* Set up the receiver port. Later this should be optional */ @@ -861,6 +1025,11 @@ void PIOS_Board_Init(void) case HWSETTINGS_RM_RCVRPORT_PPMOUTPUTS: case HWSETTINGS_RM_RCVRPORT_PPMPWM: case HWSETTINGS_RM_RCVRPORT_PPMTELEMETRY: + case HWSETTINGS_RM_RCVRPORT_PPMDEBUGCONSOLE: + case HWSETTINGS_RM_RCVRPORT_PPMCOMBRIDGE: + case HWSETTINGS_RM_RCVRPORT_PPMMSP: + case HWSETTINGS_RM_RCVRPORT_PPMMAVLINK: + case HWSETTINGS_RM_RCVRPORT_PPMGPS: #if defined(PIOS_INCLUDE_PPM) PIOS_Board_configure_ppm(&pios_ppm_cfg); @@ -874,22 +1043,42 @@ void PIOS_Board_Init(void) PIOS_Board_configure_pwm(&pios_pwm_ppm_cfg); } - if (hwsettings_rcvrport == HWSETTINGS_RM_RCVRPORT_PPMTELEMETRY) { - PIOS_Board_configure_com(&pios_usart_rcvrport_cfg, PIOS_COM_TELEM_RF_RX_BUF_LEN, PIOS_COM_TELEM_RF_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_telem_rf_id); - } - break; #endif /* PIOS_INCLUDE_PPM */ case HWSETTINGS_RM_RCVRPORT_OUTPUTS: // configure only the servo outputs pios_servo_cfg = &pios_servo_cfg_out_in; break; + } + + // Configure rcvrport usart + switch (hwsettings_rcvrport) { case HWSETTINGS_RM_RCVRPORT_TELEMETRY: + case HWSETTINGS_RM_RCVRPORT_PPMTELEMETRY: PIOS_Board_configure_com(&pios_usart_rcvrport_cfg, PIOS_COM_TELEM_RF_RX_BUF_LEN, PIOS_COM_TELEM_RF_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_telem_rf_id); break; + case HWSETTINGS_RM_RCVRPORT_DEBUGCONSOLE: + case HWSETTINGS_RM_RCVRPORT_PPMDEBUGCONSOLE: +#if defined(PIOS_INCLUDE_DEBUG_CONSOLE) + PIOS_Board_configure_com(&pios_usart_rcvrport_cfg, 0, PIOS_COM_DEBUGCONSOLE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_debug_id); +#endif /* PIOS_INCLUDE_DEBUG_CONSOLE */ + break; case HWSETTINGS_RM_RCVRPORT_COMBRIDGE: + case HWSETTINGS_RM_RCVRPORT_PPMCOMBRIDGE: PIOS_Board_configure_com(&pios_usart_rcvrport_cfg, PIOS_COM_BRIDGE_RX_BUF_LEN, PIOS_COM_BRIDGE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_bridge_id); break; + case HWSETTINGS_RM_RCVRPORT_MSP: + case HWSETTINGS_RM_RCVRPORT_PPMMSP: + PIOS_Board_configure_com(&pios_usart_rcvrport_cfg, PIOS_COM_MSP_RX_BUF_LEN, PIOS_COM_MSP_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_msp_id); + break; + case HWSETTINGS_RM_RCVRPORT_MAVLINK: + case HWSETTINGS_RM_RCVRPORT_PPMMAVLINK: + PIOS_Board_configure_com(&pios_usart_rcvrport_cfg, 0, PIOS_COM_MAVLINK_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_mavlink_id); + break; + case HWSETTINGS_RM_RCVRPORT_GPS: + case HWSETTINGS_RM_RCVRPORT_PPMGPS: + PIOS_Board_configure_com(&pios_usart_rcvrport_cfg, PIOS_COM_GPS_RX_BUF_LEN, PIOS_COM_GPS_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_gps_id); + break; } #if defined(PIOS_INCLUDE_GCSRCVR) @@ -933,10 +1122,10 @@ void PIOS_Board_Init(void) }; GPIO_Init(GPIOA, &gpioA8); + // init I2C1 for use with the internal mag and baro if (PIOS_I2C_Init(&pios_i2c_mag_pressure_adapter_id, &pios_i2c_mag_pressure_adapter_cfg)) { PIOS_DEBUG_Assert(0); } - PIOS_DELAY_WaitmS(50); #if defined(PIOS_INCLUDE_ADC) @@ -949,9 +1138,24 @@ void PIOS_Board_Init(void) PIOS_MPU6000_Register(); #endif +#ifdef PIOS_INCLUDE_WDG + // give HMC5x83 on I2C some extra time to allow for reset, etc. if needed + // this is not in a loop, so it is safe + // leave this here even if PIOS_INCLUDE_HMC5X83 is undefined + // to avoid making something else fail when HMC5X83 is removed + PIOS_WDG_Clear(); +#endif /* PIOS_INCLUDE_WDG */ + #if defined(PIOS_INCLUDE_HMC5X83) - onboard_mag = PIOS_HMC5x83_Init(&pios_hmc5x83_cfg, pios_i2c_mag_pressure_adapter_id, 0); - PIOS_HMC5x83_Register(onboard_mag); + // attach the 5x83 mag to the previously inited I2C1 + onboard_mag = PIOS_HMC5x83_Init(&pios_hmc5x83_internal_cfg, pios_i2c_mag_pressure_adapter_id, 0); +#ifdef PIOS_INCLUDE_WDG + // give HMC5x83 on I2C some extra time to allow for reset, etc. if needed + // this is not in a loop, so it is safe + PIOS_WDG_Clear(); +#endif /* PIOS_INCLUDE_WDG */ + // add this sensor to the sensor task's list + PIOS_HMC5x83_Register(onboard_mag, PIOS_SENSORS_TYPE_3AXIS_MAG); #endif #if defined(PIOS_INCLUDE_MS5611) @@ -979,6 +1183,8 @@ void PIOS_Board_Init(void) } } #endif // PIOS_INCLUDE_ADC + + DEBUG_PRINTF(2, "Board complete\r\n"); } /** diff --git a/flight/targets/boards/revolution/firmware/revolution.cpp b/flight/targets/boards/revolution/firmware/revolution.cpp index 268325b26..8c5bbf28c 100644 --- a/flight/targets/boards/revolution/firmware/revolution.cpp +++ b/flight/targets/boards/revolution/firmware/revolution.cpp @@ -1,17 +1,18 @@ /** ****************************************************************************** - * @addtogroup OpenPilotSystem OpenPilot System - * @brief These files are the core system files of OpenPilot. - * They are the ground layer just above PiOS. In practice, OpenPilot actually starts - * in the main() function of openpilot.c + * @addtogroup LibrePilotSystem LibrePilot System + * @brief These files are the core system files for Revolution. + * They are the ground layer just above PiOS. In practice, Revolution actually starts + * in the main() function of revolution.cpp * @{ - * @addtogroup OpenPilotCore OpenPilot Core - * @brief This is where the OP firmware starts. Those files also define the compile-time + * @addtogroup LibrePilotCore LibrePilot Core + * @brief This is where the LP firmware starts. Those files also define the compile-time * options of the firmware. * @{ - * @file openpilot.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @brief Sets up and runs main OpenPilot tasks. + * @file revolution.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2015 + * @brief Sets up and runs main tasks. * @see The GNU Public License (GPL) Version 3 * *****************************************************************************/ @@ -34,46 +35,12 @@ extern "C" { #include "inc/openpilot.h" #include +#include -/* Task Priorities */ -#define PRIORITY_TASK_HOOKS (tskIDLE_PRIORITY + 3) /* Global Variables */ /* Local Variables */ -#define INCLUDE_TEST_TASKS 0 -#if INCLUDE_TEST_TASKS -static uint8_t sdcard_available; -#endif -char Buffer[1024]; -uint32_t Cache; - -/* Function Prototypes */ -#if INCLUDE_TEST_TASKS -static void TaskTick(void *pvParameters); -static void TaskTesting(void *pvParameters); -static void TaskHIDTest(void *pvParameters); -static void TaskServos(void *pvParameters); -static void TaskSDCard(void *pvParameters); -#endif -int32_t CONSOLE_Parse(uint8_t port, char c); -void OP_ADC_NotifyChange(uint32_t pin, uint32_t pin_value); - -/* Prototype of PIOS_Board_Init() function */ -extern void PIOS_Board_Init(void); -extern void Stack_Change(void); -static void Stack_Change_Weak() __attribute__((weakref("Stack_Change"))); - -/* Local Variables */ -#define INIT_TASK_PRIORITY (tskIDLE_PRIORITY + configMAX_PRIORITIES - 1) // max priority -#define INIT_TASK_STACK (1024 / 4) // XXX this seems excessive -static xTaskHandle initTaskHandle; - -/* Function Prototypes */ -static void initTask(void *parameters); - -/* Prototype of generated InitModules() function */ -extern void InitModules(void); } /** @@ -87,8 +54,6 @@ extern void InitModules(void); */ int main() { - int result; - /* NOTE: Do NOT modify the following start-up sequence */ /* Any new initialization functions should be added in OpenPilotInit() */ vPortInitialiseBlocks(); @@ -96,12 +61,7 @@ int main() /* Brings up System using CMSIS functions, enables the LEDs. */ PIOS_SYS_Init(); - /* For Revolution we use a FreeRTOS task to bring up the system so we can */ - /* always rely on FreeRTOS primitive */ - result = xTaskCreate(initTask, "init", - INIT_TASK_STACK, NULL, INIT_TASK_PRIORITY, - &initTaskHandle); - PIOS_Assert(result == pdPASS); + SystemModStart(); /* Start the FreeRTOS scheduler */ vTaskStartScheduler(); @@ -117,22 +77,7 @@ int main() return 0; } -/** - * Initialisation task. - * - * Runs board and module initialisation, then terminates. - */ -void initTask(__attribute__((unused)) void *parameters) -{ - /* board driver init */ - PIOS_Board_Init(); - /* Initialize modules */ - MODULE_INITIALISE_ALL; - - /* terminate this task */ - vTaskDelete(NULL); -} /** * @} diff --git a/flight/targets/boards/revolution/pios_board.h b/flight/targets/boards/revolution/pios_board.h index ff723d419..a97fdbd67 100644 --- a/flight/targets/boards/revolution/pios_board.h +++ b/flight/targets/boards/revolution/pios_board.h @@ -5,7 +5,8 @@ * @addtogroup OpenPilotCore OpenPilot Core * @{ * @file pios_board.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. * @brief Defines board hardware for the OpenPilot Version 1.1 hardware. * @see The GNU Public License (GPL) Version 3 * @@ -147,6 +148,9 @@ extern uint32_t pios_com_telem_usb_id; extern uint32_t pios_com_bridge_id; extern uint32_t pios_com_vcp_id; extern uint32_t pios_com_hkosd_id; +extern uint32_t pios_com_msp_id; +extern uint32_t pios_com_mavlink_id; + #define PIOS_COM_GPS (pios_com_gps_id) #define PIOS_COM_TELEM_USB (pios_com_telem_usb_id) #define PIOS_COM_TELEM_RF (pios_com_telem_rf_id) @@ -154,6 +158,8 @@ extern uint32_t pios_com_hkosd_id; #define PIOS_COM_BRIDGE (pios_com_bridge_id) #define PIOS_COM_VCP (pios_com_vcp_id) #define PIOS_COM_OSDHK (pios_com_hkosd_id) +#define PIOS_COM_MSP (pios_com_msp_id) +#define PIOS_COM_MAVLINK (pios_com_mavlink_id) #if defined(PIOS_INCLUDE_DEBUG_CONSOLE) extern uint32_t pios_com_debug_id; @@ -237,7 +243,7 @@ extern uint32_t pios_packet_handler; // Receiver PPM input // ------------------------- #define PIOS_PPM_MAX_DEVS 1 -#define PIOS_PPM_NUM_INPUTS 12 +#define PIOS_PPM_NUM_INPUTS 16 // ------------------------- // Receiver PWM input @@ -257,6 +263,18 @@ extern uint32_t pios_packet_handler; #define PIOS_SBUS_MAX_DEVS 1 #define PIOS_SBUS_NUM_INPUTS (16 + 2) +// ------------------------- +// Receiver HOTT input +// ------------------------- +#define PIOS_HOTT_MAX_DEVS 1 +#define PIOS_HOTT_NUM_INPUTS 32 + +// ------------------------- +// Receiver EX.Bus input +// ------------------------- +#define PIOS_EXBUS_MAX_DEVS 1 +#define PIOS_EXBUS_NUM_INPUTS 16 + // ------------------------- // Receiver Multiplex SRXL input // ------------------------- @@ -269,6 +287,12 @@ extern uint32_t pios_packet_handler; #define PIOS_DSM_MAX_DEVS 2 #define PIOS_DSM_NUM_INPUTS 12 +// ------------------------- +// Receiver FlySky IBus input +// ------------------------- +#define PIOS_IBUS_MAX_DEVS 1 +#define PIOS_IBUS_NUM_INPUTS 10 + // ------------------------- // Servo outputs // ------------------------- diff --git a/flight/targets/boards/revonano/board_hw_defs.c b/flight/targets/boards/revonano/board_hw_defs.c index 2c3deefe0..63f019913 100644 --- a/flight/targets/boards/revonano/board_hw_defs.c +++ b/flight/targets/boards/revonano/board_hw_defs.c @@ -1,7 +1,8 @@ /** ****************************************************************************** * @file board_hw_defs.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014. * @addtogroup OpenPilotSystem OpenPilot System * @{ * @addtogroup OpenPilotCore OpenPilot Core @@ -535,6 +536,55 @@ static const struct pios_dsm_cfg pios_dsm_flexi_cfg = { #endif /* PIOS_INCLUDE_DSM */ +#if defined(PIOS_INCLUDE_HOTT) +/* + * HOTT USART + */ +#include + +static const struct pios_usart_cfg pios_usart_hott_flexi_cfg = { + .regs = FLEXI_USART_REGS, + .remap = FLEXI_USART_REMAP, + .init = { + .USART_BaudRate = 115200, + .USART_WordLength = USART_WordLength_8b, + .USART_Parity = USART_Parity_No, + .USART_StopBits = USART_StopBits_1, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + .USART_Mode = USART_Mode_Rx, + }, + .irq = { + .init = { + .NVIC_IRQChannel = FLEXI_USART_IRQ, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .rx = { + .gpio = FLEXI_USART_RX_GPIO, + .init = { + .GPIO_Pin = FLEXI_USART_RX_PIN, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, + .tx = { + .gpio = FLEXI_USART_TX_GPIO, + .init = { + .GPIO_Pin = FLEXI_USART_TX_PIN, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, +}; + +#endif /* PIOS_INCLUDE_HOTT */ + #if defined(PIOS_INCLUDE_SRXL) /* * SRXL USART @@ -583,6 +633,105 @@ static const struct pios_usart_cfg pios_usart_srxl_flexi_cfg = { }; #endif /* PIOS_INCLUDE_SRXL */ + +#if defined(PIOS_INCLUDE_IBUS) +/* + * IBUS USART + */ +#include + +static const struct pios_usart_cfg pios_usart_ibus_flexi_cfg = { + .regs = FLEXI_USART_REGS, + .remap = FLEXI_USART_REMAP, + .init = { + .USART_BaudRate = 115200, + .USART_WordLength = USART_WordLength_8b, + .USART_Parity = USART_Parity_No, + .USART_StopBits = USART_StopBits_1, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + .USART_Mode = USART_Mode_Rx, + }, + .irq = { + .init = { + .NVIC_IRQChannel = FLEXI_USART_IRQ, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .rx = { + .gpio = FLEXI_USART_RX_GPIO, + .init = { + .GPIO_Pin = FLEXI_USART_RX_PIN, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, + .tx = { + .gpio = FLEXI_USART_TX_GPIO, + .init = { + .GPIO_Pin = FLEXI_USART_TX_PIN, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, +}; + +#endif /* PIOS_INCLUDE_IBUS */ + +#if defined(PIOS_INCLUDE_EXBUS) +/* + * EXBUS USART + */ +#include + +static const struct pios_usart_cfg pios_usart_exbus_flexi_cfg = { + .regs = FLEXI_USART_REGS, + .remap = FLEXI_USART_REMAP, + .init = { + .USART_BaudRate = 125000, + .USART_WordLength = USART_WordLength_8b, + .USART_Parity = USART_Parity_No, + .USART_StopBits = USART_StopBits_1, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + .USART_Mode = USART_Mode_Rx, + }, + .irq = { + .init = { + .NVIC_IRQChannel = FLEXI_USART_IRQ, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .rx = { + .gpio = FLEXI_USART_RX_GPIO, + .init = { + .GPIO_Pin = FLEXI_USART_RX_PIN, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, + .tx = { + .gpio = FLEXI_USART_TX_GPIO, + .init = { + .GPIO_Pin = FLEXI_USART_TX_PIN, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, +}; + +#endif /* PIOS_INCLUDE_EXBUS */ + /* * HK OSD */ @@ -780,7 +929,7 @@ static const struct pios_i2c_adapter_cfg pios_i2c_flexiport_adapter_cfg = { .GPIO_Mode = GPIO_Mode_AF, .GPIO_Speed = GPIO_Speed_50MHz, .GPIO_OType = GPIO_OType_OD, - .GPIO_PuPd = GPIO_PuPd_NOPULL, + .GPIO_PuPd = GPIO_PuPd_UP, }, }, .sda = { @@ -790,7 +939,7 @@ static const struct pios_i2c_adapter_cfg pios_i2c_flexiport_adapter_cfg = { .GPIO_Mode = GPIO_Mode_AF, .GPIO_Speed = GPIO_Speed_50MHz, .GPIO_OType = GPIO_OType_OD, - .GPIO_PuPd = GPIO_PuPd_NOPULL, + .GPIO_PuPd = GPIO_PuPd_UP, }, }, .event = { diff --git a/flight/targets/boards/revonano/bootloader/main.c b/flight/targets/boards/revonano/bootloader/main.c index 5c6e08db7..09a54a094 100644 --- a/flight/targets/boards/revonano/bootloader/main.c +++ b/flight/targets/boards/revonano/bootloader/main.c @@ -34,9 +34,8 @@ #include #include /* PIOS_USBHOOK_* */ #include +#include -/* Prototype of PIOS_Board_Init() function */ -extern void PIOS_Board_Init(void); extern void FLASH_Download(); void check_bor(); #define BSL_HOLD_STATE ((PIOS_USB_DETECT_GPIO_PORT->IDR & PIOS_USB_DETECT_GPIO_PIN) ? 0 : 1) diff --git a/flight/targets/boards/revonano/firmware/Makefile b/flight/targets/boards/revonano/firmware/Makefile index a5f9fb8bc..67d01fac7 100644 --- a/flight/targets/boards/revonano/firmware/Makefile +++ b/flight/targets/boards/revonano/firmware/Makefile @@ -1,6 +1,6 @@ # -# Copyright (c) 2015, The LibrePilot Project, http://www.librepilot.org -# Copyright (c) 2009-2014, The OpenPilot Team, http://www.openpilot.org +# Copyright (C) 2015-2016, The LibrePilot Project, http://www.librepilot.org +# Copyright (C) 2009-2014, The OpenPilot Team, http://www.openpilot.org # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -51,7 +51,10 @@ MODULES += PathFollower MODULES += Telemetry MODULES += Notify +OPTMODULES += AutoTune OPTMODULES += ComUsbBridge +OPTMODULES += UAVOMSPBridge +OPTMODULES += UAVOMavlinkBridge SRC += $(FLIGHTLIB)/notification.c @@ -91,7 +94,6 @@ ifndef TESTAPP SRC += $(FLIGHTLIB)/plans.c SRC += $(FLIGHTLIB)/WorldMagModel.c SRC += $(FLIGHTLIB)/insgps13state.c - CPPSRC += $(FLIGHTLIB)/mini_cpp.cpp SRC += $(FLIGHTLIB)/lednotification.c SRC += $(FLIGHTLIB)/auxmagsupport.c ## UAVObjects diff --git a/flight/targets/boards/revonano/firmware/UAVObjects.inc b/flight/targets/boards/revonano/firmware/UAVObjects.inc index 0b751c1d0..6100c4750 100644 --- a/flight/targets/boards/revonano/firmware/UAVObjects.inc +++ b/flight/targets/boards/revonano/firmware/UAVObjects.inc @@ -1,5 +1,6 @@ # -# Copyright (c) 2009-2013, The OpenPilot Team, http://www.openpilot.org +# Copyright (C) 2016, The LibrePilot Project, http://www.librepilot.org +# Copyright (C) 2009-2013, The OpenPilot Team, http://www.openpilot.org # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -125,6 +126,8 @@ UAVOBJSRCFILENAMES += txpidsettings UAVOBJSRCFILENAMES += txpidstatus UAVOBJSRCFILENAMES += takeofflocation UAVOBJSRCFILENAMES += perfcounter +UAVOBJSRCFILENAMES += systemidentsettings +UAVOBJSRCFILENAMES += systemidentstate UAVOBJSRC = $(foreach UAVOBJSRCFILE,$(UAVOBJSRCFILENAMES),$(FLIGHT_UAVOBJ_DIR)/$(UAVOBJSRCFILE).c ) UAVOBJDEFINE = $(foreach UAVOBJSRCFILE,$(UAVOBJSRCFILENAMES),-DUAVOBJ_INIT_$(UAVOBJSRCFILE) ) diff --git a/flight/targets/boards/revonano/firmware/inc/pios_config.h b/flight/targets/boards/revonano/firmware/inc/pios_config.h index 16803c751..49a64f09a 100644 --- a/flight/targets/boards/revonano/firmware/inc/pios_config.h +++ b/flight/targets/boards/revonano/firmware/inc/pios_config.h @@ -5,7 +5,8 @@ * @addtogroup OpenPilotCore OpenPilot Core * @{ * @file pios_config.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2013. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2013. * @brief PiOS configuration header, the compile time config file for the PIOS. * Defines which PiOS libraries and features are included in the firmware. * @see The GNU Public License (GPL) Version 3 @@ -84,7 +85,7 @@ // #define PIOS_INCLUDE_MPU6000 // #define PIOS_MPU6000_ACCEL /* #define PIOS_INCLUDE_HMC5843 */ -// #define PIOS_INCLUDE_HMC5X83 +#define PIOS_INCLUDE_HMC5X83 // #define PIOS_HMC5X83_HAS_GPIOS /* #define PIOS_INCLUDE_BMP085 */ #define PIOS_INCLUDE_MS5611 @@ -108,6 +109,9 @@ #define PIOS_INCLUDE_DSM #define PIOS_INCLUDE_SBUS #define PIOS_INCLUDE_SRXL +#define PIOS_INCLUDE_HOTT +#define PIOS_INCLUDE_EXBUS +#define PIOS_INCLUDE_IBUS #define PIOS_INCLUDE_GCSRCVR // #define PIOS_INCLUDE_OPLINKRCVR @@ -154,6 +158,7 @@ /* #define PIOS_GPS_MINIMAL */ #define PIOS_INCLUDE_GPS_NMEA_PARSER #define PIOS_INCLUDE_GPS_UBX_PARSER +#define PIOS_INCLUDE_GPS_DJI_PARSER #define PIOS_GPS_SETS_HOMELOCATION /* Stabilization options */ diff --git a/flight/targets/boards/revonano/firmware/pios_board.c b/flight/targets/boards/revonano/firmware/pios_board.c index dcf373a51..0de1b0eed 100644 --- a/flight/targets/boards/revonano/firmware/pios_board.c +++ b/flight/targets/boards/revonano/firmware/pios_board.c @@ -1,8 +1,9 @@ /** ****************************************************************************** * @file pios_board.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2011. - * @author PhoenixPilot, http://github.com/PhoenixPilot, Copyright (C) 2012 + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2011. + * PhoenixPilot, http://github.com/PhoenixPilot, Copyright (C) 2012 * @addtogroup OpenPilotSystem OpenPilot System * @{ * @addtogroup OpenPilotCore OpenPilot Core @@ -38,6 +39,7 @@ #include #include #include +#include #ifdef PIOS_INCLUDE_INSTRUMENTATION #include @@ -92,9 +94,26 @@ void PIOS_ADC_DMC_irq_handler(void) /* Call into the generic code to handle the IRQ for this specific device */ PIOS_ADC_DMA_Handler(); } - #endif /* if defined(PIOS_INCLUDE_ADC) */ +#if defined(PIOS_INCLUDE_HMC5X83) +#include "pios_hmc5x83.h" +pios_hmc5x83_dev_t external_mag = 0; + +static const struct pios_hmc5x83_cfg pios_hmc5x83_external_cfg = { +#ifdef PIOS_HMC5X83_HAS_GPIOS + .exti_cfg = NULL, +#endif + .M_ODR = PIOS_HMC5x83_ODR_75, // if you change this for auxmag, change AUX_MAG_SKIP in sensors.c + .Meas_Conf = PIOS_HMC5x83_MEASCONF_NORMAL, + .Gain = PIOS_HMC5x83_GAIN_1_9, + .Mode = PIOS_HMC5x83_MODE_CONTINUOUS, + .TempCompensation = false, + .Driver = &PIOS_HMC5x83_I2C_DRIVER, + .Orientation = PIOS_HMC5X83_ORIENTATION_EAST_NORTH_UP, // ENU for GPSV9, WND for typical I2C mag +}; +#endif /* PIOS_INCLUDE_HMC5X83 */ + /** * Configuration for the MS5611 chip */ @@ -188,6 +207,11 @@ uint32_t pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_NONE]; #define PIOS_COM_HKOSD_RX_BUF_LEN 22 #define PIOS_COM_HKOSD_TX_BUF_LEN 22 +#define PIOS_COM_MSP_TX_BUF_LEN 128 +#define PIOS_COM_MSP_RX_BUF_LEN 64 + +#define PIOS_COM_MAVLINK_TX_BUF_LEN 128 + #if defined(PIOS_INCLUDE_DEBUG_CONSOLE) #define PIOS_COM_DEBUGCONSOLE_TX_BUF_LEN 40 uint32_t pios_com_debug_id; @@ -200,16 +224,20 @@ uint32_t pios_com_rf_id = 0; uint32_t pios_com_bridge_id = 0; uint32_t pios_com_overo_id = 0; uint32_t pios_com_hkosd_id = 0; - +uint32_t pios_com_msp_id = 0; uint32_t pios_com_vcp_id = 0; +uint32_t pios_com_mavlink_id = 0; uintptr_t pios_uavo_settings_fs_id; uintptr_t pios_user_fs_id; /* - * Setup a com port based on the passed cfg, driver and buffer sizes. tx size of -1 make the port rx only + * Setup a com port based on the passed cfg, driver and buffer sizes. + * tx size = 0 make the port rx only + * rx size = 0 make the port tx only + * having both tx and rx size = 0 is not valid and will fail further down in PIOS_COM_Init() */ -static void PIOS_Board_configure_com(const struct pios_usart_cfg *usart_port_cfg, size_t rx_buf_len, size_t tx_buf_len, +static void PIOS_Board_configure_com(const struct pios_usart_cfg *usart_port_cfg, uint16_t rx_buf_len, uint16_t tx_buf_len, const struct pios_com_driver *com_driver, uint32_t *pios_com_id) { uint32_t pios_usart_id; @@ -218,23 +246,22 @@ static void PIOS_Board_configure_com(const struct pios_usart_cfg *usart_port_cfg PIOS_Assert(0); } - uint8_t *rx_buffer = (uint8_t *)pios_malloc(rx_buf_len); - PIOS_Assert(rx_buffer); - if (tx_buf_len != (size_t)-1) { // this is the case for rx/tx ports - uint8_t *tx_buffer = (uint8_t *)pios_malloc(tx_buf_len); - PIOS_Assert(tx_buffer); + uint8_t *rx_buffer = 0, *tx_buffer = 0; - if (PIOS_COM_Init(pios_com_id, com_driver, pios_usart_id, - rx_buffer, rx_buf_len, - tx_buffer, tx_buf_len)) { - PIOS_Assert(0); - } - } else { // rx only port - if (PIOS_COM_Init(pios_com_id, com_driver, pios_usart_id, - rx_buffer, rx_buf_len, - NULL, 0)) { - PIOS_Assert(0); - } + if (rx_buf_len > 0) { + rx_buffer = (uint8_t *)pios_malloc(rx_buf_len); + PIOS_Assert(rx_buffer); + } + + if (tx_buf_len > 0) { + tx_buffer = (uint8_t *)pios_malloc(tx_buf_len); + PIOS_Assert(tx_buffer); + } + + if (PIOS_COM_Init(pios_com_id, com_driver, pios_usart_id, + rx_buffer, rx_buf_len, + tx_buffer, tx_buf_len)) { + PIOS_Assert(0); } } @@ -261,6 +288,27 @@ static void PIOS_Board_configure_dsm(const struct pios_usart_cfg *pios_usart_dsm pios_rcvr_group_map[channelgroup] = pios_dsm_rcvr_id; } +static void PIOS_Board_configure_ibus(const struct pios_usart_cfg *usart_cfg) +{ + uint32_t pios_usart_ibus_id; + + if (PIOS_USART_Init(&pios_usart_ibus_id, usart_cfg)) { + PIOS_Assert(0); + } + + uint32_t pios_ibus_id; + if (PIOS_IBUS_Init(&pios_ibus_id, &pios_usart_com_driver, pios_usart_ibus_id)) { + PIOS_Assert(0); + } + + uint32_t pios_ibus_rcvr_id; + if (PIOS_RCVR_Init(&pios_ibus_rcvr_id, &pios_ibus_rcvr_driver, pios_ibus_id)) { + PIOS_Assert(0); + } + + pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_IBUS] = pios_ibus_rcvr_id; +} + static void PIOS_Board_configure_pwm(const struct pios_pwm_cfg *pwm_cfg) { /* Set up the receiver port. Later this should be optional */ @@ -360,6 +408,7 @@ void PIOS_Board_Init(void) PIOS_IAP_WriteBootCmd(1, 0); PIOS_IAP_WriteBootCmd(2, 0); } + #ifdef PIOS_INCLUDE_WDG PIOS_WDG_Init(); #endif @@ -596,6 +645,12 @@ void PIOS_Board_Init(void) case HWSETTINGS_RM_MAINPORT_COMBRIDGE: PIOS_Board_configure_com(&pios_usart_main_cfg, PIOS_COM_BRIDGE_RX_BUF_LEN, PIOS_COM_BRIDGE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_bridge_id); break; + case HWSETTINGS_RM_MAINPORT_MSP: + PIOS_Board_configure_com(&pios_usart_main_cfg, PIOS_COM_MSP_RX_BUF_LEN, PIOS_COM_MSP_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_msp_id); + break; + case HWSETTINGS_RM_MAINPORT_MAVLINK: + PIOS_Board_configure_com(&pios_usart_main_cfg, 0, PIOS_COM_MAVLINK_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_mavlink_id); + break; case HWSETTINGS_RM_MAINPORT_OSDHK: PIOS_Board_configure_com(&pios_usart_hkosd_main_cfg, PIOS_COM_HKOSD_RX_BUF_LEN, PIOS_COM_HKOSD_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_hkosd_id); break; @@ -617,11 +672,40 @@ void PIOS_Board_Init(void) break; case HWSETTINGS_RM_FLEXIPORT_I2C: #if defined(PIOS_INCLUDE_I2C) - { - if (PIOS_I2C_Init(&pios_i2c_flexiport_adapter_id, &pios_i2c_flexiport_adapter_cfg)) { - PIOS_Assert(0); - } + if (PIOS_I2C_Init(&pios_i2c_flexiport_adapter_id, &pios_i2c_flexiport_adapter_cfg)) { + PIOS_Assert(0); } + PIOS_DELAY_WaitmS(50); // this was after the other PIOS_I2C_Init(), so I copied it here too +#ifdef PIOS_INCLUDE_WDG + // give HMC5x83 on I2C some extra time to allow for reset, etc. if needed + // this is not in a loop, so it is safe + // leave this here even if PIOS_INCLUDE_HMC5X83 is undefined + // to avoid making something else fail when HMC5X83 is removed + PIOS_WDG_Clear(); +#endif /* PIOS_INCLUDE_WDG */ +#if defined(PIOS_INCLUDE_HMC5X83) + // get auxmag type + AuxMagSettingsTypeOptions option; + AuxMagSettingsInitialize(); + AuxMagSettingsTypeGet(&option); + // if the aux mag type is FlexiPort then set it up + if (option == AUXMAGSETTINGS_TYPE_FLEXI) { + // attach the 5x83 mag to the previously inited I2C2 + external_mag = PIOS_HMC5x83_Init(&pios_hmc5x83_external_cfg, pios_i2c_flexiport_adapter_id, 0); +#ifdef PIOS_INCLUDE_WDG + // give HMC5x83 on I2C some extra time to allow for reset, etc. if needed + // this is not in a loop, so it is safe + PIOS_WDG_Clear(); +#endif /* PIOS_INCLUDE_WDG */ + // add this sensor to the sensor task's list + // be careful that you don't register a slow, unimportant sensor after registering the fastest sensor + // and before registering some other fast and important sensor + // as that would cause delay and time jitter for the second fast sensor + PIOS_HMC5x83_Register(external_mag, PIOS_SENSORS_TYPE_3AXIS_AUXMAG); + // mag alarm is cleared later, so use I2C + AlarmsSet(SYSTEMALARMS_ALARM_I2C, (external_mag) ? SYSTEMALARMS_ALARM_OK : SYSTEMALARMS_ALARM_WARNING); + } +#endif /* PIOS_INCLUDE_HMC5X83 */ #endif /* PIOS_INCLUDE_I2C */ break; case HWSETTINGS_RM_FLEXIPORT_GPS: @@ -635,13 +719,19 @@ void PIOS_Board_Init(void) case HWSETTINGS_RM_FLEXIPORT_DEBUGCONSOLE: #if defined(PIOS_INCLUDE_DEBUG_CONSOLE) { - PIOS_Board_configure_com(&pios_usart_main_cfg, 0, PIOS_COM_DEBUGCONSOLE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_debug_id); + PIOS_Board_configure_com(&pios_usart_flexi_cfg, 0, PIOS_COM_DEBUGCONSOLE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_debug_id); } #endif /* PIOS_INCLUDE_DEBUG_CONSOLE */ break; case HWSETTINGS_RM_FLEXIPORT_COMBRIDGE: PIOS_Board_configure_com(&pios_usart_flexi_cfg, PIOS_COM_BRIDGE_RX_BUF_LEN, PIOS_COM_BRIDGE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_bridge_id); break; + case HWSETTINGS_RM_FLEXIPORT_MSP: + PIOS_Board_configure_com(&pios_usart_flexi_cfg, PIOS_COM_MSP_RX_BUF_LEN, PIOS_COM_MSP_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_msp_id); + break; + case HWSETTINGS_RM_FLEXIPORT_MAVLINK: + PIOS_Board_configure_com(&pios_usart_flexi_cfg, 0, PIOS_COM_MAVLINK_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_mavlink_id); + break; case HWSETTINGS_RM_FLEXIPORT_OSDHK: PIOS_Board_configure_com(&pios_usart_hkosd_flexi_cfg, PIOS_COM_HKOSD_RX_BUF_LEN, PIOS_COM_HKOSD_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_hkosd_id); break; @@ -664,12 +754,64 @@ void PIOS_Board_Init(void) } pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_SRXL] = pios_srxl_rcvr_id; } -#endif +#endif /* PIOS_INCLUDE_SRXL */ + break; + + case HWSETTINGS_RM_FLEXIPORT_IBUS: +#if defined(PIOS_INCLUDE_IBUS) + PIOS_Board_configure_ibus(&pios_usart_ibus_flexi_cfg); +#endif /* PIOS_INCLUDE_IBUS */ + break; + + case HWSETTINGS_RM_FLEXIPORT_HOTTSUMD: + case HWSETTINGS_RM_FLEXIPORT_HOTTSUMH: +#if defined(PIOS_INCLUDE_HOTT) + { + uint32_t pios_usart_hott_id; + if (PIOS_USART_Init(&pios_usart_hott_id, &pios_usart_hott_flexi_cfg)) { + PIOS_Assert(0); + } + + uint32_t pios_hott_id; + if (PIOS_HOTT_Init(&pios_hott_id, &pios_usart_com_driver, pios_usart_hott_id, + hwsettings_flexiport == HWSETTINGS_RM_FLEXIPORT_HOTTSUMD ? PIOS_HOTT_PROTO_SUMD : PIOS_HOTT_PROTO_SUMH)) { + PIOS_Assert(0); + } + + uint32_t pios_hott_rcvr_id; + if (PIOS_RCVR_Init(&pios_hott_rcvr_id, &pios_hott_rcvr_driver, pios_hott_id)) { + PIOS_Assert(0); + } + pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_HOTT] = pios_hott_rcvr_id; + } +#endif /* PIOS_INCLUDE_HOTT */ + break; + + case HWSETTINGS_RM_FLEXIPORT_EXBUS: +#if defined(PIOS_INCLUDE_EXBUS) + { + uint32_t pios_usart_exbus_id; + if (PIOS_USART_Init(&pios_usart_exbus_id, &pios_usart_exbus_flexi_cfg)) { + PIOS_Assert(0); + } + + uint32_t pios_exbus_id; + if (PIOS_EXBUS_Init(&pios_exbus_id, &pios_usart_com_driver, pios_usart_exbus_id)) { + PIOS_Assert(0); + } + + uint32_t pios_exbus_rcvr_id; + if (PIOS_RCVR_Init(&pios_exbus_rcvr_id, &pios_exbus_rcvr_driver, pios_exbus_id)) { + PIOS_Assert(0); + } + pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_EXBUS] = pios_exbus_rcvr_id; + } +#endif /* PIOS_INCLUDE_EXBUS */ break; } /* hwsettings_rm_flexiport */ -#if defined(PIOS_INCLUDE_PWM) || defined(PIOS_INCLUDE_PWM) +#if defined(PIOS_INCLUDE_PWM) || defined(PIOS_INCLUDE_PPM) const struct pios_servo_cfg *pios_servo_cfg; // default to servo outputs only @@ -796,7 +938,9 @@ SystemAlarmsExtendedAlarmStatusOptions RevoNanoConfigHook() case HWSETTINGS_RM_RCVRPORT_PWM: for (uint8_t i = 0; i < ACTUATORSETTINGS_BANKMODE_NUMELEM; i++) { if (modes[i] == ACTUATORSETTINGS_BANKMODE_PWMSYNC || - modes[i] == ACTUATORSETTINGS_BANKMODE_ONESHOT125) { + modes[i] == ACTUATORSETTINGS_BANKMODE_ONESHOT125 || + modes[i] == ACTUATORSETTINGS_BANKMODE_ONESHOT42 || + modes[i] == ACTUATORSETTINGS_BANKMODE_MULTISHOT) { return SYSTEMALARMS_EXTENDEDALARMSTATUS_UNSUPPORTEDCONFIG_ONESHOT;; } } diff --git a/flight/targets/boards/revonano/firmware/revolution.cpp b/flight/targets/boards/revonano/firmware/revolution.cpp index 70d0b2245..8c5bbf28c 100644 --- a/flight/targets/boards/revonano/firmware/revolution.cpp +++ b/flight/targets/boards/revonano/firmware/revolution.cpp @@ -1,17 +1,18 @@ /** ****************************************************************************** - * @addtogroup OpenPilotSystem OpenPilot System - * @brief These files are the core system files of OpenPilot. - * They are the ground layer just above PiOS. In practice, OpenPilot actually starts - * in the main() function of openpilot.c + * @addtogroup LibrePilotSystem LibrePilot System + * @brief These files are the core system files for Revolution. + * They are the ground layer just above PiOS. In practice, Revolution actually starts + * in the main() function of revolution.cpp * @{ - * @addtogroup OpenPilotCore OpenPilot Core - * @brief This is where the OP firmware starts. Those files also define the compile-time + * @addtogroup LibrePilotCore LibrePilot Core + * @brief This is where the LP firmware starts. Those files also define the compile-time * options of the firmware. * @{ - * @file openpilot.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @brief Sets up and runs main OpenPilot tasks. + * @file revolution.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2015 + * @brief Sets up and runs main tasks. * @see The GNU Public License (GPL) Version 3 * *****************************************************************************/ @@ -34,29 +35,12 @@ extern "C" { #include "inc/openpilot.h" #include +#include -/* Task Priorities */ -#define PRIORITY_TASK_HOOKS (tskIDLE_PRIORITY + 3) /* Global Variables */ /* Local Variables */ - -/* Prototype of PIOS_Board_Init() function */ -extern void PIOS_Board_Init(void); -extern void Stack_Change(void); -static void Stack_Change_Weak() __attribute__((weakref("Stack_Change"))); - -/* Local Variables */ -#define INIT_TASK_PRIORITY (tskIDLE_PRIORITY + configMAX_PRIORITIES - 1) // max priority -#define INIT_TASK_STACK (1024 / 4) // XXX this seems excessive -static xTaskHandle initTaskHandle; - -/* Function Prototypes */ -static void initTask(void *parameters); - -/* Prototype of generated InitModules() function */ -extern void InitModules(void); } /** @@ -70,8 +54,6 @@ extern void InitModules(void); */ int main() { - int result; - /* NOTE: Do NOT modify the following start-up sequence */ /* Any new initialization functions should be added in OpenPilotInit() */ vPortInitialiseBlocks(); @@ -79,12 +61,7 @@ int main() /* Brings up System using CMSIS functions, enables the LEDs. */ PIOS_SYS_Init(); - /* For Revolution we use a FreeRTOS task to bring up the system so we can */ - /* always rely on FreeRTOS primitive */ - result = xTaskCreate(initTask, "init", - INIT_TASK_STACK, NULL, INIT_TASK_PRIORITY, - &initTaskHandle); - PIOS_Assert(result == pdPASS); + SystemModStart(); /* Start the FreeRTOS scheduler */ vTaskStartScheduler(); @@ -100,22 +77,7 @@ int main() return 0; } -/** - * Initialisation task. - * - * Runs board and module initialisation, then terminates. - */ -void initTask(__attribute__((unused)) void *parameters) -{ - /* board driver init */ - PIOS_Board_Init(); - /* Initialize modules */ - MODULE_INITIALISE_ALL; - - /* terminate this task */ - vTaskDelete(NULL); -} /** * @} diff --git a/flight/targets/boards/revonano/pios_board.h b/flight/targets/boards/revonano/pios_board.h index 54776fe34..43c55959c 100644 --- a/flight/targets/boards/revonano/pios_board.h +++ b/flight/targets/boards/revonano/pios_board.h @@ -5,7 +5,8 @@ * @addtogroup OpenPilotCore OpenPilot Core * @{ * @file pios_board.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. * @brief Defines board hardware for the OpenPilot Version 1.1 hardware. * @see The GNU Public License (GPL) Version 3 * @@ -147,6 +148,9 @@ extern uint32_t pios_com_telem_usb_id; extern uint32_t pios_com_bridge_id; extern uint32_t pios_com_vcp_id; extern uint32_t pios_com_hkosd_id; +extern uint32_t pios_com_msp_id; +extern uint32_t pios_com_mavlink_id; + #define PIOS_COM_GPS (pios_com_gps_id) #define PIOS_COM_TELEM_USB (pios_com_telem_usb_id) #define PIOS_COM_TELEM_RF (pios_com_telem_rf_id) @@ -154,6 +158,8 @@ extern uint32_t pios_com_hkosd_id; #define PIOS_COM_BRIDGE (pios_com_bridge_id) #define PIOS_COM_VCP (pios_com_vcp_id) #define PIOS_COM_OSDHK (pios_com_hkosd_id) +#define PIOS_COM_MSP (pios_com_msp_id) +#define PIOS_COM_MAVLINK (pios_com_mavlink_id) #if defined(PIOS_INCLUDE_DEBUG_CONSOLE) extern uint32_t pios_com_debug_id; @@ -237,7 +243,7 @@ extern uint32_t pios_packet_handler; // Receiver PPM input // ------------------------- #define PIOS_PPM_MAX_DEVS 1 -#define PIOS_PPM_NUM_INPUTS 12 +#define PIOS_PPM_NUM_INPUTS 16 // ------------------------- // Receiver PWM input @@ -257,6 +263,18 @@ extern uint32_t pios_packet_handler; #define PIOS_SBUS_MAX_DEVS 1 #define PIOS_SBUS_NUM_INPUTS (16 + 2) +// ------------------------- +// Receiver HOTT input +// ------------------------- +#define PIOS_HOTT_MAX_DEVS 1 +#define PIOS_HOTT_NUM_INPUTS 32 + +// ------------------------- +// Receiver EX.Bus input +// ------------------------- +#define PIOS_EXBUS_MAX_DEVS 1 +#define PIOS_EXBUS_NUM_INPUTS 16 + // ------------------------- // Receiver Multiplex SRXL input // ------------------------- @@ -269,6 +287,12 @@ extern uint32_t pios_packet_handler; #define PIOS_DSM_MAX_DEVS 2 #define PIOS_DSM_NUM_INPUTS 12 +// ------------------------- +// Receiver FlySky IBus input +// ------------------------- +#define PIOS_IBUS_MAX_DEVS 1 +#define PIOS_IBUS_NUM_INPUTS 10 + // ------------------------- // Servo outputs // ------------------------- diff --git a/flight/targets/boards/revonano/pios_usb_board_data.c b/flight/targets/boards/revonano/pios_usb_board_data.c index be0d07952..c643e0321 100644 --- a/flight/targets/boards/revonano/pios_usb_board_data.c +++ b/flight/targets/boards/revonano/pios_usb_board_data.c @@ -33,7 +33,7 @@ #include /* PIOS_USBHOOK_* */ #include /* PIOS_USB_UTIL_AsciiToUtf8 */ -static const uint8_t usb_product_id[22] = { +static const uint8_t usb_product_id[10] = { sizeof(usb_product_id), USB_DESC_TYPE_STRING, 'N', 0, diff --git a/flight/targets/boards/revoproto/board_hw_defs.c b/flight/targets/boards/revoproto/board_hw_defs.c index 332320935..bda92eb18 100644 --- a/flight/targets/boards/revoproto/board_hw_defs.c +++ b/flight/targets/boards/revoproto/board_hw_defs.c @@ -1288,7 +1288,7 @@ static const struct pios_i2c_adapter_cfg pios_i2c_flexiport_adapter_cfg = { .GPIO_Mode = GPIO_Mode_AF, .GPIO_Speed = GPIO_Speed_50MHz, .GPIO_OType = GPIO_OType_OD, - .GPIO_PuPd = GPIO_PuPd_NOPULL, + .GPIO_PuPd = GPIO_PuPd_UP, }, }, .sda = { @@ -1298,7 +1298,7 @@ static const struct pios_i2c_adapter_cfg pios_i2c_flexiport_adapter_cfg = { .GPIO_Mode = GPIO_Mode_AF, .GPIO_Speed = GPIO_Speed_50MHz, .GPIO_OType = GPIO_OType_OD, - .GPIO_PuPd = GPIO_PuPd_NOPULL, + .GPIO_PuPd = GPIO_PuPd_UP, }, }, .event = { diff --git a/flight/targets/boards/revoproto/bootloader/main.c b/flight/targets/boards/revoproto/bootloader/main.c index 5c6e08db7..09a54a094 100644 --- a/flight/targets/boards/revoproto/bootloader/main.c +++ b/flight/targets/boards/revoproto/bootloader/main.c @@ -34,9 +34,8 @@ #include #include /* PIOS_USBHOOK_* */ #include +#include -/* Prototype of PIOS_Board_Init() function */ -extern void PIOS_Board_Init(void); extern void FLASH_Download(); void check_bor(); #define BSL_HOLD_STATE ((PIOS_USB_DETECT_GPIO_PORT->IDR & PIOS_USB_DETECT_GPIO_PIN) ? 0 : 1) diff --git a/flight/targets/boards/revoproto/firmware/Makefile b/flight/targets/boards/revoproto/firmware/Makefile index a5bd81a47..809fda826 100644 --- a/flight/targets/boards/revoproto/firmware/Makefile +++ b/flight/targets/boards/revoproto/firmware/Makefile @@ -1,7 +1,7 @@ # -# Copyright (c) 2015, The LibrePilot Project, http://www.librepilot.org -# Copyright (c) 2009-2013, The OpenPilot Team, http://www.openpilot.org -# Copyright (c) 2012, PhoenixPilot, http://github.com/PhoenixPilot +# Copyright (C) 2015-2016, The LibrePilot Project, http://www.librepilot.org +# Copyright (C) 2009-2013, The OpenPilot Team, http://www.openpilot.org +# Copyright (C) 2012, PhoenixPilot, http://github.com/PhoenixPilot # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -52,7 +52,10 @@ MODULES += Telemetry SRC += $(FLIGHTLIB)/notification.c +OPTMODULES += AutoTune OPTMODULES += ComUsbBridge +OPTMODULES += UAVOMSPBridge +OPTMODULES += UAVOMavlinkBridge # Include all camera options CDEFS += -DUSE_INPUT_LPF -DUSE_GIMBAL_LPF -DUSE_GIMBAL_FF @@ -90,8 +93,6 @@ ifndef TESTAPP SRC += $(FLIGHTLIB)/WorldMagModel.c SRC += $(FLIGHTLIB)/insgps13state.c SRC += $(FLIGHTLIB)/auxmagsupport.c - CPPSRC += $(FLIGHTLIB)/mini_cpp.cpp - ## UAVObjects include ./UAVObjects.inc diff --git a/flight/targets/boards/revoproto/firmware/UAVObjects.inc b/flight/targets/boards/revoproto/firmware/UAVObjects.inc index c98bc205e..cba723f6b 100644 --- a/flight/targets/boards/revoproto/firmware/UAVObjects.inc +++ b/flight/targets/boards/revoproto/firmware/UAVObjects.inc @@ -1,5 +1,6 @@ # -# Copyright (c) 2009-2013, The OpenPilot Team, http://www.openpilot.org +# Copyright (C) 2016, The LibrePilot Project, http://www.librepilot.org +# Copyright (C) 2009-2013, The OpenPilot Team, http://www.openpilot.org # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -124,6 +125,9 @@ UAVOBJSRCFILENAMES += mpugyroaccelsettings UAVOBJSRCFILENAMES += txpidsettings UAVOBJSRCFILENAMES += txpidstatus UAVOBJSRCFILENAMES += takeofflocation +# UAVOBJSRCFILENAMES += perfcounter +UAVOBJSRCFILENAMES += systemidentsettings +UAVOBJSRCFILENAMES += systemidentstate UAVOBJSRC = $(foreach UAVOBJSRCFILE,$(UAVOBJSRCFILENAMES),$(FLIGHT_UAVOBJ_DIR)/$(UAVOBJSRCFILE).c ) UAVOBJDEFINE = $(foreach UAVOBJSRCFILE,$(UAVOBJSRCFILENAMES),-DUAVOBJ_INIT_$(UAVOBJSRCFILE) ) diff --git a/flight/targets/boards/revoproto/firmware/inc/pios_config.h b/flight/targets/boards/revoproto/firmware/inc/pios_config.h index 270c9507a..468264855 100644 --- a/flight/targets/boards/revoproto/firmware/inc/pios_config.h +++ b/flight/targets/boards/revoproto/firmware/inc/pios_config.h @@ -5,7 +5,8 @@ * @addtogroup OpenPilotCore OpenPilot Core * @{ * @file pios_config.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2013. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2013. * @brief PiOS configuration header, the compile time config file for the PIOS. * Defines which PiOS libraries and features are included in the firmware. * @see The GNU Public License (GPL) Version 3 @@ -141,6 +142,7 @@ /* #define PIOS_GPS_MINIMAL */ #define PIOS_INCLUDE_GPS_NMEA_PARSER #define PIOS_INCLUDE_GPS_UBX_PARSER +#define PIOS_INCLUDE_GPS_DJI_PARSER #define PIOS_GPS_SETS_HOMELOCATION /* Stabilization options */ diff --git a/flight/targets/boards/revoproto/firmware/pios_board.c b/flight/targets/boards/revoproto/firmware/pios_board.c index b0c9030ec..025acce6e 100644 --- a/flight/targets/boards/revoproto/firmware/pios_board.c +++ b/flight/targets/boards/revoproto/firmware/pios_board.c @@ -31,6 +31,7 @@ #include #include #include +#include /* * Pull in the board-specific static HW definitions. @@ -84,8 +85,10 @@ void PIOS_ADC_DMC_irq_handler(void) #if defined(PIOS_INCLUDE_HMC5X83) #include "pios_hmc5x83.h" -pios_hmc5x83_dev_t onboard_mag = 0; +pios_hmc5x83_dev_t onboard_mag = 0; +pios_hmc5x83_dev_t external_mag = 0; +#ifdef PIOS_HMC5X83_HAS_GPIOS bool pios_board_internal_mag_handler() { return PIOS_HMC5x83_IRQHandler(onboard_mag); @@ -120,15 +123,32 @@ static const struct pios_exti_cfg pios_exti_hmc5x83_cfg __exti_config = { }, }, }; +#endif /* PIOS_HMC5X83_HAS_GPIOS */ -static const struct pios_hmc5x83_cfg pios_hmc5x83_cfg = { - .exti_cfg = &pios_exti_hmc5x83_cfg, - .M_ODR = PIOS_HMC5x83_ODR_75, - .Meas_Conf = PIOS_HMC5x83_MEASCONF_NORMAL, - .Gain = PIOS_HMC5x83_GAIN_1_9, - .Mode = PIOS_HMC5x83_MODE_CONTINUOUS, - .Driver = &PIOS_HMC5x83_I2C_DRIVER, - .Orientation = PIOS_HMC5X83_ORIENTATION_EAST_NORTH_UP, +static const struct pios_hmc5x83_cfg pios_hmc5x83_internal_cfg = { +#ifdef PIOS_HMC5X83_HAS_GPIOS + .exti_cfg = &pios_exti_hmc5x83_cfg, +#endif + .M_ODR = PIOS_HMC5x83_ODR_75, + .Meas_Conf = PIOS_HMC5x83_MEASCONF_NORMAL, + .Gain = PIOS_HMC5x83_GAIN_1_9, + .Mode = PIOS_HMC5x83_MODE_CONTINUOUS, + .TempCompensation = false, + .Driver = &PIOS_HMC5x83_I2C_DRIVER, + .Orientation = PIOS_HMC5X83_ORIENTATION_EAST_NORTH_UP, +}; + +static const struct pios_hmc5x83_cfg pios_hmc5x83_external_cfg = { +#ifdef PIOS_HMC5X83_HAS_GPIOS + .exti_cfg = NULL, +#endif + .M_ODR = PIOS_HMC5x83_ODR_75, // if you change this for auxmag, change AUX_MAG_SKIP in sensors.c + .Meas_Conf = PIOS_HMC5x83_MEASCONF_NORMAL, + .Gain = PIOS_HMC5x83_GAIN_1_9, + .Mode = PIOS_HMC5x83_MODE_CONTINUOUS, + .TempCompensation = false, + .Driver = &PIOS_HMC5x83_I2C_DRIVER, + .Orientation = PIOS_HMC5X83_ORIENTATION_EAST_NORTH_UP, }; #endif /* PIOS_INCLUDE_HMC5X83 */ @@ -307,6 +327,10 @@ uint32_t pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_NONE]; #define PIOS_COM_HKOSD_RX_BUF_LEN 22 #define PIOS_COM_HKOSD_TX_BUF_LEN 22 +#define PIOS_COM_MSP_TX_BUF_LEN 128 +#define PIOS_COM_MSP_RX_BUF_LEN 64 + +#define PIOS_COM_MAVLINK_TX_BUF_LEN 128 uint32_t pios_com_aux_id = 0; uint32_t pios_com_gps_id = 0; @@ -315,6 +339,8 @@ uint32_t pios_com_telem_rf_id = 0; uint32_t pios_com_bridge_id = 0; uint32_t pios_com_overo_id = 0; uint32_t pios_com_hkosd_id = 0; +uint32_t pios_com_msp_id = 0; +uint32_t pios_com_mavlink_id = 0; uintptr_t pios_uavo_settings_fs_id; uintptr_t pios_user_fs_id; @@ -322,9 +348,9 @@ uintptr_t pios_user_fs_id; uint32_t pios_com_vcp_id = 0; /* - * Setup a com port based on the passed cfg, driver and buffer sizes. tx size of -1 make the port rx only + * Setup a com port based on the passed cfg, driver and buffer sizes. tx size = 0 make the port rx only */ -static void PIOS_Board_configure_com(const struct pios_usart_cfg *usart_port_cfg, size_t rx_buf_len, size_t tx_buf_len, +static void PIOS_Board_configure_com(const struct pios_usart_cfg *usart_port_cfg, uint16_t rx_buf_len, uint16_t tx_buf_len, const struct pios_com_driver *com_driver, uint32_t *pios_com_id) { uint32_t pios_usart_id; @@ -335,7 +361,7 @@ static void PIOS_Board_configure_com(const struct pios_usart_cfg *usart_port_cfg uint8_t *rx_buffer = (uint8_t *)pios_malloc(rx_buf_len); PIOS_Assert(rx_buffer); - if (tx_buf_len != (size_t)-1) { // this is the case for rx/tx ports + if (tx_buf_len > 0) { // this is the case for rx/tx ports uint8_t *tx_buffer = (uint8_t *)pios_malloc(tx_buf_len); PIOS_Assert(tx_buffer); @@ -644,6 +670,12 @@ void PIOS_Board_Init(void) case HWSETTINGS_RV_TELEMETRYPORT_COMBRIDGE: PIOS_Board_configure_com(&pios_usart_telem_cfg, PIOS_COM_BRIDGE_RX_BUF_LEN, PIOS_COM_BRIDGE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_bridge_id); break; + case HWSETTINGS_RV_TELEMETRYPORT_MSP: + PIOS_Board_configure_com(&pios_usart_telem_cfg, PIOS_COM_MSP_RX_BUF_LEN, PIOS_COM_MSP_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_msp_id); + break; + case HWSETTINGS_RV_TELEMETRYPORT_MAVLINK: + PIOS_Board_configure_com(&pios_usart_telem_cfg, 0, PIOS_COM_MAVLINK_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_mavlink_id); + break; } /* hwsettings_rv_telemetryport */ /* Configure GPS port */ @@ -658,7 +690,7 @@ void PIOS_Board_Init(void) break; case HWSETTINGS_RV_GPSPORT_GPS: - PIOS_Board_configure_com(&pios_usart_gps_cfg, PIOS_COM_GPS_RX_BUF_LEN, -1, &pios_usart_com_driver, &pios_com_gps_id); + PIOS_Board_configure_com(&pios_usart_gps_cfg, PIOS_COM_GPS_RX_BUF_LEN, 0, &pios_usart_com_driver, &pios_com_gps_id); break; case HWSETTINGS_RV_GPSPORT_COMAUX: @@ -668,6 +700,12 @@ void PIOS_Board_Init(void) case HWSETTINGS_RV_GPSPORT_COMBRIDGE: PIOS_Board_configure_com(&pios_usart_gps_cfg, PIOS_COM_BRIDGE_RX_BUF_LEN, PIOS_COM_BRIDGE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_bridge_id); break; + case HWSETTINGS_RV_GPSPORT_MSP: + PIOS_Board_configure_com(&pios_usart_gps_cfg, PIOS_COM_MSP_RX_BUF_LEN, PIOS_COM_MSP_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_msp_id); + break; + case HWSETTINGS_RV_GPSPORT_MAVLINK: + PIOS_Board_configure_com(&pios_usart_gps_cfg, 0, PIOS_COM_MAVLINK_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_mavlink_id); + break; } /* hwsettings_rv_gpsport */ /* Configure AUXPort */ @@ -693,6 +731,12 @@ void PIOS_Board_Init(void) case HWSETTINGS_RV_AUXPORT_COMBRIDGE: PIOS_Board_configure_com(&pios_usart_aux_cfg, PIOS_COM_BRIDGE_RX_BUF_LEN, PIOS_COM_BRIDGE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_bridge_id); break; + case HWSETTINGS_RV_AUXPORT_MSP: + PIOS_Board_configure_com(&pios_usart_aux_cfg, PIOS_COM_MSP_RX_BUF_LEN, PIOS_COM_MSP_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_msp_id); + break; + case HWSETTINGS_RV_AUXPORT_MAVLINK: + PIOS_Board_configure_com(&pios_usart_aux_cfg, 0, PIOS_COM_MAVLINK_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_mavlink_id); + break; case HWSETTINGS_RV_AUXPORT_OSDHK: PIOS_Board_configure_com(&pios_usart_hkosd_aux_cfg, PIOS_COM_HKOSD_RX_BUF_LEN, PIOS_COM_HKOSD_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_hkosd_id); break; @@ -738,6 +782,12 @@ void PIOS_Board_Init(void) case HWSETTINGS_RV_AUXSBUSPORT_COMBRIDGE: PIOS_Board_configure_com(&pios_usart_auxsbus_cfg, PIOS_COM_BRIDGE_RX_BUF_LEN, PIOS_COM_BRIDGE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_bridge_id); break; + case HWSETTINGS_RV_AUXSBUSPORT_MSP: + PIOS_Board_configure_com(&pios_usart_auxsbus_cfg, PIOS_COM_MSP_RX_BUF_LEN, PIOS_COM_MSP_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_msp_id); + break; + case HWSETTINGS_RV_AUXSBUSPORT_MAVLINK: + PIOS_Board_configure_com(&pios_usart_auxsbus_cfg, 0, PIOS_COM_MAVLINK_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_mavlink_id); + break; case HWSETTINGS_RV_AUXSBUSPORT_OSDHK: PIOS_Board_configure_com(&pios_usart_hkosd_auxsbus_cfg, PIOS_COM_HKOSD_RX_BUF_LEN, PIOS_COM_HKOSD_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_hkosd_id); break; @@ -753,14 +803,39 @@ void PIOS_Board_Init(void) break; case HWSETTINGS_RV_FLEXIPORT_I2C: #if defined(PIOS_INCLUDE_I2C) - { - if (PIOS_I2C_Init(&pios_i2c_flexiport_adapter_id, &pios_i2c_flexiport_adapter_cfg)) { - PIOS_Assert(0); - } + if (PIOS_I2C_Init(&pios_i2c_flexiport_adapter_id, &pios_i2c_flexiport_adapter_cfg)) { + PIOS_Assert(0); } + PIOS_DELAY_WaitmS(50); // this was after the other PIOS_I2C_Init(), so I copied it here too +#ifdef PIOS_INCLUDE_WDG + // give HMC5x83 on I2C some extra time to allow for reset, etc. if needed + // this is not in a loop, so it is safe + // leave this here even if PIOS_INCLUDE_HMC5X83 is undefined + // to avoid making something else fail when HMC5X83 is removed + PIOS_WDG_Clear(); +#endif /* PIOS_INCLUDE_WDG */ +#if defined(PIOS_INCLUDE_HMC5X83) + // get auxmag type + AuxMagSettingsTypeOptions option; + AuxMagSettingsInitialize(); + AuxMagSettingsTypeGet(&option); + // if the aux mag type is FlexiPort then set it up + if (option == AUXMAGSETTINGS_TYPE_FLEXI) { + // attach the 5x83 mag to the previously inited I2C2 + external_mag = PIOS_HMC5x83_Init(&pios_hmc5x83_external_cfg, pios_i2c_flexiport_adapter_id, 0); +#ifdef PIOS_INCLUDE_WDG + // give HMC5x83 on I2C some extra time to allow for reset, etc. if needed + // this is not in a loop, so it is safe + PIOS_WDG_Clear(); +#endif /* PIOS_INCLUDE_WDG */ + // add this sensor to the sensor task's list + PIOS_HMC5x83_Register(external_mag, PIOS_SENSORS_TYPE_3AXIS_AUXMAG); + // mag alarm is cleared later, so use I2C + AlarmsSet(SYSTEMALARMS_ALARM_I2C, (external_mag) ? SYSTEMALARMS_ALARM_OK : SYSTEMALARMS_ALARM_WARNING); + } +#endif /* PIOS_INCLUDE_HMC5X83 */ #endif /* PIOS_INCLUDE_I2C */ break; - case HWSETTINGS_RV_FLEXIPORT_DSM: // TODO: Define the various Channelgroup for Revo dsm inputs and handle here PIOS_Board_configure_dsm(&pios_usart_dsm_flexi_cfg, &pios_dsm_flexi_cfg, @@ -772,6 +847,12 @@ void PIOS_Board_Init(void) case HWSETTINGS_RV_FLEXIPORT_COMBRIDGE: PIOS_Board_configure_com(&pios_usart_flexi_cfg, PIOS_COM_BRIDGE_RX_BUF_LEN, PIOS_COM_BRIDGE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_bridge_id); break; + case HWSETTINGS_RV_FLEXIPORT_MSP: + PIOS_Board_configure_com(&pios_usart_flexi_cfg, PIOS_COM_MSP_RX_BUF_LEN, PIOS_COM_MSP_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_msp_id); + break; + case HWSETTINGS_RV_FLEXIPORT_MAVLINK: + PIOS_Board_configure_com(&pios_usart_flexi_cfg, 0, PIOS_COM_MAVLINK_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_mavlink_id); + break; } /* hwsettings_rv_flexiport */ @@ -879,10 +960,12 @@ void PIOS_Board_Init(void) PIOS_DEBUG_Init(pios_tim_servoport_all_pins, NELEMENTS(pios_tim_servoport_all_pins)); #endif + // init I2C1 for use with the internal mag if (PIOS_I2C_Init(&pios_i2c_mag_adapter_id, &pios_i2c_mag_adapter_cfg)) { PIOS_DEBUG_Assert(0); } + // init I2C1 for use with the internal baro if (PIOS_I2C_Init(&pios_i2c_pressure_adapter_id, &pios_i2c_pressure_adapter_cfg)) { PIOS_DEBUG_Assert(0); } @@ -893,9 +976,24 @@ void PIOS_Board_Init(void) PIOS_ADC_Init(&pios_adc_cfg); #endif +#ifdef PIOS_INCLUDE_WDG + // give HMC5x83 on I2C some extra time to allow for reset, etc. if needed + // this is not in a loop, so it is safe + // leave this here even if PIOS_INCLUDE_HMC5X83 is undefined + // to avoid making something else fail when HMC5X83 is removed + PIOS_WDG_Clear(); +#endif /* PIOS_INCLUDE_WDG */ + #if defined(PIOS_INCLUDE_HMC5X83) - onboard_mag = PIOS_HMC5x83_Init(&pios_hmc5x83_cfg, pios_i2c_mag_adapter_id, 0); - PIOS_HMC5x83_Register(onboard_mag); + // attach the 5x83 mag to the previously inited I2C1 + onboard_mag = PIOS_HMC5x83_Init(&pios_hmc5x83_internal_cfg, pios_i2c_mag_adapter_id, 0); +#ifdef PIOS_INCLUDE_WDG + // give HMC5x83 on I2C some extra time to allow for reset, etc. if needed + // this is not in a loop, so it is safe + PIOS_WDG_Clear(); +#endif /* PIOS_INCLUDE_WDG */ + // add this sensor to the sensor task's list + PIOS_HMC5x83_Register(onboard_mag, PIOS_SENSORS_TYPE_3AXIS_MAG); #endif #if defined(PIOS_INCLUDE_MS5611) diff --git a/flight/targets/boards/revoproto/firmware/revolution.cpp b/flight/targets/boards/revoproto/firmware/revolution.cpp index 268325b26..8c5bbf28c 100644 --- a/flight/targets/boards/revoproto/firmware/revolution.cpp +++ b/flight/targets/boards/revoproto/firmware/revolution.cpp @@ -1,17 +1,18 @@ /** ****************************************************************************** - * @addtogroup OpenPilotSystem OpenPilot System - * @brief These files are the core system files of OpenPilot. - * They are the ground layer just above PiOS. In practice, OpenPilot actually starts - * in the main() function of openpilot.c + * @addtogroup LibrePilotSystem LibrePilot System + * @brief These files are the core system files for Revolution. + * They are the ground layer just above PiOS. In practice, Revolution actually starts + * in the main() function of revolution.cpp * @{ - * @addtogroup OpenPilotCore OpenPilot Core - * @brief This is where the OP firmware starts. Those files also define the compile-time + * @addtogroup LibrePilotCore LibrePilot Core + * @brief This is where the LP firmware starts. Those files also define the compile-time * options of the firmware. * @{ - * @file openpilot.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @brief Sets up and runs main OpenPilot tasks. + * @file revolution.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2015 + * @brief Sets up and runs main tasks. * @see The GNU Public License (GPL) Version 3 * *****************************************************************************/ @@ -34,46 +35,12 @@ extern "C" { #include "inc/openpilot.h" #include +#include -/* Task Priorities */ -#define PRIORITY_TASK_HOOKS (tskIDLE_PRIORITY + 3) /* Global Variables */ /* Local Variables */ -#define INCLUDE_TEST_TASKS 0 -#if INCLUDE_TEST_TASKS -static uint8_t sdcard_available; -#endif -char Buffer[1024]; -uint32_t Cache; - -/* Function Prototypes */ -#if INCLUDE_TEST_TASKS -static void TaskTick(void *pvParameters); -static void TaskTesting(void *pvParameters); -static void TaskHIDTest(void *pvParameters); -static void TaskServos(void *pvParameters); -static void TaskSDCard(void *pvParameters); -#endif -int32_t CONSOLE_Parse(uint8_t port, char c); -void OP_ADC_NotifyChange(uint32_t pin, uint32_t pin_value); - -/* Prototype of PIOS_Board_Init() function */ -extern void PIOS_Board_Init(void); -extern void Stack_Change(void); -static void Stack_Change_Weak() __attribute__((weakref("Stack_Change"))); - -/* Local Variables */ -#define INIT_TASK_PRIORITY (tskIDLE_PRIORITY + configMAX_PRIORITIES - 1) // max priority -#define INIT_TASK_STACK (1024 / 4) // XXX this seems excessive -static xTaskHandle initTaskHandle; - -/* Function Prototypes */ -static void initTask(void *parameters); - -/* Prototype of generated InitModules() function */ -extern void InitModules(void); } /** @@ -87,8 +54,6 @@ extern void InitModules(void); */ int main() { - int result; - /* NOTE: Do NOT modify the following start-up sequence */ /* Any new initialization functions should be added in OpenPilotInit() */ vPortInitialiseBlocks(); @@ -96,12 +61,7 @@ int main() /* Brings up System using CMSIS functions, enables the LEDs. */ PIOS_SYS_Init(); - /* For Revolution we use a FreeRTOS task to bring up the system so we can */ - /* always rely on FreeRTOS primitive */ - result = xTaskCreate(initTask, "init", - INIT_TASK_STACK, NULL, INIT_TASK_PRIORITY, - &initTaskHandle); - PIOS_Assert(result == pdPASS); + SystemModStart(); /* Start the FreeRTOS scheduler */ vTaskStartScheduler(); @@ -117,22 +77,7 @@ int main() return 0; } -/** - * Initialisation task. - * - * Runs board and module initialisation, then terminates. - */ -void initTask(__attribute__((unused)) void *parameters) -{ - /* board driver init */ - PIOS_Board_Init(); - /* Initialize modules */ - MODULE_INITIALISE_ALL; - - /* terminate this task */ - vTaskDelete(NULL); -} /** * @} diff --git a/flight/targets/boards/revoproto/pios_board.h b/flight/targets/boards/revoproto/pios_board.h index 30cab6600..60572cdc7 100644 --- a/flight/targets/boards/revoproto/pios_board.h +++ b/flight/targets/boards/revoproto/pios_board.h @@ -126,6 +126,9 @@ extern uint32_t pios_com_telem_usb_id; extern uint32_t pios_com_bridge_id; extern uint32_t pios_com_vcp_id; extern uint32_t pios_com_hkosd_id; +extern uint32_t pios_com_msp_id; +extern uint32_t pios_com_mavlink_id; + #define PIOS_COM_AUX (pios_com_aux_id) #define PIOS_COM_GPS (pios_com_gps_id) #define PIOS_COM_TELEM_USB (pios_com_telem_usb_id) @@ -134,6 +137,8 @@ extern uint32_t pios_com_hkosd_id; #define PIOS_COM_VCP (pios_com_vcp_id) #define PIOS_COM_DEBUG PIOS_COM_AUX #define PIOS_COM_OSDHK (pios_com_hkosd_id) +#define PIOS_COM_MSP (pios_com_msp_id) +#define PIOS_COM_MAVLINK (pios_com_mavlink_id) // ------------------------ // TELEMETRY @@ -194,7 +199,7 @@ extern uint32_t pios_com_hkosd_id; // Receiver PPM input // ------------------------- #define PIOS_PPM_MAX_DEVS 1 -#define PIOS_PPM_NUM_INPUTS 12 +#define PIOS_PPM_NUM_INPUTS 16 // ------------------------- // Receiver PWM input diff --git a/flight/targets/boards/simposix/firmware/Makefile b/flight/targets/boards/simposix/firmware/Makefile index bd55a7f4a..1849b9740 100644 --- a/flight/targets/boards/simposix/firmware/Makefile +++ b/flight/targets/boards/simposix/firmware/Makefile @@ -2,6 +2,7 @@ # # TODO: This file should be reworked. It will be done as a part of sim target refactoring. # +# Copyright (C) 2015-2016 The LibrePilot Project, http://www.librepilot.org # The OpenPilot Team, http://www.openpilot.org, Copyright (C) 2009. # # @@ -49,6 +50,8 @@ MODULES += Airspeed SRC += $(FLIGHTLIB)/notification.c +OPTMODULES += AutoTune + # Paths OPSYSTEM = . BOARDINC = .. @@ -323,31 +326,31 @@ endif # Link: create ELF output file from object files. -$(eval $(call LINK_CXX_TEMPLATE, $(OUTDIR)/$(TARGET).elf, $(ALLOBJ))) +$(eval $(call LINK_CXX_TEMPLATE,$(OUTDIR)/$(TARGET).elf,$(ALLOBJ))) # Assemble: create object files from assembler source files. -$(foreach src, $(ASRC), $(eval $(call ASSEMBLE_TEMPLATE, $(src)))) +$(foreach src, $(ASRC), $(eval $(call ASSEMBLE_TEMPLATE,$(src)))) # Assemble: create object files from assembler source files. ARM-only -$(foreach src, $(ASRCARM), $(eval $(call ASSEMBLE_ARM_TEMPLATE, $(src)))) +$(foreach src, $(ASRCARM), $(eval $(call ASSEMBLE_ARM_TEMPLATE,$(src)))) # Compile: create object files from C source files. -$(foreach src, $(SRC), $(eval $(call COMPILE_C_TEMPLATE, $(src)))) +$(foreach src, $(SRC), $(eval $(call COMPILE_C_TEMPLATE,$(src)))) # Compile: create object files from C source files. ARM-only -$(foreach src, $(SRCARM), $(eval $(call COMPILE_C_ARM_TEMPLATE, $(src)))) +$(foreach src, $(SRCARM), $(eval $(call COMPILE_C_ARM_TEMPLATE,$(src)))) # Compile: create object files from C++ source files. -$(foreach src, $(CPPSRC), $(eval $(call COMPILE_CXX_TEMPLATE, $(src)))) +$(foreach src, $(CPPSRC), $(eval $(call COMPILE_CXX_TEMPLATE,$(src)))) # Compile: create object files from C++ source files. ARM-only -$(foreach src, $(CPPSRCARM), $(eval $(call COMPILE_CPP_ARM_TEMPLATE, $(src)))) +$(foreach src, $(CPPSRCARM), $(eval $(call COMPILE_CPP_ARM_TEMPLATE,$(src)))) # Compile: create assembler files from C source files. ARM/Thumb -$(eval $(call PARTIAL_COMPILE_TEMPLATE, SRC)) +$(eval $(call PARTIAL_COMPILE_TEMPLATE,SRC)) # Compile: create assembler files from C source files. ARM only -$(eval $(call PARTIAL_COMPILE_ARM_TEMPLATE, SRCARM)) +$(eval $(call PARTIAL_COMPILE_ARM_TEMPLATE,SRCARM)) $(OUTDIR)/$(TARGET).bin.o: $(OUTDIR)/$(TARGET).bin diff --git a/flight/targets/boards/simposix/firmware/UAVObjects.inc b/flight/targets/boards/simposix/firmware/UAVObjects.inc index 928a1c0dc..52093b2e9 100644 --- a/flight/targets/boards/simposix/firmware/UAVObjects.inc +++ b/flight/targets/boards/simposix/firmware/UAVObjects.inc @@ -3,6 +3,7 @@ # # Makefile for OpenPilot UAVObject code # +# Copyright (C) 2016, The LibrePilot Project, http://www.librepilot.org # The OpenPilot Team, http://www.openpilot.org, Copyright (C) 2011. # # This program is free software; you can redistribute it and/or modify @@ -119,6 +120,9 @@ UAVOBJSRCFILENAMES += altitudeholdstatus UAVOBJSRCFILENAMES += ekfconfiguration UAVOBJSRCFILENAMES += ekfstatevariance UAVOBJSRCFILENAMES += takeofflocation +# UAVOBJSRCFILENAMES += perfcounter +UAVOBJSRCFILENAMES += systemidentsettings +UAVOBJSRCFILENAMES += systemidentstate UAVOBJSRC = $(foreach UAVOBJSRCFILE,$(UAVOBJSRCFILENAMES),$(FLIGHT_UAVOBJ_DIR)/$(UAVOBJSRCFILE).c ) UAVOBJDEFINE = $(foreach UAVOBJSRCFILE,$(UAVOBJSRCFILENAMES),-DUAVOBJ_INIT_$(UAVOBJSRCFILE) ) diff --git a/flight/targets/boards/simposix/firmware/pios_board.c b/flight/targets/boards/simposix/firmware/pios_board.c index 19799d2d4..68ba9491a 100644 --- a/flight/targets/boards/simposix/firmware/pios_board.c +++ b/flight/targets/boards/simposix/firmware/pios_board.c @@ -79,9 +79,9 @@ uintptr_t pios_uavo_settings_fs_id; uintptr_t pios_user_fs_id; /* - * Setup a com port based on the passed cfg, driver and buffer sizes. tx size of -1 make the port rx only + * Setup a com port based on the passed cfg, driver and buffer sizes. tx size = 0 make the port rx only */ -static void PIOS_Board_configure_com(const struct pios_udp_cfg *usart_port_cfg, size_t rx_buf_len, size_t tx_buf_len, +static void PIOS_Board_configure_com(const struct pios_udp_cfg *usart_port_cfg, uint16_t rx_buf_len, uint16_t tx_buf_len, const struct pios_com_driver *com_driver, uint32_t *pios_com_id) { uint32_t pios_usart_id; @@ -92,7 +92,7 @@ static void PIOS_Board_configure_com(const struct pios_udp_cfg *usart_port_cfg, uint8_t *rx_buffer = (uint8_t *)pvPortMalloc(rx_buf_len); PIOS_Assert(rx_buffer); - if (tx_buf_len != -1) { // this is the case for rx/tx ports + if (tx_buf_len > 0) { // this is the case for rx/tx ports uint8_t *tx_buffer = (uint8_t *)pvPortMalloc(tx_buf_len); PIOS_Assert(tx_buffer); @@ -180,7 +180,7 @@ void PIOS_Board_Init(void) break; case HWSETTINGS_RV_GPSPORT_GPS: - PIOS_Board_configure_com(&pios_udp_gps_cfg, PIOS_COM_GPS_RX_BUF_LEN, -1, &pios_udp_com_driver, &pios_com_gps_id); + PIOS_Board_configure_com(&pios_udp_gps_cfg, PIOS_COM_GPS_RX_BUF_LEN, 0, &pios_udp_com_driver, &pios_com_gps_id); break; case HWSETTINGS_RV_GPSPORT_COMAUX: diff --git a/flight/targets/boards/simposix/firmware/simposix.cpp b/flight/targets/boards/simposix/firmware/simposix.cpp index 69e53de79..f050ca317 100644 --- a/flight/targets/boards/simposix/firmware/simposix.cpp +++ b/flight/targets/boards/simposix/firmware/simposix.cpp @@ -1,17 +1,18 @@ /** ****************************************************************************** - * @addtogroup OpenPilotSystem OpenPilot System - * @brief These files are the core system files of OpenPilot. - * They are the ground layer just above PiOS. In practice, OpenPilot actually starts - * in the main() function of openpilot.c + * @addtogroup LibrePilotSystem LibrePilot System + * @brief These files are the core system files for Simposix. + * They are the ground layer just above PiOS. In practice, Simposix actually starts + * in the main() function of simposix.c * @{ - * @addtogroup OpenPilotCore OpenPilot Core - * @brief This is where the OP firmware starts. Those files also define the compile-time + * @addtogroup LibrePilotCore LibrePilot Core + * @brief This is where the LP firmware starts. Those files also define the compile-time * options of the firmware. * @{ - * @file openpilot.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @brief Sets up and runs main OpenPilot tasks. + * @file simposix.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2015 + * @brief Sets up and runs main tasks. * @see The GNU Public License (GPL) Version 3 * *****************************************************************************/ @@ -35,46 +36,7 @@ extern "C" { #include "inc/openpilot.h" #include #include - -/* Task Priorities */ -#define PRIORITY_TASK_HOOKS (tskIDLE_PRIORITY + 3) - -/* Global Variables */ - -/* Local Variables */ -#define INCLUDE_TEST_TASKS 0 -#if INCLUDE_TEST_TASKS -static uint8_t sdcard_available; -#endif -char Buffer[1024]; -uint32_t Cache; - -/* Function Prototypes */ -#if INCLUDE_TEST_TASKS -static void TaskTick(void *pvParameters); -static void TaskTesting(void *pvParameters); -static void TaskHIDTest(void *pvParameters); -static void TaskServos(void *pvParameters); -static void TaskSDCard(void *pvParameters); -#endif -int32_t CONSOLE_Parse(uint8_t port, char c); -void OP_ADC_NotifyChange(uint32_t pin, uint32_t pin_value); - -/* Prototype of PIOS_Board_Init() function */ -extern void PIOS_Board_Init(void); -extern void Stack_Change(void); -static void Stack_Change_Weak() __attribute__((weakref("Stack_Change"))); - -/* Local Variables */ -#define INIT_TASK_PRIORITY (tskIDLE_PRIORITY + configMAX_PRIORITIES - 1) // max priority -#define INIT_TASK_STACK (1024 / 4) // XXX this seems excessive -static xTaskHandle initTaskHandle; - -/* Function Prototypes */ -static void initTask(void *parameters); - -/* Prototype of generated InitModules() function */ -extern void InitModules(void); +#include } /** @@ -88,20 +50,10 @@ extern void InitModules(void); */ int main() { - int result; - - /* NOTE: Do NOT modify the following start-up sequence */ - /* Any new initialization functions should be added in OpenPilotInit() */ - /* Brings up System using CMSIS functions, enables the LEDs. */ PIOS_SYS_Init(); - /* For Revolution we use a FreeRTOS task to bring up the system so we can */ - /* always rely on FreeRTOS primitive */ - result = xTaskCreate(initTask, "init", - INIT_TASK_STACK, NULL, INIT_TASK_PRIORITY, - &initTaskHandle); - PIOS_Assert(result == pdPASS); + SystemModStart(); /* Start the FreeRTOS scheduler */ vTaskStartScheduler(); @@ -117,22 +69,6 @@ int main() return 0; } -/** - * Initialisation task. - * - * Runs board and module initialisation, then terminates. - */ -void initTask(__attribute__((unused)) void *parameters) -{ - /* board driver init */ - PIOS_Board_Init(); - - /* Initialize modules */ - MODULE_INITIALISE_ALL; - - /* terminate this task */ - vTaskDelete(NULL); -} /** * @} diff --git a/flight/targets/boards/sparky2/board-info.mk b/flight/targets/boards/sparky2/board-info.mk new file mode 100644 index 000000000..8e1b85744 --- /dev/null +++ b/flight/targets/boards/sparky2/board-info.mk @@ -0,0 +1,47 @@ +BOARD_TYPE := 0x92 +BOARD_REVISION := 0x01 +BOOTLOADER_VERSION := 0x06 +HW_TYPE := 0x00 + +MCU := cortex-m4 +CHIP := STM32F405RGT +BOARD := STM32F4xx_RM +MODEL := HD +MODEL_SUFFIX := + +OPENOCD_JTAG_CONFIG := stlink-v2.cfg +OPENOCD_CONFIG := stm32f4xx.stlink.cfg + +# Flash memory map for Sparky2: +# Sector start size use +# 0 0x0800 0000 16k BL +# 1 0x0800 4000 16k BL +# 2 0x0800 8000 16k EE +# 3 0x0800 C000 16k EE +# 4 0x0801 0000 64k Unused +# 5 0x0802 0000 128k FW +# 6 0x0804 0000 128k FW +# 7 0x0806 0000 128k FW +# 8 0x0808 0000 128k Unused +# 9 0x080A 0000 128k Unused +# 10 0x080C 0000 128k Unused .. +# 11 0x080E 0000 128k Unused + +# Note: These must match the values in link_$(BOARD)_memory.ld +BL_BANK_BASE := 0x08000000 # Start of bootloader flash +BL_BANK_SIZE := 0x00008000 # Should include BD_INFO region + +# 16KB for settings storage + +EE_BANK_BASE := 0x08008000 # EEPROM storage area +EE_BANK_SIZE := 0x00008000 # Size of EEPROM storage area + +# Leave the remaining 64KB sectors for other uses + +FW_BANK_BASE := 0x08020000 # Start of firmware flash +FW_BANK_SIZE := 0x000A0000 # Should include FW_DESC_SIZE + +FW_DESC_SIZE := 0x00000064 + +OSCILLATOR_FREQ := 8000000 +SYSCLK_FREQ := 168000000 diff --git a/flight/targets/boards/sparky2/board_hw_defs.c b/flight/targets/boards/sparky2/board_hw_defs.c new file mode 100644 index 000000000..25afb14e2 --- /dev/null +++ b/flight/targets/boards/sparky2/board_hw_defs.c @@ -0,0 +1,1908 @@ +/** + **************************************************************************************** + * @file board_hw_defs.c + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. + * PhoenixPilot, http://github.com/PhoenixPilot, Copyright (C) 2012 + * @addtogroup OpenPilotSystem OpenPilot System + * @{ + * @addtogroup OpenPilotCore OpenPilot Core + * @{ + * @brief Defines board specific static initializers for hardware for the Sparky2 board. + ***************************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#if defined(PIOS_INCLUDE_LED) + +#include + +static const struct pios_gpio pios_leds_v2[] = { + [PIOS_LED_HEARTBEAT] = { + .pin = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_5, + .GPIO_Speed = GPIO_Speed_50MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, + .active_low = true + }, + [PIOS_LED_ALARM] = { + .pin = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_4, + .GPIO_Speed = GPIO_Speed_50MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, + .active_low = true + }, + // the other LED in the TL code is accessed this way + [PIOS_LED_LINK] = { + .pin = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_6, + .GPIO_Speed = GPIO_Speed_50MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, + .active_low = true + }, +#if (0 && defined(PIOS_RFM22B_DEBUG_ON_TELEM)) +// Revo hardware config + [PIOS_LED_D1] = { + .pin = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_13, + .GPIO_Speed = GPIO_Speed_50MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, + }, + [PIOS_LED_D2] = { + .pin = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_14, + .GPIO_Speed = GPIO_Speed_50MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, + }, + [PIOS_LED_D3] = { + .pin = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_15, + .GPIO_Speed = GPIO_Speed_50MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, + }, + [PIOS_LED_D4] = { + .pin = { + .gpio = GPIOC, + .init = { + .GPIO_Pin = GPIO_Pin_6, + .GPIO_Speed = GPIO_Speed_50MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, + }, +#endif /* (0 && defined(PIOS_RFM22B_DEBUG_ON_TELEM)) */ +}; + +static const struct pios_gpio_cfg pios_led_v2_cfg = { + .gpios = pios_leds_v2, + .num_gpios = NELEMENTS(pios_leds_v2), +}; + +const struct pios_gpio_cfg *PIOS_BOARD_HW_DEFS_GetLedCfg(__attribute__((unused)) uint32_t board_revision) +{ + return &pios_led_v2_cfg; +} + +#endif /* PIOS_INCLUDE_LED */ + +#if defined(PIOS_INCLUDE_SPI) +#include + +/* + * SPI1 Interface + * Used for MPU9250 gyro, accelerometer and mag + */ +void PIOS_SPI_gyro_irq_handler(void); +void DMA2_Stream0_IRQHandler(void) __attribute__((alias("PIOS_SPI_gyro_irq_handler"))); +void DMA2_Stream3_IRQHandler(void) __attribute__((alias("PIOS_SPI_gyro_irq_handler"))); +static const struct pios_spi_cfg pios_spi_gyro_cfg = { + .regs = SPI1, + .remap = GPIO_AF_SPI1, + .init = { + .SPI_Mode = SPI_Mode_Master, + .SPI_Direction = SPI_Direction_2Lines_FullDuplex, + .SPI_DataSize = SPI_DataSize_8b, + .SPI_NSS = SPI_NSS_Soft, + .SPI_FirstBit = SPI_FirstBit_MSB, + .SPI_CRCPolynomial = 7, + .SPI_CPOL = SPI_CPOL_High, + .SPI_CPHA = SPI_CPHA_2Edge, + .SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16, + }, + .use_crc = false, + .dma = { + .irq = { + .flags = (DMA_IT_TCIF0 | DMA_IT_TEIF0 | DMA_IT_HTIF0), + .init = { + .NVIC_IRQChannel = DMA2_Stream0_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + + .rx = { + .channel = DMA2_Stream0, + .init = { + .DMA_Channel = DMA_Channel_3, + .DMA_PeripheralBaseAddr = (uint32_t)&(SPI1->DR), + .DMA_DIR = DMA_DIR_PeripheralToMemory, + .DMA_PeripheralInc = DMA_PeripheralInc_Disable, + .DMA_MemoryInc = DMA_MemoryInc_Enable, + .DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte, + .DMA_MemoryDataSize = DMA_MemoryDataSize_Byte, + .DMA_Mode = DMA_Mode_Normal, + .DMA_Priority = DMA_Priority_Medium, + .DMA_FIFOMode = DMA_FIFOMode_Disable, + /* .DMA_FIFOThreshold */ + .DMA_MemoryBurst = DMA_MemoryBurst_Single, + .DMA_PeripheralBurst = DMA_PeripheralBurst_Single, + }, + }, + .tx = { + .channel = DMA2_Stream3, + .init = { + .DMA_Channel = DMA_Channel_3, + .DMA_PeripheralBaseAddr = (uint32_t)&(SPI1->DR), + .DMA_DIR = DMA_DIR_MemoryToPeripheral, + .DMA_PeripheralInc = DMA_PeripheralInc_Disable, + .DMA_MemoryInc = DMA_MemoryInc_Enable, + .DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte, + .DMA_MemoryDataSize = DMA_MemoryDataSize_Byte, + .DMA_Mode = DMA_Mode_Normal, + .DMA_Priority = DMA_Priority_High, + .DMA_FIFOMode = DMA_FIFOMode_Disable, + /* .DMA_FIFOThreshold */ + .DMA_MemoryBurst = DMA_MemoryBurst_Single, + .DMA_PeripheralBurst = DMA_PeripheralBurst_Single, + }, + }, + }, + .sclk = { + .gpio = GPIOA, + .init = { + .GPIO_Pin = GPIO_Pin_5, + .GPIO_Speed = GPIO_Speed_100MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, + .miso = { + .gpio = GPIOA, + .init = { + .GPIO_Pin = GPIO_Pin_6, + .GPIO_Speed = GPIO_Speed_50MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, + .mosi = { + .gpio = GPIOA, + .init = { + .GPIO_Pin = GPIO_Pin_7, + .GPIO_Speed = GPIO_Speed_50MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, + .slave_count = 1, + .ssel = { + { + .gpio = GPIOC, + .init = { + .GPIO_Pin = GPIO_Pin_4, + .GPIO_Speed = GPIO_Speed_50MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + } + } + } +}; + +static uint32_t pios_spi_gyro_id; +void PIOS_SPI_gyro_irq_handler(void) +{ + /* Call into the generic code to handle the IRQ for this specific device */ + PIOS_SPI_IRQ_Handler(pios_spi_gyro_id); +} + + +/* + * SPI3 Interface + * Used for Flash and the RFM22B + */ +void PIOS_SPI_telem_flash_irq_handler(void); +void DMA1_Stream0_IRQHandler(void) __attribute__((alias("PIOS_SPI_telem_flash_irq_handler"))); +void DMA1_Stream5_IRQHandler(void) __attribute__((alias("PIOS_SPI_telem_flash_irq_handler"))); +static const struct pios_spi_cfg pios_spi_telem_flash_cfg = { + .regs = SPI3, + .remap = GPIO_AF_SPI3, + .init = { + .SPI_Mode = SPI_Mode_Master, + .SPI_Direction = SPI_Direction_2Lines_FullDuplex, + .SPI_DataSize = SPI_DataSize_8b, + .SPI_NSS = SPI_NSS_Soft, + .SPI_FirstBit = SPI_FirstBit_MSB, + .SPI_CRCPolynomial = 7, + .SPI_CPOL = SPI_CPOL_Low, + .SPI_CPHA = SPI_CPHA_1Edge, + .SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8, + }, + .use_crc = false, + .dma = { + .irq = { + // Note this is the stream ID that triggers interrupts (in this case RX) + .flags = (DMA_IT_TCIF0 | DMA_IT_TEIF0 | DMA_IT_HTIF0), + .init = { + .NVIC_IRQChannel = DMA1_Stream0_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + + .rx = { + .channel = DMA1_Stream0, + .init = { + .DMA_Channel = DMA_Channel_0, + .DMA_PeripheralBaseAddr = (uint32_t)&(SPI3->DR), + .DMA_DIR = DMA_DIR_PeripheralToMemory, + .DMA_PeripheralInc = DMA_PeripheralInc_Disable, + .DMA_MemoryInc = DMA_MemoryInc_Enable, + .DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte, + .DMA_MemoryDataSize = DMA_MemoryDataSize_Byte, + .DMA_Mode = DMA_Mode_Normal, + .DMA_Priority = DMA_Priority_Medium, + // TODO: Enable FIFO + .DMA_FIFOMode = DMA_FIFOMode_Disable, + .DMA_FIFOThreshold = DMA_FIFOThreshold_Full, + .DMA_MemoryBurst = DMA_MemoryBurst_Single, + .DMA_PeripheralBurst = DMA_PeripheralBurst_Single, + }, + }, + .tx = { + .channel = DMA1_Stream5, + .init = { + .DMA_Channel = DMA_Channel_0, + .DMA_PeripheralBaseAddr = (uint32_t)&(SPI3->DR), + .DMA_DIR = DMA_DIR_MemoryToPeripheral, + .DMA_PeripheralInc = DMA_PeripheralInc_Disable, + .DMA_MemoryInc = DMA_MemoryInc_Enable, + .DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte, + .DMA_MemoryDataSize = DMA_MemoryDataSize_Byte, + .DMA_Mode = DMA_Mode_Normal, + .DMA_Priority = DMA_Priority_Medium, + .DMA_FIFOMode = DMA_FIFOMode_Disable, + .DMA_FIFOThreshold = DMA_FIFOThreshold_Full, + .DMA_MemoryBurst = DMA_MemoryBurst_Single, + .DMA_PeripheralBurst = DMA_PeripheralBurst_Single, + }, + }, + }, + .sclk = { + .gpio = GPIOC, + .init = { + .GPIO_Pin = GPIO_Pin_10, + .GPIO_Speed = GPIO_Speed_100MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_NOPULL + }, + }, + .miso = { + .gpio = GPIOC, + .init = { + .GPIO_Pin = GPIO_Pin_11, + .GPIO_Speed = GPIO_Speed_50MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_NOPULL + }, + }, + .mosi = { + .gpio = GPIOC, + .init = { + .GPIO_Pin = GPIO_Pin_12, + .GPIO_Speed = GPIO_Speed_50MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_NOPULL + }, + }, + .slave_count = 2, + .ssel = { + { // RFM22b + .gpio = GPIOA, + .init = { + .GPIO_Pin = GPIO_Pin_15, + .GPIO_Speed = GPIO_Speed_50MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + } + }, + { // Flash + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_3, + .GPIO_Speed = GPIO_Speed_50MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + } + }, + }, +}; + +uint32_t pios_spi_telem_flash_id; +void PIOS_SPI_telem_flash_irq_handler(void) +{ + /* Call into the generic code to handle the IRQ for this specific device */ + PIOS_SPI_IRQ_Handler(pios_spi_telem_flash_id); +} + + +#if defined(PIOS_INCLUDE_RFM22B) +#include + +static const struct pios_exti_cfg pios_exti_rfm22b_cfg __exti_config = { + .vector = PIOS_RFM22_EXT_Int, + .line = EXTI_Line2, + .pin = { + .gpio = GPIOD, + .init = { + .GPIO_Pin = GPIO_Pin_2, + .GPIO_Speed = GPIO_Speed_100MHz, + .GPIO_Mode = GPIO_Mode_IN, + .GPIO_OType = GPIO_OType_OD, + .GPIO_PuPd = GPIO_PuPd_NOPULL, + }, + }, + .irq = { + .init = { + .NVIC_IRQChannel = EXTI2_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_LOW, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .exti = { + .init = { + .EXTI_Line = EXTI_Line2, // matches above GPIO pin + .EXTI_Mode = EXTI_Mode_Interrupt, + .EXTI_Trigger = EXTI_Trigger_Falling, + .EXTI_LineCmd = ENABLE, + }, + }, +}; + +const struct pios_rfm22b_cfg pios_rfm22b_cfg = { + .spi_cfg = &pios_spi_telem_flash_cfg, + .exti_cfg = &pios_exti_rfm22b_cfg, + .RFXtalCap = 0x7f, + .slave_num = 0, + .gpio_direction = GPIO0_TX_GPIO1_RX, +}; + +const struct pios_rfm22b_cfg *PIOS_BOARD_HW_DEFS_GetRfm22Cfg(__attribute__((unused)) uint32_t board_revision) +{ + return &pios_rfm22b_cfg; +} + +#endif /* PIOS_INCLUDE_RFM22B */ + +#if defined(PIOS_INCLUDE_OPENLRS) + +#include + +static const struct pios_exti_cfg pios_exti_openlrs_cfg __exti_config = { + .vector = PIOS_OpenLRS_EXT_Int, + .line = EXTI_Line2, + .pin = { + .gpio = GPIOD, + .init = { + .GPIO_Pin = GPIO_Pin_2, + .GPIO_Speed = GPIO_Speed_100MHz, + .GPIO_Mode = GPIO_Mode_IN, + .GPIO_OType = GPIO_OType_OD, + .GPIO_PuPd = GPIO_PuPd_NOPULL, + }, + }, + .irq = { + .init = { + .NVIC_IRQChannel = EXTI2_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_LOW, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .exti = { + .init = { + .EXTI_Line = EXTI_Line2, // matches above GPIO pin + .EXTI_Mode = EXTI_Mode_Interrupt, + .EXTI_Trigger = EXTI_Trigger_Falling, + .EXTI_LineCmd = ENABLE, + }, + }, +}; + +const struct pios_openlrs_cfg pios_openlrs_cfg = { + .spi_cfg = &pios_spi_telem_flash_cfg, + .exti_cfg = &pios_exti_openlrs_cfg, + .gpio_direction = GPIO0_TX_GPIO1_RX, +}; + +const struct pios_openlrs_cfg *PIOS_BOARD_HW_DEFS_GetOpenLRSCfg() +{ + return &pios_openlrs_cfg; +} + +#endif /* PIOS_INCLUDE_OPENLRS */ + + +#endif /* PIOS_INCLUDE_SPI */ + +#if defined(PIOS_INCLUDE_FLASH) +#include "pios_flashfs_logfs_priv.h" +#include "pios_flash_jedec_priv.h" +#include "pios_flash_internal_priv.h" + +static const struct flashfs_logfs_cfg flashfs_external_user_cfg = { + .fs_magic = 0x99abceff, + .total_fs_size = 0x001C0000, /* 2M bytes (32 sectors = entire chip) */ + .arena_size = 0x000E0000, /* biggest possible arena size fssize/2 */ + .slot_size = 0x00000100, /* 256 bytes */ + + .start_offset = 0x00040000, /* start offset */ + .sector_size = 0x00010000, /* 64K bytes */ + .page_size = 0x00000100, /* 256 bytes */ +}; + +static const struct flashfs_logfs_cfg flashfs_external_system_cfg = { + .fs_magic = 0x99bbcdef, + .total_fs_size = 0x00040000, /* 2M bytes (32 sectors = entire chip) */ + .arena_size = 0x00010000, /* 256 * slot size */ + .slot_size = 0x00000100, /* 256 bytes */ + + .start_offset = 0, /* start at the beginning of the chip */ + .sector_size = 0x00010000, /* 64K bytes */ + .page_size = 0x00000100, /* 256 bytes */ +}; + + +static const struct pios_flash_internal_cfg flash_internal_cfg = {}; + +static const struct flashfs_logfs_cfg flashfs_internal_cfg = { + .fs_magic = 0x99abcfef, + .total_fs_size = EE_BANK_SIZE, /* 32K bytes (2x16KB sectors) */ + .arena_size = 0x00004000, /* 64 * slot size = 16K bytes = 1 sector */ + .slot_size = 0x00000100, /* 256 bytes */ + + .start_offset = EE_BANK_BASE, /* start after the bootloader */ + .sector_size = 0x00004000, /* 16K bytes */ + .page_size = 0x00004000, /* 16K bytes */ +}; + +#endif /* PIOS_INCLUDE_FLASH */ + +#include + +#ifdef PIOS_INCLUDE_COM_TELEM + +/* + * MAIN PORT + */ +static const struct pios_usart_cfg pios_usart_main_cfg = { + .regs = USART1, + .remap = GPIO_AF_USART1, + .init = { + .USART_BaudRate = 57600, + .USART_WordLength = USART_WordLength_8b, + .USART_Parity = USART_Parity_No, + .USART_StopBits = USART_StopBits_1, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + .USART_Mode = USART_Mode_Rx | USART_Mode_Tx, + }, + .irq = { + .init = { + .NVIC_IRQChannel = USART1_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .rx = { + .gpio = GPIOA, + .init = { + .GPIO_Pin = GPIO_Pin_10, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, + .tx = { + .gpio = GPIOA, + .init = { + .GPIO_Pin = GPIO_Pin_9, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, +}; +#endif /* PIOS_INCLUDE_COM_TELEM */ + +#ifdef PIOS_INCLUDE_DSM + +#include "pios_dsm_priv.h" +static const struct pios_usart_cfg pios_usart_dsm_main_cfg = { + .regs = USART1, + .remap = GPIO_AF_USART1, + .init = { + .USART_BaudRate = 115200, + .USART_WordLength = USART_WordLength_8b, + .USART_Parity = USART_Parity_No, + .USART_StopBits = USART_StopBits_1, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + .USART_Mode = USART_Mode_Rx, + }, + .irq = { + .init = { + .NVIC_IRQChannel = USART1_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .rx = { + .gpio = GPIOA, + .init = { + .GPIO_Pin = GPIO_Pin_10, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, + .tx = { + .gpio = GPIOA, + .init = { + .GPIO_Pin = GPIO_Pin_9, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, +}; + +// Because of the inverter on the main port this will not +// work. Notice the mode is set to IN to maintain API +// compatibility but protect the pins +static const struct pios_dsm_cfg pios_dsm_main_cfg = { + .bind = { + .gpio = GPIOA, + .init = { + .GPIO_Pin = GPIO_Pin_10, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_IN, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_NOPULL + }, + }, +}; + +#endif /* PIOS_INCLUDE_DSM */ + +#ifdef PIOS_INCLUDE_COM_FLEXI +/* + * FLEXI PORT + */ +static const struct pios_usart_cfg pios_usart_flexi_cfg = { + .regs = USART3, + .remap = GPIO_AF_USART3, + .init = { + .USART_BaudRate = 57600, + .USART_WordLength = USART_WordLength_8b, + .USART_Parity = USART_Parity_No, + .USART_StopBits = USART_StopBits_1, + .USART_HardwareFlowControl = + USART_HardwareFlowControl_None, + .USART_Mode = USART_Mode_Rx | USART_Mode_Tx, + }, + .irq = { + .init = { + .NVIC_IRQChannel = USART3_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .rx = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_11, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, + .tx = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_10, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, +}; + +#endif /* PIOS_INCLUDE_COM_FLEXI */ + +#ifdef PIOS_INCLUDE_DSM + +#include "pios_dsm_priv.h" +static const struct pios_usart_cfg pios_usart_dsm_flexi_cfg = { + .regs = USART3, + .remap = GPIO_AF_USART3, + .init = { + .USART_BaudRate = 115200, + .USART_WordLength = USART_WordLength_8b, + .USART_Parity = USART_Parity_No, + .USART_StopBits = USART_StopBits_1, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + .USART_Mode = USART_Mode_Rx, + }, + .irq = { + .init = { + .NVIC_IRQChannel = USART3_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .rx = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_11, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, + .tx = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_10, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, +}; + +static const struct pios_dsm_cfg pios_dsm_flexi_cfg = { + .bind = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_11, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_NOPULL + }, + }, +}; + +#endif /* PIOS_INCLUDE_DSM */ + +#if defined(PIOS_INCLUDE_SRXL) +/* + * SRXL USART + */ +#include + +static const struct pios_usart_cfg pios_usart_srxl_flexi_cfg = { + .regs = USART3, + .remap = GPIO_AF_USART3, + .init = { + .USART_BaudRate = 115200, + .USART_WordLength = USART_WordLength_8b, + .USART_Parity = USART_Parity_No, + .USART_StopBits = USART_StopBits_1, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + .USART_Mode = USART_Mode_Rx, + }, + .irq = { + .init = { + .NVIC_IRQChannel = USART3_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .rx = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_11, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, + .tx = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_10, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, +}; + +static const struct pios_usart_cfg pios_usart_srxl_rcvr_cfg = { + .regs = USART6, + .remap = GPIO_AF_USART6, + .init = { + .USART_BaudRate = 115200, + .USART_WordLength = USART_WordLength_8b, + .USART_Parity = USART_Parity_No, + .USART_StopBits = USART_StopBits_1, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + .USART_Mode = USART_Mode_Rx, + }, + .irq = { + .init = { + .NVIC_IRQChannel = USART6_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .rx = { + .gpio = GPIOC, + .init = { + .GPIO_Pin = GPIO_Pin_7, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, +}; + +#endif /* PIOS_INCLUDE_SRXL */ + +#if defined(PIOS_INCLUDE_IBUS) +/* + * IBUS USART + */ +#include + +static const struct pios_usart_cfg pios_usart_ibus_flexi_cfg = { + .regs = USART3, + .remap = GPIO_AF_USART3, + .init = { + .USART_BaudRate = 115200, + .USART_WordLength = USART_WordLength_8b, + .USART_Parity = USART_Parity_No, + .USART_StopBits = USART_StopBits_1, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + .USART_Mode = USART_Mode_Rx, + }, + .irq = { + .init = { + .NVIC_IRQChannel = USART3_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .rx = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_11, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, + .tx = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_10, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, +}; + +static const struct pios_usart_cfg pios_usart_ibus_rcvr_cfg = { + .regs = USART6, + .remap = GPIO_AF_USART6, + .init = { + .USART_BaudRate = 115200, + .USART_WordLength = USART_WordLength_8b, + .USART_Parity = USART_Parity_No, + .USART_StopBits = USART_StopBits_1, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + .USART_Mode = USART_Mode_Rx, + }, + .irq = { + .init = { + .NVIC_IRQChannel = USART6_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .rx = { + .gpio = GPIOC, + .init = { + .GPIO_Pin = GPIO_Pin_7, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, +}; + +#endif /* PIOS_INCLUDE_IBUS */ + +// these were copied from Revo support +// they might need to be further modified for Sparky2 support +#if defined(PIOS_INCLUDE_HOTT) +/* + * HOTT USART + */ +#include + +static const struct pios_usart_cfg pios_usart_hott_flexi_cfg = { + .regs = USART3, + .remap = GPIO_AF_USART3, + .init = { + .USART_BaudRate = 115200, + .USART_WordLength = USART_WordLength_8b, + .USART_Parity = USART_Parity_No, + .USART_StopBits = USART_StopBits_1, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + .USART_Mode = USART_Mode_Rx, + }, + .irq = { + .init = { + .NVIC_IRQChannel = USART3_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .rx = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_11, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, + .tx = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_10, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, +}; + +static const struct pios_usart_cfg pios_usart_hott_rcvr_cfg = { + .regs = USART6, + .remap = GPIO_AF_USART6, + .init = { + .USART_BaudRate = 115200, + .USART_WordLength = USART_WordLength_8b, + .USART_Parity = USART_Parity_No, + .USART_StopBits = USART_StopBits_1, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + .USART_Mode = USART_Mode_Rx, + }, + .irq = { + .init = { + .NVIC_IRQChannel = USART6_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .rx = { + .gpio = GPIOC, + .init = { + .GPIO_Pin = GPIO_Pin_7, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, +}; + +#endif /* PIOS_INCLUDE_HOTT */ + +#if defined(PIOS_INCLUDE_EXBUS) +/* + * EXBUS USART + */ +#include + +static const struct pios_usart_cfg pios_usart_exbus_flexi_cfg = { + .regs = USART3, + .remap = GPIO_AF_USART3, + .init = { + .USART_BaudRate = 125000, + .USART_WordLength = USART_WordLength_8b, + .USART_Parity = USART_Parity_No, + .USART_StopBits = USART_StopBits_1, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + .USART_Mode = USART_Mode_Rx, + }, + .irq = { + .init = { + .NVIC_IRQChannel = USART3_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .rx = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_11, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, + .tx = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_10, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, +}; + +static const struct pios_usart_cfg pios_usart_exbus_rcvr_cfg = { + .regs = USART6, + .remap = GPIO_AF_USART6, + .init = { + .USART_BaudRate = 125000, + .USART_WordLength = USART_WordLength_8b, + .USART_Parity = USART_Parity_No, + .USART_StopBits = USART_StopBits_1, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + .USART_Mode = USART_Mode_Rx, + }, + .irq = { + .init = { + .NVIC_IRQChannel = USART6_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .rx = { + .gpio = GPIOC, + .init = { + .GPIO_Pin = GPIO_Pin_7, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, +}; + +#endif /* PIOS_INCLUDE_EXBUS */ + +/* + * HK OSD + */ +static const struct pios_usart_cfg pios_usart_hkosd_main_cfg = { + .regs = USART1, + .remap = GPIO_AF_USART1, + .init = { + .USART_BaudRate = 57600, + .USART_WordLength = USART_WordLength_8b, + .USART_Parity = USART_Parity_No, + .USART_StopBits = USART_StopBits_1, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + .USART_Mode = USART_Mode_Rx | USART_Mode_Tx, + }, + .irq = { + .init = { + .NVIC_IRQChannel = USART1_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .rx = { + .gpio = GPIOA, + .init = { + .GPIO_Pin = GPIO_Pin_10, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, + .tx = { + .gpio = GPIOA, + .init = { + .GPIO_Pin = GPIO_Pin_9, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, +}; + +static const struct pios_usart_cfg pios_usart_hkosd_flexi_cfg = { + .regs = USART3, + .remap = GPIO_AF_USART3, + .init = { + .USART_BaudRate = 57600, + .USART_WordLength = USART_WordLength_8b, + .USART_Parity = USART_Parity_No, + .USART_StopBits = USART_StopBits_1, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + .USART_Mode = USART_Mode_Rx | USART_Mode_Tx, + }, + .irq = { + .init = { + .NVIC_IRQChannel = USART3_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .rx = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_11, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, + .tx = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_10, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, +}; + + +/* + * RCVR PORT + */ + +#if defined(PIOS_INCLUDE_SBUS) +/* + * S.Bus USART + */ +#include + +static const struct pios_usart_cfg pios_usart_sbus_rcvr_cfg = { + .regs = USART6, + .remap = GPIO_AF_USART6, + .init = { + .USART_BaudRate = 100000, + .USART_WordLength = USART_WordLength_8b, + .USART_Parity = USART_Parity_Even, + .USART_StopBits = USART_StopBits_2, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + .USART_Mode = USART_Mode_Rx, + }, + .irq = { + .init = { + .NVIC_IRQChannel = USART6_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .rx = { + .gpio = GPIOC, + .init = { + .GPIO_Pin = GPIO_Pin_7, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, +}; + + +static const struct pios_sbus_cfg pios_sbus_cfg = { + /* Inverter configuration */ + .inv = { + .gpio = GPIOC, + .init = { + .GPIO_Pin = GPIO_Pin_6, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, + .gpio_inv_enable = Bit_SET, + .gpio_inv_disable = Bit_RESET, + .gpio_clk_func = RCC_AHB1PeriphClockCmd, + .gpio_clk_periph = RCC_AHB1Periph_GPIOC, +}; + +#endif /* PIOS_INCLUDE_SBUS */ + +#ifdef PIOS_INCLUDE_DSM + +// It looks like TL notes originally came from OP's pios_dsm_main_cfg +// (TL note) Because of the inverter on the main port this will not +// (TL note) work. Notice the mode is set to IN to maintain API +// (TL note) compatibility but protect the pins +static const struct pios_dsm_cfg pios_dsm_rcvr_cfg = { + .bind = { + .gpio = GPIOC, + .init = { + .GPIO_Pin = GPIO_Pin_7, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_NOPULL + }, + }, +}; + + +static const struct pios_usart_cfg pios_usart_dsm_rcvr_cfg = { + .regs = USART6, + .remap = GPIO_AF_USART6, + .init = { + .USART_BaudRate = 115200, + .USART_WordLength = USART_WordLength_8b, + .USART_Parity = USART_Parity_No, + .USART_StopBits = USART_StopBits_1, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + .USART_Mode = USART_Mode_Rx, + }, + .irq = { + .init = { + .NVIC_IRQChannel = USART6_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .rx = { + .gpio = GPIOC, + .init = { + .GPIO_Pin = GPIO_Pin_7, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP + }, + }, +}; + +#endif /* PIOS_INCLUDE_DSM */ + + +#if defined(PIOS_INCLUDE_COM) + +#include + +#endif /* PIOS_INCLUDE_COM */ + +#if defined(PIOS_INCLUDE_I2C) + +#include + +/* + * I2C Adapters + */ +void PIOS_i2c_mag_pressure_adapter_ev_irq_handler(void); +void PIOS_i2c_mag_pressure_adapter_er_irq_handler(void); +void I2C1_EV_IRQHandler() +__attribute__((alias("PIOS_i2c_mag_pressure_adapter_ev_irq_handler"))); +void I2C1_ER_IRQHandler() +__attribute__((alias("PIOS_i2c_mag_pressure_adapter_er_irq_handler"))); + +static const struct pios_i2c_adapter_cfg pios_i2c_mag_pressure_adapter_cfg = { + .regs = I2C1, + .remapSCL = GPIO_AF_I2C1, + .remapSDA = GPIO_AF_I2C1, + .init = { + .I2C_Mode = I2C_Mode_I2C, + .I2C_OwnAddress1 = 0, + .I2C_Ack = I2C_Ack_Enable, + .I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit, + .I2C_DutyCycle = I2C_DutyCycle_2, + .I2C_ClockSpeed = 400000, /* bits/s */ + }, + .transfer_timeout_ms = 50, + .scl = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_8, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_Speed = GPIO_Speed_50MHz, + .GPIO_OType = GPIO_OType_OD, + .GPIO_PuPd = GPIO_PuPd_UP, + }, + }, + .sda = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_9, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_Speed = GPIO_Speed_50MHz, + .GPIO_OType = GPIO_OType_OD, + .GPIO_PuPd = GPIO_PuPd_UP, + }, + }, + .event = { + .flags = 0, /* FIXME: check this */ + .init = { + .NVIC_IRQChannel = I2C1_EV_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGHEST, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .error = { + .flags = 0, /* FIXME: check this */ + .init = { + .NVIC_IRQChannel = I2C1_ER_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGHEST, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, +}; + +uint32_t pios_i2c_mag_pressure_adapter_id; +void PIOS_i2c_mag_pressure_adapter_ev_irq_handler(void) +{ + /* Call into the generic code to handle the IRQ for this specific device */ + PIOS_I2C_EV_IRQ_Handler(pios_i2c_mag_pressure_adapter_id); +} + +void PIOS_i2c_mag_pressure_adapter_er_irq_handler(void) +{ + /* Call into the generic code to handle the IRQ for this specific device */ + PIOS_I2C_ER_IRQ_Handler(pios_i2c_mag_pressure_adapter_id); +} + + +void PIOS_I2C_flexiport_adapter_ev_irq_handler(void); +void PIOS_I2C_flexiport_adapter_er_irq_handler(void); +void I2C2_EV_IRQHandler() __attribute__((alias("PIOS_I2C_flexiport_adapter_ev_irq_handler"))); +void I2C2_ER_IRQHandler() __attribute__((alias("PIOS_I2C_flexiport_adapter_er_irq_handler"))); + +static const struct pios_i2c_adapter_cfg pios_i2c_flexiport_adapter_cfg = { + .regs = I2C2, + .remapSCL = GPIO_AF_I2C2, + .remapSDA = GPIO_AF_I2C2, + .init = { + .I2C_Mode = I2C_Mode_I2C, + .I2C_OwnAddress1 = 0, + .I2C_Ack = I2C_Ack_Enable, + .I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit, + .I2C_DutyCycle = I2C_DutyCycle_2, + .I2C_ClockSpeed = 400000, /* bits/s */ + }, + .transfer_timeout_ms = 50, + .scl = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_10, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_Speed = GPIO_Speed_50MHz, + .GPIO_OType = GPIO_OType_OD, + .GPIO_PuPd = GPIO_PuPd_UP, + }, + }, + .sda = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_11, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_Speed = GPIO_Speed_50MHz, + .GPIO_OType = GPIO_OType_OD, + .GPIO_PuPd = GPIO_PuPd_UP, + }, + }, + .event = { + .flags = 0, /* FIXME: check this */ + .init = { + .NVIC_IRQChannel = I2C2_EV_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGHEST, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .error = { + .flags = 0, /* FIXME: check this */ + .init = { + .NVIC_IRQChannel = I2C2_ER_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGHEST, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, +}; + +uint32_t pios_i2c_flexiport_adapter_id; +void PIOS_I2C_flexiport_adapter_ev_irq_handler(void) +{ + /* Call into the generic code to handle the IRQ for this specific device */ + PIOS_I2C_EV_IRQ_Handler(pios_i2c_flexiport_adapter_id); +} + +void PIOS_I2C_flexiport_adapter_er_irq_handler(void) +{ + /* Call into the generic code to handle the IRQ for this specific device */ + PIOS_I2C_ER_IRQ_Handler(pios_i2c_flexiport_adapter_id); +} + + +void PIOS_i2c_mag_pressure_adapter_ev_irq_handler(void); +void PIOS_i2c_mag_pressure_adapter_er_irq_handler(void); + +#endif /* PIOS_INCLUDE_I2C */ + +#if defined(PIOS_INCLUDE_RTC) +/* + * Realtime Clock (RTC) + */ +#include + +void PIOS_RTC_IRQ_Handler(void); +void RTC_WKUP_IRQHandler() __attribute__((alias("PIOS_RTC_IRQ_Handler"))); +static const struct pios_rtc_cfg pios_rtc_main_cfg = { + .clksrc = RCC_RTCCLKSource_HSE_Div8, // Divide 8 Mhz crystal down to 1 + // For some reason it's acting like crystal is 16 Mhz. This clock is then divided + // by another 16 to give a nominal 62.5 khz clock + .prescaler = 100, // Every 100 cycles gives 625 Hz + .irq = { + .init = { + .NVIC_IRQChannel = RTC_WKUP_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, +}; + +void PIOS_RTC_IRQ_Handler(void) +{ + PIOS_RTC_irq_handler(); +} + +#endif /* if defined(PIOS_INCLUDE_RTC) */ + +#include "pios_tim_priv.h" + +static const TIM_TimeBaseInitTypeDef tim_3_5_time_base = { + .TIM_Prescaler = (PIOS_PERIPHERAL_APB1_CLOCK / 1000000) - 1, + .TIM_ClockDivision = TIM_CKD_DIV1, + .TIM_CounterMode = TIM_CounterMode_Up, + .TIM_Period = ((1000000 / PIOS_SERVO_UPDATE_HZ) - 1), + .TIM_RepetitionCounter = 0x0000, +}; +static const TIM_TimeBaseInitTypeDef tim_9_10_11_time_base = { + .TIM_Prescaler = (PIOS_PERIPHERAL_APB2_CLOCK / 1000000) - 1, + .TIM_ClockDivision = TIM_CKD_DIV1, + .TIM_CounterMode = TIM_CounterMode_Up, + .TIM_Period = ((1000000 / PIOS_SERVO_UPDATE_HZ) - 1), + .TIM_RepetitionCounter = 0x0000, +}; + +static const struct pios_tim_clock_cfg tim_2_cfg = { + .timer = TIM2, + .time_base_init = &tim_3_5_time_base, + .irq = { + .init = { + .NVIC_IRQChannel = TIM2_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, +}; + +static const struct pios_tim_clock_cfg tim_3_cfg = { + .timer = TIM3, + .time_base_init = &tim_3_5_time_base, + .irq = { + .init = { + .NVIC_IRQChannel = TIM3_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, +}; + +static const struct pios_tim_clock_cfg tim_5_cfg = { + .timer = TIM5, + .time_base_init = &tim_3_5_time_base, + .irq = { + .init = { + .NVIC_IRQChannel = TIM5_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, +}; + +static const struct pios_tim_clock_cfg tim_9_cfg = { + .timer = TIM9, + .time_base_init = &tim_9_10_11_time_base, + .irq = { + .init = { + .NVIC_IRQChannel = TIM1_BRK_TIM9_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, +}; + +static const struct pios_tim_clock_cfg tim_10_cfg = { + .timer = TIM10, + .time_base_init = &tim_9_10_11_time_base, + .irq = { + .init = { + .NVIC_IRQChannel = TIM1_UP_TIM10_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, +}; + +static const struct pios_tim_clock_cfg tim_11_cfg = { + .timer = TIM11, + .time_base_init = &tim_9_10_11_time_base, + .irq = { + .init = { + .NVIC_IRQChannel = TIM1_TRG_COM_TIM11_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, +}; + +// Set up timers that only have inputs on APB1 +// TIM2,3,4,5,6,7,12,13,14 +static const TIM_TimeBaseInitTypeDef tim_apb1_time_base = { + .TIM_Prescaler = (PIOS_PERIPHERAL_APB1_CLOCK / 1000000) - 1, + .TIM_ClockDivision = TIM_CKD_DIV1, + .TIM_CounterMode = TIM_CounterMode_Up, + .TIM_Period = 0xFFFF, + .TIM_RepetitionCounter = 0x0000, +}; + + +// Set up timers that only have inputs on APB2 +// TIM1,8,9,10,11 +static const TIM_TimeBaseInitTypeDef tim_apb2_time_base = { + .TIM_Prescaler = (PIOS_PERIPHERAL_APB2_CLOCK / 1000000) - 1, + .TIM_ClockDivision = TIM_CKD_DIV1, + .TIM_CounterMode = TIM_CounterMode_Up, + .TIM_Period = 0xFFFF, + .TIM_RepetitionCounter = 0x0000, +}; + +static const struct pios_tim_clock_cfg tim_1_cfg = { + .timer = TIM1, + .time_base_init = &tim_apb2_time_base, + .irq = { + .init = { + .NVIC_IRQChannel = TIM1_CC_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, +}; + +static const struct pios_tim_clock_cfg tim_4_cfg = { + .timer = TIM4, + .time_base_init = &tim_apb1_time_base, + .irq = { + .init = { + .NVIC_IRQChannel = TIM4_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, +}; +static const struct pios_tim_clock_cfg tim_8_cfg = { + .timer = TIM8, + .time_base_init = &tim_apb2_time_base, + .irq = { + .init = { + .NVIC_IRQChannel = TIM8_CC_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, +}; + +static const struct pios_tim_clock_cfg tim_12_cfg = { + .timer = TIM12, + .time_base_init = &tim_apb1_time_base, + .irq = { + .init = { + .NVIC_IRQChannel = TIM8_BRK_TIM12_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, +}; + +#include +#include +static const struct pios_tim_channel dummmy_timer = + TIM_SERVO_CHANNEL_CONFIG(TIM9, 1, E, 5); // dummy unused timer + gpio. Hack to free tim1 + +/** + * Pios servo configuration structures + * Using TIM3, TIM9, TIM2, TIM5 + */ +static const struct pios_tim_channel pios_tim_servoport_all_pins[] = { + TIM_SERVO_CHANNEL_CONFIG(TIM3, 3, B, 0), + TIM_SERVO_CHANNEL_CONFIG(TIM3, 4, B, 1), + TIM_SERVO_CHANNEL_CONFIG(TIM9, 2, A, 3), + TIM_SERVO_CHANNEL_CONFIG(TIM2, 3, A, 2), + TIM_SERVO_CHANNEL_CONFIG(TIM5, 2, A, 1), + TIM_SERVO_CHANNEL_CONFIG(TIM5, 1, A, 0), + + // PWM pins on CONN7 + TIM_SERVO_CHANNEL_CONFIG(TIM8, 4, C, 9), + TIM_SERVO_CHANNEL_CONFIG(TIM8, 3, C, 8), + TIM_SERVO_CHANNEL_CONFIG(TIM12, 2, B, 15), + TIM_SERVO_CHANNEL_CONFIG(TIM12, 1, B, 14), +}; + +#define PIOS_SERVOPORT_ALL_PINS_PWMOUT (NELEMENTS(pios_tim_servoport_all_pins)) + +const struct pios_servo_cfg pios_servo_cfg_out = { + .tim_oc_init = { + .TIM_OCMode = TIM_OCMode_PWM1, + .TIM_OutputState = TIM_OutputState_Enable, + .TIM_OutputNState = TIM_OutputNState_Disable, + .TIM_Pulse = PIOS_SERVOS_INITIAL_POSITION, + .TIM_OCPolarity = TIM_OCPolarity_High, + .TIM_OCNPolarity = TIM_OCPolarity_High, + .TIM_OCIdleState = TIM_OCIdleState_Reset, + .TIM_OCNIdleState = TIM_OCNIdleState_Reset, + }, + .channels = pios_tim_servoport_all_pins, + .num_channels = PIOS_SERVOPORT_ALL_PINS_PWMOUT, +}; +#if defined(PIOS_INCLUDE_PPM) +#include +static const struct pios_tim_channel pios_tim_rcvr_all_channels[] = { + TIM_SERVO_CHANNEL_CONFIG(TIM8, 2, C, 7), +}; + +/* + * PPM Input + */ + +#include +static const struct pios_ppm_cfg pios_ppm_cfg = { + .tim_ic_init = { + .TIM_ICPolarity = TIM_ICPolarity_Rising, + .TIM_ICSelection = TIM_ICSelection_DirectTI, + .TIM_ICPrescaler = TIM_ICPSC_DIV1, + .TIM_ICFilter = 0x0, + .TIM_Channel = TIM_Channel_2, + }, + /* Use only the first channel for ppm */ + .channels = &pios_tim_rcvr_all_channels[0], + .num_channels = 1, +}; + +#endif // PPM + +#if defined(PIOS_INCLUDE_GCSRCVR) +#include "pios_gcsrcvr_priv.h" +#endif /* PIOS_INCLUDE_GCSRCVR */ + +#if defined(PIOS_INCLUDE_RCVR) +#include "pios_rcvr_priv.h" +#endif /* PIOS_INCLUDE_RCVR */ + +#if defined(PIOS_INCLUDE_USB) +#include "pios_usb_priv.h" + +static const struct pios_usb_cfg pios_usb_main_rm2_cfg = { + .irq = { + .init = { + .NVIC_IRQChannel = OTG_FS_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, + .NVIC_IRQChannelSubPriority = 0, // PriorityGroup=4 + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .vsense = { + .gpio = GPIOA, + .init = { + .GPIO_Pin = GPIO_Pin_8, + .GPIO_Speed = GPIO_Speed_25MHz, + .GPIO_Mode = GPIO_Mode_IN, + .GPIO_OType = GPIO_OType_OD, + }, + }, + .vsense_active_low = false +}; + +const struct pios_usb_cfg *PIOS_BOARD_HW_DEFS_GetUsbCfg(__attribute__((unused)) uint32_t board_revision) +{ + return &pios_usb_main_rm2_cfg; +} + +#include "pios_usb_board_data_priv.h" +#include "pios_usb_desc_hid_cdc_priv.h" +#include "pios_usb_desc_hid_only_priv.h" +#include "pios_usbhook.h" + +#endif /* PIOS_INCLUDE_USB */ + +#if defined(PIOS_INCLUDE_COM_MSG) + +#include + +#endif /* PIOS_INCLUDE_COM_MSG */ + +#if defined(PIOS_INCLUDE_USB_HID) && !defined(PIOS_INCLUDE_USB_CDC) +#include + +const struct pios_usb_hid_cfg pios_usb_hid_cfg = { + .data_if = 0, + .data_rx_ep = 1, + .data_tx_ep = 1, +}; +#endif /* PIOS_INCLUDE_USB_HID && !PIOS_INCLUDE_USB_CDC */ + +#if defined(PIOS_INCLUDE_USB_HID) && defined(PIOS_INCLUDE_USB_CDC) +#include + +const struct pios_usb_cdc_cfg pios_usb_cdc_cfg = { + .ctrl_if = 0, + .ctrl_tx_ep = 2, + + .data_if = 1, + .data_rx_ep = 3, + .data_tx_ep = 3, +}; + +#include + +const struct pios_usb_hid_cfg pios_usb_hid_cfg = { + .data_if = 2, + .data_rx_ep = 1, + .data_tx_ep = 1, +}; +#endif /* PIOS_INCLUDE_USB_HID && PIOS_INCLUDE_USB_CDC */ + +#ifdef PIOS_INCLUDE_WS2811 +#include +#include +#define PIOS_WS2811_TIM_DIVIDER (PIOS_PERIPHERAL_APB2_CLOCK / (800000 * PIOS_WS2811_TIM_PERIOD)) + +void DMA2_Stream1_IRQHandler(void) __attribute__((alias("PIOS_WS2811_irq_handler"))); +// list of pin configurable as ws281x outputs. +// this will not clash with PWM in or servo output as +// pins will be reconfigured as _OUT so the alternate function is disabled. +const struct pios_ws2811_pin_cfg pios_ws2811_pin_cfg[] = { + [HWSETTINGS_WS2811LED_OUT_SERVOOUT1] = { + .gpio = GPIOB, + .gpioInit = { + .GPIO_Pin = GPIO_Pin_0, + .GPIO_Speed = GPIO_Speed_25MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + }, + }, + [HWSETTINGS_WS2811LED_OUT_SERVOOUT2] = { + .gpio = GPIOB, + .gpioInit = { + .GPIO_Pin = GPIO_Pin_1, + .GPIO_Speed = GPIO_Speed_25MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + }, + }, + [HWSETTINGS_WS2811LED_OUT_SERVOOUT3] = { + .gpio = GPIOA, + .gpioInit = { + .GPIO_Pin = GPIO_Pin_3, + .GPIO_Speed = GPIO_Speed_25MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + }, + }, + [HWSETTINGS_WS2811LED_OUT_SERVOOUT4] = { + .gpio = GPIOA, + .gpioInit = { + .GPIO_Pin = GPIO_Pin_2, + .GPIO_Speed = GPIO_Speed_25MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + }, + }, + [HWSETTINGS_WS2811LED_OUT_SERVOOUT5] = { + .gpio = GPIOA, + .gpioInit = { + .GPIO_Pin = GPIO_Pin_1, + .GPIO_Speed = GPIO_Speed_25MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + }, + }, + [HWSETTINGS_WS2811LED_OUT_SERVOOUT6] = { + .gpio = GPIOA, + .gpioInit = { + .GPIO_Pin = GPIO_Pin_0, + .GPIO_Speed = GPIO_Speed_25MHz, + .GPIO_Mode = GPIO_Mode_OUT, + .GPIO_OType = GPIO_OType_PP, + }, + }, +}; + +const struct pios_ws2811_cfg pios_ws2811_cfg = { + .timer = TIM1, + .timerInit = { + .TIM_Prescaler = PIOS_WS2811_TIM_DIVIDER - 1, + .TIM_ClockDivision = TIM_CKD_DIV1, + .TIM_CounterMode = TIM_CounterMode_Up, + // period (1.25 uS per period + .TIM_Period = PIOS_WS2811_TIM_PERIOD, + .TIM_RepetitionCounter = 0x0000, + }, + + .timerCh1 = 1, + .streamCh1 = DMA2_Stream1, + .timerCh2 = 3, + .streamCh2 = DMA2_Stream6, + .streamUpdate = DMA2_Stream5, + + // DMA streamCh1, triggered by timerCh1 pwm signal. + // if FrameBuffer indicates, reset output value early to indicate "0" bit to ws2812 + .dmaInitCh1 = PIOS_WS2811_DMA_CH1_CONFIG(DMA_Channel_6), + .dmaItCh1 = DMA_IT_TEIF1 | DMA_IT_TCIF1, + + // DMA streamCh2, triggered by timerCh2 pwm signal. + // Reset output value late to indicate "1" bit to ws2812. + .dmaInitCh2 = PIOS_WS2811_DMA_CH2_CONFIG(DMA_Channel_6), + .dmaItCh2 = DMA_IT_TEIF6 | DMA_IT_TCIF6, + + // DMA streamUpdate Triggered by timer update event + // Outputs a high logic level at beginning of a cycle + .dmaInitUpdate = PIOS_WS2811_DMA_UPDATE_CONFIG(DMA_Channel_6), + .dmaItUpdate = DMA_IT_TEIF5 | DMA_IT_TCIF5, + .dmaSource = TIM_DMA_CC1 | TIM_DMA_CC3 | TIM_DMA_Update, + + // DMAInitCh1 interrupt vector, used to block timer at end of framebuffer transfer + .irq = { + .flags = (DMA_IT_TCIF1), + .init = { + .NVIC_IRQChannel = DMA2_Stream1_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGHEST, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, +}; + +void PIOS_WS2811_irq_handler(void) +{ + PIOS_WS2811_DMA_irq_handler(); +} +#endif // PIOS_INCLUDE_WS2811 diff --git a/flight/targets/boards/sparky2/bootloader/Makefile b/flight/targets/boards/sparky2/bootloader/Makefile new file mode 100644 index 000000000..8ed53e40c --- /dev/null +++ b/flight/targets/boards/sparky2/bootloader/Makefile @@ -0,0 +1,27 @@ +# +# Copyright (c) 2015, The LibrePilot Project, http://www.librepilot.org +# Copyright (c) 2009-2013, The OpenPilot Team, http://www.openpilot.org +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +ifndef FLIGHT_MAKEFILE + $(error Top level Makefile must be used to build this target) +endif + +include ../board-info.mk +include $(FLIGHT_ROOT_DIR)/make/firmware-defs.mk +include $(FLIGHT_ROOT_DIR)/make/boot-defs.mk +include $(FLIGHT_ROOT_DIR)/make/common-defs.mk diff --git a/flight/targets/boards/sparky2/bootloader/inc/common.h b/flight/targets/boards/sparky2/bootloader/inc/common.h new file mode 100644 index 000000000..e64b89014 --- /dev/null +++ b/flight/targets/boards/sparky2/bootloader/inc/common.h @@ -0,0 +1,115 @@ +/** + ****************************************************************************** + * @addtogroup CopterControlBL CopterControl BootLoader + * @brief These files contain the code to the CopterControl Bootloader. + * + * @{ + * @file common.c + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @brief This file contains various common defines for the BootLoader + * @see The GNU Public License (GPL) Version 3 + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef COMMON_H_ +#define COMMON_H_ + +// #include "board.h" + +typedef enum { + start, keepgoing, +} DownloadAction; + +/**************************************************/ +/* OP_DFU states */ +/**************************************************/ + +typedef enum { + DFUidle, // 0 + uploading, // 1 + wrong_packet_received, // 2 + too_many_packets, // 3 + too_few_packets, // 4 + Last_operation_Success, // 5 + downloading, // 6 + BLidle, // 7 + Last_operation_failed, // 8 + uploadingStarting, // 9 + outsideDevCapabilities, // 10 + CRC_Fail, // 11 + failed_jump, +// 12 +} DFUStates; +/**************************************************/ +/* OP_DFU commands */ +/**************************************************/ +typedef enum { + Reserved, // 0 + Req_Capabilities, // 1 + Rep_Capabilities, // 2 + EnterDFU, // 3 + JumpFW, // 4 + Reset, // 5 + Abort_Operation, // 6 + Upload, // 7 + Op_END, // 8 + Download_Req, // 9 + Download, // 10 + Status_Request, // 11 + Status_Rep +// 12 +} DFUCommands; + +typedef enum { + High_Density, Medium_Density +} DeviceType; +/**************************************************/ +/* OP_DFU transfer types */ +/**************************************************/ +typedef enum { + FW, // 0 + Descript +// 2 +} DFUTransfer; +/**************************************************/ +/* OP_DFU transfer port */ +/**************************************************/ +typedef enum { + Usb, // 0 + Serial +// 2 +} DFUPort; +/**************************************************/ +/* OP_DFU programable programable HW types */ +/**************************************************/ +typedef enum { + Self_flash, // 0 + Remote_flash_via_spi +// 1 +} DFUProgType; +/**************************************************/ +/* OP_DFU programable sources */ +/**************************************************/ +#define USB 0 +#define SPI 1 + +#define DownloadDelay 100000 + +#define MAX_DEL_RETRYS 3 +#define MAX_WRI_RETRYS 3 + +#endif /* COMMON_H_ */ diff --git a/ground/gcs/src/libs/utils/settingsutils.cpp b/flight/targets/boards/sparky2/bootloader/inc/pios_config.h similarity index 62% rename from ground/gcs/src/libs/utils/settingsutils.cpp rename to flight/targets/boards/sparky2/bootloader/inc/pios_config.h index c10b9ab42..7f2a165d7 100644 --- a/ground/gcs/src/libs/utils/settingsutils.cpp +++ b/flight/targets/boards/sparky2/bootloader/inc/pios_config.h @@ -1,13 +1,11 @@ /** ****************************************************************************** * - * @file settingsutils.cpp + * @file pios_config.h * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009. - * @brief + * @brief PiOS configuration header. + * - Central compile time config for the project. * @see The GNU Public License (GPL) Version 3 - * @defgroup - * @{ * *****************************************************************************/ /* @@ -26,23 +24,21 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "settingsutils.h" +#ifndef PIOS_CONFIG_H +#define PIOS_CONFIG_H -#include -namespace Utils { -QTCREATOR_UTILS_EXPORT QString settingsKey(const QString &category) -{ - QString rc(category); - const QChar underscore = QLatin1Char('_'); - const int size = rc.size(); +#define PIOS_INCLUDE_DELAY +#define PIOS_INCLUDE_SYS +#define PIOS_INCLUDE_IRQ +#define PIOS_INCLUDE_USB +#define PIOS_INCLUDE_USB_HID +#define PIOS_INCLUDE_LED +#define PIOS_INCLUDE_IAP +#define PIOS_INCLUDE_GPIO +#define PIOS_INCLUDE_COM +#define PIOS_INCLUDE_COM_MSG +#define PIOS_INCLUDE_BL_HELPER +#define PIOS_INCLUDE_BL_HELPER_WRITE_SUPPORT - for (int i = 0; i < size; i++) { - const QChar c = rc.at(i); - if (!c.isLetterOrNumber() && c != underscore) { - rc[i] = underscore; - } - } - return rc; -} -} // namespace Utils +#endif /* PIOS_CONFIG_H */ diff --git a/flight/targets/boards/sparky2/bootloader/inc/pios_usb_board_data.h b/flight/targets/boards/sparky2/bootloader/inc/pios_usb_board_data.h new file mode 100644 index 000000000..d3deddfde --- /dev/null +++ b/flight/targets/boards/sparky2/bootloader/inc/pios_usb_board_data.h @@ -0,0 +1,54 @@ +/** + *********************************************************************************** + * @addtogroup PIOS PIOS Core hardware abstraction layer + * @{ + * @addtogroup PIOS_USB_BOARD Board specific USB definitions + * @brief Board specific USB definitions + * @{ + * + * @file pios_usb_board_data.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @brief Board specific USB definitions + * @see The GNU Public License (GPL) Version 3 + * + **********************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PIOS_USB_BOARD_DATA_H +#define PIOS_USB_BOARD_DATA_H + +// Note : changing below length will require changes to the USB buffer setup +#define PIOS_USB_BOARD_HID_DATA_LENGTH 64 + +#define PIOS_USB_BOARD_EP_NUM 2 + +#include /* struct usb_* */ + +#define PIOS_USB_BOARD_PRODUCT_ID USB_PRODUCT_ID_SPARKY2 +#define PIOS_USB_BOARD_DEVICE_VER USB_OP_DEVICE_VER(USB_OP_BOARD_ID_SPARKY2, USB_OP_BOARD_MODE_BL) +#define PIOS_USB_BOARD_SN_SUFFIX "+BL" + +/* + * The bootloader uses a simplified report structure + * BL: ... + * FW: ... + * This define changes the behaviour in pios_usb_hid.c + */ +#define PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE + +#endif /* PIOS_USB_BOARD_DATA_H */ diff --git a/flight/targets/boards/sparky2/bootloader/main.c b/flight/targets/boards/sparky2/bootloader/main.c new file mode 100644 index 000000000..70b18409e --- /dev/null +++ b/flight/targets/boards/sparky2/bootloader/main.c @@ -0,0 +1,257 @@ +/** + *********************************************************************************** + * @addtogroup Sparky2BL Sparky2 BootLoader + * @brief These files contain the code to the Sparky2 Bootloader. + * + * @{ + * @file main.c + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @brief This is the file with the main function of the Sparky2 BootLoader + * @see The GNU Public License (GPL) Version 3 + * + **********************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include /* PIOS_USBHOOK_* */ +#include +#include + +extern void FLASH_Download(); +void check_bor(); +#define BSL_HOLD_STATE ((PIOS_USB_DETECT_GPIO_PORT->IDR & PIOS_USB_DETECT_GPIO_PIN) ? 0 : 1) + +/* Private typedef -----------------------------------------------------------*/ +typedef void (*pFunction)(void); +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +pFunction Jump_To_Application; +uint32_t JumpAddress; + +/// LEDs PWM +uint32_t period1 = 5000; // 5 mS +uint32_t sweep_steps1 = 100; // * 5 mS -> 500 mS +uint32_t period2 = 5000; // 5 mS +uint32_t sweep_steps2 = 100; // * 5 mS -> 500 mS + + +//////////////////////////////////////// +uint8_t tempcount = 0; + +/* Extern variables ----------------------------------------------------------*/ +DFUStates DeviceState; +int16_t status = 0; +bool JumpToApp = false; +bool GO_dfu = false; +bool USB_connected = false; +bool User_DFU_request = false; +static uint8_t mReceive_Buffer[63]; +/* Private function prototypes -----------------------------------------------*/ +uint32_t LedPWM(uint32_t pwm_period, uint32_t pwm_sweep_steps, uint32_t count); +uint8_t processRX(); +void jump_to_app(); + +int main() +{ + PIOS_SYS_Init(); + PIOS_Board_Init(); + PIOS_IAP_Init(); + + // Make sure the brown out reset value for this chip + // is 2.7 volts + check_bor(); + + USB_connected = PIOS_USB_CheckAvailable(0); + + if (PIOS_IAP_CheckRequest() == true) { + PIOS_DELAY_WaitmS(1000); + User_DFU_request = true; + PIOS_IAP_ClearRequest(); + } + + GO_dfu = (USB_connected == true) || (User_DFU_request == true); + + if (GO_dfu == true) { + if (User_DFU_request == true) { + DeviceState = DFUidle; + } else { + DeviceState = BLidle; + } + } else { + JumpToApp = true; + } + + uint32_t stopwatch = 0; + uint32_t prev_ticks = PIOS_DELAY_GetuS(); + while (true) { + /* Update the stopwatch */ + uint32_t elapsed_ticks = PIOS_DELAY_GetuSSince(prev_ticks); + prev_ticks += elapsed_ticks; + stopwatch += elapsed_ticks; + + if (JumpToApp == true) { + jump_to_app(); + } + + switch (DeviceState) { + case Last_operation_Success: + case uploadingStarting: + case DFUidle: + period1 = 5000; + sweep_steps1 = 100; + PIOS_LED_Off(PIOS_LED_HEARTBEAT); + period2 = 0; + break; + case uploading: + period1 = 5000; + sweep_steps1 = 100; + period2 = 2500; + sweep_steps2 = 50; + break; + case downloading: + period1 = 2500; + sweep_steps1 = 50; + PIOS_LED_Off(PIOS_LED_HEARTBEAT); + period2 = 0; + break; + case BLidle: + period1 = 0; + PIOS_LED_On(PIOS_LED_HEARTBEAT); + period2 = 0; + break; + default: // error + period1 = 5000; + sweep_steps1 = 100; + period2 = 5000; + sweep_steps2 = 100; + } + + if (period1 != 0) { + if (LedPWM(period1, sweep_steps1, stopwatch)) { + PIOS_LED_On(PIOS_LED_HEARTBEAT); + } else { + PIOS_LED_Off(PIOS_LED_HEARTBEAT); + } + } else { + PIOS_LED_On(PIOS_LED_HEARTBEAT); + } + + if (period2 != 0) { + if (LedPWM(period2, sweep_steps2, stopwatch)) { + PIOS_LED_On(PIOS_LED_HEARTBEAT); + } else { + PIOS_LED_Off(PIOS_LED_HEARTBEAT); + } + } else { + PIOS_LED_Off(PIOS_LED_HEARTBEAT); + } + + if (stopwatch > 50 * 1000 * 1000) { + stopwatch = 0; + } + if ((stopwatch > 6 * 1000 * 1000) && ((DeviceState == BLidle) || (DeviceState == DFUidle && !USB_connected))) { + JumpToApp = true; + } + + processRX(); + DataDownload(start); + } +} + +void jump_to_app() +{ + const struct pios_board_info *bdinfo = &pios_board_info_blob; + + PIOS_LED_On(PIOS_LED_HEARTBEAT); + // Look at cm3_vectors struct in startup. In a fw image the first uint32_t contains the address of the top of irqstack + uint32_t fwIrqStackBase = (*(__IO uint32_t *)bdinfo->fw_base) & 0xFFFE0000; + // Check for the two possible irqstack locations (sram or core coupled sram) + if (fwIrqStackBase == 0x20000000 || fwIrqStackBase == 0x10000000) { + /* Jump to user application */ + FLASH_Lock(); + RCC_APB2PeriphResetCmd(0xffffffff, ENABLE); + RCC_APB1PeriphResetCmd(0xffffffff, ENABLE); + RCC_APB2PeriphResetCmd(0xffffffff, DISABLE); + RCC_APB1PeriphResetCmd(0xffffffff, DISABLE); + + PIOS_USBHOOK_Deactivate(); + + JumpAddress = *(__IO uint32_t *)(bdinfo->fw_base + 4); + Jump_To_Application = (pFunction)JumpAddress; + /* Initialize user application's Stack Pointer */ + __set_MSP(*(__IO uint32_t *)bdinfo->fw_base); + Jump_To_Application(); + } else { + DeviceState = failed_jump; + return; + } +} +uint32_t LedPWM(uint32_t pwm_period, uint32_t pwm_sweep_steps, uint32_t count) +{ + uint32_t curr_step = (count / pwm_period) % pwm_sweep_steps; /* 0 - pwm_sweep_steps */ + uint32_t pwm_duty = pwm_period * curr_step / pwm_sweep_steps; /* fraction of pwm_period */ + + uint32_t curr_sweep = (count / (pwm_period * pwm_sweep_steps)); /* ticks once per full sweep */ + + if (curr_sweep & 1) { + pwm_duty = pwm_period - pwm_duty; /* reverse direction in odd sweeps */ + } + return ((count % pwm_period) > pwm_duty) ? 1 : 0; +} + +uint8_t processRX() +{ + if (PIOS_COM_MSG_Receive(PIOS_COM_TELEM_USB, mReceive_Buffer, sizeof(mReceive_Buffer))) { + processComand(mReceive_Buffer); + } + return true; +} + +/** + * Check the brown out reset threshold is 2.7 volts and if not + * resets it. This solves an issue that can prevent boards + * powering up with some BEC + */ +void check_bor() +{ + uint8_t bor = FLASH_OB_GetBOR(); + + if (bor != OB_BOR_LEVEL3) { + FLASH_OB_Unlock(); + FLASH_OB_BORConfig(OB_BOR_LEVEL3); + FLASH_OB_Launch(); + while (FLASH_WaitForLastOperation() == FLASH_BUSY) { + ; + } + FLASH_OB_Lock(); + while (FLASH_WaitForLastOperation() == FLASH_BUSY) { + ; + } + } +} + +int32_t platform_senddata(const uint8_t *msg, uint16_t msg_len) +{ + return PIOS_COM_MSG_Send(PIOS_COM_TELEM_USB, msg, msg_len); +} diff --git a/flight/targets/boards/sparky2/bootloader/pios_board.c b/flight/targets/boards/sparky2/bootloader/pios_board.c new file mode 100644 index 000000000..5352c7f73 --- /dev/null +++ b/flight/targets/boards/sparky2/bootloader/pios_board.c @@ -0,0 +1,84 @@ +/** + ****************************************************************************** + * + * @file pios_board.c + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @brief Defines board specific static initializers for hardware for the AHRS board. + * @see The GNU Public License (GPL) Version 3 + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +/* + * Pull in the board-specific static HW definitions. + * Including .c files is a bit ugly but this allows all of + * the HW definitions to be const and static to limit their + * scope. + * + * NOTE: THIS IS THE ONLY PLACE THAT SHOULD EVER INCLUDE THIS FILE + */ +#include "../board_hw_defs.c" + +uint32_t pios_com_telem_usb_id; + +static bool board_init_complete = false; +void PIOS_Board_Init() +{ + if (board_init_complete) { + return; + } + + /* Delay system */ + PIOS_DELAY_Init(); + + const struct pios_board_info *bdinfo = &pios_board_info_blob; + +#if defined(PIOS_INCLUDE_LED) + const struct pios_gpio_cfg *led_cfg = PIOS_BOARD_HW_DEFS_GetLedCfg(bdinfo->board_rev); + PIOS_Assert(led_cfg); + PIOS_LED_Init(led_cfg); +#endif /* PIOS_INCLUDE_LED */ + +#if defined(PIOS_INCLUDE_USB) + /* Initialize board specific USB data */ + PIOS_USB_BOARD_DATA_Init(); + + /* Activate the HID-only USB configuration */ + PIOS_USB_DESC_HID_ONLY_Init(); + + uint32_t pios_usb_id; + PIOS_USB_Init(&pios_usb_id, PIOS_BOARD_HW_DEFS_GetUsbCfg(bdinfo->board_rev)); + +#if defined(PIOS_INCLUDE_USB_HID) && defined(PIOS_INCLUDE_COM_MSG) + uint32_t pios_usb_hid_id; + if (PIOS_USB_HID_Init(&pios_usb_hid_id, &pios_usb_hid_cfg, pios_usb_id)) { + PIOS_Assert(0); + } + if (PIOS_COM_MSG_Init(&pios_com_telem_usb_id, &pios_usb_hid_com_driver, pios_usb_hid_id)) { + PIOS_Assert(0); + } +#endif /* PIOS_INCLUDE_USB_HID && PIOS_INCLUDE_COM_MSG */ + + PIOS_USBHOOK_Activate(); + +#endif /* PIOS_INCLUDE_USB */ + + board_init_complete = true; +} diff --git a/flight/targets/boards/sparky2/firmware/Makefile b/flight/targets/boards/sparky2/firmware/Makefile new file mode 100644 index 000000000..7ee3837a4 --- /dev/null +++ b/flight/targets/boards/sparky2/firmware/Makefile @@ -0,0 +1,118 @@ +# +# Copyright (C) 2015-2016, The LibrePilot Project, http://www.librepilot.org +# Copyright (C) 2009-2013, The OpenPilot Team, http://www.openpilot.org +# Copyright (C) 2012, PhoenixPilot, http://github.com/PhoenixPilot +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +##### + +ifndef FLIGHT_MAKEFILE + $(error Top level Makefile must be used to build this target) +endif + +include ../board-info.mk +include $(FLIGHT_ROOT_DIR)/make/firmware-defs.mk + +# Sparky2 C++ support +USE_CXX = YES + +# ARM DSP library +USE_DSP_LIB ?= NO + +# List of mandatory modules to include +MODULES += Sensors +MODULES += StateEstimation +MODULES += Airspeed +MODULES += Stabilization +MODULES += ManualControl +MODULES += Receiver +MODULES += Actuator +MODULES += GPS +MODULES += TxPID +MODULES += CameraStab +MODULES += Battery +MODULES += FirmwareIAP +MODULES += Radio +MODULES += PathPlanner +MODULES += PathFollower +MODULES += Osd/osdoutout +MODULES += Logging +MODULES += Telemetry +MODULES += Notify + +OPTMODULES += AutoTune +OPTMODULES += ComUsbBridge +OPTMODULES += UAVOMSPBridge +OPTMODULES += UAVOMavlinkBridge + +SRC += $(FLIGHTLIB)/notification.c + +# Include all camera options +CDEFS += -DUSE_INPUT_LPF -DUSE_GIMBAL_LPF -DUSE_GIMBAL_FF + +# Some diagnostics +CDEFS += -DDIAG_TASKS + +# Misc options +CFLAGS += -ffast-math + +# List C source files here (C dependencies are automatically generated). +# Use file-extension c for "c-only"-files +ifndef TESTAPP + ## Application Core + SRC += ../pios_usb_board_data.c + SRC += $(OPMODULEDIR)/System/systemmod.c + CPPSRC += $(OPSYSTEM)/sparky2.cpp + SRC += $(OPSYSTEM)/pios_board.c + SRC += $(FLIGHTLIB)/alarms.c + SRC += $(FLIGHTLIB)/instrumentation.c + SRC += $(OPUAVTALK)/uavtalk.c + SRC += $(OPUAVOBJ)/uavobjectmanager.c + SRC += $(OPUAVOBJ)/uavobjectpersistence.c + SRC += $(OPUAVOBJ)/eventdispatcher.c + SRC += $(PIOSCOMMON)/pios_flashfs_logfs.c + SRC += $(PIOSCOMMON)/pios_flash_jedec.c + + #ifeq ($(DEBUG), YES) + SRC += $(OPSYSTEM)/dcc_stdio.c + SRC += $(OPSYSTEM)/cm3_fault_handlers.c + #endif + + ## Misc library functions + SRC += $(FLIGHTLIB)/paths.c + SRC += $(FLIGHTLIB)/plans.c + SRC += $(FLIGHTLIB)/WorldMagModel.c + SRC += $(FLIGHTLIB)/insgps13state.c + SRC += $(FLIGHTLIB)/auxmagsupport.c + SRC += $(FLIGHTLIB)/lednotification.c + SRC += $(FLIGHTLIB)/sha1.c + + ## UAVObjects + include ./UAVObjects.inc + SRC += $(UAVOBJSRC) +else + ## Test Code + SRC += $(OPTESTS)/test_common.c + SRC += $(OPTESTS)/$(TESTAPP).c +endif + +# Optional component libraries +include $(FLIGHTLIB)/rscode/library.mk + +#include $(FLIGHTLIB)/PyMite/pymite.mk + + +include $(FLIGHT_ROOT_DIR)/make/apps-defs.mk +include $(FLIGHT_ROOT_DIR)/make/common-defs.mk diff --git a/flight/targets/boards/sparky2/firmware/Makefile.osx b/flight/targets/boards/sparky2/firmware/Makefile.osx new file mode 100644 index 000000000..3158447bd --- /dev/null +++ b/flight/targets/boards/sparky2/firmware/Makefile.osx @@ -0,0 +1,656 @@ + ##### + # Project: RevoMini + # + # + # Makefile for OpenPilot project build PiOS and the AP. + # + # The OpenPilot Team, http://www.openpilot.org, Copyright (C) 2012. + # + # + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by + # the Free Software Foundation; either version 3 of the License, or + # (at your option) any later version. + # + # This program is distributed in the hope that it will be useful, but + # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + # for more details. + # + # You should have received a copy of the GNU General Public License along + # with this program; if not, write to the Free Software Foundation, Inc., + # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + ##### + + +# Set developer code and compile options +# Set to YES to compile for debugging +DEBUG ?= YES + +# Set to YES to use the Servo output pins for debugging via scope or logic analyser +ENABLE_DEBUG_PINS ?= NO + +# Set to Yes to enable the AUX UART which is mapped on the S1 (Tx) and S2 (Rx) servo outputs +ENABLE_AUX_UART ?= NO + +# +USE_BOOTLOADER ?= NO + + +# Set to YES when using Code Sourcery toolchain +CODE_SOURCERY ?= NO + +# Remove command is different for Code Sourcery on Windows +REMOVE_CMD ?= rm + +FLASH_TOOL = OPENOCD + +# YES enables -mthumb option to flags for source-files listed +# in SRC and CPPSRC +USE_THUMB_MODE = YES + +# List of modules to include +MODULES += Actuator ManualControl Stabilization +MODULES += AltitudeHold FixedWingPathFollower PathPlanner +#MODULES += VtolPathFollower ## OP-700: VtolPathFollower disabled because its currently unsafe - remove this line once Sambas code has been merged +MODULES += Attitude/revolution +#MODULES += OveroSync/simulated + +# To run simulation instead of connect to SITL +MODULES += Sensors/simulated + +MODULES += Telemetry + +# MCU name, submodel and board +# - MCU used for compiler-option (-mtune) +# - MODEL used for linker-script name (-T) and passed as define +# - BOARD just passed as define (optional) +MCU = i686 +#CHIP = STM32F103RET +#BOARD = STM3210E_OP +MODEL = HD +ifeq ($(USE_BOOTLOADER), YES) +BOOT_MODEL = $(MODEL)_BL + +else +BOOT_MODEL = $(MODEL)_NB +endif + +# Directory for output files (lst, obj, dep, elf, sym, map, hex, bin etc.) +OUTDIR = ../../build/sim_osx + +# Target file name (without extension). +TARGET = RevoMini + +# Paths +OPSYSTEM = ./System +OPSYSTEMINC = $(OPSYSTEM)/inc +OPUAVTALK = ../UAVTalk +OPUAVTALKINC = $(OPUAVTALK)/inc +OPUAVOBJ = ../UAVObjects +OPUAVOBJINC = $(OPUAVOBJ)/inc +OPTESTS = ./Tests +OPMODULEDIR = ../modules +FLIGHTLIB = ../libraries +FLIGHTLIBINC = $(FLIGHTLIB)/inc +PIOS = ../PiOS.osx +PIOSINC = $(PIOS)/inc +PIOSPOSIX = $(PIOS)/osx +APPLIBDIR = $(PIOSPOSIX)/libraries +RTOSDIR = $(APPLIBDIR)/FreeRTOS +RTOSSRCDIR = $(RTOSDIR)/Source +RTOSINCDIR = $(RTOSSRCDIR)/include +DOXYGENDIR = ../Doc/Doxygen +PYMITE = $(FLIGHTLIB)/PyMite +PYMITELIB = $(PYMITE)/lib +PYMITEPLAT = $(PYMITE)/platform/openpilot_sitl +PYMITETOOLS = $(PYMITE)/tools +PYMITEVM = $(PYMITE)/vm +PYMITEINC = $(PYMITEVM) +PYMITEINC += $(PYMITEPLAT) +PYMITEINC += $(OUTDIR) +FLIGHTPLANLIB = $(OPMODULEDIR)/FlightPlan/lib +FLIGHTPLANS = $(OPMODULEDIR)/FlightPlan/flightplans + +UAVOBJPYTHONSYNTHDIR = $(OUTDIR)/../uavobject-synthetics/python + +# List C source files here. (C dependencies are automatically generated.) +# use file-extension c for "c-only"-files + +MODNAMES = $(notdir ${MODULES}) + +ifndef TESTAPP + +## PyMite files +SRC += $(OUTDIR)/pmlib_img.c +SRC += $(OUTDIR)/pmlib_nat.c +SRC += $(OUTDIR)/pmlibusr_img.c +SRC += $(OUTDIR)/pmlibusr_nat.c +SRC += $(wildcard ${PYMITEVM}/*.c) +SRC += $(wildcard ${PYMITEPLAT}/*.c) + +## MODULES +SRC += ${foreach MOD, ${MODULES}, ${wildcard ${OPMODULEDIR}/${MOD}/*.c}} +SRC += ${OUTDIR}/InitMods.c +## OPENPILOT CORE: +SRC += ${OPMODULEDIR}/System/systemmod.c +SRC += $(OPSYSTEM)/revolution.c +SRC += $(OPSYSTEM)/pios_board_sim.c +SRC += $(OPSYSTEM)/alarms.c +SRC += $(OPUAVTALK)/uavtalk.c +SRC += $(OPUAVOBJ)/uavobjectmanager.c +SRC += $(OPUAVOBJ)/eventdispatcher.c +SRC += $(FLIGHT_UAVOBJ_DIR)/uavobjectsinit.c +else +## TESTCODE +SRC += $(OPTESTS)/test_common.c +SRC += $(OPTESTS)/$(TESTAPP).c +endif + + + +## UAVOBJECTS +ifndef TESTAPP +#include $(FLIGHT_UAVOBJ_DIR)/Makefile.inc +include ./UAVObjects.inc + +UAVOBJSRCFILENAMES += attitudesimulated +UAVOBJSRC = $(foreach UAVOBJSRCFILE,$(UAVOBJSRCFILENAMES),$(FLIGHT_UAVOBJ_DIR)/$(UAVOBJSRCFILE).c ) +UAVOBJDEFINE = $(foreach UAVOBJSRCFILE,$(UAVOBJSRCFILENAMES),-DUAVOBJ_INIT_$(UAVOBJSRCFILE) ) + +SRC += $(UAVOBJSRC) +CFLAGS_UAVOBJECTS = $(UAVOBJDEFINE) +endif + +## PIOS Hardware (posix) +SRC += $(PIOSPOSIX)/pios_crc.c +SRC += $(PIOSPOSIX)/pios_sys.c +SRC += $(PIOSPOSIX)/pios_led.c +SRC += $(PIOSPOSIX)/pios_irq.c +SRC += $(PIOSPOSIX)/pios_delay.c +SRC += $(PIOSPOSIX)/pios_sdcard.c +SRC += $(PIOSPOSIX)/pios_udp.c +SRC += $(PIOSPOSIX)/pios_tcp.c +SRC += $(PIOSPOSIX)/pios_com.c +SRC += $(PIOSPOSIX)/pios_servo.c +SRC += $(PIOSPOSIX)/pios_wdg.c +SRC += $(PIOSPOSIX)/pios_debug.c + +SRC += $(PIOSPOSIX)/pios_rcvr.c +SRC += $(PIOSPOSIX)/pios_gcsrcvr.c + +## Libraries for flight calculations +SRC += $(FLIGHTLIB)/fifo_buffer.c +SRC += $(FLIGHTLIB)/WorldMagModel.c +SRC += $(FLIGHTLIB)/CoordinateConversions.c +SRC += $(FLIGHTLIB)/paths.c +SRC += $(FLIGHTLIB)/insgps13state.c + +## RTOS and RTOS Portable +SRC += $(RTOSSRCDIR)/list.c +SRC += $(RTOSSRCDIR)/queue.c +UNAME := $(shell uname) +SRC += $(RTOSSRCDIR)/task.c +SRC += $(RTOSSRCDIR)/timers.c +SRC += $(RTOSSRCDIR)/portable/GCC/Posix/port.c +SRC += $(RTOSSRCDIR)/portable/MemMang/heap_3.c + + + +# List C source files here which must be compiled in ARM-Mode (no -mthumb). +# use file-extension c for "c-only"-files +## just for testing, timer.c could be compiled in thumb-mode too +SRCARM = + +# List C++ source files here. +# use file-extension .cpp for C++-files (not .C) +CPPSRC = + +# List C++ source files here which must be compiled in ARM-Mode. +# use file-extension .cpp for C++-files (not .C) +#CPPSRCARM = $(TARGET).cpp +CPPSRCARM = + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +EXTRAINCDIRS = $(OPSYSTEM) +EXTRAINCDIRS += $(OPSYSTEMINC) +EXTRAINCDIRS += $(OPUAVTALK) +EXTRAINCDIRS += $(OPUAVTALKINC) +EXTRAINCDIRS += $(OPUAVOBJ) +EXTRAINCDIRS += $(OPUAVOBJINC) +EXTRAINCDIRS += $(FLIGHT_UAVOBJ_DIR) +EXTRAINCDIRS += $(PIOS) +EXTRAINCDIRS += $(PIOSINC) +EXTRAINCDIRS += $(FLIGHTLIBINC) +EXTRAINCDIRS += $(PIOSPOSIX) +EXTRAINCDIRS += $(RTOSINCDIR) +EXTRAINCDIRS += $(APPLIBDIR) +EXTRAINCDIRS += $(RTOSSRCDIR)/portable/GCC/Posix +EXTRAINCDIRS += $(PYMITEINC) + +EXTRAINCDIRS += ${foreach MOD, ${MODULES}, $(OPMODULEDIR)/${MOD}/inc} ${OPMODULEDIR}/System/inc + + +# List any extra directories to look for library files here. +# Also add directories where the linker should search for +# includes from linker-script to the list +# Each directory must be seperated by a space. +EXTRA_LIBDIRS = + +# Extra Libraries +# Each library-name must be seperated by a space. +# i.e. to link with libxyz.a, libabc.a and libefsl.a: +# EXTRA_LIBS = xyz abc efsl +# for newlib-lpc (file: libnewlibc-lpc.a): +# EXTRA_LIBS = newlib-lpc +EXTRA_LIBS = + +# Path to Linker-Scripts +LINKERSCRIPTPATH = $(PIOSSTM32F10X) + +# Optimization level, can be [0, 1, 2, 3, s]. +# 0 = turn off optimization. s = optimize for size. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) + +ifeq ($(DEBUG),YES) +OPT = 0 +else +OPT = s +endif + +# Output format. (can be ihex or binary or both) +# binary to create a load-image in raw-binary format i.e. for SAM-BA, +# ihex to create a load-image in Intel hex format +#LOADFORMAT = ihex +#LOADFORMAT = binary +LOADFORMAT = both + +# Debugging format. +#DEBUGF = dwarf-2 + +# Place project-specific -D (define) and/or +# -U options for C here. +ifeq ($(ENABLE_DEBUG_PINS), YES) +CDEFS += -DPIOS_ENABLE_DEBUG_PINS +endif +ifeq ($(ENABLE_AUX_UART), YES) +CDEFS += -DPIOS_ENABLE_AUX_UART +endif +ifeq ($(USE_BOOTLOADER), YES) +CDEFS += -DUSE_BOOTLOADER +endif + +# Compiler flag to set the C Standard level. +# c89 - "ANSI" C +# gnu89 - c89 plus GCC extensions +# c99 - ISO C99 standard (not yet fully implemented) +# gnu99 - c99 plus GCC extensions +CSTANDARD = -std=gnu99 + +#----- + +# Compiler flags. + +# -g*: generate debugging information +# -O*: optimization level +# -f...: tuning, see GCC manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -adhlns...: create assembler listing +# +# Flags for C and C++ (arm-elf-gcc/arm-elf-g++) + +ifeq ($(DEBUG),YES) +CFLAGS = -g$(DEBUGF) -DDEBUG +endif + +CFLAGS += -DDIAG_TASKS + +CFLAGS += $(CFLAGS_UAVOBJECTS) +CFLAGS += -DARCH_POSIX +CFLAGS += -O$(OPT) +CFLAGS += -mtune=$(MCU) +CFLAGS += $(CDEFS) +CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) -I. + +#CFLAGS += ARCH=arm +#CROSS_COMPILE=/usr/local/android-ndk-r5/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi- + +CFLAGS += -fomit-frame-pointer +ifeq ($(CODE_SOURCERY), YES) +CFLAGS += -fpromote-loop-indices +endif + +CFLAGS += -Wall +CFLAGS += -Werror +# Compiler flags to generate dependency files: +CFLAGS += -MD -MP -MF $(OUTDIR)/dep/$(@F).d + +# flags only for C +#CONLYFLAGS += -Wnested-externs +CONLYFLAGS += $(CSTANDARD) + +# Assembler flags. +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlns: create listing +ASFLAGS = -mtune=$(MCU) -I. -x assembler-with-cpp +ASFLAGS += $(ADEFS) +ASFLAGS += -Wa,-adhlns=$(addprefix $(OUTDIR)/, $(notdir $(addsuffix .lst, $(basename $<)))) +ASFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) + +MATH_LIB = -lm + +# Linker flags. +# -Wl,...: tell GCC to pass this to linker. +# -Map: create map file +# --cref: add cross reference to map file +LDFLAGS += -lpthread +LDFLAGS += $(patsubst %,-L%,$(EXTRA_LIBDIRS)) +LDFLAGS += -lc +LDFLAGS += $(patsubst %,-l%,$(EXTRA_LIBS)) +LDFLAGS += $(MATH_LIB) +LDFLAGS += -lc -lgcc + +# To include simulation model +LDFLAGS += -L$(OUTDIR) +#LDFLAGS += -lsimmodel + + +# Define programs and commands. +CC = $(ARM_SDK_PREFIX)gcc +CPP = $(ARM_SDK_PREFIX)g++ +AR = $(ARM_SDK_PREFIX)ar +OBJCOPY = $(ARM_SDK_PREFIX)objcopy +OBJDUMP = $(ARM_SDK_PREFIX)objdump +SIZE = $(ARM_SDK_PREFIX)size +NM = $(ARM_SDK_PREFIX)nm +REMOVE = rm -f + + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = ${quote}-------- begin (mode: $(RUN_MODE)) --------${quote} +MSG_END = ${quote}-------- end --------${quote} +MSG_MODINIT = ${quote}**** Generating ModInit.c${quote} +MSG_SIZE_BEFORE = ${quote}Size before:${quote} +MSG_SIZE_AFTER = ${quote}Size after build:${quote} +MSG_LOAD_FILE = ${quote}Creating load file:${quote} +MSG_EXTENDED_LISTING = ${quote}Creating Extended Listing/Disassembly:${quote} +MSG_SYMBOL_TABLE = ${quote}Creating Symbol Table:${quote} +MSG_LINKING = ${quote}**** Linking :${quote} +MSG_COMPILING = ${quote}**** Compiling C :${quote} +MSG_COMPILING_ARM = ${quote}**** Compiling C (ARM-only):${quote} +MSG_COMPILINGCPP = ${quote}Compiling C++ :${quote} +MSG_COMPILINGCPP_ARM = ${quote}Compiling C++ (ARM-only):${quote} +MSG_ASSEMBLING = ${quote}**** Assembling:${quote} +MSG_ASSEMBLING_ARM = ${quote}****Assembling (ARM-only):${quote} +MSG_CLEANING = ${quote}Cleaning project:${quote} +MSG_FORMATERROR = ${quote}Can not handle output-format${quote} +MSG_ASMFROMC = ${quote}Creating asm-File from C-Source:${quote} +MSG_ASMFROMC_ARM = ${quote}Creating asm-File from C-Source (ARM-only):${quote} +MSG_PYMITEINIT = ${quote}**** Generating PyMite intermediate code${quote} + +# List of all source files. +ALLSRC = $(ASRCARM) $(ASRC) $(SRCARM) $(SRC) $(CPPSRCARM) $(CPPSRC) +# List of all source files without directory and file-extension. +ALLSRCBASE = $(notdir $(basename $(ALLSRC))) + +# Define all object files. +ALLOBJ = $(addprefix $(OUTDIR)/, $(addsuffix .o, $(ALLSRCBASE))) + +# Define all listing files (used for make clean). +LSTFILES = $(addprefix $(OUTDIR)/, $(addsuffix .lst, $(ALLSRCBASE))) +# Define all depedency-files (used for make clean). +DEPFILES = $(addprefix $(OUTDIR)/dep/, $(addsuffix .o.d, $(ALLSRCBASE))) + +elf: $(OUTDIR)/$(TARGET).elf +lss: $(OUTDIR)/$(TARGET).lss +sym: $(OUTDIR)/$(TARGET).sym +hex: $(OUTDIR)/$(TARGET).hex +bin: $(OUTDIR)/$(TARGET).bin + +# Default target. +#all: begin gccversion sizebefore build sizeafter finished end +#all: begin gencode gccversion build sizeafter finished end +all: elf + +ifeq ($(LOADFORMAT),ihex) +build: elf hex lss sym +else +ifeq ($(LOADFORMAT),binary) +build: elf bin lss sym +else +ifeq ($(LOADFORMAT),both) +build: elf hex bin lss sym +else +$(error "$(MSG_FORMATERROR) $(FORMAT)") +endif +endif +endif + +# Generate intermediate code +gencode: ${OUTDIR}/InitMods.c ${OUTDIR}/pmlib_img.c ${OUTDIR}/pmlib_nat.c ${OUTDIR}/pmlibusr_img.c ${OUTDIR}/pmlibusr_nat.c ${OUTDIR}/pmfeatures.h + +getmodname = $(firstword $(subst /, ,$1)) + +MOD_GEN := $(foreach MOD,$(MODULES),$(call getmodname,$(MOD))) + +# Generate code for module initialization +${OUTDIR}/InitMods.c: Makefile.osx + echo ${MOD_GEN} + @echo ${MSG_MODINIT} + @echo ${quote}// Autogenerated file${quote} > ${OUTDIR}/InitMods.c + @echo ${quote}${foreach MOD, ${MOD_GEN}, extern unsigned int ${MOD}Initialize(void);}${quote} >> ${OUTDIR}/InitMods.c + @echo ${quote}${foreach MOD, ${MOD_GEN}, extern unsigned int ${MOD}Start(void);}${quote} >> ${OUTDIR}/InitMods.c + @echo ${quote}void InitModules() {${quote} >> ${OUTDIR}/InitMods.c + @echo ${quote}${foreach MOD, ${MOD_GEN}, ${MOD}Initialize();}${quote} >> ${OUTDIR}/InitMods.c + @echo ${quote}}${quote} >> ${OUTDIR}/InitMods.c + @echo ${quote}void StartModules() {${quote} >> ${OUTDIR}/InitMods.c + @echo ${quote}${foreach MOD, ${MOD_GEN}, ${MOD}Start();}${quote} >> ${OUTDIR}/InitMods.c + @echo ${quote}}${quote} >> ${OUTDIR}/InitMods.c + +# Generate code for PyMite +${OUTDIR}/pmlib_img.c ${OUTDIR}/pmlib_nat.c ${OUTDIR}/pmlibusr_img.c ${OUTDIR}/pmlibusr_nat.c ${OUTDIR}/pmfeatures.h: $(wildcard ${PYMITELIB}/*.py) $(wildcard ${PYMITEPLAT}/*.py) $(wildcard ${FLIGHTPLANLIB}/*.py) $(wildcard ${FLIGHTPLANS}/*.py) $(wildcard $(UAVOBJPYTHONSYNTHDIR)/*.py) + @echo ${MSG_PYMITEINIT} + @$(PYTHON) $(PYMITETOOLS)/pmImgCreator.py -f $(PYMITEPLAT)/pmfeatures.py -c -s --memspace=flash -o $(OUTDIR)/pmlib_img.c --native-file=$(OUTDIR)/pmlib_nat.c $(PYMITELIB)/list.py $(PYMITELIB)/dict.py $(PYMITELIB)/__bi.py $(PYMITELIB)/sys.py $(PYMITELIB)/string.py $(wildcard $(FLIGHTPLANLIB)/*.py) $(wildcard $(UAVOBJPYTHONSYNTHDIR)/*.py) + @$(PYTHON) $(PYMITETOOLS)/pmGenPmFeatures.py $(PYMITEPLAT)/pmfeatures.py > $(OUTDIR)/pmfeatures.h + @$(PYTHON) $(PYMITETOOLS)/pmImgCreator.py -f $(PYMITEPLAT)/pmfeatures.py -c -u -o $(OUTDIR)/pmlibusr_img.c --native-file=$(OUTDIR)/pmlibusr_nat.c $(FLIGHTPLANS)/test.py + +# Eye candy. +begin: +## @echo + @echo $(MSG_BEGIN) + +finished: +## @echo $(MSG_ERRORS_NONE) + +end: + @echo $(MSG_END) +## @echo + +# Display sizes of sections. +ELFSIZE = $(SIZE) -A $(OUTDIR)/$(TARGET).elf +##ELFSIZE = $(SIZE) --format=Berkeley --common $(OUTDIR)/$(TARGET).elf +sizebefore: +# @if [ -f $(OUTDIR)/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi + +sizeafter: +# @if [ -f $(OUTDIR)/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi + @echo $(MSG_SIZE_AFTER) + $(ELFSIZE) + +# Display compiler version information. +gccversion : + @$(CC) --version +# @echo $(ALLOBJ) + +# Program the device. +ifeq ($(USE_BOOTLOADER), YES) +# Program the device with OP Upload Tool". +program: $(OUTDIR)/$(TARGET).bin + @echo ${quote}Programming with OP Upload Tool${quote} + ../../ground/src/experimental/upload-build-desktop/debug/OPUploadTool -d 0 -p $(OUTDIR)/$(TARGET).bin +else +ifeq ($(FLASH_TOOL),OPENOCD) +# Program the device with Dominic Rath's OPENOCD in "batch-mode", needs cfg and "reset-script". +program: $(OUTDIR)/$(TARGET).elf + @echo ${quote}Programming with OPENOCD${quote} + $(OOCD_EXE) $(OOCD_CL) +endif +endif + +# Create final output file (.hex) from ELF output file. +%.hex: %.elf +## @echo + @echo $(MSG_LOAD_FILE) $@ + $(OBJCOPY) -O ihex $< $@ + +# Create final output file (.bin) from ELF output file. +%.bin: %.elf +## @echo + @echo $(MSG_LOAD_FILE) $@ + $(OBJCOPY) -O binary $< $@ + +# Create extended listing file/disassambly from ELF output file. +# using objdump testing: option -C +%.lss: %.elf +## @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S -C -r $< > $@ +# $(OBJDUMP) -x -S $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf +## @echo + @echo $(MSG_SYMBOL_TABLE) $@ + $(NM) -n $< > $@ + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(ALLOBJ) +%.elf: $(ALLOBJ) + @echo $(MSG_LINKING) $@ +# use $(CC) for C-only projects or $(CPP) for C++-projects: + $(CC) $(THUMB) $(CFLAGS) $(ALLOBJ) --output $@ $(LDFLAGS) +# $(CPP) $(THUMB) $(CFLAGS) $(ALLOBJ) --output $@ $(LDFLAGS) + + +# Assemble: create object files from assembler source files. +define ASSEMBLE_TEMPLATE +$(OUTDIR)/$(notdir $(basename $(1))).o : $(1) +## @echo + @echo $(MSG_ASSEMBLING) $$< to $$@ + $(CC) -c $(THUMB) $$(ASFLAGS) $$< -o $$@ +endef +$(foreach src, $(ASRC), $(eval $(call ASSEMBLE_TEMPLATE, $(src)))) + +# Assemble: create object files from assembler source files. ARM-only +define ASSEMBLE_ARM_TEMPLATE +$(OUTDIR)/$(notdir $(basename $(1))).o : $(1) +## @echo + @echo $(MSG_ASSEMBLING_ARM) $$< to $$@ + $(CC) -c $$(ASFLAGS) $$< -o $$@ +endef +$(foreach src, $(ASRCARM), $(eval $(call ASSEMBLE_ARM_TEMPLATE, $(src)))) + + +# Compile: create object files from C source files. +define COMPILE_C_TEMPLATE +$(OUTDIR)/$(notdir $(basename $(1))).o : $(1) +## @echo + @echo $(MSG_COMPILING) $$< to $$@ + $(CC) -c $(THUMB) $$(CFLAGS) $$(CONLYFLAGS) $$< -o $$@ +endef +$(foreach src, $(SRC), $(eval $(call COMPILE_C_TEMPLATE, $(src)))) + +# Compile: create object files from C source files. ARM-only +define COMPILE_C_ARM_TEMPLATE +$(OUTDIR)/$(notdir $(basename $(1))).o : $(1) +## @echo + @echo $(MSG_COMPILING_ARM) $$< to $$@ + $(CC) -c $$(CFLAGS) $$(CONLYFLAGS) $$< -o $$@ +endef +$(foreach src, $(SRCARM), $(eval $(call COMPILE_C_ARM_TEMPLATE, $(src)))) + + +# Compile: create object files from C++ source files. +define COMPILE_CPP_TEMPLATE +$(OUTDIR)/$(notdir $(basename $(1))).o : $(1) +## @echo + @echo $(MSG_COMPILINGCPP) $$< to $$@ + $(CC) -c $(THUMB) $$(CFLAGS) $$(CPPFLAGS) $$< -o $$@ +endef +$(foreach src, $(CPPSRC), $(eval $(call COMPILE_CPP_TEMPLATE, $(src)))) + +# Compile: create object files from C++ source files. ARM-only +define COMPILE_CPP_ARM_TEMPLATE +$(OUTDIR)/$(notdir $(basename $(1))).o : $(1) +## @echo + @echo $(MSG_COMPILINGCPP_ARM) $$< to $$@ + $(CC) -c $$(CFLAGS) $$(CPPFLAGS) $$< -o $$@ +endef +$(foreach src, $(CPPSRCARM), $(eval $(call COMPILE_CPP_ARM_TEMPLATE, $(src)))) + + +# Compile: create assembler files from C source files. ARM/Thumb +$(SRC:.c=.s) : %.s : %.c + @echo $(MSG_ASMFROMC) $< to $@ + $(CC) $(THUMB) -S $(CFLAGS) $(CONLYFLAGS) $< -o $@ + +# Compile: create assembler files from C source files. ARM only +$(SRCARM:.c=.s) : %.s : %.c + @echo $(MSG_ASMFROMC_ARM) $< to $@ + $(CC) -S $(CFLAGS) $(CONLYFLAGS) $< -o $@ + +# Generate Doxygen documents +docs: + doxygen $(DOXYGENDIR)/doxygen.cfg + +# Target: clean project. +clean: begin clean_list finished end + +clean_list : +## @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(OUTDIR)/$(TARGET).map + $(REMOVE) $(OUTDIR)/$(TARGET).elf + $(REMOVE) $(OUTDIR)/$(TARGET).hex + $(REMOVE) $(OUTDIR)/$(TARGET).bin + $(REMOVE) $(OUTDIR)/$(TARGET).sym + $(REMOVE) $(OUTDIR)/$(TARGET).lss + $(REMOVE) $(wildcard $(OUTDIR)/*.c) + $(REMOVE) $(wildcard $(OUTDIR)/*.h) + $(REMOVE) $(ALLOBJ) + $(REMOVE) $(LSTFILES) + $(REMOVE) $(DEPFILES) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRCARM:.c=.s) + $(REMOVE) $(CPPSRC:.cpp=.s) + $(REMOVE) $(CPPSRCARM:.cpp=.s) + + +# Create output files directory +# all known MS Windows OS define the ComSpec environment variable +ifdef ComSpec +$(shell md $(OUTDIR) 2>NUL) +else +$(shell mkdir $(OUTDIR) 2>/dev/null) +endif + +# Include the dependency files. +ifdef ComSpec +-include $(shell md $(OUTDIR)\dep 2>NUL) $(wildcard $(OUTDIR)/dep/*) +else +-include $(shell mkdir $(OUTDIR) 2>/dev/null) $(shell mkdir $(OUTDIR)/dep 2>/dev/null) $(wildcard $(OUTDIR)/dep/*) +endif + + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion \ +build elf hex bin lss sym clean clean_list program gencode + diff --git a/flight/targets/boards/sparky2/firmware/UAVObjects.inc b/flight/targets/boards/sparky2/firmware/UAVObjects.inc new file mode 100644 index 000000000..4835fa649 --- /dev/null +++ b/flight/targets/boards/sparky2/firmware/UAVObjects.inc @@ -0,0 +1,133 @@ +# +# Copyright (C) 2016, The LibrePilot Project, http://www.librepilot.org +# Copyright (C) 2009-2013, The OpenPilot Team, http://www.openpilot.org +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# These are the UAVObjects supposed to be build as part of the target +# (all architectures) +UAVOBJSRCFILENAMES = +UAVOBJSRCFILENAMES += statusgrounddrive +UAVOBJSRCFILENAMES += statusvtolautotakeoff +UAVOBJSRCFILENAMES += pidstatus +UAVOBJSRCFILENAMES += statusvtolland +UAVOBJSRCFILENAMES += vtolselftuningstats +UAVOBJSRCFILENAMES += accelgyrosettings +UAVOBJSRCFILENAMES += accessorydesired +UAVOBJSRCFILENAMES += actuatorcommand +UAVOBJSRCFILENAMES += actuatordesired +UAVOBJSRCFILENAMES += actuatorsettings +UAVOBJSRCFILENAMES += attitudesettings +UAVOBJSRCFILENAMES += attitudestate +UAVOBJSRCFILENAMES += gyrostate +UAVOBJSRCFILENAMES += gyrosensor +UAVOBJSRCFILENAMES += accelstate +UAVOBJSRCFILENAMES += accelsensor +UAVOBJSRCFILENAMES += magsensor +UAVOBJSRCFILENAMES += auxmagsensor +UAVOBJSRCFILENAMES += auxmagsettings +UAVOBJSRCFILENAMES += magstate +UAVOBJSRCFILENAMES += barosensor +UAVOBJSRCFILENAMES += airspeedsensor +UAVOBJSRCFILENAMES += airspeedsettings +UAVOBJSRCFILENAMES += airspeedstate +UAVOBJSRCFILENAMES += debuglogsettings +UAVOBJSRCFILENAMES += debuglogcontrol +UAVOBJSRCFILENAMES += debuglogstatus +UAVOBJSRCFILENAMES += debuglogentry +UAVOBJSRCFILENAMES += flightbatterysettings +UAVOBJSRCFILENAMES += firmwareiapobj +UAVOBJSRCFILENAMES += flightbatterystate +UAVOBJSRCFILENAMES += flightplancontrol +UAVOBJSRCFILENAMES += flightplansettings +UAVOBJSRCFILENAMES += flightplanstatus +UAVOBJSRCFILENAMES += flighttelemetrystats +UAVOBJSRCFILENAMES += gcstelemetrystats +UAVOBJSRCFILENAMES += gcsreceiver +UAVOBJSRCFILENAMES += gpspositionsensor +UAVOBJSRCFILENAMES += gpssatellites +UAVOBJSRCFILENAMES += gpstime +UAVOBJSRCFILENAMES += gpsvelocitysensor +UAVOBJSRCFILENAMES += gpssettings +UAVOBJSRCFILENAMES += gpsextendedstatus +UAVOBJSRCFILENAMES += fixedwingpathfollowersettings +UAVOBJSRCFILENAMES += fixedwingpathfollowerstatus +UAVOBJSRCFILENAMES += vtolpathfollowersettings +UAVOBJSRCFILENAMES += groundpathfollowersettings +UAVOBJSRCFILENAMES += homelocation +UAVOBJSRCFILENAMES += i2cstats +UAVOBJSRCFILENAMES += manualcontrolcommand +UAVOBJSRCFILENAMES += manualcontrolsettings +UAVOBJSRCFILENAMES += flightmodesettings +UAVOBJSRCFILENAMES += mixersettings +UAVOBJSRCFILENAMES += mixerstatus +UAVOBJSRCFILENAMES += nedaccel +UAVOBJSRCFILENAMES += objectpersistence +UAVOBJSRCFILENAMES += oplinkreceiver +UAVOBJSRCFILENAMES += overosyncstats +UAVOBJSRCFILENAMES += overosyncsettings +UAVOBJSRCFILENAMES += pathaction +UAVOBJSRCFILENAMES += pathdesired +UAVOBJSRCFILENAMES += pathplan +UAVOBJSRCFILENAMES += pathstatus +UAVOBJSRCFILENAMES += pathsummary +UAVOBJSRCFILENAMES += positionstate +UAVOBJSRCFILENAMES += ratedesired +UAVOBJSRCFILENAMES += ekfconfiguration +UAVOBJSRCFILENAMES += ekfstatevariance +UAVOBJSRCFILENAMES += revocalibration +UAVOBJSRCFILENAMES += revosettings +UAVOBJSRCFILENAMES += sonaraltitude +UAVOBJSRCFILENAMES += stabilizationdesired +UAVOBJSRCFILENAMES += stabilizationsettings +UAVOBJSRCFILENAMES += stabilizationsettingsbank1 +UAVOBJSRCFILENAMES += stabilizationsettingsbank2 +UAVOBJSRCFILENAMES += stabilizationsettingsbank3 +UAVOBJSRCFILENAMES += stabilizationstatus +UAVOBJSRCFILENAMES += stabilizationbank +UAVOBJSRCFILENAMES += systemalarms +UAVOBJSRCFILENAMES += systemsettings +UAVOBJSRCFILENAMES += systemstats +UAVOBJSRCFILENAMES += taskinfo +UAVOBJSRCFILENAMES += callbackinfo +UAVOBJSRCFILENAMES += velocitystate +UAVOBJSRCFILENAMES += velocitydesired +UAVOBJSRCFILENAMES += watchdogstatus +UAVOBJSRCFILENAMES += flightstatus +UAVOBJSRCFILENAMES += hwsettings +UAVOBJSRCFILENAMES += receiveractivity +UAVOBJSRCFILENAMES += receiverstatus +UAVOBJSRCFILENAMES += cameradesired +UAVOBJSRCFILENAMES += camerastabsettings +UAVOBJSRCFILENAMES += altitudeholdsettings +UAVOBJSRCFILENAMES += oplinksettings +UAVOBJSRCFILENAMES += oplinkstatus +UAVOBJSRCFILENAMES += altitudefiltersettings +UAVOBJSRCFILENAMES += altitudeholdstatus +UAVOBJSRCFILENAMES += waypoint +UAVOBJSRCFILENAMES += waypointactive +UAVOBJSRCFILENAMES += poilocation +UAVOBJSRCFILENAMES += poilearnsettings +UAVOBJSRCFILENAMES += mpugyroaccelsettings +UAVOBJSRCFILENAMES += txpidsettings +UAVOBJSRCFILENAMES += txpidstatus +UAVOBJSRCFILENAMES += takeofflocation +UAVOBJSRCFILENAMES += perfcounter +UAVOBJSRCFILENAMES += systemidentsettings +UAVOBJSRCFILENAMES += systemidentstate + +UAVOBJSRC = $(foreach UAVOBJSRCFILE,$(UAVOBJSRCFILENAMES),$(FLIGHT_UAVOBJ_DIR)/$(UAVOBJSRCFILE).c ) +UAVOBJDEFINE = $(foreach UAVOBJSRCFILE,$(UAVOBJSRCFILENAMES),-DUAVOBJ_INIT_$(UAVOBJSRCFILE) ) diff --git a/flight/targets/boards/sparky2/firmware/cm3_fault_handlers.c b/flight/targets/boards/sparky2/firmware/cm3_fault_handlers.c new file mode 100644 index 000000000..e74ffa76a --- /dev/null +++ b/flight/targets/boards/sparky2/firmware/cm3_fault_handlers.c @@ -0,0 +1,90 @@ +/* + * cm3_fault_handlers.c + * + * Created on: Apr 24, 2011 + * Author: msmith + */ + +#include +#include "inc/dcc_stdio.h" +#ifdef STM32F4XX +# include +#endif +#ifdef STM32F2XX +# include +#endif + +#define FAULT_TRAMPOLINE(_vec) \ + __attribute__((naked, no_instrument_function)) \ + void \ + _vec##_Handler(void) \ + { \ + __asm(".syntax unified\n" \ + "MOVS R0, #4 \n" \ + "MOV R1, LR \n" \ + "TST R0, R1 \n" \ + "BEQ 1f \n" \ + "MRS R0, PSP \n" \ + "B " #_vec "_Handler2 \n" \ + "1: \n" \ + "MRS R0, MSP \n" \ + "B " #_vec "_Handler2 \n" \ + ".syntax divided\n"); \ + } \ + struct hack + +struct cm3_frame { + uint32_t r0; + uint32_t r1; + uint32_t r2; + uint32_t r3; + uint32_t r12; + uint32_t lr; + uint32_t pc; + uint32_t psr; +}; + +FAULT_TRAMPOLINE(HardFault); +FAULT_TRAMPOLINE(BusFault); +FAULT_TRAMPOLINE(UsageFault); + +/* this is a hackaround to avoid an issue where dereferencing SCB seems to result in bad codegen and a link error */ +#define SCB_REG(_reg) (*(uint32_t *)&(SCB->_reg)) + +void HardFault_Handler2(struct cm3_frame *frame) +{ + dbg_write_str("\nHARD FAULT"); + dbg_write_hex32(frame->pc); + dbg_write_char('\n'); + dbg_write_hex32(SCB_REG(HFSR)); + dbg_write_char('\n'); + for (;;) { + ; + } +} + +void BusFault_Handler2(struct cm3_frame *frame) +{ + dbg_write_str("\nBUS FAULT"); + dbg_write_hex32(frame->pc); + dbg_write_char('\n'); + dbg_write_hex32(SCB_REG(CFSR)); + dbg_write_char('\n'); + dbg_write_hex32(SCB_REG(BFAR)); + dbg_write_char('\n'); + for (;;) { + ; + } +} + +void UsageFault_Handler2(struct cm3_frame *frame) +{ + dbg_write_str("\nUSAGE FAULT"); + dbg_write_hex32(frame->pc); + dbg_write_char('\n'); + dbg_write_hex32(SCB_REG(CFSR)); + dbg_write_char('\n'); + for (;;) { + ; + } +} diff --git a/flight/targets/boards/sparky2/firmware/dcc_stdio.c b/flight/targets/boards/sparky2/firmware/dcc_stdio.c new file mode 100644 index 000000000..1a522e9a0 --- /dev/null +++ b/flight/targets/boards/sparky2/firmware/dcc_stdio.c @@ -0,0 +1,149 @@ +/*************************************************************************** +* Copyright (C) 2008 by Dominic Rath * +* Dominic.Rath@gmx.de * +* Copyright (C) 2008 by Spencer Oliver * +* spen@spen-soft.co.uk * +* Copyright (C) 2008 by Frederik Kriewtz * +* frederik@kriewitz.eu * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License for more details. * +* * +* You should have received a copy of the GNU General Public License * +* along with this program; if not, write to the * +* Free Software Foundation, Inc., * +* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * +***************************************************************************/ + +#include "inc/dcc_stdio.h" + +#define TARGET_REQ_TRACEMSG 0x00 +#define TARGET_REQ_DEBUGMSG_ASCII 0x01 +#define TARGET_REQ_DEBUGMSG_HEXMSG(size) (0x01 | ((size & 0xff) << 8)) +#define TARGET_REQ_DEBUGCHAR 0x02 + +/* we use the cortex_m3 DCRDR reg to simulate a arm7_9 dcc channel + * DCRDR[7:0] is used by target for status + * DCRDR[15:8] is used by target for write buffer + * DCRDR[23:16] is used for by host for status + * DCRDR[31:24] is used for by host for write buffer */ + +#define NVIC_DBG_DATA_R (*((volatile unsigned short *)0xE000EDF8)) + +#define BUSY 1 + +void dbg_write(unsigned long dcc_data) +{ + int len = 4; + + while (len--) { + /* wait for data ready */ + while (NVIC_DBG_DATA_R & BUSY) { + ; + } + + /* write our data and set write flag - tell host there is data*/ + NVIC_DBG_DATA_R = (unsigned short)(((dcc_data & 0xff) << 8) | BUSY); + dcc_data >>= 8; + } +} + +void dbg_trace_point(unsigned long number) +{ + dbg_write(TARGET_REQ_TRACEMSG | (number << 8)); +} + +void dbg_write_u32(const unsigned long *val, long len) +{ + dbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(4) | ((len & 0xffff) << 16)); + + while (len > 0) { + dbg_write(*val); + + val++; + len--; + } +} + +void dbg_write_u16(const unsigned short *val, long len) +{ + unsigned long dcc_data; + + dbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(2) | ((len & 0xffff) << 16)); + + while (len > 0) { + dcc_data = val[0] + | ((len > 1) ? val[1] << 16 : 0x0000); + + dbg_write(dcc_data); + + val += 2; + len -= 2; + } +} + +void dbg_write_u8(const unsigned char *val, long len) +{ + unsigned long dcc_data; + + dbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(1) | ((len & 0xffff) << 16)); + + while (len > 0) { + dcc_data = val[0] + | ((len > 1) ? val[1] << 8 : 0x00) + | ((len > 2) ? val[2] << 16 : 0x00) + | ((len > 3) ? val[3] << 24 : 0x00); + + dbg_write(dcc_data); + + val += 4; + len -= 4; + } +} + +void dbg_write_str(const char *msg) +{ + long len; + unsigned long dcc_data; + + for (len = 0; msg[len] && (len < 65536); len++) { + ; + } + + dbg_write(TARGET_REQ_DEBUGMSG_ASCII | ((len & 0xffff) << 16)); + + while (len > 0) { + dcc_data = msg[0] + | ((len > 1) ? msg[1] << 8 : 0x00) + | ((len > 2) ? msg[2] << 16 : 0x00) + | ((len > 3) ? msg[3] << 24 : 0x00); + dbg_write(dcc_data); + + msg += 4; + len -= 4; + } +} + +void dbg_write_char(char msg) +{ + dbg_write(TARGET_REQ_DEBUGCHAR | ((msg & 0xff) << 16)); +} + +void dbg_write_hex32(const unsigned long val) +{ + static const char hextab[] = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' + }; + + for (int shift = 28; shift >= 0; shift -= 4) { + dbg_write_char(hextab[(val >> shift) & 0xf]); + } +} diff --git a/flight/targets/boards/sparky2/firmware/inc/FreeRTOSConfig.h b/flight/targets/boards/sparky2/firmware/inc/FreeRTOSConfig.h new file mode 100644 index 000000000..8befa7a00 --- /dev/null +++ b/flight/targets/boards/sparky2/firmware/inc/FreeRTOSConfig.h @@ -0,0 +1,104 @@ +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- +* Application specific definitions. +* +* These definitions should be adjusted for your particular hardware and +* application requirements. +* +* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE +* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. +* +* See http://www.freertos.org/a00110.html. +*----------------------------------------------------------*/ + +/** + * @addtogroup PIOS PIOS + * @{ + * @addtogroup FreeRTOS FreeRTOS + * @{ + */ + +/* Notes: We use 5 task priorities */ + +#define configCPU_CLOCK_HZ (SYSCLK_FREQ) // really the NVIC clock ... +#define configTICK_RATE_HZ ((portTickType)1000) +#define configMAX_PRIORITIES ((unsigned portBASE_TYPE)5) +#define configMINIMAL_STACK_SIZE ((unsigned short)512) +#define configTOTAL_HEAP_SIZE ((size_t)(180 * 1024)) // this is minimum, not total +#define configMAX_TASK_NAME_LEN (16) + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 0 +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 0 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 0 +#define configUSE_ALTERNATIVE_API 0 +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configQUEUE_REGISTRY_SIZE 10 + +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES - 1) /* run timers at max priority */ +#define configTIMER_QUEUE_LENGTH 10 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES (2) + +/* Set the following definitions to 1 to include the API function, or zero + to exclude the API function. */ + +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 1 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_xTaskGetIdleTaskHandle 1 + +/* This is the raw value as per the Cortex-M3 NVIC. Values can be 255 + (lowest) to 1 (highest maskable) to 0 (highest non-maskable). */ +#define configKERNEL_INTERRUPT_PRIORITY 15 << 4 /* equivalent to NVIC priority 15 */ + #define configMAX_SYSCALL_INTERRUPT_PRIORITY 3 << 4 /* equivalent to NVIC priority 3 */ + +/* This is the value being used as per the ST library which permits 16 + priority values, 0 to 15. This must correspond to the + configKERNEL_INTERRUPT_PRIORITY setting. Here 15 corresponds to the lowest + NVIC value of 255. */ +#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15 + +/* Enable run time stats collection */ +#define configGENERATE_RUN_TIME_STATS 1 +#define INCLUDE_uxTaskGetRunTime 1 + +/* + * Once we move to CMSIS2 we can at least use: + * + * CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + * + * (still nothing for the DWT registers, surprisingly) + */ +#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() \ + do { \ + (*(unsigned long *)0xe000edfc) |= (1 << 24); /* DEMCR |= DEMCR_TRCENA */ \ + (*(unsigned long *)0xe0001000) |= 1; /* DWT_CTRL |= DWT_CYCCNT_ENA */ \ + } \ + while (0) +#define portGET_RUN_TIME_COUNTER_VALUE() (*(unsigned long *)0xe0001004) /* DWT_CYCCNT */ + + +/** + * @} + */ + +#endif /* FREERTOS_CONFIG_H */ diff --git a/flight/targets/boards/sparky2/firmware/inc/dcc_stdio.h b/flight/targets/boards/sparky2/firmware/inc/dcc_stdio.h new file mode 100644 index 000000000..3d7354918 --- /dev/null +++ b/flight/targets/boards/sparky2/firmware/inc/dcc_stdio.h @@ -0,0 +1,36 @@ +/*************************************************************************** +* Copyright (C) 2008 by Dominic Rath * +* Dominic.Rath@gmx.de * +* Copyright (C) 2008 by Spencer Oliver * +* spen@spen-soft.co.uk * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License for more details. * +* * +* You should have received a copy of the GNU General Public License * +* along with this program; if not, write to the * +* Free Software Foundation, Inc., * +* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * +***************************************************************************/ + +#ifndef DCC_STDIO_H +#define DCC_STDIO_H + +void dbg_trace_point(unsigned long number); + +void dbg_write_u32(const unsigned long *val, long len); +void dbg_write_u16(const unsigned short *val, long len); +void dbg_write_u8(const unsigned char *val, long len); + +void dbg_write_str(const char *msg); +void dbg_write_char(char msg); +void dbg_write_hex32(const unsigned long val); + +#endif /* DCC_STDIO_H */ diff --git a/ground/gcs/src/plugins/config/defaulthwsettingswidget.cpp b/flight/targets/boards/sparky2/firmware/inc/openpilot.h similarity index 63% rename from ground/gcs/src/plugins/config/defaulthwsettingswidget.cpp rename to flight/targets/boards/sparky2/firmware/inc/openpilot.h index 21b9274e4..42c876722 100644 --- a/ground/gcs/src/plugins/config/defaulthwsettingswidget.cpp +++ b/flight/targets/boards/sparky2/firmware/inc/openpilot.h @@ -1,13 +1,14 @@ /** ****************************************************************************** - * - * @file DefaultHwSettingsWidget.cpp + * @addtogroup OpenPilotSystem OpenPilot System + * @{ + * @addtogroup OpenPilotCore OpenPilot Core + * @{ + * @file openpilot.h * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @addtogroup GCSPlugins GCS Plugins - * @{ - * @addtogroup ConfigPlugin Config Plugin - * @{ - * @brief Placeholder for attitude panel until board is connected. + * @brief Main OpenPilot header. + * @see The GNU Public License (GPL) Version 3 + * *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify @@ -24,20 +25,28 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "defaulthwsettingswidget.h" -#include "ui_defaultattitude.h" -#include -#include -#include -DefaultHwSettingsWidget::DefaultHwSettingsWidget(QWidget *parent) : - QWidget(parent), - ui(new Ui_defaulthwsettings) -{ - ui->setupUi(this); -} -DefaultHwSettingsWidget::~DefaultHwSettingsWidget() -{ - delete ui; -} +#ifndef OPENPILOT_H +#define OPENPILOT_H + +/* PIOS Includes */ +#include + +/* OpenPilot Libraries */ +#include +#include +#include +#include + +#include "alarms.h" +#include + +/* Global Functions */ +void OpenPilotInit(void); + +#endif /* OPENPILOT_H */ +/** + * @} + * @} + */ diff --git a/flight/targets/boards/sparky2/firmware/inc/pios_board_sim.h b/flight/targets/boards/sparky2/firmware/inc/pios_board_sim.h new file mode 100644 index 000000000..68a32b116 --- /dev/null +++ b/flight/targets/boards/sparky2/firmware/inc/pios_board_sim.h @@ -0,0 +1,82 @@ +/** + ****************************************************************************** + * + * @file pios_board.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @brief Defines board hardware for the OpenPilot Version 1.1 hardware. + * @see The GNU Public License (GPL) Version 3 + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef PIOS_BOARD_H +#define PIOS_BOARD_H + + +// ------------------------ +// PIOS_LED +// ------------------------ +#define PIOS_LED_ALARM 0 +#define PIOS_LED_HEARTBEAT 1 +#define PIOS_LED_NUM 2 + +// ------------------------- +// COM +// +// See also pios_board_posix.c +// ------------------------- +// #define PIOS_USART_TX_BUFFER_SIZE 256 +#define PIOS_COM_BUFFER_SIZE 1024 +#define PIOS_COM_MAX_DEVS 255 +#define PIOS_UDP_RX_BUFFER_SIZE PIOS_COM_BUFFER_SIZE +#define PIOS_TCP_RX_BUFFER_SIZE PIOS_COM_BUFFER_SIZE + +extern uint32_t pios_com_telem_rf_id; +extern uint32_t pios_com_telem_usb_id; +extern uint32_t pios_com_gps_id; +extern uint32_t pios_com_aux_id; +extern uint32_t pios_com_spectrum_id; + +#define PIOS_COM_TELEM_RF (pios_com_telem_rf_id) +#define PIOS_COM_TELEM_USB (pios_com_telem_usb_id) +#define PIOS_COM_GPS (pios_com_gps_id) + +#ifdef PIOS_ENABLE_AUX_UART +#define PIOS_COM_AUX (pios_com_aux_id) +#define PIOS_COM_DEBUG (PIOS_COM_AUX) +#endif + +#define PIOS_GCSRCVR_TIMEOUT_MS 200 +/** + * glue macros for file IO + * STM32 uses DOSFS for file IO + */ +#define PIOS_FOPEN_READ(filename, file) (file = fopen((char *)filename, "r")) == NULL + +#define PIOS_FOPEN_WRITE(filename, file) (file = fopen((char *)filename, "w")) == NULL + +#define PIOS_FREAD(file, bufferadr, length, resultadr) (*resultadr = fread((uint8_t *)bufferadr, 1, length, *file)) != length + +#define PIOS_FWRITE(file, bufferadr, length, resultadr) *resultadr = fwrite((uint8_t *)bufferadr, 1, length, *file) + + +#define PIOS_FCLOSE(file) fclose(file) + +#define PIOS_FUNLINK(file) unlink((char *)filename) + +#endif /* PIOS_BOARD_H */ diff --git a/flight/targets/boards/sparky2/firmware/inc/pios_config.h b/flight/targets/boards/sparky2/firmware/inc/pios_config.h new file mode 100644 index 000000000..e823a82a1 --- /dev/null +++ b/flight/targets/boards/sparky2/firmware/inc/pios_config.h @@ -0,0 +1,200 @@ +/** + ****************************************************************************** + * @addtogroup OpenPilotSystem OpenPilot System + * @{ + * @addtogroup OpenPilotCore OpenPilot Core + * @{ + * @file pios_config.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2013. + * @brief PiOS configuration header, the compile time config file for the PIOS. + * Defines which PiOS libraries and features are included in the firmware. + * @see The GNU Public License (GPL) Version 3 + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PIOS_CONFIG_H +#define PIOS_CONFIG_H + +/* + * Below is a complete list of PIOS configurable options. + * Please do not remove or rearrange them. Only comment out + * unused options in the list. See main pios.h header for more + * details. + */ + +/* #define PIOS_INCLUDE_DEBUG_CONSOLE */ +/* #define DEBUG_LEVEL 0 */ +/* #define PIOS_ENABLE_DEBUG_PINS */ + +/* PIOS FreeRTOS support */ +#define PIOS_INCLUDE_FREERTOS + +/* PIOS Callback Scheduler support */ +#define PIOS_INCLUDE_CALLBACKSCHEDULER + +/* PIOS bootloader helper */ +#define PIOS_INCLUDE_BL_HELPER +/* #define PIOS_INCLUDE_BL_HELPER_WRITE_SUPPORT */ + +/* PIOS system functions */ +#define PIOS_INCLUDE_DELAY +#define PIOS_INCLUDE_INITCALL +#define PIOS_INCLUDE_SYS +#define PIOS_INCLUDE_TASK_MONITOR + +#define PIOS_INCLUDE_INSTRUMENTATION +#define PIOS_INSTRUMENTATION_MAX_COUNTERS 10 + +/* PIOS hardware peripherals */ +#define PIOS_INCLUDE_IRQ +#define PIOS_INCLUDE_RTC +#define PIOS_INCLUDE_TIM +#define PIOS_INCLUDE_USART +#define PIOS_INCLUDE_ADC +#define PIOS_INCLUDE_I2C +#define PIOS_INCLUDE_SPI +#define PIOS_INCLUDE_GPIO +#define PIOS_INCLUDE_EXTI +#define PIOS_INCLUDE_WDG + +/* PIOS USB functions */ +#define PIOS_INCLUDE_USB +#define PIOS_INCLUDE_USB_HID +#define PIOS_INCLUDE_USB_CDC +/* #define PIOS_INCLUDE_USB_RCTX */ + +/* PIOS sensor interfaces */ +/* #define PIOS_INCLUDE_ADXL345 */ +/* #define PIOS_INCLUDE_BMA180 */ +/* #define PIOS_INCLUDE_L3GD20 */ +/* #define PIOS_INCLUDE_MPU6000 */ +/* seems to be completely unused #define PIOS_MPU6000_ACCEL */ +/* #define PIOS_INCLUDE_HMC5843 */ +#define PIOS_INCLUDE_HMC5X83 +/* Sparky2 5X83s are all external and thus don't have GPIOs #define PIOS_HMC5X83_HAS_GPIOS */ +/* #define PIOS_INCLUDE_BMP085 */ +#define PIOS_INCLUDE_MS5611 +#define PIOS_INCLUDE_MPXV +#define PIOS_INCLUDE_ETASV3 +#define PIOS_INCLUDE_MS4525DO +#define PIOS_INCLUDE_MPU9250 +#define PIOS_MPU9250_ACCEL +#define PIOS_MPU9250_MAG + +#define PIOS_SENSOR_RATE 500.0f + +#define PIOS_INCLUDE_WS2811 + +/* #define PIOS_INCLUDE_HCSR04 */ + +/* PIOS receiver drivers */ +/* #define PIOS_INCLUDE_PWM */ +#define PIOS_INCLUDE_PPM +/* #define PIOS_INCLUDE_PPM_FLEXI */ +#define PIOS_INCLUDE_DSM +#define PIOS_INCLUDE_SBUS +#define PIOS_INCLUDE_SRXL +#define PIOS_INCLUDE_HOTT +#define PIOS_INCLUDE_EXBUS +#define PIOS_INCLUDE_IBUS +#define PIOS_INCLUDE_GCSRCVR +#define PIOS_INCLUDE_OPLINKRCVR +#define PIOS_INCLUDE_OPENLRS_RCVR + +/* PIOS abstract receiver interface */ +#define PIOS_INCLUDE_RCVR + +/* PIOS common peripherals */ +#define PIOS_INCLUDE_LED +#define PIOS_INCLUDE_IAP +#define PIOS_INCLUDE_SERVO +/* #define PIOS_INCLUDE_I2C_ESC */ +/* #define PIOS_INCLUDE_OVERO */ +/* #define PIOS_OVERO_SPI */ +/* #define PIOS_INCLUDE_SDCARD */ +/* #define LOG_FILENAME "startup.log" */ +#define PIOS_INCLUDE_FLASH +#define PIOS_INCLUDE_FLASH_INTERNAL +#define PIOS_INCLUDE_FLASH_LOGFS_SETTINGS +/* #define PIOS_INCLUDE_FLASH_OBJLIST */ +/* #define PIOS_INCLUDE_FLASH_EEPROM */ +#define FLASH_FREERTOS + +#define PIOS_INCLUDE_DEBUGLOG + +/* PIOS radio modules */ +#define PIOS_INCLUDE_RFM22B +#define PIOS_INCLUDE_RFM22B_COM +#define PIOS_INCLUDE_OPENLRS +/* #define PIOS_INCLUDE_PPM_OUT */ +/* #define PIOS_RFM22B_DEBUG_ON_TELEM */ + +/* PIOS misc peripherals */ +/* #define PIOS_INCLUDE_VIDEO */ +/* #define PIOS_INCLUDE_WAVE */ +/* #define PIOS_INCLUDE_UDP */ + +/* PIOS abstract comms interface with options */ +#define PIOS_INCLUDE_COM +/* #define PIOS_INCLUDE_COM_MSG */ +/* #define PIOS_INCLUDE_TELEMETRY_RF */ +#define PIOS_INCLUDE_COM_TELEM +#define PIOS_INCLUDE_COM_FLEXI +/* #define PIOS_INCLUDE_COM_AUX */ +#define PIOS_TELEM_PRIORITY_QUEUE +#define PIOS_INCLUDE_GPS +/* #define PIOS_GPS_MINIMAL */ +#define PIOS_INCLUDE_GPS_NMEA_PARSER +#define PIOS_INCLUDE_GPS_UBX_PARSER +#define PIOS_INCLUDE_GPS_DJI_PARSER +#define PIOS_GPS_SETS_HOMELOCATION + +/* Stabilization options */ +#define PIOS_QUATERNION_STABILIZATION + +/* Performance counters */ +#define IDLE_COUNTS_PER_SEC_AT_NO_LOAD 8379692 + +/* Alarm Thresholds */ +#define HEAP_LIMIT_WARNING 1000 +#define HEAP_LIMIT_CRITICAL 500 +#define IRQSTACK_LIMIT_WARNING 150 +#define IRQSTACK_LIMIT_CRITICAL 80 +#define CPULOAD_LIMIT_WARNING 80 +#define CPULOAD_LIMIT_CRITICAL 95 + +/* Task stack sizes */ +/* #define PIOS_ACTUATOR_STACK_SIZE 1020 */ +/* #define PIOS_MANUAL_STACK_SIZE 800 */ +#define PIOS_SYSTEM_STACK_SIZE 1536 +/* #define PIOS_STABILIZATION_STACK_SIZE 524 */ +/* #define PIOS_TELEM_STACK_SIZE 500 */ +/* #define PIOS_EVENTDISPATCHER_STACK_SIZE 130 */ + +/* This can't be too high to stop eventdispatcher thread overflowing */ +#define PIOS_EVENTDISAPTCHER_QUEUE 10 + +/* Revolution series */ +#define REVOLUTION + +#endif /* PIOS_CONFIG_H */ + +/** + * @} + * @} + */ diff --git a/flight/targets/boards/sparky2/firmware/inc/pios_config_sim.h b/flight/targets/boards/sparky2/firmware/inc/pios_config_sim.h new file mode 100644 index 000000000..c74e0d2f7 --- /dev/null +++ b/flight/targets/boards/sparky2/firmware/inc/pios_config_sim.h @@ -0,0 +1,81 @@ +/** + ****************************************************************************** + * + * @file pios_config.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @brief PiOS configuration header. + * Central compile time config for the project. + * @see The GNU Public License (GPL) Version 3 + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef PIOS_CONFIG_POSIX_H +#define PIOS_CONFIG_POSIX_H + + +/* Enable/Disable PiOS Modules */ +#define PIOS_INCLUDE_SYS +#define PIOS_INCLUDE_DELAY +#define PIOS_INCLUDE_LED +#define PIOS_INCLUDE_SDCARD +#define PIOS_INCLUDE_FREERTOS +#define PIOS_INCLUDE_CALLBACKSCHEDULER +#define PIOS_INCLUDE_TASK_MONITOR +#define PIOS_INCLUDE_COM +// #define PIOS_INCLUDE_GPS +#define PIOS_INCLUDE_IRQ +#define PIOS_INCLUDE_TELEMETRY_RF +#define PIOS_INCLUDE_TCP +#define PIOS_INCLUDE_UDP +#define PIOS_INCLUDE_SERVO +#define PIOS_INCLUDE_RCVR +#define PIOS_INCLUDE_GCSRCVR + +#define PIOS_RCVR_MAX_CHANNELS 12 +#define PIOS_RCVR_MAX_DEVS 3 + +/* Defaults for Logging */ +#define LOG_FILENAME "PIOS.LOG" +#define STARTUP_LOG_ENABLED 1 + +/* COM Module */ +#define GPS_BAUDRATE 19200 +#define TELEM_BAUDRATE 19200 +#define AUXUART_ENABLED 0 +#define AUXUART_BAUDRATE 19200 + +#define TELEM_QUEUE_SIZE 20 +#define PIOS_TELEM_STACK_SIZE 2048 + +/* Stabilization options */ +#define PIOS_QUATERNION_STABILIZATION + +/* GPS options */ +#define PIOS_GPS_SETS_HOMELOCATION + +#define HEAP_LIMIT_WARNING 4000 +#define HEAP_LIMIT_CRITICAL 1000 +#define IRQSTACK_LIMIT_WARNING 150 +#define IRQSTACK_LIMIT_CRITICAL 80 +#define CPULOAD_LIMIT_WARNING 80 +#define CPULOAD_LIMIT_CRITICAL 95 + +#define REVOLUTION + +#endif /* PIOS_CONFIG_POSIX_H */ diff --git a/flight/targets/boards/sparky2/firmware/inc/pios_usb_board_data.h b/flight/targets/boards/sparky2/firmware/inc/pios_usb_board_data.h new file mode 100644 index 000000000..87c2cd905 --- /dev/null +++ b/flight/targets/boards/sparky2/firmware/inc/pios_usb_board_data.h @@ -0,0 +1,47 @@ +/** + *********************************************************************************** + * @addtogroup PIOS PIOS Core hardware abstraction layer + * @{ + * @addtogroup PIOS_USB_BOARD Board specific USB definitions + * @brief Board specific USB definitions + * @{ + * + * @file pios_usb_board_data.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @see The GNU Public License (GPL) Version 3 + * + **********************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PIOS_USB_BOARD_DATA_H +#define PIOS_USB_BOARD_DATA_H + +// Note : changing below length will require changes to the USB buffer setup +#define PIOS_USB_BOARD_CDC_DATA_LENGTH 64 +#define PIOS_USB_BOARD_CDC_MGMT_LENGTH 32 +#define PIOS_USB_BOARD_HID_DATA_LENGTH 64 + +#define PIOS_USB_BOARD_EP_NUM 4 + +#include /* USB_* macros */ + +#define PIOS_USB_BOARD_PRODUCT_ID USB_PRODUCT_ID_SPARKY2 +#define PIOS_USB_BOARD_DEVICE_VER USB_OP_DEVICE_VER(USB_OP_BOARD_ID_SPARKY2, USB_OP_BOARD_MODE_FW) +#define PIOS_USB_BOARD_SN_SUFFIX "+FW" + +#endif /* PIOS_USB_BOARD_DATA_H */ diff --git a/flight/targets/boards/sparky2/firmware/pios_board.c b/flight/targets/boards/sparky2/firmware/pios_board.c new file mode 100644 index 000000000..e8a82a2f4 --- /dev/null +++ b/flight/targets/boards/sparky2/firmware/pios_board.c @@ -0,0 +1,1166 @@ +/** + **************************************************************************************** + * @file pios_board.c + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2011. + * PhoenixPilot, http://github.com/PhoenixPilot, Copyright (C) 2012 + * @addtogroup OpenPilotSystem OpenPilot System + * @{ + * @addtogroup OpenPilotCore OpenPilot Core + * @{ + * @brief Defines board specific static initializers for hardware for the Sparky2 board. + ***************************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "inc/openpilot.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef PIOS_INCLUDE_INSTRUMENTATION +#include +#endif + +/* + * Pull in the board-specific static HW definitions. + * Including .c files is a bit ugly but this allows all of + * the HW definitions to be const and static to limit their + * scope. + * + * NOTE: THIS IS THE ONLY PLACE THAT SHOULD EVER INCLUDE THIS FILE + */ +#include "../board_hw_defs.c" + +/** + * Sensor configurations + */ + +#if defined(PIOS_INCLUDE_ADC) + +#include "pios_adc_priv.h" +void PIOS_ADC_DMC_irq_handler(void); +void DMA2_Stream4_IRQHandler(void) __attribute__((alias("PIOS_ADC_DMC_irq_handler"))); +struct pios_adc_cfg pios_adc_cfg = { + .adc_dev = ADC1, + .dma = { + .irq = { + .flags = (DMA_FLAG_TCIF4 | DMA_FLAG_TEIF4 | DMA_FLAG_HTIF4), + .init = { + .NVIC_IRQChannel = DMA2_Stream4_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_LOW, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .rx = { + .channel = DMA2_Stream4, + .init = { + .DMA_Channel = DMA_Channel_0, + .DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR + }, + } + }, + .half_flag = DMA_IT_HTIF4, + .full_flag = DMA_IT_TCIF4, +}; +void PIOS_ADC_DMC_irq_handler(void) +{ + /* Call into the generic code to handle the IRQ for this specific device */ + PIOS_ADC_DMA_Handler(); +} + +#endif /* if defined(PIOS_INCLUDE_ADC) */ + +#if defined(PIOS_INCLUDE_HMC5X83) +#include "pios_hmc5x83.h" +pios_hmc5x83_dev_t i2c_port_mag = 0; +pios_hmc5x83_dev_t flexi_port_mag = 0; + +static const struct pios_hmc5x83_cfg pios_hmc5x83_cfg = { +#ifdef PIOS_HMC5X83_HAS_GPIOS + .exti_cfg = NULL, +#endif /* PIOS_HMC5X83_HAS_GPIOS */ + .M_ODR = PIOS_HMC5x83_ODR_75, + .Meas_Conf = PIOS_HMC5x83_MEASCONF_NORMAL, + .Gain = PIOS_HMC5x83_GAIN_1_9, + .Mode = PIOS_HMC5x83_MODE_CONTINUOUS, + .Driver = &PIOS_HMC5x83_I2C_DRIVER, + .Orientation = PIOS_HMC5X83_ORIENTATION_EAST_NORTH_UP, +}; +#endif /* PIOS_INCLUDE_HMC5X83 */ + +/** + * Configuration for the MS5611 chip + */ +#if defined(PIOS_INCLUDE_MS5611) +#include "pios_ms5611.h" +static const struct pios_ms5611_cfg pios_ms5611_cfg = { + .oversampling = MS5611_OSR_4096, +}; +#endif /* PIOS_INCLUDE_MS5611 */ + +/** + * Configuration for the MPU9250 chip + */ +#if defined(PIOS_INCLUDE_MPU9250) +#include "pios_mpu9250.h" +#include "pios_mpu9250_config.h" +static const struct pios_exti_cfg pios_exti_mpu9250_cfg __exti_config = { + .vector = PIOS_MPU9250_IRQHandler, + .line = EXTI_Line5, + .pin = { + .gpio = GPIOC, + .init = { + .GPIO_Pin = GPIO_Pin_5, + .GPIO_Speed = GPIO_Speed_100MHz, + .GPIO_Mode = GPIO_Mode_IN, + .GPIO_OType = GPIO_OType_OD, + .GPIO_PuPd = GPIO_PuPd_NOPULL, + }, + }, + .irq = { + .init = { + .NVIC_IRQChannel = EXTI9_5_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .exti = { + .init = { + .EXTI_Line = EXTI_Line5, // matches above GPIO pin + .EXTI_Mode = EXTI_Mode_Interrupt, + .EXTI_Trigger = EXTI_Trigger_Rising, + .EXTI_LineCmd = ENABLE, + }, + }, +}; + +static const struct pios_mpu9250_cfg pios_mpu9250_cfg = { + .exti_cfg = &pios_exti_mpu9250_cfg, + .Fifo_store = 0, + // Clock at 8 khz + .Smpl_rate_div_no_dlp = 0, + // with dlp on output rate is 1000Hz + .Smpl_rate_div_dlp = 0, + .interrupt_cfg = PIOS_MPU9250_INT_CLR_ANYRD, // | PIOS_MPU9250_INT_LATCH_EN, + .interrupt_en = PIOS_MPU9250_INTEN_DATA_RDY, + .User_ctl = PIOS_MPU9250_USERCTL_DIS_I2C | PIOS_MPU9250_USERCTL_I2C_MST_EN, + .Pwr_mgmt_clk = PIOS_MPU9250_PWRMGMT_PLL_Z_CLK, + .accel_range = PIOS_MPU9250_ACCEL_8G, + .gyro_range = PIOS_MPU9250_SCALE_2000_DEG, + .filter = PIOS_MPU9250_LOWPASS_256_HZ, + .orientation = PIOS_MPU9250_TOP_180DEG, + .fast_prescaler = PIOS_SPI_PRESCALER_4, + .std_prescaler = PIOS_SPI_PRESCALER_64, + .max_downsample = 26, +}; +#endif /* PIOS_INCLUDE_MPU9250 */ + + +/* One slot per selectable receiver group. + * eg. PWM, PPM, GCS, SPEKTRUM1, SPEKTRUM2, SBUS + * NOTE: No slot in this map for NONE. + */ +uint32_t pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_NONE]; + +#define PIOS_COM_TELEM_RF_RX_BUF_LEN 512 +#define PIOS_COM_TELEM_RF_TX_BUF_LEN 512 + +#define PIOS_COM_GPS_RX_BUF_LEN 128 +#define PIOS_COM_GPS_TX_BUF_LEN 32 + +#define PIOS_COM_TELEM_USB_RX_BUF_LEN 65 +#define PIOS_COM_TELEM_USB_TX_BUF_LEN 65 + +#define PIOS_COM_BRIDGE_RX_BUF_LEN 65 +#define PIOS_COM_BRIDGE_TX_BUF_LEN 12 + +#define PIOS_COM_RFM22B_RF_RX_BUF_LEN 512 +#define PIOS_COM_RFM22B_RF_TX_BUF_LEN 512 + +#define PIOS_COM_HKOSD_RX_BUF_LEN 22 +#define PIOS_COM_HKOSD_TX_BUF_LEN 22 + +#define PIOS_COM_MSP_TX_BUF_LEN 128 +#define PIOS_COM_MSP_RX_BUF_LEN 64 + +#define PIOS_COM_MAVLINK_TX_BUF_LEN 128 + +#if defined(PIOS_INCLUDE_DEBUG_CONSOLE) +#define PIOS_COM_DEBUGCONSOLE_TX_BUF_LEN 40 +uint32_t pios_com_debug_id; +#endif /* PIOS_INCLUDE_DEBUG_CONSOLE */ + +uint32_t pios_com_gps_id = 0; +uint32_t pios_com_telem_usb_id = 0; +uint32_t pios_com_telem_rf_id = 0; +uint32_t pios_com_rf_id = 0; +uint32_t pios_com_bridge_id = 0; +uint32_t pios_com_overo_id = 0; +uint32_t pios_com_hkosd_id = 0; +uint32_t pios_com_msp_id = 0; +uint32_t pios_com_mavlink_id = 0; +uint32_t pios_com_vcp_id = 0; + +#if defined(PIOS_INCLUDE_RFM22B) +uint32_t pios_rfm22b_id = 0; +#endif + +uintptr_t pios_uavo_settings_fs_id; +uintptr_t pios_user_fs_id; + +/* + * Setup a com port based on the passed cfg, driver and buffer sizes. + * tx size = 0 make the port rx only + * rx size = 0 make the port tx only + * having both tx and rx size = 0 is not valid and will fail further down in PIOS_COM_Init() + */ +static void PIOS_Board_configure_com(const struct pios_usart_cfg *usart_port_cfg, uint16_t rx_buf_len, uint16_t tx_buf_len, + const struct pios_com_driver *com_driver, uint32_t *pios_com_id) +{ + uint32_t pios_usart_id; + + if (PIOS_USART_Init(&pios_usart_id, usart_port_cfg)) { + PIOS_Assert(0); + } + + uint8_t *rx_buffer = 0, *tx_buffer = 0; + + if (rx_buf_len > 0) { + rx_buffer = (uint8_t *)pios_malloc(rx_buf_len); + PIOS_Assert(rx_buffer); + } + + if (tx_buf_len > 0) { + tx_buffer = (uint8_t *)pios_malloc(tx_buf_len); + PIOS_Assert(tx_buffer); + } + + if (PIOS_COM_Init(pios_com_id, com_driver, pios_usart_id, + rx_buffer, rx_buf_len, + tx_buffer, tx_buf_len)) { + PIOS_Assert(0); + } +} + +static void PIOS_Board_configure_dsm(const struct pios_usart_cfg *pios_usart_dsm_cfg, const struct pios_dsm_cfg *pios_dsm_cfg, + const struct pios_com_driver *usart_com_driver, + ManualControlSettingsChannelGroupsOptions channelgroup, uint8_t *bind) +{ + uint32_t pios_usart_dsm_id; + + if (PIOS_USART_Init(&pios_usart_dsm_id, pios_usart_dsm_cfg)) { + PIOS_Assert(0); + } + + uint32_t pios_dsm_id; + if (PIOS_DSM_Init(&pios_dsm_id, pios_dsm_cfg, usart_com_driver, + pios_usart_dsm_id, *bind)) { + PIOS_Assert(0); + } + + uint32_t pios_dsm_rcvr_id; + if (PIOS_RCVR_Init(&pios_dsm_rcvr_id, &pios_dsm_rcvr_driver, pios_dsm_id)) { + PIOS_Assert(0); + } + pios_rcvr_group_map[channelgroup] = pios_dsm_rcvr_id; +} + +static void PIOS_Board_configure_ppm(const struct pios_ppm_cfg *ppm_cfg) +{ + uint32_t pios_ppm_id; + + PIOS_PPM_Init(&pios_ppm_id, ppm_cfg); + + uint32_t pios_ppm_rcvr_id; + if (PIOS_RCVR_Init(&pios_ppm_rcvr_id, &pios_ppm_rcvr_driver, pios_ppm_id)) { + PIOS_Assert(0); + } + pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_PPM] = pios_ppm_rcvr_id; +} + +static void PIOS_Board_configure_srxl(const struct pios_usart_cfg *usart_cfg) +{ + uint32_t pios_usart_srxl_id; + + if (PIOS_USART_Init(&pios_usart_srxl_id, usart_cfg)) { + PIOS_Assert(0); + } + + uint32_t pios_srxl_id; + if (PIOS_SRXL_Init(&pios_srxl_id, &pios_usart_com_driver, pios_usart_srxl_id)) { + PIOS_Assert(0); + } + + uint32_t pios_srxl_rcvr_id; + if (PIOS_RCVR_Init(&pios_srxl_rcvr_id, &pios_srxl_rcvr_driver, pios_srxl_id)) { + PIOS_Assert(0); + } + + pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_SRXL] = pios_srxl_rcvr_id; +} + +static void PIOS_Board_configure_ibus(const struct pios_usart_cfg *usart_cfg) +{ + uint32_t pios_usart_ibus_id; + + if (PIOS_USART_Init(&pios_usart_ibus_id, usart_cfg)) { + PIOS_Assert(0); + } + + uint32_t pios_ibus_id; + if (PIOS_IBUS_Init(&pios_ibus_id, &pios_usart_com_driver, pios_usart_ibus_id)) { + PIOS_Assert(0); + } + + uint32_t pios_ibus_rcvr_id; + if (PIOS_RCVR_Init(&pios_ibus_rcvr_id, &pios_ibus_rcvr_driver, pios_ibus_id)) { + PIOS_Assert(0); + } + + pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_IBUS] = pios_ibus_rcvr_id; +} + + +static void PIOS_Board_configure_exbus(const struct pios_usart_cfg *usart_cfg) +{ + uint32_t pios_usart_exbus_id; + + if (PIOS_USART_Init(&pios_usart_exbus_id, usart_cfg)) { + PIOS_Assert(0); + } + + uint32_t pios_exbus_id; + if (PIOS_EXBUS_Init(&pios_exbus_id, &pios_usart_com_driver, pios_usart_exbus_id)) { + PIOS_Assert(0); + } + + uint32_t pios_exbus_rcvr_id; + if (PIOS_RCVR_Init(&pios_exbus_rcvr_id, &pios_exbus_rcvr_driver, pios_exbus_id)) { + PIOS_Assert(0); + } + pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_EXBUS] = pios_exbus_rcvr_id; +} + +static void PIOS_Board_configure_hott(const struct pios_usart_cfg *usart_cfg, enum pios_hott_proto proto) +{ + uint32_t pios_usart_hott_id; + + if (PIOS_USART_Init(&pios_usart_hott_id, usart_cfg)) { + PIOS_Assert(0); + } + + uint32_t pios_hott_id; + if (PIOS_HOTT_Init(&pios_hott_id, &pios_usart_com_driver, pios_usart_hott_id, proto)) { + PIOS_Assert(0); + } + + uint32_t pios_hott_rcvr_id; + if (PIOS_RCVR_Init(&pios_hott_rcvr_id, &pios_hott_rcvr_driver, pios_hott_id)) { + PIOS_Assert(0); + } + pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_HOTT] = pios_hott_rcvr_id; +} + +static void PIOS_Board_PPM_callback(const int16_t *channels) +{ + OPLinkReceiverData opl_rcvr; + + for (uint8_t i = 0; i < OPLINKRECEIVER_CHANNEL_NUMELEM; ++i) { + opl_rcvr.Channel[i] = (i < RFM22B_PPM_NUM_CHANNELS) ? channels[i] : PIOS_RCVR_TIMEOUT; + } + OPLinkReceiverSet(&opl_rcvr); +} + +/** + * PIOS_Board_Init() + * initializes all the core subsystems on this specific hardware + * called from System/openpilot.c + */ + +#include + +void PIOS_Board_Init(void) +{ + /* Delay system */ + PIOS_DELAY_Init(); + + const struct pios_board_info *bdinfo = &pios_board_info_blob; + +#if defined(PIOS_INCLUDE_LED) + const struct pios_gpio_cfg *led_cfg = PIOS_BOARD_HW_DEFS_GetLedCfg(bdinfo->board_rev); + PIOS_Assert(led_cfg); + PIOS_LED_Init(led_cfg); +#endif /* PIOS_INCLUDE_LED */ + + +#ifdef PIOS_INCLUDE_INSTRUMENTATION + PIOS_Instrumentation_Init(PIOS_INSTRUMENTATION_MAX_COUNTERS); +#endif + + /* Set up the SPI interface to the gyro/acelerometer */ + if (PIOS_SPI_Init(&pios_spi_gyro_id, &pios_spi_gyro_cfg)) { + PIOS_DEBUG_Assert(0); + } + + /* Set up the SPI interface to the flash and rfm22b */ + if (PIOS_SPI_Init(&pios_spi_telem_flash_id, &pios_spi_telem_flash_cfg)) { + PIOS_DEBUG_Assert(0); + } + +#ifdef PIOS_INCLUDE_I2C + if (PIOS_I2C_Init(&pios_i2c_mag_pressure_adapter_id, &pios_i2c_mag_pressure_adapter_cfg)) { + PIOS_DEBUG_Assert(0); + } +#endif + +#if defined(PIOS_INCLUDE_FLASH) + /* Connect flash to the appropriate interface and configure it */ + uintptr_t flash_id = 0; + + // Initialize the external USER flash + if (PIOS_Flash_Jedec_Init(&flash_id, pios_spi_telem_flash_id, 1)) { + PIOS_DEBUG_Assert(0); + } + + if (PIOS_FLASHFS_Logfs_Init(&pios_uavo_settings_fs_id, &flashfs_external_system_cfg, &pios_jedec_flash_driver, flash_id)) { + PIOS_DEBUG_Assert(0); + } +#endif /* if defined(PIOS_INCLUDE_FLASH) */ + +#if defined(PIOS_INCLUDE_RTC) + PIOS_RTC_Init(&pios_rtc_main_cfg); +#endif + /* IAP System Setup */ + PIOS_IAP_Init(); + // check for safe mode commands from gcs + if (PIOS_IAP_ReadBootCmd(0) == PIOS_IAP_CLEAR_FLASH_CMD_0 && + PIOS_IAP_ReadBootCmd(1) == PIOS_IAP_CLEAR_FLASH_CMD_1 && + PIOS_IAP_ReadBootCmd(2) == PIOS_IAP_CLEAR_FLASH_CMD_2) { + PIOS_FLASHFS_Format(pios_uavo_settings_fs_id); + PIOS_IAP_WriteBootCmd(0, 0); + PIOS_IAP_WriteBootCmd(1, 0); + PIOS_IAP_WriteBootCmd(2, 0); + } +#ifdef PIOS_INCLUDE_WDG + PIOS_WDG_Init(); +#endif + + /* Initialize the task monitor */ + if (PIOS_TASK_MONITOR_Initialize(TASKINFO_RUNNING_NUMELEM)) { + PIOS_Assert(0); + } + + /* Initialize the delayed callback library */ + PIOS_CALLBACKSCHEDULER_Initialize(); + + /* Initialize UAVObject libraries */ + EventDispatcherInitialize(); + UAVObjInitialize(); + HwSettingsInitialize(); +#if defined(PIOS_INCLUDE_RFM22B) + OPLinkSettingsInitialize(); + OPLinkStatusInitialize(); +#endif /* PIOS_INCLUDE_RFM22B */ +#if defined(PIOS_INCLUDE_HMC5X83) + AuxMagSettingsInitialize(); +#endif /* PIOS_INCLUDE_HMC5X83 */ + + /* Initialize the alarms library */ + AlarmsInitialize(); + + /* Set up pulse timers */ + PIOS_TIM_InitClock(&tim_1_cfg); + PIOS_TIM_InitClock(&tim_2_cfg); + PIOS_TIM_InitClock(&tim_3_cfg); + PIOS_TIM_InitClock(&tim_4_cfg); + PIOS_TIM_InitClock(&tim_5_cfg); + PIOS_TIM_InitClock(&tim_8_cfg); + PIOS_TIM_InitClock(&tim_9_cfg); + PIOS_TIM_InitClock(&tim_10_cfg); + PIOS_TIM_InitClock(&tim_11_cfg); + PIOS_TIM_InitClock(&tim_12_cfg); + + uint16_t boot_count = PIOS_IAP_ReadBootCount(); + if (boot_count < 3) { + PIOS_IAP_WriteBootCount(++boot_count); + AlarmsClear(SYSTEMALARMS_ALARM_BOOTFAULT); + } else { + /* Too many failed boot attempts, force hwsettings to defaults */ + HwSettingsSetDefaults(HwSettingsHandle(), 0); + AlarmsSet(SYSTEMALARMS_ALARM_BOOTFAULT, SYSTEMALARMS_ALARM_CRITICAL); + } + + /* Configure IO ports */ + uint8_t hwsettings_DSMxBind; + HwSettingsDSMxBindGet(&hwsettings_DSMxBind); + + /* Configure FlexiPort */ + uint8_t hwsettings_flexiport; + HwSettingsSPK2_FlexiPortGet(&hwsettings_flexiport); + switch (hwsettings_flexiport) { + case HWSETTINGS_SPK2_FLEXIPORT_DISABLED: + break; + case HWSETTINGS_SPK2_FLEXIPORT_TELEMETRY: + PIOS_Board_configure_com(&pios_usart_flexi_cfg, PIOS_COM_TELEM_RF_RX_BUF_LEN, PIOS_COM_TELEM_RF_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_telem_rf_id); + break; + case HWSETTINGS_SPK2_FLEXIPORT_I2C: +#if defined(PIOS_INCLUDE_I2C) +#if defined(PIOS_INCLUDE_HMC5X83) + { + // get auxmag type + AuxMagSettingsTypeOptions option; + AuxMagSettingsTypeGet(&option); + // the FlexiPort type is I2C, so if the AuxMag type is Flexi(Port) then set it up + if (option == AUXMAGSETTINGS_TYPE_FLEXI) { + if (PIOS_I2C_Init(&pios_i2c_flexiport_adapter_id, &pios_i2c_flexiport_adapter_cfg)) { + PIOS_Assert(0); + } + PIOS_DELAY_WaitmS(50); // this was after the other PIOS_I2C_Init(), so I copied it here too +#ifdef PIOS_INCLUDE_WDG + // give HMC5x83 on I2C some extra time to allow for reset, etc. if needed + // this is not in a loop, so it is safe + // leave this here even if PIOS_INCLUDE_HMC5X83 is undefined + // to avoid making something else fail when HMC5X83 is removed + PIOS_WDG_Clear(); +#endif /* PIOS_INCLUDE_WDG */ + // attach the 5x83 mag to the previously inited I2C2 + flexi_port_mag = PIOS_HMC5x83_Init(&pios_hmc5x83_cfg, pios_i2c_flexiport_adapter_id, 0); +#ifdef PIOS_INCLUDE_WDG + // give HMC5x83 on I2C some extra time to allow for reset, etc. if needed + // this is not in a loop, so it is safe + PIOS_WDG_Clear(); +#endif /* PIOS_INCLUDE_WDG */ + // add this sensor to the sensor task's list + // be careful that you don't register a slow, unimportant sensor after registering the fastest sensor + // and before registering some other fast and important sensor + // as that would cause delay and time jitter for the second fast sensor + PIOS_HMC5x83_Register(flexi_port_mag, PIOS_SENSORS_TYPE_3AXIS_AUXMAG); + // mag alarm is cleared later, so use I2C + AlarmsSet(SYSTEMALARMS_ALARM_I2C, (flexi_port_mag) ? SYSTEMALARMS_ALARM_OK : SYSTEMALARMS_ALARM_WARNING); + } + } +#endif /* PIOS_INCLUDE_HMC5X83 */ +#endif /* PIOS_INCLUDE_I2C */ + break; + case HWSETTINGS_SPK2_FLEXIPORT_GPS: + PIOS_Board_configure_com(&pios_usart_flexi_cfg, PIOS_COM_GPS_RX_BUF_LEN, PIOS_COM_GPS_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_gps_id); + break; + case HWSETTINGS_SPK2_FLEXIPORT_DSM: + // TODO: Define the various Channelgroup for Sparky2 dsm inputs and handle here + PIOS_Board_configure_dsm(&pios_usart_dsm_flexi_cfg, &pios_dsm_flexi_cfg, + &pios_usart_com_driver, MANUALCONTROLSETTINGS_CHANNELGROUPS_DSMFLEXIPORT, &hwsettings_DSMxBind); + break; + case HWSETTINGS_SPK2_FLEXIPORT_DEBUGCONSOLE: +#if defined(PIOS_INCLUDE_DEBUG_CONSOLE) + { + PIOS_Board_configure_com(&pios_usart_flexi_cfg, 0, PIOS_COM_DEBUGCONSOLE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_debug_id); + } +#endif /* PIOS_INCLUDE_DEBUG_CONSOLE */ + break; + case HWSETTINGS_SPK2_FLEXIPORT_COMBRIDGE: + PIOS_Board_configure_com(&pios_usart_flexi_cfg, PIOS_COM_BRIDGE_RX_BUF_LEN, PIOS_COM_BRIDGE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_bridge_id); + break; + case HWSETTINGS_SPK2_FLEXIPORT_MSP: + PIOS_Board_configure_com(&pios_usart_flexi_cfg, PIOS_COM_MSP_RX_BUF_LEN, PIOS_COM_MSP_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_msp_id); + break; + case HWSETTINGS_SPK2_FLEXIPORT_MAVLINK: + PIOS_Board_configure_com(&pios_usart_flexi_cfg, 0, PIOS_COM_MAVLINK_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_mavlink_id); + break; + case HWSETTINGS_SPK2_FLEXIPORT_OSDHK: + PIOS_Board_configure_com(&pios_usart_hkosd_flexi_cfg, PIOS_COM_HKOSD_RX_BUF_LEN, PIOS_COM_HKOSD_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_hkosd_id); + break; + case HWSETTINGS_SPK2_FLEXIPORT_SRXL: +#if defined(PIOS_INCLUDE_SRXL) + PIOS_Board_configure_srxl(&pios_usart_srxl_flexi_cfg); +#endif /* PIOS_INCLUDE_SRXL */ + break; + + case HWSETTINGS_SPK2_FLEXIPORT_IBUS: +#if defined(PIOS_INCLUDE_IBUS) + PIOS_Board_configure_ibus(&pios_usart_ibus_flexi_cfg); +#endif /* PIOS_INCLUDE_IBUS */ + break; + + case HWSETTINGS_SPK2_FLEXIPORT_HOTTSUMD: + case HWSETTINGS_SPK2_FLEXIPORT_HOTTSUMH: +#if defined(PIOS_INCLUDE_HOTT) + PIOS_Board_configure_hott(&pios_usart_hott_flexi_cfg, + hwsettings_flexiport == HWSETTINGS_SPK2_FLEXIPORT_HOTTSUMD ? PIOS_HOTT_PROTO_SUMD : PIOS_HOTT_PROTO_SUMH); +#endif /* PIOS_INCLUDE_HOTT */ + break; + + case HWSETTINGS_SPK2_FLEXIPORT_EXBUS: +#if defined(PIOS_INCLUDE_EXBUS) + PIOS_Board_configure_exbus(&pios_usart_exbus_flexi_cfg); +#endif /* PIOS_INCLUDE_EXBUS */ + break; + } /* hwsettings_spk2_flexiport */ + + /* Moved this here to allow binding on flexiport */ +#if defined(PIOS_INCLUDE_FLASH) + if (PIOS_FLASHFS_Logfs_Init(&pios_user_fs_id, &flashfs_external_user_cfg, &pios_jedec_flash_driver, flash_id)) { + PIOS_DEBUG_Assert(0); + } +#endif /* if defined(PIOS_INCLUDE_FLASH) */ + +#if defined(PIOS_INCLUDE_USB) + /* Initialize board specific USB data */ + PIOS_USB_BOARD_DATA_Init(); + + /* Flags to determine if various USB interfaces are advertised */ + bool usb_hid_present = false; + bool usb_cdc_present = false; + +#if defined(PIOS_INCLUDE_USB_CDC) + if (PIOS_USB_DESC_HID_CDC_Init()) { + PIOS_Assert(0); + } + usb_hid_present = true; + usb_cdc_present = true; +#else + if (PIOS_USB_DESC_HID_ONLY_Init()) { + PIOS_Assert(0); + } + usb_hid_present = true; +#endif + + uint32_t pios_usb_id; + PIOS_USB_Init(&pios_usb_id, PIOS_BOARD_HW_DEFS_GetUsbCfg(bdinfo->board_rev)); + +#if defined(PIOS_INCLUDE_USB_CDC) + + uint8_t hwsettings_usb_vcpport; + /* Configure the USB VCP port */ + HwSettingsUSB_VCPPortGet(&hwsettings_usb_vcpport); + + if (!usb_cdc_present) { + /* Force VCP port function to disabled if we haven't advertised VCP in our USB descriptor */ + hwsettings_usb_vcpport = HWSETTINGS_USB_VCPPORT_DISABLED; + } + uint32_t pios_usb_cdc_id; + if (PIOS_USB_CDC_Init(&pios_usb_cdc_id, &pios_usb_cdc_cfg, pios_usb_id)) { + PIOS_Assert(0); + } + + uint32_t pios_usb_hid_id; + if (PIOS_USB_HID_Init(&pios_usb_hid_id, &pios_usb_hid_cfg, pios_usb_id)) { + PIOS_Assert(0); + } + + switch (hwsettings_usb_vcpport) { + case HWSETTINGS_USB_VCPPORT_DISABLED: + break; + case HWSETTINGS_USB_VCPPORT_USBTELEMETRY: +#if defined(PIOS_INCLUDE_COM) + { + uint8_t *rx_buffer = (uint8_t *)pios_malloc(PIOS_COM_TELEM_USB_RX_BUF_LEN); + uint8_t *tx_buffer = (uint8_t *)pios_malloc(PIOS_COM_TELEM_USB_TX_BUF_LEN); + PIOS_Assert(rx_buffer); + PIOS_Assert(tx_buffer); + if (PIOS_COM_Init(&pios_com_telem_usb_id, &pios_usb_cdc_com_driver, pios_usb_cdc_id, + rx_buffer, PIOS_COM_TELEM_USB_RX_BUF_LEN, + tx_buffer, PIOS_COM_TELEM_USB_TX_BUF_LEN)) { + PIOS_Assert(0); + } + } +#endif /* PIOS_INCLUDE_COM */ + break; + case HWSETTINGS_USB_VCPPORT_COMBRIDGE: +#if defined(PIOS_INCLUDE_COM) + { + uint8_t *rx_buffer = (uint8_t *)pios_malloc(PIOS_COM_BRIDGE_RX_BUF_LEN); + uint8_t *tx_buffer = (uint8_t *)pios_malloc(PIOS_COM_BRIDGE_TX_BUF_LEN); + PIOS_Assert(rx_buffer); + PIOS_Assert(tx_buffer); + if (PIOS_COM_Init(&pios_com_vcp_id, &pios_usb_cdc_com_driver, pios_usb_cdc_id, + rx_buffer, PIOS_COM_BRIDGE_RX_BUF_LEN, + tx_buffer, PIOS_COM_BRIDGE_TX_BUF_LEN)) { + PIOS_Assert(0); + } + } +#endif /* PIOS_INCLUDE_COM */ + break; + case HWSETTINGS_USB_VCPPORT_DEBUGCONSOLE: +#if defined(PIOS_INCLUDE_COM) +#if defined(PIOS_INCLUDE_DEBUG_CONSOLE) + { + uint8_t *tx_buffer = (uint8_t *)pios_malloc(PIOS_COM_DEBUGCONSOLE_TX_BUF_LEN); + PIOS_Assert(tx_buffer); + if (PIOS_COM_Init(&pios_com_debug_id, &pios_usb_cdc_com_driver, pios_usb_cdc_id, + NULL, 0, + tx_buffer, PIOS_COM_DEBUGCONSOLE_TX_BUF_LEN)) { + PIOS_Assert(0); + } + } +#endif /* PIOS_INCLUDE_DEBUG_CONSOLE */ +#endif /* PIOS_INCLUDE_COM */ + + break; + } +#endif /* PIOS_INCLUDE_USB_CDC */ + +#if defined(PIOS_INCLUDE_USB_HID) + /* Configure the usb HID port */ + uint8_t hwsettings_usb_hidport; + HwSettingsUSB_HIDPortGet(&hwsettings_usb_hidport); + + if (!usb_hid_present) { + /* Force HID port function to disabled if we haven't advertised HID in our USB descriptor */ + hwsettings_usb_hidport = HWSETTINGS_USB_HIDPORT_DISABLED; + } + + switch (hwsettings_usb_hidport) { + case HWSETTINGS_USB_HIDPORT_DISABLED: + break; + case HWSETTINGS_USB_HIDPORT_USBTELEMETRY: +#if defined(PIOS_INCLUDE_COM) + { + uint8_t *rx_buffer = (uint8_t *)pios_malloc(PIOS_COM_TELEM_USB_RX_BUF_LEN); + uint8_t *tx_buffer = (uint8_t *)pios_malloc(PIOS_COM_TELEM_USB_TX_BUF_LEN); + PIOS_Assert(rx_buffer); + PIOS_Assert(tx_buffer); + if (PIOS_COM_Init(&pios_com_telem_usb_id, &pios_usb_hid_com_driver, pios_usb_hid_id, + rx_buffer, PIOS_COM_TELEM_USB_RX_BUF_LEN, + tx_buffer, PIOS_COM_TELEM_USB_TX_BUF_LEN)) { + PIOS_Assert(0); + } + } +#endif /* PIOS_INCLUDE_COM */ + break; + } + +#endif /* PIOS_INCLUDE_USB_HID */ + + if (usb_hid_present || usb_cdc_present) { + PIOS_USBHOOK_Activate(); + } +#endif /* PIOS_INCLUDE_USB */ + + + /* Configure main USART port */ + uint8_t hwsettings_mainport; + HwSettingsSPK2_MainPortGet(&hwsettings_mainport); + switch (hwsettings_mainport) { + case HWSETTINGS_SPK2_MAINPORT_DISABLED: + break; + case HWSETTINGS_SPK2_MAINPORT_TELEMETRY: + PIOS_Board_configure_com(&pios_usart_main_cfg, PIOS_COM_TELEM_RF_RX_BUF_LEN, PIOS_COM_TELEM_RF_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_telem_rf_id); + break; + case HWSETTINGS_SPK2_MAINPORT_GPS: + PIOS_Board_configure_com(&pios_usart_main_cfg, PIOS_COM_GPS_RX_BUF_LEN, PIOS_COM_GPS_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_gps_id); + break; + case HWSETTINGS_SPK2_MAINPORT_DSM: + // Force binding to zero on the main port + hwsettings_DSMxBind = 0; + + // TODO: Define the various Channelgroup for Sparky2 dsm inputs and handle here + PIOS_Board_configure_dsm(&pios_usart_dsm_main_cfg, &pios_dsm_main_cfg, + &pios_usart_com_driver, MANUALCONTROLSETTINGS_CHANNELGROUPS_DSMMAINPORT, &hwsettings_DSMxBind); + break; + case HWSETTINGS_SPK2_MAINPORT_DEBUGCONSOLE: +#if defined(PIOS_INCLUDE_DEBUG_CONSOLE) + { + PIOS_Board_configure_com(&pios_usart_main_cfg, 0, PIOS_COM_DEBUGCONSOLE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_debug_id); + } +#endif /* PIOS_INCLUDE_DEBUG_CONSOLE */ + break; + case HWSETTINGS_SPK2_MAINPORT_COMBRIDGE: + PIOS_Board_configure_com(&pios_usart_main_cfg, PIOS_COM_BRIDGE_RX_BUF_LEN, PIOS_COM_BRIDGE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_bridge_id); + break; + case HWSETTINGS_SPK2_MAINPORT_MSP: + PIOS_Board_configure_com(&pios_usart_main_cfg, PIOS_COM_MSP_RX_BUF_LEN, PIOS_COM_MSP_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_msp_id); + break; + case HWSETTINGS_SPK2_MAINPORT_MAVLINK: + PIOS_Board_configure_com(&pios_usart_main_cfg, 0, PIOS_COM_MAVLINK_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_mavlink_id); + break; + case HWSETTINGS_SPK2_MAINPORT_OSDHK: + PIOS_Board_configure_com(&pios_usart_hkosd_main_cfg, PIOS_COM_HKOSD_RX_BUF_LEN, PIOS_COM_HKOSD_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_hkosd_id); + break; + } /* hwsettings_spk2_mainport */ + + + /* Initalize the RFM22B radio COM device. */ +#if defined(PIOS_INCLUDE_RFM22B) + + /* Fetch the OPinkSettings object. */ + OPLinkSettingsData oplinkSettings; + OPLinkSettingsGet(&oplinkSettings); + + // Initialize out status object. + OPLinkStatusData oplinkStatus; + OPLinkStatusGet(&oplinkStatus); + oplinkStatus.BoardType = bdinfo->board_type; + PIOS_BL_HELPER_FLASH_Read_Description(oplinkStatus.Description, OPLINKSTATUS_DESCRIPTION_NUMELEM); + PIOS_SYS_SerialNumberGetBinary(oplinkStatus.CPUSerial); + oplinkStatus.BoardRevision = bdinfo->board_rev; + + /* Is the radio turned on? */ + bool is_coordinator = (oplinkSettings.Protocol == OPLINKSETTINGS_PROTOCOL_OPLINKCOORDINATOR); + bool openlrs = (oplinkSettings.Protocol == OPLINKSETTINGS_PROTOCOL_OPENLRS); + bool data_mode = ((oplinkSettings.LinkType == OPLINKSETTINGS_LINKTYPE_DATA) || + (oplinkSettings.LinkType == OPLINKSETTINGS_LINKTYPE_DATAANDCONTROL)); + bool ppm_mode = ((oplinkSettings.LinkType == OPLINKSETTINGS_LINKTYPE_CONTROL) || + (oplinkSettings.LinkType == OPLINKSETTINGS_LINKTYPE_DATAANDCONTROL)); + bool ppm_only = (oplinkSettings.LinkType == OPLINKSETTINGS_LINKTYPE_CONTROL); + bool is_enabled = ((oplinkSettings.Protocol != OPLINKSETTINGS_PROTOCOL_DISABLED) && + ((oplinkSettings.MaxRFPower != OPLINKSETTINGS_MAXRFPOWER_0) || openlrs)); + if (is_enabled) { + if (openlrs) { +#if defined(PIOS_INCLUDE_OPENLRS_RCVR) + const struct pios_openlrs_cfg *openlrs_cfg = PIOS_BOARD_HW_DEFS_GetOpenLRSCfg(); + uint32_t openlrs_id; + + PIOS_OpenLRS_Init(&openlrs_id, PIOS_RFM22_SPI_PORT, 0, openlrs_cfg); + { + uint32_t openlrsrcvr_id; + PIOS_OpenLRS_Rcvr_Init(&openlrsrcvr_id, openlrs_id); + uint32_t openlrsrcvr_rcvr_id; + if (PIOS_RCVR_Init(&openlrsrcvr_rcvr_id, &pios_openlrs_rcvr_driver, openlrsrcvr_id)) { + PIOS_Assert(0); + } + pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_OPENLRS] = openlrsrcvr_rcvr_id; + } +#endif /* PIOS_INCLUDE_OPENLRS_RCVR */ + } else { + /* Configure the RFM22B device. */ + const struct pios_rfm22b_cfg *rfm22b_cfg = PIOS_BOARD_HW_DEFS_GetRfm22Cfg(bdinfo->board_rev); + if (PIOS_RFM22B_Init(&pios_rfm22b_id, PIOS_RFM22_SPI_PORT, rfm22b_cfg->slave_num, rfm22b_cfg)) { + PIOS_Assert(0); + } + + /* Configure the radio com interface */ + uint8_t *rx_buffer = (uint8_t *)pios_malloc(PIOS_COM_RFM22B_RF_RX_BUF_LEN); + uint8_t *tx_buffer = (uint8_t *)pios_malloc(PIOS_COM_RFM22B_RF_TX_BUF_LEN); + PIOS_Assert(rx_buffer); + PIOS_Assert(tx_buffer); + if (PIOS_COM_Init(&pios_com_rf_id, &pios_rfm22b_com_driver, pios_rfm22b_id, + rx_buffer, PIOS_COM_RFM22B_RF_RX_BUF_LEN, + tx_buffer, PIOS_COM_RFM22B_RF_TX_BUF_LEN)) { + PIOS_Assert(0); + } + + oplinkStatus.LinkState = OPLINKSTATUS_LINKSTATE_ENABLED; + + // Set the RF data rate on the modem to ~2X the selected buad rate because the modem is half duplex. + enum rfm22b_datarate datarate = RFM22_datarate_64000; + switch (oplinkSettings.ComSpeed) { + case OPLINKSETTINGS_COMSPEED_4800: + datarate = RFM22_datarate_9600; + break; + case OPLINKSETTINGS_COMSPEED_9600: + datarate = RFM22_datarate_19200; + break; + case OPLINKSETTINGS_COMSPEED_19200: + datarate = RFM22_datarate_32000; + break; + case OPLINKSETTINGS_COMSPEED_38400: + datarate = RFM22_datarate_64000; + break; + case OPLINKSETTINGS_COMSPEED_57600: + datarate = RFM22_datarate_100000; + break; + case OPLINKSETTINGS_COMSPEED_115200: + datarate = RFM22_datarate_192000; + break; + } + + /* Set the radio configuration parameters. */ + PIOS_RFM22B_SetDeviceID(pios_rfm22b_id, oplinkSettings.CustomDeviceID); + PIOS_RFM22B_SetCoordinatorID(pios_rfm22b_id, oplinkSettings.CoordID); + PIOS_RFM22B_SetChannelConfig(pios_rfm22b_id, datarate, oplinkSettings.MinChannel, oplinkSettings.MaxChannel, is_coordinator, data_mode, ppm_mode); + + /* Set the PPM callback if we should be receiving PPM. */ + if (ppm_mode || (ppm_only && !is_coordinator)) { + PIOS_RFM22B_SetPPMCallback(pios_rfm22b_id, PIOS_Board_PPM_callback); + } + + /* Set the modem Tx poer level */ + switch (oplinkSettings.MaxRFPower) { + case OPLINKSETTINGS_MAXRFPOWER_125: + PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_0); + break; + case OPLINKSETTINGS_MAXRFPOWER_16: + PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_1); + break; + case OPLINKSETTINGS_MAXRFPOWER_316: + PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_2); + break; + case OPLINKSETTINGS_MAXRFPOWER_63: + PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_3); + break; + case OPLINKSETTINGS_MAXRFPOWER_126: + PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_4); + break; + case OPLINKSETTINGS_MAXRFPOWER_25: + PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_5); + break; + case OPLINKSETTINGS_MAXRFPOWER_50: + PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_6); + break; + case OPLINKSETTINGS_MAXRFPOWER_100: + PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_7); + break; + default: + // do nothing + break; + } + + /* Reinitialize the modem. */ + PIOS_RFM22B_Reinit(pios_rfm22b_id); + } + } else { + oplinkStatus.LinkState = OPLINKSTATUS_LINKSTATE_DISABLED; + } + + OPLinkStatusSet(&oplinkStatus); +#endif /* PIOS_INCLUDE_RFM22B */ + +#if 1 +#if defined(PIOS_INCLUDE_PPM) + const struct pios_servo_cfg *pios_servo_cfg; + // default to servo outputs only + pios_servo_cfg = &pios_servo_cfg_out; +#endif +#endif + + // Configure the receiver port + // Sparky2 receiver input on PC7 TIM8 CH2 + // include PPM,S.Bus,DSM,SRXL,IBus,EX.Bus,HoTT SUMD,HoTT SUMH + uint8_t hwsettings_rcvrport; + HwSettingsSPK2_RcvrPortGet(&hwsettings_rcvrport); + + switch (hwsettings_rcvrport) { + case HWSETTINGS_SPK2_RCVRPORT_PPM: +#if defined(PIOS_INCLUDE_PPM) + PIOS_Board_configure_ppm(&pios_ppm_cfg); +#endif /* PIOS_INCLUDE_PPM */ + break; + case HWSETTINGS_SPK2_RCVRPORT_SBUS: +#if defined(PIOS_INCLUDE_SBUS) + { + uint32_t pios_usart_sbus_id; + if (PIOS_USART_Init(&pios_usart_sbus_id, &pios_usart_sbus_rcvr_cfg)) { + PIOS_Assert(0); + } + + uint32_t pios_sbus_id; + if (PIOS_SBus_Init(&pios_sbus_id, &pios_sbus_cfg, &pios_usart_com_driver, pios_usart_sbus_id)) { + PIOS_Assert(0); + } + + uint32_t pios_sbus_rcvr_id; + if (PIOS_RCVR_Init(&pios_sbus_rcvr_id, &pios_sbus_rcvr_driver, pios_sbus_id)) { + PIOS_Assert(0); + } + pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_SBUS] = pios_sbus_rcvr_id; + } +#endif + break; + case HWSETTINGS_SPK2_RCVRPORT_SRXL: +#if defined(PIOS_INCLUDE_SRXL) + PIOS_Board_configure_srxl(&pios_usart_srxl_rcvr_cfg); +#endif /* PIOS_INCLUDE_SRXL */ + break; + case HWSETTINGS_SPK2_RCVRPORT_IBUS: +#if defined(PIOS_INCLUDE_IBUS) + PIOS_Board_configure_ibus(&pios_usart_ibus_rcvr_cfg); +#endif /* PIOS_INCLUDE_IBUS */ + break; + case HWSETTINGS_SPK2_RCVRPORT_HOTTSUMD: + case HWSETTINGS_SPK2_RCVRPORT_HOTTSUMH: +#if defined(PIOS_INCLUDE_HOTT) + PIOS_Board_configure_hott(&pios_usart_hott_rcvr_cfg, + hwsettings_rcvrport == HWSETTINGS_SPK2_RCVRPORT_HOTTSUMD ? PIOS_HOTT_PROTO_SUMD : PIOS_HOTT_PROTO_SUMH); +#endif /* PIOS_INCLUDE_HOTT */ + break; + + case HWSETTINGS_SPK2_RCVRPORT_EXBUS: +#if defined(PIOS_INCLUDE_EXBUS) + PIOS_Board_configure_exbus(&pios_usart_exbus_rcvr_cfg); +#endif /* PIOS_INCLUDE_EXBUS */ + break; + case HWSETTINGS_SPK2_RCVRPORT_DSM: + // TODO: Define the various Channelgroup for Sparky2 dsm inputs and handle here + PIOS_Board_configure_dsm(&pios_usart_dsm_rcvr_cfg, &pios_dsm_rcvr_cfg, + &pios_usart_com_driver, MANUALCONTROLSETTINGS_CHANNELGROUPS_DSMRCVRPORT, &hwsettings_DSMxBind); + break; + default: + break; + } + + if (hwsettings_rcvrport != HWSETTINGS_SPK2_RCVRPORT_SBUS) { + GPIO_Init(pios_sbus_cfg.inv.gpio, &pios_sbus_cfg.inv.init); + GPIO_WriteBit(pios_sbus_cfg.inv.gpio, pios_sbus_cfg.inv.init.GPIO_Pin, pios_sbus_cfg.gpio_inv_disable); + } + +#if defined(PIOS_INCLUDE_GCSRCVR) + GCSReceiverInitialize(); + uint32_t pios_gcsrcvr_id; + PIOS_GCSRCVR_Init(&pios_gcsrcvr_id); + uint32_t pios_gcsrcvr_rcvr_id; + if (PIOS_RCVR_Init(&pios_gcsrcvr_rcvr_id, &pios_gcsrcvr_rcvr_driver, pios_gcsrcvr_id)) { + PIOS_Assert(0); + } + pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_GCS] = pios_gcsrcvr_rcvr_id; +#endif /* PIOS_INCLUDE_GCSRCVR */ + +#if defined(PIOS_INCLUDE_OPLINKRCVR) + { + OPLinkReceiverInitialize(); + uint32_t pios_oplinkrcvr_id; + PIOS_OPLinkRCVR_Init(&pios_oplinkrcvr_id); + uint32_t pios_oplinkrcvr_rcvr_id; + if (PIOS_RCVR_Init(&pios_oplinkrcvr_rcvr_id, &pios_oplinkrcvr_rcvr_driver, pios_oplinkrcvr_id)) { + PIOS_Assert(0); + } + pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_OPLINK] = pios_oplinkrcvr_rcvr_id; + } +#endif /* PIOS_INCLUDE_OPLINKRCVR */ + +#if 1 +#ifndef PIOS_ENABLE_DEBUG_PINS + // pios_servo_cfg points to the correct configuration based on input port settings + PIOS_Servo_Init(pios_servo_cfg); +#else + PIOS_DEBUG_Init(pios_tim_servoport_all_pins, NELEMENTS(pios_tim_servoport_all_pins)); +#endif +#endif + + // Disable GPIO_A8 Pullup to prevent wrong results on battery voltage readout + GPIO_InitTypeDef gpioA8 = { + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_IN, + .GPIO_PuPd = GPIO_PuPd_NOPULL, + .GPIO_Pin = GPIO_Pin_8, + .GPIO_OType = GPIO_OType_OD, + }; + GPIO_Init(GPIOA, &gpioA8); + +#if defined(PIOS_INCLUDE_ADC) + PIOS_ADC_Init(&pios_adc_cfg); +#endif + +#if defined(PIOS_INCLUDE_MPU9250) + PIOS_MPU9250_Init(pios_spi_gyro_id, 0, &pios_mpu9250_cfg); + PIOS_MPU9250_CONFIG_Configure(); + PIOS_MPU9250_MainRegister(); + PIOS_MPU9250_MagRegister(); +#endif + +#if 0 +#ifdef PIOS_INCLUDE_WDG + // give HMC5x83 on I2C some extra time to allow for reset, etc. if needed + // this is not in a loop, so it is safe + // leave this here even if PIOS_INCLUDE_HMC5X83 is undefined + // to avoid making something else fail when HMC5X83 is removed + PIOS_WDG_Clear(); +#endif /* PIOS_INCLUDE_WDG */ + +#if defined(PIOS_INCLUDE_HMC5X83) + // on board mag is in the MPU9250 + // this hmc5x83 mag is an external mag + i2c_port_mag = PIOS_HMC5x83_Init(&pios_hmc5x83_cfg, pios_i2c_mag_pressure_adapter_id, 0); +#ifdef PIOS_INCLUDE_WDG + // give HMC5x83 on I2C some extra time to allow for reset, etc. if needed + // this is not in a loop, so it is safe + PIOS_WDG_Clear(); +#endif /* PIOS_INCLUDE_WDG */ + PIOS_HMC5x83_Register(i2c_port_mag, PIOS_SENSORS_TYPE_3AXIS_AUXMAG); +#endif /* PIOS_INCLUDE_HMC5X83 */ + +#else /* if 0 */ + +#if defined(PIOS_INCLUDE_I2C) +#ifdef PIOS_INCLUDE_WDG + // give HMC5x83 on I2C some extra time to allow for reset, etc. if needed + // this is not in a loop, so it is safe + // leave this here even if PIOS_INCLUDE_HMC5X83 is undefined + // to avoid making something else fail when HMC5X83 is removed + PIOS_WDG_Clear(); +#endif /* PIOS_INCLUDE_WDG */ +#if defined(PIOS_INCLUDE_HMC5X83) + // get auxmag type + HwSettingsSPK2_I2CPortOptions i2cOption; + AuxMagSettingsTypeOptions option; + HwSettingsSPK2_I2CPortGet(&i2cOption); + AuxMagSettingsTypeGet(&option); + // if the I2CPort type is I2C(Port) and the AuxMag type is I2C(Port) then set it up + if (i2cOption == HWSETTINGS_SPK2_I2CPORT_I2C && option == AUXMAGSETTINGS_TYPE_I2C) { + // attach the 5x83 mag to the previously inited I2C2 + i2c_port_mag = PIOS_HMC5x83_Init(&pios_hmc5x83_cfg, pios_i2c_mag_pressure_adapter_id, 0); +#ifdef PIOS_INCLUDE_WDG + // give HMC5x83 on I2C some extra time to allow for reset, etc. if needed + // this is not in a loop, so it is safe + PIOS_WDG_Clear(); +#endif /* PIOS_INCLUDE_WDG */ + // add this sensor to the sensor task's list + // be careful that you don't register a slow, unimportant sensor after registering the fastest sensor + // and before registering some other fast and important sensor + // as that would cause delay and time jitter for the second fast sensor + PIOS_HMC5x83_Register(i2c_port_mag, PIOS_SENSORS_TYPE_3AXIS_AUXMAG); + // mag alarm is cleared later, so use I2C + AlarmsSet(SYSTEMALARMS_ALARM_I2C, (i2c_port_mag) ? SYSTEMALARMS_ALARM_OK : SYSTEMALARMS_ALARM_WARNING); + } +#endif /* PIOS_INCLUDE_HMC5X83 */ +#endif /* PIOS_INCLUDE_I2C */ +#endif /* 0 */ + +#if defined(PIOS_INCLUDE_MS5611) + PIOS_MS5611_Init(&pios_ms5611_cfg, pios_i2c_mag_pressure_adapter_id); + PIOS_MS5611_Register(); +#endif /* PIOS_INCLUDE_MS5611 */ + + #ifdef PIOS_INCLUDE_WS2811 +#include + HwSettingsWS2811LED_OutOptions ws2811_pin_settings; + HwSettingsWS2811LED_OutGet(&ws2811_pin_settings); + + if (ws2811_pin_settings != HWSETTINGS_WS2811LED_OUT_DISABLED && ws2811_pin_settings < NELEMENTS(pios_ws2811_pin_cfg)) { + PIOS_WS2811_Init(&pios_ws2811_cfg, &pios_ws2811_pin_cfg[ws2811_pin_settings]); + } +#endif // PIOS_INCLUDE_WS2811 +#ifdef PIOS_INCLUDE_ADC + { + uint8_t adc_config[HWSETTINGS_ADCROUTING_NUMELEM]; + HwSettingsADCRoutingArrayGet(adc_config); + for (uint32_t i = 0; i < HWSETTINGS_ADCROUTING_NUMELEM; i++) { + if (adc_config[i] != HWSETTINGS_ADCROUTING_DISABLED) { + PIOS_ADC_PinSetup(i); + } + } + } +#endif // PIOS_INCLUDE_ADC +} + +/** + * @} + * @} + */ diff --git a/flight/targets/boards/sparky2/firmware/pios_board_sim.c b/flight/targets/boards/sparky2/firmware/pios_board_sim.c new file mode 100644 index 000000000..2171be22c --- /dev/null +++ b/flight/targets/boards/sparky2/firmware/pios_board_sim.c @@ -0,0 +1,227 @@ +/** + ****************************************************************************** + * + * @file pios_board.c + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @brief Defines board specific static initializers for hardware for the OpenPilot board. + * @see The GNU Public License (GPL) Version 3 + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "inc/openpilot.h" +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +void Stack_Change() {} + +void Stack_Change_Weak() {} + + +const struct pios_tcp_cfg pios_tcp_telem_cfg = { + .ip = "0.0.0.0", + .port = 9001, +}; + +const struct pios_udp_cfg pios_udp_telem_cfg = { + .ip = "0.0.0.0", + .port = 9001, +}; + +const struct pios_tcp_cfg pios_tcp_gps_cfg = { + .ip = "0.0.0.0", + .port = 9001, +}; +const struct pios_tcp_cfg pios_tcp_debug_cfg = { + .ip = "0.0.0.0", + .port = 9002, +}; + +#ifdef PIOS_COM_AUX +/* + * AUX USART + */ +const struct pios_tcp_cfg pios_tcp_aux_cfg = { + .ip = "0.0.0.0", + .port = 9003, +}; +#endif + +#define PIOS_COM_TELEM_RF_RX_BUF_LEN 192 +#define PIOS_COM_TELEM_RF_TX_BUF_LEN 192 +#define PIOS_COM_GPS_RX_BUF_LEN 96 + +/* + * Board specific number of devices. + */ +/* + struct pios_udp_dev pios_udp_devs[] = { + #define PIOS_UDP_TELEM 0 + { + .cfg = &pios_udp0_cfg, + }, + #define PIOS_UDP_GPS 1 + { + .cfg = &pios_udp1_cfg, + }, + #define PIOS_UDP_LOCAL 2 + { + .cfg = &pios_udp2_cfg, + }, + #ifdef PIOS_COM_AUX + #define PIOS_UDP_AUX 3 + { + .cfg = &pios_udp3_cfg, + }, + #endif + }; + + uint8_t pios_udp_num_devices = NELEMENTS(pios_udp_devs); + */ +/* + * COM devices + */ + +/* + * Board specific number of devices. + */ +extern const struct pios_com_driver pios_serial_com_driver; +extern const struct pios_com_driver pios_udp_com_driver; +extern const struct pios_com_driver pios_tcp_com_driver; + +uint32_t pios_com_telem_rf_id; +uint32_t pios_com_telem_usb_id; +uint32_t pios_com_gps_id; +uint32_t pios_com_aux_id; +uint32_t pios_com_spectrum_id; +uint32_t pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_NONE]; + +/** + * PIOS_Board_Init() + * initializes all the core systems on this specific hardware + * called from System/openpilot.c + */ +void PIOS_Board_Init(void) +{ + /* Delay system */ + PIOS_DELAY_Init(); + + /* Initialize the delayed callback library */ + PIOS_CALLBACKSCHEDULER_Initialize(); + + /* Initialize UAVObject libraries */ + EventDispatcherInitialize(); + UAVObjInitialize(); + UAVObjectsInitializeAll(); + + AccelSensorInitialize(); + BaroSensorInitialize(); + MagSensorInitialize(); + GPSPositionSensorInitialize(); + GyroSensorInitialize(); + + /* Initialize the alarms library */ + AlarmsInitialize(); + + /* Initialize the task monitor */ + if (PIOS_TASK_MONITOR_Initialize(TASKINFO_RUNNING_NUMELEM)) { + PIOS_Assert(0); + } + +#if defined(PIOS_INCLUDE_COM) +#if defined(PIOS_INCLUDE_TELEMETRY_RF) && 1 + { + uint32_t pios_tcp_telem_rf_id; + if (PIOS_TCP_Init(&pios_tcp_telem_rf_id, &pios_tcp_telem_cfg)) { + PIOS_Assert(0); + } + + uint8_t *rx_buffer = (uint8_t *)pvPortMalloc(PIOS_COM_TELEM_RF_RX_BUF_LEN); + uint8_t *tx_buffer = (uint8_t *)pvPortMalloc(PIOS_COM_TELEM_RF_TX_BUF_LEN); + PIOS_Assert(rx_buffer); + PIOS_Assert(tx_buffer); + if (PIOS_COM_Init(&pios_com_telem_rf_id, &pios_tcp_com_driver, pios_tcp_telem_rf_id, + rx_buffer, PIOS_COM_TELEM_RF_RX_BUF_LEN, + tx_buffer, PIOS_COM_TELEM_RF_TX_BUF_LEN)) { + PIOS_Assert(0); + } + } +#endif /* PIOS_INCLUDE_TELEMETRY_RF */ + +#if defined(PIOS_INCLUDE_TELEMETRY_RF) && 0 + { + uint32_t pios_udp_telem_rf_id; + if (PIOS_UDP_Init(&pios_udp_telem_rf_id, &pios_udp_telem_cfg)) { + PIOS_Assert(0); + } + + uint8_t *rx_buffer = (uint8_t *)pvPortMalloc(PIOS_COM_TELEM_RF_RX_BUF_LEN); + uint8_t *tx_buffer = (uint8_t *)pvPortMalloc(PIOS_COM_TELEM_RF_TX_BUF_LEN); + PIOS_Assert(rx_buffer); + PIOS_Assert(tx_buffer); + if (PIOS_COM_Init(&pios_com_telem_rf_id, &pios_udp_com_driver, pios_udp_telem_rf_id, + rx_buffer, PIOS_COM_TELEM_RF_RX_BUF_LEN, + tx_buffer, PIOS_COM_TELEM_RF_TX_BUF_LEN)) { + PIOS_Assert(0); + } + } +#endif /* PIOS_INCLUDE_TELEMETRY_RF */ + + +#if defined(PIOS_INCLUDE_GPS) + { + uint32_t pios_tcp_gps_id; + if (PIOS_TCP_Init(&pios_tcp_gps_id, &pios_tcp_gps_cfg)) { + PIOS_Assert(0); + } + uint8_t *rx_buffer = (uint8_t *)pvPortMalloc(PIOS_COM_GPS_RX_BUF_LEN); + PIOS_Assert(rx_buffer); + if (PIOS_COM_Init(&pios_com_gps_id, &pios_tcp_com_driver, pios_tcp_gps_id, + rx_buffer, PIOS_COM_GPS_RX_BUF_LEN, + NULL, 0)) { + PIOS_Assert(0); + } + } +#endif /* PIOS_INCLUDE_GPS */ +#endif /* if defined(PIOS_INCLUDE_COM) */ + +#if defined(PIOS_INCLUDE_GCSRCVR) + GCSReceiverInitialize(); + uint32_t pios_gcsrcvr_id; + PIOS_GCSRCVR_Init(&pios_gcsrcvr_id); + uint32_t pios_gcsrcvr_rcvr_id; + if (PIOS_RCVR_Init(&pios_gcsrcvr_rcvr_id, &pios_gcsrcvr_rcvr_driver, pios_gcsrcvr_id)) { + PIOS_Assert(0); + } + pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_GCS] = pios_gcsrcvr_rcvr_id; +#endif /* PIOS_INCLUDE_GCSRCVR */ +} + +/** + * @} + */ diff --git a/flight/targets/boards/sparky2/firmware/sparky2.cpp b/flight/targets/boards/sparky2/firmware/sparky2.cpp new file mode 100644 index 000000000..5f0a20885 --- /dev/null +++ b/flight/targets/boards/sparky2/firmware/sparky2.cpp @@ -0,0 +1,85 @@ +/** + **************************************************************************************** + * @addtogroup LibrePilotSystem LibrePilot System + * @brief These files are the core system files for Sparky2. + * They are the ground layer just above PiOS. In practice, Sparky2 actually starts + * in the main() function of sparky2.cpp + * @{ + * @addtogroup LibrePilotCore LibrePilot Core + * @brief This is where the LP firmware starts. Those files also define the compile-time + * options of the firmware. + * @{ + * @file sparky2.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2015 + * @brief Sets up and runs main tasks. + * @see The GNU Public License (GPL) Version 3 + * + ***************************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +extern "C" { +#include "inc/openpilot.h" +#include +#include + + +/* Global Variables */ + +/* Local Variables */ +} + +/** + * OpenPilot Main function: + * + * Initialize PiOS
+ * Create the "System" task (SystemModInitializein Modules/System/systemmod.c)
+ * Start FreeRTOS Scheduler (vTaskStartScheduler)
+ * If something goes wrong, blink LED1 and LED2 every 100ms + * + */ +int main() +{ + /* NOTE: Do NOT modify the following start-up sequence */ + /* Any new initialization functions should be added in OpenPilotInit() */ + vPortInitialiseBlocks(); + + /* Brings up System using CMSIS functions, enables the LEDs. */ + PIOS_SYS_Init(); + + SystemModStart(); + + /* Start the FreeRTOS scheduler */ + vTaskStartScheduler(); + + /* If all is well we will never reach here as the scheduler will now be running. */ + /* Do some PIOS_LED_HEARTBEAT to user that something bad just happened */ + PIOS_LED_Off(PIOS_LED_HEARTBEAT); \ + for (;;) { \ + PIOS_LED_Toggle(PIOS_LED_HEARTBEAT); \ + PIOS_DELAY_WaitmS(100); \ + } + ; + + return 0; +} + + +/** + * @} + * @} + */ diff --git a/flight/targets/boards/sparky2/pios_board.h b/flight/targets/boards/sparky2/pios_board.h new file mode 100644 index 000000000..63986b0fb --- /dev/null +++ b/flight/targets/boards/sparky2/pios_board.h @@ -0,0 +1,351 @@ +/** + ****************************************************************************** + * @addtogroup OpenPilotSystem OpenPilot System + * @{ + * @addtogroup OpenPilotCore OpenPilot Core + * @{ + * @file pios_board.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. + * @brief Defines board hardware for the OpenPilot Version 1.1 hardware. + * @see The GNU Public License (GPL) Version 3 + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PIOS_BOARD_H +#define PIOS_BOARD_H + +#include +// ------------------------ +// Timers and Channels Used +// ------------------------ +/* + Timer | Channel 1 | Channel 2 | Channel 3 | Channel 4 + ------+-----------+-----------+-----------+---------- + TIM1 | | | | + TIM2 | --------------- PIOS_DELAY ----------------- + TIM3 | | | | + TIM4 | | | | + TIM5 | | | | + TIM6 | | | | + TIM7 | | | | + TIM8 | | | | + ------+-----------+-----------+-----------+---------- + */ + +// ------------------------ +// DMA Channels Used +// ------------------------ +/* Channel 1 - */ +/* Channel 2 - SPI1 RX */ +/* Channel 3 - SPI1 TX */ +/* Channel 4 - SPI2 RX */ +/* Channel 5 - SPI2 TX */ +/* Channel 6 - */ +/* Channel 7 - */ +/* Channel 8 - */ +/* Channel 9 - */ +/* Channel 10 - */ +/* Channel 11 - */ +/* Channel 12 - */ + +// ------------------------ +// BOOTLOADER_SETTINGS +// ------------------------ +#define BOARD_READABLE true +#define BOARD_WRITABLE true +#define MAX_DEL_RETRYS 3 + +// ------------------------ +// PIOS_LED +// ------------------------ +#define PIOS_LED_HEARTBEAT 0 +#define PIOS_LED_ALARM 1 +#define PIOS_LED_LINK 2 + +#ifdef PIOS_RFM22B_DEBUG_ON_TELEM +#define PIOS_LED_D1 2 +#define PIOS_LED_D2 3 +#define PIOS_LED_D3 4 +#define PIOS_LED_D4 5 + +#define D1_LED_ON PIOS_LED_On(PIOS_LED_D1) +#define D1_LED_OFF PIOS_LED_Off(PIOS_LED_D1) +#define D1_LED_TOGGLE PIOS_LED_Toggle(PIOS_LED_D1) + +#define D2_LED_ON PIOS_LED_On(PIOS_LED_D2) +#define D2_LED_OFF PIOS_LED_Off(PIOS_LED_D2) +#define D2_LED_TOGGLE PIOS_LED_Toggle(PIOS_LED_D2) + +#define D3_LED_ON PIOS_LED_On(PIOS_LED_D3) +#define D3_LED_OFF PIOS_LED_Off(PIOS_LED_D3) +#define D3_LED_TOGGLE PIOS_LED_Toggle(PIOS_LED_D3) + +#define D4_LED_ON PIOS_LED_On(PIOS_LED_D4) +#define D4_LED_OFF PIOS_LED_Off(PIOS_LED_D4) +#define D4_LED_TOGGLE PIOS_LED_Toggle(PIOS_LED_D4) +#endif /* PIOS_RFM22B_DEBUG_ON_TELEM */ + +// ------------------------ +// PIOS_SPI +// See also pios_board.c +// ------------------------ +#define PIOS_SPI_MAX_DEVS 3 + +// ------------------------ +// PIOS_WDG +// ------------------------ +#define PIOS_WATCHDOG_TIMEOUT 250 +#define PIOS_WDG_REGISTER RTC_BKP_DR4 +#define PIOS_WDG_ACTUATOR 0x0001 +#define PIOS_WDG_STABILIZATION 0x0002 +#define PIOS_WDG_ATTITUDE 0x0004 +#define PIOS_WDG_MANUAL 0x0008 +#define PIOS_WDG_SENSORS 0x0010 + +// ------------------------ +// PIOS_I2C +// See also pios_board.c +// ------------------------ +#define PIOS_I2C_MAX_DEVS 3 +extern uint32_t pios_i2c_mag_pressure_adapter_id; +#define PIOS_I2C_MAIN_ADAPTER (pios_i2c_mag_pressure_adapter_id) +extern uint32_t pios_i2c_flexiport_adapter_id; +#define PIOS_I2C_FLEXI_ADAPTER (pios_i2c_flexiport_adapter_id) +#define PIOS_I2C_ETASV3_ADAPTER (PIOS_I2C_FLEXI_ADAPTER) +#define PIOS_I2C_MS4525DO_ADAPTER (PIOS_I2C_FLEXI_ADAPTER) + +// ------------------------- +// PIOS_USART +// +// See also pios_board.c +// ------------------------- +#define PIOS_USART_MAX_DEVS 5 + +// ------------------------- +// PIOS_COM +// +// See also pios_board.c +// ------------------------- +#define PIOS_COM_MAX_DEVS 4 +extern uint32_t pios_com_telem_rf_id; +extern uint32_t pios_com_rf_id; +extern uint32_t pios_com_gps_id; +extern uint32_t pios_com_telem_usb_id; +extern uint32_t pios_com_bridge_id; +extern uint32_t pios_com_vcp_id; +extern uint32_t pios_com_hkosd_id; +extern uint32_t pios_com_msp_id; +extern uint32_t pios_com_mavlink_id; + +#define PIOS_COM_GPS (pios_com_gps_id) +#define PIOS_COM_TELEM_USB (pios_com_telem_usb_id) +#define PIOS_COM_TELEM_RF (pios_com_telem_rf_id) +#define PIOS_COM_RF (pios_com_rf_id) +#define PIOS_COM_BRIDGE (pios_com_bridge_id) +#define PIOS_COM_VCP (pios_com_vcp_id) +#define PIOS_COM_OSDHK (pios_com_hkosd_id) +#define PIOS_COM_MSP (pios_com_msp_id) +#define PIOS_COM_MAVLINK (pios_com_mavlink_id) + +#if defined(PIOS_INCLUDE_DEBUG_CONSOLE) +extern uint32_t pios_com_debug_id; +#define PIOS_COM_DEBUG (pios_com_debug_id) +#endif /* PIOS_INCLUDE_DEBUG_CONSOLE */ + +#if defined(PIOS_INCLUDE_RFM22B) +extern uint32_t pios_rfm22b_id; +extern uint32_t pios_spi_telem_flash_id; +#define PIOS_RFM22_SPI_PORT (pios_spi_telem_flash_id) +#endif /* PIOS_INCLUDE_RFM22B */ + +// ------------------------- +// Packet Handler +// ------------------------- +#define RS_ECC_NPARITY 4 +#define PIOS_PH_MAX_PACKET 255 +#define PIOS_PH_WIN_SIZE 3 +#define PIOS_PH_MAX_CONNECTIONS 1 +extern uint32_t pios_packet_handler; +#define PIOS_PACKET_HANDLER (pios_packet_handler) + +// ------------------------ +// TELEMETRY +// ------------------------ +#define TELEM_QUEUE_SIZE 80 +#define PIOS_TELEM_STACK_SIZE 800 + +// ------------------------- +// System Settings +// +// See also System_stm32f4xx.c +// ------------------------- +// These macros are deprecated +// please use PIOS_PERIPHERAL_APBx_CLOCK According to the table below +// #define PIOS_MASTER_CLOCK +// #define PIOS_PERIPHERAL_CLOCK +// #define PIOS_PERIPHERAL_CLOCK + +#define PIOS_SYSCLK 168000000 +// Peripherals that belongs to APB1 are: +// DAC |PWR |CAN1,2 +// I2C1,2,3 |UART4,5 |USART3,2 +// I2S3Ext |SPI3/I2S3 |SPI2/I2S2 +// I2S2Ext |IWDG |WWDG +// RTC/BKP reg +// TIM2,3,4,5,6,7,12,13,14 + +// Calculated as SYSCLK / APBPresc * (APBPre == 1 ? 1 : 2) +// Default APB1 Prescaler = 4 +#define PIOS_PERIPHERAL_APB1_CLOCK (PIOS_SYSCLK / 2) + +// Peripherals belonging to APB2 +// SDIO |EXTI |SYSCFG |SPI1 +// ADC1,2,3 +// USART1,6 +// TIM1,8,9,10,11 +// +// Default APB2 Prescaler = 2 +// +#define PIOS_PERIPHERAL_APB2_CLOCK PIOS_SYSCLK + +// ------------------------- +// Interrupt Priorities +// ------------------------- +#define PIOS_IRQ_PRIO_LOW 12 // lower than RTOS +#define PIOS_IRQ_PRIO_MID 8 // higher than RTOS +#define PIOS_IRQ_PRIO_HIGH 5 // for SPI, ADC, I2C etc... +#define PIOS_IRQ_PRIO_HIGHEST 4 // for USART etc... +// ------------------------ +// PIOS_RCVR +// See also pios_board.c +// ------------------------ +#define PIOS_RCVR_MAX_DEVS 3 +#define PIOS_RCVR_MAX_CHANNELS 12 +#define PIOS_GCSRCVR_TIMEOUT_MS 100 +#define PIOS_RFM22B_RCVR_TIMEOUT_MS 200 +#define PIOS_OPLINK_RCVR_TIMEOUT_MS 100 + +// ------------------------- +// Receiver PPM input +// ------------------------- +#define PIOS_PPM_MAX_DEVS 1 +#define PIOS_PPM_NUM_INPUTS 16 + +// ------------------------- +// Receiver PWM input +// ------------------------- +#define PIOS_PWM_MAX_DEVS 1 +#define PIOS_PWM_NUM_INPUTS 8 + +// ------------------------- +// Receiver SPEKTRUM input +// ------------------------- +#define PIOS_SPEKTRUM_MAX_DEVS 2 +#define PIOS_SPEKTRUM_NUM_INPUTS 12 + +// ------------------------- +// Receiver S.Bus input +// ------------------------- +#define PIOS_SBUS_MAX_DEVS 1 +#define PIOS_SBUS_NUM_INPUTS (16 + 2) + +// ------------------------- +// Receiver HOTT input +// ------------------------- +#define PIOS_HOTT_MAX_DEVS 1 +#define PIOS_HOTT_NUM_INPUTS 32 + +// ------------------------- +// Receiver EX.Bus input +// ------------------------- +#define PIOS_EXBUS_MAX_DEVS 1 +#define PIOS_EXBUS_NUM_INPUTS 16 + +// ------------------------- +// Receiver Multiplex SRXL input +// ------------------------- +#define PIOS_SRXL_MAX_DEVS 1 +#define PIOS_SRXL_NUM_INPUTS 16 + +// ------------------------- +// Receiver DSM input +// ------------------------- +#define PIOS_DSM_MAX_DEVS 2 +#define PIOS_DSM_NUM_INPUTS 12 + +// ------------------------- +// Receiver FlySky IBus input +// ------------------------- +#define PIOS_IBUS_MAX_DEVS 1 +#define PIOS_IBUS_NUM_INPUTS 10 + +// ------------------------- +// Servo outputs +// ------------------------- +#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 +// -------------------------- +#define PIOS_TIM_MAX_DEVS 6 + +// ------------------------- +// ADC +// PIOS_ADC_PinGet(0) = Current sensor +// PIOS_ADC_PinGet(1) = Voltage sensor +// PIOS_ADC_PinGet(7) = VREF +// PIOS_ADC_PinGet(8) = Temperature sensor +// ------------------------- +#define PIOS_DMA_PIN_CONFIG \ + { \ + { GPIOC, GPIO_Pin_2, ADC_Channel_12, false }, /* Analog port pin 3 */ \ + { GPIOC, GPIO_Pin_3, ADC_Channel_13, false }, /* Analog port pin 4 */ \ + { GPIOA, GPIO_Pin_4, ADC_Channel_4, false }, /* Analog port pin2 (DAC) */ \ + { GPIOA, GPIO_Pin_3, ADC_Channel_3, false }, /* Servo pin 3 */ \ + { GPIOA, GPIO_Pin_2, ADC_Channel_2, false }, /* Servo pin 4 */ \ + { GPIOA, GPIO_Pin_1, ADC_Channel_1, false }, /* Servo pin 5 */ \ + { GPIOA, GPIO_Pin_0, ADC_Channel_9, false }, /* Servo pin 6 */ \ + { NULL, 0, ADC_Channel_Vrefint, false }, /* Voltage reference */ \ + { NULL, 0, ADC_Channel_TempSensor, false }, /* Temperature sensor */ \ + } + +/* we have to do all this to satisfy the PIOS_ADC_MAX_SAMPLES define in pios_adc.h */ +/* which is annoying because this then determines the rate at which we generate buffer turnover events */ +/* the objective here is to get enough buffer space to support 100Hz averaging rate */ +#define PIOS_ADC_NUM_CHANNELS 9 +#define PIOS_ADC_MAX_OVERSAMPLING 2 +#define PIOS_ADC_USE_ADC2 0 + +#define PIOS_ADC_USE_TEMP_SENSOR +#define PIOS_ADC_TEMPERATURE_PIN 8 + +// ------------------------- +// USB +// ------------------------- +#define PIOS_USB_MAX_DEVS 1 +#define PIOS_USB_ENABLED 1 /* Should remove all references to this */ +#define PIOS_USB_HID_MAX_DEVS 1 + +#endif /* PIOS_BOARD_H */ + +/** + * @} + * @} + */ diff --git a/flight/targets/boards/sparky2/pios_usb_board_data.c b/flight/targets/boards/sparky2/pios_usb_board_data.c new file mode 100644 index 000000000..48756666c --- /dev/null +++ b/flight/targets/boards/sparky2/pios_usb_board_data.c @@ -0,0 +1,99 @@ +/** + ****************************************************************************** + * @addtogroup PIOS PIOS Core hardware abstraction layer + * @{ + * @addtogroup PIOS_USB_BOARD Board specific USB definitions + * @brief Board specific USB definitions + * @{ + * + * @file pios_usb_board_data.c + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @brief Board specific USB definitions + * @see The GNU Public License (GPL) Version 3 + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "inc/pios_usb_board_data.h" /* struct usb_*, USB_* */ +#include /* PIOS_SYS_SerialNumberGet */ +#include /* PIOS_USBHOOK_* */ +#include /* PIOS_USB_UTIL_AsciiToUtf8 */ + +static const uint8_t usb_product_id[22] = { + sizeof(usb_product_id), + USB_DESC_TYPE_STRING, + 'S', 0, + 'p', 0, + 'a', 0, + 'r', 0, + 'k', 0, + 'y', 0, + ' ', 0, + '2', 0, + '.', 0, + '0', 0, +}; + +static uint8_t usb_serial_number[2 + PIOS_SYS_SERIAL_NUM_ASCII_LEN * 2 + (sizeof(PIOS_USB_BOARD_SN_SUFFIX) - 1) * 2] = { + sizeof(usb_serial_number), + USB_DESC_TYPE_STRING, +}; + +static const struct usb_string_langid usb_lang_id = { + .bLength = sizeof(usb_lang_id), + .bDescriptorType = USB_DESC_TYPE_STRING, + .bLangID = htousbs(USB_LANGID_ENGLISH_US), +}; + +static const uint8_t usb_vendor_id[28] = { + sizeof(usb_vendor_id), + USB_DESC_TYPE_STRING, + 'o', 0, + 'p', 0, + 'e', 0, + 'n', 0, + 'p', 0, + 'i', 0, + 'l', 0, + 'o', 0, + 't', 0, + '.', 0, + 'o', 0, + 'r', 0, + 'g', 0 +}; + +int32_t PIOS_USB_BOARD_DATA_Init(void) +{ + /* Load device serial number into serial number string */ + uint8_t sn[PIOS_SYS_SERIAL_NUM_ASCII_LEN + 1]; + + PIOS_SYS_SerialNumberGet((char *)sn); + + /* Concatenate the device serial number and the appropriate suffix ("+BL" or "+FW") into the USB serial number */ + uint8_t *utf8 = &(usb_serial_number[2]); + utf8 = PIOS_USB_UTIL_AsciiToUtf8(utf8, sn, PIOS_SYS_SERIAL_NUM_ASCII_LEN); + utf8 = PIOS_USB_UTIL_AsciiToUtf8(utf8, (uint8_t *)PIOS_USB_BOARD_SN_SUFFIX, sizeof(PIOS_USB_BOARD_SN_SUFFIX) - 1); + + PIOS_USBHOOK_RegisterString(USB_STRING_DESC_PRODUCT, (uint8_t *)&usb_product_id, sizeof(usb_product_id)); + PIOS_USBHOOK_RegisterString(USB_STRING_DESC_SERIAL, (uint8_t *)&usb_serial_number, sizeof(usb_serial_number)); + + PIOS_USBHOOK_RegisterString(USB_STRING_DESC_LANG, (uint8_t *)&usb_lang_id, sizeof(usb_lang_id)); + PIOS_USBHOOK_RegisterString(USB_STRING_DESC_VENDOR, (uint8_t *)&usb_vendor_id, sizeof(usb_vendor_id)); + + return 0; +} diff --git a/flight/targets/common/bootloader_updater/main.c b/flight/targets/common/bootloader_updater/main.c index 385bbdd3d..00dd28b8e 100644 --- a/flight/targets/common/bootloader_updater/main.c +++ b/flight/targets/common/bootloader_updater/main.c @@ -30,10 +30,10 @@ #include #include #include +#include #define MAX_WRI_RETRYS 3 -/* Prototype of PIOS_Board_Init() function */ -extern void PIOS_Board_Init(void); + extern void FLASH_Download(); void error(int, int); @@ -78,9 +78,16 @@ int main() struct pios_board_info *new_board_info_blob = (struct pios_board_info *)((uint32_t)embedded_image_start + board_info_blob_offset); /* Compare the two board info blobs to make sure they're for the same HW revision */ - if ((pios_board_info_blob.magic != new_board_info_blob->magic) || - (pios_board_info_blob.board_type != new_board_info_blob->board_type) || - (pios_board_info_blob.board_rev != new_board_info_blob->board_rev)) { + if ((pios_board_info_blob.magic != new_board_info_blob->magic) +#if PIOS_USB_BOARD_PRODUCT_ID == USB_PRODUCT_ID_SPARKY2 + || (((pios_board_info_blob.board_type != new_board_info_blob->board_type) + || (pios_board_info_blob.board_rev != new_board_info_blob->board_rev)) + && ((pios_board_info_blob.board_type != 0x0b) || (pios_board_info_blob.board_rev != 0x01))) +#else + || (pios_board_info_blob.board_type != new_board_info_blob->board_type) + || (pios_board_info_blob.board_rev != new_board_info_blob->board_rev) +#endif + ) { error(PIOS_LED_HEARTBEAT, 2); } diff --git a/flight/uavobjects/inc/uavobject.h.template b/flight/uavobjects/inc/uavobject.h.template index 6f3317f7f..349a01c1d 100644 --- a/flight/uavobjects/inc/uavobject.h.template +++ b/flight/uavobjects/inc/uavobject.h.template @@ -1,20 +1,20 @@ /** ****************************************************************************** * @addtogroup UAVObjects OpenPilot UAVObjects - * @{ - * @addtogroup $(NAME) $(NAME) + * @{ + * @addtogroup $(NAME) $(NAME) * @brief $(DESCRIPTION) * * Autogenerated files and functions for $(NAME) Object * - * @{ + * @{ * * @file $(NAMELC).h * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2013. - * @brief Implementation of the $(NAME) object. This file has been + * @brief Implementation of the $(NAME) object. This file has been * automatically generated by the UAVObjectGenerator. - * - * @note Object definition file: $(XMLFILE). + * + * @note Object definition file: $(XMLFILE). * This is an automatically generated file. * DO NOT modify manually. * @@ -39,7 +39,7 @@ #ifndef $(NAMEUC)_H #define $(NAMEUC)_H - +#include /* Object constants */ #define $(NAMEUC)_OBJID $(OBJIDHEX) #define $(NAMEUC)_ISSINGLEINST $(ISSINGLEINST) @@ -61,7 +61,8 @@ $(DATASTRUCTURES) * (eg a single instance on the heap) */ typedef struct { -$(DATAFIELDS)} __attribute__((packed)) $(NAME)DataPacked; + $(DATAFIELDS) +} __attribute__((packed)) $(NAME)DataPacked; /* * Packed Object data. @@ -69,24 +70,59 @@ $(DATAFIELDS)} __attribute__((packed)) $(NAME)DataPacked; * on Cortex M4F during load/store of float UAVO fields */ typedef $(NAME)DataPacked __attribute__((aligned(4))) $(NAME)Data; - + /* Typesafe Object access functions */ -static inline int32_t $(NAME)Get($(NAME)Data *dataOut) { return UAVObjGetData($(NAME)Handle(), dataOut); } -static inline int32_t $(NAME)Set(const $(NAME)Data *dataIn) { return UAVObjSetData($(NAME)Handle(), dataIn); } -static inline int32_t $(NAME)InstGet(uint16_t instId, $(NAME)Data *dataOut) { return UAVObjGetInstanceData($(NAME)Handle(), instId, dataOut); } -static inline int32_t $(NAME)InstSet(uint16_t instId, const $(NAME)Data *dataIn) { return UAVObjSetInstanceData($(NAME)Handle(), instId, dataIn); } -static inline int32_t $(NAME)ConnectQueue(xQueueHandle queue) { return UAVObjConnectQueue($(NAME)Handle(), queue, EV_MASK_ALL_UPDATES); } -static inline int32_t $(NAME)ConnectCallback(UAVObjEventCallback cb) { return UAVObjConnectCallback($(NAME)Handle(), cb, EV_MASK_ALL_UPDATES); } -static inline uint16_t $(NAME)CreateInstance() { return UAVObjCreateInstance($(NAME)Handle(), &$(NAME)SetDefaults); } -static inline void $(NAME)RequestUpdate() { UAVObjRequestUpdate($(NAME)Handle()); } -static inline void $(NAME)RequestInstUpdate(uint16_t instId) { UAVObjRequestInstanceUpdate($(NAME)Handle(), instId); } -static inline void $(NAME)Updated() { UAVObjUpdated($(NAME)Handle()); } -static inline void $(NAME)InstUpdated(uint16_t instId) { UAVObjInstanceUpdated($(NAME)Handle(), instId); } -static inline void $(NAME)Logging() { UAVObjLogging($(NAME)Handle()); } -static inline void $(NAME)InstLogging(uint16_t instId) { UAVObjInstanceLogging($(NAME)Handle(), instId); } -static inline int32_t $(NAME)GetMetadata(UAVObjMetadata *dataOut) { return UAVObjGetMetadata($(NAME)Handle(), dataOut); } -static inline int32_t $(NAME)SetMetadata(const UAVObjMetadata *dataIn) { return UAVObjSetMetadata($(NAME)Handle(), dataIn); } -static inline int8_t $(NAME)ReadOnly() { return UAVObjReadOnly($(NAME)Handle()); } +static inline int32_t $(NAME)Get($(NAME)Data * dataOut) { + return UAVObjGetData($(NAME)Handle(), dataOut); +} +static inline int32_t $(NAME)Set(const $(NAME)Data * dataIn) { + return UAVObjSetData($(NAME)Handle(), dataIn); +} +static inline int32_t $(NAME)InstGet(uint16_t instId, $(NAME)Data * dataOut) { + return UAVObjGetInstanceData($(NAME)Handle(), instId, dataOut); +} +static inline int32_t $(NAME)InstSet(uint16_t instId, const $(NAME)Data * dataIn) { + return UAVObjSetInstanceData($(NAME)Handle(), instId, dataIn); +} +static inline int32_t $(NAME)ConnectQueue(xQueueHandle queue) { + return UAVObjConnectQueue($(NAME)Handle(), queue, EV_MASK_ALL_UPDATES); +} +static inline int32_t $(NAME)ConnectCallback(UAVObjEventCallback cb) { + return UAVObjConnectCallback($(NAME)Handle(), cb, EV_MASK_ALL_UPDATES, false); +} +static inline int32_t $(NAME)ConnectFastCallback(UAVObjEventCallback cb) { + return UAVObjConnectCallback($(NAME)Handle(), cb, EV_MASK_ALL_UPDATES, true); +} +static inline uint16_t $(NAME)CreateInstance() { + return UAVObjCreateInstance($(NAME)Handle(), &$(NAME)SetDefaults); +} +static inline void $(NAME)RequestUpdate() { + UAVObjRequestUpdate($(NAME)Handle()); +} +static inline void $(NAME)RequestInstUpdate(uint16_t instId) { + UAVObjRequestInstanceUpdate($(NAME)Handle(), instId); +} +static inline void $(NAME)Updated() { + UAVObjUpdated($(NAME)Handle()); +} +static inline void $(NAME)InstUpdated(uint16_t instId) { + UAVObjInstanceUpdated($(NAME)Handle(), instId); +} +static inline void $(NAME)Logging() { + UAVObjLogging($(NAME)Handle()); +} +static inline void $(NAME)InstLogging(uint16_t instId) { + UAVObjInstanceLogging($(NAME)Handle(), instId); +} +static inline int32_t $(NAME)GetMetadata(UAVObjMetadata * dataOut) { + return UAVObjGetMetadata($(NAME)Handle(), dataOut); +} +static inline int32_t $(NAME)SetMetadata(const UAVObjMetadata * dataIn) { + return UAVObjSetMetadata($(NAME)Handle(), dataIn); +} +static inline int8_t $(NAME)ReadOnly() { + return UAVObjReadOnly($(NAME)Handle()); +} /* Set/Get functions */ $(SETGETFIELDSEXTERN) diff --git a/flight/uavobjects/inc/uavobjectmanager.h b/flight/uavobjects/inc/uavobjectmanager.h index 4f07f5953..7317e99df 100644 --- a/flight/uavobjects/inc/uavobjectmanager.h +++ b/flight/uavobjects/inc/uavobjectmanager.h @@ -236,7 +236,7 @@ void UAVObjSetLoggingUpdateMode(UAVObjMetadata *dataOut, UAVObjUpdateMode val); int8_t UAVObjReadOnly(UAVObjHandle obj); int32_t UAVObjConnectQueue(UAVObjHandle obj_handle, xQueueHandle queue, uint8_t eventMask); int32_t UAVObjDisconnectQueue(UAVObjHandle obj_handle, xQueueHandle queue); -int32_t UAVObjConnectCallback(UAVObjHandle obj_handle, UAVObjEventCallback cb, uint8_t eventMask); +int32_t UAVObjConnectCallback(UAVObjHandle obj_handle, UAVObjEventCallback cb, uint8_t eventMask, bool fast); int32_t UAVObjDisconnectCallback(UAVObjHandle obj_handle, UAVObjEventCallback cb); void UAVObjRequestUpdate(UAVObjHandle obj); void UAVObjRequestInstanceUpdate(UAVObjHandle obj_handle, uint16_t instId); diff --git a/flight/uavobjects/inc/uavobjectprivate.h b/flight/uavobjects/inc/uavobjectprivate.h index aff8364e0..88229f44e 100644 --- a/flight/uavobjects/inc/uavobjectprivate.h +++ b/flight/uavobjects/inc/uavobjectprivate.h @@ -73,6 +73,7 @@ struct ObjectEventEntry { xQueueHandle queue; UAVObjEventCallback cb; uint8_t eventMask; + bool fast; }; /* diff --git a/flight/uavobjects/uavobjectmanager.c b/flight/uavobjects/uavobjectmanager.c index fc66266c4..9916af9c0 100644 --- a/flight/uavobjects/uavobjectmanager.c +++ b/flight/uavobjects/uavobjectmanager.c @@ -37,7 +37,7 @@ // Private functions static InstanceHandle createInstance(struct UAVOData *obj, uint16_t instId); -static int32_t connectObj(UAVObjHandle obj_handle, xQueueHandle queue, UAVObjEventCallback cb, uint8_t eventMask); +static int32_t connectObj(UAVObjHandle obj_handle, xQueueHandle queue, UAVObjEventCallback cb, uint8_t eventMask, bool fast); static int32_t disconnectObj(UAVObjHandle obj_handle, xQueueHandle queue, UAVObjEventCallback cb); static void instanceAutoUpdated(UAVObjHandle obj_handle, uint16_t instId); @@ -67,6 +67,84 @@ static const UAVObjMetadata defMetadata = { static UAVObjStats stats; + +static inline bool IsMetaobject(UAVObjHandle obj_handle) +{ + /* Recover the common object header */ + struct UAVOBase *uavo_base = (struct UAVOBase *)obj_handle; + + return uavo_base->flags.isMeta; +} + +static inline bool IsSingleInstance(UAVObjHandle obj_handle) +{ + /* Recover the common object header */ + struct UAVOBase *uavo_base = (struct UAVOBase *)obj_handle; + + return uavo_base->flags.isSingle; +} + +static inline bool IsSettings(UAVObjHandle obj_handle) +{ + /* Recover the common object header */ + struct UAVOBase *uavo_base = (struct UAVOBase *)obj_handle; + + return uavo_base->flags.isSettings; +} + +static inline bool IsPriority(UAVObjHandle obj_handle) +{ + /* Recover the common object header */ + struct UAVOBase *uavo_base = (struct UAVOBase *)obj_handle; + + return uavo_base->flags.isPriority; +} + +/** + * Is this a metaobject? + * \param[in] obj The object handle + * \return True (1) if this is metaobject + */ +bool UAVObjIsMetaobject(UAVObjHandle obj_handle) +{ + PIOS_Assert(obj_handle); + return IsMetaobject(obj_handle); +} + +/** + * Does this object contains a single instance or multiple instances? + * \param[in] obj The object handle + * \return True (1) if this is a single instance object + */ +bool UAVObjIsSingleInstance(UAVObjHandle obj_handle) +{ + PIOS_Assert(obj_handle); + return IsSingleInstance(obj_handle); +} + +/** + * Is this a settings object? + * \param[in] obj The object handle + * \return True (1) if this is a settings object + */ +bool UAVObjIsSettings(UAVObjHandle obj_handle) +{ + PIOS_Assert(obj_handle); + return IsSettings(obj_handle); +} + + +/** + * Is this a prioritized object? + * \param[in] obj The object handle + * \return True (1) if this is a prioritized object + */ +bool UAVObjIsPriority(UAVObjHandle obj_handle) +{ + return IsPriority(obj_handle); +} + + /** * Initialize the object manager * \return 0 Success @@ -309,7 +387,7 @@ uint32_t UAVObjGetID(UAVObjHandle obj_handle) /* Recover the common object header */ struct UAVOBase *uavo_base = (struct UAVOBase *)obj_handle; - if (UAVObjIsMetaobject(obj_handle)) { + if (IsMetaobject(obj_handle)) { /* We have a meta object, find our containing UAVO */ struct UAVOData *uavo_data = container_of((struct UAVOMeta *)uavo_base, struct UAVOData, metaObj); @@ -362,7 +440,7 @@ UAVObjHandle UAVObjGetLinkedObj(UAVObjHandle obj_handle) /* Recover the common object header */ struct UAVOBase *uavo_base = (struct UAVOBase *)obj_handle; - if (UAVObjIsMetaobject(obj_handle)) { + if (IsMetaobject(obj_handle)) { /* We have a meta object, find our containing UAVO. */ struct UAVOData *uavo_data = container_of((struct UAVOMeta *)uavo_base, struct UAVOData, metaObj); @@ -384,7 +462,7 @@ uint16_t UAVObjGetNumInstances(UAVObjHandle obj_handle) { PIOS_Assert(obj_handle); - if (UAVObjIsSingleInstance(obj_handle)) { + if (IsSingleInstance(obj_handle)) { /* Only one instance is allowed */ return 1; } else { @@ -405,7 +483,7 @@ uint16_t UAVObjCreateInstance(UAVObjHandle obj_handle, { PIOS_Assert(obj_handle); - if (UAVObjIsMetaobject(obj_handle)) { + if (IsMetaobject(obj_handle)) { return 0; } @@ -433,67 +511,6 @@ unlock_exit: return instId; } -/** - * Does this object contains a single instance or multiple instances? - * \param[in] obj The object handle - * \return True (1) if this is a single instance object - */ -bool UAVObjIsSingleInstance(UAVObjHandle obj_handle) -{ - PIOS_Assert(obj_handle); - - /* Recover the common object header */ - struct UAVOBase *uavo_base = (struct UAVOBase *)obj_handle; - - return uavo_base->flags.isSingle; -} - -/** - * Is this a metaobject? - * \param[in] obj The object handle - * \return True (1) if this is metaobject - */ -bool UAVObjIsMetaobject(UAVObjHandle obj_handle) -{ - PIOS_Assert(obj_handle); - - /* Recover the common object header */ - struct UAVOBase *uavo_base = (struct UAVOBase *)obj_handle; - - return uavo_base->flags.isMeta; -} - -/** - * Is this a settings object? - * \param[in] obj The object handle - * \return True (1) if this is a settings object - */ -bool UAVObjIsSettings(UAVObjHandle obj_handle) -{ - PIOS_Assert(obj_handle); - - /* Recover the common object header */ - struct UAVOBase *uavo_base = (struct UAVOBase *)obj_handle; - - return uavo_base->flags.isSettings; -} - -/** - * Is this a prioritized object? - * \param[in] obj The object handle - * \return True (1) if this is a prioritized object - */ -bool UAVObjIsPriority(UAVObjHandle obj_handle) -{ - PIOS_Assert(obj_handle); - - /* Recover the common object header */ - struct UAVOBase *uavo_base = (struct UAVOBase *)obj_handle; - - return uavo_base->flags.isPriority; -} - - /** * Unpack an object from a byte array * \param[in] obj The object handle @@ -510,7 +527,7 @@ int32_t UAVObjUnpack(UAVObjHandle obj_handle, uint16_t instId, const uint8_t *da int32_t rc = -1; - if (UAVObjIsMetaobject(obj_handle)) { + if (IsMetaobject(obj_handle)) { if (instId != 0) { goto unlock_exit; } @@ -561,7 +578,7 @@ int32_t UAVObjPack(UAVObjHandle obj_handle, uint16_t instId, uint8_t *dataOut) int32_t rc = -1; - if (UAVObjIsMetaobject(obj_handle)) { + if (IsMetaobject(obj_handle)) { if (instId != 0) { goto unlock_exit; } @@ -603,7 +620,7 @@ uint8_t UAVObjUpdateCRC(UAVObjHandle obj_handle, uint16_t instId, uint8_t crc) // Lock xSemaphoreTakeRecursive(mutex, portMAX_DELAY); - if (UAVObjIsMetaobject(obj_handle)) { + if (IsMetaobject(obj_handle)) { if (instId != 0) { goto unlock_exit; } @@ -642,7 +659,7 @@ void UAVObjInstanceWriteToLog(UAVObjHandle obj_handle, uint16_t instId) // Lock xSemaphoreTakeRecursive(mutex, portMAX_DELAY); - if (UAVObjIsMetaobject(obj_handle)) { + if (IsMetaobject(obj_handle)) { if (instId != 0) { goto unlock_exit; } @@ -683,7 +700,7 @@ int32_t UAVObjSaveSettings() // Save all settings objects UAVO_LIST_ITERATE(obj) // Check if this is a settings object - if (UAVObjIsSettings(obj)) { + if (IsSettings(obj)) { // Save object if (UAVObjSave((UAVObjHandle)obj, 0) == -1) { @@ -713,7 +730,7 @@ int32_t UAVObjLoadSettings() // Load all settings objects UAVO_LIST_ITERATE(obj) // Check if this is a settings object - if (UAVObjIsSettings(obj)) { + if (IsSettings(obj)) { // Load object if (UAVObjLoad((UAVObjHandle)obj, 0) == -1) { @@ -743,7 +760,7 @@ int32_t UAVObjDeleteSettings() // Save all settings objects UAVO_LIST_ITERATE(obj) // Check if this is a settings object - if (UAVObjIsSettings(obj)) { + if (IsSettings(obj)) { // Save object if (UAVObjDelete((UAVObjHandle)obj, 0) == -1) { @@ -901,7 +918,7 @@ int32_t UAVObjSetInstanceData(UAVObjHandle obj_handle, uint16_t instId, int32_t rc = -1; - if (UAVObjIsMetaobject(obj_handle)) { + if (IsMetaobject(obj_handle)) { if (instId != 0) { goto unlock_exit; } @@ -951,7 +968,7 @@ int32_t UAVObjSetInstanceDataField(UAVObjHandle obj_handle, uint16_t instId, con int32_t rc = -1; - if (UAVObjIsMetaobject(obj_handle)) { + if (IsMetaobject(obj_handle)) { // Get instance information if (instId != 0) { goto unlock_exit; @@ -1018,7 +1035,7 @@ int32_t UAVObjGetInstanceData(UAVObjHandle obj_handle, uint16_t instId, int32_t rc = -1; - if (UAVObjIsMetaobject(obj_handle)) { + if (IsMetaobject(obj_handle)) { // Get instance information if (instId != 0) { goto unlock_exit; @@ -1064,7 +1081,7 @@ int32_t UAVObjGetInstanceDataField(UAVObjHandle obj_handle, uint16_t instId, voi int32_t rc = -1; - if (UAVObjIsMetaobject(obj_handle)) { + if (IsMetaobject(obj_handle)) { // Get instance information if (instId != 0) { goto unlock_exit; @@ -1117,7 +1134,7 @@ int32_t UAVObjSetMetadata(UAVObjHandle obj_handle, const UAVObjMetadata *dataIn) PIOS_Assert(obj_handle); // Set metadata (metadata of metaobjects can not be modified) - if (UAVObjIsMetaobject(obj_handle)) { + if (IsMetaobject(obj_handle)) { return -1; } @@ -1143,7 +1160,7 @@ int32_t UAVObjGetMetadata(UAVObjHandle obj_handle, UAVObjMetadata *dataOut) xSemaphoreTakeRecursive(mutex, portMAX_DELAY); // Get metadata - if (UAVObjIsMetaobject(obj_handle)) { + if (IsMetaobject(obj_handle)) { memcpy(dataOut, &defMetadata, sizeof(UAVObjMetadata)); } else { UAVObjGetData((UAVObjHandle)MetaObjectPtr((struct UAVOData *)obj_handle), @@ -1325,7 +1342,7 @@ void UAVObjSetLoggingUpdateMode(UAVObjMetadata *metadata, UAVObjUpdateMode val) int8_t UAVObjReadOnly(UAVObjHandle obj_handle) { PIOS_Assert(obj_handle); - if (!UAVObjIsMetaobject(obj_handle)) { + if (!IsMetaobject(obj_handle)) { return UAVObjGetAccess(LinkedMetaDataPtr((struct UAVOData *)obj_handle)) == ACCESS_READONLY; } return -1; @@ -1346,7 +1363,7 @@ int32_t UAVObjConnectQueue(UAVObjHandle obj_handle, xQueueHandle queue, PIOS_Assert(queue); int32_t res; xSemaphoreTakeRecursive(mutex, portMAX_DELAY); - res = connectObj(obj_handle, queue, 0, eventMask); + res = connectObj(obj_handle, queue, 0, eventMask, false); xSemaphoreGiveRecursive(mutex); return res; } @@ -1377,12 +1394,12 @@ int32_t UAVObjDisconnectQueue(UAVObjHandle obj_handle, xQueueHandle queue) * \return 0 if success or -1 if failure */ int32_t UAVObjConnectCallback(UAVObjHandle obj_handle, UAVObjEventCallback cb, - uint8_t eventMask) + uint8_t eventMask, bool fast) { PIOS_Assert(obj_handle); int32_t res; xSemaphoreTakeRecursive(mutex, portMAX_DELAY); - res = connectObj(obj_handle, 0, cb, eventMask); + res = connectObj(obj_handle, 0, cb, eventMask, fast); xSemaphoreGiveRecursive(mutex); return res; } @@ -1535,8 +1552,10 @@ int32_t sendEvent(struct UAVOBase *obj, uint16_t instId, UAVObjEventType trigger // Invoke callback (from event task) if a valid one is registered if (event->cb) { - // invoke callback from the event task, will not block - if (EventCallbackDispatch(&msg, event->cb) != pdTRUE) { + if (event->fast) { + event->cb(&msg); + } else if (EventCallbackDispatch(&msg, event->cb) != pdTRUE) { + // invoke callback from the event task, will not block ++stats.eventCallbackErrors; stats.lastCallbackErrorID = UAVObjGetID(obj); } @@ -1555,7 +1574,7 @@ static InstanceHandle createInstance(struct UAVOData *obj, uint16_t instId) struct UAVOMultiInst *instEntry; /* Don't allow more than one instance for single instance objects */ - if (UAVObjIsSingleInstance(&(obj->base))) { + if (IsSingleInstance(&(obj->base))) { PIOS_Assert(0); return NULL; } @@ -1600,7 +1619,7 @@ static InstanceHandle createInstance(struct UAVOData *obj, uint16_t instId) */ InstanceHandle getInstance(struct UAVOData *obj, uint16_t instId) { - if (UAVObjIsMetaobject(&obj->base)) { + if (IsMetaobject(&obj->base)) { /* Metadata Instance */ if (instId != 0) { @@ -1610,7 +1629,7 @@ InstanceHandle getInstance(struct UAVOData *obj, uint16_t instId) /* Augment our pointer to reflect the proper type */ struct UAVOMeta *uavo_meta = (struct UAVOMeta *)obj; return &(uavo_meta->instance0); - } else if (UAVObjIsSingleInstance(&(obj->base))) { + } else if (IsSingleInstance(&(obj->base))) { /* Single Instance */ if (instId != 0) { @@ -1651,7 +1670,7 @@ InstanceHandle getInstance(struct UAVOData *obj, uint16_t instId) * \return 0 if success or -1 if failure */ static int32_t connectObj(UAVObjHandle obj_handle, xQueueHandle queue, - UAVObjEventCallback cb, uint8_t eventMask) + UAVObjEventCallback cb, uint8_t eventMask, bool fast) { struct ObjectEventEntry *event; struct UAVOBase *obj; @@ -1662,6 +1681,7 @@ static int32_t connectObj(UAVObjHandle obj_handle, xQueueHandle queue, if (event->queue == queue && event->cb == cb) { // Already connected, update event mask and return event->eventMask = eventMask; + event->fast = fast; return 0; } } @@ -1674,6 +1694,7 @@ static int32_t connectObj(UAVObjHandle obj_handle, xQueueHandle queue, event->queue = queue; event->cb = cb; event->eventMask = eventMask; + event->fast = fast; LL_APPEND(obj->next_event, event); // Done diff --git a/ground/gcs/copydata.pro b/ground/gcs/copydata.pro index ab43eb464..e2fc81a67 100644 --- a/ground/gcs/copydata.pro +++ b/ground/gcs/copydata.pro @@ -3,131 +3,160 @@ include(gcs.pri) TEMPLATE = aux # Copy Qt runtime libraries into the build directory (to run or package) -equals(copyqt, 1) { - linux { - QT_LIBS = libQt5Core.so.5 \ - libQt5Gui.so.5 \ - libQt5Widgets.so.5 \ - libQt5Network.so.5 \ - libQt5OpenGL.so.5 \ - libQt5Sql.so.5 \ - libQt5Svg.so.5 \ - libQt5Test.so.5 \ - libQt5Xml.so.5 \ - libQt5Declarative.so.5 \ - libQt5XmlPatterns.so.5 \ - libQt5Script.so.5 \ - libQt5Concurrent.so.5 \ - libQt5PrintSupport.so.5 \ - libQt5SerialPort.so.5 \ - libQt5Multimedia.so.5 \ - libQt5MultimediaWidgets.so.5 \ - libQt5Quick.so.5 \ - libQt5QuickWidgets.so.5 \ - libQt5Qml.so.5 \ - libQt5DBus.so.5 \ - libQt5QuickParticles.so.5 \ - libqgsttools_p.so.1 \ - libicui18n.so.53 \ - libicuuc.so.53 \ - libicudata.so.53 - for(lib, QT_LIBS) { - addCopyFileTarget($${lib},$$[QT_INSTALL_LIBS],$${GCS_QT_LIBRARY_PATH}) - } - QT_PLUGINS = iconengines/libqsvgicon.so \ - imageformats/libqgif.so \ - imageformats/libqico.so \ - imageformats/libqjpeg.so \ - imageformats/libqmng.so \ - imageformats/libqsvg.so \ - imageformats/libqtiff.so \ - mediaservice/libgstaudiodecoder.so \ - mediaservice/libgstmediaplayer.so \ - platforms/libqxcb.so \ - sqldrivers/libqsqlite.so +linux { + QT_LIBS = \ + libQt5Core.so.5 \ + libQt5Gui.so.5 \ + libQt5Widgets.so.5 \ + libQt5Network.so.5 \ + libQt5OpenGL.so.5 \ + libQt5Sql.so.5 \ + libQt5Svg.so.5 \ + libQt5Test.so.5 \ + libQt5Xml.so.5 \ + libQt5XmlPatterns.so.5 \ + libQt5Script.so.5 \ + libQt5Concurrent.so.5 \ + libQt5PrintSupport.so.5 \ + libQt5SerialPort.so.5 \ + libQt5Multimedia.so.5 \ + libQt5MultimediaWidgets.so.5 \ + libQt5Quick.so.5 \ + libQt5QuickWidgets.so.5 \ + libQt5Qml.so.5 \ + libQt5DBus.so.5 \ + libQt5QuickParticles.so.5 \ + libQt5XcbQpa.so.5 \ + libQt5X11Extras.so.5 \ + libicui18n.so.56 \ + libicuuc.so.56 \ + libicudata.so.56 + + contains(QT_ARCH, x86_64) { + QT_LIBS += \ + libqgsttools_p.so.1 } - win32 { - # set debug suffix if needed - CONFIG(debug, debug|release):DS = "d" - - # copy Qt DLLs - QT_DLLS = Qt5Core$${DS}.dll \ - Qt5Gui$${DS}.dll \ - Qt5Widgets$${DS}.dll \ - Qt5Network$${DS}.dll \ - Qt5OpenGL$${DS}.dll \ - Qt5Sql$${DS}.dll \ - Qt5Svg$${DS}.dll \ - Qt5Test$${DS}.dll \ - Qt5Xml$${DS}.dll \ - Qt5Declarative$${DS}.dll \ - Qt5XmlPatterns$${DS}.dll \ - Qt5Script$${DS}.dll \ - Qt5Concurrent$${DS}.dll \ - Qt5PrintSupport$${DS}.dll \ - Qt5SerialPort$${DS}.dll \ - Qt5Multimedia$${DS}.dll \ - Qt5MultimediaWidgets$${DS}.dll \ - Qt5Quick$${DS}.dll \ - Qt5QuickWidgets$${DS}.dll \ - Qt5Qml$${DS}.dll \ - icuin53.dll \ - icudt53.dll \ - icuuc53.dll - # it is more robust to take the following DLLs from Qt rather than from MinGW - QT_DLLS += libgcc_s_dw2-1.dll \ - libstdc++-6.dll \ - libwinpthread-1.dll - for(dll, QT_DLLS) { - addCopyFileTarget($${dll},$$[QT_INSTALL_BINS],$${GCS_APP_PATH}) - } - - # copy OpenSSL DLLs - OPENSSL_DLLS = \ - ssleay32.dll \ - libeay32.dll - for(dll, OPENSSL_DLLS) { - addCopyFileTarget($${dll},$${OPENSSL_DIR},$${GCS_APP_PATH}) - } - - # copy OpenGL DLL - OPENGL_DLLS = \ - opengl32_32/opengl32.dll - for(dll, OPENGL_DLLS) { - addCopyFileTarget($${dll},$${MESAWIN_DIR},$${GCS_APP_PATH}) - } - - QT_PLUGINS = iconengines/qsvgicon$${DS}.dll \ - imageformats/qgif$${DS}.dll \ - imageformats/qico$${DS}.dll \ - imageformats/qjpeg$${DS}.dll \ - imageformats/qmng$${DS}.dll \ - imageformats/qsvg$${DS}.dll \ - imageformats/qtiff$${DS}.dll \ - platforms/qwindows$${DS}.dll \ - mediaservice/dsengine$${DS}.dll \ - sqldrivers/qsqlite$${DS}.dll + for(lib, QT_LIBS) { + addCopyFileTarget($${lib},$$[QT_INSTALL_LIBS],$${GCS_QT_LIBRARY_PATH}) } - for(plugin, QT_PLUGINS) { - addCopyFileTarget($${plugin},$$[QT_INSTALL_PLUGINS],$${GCS_QT_PLUGINS_PATH}) - } + QT_PLUGINS = \ + iconengines/libqsvgicon.so \ + imageformats/libqgif.so \ + imageformats/libqico.so \ + imageformats/libqjpeg.so \ + imageformats/libqsvg.so \ + imageformats/libqtiff.so \ + platforms/libqxcb.so \ + xcbglintegrations/libqxcb-glx-integration.so \ + sqldrivers/libqsqlite.so - # Copy QtQuick2 complete directories - # Some of these directories have a lot of files - # Easier to copy everything - QT_QUICK2_DIRS = QtQuick/Controls \ - QtQuick/Dialogs \ - QtQuick/Layouts \ - QtQuick/LocalStorage \ - QtQuick/Particles.2 \ - QtQuick/PrivateWidgets \ - QtQuick/Window.2 \ - QtQuick/XmlListModel \ - QtQuick.2 - for(dir, QT_QUICK2_DIRS) { - addCopyDirTarget($${dir},$$[QT_INSTALL_QML],$${GCS_QT_QML_PATH}) + contains(QT_ARCH, x86_64) { + QT_PLUGINS += \ + mediaservice/libgstaudiodecoder.so \ + mediaservice/libgstmediaplayer.so + } else { + QT_PLUGINS += \ + mediaservice/libqtmedia_audioengine.so } } + +win32 { + # set debug suffix if needed + CONFIG(debug, debug|release):DS = "d" + + # copy Qt DLLs + QT_DLLS = \ + Qt5Core$${DS}.dll \ + Qt5Gui$${DS}.dll \ + Qt5Widgets$${DS}.dll \ + Qt5Network$${DS}.dll \ + Qt5OpenGL$${DS}.dll \ + Qt5Sql$${DS}.dll \ + Qt5Svg$${DS}.dll \ + Qt5Test$${DS}.dll \ + Qt5Xml$${DS}.dll \ + Qt5XmlPatterns$${DS}.dll \ + Qt5Script$${DS}.dll \ + Qt5Concurrent$${DS}.dll \ + Qt5PrintSupport$${DS}.dll \ + Qt5SerialPort$${DS}.dll \ + Qt5Multimedia$${DS}.dll \ + Qt5MultimediaWidgets$${DS}.dll \ + Qt5Quick$${DS}.dll \ + Qt5QuickWidgets$${DS}.dll \ + Qt5Qml$${DS}.dll \ + libicuin57.dll \ + libicudt57.dll \ + libicuuc57.dll \ + libstdc++-6.dll \ + libwinpthread-1.dll \ + libpcre-1.dll \ + libpcre16-0.dll \ + zlib1.dll \ + libharfbuzz-0.dll \ + libgraphite2.dll \ + libfreetype-6.dll \ + libbz2-1.dll \ + libpng16-16.dll \ + libjpeg-8.dll \ + libglib-2.0-0.dll \ + libintl-8.dll \ + libiconv-2.dll + + contains(QT_ARCH, i386) { + QT_DLLS += \ + libgcc_s_dw2-1.dll + } else { + QT_DLLS += \ + libgcc_s_seh-1.dll + } + + for(dll, QT_DLLS) { + addCopyFileTarget($${dll},$$[QT_INSTALL_BINS],$${GCS_APP_PATH}) + } + + # copy OpenSSL DLLs + OPENSSL_DLLS = \ + ssleay32.dll \ + libeay32.dll + + for(dll, OPENSSL_DLLS) { + addCopyFileTarget($${dll},$$[QT_INSTALL_BINS],$${GCS_APP_PATH}) + } + + QT_PLUGINS = \ + iconengines/qsvgicon$${DS}.dll \ + imageformats/qgif$${DS}.dll \ + imageformats/qico$${DS}.dll \ + imageformats/qjpeg$${DS}.dll \ + imageformats/qsvg$${DS}.dll \ + imageformats/qtiff$${DS}.dll \ + platforms/qwindows$${DS}.dll \ + mediaservice/dsengine$${DS}.dll \ + sqldrivers/qsqlite$${DS}.dll +} + +for(plugin, QT_PLUGINS) { + addCopyFileTarget($${plugin},$$[QT_INSTALL_PLUGINS],$${GCS_QT_PLUGINS_PATH}) +} + +# Copy QtQuick2 complete directories +# Some of these directories have a lot of files +# Easier to copy everything +QT_QUICK2_DIRS = \ + QtQuick/Controls \ + QtQuick/Dialogs \ + QtQuick/Layouts \ + QtQuick/LocalStorage \ + QtQuick/Particles.2 \ + QtQuick/PrivateWidgets \ + QtQuick/Window.2 \ + QtQuick/XmlListModel \ + QtQuick.2 + +for(dir, QT_QUICK2_DIRS) { + addCopyDirTarget($${dir},$$[QT_INSTALL_QML],$${GCS_QT_QML_PATH}) +} diff --git a/ground/gcs/gcs.pri b/ground/gcs/gcs.pri index 143b34daa..cb25cd54f 100644 --- a/ground/gcs/gcs.pri +++ b/ground/gcs/gcs.pri @@ -103,6 +103,9 @@ equals(TEST, 1) { DEFINES += WITH_TESTS } +# don't build both debug and release +CONFIG -= debug_and_release + #ideally, we would want a qmake.conf patch, but this does the trick... win32:!isEmpty(QMAKE_SH):QMAKE_COPY_DIR = cp -r -f @@ -159,7 +162,6 @@ macx { GCS_DOC_PATH = $$GCS_DATA_PATH/doc copydata = 1 copyqt = 1 - copyosg = 1 } else { GCS_APP_TARGET = $$GCS_SMALL_NAME GCS_PATH = $$GCS_BUILD_TREE @@ -172,20 +174,10 @@ macx { !isEqual(GCS_SOURCE_TREE, $$GCS_BUILD_TREE):copydata = 1 win32 { - SDL_DIR = $$(SDL_DIR) - isEmpty(SDL_DIR):SDL_DIR = $${TOOLS_DIR}/SDL-1.2.15 - - OPENSSL_DIR = $$(OPENSSL_DIR) - isEmpty(OPENSSL_DIR):OPENSSL_DIR = $${TOOLS_DIR}/openssl-1.0.1e-win32 - - MESAWIN_DIR = $$(MESAWIN_DIR) - isEmpty(MESAWIN_DIR):MESAWIN_DIR = $${TOOLS_DIR}/mesawin - GCS_QT_PLUGINS_PATH = $$GCS_APP_PATH GCS_QT_QML_PATH = $$GCS_APP_PATH copyqt = $$copydata - copyosg = $$copydata } else { GCS_QT_BASEPATH = $$GCS_LIBRARY_PATH/qt5 GCS_QT_LIBRARY_PATH = $$GCS_QT_BASEPATH/lib @@ -198,11 +190,9 @@ macx { } else { copyqt = 0 } - copyosg = 1 } } - INCLUDEPATH += \ $$GCS_SOURCE_TREE/src/libs @@ -246,7 +236,25 @@ win32 { QMAKE_CXXFLAGS += -mno-ms-bitfields } -# Stricter warnigs turned on for OS X. +# Explicit setting of C++11 +CONFIG += c++11 + +address_sanitizer { + # enable asan by adding "address_sanitizer" to your root config file + # see https://github.com/google/sanitizers + # see https://blog.qt.io/blog/2013/04/17/using-gccs-4-8-0-address-sanitizer-with-qt/ + # + # to use, simply compile and run, asan will crash with a report if an error is found. + # if you don't see symbols, try this: ./build/librepilot-gcs_debug/bin/librepilot-gcs 2>&1 | ./make/scripts/asan_symbolize.py + # + # Note: asan will apply only to GCS and not to third party libraries (Qt, osg, ...). + + QMAKE_CXXFLAGS += -fsanitize=address -g -fno-omit-frame-pointer + QMAKE_CFLAGS += -fsanitize=address -g -fno-omit-frame-pointer + QMAKE_LFLAGS += -fsanitize=address -g +} + +# Stricter warnings turned on for OS X. macx { CONFIG += warn_on !warn_off { @@ -254,10 +262,11 @@ macx { QMAKE_CFLAGS_WARN_ON += -Werror QMAKE_CXXFLAGS_WARN_ON += -Wno-gnu-static-float-init } + # building with libc++ is needed when linking with osg/gdal + QMAKE_CXXFLAGS += -stdlib=libc++ + QMAKE_LFLAGS += -stdlib=libc++ } - # use ccache when available QMAKE_CC = $$(CCACHE) $$QMAKE_CC QMAKE_CXX = $$(CCACHE) $$QMAKE_CXX - diff --git a/ground/gcs/gcs.pro b/ground/gcs/gcs.pro index e2e29d52d..0cd071d02 100644 --- a/ground/gcs/gcs.pro +++ b/ground/gcs/gcs.pro @@ -1,6 +1,7 @@ # -# Qmake project for the OpenPilot GCS. +# Qmake project for the LibrePilot GCS. # Copyright (c) 2009-2013, The OpenPilot Team, http://www.openpilot.org +# Copyright (c) 2015-2016, The LibrePilot Team, http://www.librepilot.org # cache() @@ -31,6 +32,13 @@ CONFIG += ordered DEFINES += USE_PATHPLANNER -SUBDIRS = src copydata +SUBDIRS = src -copydata.file = copydata.pro +equals(copyqt, 1) { + SUBDIRS += copydata + copydata.file = copydata.pro + win32 { + SUBDIRS += opengl + opengl.file = opengl.pro + } +} diff --git a/ground/gcs/opengl.pro b/ground/gcs/opengl.pro new file mode 100644 index 000000000..b912b33a0 --- /dev/null +++ b/ground/gcs/opengl.pro @@ -0,0 +1,38 @@ +# copy legacy OpenGL DLL + +TEMPLATE = aux + +include(gcs.pri) + +MESAWIN_DIR = $$(MESAWIN_DIR) +isEmpty(MESAWIN_DIR):MESAWIN_DIR = $${TOOLS_DIR}/mesawin + +# opengl32.dll will be copied to ./bin/opengl32/ for the installer to use +# the installer packages the dll and optionally allows to install it to ./bin/ +# this implies that the opengl32.dll will not be used in a dev environment, +# unless it is copied to the ./bin/ ... + +exists($${MESAWIN_DIR}) { + contains(QT_ARCH, i386) { + # take opengl32.dll from mesa (32 bit) + OPENGL_DIR = $${MESAWIN_DIR}/opengl32_32 + } + else { + # take opengl32.dll from mesa (64 bit) + OPENGL_DIR = $${MESAWIN_DIR}/opengl32_64 + } +} +else { + # take opengl32.dll from mingw32/bin/ + # WARNING : doesn't currently work, GCS crashes at startup when using msys2 opengl32.dll + warning("msys2 opengl32.dll breaks GCS, please install mesa with: make mesawin_install") + # skip installing opengl32.dll, the package target will fail when creating the installer + #OPENGL_DIR = $$[QT_INSTALL_BINS] +} + +OPENGL_DLLS = \ + opengl32.dll + +exists($${OPENGL_DIR}):for(dll, OPENGL_DLLS) { + addCopyFileTarget($${dll},$${OPENGL_DIR},$${GCS_APP_PATH}/opengl32) +} diff --git a/ground/gcs/src/app/gcssplashscreen.cpp b/ground/gcs/src/app/gcssplashscreen.cpp index cffac1202..058ed8852 100644 --- a/ground/gcs/src/app/gcssplashscreen.cpp +++ b/ground/gcs/src/app/gcssplashscreen.cpp @@ -45,7 +45,7 @@ GCSSplashScreen::GCSSplashScreen() : m_painter->setFont(font); m_painter->drawText(405, 170, QString(CopyrightSymbol) + - QString(" ") + VersionInfo::year() + + QString(" 2015-") + VersionInfo::year() + QString(tr(" The %1 Project - All Rights Reserved").arg(ORG_BIG_NAME))); m_painter->drawText(405, 182, QString(CopyrightSymbol) + diff --git a/ground/gcs/src/app/main.cpp b/ground/gcs/src/app/main.cpp index f13bcec76..9644bea5c 100644 --- a/ground/gcs/src/app/main.cpp +++ b/ground/gcs/src/app/main.cpp @@ -84,6 +84,7 @@ #include "qtsingleapplication.h" #include "utils/xmlconfig.h" #include "utils/pathutils.h" +#include "utils/filelogger.h" #include "gcssplashscreen.h" #include @@ -108,7 +109,6 @@ #include #include -namespace { typedef QList PluginSpecSet; typedef QMap AppOptions; typedef QMap AppOptionValues; @@ -209,6 +209,11 @@ inline QString msgSendArgumentFailed() "Unable to send command line arguments to the already running instance. It appears to be not responding."); } +inline QString msgLogfileOpenFailed(const QString &fileName) +{ + return QCoreApplication::translate("Application", "Failed to open log file %1").arg(fileName); +} + // Prepare a remote argument: If it is a relative file, add the current directory // since the the central instance might be running in a different directory. inline QString prepareRemoteArgument(const QString &arg) @@ -261,6 +266,16 @@ void systemInit() // TODO revisit this... QApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings, true); +#ifdef Q_OS_WIN +#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) + // see https://doc-snapshots.qt.io/qt5-5.6/highdpi.html + qputenv("QT_AUTO_SCREEN_SCALE_FACTOR", "1"); +#else + // see http://doc.qt.io/qt-5/highdpi.html + qputenv("QT_DEVICE_PIXEL_RATIO", "auto"); +#endif +#endif + // Force "basic" render loop // Only Mac uses "threaded" by default and that mode currently does not work well with OSGViewport qputenv("QSG_RENDER_LOOP", "basic"); @@ -271,44 +286,22 @@ void systemInit() QSurfaceFormat::setDefaultFormat(format); } -static QTextStream *logStream; +static FileLogger *logger; void mainMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) { - Q_UNUSED(context); - - QTextStream &out = *logStream; - - // logStream << QTime::currentTime().toString("hh:mm:ss.zzz "); - - switch (type) { - case QtDebugMsg: - out << "DBG: "; - break; - case QtWarningMsg: - out << "WRN: "; - break; - case QtCriticalMsg: - out << "CRT: "; - break; - case QtFatalMsg: - out << "FTL: "; - break; - } - - out << msg << '\n'; - out.flush(); + logger->log(type, context, msg); } +Q_DECLARE_METATYPE(QtMsgType) + void logInit(QString fileName) { - QFile *file = new QFile(fileName); - - if (file->open(QIODevice::WriteOnly | QIODevice::Text)) { - logStream = new QTextStream(file); - qInstallMessageHandler(mainMessageOutput); - } else { - // TODO error popup + qRegisterMetaType(); + qInstallMessageHandler(mainMessageOutput); + logger = new FileLogger(); + if (!logger->start(fileName)) { + displayError(msgLogfileOpenFailed(fileName)); } } @@ -421,19 +414,21 @@ void loadTranslators(QString language, QTranslator &translator, QTranslator &qtT const QString &creatorTrPath = Utils::GetDataPath() + QLatin1String("translations"); if (translator.load(QLatin1String("gcs_") + language, creatorTrPath)) { + // Install gcs_xx.qm translation file + QCoreApplication::installTranslator(&translator); + const QString &qtTrPath = QLibraryInfo::location(QLibraryInfo::TranslationsPath); const QString &qtTrFile = QLatin1String("qt_") + language; // Binary installer puts Qt tr files into creatorTrPath if (qtTranslator.load(qtTrFile, qtTrPath) || qtTranslator.load(qtTrFile, creatorTrPath)) { - QCoreApplication::installTranslator(&translator); + // Install main qt_xx.qm translation file QCoreApplication::installTranslator(&qtTranslator); - } else { - // unload() - translator.load(QString()); } + } else { + // unload(), no gcs translation found + translator.load(QString()); } } -} // namespace anonymous int main(int argc, char * *argv) { @@ -471,6 +466,8 @@ int main(int argc, char * *argv) if (appOptionValues.contains(LOG_FILE_OPTION)) { QString logFileName = appOptionValues.value(LOG_FILE_OPTION); logInit(logFileName); + // relog command line arguments for the benefit of the file logger... + qDebug() << "Command line" << app.arguments(); } // load user settings @@ -621,5 +618,9 @@ int main(int argc, char * *argv) qDebug() << "main - GCS ran for" << timer.elapsed() << "ms"; + if (logger) { + delete logger; + } + return ret; } diff --git a/ground/gcs/src/app/splash.png b/ground/gcs/src/app/splash.png index 304b6ef3a..01b165757 100644 Binary files a/ground/gcs/src/app/splash.png and b/ground/gcs/src/app/splash.png differ diff --git a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/main.cpp b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/main.cpp index b52a51ba2..793c6787d 100644 --- a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/main.cpp +++ b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/main.cpp @@ -15,8 +15,8 @@ int main(int argc, char *argv[]) bool use_serial = false; bool verify; bool debug = false; - bool umodereset = false; - OP_DFU::Actions action; + // bool umodereset = false; + OP_DFU::Actions action = OP_DFU::actionNone; QString file; QString serialport; QString description; @@ -27,7 +27,7 @@ int main(int argc, char *argv[]) debug = true; } if (args.contains("-ur")) { - umodereset = true; + // umodereset = true; } standardOutput << "OpenPilot serial firmware uploader tool." << endl; if (args.indexOf(PROGRAMFW) + 1 < args.length()) { @@ -57,17 +57,17 @@ int main(int argc, char *argv[]) } action = OP_DFU::actionProgram; } else if (args.contains(COMPARECRC) || args.contains(COMPAREALL)) { - int index; + // int index; if (args.contains(COMPARECRC)) { - index = args.indexOf(COMPARECRC); + // index = args.indexOf(COMPARECRC); action = OP_DFU::actionCompareCrc; } else { - index = args.indexOf(COMPAREALL); + // index = args.indexOf(COMPAREALL); action = OP_DFU::actionCompareAll; } } else if (args.contains(DOWNLOAD)) { - int index; - index = args.indexOf(DOWNLOAD); + // int index; + // index = args.indexOf(DOWNLOAD); action = OP_DFU::actionDownload; } else if (args.contains(STATUSREQUEST)) { action = OP_DFU::actionStatusReq; diff --git a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/op_dfu.cpp b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/op_dfu.cpp index c0ef3b04d..f2b6071da 100644 --- a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/op_dfu.cpp +++ b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/op_dfu.cpp @@ -1119,11 +1119,12 @@ int DFUObject::receiveData(void *data, int size) } } -#define BOARD_ID_MB 1 -#define BOARD_ID_INS 2 -#define BOARD_ID_PIP 3 -#define BOARD_ID_CC 4 -#define BOARD_ID_REVO 9 +#define BOARD_ID_MB 1 +#define BOARD_ID_INS 2 +#define BOARD_ID_PIP 3 +#define BOARD_ID_CC 4 +#define BOARD_ID_REVO 9 +#define BOARD_ID_SPARKY2 0x92 /** Gets the type of board connected @@ -1152,6 +1153,9 @@ OP_DFU::eBoardType DFUObject::GetBoardType(int boardNum) case BOARD_ID_REVO: // Revo board brdType = eBoardRevo; break; + case BOARD_ID_SPARKY2: // Sparky2 board + brdType = eBoardSparky2; + break; } return brdType; } diff --git a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/op_dfu.h b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/op_dfu.h index 4da818593..ed84865ec 100644 --- a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/op_dfu.h +++ b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/op_dfu.h @@ -75,6 +75,7 @@ enum Status { }; enum Actions { + actionNone, actionProgram, actionProgramAndVerify, actionDownload, @@ -109,6 +110,7 @@ enum eBoardType { eBoardPip = 3, eBoardCC = 4, eBoardRevo = 9, + eBoardSparky2 = 0x92, }; struct device { diff --git a/ground/gcs/src/libs/eigen/.hg_archival.txt b/ground/gcs/src/libs/eigen/.hg_archival.txt index 9fceca658..c4115d7f6 100644 --- a/ground/gcs/src/libs/eigen/.hg_archival.txt +++ b/ground/gcs/src/libs/eigen/.hg_archival.txt @@ -1,4 +1,4 @@ repo: 8a21fd850624c931e448cbcfb38168cb2717c790 -node: ffa86ffb557094721ca71dcea6aed2651b9fd610 +node: 07105f7124f9aef00a68c85e0fc606e65d3d6c15 branch: 3.2 -tag: 3.2.0 +tag: 3.2.8 diff --git a/ground/gcs/src/libs/eigen/.hgtags b/ground/gcs/src/libs/eigen/.hgtags index 1b9b1142e..8f0097f20 100644 --- a/ground/gcs/src/libs/eigen/.hgtags +++ b/ground/gcs/src/libs/eigen/.hgtags @@ -23,3 +23,11 @@ bf4cb8c934fa3a79f45f1e629610f0225e93e493 3.1.0-rc2 da195914abcc1d739027cbee7c52077aab30b336 3.2-beta1 4b687cad1d23066f66863f4f87298447298443df 3.2-rc1 1eeda7b1258bcd306018c0738e2b6a8543661141 3.2-rc2 +ffa86ffb557094721ca71dcea6aed2651b9fd610 3.2.0 +6b38706d90a9fe182e66ab88477b3dbde34b9f66 3.2.1 +1306d75b4a21891e59ff9bd96678882cf831e39f 3.2.2 +36fd1ba04c120cfdd90f3e4cede47f43b21d19ad 3.2.3 +10219c95fe653d4962aa9db4946f6fbea96dd740 3.2.4 +bdd17ee3b1b3a166cd5ec36dcad4fc1f3faf774a 3.2.5 +c58038c56923e0fd86de3ded18e03df442e66dfb 3.2.6 +b30b87236a1b1552af32ac34075ee5696a9b5a33 3.2.7 diff --git a/ground/gcs/src/libs/eigen/CMakeLists.txt b/ground/gcs/src/libs/eigen/CMakeLists.txt index ad0269ea6..77e9f2d35 100644 --- a/ground/gcs/src/libs/eigen/CMakeLists.txt +++ b/ground/gcs/src/libs/eigen/CMakeLists.txt @@ -1,6 +1,5 @@ project(Eigen) - -cmake_minimum_required(VERSION 2.8.2) +cmake_minimum_required(VERSION 2.8.5) # guard against in-source builds @@ -55,6 +54,7 @@ endif(EIGEN_HG_CHANGESET) include(CheckCXXCompilerFlag) +include(GNUInstallDirs) set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) @@ -204,7 +204,7 @@ if(NOT MSVC) option(EIGEN_TEST_NEON "Enable/Disable Neon in tests/examples" OFF) if(EIGEN_TEST_NEON) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon -mcpu=cortex-a"8) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon -mcpu=cortex-a8") message(STATUS "Enabling NEON in tests/examples") endif() @@ -288,25 +288,26 @@ option(EIGEN_TEST_C++0x "Enables all C++0x features." OFF) include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) -# the user modifiable install path for header files -set(EIGEN_INCLUDE_INSTALL_DIR ${EIGEN_INCLUDE_INSTALL_DIR} CACHE PATH "The directory where we install the header files (optional)") - -# set the internal install path for header files which depends on wether the user modifiable -# EIGEN_INCLUDE_INSTALL_DIR has been set by the user or not. -if(EIGEN_INCLUDE_INSTALL_DIR) - set(INCLUDE_INSTALL_DIR - ${EIGEN_INCLUDE_INSTALL_DIR} - CACHE INTERNAL - "The directory where we install the header files (internal)" - ) +# Backward compatibility support for EIGEN_INCLUDE_INSTALL_DIR +if(EIGEN_INCLUDE_INSTALL_DIR AND NOT INCLUDE_INSTALL_DIR) + set(INCLUDE_INSTALL_DIR ${EIGEN_INCLUDE_INSTALL_DIR} + CACHE PATH "The directory relative to CMAKE_PREFIX_PATH where Eigen header files are installed") else() set(INCLUDE_INSTALL_DIR - "${CMAKE_INSTALL_PREFIX}/include/eigen3" - CACHE INTERNAL - "The directory where we install the header files (internal)" - ) + "${CMAKE_INSTALL_INCLUDEDIR}/eigen3" + CACHE PATH "The directory relative to CMAKE_PREFIX_PATH where Eigen header files are installed" + ) endif() +set(CMAKEPACKAGE_INSTALL_DIR + "${CMAKE_INSTALL_LIBDIR}/cmake/eigen3" + CACHE PATH "The directory relative to CMAKE_PREFIX_PATH where Eigen3Config.cmake is installed" + ) +set(PKGCONFIG_INSTALL_DIR + "${CMAKE_INSTALL_DATADIR}/pkgconfig" + CACHE PATH "The directory relative to CMAKE_PREFIX_PATH where eigen3.pc is installed" + ) + # similar to set_target_properties but append the property instead of overwriting it macro(ei_add_target_property target prop value) @@ -324,21 +325,9 @@ install(FILES ) if(EIGEN_BUILD_PKGCONFIG) - SET(path_separator ":") - STRING(REPLACE ${path_separator} ";" pkg_config_libdir_search "$ENV{PKG_CONFIG_LIBDIR}") - message(STATUS "searching for 'pkgconfig' directory in PKG_CONFIG_LIBDIR ( $ENV{PKG_CONFIG_LIBDIR} ), ${CMAKE_INSTALL_PREFIX}/share, and ${CMAKE_INSTALL_PREFIX}/lib") - FIND_PATH(pkg_config_libdir pkgconfig ${pkg_config_libdir_search} ${CMAKE_INSTALL_PREFIX}/share ${CMAKE_INSTALL_PREFIX}/lib ${pkg_config_libdir_search}) - if(pkg_config_libdir) - SET(pkg_config_install_dir ${pkg_config_libdir}) - message(STATUS "found ${pkg_config_libdir}/pkgconfig" ) - else(pkg_config_libdir) - SET(pkg_config_install_dir ${CMAKE_INSTALL_PREFIX}/share) - message(STATUS "pkgconfig not found; installing in ${pkg_config_install_dir}" ) - endif(pkg_config_libdir) - - configure_file(eigen3.pc.in eigen3.pc) + configure_file(eigen3.pc.in eigen3.pc @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/eigen3.pc - DESTINATION ${pkg_config_install_dir}/pkgconfig + DESTINATION ${PKGCONFIG_INSTALL_DIR} ) endif(EIGEN_BUILD_PKGCONFIG) @@ -401,12 +390,15 @@ if(cmake_generator_tolower MATCHES "makefile") message(STATUS "--------------+--------------------------------------------------------------") message(STATUS "Command | Description") message(STATUS "--------------+--------------------------------------------------------------") - message(STATUS "make install | Install to ${CMAKE_INSTALL_PREFIX}. To change that:") - message(STATUS " | cmake . -DCMAKE_INSTALL_PREFIX=yourpath") - message(STATUS " | Eigen headers will then be installed to:") - message(STATUS " | ${INCLUDE_INSTALL_DIR}") - message(STATUS " | To install Eigen headers to a separate location, do:") - message(STATUS " | cmake . -DEIGEN_INCLUDE_INSTALL_DIR=yourpath") + message(STATUS "make install | Install Eigen. Headers will be installed to:") + message(STATUS " | /") + message(STATUS " | Using the following values:") + message(STATUS " | CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") + message(STATUS " | INCLUDE_INSTALL_DIR: ${INCLUDE_INSTALL_DIR}") + message(STATUS " | Change the install location of Eigen headers using:") + message(STATUS " | cmake . -DCMAKE_INSTALL_PREFIX=yourprefix") + message(STATUS " | Or:") + message(STATUS " | cmake . -DINCLUDE_INSTALL_DIR=yourdir") message(STATUS "make doc | Generate the API documentation, requires Doxygen & LaTeX") message(STATUS "make check | Build and run the unit-tests. Read this page:") message(STATUS " | http://eigen.tuxfamily.org/index.php?title=Tests") diff --git a/ground/gcs/src/libs/eigen/CTestConfig.cmake b/ground/gcs/src/libs/eigen/CTestConfig.cmake index 4c0027824..0557c491a 100644 --- a/ground/gcs/src/libs/eigen/CTestConfig.cmake +++ b/ground/gcs/src/libs/eigen/CTestConfig.cmake @@ -4,14 +4,10 @@ ## # The following are required to uses Dart and the Cdash dashboard ## ENABLE_TESTING() ## INCLUDE(CTest) -set(CTEST_PROJECT_NAME "Eigen") +set(CTEST_PROJECT_NAME "Eigen3.2") set(CTEST_NIGHTLY_START_TIME "00:00:00 UTC") set(CTEST_DROP_METHOD "http") set(CTEST_DROP_SITE "manao.inria.fr") -set(CTEST_DROP_LOCATION "/CDash/submit.php?project=Eigen") +set(CTEST_DROP_LOCATION "/CDash/submit.php?project=Eigen3.2") set(CTEST_DROP_SITE_CDASH TRUE) -set(CTEST_PROJECT_SUBPROJECTS -Official -Unsupported -) diff --git a/ground/gcs/src/libs/eigen/Eigen/CholmodSupport b/ground/gcs/src/libs/eigen/Eigen/CholmodSupport index 745b884e7..88c29a646 100644 --- a/ground/gcs/src/libs/eigen/Eigen/CholmodSupport +++ b/ground/gcs/src/libs/eigen/Eigen/CholmodSupport @@ -12,7 +12,7 @@ extern "C" { /** \ingroup Support_modules * \defgroup CholmodSupport_Module CholmodSupport module * - * This module provides an interface to the Cholmod library which is part of the suitesparse package. + * This module provides an interface to the Cholmod library which is part of the suitesparse package. * It provides the two following main factorization classes: * - class CholmodSupernodalLLT: a supernodal LLT Cholesky factorization. * - class CholmodDecomposiiton: a general L(D)LT Cholesky factorization with automatic or explicit runtime selection of the underlying factorization method (supernodal or simplicial). diff --git a/ground/gcs/src/libs/eigen/Eigen/Core b/ground/gcs/src/libs/eigen/Eigen/Core index 9131cc3fc..509c529e1 100644 --- a/ground/gcs/src/libs/eigen/Eigen/Core +++ b/ground/gcs/src/libs/eigen/Eigen/Core @@ -95,7 +95,7 @@ extern "C" { // In theory we should only include immintrin.h and not the other *mmintrin.h header files directly. // Doing so triggers some issues with ICC. However old gcc versions seems to not have this file, thus: - #ifdef __INTEL_COMPILER + #if defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1110 #include #else #include @@ -123,7 +123,7 @@ #undef bool #undef vector #undef pixel - #elif defined __ARM_NEON__ + #elif defined __ARM_NEON #define EIGEN_VECTORIZE #define EIGEN_VECTORIZE_NEON #include @@ -165,7 +165,7 @@ #endif // required for __cpuid, needs to be included after cmath -#if defined(_MSC_VER) && (defined(_M_IX86)||defined(_M_X64)) +#if defined(_MSC_VER) && (defined(_M_IX86)||defined(_M_X64)) && (!defined(_WIN32_WCE)) #include #endif diff --git a/ground/gcs/src/libs/eigen/Eigen/Eigen2Support b/ground/gcs/src/libs/eigen/Eigen/Eigen2Support index 36156d29a..6aa009d20 100644 --- a/ground/gcs/src/libs/eigen/Eigen/Eigen2Support +++ b/ground/gcs/src/libs/eigen/Eigen/Eigen2Support @@ -14,12 +14,25 @@ #error Eigen2 support must be enabled by defining EIGEN2_SUPPORT before including any Eigen header #endif +#ifndef EIGEN_NO_EIGEN2_DEPRECATED_WARNING + +#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__) +#warning "Eigen2 support is deprecated in Eigen 3.2.x and it will be removed in Eigen 3.3. (Define EIGEN_NO_EIGEN2_DEPRECATED_WARNING to disable this warning)" +#else +#pragma message ("Eigen2 support is deprecated in Eigen 3.2.x and it will be removed in Eigen 3.3. (Define EIGEN_NO_EIGEN2_DEPRECATED_WARNING to disable this warning)") +#endif + +#endif // EIGEN_NO_EIGEN2_DEPRECATED_WARNING + #include "src/Core/util/DisableStupidWarnings.h" /** \ingroup Support_modules * \defgroup Eigen2Support_Module Eigen2 support module - * This module provides a couple of deprecated functions improving the compatibility with Eigen2. * + * \warning Eigen2 support is deprecated in Eigen 3.2.x and it will be removed in Eigen 3.3. + * + * This module provides a couple of deprecated functions improving the compatibility with Eigen2. + * * To use it, define EIGEN2_SUPPORT before including any Eigen header * \code * #define EIGEN2_SUPPORT diff --git a/ground/gcs/src/libs/eigen/Eigen/SPQRSupport b/ground/gcs/src/libs/eigen/Eigen/SPQRSupport index 77016442e..7f1eb4770 100644 --- a/ground/gcs/src/libs/eigen/Eigen/SPQRSupport +++ b/ground/gcs/src/libs/eigen/Eigen/SPQRSupport @@ -10,7 +10,7 @@ /** \ingroup Support_modules * \defgroup SPQRSupport_Module SuiteSparseQR module * - * This module provides an interface to the SPQR library, which is part of the suitesparse package. + * This module provides an interface to the SPQR library, which is part of the suitesparse package. * * \code * #include diff --git a/ground/gcs/src/libs/eigen/Eigen/SparseCore b/ground/gcs/src/libs/eigen/Eigen/SparseCore index 9b5be5e15..24bcf0156 100644 --- a/ground/gcs/src/libs/eigen/Eigen/SparseCore +++ b/ground/gcs/src/libs/eigen/Eigen/SparseCore @@ -14,7 +14,7 @@ /** * \defgroup SparseCore_Module SparseCore module * - * This module provides a sparse matrix representation, and basic associatd matrix manipulations + * This module provides a sparse matrix representation, and basic associated matrix manipulations * and operations. * * See the \ref TutorialSparse "Sparse tutorial" diff --git a/ground/gcs/src/libs/eigen/Eigen/UmfPackSupport b/ground/gcs/src/libs/eigen/Eigen/UmfPackSupport index 984f64a84..7b1b66064 100644 --- a/ground/gcs/src/libs/eigen/Eigen/UmfPackSupport +++ b/ground/gcs/src/libs/eigen/Eigen/UmfPackSupport @@ -12,7 +12,7 @@ extern "C" { /** \ingroup Support_modules * \defgroup UmfPackSupport_Module UmfPackSupport module * - * This module provides an interface to the UmfPack library which is part of the suitesparse package. + * This module provides an interface to the UmfPack library which is part of the suitesparse package. * It provides the following factorization class: * - class UmfPackLU: a multifrontal sequential LU factorization. * diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Cholesky/LDLT.h b/ground/gcs/src/libs/eigen/Eigen/src/Cholesky/LDLT.h index d19cb3968..abd30bd91 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Cholesky/LDLT.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Cholesky/LDLT.h @@ -16,7 +16,10 @@ namespace Eigen { namespace internal { -template struct LDLT_Traits; + template struct LDLT_Traits; + + // PositiveSemiDef means positive semi-definite and non-zero; same for NegativeSemiDef + enum SignMatrix { PositiveSemiDef, NegativeSemiDef, ZeroSign, Indefinite }; } /** \ingroup Cholesky_Module @@ -69,7 +72,12 @@ template class LDLT * The default constructor is useful in cases in which the user intends to * perform decompositions via LDLT::compute(const MatrixType&). */ - LDLT() : m_matrix(), m_transpositions(), m_isInitialized(false) {} + LDLT() + : m_matrix(), + m_transpositions(), + m_sign(internal::ZeroSign), + m_isInitialized(false) + {} /** \brief Default Constructor with memory preallocation * @@ -81,6 +89,7 @@ template class LDLT : m_matrix(size, size), m_transpositions(size), m_temporary(size), + m_sign(internal::ZeroSign), m_isInitialized(false) {} @@ -93,6 +102,7 @@ template class LDLT : m_matrix(matrix.rows(), matrix.cols()), m_transpositions(matrix.rows()), m_temporary(matrix.rows()), + m_sign(internal::ZeroSign), m_isInitialized(false) { compute(matrix); @@ -139,7 +149,7 @@ template class LDLT inline bool isPositive() const { eigen_assert(m_isInitialized && "LDLT is not initialized."); - return m_sign == 1; + return m_sign == internal::PositiveSemiDef || m_sign == internal::ZeroSign; } #ifdef EIGEN2_SUPPORT @@ -153,7 +163,7 @@ template class LDLT inline bool isNegative(void) const { eigen_assert(m_isInitialized && "LDLT is not initialized."); - return m_sign == -1; + return m_sign == internal::NegativeSemiDef || m_sign == internal::ZeroSign; } /** \returns a solution x of \f$ A x = b \f$ using the current decomposition of A. @@ -225,6 +235,11 @@ template class LDLT } protected: + + static void check_template_parameters() + { + EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); + } /** \internal * Used to compute and store the Cholesky decomposition A = L D L^* = U^* D U. @@ -235,7 +250,7 @@ template class LDLT MatrixType m_matrix; TranspositionType m_transpositions; TmpMatrixType m_temporary; - int m_sign; + internal::SignMatrix m_sign; bool m_isInitialized; }; @@ -246,7 +261,7 @@ template struct ldlt_inplace; template<> struct ldlt_inplace { template - static bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, int* sign=0) + static bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, SignMatrix& sign) { using std::abs; typedef typename MatrixType::Scalar Scalar; @@ -258,36 +273,19 @@ template<> struct ldlt_inplace if (size <= 1) { transpositions.setIdentity(); - if(sign) - *sign = numext::real(mat.coeff(0,0))>0 ? 1:-1; + if (numext::real(mat.coeff(0,0)) > 0) sign = PositiveSemiDef; + else if (numext::real(mat.coeff(0,0)) < 0) sign = NegativeSemiDef; + else sign = ZeroSign; return true; } - RealScalar cutoff(0), biggest_in_corner; - for (Index k = 0; k < size; ++k) { // Find largest diagonal element Index index_of_biggest_in_corner; - biggest_in_corner = mat.diagonal().tail(size-k).cwiseAbs().maxCoeff(&index_of_biggest_in_corner); + mat.diagonal().tail(size-k).cwiseAbs().maxCoeff(&index_of_biggest_in_corner); index_of_biggest_in_corner += k; - if(k == 0) - { - // The biggest overall is the point of reference to which further diagonals - // are compared; if any diagonal is negligible compared - // to the largest overall, the algorithm bails. - cutoff = abs(NumTraits::epsilon() * biggest_in_corner); - } - - // Finish early if the matrix is not full rank. - if(biggest_in_corner < cutoff) - { - for(Index i = k; i < size; i++) transpositions.coeffRef(i) = i; - if(sign) *sign = 0; - break; - } - transpositions.coeffRef(k) = index_of_biggest_in_corner; if(k != index_of_biggest_in_corner) { @@ -318,22 +316,27 @@ template<> struct ldlt_inplace if(k>0) { - temp.head(k) = mat.diagonal().head(k).asDiagonal() * A10.adjoint(); + temp.head(k) = mat.diagonal().real().head(k).asDiagonal() * A10.adjoint(); mat.coeffRef(k,k) -= (A10 * temp.head(k)).value(); if(rs>0) A21.noalias() -= A20 * temp.head(k); } - if((rs>0) && (abs(mat.coeffRef(k,k)) > cutoff)) - A21 /= mat.coeffRef(k,k); - if(sign) - { - // LDLT is not guaranteed to work for indefinite matrices, but let's try to get the sign right - int newSign = numext::real(mat.diagonal().coeff(index_of_biggest_in_corner)) > 0; - if(k == 0) - *sign = newSign; - else if(*sign != newSign) - *sign = 0; + // In some previous versions of Eigen (e.g., 3.2.1), the scaling was omitted if the pivot + // was smaller than the cutoff value. However, soince LDLT is not rank-revealing + // we should only make sure we do not introduce INF or NaN values. + // LAPACK also uses 0 as the cutoff value. + RealScalar realAkk = numext::real(mat.coeffRef(k,k)); + if((rs>0) && (abs(realAkk) > RealScalar(0))) + A21 /= realAkk; + + if (sign == PositiveSemiDef) { + if (realAkk < 0) sign = Indefinite; + } else if (sign == NegativeSemiDef) { + if (realAkk > 0) sign = Indefinite; + } else if (sign == ZeroSign) { + if (realAkk > 0) sign = PositiveSemiDef; + else if (realAkk < 0) sign = NegativeSemiDef; } } @@ -399,7 +402,7 @@ template<> struct ldlt_inplace template<> struct ldlt_inplace { template - static EIGEN_STRONG_INLINE bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, int* sign=0) + static EIGEN_STRONG_INLINE bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, SignMatrix& sign) { Transpose matt(mat); return ldlt_inplace::unblocked(matt, transpositions, temp, sign); @@ -436,6 +439,8 @@ template struct LDLT_Traits template LDLT& LDLT::compute(const MatrixType& a) { + check_template_parameters(); + eigen_assert(a.rows()==a.cols()); const Index size = a.rows(); @@ -444,8 +449,9 @@ LDLT& LDLT::compute(const MatrixType& a) m_transpositions.resize(size); m_isInitialized = false; m_temporary.resize(size); + m_sign = internal::ZeroSign; - internal::ldlt_inplace::unblocked(m_matrix, m_transpositions, m_temporary, &m_sign); + internal::ldlt_inplace::unblocked(m_matrix, m_transpositions, m_temporary, m_sign); m_isInitialized = true; return *this; @@ -458,7 +464,7 @@ LDLT& LDLT::compute(const MatrixType& a) */ template template -LDLT& LDLT::rankUpdate(const MatrixBase& w, const typename NumTraits::Real& sigma) +LDLT& LDLT::rankUpdate(const MatrixBase& w, const typename LDLT::RealScalar& sigma) { const Index size = w.rows(); if (m_isInitialized) @@ -473,7 +479,7 @@ LDLT& LDLT::rankUpdate(const MatrixBase=0 ? 1 : -1; + m_sign = sigma>=0 ? internal::PositiveSemiDef : internal::NegativeSemiDef; m_isInitialized = true; } @@ -504,16 +510,21 @@ struct solve_retval, Rhs> using std::abs; using std::max; typedef typename LDLTType::MatrixType MatrixType; - typedef typename LDLTType::Scalar Scalar; typedef typename LDLTType::RealScalar RealScalar; - const Diagonal vectorD = dec().vectorD(); - RealScalar tolerance = (max)(vectorD.array().abs().maxCoeff() * NumTraits::epsilon(), - RealScalar(1) / NumTraits::highest()); // motivated by LAPACK's xGELSS + const typename Diagonal::RealReturnType vectorD(dec().vectorD()); + // In some previous versions, tolerance was set to the max of 1/highest and the maximal diagonal entry * epsilon + // as motivated by LAPACK's xGELSS: + // RealScalar tolerance = (max)(vectorD.array().abs().maxCoeff() *NumTraits::epsilon(),RealScalar(1) / NumTraits::highest()); + // However, LDLT is not rank revealing, and so adjusting the tolerance wrt to the highest + // diagonal element is not well justified and to numerical issues in some cases. + // Moreover, Lapack's xSYTRS routines use 0 for the tolerance. + RealScalar tolerance = RealScalar(1) / NumTraits::highest(); + for (Index i = 0; i < vectorD.size(); ++i) { if(abs(vectorD(i)) > tolerance) - dst.row(i) /= vectorD(i); + dst.row(i) /= vectorD(i); else - dst.row(i).setZero(); + dst.row(i).setZero(); } // dst = L^-T (D^-1 L^-1 P b) @@ -566,7 +577,7 @@ MatrixType LDLT::reconstructedMatrix() const // L^* P res = matrixU() * res; // D(L^*P) - res = vectorD().asDiagonal() * res; + res = vectorD().real().asDiagonal() * res; // L(DL^*P) res = matrixL() * res; // P^T (LDL^*P) diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Cholesky/LLT.h b/ground/gcs/src/libs/eigen/Eigen/src/Cholesky/LLT.h index 2e6189f7d..7c11a2dc2 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Cholesky/LLT.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Cholesky/LLT.h @@ -174,6 +174,12 @@ template class LLT LLT rankUpdate(const VectorType& vec, const RealScalar& sigma = 1); protected: + + static void check_template_parameters() + { + EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); + } + /** \internal * Used to compute and store L * The strict upper part is not used and even not initialized. @@ -283,7 +289,7 @@ template struct llt_inplace return k; mat.coeffRef(k,k) = x = sqrt(x); if (k>0 && rs>0) A21.noalias() -= A20 * A10.adjoint(); - if (rs>0) A21 *= RealScalar(1)/x; + if (rs>0) A21 /= x; } return -1; } @@ -384,6 +390,8 @@ template struct LLT_Traits template LLT& LLT::compute(const MatrixType& a) { + check_template_parameters(); + eigen_assert(a.rows()==a.cols()); const Index size = a.rows(); m_matrix.resize(size, size); diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Cholesky/LLT_MKL.h b/ground/gcs/src/libs/eigen/Eigen/src/Cholesky/LLT_MKL.h index 64daa445c..66675d747 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Cholesky/LLT_MKL.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Cholesky/LLT_MKL.h @@ -60,7 +60,7 @@ template<> struct mkl_llt \ lda = m.outerStride(); \ \ info = LAPACKE_##MKLPREFIX##potrf( matrix_order, uplo, size, (MKLTYPE*)a, lda ); \ - info = (info==0) ? Success : NumericalIssue; \ + info = (info==0) ? -1 : info>0 ? info-1 : size; \ return info; \ } \ }; \ diff --git a/ground/gcs/src/libs/eigen/Eigen/src/CholmodSupport/CholmodSupport.h b/ground/gcs/src/libs/eigen/Eigen/src/CholmodSupport/CholmodSupport.h index 783324b0b..99dbe171c 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/CholmodSupport/CholmodSupport.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/CholmodSupport/CholmodSupport.h @@ -58,10 +58,12 @@ cholmod_sparse viewAsCholmod(SparseMatrix<_Scalar,_Options,_Index>& mat) res.p = mat.outerIndexPtr(); res.i = mat.innerIndexPtr(); res.x = mat.valuePtr(); + res.z = 0; res.sorted = 1; if(mat.isCompressed()) { res.packed = 1; + res.nz = 0; } else { @@ -76,7 +78,7 @@ cholmod_sparse viewAsCholmod(SparseMatrix<_Scalar,_Options,_Index>& mat) { res.itype = CHOLMOD_INT; } - else if (internal::is_same<_Index,UF_long>::value) + else if (internal::is_same<_Index,SuiteSparse_long>::value) { res.itype = CHOLMOD_LONG; } @@ -170,6 +172,7 @@ class CholmodBase : internal::noncopyable CholmodBase() : m_cholmodFactor(0), m_info(Success), m_isInitialized(false) { + m_shiftOffset[0] = m_shiftOffset[1] = RealScalar(0.0); cholmod_start(&m_cholmod); } @@ -241,7 +244,7 @@ class CholmodBase : internal::noncopyable return internal::sparse_solve_retval(*this, b.derived()); } - /** Performs a symbolic decomposition on the sparcity of \a matrix. + /** Performs a symbolic decomposition on the sparsity pattern of \a matrix. * * This function is particularly useful when solving for several problems having the same structure. * @@ -265,7 +268,7 @@ class CholmodBase : internal::noncopyable /** Performs a numeric decomposition of \a matrix * - * The given matrix must has the same sparcity than the matrix on which the symbolic decomposition has been performed. + * The given matrix must have the same sparsity pattern as the matrix on which the symbolic decomposition has been performed. * * \sa analyzePattern() */ @@ -302,7 +305,7 @@ class CholmodBase : internal::noncopyable { this->m_info = NumericalIssue; } - // TODO optimize this copy by swapping when possible (be carreful with alignment, etc.) + // TODO optimize this copy by swapping when possible (be careful with alignment, etc.) dest = Matrix::Map(reinterpret_cast(x_cd->x),b.rows(),b.cols()); cholmod_free_dense(&x_cd, &m_cholmod); } @@ -323,7 +326,7 @@ class CholmodBase : internal::noncopyable { this->m_info = NumericalIssue; } - // TODO optimize this copy by swapping when possible (be carreful with alignment, etc.) + // TODO optimize this copy by swapping when possible (be careful with alignment, etc.) dest = viewAsEigen(*x_cs); cholmod_free_sparse(&x_cs, &m_cholmod); } @@ -365,8 +368,8 @@ class CholmodBase : internal::noncopyable * * This class allows to solve for A.X = B sparse linear problems via a simplicial LL^T Cholesky factorization * using the Cholmod library. - * This simplicial variant is equivalent to Eigen's built-in SimplicialLLT class. Thefore, it has little practical interest. - * The sparse matrix A must be selfajoint and positive definite. The vectors or matrices + * This simplicial variant is equivalent to Eigen's built-in SimplicialLLT class. Therefore, it has little practical interest. + * The sparse matrix A must be selfadjoint and positive definite. The vectors or matrices * X and B can be either dense or sparse. * * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> @@ -392,7 +395,7 @@ class CholmodSimplicialLLT : public CholmodBase<_MatrixType, _UpLo, CholmodSimpl CholmodSimplicialLLT(const MatrixType& matrix) : Base() { init(); - compute(matrix); + Base::compute(matrix); } ~CholmodSimplicialLLT() {} @@ -412,8 +415,8 @@ class CholmodSimplicialLLT : public CholmodBase<_MatrixType, _UpLo, CholmodSimpl * * This class allows to solve for A.X = B sparse linear problems via a simplicial LDL^T Cholesky factorization * using the Cholmod library. - * This simplicial variant is equivalent to Eigen's built-in SimplicialLDLT class. Thefore, it has little practical interest. - * The sparse matrix A must be selfajoint and positive definite. The vectors or matrices + * This simplicial variant is equivalent to Eigen's built-in SimplicialLDLT class. Therefore, it has little practical interest. + * The sparse matrix A must be selfadjoint and positive definite. The vectors or matrices * X and B can be either dense or sparse. * * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> @@ -439,7 +442,7 @@ class CholmodSimplicialLDLT : public CholmodBase<_MatrixType, _UpLo, CholmodSimp CholmodSimplicialLDLT(const MatrixType& matrix) : Base() { init(); - compute(matrix); + Base::compute(matrix); } ~CholmodSimplicialLDLT() {} @@ -458,7 +461,7 @@ class CholmodSimplicialLDLT : public CholmodBase<_MatrixType, _UpLo, CholmodSimp * This class allows to solve for A.X = B sparse linear problems via a supernodal LL^T Cholesky factorization * using the Cholmod library. * This supernodal variant performs best on dense enough problems, e.g., 3D FEM, or very high order 2D FEM. - * The sparse matrix A must be selfajoint and positive definite. The vectors or matrices + * The sparse matrix A must be selfadjoint and positive definite. The vectors or matrices * X and B can be either dense or sparse. * * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> @@ -484,7 +487,7 @@ class CholmodSupernodalLLT : public CholmodBase<_MatrixType, _UpLo, CholmodSuper CholmodSupernodalLLT(const MatrixType& matrix) : Base() { init(); - compute(matrix); + Base::compute(matrix); } ~CholmodSupernodalLLT() {} @@ -501,7 +504,7 @@ class CholmodSupernodalLLT : public CholmodBase<_MatrixType, _UpLo, CholmodSuper * \brief A general Cholesky factorization and solver based on Cholmod * * This class allows to solve for A.X = B sparse linear problems via a LL^T or LDL^T Cholesky factorization - * using the Cholmod library. The sparse matrix A must be selfajoint and positive definite. The vectors or matrices + * using the Cholmod library. The sparse matrix A must be selfadjoint and positive definite. The vectors or matrices * X and B can be either dense or sparse. * * This variant permits to change the underlying Cholesky method at runtime. @@ -531,7 +534,7 @@ class CholmodDecomposition : public CholmodBase<_MatrixType, _UpLo, CholmodDecom CholmodDecomposition(const MatrixType& matrix) : Base() { init(); - compute(matrix); + Base::compute(matrix); } ~CholmodDecomposition() {} diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/Array.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/Array.h index 497efff66..0b9c38c82 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/Array.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/Array.h @@ -124,6 +124,21 @@ class Array } #endif +#ifdef EIGEN_HAVE_RVALUE_REFERENCES + Array(Array&& other) + : Base(std::move(other)) + { + Base::_check_template_params(); + if (RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic) + Base::_set_noalias(other); + } + Array& operator=(Array&& other) + { + other.swap(*this); + return *this; + } +#endif + /** Constructs a vector or row-vector with given dimension. \only_for_vectors * * Note that this is only useful for dynamic-size vectors. For fixed-size vectors, @@ -210,7 +225,7 @@ class Array : Base(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols()) { Base::_check_template_params(); - Base::resize(other.rows(), other.cols()); + Base::_resize_to_match(other); *this = other; } diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/ArrayBase.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/ArrayBase.h index 38852600d..33ff55371 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/ArrayBase.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/ArrayBase.h @@ -46,9 +46,6 @@ template class ArrayBase typedef ArrayBase Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl; - using internal::special_scalar_op_base::Scalar, - typename NumTraits::Scalar>::Real>::operator*; - typedef typename internal::traits::StorageKind StorageKind; typedef typename internal::traits::Index Index; typedef typename internal::traits::Scalar Scalar; @@ -56,6 +53,7 @@ template class ArrayBase typedef typename NumTraits::Real RealScalar; typedef DenseBase Base; + using Base::operator*; using Base::RowsAtCompileTime; using Base::ColsAtCompileTime; using Base::SizeAtCompileTime; diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/ArrayWrapper.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/ArrayWrapper.h index a791bc358..b4641e2a0 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/ArrayWrapper.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/ArrayWrapper.h @@ -29,6 +29,11 @@ struct traits > : public traits::type > { typedef ArrayXpr XprKind; + // Let's remove NestByRefBit + enum { + Flags0 = traits::type >::Flags, + Flags = Flags0 & ~NestByRefBit + }; }; } @@ -149,6 +154,11 @@ struct traits > : public traits::type > { typedef MatrixXpr XprKind; + // Let's remove NestByRefBit + enum { + Flags0 = traits::type >::Flags, + Flags = Flags0 & ~NestByRefBit + }; }; } diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/Assign.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/Assign.h index 1dccc2f42..f48173172 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/Assign.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/Assign.h @@ -439,19 +439,26 @@ struct assign_impl PacketTraits; + typedef typename Derived1::Scalar Scalar; + typedef packet_traits PacketTraits; enum { packetSize = PacketTraits::size, alignable = PacketTraits::AlignedOnScalar, - dstAlignment = alignable ? Aligned : int(assign_traits::DstIsAligned) , + dstIsAligned = assign_traits::DstIsAligned, + dstAlignment = alignable ? Aligned : int(dstIsAligned), srcAlignment = assign_traits::JointAlignment }; + const Scalar *dst_ptr = &dst.coeffRef(0,0); + if((!bool(dstIsAligned)) && (size_t(dst_ptr) % sizeof(Scalar))>0) + { + // the pointer is not aligend-on scalar, so alignment is not possible + return assign_impl::run(dst, src); + } const Index packetAlignedMask = packetSize - 1; const Index innerSize = dst.innerSize(); const Index outerSize = dst.outerSize(); const Index alignedStep = alignable ? (packetSize - dst.outerStride() % packetSize) & packetAlignedMask : 0; - Index alignedStart = ((!alignable) || assign_traits::DstIsAligned) ? 0 - : internal::first_aligned(&dst.coeffRef(0,0), innerSize); + Index alignedStart = ((!alignable) || bool(dstIsAligned)) ? 0 : internal::first_aligned(dst_ptr, innerSize); for(Index outer = 0; outer < outerSize; ++outer) { diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/Block.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/Block.h index 358b3188b..827894443 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/Block.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/Block.h @@ -66,8 +66,9 @@ struct traits > : traits::MaxColsAtCompileTime), XprTypeIsRowMajor = (int(traits::Flags)&RowMajorBit) != 0, - IsRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1 - : (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0 + IsDense = is_same::value, + IsRowMajor = (IsDense&&MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1 + : (IsDense&&MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0 : XprTypeIsRowMajor, HasSameStorageOrderAsXprType = (IsRowMajor == XprTypeIsRowMajor), InnerSize = IsRowMajor ? int(ColsAtCompileTime) : int(RowsAtCompileTime), @@ -81,7 +82,7 @@ struct traits > : traits::Flags&LinearAccessBit))) ? LinearAccessBit : 0, FlagsLvalueBit = is_lvalue::value ? LvalueBit : 0, FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0, Flags0 = traits::Flags & ( (HereditaryBits & ~RowMajorBit) | diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/BooleanRedux.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/BooleanRedux.h index 6e37e031a..be9f48a8c 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/BooleanRedux.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/BooleanRedux.h @@ -29,9 +29,9 @@ struct all_unroller }; template -struct all_unroller +struct all_unroller { - static inline bool run(const Derived &mat) { return mat.coeff(0, 0); } + static inline bool run(const Derived &/*mat*/) { return true; } }; template @@ -55,9 +55,9 @@ struct any_unroller }; template -struct any_unroller +struct any_unroller { - static inline bool run(const Derived &mat) { return mat.coeff(0, 0); } + static inline bool run(const Derived & /*mat*/) { return false; } }; template diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/CommaInitializer.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/CommaInitializer.h index a96867af4..a036d8c3b 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/CommaInitializer.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/CommaInitializer.h @@ -43,6 +43,17 @@ struct CommaInitializer m_xpr.block(0, 0, other.rows(), other.cols()) = other; } + /* Copy/Move constructor which transfers ownership. This is crucial in + * absence of return value optimization to avoid assertions during destruction. */ + // FIXME in C++11 mode this could be replaced by a proper RValue constructor + inline CommaInitializer(const CommaInitializer& o) + : m_xpr(o.m_xpr), m_row(o.m_row), m_col(o.m_col), m_currentBlockRows(o.m_currentBlockRows) { + // Mark original object as finished. In absence of R-value references we need to const_cast: + const_cast(o).m_row = m_xpr.rows(); + const_cast(o).m_col = m_xpr.cols(); + const_cast(o).m_currentBlockRows = 0; + } + /* inserts a scalar value in the target matrix */ CommaInitializer& operator,(const Scalar& s) { diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/CwiseBinaryOp.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/CwiseBinaryOp.h index 586f77aaf..519a866e6 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/CwiseBinaryOp.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/CwiseBinaryOp.h @@ -81,7 +81,8 @@ struct traits > ) ), Flags = (Flags0 & ~RowMajorBit) | (LhsFlags & RowMajorBit), - CoeffReadCost = LhsCoeffReadCost + RhsCoeffReadCost + functor_traits::Cost + Cost0 = EIGEN_ADD_COST(LhsCoeffReadCost,RhsCoeffReadCost), + CoeffReadCost = EIGEN_ADD_COST(Cost0,functor_traits::Cost) }; }; } // end namespace internal diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/CwiseUnaryOp.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/CwiseUnaryOp.h index f2de749f9..f7ee60e98 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/CwiseUnaryOp.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/CwiseUnaryOp.h @@ -47,7 +47,7 @@ struct traits > Flags = _XprTypeNested::Flags & ( HereditaryBits | LinearAccessBit | AlignedBit | (functor_traits::PacketAccess ? PacketAccessBit : 0)), - CoeffReadCost = _XprTypeNested::CoeffReadCost + functor_traits::Cost + CoeffReadCost = EIGEN_ADD_COST(_XprTypeNested::CoeffReadCost, functor_traits::Cost) }; }; } diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/CwiseUnaryView.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/CwiseUnaryView.h index b2638d326..f3b2ffeb6 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/CwiseUnaryView.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/CwiseUnaryView.h @@ -38,7 +38,7 @@ struct traits > typedef typename remove_all::type _MatrixTypeNested; enum { Flags = (traits<_MatrixTypeNested>::Flags & (HereditaryBits | LvalueBit | LinearAccessBit | DirectAccessBit)), - CoeffReadCost = traits<_MatrixTypeNested>::CoeffReadCost + functor_traits::Cost, + CoeffReadCost = EIGEN_ADD_COST(traits<_MatrixTypeNested>::CoeffReadCost, functor_traits::Cost), MatrixTypeInnerStride = inner_stride_at_compile_time::ret, // need to cast the sizeof's from size_t to int explicitly, otherwise: // "error: no integral type can represent all of the enumerator values diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/DenseBase.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/DenseBase.h index c5800f6c8..4b371b075 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/DenseBase.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/DenseBase.h @@ -40,15 +40,14 @@ static inline void check_DenseIndex_is_signed() { */ template class DenseBase #ifndef EIGEN_PARSED_BY_DOXYGEN - : public internal::special_scalar_op_base::Scalar, - typename NumTraits::Scalar>::Real> + : public internal::special_scalar_op_base::Scalar, + typename NumTraits::Scalar>::Real, + DenseCoeffsBase > #else : public DenseCoeffsBase #endif // not EIGEN_PARSED_BY_DOXYGEN { public: - using internal::special_scalar_op_base::Scalar, - typename NumTraits::Scalar>::Real>::operator*; class InnerIterator; @@ -63,8 +62,9 @@ template class DenseBase typedef typename internal::traits::Scalar Scalar; typedef typename internal::packet_traits::type PacketScalar; typedef typename NumTraits::Real RealScalar; + typedef internal::special_scalar_op_base > Base; - typedef DenseCoeffsBase Base; + using Base::operator*; using Base::derived; using Base::const_cast_derived; using Base::rows; @@ -183,10 +183,6 @@ template class DenseBase /** \returns the number of nonzero coefficients which is in practice the number * of stored coefficients. */ inline Index nonZeros() const { return size(); } - /** \returns true if either the number of rows or the number of columns is equal to 1. - * In other words, this function returns - * \code rows()==1 || cols()==1 \endcode - * \sa rows(), cols(), IsVectorAtCompileTime. */ /** \returns the outer size. * @@ -266,11 +262,13 @@ template class DenseBase template Derived& operator=(const ReturnByValue& func); -#ifndef EIGEN_PARSED_BY_DOXYGEN - /** Copies \a other into *this without evaluating other. \returns a reference to *this. */ + /** \internal Copies \a other into *this without evaluating other. \returns a reference to *this. */ template Derived& lazyAssign(const DenseBase& other); -#endif // not EIGEN_PARSED_BY_DOXYGEN + + /** \internal Evaluates \a other into *this. \returns a reference to *this. */ + template + Derived& lazyAssign(const ReturnByValue& other); CommaInitializer operator<< (const Scalar& s); @@ -462,8 +460,10 @@ template class DenseBase template RealScalar lpNorm() const; template - const Replicate replicate() const; - const Replicate replicate(Index rowFacor,Index colFactor) const; + inline const Replicate replicate() const; + + typedef Replicate ReplicateReturnType; + inline const ReplicateReturnType replicate(Index rowFacor,Index colFactor) const; typedef Reverse ReverseReturnType; typedef const Reverse ConstReverseReturnType; diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/DenseStorage.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/DenseStorage.h index 3e7f9c1b7..568493cba 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/DenseStorage.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/DenseStorage.h @@ -24,6 +24,14 @@ namespace internal { struct constructor_without_unaligned_array_assert {}; +template void check_static_allocation_size() +{ + // if EIGEN_STACK_ALLOCATION_LIMIT is defined to 0, then no limit + #if EIGEN_STACK_ALLOCATION_LIMIT + EIGEN_STATIC_ASSERT(Size * sizeof(T) <= EIGEN_STACK_ALLOCATION_LIMIT, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG); + #endif +} + /** \internal * Static array. If the MatrixOrArrayOptions require auto-alignment, the array will be automatically aligned: * to 16 bytes boundary if the total size is a multiple of 16 bytes. @@ -38,12 +46,12 @@ struct plain_array plain_array() { - EIGEN_STATIC_ASSERT(Size * sizeof(T) <= 128 * 128 * 8, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG); + check_static_allocation_size(); } plain_array(constructor_without_unaligned_array_assert) { - EIGEN_STATIC_ASSERT(Size * sizeof(T) <= 128 * 128 * 8, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG); + check_static_allocation_size(); } }; @@ -76,12 +84,12 @@ struct plain_array plain_array() { EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(0xf); - EIGEN_STATIC_ASSERT(Size * sizeof(T) <= 128 * 128 * 8, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG); + check_static_allocation_size(); } plain_array(constructor_without_unaligned_array_assert) { - EIGEN_STATIC_ASSERT(Size * sizeof(T) <= 128 * 128 * 8, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG); + check_static_allocation_size(); } }; @@ -114,33 +122,41 @@ template class DenseSt { internal::plain_array m_data; public: - inline DenseStorage() {} - inline DenseStorage(internal::constructor_without_unaligned_array_assert) + DenseStorage() {} + DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(internal::constructor_without_unaligned_array_assert()) {} - inline DenseStorage(DenseIndex,DenseIndex,DenseIndex) {} - inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); } - static inline DenseIndex rows(void) {return _Rows;} - static inline DenseIndex cols(void) {return _Cols;} - inline void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {} - inline void resize(DenseIndex,DenseIndex,DenseIndex) {} - inline const T *data() const { return m_data.array; } - inline T *data() { return m_data.array; } + DenseStorage(const DenseStorage& other) : m_data(other.m_data) {} + DenseStorage& operator=(const DenseStorage& other) + { + if (this != &other) m_data = other.m_data; + return *this; + } + DenseStorage(DenseIndex,DenseIndex,DenseIndex) {} + void swap(DenseStorage& other) { std::swap(m_data,other.m_data); } + static DenseIndex rows(void) {return _Rows;} + static DenseIndex cols(void) {return _Cols;} + void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {} + void resize(DenseIndex,DenseIndex,DenseIndex) {} + const T *data() const { return m_data.array; } + T *data() { return m_data.array; } }; // null matrix template class DenseStorage { public: - inline DenseStorage() {} - inline DenseStorage(internal::constructor_without_unaligned_array_assert) {} - inline DenseStorage(DenseIndex,DenseIndex,DenseIndex) {} - inline void swap(DenseStorage& ) {} - static inline DenseIndex rows(void) {return _Rows;} - static inline DenseIndex cols(void) {return _Cols;} - inline void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {} - inline void resize(DenseIndex,DenseIndex,DenseIndex) {} - inline const T *data() const { return 0; } - inline T *data() { return 0; } + DenseStorage() {} + DenseStorage(internal::constructor_without_unaligned_array_assert) {} + DenseStorage(const DenseStorage&) {} + DenseStorage& operator=(const DenseStorage&) { return *this; } + DenseStorage(DenseIndex,DenseIndex,DenseIndex) {} + void swap(DenseStorage& ) {} + static DenseIndex rows(void) {return _Rows;} + static DenseIndex cols(void) {return _Cols;} + void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {} + void resize(DenseIndex,DenseIndex,DenseIndex) {} + const T *data() const { return 0; } + T *data() { return 0; } }; // more specializations for null matrices; these are necessary to resolve ambiguities @@ -160,18 +176,29 @@ template class DenseStorage class DenseStorage m_data; DenseIndex m_rows; public: - inline DenseStorage() : m_rows(0) {} - inline DenseStorage(internal::constructor_without_unaligned_array_assert) + DenseStorage() : m_rows(0) {} + DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0) {} - inline DenseStorage(DenseIndex, DenseIndex nbRows, DenseIndex) : m_rows(nbRows) {} - inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); } - inline DenseIndex rows(void) const {return m_rows;} - inline DenseIndex cols(void) const {return _Cols;} - inline void conservativeResize(DenseIndex, DenseIndex nbRows, DenseIndex) { m_rows = nbRows; } - inline void resize(DenseIndex, DenseIndex nbRows, DenseIndex) { m_rows = nbRows; } - inline const T *data() const { return m_data.array; } - inline T *data() { return m_data.array; } + DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_rows(other.m_rows) {} + DenseStorage& operator=(const DenseStorage& other) + { + if (this != &other) + { + m_data = other.m_data; + m_rows = other.m_rows; + } + return *this; + } + DenseStorage(DenseIndex, DenseIndex nbRows, DenseIndex) : m_rows(nbRows) {} + void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); } + DenseIndex rows(void) const {return m_rows;} + DenseIndex cols(void) const {return _Cols;} + void conservativeResize(DenseIndex, DenseIndex nbRows, DenseIndex) { m_rows = nbRows; } + void resize(DenseIndex, DenseIndex nbRows, DenseIndex) { m_rows = nbRows; } + const T *data() const { return m_data.array; } + T *data() { return m_data.array; } }; // dynamic-size matrix with fixed-size storage and fixed height @@ -199,17 +236,27 @@ template class DenseStorage m_data; DenseIndex m_cols; public: - inline DenseStorage() : m_cols(0) {} - inline DenseStorage(internal::constructor_without_unaligned_array_assert) + DenseStorage() : m_cols(0) {} + DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(internal::constructor_without_unaligned_array_assert()), m_cols(0) {} - inline DenseStorage(DenseIndex, DenseIndex, DenseIndex nbCols) : m_cols(nbCols) {} - inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); } - inline DenseIndex rows(void) const {return _Rows;} - inline DenseIndex cols(void) const {return m_cols;} - inline void conservativeResize(DenseIndex, DenseIndex, DenseIndex nbCols) { m_cols = nbCols; } - inline void resize(DenseIndex, DenseIndex, DenseIndex nbCols) { m_cols = nbCols; } - inline const T *data() const { return m_data.array; } - inline T *data() { return m_data.array; } + DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_cols(other.m_cols) {} + DenseStorage& operator=(const DenseStorage& other) + { + if (this != &other) + { + m_data = other.m_data; + m_cols = other.m_cols; + } + return *this; + } + DenseStorage(DenseIndex, DenseIndex, DenseIndex nbCols) : m_cols(nbCols) {} + void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); } + DenseIndex rows(void) const {return _Rows;} + DenseIndex cols(void) const {return m_cols;} + void conservativeResize(DenseIndex, DenseIndex, DenseIndex nbCols) { m_cols = nbCols; } + void resize(DenseIndex, DenseIndex, DenseIndex nbCols) { m_cols = nbCols; } + const T *data() const { return m_data.array; } + T *data() { return m_data.array; } }; // purely dynamic matrix. @@ -219,18 +266,35 @@ template class DenseStorage(size)), m_rows(nbRows), m_cols(nbCols) { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN } - inline ~DenseStorage() { internal::conditional_aligned_delete_auto(m_data, m_rows*m_cols); } - inline void swap(DenseStorage& other) +#ifdef EIGEN_HAVE_RVALUE_REFERENCES + DenseStorage(DenseStorage&& other) + : m_data(std::move(other.m_data)) + , m_rows(std::move(other.m_rows)) + , m_cols(std::move(other.m_cols)) + { + other.m_data = nullptr; + } + DenseStorage& operator=(DenseStorage&& other) + { + using std::swap; + swap(m_data, other.m_data); + swap(m_rows, other.m_rows); + swap(m_cols, other.m_cols); + return *this; + } +#endif + ~DenseStorage() { internal::conditional_aligned_delete_auto(m_data, m_rows*m_cols); } + void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); } - inline DenseIndex rows(void) const {return m_rows;} - inline DenseIndex cols(void) const {return m_cols;} - inline void conservativeResize(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols) + DenseIndex rows(void) const {return m_rows;} + DenseIndex cols(void) const {return m_cols;} + void conservativeResize(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols) { m_data = internal::conditional_aligned_realloc_new_auto(m_data, size, m_rows*m_cols); m_rows = nbRows; @@ -250,8 +314,11 @@ template class DenseStorage class DenseStorage(size)), m_cols(nbCols) + DenseStorage() : m_data(0), m_cols(0) {} + DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {} + DenseStorage(DenseIndex size, DenseIndex, DenseIndex nbCols) : m_data(internal::conditional_aligned_new_auto(size)), m_cols(nbCols) { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN } - inline ~DenseStorage() { internal::conditional_aligned_delete_auto(m_data, _Rows*m_cols); } - inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); } - static inline DenseIndex rows(void) {return _Rows;} - inline DenseIndex cols(void) const {return m_cols;} - inline void conservativeResize(DenseIndex size, DenseIndex, DenseIndex nbCols) +#ifdef EIGEN_HAVE_RVALUE_REFERENCES + DenseStorage(DenseStorage&& other) + : m_data(std::move(other.m_data)) + , m_cols(std::move(other.m_cols)) + { + other.m_data = nullptr; + } + DenseStorage& operator=(DenseStorage&& other) + { + using std::swap; + swap(m_data, other.m_data); + swap(m_cols, other.m_cols); + return *this; + } +#endif + ~DenseStorage() { internal::conditional_aligned_delete_auto(m_data, _Rows*m_cols); } + void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); } + static DenseIndex rows(void) {return _Rows;} + DenseIndex cols(void) const {return m_cols;} + void conservativeResize(DenseIndex size, DenseIndex, DenseIndex nbCols) { m_data = internal::conditional_aligned_realloc_new_auto(m_data, size, _Rows*m_cols); m_cols = nbCols; @@ -286,8 +368,11 @@ template class DenseStorage class DenseStorage(size)), m_rows(nbRows) + DenseStorage() : m_data(0), m_rows(0) {} + DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {} + DenseStorage(DenseIndex size, DenseIndex nbRows, DenseIndex) : m_data(internal::conditional_aligned_new_auto(size)), m_rows(nbRows) { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN } - inline ~DenseStorage() { internal::conditional_aligned_delete_auto(m_data, _Cols*m_rows); } - inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); } - inline DenseIndex rows(void) const {return m_rows;} - static inline DenseIndex cols(void) {return _Cols;} - inline void conservativeResize(DenseIndex size, DenseIndex nbRows, DenseIndex) +#ifdef EIGEN_HAVE_RVALUE_REFERENCES + DenseStorage(DenseStorage&& other) + : m_data(std::move(other.m_data)) + , m_rows(std::move(other.m_rows)) + { + other.m_data = nullptr; + } + DenseStorage& operator=(DenseStorage&& other) + { + using std::swap; + swap(m_data, other.m_data); + swap(m_rows, other.m_rows); + return *this; + } +#endif + ~DenseStorage() { internal::conditional_aligned_delete_auto(m_data, _Cols*m_rows); } + void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); } + DenseIndex rows(void) const {return m_rows;} + static DenseIndex cols(void) {return _Cols;} + void conservativeResize(DenseIndex size, DenseIndex nbRows, DenseIndex) { m_data = internal::conditional_aligned_realloc_new_auto(m_data, size, m_rows*_Cols); m_rows = nbRows; @@ -322,8 +422,11 @@ template class DenseStorage::diagonal() const * * \sa MatrixBase::diagonal(), class Diagonal */ template -inline typename MatrixBase::template DiagonalIndexReturnType::Type +inline typename MatrixBase::DiagonalDynamicIndexReturnType MatrixBase::diagonal(Index index) { - return typename DiagonalIndexReturnType::Type(derived(), index); + return DiagonalDynamicIndexReturnType(derived(), index); } /** This is the const version of diagonal(Index). */ template -inline typename MatrixBase::template ConstDiagonalIndexReturnType::Type +inline typename MatrixBase::ConstDiagonalDynamicIndexReturnType MatrixBase::diagonal(Index index) const { - return typename ConstDiagonalIndexReturnType::Type(derived(), index); + return ConstDiagonalDynamicIndexReturnType(derived(), index); } /** \returns an expression of the \a DiagIndex-th sub or super diagonal of the matrix \c *this diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/DiagonalProduct.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/DiagonalProduct.h index c03a0c2e1..cc6b536e1 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/DiagonalProduct.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/DiagonalProduct.h @@ -34,8 +34,9 @@ struct traits > _Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && _SameTypes && (_ScalarAccessOnDiag || (bool(int(DiagonalType::DiagonalVectorType::Flags)&PacketAccessBit))), _LinearAccessMask = (RowsAtCompileTime==1 || ColsAtCompileTime==1) ? LinearAccessBit : 0, - Flags = ((HereditaryBits|_LinearAccessMask) & (unsigned int)(MatrixType::Flags)) | (_Vectorizable ? PacketAccessBit : 0) | AlignedBit,//(int(MatrixType::Flags)&int(DiagonalType::DiagonalVectorType::Flags)&AlignedBit), - CoeffReadCost = NumTraits::MulCost + MatrixType::CoeffReadCost + DiagonalType::DiagonalVectorType::CoeffReadCost + Flags = ((HereditaryBits|_LinearAccessMask|AlignedBit) & (unsigned int)(MatrixType::Flags)) | (_Vectorizable ? PacketAccessBit : 0),//(int(MatrixType::Flags)&int(DiagonalType::DiagonalVectorType::Flags)&AlignedBit), + Cost0 = EIGEN_ADD_COST(NumTraits::MulCost, MatrixType::CoeffReadCost), + CoeffReadCost = EIGEN_ADD_COST(Cost0,DiagonalType::DiagonalVectorType::CoeffReadCost) }; }; } diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/EigenBase.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/EigenBase.h index 2b8dd1b70..fadb45852 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/EigenBase.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/EigenBase.h @@ -126,36 +126,6 @@ Derived& DenseBase::operator-=(const EigenBase &other) return derived(); } -/** replaces \c *this by \c *this * \a other. - * - * \returns a reference to \c *this - */ -template -template -inline Derived& -MatrixBase::operator*=(const EigenBase &other) -{ - other.derived().applyThisOnTheRight(derived()); - return derived(); -} - -/** replaces \c *this by \c *this * \a other. It is equivalent to MatrixBase::operator*=(). - */ -template -template -inline void MatrixBase::applyOnTheRight(const EigenBase &other) -{ - other.derived().applyThisOnTheRight(derived()); -} - -/** replaces \c *this by \c *this * \a other. */ -template -template -inline void MatrixBase::applyOnTheLeft(const EigenBase &other) -{ - other.derived().applyThisOnTheLeft(derived()); -} - } // end namespace Eigen #endif // EIGEN_EIGENBASE_H diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/Functors.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/Functors.h index 04fb21732..5f14c6587 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/Functors.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/Functors.h @@ -259,6 +259,47 @@ template<> struct functor_traits { }; }; +/** \internal + * \brief Template functors for comparison of two scalars + * \todo Implement packet-comparisons + */ +template struct scalar_cmp_op; + +template +struct functor_traits > { + enum { + Cost = NumTraits::AddCost, + PacketAccess = false + }; +}; + +template +struct result_of(Scalar,Scalar)> { + typedef bool type; +}; + + +template struct scalar_cmp_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op) + EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a==b;} +}; +template struct scalar_cmp_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op) + EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a struct scalar_cmp_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op) + EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a<=b;} +}; +template struct scalar_cmp_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op) + EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return !(a<=b || b<=a);} +}; +template struct scalar_cmp_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op) + EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a!=b;} +}; + // unary functors: /** \internal @@ -589,7 +630,7 @@ struct linspaced_op_impl template EIGEN_STRONG_INLINE const Packet packetOp(Index i) const - { return internal::padd(m_lowPacket, pmul(m_stepPacket, padd(pset1(i),m_interPacket))); } + { return internal::padd(m_lowPacket, pmul(m_stepPacket, padd(pset1(Scalar(i)),m_interPacket))); } const Scalar m_low; const Scalar m_step; @@ -609,7 +650,7 @@ template struct functor_traits< linspaced_o template struct linspaced_op { typedef typename packet_traits::type Packet; - linspaced_op(const Scalar& low, const Scalar& high, DenseIndex num_steps) : impl((num_steps==1 ? high : low), (num_steps==1 ? Scalar() : (high-low)/(num_steps-1))) {} + linspaced_op(const Scalar& low, const Scalar& high, DenseIndex num_steps) : impl((num_steps==1 ? high : low), (num_steps==1 ? Scalar() : (high-low)/Scalar(num_steps-1))) {} template EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return impl(i); } diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/GeneralProduct.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/GeneralProduct.h index 2a59d9464..29ac522d2 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/GeneralProduct.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/GeneralProduct.h @@ -232,7 +232,7 @@ EIGEN_DONT_INLINE void outer_product_selector_run(const ProductType& prod, Dest& // FIXME not very good if rhs is real and lhs complex while alpha is real too const Index cols = dest.cols(); for (Index j=0; j @@ -257,7 +257,7 @@ template class GeneralProduct : public ProductBase, Lhs, Rhs> { - template struct IsRowMajor : internal::conditional<(int(T::Flags)&RowMajorBit), internal::true_type, internal::false_type>::type {}; + template struct is_row_major : internal::conditional<(int(T::Flags)&RowMajorBit), internal::true_type, internal::false_type>::type {}; public: EIGEN_PRODUCT_PUBLIC_INTERFACE(GeneralProduct) @@ -281,22 +281,22 @@ class GeneralProduct template inline void evalTo(Dest& dest) const { - internal::outer_product_selector_run(*this, dest, set(), IsRowMajor()); + internal::outer_product_selector_run(*this, dest, set(), is_row_major()); } template inline void addTo(Dest& dest) const { - internal::outer_product_selector_run(*this, dest, add(), IsRowMajor()); + internal::outer_product_selector_run(*this, dest, add(), is_row_major()); } template inline void subTo(Dest& dest) const { - internal::outer_product_selector_run(*this, dest, sub(), IsRowMajor()); + internal::outer_product_selector_run(*this, dest, sub(), is_row_major()); } template void scaleAndAddTo(Dest& dest, const Scalar& alpha) const { - internal::outer_product_selector_run(*this, dest, adds(alpha), IsRowMajor()); + internal::outer_product_selector_run(*this, dest, adds(alpha), is_row_major()); } }; @@ -425,15 +425,18 @@ template<> struct gemv_selector ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs()) * RhsBlasTraits::extractScalarFactor(prod.rhs()); + // make sure Dest is a compile-time vector type (bug 1166) + typedef typename conditional::type ActualDest; + enum { // FIXME find a way to allow an inner stride on the result if packet_traits::size==1 // on, the other hand it is good for the cache to pack the vector anyways... - EvalToDestAtCompileTime = Dest::InnerStrideAtCompileTime==1, + EvalToDestAtCompileTime = (ActualDest::InnerStrideAtCompileTime==1), ComplexByReal = (NumTraits::IsComplex) && (!NumTraits::IsComplex), - MightCannotUseDest = (Dest::InnerStrideAtCompileTime!=1) || ComplexByReal + MightCannotUseDest = (ActualDest::InnerStrideAtCompileTime!=1) || ComplexByReal }; - gemv_static_vector_if static_dest; + gemv_static_vector_if static_dest; bool alphaIsCompatible = (!ComplexByReal) || (numext::imag(actualAlpha)==RealScalar(0)); bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible; @@ -522,7 +525,7 @@ template<> struct gemv_selector actualLhs.rows(), actualLhs.cols(), actualLhs.data(), actualLhs.outerStride(), actualRhsPtr, 1, - dest.data(), dest.innerStride(), + dest.data(), dest.col(0).innerStride(), //NOTE if dest is not a vector at compile-time, then dest.innerStride() might be wrong. (bug 1166) actualAlpha); } }; diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/IO.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/IO.h index c8d5f6379..8d4bc59e9 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/IO.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/IO.h @@ -185,21 +185,22 @@ std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat& explicit_precision = fmt.precision; } + std::streamsize old_precision = 0; + if(explicit_precision) old_precision = s.precision(explicit_precision); + bool align_cols = !(fmt.flags & DontAlignCols); if(align_cols) { // compute the largest width - for(Index j = 1; j < m.cols(); ++j) + for(Index j = 0; j < m.cols(); ++j) for(Index i = 0; i < m.rows(); ++i) { std::stringstream sstr; - if(explicit_precision) sstr.precision(explicit_precision); + sstr.copyfmt(s); sstr << m.coeff(i,j); width = std::max(width, Index(sstr.str().length())); } } - std::streamsize old_precision = 0; - if(explicit_precision) old_precision = s.precision(explicit_precision); s << fmt.matPrefix; for(Index i = 0; i < m.rows(); ++i) { diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/MapBase.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/MapBase.h index 6876de588..81efc4a6d 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/MapBase.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/MapBase.h @@ -123,7 +123,7 @@ template class MapBase return internal::ploadt(m_data + index * innerStride()); } - inline MapBase(PointerType dataPtr) : m_data(dataPtr), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime) + explicit inline MapBase(PointerType dataPtr) : m_data(dataPtr), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime) { EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived) checkSanity(); @@ -149,6 +149,10 @@ template class MapBase checkSanity(); } + #ifdef EIGEN_MAPBASE_PLUGIN + #include EIGEN_MAPBASE_PLUGIN + #endif + protected: void checkSanity() const @@ -157,7 +161,7 @@ template class MapBase internal::inner_stride_at_compile_time::ret==1), PACKET_ACCESS_REQUIRES_TO_HAVE_INNER_STRIDE_FIXED_TO_1); eigen_assert(EIGEN_IMPLIES(internal::traits::Flags&AlignedBit, (size_t(m_data) % 16) == 0) - && "data is not aligned"); + && "input pointer is not aligned on a 16 byte boundary"); } PointerType m_data; @@ -168,6 +172,7 @@ template class MapBase template class MapBase : public MapBase { + typedef MapBase ReadOnlyMapBase; public: typedef MapBase Base; @@ -230,13 +235,17 @@ template class MapBase Derived& operator=(const MapBase& other) { - Base::Base::operator=(other); + ReadOnlyMapBase::Base::operator=(other); return derived(); } - using Base::Base::operator=; + // In theory we could simply refer to Base:Base::operator=, but MSVC does not like Base::Base, + // see bugs 821 and 920. + using ReadOnlyMapBase::Base::operator=; }; +#undef EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS + } // end namespace Eigen #endif // EIGEN_MAPBASE_H diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/MathFunctions.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/MathFunctions.h index 2bfc5ebd9..4e17ecd4b 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/MathFunctions.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/MathFunctions.h @@ -294,7 +294,7 @@ struct hypot_impl RealScalar _x = abs(x); RealScalar _y = abs(y); RealScalar p = (max)(_x, _y); - if(p==RealScalar(0)) return 0; + if(p==RealScalar(0)) return RealScalar(0); RealScalar q = (min)(_x, _y); RealScalar qp = q/p; return p * sqrt(RealScalar(1) + qp*qp); @@ -707,21 +707,21 @@ struct scalar_fuzzy_impl : scalar_fuzzy_default_impl:: template inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, - typename NumTraits::Real precision = NumTraits::dummy_precision()) + const typename NumTraits::Real &precision = NumTraits::dummy_precision()) { return scalar_fuzzy_impl::template isMuchSmallerThan(x, y, precision); } template inline bool isApprox(const Scalar& x, const Scalar& y, - typename NumTraits::Real precision = NumTraits::dummy_precision()) + const typename NumTraits::Real &precision = NumTraits::dummy_precision()) { return scalar_fuzzy_impl::isApprox(x, y, precision); } template inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, - typename NumTraits::Real precision = NumTraits::dummy_precision()) + const typename NumTraits::Real &precision = NumTraits::dummy_precision()) { return scalar_fuzzy_impl::isApproxOrLessThan(x, y, precision); } diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/Matrix.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/Matrix.h index 0ba5d90cc..02be142d8 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/Matrix.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/Matrix.h @@ -211,6 +211,21 @@ class Matrix : Base(internal::constructor_without_unaligned_array_assert()) { Base::_check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED } +#ifdef EIGEN_HAVE_RVALUE_REFERENCES + Matrix(Matrix&& other) + : Base(std::move(other)) + { + Base::_check_template_params(); + if (RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic) + Base::_set_noalias(other); + } + Matrix& operator=(Matrix&& other) + { + other.swap(*this); + return *this; + } +#endif + /** \brief Constructs a vector or row-vector with given dimension. \only_for_vectors * * Note that this is only useful for dynamic-size vectors. For fixed-size vectors, @@ -304,7 +319,7 @@ class Matrix : Base(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols()) { Base::_check_template_params(); - Base::resize(other.rows(), other.cols()); + Base::_resize_to_match(other); // FIXME/CHECK: isn't *this = other.derived() more efficient. it allows to // go for pure _set() implementations, right? *this = other; diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/MatrixBase.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/MatrixBase.h index 9193b6abb..e83ef4dc0 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/MatrixBase.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/MatrixBase.h @@ -159,13 +159,11 @@ template class MatrixBase template Derived& operator=(const ReturnByValue& other); -#ifndef EIGEN_PARSED_BY_DOXYGEN template Derived& lazyAssign(const ProductBase& other); template Derived& lazyAssign(const MatrixPowerProduct& other); -#endif // not EIGEN_PARSED_BY_DOXYGEN template Derived& operator+=(const MatrixBase& other); @@ -215,7 +213,7 @@ template class MatrixBase typedef Diagonal DiagonalReturnType; DiagonalReturnType diagonal(); - typedef typename internal::add_const >::type ConstDiagonalReturnType; + typedef typename internal::add_const >::type ConstDiagonalReturnType; ConstDiagonalReturnType diagonal() const; template struct DiagonalIndexReturnType { typedef Diagonal Type; }; @@ -223,16 +221,12 @@ template class MatrixBase template typename DiagonalIndexReturnType::Type diagonal(); template typename ConstDiagonalIndexReturnType::Type diagonal() const; + + typedef Diagonal DiagonalDynamicIndexReturnType; + typedef typename internal::add_const >::type ConstDiagonalDynamicIndexReturnType; - // Note: The "MatrixBase::" prefixes are added to help MSVC9 to match these declarations with the later implementations. - // On the other hand they confuse MSVC8... - #if (defined _MSC_VER) && (_MSC_VER >= 1500) // 2008 or later - typename MatrixBase::template DiagonalIndexReturnType::Type diagonal(Index index); - typename MatrixBase::template ConstDiagonalIndexReturnType::Type diagonal(Index index) const; - #else - typename DiagonalIndexReturnType::Type diagonal(Index index); - typename ConstDiagonalIndexReturnType::Type diagonal(Index index) const; - #endif + DiagonalDynamicIndexReturnType diagonal(Index index); + ConstDiagonalDynamicIndexReturnType diagonal(Index index) const; #ifdef EIGEN2_SUPPORT template typename internal::eigen2_part_return_type::type part(); @@ -446,6 +440,15 @@ template class MatrixBase template void applyOnTheRight(Index p, Index q, const JacobiRotation& j); +///////// SparseCore module ///////// + + template + EIGEN_STRONG_INLINE const typename SparseMatrixBase::template CwiseProductDenseReturnType::Type + cwiseProduct(const SparseMatrixBase &other) const + { + return other.cwiseProduct(derived()); + } + ///////// MatrixFunctions module ///////// typedef typename internal::stem_function::type StemFunction; @@ -510,6 +513,51 @@ template class MatrixBase {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;} }; + +/*************************************************************************** +* Implementation of matrix base methods +***************************************************************************/ + +/** replaces \c *this by \c *this * \a other. + * + * \returns a reference to \c *this + * + * Example: \include MatrixBase_applyOnTheRight.cpp + * Output: \verbinclude MatrixBase_applyOnTheRight.out + */ +template +template +inline Derived& +MatrixBase::operator*=(const EigenBase &other) +{ + other.derived().applyThisOnTheRight(derived()); + return derived(); +} + +/** replaces \c *this by \c *this * \a other. It is equivalent to MatrixBase::operator*=(). + * + * Example: \include MatrixBase_applyOnTheRight.cpp + * Output: \verbinclude MatrixBase_applyOnTheRight.out + */ +template +template +inline void MatrixBase::applyOnTheRight(const EigenBase &other) +{ + other.derived().applyThisOnTheRight(derived()); +} + +/** replaces \c *this by \a other * \c *this. + * + * Example: \include MatrixBase_applyOnTheLeft.cpp + * Output: \verbinclude MatrixBase_applyOnTheLeft.out + */ +template +template +inline void MatrixBase::applyOnTheLeft(const EigenBase &other) +{ + other.derived().applyThisOnTheLeft(derived()); +} + } // end namespace Eigen #endif // EIGEN_MATRIXBASE_H diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/PermutationMatrix.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/PermutationMatrix.h index 4fc5dd318..85ffae265 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/PermutationMatrix.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/PermutationMatrix.h @@ -250,6 +250,35 @@ class PermutationBase : public EigenBase template friend inline PlainPermutationType operator*(const Transpose >& other, const PermutationBase& perm) { return PlainPermutationType(internal::PermPermProduct, other.eval(), perm); } + + /** \returns the determinant of the permutation matrix, which is either 1 or -1 depending on the parity of the permutation. + * + * This function is O(\c n) procedure allocating a buffer of \c n booleans. + */ + Index determinant() const + { + Index res = 1; + Index n = size(); + Matrix mask(n); + mask.fill(false); + Index r = 0; + while(r < n) + { + // search for the next seed + while(r=n) + break; + // we got one, let's follow it until we are back to the seed + Index k0 = r++; + mask.coeffRef(k0) = true; + for(Index k=indices().coeff(k0); k!=k0; k=indices().coeff(k)) + { + mask.coeffRef(k) = true; + res = -res; + } + } + return res; + } protected: @@ -553,8 +582,12 @@ struct permut_matrix_product_retval template inline void evalTo(Dest& dst) const { const Index n = Side==OnTheLeft ? rows() : cols(); - - if(is_same::value && extract_data(dst) == extract_data(m_matrix)) + // FIXME we need an is_same for expression that is not sensitive to constness. For instance + // is_same_xpr, Block >::value should be true. + if( is_same::value + && blas_traits::HasUsableDirectAccess + && blas_traits::HasUsableDirectAccess + && extract_data(dst) == extract_data(m_matrix)) { // apply the permutation inplace Matrix mask(m_permutation.size()); diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/PlainObjectBase.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/PlainObjectBase.h index af0a479c7..a4e4af4a7 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/PlainObjectBase.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/PlainObjectBase.h @@ -47,7 +47,10 @@ template<> struct check_rows_cols_for_overflow { } }; -template struct conservative_resize_like_impl; +template +struct conservative_resize_like_impl; template struct matrix_swap_impl; @@ -434,6 +437,36 @@ class PlainObjectBase : public internal::dense_xpr_base::type } #endif +#ifdef EIGEN_HAVE_RVALUE_REFERENCES + PlainObjectBase(PlainObjectBase&& other) + : m_storage( std::move(other.m_storage) ) + { + } + + PlainObjectBase& operator=(PlainObjectBase&& other) + { + using std::swap; + swap(m_storage, other.m_storage); + return *this; + } +#endif + + /** Copy constructor */ + EIGEN_STRONG_INLINE PlainObjectBase(const PlainObjectBase& other) + : m_storage() + { + _check_template_params(); + lazyAssign(other); + } + + template + EIGEN_STRONG_INLINE PlainObjectBase(const DenseBase &other) + : m_storage() + { + _check_template_params(); + lazyAssign(other); + } + EIGEN_STRONG_INLINE PlainObjectBase(Index a_size, Index nbRows, Index nbCols) : m_storage(a_size, nbRows, nbCols) { @@ -570,6 +603,8 @@ class PlainObjectBase : public internal::dense_xpr_base::type : (rows() == other.rows() && cols() == other.cols()))) && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined"); EIGEN_ONLY_USED_FOR_DEBUG(other); + if(this->size()==0) + resizeLike(other); #else resizeLike(other); #endif @@ -668,8 +703,10 @@ private: enum { ThisConstantIsPrivateInPlainObjectBase }; }; +namespace internal { + template -struct internal::conservative_resize_like_impl +struct conservative_resize_like_impl { typedef typename Derived::Index Index; static void run(DenseBase& _this, Index rows, Index cols) @@ -729,11 +766,14 @@ struct internal::conservative_resize_like_impl } }; -namespace internal { - +// Here, the specialization for vectors inherits from the general matrix case +// to allow calling .conservativeResize(rows,cols) on vectors. template struct conservative_resize_like_impl + : conservative_resize_like_impl { + using conservative_resize_like_impl::run; + typedef typename Derived::Index Index; static void run(DenseBase& _this, Index size) { diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/ProductBase.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/ProductBase.h index a494b5f87..cf74470a9 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/ProductBase.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/ProductBase.h @@ -85,7 +85,14 @@ class ProductBase : public MatrixBase public: +#ifndef EIGEN_NO_MALLOC + typedef typename Base::PlainObject BasePlainObject; + typedef Matrix DynPlainObject; + typedef typename internal::conditional<(BasePlainObject::SizeAtCompileTime==Dynamic) || (BasePlainObject::SizeAtCompileTime*int(sizeof(Scalar)) < int(EIGEN_STACK_ALLOCATION_LIMIT)), + BasePlainObject, DynPlainObject>::type PlainObject; +#else typedef typename Base::PlainObject PlainObject; +#endif ProductBase(const Lhs& a_lhs, const Rhs& a_rhs) : m_lhs(a_lhs), m_rhs(a_rhs) @@ -180,7 +187,12 @@ namespace internal { template struct nested, N, PlainObject> { - typedef PlainObject const& type; + typedef typename GeneralProduct::PlainObject const& type; +}; +template +struct nested, N, PlainObject> +{ + typedef typename GeneralProduct::PlainObject const& type; }; } diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/Redux.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/Redux.h index 50548fa9a..9b8662a6f 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/Redux.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/Redux.h @@ -247,8 +247,9 @@ struct redux_impl } }; -template -struct redux_impl +// NOTE: for SliceVectorizedTraversal we simply bypass unrolling +template +struct redux_impl { typedef typename Derived::Scalar Scalar; typedef typename packet_traits::type PacketScalar; diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/Ref.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/Ref.h index aba795bdb..7a3becaf8 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/Ref.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/Ref.h @@ -94,24 +94,26 @@ struct traits > typedef _PlainObjectType PlainObjectType; typedef _StrideType StrideType; enum { - Options = _Options + Options = _Options, + Flags = traits >::Flags | NestByRefBit }; template struct match { enum { HasDirectAccess = internal::has_direct_access::ret, - StorageOrderMatch = PlainObjectType::IsVectorAtCompileTime || ((PlainObjectType::Flags&RowMajorBit)==(Derived::Flags&RowMajorBit)), + StorageOrderMatch = PlainObjectType::IsVectorAtCompileTime || Derived::IsVectorAtCompileTime || ((PlainObjectType::Flags&RowMajorBit)==(Derived::Flags&RowMajorBit)), InnerStrideMatch = int(StrideType::InnerStrideAtCompileTime)==int(Dynamic) || int(StrideType::InnerStrideAtCompileTime)==int(Derived::InnerStrideAtCompileTime) || (int(StrideType::InnerStrideAtCompileTime)==0 && int(Derived::InnerStrideAtCompileTime)==1), OuterStrideMatch = Derived::IsVectorAtCompileTime || int(StrideType::OuterStrideAtCompileTime)==int(Dynamic) || int(StrideType::OuterStrideAtCompileTime)==int(Derived::OuterStrideAtCompileTime), AlignmentMatch = (_Options!=Aligned) || ((PlainObjectType::Flags&AlignedBit)==0) || ((traits::Flags&AlignedBit)==AlignedBit), - MatchAtCompileTime = HasDirectAccess && StorageOrderMatch && InnerStrideMatch && OuterStrideMatch && AlignmentMatch + ScalarTypeMatch = internal::is_same::value, + MatchAtCompileTime = HasDirectAccess && StorageOrderMatch && InnerStrideMatch && OuterStrideMatch && AlignmentMatch && ScalarTypeMatch }; typedef typename internal::conditional::type type; }; - + }; template @@ -171,8 +173,12 @@ protected: } else ::new (static_cast(this)) Base(expr.data(), expr.rows(), expr.cols()); - ::new (&m_stride) StrideBase(StrideType::OuterStrideAtCompileTime==0?0:expr.outerStride(), - StrideType::InnerStrideAtCompileTime==0?0:expr.innerStride()); + + if(Expression::IsVectorAtCompileTime && (!PlainObjectType::IsVectorAtCompileTime) && ((Expression::Flags&RowMajorBit)!=(PlainObjectType::Flags&RowMajorBit))) + ::new (&m_stride) StrideBase(expr.innerStride(), StrideType::InnerStrideAtCompileTime==0?0:1); + else + ::new (&m_stride) StrideBase(StrideType::OuterStrideAtCompileTime==0?0:expr.outerStride(), + StrideType::InnerStrideAtCompileTime==0?0:expr.innerStride()); } StrideBase m_stride; @@ -182,7 +188,11 @@ protected: template class Ref : public RefBase > { + private: typedef internal::traits Traits; + template + inline Ref(const PlainObjectBase& expr, + typename internal::enable_if::MatchAtCompileTime),Derived>::type* = 0); public: typedef RefBase Base; @@ -194,17 +204,20 @@ template class Ref inline Ref(PlainObjectBase& expr, typename internal::enable_if::MatchAtCompileTime),Derived>::type* = 0) { - Base::construct(expr); + EIGEN_STATIC_ASSERT(static_cast(Traits::template match::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH); + Base::construct(expr.derived()); } template inline Ref(const DenseBase& expr, - typename internal::enable_if::value&&bool(Traits::template match::MatchAtCompileTime)),Derived>::type* = 0, - int = Derived::ThisConstantIsPrivateInPlainObjectBase) + typename internal::enable_if::MatchAtCompileTime),Derived>::type* = 0) #else template inline Ref(DenseBase& expr) #endif { + EIGEN_STATIC_ASSERT(static_cast(internal::is_lvalue::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY); + EIGEN_STATIC_ASSERT(static_cast(Traits::template match::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH); + enum { THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY = Derived::ThisConstantIsPrivateInPlainObjectBase}; Base::construct(expr.const_cast_derived()); } @@ -223,13 +236,23 @@ template class Ref< EIGEN_DENSE_PUBLIC_INTERFACE(Ref) template - inline Ref(const DenseBase& expr) + inline Ref(const DenseBase& expr, + typename internal::enable_if::ScalarTypeMatch),Derived>::type* = 0) { // std::cout << match_helper::HasDirectAccess << "," << match_helper::OuterStrideMatch << "," << match_helper::InnerStrideMatch << "\n"; // std::cout << int(StrideType::OuterStrideAtCompileTime) << " - " << int(Derived::OuterStrideAtCompileTime) << "\n"; // std::cout << int(StrideType::InnerStrideAtCompileTime) << " - " << int(Derived::InnerStrideAtCompileTime) << "\n"; construct(expr.derived(), typename Traits::template match::type()); } + + inline Ref(const Ref& other) : Base(other) { + // copy constructor shall not copy the m_object, to avoid unnecessary malloc and copy + } + + template + inline Ref(const RefBase& other) { + construct(other.derived(), typename Traits::template match::type()); + } protected: diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/Replicate.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/Replicate.h index dde86a834..ac4537c14 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/Replicate.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/Replicate.h @@ -135,7 +135,7 @@ template class Replicate */ template template -inline const Replicate +const Replicate DenseBase::replicate() const { return Replicate(derived()); @@ -150,7 +150,7 @@ DenseBase::replicate() const * \sa VectorwiseOp::replicate(), DenseBase::replicate(), class Replicate */ template -inline const Replicate +const typename DenseBase::ReplicateReturnType DenseBase::replicate(Index rowFactor,Index colFactor) const { return Replicate(derived(),rowFactor,colFactor); diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/ReturnByValue.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/ReturnByValue.h index d66c24ba0..f635598dc 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/ReturnByValue.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/ReturnByValue.h @@ -72,6 +72,8 @@ template class ReturnByValue const Unusable& coeff(Index,Index) const { return *reinterpret_cast(this); } Unusable& coeffRef(Index) { return *reinterpret_cast(this); } Unusable& coeffRef(Index,Index) { return *reinterpret_cast(this); } + template Unusable& packet(Index) const; + template Unusable& packet(Index, Index) const; #endif }; @@ -83,6 +85,15 @@ Derived& DenseBase::operator=(const ReturnByValue& other) return derived(); } +template +template +Derived& DenseBase::lazyAssign(const ReturnByValue& other) +{ + other.evalTo(derived()); + return derived(); +} + + } // end namespace Eigen #endif // EIGEN_RETURNBYVALUE_H diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/SelfCwiseBinaryOp.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/SelfCwiseBinaryOp.h index 22f3047b4..0956475af 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/SelfCwiseBinaryOp.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/SelfCwiseBinaryOp.h @@ -180,15 +180,9 @@ inline Derived& DenseBase::operator*=(const Scalar& other) template inline Derived& DenseBase::operator/=(const Scalar& other) { - typedef typename internal::conditional::IsInteger, - internal::scalar_quotient_op, - internal::scalar_product_op >::type BinOp; typedef typename Derived::PlainObject PlainObject; - SelfCwiseBinaryOp tmp(derived()); - Scalar actual_other; - if(NumTraits::IsInteger) actual_other = other; - else actual_other = Scalar(1)/other; - tmp = PlainObject::Constant(rows(),cols(), actual_other); + SelfCwiseBinaryOp, Derived, typename PlainObject::ConstantReturnType> tmp(derived()); + tmp = PlainObject::Constant(rows(),cols(), other); return derived(); } diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/SolveTriangular.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/SolveTriangular.h index ef17f288e..83565ddd8 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/SolveTriangular.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/SolveTriangular.h @@ -116,17 +116,17 @@ template struct triangular_solver_unroller { enum { IsLower = ((Mode&Lower)==Lower), - I = IsLower ? Index : Size - Index - 1, - S = IsLower ? 0 : I+1 + RowIndex = IsLower ? Index : Size - Index - 1, + S = IsLower ? 0 : RowIndex+1 }; static void run(const Lhs& lhs, Rhs& rhs) { if (Index>0) - rhs.coeffRef(I) -= lhs.row(I).template segment(S).transpose() + rhs.coeffRef(RowIndex) -= lhs.row(RowIndex).template segment(S).transpose() .cwiseProduct(rhs.template segment(S)).sum(); if(!(Mode & UnitDiag)) - rhs.coeffRef(I) /= lhs.coeff(I,I); + rhs.coeffRef(RowIndex) /= lhs.coeff(RowIndex,RowIndex); triangular_solver_unroller::run(lhs,rhs); } diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/StableNorm.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/StableNorm.h index c83e955ee..389d94275 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/StableNorm.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/StableNorm.h @@ -17,16 +17,29 @@ namespace internal { template inline void stable_norm_kernel(const ExpressionType& bl, Scalar& ssq, Scalar& scale, Scalar& invScale) { - Scalar max = bl.cwiseAbs().maxCoeff(); - if (max>scale) + using std::max; + Scalar maxCoeff = bl.cwiseAbs().maxCoeff(); + + if (maxCoeff>scale) { - ssq = ssq * numext::abs2(scale/max); - scale = max; - invScale = Scalar(1)/scale; + ssq = ssq * numext::abs2(scale/maxCoeff); + Scalar tmp = Scalar(1)/maxCoeff; + if(tmp > NumTraits::highest()) + { + invScale = NumTraits::highest(); + scale = Scalar(1)/invScale; + } + else + { + scale = maxCoeff; + invScale = tmp; + } } - // TODO if the max is much much smaller than the current scale, + + // TODO if the maxCoeff is much much smaller than the current scale, // then we can neglect this sub vector - ssq += (bl*invScale).squaredNorm(); + if(scale>Scalar(0)) // if scale==0, then bl is 0 + ssq += (bl*invScale).squaredNorm(); } template diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/Transpose.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/Transpose.h index f21b3aa65..22096ea2f 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/Transpose.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/Transpose.h @@ -284,7 +284,8 @@ struct inplace_transpose_selector { // non square matrix * Notice however that this method is only useful if you want to replace a matrix by its own transpose. * If you just need the transpose of a matrix, use transpose(). * - * \note if the matrix is not square, then \c *this must be a resizable matrix. + * \note if the matrix is not square, then \c *this must be a resizable matrix. + * This excludes (non-square) fixed-size matrices, block-expressions and maps. * * \sa transpose(), adjoint(), adjointInPlace() */ template @@ -315,6 +316,7 @@ inline void DenseBase::transposeInPlace() * If you just need the adjoint of a matrix, use adjoint(). * * \note if the matrix is not square, then \c *this must be a resizable matrix. + * This excludes (non-square) fixed-size matrices, block-expressions and maps. * * \sa transpose(), adjoint(), transposeInPlace() */ template diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/TriangularMatrix.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/TriangularMatrix.h index fba07365f..4d65392c6 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/TriangularMatrix.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/TriangularMatrix.h @@ -278,21 +278,21 @@ template class TriangularView /** Efficient triangular matrix times vector/matrix product */ template - TriangularProduct + TriangularProduct operator*(const MatrixBase& rhs) const { return TriangularProduct - + (m_matrix, rhs.derived()); } /** Efficient vector/matrix times triangular matrix product */ template friend - TriangularProduct + TriangularProduct operator*(const MatrixBase& lhs, const TriangularView& rhs) { return TriangularProduct - + (lhs.derived(),rhs.m_matrix); } @@ -380,19 +380,19 @@ template class TriangularView EIGEN_STRONG_INLINE TriangularView& operator=(const ProductBase& other) { setZero(); - return assignProduct(other,1); + return assignProduct(other.derived(),1); } template EIGEN_STRONG_INLINE TriangularView& operator+=(const ProductBase& other) { - return assignProduct(other,1); + return assignProduct(other.derived(),1); } template EIGEN_STRONG_INLINE TriangularView& operator-=(const ProductBase& other) { - return assignProduct(other,-1); + return assignProduct(other.derived(),-1); } @@ -400,25 +400,34 @@ template class TriangularView EIGEN_STRONG_INLINE TriangularView& operator=(const ScaledProduct& other) { setZero(); - return assignProduct(other,other.alpha()); + return assignProduct(other.derived(),other.alpha()); } template EIGEN_STRONG_INLINE TriangularView& operator+=(const ScaledProduct& other) { - return assignProduct(other,other.alpha()); + return assignProduct(other.derived(),other.alpha()); } template EIGEN_STRONG_INLINE TriangularView& operator-=(const ScaledProduct& other) { - return assignProduct(other,-other.alpha()); + return assignProduct(other.derived(),-other.alpha()); } protected: template EIGEN_STRONG_INLINE TriangularView& assignProduct(const ProductBase& prod, const Scalar& alpha); + + template + EIGEN_STRONG_INLINE TriangularView& assignProduct(const TriangularProduct& prod, const Scalar& alpha) + { + lazyAssign(alpha*prod.eval()); + return *this; + } MatrixTypeNested m_matrix; }; diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/VectorwiseOp.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/VectorwiseOp.h index 511564875..d5ab03664 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/VectorwiseOp.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/VectorwiseOp.h @@ -50,7 +50,7 @@ struct traits > MaxColsAtCompileTime = Direction==Horizontal ? 1 : MatrixType::MaxColsAtCompileTime, Flags0 = (unsigned int)_MatrixTypeNested::Flags & HereditaryBits, Flags = (Flags0 & ~RowMajorBit) | (RowsAtCompileTime == 1 ? RowMajorBit : 0), - TraversalSize = Direction==Vertical ? RowsAtCompileTime : ColsAtCompileTime + TraversalSize = Direction==Vertical ? MatrixType::RowsAtCompileTime : MatrixType::ColsAtCompileTime }; #if EIGEN_GNUC_AT_LEAST(3,4) typedef typename MemberOp::template Cost CostOpType; @@ -58,7 +58,8 @@ struct traits > typedef typename MemberOp::template Cost CostOpType; #endif enum { - CoeffReadCost = TraversalSize * traits<_MatrixTypeNested>::CoeffReadCost + int(CostOpType::value) + CoeffReadCost = TraversalSize==Dynamic ? Dynamic + : TraversalSize * traits<_MatrixTypeNested>::CoeffReadCost + int(CostOpType::value) }; }; } diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/Visitor.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/Visitor.h index 64867b7a2..dd94eb8f0 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/Visitor.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/Visitor.h @@ -76,14 +76,17 @@ template template void DenseBase::visit(Visitor& visitor) const { + typedef typename internal::remove_all::type ThisNested; + typename Derived::Nested thisNested(derived()); + enum { unroll = SizeAtCompileTime != Dynamic && CoeffReadCost != Dynamic && (SizeAtCompileTime == 1 || internal::functor_traits::Cost != Dynamic) && SizeAtCompileTime * CoeffReadCost + (SizeAtCompileTime-1) * internal::functor_traits::Cost <= EIGEN_UNROLLING_LIMIT }; - return internal::visitor_impl::run(derived(), visitor); + >::run(thisNested, visitor); } namespace internal { diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/arch/NEON/Complex.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/arch/NEON/Complex.h index f183d31de..8d9255eef 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/arch/NEON/Complex.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/arch/NEON/Complex.h @@ -110,7 +110,7 @@ template<> EIGEN_STRONG_INLINE Packet2cf ploaddup(const std::complex< template<> EIGEN_STRONG_INLINE void pstore >(std::complex * to, const Packet2cf& from) { EIGEN_DEBUG_ALIGNED_STORE pstore((float*)to, from.v); } template<> EIGEN_STRONG_INLINE void pstoreu >(std::complex * to, const Packet2cf& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((float*)to, from.v); } -template<> EIGEN_STRONG_INLINE void prefetch >(const std::complex * addr) { __pld((float *)addr); } +template<> EIGEN_STRONG_INLINE void prefetch >(const std::complex * addr) { EIGEN_ARM_PREFETCH((float *)addr); } template<> EIGEN_STRONG_INLINE std::complex pfirst(const Packet2cf& a) { diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/arch/NEON/PacketMath.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/arch/NEON/PacketMath.h index 163bac215..d49670e04 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/arch/NEON/PacketMath.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/arch/NEON/PacketMath.h @@ -48,9 +48,18 @@ typedef uint32x4_t Packet4ui; #define EIGEN_INIT_NEON_PACKET2(X, Y) {X, Y} #define EIGEN_INIT_NEON_PACKET4(X, Y, Z, W) {X, Y, Z, W} #endif - -#ifndef __pld -#define __pld(x) asm volatile ( " pld [%[addr]]\n" :: [addr] "r" (x) : "cc" ); + +// arm64 does have the pld instruction. If available, let's trust the __builtin_prefetch built-in function +// which available on LLVM and GCC (at least) +#if EIGEN_HAS_BUILTIN(__builtin_prefetch) || defined(__GNUC__) + #define EIGEN_ARM_PREFETCH(ADDR) __builtin_prefetch(ADDR); +#elif defined __pld + #define EIGEN_ARM_PREFETCH(ADDR) __pld(ADDR) +#elif !defined(__aarch64__) + #define EIGEN_ARM_PREFETCH(ADDR) __asm__ __volatile__ ( " pld [%[addr]]\n" :: [addr] "r" (ADDR) : "cc" ); +#else + // by default no explicit prefetching + #define EIGEN_ARM_PREFETCH(ADDR) #endif template<> struct packet_traits : default_packet_traits @@ -209,8 +218,8 @@ template<> EIGEN_STRONG_INLINE void pstore(int* to, const Packet4i& f template<> EIGEN_STRONG_INLINE void pstoreu(float* to, const Packet4f& from) { EIGEN_DEBUG_UNALIGNED_STORE vst1q_f32(to, from); } template<> EIGEN_STRONG_INLINE void pstoreu(int* to, const Packet4i& from) { EIGEN_DEBUG_UNALIGNED_STORE vst1q_s32(to, from); } -template<> EIGEN_STRONG_INLINE void prefetch(const float* addr) { __pld(addr); } -template<> EIGEN_STRONG_INLINE void prefetch(const int* addr) { __pld(addr); } +template<> EIGEN_STRONG_INLINE void prefetch(const float* addr) { EIGEN_ARM_PREFETCH(addr); } +template<> EIGEN_STRONG_INLINE void prefetch(const int* addr) { EIGEN_ARM_PREFETCH(addr); } // FIXME only store the 2 first elements ? template<> EIGEN_STRONG_INLINE float pfirst(const Packet4f& a) { float EIGEN_ALIGN16 x[4]; vst1q_f32(x, a); return x[0]; } @@ -375,6 +384,7 @@ template<> EIGEN_STRONG_INLINE int predux_max(const Packet4i& a) a_lo = vget_low_s32(a); a_hi = vget_high_s32(a); max = vpmax_s32(a_lo, a_hi); + max = vpmax_s32(max, max); return vget_lane_s32(max, 0); } diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/arch/SSE/MathFunctions.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/arch/SSE/MathFunctions.h index 3376a984e..2b07168ae 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/arch/SSE/MathFunctions.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/arch/SSE/MathFunctions.h @@ -52,7 +52,7 @@ Packet4f plog(const Packet4f& _x) Packet4i emm0; - Packet4f invalid_mask = _mm_cmplt_ps(x, _mm_setzero_ps()); + Packet4f invalid_mask = _mm_cmpnge_ps(x, _mm_setzero_ps()); // not greater equal is true if x is NaN Packet4f iszero_mask = _mm_cmpeq_ps(x, _mm_setzero_ps()); x = pmax(x, p4f_min_norm_pos); /* cut off denormalized stuff */ @@ -126,7 +126,7 @@ Packet4f pexp(const Packet4f& _x) _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p4, 1.6666665459E-1f); _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p5, 5.0000001201E-1f); - Packet4f tmp = _mm_setzero_ps(), fx; + Packet4f tmp, fx; Packet4i emm0; // clamp x @@ -166,7 +166,7 @@ Packet4f pexp(const Packet4f& _x) emm0 = _mm_cvttps_epi32(fx); emm0 = _mm_add_epi32(emm0, p4i_0x7f); emm0 = _mm_slli_epi32(emm0, 23); - return pmul(y, _mm_castsi128_ps(emm0)); + return pmax(pmul(y, Packet4f(_mm_castsi128_ps(emm0))), _x); } template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet2d pexp(const Packet2d& _x) @@ -195,7 +195,7 @@ Packet2d pexp(const Packet2d& _x) _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_C2, 1.42860682030941723212e-6); static const __m128i p4i_1023_0 = _mm_setr_epi32(1023, 1023, 0, 0); - Packet2d tmp = _mm_setzero_pd(), fx; + Packet2d tmp, fx; Packet4i emm0; // clamp x @@ -239,7 +239,7 @@ Packet2d pexp(const Packet2d& _x) emm0 = _mm_add_epi32(emm0, p4i_1023_0); emm0 = _mm_slli_epi32(emm0, 20); emm0 = _mm_shuffle_epi32(emm0, _MM_SHUFFLE(1,2,0,3)); - return pmul(x, _mm_castsi128_pd(emm0)); + return pmax(pmul(x, Packet2d(_mm_castsi128_pd(emm0))), _x); } /* evaluation of 4 sines at onces, using SSE2 intrinsics. @@ -279,7 +279,7 @@ Packet4f psin(const Packet4f& _x) _EIGEN_DECLARE_CONST_Packet4f(coscof_p2, 4.166664568298827E-002f); _EIGEN_DECLARE_CONST_Packet4f(cephes_FOPI, 1.27323954473516f); // 4 / M_PI - Packet4f xmm1, xmm2 = _mm_setzero_ps(), xmm3, sign_bit, y; + Packet4f xmm1, xmm2, xmm3, sign_bit, y; Packet4i emm0, emm2; sign_bit = x; @@ -378,7 +378,7 @@ Packet4f pcos(const Packet4f& _x) _EIGEN_DECLARE_CONST_Packet4f(coscof_p2, 4.166664568298827E-002f); _EIGEN_DECLARE_CONST_Packet4f(cephes_FOPI, 1.27323954473516f); // 4 / M_PI - Packet4f xmm1, xmm2 = _mm_setzero_ps(), xmm3, y; + Packet4f xmm1, xmm2, xmm3, y; Packet4i emm0, emm2; x = pabs(x); @@ -442,8 +442,11 @@ Packet4f pcos(const Packet4f& _x) return _mm_xor_ps(y, sign_bit); } +#if EIGEN_FAST_MATH + // This is based on Quake3's fast inverse square root. // For detail see here: http://www.beyond3d.com/content/articles/8/ +// It lacks 1 (or 2 bits in some rare cases) of precision, and does not handle negative, +inf, or denormalized numbers correctly. template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet4f psqrt(const Packet4f& _x) { @@ -457,6 +460,14 @@ Packet4f psqrt(const Packet4f& _x) return pmul(_x,x); } +#else + +template<> EIGEN_STRONG_INLINE Packet4f psqrt(const Packet4f& x) { return _mm_sqrt_ps(x); } + +#endif + +template<> EIGEN_STRONG_INLINE Packet2d psqrt(const Packet2d& x) { return _mm_sqrt_pd(x); } + } // end namespace internal } // end namespace Eigen diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/arch/SSE/PacketMath.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/arch/SSE/PacketMath.h index e256f4bac..bef898b1f 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/arch/SSE/PacketMath.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/arch/SSE/PacketMath.h @@ -83,7 +83,8 @@ template<> struct packet_traits : default_packet_traits size=2, HasDiv = 1, - HasExp = 1 + HasExp = 1, + HasSqrt = 1 }; }; template<> struct packet_traits : default_packet_traits @@ -234,63 +235,27 @@ template<> EIGEN_STRONG_INLINE Packet4i pload(const int* from) { E return _mm_loadu_ps(from); #endif } - template<> EIGEN_STRONG_INLINE Packet2d ploadu(const double* from) { EIGEN_DEBUG_UNALIGNED_LOAD return _mm_loadu_pd(from); } - template<> EIGEN_STRONG_INLINE Packet4i ploadu(const int* from) { EIGEN_DEBUG_UNALIGNED_LOAD return _mm_loadu_si128(reinterpret_cast(from)); } #else -// Fast unaligned loads. Note that here we cannot directly use intrinsics: this would -// require pointer casting to incompatible pointer types and leads to invalid code -// because of the strict aliasing rule. The "dummy" stuff are required to enforce -// a correct instruction dependency. -// TODO: do the same for MSVC (ICC is compatible) // NOTE: with the code below, MSVC's compiler crashes! -#if defined(__GNUC__) && defined(__i386__) - // bug 195: gcc/i386 emits weird x87 fldl/fstpl instructions for _mm_load_sd - #define EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS 1 -#elif defined(__clang__) - // bug 201: Segfaults in __mm_loadh_pd with clang 2.8 - #define EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS 1 -#else - #define EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS 0 -#endif - template<> EIGEN_STRONG_INLINE Packet4f ploadu(const float* from) { EIGEN_DEBUG_UNALIGNED_LOAD -#if EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS return _mm_loadu_ps(from); -#else - __m128d res; - res = _mm_load_sd((const double*)(from)) ; - res = _mm_loadh_pd(res, (const double*)(from+2)) ; - return _mm_castpd_ps(res); -#endif } +#endif + template<> EIGEN_STRONG_INLINE Packet2d ploadu(const double* from) { EIGEN_DEBUG_UNALIGNED_LOAD -#if EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS return _mm_loadu_pd(from); -#else - __m128d res; - res = _mm_load_sd(from) ; - res = _mm_loadh_pd(res,from+1); - return res; -#endif } template<> EIGEN_STRONG_INLINE Packet4i ploadu(const int* from) { EIGEN_DEBUG_UNALIGNED_LOAD -#if EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS - return _mm_loadu_si128(reinterpret_cast(from)); -#else - __m128d res; - res = _mm_load_sd((const double*)(from)) ; - res = _mm_loadh_pd(res, (const double*)(from+2)) ; - return _mm_castpd_si128(res); -#endif + return _mm_loadu_si128(reinterpret_cast(from)); } -#endif + template<> EIGEN_STRONG_INLINE Packet4f ploaddup(const float* from) { @@ -507,8 +472,8 @@ template<> EIGEN_STRONG_INLINE int predux_min(const Packet4i& a) // for GCC (eg., it does not like using std::min after the pstore !!) EIGEN_ALIGN16 int aux[4]; pstore(aux, a); - register int aux0 = aux[0] EIGEN_STRONG_INLINE int predux_max(const Packet4i& a) // for GCC (eg., it does not like using std::min after the pstore !!) EIGEN_ALIGN16 int aux[4]; pstore(aux, a); - register int aux0 = aux[0]>aux[1] ? aux[0] : aux[1]; - register int aux2 = aux[2]>aux[3] ? aux[2] : aux[3]; + int aux0 = aux[0]>aux[1] ? aux[0] : aux[1]; + int aux2 = aux[2]>aux[3] ? aux[2] : aux[3]; return aux0>aux2 ? aux0 : aux2; } diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/products/CoeffBasedProduct.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/products/CoeffBasedProduct.h index c06a0df1c..2a9d65b94 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/products/CoeffBasedProduct.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/products/CoeffBasedProduct.h @@ -90,6 +90,7 @@ struct traits > | (SameType && (CanVectorizeLhs || CanVectorizeRhs) ? PacketAccessBit : 0), CoeffReadCost = InnerSize == Dynamic ? Dynamic + : InnerSize == 0 ? 0 : InnerSize * (NumTraits::MulCost + LhsCoeffReadCost + RhsCoeffReadCost) + (InnerSize - 1) * NumTraits::AddCost, @@ -133,7 +134,7 @@ class CoeffBasedProduct }; typedef internal::product_coeff_impl ScalarCoeffImpl; typedef CoeffBasedProduct LazyCoeffBasedProductType; @@ -184,7 +185,7 @@ class CoeffBasedProduct { PacketScalar res; internal::product_packet_impl ::run(row, col, m_lhs, m_rhs, res); return res; @@ -242,12 +243,12 @@ struct product_coeff_impl static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar &res) { product_coeff_impl::run(row, col, lhs, rhs, res); - res += lhs.coeff(row, UnrollingIndex) * rhs.coeff(UnrollingIndex, col); + res += lhs.coeff(row, UnrollingIndex-1) * rhs.coeff(UnrollingIndex-1, col); } }; template -struct product_coeff_impl +struct product_coeff_impl { typedef typename Lhs::Index Index; static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar &res) @@ -256,16 +257,23 @@ struct product_coeff_impl } }; +template +struct product_coeff_impl +{ + typedef typename Lhs::Index Index; + static EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/, const Rhs& /*rhs*/, RetScalar &res) + { + res = RetScalar(0); + } +}; + template struct product_coeff_impl { typedef typename Lhs::Index Index; static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar& res) { - eigen_assert(lhs.cols()>0 && "you are using a non initialized matrix"); - res = lhs.coeff(row, 0) * rhs.coeff(0, col); - for(Index i = 1; i < lhs.cols(); ++i) - res += lhs.coeff(row, i) * rhs.coeff(i, col); + res = (lhs.row(row).transpose().cwiseProduct( rhs.col(col) )).sum(); } }; @@ -295,6 +303,16 @@ struct product_coeff_vectorized_unroller<0, Lhs, Rhs, Packet> } }; +template +struct product_coeff_impl +{ + typedef typename Lhs::Index Index; + static EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/, const Rhs& /*rhs*/, RetScalar &res) + { + res = 0; + } +}; + template struct product_coeff_impl { @@ -304,8 +322,7 @@ struct product_coeff_impl::run(row, col, lhs, rhs, pres); - product_coeff_impl::run(row, col, lhs, rhs, res); + product_coeff_vectorized_unroller::run(row, col, lhs, rhs, pres); res = predux(pres); } }; @@ -373,7 +390,7 @@ struct product_packet_impl static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) { product_packet_impl::run(row, col, lhs, rhs, res); - res = pmadd(pset1(lhs.coeff(row, UnrollingIndex)), rhs.template packet(UnrollingIndex, col), res); + res = pmadd(pset1(lhs.coeff(row, UnrollingIndex-1)), rhs.template packet(UnrollingIndex-1, col), res); } }; @@ -384,12 +401,12 @@ struct product_packet_impl static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) { product_packet_impl::run(row, col, lhs, rhs, res); - res = pmadd(lhs.template packet(row, UnrollingIndex), pset1(rhs.coeff(UnrollingIndex, col)), res); + res = pmadd(lhs.template packet(row, UnrollingIndex-1), pset1(rhs.coeff(UnrollingIndex-1, col)), res); } }; template -struct product_packet_impl +struct product_packet_impl { typedef typename Lhs::Index Index; static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) @@ -399,7 +416,7 @@ struct product_packet_impl }; template -struct product_packet_impl +struct product_packet_impl { typedef typename Lhs::Index Index; static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) @@ -408,16 +425,35 @@ struct product_packet_impl } }; +template +struct product_packet_impl +{ + typedef typename Lhs::Index Index; + static EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/, const Rhs& /*rhs*/, Packet &res) + { + res = pset1(0); + } +}; + +template +struct product_packet_impl +{ + typedef typename Lhs::Index Index; + static EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/, const Rhs& /*rhs*/, Packet &res) + { + res = pset1(0); + } +}; + template struct product_packet_impl { typedef typename Lhs::Index Index; static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet& res) { - eigen_assert(lhs.cols()>0 && "you are using a non initialized matrix"); - res = pmul(pset1(lhs.coeff(row, 0)),rhs.template packet(0, col)); - for(Index i = 1; i < lhs.cols(); ++i) - res = pmadd(pset1(lhs.coeff(row, i)), rhs.template packet(i, col), res); + res = pset1(0); + for(Index i = 0; i < lhs.cols(); ++i) + res = pmadd(pset1(lhs.coeff(row, i)), rhs.template packet(i, col), res); } }; @@ -427,10 +463,9 @@ struct product_packet_impl typedef typename Lhs::Index Index; static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet& res) { - eigen_assert(lhs.cols()>0 && "you are using a non initialized matrix"); - res = pmul(lhs.template packet(row, 0), pset1(rhs.coeff(0, col))); - for(Index i = 1; i < lhs.cols(); ++i) - res = pmadd(lhs.template packet(row, i), pset1(rhs.coeff(i, col)), res); + res = pset1(0); + for(Index i = 0; i < lhs.cols(); ++i) + res = pmadd(lhs.template packet(row, i), pset1(rhs.coeff(i, col)), res); } }; diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/products/GeneralBlockPanelKernel.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/products/GeneralBlockPanelKernel.h index 780fa74d3..bcdca5b0d 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/products/GeneralBlockPanelKernel.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/products/GeneralBlockPanelKernel.h @@ -1128,6 +1128,8 @@ EIGEN_DONT_INLINE void gemm_pack_lhs::size }; EIGEN_ASM_COMMENT("EIGEN PRODUCT PACK LHS"); + EIGEN_UNUSED_VARIABLE(stride) + EIGEN_UNUSED_VARIABLE(offset) eigen_assert(((!PanelMode) && stride==0 && offset==0) || (PanelMode && stride>=depth && offset<=stride)); eigen_assert( (StorageOrder==RowMajor) || ((Pack1%PacketSize)==0 && Pack1<=4*PacketSize) ); conj_if::IsComplex && Conjugate> cj; @@ -1215,6 +1217,8 @@ EIGEN_DONT_INLINE void gemm_pack_rhs=depth && offset<=stride)); conj_if::IsComplex && Conjugate> cj; Index packet_cols = (cols/nr) * nr; @@ -1266,6 +1270,8 @@ EIGEN_DONT_INLINE void gemm_pack_rhs=depth && offset<=stride)); conj_if::IsComplex && Conjugate> cj; Index packet_cols = (cols/nr) * nr; diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/products/GeneralMatrixMatrix.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/products/GeneralMatrixMatrix.h index 3f5ffcf51..cfd2f0095 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/products/GeneralMatrixMatrix.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/products/GeneralMatrixMatrix.h @@ -140,8 +140,10 @@ static void run(Index rows, Index cols, Index depth, // Release all the sub blocks B'_j of B' for the current thread, // i.e., we simply decrement the number of users by 1 for(Index j=0; j GeneralProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) { +#if !(defined(EIGEN_NO_STATIC_ASSERT) && defined(EIGEN_NO_DEBUG)) typedef internal::scalar_product_op BinOp; EIGEN_CHECK_BINARY_COMPATIBILIY(BinOp,LhsScalar,RhsScalar); +#endif } template void scaleAndAddTo(Dest& dst, const Scalar& alpha) const { eigen_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols()); + if(m_lhs.cols()==0 || m_lhs.rows()==0 || m_rhs.cols()==0) + return; typename internal::add_const_on_value_type::type lhs = LhsBlasTraits::extract(m_lhs); typename internal::add_const_on_value_type::type rhs = RhsBlasTraits::extract(m_rhs); diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/products/GeneralMatrixVector.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/products/GeneralMatrixVector.h index c1cb78498..09387703e 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/products/GeneralMatrixVector.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/products/GeneralMatrixVector.h @@ -52,11 +52,7 @@ EIGEN_DONT_INLINE static void run( Index rows, Index cols, const LhsScalar* lhs, Index lhsStride, const RhsScalar* rhs, Index rhsIncr, - ResScalar* res, Index - #ifdef EIGEN_INTERNAL_DEBUGGING - resIncr - #endif - , RhsScalar alpha); + ResScalar* res, Index resIncr, RhsScalar alpha); }; template @@ -64,12 +60,9 @@ EIGEN_DONT_INLINE void general_matrix_vector_product(&lhs0[i]), ptmp0, pload(&res[i]))); + pstore(&res[i], pcj.pmadd(pload(&lhs0[i]), ptmp0, pload(&res[i]))); else for (Index i = alignedStart;i(&lhs0[i]), ptmp0, pload(&res[i]))); diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/products/Parallelizer.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/products/Parallelizer.h index 5c3e9b7ac..6937ee332 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/products/Parallelizer.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/products/Parallelizer.h @@ -125,19 +125,22 @@ void parallelize_gemm(const Functor& func, Index rows, Index cols, bool transpos if(transpose) std::swap(rows,cols); - Index blockCols = (cols / threads) & ~Index(0x3); - Index blockRows = (rows / threads) & ~Index(0x7); - GemmParallelInfo* info = new GemmParallelInfo[threads]; - #pragma omp parallel for schedule(static,1) num_threads(threads) - for(Index i=0; i(t0); @@ -147,7 +147,7 @@ EIGEN_DONT_INLINE void selfadjoint_matrix_vector_product class Rotation2D; template class AngleAxis; template class Translation; +// Sparse module: +template class SparseMatrixBase; + #ifdef EIGEN2_SUPPORT template class eigen2_RotationBase; template class eigen2_Cross; diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/util/MKL_support.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/util/MKL_support.h index 1e6e355d6..1ef3b61db 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/util/MKL_support.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/util/MKL_support.h @@ -54,11 +54,60 @@ #endif #if defined EIGEN_USE_MKL +# include +/*Check IMKL version for compatibility: < 10.3 is not usable with Eigen*/ +# ifndef INTEL_MKL_VERSION +# undef EIGEN_USE_MKL /* INTEL_MKL_VERSION is not even defined on older versions */ +# elif INTEL_MKL_VERSION < 100305 /* the intel-mkl-103-release-notes say this was when the lapacke.h interface was added*/ +# undef EIGEN_USE_MKL +# endif +# ifndef EIGEN_USE_MKL + /*If the MKL version is too old, undef everything*/ +# undef EIGEN_USE_MKL_ALL +# undef EIGEN_USE_BLAS +# undef EIGEN_USE_LAPACKE +# undef EIGEN_USE_MKL_VML +# undef EIGEN_USE_LAPACKE_STRICT +# undef EIGEN_USE_LAPACKE +# endif +#endif -#include +#if defined EIGEN_USE_MKL #include #define EIGEN_MKL_VML_THRESHOLD 128 +/* MKL_DOMAIN_BLAS, etc are defined only in 10.3 update 7 */ +/* MKL_BLAS, etc are not defined in 11.2 */ +#ifdef MKL_DOMAIN_ALL +#define EIGEN_MKL_DOMAIN_ALL MKL_DOMAIN_ALL +#else +#define EIGEN_MKL_DOMAIN_ALL MKL_ALL +#endif + +#ifdef MKL_DOMAIN_BLAS +#define EIGEN_MKL_DOMAIN_BLAS MKL_DOMAIN_BLAS +#else +#define EIGEN_MKL_DOMAIN_BLAS MKL_BLAS +#endif + +#ifdef MKL_DOMAIN_FFT +#define EIGEN_MKL_DOMAIN_FFT MKL_DOMAIN_FFT +#else +#define EIGEN_MKL_DOMAIN_FFT MKL_FFT +#endif + +#ifdef MKL_DOMAIN_VML +#define EIGEN_MKL_DOMAIN_VML MKL_DOMAIN_VML +#else +#define EIGEN_MKL_DOMAIN_VML MKL_VML +#endif + +#ifdef MKL_DOMAIN_PARDISO +#define EIGEN_MKL_DOMAIN_PARDISO MKL_DOMAIN_PARDISO +#else +#define EIGEN_MKL_DOMAIN_PARDISO MKL_PARDISO +#endif + namespace Eigen { typedef std::complex dcomplex; diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/util/Macros.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/util/Macros.h index a50f1f8c8..e0d90eb82 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/util/Macros.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/util/Macros.h @@ -13,23 +13,292 @@ #define EIGEN_WORLD_VERSION 3 #define EIGEN_MAJOR_VERSION 2 -#define EIGEN_MINOR_VERSION 0 +#define EIGEN_MINOR_VERSION 8 #define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \ (EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \ EIGEN_MINOR_VERSION>=z)))) + + +// Compiler identification, EIGEN_COMP_* + +/// \internal EIGEN_COMP_GNUC set to 1 for all compilers compatible with GCC #ifdef __GNUC__ + #define EIGEN_COMP_GNUC 1 +#else + #define EIGEN_COMP_GNUC 0 +#endif + +/// \internal EIGEN_COMP_CLANG set to 1 if the compiler is clang (alias for __clang__) +#if defined(__clang__) + #define EIGEN_COMP_CLANG 1 +#else + #define EIGEN_COMP_CLANG 0 +#endif + + +/// \internal EIGEN_COMP_LLVM set to 1 if the compiler backend is llvm +#if defined(__llvm__) + #define EIGEN_COMP_LLVM 1 +#else + #define EIGEN_COMP_LLVM 0 +#endif + +/// \internal EIGEN_COMP_ICC set to __INTEL_COMPILER if the compiler is Intel compiler, 0 otherwise +#if defined(__INTEL_COMPILER) + #define EIGEN_COMP_ICC __INTEL_COMPILER +#else + #define EIGEN_COMP_ICC 0 +#endif + +/// \internal EIGEN_COMP_MINGW set to 1 if the compiler is mingw +#if defined(__MINGW32__) + #define EIGEN_COMP_MINGW 1 +#else + #define EIGEN_COMP_MINGW 0 +#endif + +/// \internal EIGEN_COMP_SUNCC set to 1 if the compiler is Solaris Studio +#if defined(__SUNPRO_CC) + #define EIGEN_COMP_SUNCC 1 +#else + #define EIGEN_COMP_SUNCC 0 +#endif + +/// \internal EIGEN_COMP_MSVC set to _MSC_VER if the compiler is Microsoft Visual C++, 0 otherwise. +#if defined(_MSC_VER) + #define EIGEN_COMP_MSVC _MSC_VER +#else + #define EIGEN_COMP_MSVC 0 +#endif + +/// \internal EIGEN_COMP_MSVC_STRICT set to 1 if the compiler is really Microsoft Visual C++ and not ,e.g., ICC +#if EIGEN_COMP_MSVC && !(EIGEN_COMP_ICC) + #define EIGEN_COMP_MSVC_STRICT _MSC_VER +#else + #define EIGEN_COMP_MSVC_STRICT 0 +#endif + +/// \internal EIGEN_COMP_IBM set to 1 if the compiler is IBM XL C++ +#if defined(__IBMCPP__) || defined(__xlc__) + #define EIGEN_COMP_IBM 1 +#else + #define EIGEN_COMP_IBM 0 +#endif + +/// \internal EIGEN_COMP_PGI set to 1 if the compiler is Portland Group Compiler +#if defined(__PGI) + #define EIGEN_COMP_PGI 1 +#else + #define EIGEN_COMP_PGI 0 +#endif + +/// \internal EIGEN_COMP_ARM set to 1 if the compiler is ARM Compiler +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) + #define EIGEN_COMP_ARM 1 +#else + #define EIGEN_COMP_ARM 0 +#endif + + +/// \internal EIGEN_GNUC_STRICT set to 1 if the compiler is really GCC and not a compatible compiler (e.g., ICC, clang, mingw, etc.) +#if EIGEN_COMP_GNUC && !(EIGEN_COMP_CLANG || EIGEN_COMP_ICC || EIGEN_COMP_MINGW || EIGEN_COMP_PGI || EIGEN_COMP_IBM || EIGEN_COMP_ARM ) + #define EIGEN_COMP_GNUC_STRICT 1 +#else + #define EIGEN_COMP_GNUC_STRICT 0 +#endif + + +#if EIGEN_COMP_GNUC #define EIGEN_GNUC_AT_LEAST(x,y) ((__GNUC__==x && __GNUC_MINOR__>=y) || __GNUC__>x) + #define EIGEN_GNUC_AT_MOST(x,y) ((__GNUC__==x && __GNUC_MINOR__<=y) || __GNUC__= 201103L) || \ + (defined(_MSC_VER) && _MSC_VER >= 1600)) + #define EIGEN_HAVE_RVALUE_REFERENCES +#endif + + +// Cross compiler wrapper around LLVM's __has_builtin +#ifdef __has_builtin +# define EIGEN_HAS_BUILTIN(x) __has_builtin(x) +#else +# define EIGEN_HAS_BUILTIN(x) 0 +#endif + /** Allows to disable some optimizations which might affect the accuracy of the result. * Such optimization are enabled by default, and set EIGEN_FAST_MATH to 0 to disable them. * They currently include: @@ -238,11 +522,16 @@ #endif // Suppresses 'unused variable' warnings. -#define EIGEN_UNUSED_VARIABLE(var) (void)var; +namespace Eigen { + namespace internal { + template void ignore_unused_variable(const T&) {} + } +} +#define EIGEN_UNUSED_VARIABLE(var) Eigen::internal::ignore_unused_variable(var); #if !defined(EIGEN_ASM_COMMENT) #if (defined __GNUC__) && ( defined(__i386__) || defined(__x86_64__) ) - #define EIGEN_ASM_COMMENT(X) asm("#" X) + #define EIGEN_ASM_COMMENT(X) __asm__("#" X) #else #define EIGEN_ASM_COMMENT(X) #endif @@ -266,6 +555,7 @@ #error Please tell me what is the equivalent of __attribute__((aligned(n))) for your compiler #endif +#define EIGEN_ALIGN8 EIGEN_ALIGN_TO_BOUNDARY(8) #define EIGEN_ALIGN16 EIGEN_ALIGN_TO_BOUNDARY(16) #if EIGEN_ALIGN_STATICALLY @@ -284,7 +574,8 @@ #endif #ifndef EIGEN_STACK_ALLOCATION_LIMIT -#define EIGEN_STACK_ALLOCATION_LIMIT 20000 +// 131072 == 128 KB +#define EIGEN_STACK_ALLOCATION_LIMIT 131072 #endif #ifndef EIGEN_DEFAULT_IO_FORMAT @@ -300,7 +591,7 @@ // just an empty macro ! #define EIGEN_EMPTY -#if defined(_MSC_VER) && (!defined(__INTEL_COMPILER)) +#if defined(_MSC_VER) && (_MSC_VER < 1900) && (!defined(__INTEL_COMPILER)) #define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \ using Base::operator =; #elif defined(__clang__) // workaround clang bug (see http://forum.kde.org/viewtopic.php?f=74&t=102653) @@ -319,8 +610,11 @@ } #endif -#define EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Derived) \ - EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) +/** \internal + * \brief Macro to manually inherit assignment operators. + * This is necessary, because the implicitly defined assignment operator gets deleted when a custom operator= is defined. + */ +#define EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Derived) EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) /** * Just a side note. Commenting within defines works only by documenting @@ -392,6 +686,8 @@ #define EIGEN_SIZE_MAX(a,b) (((int)a == Dynamic || (int)b == Dynamic) ? Dynamic \ : ((int)a >= (int)b) ? (int)a : (int)b) +#define EIGEN_ADD_COST(a,b) int(a)==Dynamic || int(b)==Dynamic ? Dynamic : int(a)+int(b) + #define EIGEN_LOGICAL_XOR(a,b) (((a) || (b)) && !((a) && (b))) #define EIGEN_IMPLIES(a,b) (!(a) || (b)) diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/util/Memory.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/util/Memory.h index 451535a0c..bc1ea69ed 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/util/Memory.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/util/Memory.h @@ -63,7 +63,7 @@ // Currently, let's include it only on unix systems: #if defined(__unix__) || defined(__unix) #include - #if ((defined __QNXNTO__) || (defined _GNU_SOURCE) || ((defined _XOPEN_SOURCE) && (_XOPEN_SOURCE >= 600))) && (defined _POSIX_ADVISORY_INFO) && (_POSIX_ADVISORY_INFO > 0) + #if ((defined __QNXNTO__) || (defined _GNU_SOURCE) || (defined __PGI) || ((defined _XOPEN_SOURCE) && (_XOPEN_SOURCE >= 600))) && (defined _POSIX_ADVISORY_INFO) && (_POSIX_ADVISORY_INFO > 0) #define EIGEN_HAS_POSIX_MEMALIGN 1 #endif #endif @@ -272,12 +272,12 @@ inline void* aligned_realloc(void *ptr, size_t new_size, size_t old_size) // The defined(_mm_free) is just here to verify that this MSVC version // implements _mm_malloc/_mm_free based on the corresponding _aligned_ // functions. This may not always be the case and we just try to be safe. - #if defined(_MSC_VER) && defined(_mm_free) + #if defined(_MSC_VER) && (!defined(_WIN32_WCE)) && defined(_mm_free) result = _aligned_realloc(ptr,new_size,16); #else result = generic_aligned_realloc(ptr,new_size,old_size); #endif -#elif defined(_MSC_VER) +#elif defined(_MSC_VER) && (!defined(_WIN32_WCE)) result = _aligned_realloc(ptr,new_size,16); #else result = handmade_aligned_realloc(ptr,new_size,old_size); @@ -417,6 +417,8 @@ template inline T* conditional_aligned_realloc_new(T* pt template inline T* conditional_aligned_new_auto(size_t size) { + if(size==0) + return 0; // short-cut. Also fixes Bug 884 check_size_for_overflow(size); T *result = reinterpret_cast(conditional_aligned_malloc(sizeof(T)*size)); if(NumTraits::RequireInitialization) @@ -464,9 +466,8 @@ template inline void conditional_aligned_delete_auto(T * template static inline Index first_aligned(const Scalar* array, Index size) { - enum { PacketSize = packet_traits::size, - PacketAlignedMask = PacketSize-1 - }; + static const Index PacketSize = packet_traits::size; + static const Index PacketAlignedMask = PacketSize-1; if(PacketSize==1) { @@ -522,7 +523,7 @@ template struct smart_copy_helper { // you can overwrite Eigen's default behavior regarding alloca by defining EIGEN_ALLOCA // to the appropriate stack allocation function #ifndef EIGEN_ALLOCA - #if (defined __linux__) + #if (defined __linux__) || (defined __APPLE__) || (defined alloca) #define EIGEN_ALLOCA alloca #elif defined(_MSC_VER) #define EIGEN_ALLOCA _alloca @@ -578,7 +579,7 @@ template class aligned_stack_memory_handler */ #ifdef EIGEN_ALLOCA - #ifdef __arm__ + #if defined(__arm__) || defined(_WIN32) #define EIGEN_ALIGNED_ALLOCA(SIZE) reinterpret_cast((reinterpret_cast(EIGEN_ALLOCA(SIZE+16)) & ~(size_t(15))) + 16) #else #define EIGEN_ALIGNED_ALLOCA EIGEN_ALLOCA @@ -612,7 +613,6 @@ template class aligned_stack_memory_handler void* operator new(size_t size, const std::nothrow_t&) throw() { \ try { return Eigen::internal::conditional_aligned_malloc(size); } \ catch (...) { return 0; } \ - return 0; \ } #else #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \ @@ -630,11 +630,15 @@ template class aligned_stack_memory_handler } \ void operator delete(void * ptr) throw() { Eigen::internal::conditional_aligned_free(ptr); } \ void operator delete[](void * ptr) throw() { Eigen::internal::conditional_aligned_free(ptr); } \ + void operator delete(void * ptr, std::size_t /* sz */) throw() { Eigen::internal::conditional_aligned_free(ptr); } \ + void operator delete[](void * ptr, std::size_t /* sz */) throw() { Eigen::internal::conditional_aligned_free(ptr); } \ /* in-place new and delete. since (at least afaik) there is no actual */ \ /* memory allocated we can safely let the default implementation handle */ \ /* this particular case. */ \ static void *operator new(size_t size, void *ptr) { return ::operator new(size,ptr); } \ + static void *operator new[](size_t size, void* ptr) { return ::operator new[](size,ptr); } \ void operator delete(void * memory, void *ptr) throw() { return ::operator delete(memory,ptr); } \ + void operator delete[](void * memory, void *ptr) throw() { return ::operator delete[](memory,ptr); } \ /* nothrow-new (returns zero instead of std::bad_alloc) */ \ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \ void operator delete(void *ptr, const std::nothrow_t&) throw() { \ @@ -729,15 +733,6 @@ public: ::new( p ) T( value ); } - // Support for c++11 -#if (__cplusplus >= 201103L) - template - void construct(pointer p, Args&&... args) - { - ::new(p) T(std::forward(args)...); - } -#endif - void destroy( pointer p ) { p->~T(); @@ -784,9 +779,9 @@ namespace internal { #ifdef EIGEN_CPUID -inline bool cpuid_is_vendor(int abcd[4], const char* vendor) +inline bool cpuid_is_vendor(int abcd[4], const int vendor[3]) { - return abcd[1]==(reinterpret_cast(vendor))[0] && abcd[3]==(reinterpret_cast(vendor))[1] && abcd[2]==(reinterpret_cast(vendor))[2]; + return abcd[1]==vendor[0] && abcd[3]==vendor[1] && abcd[2]==vendor[2]; } inline void queryCacheSizes_intel_direct(int& l1, int& l2, int& l3) @@ -928,13 +923,16 @@ inline void queryCacheSizes(int& l1, int& l2, int& l3) { #ifdef EIGEN_CPUID int abcd[4]; + const int GenuineIntel[] = {0x756e6547, 0x49656e69, 0x6c65746e}; + const int AuthenticAMD[] = {0x68747541, 0x69746e65, 0x444d4163}; + const int AMDisbetter_[] = {0x69444d41, 0x74656273, 0x21726574}; // "AMDisbetter!" // identify the CPU vendor EIGEN_CPUID(abcd,0x0,0); int max_std_funcs = abcd[1]; - if(cpuid_is_vendor(abcd,"GenuineIntel")) + if(cpuid_is_vendor(abcd,GenuineIntel)) queryCacheSizes_intel(l1,l2,l3,max_std_funcs); - else if(cpuid_is_vendor(abcd,"AuthenticAMD") || cpuid_is_vendor(abcd,"AMDisbetter!")) + else if(cpuid_is_vendor(abcd,AuthenticAMD) || cpuid_is_vendor(abcd,AMDisbetter_)) queryCacheSizes_amd(l1,l2,l3); else // by default let's use Intel's API diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/util/StaticAssert.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/util/StaticAssert.h index 8872c5b64..e53d2b878 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/util/StaticAssert.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/util/StaticAssert.h @@ -26,7 +26,7 @@ #ifndef EIGEN_NO_STATIC_ASSERT - #if defined(__GXX_EXPERIMENTAL_CXX0X__) || (defined(_MSC_VER) && (_MSC_VER >= 1600)) + #if __has_feature(cxx_static_assert) || (defined(__cplusplus) && __cplusplus >= 201103L) || (EIGEN_COMP_MSVC >= 1600) // if native static_assert is enabled, let's use it #define EIGEN_STATIC_ASSERT(X,MSG) static_assert(X,#MSG); @@ -90,7 +90,9 @@ YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED, THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE, THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH, - OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG + OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG, + IMPLICIT_CONVERSION_TO_SCALAR_IS_FOR_INNER_PRODUCT_ONLY, + STORAGE_LAYOUT_DOES_NOT_MATCH }; }; diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Core/util/XprHelper.h b/ground/gcs/src/libs/eigen/Eigen/src/Core/util/XprHelper.h index 3c4773054..d05f8e5f6 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Core/util/XprHelper.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Core/util/XprHelper.h @@ -341,7 +341,7 @@ template::type> str }; template -T* const_cast_ptr(const T* ptr) +inline T* const_cast_ptr(const T* ptr) { return const_cast(ptr); } @@ -366,17 +366,17 @@ struct dense_xpr_base /** \internal Helper base class to add a scalar multiple operator * overloads for complex types */ -template::value > -struct special_scalar_op_base : public DenseCoeffsBase +struct special_scalar_op_base : public BaseType { // dummy operator* so that the // "using special_scalar_op_base::operator*" compiles void operator*() const; }; -template -struct special_scalar_op_base : public DenseCoeffsBase +template +struct special_scalar_op_base : public BaseType { const CwiseUnaryOp, Derived> operator*(const OtherScalar& scalar) const diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Eigen2Support/LeastSquares.h b/ground/gcs/src/libs/eigen/Eigen/src/Eigen2Support/LeastSquares.h index 0e6fdb488..7992d4944 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Eigen2Support/LeastSquares.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Eigen2Support/LeastSquares.h @@ -147,7 +147,6 @@ void fitHyperplane(int numPoints, // compute the covariance matrix CovMatrixType covMat = CovMatrixType::Zero(size, size); - VectorType remean = VectorType::Zero(size); for(int i = 0; i < numPoints; ++i) { VectorType diff = (*(points[i]) - mean).conjugate(); diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Eigen2Support/SVD.h b/ground/gcs/src/libs/eigen/Eigen/src/Eigen2Support/SVD.h index 077d26d54..3d03d2288 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Eigen2Support/SVD.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Eigen2Support/SVD.h @@ -512,8 +512,7 @@ template template bool SVD::solve(const MatrixBase &b, ResultType* result) const { - const int rows = m_matU.rows(); - ei_assert(b.rows() == rows); + ei_assert(b.rows() == m_matU.rows()); Scalar maxVal = m_sigma.cwise().abs().maxCoeff(); for (int j=0; j class ComplexEigenSolver } protected: + + static void check_template_parameters() + { + EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); + } + EigenvectorType m_eivec; EigenvalueType m_eivalues; ComplexSchur m_schur; @@ -251,6 +257,8 @@ template ComplexEigenSolver& ComplexEigenSolver::compute(const MatrixType& matrix, bool computeEigenvectors) { + check_template_parameters(); + // this code is inspired from Jampack eigen_assert(matrix.cols() == matrix.rows()); diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Eigenvalues/ComplexSchur_MKL.h b/ground/gcs/src/libs/eigen/Eigen/src/Eigenvalues/ComplexSchur_MKL.h index 91496ae5b..27aed923c 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Eigenvalues/ComplexSchur_MKL.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Eigenvalues/ComplexSchur_MKL.h @@ -45,7 +45,6 @@ ComplexSchur >& \ ComplexSchur >::compute(const Matrix& matrix, bool computeU) \ { \ typedef Matrix MatrixType; \ - typedef MatrixType::Scalar Scalar; \ typedef MatrixType::RealScalar RealScalar; \ typedef std::complex ComplexScalar; \ \ diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Eigenvalues/EigenSolver.h b/ground/gcs/src/libs/eigen/Eigen/src/Eigenvalues/EigenSolver.h index 6e7150685..20c59a7a2 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Eigenvalues/EigenSolver.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Eigenvalues/EigenSolver.h @@ -298,6 +298,13 @@ template class EigenSolver void doComputeEigenvectors(); protected: + + static void check_template_parameters() + { + EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); + EIGEN_STATIC_ASSERT(!NumTraits::IsComplex, NUMERIC_TYPE_MUST_BE_REAL); + } + MatrixType m_eivec; EigenvalueType m_eivalues; bool m_isInitialized; @@ -364,6 +371,8 @@ template EigenSolver& EigenSolver::compute(const MatrixType& matrix, bool computeEigenvectors) { + check_template_parameters(); + using std::sqrt; using std::abs; eigen_assert(matrix.cols() == matrix.rows()); diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h b/ground/gcs/src/libs/eigen/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h index dc240e13e..956e80d9e 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h @@ -263,6 +263,13 @@ template class GeneralizedEigenSolver } protected: + + static void check_template_parameters() + { + EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); + EIGEN_STATIC_ASSERT(!NumTraits::IsComplex, NUMERIC_TYPE_MUST_BE_REAL); + } + MatrixType m_eivec; ComplexVectorType m_alphas; VectorType m_betas; @@ -290,6 +297,8 @@ template GeneralizedEigenSolver& GeneralizedEigenSolver::compute(const MatrixType& A, const MatrixType& B, bool computeEigenvectors) { + check_template_parameters(); + using std::sqrt; using std::abs; eigen_assert(A.cols() == A.rows() && B.cols() == A.rows() && B.cols() == B.rows()); diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Eigenvalues/RealQZ.h b/ground/gcs/src/libs/eigen/Eigen/src/Eigenvalues/RealQZ.h index 5706eeebe..aa3833eba 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Eigenvalues/RealQZ.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Eigenvalues/RealQZ.h @@ -240,10 +240,10 @@ namespace Eigen { m_S.coeffRef(i,j) = Scalar(0.0); m_S.rightCols(dim-j-1).applyOnTheLeft(i-1,i,G.adjoint()); m_T.rightCols(dim-i+1).applyOnTheLeft(i-1,i,G.adjoint()); + // update Q + if (m_computeQZ) + m_Q.applyOnTheRight(i-1,i,G); } - // update Q - if (m_computeQZ) - m_Q.applyOnTheRight(i-1,i,G); // kill T(i,i-1) if(m_T.coeff(i,i-1)!=Scalar(0)) { @@ -251,10 +251,10 @@ namespace Eigen { m_T.coeffRef(i,i-1) = Scalar(0.0); m_S.applyOnTheRight(i,i-1,G); m_T.topRows(i).applyOnTheRight(i,i-1,G); + // update Z + if (m_computeQZ) + m_Z.applyOnTheLeft(i,i-1,G.adjoint()); } - // update Z - if (m_computeQZ) - m_Z.applyOnTheLeft(i,i-1,G.adjoint()); } } } @@ -313,7 +313,7 @@ namespace Eigen { using std::abs; using std::sqrt; const Index dim=m_S.cols(); - if (abs(m_S.coeff(i+1,i)==Scalar(0))) + if (abs(m_S.coeff(i+1,i))==Scalar(0)) return; Index z = findSmallDiagEntry(i,i+1); if (z==i-1) diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Eigenvalues/RealSchur.h b/ground/gcs/src/libs/eigen/Eigen/src/Eigenvalues/RealSchur.h index 64d136341..16d387537 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Eigenvalues/RealSchur.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Eigenvalues/RealSchur.h @@ -234,7 +234,7 @@ template class RealSchur typedef Matrix Vector3s; Scalar computeNormOfT(); - Index findSmallSubdiagEntry(Index iu, const Scalar& norm); + Index findSmallSubdiagEntry(Index iu); void splitOffTwoRows(Index iu, bool computeU, const Scalar& exshift); void computeShift(Index iu, Index iter, Scalar& exshift, Vector3s& shiftInfo); void initFrancisQRStep(Index il, Index iu, const Vector3s& shiftInfo, Index& im, Vector3s& firstHouseholderVector); @@ -286,7 +286,7 @@ RealSchur& RealSchur::computeFromHessenberg(const HessMa { while (iu >= 0) { - Index il = findSmallSubdiagEntry(iu, norm); + Index il = findSmallSubdiagEntry(iu); // Check for convergence if (il == iu) // One root found @@ -343,16 +343,14 @@ inline typename MatrixType::Scalar RealSchur::computeNormOfT() /** \internal Look for single small sub-diagonal element and returns its index */ template -inline typename MatrixType::Index RealSchur::findSmallSubdiagEntry(Index iu, const Scalar& norm) +inline typename MatrixType::Index RealSchur::findSmallSubdiagEntry(Index iu) { using std::abs; Index res = iu; while (res > 0) { Scalar s = abs(m_matT.coeff(res-1,res-1)) + abs(m_matT.coeff(res,res)); - if (s == 0.0) - s = norm; - if (abs(m_matT.coeff(res,res-1)) < NumTraits::epsilon() * s) + if (abs(m_matT.coeff(res,res-1)) <= NumTraits::epsilon() * s) break; res--; } @@ -457,9 +455,7 @@ inline void RealSchur::initFrancisQRStep(Index il, Index iu, const V const Scalar lhs = m_matT.coeff(im,im-1) * (abs(v.coeff(1)) + abs(v.coeff(2))); const Scalar rhs = v.coeff(0) * (abs(m_matT.coeff(im-1,im-1)) + abs(Tmm) + abs(m_matT.coeff(im+1,im+1))); if (abs(lhs) < NumTraits::epsilon() * rhs) - { break; - } } } diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Eigenvalues/RealSchur_MKL.h b/ground/gcs/src/libs/eigen/Eigen/src/Eigenvalues/RealSchur_MKL.h index ad9736460..c3089b468 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Eigenvalues/RealSchur_MKL.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Eigenvalues/RealSchur_MKL.h @@ -44,10 +44,6 @@ template<> inline \ RealSchur >& \ RealSchur >::compute(const Matrix& matrix, bool computeU) \ { \ - typedef Matrix MatrixType; \ - typedef MatrixType::Scalar Scalar; \ - typedef MatrixType::RealScalar RealScalar; \ -\ eigen_assert(matrix.cols() == matrix.rows()); \ \ lapack_int n = matrix.cols(), sdim, info; \ diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h b/ground/gcs/src/libs/eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h index 3993046a8..1131c8af8 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h @@ -80,6 +80,8 @@ template class SelfAdjointEigenSolver /** \brief Scalar type for matrices of type \p _MatrixType. */ typedef typename MatrixType::Scalar Scalar; typedef typename MatrixType::Index Index; + + typedef Matrix EigenvectorsType; /** \brief Real scalar type for \p _MatrixType. * @@ -225,7 +227,7 @@ template class SelfAdjointEigenSolver * * \sa eigenvalues() */ - const MatrixType& eigenvectors() const + const EigenvectorsType& eigenvectors() const { eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized."); eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues."); @@ -351,7 +353,12 @@ template class SelfAdjointEigenSolver #endif // EIGEN2_SUPPORT protected: - MatrixType m_eivec; + static void check_template_parameters() + { + EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); + } + + EigenvectorsType m_eivec; RealVectorType m_eivalues; typename TridiagonalizationType::SubDiagonalType m_subdiag; ComputationInfo m_info; @@ -376,7 +383,7 @@ template class SelfAdjointEigenSolver * "implicit symmetric QR step with Wilkinson shift" */ namespace internal { -template +template static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index start, Index end, Scalar* matrixQ, Index n); } @@ -384,6 +391,8 @@ template SelfAdjointEigenSolver& SelfAdjointEigenSolver ::compute(const MatrixType& matrix, int options) { + check_template_parameters(); + using std::abs; eigen_assert(matrix.cols() == matrix.rows()); eigen_assert((options&~(EigVecMask|GenEigMask))==0 @@ -406,7 +415,7 @@ SelfAdjointEigenSolver& SelfAdjointEigenSolver // declare some aliases RealVectorType& diag = m_eivalues; - MatrixType& mat = m_eivec; + EigenvectorsType& mat = m_eivec; // map the matrix coefficients to [-1:1] to avoid over- and underflow. mat = matrix.template triangularView(); @@ -442,7 +451,7 @@ SelfAdjointEigenSolver& SelfAdjointEigenSolver while (start>0 && m_subdiag[start-1]!=0) start--; - internal::tridiagonal_qr_step(diag.data(), m_subdiag.data(), start, end, computeEigenvectors ? m_eivec.data() : (Scalar*)0, n); + internal::tridiagonal_qr_step(diag.data(), m_subdiag.data(), start, end, computeEigenvectors ? m_eivec.data() : (Scalar*)0, n); } if (iter <= m_maxIterations * n) @@ -490,7 +499,13 @@ template struct direct_selfadjoint_eigenvalues struct direct_selfadjoint_eigenvalues Scalar(0)) + Scalar a_over_3 = (c2*c2_over_3 - c1)*s_inv3; + if(a_over_3 Scalar(0)) + Scalar q = a_over_3*a_over_3*a_over_3 - half_b*half_b; + if(q 0, atan2 is in [0, pi] and theta is in [0, pi/3] Scalar cos_theta = cos(theta); Scalar sin_theta = sin(theta); - roots(0) = c2_over_3 + Scalar(2)*rho*cos_theta; - roots(1) = c2_over_3 - rho*(cos_theta + s_sqrt3*sin_theta); - roots(2) = c2_over_3 - rho*(cos_theta - s_sqrt3*sin_theta); - - // Sort in increasing order. - if (roots(0) >= roots(1)) - std::swap(roots(0),roots(1)); - if (roots(1) >= roots(2)) - { - std::swap(roots(1),roots(2)); - if (roots(0) >= roots(1)) - std::swap(roots(0),roots(1)); - } + // roots are already sorted, since cos is monotonically decreasing on [0, pi] + roots(0) = c2_over_3 - rho*(cos_theta + s_sqrt3*sin_theta); // == 2*rho*cos(theta+2pi/3) + roots(1) = c2_over_3 - rho*(cos_theta - s_sqrt3*sin_theta); // == 2*rho*cos(theta+ pi/3) + roots(2) = c2_over_3 + Scalar(2)*rho*cos_theta; } - + + static inline bool extract_kernel(MatrixType& mat, Ref res, Ref representative) + { + using std::abs; + Index i0; + // Find non-zero column i0 (by construction, there must exist a non zero coefficient on the diagonal): + mat.diagonal().cwiseAbs().maxCoeff(&i0); + // mat.col(i0) is a good candidate for an orthogonal vector to the current eigenvector, + // so let's save it: + representative = mat.col(i0); + Scalar n0, n1; + VectorType c0, c1; + n0 = (c0 = representative.cross(mat.col((i0+1)%3))).squaredNorm(); + n1 = (c1 = representative.cross(mat.col((i0+2)%3))).squaredNorm(); + if(n0>n1) res = c0/std::sqrt(n0); + else res = c1/std::sqrt(n1); + + return true; + } + static inline void run(SolverType& solver, const MatrixType& mat, int options) { - using std::sqrt; eigen_assert(mat.cols() == 3 && mat.cols() == mat.rows()); eigen_assert((options&~(EigVecMask|GenEigMask))==0 && (options&EigVecMask)!=EigVecMask && "invalid option parameter"); bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors; - MatrixType& eivecs = solver.m_eivec; + EigenvectorsType& eivecs = solver.m_eivec; VectorType& eivals = solver.m_eivalues; - // map the matrix coefficients to [-1:1] to avoid over- and underflow. - Scalar scale = mat.cwiseAbs().maxCoeff(); - MatrixType scaledMat = mat / scale; + // Shift the matrix to the mean eigenvalue and map the matrix coefficients to [-1:1] to avoid over- and underflow. + Scalar shift = mat.trace() / Scalar(3); + // TODO Avoid this copy. Currently it is necessary to suppress bogus values when determining maxCoeff and for computing the eigenvectors later + MatrixType scaledMat = mat.template selfadjointView(); + scaledMat.diagonal().array() -= shift; + Scalar scale = scaledMat.cwiseAbs().maxCoeff(); + if(scale > 0) scaledMat /= scale; // TODO for scale==0 we could save the remaining operations // compute the eigenvalues computeRoots(scaledMat,eivals); - // compute the eigen vectors + // compute the eigenvectors if(computeEigenvectors) { - Scalar safeNorm2 = Eigen::NumTraits::epsilon(); - safeNorm2 *= safeNorm2; if((eivals(2)-eivals(0))<=Eigen::NumTraits::epsilon()) { + // All three eigenvalues are numerically the same eivecs.setIdentity(); } else { - scaledMat = scaledMat.template selfadjointView(); MatrixType tmp; tmp = scaledMat; + // Compute the eigenvector of the most distinct eigenvalue Scalar d0 = eivals(2) - eivals(1); Scalar d1 = eivals(1) - eivals(0); - int k = d0 > d1 ? 2 : 0; - d0 = d0 > d1 ? d1 : d0; - - tmp.diagonal().array () -= eivals(k); - VectorType cross; - Scalar n; - n = (cross = tmp.row(0).cross(tmp.row(1))).squaredNorm(); - - if(n>safeNorm2) - eivecs.col(k) = cross / sqrt(n); - else + Index k(0), l(2); + if(d0 > d1) { - n = (cross = tmp.row(0).cross(tmp.row(2))).squaredNorm(); - - if(n>safeNorm2) - eivecs.col(k) = cross / sqrt(n); - else - { - n = (cross = tmp.row(1).cross(tmp.row(2))).squaredNorm(); - - if(n>safeNorm2) - eivecs.col(k) = cross / sqrt(n); - else - { - // the input matrix and/or the eigenvaues probably contains some inf/NaN, - // => exit - // scale back to the original size. - eivals *= scale; - - solver.m_info = NumericalIssue; - solver.m_isInitialized = true; - solver.m_eigenvectorsOk = computeEigenvectors; - return; - } - } + std::swap(k,l); + d0 = d1; } - tmp = scaledMat; - tmp.diagonal().array() -= eivals(1); - - if(d0<=Eigen::NumTraits::epsilon()) - eivecs.col(1) = eivecs.col(k).unitOrthogonal(); - else + // Compute the eigenvector of index k { - n = (cross = eivecs.col(k).cross(tmp.row(0).normalized())).squaredNorm(); - if(n>safeNorm2) - eivecs.col(1) = cross / sqrt(n); - else - { - n = (cross = eivecs.col(k).cross(tmp.row(1))).squaredNorm(); - if(n>safeNorm2) - eivecs.col(1) = cross / sqrt(n); - else - { - n = (cross = eivecs.col(k).cross(tmp.row(2))).squaredNorm(); - if(n>safeNorm2) - eivecs.col(1) = cross / sqrt(n); - else - { - // we should never reach this point, - // if so the last two eigenvalues are likely to ve very closed to each other - eivecs.col(1) = eivecs.col(k).unitOrthogonal(); - } - } - } - - // make sure that eivecs[1] is orthogonal to eivecs[2] - Scalar d = eivecs.col(1).dot(eivecs.col(k)); - eivecs.col(1) = (eivecs.col(1) - d * eivecs.col(k)).normalized(); + tmp.diagonal().array () -= eivals(k); + // By construction, 'tmp' is of rank 2, and its kernel corresponds to the respective eigenvector. + extract_kernel(tmp, eivecs.col(k), eivecs.col(l)); } - eivecs.col(k==2 ? 0 : 2) = eivecs.col(k).cross(eivecs.col(1)).normalized(); + // Compute eigenvector of index l + if(d0<=2*Eigen::NumTraits::epsilon()*d1) + { + // If d0 is too small, then the two other eigenvalues are numerically the same, + // and thus we only have to ortho-normalize the near orthogonal vector we saved above. + eivecs.col(l) -= eivecs.col(k).dot(eivecs.col(l))*eivecs.col(l); + eivecs.col(l).normalize(); + } + else + { + tmp = scaledMat; + tmp.diagonal().array () -= eivals(l); + + VectorType dummy; + extract_kernel(tmp, eivecs.col(l), dummy); + } + + // Compute last eigenvector from the other two + eivecs.col(1) = eivecs.col(2).cross(eivecs.col(0)).normalized(); } } + // Rescale back to the original size. eivals *= scale; + eivals.array() += shift; solver.m_info = Success; solver.m_isInitialized = true; @@ -665,11 +655,12 @@ template struct direct_selfadjoint_eigenvalues struct direct_selfadjoint_eigenvalues struct direct_selfadjoint_eigenvaluesc2) + if((eivals(1)-eivals(0))<=abs(eivals(1))*Eigen::NumTraits::epsilon()) { - eivecs.col(1) << -scaledMat(1,0), scaledMat(0,0); - eivecs.col(1) /= sqrt(a2+b2); + eivecs.setIdentity(); } else { - eivecs.col(1) << -scaledMat(1,1), scaledMat(1,0); - eivecs.col(1) /= sqrt(c2+b2); - } + scaledMat.diagonal().array () -= eivals(1); + Scalar a2 = numext::abs2(scaledMat(0,0)); + Scalar c2 = numext::abs2(scaledMat(1,1)); + Scalar b2 = numext::abs2(scaledMat(1,0)); + if(a2>c2) + { + eivecs.col(1) << -scaledMat(1,0), scaledMat(0,0); + eivecs.col(1) /= sqrt(a2+b2); + } + else + { + eivecs.col(1) << -scaledMat(1,1), scaledMat(1,0); + eivecs.col(1) /= sqrt(c2+b2); + } - eivecs.col(0) << eivecs.col(1).unitOrthogonal(); + eivecs.col(0) << eivecs.col(1).unitOrthogonal(); + } } // Rescale back to the original size. @@ -736,7 +736,7 @@ SelfAdjointEigenSolver& SelfAdjointEigenSolver } namespace internal { -template +template static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index start, Index end, Scalar* matrixQ, Index n) { using std::abs; @@ -788,8 +788,7 @@ static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index sta // apply the givens rotation to the unit matrix Q = Q * G if (matrixQ) { - // FIXME if StorageOrder == RowMajor this operation is not very efficient - Map > q(matrixQ,n,n); + Map > q(matrixQ,n,n); q.applyOnTheRight(k,k+1,rot); } } diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Geometry/AlignedBox.h b/ground/gcs/src/libs/eigen/Eigen/src/Geometry/AlignedBox.h index 8e186d57a..7e1cd9eb7 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Geometry/AlignedBox.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Geometry/AlignedBox.h @@ -19,10 +19,12 @@ namespace Eigen { * * \brief An axis aligned box * - * \param _Scalar the type of the scalar coefficients - * \param _AmbientDim the dimension of the ambient space, can be a compile time value or Dynamic. + * \tparam _Scalar the type of the scalar coefficients + * \tparam _AmbientDim the dimension of the ambient space, can be a compile time value or Dynamic. * * This class represents an axis aligned box as a pair of the minimal and maximal corners. + * \warning The result of most methods is undefined when applied to an empty box. You can check for empty boxes using isEmpty(). + * \sa alignedboxtypedefs */ template class AlignedBox @@ -40,18 +42,21 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim) /** Define constants to name the corners of a 1D, 2D or 3D axis aligned bounding box */ enum CornerType { - /** 1D names */ + /** 1D names @{ */ Min=0, Max=1, + /** @} */ - /** Added names for 2D */ + /** Identifier for 2D corner @{ */ BottomLeft=0, BottomRight=1, TopLeft=2, TopRight=3, + /** @} */ - /** Added names for 3D */ + /** Identifier for 3D corner @{ */ BottomLeftFloor=0, BottomRightFloor=1, TopLeftFloor=2, TopRightFloor=3, BottomLeftCeil=4, BottomRightCeil=5, TopLeftCeil=6, TopRightCeil=7 + /** @} */ }; @@ -63,34 +68,33 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim) inline explicit AlignedBox(Index _dim) : m_min(_dim), m_max(_dim) { setEmpty(); } - /** Constructs a box with extremities \a _min and \a _max. */ + /** Constructs a box with extremities \a _min and \a _max. + * \warning If either component of \a _min is larger than the same component of \a _max, the constructed box is empty. */ template inline AlignedBox(const OtherVectorType1& _min, const OtherVectorType2& _max) : m_min(_min), m_max(_max) {} /** Constructs a box containing a single point \a p. */ template - inline explicit AlignedBox(const MatrixBase& a_p) - { - typename internal::nested::type p(a_p.derived()); - m_min = p; - m_max = p; - } + inline explicit AlignedBox(const MatrixBase& p) : m_min(p), m_max(m_min) + { } ~AlignedBox() {} /** \returns the dimension in which the box holds */ inline Index dim() const { return AmbientDimAtCompileTime==Dynamic ? m_min.size() : Index(AmbientDimAtCompileTime); } - /** \deprecated use isEmpty */ + /** \deprecated use isEmpty() */ inline bool isNull() const { return isEmpty(); } - /** \deprecated use setEmpty */ + /** \deprecated use setEmpty() */ inline void setNull() { setEmpty(); } - /** \returns true if the box is empty. */ + /** \returns true if the box is empty. + * \sa setEmpty */ inline bool isEmpty() const { return (m_min.array() > m_max.array()).any(); } - /** Makes \c *this an empty box. */ + /** Makes \c *this an empty box. + * \sa isEmpty */ inline void setEmpty() { m_min.setConstant( ScalarTraits::highest() ); @@ -159,7 +163,7 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim) * a uniform distribution */ inline VectorType sample() const { - VectorType r; + VectorType r(dim()); for(Index d=0; d - inline bool contains(const MatrixBase& a_p) const + inline bool contains(const MatrixBase& p) const { - typename internal::nested::type p(a_p.derived()); - return (m_min.array()<=p.array()).all() && (p.array()<=m_max.array()).all(); + typename internal::nested::type p_n(p.derived()); + return (m_min.array()<=p_n.array()).all() && (p_n.array()<=m_max.array()).all(); } /** \returns true if the box \a b is entirely inside the box \c *this. */ inline bool contains(const AlignedBox& b) const { return (m_min.array()<=(b.min)().array()).all() && ((b.max)().array()<=m_max.array()).all(); } - /** Extends \c *this such that it contains the point \a p and returns a reference to \c *this. */ + /** \returns true if the box \a b is intersecting the box \c *this. + * \sa intersection, clamp */ + inline bool intersects(const AlignedBox& b) const + { return (m_min.array()<=(b.max)().array()).all() && ((b.min)().array()<=m_max.array()).all(); } + + /** Extends \c *this such that it contains the point \a p and returns a reference to \c *this. + * \sa extend(const AlignedBox&) */ template - inline AlignedBox& extend(const MatrixBase& a_p) + inline AlignedBox& extend(const MatrixBase& p) { - typename internal::nested::type p(a_p.derived()); - m_min = m_min.cwiseMin(p); - m_max = m_max.cwiseMax(p); + typename internal::nested::type p_n(p.derived()); + m_min = m_min.cwiseMin(p_n); + m_max = m_max.cwiseMax(p_n); return *this; } - /** Extends \c *this such that it contains the box \a b and returns a reference to \c *this. */ + /** Extends \c *this such that it contains the box \a b and returns a reference to \c *this. + * \sa merged, extend(const MatrixBase&) */ inline AlignedBox& extend(const AlignedBox& b) { m_min = m_min.cwiseMin(b.m_min); @@ -203,7 +214,9 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim) return *this; } - /** Clamps \c *this by the box \a b and returns a reference to \c *this. */ + /** Clamps \c *this by the box \a b and returns a reference to \c *this. + * \note If the boxes don't intersect, the resulting box is empty. + * \sa intersection(), intersects() */ inline AlignedBox& clamp(const AlignedBox& b) { m_min = m_min.cwiseMax(b.m_min); @@ -211,11 +224,15 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim) return *this; } - /** Returns an AlignedBox that is the intersection of \a b and \c *this */ + /** Returns an AlignedBox that is the intersection of \a b and \c *this + * \note If the boxes don't intersect, the resulting box is empty. + * \sa intersects(), clamp, contains() */ inline AlignedBox intersection(const AlignedBox& b) const {return AlignedBox(m_min.cwiseMax(b.m_min), m_max.cwiseMin(b.m_max)); } - /** Returns an AlignedBox that is the union of \a b and \c *this */ + /** Returns an AlignedBox that is the union of \a b and \c *this. + * \note Merging with an empty box may result in a box bigger than \c *this. + * \sa extend(const AlignedBox&) */ inline AlignedBox merged(const AlignedBox& b) const { return AlignedBox(m_min.cwiseMin(b.m_min), m_max.cwiseMax(b.m_max)); } @@ -231,20 +248,20 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim) /** \returns the squared distance between the point \a p and the box \c *this, * and zero if \a p is inside the box. - * \sa exteriorDistance() + * \sa exteriorDistance(const MatrixBase&), squaredExteriorDistance(const AlignedBox&) */ template - inline Scalar squaredExteriorDistance(const MatrixBase& a_p) const; + inline Scalar squaredExteriorDistance(const MatrixBase& p) const; /** \returns the squared distance between the boxes \a b and \c *this, * and zero if the boxes intersect. - * \sa exteriorDistance() + * \sa exteriorDistance(const AlignedBox&), squaredExteriorDistance(const MatrixBase&) */ inline Scalar squaredExteriorDistance(const AlignedBox& b) const; /** \returns the distance between the point \a p and the box \c *this, * and zero if \a p is inside the box. - * \sa squaredExteriorDistance() + * \sa squaredExteriorDistance(const MatrixBase&), exteriorDistance(const AlignedBox&) */ template inline NonInteger exteriorDistance(const MatrixBase& p) const @@ -252,7 +269,7 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim) /** \returns the distance between the boxes \a b and \c *this, * and zero if the boxes intersect. - * \sa squaredExteriorDistance() + * \sa squaredExteriorDistance(const AlignedBox&), exteriorDistance(const MatrixBase&) */ inline NonInteger exteriorDistance(const AlignedBox& b) const { using std::sqrt; return sqrt(NonInteger(squaredExteriorDistance(b))); } diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Geometry/AngleAxis.h b/ground/gcs/src/libs/eigen/Eigen/src/Geometry/AngleAxis.h index 553d38c74..a8d3cdcfa 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Geometry/AngleAxis.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Geometry/AngleAxis.h @@ -83,10 +83,17 @@ public: template inline explicit AngleAxis(const MatrixBase& m) { *this = m; } + /** \returns the value of the rotation angle in radian */ Scalar angle() const { return m_angle; } + /** \returns a read-write reference to the stored angle in radian */ Scalar& angle() { return m_angle; } + /** \returns the rotation axis */ const Vector3& axis() const { return m_axis; } + /** \returns a read-write reference to the stored rotation axis. + * + * \warning The rotation axis must remain a \b unit vector. + */ Vector3& axis() { return m_axis; } /** Concatenates two rotations */ @@ -131,7 +138,7 @@ public: m_angle = Scalar(other.angle()); } - static inline const AngleAxis Identity() { return AngleAxis(0, Vector3::UnitX()); } + static inline const AngleAxis Identity() { return AngleAxis(Scalar(0), Vector3::UnitX()); } /** \returns \c true if \c *this is approximately equal to \a other, within the precision * determined by \a prec. @@ -165,8 +172,8 @@ AngleAxis& AngleAxis::operator=(const QuaternionBase::dummy_precision()*NumTraits::dummy_precision()) { - m_angle = 0; - m_axis << 1, 0, 0; + m_angle = Scalar(0); + m_axis << Scalar(1), Scalar(0), Scalar(0); } else { diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Geometry/EulerAngles.h b/ground/gcs/src/libs/eigen/Eigen/src/Geometry/EulerAngles.h index 97984d590..82802fb43 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Geometry/EulerAngles.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Geometry/EulerAngles.h @@ -28,7 +28,7 @@ namespace Eigen { * * AngleAxisf(ea[2], Vector3f::UnitZ()); \endcode * This corresponds to the right-multiply conventions (with right hand side frames). * - * The returned angles are in the ranges [0:pi]x[0:pi]x[-pi:pi]. + * The returned angles are in the ranges [0:pi]x[-pi:pi]x[-pi:pi]. * * \sa class AngleAxis */ diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Geometry/Homogeneous.h b/ground/gcs/src/libs/eigen/Eigen/src/Geometry/Homogeneous.h index 00e71d190..372e422b9 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Geometry/Homogeneous.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Geometry/Homogeneous.h @@ -79,7 +79,7 @@ template class Homogeneous { if( (int(Direction)==Vertical && row==m_matrix.rows()) || (int(Direction)==Horizontal && col==m_matrix.cols())) - return 1; + return Scalar(1); return m_matrix.coeff(row, col); } diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Geometry/Hyperplane.h b/ground/gcs/src/libs/eigen/Eigen/src/Geometry/Hyperplane.h index aeff43fef..00b7c4300 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Geometry/Hyperplane.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Geometry/Hyperplane.h @@ -100,7 +100,17 @@ public: { EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(VectorType, 3) Hyperplane result(p0.size()); - result.normal() = (p2 - p0).cross(p1 - p0).normalized(); + VectorType v0(p2 - p0), v1(p1 - p0); + result.normal() = v0.cross(v1); + RealScalar norm = result.normal().norm(); + if(norm <= v0.norm() * v1.norm() * NumTraits::epsilon()) + { + Matrix m; m << v0.transpose(), v1.transpose(); + JacobiSVD > svd(m, ComputeFullV); + result.normal() = svd.matrixV().col(2); + } + else + result.normal() /= norm; result.offset() = -p0.dot(result.normal()); return result; } diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Geometry/ParametrizedLine.h b/ground/gcs/src/libs/eigen/Eigen/src/Geometry/ParametrizedLine.h index 77fa228e6..cf3252df9 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Geometry/ParametrizedLine.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Geometry/ParametrizedLine.h @@ -129,7 +129,7 @@ public: * determined by \a prec. * * \sa MatrixBase::isApprox() */ - bool isApprox(const ParametrizedLine& other, typename NumTraits::Real prec = NumTraits::dummy_precision()) const + bool isApprox(const ParametrizedLine& other, const typename NumTraits::Real& prec = NumTraits::dummy_precision()) const { return m_origin.isApprox(other.m_origin, prec) && m_direction.isApprox(other.m_direction, prec); } protected: diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Geometry/Quaternion.h b/ground/gcs/src/libs/eigen/Eigen/src/Geometry/Quaternion.h index e135f2b66..25ed17bb6 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Geometry/Quaternion.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Geometry/Quaternion.h @@ -102,11 +102,11 @@ public: /** \returns a quaternion representing an identity rotation * \sa MatrixBase::Identity() */ - static inline Quaternion Identity() { return Quaternion(1, 0, 0, 0); } + static inline Quaternion Identity() { return Quaternion(Scalar(1), Scalar(0), Scalar(0), Scalar(0)); } /** \sa QuaternionBase::Identity(), MatrixBase::setIdentity() */ - inline QuaternionBase& setIdentity() { coeffs() << 0, 0, 0, 1; return *this; } + inline QuaternionBase& setIdentity() { coeffs() << Scalar(0), Scalar(0), Scalar(0), Scalar(1); return *this; } /** \returns the squared norm of the quaternion's coefficients * \sa QuaternionBase::norm(), MatrixBase::squaredNorm() @@ -150,10 +150,6 @@ public: /** \returns the conjugated quaternion */ Quaternion conjugate() const; - /** \returns an interpolation for a constant motion between \a other and \c *this - * \a t in [0;1] - * see http://en.wikipedia.org/wiki/Slerp - */ template Quaternion slerp(const Scalar& t, const QuaternionBase& other) const; /** \returns \c true if \c *this is approximately equal to \a other, within the precision @@ -165,7 +161,7 @@ public: { return coeffs().isApprox(other.coeffs(), prec); } /** return the result vector of \a v through the rotation*/ - EIGEN_STRONG_INLINE Vector3 _transformVector(Vector3 v) const; + EIGEN_STRONG_INLINE Vector3 _transformVector(const Vector3& v) const; /** \returns \c *this with scalar type casted to \a NewScalarType * @@ -194,11 +190,11 @@ public: * \brief The quaternion class used to represent 3D orientations and rotations * * \tparam _Scalar the scalar type, i.e., the type of the coefficients - * \tparam _Options controls the memory alignement of the coeffecients. Can be \# AutoAlign or \# DontAlign. Default is AutoAlign. + * \tparam _Options controls the memory alignment of the coefficients. Can be \# AutoAlign or \# DontAlign. Default is AutoAlign. * * This class represents a quaternion \f$ w+xi+yj+zk \f$ that is a convenient representation of * orientations and rotations of objects in three dimensions. Compared to other representations - * like Euler angles or 3x3 matrices, quatertions offer the following advantages: + * like Euler angles or 3x3 matrices, quaternions offer the following advantages: * \li \b compact storage (4 scalars) * \li \b efficient to compose (28 flops), * \li \b stable spherical interpolation @@ -207,6 +203,8 @@ public: * \li \c Quaternionf for \c float * \li \c Quaterniond for \c double * + * \warning Operations interpreting the quaternion as rotation have undefined behavior if the quaternion is not normalized. + * * \sa class AngleAxis, class Transform */ @@ -233,7 +231,7 @@ class Quaternion : public QuaternionBase > public: typedef _Scalar Scalar; - EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Quaternion) + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Quaternion) using Base::operator*=; typedef typename internal::traits::Coefficients Coefficients; @@ -343,12 +341,12 @@ class Map, _Options > public: typedef _Scalar Scalar; typedef typename internal::traits::Coefficients Coefficients; - EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Map) + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Map) using Base::operator*=; /** Constructs a Mapped Quaternion object from the pointer \a coeffs * - * The pointer \a coeffs must reference the four coeffecients of Quaternion in the following order: + * The pointer \a coeffs must reference the four coefficients of Quaternion in the following order: * \code *coeffs == {x, y, z, w} \endcode * * If the template parameter _Options is set to #Aligned, then the pointer coeffs must be aligned. */ @@ -380,12 +378,12 @@ class Map, _Options > public: typedef _Scalar Scalar; typedef typename internal::traits::Coefficients Coefficients; - EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Map) + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Map) using Base::operator*=; /** Constructs a Mapped Quaternion object from the pointer \a coeffs * - * The pointer \a coeffs must reference the four coeffecients of Quaternion in the following order: + * The pointer \a coeffs must reference the four coefficients of Quaternion in the following order: * \code *coeffs == {x, y, z, w} \endcode * * If the template parameter _Options is set to #Aligned, then the pointer coeffs must be aligned. */ @@ -399,16 +397,16 @@ class Map, _Options > }; /** \ingroup Geometry_Module - * Map an unaligned array of single precision scalar as a quaternion */ + * Map an unaligned array of single precision scalars as a quaternion */ typedef Map, 0> QuaternionMapf; /** \ingroup Geometry_Module - * Map an unaligned array of double precision scalar as a quaternion */ + * Map an unaligned array of double precision scalars as a quaternion */ typedef Map, 0> QuaternionMapd; /** \ingroup Geometry_Module - * Map a 16-bits aligned array of double precision scalars as a quaternion */ + * Map a 16-byte aligned array of single precision scalars as a quaternion */ typedef Map, Aligned> QuaternionMapAlignedf; /** \ingroup Geometry_Module - * Map a 16-bits aligned array of double precision scalars as a quaternion */ + * Map a 16-byte aligned array of double precision scalars as a quaternion */ typedef Map, Aligned> QuaternionMapAlignedd; /*************************************************************************** @@ -463,12 +461,12 @@ EIGEN_STRONG_INLINE Derived& QuaternionBase::operator*= (const Quaterni */ template EIGEN_STRONG_INLINE typename QuaternionBase::Vector3 -QuaternionBase::_transformVector(Vector3 v) const +QuaternionBase::_transformVector(const Vector3& v) const { // Note that this algorithm comes from the optimization by hand // of the conversion to a Matrix followed by a Matrix/Vector product. // It appears to be much faster than the common algorithm found - // in the litterature (30 versus 39 flops). It also requires two + // in the literature (30 versus 39 flops). It also requires two // Vector3 as temporaries. Vector3 uv = this->vec().cross(v); uv += uv; @@ -579,7 +577,7 @@ inline Derived& QuaternionBase::setFromTwoVectors(const MatrixBase accuraletly compute the rotation axis by computing the + // => accurately compute the rotation axis by computing the // intersection of the two planes. This is done by solving: // x^T v0 = 0 // x^T v1 = 0 @@ -588,7 +586,7 @@ inline Derived& QuaternionBase::setFromTwoVectors(const MatrixBase::dummy_precision()) { - c = max(c,-1); + c = (max)(c,Scalar(-1)); Matrix m; m << v0.transpose(), v1.transpose(); JacobiSVD > svd(m, ComputeFullV); Vector3 axis = svd.matrixV().col(2); @@ -639,7 +637,7 @@ inline Quaternion::Scalar> QuaternionBasesquaredNorm(); - if (n2 > 0) + if (n2 > Scalar(0)) return Quaternion(conjugate().coeffs() / n2); else { @@ -669,16 +667,19 @@ template inline typename internal::traits::Scalar QuaternionBase::angularDistance(const QuaternionBase& other) const { - using std::acos; + using std::atan2; using std::abs; - double d = abs(this->dot(other)); - if (d>=1.0) - return Scalar(0); - return static_cast(2 * acos(d)); + Quaternion d = (*this) * other.conjugate(); + return Scalar(2) * atan2( d.vec().norm(), abs(d.w()) ); } + + /** \returns the spherical linear interpolation between the two quaternions - * \c *this and \a other at the parameter \a t + * \c *this and \a other at the parameter \a t in [0;1]. + * + * This represents an interpolation for a constant motion between \c *this and \a other, + * see also http://en.wikipedia.org/wiki/Slerp. */ template template @@ -709,7 +710,7 @@ QuaternionBase::slerp(const Scalar& t, const QuaternionBase(scale0 * coeffs() + scale1 * other.coeffs()); } diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Geometry/Rotation2D.h b/ground/gcs/src/libs/eigen/Eigen/src/Geometry/Rotation2D.h index 1cac343a5..a2d59fce1 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Geometry/Rotation2D.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Geometry/Rotation2D.h @@ -60,6 +60,9 @@ public: /** Construct a 2D counter clock wise rotation from the angle \a a in radian. */ inline Rotation2D(const Scalar& a) : m_angle(a) {} + + /** Default constructor wihtout initialization. The represented rotation is undefined. */ + Rotation2D() {} /** \returns the rotation angle */ inline Scalar angle() const { return m_angle; } @@ -81,10 +84,10 @@ public: /** Applies the rotation to a 2D vector */ Vector2 operator* (const Vector2& vec) const { return toRotationMatrix() * vec; } - + template Rotation2D& fromRotationMatrix(const MatrixBase& m); - Matrix2 toRotationMatrix(void) const; + Matrix2 toRotationMatrix() const; /** \returns the spherical interpolation between \c *this and \a other using * parameter \a t. It is in fact equivalent to a linear interpolation. diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Geometry/Transform.h b/ground/gcs/src/libs/eigen/Eigen/src/Geometry/Transform.h index 887e718d6..0186f3b82 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Geometry/Transform.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Geometry/Transform.h @@ -62,6 +62,8 @@ struct transform_construct_from_matrix; template struct transform_take_affine_part; +template struct transform_make_affine; + } // end namespace internal /** \geometry_module \ingroup Geometry_Module @@ -100,15 +102,15 @@ template struct transform_take_affine_part; * * However, unlike a plain matrix, the Transform class provides many features * simplifying both its assembly and usage. In particular, it can be composed - * with any other transformations (Transform,Translation,RotationBase,Matrix) + * with any other transformations (Transform,Translation,RotationBase,DiagonalMatrix) * and can be directly used to transform implicit homogeneous vectors. All these * operations are handled via the operator*. For the composition of transformations, * its principle consists to first convert the right/left hand sides of the product * to a compatible (Dim+1)^2 matrix and then perform a pure matrix product. * Of course, internally, operator* tries to perform the minimal number of operations * according to the nature of each terms. Likewise, when applying the transform - * to non homogeneous vectors, the latters are automatically promoted to homogeneous - * one before doing the matrix product. The convertions to homogeneous representations + * to points, the latters are automatically promoted to homogeneous vectors + * before doing the matrix product. The conventions to homogeneous representations * are performed as follow: * * \b Translation t (Dim)x(1): @@ -122,7 +124,7 @@ template struct transform_take_affine_part; * R & 0\\ * 0\,...\,0 & 1 * \end{array} \right) \f$ - * + * + * \b Scaling \b DiagonalMatrix S (Dim)x(Dim): + * \f$ \left( \begin{array}{cc} + * S & 0\\ + * 0\,...\,0 & 1 + * \end{array} \right) \f$ * - * \b Column \b vector v (Dim)x(1): + * \b Column \b point v (Dim)x(1): * \f$ \left( \begin{array}{c} * v\\ * 1 * \end{array} \right) \f$ * - * \b Set \b of \b column \b vectors V1...Vn (Dim)x(n): + * \b Set \b of \b column \b points V1...Vn (Dim)x(n): * \f$ \left( \begin{array}{ccc} * v_1 & ... & v_n\\ * 1 & ... & 1 @@ -194,9 +202,9 @@ public: /** type of the matrix used to represent the linear part of the transformation */ typedef Matrix LinearMatrixType; /** type of read/write reference to the linear part of the transformation */ - typedef Block LinearPart; + typedef Block LinearPart; /** type of read reference to the linear part of the transformation */ - typedef const Block ConstLinearPart; + typedef const Block ConstLinearPart; /** type of read/write reference to the affine part of the transformation */ typedef typename internal::conditional::run(m_matrix); } inline Transform(const Transform& other) @@ -383,26 +390,39 @@ public: /** \returns a writable expression of the translation vector of the transformation */ inline TranslationPart translation() { return TranslationPart(m_matrix,0,Dim); } - /** \returns an expression of the product between the transform \c *this and a matrix expression \a other + /** \returns an expression of the product between the transform \c *this and a matrix expression \a other. * - * The right hand side \a other might be either: - * \li a vector of size Dim, + * The right-hand-side \a other can be either: * \li an homogeneous vector of size Dim+1, - * \li a set of vectors of size Dim x Dynamic, - * \li a set of homogeneous vectors of size Dim+1 x Dynamic, - * \li a linear transformation matrix of size Dim x Dim, - * \li an affine transformation matrix of size Dim x Dim+1, + * \li a set of homogeneous vectors of size Dim+1 x N, * \li a transformation matrix of size Dim+1 x Dim+1. + * + * Moreover, if \c *this represents an affine transformation (i.e., Mode!=Projective), then \a other can also be: + * \li a point of size Dim (computes: \code this->linear() * other + this->translation()\endcode), + * \li a set of N points as a Dim x N matrix (computes: \code (this->linear() * other).colwise() + this->translation()\endcode), + * + * In all cases, the return type is a matrix or vector of same sizes as the right-hand-side \a other. + * + * If you want to interpret \a other as a linear or affine transformation, then first convert it to a Transform<> type, + * or do your own cooking. + * + * Finally, if you want to apply Affine transformations to vectors, then explicitly apply the linear part only: + * \code + * Affine3f A; + * Vector3f v1, v2; + * v2 = A.linear() * v1; + * \endcode + * */ // note: this function is defined here because some compilers cannot find the respective declaration template - EIGEN_STRONG_INLINE const typename internal::transform_right_product_impl::ResultType + EIGEN_STRONG_INLINE const typename OtherDerived::PlainObject operator * (const EigenBase &other) const { return internal::transform_right_product_impl::run(*this,other.derived()); } /** \returns the product expression of a transformation matrix \a a times a transform \a b * - * The left hand side \a other might be either: + * The left hand side \a other can be either: * \li a linear transformation matrix of size Dim x Dim, * \li an affine transformation matrix of size Dim x Dim+1, * \li a general transformation matrix of size Dim+1 x Dim+1. @@ -530,9 +550,9 @@ public: inline Transform& operator=(const UniformScaling& t); inline Transform& operator*=(const UniformScaling& s) { return scale(s.factor()); } - inline Transform operator*(const UniformScaling& s) const + inline Transform operator*(const UniformScaling& s) const { - Transform res = *this; + Transform res = *this; res.scale(s.factor()); return res; } @@ -591,11 +611,7 @@ public: */ void makeAffine() { - if(int(Mode)!=int(AffineCompact)) - { - matrix().template block<1,Dim>(Dim,0).setZero(); - matrix().coeffRef(Dim,Dim) = Scalar(1); - } + internal::transform_make_affine::run(m_matrix); } /** \internal @@ -1079,6 +1095,24 @@ Transform::fromPositionOrientationScale(const MatrixBas namespace internal { +template +struct transform_make_affine +{ + template + static void run(MatrixType &mat) + { + static const int Dim = MatrixType::ColsAtCompileTime-1; + mat.template block<1,Dim>(Dim,0).setZero(); + mat.coeffRef(Dim,Dim) = typename MatrixType::Scalar(1); + } +}; + +template<> +struct transform_make_affine +{ + template static void run(MatrixType &) { } +}; + // selector needed to avoid taking the inverse of a 3x4 matrix template struct projective_transform_inverse diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Geometry/Translation.h b/ground/gcs/src/libs/eigen/Eigen/src/Geometry/Translation.h index 7fda179cc..2e7798686 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Geometry/Translation.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Geometry/Translation.h @@ -162,7 +162,7 @@ public: * determined by \a prec. * * \sa MatrixBase::isApprox() */ - bool isApprox(const Translation& other, typename NumTraits::Real prec = NumTraits::dummy_precision()) const + bool isApprox(const Translation& other, const typename NumTraits::Real& prec = NumTraits::dummy_precision()) const { return m_coeffs.isApprox(other.m_coeffs, prec); } }; diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Geometry/Umeyama.h b/ground/gcs/src/libs/eigen/Eigen/src/Geometry/Umeyama.h index 345b47e0c..5e20662f8 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Geometry/Umeyama.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Geometry/Umeyama.h @@ -113,7 +113,7 @@ umeyama(const MatrixBase& src, const MatrixBase& dst, boo const Index n = src.cols(); // number of measurements // required for demeaning ... - const RealScalar one_over_n = 1 / static_cast(n); + const RealScalar one_over_n = RealScalar(1) / static_cast(n); // computation of mean const VectorType src_mean = src.rowwise().sum() * one_over_n; @@ -136,16 +136,16 @@ umeyama(const MatrixBase& src, const MatrixBase& dst, boo // Eq. (39) VectorType S = VectorType::Ones(m); - if (sigma.determinant()<0) S(m-1) = -1; + if (sigma.determinant() 0 ) { + if ( svd.matrixU().determinant() * svd.matrixV().determinant() > Scalar(0) ) { Rt.block(0,0,m,m).noalias() = svd.matrixU()*svd.matrixV().transpose(); } else { - const Scalar s = S(m-1); S(m-1) = -1; + const Scalar s = S(m-1); S(m-1) = Scalar(-1); Rt.block(0,0,m,m).noalias() = svd.matrixU() * S.asDiagonal() * svd.matrixV().transpose(); S(m-1) = s; } @@ -156,7 +156,7 @@ umeyama(const MatrixBase& src, const MatrixBase& dst, boo if (with_scaling) { // Eq. (42) - const Scalar c = 1/src_var * svd.singularValues().dot(S); + const Scalar c = Scalar(1)/src_var * svd.singularValues().dot(S); // Eq. (41) Rt.col(m).head(m) = dst_mean; diff --git a/ground/gcs/src/libs/eigen/Eigen/src/Householder/BlockHouseholder.h b/ground/gcs/src/libs/eigen/Eigen/src/Householder/BlockHouseholder.h index 1991c6527..60dbea5f5 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/Householder/BlockHouseholder.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/Householder/BlockHouseholder.h @@ -48,7 +48,7 @@ void apply_block_householder_on_the_left(MatrixType& mat, const VectorsType& vec typedef typename MatrixType::Index Index; enum { TFactorSize = MatrixType::ColsAtCompileTime }; Index nbVecs = vectors.cols(); - Matrix T(nbVecs,nbVecs); + Matrix T(nbVecs,nbVecs); make_block_householder_triangular_factor(T, vectors, hCoeffs); const TriangularView& V(vectors); diff --git a/ground/gcs/src/libs/eigen/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h b/ground/gcs/src/libs/eigen/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h index 73ca9bfde..1f3c060d0 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h @@ -65,10 +65,10 @@ class DiagonalPreconditioner { typename MatType::InnerIterator it(mat,j); while(it && it.index()!=j) ++it; - if(it && it.index()==j) + if(it && it.index()==j && it.value()!=Scalar(0)) m_invdiag(j) = Scalar(1)/it.value(); else - m_invdiag(j) = 0; + m_invdiag(j) = Scalar(1); } m_isInitialized = true; return *this; diff --git a/ground/gcs/src/libs/eigen/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h b/ground/gcs/src/libs/eigen/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h index 6fc6ab852..551221907 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h @@ -39,7 +39,6 @@ bool bicgstab(const MatrixType& mat, const Rhs& rhs, Dest& x, int maxIters = iters; int n = mat.cols(); - x = precond.solve(x); VectorType r = rhs - mat * x; VectorType r0 = r; @@ -61,6 +60,7 @@ bool bicgstab(const MatrixType& mat, const Rhs& rhs, Dest& x, VectorType s(n), t(n); RealScalar tol2 = tol*tol; + RealScalar eps2 = NumTraits::epsilon()*NumTraits::epsilon(); int i = 0; int restarts = 0; @@ -69,7 +69,7 @@ bool bicgstab(const MatrixType& mat, const Rhs& rhs, Dest& x, Scalar rho_old = rho; rho = r0.dot(r); - if (internal::isMuchSmallerThan(rho,r0_sqnorm)) + if (abs(rho) < eps2*r0_sqnorm) { // The new residual vector became too orthogonal to the arbitrarily choosen direction r0 // Let's restart with a new r0: @@ -142,7 +142,7 @@ struct traits > * SparseMatrix A(n,n); * // fill A and b * BiCGSTAB > solver; - * solver(A); + * solver.compute(A); * x = solver.solve(b); * std::cout << "#iterations: " << solver.iterations() << std::endl; * std::cout << "estimated error: " << solver.error() << std::endl; @@ -151,20 +151,7 @@ struct traits > * \endcode * * By default the iterations start with x=0 as an initial guess of the solution. - * One can control the start using the solveWithGuess() method. Here is a step by - * step execution example starting with a random guess and printing the evolution - * of the estimated error: - * * \code - * x = VectorXd::Random(n); - * solver.setMaxIterations(1); - * int i = 0; - * do { - * x = solver.solveWithGuess(b,x); - * std::cout << i << " : " << solver.error() << std::endl; - * ++i; - * } while (solver.info()!=Success && i<100); - * \endcode - * Note that such a step by step excution is slightly slower. + * One can control the start using the solveWithGuess() method. * * \sa class SimplicialCholesky, DiagonalPreconditioner, IdentityPreconditioner */ @@ -199,7 +186,8 @@ public: * this class becomes invalid. Call compute() to update it with the new * matrix A, or modify a copy of A. */ - BiCGSTAB(const MatrixType& A) : Base(A) {} + template + explicit BiCGSTAB(const EigenBase& A) : Base(A.derived()) {} ~BiCGSTAB() {} diff --git a/ground/gcs/src/libs/eigen/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h b/ground/gcs/src/libs/eigen/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h index a74a8155e..7dd4010c3 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h @@ -112,9 +112,9 @@ struct traits > * This class allows to solve for A.x = b sparse linear problems using a conjugate gradient algorithm. * The sparse matrix A must be selfadjoint. The vectors x and b can be either dense or sparse. * - * \tparam _MatrixType the type of the sparse matrix A, can be a dense or a sparse matrix. - * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower - * or Upper. Default is Lower. + * \tparam _MatrixType the type of the matrix A, can be a dense or a sparse matrix. + * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower, + * Upper, or Lower|Upper in which the full matrix entries will be considered. Default is Lower. * \tparam _Preconditioner the type of the preconditioner. Default is DiagonalPreconditioner * * The maximal number of iterations and tolerance value can be controlled via the setMaxIterations() @@ -137,21 +137,10 @@ struct traits > * \endcode * * By default the iterations start with x=0 as an initial guess of the solution. - * One can control the start using the solveWithGuess() method. Here is a step by - * step execution example starting with a random guess and printing the evolution - * of the estimated error: - * * \code - * x = VectorXd::Random(n); - * cg.setMaxIterations(1); - * int i = 0; - * do { - * x = cg.solveWithGuess(b,x); - * std::cout << i << " : " << cg.error() << std::endl; - * ++i; - * } while (cg.info()!=Success && i<100); - * \endcode - * Note that such a step by step excution is slightly slower. + * One can control the start using the solveWithGuess() method. * + * ConjugateGradient can also be used in a matrix-free context, see the following \link MatrixfreeSolverExample example \endlink. + * * \sa class SimplicialCholesky, DiagonalPreconditioner, IdentityPreconditioner */ template< typename _MatrixType, int _UpLo, typename _Preconditioner> @@ -189,7 +178,8 @@ public: * this class becomes invalid. Call compute() to update it with the new * matrix A, or modify a copy of A. */ - ConjugateGradient(const MatrixType& A) : Base(A) {} + template + explicit ConjugateGradient(const EigenBase& A) : Base(A.derived()) {} ~ConjugateGradient() {} @@ -213,6 +203,10 @@ public: template void _solveWithGuess(const Rhs& b, Dest& x) const { + typedef typename internal::conditional + >::type MatrixWrapperType; m_iterations = Base::maxIterations(); m_error = Base::m_tolerance; @@ -222,8 +216,7 @@ public: m_error = Base::m_tolerance; typename Dest::ColXpr xj(x,j); - internal::conjugate_gradient(mp_matrix->template selfadjointView(), b.col(j), xj, - Base::m_preconditioner, m_iterations, m_error); + internal::conjugate_gradient(MatrixWrapperType(*mp_matrix), b.col(j), xj, Base::m_preconditioner, m_iterations, m_error); } m_isInitialized = true; @@ -234,7 +227,7 @@ public: template void _solve(const Rhs& b, Dest& x) const { - x.setOnes(); + x.setZero(); _solveWithGuess(b,x); } diff --git a/ground/gcs/src/libs/eigen/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h b/ground/gcs/src/libs/eigen/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h index b55afc136..d3f37fea2 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h @@ -150,7 +150,6 @@ class IncompleteLUT : internal::noncopyable { analyzePattern(amat); factorize(amat); - m_isInitialized = m_factorizationIsOk; return *this; } @@ -160,7 +159,7 @@ class IncompleteLUT : internal::noncopyable template void _solve(const Rhs& b, Dest& x) const { - x = m_Pinv * b; + x = m_Pinv * b; x = m_lu.template triangularView().solve(x); x = m_lu.template triangularView().solve(x); x = m_P * x; @@ -223,18 +222,29 @@ template void IncompleteLUT::analyzePattern(const _MatrixType& amat) { // Compute the Fill-reducing permutation + // Since ILUT does not perform any numerical pivoting, + // it is highly preferable to keep the diagonal through symmetric permutations. +#ifndef EIGEN_MPL2_ONLY + // To this end, let's symmetrize the pattern and perform AMD on it. SparseMatrix mat1 = amat; SparseMatrix mat2 = amat.transpose(); - // Symmetrize the pattern // FIXME for a matrix with nearly symmetric pattern, mat2+mat1 is the appropriate choice. // on the other hand for a really non-symmetric pattern, mat2*mat1 should be prefered... SparseMatrix AtA = mat2 + mat1; - AtA.prune(keep_diag()); - internal::minimum_degree_ordering(AtA, m_P); // Then compute the AMD ordering... - - m_Pinv = m_P.inverse(); // ... and the inverse permutation + AMDOrdering ordering; + ordering(AtA,m_P); + m_Pinv = m_P.inverse(); // cache the inverse permutation +#else + // If AMD is not available, (MPL2-only), then let's use the slower COLAMD routine. + SparseMatrix mat1 = amat; + COLAMDOrdering ordering; + ordering(mat1,m_Pinv); + m_P = m_Pinv.inverse(); +#endif m_analysisIsOk = true; + m_factorizationIsOk = false; + m_isInitialized = false; } template @@ -442,6 +452,7 @@ void IncompleteLUT::factorize(const _MatrixType& amat) m_lu.makeCompressed(); m_factorizationIsOk = true; + m_isInitialized = m_factorizationIsOk; m_info = Success; } diff --git a/ground/gcs/src/libs/eigen/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h b/ground/gcs/src/libs/eigen/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h index 2036922d6..501ef2f8d 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h @@ -49,10 +49,11 @@ public: * this class becomes invalid. Call compute() to update it with the new * matrix A, or modify a copy of A. */ - IterativeSolverBase(const MatrixType& A) + template + IterativeSolverBase(const EigenBase& A) { init(); - compute(A); + compute(A.derived()); } ~IterativeSolverBase() {} @@ -62,9 +63,11 @@ public: * Currently, this function mostly call analyzePattern on the preconditioner. In the future * we might, for instance, implement column reodering for faster matrix vector products. */ - Derived& analyzePattern(const MatrixType& A) + template + Derived& analyzePattern(const EigenBase& A) { - m_preconditioner.analyzePattern(A); + grabInput(A.derived()); + m_preconditioner.analyzePattern(*mp_matrix); m_isInitialized = true; m_analysisIsOk = true; m_info = Success; @@ -80,11 +83,12 @@ public: * this class becomes invalid. Call compute() to update it with the new * matrix A, or modify a copy of A. */ - Derived& factorize(const MatrixType& A) + template + Derived& factorize(const EigenBase& A) { + grabInput(A.derived()); eigen_assert(m_analysisIsOk && "You must first call analyzePattern()"); - mp_matrix = &A; - m_preconditioner.factorize(A); + m_preconditioner.factorize(*mp_matrix); m_factorizationIsOk = true; m_info = Success; return derived(); @@ -100,10 +104,11 @@ public: * this class becomes invalid. Call compute() to update it with the new * matrix A, or modify a copy of A. */ - Derived& compute(const MatrixType& A) + template + Derived& compute(const EigenBase& A) { - mp_matrix = &A; - m_preconditioner.compute(A); + grabInput(A.derived()); + m_preconditioner.compute(*mp_matrix); m_isInitialized = true; m_analysisIsOk = true; m_factorizationIsOk = true; @@ -212,6 +217,28 @@ public: } protected: + + template + void grabInput(const EigenBase& A) + { + // we const cast to prevent the creation of a MatrixType temporary by the compiler. + grabInput_impl(A.const_cast_derived()); + } + + template + void grabInput_impl(const EigenBase& A) + { + m_copyMatrix = A; + mp_matrix = &m_copyMatrix; + } + + void grabInput_impl(MatrixType& A) + { + if(MatrixType::RowsAtCompileTime==Dynamic && MatrixType::ColsAtCompileTime==Dynamic) + m_copyMatrix.resize(0,0); + mp_matrix = &A; + } + void init() { m_isInitialized = false; @@ -220,6 +247,7 @@ protected: m_maxIterations = -1; m_tolerance = NumTraits::epsilon(); } + MatrixType m_copyMatrix; const MatrixType* mp_matrix; Preconditioner m_preconditioner; diff --git a/ground/gcs/src/libs/eigen/Eigen/src/LU/FullPivLU.h b/ground/gcs/src/libs/eigen/Eigen/src/LU/FullPivLU.h index dfe25f424..e38470463 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/LU/FullPivLU.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/LU/FullPivLU.h @@ -20,10 +20,11 @@ namespace Eigen { * * \param MatrixType the type of the matrix of which we are computing the LU decomposition * - * This class represents a LU decomposition of any matrix, with complete pivoting: the matrix A - * is decomposed as A = PLUQ where L is unit-lower-triangular, U is upper-triangular, and P and Q - * are permutation matrices. This is a rank-revealing LU decomposition. The eigenvalues (diagonal - * coefficients) of U are sorted in such a way that any zeros are at the end. + * This class represents a LU decomposition of any matrix, with complete pivoting: the matrix A is + * decomposed as \f$ A = P^{-1} L U Q^{-1} \f$ where L is unit-lower-triangular, U is + * upper-triangular, and P and Q are permutation matrices. This is a rank-revealing LU + * decomposition. The eigenvalues (diagonal coefficients) of U are sorted in such a way that any + * zeros are at the end. * * This decomposition provides the generic approach to solving systems of linear equations, computing * the rank, invertibility, inverse, kernel, and determinant. @@ -373,6 +374,12 @@ template class FullPivLU inline Index cols() const { return m_lu.cols(); } protected: + + static void check_template_parameters() + { + EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); + } + MatrixType m_lu; PermutationPType m_p; PermutationQType m_q; @@ -417,6 +424,8 @@ FullPivLU::FullPivLU(const MatrixType& matrix) template FullPivLU& FullPivLU::compute(const MatrixType& matrix) { + check_template_parameters(); + // the permutations are stored as int indices, so just to be sure: eigen_assert(matrix.rows()<=NumTraits::highest() && matrix.cols()<=NumTraits::highest()); @@ -511,8 +520,8 @@ typename internal::traits::Scalar FullPivLU::determinant } /** \returns the matrix represented by the decomposition, - * i.e., it returns the product: P^{-1} L U Q^{-1}. - * This function is provided for debug purpose. */ + * i.e., it returns the product: \f$ P^{-1} L U Q^{-1} \f$. + * This function is provided for debug purposes. */ template MatrixType FullPivLU::reconstructedMatrix() const { @@ -679,7 +688,7 @@ struct solve_retval, Rhs> */ const Index rows = dec().rows(), cols = dec().cols(), - nonzero_pivots = dec().nonzeroPivots(); + nonzero_pivots = dec().rank(); eigen_assert(rhs().rows() == rows); const Index smalldim = (std::min)(rows, cols); diff --git a/ground/gcs/src/libs/eigen/Eigen/src/LU/PartialPivLU.h b/ground/gcs/src/libs/eigen/Eigen/src/LU/PartialPivLU.h index 740ee694c..7d1db948c 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/LU/PartialPivLU.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/LU/PartialPivLU.h @@ -171,6 +171,12 @@ template class PartialPivLU inline Index cols() const { return m_lu.cols(); } protected: + + static void check_template_parameters() + { + EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); + } + MatrixType m_lu; PermutationType m_p; TranspositionType m_rowsTranspositions; @@ -386,6 +392,8 @@ void partial_lu_inplace(MatrixType& lu, TranspositionType& row_transpositions, t template PartialPivLU& PartialPivLU::compute(const MatrixType& matrix) { + check_template_parameters(); + // the row permutation is stored as int indices, so just to be sure: eigen_assert(matrix.rows()::highest()); diff --git a/ground/gcs/src/libs/eigen/Eigen/src/OrderingMethods/Amd.h b/ground/gcs/src/libs/eigen/Eigen/src/OrderingMethods/Amd.h index 41b4fd7e3..658b954c7 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/OrderingMethods/Amd.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/OrderingMethods/Amd.h @@ -8,7 +8,7 @@ NOTE: this routine has been adapted from the CSparse library: Copyright (c) 2006, Timothy A. Davis. -http://www.cise.ufl.edu/research/sparse/CSparse +http://www.suitesparse.com CSparse is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -137,22 +137,27 @@ void minimum_degree_ordering(SparseMatrix& C, Permutation degree[i] = len[i]; // degree of node i } mark = internal::cs_wclear(0, 0, w, n); /* clear w */ - elen[n] = -2; /* n is a dead element */ - Cp[n] = -1; /* n is a root of assembly tree */ - w[n] = 0; /* n is a dead element */ /* --- Initialize degree lists ------------------------------------------ */ for(i = 0; i < n; i++) { + bool has_diag = false; + for(p = Cp[i]; p dense) /* node i is dense */ + else if(d > dense || !has_diag) /* node i is dense or has no structural diagonal element */ { nv[i] = 0; /* absorb i into element n */ elen[i] = -1; /* node i is dead */ @@ -168,6 +173,10 @@ void minimum_degree_ordering(SparseMatrix& C, Permutation } } + elen[n] = -2; /* n is a dead element */ + Cp[n] = -1; /* n is a root of assembly tree */ + w[n] = 0; /* n is a dead element */ + while (nel < n) /* while (selecting pivots) do */ { /* --- Select node of minimum approximate degree -------------------- */ diff --git a/ground/gcs/src/libs/eigen/Eigen/src/OrderingMethods/Eigen_Colamd.h b/ground/gcs/src/libs/eigen/Eigen/src/OrderingMethods/Eigen_Colamd.h index 44548f660..359fd4417 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/OrderingMethods/Eigen_Colamd.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/OrderingMethods/Eigen_Colamd.h @@ -41,12 +41,8 @@ // // The colamd/symamd library is available at // -// http://www.cise.ufl.edu/research/sparse/colamd/ +// http://www.suitesparse.com -// This is the http://www.cise.ufl.edu/research/sparse/colamd/colamd.h -// file. It is required by the colamd.c, colamdmex.c, and symamdmex.c -// files, and by any C code that calls the routines whose prototypes are -// listed below, or that uses the colamd/symamd definitions listed below. #ifndef EIGEN_COLAMD_H #define EIGEN_COLAMD_H @@ -102,9 +98,6 @@ namespace internal { /* === Definitions ========================================================== */ /* ========================================================================== */ -#define COLAMD_MAX(a,b) (((a) > (b)) ? (a) : (b)) -#define COLAMD_MIN(a,b) (((a) < (b)) ? (a) : (b)) - #define ONES_COMPLEMENT(r) (-(r)-1) /* -------------------------------------------------------------------------- */ @@ -516,7 +509,7 @@ static Index init_rows_cols /* returns true if OK, or false otherwise */ Col [col].start = p [col] ; Col [col].length = p [col+1] - p [col] ; - if (Col [col].length < 0) + if ((Col [col].length) < 0) // extra parentheses to work-around gcc bug 10200 { /* column pointers must be non-decreasing */ stats [COLAMD_STATUS] = COLAMD_ERROR_col_length_negative ; @@ -739,8 +732,8 @@ static void init_scoring /* === Extract knobs ==================================================== */ - dense_row_count = COLAMD_MAX (0, COLAMD_MIN (knobs [COLAMD_DENSE_ROW] * n_col, n_col)) ; - dense_col_count = COLAMD_MAX (0, COLAMD_MIN (knobs [COLAMD_DENSE_COL] * n_row, n_row)) ; + dense_row_count = std::max(0, (std::min)(Index(knobs [COLAMD_DENSE_ROW] * n_col), n_col)) ; + dense_col_count = std::max(0, (std::min)(Index(knobs [COLAMD_DENSE_COL] * n_row), n_row)) ; COLAMD_DEBUG1 (("colamd: densecount: %d %d\n", dense_row_count, dense_col_count)) ; max_deg = 0 ; n_col2 = n_col ; @@ -804,7 +797,7 @@ static void init_scoring else { /* keep track of max degree of remaining rows */ - max_deg = COLAMD_MAX (max_deg, deg) ; + max_deg = (std::max)(max_deg, deg) ; } } COLAMD_DEBUG1 (("colamd: Dense and null rows killed: %d\n", n_row - n_row2)) ; @@ -842,7 +835,7 @@ static void init_scoring /* add row's external degree */ score += Row [row].shared1.degree - 1 ; /* guard against integer overflow */ - score = COLAMD_MIN (score, n_col) ; + score = (std::min)(score, n_col) ; } /* determine pruned column length */ col_length = (Index) (new_cp - &A [Col [c].start]) ; @@ -914,7 +907,7 @@ static void init_scoring head [score] = c ; /* see if this score is less than current min */ - min_score = COLAMD_MIN (min_score, score) ; + min_score = (std::min)(min_score, score) ; } @@ -1040,7 +1033,7 @@ static Index find_ordering /* return the number of garbage collections */ /* === Garbage_collection, if necessary ============================= */ - needed_memory = COLAMD_MIN (pivot_col_score, n_col - k) ; + needed_memory = (std::min)(pivot_col_score, n_col - k) ; if (pfree + needed_memory >= Alen) { pfree = Eigen::internal::garbage_collection (n_row, n_col, Row, Col, A, &A [pfree]) ; @@ -1099,7 +1092,7 @@ static Index find_ordering /* return the number of garbage collections */ /* clear tag on pivot column */ Col [pivot_col].shared1.thickness = pivot_col_thickness ; - max_deg = COLAMD_MAX (max_deg, pivot_row_degree) ; + max_deg = (std::max)(max_deg, pivot_row_degree) ; /* === Kill all rows used to construct pivot row ==================== */ @@ -1273,7 +1266,7 @@ static Index find_ordering /* return the number of garbage collections */ /* add set difference */ cur_score += row_mark - tag_mark ; /* integer overflow... */ - cur_score = COLAMD_MIN (cur_score, n_col) ; + cur_score = (std::min)(cur_score, n_col) ; } /* recompute the column's length */ @@ -1386,7 +1379,7 @@ static Index find_ordering /* return the number of garbage collections */ cur_score -= Col [col].shared1.thickness ; /* make sure score is less or equal than the max score */ - cur_score = COLAMD_MIN (cur_score, max_score) ; + cur_score = (std::min)(cur_score, max_score) ; COLAMD_ASSERT (cur_score >= 0) ; /* store updated score */ @@ -1409,7 +1402,7 @@ static Index find_ordering /* return the number of garbage collections */ head [cur_score] = col ; /* see if this score is less than current min */ - min_score = COLAMD_MIN (min_score, cur_score) ; + min_score = (std::min)(min_score, cur_score) ; } diff --git a/ground/gcs/src/libs/eigen/Eigen/src/OrderingMethods/Ordering.h b/ground/gcs/src/libs/eigen/Eigen/src/OrderingMethods/Ordering.h index b4da6531a..f3c31f9cb 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/OrderingMethods/Ordering.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/OrderingMethods/Ordering.h @@ -109,7 +109,7 @@ class NaturalOrdering * \class COLAMDOrdering * * Functor computing the \em column \em approximate \em minimum \em degree ordering - * The matrix should be in column-major format + * The matrix should be in column-major and \b compressed format (see SparseMatrix::makeCompressed()). */ template class COLAMDOrdering @@ -118,10 +118,14 @@ class COLAMDOrdering typedef PermutationMatrix PermutationType; typedef Matrix IndexVector; - /** Compute the permutation vector form a sparse matrix */ + /** Compute the permutation vector \a perm form the sparse matrix \a mat + * \warning The input sparse matrix \a mat must be in compressed mode (see SparseMatrix::makeCompressed()). + */ template void operator() (const MatrixType& mat, PermutationType& perm) { + eigen_assert(mat.isCompressed() && "COLAMDOrdering requires a sparse matrix in compressed mode. Call .makeCompressed() before passing it to COLAMDOrdering"); + Index m = mat.rows(); Index n = mat.cols(); Index nnz = mat.nonZeros(); @@ -132,12 +136,12 @@ class COLAMDOrdering Index stats [COLAMD_STATS]; internal::colamd_set_defaults(knobs); - Index info; IndexVector p(n+1), A(Alen); for(Index i=0; i <= n; i++) p(i) = mat.outerIndexPtr()[i]; for(Index i=0; i < nnz; i++) A(i) = mat.innerIndexPtr()[i]; // Call Colamd routine to compute the ordering - info = internal::colamd(m, n, Alen, A.data(), p.data(), knobs, stats); + Index info = internal::colamd(m, n, Alen, A.data(), p.data(), knobs, stats); + EIGEN_UNUSED_VARIABLE(info); eigen_assert( info && "COLAMD failed " ); perm.resize(n); diff --git a/ground/gcs/src/libs/eigen/Eigen/src/PardisoSupport/PardisoSupport.h b/ground/gcs/src/libs/eigen/Eigen/src/PardisoSupport/PardisoSupport.h index 1c48f0df7..18cd7d88a 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/PardisoSupport/PardisoSupport.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/PardisoSupport/PardisoSupport.h @@ -219,7 +219,7 @@ class PardisoImpl void pardisoInit(int type) { m_type = type; - bool symmetric = abs(m_type) < 10; + bool symmetric = std::abs(m_type) < 10; m_iparm[0] = 1; // No solver default m_iparm[1] = 3; // use Metis for the ordering m_iparm[2] = 1; // Numbers of processors, value of OMP_NUM_THREADS diff --git a/ground/gcs/src/libs/eigen/Eigen/src/QR/ColPivHouseholderQR.h b/ground/gcs/src/libs/eigen/Eigen/src/QR/ColPivHouseholderQR.h index 8b01f8179..567eab7cd 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/QR/ColPivHouseholderQR.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/QR/ColPivHouseholderQR.h @@ -76,7 +76,8 @@ template class ColPivHouseholderQR m_colsTranspositions(), m_temp(), m_colSqNorms(), - m_isInitialized(false) {} + m_isInitialized(false), + m_usePrescribedThreshold(false) {} /** \brief Default Constructor with memory preallocation * @@ -349,7 +350,7 @@ template class ColPivHouseholderQR return m_usePrescribedThreshold ? m_prescribedThreshold // this formula comes from experimenting (see "LU precision tuning" thread on the list) // and turns out to be identical to Higham's formula used already in LDLt. - : NumTraits::epsilon() * m_qr.diagonalSize(); + : NumTraits::epsilon() * RealScalar(m_qr.diagonalSize()); } /** \returns the number of nonzero pivots in the QR decomposition. @@ -383,6 +384,12 @@ template class ColPivHouseholderQR } protected: + + static void check_template_parameters() + { + EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); + } + MatrixType m_qr; HCoeffsType m_hCoeffs; PermutationType m_colsPermutation; @@ -421,6 +428,8 @@ typename MatrixType::RealScalar ColPivHouseholderQR::logAbsDetermina template ColPivHouseholderQR& ColPivHouseholderQR::compute(const MatrixType& matrix) { + check_template_parameters(); + using std::abs; Index rows = matrix.rows(); Index cols = matrix.cols(); @@ -462,20 +471,10 @@ ColPivHouseholderQR& ColPivHouseholderQR::compute(const // we store that back into our table: it can't hurt to correct our table. m_colSqNorms.coeffRef(biggest_col_index) = biggest_col_sq_norm; - // if the current biggest column is smaller than epsilon times the initial biggest column, - // terminate to avoid generating nan/inf values. - // Note that here, if we test instead for "biggest == 0", we get a failure every 1000 (or so) - // repetitions of the unit test, with the result of solve() filled with large values of the order - // of 1/(size*epsilon). - if(biggest_col_sq_norm < threshold_helper * RealScalar(rows-k)) - { + // Track the number of meaningful pivots but do not stop the decomposition to make + // sure that the initial matrix is properly reproduced. See bug 941. + if(m_nonzero_pivots==size && biggest_col_sq_norm < threshold_helper * RealScalar(rows-k)) m_nonzero_pivots = k; - m_hCoeffs.tail(size-k).setZero(); - m_qr.bottomRightCorner(rows-k,cols-k) - .template triangularView() - .setZero(); - break; - } // apply the transposition to the columns m_colsTranspositions.coeffRef(k) = biggest_col_index; @@ -504,7 +503,7 @@ ColPivHouseholderQR& ColPivHouseholderQR::compute(const } m_colsPermutation.setIdentity(PermIndexType(cols)); - for(PermIndexType k = 0; k < m_nonzero_pivots; ++k) + for(PermIndexType k = 0; k < size/*m_nonzero_pivots*/; ++k) m_colsPermutation.applyTranspositionOnTheRight(k, PermIndexType(m_colsTranspositions.coeff(k))); m_det_pq = (number_of_transpositions%2) ? -1 : 1; @@ -554,13 +553,15 @@ struct solve_retval, Rhs> } // end namespace internal -/** \returns the matrix Q as a sequence of householder transformations */ +/** \returns the matrix Q as a sequence of householder transformations. + * You can extract the meaningful part only by using: + * \code qr.householderQ().setLength(qr.nonzeroPivots()) \endcode*/ template typename ColPivHouseholderQR::HouseholderSequenceType ColPivHouseholderQR ::householderQ() const { eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized."); - return HouseholderSequenceType(m_qr, m_hCoeffs.conjugate()).setLength(m_nonzero_pivots); + return HouseholderSequenceType(m_qr, m_hCoeffs.conjugate()); } /** \return the column-pivoting Householder QR decomposition of \c *this. diff --git a/ground/gcs/src/libs/eigen/Eigen/src/QR/ColPivHouseholderQR_MKL.h b/ground/gcs/src/libs/eigen/Eigen/src/QR/ColPivHouseholderQR_MKL.h index b5b198326..7b6ba0a5e 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/QR/ColPivHouseholderQR_MKL.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/QR/ColPivHouseholderQR_MKL.h @@ -49,7 +49,6 @@ ColPivHouseholderQR MatrixType; \ - typedef MatrixType::Scalar Scalar; \ typedef MatrixType::RealScalar RealScalar; \ Index rows = matrix.rows();\ Index cols = matrix.cols();\ diff --git a/ground/gcs/src/libs/eigen/Eigen/src/QR/FullPivHouseholderQR.h b/ground/gcs/src/libs/eigen/Eigen/src/QR/FullPivHouseholderQR.h index 0dd5ad347..0b39966e1 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/QR/FullPivHouseholderQR.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/QR/FullPivHouseholderQR.h @@ -63,9 +63,10 @@ template class FullPivHouseholderQR typedef typename MatrixType::Index Index; typedef internal::FullPivHouseholderQRMatrixQReturnType MatrixQReturnType; typedef typename internal::plain_diag_type::type HCoeffsType; - typedef Matrix IntRowVectorType; + typedef Matrix IntDiagSizeVectorType; typedef PermutationMatrix PermutationType; - typedef typename internal::plain_col_type::type IntColVectorType; typedef typename internal::plain_row_type::type RowVectorType; typedef typename internal::plain_col_type::type ColVectorType; @@ -93,10 +94,10 @@ template class FullPivHouseholderQR FullPivHouseholderQR(Index rows, Index cols) : m_qr(rows, cols), m_hCoeffs((std::min)(rows,cols)), - m_rows_transpositions(rows), - m_cols_transpositions(cols), + m_rows_transpositions((std::min)(rows,cols)), + m_cols_transpositions((std::min)(rows,cols)), m_cols_permutation(cols), - m_temp((std::min)(rows,cols)), + m_temp(cols), m_isInitialized(false), m_usePrescribedThreshold(false) {} @@ -115,10 +116,10 @@ template class FullPivHouseholderQR FullPivHouseholderQR(const MatrixType& matrix) : m_qr(matrix.rows(), matrix.cols()), m_hCoeffs((std::min)(matrix.rows(), matrix.cols())), - m_rows_transpositions(matrix.rows()), - m_cols_transpositions(matrix.cols()), + m_rows_transpositions((std::min)(matrix.rows(), matrix.cols())), + m_cols_transpositions((std::min)(matrix.rows(), matrix.cols())), m_cols_permutation(matrix.cols()), - m_temp((std::min)(matrix.rows(), matrix.cols())), + m_temp(matrix.cols()), m_isInitialized(false), m_usePrescribedThreshold(false) { @@ -126,11 +127,12 @@ template class FullPivHouseholderQR } /** This method finds a solution x to the equation Ax=b, where A is the matrix of which - * *this is the QR decomposition, if any exists. + * \c *this is the QR decomposition. * * \param b the right-hand-side of the equation to solve. * - * \returns a solution. + * \returns the exact or least-square solution if the rank is greater or equal to the number of columns of A, + * and an arbitrary solution otherwise. * * \note The case where b is a matrix is not yet implemented. Also, this * code is space inefficient. @@ -172,7 +174,7 @@ template class FullPivHouseholderQR } /** \returns a const reference to the vector of indices representing the rows transpositions */ - const IntColVectorType& rowsTranspositions() const + const IntDiagSizeVectorType& rowsTranspositions() const { eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); return m_rows_transpositions; @@ -344,7 +346,7 @@ template class FullPivHouseholderQR return m_usePrescribedThreshold ? m_prescribedThreshold // this formula comes from experimenting (see "LU precision tuning" thread on the list) // and turns out to be identical to Higham's formula used already in LDLt. - : NumTraits::epsilon() * m_qr.diagonalSize(); + : NumTraits::epsilon() * RealScalar(m_qr.diagonalSize()); } /** \returns the number of nonzero pivots in the QR decomposition. @@ -366,10 +368,16 @@ template class FullPivHouseholderQR RealScalar maxPivot() const { return m_maxpivot; } protected: + + static void check_template_parameters() + { + EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); + } + MatrixType m_qr; HCoeffsType m_hCoeffs; - IntColVectorType m_rows_transpositions; - IntRowVectorType m_cols_transpositions; + IntDiagSizeVectorType m_rows_transpositions; + IntDiagSizeVectorType m_cols_transpositions; PermutationType m_cols_permutation; RowVectorType m_temp; bool m_isInitialized, m_usePrescribedThreshold; @@ -405,6 +413,8 @@ typename MatrixType::RealScalar FullPivHouseholderQR::logAbsDetermin template FullPivHouseholderQR& FullPivHouseholderQR::compute(const MatrixType& matrix) { + check_template_parameters(); + using std::abs; Index rows = matrix.rows(); Index cols = matrix.cols(); @@ -415,10 +425,10 @@ FullPivHouseholderQR& FullPivHouseholderQR::compute(cons m_temp.resize(cols); - m_precision = NumTraits::epsilon() * size; + m_precision = NumTraits::epsilon() * RealScalar(size); - m_rows_transpositions.resize(matrix.rows()); - m_cols_transpositions.resize(matrix.cols()); + m_rows_transpositions.resize(size); + m_cols_transpositions.resize(size); Index number_of_transpositions = 0; RealScalar biggest(0); @@ -516,17 +526,6 @@ struct solve_retval, Rhs> dec().hCoeffs().coeff(k), &temp.coeffRef(0)); } - if(!dec().isSurjective()) - { - // is c is in the image of R ? - RealScalar biggest_in_upper_part_of_c = c.topRows( dec().rank() ).cwiseAbs().maxCoeff(); - RealScalar biggest_in_lower_part_of_c = c.bottomRows(rows-dec().rank()).cwiseAbs().maxCoeff(); - // FIXME brain dead - const RealScalar m_precision = NumTraits::epsilon() * (std::min)(rows,cols); - // this internal:: prefix is needed by at least gcc 3.4 and ICC - if(!internal::isMuchSmallerThan(biggest_in_lower_part_of_c, biggest_in_upper_part_of_c, m_precision)) - return; - } dec().matrixQR() .topLeftCorner(dec().rank(), dec().rank()) .template triangularView() @@ -548,14 +547,14 @@ template struct FullPivHouseholderQRMatrixQReturnType { public: typedef typename MatrixType::Index Index; - typedef typename internal::plain_col_type::type IntColVectorType; + typedef typename FullPivHouseholderQR::IntDiagSizeVectorType IntDiagSizeVectorType; typedef typename internal::plain_diag_type::type HCoeffsType; typedef Matrix WorkVectorType; FullPivHouseholderQRMatrixQReturnType(const MatrixType& qr, const HCoeffsType& hCoeffs, - const IntColVectorType& rowsTranspositions) + const IntDiagSizeVectorType& rowsTranspositions) : m_qr(qr), m_hCoeffs(hCoeffs), m_rowsTranspositions(rowsTranspositions) @@ -595,7 +594,7 @@ public: protected: typename MatrixType::Nested m_qr; typename HCoeffsType::Nested m_hCoeffs; - typename IntColVectorType::Nested m_rowsTranspositions; + typename IntDiagSizeVectorType::Nested m_rowsTranspositions; }; } // end namespace internal diff --git a/ground/gcs/src/libs/eigen/Eigen/src/QR/HouseholderQR.h b/ground/gcs/src/libs/eigen/Eigen/src/QR/HouseholderQR.h index abc61bcbb..343a66499 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/QR/HouseholderQR.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/QR/HouseholderQR.h @@ -189,6 +189,12 @@ template class HouseholderQR const HCoeffsType& hCoeffs() const { return m_hCoeffs; } protected: + + static void check_template_parameters() + { + EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); + } + MatrixType m_qr; HCoeffsType m_hCoeffs; RowVectorType m_temp; @@ -251,56 +257,62 @@ void householder_qr_inplace_unblocked(MatrixQR& mat, HCoeffs& hCoeffs, typename } /** \internal */ -template -void householder_qr_inplace_blocked(MatrixQR& mat, HCoeffs& hCoeffs, - typename MatrixQR::Index maxBlockSize=32, - typename MatrixQR::Scalar* tempData = 0) +template +struct householder_qr_inplace_blocked { - typedef typename MatrixQR::Index Index; - typedef typename MatrixQR::Scalar Scalar; - typedef Block BlockType; - - Index rows = mat.rows(); - Index cols = mat.cols(); - Index size = (std::min)(rows, cols); - - typedef Matrix TempType; - TempType tempVector; - if(tempData==0) + // This is specialized for MKL-supported Scalar types in HouseholderQR_MKL.h + static void run(MatrixQR& mat, HCoeffs& hCoeffs, + typename MatrixQR::Index maxBlockSize=32, + typename MatrixQR::Scalar* tempData = 0) { - tempVector.resize(cols); - tempData = tempVector.data(); - } + typedef typename MatrixQR::Index Index; + typedef typename MatrixQR::Scalar Scalar; + typedef Block BlockType; - Index blockSize = (std::min)(maxBlockSize,size); + Index rows = mat.rows(); + Index cols = mat.cols(); + Index size = (std::min)(rows, cols); - Index k = 0; - for (k = 0; k < size; k += blockSize) - { - Index bs = (std::min)(size-k,blockSize); // actual size of the block - Index tcols = cols - k - bs; // trailing columns - Index brows = rows-k; // rows of the block - - // partition the matrix: - // A00 | A01 | A02 - // mat = A10 | A11 | A12 - // A20 | A21 | A22 - // and performs the qr dec of [A11^T A12^T]^T - // and update [A21^T A22^T]^T using level 3 operations. - // Finally, the algorithm continue on A22 - - BlockType A11_21 = mat.block(k,k,brows,bs); - Block hCoeffsSegment = hCoeffs.segment(k,bs); - - householder_qr_inplace_unblocked(A11_21, hCoeffsSegment, tempData); - - if(tcols) + typedef Matrix TempType; + TempType tempVector; + if(tempData==0) { - BlockType A21_22 = mat.block(k,k+bs,brows,tcols); - apply_block_householder_on_the_left(A21_22,A11_21,hCoeffsSegment.adjoint()); + tempVector.resize(cols); + tempData = tempVector.data(); + } + + Index blockSize = (std::min)(maxBlockSize,size); + + Index k = 0; + for (k = 0; k < size; k += blockSize) + { + Index bs = (std::min)(size-k,blockSize); // actual size of the block + Index tcols = cols - k - bs; // trailing columns + Index brows = rows-k; // rows of the block + + // partition the matrix: + // A00 | A01 | A02 + // mat = A10 | A11 | A12 + // A20 | A21 | A22 + // and performs the qr dec of [A11^T A12^T]^T + // and update [A21^T A22^T]^T using level 3 operations. + // Finally, the algorithm continue on A22 + + BlockType A11_21 = mat.block(k,k,brows,bs); + Block hCoeffsSegment = hCoeffs.segment(k,bs); + + householder_qr_inplace_unblocked(A11_21, hCoeffsSegment, tempData); + + if(tcols) + { + BlockType A21_22 = mat.block(k,k+bs,brows,tcols); + apply_block_householder_on_the_left(A21_22,A11_21,hCoeffsSegment.adjoint()); + } } } -} +}; template struct solve_retval, Rhs> @@ -343,6 +355,8 @@ struct solve_retval, Rhs> template HouseholderQR& HouseholderQR::compute(const MatrixType& matrix) { + check_template_parameters(); + Index rows = matrix.rows(); Index cols = matrix.cols(); Index size = (std::min)(rows,cols); @@ -352,7 +366,7 @@ HouseholderQR& HouseholderQR::compute(const MatrixType& m_temp.resize(cols); - internal::householder_qr_inplace_blocked(m_qr, m_hCoeffs, 48, m_temp.data()); + internal::householder_qr_inplace_blocked::run(m_qr, m_hCoeffs, 48, m_temp.data()); m_isInitialized = true; return *this; diff --git a/ground/gcs/src/libs/eigen/Eigen/src/QR/HouseholderQR_MKL.h b/ground/gcs/src/libs/eigen/Eigen/src/QR/HouseholderQR_MKL.h index 5313de604..b80f1b48d 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/QR/HouseholderQR_MKL.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/QR/HouseholderQR_MKL.h @@ -34,28 +34,30 @@ #ifndef EIGEN_QR_MKL_H #define EIGEN_QR_MKL_H -#include "Eigen/src/Core/util/MKL_support.h" +#include "../Core/util/MKL_support.h" namespace Eigen { -namespace internal { + namespace internal { -/** \internal Specialization for the data types supported by MKL */ + /** \internal Specialization for the data types supported by MKL */ #define EIGEN_MKL_QR_NOPIV(EIGTYPE, MKLTYPE, MKLPREFIX) \ template \ -void householder_qr_inplace_blocked(MatrixQR& mat, HCoeffs& hCoeffs, \ - typename MatrixQR::Index maxBlockSize=32, \ - EIGTYPE* tempData = 0) \ +struct householder_qr_inplace_blocked \ { \ - lapack_int m = mat.rows(); \ - lapack_int n = mat.cols(); \ - lapack_int lda = mat.outerStride(); \ - lapack_int matrix_order = (MatrixQR::IsRowMajor) ? LAPACK_ROW_MAJOR : LAPACK_COL_MAJOR; \ - LAPACKE_##MKLPREFIX##geqrf( matrix_order, m, n, (MKLTYPE*)mat.data(), lda, (MKLTYPE*)hCoeffs.data()); \ - hCoeffs.adjointInPlace(); \ -\ -} + static void run(MatrixQR& mat, HCoeffs& hCoeffs, \ + typename MatrixQR::Index = 32, \ + typename MatrixQR::Scalar* = 0) \ + { \ + lapack_int m = (lapack_int) mat.rows(); \ + lapack_int n = (lapack_int) mat.cols(); \ + lapack_int lda = (lapack_int) mat.outerStride(); \ + lapack_int matrix_order = (MatrixQR::IsRowMajor) ? LAPACK_ROW_MAJOR : LAPACK_COL_MAJOR; \ + LAPACKE_##MKLPREFIX##geqrf( matrix_order, m, n, (MKLTYPE*)mat.data(), lda, (MKLTYPE*)hCoeffs.data()); \ + hCoeffs.adjointInPlace(); \ + } \ +}; EIGEN_MKL_QR_NOPIV(double, double, d) EIGEN_MKL_QR_NOPIV(float, float, s) diff --git a/ground/gcs/src/libs/eigen/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h b/ground/gcs/src/libs/eigen/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h index aa41f434c..36138101d 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h @@ -47,7 +47,7 @@ namespace Eigen { * You can then apply it to a vector. * * R is the sparse triangular factor. Use matrixQR() to get it as SparseMatrix. - * NOTE : The Index type of R is always UF_long. You can get it with SPQR::Index + * NOTE : The Index type of R is always SuiteSparse_long. You can get it with SPQR::Index * * \tparam _MatrixType The type of the sparse matrix A, must be a column-major SparseMatrix<> * NOTE @@ -59,22 +59,18 @@ class SPQR public: typedef typename _MatrixType::Scalar Scalar; typedef typename _MatrixType::RealScalar RealScalar; - typedef UF_long Index ; + typedef SuiteSparse_long Index ; typedef SparseMatrix MatrixType; typedef PermutationMatrix PermutationType; public: SPQR() - : m_ordering(SPQR_ORDERING_DEFAULT), - m_allow_tol(SPQR_DEFAULT_TOL), - m_tolerance (NumTraits::epsilon()) + : m_isInitialized(false), m_ordering(SPQR_ORDERING_DEFAULT), m_allow_tol(SPQR_DEFAULT_TOL), m_tolerance (NumTraits::epsilon()), m_useDefaultThreshold(true) { cholmod_l_start(&m_cc); } - SPQR(const _MatrixType& matrix) - : m_ordering(SPQR_ORDERING_DEFAULT), - m_allow_tol(SPQR_DEFAULT_TOL), - m_tolerance (NumTraits::epsilon()) + SPQR(const _MatrixType& matrix) + : m_isInitialized(false), m_ordering(SPQR_ORDERING_DEFAULT), m_allow_tol(SPQR_DEFAULT_TOL), m_tolerance (NumTraits::epsilon()), m_useDefaultThreshold(true) { cholmod_l_start(&m_cc); compute(matrix); @@ -82,21 +78,43 @@ class SPQR ~SPQR() { - // Calls SuiteSparseQR_free() + SPQR_free(); + cholmod_l_finish(&m_cc); + } + void SPQR_free() + { cholmod_l_free_sparse(&m_H, &m_cc); cholmod_l_free_sparse(&m_cR, &m_cc); cholmod_l_free_dense(&m_HTau, &m_cc); std::free(m_E); std::free(m_HPinv); - cholmod_l_finish(&m_cc); } + void compute(const _MatrixType& matrix) { + if(m_isInitialized) SPQR_free(); + MatrixType mat(matrix); + + /* Compute the default threshold as in MatLab, see: + * Tim Davis, "Algorithm 915, SuiteSparseQR: Multifrontal Multithreaded Rank-Revealing + * Sparse QR Factorization, ACM Trans. on Math. Soft. 38(1), 2011, Page 8:3 + */ + RealScalar pivotThreshold = m_tolerance; + if(m_useDefaultThreshold) + { + using std::max; + RealScalar max2Norm = 0.0; + for (int j = 0; j < mat.cols(); j++) max2Norm = (max)(max2Norm, mat.col(j).norm()); + if(max2Norm==RealScalar(0)) + max2Norm = RealScalar(1); + pivotThreshold = 20 * (mat.rows() + mat.cols()) * max2Norm * NumTraits::epsilon(); + } + cholmod_sparse A; A = viewAsCholmod(mat); Index col = matrix.cols(); - m_rank = SuiteSparseQR(m_ordering, m_tolerance, col, &A, + m_rank = SuiteSparseQR(m_ordering, pivotThreshold, col, &A, &m_cR, &m_E, &m_H, &m_HPinv, &m_HTau, &m_cc); if (!m_cR) @@ -112,7 +130,7 @@ class SPQR /** * Get the number of rows of the input matrix and the Q matrix */ - inline Index rows() const {return m_H->nrow; } + inline Index rows() const {return m_cR->nrow; } /** * Get the number of columns of the input matrix. @@ -137,16 +155,25 @@ class SPQR { eigen_assert(m_isInitialized && " The QR factorization should be computed first, call compute()"); eigen_assert(b.cols()==1 && "This method is for vectors only"); - + //Compute Q^T * b - Dest y; + typename Dest::PlainObject y, y2; y = matrixQ().transpose() * b; - // Solves with the triangular matrix R + + // Solves with the triangular matrix R Index rk = this->rank(); - y.topRows(rk) = this->matrixR().topLeftCorner(rk, rk).template triangularView().solve(y.topRows(rk)); - y.bottomRows(cols()-rk).setZero(); + y2 = y; + y.resize((std::max)(cols(),Index(y.rows())),y.cols()); + y.topRows(rk) = this->matrixR().topLeftCorner(rk, rk).template triangularView().solve(y2.topRows(rk)); + // Apply the column permutation - dest.topRows(cols()) = colsPermutation() * y.topRows(cols()); + // colsPermutation() performs a copy of the permutation, + // so let's apply it manually: + for(Index i = 0; i < rk; ++i) dest.row(m_E[i]) = y.row(i); + for(Index i = rk; i < cols(); ++i) dest.row(m_E[i]).setZero(); + +// y.bottomRows(y.rows()-rk).setZero(); +// dest = colsPermutation() * y.topRows(cols()); m_info = Success; } @@ -189,7 +216,11 @@ class SPQR /// Set the fill-reducing ordering method to be used void setSPQROrdering(int ord) { m_ordering = ord;} /// Set the tolerance tol to treat columns with 2-norm < =tol as zero - void setPivotThreshold(const RealScalar& tol) { m_tolerance = tol; } + void setPivotThreshold(const RealScalar& tol) + { + m_useDefaultThreshold = false; + m_tolerance = tol; + } /** \returns a pointer to the SPQR workspace */ cholmod_common *cholmodCommon() const { return &m_cc; } @@ -222,6 +253,7 @@ class SPQR mutable cholmod_dense *m_HTau; // The Householder coefficients mutable Index m_rank; // The rank of the matrix mutable cholmod_common m_cc; // Workspace and parameters + bool m_useDefaultThreshold; // Use default threshold template friend struct SPQR_QProduct; }; diff --git a/ground/gcs/src/libs/eigen/Eigen/src/SVD/JacobiSVD.h b/ground/gcs/src/libs/eigen/Eigen/src/SVD/JacobiSVD.h index 4786768ff..89ace381e 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/SVD/JacobiSVD.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/SVD/JacobiSVD.h @@ -375,14 +375,19 @@ struct svd_precondition_2x2_block_to_be_real Scalar z; JacobiRotation rot; RealScalar n = sqrt(numext::abs2(work_matrix.coeff(p,p)) + numext::abs2(work_matrix.coeff(q,p))); + if(n==0) { z = abs(work_matrix.coeff(p,q)) / work_matrix.coeff(p,q); work_matrix.row(p) *= z; if(svd.computeU()) svd.m_matrixU.col(p) *= conj(z); - z = abs(work_matrix.coeff(q,q)) / work_matrix.coeff(q,q); - work_matrix.row(q) *= z; - if(svd.computeU()) svd.m_matrixU.col(q) *= conj(z); + if(work_matrix.coeff(q,q)!=Scalar(0)) + { + z = abs(work_matrix.coeff(q,q)) / work_matrix.coeff(q,q); + work_matrix.row(q) *= z; + if(svd.computeU()) svd.m_matrixU.col(q) *= conj(z); + } + // otherwise the second row is already zero, so we have nothing to do. } else { @@ -412,6 +417,7 @@ void real_2x2_jacobi_svd(const MatrixType& matrix, Index p, Index q, JacobiRotation *j_right) { using std::sqrt; + using std::abs; Matrix m; m << numext::real(matrix.coeff(p,p)), numext::real(matrix.coeff(p,q)), numext::real(matrix.coeff(q,p)), numext::real(matrix.coeff(q,q)); @@ -425,9 +431,11 @@ void real_2x2_jacobi_svd(const MatrixType& matrix, Index p, Index q, } else { - RealScalar u = d / t; - rot1.c() = RealScalar(1) / sqrt(RealScalar(1) + numext::abs2(u)); - rot1.s() = rot1.c() * u; + RealScalar t2d2 = numext::hypot(t,d); + rot1.c() = abs(t)/t2d2; + rot1.s() = d/t2d2; + if(tmakeJacobi(m,0,1); @@ -528,8 +536,9 @@ template class JacobiSVD JacobiSVD() : m_isInitialized(false), m_isAllocated(false), + m_usePrescribedThreshold(false), m_computationOptions(0), - m_rows(-1), m_cols(-1) + m_rows(-1), m_cols(-1), m_diagSize(0) {} @@ -542,6 +551,7 @@ template class JacobiSVD JacobiSVD(Index rows, Index cols, unsigned int computationOptions = 0) : m_isInitialized(false), m_isAllocated(false), + m_usePrescribedThreshold(false), m_computationOptions(0), m_rows(-1), m_cols(-1) { @@ -561,6 +571,7 @@ template class JacobiSVD JacobiSVD(const MatrixType& matrix, unsigned int computationOptions = 0) : m_isInitialized(false), m_isAllocated(false), + m_usePrescribedThreshold(false), m_computationOptions(0), m_rows(-1), m_cols(-1) { @@ -662,23 +673,92 @@ template class JacobiSVD eigen_assert(m_isInitialized && "JacobiSVD is not initialized."); return m_nonzeroSingularValues; } + + /** \returns the rank of the matrix of which \c *this is the SVD. + * + * \note This method has to determine which singular values should be considered nonzero. + * For that, it uses the threshold value that you can control by calling + * setThreshold(const RealScalar&). + */ + inline Index rank() const + { + using std::abs; + eigen_assert(m_isInitialized && "JacobiSVD is not initialized."); + if(m_singularValues.size()==0) return 0; + RealScalar premultiplied_threshold = m_singularValues.coeff(0) * threshold(); + Index i = m_nonzeroSingularValues-1; + while(i>=0 && m_singularValues.coeff(i) < premultiplied_threshold) --i; + return i+1; + } + + /** Allows to prescribe a threshold to be used by certain methods, such as rank() and solve(), + * which need to determine when singular values are to be considered nonzero. + * This is not used for the SVD decomposition itself. + * + * When it needs to get the threshold value, Eigen calls threshold(). + * The default is \c NumTraits::epsilon() + * + * \param threshold The new value to use as the threshold. + * + * A singular value will be considered nonzero if its value is strictly greater than + * \f$ \vert singular value \vert \leqslant threshold \times \vert max singular value \vert \f$. + * + * If you want to come back to the default behavior, call setThreshold(Default_t) + */ + JacobiSVD& setThreshold(const RealScalar& threshold) + { + m_usePrescribedThreshold = true; + m_prescribedThreshold = threshold; + return *this; + } + + /** Allows to come back to the default behavior, letting Eigen use its default formula for + * determining the threshold. + * + * You should pass the special object Eigen::Default as parameter here. + * \code svd.setThreshold(Eigen::Default); \endcode + * + * See the documentation of setThreshold(const RealScalar&). + */ + JacobiSVD& setThreshold(Default_t) + { + m_usePrescribedThreshold = false; + return *this; + } + + /** Returns the threshold that will be used by certain methods such as rank(). + * + * See the documentation of setThreshold(const RealScalar&). + */ + RealScalar threshold() const + { + eigen_assert(m_isInitialized || m_usePrescribedThreshold); + return m_usePrescribedThreshold ? m_prescribedThreshold + : (std::max)(1,m_diagSize)*NumTraits::epsilon(); + } inline Index rows() const { return m_rows; } inline Index cols() const { return m_cols; } private: void allocate(Index rows, Index cols, unsigned int computationOptions); + + static void check_template_parameters() + { + EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); + } protected: MatrixUType m_matrixU; MatrixVType m_matrixV; SingularValuesType m_singularValues; WorkMatrixType m_workMatrix; - bool m_isInitialized, m_isAllocated; + bool m_isInitialized, m_isAllocated, m_usePrescribedThreshold; bool m_computeFullU, m_computeThinU; bool m_computeFullV, m_computeThinV; unsigned int m_computationOptions; Index m_nonzeroSingularValues, m_rows, m_cols, m_diagSize; + RealScalar m_prescribedThreshold; template friend struct internal::svd_precondition_2x2_block_to_be_real; @@ -687,6 +767,7 @@ template class JacobiSVD internal::qr_preconditioner_impl m_qr_precond_morecols; internal::qr_preconditioner_impl m_qr_precond_morerows; + MatrixType m_scaledMatrix; }; template @@ -733,14 +814,17 @@ void JacobiSVD::allocate(Index rows, Index cols, u : 0); m_workMatrix.resize(m_diagSize, m_diagSize); - if(m_cols>m_rows) m_qr_precond_morecols.allocate(*this); - if(m_rows>m_cols) m_qr_precond_morerows.allocate(*this); + if(m_cols>m_rows) m_qr_precond_morecols.allocate(*this); + if(m_rows>m_cols) m_qr_precond_morerows.allocate(*this); + if(m_rows!=m_cols) m_scaledMatrix.resize(rows,cols); } template JacobiSVD& JacobiSVD::compute(const MatrixType& matrix, unsigned int computationOptions) { + check_template_parameters(); + using std::abs; allocate(matrix.rows(), matrix.cols(), computationOptions); @@ -751,11 +835,21 @@ JacobiSVD::compute(const MatrixType& matrix, unsig // limit for very small denormal numbers to be considered zero in order to avoid infinite loops (see bug 286) const RealScalar considerAsZero = RealScalar(2) * std::numeric_limits::denorm_min(); + // Scaling factor to reduce over/under-flows + RealScalar scale = matrix.cwiseAbs().maxCoeff(); + if(scale==RealScalar(0)) scale = RealScalar(1); + /*** step 1. The R-SVD step: we use a QR decomposition to reduce to the case of a square matrix */ - if(!m_qr_precond_morecols.run(*this, matrix) && !m_qr_precond_morerows.run(*this, matrix)) + if(m_rows!=m_cols) { - m_workMatrix = matrix.block(0,0,m_diagSize,m_diagSize); + m_scaledMatrix = matrix / scale; + m_qr_precond_morecols.run(*this, m_scaledMatrix); + m_qr_precond_morerows.run(*this, m_scaledMatrix); + } + else + { + m_workMatrix = matrix.block(0,0,m_diagSize,m_diagSize) / scale; if(m_computeFullU) m_matrixU.setIdentity(m_rows,m_rows); if(m_computeThinU) m_matrixU.setIdentity(m_rows,m_diagSize); if(m_computeFullV) m_matrixV.setIdentity(m_cols,m_cols); @@ -781,7 +875,8 @@ JacobiSVD::compute(const MatrixType& matrix, unsig using std::max; RealScalar threshold = (max)(considerAsZero, precision * (max)(abs(m_workMatrix.coeff(p,p)), abs(m_workMatrix.coeff(q,q)))); - if((max)(abs(m_workMatrix.coeff(p,q)),abs(m_workMatrix.coeff(q,p))) > threshold) + // We compare both values to threshold instead of calling max to be robust to NaN (See bug 791) + if(abs(m_workMatrix.coeff(p,q))>threshold || abs(m_workMatrix.coeff(q,p)) > threshold) { finished = false; @@ -830,6 +925,8 @@ JacobiSVD::compute(const MatrixType& matrix, unsig if(computeV()) m_matrixV.col(pos).swap(m_matrixV.col(i)); } } + + m_singularValues *= scale; m_isInitialized = true; return *this; @@ -851,11 +948,11 @@ struct solve_retval, Rhs> // So A^{-1} = V S^{-1} U^* Matrix tmp; - Index nonzeroSingVals = dec().nonzeroSingularValues(); + Index rank = dec().rank(); - tmp.noalias() = dec().matrixU().leftCols(nonzeroSingVals).adjoint() * rhs(); - tmp = dec().singularValues().head(nonzeroSingVals).asDiagonal().inverse() * tmp; - dst = dec().matrixV().leftCols(nonzeroSingVals) * tmp; + tmp.noalias() = dec().matrixU().leftCols(rank).adjoint() * rhs(); + tmp = dec().singularValues().head(rank).asDiagonal().inverse() * tmp; + dst = dec().matrixV().leftCols(rank) * tmp; } }; } // end namespace internal diff --git a/ground/gcs/src/libs/eigen/Eigen/src/SVD/JacobiSVD_MKL.h b/ground/gcs/src/libs/eigen/Eigen/src/SVD/JacobiSVD_MKL.h index decda7540..14e461c4e 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/SVD/JacobiSVD_MKL.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/SVD/JacobiSVD_MKL.h @@ -45,8 +45,8 @@ JacobiSVD, ColPiv JacobiSVD, ColPivHouseholderQRPreconditioner>::compute(const Matrix& matrix, unsigned int computationOptions) \ { \ typedef Matrix MatrixType; \ - typedef MatrixType::Scalar Scalar; \ - typedef MatrixType::RealScalar RealScalar; \ + /*typedef MatrixType::Scalar Scalar;*/ \ + /*typedef MatrixType::RealScalar RealScalar;*/ \ allocate(matrix.rows(), matrix.cols(), computationOptions); \ \ /*const RealScalar precision = RealScalar(2) * NumTraits::epsilon();*/ \ diff --git a/ground/gcs/src/libs/eigen/Eigen/src/SparseCholesky/SimplicialCholesky.h b/ground/gcs/src/libs/eigen/Eigen/src/SparseCholesky/SimplicialCholesky.h index f41d7e010..e1f96ba5a 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/SparseCholesky/SimplicialCholesky.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/SparseCholesky/SimplicialCholesky.h @@ -37,6 +37,7 @@ class SimplicialCholeskyBase : internal::noncopyable { public: typedef typename internal::traits::MatrixType MatrixType; + typedef typename internal::traits::OrderingType OrderingType; enum { UpLo = internal::traits::UpLo }; typedef typename MatrixType::Scalar Scalar; typedef typename MatrixType::RealScalar RealScalar; @@ -240,15 +241,16 @@ class SimplicialCholeskyBase : internal::noncopyable RealScalar m_shiftScale; }; -template class SimplicialLLT; -template class SimplicialLDLT; -template class SimplicialCholesky; +template > class SimplicialLLT; +template > class SimplicialLDLT; +template > class SimplicialCholesky; namespace internal { -template struct traits > +template struct traits > { typedef _MatrixType MatrixType; + typedef _Ordering OrderingType; enum { UpLo = _UpLo }; typedef typename MatrixType::Scalar Scalar; typedef typename MatrixType::Index Index; @@ -259,9 +261,10 @@ template struct traits struct traits > +template struct traits > { typedef _MatrixType MatrixType; + typedef _Ordering OrderingType; enum { UpLo = _UpLo }; typedef typename MatrixType::Scalar Scalar; typedef typename MatrixType::Index Index; @@ -272,9 +275,10 @@ template struct traits struct traits > +template struct traits > { typedef _MatrixType MatrixType; + typedef _Ordering OrderingType; enum { UpLo = _UpLo }; }; @@ -294,11 +298,12 @@ template struct traits * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower * or Upper. Default is Lower. + * \tparam _Ordering The ordering method to use, either AMDOrdering<> or NaturalOrdering<>. Default is AMDOrdering<> * - * \sa class SimplicialLDLT + * \sa class SimplicialLDLT, class AMDOrdering, class NaturalOrdering */ -template - class SimplicialLLT : public SimplicialCholeskyBase > +template + class SimplicialLLT : public SimplicialCholeskyBase > { public: typedef _MatrixType MatrixType; @@ -382,11 +387,12 @@ public: * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower * or Upper. Default is Lower. + * \tparam _Ordering The ordering method to use, either AMDOrdering<> or NaturalOrdering<>. Default is AMDOrdering<> * - * \sa class SimplicialLLT + * \sa class SimplicialLLT, class AMDOrdering, class NaturalOrdering */ -template - class SimplicialLDLT : public SimplicialCholeskyBase > +template + class SimplicialLDLT : public SimplicialCholeskyBase > { public: typedef _MatrixType MatrixType; @@ -467,8 +473,8 @@ public: * * \sa class SimplicialLDLT, class SimplicialLLT */ -template - class SimplicialCholesky : public SimplicialCholeskyBase > +template + class SimplicialCholesky : public SimplicialCholeskyBase > { public: typedef _MatrixType MatrixType; @@ -612,15 +618,13 @@ void SimplicialCholeskyBase::ordering(const MatrixType& a, CholMatrixTy { eigen_assert(a.rows()==a.cols()); const Index size = a.rows(); - // TODO allows to configure the permutation // Note that amd compute the inverse permutation { CholMatrixType C; C = a.template selfadjointView(); - // remove diagonal entries: - // seems not to be needed - // C.prune(keep_diag()); - internal::minimum_degree_ordering(C, m_Pinv); + + OrderingType ordering; + ordering(C,m_Pinv); } if(m_Pinv.size()>0) diff --git a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/AmbiVector.h b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/AmbiVector.h index 17fff96a7..220c6451c 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/AmbiVector.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/AmbiVector.h @@ -69,7 +69,7 @@ class AmbiVector delete[] m_buffer; if (size<1000) { - Index allocSize = (size * sizeof(ListEl))/sizeof(Scalar); + Index allocSize = (size * sizeof(ListEl) + sizeof(Scalar) - 1)/sizeof(Scalar); m_allocatedElements = (allocSize*sizeof(Scalar))/sizeof(ListEl); m_buffer = new Scalar[allocSize]; } @@ -88,7 +88,7 @@ class AmbiVector Index copyElements = m_allocatedElements; m_allocatedElements = (std::min)(Index(m_allocatedElements*1.5),m_size); Index allocSize = m_allocatedElements * sizeof(ListEl); - allocSize = allocSize/sizeof(Scalar) + (allocSize%sizeof(Scalar)>0?1:0); + allocSize = (allocSize + sizeof(Scalar) - 1)/sizeof(Scalar); Scalar* newBuffer = new Scalar[allocSize]; memcpy(newBuffer, m_buffer, copyElements * sizeof(ListEl)); delete[] m_buffer; diff --git a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/CompressedStorage.h b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/CompressedStorage.h index 3321fab4a..a667cb56e 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/CompressedStorage.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/CompressedStorage.h @@ -51,8 +51,8 @@ class CompressedStorage CompressedStorage& operator=(const CompressedStorage& other) { resize(other.size()); - memcpy(m_values, other.m_values, m_size * sizeof(Scalar)); - memcpy(m_indices, other.m_indices, m_size * sizeof(Index)); + internal::smart_copy(other.m_values, other.m_values + m_size, m_values); + internal::smart_copy(other.m_indices, other.m_indices + m_size, m_indices); return *this; } @@ -83,10 +83,10 @@ class CompressedStorage reallocate(m_size); } - void resize(size_t size, float reserveSizeFactor = 0) + void resize(size_t size, double reserveSizeFactor = 0) { if (m_allocatedSize1) std::sort(indices.data(),indices.data()+nnz); - for(int k=0; k RowMajorMatrix; - typedef SparseMatrix ColMajorMatrix; + typedef SparseMatrix RowMajorMatrix; + typedef SparseMatrix ColMajorMatrix; ColMajorMatrix resCol(lhs.rows(),rhs.cols()); internal::conservative_sparse_sparse_product_impl(lhs, rhs, resCol); // sort the non zeros: @@ -149,7 +149,7 @@ struct conservative_sparse_sparse_product_selector RowMajorMatrix; + typedef SparseMatrix RowMajorMatrix; RowMajorMatrix rhsRow = rhs; RowMajorMatrix resRow(lhs.rows(), rhs.cols()); internal::conservative_sparse_sparse_product_impl(rhsRow, lhs, resRow); @@ -162,7 +162,7 @@ struct conservative_sparse_sparse_product_selector RowMajorMatrix; + typedef SparseMatrix RowMajorMatrix; RowMajorMatrix lhsRow = lhs; RowMajorMatrix resRow(lhs.rows(), rhs.cols()); internal::conservative_sparse_sparse_product_impl(rhs, lhsRow, resRow); @@ -175,7 +175,7 @@ struct conservative_sparse_sparse_product_selector RowMajorMatrix; + typedef SparseMatrix RowMajorMatrix; RowMajorMatrix resRow(lhs.rows(), rhs.cols()); internal::conservative_sparse_sparse_product_impl(rhs, lhs, resRow); res = resRow; @@ -190,7 +190,7 @@ struct conservative_sparse_sparse_product_selector ColMajorMatrix; + typedef SparseMatrix ColMajorMatrix; ColMajorMatrix resCol(lhs.rows(), rhs.cols()); internal::conservative_sparse_sparse_product_impl(lhs, rhs, resCol); res = resCol; @@ -202,7 +202,7 @@ struct conservative_sparse_sparse_product_selector ColMajorMatrix; + typedef SparseMatrix ColMajorMatrix; ColMajorMatrix lhsCol = lhs; ColMajorMatrix resCol(lhs.rows(), rhs.cols()); internal::conservative_sparse_sparse_product_impl(lhsCol, rhs, resCol); @@ -215,7 +215,7 @@ struct conservative_sparse_sparse_product_selector ColMajorMatrix; + typedef SparseMatrix ColMajorMatrix; ColMajorMatrix rhsCol = rhs; ColMajorMatrix resCol(lhs.rows(), rhs.cols()); internal::conservative_sparse_sparse_product_impl(lhs, rhsCol, resCol); @@ -228,8 +228,8 @@ struct conservative_sparse_sparse_product_selector RowMajorMatrix; - typedef SparseMatrix ColMajorMatrix; + typedef SparseMatrix RowMajorMatrix; + typedef SparseMatrix ColMajorMatrix; RowMajorMatrix resRow(lhs.rows(),rhs.cols()); internal::conservative_sparse_sparse_product_impl(rhs, lhs, resRow); // sort the non zeros: diff --git a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/MappedSparseMatrix.h b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/MappedSparseMatrix.h index 93cd4832d..ab1a266a9 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/MappedSparseMatrix.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/MappedSparseMatrix.h @@ -50,6 +50,8 @@ class MappedSparseMatrix inline Index cols() const { return IsRowMajor ? m_innerSize : m_outerSize; } inline Index innerSize() const { return m_innerSize; } inline Index outerSize() const { return m_outerSize; } + + bool isCompressed() const { return true; } //---------------------------------------- // direct access interface diff --git a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseBlock.h b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseBlock.h index 0b3e193db..4f4983508 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseBlock.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseBlock.h @@ -57,6 +57,16 @@ public: inline BlockImpl(const XprType& xpr, int startRow, int startCol, int blockRows, int blockCols) : m_matrix(xpr), m_outerStart(IsRowMajor ? startRow : startCol), m_outerSize(IsRowMajor ? blockRows : blockCols) {} + + inline const Scalar coeff(int row, int col) const + { + return m_matrix.coeff(row + IsRowMajor ? m_outerStart : 0, col +IsRowMajor ? 0 : m_outerStart); + } + + inline const Scalar coeff(int index) const + { + return m_matrix.coeff(IsRowMajor ? m_outerStart : index, IsRowMajor ? index : m_outerStart); + } EIGEN_STRONG_INLINE Index rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); } EIGEN_STRONG_INLINE Index cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); } @@ -66,6 +76,10 @@ public: typename XprType::Nested m_matrix; Index m_outerStart; const internal::variable_if_dynamic m_outerSize; + + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl) + private: + Index nonZeros() const; }; @@ -80,6 +94,7 @@ class BlockImpl,BlockRows,BlockCols,true typedef SparseMatrix<_Scalar, _Options, _Index> SparseMatrixType; typedef typename internal::remove_all::type _MatrixTypeNested; typedef Block BlockType; + typedef Block ConstBlockType; public: enum { IsRowMajor = internal::traits::IsRowMajor }; EIGEN_SPARSE_PUBLIC_INTERFACE(BlockType) @@ -221,6 +236,21 @@ public: else return Map >(m_matrix.innerNonZeroPtr()+m_outerStart, m_outerSize.value()).sum(); } + + inline Scalar& coeffRef(int row, int col) + { + return m_matrix.const_cast_derived().coeffRef(row + (IsRowMajor ? m_outerStart : 0), col + (IsRowMajor ? 0 : m_outerStart)); + } + + inline const Scalar coeff(int row, int col) const + { + return m_matrix.coeff(row + (IsRowMajor ? m_outerStart : 0), col + (IsRowMajor ? 0 : m_outerStart)); + } + + inline const Scalar coeff(int index) const + { + return m_matrix.coeff(IsRowMajor ? m_outerStart : index, IsRowMajor ? index : m_outerStart); + } const Scalar& lastCoeff() const { @@ -243,6 +273,104 @@ public: }; + +template +class BlockImpl,BlockRows,BlockCols,true,Sparse> + : public SparseMatrixBase,BlockRows,BlockCols,true> > +{ + typedef SparseMatrix<_Scalar, _Options, _Index> SparseMatrixType; + typedef typename internal::remove_all::type _MatrixTypeNested; + typedef Block BlockType; +public: + enum { IsRowMajor = internal::traits::IsRowMajor }; + EIGEN_SPARSE_PUBLIC_INTERFACE(BlockType) +protected: + enum { OuterSize = IsRowMajor ? BlockRows : BlockCols }; +public: + + class InnerIterator: public SparseMatrixType::InnerIterator + { + public: + inline InnerIterator(const BlockType& xpr, Index outer) + : SparseMatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer) + {} + inline Index row() const { return IsRowMajor ? m_outer : this->index(); } + inline Index col() const { return IsRowMajor ? this->index() : m_outer; } + protected: + Index m_outer; + }; + class ReverseInnerIterator: public SparseMatrixType::ReverseInnerIterator + { + public: + inline ReverseInnerIterator(const BlockType& xpr, Index outer) + : SparseMatrixType::ReverseInnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer) + {} + inline Index row() const { return IsRowMajor ? m_outer : this->index(); } + inline Index col() const { return IsRowMajor ? this->index() : m_outer; } + protected: + Index m_outer; + }; + + inline BlockImpl(const SparseMatrixType& xpr, int i) + : m_matrix(xpr), m_outerStart(i), m_outerSize(OuterSize) + {} + + inline BlockImpl(const SparseMatrixType& xpr, int startRow, int startCol, int blockRows, int blockCols) + : m_matrix(xpr), m_outerStart(IsRowMajor ? startRow : startCol), m_outerSize(IsRowMajor ? blockRows : blockCols) + {} + + inline const Scalar* valuePtr() const + { return m_matrix.valuePtr() + m_matrix.outerIndexPtr()[m_outerStart]; } + + inline const Index* innerIndexPtr() const + { return m_matrix.innerIndexPtr() + m_matrix.outerIndexPtr()[m_outerStart]; } + + inline const Index* outerIndexPtr() const + { return m_matrix.outerIndexPtr() + m_outerStart; } + + Index nonZeros() const + { + if(m_matrix.isCompressed()) + return std::size_t(m_matrix.outerIndexPtr()[m_outerStart+m_outerSize.value()]) + - std::size_t(m_matrix.outerIndexPtr()[m_outerStart]); + else if(m_outerSize.value()==0) + return 0; + else + return Map >(m_matrix.innerNonZeroPtr()+m_outerStart, m_outerSize.value()).sum(); + } + + inline const Scalar coeff(int row, int col) const + { + return m_matrix.coeff(row + (IsRowMajor ? m_outerStart : 0), col + (IsRowMajor ? 0 : m_outerStart)); + } + + inline const Scalar coeff(int index) const + { + return m_matrix.coeff(IsRowMajor ? m_outerStart : index, IsRowMajor ? index : m_outerStart); + } + + const Scalar& lastCoeff() const + { + EIGEN_STATIC_ASSERT_VECTOR_ONLY(BlockImpl); + eigen_assert(nonZeros()>0); + if(m_matrix.isCompressed()) + return m_matrix.valuePtr()[m_matrix.outerIndexPtr()[m_outerStart+1]-1]; + else + return m_matrix.valuePtr()[m_matrix.outerIndexPtr()[m_outerStart]+m_matrix.innerNonZeroPtr()[m_outerStart]-1]; + } + + EIGEN_STRONG_INLINE Index rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); } + EIGEN_STRONG_INLINE Index cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); } + + protected: + + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl) + + typename SparseMatrixType::Nested m_matrix; + Index m_outerStart; + const internal::variable_if_dynamic m_outerSize; +}; + //---------- /** \returns the \a outer -th column (resp. row) of the matrix \c *this if \c *this @@ -263,7 +391,8 @@ const typename SparseMatrixBase::ConstInnerVectorReturnType SparseMatri * is col-major (resp. row-major). */ template -Block SparseMatrixBase::innerVectors(Index outerStart, Index outerSize) +typename SparseMatrixBase::InnerVectorsReturnType +SparseMatrixBase::innerVectors(Index outerStart, Index outerSize) { return Block(derived(), IsRowMajor ? outerStart : 0, IsRowMajor ? 0 : outerStart, @@ -275,7 +404,8 @@ Block SparseMatrixBase::innerVectors(Inde * is col-major (resp. row-major). Read-only. */ template -const Block SparseMatrixBase::innerVectors(Index outerStart, Index outerSize) const +const typename SparseMatrixBase::ConstInnerVectorsReturnType +SparseMatrixBase::innerVectors(Index outerStart, Index outerSize) const { return Block(derived(), IsRowMajor ? outerStart : 0, IsRowMajor ? 0 : outerStart, @@ -302,8 +432,8 @@ public: : m_matrix(xpr), m_startRow( (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0), m_startCol( (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0), - m_blockRows(xpr.rows()), - m_blockCols(xpr.cols()) + m_blockRows(BlockRows==1 ? 1 : xpr.rows()), + m_blockCols(BlockCols==1 ? 1 : xpr.cols()) {} /** Dynamic-size constructor @@ -391,15 +521,19 @@ public: protected: friend class InnerIterator; friend class ReverseInnerIterator; + + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl) typename XprType::Nested m_matrix; const internal::variable_if_dynamic m_startRow; const internal::variable_if_dynamic m_startCol; const internal::variable_if_dynamic m_blockRows; const internal::variable_if_dynamic m_blockCols; - + private: + Index nonZeros() const; }; } // end namespace Eigen #endif // EIGEN_SPARSE_BLOCK_H + diff --git a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseColEtree.h b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseColEtree.h index f89ca3814..f8745f461 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseColEtree.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseColEtree.h @@ -63,6 +63,7 @@ int coletree(const MatrixType& mat, IndexVector& parent, IndexVector& firstRowEl typedef typename MatrixType::Index Index; Index nc = mat.cols(); // Number of columns Index m = mat.rows(); + Index diagSize = (std::min)(nc,m); IndexVector root(nc); // root of subtree of etree root.setZero(); IndexVector pp(nc); // disjoint sets @@ -72,7 +73,7 @@ int coletree(const MatrixType& mat, IndexVector& parent, IndexVector& firstRowEl Index row,col; firstRowElt.resize(m); firstRowElt.setConstant(nc); - firstRowElt.segment(0, nc).setLinSpaced(nc, 0, nc-1); + firstRowElt.segment(0, diagSize).setLinSpaced(diagSize, 0, diagSize-1); bool found_diag; for (col = 0; col < nc; col++) { @@ -91,7 +92,7 @@ int coletree(const MatrixType& mat, IndexVector& parent, IndexVector& firstRowEl Index rset, cset, rroot; for (col = 0; col < nc; col++) { - found_diag = false; + found_diag = col>=m; pp(col) = col; cset = col; root(cset) = col; @@ -105,6 +106,7 @@ int coletree(const MatrixType& mat, IndexVector& parent, IndexVector& firstRowEl Index i = col; if(it) i = it.index(); if (i == col) found_diag = true; + row = firstRowElt(i); if (row >= col) continue; rset = internal::etree_find(row, pp); // Find the name of the set containing row diff --git a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseCwiseBinaryOp.h b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseCwiseBinaryOp.h index ec86ca933..546273759 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseCwiseBinaryOp.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseCwiseBinaryOp.h @@ -55,10 +55,9 @@ class CwiseBinaryOpImpl EIGEN_SPARSE_PUBLIC_INTERFACE(Derived) CwiseBinaryOpImpl() { - typedef typename internal::traits::StorageKind LhsStorageKind; - typedef typename internal::traits::StorageKind RhsStorageKind; EIGEN_STATIC_ASSERT(( - (!internal::is_same::value) + (!internal::is_same::StorageKind, + typename internal::traits::StorageKind>::value) || ((Lhs::Flags&RowMajorBit) == (Rhs::Flags&RowMajorBit))), THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH); } @@ -73,7 +72,8 @@ class CwiseBinaryOpImpl::InnerIterator typedef internal::sparse_cwise_binary_op_inner_iterator_selector< BinaryOp,Lhs,Rhs, InnerIterator> Base; - EIGEN_STRONG_INLINE InnerIterator(const CwiseBinaryOpImpl& binOp, Index outer) + // NOTE: we have to prefix Index by "typename Lhs::" to avoid an ICE with VC11 + EIGEN_STRONG_INLINE InnerIterator(const CwiseBinaryOpImpl& binOp, typename Lhs::Index outer) : Base(binOp.derived(),outer) {} }; @@ -313,10 +313,10 @@ SparseMatrixBase::operator+=(const SparseMatrixBase& othe template template -EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE +EIGEN_STRONG_INLINE const typename SparseMatrixBase::template CwiseProductDenseReturnType::Type SparseMatrixBase::cwiseProduct(const MatrixBase &other) const { - return EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE(derived(), other.derived()); + return typename CwiseProductDenseReturnType::Type(derived(), other.derived()); } } // end namespace Eigen diff --git a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseDenseProduct.h b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseDenseProduct.h index 30975c29c..ccb6ae7b7 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseDenseProduct.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseDenseProduct.h @@ -19,7 +19,10 @@ template struct SparseDenseProductRet template struct SparseDenseProductReturnType { - typedef SparseDenseOuterProduct Type; + typedef typename internal::conditional< + Lhs::IsRowMajor, + SparseDenseOuterProduct, + SparseDenseOuterProduct >::type Type; }; template struct DenseSparseProductReturnType @@ -29,7 +32,10 @@ template struct DenseSparseProductRet template struct DenseSparseProductReturnType { - typedef SparseDenseOuterProduct Type; + typedef typename internal::conditional< + Rhs::IsRowMajor, + SparseDenseOuterProduct, + SparseDenseOuterProduct >::type Type; }; namespace internal { @@ -114,18 +120,31 @@ class SparseDenseOuterProduct::InnerIterator : public _LhsNes typedef typename SparseDenseOuterProduct::Index Index; public: EIGEN_STRONG_INLINE InnerIterator(const SparseDenseOuterProduct& prod, Index outer) - : Base(prod.lhs(), 0), m_outer(outer), m_factor(prod.rhs().coeff(outer)) - { - } + : Base(prod.lhs(), 0), m_outer(outer), m_factor(get(prod.rhs(), outer, typename internal::traits::StorageKind() )) + { } inline Index outer() const { return m_outer; } - inline Index row() const { return Transpose ? Base::row() : m_outer; } - inline Index col() const { return Transpose ? m_outer : Base::row(); } + inline Index row() const { return Transpose ? m_outer : Base::index(); } + inline Index col() const { return Transpose ? Base::index() : m_outer; } inline Scalar value() const { return Base::value() * m_factor; } protected: - int m_outer; + static Scalar get(const _RhsNested &rhs, Index outer, Dense = Dense()) + { + return rhs.coeff(outer); + } + + static Scalar get(const _RhsNested &rhs, Index outer, Sparse = Sparse()) + { + typename Traits::_RhsNested::InnerIterator it(rhs, outer); + if (it && it.index()==0) + return it.value(); + + return Scalar(0); + } + + Index m_outer; Scalar m_factor; }; @@ -155,13 +174,13 @@ struct sparse_time_dense_product_impl -template -inline const typename SparseDenseProductReturnType::Type -SparseMatrixBase::operator*(const MatrixBase &other) const -{ - return typename SparseDenseProductReturnType::Type(derived(), other.derived()); -} - } // end namespace Eigen #endif // EIGEN_SPARSEDENSEPRODUCT_H diff --git a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseMatrix.h b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseMatrix.h index adceafe18..2ff201551 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseMatrix.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseMatrix.h @@ -223,7 +223,7 @@ class SparseMatrix if(isCompressed()) { - reserve(VectorXi::Constant(outerSize(), 2)); + reserve(Matrix::Constant(outerSize(), 2)); } return insertUncompressed(row,col); } @@ -402,7 +402,7 @@ class SparseMatrix * \sa insertBack, insertBackByOuterInner */ inline void startVec(Index outer) { - eigen_assert(m_outerIndex[outer]==int(m_data.size()) && "You must call startVec for each inner vector sequentially"); + eigen_assert(m_outerIndex[outer]==Index(m_data.size()) && "You must call startVec for each inner vector sequentially"); eigen_assert(m_outerIndex[outer+1]==0 && "You must call startVec for each inner vector sequentially"); m_outerIndex[outer+1] = m_outerIndex[outer]; } @@ -480,7 +480,7 @@ class SparseMatrix if(m_innerNonZeros != 0) return; m_innerNonZeros = static_cast(std::malloc(m_outerSize * sizeof(Index))); - for (int i = 0; i < m_outerSize; i++) + for (Index i = 0; i < m_outerSize; i++) { m_innerNonZeros[i] = m_outerIndex[i+1] - m_outerIndex[i]; } @@ -691,7 +691,8 @@ class SparseMatrix m_data.swap(other.m_data); } - /** Sets *this to the identity matrix */ + /** Sets *this to the identity matrix. + * This function also turns the matrix into compressed mode, and drop any reserved memory. */ inline void setIdentity() { eigen_assert(rows() == cols() && "ONLY FOR SQUARED MATRICES"); @@ -699,6 +700,8 @@ class SparseMatrix Eigen::Map >(&this->m_data.index(0), rows()).setLinSpaced(0, rows()-1); Eigen::Map >(&this->m_data.value(0), rows()).setOnes(); Eigen::Map >(this->m_outerIndex, rows()+1).setLinSpaced(0, rows()); + std::free(m_innerNonZeros); + m_innerNonZeros = 0; } inline SparseMatrix& operator=(const SparseMatrix& other) { @@ -752,8 +755,8 @@ class SparseMatrix else for (Index i=0; i trMat(mat.rows(),mat.cols()); + typedef typename SparseMatrixType::Index Index; + SparseMatrix trMat(mat.rows(),mat.cols()); - if(begin wi(trMat.outerSize()); wi.setZero(); for(InputIterator it(begin); it!=end; ++it) { @@ -1018,11 +1022,11 @@ void SparseMatrix::sumupDuplicates() { eigen_assert(!isCompressed()); // TODO, in practice we should be able to use m_innerNonZeros for that task - VectorXi wi(innerSize()); + Matrix wi(innerSize()); wi.fill(-1); Index count = 0; // for each inner-vector, wi[inner_index] will hold the position of first element into the index/value buffers - for(int j=0; j& SparseMatrix positions(dest.outerSize()); for (Index j=0; j::Scalar& Sparse size_t p = m_outerIndex[outer+1]; ++m_outerIndex[outer+1]; - float reallocRatio = 1; + double reallocRatio = 1; if (m_data.allocatedSize()<=m_data.size()) { // if there is no preallocated memory, let's reserve a minimum of 32 elements @@ -1189,13 +1193,13 @@ EIGEN_DONT_INLINE typename SparseMatrix<_Scalar,_Options,_Index>::Scalar& Sparse { // we need to reallocate the data, to reduce multiple reallocations // we use a smart resize algorithm based on the current filling ratio - // in addition, we use float to avoid integers overflows - float nnzEstimate = float(m_outerIndex[outer])*float(m_outerSize)/float(outer+1); - reallocRatio = (nnzEstimate-float(m_data.size()))/float(m_data.size()); + // in addition, we use double to avoid integers overflows + double nnzEstimate = double(m_outerIndex[outer])*double(m_outerSize)/double(outer+1); + reallocRatio = (nnzEstimate-double(m_data.size()))/double(m_data.size()); // furthermore we bound the realloc ratio to: // 1) reduce multiple minor realloc when the matrix is almost filled // 2) avoid to allocate too much memory when the matrix is almost empty - reallocRatio = (std::min)((std::max)(reallocRatio,1.5f),8.f); + reallocRatio = (std::min)((std::max)(reallocRatio,1.5),8.); } } m_data.resize(m_data.size()+1,reallocRatio); diff --git a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseMatrixBase.h b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseMatrixBase.h index 706f699b8..9341d9ad2 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseMatrixBase.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseMatrixBase.h @@ -23,7 +23,14 @@ namespace Eigen { * This class can be extended with the help of the plugin mechanism described on the page * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_SPARSEMATRIXBASE_PLUGIN. */ -template class SparseMatrixBase : public EigenBase +template class SparseMatrixBase +#ifndef EIGEN_PARSED_BY_DOXYGEN + : public internal::special_scalar_op_base::Scalar, + typename NumTraits::Scalar>::Real, + EigenBase > +#else + : public EigenBase +#endif // not EIGEN_PARSED_BY_DOXYGEN { public: @@ -36,7 +43,6 @@ template class SparseMatrixBase : public EigenBase >::type PacketReturnType; typedef SparseMatrixBase StorageBaseType; - typedef EigenBase Base; template Derived& operator=(const EigenBase &other) @@ -132,6 +138,9 @@ template class SparseMatrixBase : public EigenBase inline Derived& derived() { return *static_cast(this); } inline Derived& const_cast_derived() const { return *static_cast(const_cast(this)); } + + typedef internal::special_scalar_op_base > Base; + using Base::operator*; #endif // not EIGEN_PARSED_BY_DOXYGEN #define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::SparseMatrixBase @@ -302,8 +311,8 @@ template class SparseMatrixBase : public EigenBase } else { - SparseMatrix trans = m; - s << static_cast >&>(trans); + SparseMatrix trans = m; + s << static_cast >&>(trans); } } return s; @@ -317,20 +326,18 @@ template class SparseMatrixBase : public EigenBase Derived& operator*=(const Scalar& other); Derived& operator/=(const Scalar& other); - #define EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE \ - CwiseBinaryOp< \ - internal::scalar_product_op< \ - typename internal::scalar_product_traits< \ - typename internal::traits::Scalar, \ - typename internal::traits::Scalar \ - >::ReturnType \ - >, \ - const Derived, \ - const OtherDerived \ - > + template struct CwiseProductDenseReturnType { + typedef CwiseBinaryOp::Scalar, + typename internal::traits::Scalar + >::ReturnType>, + const Derived, + const OtherDerived + > Type; + }; template - EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE + EIGEN_STRONG_INLINE const typename CwiseProductDenseReturnType::Type cwiseProduct(const MatrixBase &other) const; // sparse * sparse @@ -358,7 +365,8 @@ template class SparseMatrixBase : public EigenBase /** sparse * dense (returns a dense object unless it is an outer product) */ template const typename SparseDenseProductReturnType::Type - operator*(const MatrixBase &other) const; + operator*(const MatrixBase &other) const + { return typename SparseDenseProductReturnType::Type(derived(), other.derived()); } /** \returns an expression of P H P^-1 where H is the matrix represented by \c *this */ SparseSymmetricPermutationProduct twistedBy(const PermutationMatrix& perm) const @@ -403,8 +411,10 @@ template class SparseMatrixBase : public EigenBase const ConstInnerVectorReturnType innerVector(Index outer) const; // set of inner-vectors - Block innerVectors(Index outerStart, Index outerSize); - const Block innerVectors(Index outerStart, Index outerSize) const; + typedef Block InnerVectorsReturnType; + typedef Block ConstInnerVectorsReturnType; + InnerVectorsReturnType innerVectors(Index outerStart, Index outerSize); + const ConstInnerVectorsReturnType innerVectors(Index outerStart, Index outerSize) const; /** \internal use operator= */ template diff --git a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparsePermutation.h b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparsePermutation.h index b897b7595..75e210009 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparsePermutation.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparsePermutation.h @@ -57,11 +57,11 @@ struct permut_sparsematrix_product_retval if(MoveOuter) { SparseMatrix tmp(m_matrix.rows(), m_matrix.cols()); - VectorXi sizes(m_matrix.outerSize()); + Matrix sizes(m_matrix.outerSize()); for(Index j=0; j tmp(m_matrix.rows(), m_matrix.cols()); - VectorXi sizes(tmp.outerSize()); + Matrix sizes(tmp.outerSize()); sizes.setZero(); PermutationMatrix perm; if((Side==OnTheLeft) ^ Transposed) diff --git a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseProduct.h b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseProduct.h index 70b6480ef..cf7663070 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseProduct.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseProduct.h @@ -16,6 +16,7 @@ template struct SparseSparseProductReturnType { typedef typename internal::traits::Scalar Scalar; + typedef typename internal::traits::Index Index; enum { LhsRowMajor = internal::traits::Flags & RowMajorBit, RhsRowMajor = internal::traits::Flags & RowMajorBit, @@ -24,11 +25,11 @@ struct SparseSparseProductReturnType }; typedef typename internal::conditional, + SparseMatrix, typename internal::nested::type>::type LhsNested; typedef typename internal::conditional, + SparseMatrix, typename internal::nested::type>::type RhsNested; typedef SparseSparseProduct Type; diff --git a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseSparseProductWithPruning.h b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseSparseProductWithPruning.h index 70857c7b6..fcc18f5c9 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseSparseProductWithPruning.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseSparseProductWithPruning.h @@ -27,7 +27,7 @@ static void sparse_sparse_product_with_pruning_impl(const Lhs& lhs, const Rhs& r // make sure to call innerSize/outerSize since we fake the storage order. Index rows = lhs.innerSize(); Index cols = rhs.outerSize(); - //int size = lhs.outerSize(); + //Index size = lhs.outerSize(); eigen_assert(lhs.outerSize() == rhs.innerSize()); // allocate a temporary buffer @@ -100,7 +100,7 @@ struct sparse_sparse_product_with_pruning_selector SparseTemporaryType; + typedef SparseMatrix SparseTemporaryType; SparseTemporaryType _res(res.rows(), res.cols()); internal::sparse_sparse_product_with_pruning_impl(lhs, rhs, _res, tolerance); res = _res; @@ -126,10 +126,11 @@ struct sparse_sparse_product_with_pruning_selector ColMajorMatrix; - ColMajorMatrix colLhs(lhs); - ColMajorMatrix colRhs(rhs); - internal::sparse_sparse_product_with_pruning_impl(colLhs, colRhs, res, tolerance); + typedef SparseMatrix ColMajorMatrixLhs; + typedef SparseMatrix ColMajorMatrixRhs; + ColMajorMatrixLhs colLhs(lhs); + ColMajorMatrixRhs colRhs(rhs); + internal::sparse_sparse_product_with_pruning_impl(colLhs, colRhs, res, tolerance); // let's transpose the product to get a column x column product // typedef SparseMatrix SparseTemporaryType; diff --git a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseTranspose.h b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseTranspose.h index 7c300ee8d..76d031d52 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseTranspose.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseTranspose.h @@ -26,7 +26,7 @@ template class TransposeImpl inline Index nonZeros() const { return derived().nestedExpression().nonZeros(); } }; -// NOTE: VC10 trigger an ICE if don't put typename TransposeImpl:: in front of Index, +// NOTE: VC10 and VC11 trigger an ICE if don't put typename TransposeImpl:: in front of Index, // a typedef typename TransposeImpl::Index Index; // does not fix the issue. // An alternative is to define the nested class in the parent class itself. @@ -40,8 +40,8 @@ template class TransposeImpl::InnerItera EIGEN_STRONG_INLINE InnerIterator(const TransposeImpl& trans, typename TransposeImpl::Index outer) : Base(trans.derived().nestedExpression(), outer) {} - Index row() const { return Base::col(); } - Index col() const { return Base::row(); } + typename TransposeImpl::Index row() const { return Base::col(); } + typename TransposeImpl::Index col() const { return Base::row(); } }; template class TransposeImpl::ReverseInnerIterator @@ -54,8 +54,8 @@ template class TransposeImpl::ReverseInn EIGEN_STRONG_INLINE ReverseInnerIterator(const TransposeImpl& xpr, typename TransposeImpl::Index outer) : Base(xpr.derived().nestedExpression(), outer) {} - Index row() const { return Base::col(); } - Index col() const { return Base::row(); } + typename TransposeImpl::Index row() const { return Base::col(); } + typename TransposeImpl::Index col() const { return Base::row(); } }; } // end namespace Eigen diff --git a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseUtil.h b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseUtil.h index 064a40707..d627546de 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseUtil.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseUtil.h @@ -67,7 +67,6 @@ const int InnerRandomAccessPattern = 0x2 | CoherentAccessPattern; const int OuterRandomAccessPattern = 0x4 | CoherentAccessPattern; const int RandomAccessPattern = 0x8 | OuterRandomAccessPattern | InnerRandomAccessPattern; -template class SparseMatrixBase; template class SparseMatrix; template class DynamicSparseMatrix; template class SparseVector; @@ -84,8 +83,10 @@ template class DenseTimeSparseProduct; template class SparseDenseOuterProduct; template struct SparseSparseProductReturnType; -template::ColsAtCompileTime> struct DenseSparseProductReturnType; -template::ColsAtCompileTime> struct SparseDenseProductReturnType; +template::ColsAtCompileTime,internal::traits::RowsAtCompileTime)> struct DenseSparseProductReturnType; +template::ColsAtCompileTime,internal::traits::RowsAtCompileTime)> struct SparseDenseProductReturnType; template class SparseSymmetricPermutationProduct; namespace internal { @@ -143,7 +144,7 @@ template struct plain_matrix_type * * \sa SparseMatrix::setFromTriplets() */ -template +template::Index > class Triplet { public: diff --git a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseVector.h b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseVector.h index 7e15c814b..49865d0e7 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseVector.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseVector.h @@ -158,6 +158,7 @@ class SparseVector Index inner = IsColVector ? row : col; Index outer = IsColVector ? col : row; + EIGEN_ONLY_USED_FOR_DEBUG(outer); eigen_assert(outer==0); return insert(inner); } diff --git a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseView.h b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseView.h index fd8450463..2820b39b8 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseView.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/SparseView.h @@ -35,9 +35,9 @@ class SparseView : public SparseMatrixBase > public: EIGEN_SPARSE_PUBLIC_INTERFACE(SparseView) - SparseView(const MatrixType& mat, const Scalar& m_reference = Scalar(0), - typename NumTraits::Real m_epsilon = NumTraits::dummy_precision()) : - m_matrix(mat), m_reference(m_reference), m_epsilon(m_epsilon) {} + explicit SparseView(const MatrixType& mat, const Scalar& reference = Scalar(0), + const RealScalar &epsilon = NumTraits::dummy_precision()) + : m_matrix(mat), m_reference(reference), m_epsilon(epsilon) {} class InnerIterator; diff --git a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/TriangularSolver.h b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/TriangularSolver.h index cb8ad82b4..ccc12af79 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/TriangularSolver.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/SparseCore/TriangularSolver.h @@ -69,7 +69,7 @@ struct sparse_solve_triangular_selector for(int i=lhs.rows()-1 ; i>=0 ; --i) { Scalar tmp = other.coeff(i,col); - Scalar l_ii = 0; + Scalar l_ii(0); typename Lhs::InnerIterator it(lhs, i); while(it && it.index() - bool _solve(const MatrixBase &B, MatrixBase &_X) const + bool _solve(const MatrixBase &B, MatrixBase &X_base) const { - Dest& X(_X.derived()); + Dest& X(X_base.derived()); eigen_assert(m_factorizationIsOk && "The matrix should be factorized first"); EIGEN_STATIC_ASSERT((Dest::Flags&RowMajorBit)==0, THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES); @@ -229,8 +229,10 @@ class SparseLU : public internal::SparseLUImplmatrixL().solveInPlace(X); @@ -258,16 +260,16 @@ class SparseLU : public internal::SparseLUImplcols(); ++j) { for (typename SCMatrix::InnerIterator it(m_Lstore, j); it; ++it) { - if(it.row() < j) continue; - if(it.row() == j) + if(it.index() == j) { - det *= (std::abs)(it.value()); + using std::abs; + det *= abs(it.value()); break; } } @@ -294,7 +296,8 @@ class SparseLU : public internal::SparseLUImplcols(); ++j) + { + for (typename SCMatrix::InnerIterator it(m_Lstore, j); it; ++it) + { + if(it.index() == j) + { + if(it.value()<0) + det = -det; + else if(it.value()==0) + return 0; + break; + } + } + } + return det * m_detPermR * m_detPermC; + } + + /** \returns The determinant of the matrix. + * + * \sa absDeterminant(), logAbsDeterminant() + */ + Scalar determinant() + { + eigen_assert(m_factorizationIsOk && "The matrix should be factorized first."); + // Initialize with the determinant of the row matrix + Scalar det = Scalar(1.); + // Note that the diagonal blocks of U are stored in supernodes, + // which are available in the L part :) + for (Index j = 0; j < this->cols(); ++j) + { + for (typename SCMatrix::InnerIterator it(m_Lstore, j); it; ++it) + { + if(it.index() == j) + { + det *= it.value(); + break; + } + } + } + return det * Scalar(m_detPermR * m_detPermC); + } protected: // Functions void initperfvalues() { - m_perfv.panel_size = 1; + m_perfv.panel_size = 16; m_perfv.relax = 1; m_perfv.maxsuper = 128; m_perfv.rowblk = 16; @@ -344,8 +390,8 @@ class SparseLU : public internal::SparseLUImpl m_perfv; RealScalar m_diagpivotthresh; // Specifies the threshold used for a diagonal entry to be an acceptable pivot - Index m_nnzL, m_nnzU; // Nonzeros in L and U factors - Index m_detPermR; // Determinant of the coefficient matrix + Index m_nnzL, m_nnzU; // Nonzeros in L and U factors + Index m_detPermR, m_detPermC; // Determinants of the permutation matrices private: // Disable copy constructor SparseLU (const SparseLU& ); @@ -621,7 +667,8 @@ void SparseLU::factorize(const MatrixType& matrix) } // Update the determinant of the row permutation matrix - if (pivrow != jj) m_detPermR *= -1; + // FIXME: the following test is not correct, we should probably take iperm_c into account and pivrow is not directly the row pivot. + if (pivrow != jj) m_detPermR = -m_detPermR; // Prune columns (0:jj-1) using column jj Base::pruneL(jj, m_perm_r.indices(), pivrow, nseg, segrep, repfnz_k, xprune, m_glu); @@ -636,10 +683,13 @@ void SparseLU::factorize(const MatrixType& matrix) jcol += panel_size; // Move to the next panel } // end for -- end elimination + m_detPermR = m_perm_r.determinant(); + m_detPermC = m_perm_c.determinant(); + // Count the number of nonzeros in factors Base::countnz(n, m_nnzL, m_nnzU, m_glu); // Apply permutation to the L subscripts - Base::fixupL(n, m_perm_r.indices(), m_glu); + Base::fixupL(n, m_perm_r.indices(), m_glu); // Create supernode matrix L m_Lstore.setInfos(m, n, m_glu.lusup, m_glu.xlusup, m_glu.lsub, m_glu.xlsub, m_glu.supno, m_glu.xsup); @@ -699,8 +749,8 @@ struct SparseLUMatrixUReturnType : internal::no_assignment_operator } else { - Map, 0, OuterStride<> > A( &(m_mapL.valuePtr()[luptr]), nsupc, nsupc, OuterStride<>(lda) ); - Map< Matrix, 0, OuterStride<> > U (&(X(fsupc,0)), nsupc, nrhs, OuterStride<>(n) ); + Map, 0, OuterStride<> > A( &(m_mapL.valuePtr()[luptr]), nsupc, nsupc, OuterStride<>(lda) ); + Map< Matrix, 0, OuterStride<> > U (&(X(fsupc,0)), nsupc, nrhs, OuterStride<>(n) ); U = A.template triangularView().solve(U); } diff --git a/ground/gcs/src/libs/eigen/Eigen/src/SparseLU/SparseLUImpl.h b/ground/gcs/src/libs/eigen/Eigen/src/SparseLU/SparseLUImpl.h index 14d70897d..99d651e40 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/SparseLU/SparseLUImpl.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/SparseLU/SparseLUImpl.h @@ -21,6 +21,8 @@ class SparseLUImpl { public: typedef Matrix ScalarVector; + typedef Matrix ScalarMatrix; + typedef Map > MappedMatrixBlock; typedef Matrix IndexVector; typedef typename ScalarVector::RealScalar RealScalar; typedef Ref > BlockScalarVector; diff --git a/ground/gcs/src/libs/eigen/Eigen/src/SparseLU/SparseLU_Memory.h b/ground/gcs/src/libs/eigen/Eigen/src/SparseLU/SparseLU_Memory.h index a5158025c..45f96d16a 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/SparseLU/SparseLU_Memory.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/SparseLU/SparseLU_Memory.h @@ -70,23 +70,30 @@ Index SparseLUImpl::expand(VectorType& vec, Index& length, Index if(num_expansions == 0 || keep_prev) new_len = length ; // First time allocate requested else - new_len = Index(alpha * length); + new_len = (std::max)(length+1,Index(alpha * length)); VectorType old_vec; // Temporary vector to hold the previous values if (nbElts > 0 ) old_vec = vec.segment(0,nbElts); //Allocate or expand the current vector - try +#ifdef EIGEN_EXCEPTIONS + try +#endif { vec.resize(new_len); } +#ifdef EIGEN_EXCEPTIONS catch(std::bad_alloc& ) +#else + if(!vec.size()) +#endif { - if ( !num_expansions ) + if (!num_expansions) { // First time to allocate from LUMemInit() - throw; // Pass the exception to LUMemInit() which has a try... catch block + // Let LUMemInit() deals with it. + return -1; } if (keep_prev) { @@ -100,12 +107,18 @@ Index SparseLUImpl::expand(VectorType& vec, Index& length, Index do { alpha = (alpha + 1)/2; - new_len = Index(alpha * length); + new_len = (std::max)(length+1,Index(alpha * length)); +#ifdef EIGEN_EXCEPTIONS try +#endif { vec.resize(new_len); } +#ifdef EIGEN_EXCEPTIONS catch(std::bad_alloc& ) +#else + if (!vec.size()) +#endif { tries += 1; if ( tries > 10) return new_len; @@ -139,10 +152,9 @@ template Index SparseLUImpl::memInit(Index m, Index n, Index annz, Index lwork, Index fillratio, Index panel_size, GlobalLU_t& glu) { Index& num_expansions = glu.num_expansions; //No memory expansions so far - num_expansions = 0; - glu.nzumax = glu.nzlumax = (std::max)(fillratio * annz, m*n); // estimated number of nonzeros in U - glu.nzlmax = (std::max)(Index(4), fillratio) * annz / 4; // estimated nnz in L factor - + num_expansions = 0; + glu.nzumax = glu.nzlumax = (std::min)(fillratio * (annz+1) / n, m) * n; // estimated number of nonzeros in U + glu.nzlmax = (std::max)(Index(4), fillratio) * (annz+1) / 4; // estimated nnz in L factor // Return the estimated size to the user if necessary Index tempSpace; tempSpace = (2*panel_size + 4 + LUNoMarker) * m * sizeof(Index) + (panel_size + 1) * m * sizeof(Scalar); @@ -166,14 +178,10 @@ Index SparseLUImpl::memInit(Index m, Index n, Index annz, Index lw // Reserve memory for L/U factors do { - try - { - expand(glu.lusup, glu.nzlumax, 0, 0, num_expansions); - expand(glu.ucol,glu.nzumax, 0, 0, num_expansions); - expand(glu.lsub,glu.nzlmax, 0, 0, num_expansions); - expand(glu.usub,glu.nzumax, 0, 1, num_expansions); - } - catch(std::bad_alloc& ) + if( (expand(glu.lusup, glu.nzlumax, 0, 0, num_expansions)<0) + || (expand(glu.ucol, glu.nzumax, 0, 0, num_expansions)<0) + || (expand (glu.lsub, glu.nzlmax, 0, 0, num_expansions)<0) + || (expand (glu.usub, glu.nzumax, 0, 1, num_expansions)<0) ) { //Reduce the estimated size and retry glu.nzlumax /= 2; @@ -181,10 +189,7 @@ Index SparseLUImpl::memInit(Index m, Index n, Index annz, Index lw glu.nzlmax /= 2; if (glu.nzlumax < annz ) return glu.nzlumax; } - } while (!glu.lusup.size() || !glu.ucol.size() || !glu.lsub.size() || !glu.usub.size()); - - ++num_expansions; return 0; diff --git a/ground/gcs/src/libs/eigen/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h b/ground/gcs/src/libs/eigen/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h index ad6f2183f..54a569408 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h @@ -189,8 +189,8 @@ class MappedSuperNodalMatrix::InnerIterator m_idval(mat.colIndexPtr()[outer]), m_startidval(m_idval), m_endidval(mat.colIndexPtr()[outer+1]), - m_idrow(mat.rowIndexPtr()[outer]), - m_endidrow(mat.rowIndexPtr()[outer+1]) + m_idrow(mat.rowIndexPtr()[mat.supToCol()[mat.colToSup()[outer]]]), + m_endidrow(mat.rowIndexPtr()[mat.supToCol()[mat.colToSup()[outer]]+1]) {} inline InnerIterator& operator++() { @@ -236,7 +236,7 @@ void MappedSuperNodalMatrix::solveInPlace( MatrixBase&X) con Index n = X.rows(); Index nrhs = X.cols(); const Scalar * Lval = valuePtr(); // Nonzero values - Matrix work(n, nrhs); // working vector + Matrix work(n, nrhs); // working vector work.setZero(); for (Index k = 0; k <= nsuper(); k ++) { @@ -267,12 +267,12 @@ void MappedSuperNodalMatrix::solveInPlace( MatrixBase&X) con Index lda = colIndexPtr()[fsupc+1] - luptr; // Triangular solve - Map, 0, OuterStride<> > A( &(Lval[luptr]), nsupc, nsupc, OuterStride<>(lda) ); - Map< Matrix, 0, OuterStride<> > U (&(X(fsupc,0)), nsupc, nrhs, OuterStride<>(n) ); + Map, 0, OuterStride<> > A( &(Lval[luptr]), nsupc, nsupc, OuterStride<>(lda) ); + Map< Matrix, 0, OuterStride<> > U (&(X(fsupc,0)), nsupc, nrhs, OuterStride<>(n) ); U = A.template triangularView().solve(U); // Matrix-vector product - new (&A) Map, 0, OuterStride<> > ( &(Lval[luptr+nsupc]), nrow, nsupc, OuterStride<>(lda) ); + new (&A) Map, 0, OuterStride<> > ( &(Lval[luptr+nsupc]), nrow, nsupc, OuterStride<>(lda) ); work.block(0, 0, nrow, nrhs) = A * U; //Begin Scatter diff --git a/ground/gcs/src/libs/eigen/Eigen/src/SparseLU/SparseLU_column_bmod.h b/ground/gcs/src/libs/eigen/Eigen/src/SparseLU/SparseLU_column_bmod.h index f24bd87d3..cacc7e987 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/SparseLU/SparseLU_column_bmod.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/SparseLU/SparseLU_column_bmod.h @@ -162,11 +162,11 @@ Index SparseLUImpl::column_bmod(const Index jcol, const Index nseg // points to the beginning of jcol in snode L\U(jsupno) ufirst = glu.xlusup(jcol) + d_fsupc; Index lda = glu.xlusup(jcol+1) - glu.xlusup(jcol); - Map, 0, OuterStride<> > A( &(glu.lusup.data()[luptr]), nsupc, nsupc, OuterStride<>(lda) ); + MappedMatrixBlock A( &(glu.lusup.data()[luptr]), nsupc, nsupc, OuterStride<>(lda) ); VectorBlock u(glu.lusup, ufirst, nsupc); u = A.template triangularView().solve(u); - new (&A) Map, 0, OuterStride<> > ( &(glu.lusup.data()[luptr+nsupc]), nrow, nsupc, OuterStride<>(lda) ); + new (&A) MappedMatrixBlock ( &(glu.lusup.data()[luptr+nsupc]), nrow, nsupc, OuterStride<>(lda) ); VectorBlock l(glu.lusup, ufirst+nsupc, nrow); l.noalias() -= A * u; diff --git a/ground/gcs/src/libs/eigen/Eigen/src/SparseLU/SparseLU_kernel_bmod.h b/ground/gcs/src/libs/eigen/Eigen/src/SparseLU/SparseLU_kernel_bmod.h index 0d0283b13..6af026754 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/SparseLU/SparseLU_kernel_bmod.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/SparseLU/SparseLU_kernel_bmod.h @@ -56,7 +56,7 @@ EIGEN_DONT_INLINE void LU_kernel_bmod::run(const int segsi // Dense triangular solve -- start effective triangle luptr += lda * no_zeros + no_zeros; // Form Eigen matrix and vector - Map, 0, OuterStride<> > A( &(lusup.data()[luptr]), segsize, segsize, OuterStride<>(lda) ); + Map, 0, OuterStride<> > A( &(lusup.data()[luptr]), segsize, segsize, OuterStride<>(lda) ); Map > u(tempv.data(), segsize); u = A.template triangularView().solve(u); @@ -65,7 +65,7 @@ EIGEN_DONT_INLINE void LU_kernel_bmod::run(const int segsi luptr += segsize; const Index PacketSize = internal::packet_traits::size; Index ldl = internal::first_multiple(nrow, PacketSize); - Map, 0, OuterStride<> > B( &(lusup.data()[luptr]), nrow, segsize, OuterStride<>(lda) ); + Map, 0, OuterStride<> > B( &(lusup.data()[luptr]), nrow, segsize, OuterStride<>(lda) ); Index aligned_offset = internal::first_aligned(tempv.data()+segsize, PacketSize); Index aligned_with_B_offset = (PacketSize-internal::first_aligned(B.data(), PacketSize))%PacketSize; Map, 0, OuterStride<> > l(tempv.data()+segsize+aligned_offset+aligned_with_B_offset, nrow, OuterStride<>(ldl) ); diff --git a/ground/gcs/src/libs/eigen/Eigen/src/SparseLU/SparseLU_panel_bmod.h b/ground/gcs/src/libs/eigen/Eigen/src/SparseLU/SparseLU_panel_bmod.h index da0e0fc3c..9d2ff2906 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/SparseLU/SparseLU_panel_bmod.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/SparseLU/SparseLU_panel_bmod.h @@ -102,7 +102,7 @@ void SparseLUImpl::panel_bmod(const Index m, const Index w, const if(nsupc >= 2) { Index ldu = internal::first_multiple(u_rows, PacketSize); - Map, Aligned, OuterStride<> > U(tempv.data(), u_rows, u_cols, OuterStride<>(ldu)); + Map > U(tempv.data(), u_rows, u_cols, OuterStride<>(ldu)); // gather U Index u_col = 0; @@ -136,17 +136,17 @@ void SparseLUImpl::panel_bmod(const Index m, const Index w, const Index lda = glu.xlusup(fsupc+1) - glu.xlusup(fsupc); no_zeros = (krep - u_rows + 1) - fsupc; luptr += lda * no_zeros + no_zeros; - Map, 0, OuterStride<> > A(glu.lusup.data()+luptr, u_rows, u_rows, OuterStride<>(lda) ); + MappedMatrixBlock A(glu.lusup.data()+luptr, u_rows, u_rows, OuterStride<>(lda) ); U = A.template triangularView().solve(U); // update luptr += u_rows; - Map, 0, OuterStride<> > B(glu.lusup.data()+luptr, nrow, u_rows, OuterStride<>(lda) ); + MappedMatrixBlock B(glu.lusup.data()+luptr, nrow, u_rows, OuterStride<>(lda) ); eigen_assert(tempv.size()>w*ldu + nrow*w + 1); Index ldl = internal::first_multiple(nrow, PacketSize); Index offset = (PacketSize-internal::first_aligned(B.data(), PacketSize)) % PacketSize; - Map, 0, OuterStride<> > L(tempv.data()+w*ldu+offset, nrow, u_cols, OuterStride<>(ldl)); + MappedMatrixBlock L(tempv.data()+w*ldu+offset, nrow, u_cols, OuterStride<>(ldl)); L.setZero(); internal::sparselu_gemm(L.rows(), L.cols(), B.cols(), B.data(), B.outerStride(), U.data(), U.outerStride(), L.data(), L.outerStride()); diff --git a/ground/gcs/src/libs/eigen/Eigen/src/SparseLU/SparseLU_pivotL.h b/ground/gcs/src/libs/eigen/Eigen/src/SparseLU/SparseLU_pivotL.h index ddcd4ec98..2e49ef667 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/SparseLU/SparseLU_pivotL.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/SparseLU/SparseLU_pivotL.h @@ -71,13 +71,14 @@ Index SparseLUImpl::pivotL(const Index jcol, const RealScalar& dia // Determine the largest abs numerical value for partial pivoting Index diagind = iperm_c(jcol); // diagonal index - RealScalar pivmax = 0.0; + RealScalar pivmax(-1.0); Index pivptr = nsupc; Index diag = emptyIdxLU; RealScalar rtemp; Index isub, icol, itemp, k; for (isub = nsupc; isub < nsupr; ++isub) { - rtemp = std::abs(lu_col_ptr[isub]); + using std::abs; + rtemp = abs(lu_col_ptr[isub]); if (rtemp > pivmax) { pivmax = rtemp; pivptr = isub; @@ -86,8 +87,9 @@ Index SparseLUImpl::pivotL(const Index jcol, const RealScalar& dia } // Test for singularity - if ( pivmax == 0.0 ) { - pivrow = lsub_ptr[pivptr]; + if ( pivmax <= RealScalar(0.0) ) { + // if pivmax == -1, the column is structurally empty, otherwise it is only numerically zero + pivrow = pivmax < RealScalar(0.0) ? diagind : lsub_ptr[pivptr]; perm_r(pivrow) = jcol; return (jcol+1); } @@ -101,7 +103,8 @@ Index SparseLUImpl::pivotL(const Index jcol, const RealScalar& dia if (diag >= 0 ) { // Diagonal element exists - rtemp = std::abs(lu_col_ptr[diag]); + using std::abs; + rtemp = abs(lu_col_ptr[diag]); if (rtemp != 0.0 && rtemp >= thresh) pivptr = diag; } pivrow = lsub_ptr[pivptr]; diff --git a/ground/gcs/src/libs/eigen/Eigen/src/SparseQR/SparseQR.h b/ground/gcs/src/libs/eigen/Eigen/src/SparseQR/SparseQR.h index 07c46e4b9..a00bd5db1 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/SparseQR/SparseQR.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/SparseQR/SparseQR.h @@ -2,7 +2,7 @@ // for linear algebra. // // Copyright (C) 2012-2013 Desire Nuentsa -// Copyright (C) 2012-2013 Gael Guennebaud +// Copyright (C) 2012-2014 Gael Guennebaud // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed @@ -58,6 +58,7 @@ namespace internal { * \tparam _OrderingType The fill-reducing ordering method. See the \link OrderingMethods_Module * OrderingMethods \endlink module for the list of built-in and external ordering methods. * + * \warning The input sparse matrix A must be in compressed mode (see SparseMatrix::makeCompressed()). * */ template @@ -74,13 +75,26 @@ class SparseQR typedef Matrix ScalarVector; typedef PermutationMatrix PermutationType; public: - SparseQR () : m_isInitialized(false), m_analysisIsok(false), m_lastError(""), m_useDefaultThreshold(true),m_isQSorted(false) + SparseQR () : m_isInitialized(false), m_analysisIsok(false), m_lastError(""), m_useDefaultThreshold(true),m_isQSorted(false),m_isEtreeOk(false) { } - SparseQR(const MatrixType& mat) : m_isInitialized(false), m_analysisIsok(false), m_lastError(""), m_useDefaultThreshold(true),m_isQSorted(false) + /** Construct a QR factorization of the matrix \a mat. + * + * \warning The matrix \a mat must be in compressed mode (see SparseMatrix::makeCompressed()). + * + * \sa compute() + */ + SparseQR(const MatrixType& mat) : m_isInitialized(false), m_analysisIsok(false), m_lastError(""), m_useDefaultThreshold(true),m_isQSorted(false),m_isEtreeOk(false) { compute(mat); } + + /** Computes the QR factorization of the sparse matrix \a mat. + * + * \warning The matrix \a mat must be in compressed mode (see SparseMatrix::makeCompressed()). + * + * \sa analyzePattern(), factorize() + */ void compute(const MatrixType& mat) { analyzePattern(mat); @@ -161,11 +175,12 @@ class SparseQR b = y; // Solve with the triangular matrix R + y.resize((std::max)(cols(),Index(y.rows())),y.cols()); y.topRows(rank) = this->matrixR().topLeftCorner(rank, rank).template triangularView().solve(b.topRows(rank)); - y.bottomRows(y.size()-rank).setZero(); + y.bottomRows(y.rows()-rank).setZero(); // Apply the column permutation - if (m_perm_c.size()) dest.topRows(cols()) = colsPermutation() * y.topRows(cols()); + if (m_perm_c.size()) dest = colsPermutation() * y.topRows(cols()); else dest = y.topRows(cols()); m_info = Success; @@ -205,7 +220,7 @@ class SparseQR /** \brief Reports whether previous computation was successful. * - * \returns \c Success if computation was succesful, + * \returns \c Success if computation was successful, * \c NumericalIssue if the QR factorization reports a numerical problem * \c InvalidInput if the input matrix is invalid * @@ -246,7 +261,8 @@ class SparseQR Index m_nonzeropivots; // Number of non zero pivots found IndexVector m_etree; // Column elimination tree IndexVector m_firstRowElt; // First element in each row - bool m_isQSorted; // whether Q is sorted or not + bool m_isQSorted; // whether Q is sorted or not + bool m_isEtreeOk; // whether the elimination tree match the initial input matrix template friend struct SparseQR_QProduct; template friend struct SparseQRMatrixQReturnType; @@ -254,20 +270,26 @@ class SparseQR }; /** \brief Preprocessing step of a QR factorization + * + * \warning The matrix \a mat must be in compressed mode (see SparseMatrix::makeCompressed()). * * In this step, the fill-reducing permutation is computed and applied to the columns of A - * and the column elimination tree is computed as well. Only the sparcity pattern of \a mat is exploited. + * and the column elimination tree is computed as well. Only the sparsity pattern of \a mat is exploited. * * \note In this step it is assumed that there is no empty row in the matrix \a mat. */ template void SparseQR::analyzePattern(const MatrixType& mat) { + eigen_assert(mat.isCompressed() && "SparseQR requires a sparse matrix in compressed mode. Call .makeCompressed() before passing it to SparseQR"); + // Copy to a column major matrix if the input is rowmajor + typename internal::conditional::type matCpy(mat); // Compute the column fill reducing ordering OrderingType ord; - ord(mat, m_perm_c); + ord(matCpy, m_perm_c); Index n = mat.cols(); Index m = mat.rows(); + Index diagSize = (std::min)(m,n); if (!m_perm_c.size()) { @@ -277,22 +299,23 @@ void SparseQR::analyzePattern(const MatrixType& mat) // Compute the column elimination tree of the permuted matrix m_outputPerm_c = m_perm_c.inverse(); - internal::coletree(mat, m_etree, m_firstRowElt, m_outputPerm_c.indices().data()); + internal::coletree(matCpy, m_etree, m_firstRowElt, m_outputPerm_c.indices().data()); + m_isEtreeOk = true; - m_R.resize(n, n); - m_Q.resize(m, n); + m_R.resize(m, n); + m_Q.resize(m, diagSize); // Allocate space for nonzero elements : rough estimation m_R.reserve(2*mat.nonZeros()); //FIXME Get a more accurate estimation through symbolic factorization with the etree m_Q.reserve(2*mat.nonZeros()); - m_hcoeffs.resize(n); + m_hcoeffs.resize(diagSize); m_analysisIsok = true; } /** \brief Performs the numerical QR factorization of the input matrix * * The function SparseQR::analyzePattern(const MatrixType&) must have been called beforehand with - * a matrix having the same sparcity pattern than \a mat. + * a matrix having the same sparsity pattern than \a mat. * * \param mat The sparse column-major matrix */ @@ -305,23 +328,47 @@ void SparseQR::factorize(const MatrixType& mat) eigen_assert(m_analysisIsok && "analyzePattern() should be called before this step"); Index m = mat.rows(); Index n = mat.cols(); - IndexVector mark(m); mark.setConstant(-1); // Record the visited nodes - IndexVector Ridx(n), Qidx(m); // Store temporarily the row indexes for the current column of R and Q - Index nzcolR, nzcolQ; // Number of nonzero for the current column of R and Q - ScalarVector tval(m); // The dense vector used to compute the current column - bool found_diag; - + Index diagSize = (std::min)(m,n); + IndexVector mark((std::max)(m,n)); mark.setConstant(-1); // Record the visited nodes + IndexVector Ridx(n), Qidx(m); // Store temporarily the row indexes for the current column of R and Q + Index nzcolR, nzcolQ; // Number of nonzero for the current column of R and Q + ScalarVector tval(m); // The dense vector used to compute the current column + RealScalar pivotThreshold = m_threshold; + + m_R.setZero(); + m_Q.setZero(); m_pmat = mat; - m_pmat.uncompress(); // To have the innerNonZeroPtr allocated - // Apply the fill-in reducing permutation lazily: - for (int i = 0; i < n; i++) + if(!m_isEtreeOk) { - Index p = m_perm_c.size() ? m_perm_c.indices()(i) : i; - m_pmat.outerIndexPtr()[p] = mat.outerIndexPtr()[i]; - m_pmat.innerNonZeroPtr()[p] = mat.outerIndexPtr()[i+1] - mat.outerIndexPtr()[i]; + m_outputPerm_c = m_perm_c.inverse(); + internal::coletree(m_pmat, m_etree, m_firstRowElt, m_outputPerm_c.indices().data()); + m_isEtreeOk = true; + } + + m_pmat.uncompress(); // To have the innerNonZeroPtr allocated + + // Apply the fill-in reducing permutation lazily: + { + // If the input is row major, copy the original column indices, + // otherwise directly use the input matrix + // + IndexVector originalOuterIndicesCpy; + const Index *originalOuterIndices = mat.outerIndexPtr(); + if(MatrixType::IsRowMajor) + { + originalOuterIndicesCpy = IndexVector::Map(m_pmat.outerIndexPtr(),n+1); + originalOuterIndices = originalOuterIndicesCpy.data(); + } + + for (int i = 0; i < n; i++) + { + Index p = m_perm_c.size() ? m_perm_c.indices()(i) : i; + m_pmat.outerIndexPtr()[p] = originalOuterIndices[i]; + m_pmat.innerNonZeroPtr()[p] = originalOuterIndices[i+1] - originalOuterIndices[i]; + } } - /* Compute the default threshold, see : + /* Compute the default threshold as in MatLab, see: * Tim Davis, "Algorithm 915, SuiteSparseQR: Multifrontal Multithreaded Rank-Revealing * Sparse QR Factorization, ACM Trans. on Math. Soft. 38(1), 2011, Page 8:3 */ @@ -329,33 +376,35 @@ void SparseQR::factorize(const MatrixType& mat) { RealScalar max2Norm = 0.0; for (int j = 0; j < n; j++) max2Norm = (max)(max2Norm, m_pmat.col(j).norm()); - m_threshold = 20 * (m + n) * max2Norm * NumTraits::epsilon(); + if(max2Norm==RealScalar(0)) + max2Norm = RealScalar(1); + pivotThreshold = 20 * (m + n) * max2Norm * NumTraits::epsilon(); } // Initialize the numerical permutation m_pivotperm.setIdentity(n); Index nonzeroCol = 0; // Record the number of valid pivots - + m_Q.startVec(0); + // Left looking rank-revealing QR factorization: compute a column of R and Q at a time for (Index col = 0; col < n; ++col) { mark.setConstant(-1); m_R.startVec(col); - m_Q.startVec(col); mark(nonzeroCol) = col; Qidx(0) = nonzeroCol; nzcolR = 0; nzcolQ = 1; - found_diag = false; + bool found_diag = nonzeroCol>=m; tval.setZero(); // Symbolic factorization: find the nonzero locations of the column k of the factors R and Q, i.e., // all the nodes (with indexes lower than rank) reachable through the column elimination tree (etree) rooted at node k. // Note: if the diagonal entry does not exist, then its contribution must be explicitly added, // thus the trick with found_diag that permits to do one more iteration on the diagonal element if this one has not been found. - for (typename MatrixType::InnerIterator itp(m_pmat, col); itp || !found_diag; ++itp) + for (typename QRMatrixType::InnerIterator itp(m_pmat, col); itp || !found_diag; ++itp) { - Index curIdx = nonzeroCol ; + Index curIdx = nonzeroCol; if(itp) curIdx = itp.row(); if(curIdx == nonzeroCol) found_diag = true; @@ -397,7 +446,7 @@ void SparseQR::factorize(const MatrixType& mat) // Browse all the indexes of R(:,col) in reverse order for (Index i = nzcolR-1; i >= 0; i--) { - Index curIdx = m_pivotperm.indices()(Ridx(i)); + Index curIdx = Ridx(i); // Apply the curIdx-th householder vector to the current column (temporarily stored into tval) Scalar tdot(0); @@ -426,33 +475,36 @@ void SparseQR::factorize(const MatrixType& mat) } } } // End update current column - - // Compute the Householder reflection that eliminate the current column - // FIXME this step should call the Householder module. - Scalar tau; - RealScalar beta; - Scalar c0 = nzcolQ ? tval(Qidx(0)) : Scalar(0); - // First, the squared norm of Q((col+1):m, col) - RealScalar sqrNorm = 0.; - for (Index itq = 1; itq < nzcolQ; ++itq) sqrNorm += numext::abs2(tval(Qidx(itq))); + Scalar tau = 0; + RealScalar beta = 0; - if(sqrNorm == RealScalar(0) && numext::imag(c0) == RealScalar(0)) + if(nonzeroCol < diagSize) { - tau = RealScalar(0); - beta = numext::real(c0); - tval(Qidx(0)) = 1; - } - else - { - beta = std::sqrt(numext::abs2(c0) + sqrNorm); - if(numext::real(c0) >= RealScalar(0)) - beta = -beta; - tval(Qidx(0)) = 1; - for (Index itq = 1; itq < nzcolQ; ++itq) - tval(Qidx(itq)) /= (c0 - beta); - tau = numext::conj((beta-c0) / beta); - + // Compute the Householder reflection that eliminate the current column + // FIXME this step should call the Householder module. + Scalar c0 = nzcolQ ? tval(Qidx(0)) : Scalar(0); + + // First, the squared norm of Q((col+1):m, col) + RealScalar sqrNorm = 0.; + for (Index itq = 1; itq < nzcolQ; ++itq) sqrNorm += numext::abs2(tval(Qidx(itq))); + if(sqrNorm == RealScalar(0) && numext::imag(c0) == RealScalar(0)) + { + beta = numext::real(c0); + tval(Qidx(0)) = 1; + } + else + { + using std::sqrt; + beta = sqrt(numext::abs2(c0) + sqrNorm); + if(numext::real(c0) >= RealScalar(0)) + beta = -beta; + tval(Qidx(0)) = 1; + for (Index itq = 1; itq < nzcolQ; ++itq) + tval(Qidx(itq)) /= (c0 - beta); + tau = numext::conj((beta-c0) / beta); + + } } // Insert values in R @@ -466,45 +518,49 @@ void SparseQR::factorize(const MatrixType& mat) } } - if(abs(beta) >= m_threshold) + if(nonzeroCol < diagSize && abs(beta) >= pivotThreshold) { m_R.insertBackByOuterInner(col, nonzeroCol) = beta; - nonzeroCol++; // The householder coefficient - m_hcoeffs(col) = tau; + m_hcoeffs(nonzeroCol) = tau; // Record the householder reflections for (Index itq = 0; itq < nzcolQ; ++itq) { Index iQ = Qidx(itq); - m_Q.insertBackByOuterInnerUnordered(col,iQ) = tval(iQ); + m_Q.insertBackByOuterInnerUnordered(nonzeroCol,iQ) = tval(iQ); tval(iQ) = Scalar(0.); - } + } + nonzeroCol++; + if(nonzeroCol void evalTo(DesType& res) const { + Index m = m_qr.rows(); Index n = m_qr.cols(); + Index diagSize = (std::min)(m,n); res = m_other; if (m_transpose) { eigen_assert(m_qr.m_Q.rows() == m_other.rows() && "Non conforming object sizes"); //Compute res = Q' * other column by column for(Index j = 0; j < res.cols(); j++){ - for (Index k = 0; k < n; k++) + for (Index k = 0; k < diagSize; k++) { Scalar tau = Scalar(0); tau = m_qr.m_Q.col(k).dot(res.col(j)); + if(tau==Scalar(0)) continue; tau = tau * m_qr.m_hcoeffs(k); res.col(j) -= tau * m_qr.m_Q.col(k); } @@ -578,14 +637,15 @@ struct SparseQR_QProduct : ReturnByValue=0; k--) + for (Index k = diagSize-1; k >=0; k--) { Scalar tau = Scalar(0); tau = m_qr.m_Q.col(k).dot(res.col(j)); + if(tau==Scalar(0)) continue; tau = tau * m_qr.m_hcoeffs(k); res.col(j) -= tau * m_qr.m_Q.col(k); } @@ -615,7 +675,7 @@ struct SparseQRMatrixQReturnType : public EigenBase(m_qr); } inline Index rows() const { return m_qr.rows(); } - inline Index cols() const { return m_qr.cols(); } + inline Index cols() const { return (std::min)(m_qr.rows(),m_qr.cols()); } // To use for operations with the transpose of Q SparseQRMatrixQTransposeReturnType transpose() const { diff --git a/ground/gcs/src/libs/eigen/Eigen/src/StlSupport/StdDeque.h b/ground/gcs/src/libs/eigen/Eigen/src/StlSupport/StdDeque.h index 4ee8e5c10..69a46b2b8 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/StlSupport/StdDeque.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/StlSupport/StdDeque.h @@ -11,14 +11,7 @@ #ifndef EIGEN_STDDEQUE_H #define EIGEN_STDDEQUE_H -#include "Eigen/src/StlSupport/details.h" - -// Define the explicit instantiation (e.g. necessary for the Intel compiler) -#if defined(__INTEL_COMPILER) || defined(__GNUC__) - #define EIGEN_EXPLICIT_STL_DEQUE_INSTANTIATION(...) template class std::deque<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> >; -#else - #define EIGEN_EXPLICIT_STL_DEQUE_INSTANTIATION(...) -#endif +#include "details.h" /** * This section contains a convenience MACRO which allows an easy specialization of @@ -26,19 +19,18 @@ * is used automatically. */ #define EIGEN_DEFINE_STL_DEQUE_SPECIALIZATION(...) \ -EIGEN_EXPLICIT_STL_DEQUE_INSTANTIATION(__VA_ARGS__) \ namespace std \ { \ - template \ - class deque<__VA_ARGS__, _Ay> \ + template<> \ + class deque<__VA_ARGS__, std::allocator<__VA_ARGS__> > \ : public deque<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > \ { \ typedef deque<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > deque_base; \ public: \ typedef __VA_ARGS__ value_type; \ - typedef typename deque_base::allocator_type allocator_type; \ - typedef typename deque_base::size_type size_type; \ - typedef typename deque_base::iterator iterator; \ + typedef deque_base::allocator_type allocator_type; \ + typedef deque_base::size_type size_type; \ + typedef deque_base::iterator iterator; \ explicit deque(const allocator_type& a = allocator_type()) : deque_base(a) {} \ template \ deque(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) : deque_base(first, last, a) {} \ diff --git a/ground/gcs/src/libs/eigen/Eigen/src/StlSupport/StdList.h b/ground/gcs/src/libs/eigen/Eigen/src/StlSupport/StdList.h index 627381ece..050c2373e 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/StlSupport/StdList.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/StlSupport/StdList.h @@ -10,14 +10,7 @@ #ifndef EIGEN_STDLIST_H #define EIGEN_STDLIST_H -#include "Eigen/src/StlSupport/details.h" - -// Define the explicit instantiation (e.g. necessary for the Intel compiler) -#if defined(__INTEL_COMPILER) || defined(__GNUC__) - #define EIGEN_EXPLICIT_STL_LIST_INSTANTIATION(...) template class std::list<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> >; -#else - #define EIGEN_EXPLICIT_STL_LIST_INSTANTIATION(...) -#endif +#include "details.h" /** * This section contains a convenience MACRO which allows an easy specialization of @@ -25,19 +18,18 @@ * is used automatically. */ #define EIGEN_DEFINE_STL_LIST_SPECIALIZATION(...) \ -EIGEN_EXPLICIT_STL_LIST_INSTANTIATION(__VA_ARGS__) \ namespace std \ { \ - template \ - class list<__VA_ARGS__, _Ay> \ + template<> \ + class list<__VA_ARGS__, std::allocator<__VA_ARGS__> > \ : public list<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > \ { \ typedef list<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > list_base; \ public: \ typedef __VA_ARGS__ value_type; \ - typedef typename list_base::allocator_type allocator_type; \ - typedef typename list_base::size_type size_type; \ - typedef typename list_base::iterator iterator; \ + typedef list_base::allocator_type allocator_type; \ + typedef list_base::size_type size_type; \ + typedef list_base::iterator iterator; \ explicit list(const allocator_type& a = allocator_type()) : list_base(a) {} \ template \ list(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) : list_base(first, last, a) {} \ diff --git a/ground/gcs/src/libs/eigen/Eigen/src/StlSupport/StdVector.h b/ground/gcs/src/libs/eigen/Eigen/src/StlSupport/StdVector.h index 40a9abefa..611664a2e 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/StlSupport/StdVector.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/StlSupport/StdVector.h @@ -11,7 +11,7 @@ #ifndef EIGEN_STDVECTOR_H #define EIGEN_STDVECTOR_H -#include "Eigen/src/StlSupport/details.h" +#include "details.h" /** * This section contains a convenience MACRO which allows an easy specialization of diff --git a/ground/gcs/src/libs/eigen/Eigen/src/UmfPackSupport/UmfPackSupport.h b/ground/gcs/src/libs/eigen/Eigen/src/UmfPackSupport/UmfPackSupport.h index 3a48cecf7..29c60c378 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/UmfPackSupport/UmfPackSupport.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/UmfPackSupport/UmfPackSupport.h @@ -107,6 +107,16 @@ inline int umfpack_get_determinant(std::complex *Mx, double *Ex, void *N return umfpack_zi_get_determinant(&mx_real,0,Ex,NumericHandle,User_Info); } +namespace internal { + template struct umfpack_helper_is_sparse_plain : false_type {}; + template + struct umfpack_helper_is_sparse_plain > + : true_type {}; + template + struct umfpack_helper_is_sparse_plain > + : true_type {}; +} + /** \ingroup UmfPackSupport_Module * \brief A sparse LU factorization and solver based on UmfPack * @@ -192,10 +202,14 @@ class UmfPackLU : internal::noncopyable * Note that the matrix should be column-major, and in compressed format for best performance. * \sa SparseMatrix::makeCompressed(). */ - void compute(const MatrixType& matrix) + template + void compute(const InputMatrixType& matrix) { - analyzePattern(matrix); - factorize(matrix); + if(m_symbolic) umfpack_free_symbolic(&m_symbolic,Scalar()); + if(m_numeric) umfpack_free_numeric(&m_numeric,Scalar()); + grapInput(matrix.derived()); + analyzePattern_impl(); + factorize_impl(); } /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. @@ -230,23 +244,15 @@ class UmfPackLU : internal::noncopyable * * \sa factorize(), compute() */ - void analyzePattern(const MatrixType& matrix) + template + void analyzePattern(const InputMatrixType& matrix) { - if(m_symbolic) - umfpack_free_symbolic(&m_symbolic,Scalar()); - if(m_numeric) - umfpack_free_numeric(&m_numeric,Scalar()); + if(m_symbolic) umfpack_free_symbolic(&m_symbolic,Scalar()); + if(m_numeric) umfpack_free_numeric(&m_numeric,Scalar()); - grapInput(matrix); + grapInput(matrix.derived()); - int errorCode = 0; - errorCode = umfpack_symbolic(matrix.rows(), matrix.cols(), m_outerIndexPtr, m_innerIndexPtr, m_valuePtr, - &m_symbolic, 0, 0); - - m_isInitialized = true; - m_info = errorCode ? InvalidInput : Success; - m_analysisIsOk = true; - m_factorizationIsOk = false; + analyzePattern_impl(); } /** Performs a numeric decomposition of \a matrix @@ -255,20 +261,16 @@ class UmfPackLU : internal::noncopyable * * \sa analyzePattern(), compute() */ - void factorize(const MatrixType& matrix) + template + void factorize(const InputMatrixType& matrix) { eigen_assert(m_analysisIsOk && "UmfPackLU: you must first call analyzePattern()"); if(m_numeric) umfpack_free_numeric(&m_numeric,Scalar()); - grapInput(matrix); - - int errorCode; - errorCode = umfpack_numeric(m_outerIndexPtr, m_innerIndexPtr, m_valuePtr, - m_symbolic, &m_numeric, 0, 0); - - m_info = errorCode ? NumericalIssue : Success; - m_factorizationIsOk = true; + grapInput(matrix.derived()); + + factorize_impl(); } #ifndef EIGEN_PARSED_BY_DOXYGEN @@ -283,19 +285,20 @@ class UmfPackLU : internal::noncopyable protected: - void init() { - m_info = InvalidInput; - m_isInitialized = false; - m_numeric = 0; - m_symbolic = 0; - m_outerIndexPtr = 0; - m_innerIndexPtr = 0; - m_valuePtr = 0; + m_info = InvalidInput; + m_isInitialized = false; + m_numeric = 0; + m_symbolic = 0; + m_outerIndexPtr = 0; + m_innerIndexPtr = 0; + m_valuePtr = 0; + m_extractedDataAreDirty = true; } - void grapInput(const MatrixType& mat) + template + void grapInput_impl(const InputMatrixType& mat, internal::true_type) { m_copyMatrix.resize(mat.rows(), mat.cols()); if( ((MatrixType::Flags&RowMajorBit)==RowMajorBit) || sizeof(typename MatrixType::Index)!=sizeof(int) || !mat.isCompressed() ) @@ -313,6 +316,45 @@ class UmfPackLU : internal::noncopyable m_valuePtr = mat.valuePtr(); } } + + template + void grapInput_impl(const InputMatrixType& mat, internal::false_type) + { + m_copyMatrix = mat; + m_outerIndexPtr = m_copyMatrix.outerIndexPtr(); + m_innerIndexPtr = m_copyMatrix.innerIndexPtr(); + m_valuePtr = m_copyMatrix.valuePtr(); + } + + template + void grapInput(const InputMatrixType& mat) + { + grapInput_impl(mat, internal::umfpack_helper_is_sparse_plain()); + } + + void analyzePattern_impl() + { + int errorCode = 0; + errorCode = umfpack_symbolic(m_copyMatrix.rows(), m_copyMatrix.cols(), m_outerIndexPtr, m_innerIndexPtr, m_valuePtr, + &m_symbolic, 0, 0); + + m_isInitialized = true; + m_info = errorCode ? InvalidInput : Success; + m_analysisIsOk = true; + m_factorizationIsOk = false; + m_extractedDataAreDirty = true; + } + + void factorize_impl() + { + int errorCode; + errorCode = umfpack_numeric(m_outerIndexPtr, m_innerIndexPtr, m_valuePtr, + m_symbolic, &m_numeric, 0, 0); + + m_info = errorCode ? NumericalIssue : Success; + m_factorizationIsOk = true; + m_extractedDataAreDirty = true; + } // cached data to reduce reallocation, etc. mutable LUMatrixType m_l; diff --git a/ground/gcs/src/libs/eigen/Eigen/src/plugins/ArrayCwiseBinaryOps.h b/ground/gcs/src/libs/eigen/Eigen/src/plugins/ArrayCwiseBinaryOps.h index 5c8c476ee..1951286f3 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/plugins/ArrayCwiseBinaryOps.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/plugins/ArrayCwiseBinaryOps.h @@ -70,6 +70,43 @@ max return (max)(Derived::PlainObject::Constant(rows(), cols(), other)); } + +#define EIGEN_MAKE_CWISE_COMP_OP(OP, COMPARATOR) \ +template \ +EIGEN_STRONG_INLINE const CwiseBinaryOp, const Derived, const OtherDerived> \ +OP(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const \ +{ \ + return CwiseBinaryOp, const Derived, const OtherDerived>(derived(), other.derived()); \ +}\ +typedef CwiseBinaryOp, const Derived, const CwiseNullaryOp, PlainObject> > Cmp ## COMPARATOR ## ReturnType; \ +typedef CwiseBinaryOp, const CwiseNullaryOp, PlainObject>, const Derived > RCmp ## COMPARATOR ## ReturnType; \ +EIGEN_STRONG_INLINE const Cmp ## COMPARATOR ## ReturnType \ +OP(const Scalar& s) const { \ + return this->OP(Derived::PlainObject::Constant(rows(), cols(), s)); \ +} \ +friend EIGEN_STRONG_INLINE const RCmp ## COMPARATOR ## ReturnType \ +OP(const Scalar& s, const Derived& d) { \ + return Derived::PlainObject::Constant(d.rows(), d.cols(), s).OP(d); \ +} + +#define EIGEN_MAKE_CWISE_COMP_R_OP(OP, R_OP, RCOMPARATOR) \ +template \ +EIGEN_STRONG_INLINE const CwiseBinaryOp, const OtherDerived, const Derived> \ +OP(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const \ +{ \ + return CwiseBinaryOp, const OtherDerived, const Derived>(other.derived(), derived()); \ +} \ +\ +inline const RCmp ## RCOMPARATOR ## ReturnType \ +OP(const Scalar& s) const { \ + return Derived::PlainObject::Constant(rows(), cols(), s).R_OP(*this); \ +} \ +friend inline const Cmp ## RCOMPARATOR ## ReturnType \ +OP(const Scalar& s, const Derived& d) { \ + return d.R_OP(Derived::PlainObject::Constant(d.rows(), d.cols(), s)); \ +} + + /** \returns an expression of the coefficient-wise \< operator of *this and \a other * * Example: \include Cwise_less.cpp @@ -77,7 +114,7 @@ max * * \sa all(), any(), operator>(), operator<=() */ -EIGEN_MAKE_CWISE_BINARY_OP(operator<,std::less) +EIGEN_MAKE_CWISE_COMP_OP(operator<, LT) /** \returns an expression of the coefficient-wise \<= operator of *this and \a other * @@ -86,7 +123,7 @@ EIGEN_MAKE_CWISE_BINARY_OP(operator<,std::less) * * \sa all(), any(), operator>=(), operator<() */ -EIGEN_MAKE_CWISE_BINARY_OP(operator<=,std::less_equal) +EIGEN_MAKE_CWISE_COMP_OP(operator<=, LE) /** \returns an expression of the coefficient-wise \> operator of *this and \a other * @@ -95,7 +132,7 @@ EIGEN_MAKE_CWISE_BINARY_OP(operator<=,std::less_equal) * * \sa all(), any(), operator>=(), operator<() */ -EIGEN_MAKE_CWISE_BINARY_OP(operator>,std::greater) +EIGEN_MAKE_CWISE_COMP_R_OP(operator>, operator<, LT) /** \returns an expression of the coefficient-wise \>= operator of *this and \a other * @@ -104,7 +141,7 @@ EIGEN_MAKE_CWISE_BINARY_OP(operator>,std::greater) * * \sa all(), any(), operator>(), operator<=() */ -EIGEN_MAKE_CWISE_BINARY_OP(operator>=,std::greater_equal) +EIGEN_MAKE_CWISE_COMP_R_OP(operator>=, operator<=, LE) /** \returns an expression of the coefficient-wise == operator of *this and \a other * @@ -118,7 +155,7 @@ EIGEN_MAKE_CWISE_BINARY_OP(operator>=,std::greater_equal) * * \sa all(), any(), isApprox(), isMuchSmallerThan() */ -EIGEN_MAKE_CWISE_BINARY_OP(operator==,std::equal_to) +EIGEN_MAKE_CWISE_COMP_OP(operator==, EQ) /** \returns an expression of the coefficient-wise != operator of *this and \a other * @@ -132,7 +169,10 @@ EIGEN_MAKE_CWISE_BINARY_OP(operator==,std::equal_to) * * \sa all(), any(), isApprox(), isMuchSmallerThan() */ -EIGEN_MAKE_CWISE_BINARY_OP(operator!=,std::not_equal_to) +EIGEN_MAKE_CWISE_COMP_OP(operator!=, NEQ) + +#undef EIGEN_MAKE_CWISE_COMP_OP +#undef EIGEN_MAKE_CWISE_COMP_R_OP // scalar addition @@ -209,3 +249,5 @@ operator||(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_OF_BOOL); return CwiseBinaryOp(derived(),other.derived()); } + + diff --git a/ground/gcs/src/libs/eigen/Eigen/src/plugins/ArrayCwiseUnaryOps.h b/ground/gcs/src/libs/eigen/Eigen/src/plugins/ArrayCwiseUnaryOps.h index a59636790..1c3ed3fcd 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/plugins/ArrayCwiseUnaryOps.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/plugins/ArrayCwiseUnaryOps.h @@ -185,19 +185,3 @@ cube() const { return derived(); } - -#define EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(METHOD_NAME,FUNCTOR) \ - inline const CwiseUnaryOp >, const Derived> \ - METHOD_NAME(const Scalar& s) const { \ - return CwiseUnaryOp >, const Derived> \ - (derived(), std::bind2nd(FUNCTOR(), s)); \ - } - -EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator==, std::equal_to) -EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator!=, std::not_equal_to) -EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator<, std::less) -EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator<=, std::less_equal) -EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator>, std::greater) -EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator>=, std::greater_equal) - - diff --git a/ground/gcs/src/libs/eigen/Eigen/src/plugins/BlockMethods.h b/ground/gcs/src/libs/eigen/Eigen/src/plugins/BlockMethods.h index 6911bedef..2788251e0 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/plugins/BlockMethods.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/plugins/BlockMethods.h @@ -113,13 +113,13 @@ inline const Block topRightCorner() const /** \returns an expression of a top-right corner of *this. * - * \tparam CRows number of rows in corner as specified at compile time - * \tparam CCols number of columns in corner as specified at compile time - * \param cRows number of rows in corner as specified at run time - * \param cCols number of columns in corner as specified at run time + * \tparam CRows number of rows in corner as specified at compile-time + * \tparam CCols number of columns in corner as specified at compile-time + * \param cRows number of rows in corner as specified at run-time + * \param cCols number of columns in corner as specified at run-time * - * This function is mainly useful for corners where the number of rows is specified at compile time - * and the number of columns is specified at run time, or vice versa. The compile-time and run-time + * This function is mainly useful for corners where the number of rows is specified at compile-time + * and the number of columns is specified at run-time, or vice versa. The compile-time and run-time * information should not contradict. In other words, \a cRows should equal \a CRows unless * \a CRows is \a Dynamic, and the same for the number of columns. * @@ -188,13 +188,13 @@ inline const Block topLeftCorner() const /** \returns an expression of a top-left corner of *this. * - * \tparam CRows number of rows in corner as specified at compile time - * \tparam CCols number of columns in corner as specified at compile time - * \param cRows number of rows in corner as specified at run time - * \param cCols number of columns in corner as specified at run time + * \tparam CRows number of rows in corner as specified at compile-time + * \tparam CCols number of columns in corner as specified at compile-time + * \param cRows number of rows in corner as specified at run-time + * \param cCols number of columns in corner as specified at run-time * - * This function is mainly useful for corners where the number of rows is specified at compile time - * and the number of columns is specified at run time, or vice versa. The compile-time and run-time + * This function is mainly useful for corners where the number of rows is specified at compile-time + * and the number of columns is specified at run-time, or vice versa. The compile-time and run-time * information should not contradict. In other words, \a cRows should equal \a CRows unless * \a CRows is \a Dynamic, and the same for the number of columns. * @@ -263,13 +263,13 @@ inline const Block bottomRightCorner() const /** \returns an expression of a bottom-right corner of *this. * - * \tparam CRows number of rows in corner as specified at compile time - * \tparam CCols number of columns in corner as specified at compile time - * \param cRows number of rows in corner as specified at run time - * \param cCols number of columns in corner as specified at run time + * \tparam CRows number of rows in corner as specified at compile-time + * \tparam CCols number of columns in corner as specified at compile-time + * \param cRows number of rows in corner as specified at run-time + * \param cCols number of columns in corner as specified at run-time * - * This function is mainly useful for corners where the number of rows is specified at compile time - * and the number of columns is specified at run time, or vice versa. The compile-time and run-time + * This function is mainly useful for corners where the number of rows is specified at compile-time + * and the number of columns is specified at run-time, or vice versa. The compile-time and run-time * information should not contradict. In other words, \a cRows should equal \a CRows unless * \a CRows is \a Dynamic, and the same for the number of columns. * @@ -338,13 +338,13 @@ inline const Block bottomLeftCorner() const /** \returns an expression of a bottom-left corner of *this. * - * \tparam CRows number of rows in corner as specified at compile time - * \tparam CCols number of columns in corner as specified at compile time - * \param cRows number of rows in corner as specified at run time - * \param cCols number of columns in corner as specified at run time + * \tparam CRows number of rows in corner as specified at compile-time + * \tparam CCols number of columns in corner as specified at compile-time + * \param cRows number of rows in corner as specified at run-time + * \param cCols number of columns in corner as specified at run-time * - * This function is mainly useful for corners where the number of rows is specified at compile time - * and the number of columns is specified at run time, or vice versa. The compile-time and run-time + * This function is mainly useful for corners where the number of rows is specified at compile-time + * and the number of columns is specified at run-time, or vice versa. The compile-time and run-time * information should not contradict. In other words, \a cRows should equal \a CRows unless * \a CRows is \a Dynamic, and the same for the number of columns. * @@ -390,7 +390,11 @@ inline ConstRowsBlockXpr topRows(Index n) const /** \returns a block consisting of the top rows of *this. * - * \tparam N the number of rows in the block + * \tparam N the number of rows in the block as specified at compile-time + * \param n the number of rows in the block as specified at run-time + * + * The compile-time and run-time information should not contradict. In other words, + * \a n should equal \a N unless \a N is \a Dynamic. * * Example: \include MatrixBase_template_int_topRows.cpp * Output: \verbinclude MatrixBase_template_int_topRows.out @@ -398,16 +402,16 @@ inline ConstRowsBlockXpr topRows(Index n) const * \sa class Block, block(Index,Index,Index,Index) */ template -inline typename NRowsBlockXpr::Type topRows() +inline typename NRowsBlockXpr::Type topRows(Index n = N) { - return typename NRowsBlockXpr::Type(derived(), 0, 0, N, cols()); + return typename NRowsBlockXpr::Type(derived(), 0, 0, n, cols()); } /** This is the const version of topRows().*/ template -inline typename ConstNRowsBlockXpr::Type topRows() const +inline typename ConstNRowsBlockXpr::Type topRows(Index n = N) const { - return typename ConstNRowsBlockXpr::Type(derived(), 0, 0, N, cols()); + return typename ConstNRowsBlockXpr::Type(derived(), 0, 0, n, cols()); } @@ -434,7 +438,11 @@ inline ConstRowsBlockXpr bottomRows(Index n) const /** \returns a block consisting of the bottom rows of *this. * - * \tparam N the number of rows in the block + * \tparam N the number of rows in the block as specified at compile-time + * \param n the number of rows in the block as specified at run-time + * + * The compile-time and run-time information should not contradict. In other words, + * \a n should equal \a N unless \a N is \a Dynamic. * * Example: \include MatrixBase_template_int_bottomRows.cpp * Output: \verbinclude MatrixBase_template_int_bottomRows.out @@ -442,16 +450,16 @@ inline ConstRowsBlockXpr bottomRows(Index n) const * \sa class Block, block(Index,Index,Index,Index) */ template -inline typename NRowsBlockXpr::Type bottomRows() +inline typename NRowsBlockXpr::Type bottomRows(Index n = N) { - return typename NRowsBlockXpr::Type(derived(), rows() - N, 0, N, cols()); + return typename NRowsBlockXpr::Type(derived(), rows() - n, 0, n, cols()); } /** This is the const version of bottomRows().*/ template -inline typename ConstNRowsBlockXpr::Type bottomRows() const +inline typename ConstNRowsBlockXpr::Type bottomRows(Index n = N) const { - return typename ConstNRowsBlockXpr::Type(derived(), rows() - N, 0, N, cols()); + return typename ConstNRowsBlockXpr::Type(derived(), rows() - n, 0, n, cols()); } @@ -459,28 +467,32 @@ inline typename ConstNRowsBlockXpr::Type bottomRows() const /** \returns a block consisting of a range of rows of *this. * * \param startRow the index of the first row in the block - * \param numRows the number of rows in the block + * \param n the number of rows in the block * * Example: \include DenseBase_middleRows_int.cpp * Output: \verbinclude DenseBase_middleRows_int.out * * \sa class Block, block(Index,Index,Index,Index) */ -inline RowsBlockXpr middleRows(Index startRow, Index numRows) +inline RowsBlockXpr middleRows(Index startRow, Index n) { - return RowsBlockXpr(derived(), startRow, 0, numRows, cols()); + return RowsBlockXpr(derived(), startRow, 0, n, cols()); } /** This is the const version of middleRows(Index,Index).*/ -inline ConstRowsBlockXpr middleRows(Index startRow, Index numRows) const +inline ConstRowsBlockXpr middleRows(Index startRow, Index n) const { - return ConstRowsBlockXpr(derived(), startRow, 0, numRows, cols()); + return ConstRowsBlockXpr(derived(), startRow, 0, n, cols()); } /** \returns a block consisting of a range of rows of *this. * - * \tparam N the number of rows in the block + * \tparam N the number of rows in the block as specified at compile-time * \param startRow the index of the first row in the block + * \param n the number of rows in the block as specified at run-time + * + * The compile-time and run-time information should not contradict. In other words, + * \a n should equal \a N unless \a N is \a Dynamic. * * Example: \include DenseBase_template_int_middleRows.cpp * Output: \verbinclude DenseBase_template_int_middleRows.out @@ -488,16 +500,16 @@ inline ConstRowsBlockXpr middleRows(Index startRow, Index numRows) const * \sa class Block, block(Index,Index,Index,Index) */ template -inline typename NRowsBlockXpr::Type middleRows(Index startRow) +inline typename NRowsBlockXpr::Type middleRows(Index startRow, Index n = N) { - return typename NRowsBlockXpr::Type(derived(), startRow, 0, N, cols()); + return typename NRowsBlockXpr::Type(derived(), startRow, 0, n, cols()); } /** This is the const version of middleRows().*/ template -inline typename ConstNRowsBlockXpr::Type middleRows(Index startRow) const +inline typename ConstNRowsBlockXpr::Type middleRows(Index startRow, Index n = N) const { - return typename ConstNRowsBlockXpr::Type(derived(), startRow, 0, N, cols()); + return typename ConstNRowsBlockXpr::Type(derived(), startRow, 0, n, cols()); } @@ -524,7 +536,11 @@ inline ConstColsBlockXpr leftCols(Index n) const /** \returns a block consisting of the left columns of *this. * - * \tparam N the number of columns in the block + * \tparam N the number of columns in the block as specified at compile-time + * \param n the number of columns in the block as specified at run-time + * + * The compile-time and run-time information should not contradict. In other words, + * \a n should equal \a N unless \a N is \a Dynamic. * * Example: \include MatrixBase_template_int_leftCols.cpp * Output: \verbinclude MatrixBase_template_int_leftCols.out @@ -532,16 +548,16 @@ inline ConstColsBlockXpr leftCols(Index n) const * \sa class Block, block(Index,Index,Index,Index) */ template -inline typename NColsBlockXpr::Type leftCols() +inline typename NColsBlockXpr::Type leftCols(Index n = N) { - return typename NColsBlockXpr::Type(derived(), 0, 0, rows(), N); + return typename NColsBlockXpr::Type(derived(), 0, 0, rows(), n); } /** This is the const version of leftCols().*/ template -inline typename ConstNColsBlockXpr::Type leftCols() const +inline typename ConstNColsBlockXpr::Type leftCols(Index n = N) const { - return typename ConstNColsBlockXpr::Type(derived(), 0, 0, rows(), N); + return typename ConstNColsBlockXpr::Type(derived(), 0, 0, rows(), n); } @@ -568,7 +584,11 @@ inline ConstColsBlockXpr rightCols(Index n) const /** \returns a block consisting of the right columns of *this. * - * \tparam N the number of columns in the block + * \tparam N the number of columns in the block as specified at compile-time + * \param n the number of columns in the block as specified at run-time + * + * The compile-time and run-time information should not contradict. In other words, + * \a n should equal \a N unless \a N is \a Dynamic. * * Example: \include MatrixBase_template_int_rightCols.cpp * Output: \verbinclude MatrixBase_template_int_rightCols.out @@ -576,16 +596,16 @@ inline ConstColsBlockXpr rightCols(Index n) const * \sa class Block, block(Index,Index,Index,Index) */ template -inline typename NColsBlockXpr::Type rightCols() +inline typename NColsBlockXpr::Type rightCols(Index n = N) { - return typename NColsBlockXpr::Type(derived(), 0, cols() - N, rows(), N); + return typename NColsBlockXpr::Type(derived(), 0, cols() - n, rows(), n); } /** This is the const version of rightCols().*/ template -inline typename ConstNColsBlockXpr::Type rightCols() const +inline typename ConstNColsBlockXpr::Type rightCols(Index n = N) const { - return typename ConstNColsBlockXpr::Type(derived(), 0, cols() - N, rows(), N); + return typename ConstNColsBlockXpr::Type(derived(), 0, cols() - n, rows(), n); } @@ -613,8 +633,12 @@ inline ConstColsBlockXpr middleCols(Index startCol, Index numCols) const /** \returns a block consisting of a range of columns of *this. * - * \tparam N the number of columns in the block + * \tparam N the number of columns in the block as specified at compile-time * \param startCol the index of the first column in the block + * \param n the number of columns in the block as specified at run-time + * + * The compile-time and run-time information should not contradict. In other words, + * \a n should equal \a N unless \a N is \a Dynamic. * * Example: \include DenseBase_template_int_middleCols.cpp * Output: \verbinclude DenseBase_template_int_middleCols.out @@ -622,16 +646,16 @@ inline ConstColsBlockXpr middleCols(Index startCol, Index numCols) const * \sa class Block, block(Index,Index,Index,Index) */ template -inline typename NColsBlockXpr::Type middleCols(Index startCol) +inline typename NColsBlockXpr::Type middleCols(Index startCol, Index n = N) { - return typename NColsBlockXpr::Type(derived(), 0, startCol, rows(), N); + return typename NColsBlockXpr::Type(derived(), 0, startCol, rows(), n); } /** This is the const version of middleCols().*/ template -inline typename ConstNColsBlockXpr::Type middleCols(Index startCol) const +inline typename ConstNColsBlockXpr::Type middleCols(Index startCol, Index n = N) const { - return typename ConstNColsBlockXpr::Type(derived(), 0, startCol, rows(), N); + return typename ConstNColsBlockXpr::Type(derived(), 0, startCol, rows(), n); } @@ -667,15 +691,15 @@ inline const Block block(Index startRow, In /** \returns an expression of a block in *this. * - * \tparam BlockRows number of rows in block as specified at compile time - * \tparam BlockCols number of columns in block as specified at compile time + * \tparam BlockRows number of rows in block as specified at compile-time + * \tparam BlockCols number of columns in block as specified at compile-time * \param startRow the first row in the block * \param startCol the first column in the block - * \param blockRows number of rows in block as specified at run time - * \param blockCols number of columns in block as specified at run time + * \param blockRows number of rows in block as specified at run-time + * \param blockCols number of columns in block as specified at run-time * - * This function is mainly useful for blocks where the number of rows is specified at compile time - * and the number of columns is specified at run time, or vice versa. The compile-time and run-time + * This function is mainly useful for blocks where the number of rows is specified at compile-time + * and the number of columns is specified at run-time, or vice versa. The compile-time and run-time * information should not contradict. In other words, \a blockRows should equal \a BlockRows unless * \a BlockRows is \a Dynamic, and the same for the number of columns. * @@ -738,7 +762,7 @@ inline ConstRowXpr row(Index i) const * \only_for_vectors * * \param start the first coefficient in the segment - * \param vecSize the number of coefficients in the segment + * \param n the number of coefficients in the segment * * Example: \include MatrixBase_segment_int_int.cpp * Output: \verbinclude MatrixBase_segment_int_int.out @@ -749,25 +773,25 @@ inline ConstRowXpr row(Index i) const * * \sa class Block, segment(Index) */ -inline SegmentReturnType segment(Index start, Index vecSize) +inline SegmentReturnType segment(Index start, Index n) { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return SegmentReturnType(derived(), start, vecSize); + return SegmentReturnType(derived(), start, n); } /** This is the const version of segment(Index,Index).*/ -inline ConstSegmentReturnType segment(Index start, Index vecSize) const +inline ConstSegmentReturnType segment(Index start, Index n) const { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return ConstSegmentReturnType(derived(), start, vecSize); + return ConstSegmentReturnType(derived(), start, n); } /** \returns a dynamic-size expression of the first coefficients of *this. * * \only_for_vectors * - * \param vecSize the number of coefficients in the block + * \param n the number of coefficients in the segment * * Example: \include MatrixBase_start_int.cpp * Output: \verbinclude MatrixBase_start_int.out @@ -778,25 +802,24 @@ inline ConstSegmentReturnType segment(Index start, Index vecSize) const * * \sa class Block, block(Index,Index) */ -inline SegmentReturnType head(Index vecSize) +inline SegmentReturnType head(Index n) { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return SegmentReturnType(derived(), 0, vecSize); + return SegmentReturnType(derived(), 0, n); } /** This is the const version of head(Index).*/ -inline ConstSegmentReturnType - head(Index vecSize) const +inline ConstSegmentReturnType head(Index n) const { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return ConstSegmentReturnType(derived(), 0, vecSize); + return ConstSegmentReturnType(derived(), 0, n); } /** \returns a dynamic-size expression of the last coefficients of *this. * * \only_for_vectors * - * \param vecSize the number of coefficients in the block + * \param n the number of coefficients in the segment * * Example: \include MatrixBase_end_int.cpp * Output: \verbinclude MatrixBase_end_int.out @@ -807,95 +830,106 @@ inline ConstSegmentReturnType * * \sa class Block, block(Index,Index) */ -inline SegmentReturnType tail(Index vecSize) +inline SegmentReturnType tail(Index n) { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return SegmentReturnType(derived(), this->size() - vecSize, vecSize); + return SegmentReturnType(derived(), this->size() - n, n); } /** This is the const version of tail(Index).*/ -inline ConstSegmentReturnType tail(Index vecSize) const +inline ConstSegmentReturnType tail(Index n) const { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return ConstSegmentReturnType(derived(), this->size() - vecSize, vecSize); + return ConstSegmentReturnType(derived(), this->size() - n, n); } /** \returns a fixed-size expression of a segment (i.e. a vector block) in \c *this * * \only_for_vectors * - * The template parameter \a Size is the number of coefficients in the block + * \tparam N the number of coefficients in the segment as specified at compile-time + * \param start the index of the first element in the segment + * \param n the number of coefficients in the segment as specified at compile-time * - * \param start the index of the first element of the sub-vector + * The compile-time and run-time information should not contradict. In other words, + * \a n should equal \a N unless \a N is \a Dynamic. * * Example: \include MatrixBase_template_int_segment.cpp * Output: \verbinclude MatrixBase_template_int_segment.out * * \sa class Block */ -template -inline typename FixedSegmentReturnType::Type segment(Index start) +template +inline typename FixedSegmentReturnType::Type segment(Index start, Index n = N) { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return typename FixedSegmentReturnType::Type(derived(), start); + return typename FixedSegmentReturnType::Type(derived(), start, n); } /** This is the const version of segment(Index).*/ -template -inline typename ConstFixedSegmentReturnType::Type segment(Index start) const +template +inline typename ConstFixedSegmentReturnType::Type segment(Index start, Index n = N) const { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return typename ConstFixedSegmentReturnType::Type(derived(), start); + return typename ConstFixedSegmentReturnType::Type(derived(), start, n); } /** \returns a fixed-size expression of the first coefficients of *this. * * \only_for_vectors * - * The template parameter \a Size is the number of coefficients in the block + * \tparam N the number of coefficients in the segment as specified at compile-time + * \param n the number of coefficients in the segment as specified at run-time + * + * The compile-time and run-time information should not contradict. In other words, + * \a n should equal \a N unless \a N is \a Dynamic. * * Example: \include MatrixBase_template_int_start.cpp * Output: \verbinclude MatrixBase_template_int_start.out * * \sa class Block */ -template -inline typename FixedSegmentReturnType::Type head() +template +inline typename FixedSegmentReturnType::Type head(Index n = N) { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return typename FixedSegmentReturnType::Type(derived(), 0); + return typename FixedSegmentReturnType::Type(derived(), 0, n); } /** This is the const version of head().*/ -template -inline typename ConstFixedSegmentReturnType::Type head() const +template +inline typename ConstFixedSegmentReturnType::Type head(Index n = N) const { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return typename ConstFixedSegmentReturnType::Type(derived(), 0); + return typename ConstFixedSegmentReturnType::Type(derived(), 0, n); } /** \returns a fixed-size expression of the last coefficients of *this. * * \only_for_vectors * - * The template parameter \a Size is the number of coefficients in the block + * \tparam N the number of coefficients in the segment as specified at compile-time + * \param n the number of coefficients in the segment as specified at run-time + * + * The compile-time and run-time information should not contradict. In other words, + * \a n should equal \a N unless \a N is \a Dynamic. * * Example: \include MatrixBase_template_int_end.cpp * Output: \verbinclude MatrixBase_template_int_end.out * * \sa class Block */ -template -inline typename FixedSegmentReturnType::Type tail() +template +inline typename FixedSegmentReturnType::Type tail(Index n = N) { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return typename FixedSegmentReturnType::Type(derived(), size() - Size); + return typename FixedSegmentReturnType::Type(derived(), size() - n); } /** This is the const version of tail.*/ -template -inline typename ConstFixedSegmentReturnType::Type tail() const +template +inline typename ConstFixedSegmentReturnType::Type tail(Index n = N) const { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return typename ConstFixedSegmentReturnType::Type(derived(), size() - Size); + return typename ConstFixedSegmentReturnType::Type(derived(), size() - n); } diff --git a/ground/gcs/src/libs/eigen/Eigen/src/plugins/MatrixCwiseBinaryOps.h b/ground/gcs/src/libs/eigen/Eigen/src/plugins/MatrixCwiseBinaryOps.h index 3a737df7b..c4a042b70 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/plugins/MatrixCwiseBinaryOps.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/plugins/MatrixCwiseBinaryOps.h @@ -83,7 +83,7 @@ cwiseMin(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const EIGEN_STRONG_INLINE const CwiseBinaryOp, const Derived, const ConstantReturnType> cwiseMin(const Scalar &other) const { - return cwiseMin(Derived::PlainObject::Constant(rows(), cols(), other)); + return cwiseMin(Derived::Constant(rows(), cols(), other)); } /** \returns an expression of the coefficient-wise max of *this and \a other @@ -107,7 +107,7 @@ cwiseMax(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const EIGEN_STRONG_INLINE const CwiseBinaryOp, const Derived, const ConstantReturnType> cwiseMax(const Scalar &other) const { - return cwiseMax(Derived::PlainObject::Constant(rows(), cols(), other)); + return cwiseMax(Derived::Constant(rows(), cols(), other)); } @@ -124,3 +124,20 @@ cwiseQuotient(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const { return CwiseBinaryOp, const Derived, const OtherDerived>(derived(), other.derived()); } + +typedef CwiseBinaryOp, const Derived, const ConstantReturnType> CwiseScalarEqualReturnType; + +/** \returns an expression of the coefficient-wise == operator of \c *this and a scalar \a s + * + * \warning this performs an exact comparison, which is generally a bad idea with floating-point types. + * In order to check for equality between two vectors or matrices with floating-point coefficients, it is + * generally a far better idea to use a fuzzy comparison as provided by isApprox() and + * isMuchSmallerThan(). + * + * \sa cwiseEqual(const MatrixBase &) const + */ +inline const CwiseScalarEqualReturnType +cwiseEqual(const Scalar& s) const +{ + return CwiseScalarEqualReturnType(derived(), Derived::Constant(rows(), cols(), s), internal::scalar_cmp_op()); +} diff --git a/ground/gcs/src/libs/eigen/Eigen/src/plugins/MatrixCwiseUnaryOps.h b/ground/gcs/src/libs/eigen/Eigen/src/plugins/MatrixCwiseUnaryOps.h index 0cf0640ba..8de10935d 100644 --- a/ground/gcs/src/libs/eigen/Eigen/src/plugins/MatrixCwiseUnaryOps.h +++ b/ground/gcs/src/libs/eigen/Eigen/src/plugins/MatrixCwiseUnaryOps.h @@ -50,18 +50,3 @@ cwiseSqrt() const { return derived(); } inline const CwiseUnaryOp, const Derived> cwiseInverse() const { return derived(); } -/** \returns an expression of the coefficient-wise == operator of \c *this and a scalar \a s - * - * \warning this performs an exact comparison, which is generally a bad idea with floating-point types. - * In order to check for equality between two vectors or matrices with floating-point coefficients, it is - * generally a far better idea to use a fuzzy comparison as provided by isApprox() and - * isMuchSmallerThan(). - * - * \sa cwiseEqual(const MatrixBase &) const - */ -inline const CwiseUnaryOp >, const Derived> -cwiseEqual(const Scalar& s) const -{ - return CwiseUnaryOp >,const Derived> - (derived(), std::bind1st(std::equal_to(), s)); -} diff --git a/ground/gcs/src/libs/eigen/blas/CMakeLists.txt b/ground/gcs/src/libs/eigen/blas/CMakeLists.txt index c35a2fdbe..a9bc05137 100644 --- a/ground/gcs/src/libs/eigen/blas/CMakeLists.txt +++ b/ground/gcs/src/libs/eigen/blas/CMakeLists.txt @@ -7,6 +7,9 @@ workaround_9220(Fortran EIGEN_Fortran_COMPILER_WORKS) if(EIGEN_Fortran_COMPILER_WORKS) enable_language(Fortran OPTIONAL) + if(NOT CMAKE_Fortran_COMPILER) + set(EIGEN_Fortran_COMPILER_WORKS OFF) + endif() endif() add_custom_target(blas) diff --git a/ground/gcs/src/libs/eigen/blas/README.txt b/ground/gcs/src/libs/eigen/blas/README.txt index 07a8bd92a..63a5203b9 100644 --- a/ground/gcs/src/libs/eigen/blas/README.txt +++ b/ground/gcs/src/libs/eigen/blas/README.txt @@ -1,9 +1,6 @@ This directory contains a BLAS library built on top of Eigen. -This is currently a work in progress which is far to be ready for use, -but feel free to contribute to it if you wish. - This module is not built by default. In order to compile it, you need to type 'make blas' from within your build dir. diff --git a/ground/gcs/src/libs/eigen/blas/xerbla.cpp b/ground/gcs/src/libs/eigen/blas/xerbla.cpp index 0d57710fe..dd39a5244 100644 --- a/ground/gcs/src/libs/eigen/blas/xerbla.cpp +++ b/ground/gcs/src/libs/eigen/blas/xerbla.cpp @@ -1,7 +1,7 @@ #include -#if (defined __GNUC__) +#if (defined __GNUC__) && (!defined __MINGW32__) && (!defined __CYGWIN__) #define EIGEN_WEAK_LINKING __attribute__ ((weak)) #else #define EIGEN_WEAK_LINKING diff --git a/ground/gcs/src/libs/eigen/cmake/EigenConfigureTesting.cmake b/ground/gcs/src/libs/eigen/cmake/EigenConfigureTesting.cmake index 228d29e97..2b11d8360 100644 --- a/ground/gcs/src/libs/eigen/cmake/EigenConfigureTesting.cmake +++ b/ground/gcs/src/libs/eigen/cmake/EigenConfigureTesting.cmake @@ -26,31 +26,20 @@ include(CTest) set(EIGEN_TEST_BUILD_FLAGS " " CACHE STRING "Options passed to the build command of unit tests") -# overwrite default DartConfiguration.tcl -# The worarounds are different for each version of the MSVC IDE -if(MSVC_IDE) - if(CMAKE_MAKE_PROGRAM_SAVE MATCHES "devenv") # devenv - set(EIGEN_MAKECOMMAND_PLACEHOLDER "${CMAKE_MAKE_PROGRAM_SAVE} Eigen.sln /build \"Release\" /project buildtests ${EIGEN_TEST_BUILD_FLAGS} \n# ") - else() # msbuild - set(EIGEN_MAKECOMMAND_PLACEHOLDER "${CMAKE_MAKE_PROGRAM_SAVE} buildtests.vcxproj /p:Configuration=\${CTEST_CONFIGURATION_TYPE} ${EIGEN_TEST_BUILD_FLAGS}\n# ") - endif() -else() - # for make and nmake - set(EIGEN_MAKECOMMAND_PLACEHOLDER "${CMAKE_MAKE_PROGRAM_SAVE} buildtests ${EIGEN_TEST_BUILD_FLAGS}") +# Overwrite default DartConfiguration.tcl such that ctest can build our unit tests. +# Recall that our unit tests are not in the "all" target, so we have to explicitely ask ctest to build our custom 'buildtests' target. +# At this stage, we can also add custom flags to the build tool through the user defined EIGEN_TEST_BUILD_FLAGS variable. +file(READ "${CMAKE_CURRENT_BINARY_DIR}/DartConfiguration.tcl" EIGEN_DART_CONFIG_FILE) +# try to grab the default flags +string(REGEX MATCH "MakeCommand:.*-- (.*)\nDefaultCTestConfigurationType" EIGEN_DUMMY ${EIGEN_DART_CONFIG_FILE}) +if(NOT CMAKE_MATCH_1) +string(REGEX MATCH "MakeCommand:.*[^c]make (.*)\nDefaultCTestConfigurationType" EIGEN_DUMMY ${EIGEN_DART_CONFIG_FILE}) endif() +string(REGEX REPLACE "MakeCommand:.*DefaultCTestConfigurationType" "MakeCommand: ${CMAKE_COMMAND} --build . --target buildtests --config \"\${CTEST_CONFIGURATION_TYPE}\" -- ${CMAKE_MATCH_1} ${EIGEN_TEST_BUILD_FLAGS}\nDefaultCTestConfigurationType" + EIGEN_DART_CONFIG_FILE2 ${EIGEN_DART_CONFIG_FILE}) +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/DartConfiguration.tcl" ${EIGEN_DART_CONFIG_FILE2}) -# copy ctest properties, which currently -# o raise the warning levels -configure_file(${CMAKE_BINARY_DIR}/DartConfiguration.tcl ${CMAKE_BINARY_DIR}/DartConfiguration.tcl) - -# restore default CMAKE_MAKE_PROGRAM -set(CMAKE_MAKE_PROGRAM ${CMAKE_MAKE_PROGRAM_SAVE}) -# un-set temporary variables so that it is like they never existed. -# CMake 2.6.3 introduces the more logical unset() syntax for this. -set(CMAKE_MAKE_PROGRAM_SAVE) -set(EIGEN_MAKECOMMAND_PLACEHOLDER) - -configure_file(${CMAKE_SOURCE_DIR}/CTestCustom.cmake.in ${CMAKE_BINARY_DIR}/CTestCustom.cmake) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CTestCustom.cmake.in ${CMAKE_BINARY_DIR}/CTestCustom.cmake) # some documentation of this function would be nice ei_init_testing() diff --git a/ground/gcs/src/libs/eigen/cmake/EigenTesting.cmake b/ground/gcs/src/libs/eigen/cmake/EigenTesting.cmake index d9e22ab1a..cbe12d51b 100644 --- a/ground/gcs/src/libs/eigen/cmake/EigenTesting.cmake +++ b/ground/gcs/src/libs/eigen/cmake/EigenTesting.cmake @@ -322,22 +322,21 @@ macro(ei_get_compilerver VAR) endif() else() # on all other system we rely on ${CMAKE_CXX_COMPILER} - # supporting a "--version" flag + # supporting a "--version" or "/version" flag - # check whether the head command exists - find_program(HEAD_EXE head NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_PATH NO_CMAKE_SYSTEM_PATH) - if(HEAD_EXE) - execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version - COMMAND head -n 1 - OUTPUT_VARIABLE eigen_cxx_compiler_version_string OUTPUT_STRIP_TRAILING_WHITESPACE) + if(WIN32 AND ${CMAKE_CXX_COMPILER_ID} EQUAL "Intel") + set(EIGEN_CXX_FLAG_VERSION "/version") else() - execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version - OUTPUT_VARIABLE eigen_cxx_compiler_version_string OUTPUT_STRIP_TRAILING_WHITESPACE) - string(REGEX REPLACE "[\n\r].*" "" eigen_cxx_compiler_version_string ${eigen_cxx_compiler_version_string}) + set(EIGEN_CXX_FLAG_VERSION "--version") endif() + execute_process(COMMAND ${CMAKE_CXX_COMPILER} ${EIGEN_CXX_FLAG_VERSION} + OUTPUT_VARIABLE eigen_cxx_compiler_version_string OUTPUT_STRIP_TRAILING_WHITESPACE) + string(REGEX REPLACE "[\n\r].*" "" eigen_cxx_compiler_version_string ${eigen_cxx_compiler_version_string}) + ei_get_compilerver_from_cxx_version_string("${eigen_cxx_compiler_version_string}" CNAME CVER) set(${VAR} "${CNAME}-${CVER}") + endif() endmacro(ei_get_compilerver) @@ -452,20 +451,12 @@ macro(ei_set_build_string) endmacro(ei_set_build_string) macro(ei_is_64bit_env VAR) - - file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/is64.cpp" - "int main() { return (sizeof(int*) == 8 ? 1 : 0); } - ") - try_run(run_res compile_res - ${CMAKE_CURRENT_BINARY_DIR} "${CMAKE_CURRENT_BINARY_DIR}/is64.cpp" - RUN_OUTPUT_VARIABLE run_output) - - if(compile_res AND run_res) - set(${VAR} ${run_res}) - elseif(CMAKE_CL_64) - set(${VAR} 1) - elseif("$ENV{Platform}" STREQUAL "X64") # nmake 64 bit + if(CMAKE_SIZEOF_VOID_P EQUAL 8) set(${VAR} 1) + elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) + set(${VAR} 0) + else() + message(WARNING "Unsupported pointer size. Please contact the authors.") endif() endmacro(ei_is_64bit_env) diff --git a/ground/gcs/src/libs/eigen/cmake/FindCholmod.cmake b/ground/gcs/src/libs/eigen/cmake/FindCholmod.cmake index 7b3046d45..23239c300 100644 --- a/ground/gcs/src/libs/eigen/cmake/FindCholmod.cmake +++ b/ground/gcs/src/libs/eigen/cmake/FindCholmod.cmake @@ -86,4 +86,4 @@ include(FindPackageHandleStandardArgs) find_package_handle_standard_args(CHOLMOD DEFAULT_MSG CHOLMOD_INCLUDES CHOLMOD_LIBRARIES) -mark_as_advanced(CHOLMOD_INCLUDES CHOLMOD_LIBRARIES AMD_LIBRARY COLAMD_LIBRARY SUITESPARSE_LIBRARY) +mark_as_advanced(CHOLMOD_INCLUDES CHOLMOD_LIBRARIES AMD_LIBRARY COLAMD_LIBRARY SUITESPARSE_LIBRARY CAMD_LIBRARY CCOLAMD_LIBRARY CHOLMOD_METIS_LIBRARY) diff --git a/ground/gcs/src/libs/eigen/cmake/FindFFTW.cmake b/ground/gcs/src/libs/eigen/cmake/FindFFTW.cmake index a9e9925e7..6c4dc9ab4 100644 --- a/ground/gcs/src/libs/eigen/cmake/FindFFTW.cmake +++ b/ground/gcs/src/libs/eigen/cmake/FindFFTW.cmake @@ -115,5 +115,5 @@ include(FindPackageHandleStandardArgs) find_package_handle_standard_args(FFTW DEFAULT_MSG FFTW_INCLUDES FFTW_LIBRARIES) -mark_as_advanced(FFTW_INCLUDES FFTW_LIBRARIES) +mark_as_advanced(FFTW_INCLUDES FFTW_LIBRARIES FFTW_LIB FFTWF_LIB FFTWL_LIB) diff --git a/ground/gcs/src/libs/eigen/cmake/FindMetis.cmake b/ground/gcs/src/libs/eigen/cmake/FindMetis.cmake index 627c3e9ae..6a0ce790c 100644 --- a/ground/gcs/src/libs/eigen/cmake/FindMetis.cmake +++ b/ground/gcs/src/libs/eigen/cmake/FindMetis.cmake @@ -10,16 +10,50 @@ find_path(METIS_INCLUDES PATHS $ENV{METISDIR} ${INCLUDE_INSTALL_DIR} - PATH_SUFFIXES + PATH_SUFFIXES + . metis include ) +macro(_metis_check_version) + file(READ "${METIS_INCLUDES}/metis.h" _metis_version_header) + + string(REGEX MATCH "define[ \t]+METIS_VER_MAJOR[ \t]+([0-9]+)" _metis_major_version_match "${_metis_version_header}") + set(METIS_MAJOR_VERSION "${CMAKE_MATCH_1}") + string(REGEX MATCH "define[ \t]+METIS_VER_MINOR[ \t]+([0-9]+)" _metis_minor_version_match "${_metis_version_header}") + set(METIS_MINOR_VERSION "${CMAKE_MATCH_1}") + string(REGEX MATCH "define[ \t]+METIS_VER_SUBMINOR[ \t]+([0-9]+)" _metis_subminor_version_match "${_metis_version_header}") + set(METIS_SUBMINOR_VERSION "${CMAKE_MATCH_1}") + if(NOT METIS_MAJOR_VERSION) + message(STATUS "Could not determine Metis version. Assuming version 4.0.0") + set(METIS_VERSION 4.0.0) + else() + set(METIS_VERSION ${METIS_MAJOR_VERSION}.${METIS_MINOR_VERSION}.${METIS_SUBMINOR_VERSION}) + endif() + if(${METIS_VERSION} VERSION_LESS ${Metis_FIND_VERSION}) + set(METIS_VERSION_OK FALSE) + else() + set(METIS_VERSION_OK TRUE) + endif() + + if(NOT METIS_VERSION_OK) + message(STATUS "Metis version ${METIS_VERSION} found in ${METIS_INCLUDES}, " + "but at least version ${Metis_FIND_VERSION} is required") + endif(NOT METIS_VERSION_OK) +endmacro(_metis_check_version) + + if(METIS_INCLUDES AND Metis_FIND_VERSION) + _metis_check_version() + else() + set(METIS_VERSION_OK TRUE) + endif() + find_library(METIS_LIBRARIES metis PATHS $ENV{METISDIR} ${LIB_INSTALL_DIR} PATH_SUFFIXES lib) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(METIS DEFAULT_MSG - METIS_INCLUDES METIS_LIBRARIES) + METIS_INCLUDES METIS_LIBRARIES METIS_VERSION_OK) mark_as_advanced(METIS_INCLUDES METIS_LIBRARIES) diff --git a/ground/gcs/src/libs/eigen/cmake/FindSPQR.cmake b/ground/gcs/src/libs/eigen/cmake/FindSPQR.cmake index 794c212af..1e958c3c1 100644 --- a/ground/gcs/src/libs/eigen/cmake/FindSPQR.cmake +++ b/ground/gcs/src/libs/eigen/cmake/FindSPQR.cmake @@ -26,7 +26,12 @@ if(SPQR_LIBRARIES) find_library(SUITESPARSE_LIBRARY SuiteSparse PATHS $ENV{SPQRDIR} ${LIB_INSTALL_DIR}) if (SUITESPARSE_LIBRARY) set(SPQR_LIBRARIES ${SPQR_LIBRARIES} ${SUITESPARSE_LIBRARY}) - endif (SUITESPARSE_LIBRARY) + endif() + + find_library(CHOLMOD_LIBRARY cholmod PATHS $ENV{UMFPACK_LIBDIR} $ENV{UMFPACKDIR} ${LIB_INSTALL_DIR}) + if(CHOLMOD_LIBRARY) + set(SPQR_LIBRARIES ${SPQR_LIBRARIES} ${CHOLMOD_LIBRARY}) + endif() endif(SPQR_LIBRARIES) diff --git a/ground/gcs/src/libs/eigen/cmake/FindUmfpack.cmake b/ground/gcs/src/libs/eigen/cmake/FindUmfpack.cmake index 16b046cd6..53cf0b49b 100644 --- a/ground/gcs/src/libs/eigen/cmake/FindUmfpack.cmake +++ b/ground/gcs/src/libs/eigen/cmake/FindUmfpack.cmake @@ -20,24 +20,29 @@ find_library(UMFPACK_LIBRARIES umfpack PATHS $ENV{UMFPACKDIR} ${LIB_INSTALL_DIR} if(UMFPACK_LIBRARIES) - if (NOT UMFPACK_LIBDIR) + if(NOT UMFPACK_LIBDIR) get_filename_component(UMFPACK_LIBDIR ${UMFPACK_LIBRARIES} PATH) endif(NOT UMFPACK_LIBDIR) find_library(COLAMD_LIBRARY colamd PATHS ${UMFPACK_LIBDIR} $ENV{UMFPACKDIR} ${LIB_INSTALL_DIR}) - if (COLAMD_LIBRARY) + if(COLAMD_LIBRARY) set(UMFPACK_LIBRARIES ${UMFPACK_LIBRARIES} ${COLAMD_LIBRARY}) - endif (COLAMD_LIBRARY) + endif () find_library(AMD_LIBRARY amd PATHS ${UMFPACK_LIBDIR} $ENV{UMFPACKDIR} ${LIB_INSTALL_DIR}) - if (AMD_LIBRARY) + if(AMD_LIBRARY) set(UMFPACK_LIBRARIES ${UMFPACK_LIBRARIES} ${AMD_LIBRARY}) - endif (AMD_LIBRARY) + endif () find_library(SUITESPARSE_LIBRARY SuiteSparse PATHS ${UMFPACK_LIBDIR} $ENV{UMFPACKDIR} ${LIB_INSTALL_DIR}) - if (SUITESPARSE_LIBRARY) + if(SUITESPARSE_LIBRARY) set(UMFPACK_LIBRARIES ${UMFPACK_LIBRARIES} ${SUITESPARSE_LIBRARY}) - endif (SUITESPARSE_LIBRARY) + endif () + + find_library(CHOLMOD_LIBRARY cholmod PATHS $ENV{UMFPACK_LIBDIR} $ENV{UMFPACKDIR} ${LIB_INSTALL_DIR}) + if(CHOLMOD_LIBRARY) + set(UMFPACK_LIBRARIES ${UMFPACK_LIBRARIES} ${CHOLMOD_LIBRARY}) + endif() endif(UMFPACK_LIBRARIES) @@ -45,4 +50,4 @@ include(FindPackageHandleStandardArgs) find_package_handle_standard_args(UMFPACK DEFAULT_MSG UMFPACK_INCLUDES UMFPACK_LIBRARIES) -mark_as_advanced(UMFPACK_INCLUDES UMFPACK_LIBRARIES AMD_LIBRARY COLAMD_LIBRARY SUITESPARSE_LIBRARY) +mark_as_advanced(UMFPACK_INCLUDES UMFPACK_LIBRARIES AMD_LIBRARY COLAMD_LIBRARY CHOLMOD_LIBRARY SUITESPARSE_LIBRARY) diff --git a/ground/gcs/src/libs/eigen/cmake/language_support.cmake b/ground/gcs/src/libs/eigen/cmake/language_support.cmake index 2ca303c92..231f7ff70 100644 --- a/ground/gcs/src/libs/eigen/cmake/language_support.cmake +++ b/ground/gcs/src/libs/eigen/cmake/language_support.cmake @@ -23,7 +23,7 @@ function(workaround_9220 language language_works) #message("DEBUG: language = ${language}") set(text "project(test NONE) - cmake_minimum_required(VERSION 2.6.0) + cmake_minimum_required(VERSION 2.8.0) set (CMAKE_Fortran_FLAGS \"${CMAKE_Fortran_FLAGS}\") set (CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS}\") enable_language(${language} OPTIONAL) @@ -33,7 +33,7 @@ function(workaround_9220 language language_works) file(WRITE ${CMAKE_BINARY_DIR}/language_tests/${language}/CMakeLists.txt ${text}) execute_process( - COMMAND ${CMAKE_COMMAND} . + COMMAND ${CMAKE_COMMAND} . -G "${CMAKE_GENERATOR}" WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/language_tests/${language} RESULT_VARIABLE return_code OUTPUT_QUIET diff --git a/ground/gcs/src/libs/eigen/doc/A05_PortingFrom2To3.dox b/ground/gcs/src/libs/eigen/doc/A05_PortingFrom2To3.dox index d885b4f6d..4d5f3ae1f 100644 --- a/ground/gcs/src/libs/eigen/doc/A05_PortingFrom2To3.dox +++ b/ground/gcs/src/libs/eigen/doc/A05_PortingFrom2To3.dox @@ -2,6 +2,8 @@ namespace Eigen { /** \page Eigen2ToEigen3 Porting from Eigen2 to Eigen3 +
Eigen2 support is deprecated in Eigen 3.2.x and it will be removed in Eigen 3.3.
+ This page lists the most important API changes between Eigen2 and Eigen3, and gives tips to help porting your application from Eigen2 to Eigen3. diff --git a/ground/gcs/src/libs/eigen/doc/A10_Eigen2SupportModes.dox b/ground/gcs/src/libs/eigen/doc/A10_Eigen2SupportModes.dox index abfdb4683..f3df91515 100644 --- a/ground/gcs/src/libs/eigen/doc/A10_Eigen2SupportModes.dox +++ b/ground/gcs/src/libs/eigen/doc/A10_Eigen2SupportModes.dox @@ -2,6 +2,8 @@ namespace Eigen { /** \page Eigen2SupportModes Eigen 2 support modes +
Eigen2 support is deprecated in Eigen 3.2.x and it will be removed in Eigen 3.3.
+ This page documents the Eigen2 support modes, a powerful tool to help migrating your project from Eigen 2 to Eigen 3. Don't miss our page on \ref Eigen2ToEigen3 "API changes" between Eigen 2 and Eigen 3. diff --git a/ground/gcs/src/libs/eigen/doc/AsciiQuickReference.txt b/ground/gcs/src/libs/eigen/doc/AsciiQuickReference.txt index 6b0a7cd6a..b9f497f87 100644 --- a/ground/gcs/src/libs/eigen/doc/AsciiQuickReference.txt +++ b/ground/gcs/src/libs/eigen/doc/AsciiQuickReference.txt @@ -16,8 +16,8 @@ double s; // Basic usage // Eigen // Matlab // comments x.size() // length(x) // vector size -C.rows() // size(C)(1) // number of rows -C.cols() // size(C)(2) // number of columns +C.rows() // size(C,1) // number of rows +C.cols() // size(C,2) // number of columns x(i) // x(i+1) // Matlab is 1-based C(i,j) // C(i+1,j+1) // @@ -41,8 +41,8 @@ MatrixXd::Ones(rows,cols) // ones(rows,cols) C.setOnes(rows,cols) // C = ones(rows,cols) MatrixXd::Random(rows,cols) // rand(rows,cols)*2-1 // MatrixXd::Random returns uniform random numbers in (-1, 1). C.setRandom(rows,cols) // C = rand(rows,cols)*2-1 -VectorXd::LinSpace(size,low,high) // linspace(low,high,size)' -v.setLinSpace(size,low,high) // v = linspace(low,high,size)' +VectorXd::LinSpaced(size,low,high) // linspace(low,high,size)' +v.setLinSpaced(size,low,high) // v = linspace(low,high,size)' // Matrix slicing and blocks. All expressions listed here are read/write. @@ -51,20 +51,34 @@ v.setLinSpace(size,low,high) // v = linspace(low,high,size)' // Eigen // Matlab x.head(n) // x(1:n) x.head() // x(1:n) -x.tail(n) // N = rows(x); x(N - n: N) -x.tail() // N = rows(x); x(N - n: N) +x.tail(n) // x(end - n + 1: end) +x.tail() // x(end - n + 1: end) x.segment(i, n) // x(i+1 : i+n) x.segment(i) // x(i+1 : i+n) P.block(i, j, rows, cols) // P(i+1 : i+rows, j+1 : j+cols) P.block(i, j) // P(i+1 : i+rows, j+1 : j+cols) +P.row(i) // P(i+1, :) +P.col(j) // P(:, j+1) +P.leftCols() // P(:, 1:cols) +P.leftCols(cols) // P(:, 1:cols) +P.middleCols(j) // P(:, j+1:j+cols) +P.middleCols(j, cols) // P(:, j+1:j+cols) +P.rightCols() // P(:, end-cols+1:end) +P.rightCols(cols) // P(:, end-cols+1:end) +P.topRows() // P(1:rows, :) +P.topRows(rows) // P(1:rows, :) +P.middleRows(i) // P(i+1:i+rows, :) +P.middleRows(i, rows) // P(i+1:i+rows, :) +P.bottomRows() // P(end-rows+1:end, :) +P.bottomRows(rows) // P(end-rows+1:end, :) P.topLeftCorner(rows, cols) // P(1:rows, 1:cols) -P.topRightCorner(rows, cols) // [m n]=size(P); P(1:rows, n-cols+1:n) -P.bottomLeftCorner(rows, cols) // [m n]=size(P); P(m-rows+1:m, 1:cols) -P.bottomRightCorner(rows, cols) // [m n]=size(P); P(m-rows+1:m, n-cols+1:n) +P.topRightCorner(rows, cols) // P(1:rows, end-cols+1:end) +P.bottomLeftCorner(rows, cols) // P(end-rows+1:end, 1:cols) +P.bottomRightCorner(rows, cols) // P(end-rows+1:end, end-cols+1:end) P.topLeftCorner() // P(1:rows, 1:cols) -P.topRightCorner() // [m n]=size(P); P(1:rows, n-cols+1:n) -P.bottomLeftCorner() // [m n]=size(P); P(m-rows+1:m, 1:cols) -P.bottomRightCorner() // [m n]=size(P); P(m-rows+1:m, n-cols+1:n) +P.topRightCorner() // P(1:rows, end-cols+1:end) +P.bottomLeftCorner() // P(end-rows+1:end, 1:cols) +P.bottomRightCorner() // P(end-rows+1:end, end-cols+1:end) // Of particular note is Eigen's swap function which is highly optimized. // Eigen // Matlab @@ -77,6 +91,8 @@ R.adjoint() // R' R.transpose() // R.' or conj(R') R.diagonal() // diag(R) x.asDiagonal() // diag(x) +R.transpose().colwise().reverse(); // rot90(R) +R.conjugate() // conj(R) // All the same as Matlab, but matlab doesn't have *= style operators. // Matrix-vector. Matrix-matrix. Matrix-scalar. @@ -125,10 +141,8 @@ int r, c; // Eigen // Matlab R.minCoeff() // min(R(:)) R.maxCoeff() // max(R(:)) -s = R.minCoeff(&r, &c) // [aa, bb] = min(R); [cc, dd] = min(aa); - // r = bb(dd); c = dd; s = cc -s = R.maxCoeff(&r, &c) // [aa, bb] = max(R); [cc, dd] = max(aa); - // row = bb(dd); col = dd; s = cc +s = R.minCoeff(&r, &c) // [s, i] = min(R(:)); [r, c] = ind2sub(size(R), i); +s = R.maxCoeff(&r, &c) // [s, i] = max(R(:)); [r, c] = ind2sub(size(R), i); R.sum() // sum(R(:)) R.colwise().sum() // sum(R) R.rowwise().sum() // sum(R, 2) or sum(R')' @@ -150,13 +164,27 @@ x.squaredNorm() // dot(x, x) Note the equivalence is not true for co x.dot(y) // dot(x, y) x.cross(y) // cross(x, y) Requires #include +//// Type conversion +// Eigen // Matlab +A.cast(); // double(A) +A.cast(); // single(A) +A.cast(); // int32(A) +A.real(); // real(A) +A.imag(); // imag(A) +// if the original type equals destination type, no work is done + +// Note that for most operations Eigen requires all operands to have the same type: +MatrixXf F = MatrixXf::Zero(3,3); +A += F; // illegal in Eigen. In Matlab A = A+F is allowed +A += F.cast(); // F converted to double and then added (generally, conversion happens on-the-fly) + // Eigen can map existing memory into Eigen matrices. float array[3]; -Map(array, 3).fill(10); -int data[4] = 1, 2, 3, 4; -Matrix2i mat2x2(data); -MatrixXi mat2x2 = Map(data); -MatrixXi mat2x2 = Map(data, 2, 2); +Vector3f::Map(array).fill(10); // create a temporary Map over array and sets entries to 10 +int data[4] = {1, 2, 3, 4}; +Matrix2i mat2x2(data); // copies data into mat2x2 +Matrix2i::Map(data) = 2*mat2x2; // overwrite elements of data with 2*mat2x2 +MatrixXi::Map(data, 2, 2) += mat2x2; // adds mat2x2 to elements of data (alternative syntax if size is not know at compile time) // Solve Ax = b. Result stored in x. Matlab: x = A \ b. x = A.ldlt().solve(b)); // A sym. p.s.d. #include diff --git a/ground/gcs/src/libs/eigen/doc/CMakeLists.txt b/ground/gcs/src/libs/eigen/doc/CMakeLists.txt index 8a493031c..02790ee43 100644 --- a/ground/gcs/src/libs/eigen/doc/CMakeLists.txt +++ b/ground/gcs/src/libs/eigen/doc/CMakeLists.txt @@ -89,9 +89,11 @@ add_dependencies(doc-unsupported-prerequisites unsupported_snippets unsupported_ add_custom_target(doc ALL COMMAND doxygen COMMAND doxygen Doxyfile-unsupported + COMMAND ${CMAKE_COMMAND} -E copy ${Eigen_BINARY_DIR}/doc/html/group__TopicUnalignedArrayAssert.html ${Eigen_BINARY_DIR}/doc/html/TopicUnalignedArrayAssert.html COMMAND ${CMAKE_COMMAND} -E rename html eigen-doc COMMAND ${CMAKE_COMMAND} -E remove eigen-doc/eigen-doc.tgz - COMMAND ${CMAKE_COMMAND} -E tar cfz eigen-doc/eigen-doc.tgz eigen-doc + COMMAND ${CMAKE_COMMAND} -E tar cfz eigen-doc.tgz eigen-doc + COMMAND ${CMAKE_COMMAND} -E rename eigen-doc.tgz eigen-doc/eigen-doc.tgz COMMAND ${CMAKE_COMMAND} -E rename eigen-doc html WORKING_DIRECTORY ${Eigen_BINARY_DIR}/doc) diff --git a/ground/gcs/src/libs/eigen/doc/Doxyfile.in b/ground/gcs/src/libs/eigen/doc/Doxyfile.in index 1a2603b04..696dd2af1 100644 --- a/ground/gcs/src/libs/eigen/doc/Doxyfile.in +++ b/ground/gcs/src/libs/eigen/doc/Doxyfile.in @@ -222,7 +222,7 @@ ALIASES = "only_for_vectors=This is only for vectors (either row- "note_about_using_kernel_to_study_multiple_solutions=If you need a complete analysis of the space of solutions, take the one solution obtained by this method and add to it elements of the kernel, as determined by kernel()." \ "note_about_checking_solutions=This method just tries to find as good a solution as possible. If you want to check whether a solution exists or if it is accurate, just call this function to get a result and then compute the error of this result, or use MatrixBase::isApprox() directly, for instance like this: \code bool a_solution_exists = (A*result).isApprox(b, precision); \endcode This method avoids dividing by zero, so that the non-existence of a solution doesn't by itself mean that you'll get \c inf or \c nan values." \ "note_try_to_help_rvo=This function returns the result by value. In order to make that efficient, it is implemented as just a return statement using a special constructor, hopefully allowing the compiler to perform a RVO (return value optimization)." \ - "nonstableyet=\warning This is not considered to be part of the stable public API yet. Changes may happen in future releases. See \ref Experimental \"Experimental parts of Eigen\" + "nonstableyet=\warning This is not considered to be part of the stable public API yet. Changes may happen in future releases. See \ref Experimental \"Experimental parts of Eigen\"" ALIASES += "eigenAutoToc= " ALIASES += "eigenManualPage=\defgroup" @@ -315,7 +315,7 @@ IDL_PROPERTY_SUPPORT = YES # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. -DISTRIBUTE_GROUP_DOC = NO +DISTRIBUTE_GROUP_DOC = YES # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a @@ -365,7 +365,7 @@ TYPEDEF_HIDES_STRUCT = NO # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols. -SYMBOL_CACHE_SIZE = 0 +# SYMBOL_CACHE_SIZE = 0 # Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be # set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given @@ -562,7 +562,7 @@ GENERATE_BUGLIST = NO # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. -GENERATE_DEPRECATEDLIST= NO +GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. @@ -1465,13 +1465,13 @@ XML_OUTPUT = xml # which can be used by a validating XML parser to check the # syntax of the XML files. -XML_SCHEMA = +# XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. -XML_DTD = +# XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting @@ -1699,7 +1699,7 @@ DOT_NUM_THREADS = 0 # the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the # directory containing the font. -DOT_FONTNAME = FreeSans +DOT_FONTNAME = # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. diff --git a/ground/gcs/src/libs/eigen/doc/LinearLeastSquares.dox b/ground/gcs/src/libs/eigen/doc/LinearLeastSquares.dox deleted file mode 100644 index ab21a87ae..000000000 --- a/ground/gcs/src/libs/eigen/doc/LinearLeastSquares.dox +++ /dev/null @@ -1,27 +0,0 @@ -namespace Eigen { - -/** \eigenManualPage LinearLeastSquares Solving linear least squares problems - -lede - -\eigenAutoToc - -\section LinearLeastSquaresCopied Copied - -The best way to do least squares solving is with a SVD decomposition. Eigen provides one as the JacobiSVD class, and its solve() -is doing least-squares solving. - -Here is an example: - - - - - - -
Example:Output:
\include TutorialLinAlgSVDSolve.cpp \verbinclude TutorialLinAlgSVDSolve.out
- -For more information, including faster but less reliable methods, read our page concentrating on \ref LinearLeastSquares "linear least squares problems". - -*/ - -} diff --git a/ground/gcs/src/libs/eigen/doc/Manual.dox b/ground/gcs/src/libs/eigen/doc/Manual.dox index 3367982ca..52427f066 100644 --- a/ground/gcs/src/libs/eigen/doc/Manual.dox +++ b/ground/gcs/src/libs/eigen/doc/Manual.dox @@ -11,6 +11,7 @@ namespace Eigen { - \subpage TopicCustomizingEigen - \subpage TopicMultiThreading - \subpage TopicUsingIntelMKL + - \subpage TopicPitfalls - \subpage TopicTemplateKeyword - \subpage UserManual_UnderstandingEigen */ @@ -120,6 +121,8 @@ namespace Eigen { \ingroup Sparse_chapter */ /** \addtogroup TopicSparseSystems \ingroup Sparse_chapter */ +/** \addtogroup MatrixfreeSolverExample + \ingroup Sparse_chapter */ /** \addtogroup Sparse_Reference \ingroup Sparse_chapter */ diff --git a/ground/gcs/src/libs/eigen/doc/MatrixfreeSolverExample.dox b/ground/gcs/src/libs/eigen/doc/MatrixfreeSolverExample.dox new file mode 100644 index 000000000..9921c7261 --- /dev/null +++ b/ground/gcs/src/libs/eigen/doc/MatrixfreeSolverExample.dox @@ -0,0 +1,21 @@ + +namespace Eigen { + +/** + +\eigenManualPage MatrixfreeSolverExample Matrix-free solvers + +Iterative solvers such as ConjugateGradient and BiCGSTAB can be used in a matrix free context. To this end, user must provide a wrapper class inheriting EigenBase<> and implementing the following methods: + - Index rows() and Index cols(): returns number of rows and columns respectively + - operator* with and Eigen dense column vector + - resize(rows,cols): needed for source compatibility (can stay empty) + +Eigen::internal::traits<> must also be specialized for the wrapper type. + +For efficiency purpose, one might also want to provide a custom preconditioner. Here is an example using ConjugateGradient and implementing also a custom Jacobi preconditioner: +\include matrixfree_cg.cpp +Output: \verbinclude matrixfree_cg.out + +*/ + +} \ No newline at end of file diff --git a/ground/gcs/src/libs/eigen/doc/Pitfalls.dox b/ground/gcs/src/libs/eigen/doc/Pitfalls.dox new file mode 100644 index 000000000..cf42effef --- /dev/null +++ b/ground/gcs/src/libs/eigen/doc/Pitfalls.dox @@ -0,0 +1,38 @@ +namespace Eigen { + +/** \page TopicPitfalls Common pitfalls + +\section TopicPitfalls_template_keyword Compilation error with template methods + +See this \link TopicTemplateKeyword page \endlink. + +\section TopicPitfalls_auto_keyword C++11 and the auto keyword + +In short: do not use the auto keywords with Eigen's expressions, unless you are 100% sure about what you are doing. In particular, do not use the auto keyword as a replacement for a Matrix<> type. Here is an example: + +\code +MatrixXd A, B; +auto C = A*B; +for(...) { ... w = C * v; ...} +\endcode + +In this example, the type of C is not a MatrixXd but an abstract expression representing a matrix product and storing references to A and B. Therefore, the product of A*B will be carried out multiple times, once per iteration of the for loop. Moreover, if the coefficients of A or B change during the iteration, then C will evaluate to different values. + +Here is another example leading to a segfault: +\code +auto C = ((A+B).eval()).transpose(); +// do something with C +\endcode +The problem is that eval() returns a temporary object (in this case a MatrixXd) which is then referenced by the Transpose<> expression. However, this temporary is deleted right after the first line, and there the C expression reference a dead object. The same issue might occur when sub expressions are automatically evaluated by Eigen as in the following example: +\code +VectorXd u, v; +auto C = u + (A*v).normalized(); +// do something with C +\endcode +where the normalized() method has to evaluate the expensive product A*v to avoid evaluating it twice. On the other hand, the following example is perfectly fine: +\code +auto C = (u + (A*v).normalized()).eval(); +\endcode +In this case, C will be a regular VectorXd object. +*/ +} diff --git a/ground/gcs/src/libs/eigen/doc/PreprocessorDirectives.dox b/ground/gcs/src/libs/eigen/doc/PreprocessorDirectives.dox index eedd5524a..cfaba35d8 100644 --- a/ground/gcs/src/libs/eigen/doc/PreprocessorDirectives.dox +++ b/ground/gcs/src/libs/eigen/doc/PreprocessorDirectives.dox @@ -62,14 +62,19 @@ run time. However, these assertions do cost time and can thus be turned off. expect that any objects passed to it are aligned. This will turn off vectorization. Not defined by default. - \b EIGEN_DONT_ALIGN_STATICALLY - disables alignment of arrays on the stack. Not defined by default, unless \c EIGEN_DONT_ALIGN is defined. + - \b EIGEN_DONT_PARALLELIZE - if defined, this disables multi-threading. This is only relevant if you enabled OpenMP. + See \ref TopicMultiThreading for details. - \b EIGEN_DONT_VECTORIZE - disables explicit vectorization when defined. Not defined by default, unless alignment is disabled by %Eigen's platform test or the user defining \c EIGEN_DONT_ALIGN. - - \b EIGEN_FAST_MATH - enables some optimizations which might affect the accuracy of the result. The only - optimization this currently includes is single precision sin() and cos() in the present of SSE - vectorization. Defined by default. + - \b EIGEN_FAST_MATH - enables some optimizations which might affect the accuracy of the result. This currently + enables the SSE vectorization of sin() and cos(), and speedups sqrt() for single precision. Defined to 1 by default. + Define it to 0 to disable. - \b EIGEN_UNROLLING_LIMIT - defines the size of a loop to enable meta unrolling. Set it to zero to disable unrolling. The size of a loop here is expressed in %Eigen's own notion of "number of FLOPS", it does not - correspond to the number of iterations or the number of instructions. The default is value 100. + correspond to the number of iterations or the number of instructions. The default is value 100. + - \b EIGEN_STACK_ALLOCATION_LIMIT - defines the maximum bytes for a buffer to be allocated on the stack. For internal + temporary buffers, dynamic memory allocation is employed as a fall back. For fixed-size matrices or arrays, exceeding + this threshold raises a compile time assertion. Use 0 to set no limit. Default is 128 KB. \section TopicPreprocessorDirectivesPlugins Plugins @@ -86,6 +91,7 @@ following macros are supported; none of them are defined by default. - \b EIGEN_MATRIX_PLUGIN - filename of plugin for extending the Matrix class. - \b EIGEN_MATRIXBASE_PLUGIN - filename of plugin for extending the MatrixBase class. - \b EIGEN_PLAINOBJECTBASE_PLUGIN - filename of plugin for extending the PlainObjectBase class. + - \b EIGEN_MAPBASE_PLUGIN - filename of plugin for extending the MapBase class. - \b EIGEN_QUATERNIONBASE_PLUGIN - filename of plugin for extending the QuaternionBase class. - \b EIGEN_SPARSEMATRIX_PLUGIN - filename of plugin for extending the SparseMatrix class. - \b EIGEN_SPARSEMATRIXBASE_PLUGIN - filename of plugin for extending the SparseMatrixBase class. diff --git a/ground/gcs/src/libs/eigen/doc/QuickReference.dox b/ground/gcs/src/libs/eigen/doc/QuickReference.dox index 5e0168649..a4be0f68a 100644 --- a/ground/gcs/src/libs/eigen/doc/QuickReference.dox +++ b/ground/gcs/src/libs/eigen/doc/QuickReference.dox @@ -405,19 +405,19 @@ array1 == array2 array1 != array2 array1 == scalar array1 != scalar array1.min(array2) array1.max(array2) array1.abs2() -array1.abs() std::abs(array1) -array1.sqrt() std::sqrt(array1) -array1.log() std::log(array1) -array1.exp() std::exp(array1) -array1.pow(exponent) std::pow(array1,exponent) +array1.abs() abs(array1) +array1.sqrt() sqrt(array1) +array1.log() log(array1) +array1.exp() exp(array1) +array1.pow(exponent) pow(array1,exponent) array1.square() array1.cube() array1.inverse() -array1.sin() std::sin(array1) -array1.cos() std::cos(array1) -array1.tan() std::tan(array1) -array1.asin() std::asin(array1) -array1.acos() std::acos(array1) +array1.sin() sin(array1) +array1.cos() cos(array1) +array1.tan() tan(array1) +array1.asin() asin(array1) +array1.acos() acos(array1) \endcode diff --git a/ground/gcs/src/libs/eigen/doc/SparseLinearSystems.dox b/ground/gcs/src/libs/eigen/doc/SparseLinearSystems.dox index c00be10d3..051a02ed9 100644 --- a/ground/gcs/src/libs/eigen/doc/SparseLinearSystems.dox +++ b/ground/gcs/src/libs/eigen/doc/SparseLinearSystems.dox @@ -35,17 +35,17 @@ They are summarized in the following table: Requires the PaStiX package, \b CeCILL-C optimized for tough problems and symmetric patterns CholmodSupernodalLLT\link CholmodSupport_Module CholmodSupport \endlinkDirect LLt factorizationSPDFill-in reducing, Leverage fast dense algebra - Requires the SuiteSparse package, \b GPL + Requires the SuiteSparse package, \b GPL UmfPackLU\link UmfPackSupport_Module UmfPackSupport \endlinkDirect LU factorizationSquareFill-in reducing, Leverage fast dense algebra - Requires the SuiteSparse package, \b GPL + Requires the SuiteSparse package, \b GPL SuperLU\link SuperLUSupport_Module SuperLUSupport \endlinkDirect LU factorizationSquareFill-in reducing, Leverage fast dense algebra Requires the SuperLU library, (BSD-like) SPQR\link SPQRSupport_Module SPQRSupport \endlink QR factorization Any, rectangularfill-in reducing, multithreaded, fast dense algebra - requires the SuiteSparse package, \b GPL recommended for linear least-squares problems, has a rank-revealing feature + requires the SuiteSparse package, \b GPL recommended for linear least-squares problems, has a rank-revealing feature Here \c SPD means symmetric positive definite. diff --git a/ground/gcs/src/libs/eigen/doc/SparseQuickReference.dox b/ground/gcs/src/libs/eigen/doc/SparseQuickReference.dox index 4a33d0cc9..e0a30edcc 100644 --- a/ground/gcs/src/libs/eigen/doc/SparseQuickReference.dox +++ b/ground/gcs/src/libs/eigen/doc/SparseQuickReference.dox @@ -21,7 +21,7 @@ i.e either row major or column major. The default is column major. Most arithmet Resize/Reserve \code - sm1.resize(m,n); //Change sm1 to a m x n matrix. + sm1.resize(m,n); // Change sm1 to a m x n matrix. sm1.reserve(nnz); // Allocate room for nnz nonzeros elements. \endcode @@ -71,11 +71,10 @@ i.e either row major or column major. The default is column major. Most arithmet Constant or Random Insertion \code -sm1.setZero(); // Set the matrix with zero elements -sm1.setConstant(val); //Replace all the nonzero values with val +sm1.setZero(); \endcode - The matrix sm1 should have been created before ??? +Remove all non-zero coefficients @@ -152,10 +151,10 @@ It is easy to perform arithmetic operations on sparse matrices provided that the Permutation \code -perm.indices(); // Reference to the vector of indices +perm.indices(); // Reference to the vector of indices sm1.twistedBy(perm); // Permute rows and columns -sm2 = sm1 * perm; //Permute the columns -sm2 = perm * sm1; // Permute the columns +sm2 = sm1 * perm; // Permute the columns +sm2 = perm * sm1; // Permute the columns \endcode @@ -182,9 +181,9 @@ sm2 = perm * sm1; // Permute the columns \section sparseotherops Other supported operations - + + - + - - + + - + + - - - + + + - - +
Operations Code Notes
Code Notes
Sub-matrices
Sub-matrices \code sm1.block(startRow, startCol, rows, cols); @@ -194,25 +193,31 @@ sm2 = perm * sm1; // Permute the columns sm1.bottomLeftCorner( rows, cols); sm1.bottomRightCorner( rows, cols); \endcode - +Contrary to dense matrices, here all these methods are read-only.\n +See \ref TutorialSparse_SubMatrices and below for read-write sub-matrices. +
Range
Range
\code - sm1.innerVector(outer); - sm1.innerVectors(start, size); - sm1.leftCols(size); - sm2.rightCols(size); - sm1.middleRows(start, numRows); - sm1.middleCols(start, numCols); - sm1.col(j); + sm1.innerVector(outer); // RW + sm1.innerVectors(start, size); // RW + sm1.leftCols(size); // RW + sm2.rightCols(size); // RO because sm2 is row-major + sm1.middleRows(start, numRows); // RO becasue sm1 is column-major + sm1.middleCols(start, numCols); // RW + sm1.col(j); // RW \endcode A inner vector is either a row (for row-major) or a column (for column-major). As stated earlier, the evaluation can be done in a matrix with different storage order +A inner vector is either a row (for row-major) or a column (for column-major).\n +As stated earlier, for a read-write sub-matrix (RW), the evaluation can be done in a matrix with different storage order. +
Triangular and selfadjoint views
Triangular and selfadjoint views \code sm2 = sm1.triangularview(); @@ -223,26 +228,30 @@ sm2 = perm * sm1; // Permute the columns \code \endcode
Triangular solve
Triangular solve
\code dv2 = sm1.triangularView().solve(dv1); - dv2 = sm1.topLeftCorner(size, size).triangularView().solve(dv1); + dv2 = sm1.topLeftCorner(size, size) + .triangularView().solve(dv1); \endcode For general sparse solve, Use any suitable module described at \ref TopicSparseSystems
Low-level API
Low-level API \code -sm1.valuePtr(); // Pointer to the values -sm1.innerIndextr(); // Pointer to the indices. -sm1.outerIndexPtr(); //Pointer to the beginning of each inner vector +sm1.valuePtr(); // Pointer to the values +sm1.innerIndextr(); // Pointer to the indices. +sm1.outerIndexPtr(); // Pointer to the beginning of each inner vector \endcode If the matrix is not in compressed form, makeCompressed() should be called before. Note that these functions are mostly provided for interoperability purposes with external libraries. A better access to the values of the matrix is done by using the InnerIterator class as described in \link TutorialSparse the Tutorial Sparse \endlink section +If the matrix is not in compressed form, makeCompressed() should be called before.\n +Note that these functions are mostly provided for interoperability purposes with external libraries.\n +A better access to the values of the matrix is done by using the InnerIterator class as described in \link TutorialSparse the Tutorial Sparse \endlink section
*/ diff --git a/ground/gcs/src/libs/eigen/doc/TopicMultithreading.dox b/ground/gcs/src/libs/eigen/doc/TopicMultithreading.dox index f7d082668..7db2b0e07 100644 --- a/ground/gcs/src/libs/eigen/doc/TopicMultithreading.dox +++ b/ground/gcs/src/libs/eigen/doc/TopicMultithreading.dox @@ -17,7 +17,7 @@ You can control the number of thread that will be used using either the OpenMP A Unless setNbThreads has been called, Eigen uses the number of threads specified by OpenMP. You can restore this bahavior by calling \code setNbThreads(0); \endcode You can query the number of threads that will be used with: \code -n = Eigen::nbThreads(n); +n = Eigen::nbThreads( ); \endcode You can disable Eigen's multi threading at compile time by defining the EIGEN_DONT_PARALLELIZE preprocessor token. diff --git a/ground/gcs/src/libs/eigen/doc/TutorialGeometry.dox b/ground/gcs/src/libs/eigen/doc/TutorialGeometry.dox index 81aeec978..372a275de 100644 --- a/ground/gcs/src/libs/eigen/doc/TutorialGeometry.dox +++ b/ground/gcs/src/libs/eigen/doc/TutorialGeometry.dox @@ -127,7 +127,7 @@ VectorNf vec1, vec2; vec2 = t.linear() * vec1;\endcode Apply a \em general transformation \n to a \b normal \b vector -(explanations)\code +(explanations)\code VectorNf n1, n2; MatrixNf normalMatrix = t.linear().inverse().transpose(); n2 = (normalMatrix * n1).normalized();\endcode diff --git a/ground/gcs/src/libs/eigen/doc/TutorialSparse.dox b/ground/gcs/src/libs/eigen/doc/TutorialSparse.dox index dbfb4a9eb..ee206cc42 100644 --- a/ground/gcs/src/libs/eigen/doc/TutorialSparse.dox +++ b/ground/gcs/src/libs/eigen/doc/TutorialSparse.dox @@ -83,7 +83,7 @@ There is no notion of compressed/uncompressed mode for a SparseVector. \section TutorialSparseExample First example -Before describing each individual class, let's start with the following typical example: solving the Lapace equation \f$ \nabla u = 0 \f$ on a regular 2D grid using a finite difference scheme and Dirichlet boundary conditions. +Before describing each individual class, let's start with the following typical example: solving the Laplace equation \f$ \nabla u = 0 \f$ on a regular 2D grid using a finite difference scheme and Dirichlet boundary conditions. Such problem can be mathematically expressed as a linear problem of the form \f$ Ax=b \f$ where \f$ x \f$ is the vector of \c m unknowns (in our case, the values of the pixels), \f$ b \f$ is the right hand side vector resulting from the boundary conditions, and \f$ A \f$ is an \f$ m \times m \f$ matrix containing only a few non-zero elements resulting from the discretization of the Laplacian operator. @@ -241,11 +241,11 @@ In the following \em sm denotes a sparse matrix, \em sv a sparse vector, \em dm sm1.real() sm1.imag() -sm1 0.5*sm1 sm1+sm2 sm1-sm2 sm1.cwiseProduct(sm2) \endcode -However, a strong restriction is that the storage orders must match. For instance, in the following example: +However, a strong restriction is that the storage orders must match. For instance, in the following example: \code sm4 = sm1 + sm2 + sm3; \endcode -sm1, sm2, and sm3 must all be row-major or all column major. +sm1, sm2, and sm3 must all be row-major or all column-major. On the other hand, there is no restriction on the target matrix sm4. For instance, this means that for computing \f$ A^T + A \f$, the matrix \f$ A^T \f$ must be evaluated into a temporary matrix of compatible storage order: \code @@ -253,12 +253,15 @@ SparseMatrix A, B; B = SparseMatrix(A.transpose()) + A; \endcode -Binary coefficient wise operators can also mix sparse and dense expressions: +Some binary coefficient-wise operators can also mix sparse and dense expressions: \code sm2 = sm1.cwiseProduct(dm1); -dm2 = sm1 + dm1; +dm1 += sm1; \endcode +However, it is not yet possible to add a sparse and a dense matrix as in dm2 = sm1 + dm1. +Please write this as the equivalent dm2 = dm1; dm2 += sm1 (we plan to lift this restriction +in the next release of %Eigen). %Sparse expressions also support transposition: \code @@ -304,6 +307,26 @@ sm2 = sm1.transpose() * P; \endcode +\subsection TutorialSparse_SubMatrices Block operations + +Regarding read-access, sparse matrices expose the same API than for dense matrices to access to sub-matrices such as blocks, columns, and rows. See \ref TutorialBlockOperations for a detailed introduction. +However, for performance reasons, writing to a sub-sparse-matrix is much more limited, and currently only contiguous sets of columns (resp. rows) of a column-major (resp. row-major) SparseMatrix are writable. Moreover, this information has to be known at compile-time, leaving out methods such as block(...) and corner*(...). The available API for write-access to a SparseMatrix are summarized below: +\code +SparseMatrix sm1; +sm1.col(j) = ...; +sm1.leftCols(ncols) = ...; +sm1.middleCols(j,ncols) = ...; +sm1.rightCols(ncols) = ...; + +SparseMatrix sm2; +sm2.row(i) = ...; +sm2.topRows(nrows) = ...; +sm2.middleRows(i,nrows) = ...; +sm2.bottomRows(nrows) = ...; +\endcode + +In addition, sparse matrices expose the SparseMatrixBase::innerVector() and SparseMatrixBase::innerVectors() methods, which are aliases to the col/middleCols methods for a column-major storage, and to the row/middleRows methods for a row-major storage. + \subsection TutorialSparse_TriangularSelfadjoint Triangular and selfadjoint views Just as with dense matrices, the triangularView() function can be used to address a triangular part of the matrix, and perform triangular solves with a dense right hand side: diff --git a/ground/gcs/src/libs/eigen/doc/UnalignedArrayAssert.dox b/ground/gcs/src/libs/eigen/doc/UnalignedArrayAssert.dox index 8c97d7874..b0d6e18f2 100644 --- a/ground/gcs/src/libs/eigen/doc/UnalignedArrayAssert.dox +++ b/ground/gcs/src/libs/eigen/doc/UnalignedArrayAssert.dox @@ -7,8 +7,8 @@ Hello! You are seeing this webpage because your program terminated on an asserti my_program: path/to/eigen/Eigen/src/Core/DenseStorage.h:44: Eigen::internal::matrix_array::internal::matrix_array() [with T = double, int Size = 2, int MatrixOptions = 2, bool Align = true]: -Assertion `(reinterpret_cast(array) & 0xf) == 0 && "this assertion -is explained here: http://eigen.tuxfamily.org/dox/UnalignedArrayAssert.html +Assertion `(reinterpret_cast(array) & (sizemask)) == 0 && "this assertion +is explained here: http://eigen.tuxfamily.org/dox/group__TopicUnalignedArrayAssert.html **** READ THIS WEB PAGE !!! ****"' failed. @@ -46,9 +46,9 @@ then you need to read this separate page: \ref TopicStructHavingEigenMembers "St Note that here, Eigen::Vector2d is only used as an example, more generally the issue arises for all \ref TopicFixedSizeVectorizable "fixed-size vectorizable Eigen types". -\section c2 Cause 2: STL Containers +\section c2 Cause 2: STL Containers or manual memory allocation -If you use STL Containers such as std::vector, std::map, ..., with Eigen objects, or with classes containing Eigen objects, like this, +If you use STL Containers such as std::vector, std::map, ..., with %Eigen objects, or with classes containing %Eigen objects, like this, \code std::vector my_vector; @@ -60,6 +60,8 @@ then you need to read this separate page: \ref TopicStlContainers "Using STL Con Note that here, Eigen::Matrix2f is only used as an example, more generally the issue arises for all \ref TopicFixedSizeVectorizable "fixed-size vectorizable Eigen types" and \ref TopicStructHavingEigenMembers "structures having such Eigen objects as member". +The same issue will be exhibited by any classes/functions by-passing operator new to allocate memory, that is, by performing custom memory allocation followed by calls to the placement new operator. This is for instance typically the case of \c std::make_shared or \c std::allocate_shared for which is the solution is to use an \ref aligned_allocator "aligned allocator" as detailed in the \ref TopicStlContainers "solution for STL containers". + \section c3 Cause 3: Passing Eigen objects by value If some function in your code is getting an Eigen object passed by value, like this, @@ -107,7 +109,10 @@ Two possibilities: 128-bit alignment code and thus preserves ABI compatibility, but completely disables vectorization. -For more information, see this FAQ. +If you want to know why defining EIGEN_DONT_VECTORIZE does not by itself disable 128-bit alignment and the assertion, here's the explanation: + +It doesn't disable the assertion, because otherwise code that runs fine without vectorization would suddenly crash when enabling vectorization. +It doesn't disable 128bit alignment, because that would mean that vectorized and non-vectorized code are not mutually ABI-compatible. This ABI compatibility is very important, even for people who develop only an in-house application, as for instance one may want to have in the same application a vectorized path and a non-vectorized path. */ diff --git a/ground/gcs/src/libs/eigen/doc/UsingIntelMKL.dox b/ground/gcs/src/libs/eigen/doc/UsingIntelMKL.dox index 4b624a156..84db992b6 100644 --- a/ground/gcs/src/libs/eigen/doc/UsingIntelMKL.dox +++ b/ground/gcs/src/libs/eigen/doc/UsingIntelMKL.dox @@ -40,7 +40,8 @@ Since Eigen version 3.1 and later, users can benefit from built-in Intel MKL opt Intel MKL provides highly optimized multi-threaded mathematical routines for x86-compatible architectures. Intel MKL is available on Linux, Mac and Windows for both Intel64 and IA32 architectures. -\warning Be aware that Intel® MKL is a proprietary software. It is the responsibility of the users to buy MKL licenses for their products. Moreover, the license of the user product has to allow linking to proprietary software that excludes any unmodified versions of the GPL. +\note +Intel® MKL is a proprietary software and it is the responsibility of users to buy or register for community (free) Intel MKL licenses for their products. Moreover, the license of the user product has to allow linking to proprietary software that excludes any unmodified versions of the GPL. Using Intel MKL through Eigen is easy: -# define the \c EIGEN_USE_MKL_ALL macro before including any Eigen's header diff --git a/ground/gcs/src/libs/eigen/doc/eigendoxy.css b/ground/gcs/src/libs/eigen/doc/eigendoxy.css index 60243d870..efaeb46dc 100644 --- a/ground/gcs/src/libs/eigen/doc/eigendoxy.css +++ b/ground/gcs/src/libs/eigen/doc/eigendoxy.css @@ -199,3 +199,13 @@ h3.version { td.width20em p.endtd { width: 20em; } + +.bigwarning { + font-size:2em; + font-weight:bold; + margin:1em; + padding:1em; + color:red; + border:solid; +} + diff --git a/ground/gcs/src/libs/eigen/doc/eigendoxy_footer.html.in b/ground/gcs/src/libs/eigen/doc/eigendoxy_footer.html.in index e62af8ed5..878244a19 100644 --- a/ground/gcs/src/libs/eigen/doc/eigendoxy_footer.html.in +++ b/ground/gcs/src/libs/eigen/doc/eigendoxy_footer.html.in @@ -17,8 +17,7 @@ $generatedby   - - ---> diff --git a/ground/gcs/src/libs/eigen/doc/examples/CMakeLists.txt b/ground/gcs/src/libs/eigen/doc/examples/CMakeLists.txt index 71b272a15..08cf8efd7 100644 --- a/ground/gcs/src/libs/eigen/doc/examples/CMakeLists.txt +++ b/ground/gcs/src/libs/eigen/doc/examples/CMakeLists.txt @@ -6,12 +6,10 @@ foreach(example_src ${examples_SRCS}) if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO) target_link_libraries(${example} ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO}) endif() - get_target_property(example_executable - ${example} LOCATION) add_custom_command( TARGET ${example} POST_BUILD - COMMAND ${example_executable} + COMMAND ${example} ARGS >${CMAKE_CURRENT_BINARY_DIR}/${example}.out ) add_dependencies(all_examples ${example}) diff --git a/ground/gcs/src/libs/eigen/doc/examples/matrixfree_cg.cpp b/ground/gcs/src/libs/eigen/doc/examples/matrixfree_cg.cpp new file mode 100644 index 000000000..f0631c3a3 --- /dev/null +++ b/ground/gcs/src/libs/eigen/doc/examples/matrixfree_cg.cpp @@ -0,0 +1,180 @@ +#include +#include +#include +#include + +class MatrixReplacement; +template class MatrixReplacement_ProductReturnType; + +namespace Eigen { +namespace internal { + template<> + struct traits : Eigen::internal::traits > + {}; + + template + struct traits > { + // The equivalent plain objet type of the product. This type is used if the product needs to be evaluated into a temporary. + typedef Eigen::Matrix ReturnType; + }; +} +} + +// Inheriting EigenBase should not be needed in the future. +class MatrixReplacement : public Eigen::EigenBase { +public: + // Expose some compile-time information to Eigen: + typedef double Scalar; + typedef double RealScalar; + enum { + ColsAtCompileTime = Eigen::Dynamic, + RowsAtCompileTime = Eigen::Dynamic, + MaxColsAtCompileTime = Eigen::Dynamic, + MaxRowsAtCompileTime = Eigen::Dynamic + }; + + Index rows() const { return 4; } + Index cols() const { return 4; } + + void resize(Index a_rows, Index a_cols) + { + // This method should not be needed in the future. + assert(a_rows==0 && a_cols==0 || a_rows==rows() && a_cols==cols()); + } + + // In the future, the return type should be Eigen::Product + template + MatrixReplacement_ProductReturnType operator*(const Eigen::MatrixBase& x) const { + return MatrixReplacement_ProductReturnType(*this, x.derived()); + } + +}; + +// The proxy class representing the product of a MatrixReplacement with a MatrixBase<> +template +class MatrixReplacement_ProductReturnType : public Eigen::ReturnByValue > { +public: + typedef MatrixReplacement::Index Index; + + // The ctor store references to the matrix and right-hand-side object (usually a vector). + MatrixReplacement_ProductReturnType(const MatrixReplacement& matrix, const Rhs& rhs) + : m_matrix(matrix), m_rhs(rhs) + {} + + Index rows() const { return m_matrix.rows(); } + Index cols() const { return m_rhs.cols(); } + + // This function is automatically called by Eigen. It must evaluate the product of matrix * rhs into y. + template + void evalTo(Dest& y) const + { + y.setZero(4); + + y(0) += 2 * m_rhs(0); y(1) += 1 * m_rhs(0); + y(0) += 1 * m_rhs(1); y(1) += 2 * m_rhs(1); y(2) += 1 * m_rhs(1); + y(1) += 1 * m_rhs(2); y(2) += 2 * m_rhs(2); y(3) += 1 * m_rhs(2); + y(2) += 1 * m_rhs(3); y(3) += 2 * m_rhs(3); + } + +protected: + const MatrixReplacement& m_matrix; + typename Rhs::Nested m_rhs; +}; + + +/*****/ + +// This class simply warp a diagonal matrix as a Jacobi preconditioner. +// In the future such simple and generic wrapper should be shipped within Eigen itsel. +template +class MyJacobiPreconditioner +{ + typedef _Scalar Scalar; + typedef Eigen::Matrix Vector; + typedef typename Vector::Index Index; + + public: + // this typedef is only to export the scalar type and compile-time dimensions to solve_retval + typedef Eigen::Matrix MatrixType; + + MyJacobiPreconditioner() : m_isInitialized(false) {} + + void setInvDiag(const Eigen::VectorXd &invdiag) { + m_invdiag=invdiag; + m_isInitialized=true; + } + + Index rows() const { return m_invdiag.size(); } + Index cols() const { return m_invdiag.size(); } + + template + MyJacobiPreconditioner& analyzePattern(const MatType& ) { return *this; } + + template + MyJacobiPreconditioner& factorize(const MatType& mat) { return *this; } + + template + MyJacobiPreconditioner& compute(const MatType& mat) { return *this; } + + template + void _solve(const Rhs& b, Dest& x) const + { + x = m_invdiag.array() * b.array() ; + } + + template inline const Eigen::internal::solve_retval + solve(const Eigen::MatrixBase& b) const + { + eigen_assert(m_isInitialized && "MyJacobiPreconditioner is not initialized."); + eigen_assert(m_invdiag.size()==b.rows() + && "MyJacobiPreconditioner::solve(): invalid number of rows of the right hand side matrix b"); + return Eigen::internal::solve_retval(*this, b.derived()); + } + + protected: + Vector m_invdiag; + bool m_isInitialized; +}; + +namespace Eigen { +namespace internal { + +template +struct solve_retval, Rhs> + : solve_retval_base, Rhs> +{ + typedef MyJacobiPreconditioner<_MatrixType> Dec; + EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) + + template void evalTo(Dest& dst) const + { + dec()._solve(rhs(),dst); + } +}; + +} +} + + +/*****/ + + +int main() +{ + MatrixReplacement A; + Eigen::VectorXd b(4), x; + b << 1, 1, 1, 1; + + // solve Ax = b using CG with matrix-free version: + Eigen::ConjugateGradient < MatrixReplacement, Eigen::Lower|Eigen::Upper, MyJacobiPreconditioner > cg; + + Eigen::VectorXd invdiag(4); + invdiag << 1./3., 1./4., 1./4., 1./3.; + + cg.preconditioner().setInvDiag(invdiag); + cg.compute(A); + x = cg.solve(b); + + std::cout << "#iterations: " << cg.iterations() << std::endl; + std::cout << "estimated error: " << cg.error() << std::endl; +} diff --git a/ground/gcs/src/libs/eigen/doc/snippets/CMakeLists.txt b/ground/gcs/src/libs/eigen/doc/snippets/CMakeLists.txt index 92a22ea61..1135900cf 100644 --- a/ground/gcs/src/libs/eigen/doc/snippets/CMakeLists.txt +++ b/ground/gcs/src/libs/eigen/doc/snippets/CMakeLists.txt @@ -14,12 +14,10 @@ foreach(snippet_src ${snippets_SRCS}) if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO) target_link_libraries(${compile_snippet_target} ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO}) endif() - get_target_property(compile_snippet_executable - ${compile_snippet_target} LOCATION) add_custom_command( TARGET ${compile_snippet_target} POST_BUILD - COMMAND ${compile_snippet_executable} + COMMAND ${compile_snippet_target} ARGS >${CMAKE_CURRENT_BINARY_DIR}/${snippet}.out ) add_dependencies(all_snippets ${compile_snippet_target}) @@ -27,4 +25,4 @@ foreach(snippet_src ${snippets_SRCS}) PROPERTIES OBJECT_DEPENDS ${snippet_src}) endforeach(snippet_src) -ei_add_target_property(compile_tut_arithmetic_transpose_aliasing COMPILE_FLAGS -DEIGEN_NO_DEBUG) \ No newline at end of file +ei_add_target_property(compile_tut_arithmetic_transpose_aliasing COMPILE_FLAGS -DEIGEN_NO_DEBUG) diff --git a/ground/gcs/src/libs/eigen/doc/snippets/MatrixBase_applyOnTheLeft.cpp b/ground/gcs/src/libs/eigen/doc/snippets/MatrixBase_applyOnTheLeft.cpp new file mode 100644 index 000000000..6398c873a --- /dev/null +++ b/ground/gcs/src/libs/eigen/doc/snippets/MatrixBase_applyOnTheLeft.cpp @@ -0,0 +1,7 @@ +Matrix3f A = Matrix3f::Random(3,3), B; +B << 0,1,0, + 0,0,1, + 1,0,0; +cout << "At start, A = " << endl << A << endl; +A.applyOnTheLeft(B); +cout << "After applyOnTheLeft, A = " << endl << A << endl; diff --git a/ground/gcs/src/libs/eigen/doc/snippets/MatrixBase_applyOnTheRight.cpp b/ground/gcs/src/libs/eigen/doc/snippets/MatrixBase_applyOnTheRight.cpp new file mode 100644 index 000000000..e4b71b2d8 --- /dev/null +++ b/ground/gcs/src/libs/eigen/doc/snippets/MatrixBase_applyOnTheRight.cpp @@ -0,0 +1,9 @@ +Matrix3f A = Matrix3f::Random(3,3), B; +B << 0,1,0, + 0,0,1, + 1,0,0; +cout << "At start, A = " << endl << A << endl; +A *= B; +cout << "After A *= B, A = " << endl << A << endl; +A.applyOnTheRight(B); // equivalent to A *= B +cout << "After applyOnTheRight, A = " << endl << A << endl; diff --git a/ground/gcs/src/libs/eigen/doc/special_examples/CMakeLists.txt b/ground/gcs/src/libs/eigen/doc/special_examples/CMakeLists.txt index 138a2f6ef..3ab75dbfe 100644 --- a/ground/gcs/src/libs/eigen/doc/special_examples/CMakeLists.txt +++ b/ground/gcs/src/libs/eigen/doc/special_examples/CMakeLists.txt @@ -1,4 +1,3 @@ - if(NOT EIGEN_TEST_NOQT) find_package(Qt4) if(QT4_FOUND) @@ -6,16 +5,17 @@ if(NOT EIGEN_TEST_NOQT) endif() endif(NOT EIGEN_TEST_NOQT) - if(QT4_FOUND) add_executable(Tutorial_sparse_example Tutorial_sparse_example.cpp Tutorial_sparse_example_details.cpp) target_link_libraries(Tutorial_sparse_example ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY}) add_custom_command( - TARGET Tutorial_sparse_example - POST_BUILD - COMMAND Tutorial_sparse_example - ARGS ${CMAKE_CURRENT_BINARY_DIR}/../html/Tutorial_sparse_example.jpeg + TARGET Tutorial_sparse_example + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/../html/ + COMMAND Tutorial_sparse_example ARGS ${CMAKE_CURRENT_BINARY_DIR}/../html/Tutorial_sparse_example.jpeg ) + add_dependencies(all_examples Tutorial_sparse_example) endif(QT4_FOUND) + diff --git a/ground/gcs/src/libs/eigen/doc/special_examples/Tutorial_sparse_example_details.cpp b/ground/gcs/src/libs/eigen/doc/special_examples/Tutorial_sparse_example_details.cpp index 8c3020b63..7d820b44a 100644 --- a/ground/gcs/src/libs/eigen/doc/special_examples/Tutorial_sparse_example_details.cpp +++ b/ground/gcs/src/libs/eigen/doc/special_examples/Tutorial_sparse_example_details.cpp @@ -11,8 +11,8 @@ void insertCoefficient(int id, int i, int j, double w, std::vector& coeffs, int n = boundary.size(); int id1 = i+j*n; - if(i==-1 || i==n) b(id) -= w * boundary(j); // constrained coeffcieint - else if(j==-1 || j==n) b(id) -= w * boundary(i); // constrained coeffcieint + if(i==-1 || i==n) b(id) -= w * boundary(j); // constrained coefficient + else if(j==-1 || j==n) b(id) -= w * boundary(i); // constrained coefficient else coeffs.push_back(T(id,id1,w)); // unknown coefficient } diff --git a/ground/gcs/src/libs/eigen/eigen3.pc.in b/ground/gcs/src/libs/eigen/eigen3.pc.in index c5855de33..3368a3aa1 100644 --- a/ground/gcs/src/libs/eigen/eigen3.pc.in +++ b/ground/gcs/src/libs/eigen/eigen3.pc.in @@ -1,6 +1,9 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix} + Name: Eigen3 Description: A C++ template library for linear algebra: vectors, matrices, and related algorithms Requires: -Version: ${EIGEN_VERSION_NUMBER} +Version: @EIGEN_VERSION_NUMBER@ Libs: -Cflags: -I${INCLUDE_INSTALL_DIR} +Cflags: -I${prefix}/@INCLUDE_INSTALL_DIR@ diff --git a/ground/gcs/src/libs/eigen/failtest/CMakeLists.txt b/ground/gcs/src/libs/eigen/failtest/CMakeLists.txt index 5afa2ac82..cadc6a255 100644 --- a/ground/gcs/src/libs/eigen/failtest/CMakeLists.txt +++ b/ground/gcs/src/libs/eigen/failtest/CMakeLists.txt @@ -26,6 +26,23 @@ ei_add_failtest("block_on_const_type_actually_const_1") ei_add_failtest("transpose_on_const_type_actually_const") ei_add_failtest("diagonal_on_const_type_actually_const") +ei_add_failtest("ref_1") +ei_add_failtest("ref_2") +ei_add_failtest("ref_3") +ei_add_failtest("ref_4") +ei_add_failtest("ref_5") + +ei_add_failtest("partialpivlu_int") +ei_add_failtest("fullpivlu_int") +ei_add_failtest("llt_int") +ei_add_failtest("ldlt_int") +ei_add_failtest("qr_int") +ei_add_failtest("colpivqr_int") +ei_add_failtest("fullpivqr_int") +ei_add_failtest("jacobisvd_int") +ei_add_failtest("eigensolver_int") +ei_add_failtest("eigensolver_cplx") + if (EIGEN_FAILTEST_FAILURE_COUNT) message(FATAL_ERROR "${EIGEN_FAILTEST_FAILURE_COUNT} out of ${EIGEN_FAILTEST_COUNT} failtests FAILED. " diff --git a/ground/gcs/src/libs/eigen/failtest/colpivqr_int.cpp b/ground/gcs/src/libs/eigen/failtest/colpivqr_int.cpp new file mode 100644 index 000000000..db11910d4 --- /dev/null +++ b/ground/gcs/src/libs/eigen/failtest/colpivqr_int.cpp @@ -0,0 +1,14 @@ +#include "../Eigen/QR" + +#ifdef EIGEN_SHOULD_FAIL_TO_BUILD +#define SCALAR int +#else +#define SCALAR float +#endif + +using namespace Eigen; + +int main() +{ + ColPivHouseholderQR > qr(Matrix::Random(10,10)); +} diff --git a/ground/gcs/src/libs/eigen/failtest/eigensolver_cplx.cpp b/ground/gcs/src/libs/eigen/failtest/eigensolver_cplx.cpp new file mode 100644 index 000000000..c2e21e189 --- /dev/null +++ b/ground/gcs/src/libs/eigen/failtest/eigensolver_cplx.cpp @@ -0,0 +1,14 @@ +#include "../Eigen/Eigenvalues" + +#ifdef EIGEN_SHOULD_FAIL_TO_BUILD +#define SCALAR std::complex +#else +#define SCALAR float +#endif + +using namespace Eigen; + +int main() +{ + EigenSolver > eig(Matrix::Random(10,10)); +} diff --git a/ground/gcs/src/libs/eigen/failtest/eigensolver_int.cpp b/ground/gcs/src/libs/eigen/failtest/eigensolver_int.cpp new file mode 100644 index 000000000..eda8dc20b --- /dev/null +++ b/ground/gcs/src/libs/eigen/failtest/eigensolver_int.cpp @@ -0,0 +1,14 @@ +#include "../Eigen/Eigenvalues" + +#ifdef EIGEN_SHOULD_FAIL_TO_BUILD +#define SCALAR int +#else +#define SCALAR float +#endif + +using namespace Eigen; + +int main() +{ + EigenSolver > eig(Matrix::Random(10,10)); +} diff --git a/ground/gcs/src/libs/eigen/failtest/fullpivlu_int.cpp b/ground/gcs/src/libs/eigen/failtest/fullpivlu_int.cpp new file mode 100644 index 000000000..e9d2c6eb3 --- /dev/null +++ b/ground/gcs/src/libs/eigen/failtest/fullpivlu_int.cpp @@ -0,0 +1,14 @@ +#include "../Eigen/LU" + +#ifdef EIGEN_SHOULD_FAIL_TO_BUILD +#define SCALAR int +#else +#define SCALAR float +#endif + +using namespace Eigen; + +int main() +{ + FullPivLU > lu(Matrix::Random(10,10)); +} diff --git a/ground/gcs/src/libs/eigen/failtest/fullpivqr_int.cpp b/ground/gcs/src/libs/eigen/failtest/fullpivqr_int.cpp new file mode 100644 index 000000000..d182a7b6b --- /dev/null +++ b/ground/gcs/src/libs/eigen/failtest/fullpivqr_int.cpp @@ -0,0 +1,14 @@ +#include "../Eigen/QR" + +#ifdef EIGEN_SHOULD_FAIL_TO_BUILD +#define SCALAR int +#else +#define SCALAR float +#endif + +using namespace Eigen; + +int main() +{ + FullPivHouseholderQR > qr(Matrix::Random(10,10)); +} diff --git a/ground/gcs/src/libs/eigen/failtest/jacobisvd_int.cpp b/ground/gcs/src/libs/eigen/failtest/jacobisvd_int.cpp new file mode 100644 index 000000000..12790aef1 --- /dev/null +++ b/ground/gcs/src/libs/eigen/failtest/jacobisvd_int.cpp @@ -0,0 +1,14 @@ +#include "../Eigen/SVD" + +#ifdef EIGEN_SHOULD_FAIL_TO_BUILD +#define SCALAR int +#else +#define SCALAR float +#endif + +using namespace Eigen; + +int main() +{ + JacobiSVD > qr(Matrix::Random(10,10)); +} diff --git a/ground/gcs/src/libs/eigen/failtest/ldlt_int.cpp b/ground/gcs/src/libs/eigen/failtest/ldlt_int.cpp new file mode 100644 index 000000000..243e45746 --- /dev/null +++ b/ground/gcs/src/libs/eigen/failtest/ldlt_int.cpp @@ -0,0 +1,14 @@ +#include "../Eigen/Cholesky" + +#ifdef EIGEN_SHOULD_FAIL_TO_BUILD +#define SCALAR int +#else +#define SCALAR float +#endif + +using namespace Eigen; + +int main() +{ + LDLT > ldlt(Matrix::Random(10,10)); +} diff --git a/ground/gcs/src/libs/eigen/failtest/llt_int.cpp b/ground/gcs/src/libs/eigen/failtest/llt_int.cpp new file mode 100644 index 000000000..cb020650d --- /dev/null +++ b/ground/gcs/src/libs/eigen/failtest/llt_int.cpp @@ -0,0 +1,14 @@ +#include "../Eigen/Cholesky" + +#ifdef EIGEN_SHOULD_FAIL_TO_BUILD +#define SCALAR int +#else +#define SCALAR float +#endif + +using namespace Eigen; + +int main() +{ + LLT > llt(Matrix::Random(10,10)); +} diff --git a/ground/gcs/src/libs/eigen/failtest/partialpivlu_int.cpp b/ground/gcs/src/libs/eigen/failtest/partialpivlu_int.cpp new file mode 100644 index 000000000..98ef282ea --- /dev/null +++ b/ground/gcs/src/libs/eigen/failtest/partialpivlu_int.cpp @@ -0,0 +1,14 @@ +#include "../Eigen/LU" + +#ifdef EIGEN_SHOULD_FAIL_TO_BUILD +#define SCALAR int +#else +#define SCALAR float +#endif + +using namespace Eigen; + +int main() +{ + PartialPivLU > lu(Matrix::Random(10,10)); +} diff --git a/ground/gcs/src/libs/eigen/failtest/qr_int.cpp b/ground/gcs/src/libs/eigen/failtest/qr_int.cpp new file mode 100644 index 000000000..ce200e818 --- /dev/null +++ b/ground/gcs/src/libs/eigen/failtest/qr_int.cpp @@ -0,0 +1,14 @@ +#include "../Eigen/QR" + +#ifdef EIGEN_SHOULD_FAIL_TO_BUILD +#define SCALAR int +#else +#define SCALAR float +#endif + +using namespace Eigen; + +int main() +{ + HouseholderQR > qr(Matrix::Random(10,10)); +} diff --git a/ground/gcs/src/libs/eigen/failtest/ref_1.cpp b/ground/gcs/src/libs/eigen/failtest/ref_1.cpp new file mode 100644 index 000000000..8b798d53d --- /dev/null +++ b/ground/gcs/src/libs/eigen/failtest/ref_1.cpp @@ -0,0 +1,18 @@ +#include "../Eigen/Core" + +#ifdef EIGEN_SHOULD_FAIL_TO_BUILD +#define CV_QUALIFIER const +#else +#define CV_QUALIFIER +#endif + +using namespace Eigen; + +void call_ref(Ref a) { } + +int main() +{ + VectorXf a(10); + CV_QUALIFIER VectorXf& ac(a); + call_ref(ac); +} diff --git a/ground/gcs/src/libs/eigen/failtest/ref_2.cpp b/ground/gcs/src/libs/eigen/failtest/ref_2.cpp new file mode 100644 index 000000000..0b779ccf5 --- /dev/null +++ b/ground/gcs/src/libs/eigen/failtest/ref_2.cpp @@ -0,0 +1,15 @@ +#include "../Eigen/Core" + +using namespace Eigen; + +void call_ref(Ref a) { } + +int main() +{ + MatrixXf A(10,10); +#ifdef EIGEN_SHOULD_FAIL_TO_BUILD + call_ref(A.row(3)); +#else + call_ref(A.col(3)); +#endif +} diff --git a/ground/gcs/src/libs/eigen/failtest/ref_3.cpp b/ground/gcs/src/libs/eigen/failtest/ref_3.cpp new file mode 100644 index 000000000..f46027d48 --- /dev/null +++ b/ground/gcs/src/libs/eigen/failtest/ref_3.cpp @@ -0,0 +1,15 @@ +#include "../Eigen/Core" + +using namespace Eigen; + +#ifdef EIGEN_SHOULD_FAIL_TO_BUILD +void call_ref(Ref a) { } +#else +void call_ref(const Ref &a) { } +#endif + +int main() +{ + VectorXf a(10); + call_ref(a+a); +} diff --git a/ground/gcs/src/libs/eigen/failtest/ref_4.cpp b/ground/gcs/src/libs/eigen/failtest/ref_4.cpp new file mode 100644 index 000000000..6c11fa4cb --- /dev/null +++ b/ground/gcs/src/libs/eigen/failtest/ref_4.cpp @@ -0,0 +1,15 @@ +#include "../Eigen/Core" + +using namespace Eigen; + +void call_ref(Ref > a) {} + +int main() +{ + MatrixXf A(10,10); +#ifdef EIGEN_SHOULD_FAIL_TO_BUILD + call_ref(A.transpose()); +#else + call_ref(A); +#endif +} diff --git a/ground/gcs/src/libs/eigen/failtest/ref_5.cpp b/ground/gcs/src/libs/eigen/failtest/ref_5.cpp new file mode 100644 index 000000000..846d52795 --- /dev/null +++ b/ground/gcs/src/libs/eigen/failtest/ref_5.cpp @@ -0,0 +1,16 @@ +#include "../Eigen/Core" + +using namespace Eigen; + +void call_ref(Ref a) { } + +int main() +{ + VectorXf a(10); + DenseBase &ac(a); +#ifdef EIGEN_SHOULD_FAIL_TO_BUILD + call_ref(ac); +#else + call_ref(ac.derived()); +#endif +} diff --git a/ground/gcs/src/libs/eigen/lapack/CMakeLists.txt b/ground/gcs/src/libs/eigen/lapack/CMakeLists.txt index 7e7444326..9883d4c72 100644 --- a/ground/gcs/src/libs/eigen/lapack/CMakeLists.txt +++ b/ground/gcs/src/libs/eigen/lapack/CMakeLists.txt @@ -7,6 +7,9 @@ workaround_9220(Fortran EIGEN_Fortran_COMPILER_WORKS) if(EIGEN_Fortran_COMPILER_WORKS) enable_language(Fortran OPTIONAL) + if(NOT CMAKE_Fortran_COMPILER) + set(EIGEN_Fortran_COMPILER_WORKS OFF) + endif() endif() add_custom_target(lapack) diff --git a/ground/gcs/src/libs/eigen/scripts/eigen_gen_docs b/ground/gcs/src/libs/eigen/scripts/eigen_gen_docs index 9b71cd8e0..0e6f9ada2 100644 --- a/ground/gcs/src/libs/eigen/scripts/eigen_gen_docs +++ b/ground/gcs/src/libs/eigen/scripts/eigen_gen_docs @@ -4,6 +4,7 @@ # You should call this script with USER set as you want, else some default # will be used USER=${USER:-'orzel'} +UPLOAD_DIR=dox #ulimit -v 1024000 @@ -14,10 +15,10 @@ mkdir build -p #step 2 : upload # (the '/' at the end of path is very important, see rsync documentation) -rsync -az --no-p --delete build/doc/html/ $USER@ssh.tuxfamily.org:eigen/eigen.tuxfamily.org-web/htdocs/dox-devel/ || { echo "upload failed"; exit 1; } +rsync -az --no-p --delete build/doc/html/ $USER@ssh.tuxfamily.org:eigen/eigen.tuxfamily.org-web/htdocs/$UPLOAD_DIR/ || { echo "upload failed"; exit 1; } #step 3 : fix the perm -ssh $USER@ssh.tuxfamily.org 'chmod -R g+w /home/eigen/eigen.tuxfamily.org-web/htdocs/dox-devel' || { echo "perm failed"; exit 1; } +ssh $USER@ssh.tuxfamily.org "chmod -R g+w /home/eigen/eigen.tuxfamily.org-web/htdocs/$UPLOAD_DIR" || { echo "perm failed"; exit 1; } echo "Uploaded successfully" diff --git a/ground/gcs/src/libs/eigen/test/CMakeLists.txt b/ground/gcs/src/libs/eigen/test/CMakeLists.txt index ccb0fc798..c0d8a4e28 100644 --- a/ground/gcs/src/libs/eigen/test/CMakeLists.txt +++ b/ground/gcs/src/libs/eigen/test/CMakeLists.txt @@ -66,7 +66,7 @@ endif() find_package(Pastix) find_package(Scotch) -find_package(Metis) +find_package(Metis 5.0 REQUIRED) if(PASTIX_FOUND AND BLAS_FOUND) add_definitions("-DEIGEN_PASTIX_SUPPORT") include_directories(${PASTIX_INCLUDES}) @@ -202,7 +202,9 @@ ei_add_test(geo_alignedbox) ei_add_test(stdvector) ei_add_test(stdvector_overload) ei_add_test(stdlist) +ei_add_test(stdlist_overload) ei_add_test(stddeque) +ei_add_test(stddeque_overload) ei_add_test(resize) ei_add_test(sparse_vector) ei_add_test(sparse_basic) @@ -222,6 +224,8 @@ ei_add_test(sizeoverflow) ei_add_test(prec_inverse_4x4) ei_add_test(vectorwiseop) ei_add_test(special_numbers) +ei_add_test(rvalue_types) +ei_add_test(mpl2only) ei_add_test(simplicial_cholesky) ei_add_test(conjugate_gradient) @@ -279,6 +283,13 @@ ei_add_property(EIGEN_TESTING_SUMMARY "CXX_FLAGS: ${CMAKE_CXX_FLAGS}\n") ei_add_property(EIGEN_TESTING_SUMMARY "Sparse lib flags: ${SPARSE_LIBS}\n") option(EIGEN_TEST_EIGEN2 "Run whole Eigen2 test suite against EIGEN2_SUPPORT" OFF) +mark_as_advanced(EIGEN_TEST_EIGEN2) if(EIGEN_TEST_EIGEN2) add_subdirectory(eigen2) endif() + + +option(EIGEN_TEST_BUILD_DOCUMENTATION "Test building the doxygen documentation" OFF) +IF(EIGEN_TEST_BUILD_DOCUMENTATION) + add_dependencies(buildtests doc) +ENDIF() diff --git a/ground/gcs/src/libs/eigen/test/array.cpp b/ground/gcs/src/libs/eigen/test/array.cpp index 8960e49f8..68f6b3d7a 100644 --- a/ground/gcs/src/libs/eigen/test/array.cpp +++ b/ground/gcs/src/libs/eigen/test/array.cpp @@ -109,6 +109,8 @@ template void comparisons(const ArrayType& m) VERIFY(! (m1 < m3).all() ); VERIFY(! (m1 > m3).all() ); } + VERIFY(!(m1 > m2 && m1 < m2).any()); + VERIFY((m1 <= m2 || m1 >= m2).all()); // comparisons to scalar VERIFY( (m1 != (m1(r,c)+1) ).any() ); @@ -167,21 +169,14 @@ template void array_real(const ArrayType& m) Scalar s1 = internal::random(); // these tests are mostly to check possible compilation issues. -// VERIFY_IS_APPROX(m1.sin(), std::sin(m1)); VERIFY_IS_APPROX(m1.sin(), sin(m1)); -// VERIFY_IS_APPROX(m1.cos(), std::cos(m1)); VERIFY_IS_APPROX(m1.cos(), cos(m1)); -// VERIFY_IS_APPROX(m1.asin(), std::asin(m1)); VERIFY_IS_APPROX(m1.asin(), asin(m1)); -// VERIFY_IS_APPROX(m1.acos(), std::acos(m1)); VERIFY_IS_APPROX(m1.acos(), acos(m1)); -// VERIFY_IS_APPROX(m1.tan(), std::tan(m1)); VERIFY_IS_APPROX(m1.tan(), tan(m1)); VERIFY_IS_APPROX(cos(m1+RealScalar(3)*m2), cos((m1+RealScalar(3)*m2).eval())); -// VERIFY_IS_APPROX(std::cos(m1+RealScalar(3)*m2), std::cos((m1+RealScalar(3)*m2).eval())); -// VERIFY_IS_APPROX(m1.abs().sqrt(), std::sqrt(std::abs(m1))); VERIFY_IS_APPROX(m1.abs().sqrt(), sqrt(abs(m1))); VERIFY_IS_APPROX(m1.abs(), sqrt(numext::abs2(m1))); @@ -190,9 +185,10 @@ template void array_real(const ArrayType& m) if(!NumTraits::IsComplex) VERIFY_IS_APPROX(numext::real(m1), m1); - VERIFY_IS_APPROX(m1.abs().log() , log(abs(m1))); + // shift argument of logarithm so that it is not zero + Scalar smallNumber = NumTraits::dummy_precision(); + VERIFY_IS_APPROX((m1.abs() + smallNumber).log() , log(abs(m1) + smallNumber)); -// VERIFY_IS_APPROX(m1.exp(), std::exp(m1)); VERIFY_IS_APPROX(m1.exp() * m2.exp(), exp(m1+m2)); VERIFY_IS_APPROX(m1.exp(), exp(m1)); VERIFY_IS_APPROX(m1.exp() / m2.exp(),(m1-m2).exp()); @@ -236,7 +232,6 @@ template void array_complex(const ArrayType& m) m2(i,j) = sqrt(m1(i,j)); VERIFY_IS_APPROX(m1.sqrt(), m2); -// VERIFY_IS_APPROX(m1.sqrt(), std::sqrt(m1)); VERIFY_IS_APPROX(m1.sqrt(), Eigen::sqrt(m1)); } diff --git a/ground/gcs/src/libs/eigen/test/array_for_matrix.cpp b/ground/gcs/src/libs/eigen/test/array_for_matrix.cpp index 1250c9ff5..9667e1f14 100644 --- a/ground/gcs/src/libs/eigen/test/array_for_matrix.cpp +++ b/ground/gcs/src/libs/eigen/test/array_for_matrix.cpp @@ -102,6 +102,7 @@ template void comparisons(const MatrixType& m) VERIFY( (m1.array() > (m1(r,c)-1) ).any() ); VERIFY( (m1.array() < (m1(r,c)+1) ).any() ); VERIFY( (m1.array() == m1(r,c) ).any() ); + VERIFY( m1.cwiseEqual(m1(r,c)).any() ); // test Select VERIFY_IS_APPROX( (m1.array() void cwise_min_max(const MatrixType& m) // min/max with scalar input VERIFY_IS_APPROX(MatrixType::Constant(rows,cols, minM1), m1.cwiseMin( minM1)); - VERIFY_IS_APPROX(m1, m1.cwiseMin( maxM1)); + VERIFY_IS_APPROX(m1, m1.cwiseMin(maxM1)); + VERIFY_IS_APPROX(-m1, (-m1).cwiseMin(-minM1)); + VERIFY_IS_APPROX(-m1.array(), ((-m1).array().min)( -minM1)); VERIFY_IS_APPROX(MatrixType::Constant(rows,cols, maxM1), m1.cwiseMax( maxM1)); - VERIFY_IS_APPROX(m1, m1.cwiseMax( minM1)); + VERIFY_IS_APPROX(m1, m1.cwiseMax(minM1)); + VERIFY_IS_APPROX(-m1, (-m1).cwiseMax(-maxM1)); + VERIFY_IS_APPROX(-m1.array(), ((-m1).array().max)(-maxM1)); VERIFY_IS_APPROX(MatrixType::Constant(rows,cols, minM1).array(), (m1.array().min)( minM1)); VERIFY_IS_APPROX(m1.array(), (m1.array().min)( maxM1)); @@ -202,6 +207,12 @@ template void resize(const MatrixTraits& t) VERIFY(a1.size()==cols); } +void regression_bug_654() +{ + ArrayXf a = RowVectorXf(3); + VectorXf v = Array(3); +} + void test_array_for_matrix() { for(int i = 0; i < g_repeat; i++) { @@ -239,4 +250,5 @@ void test_array_for_matrix() CALL_SUBTEST_5( resize(MatrixXf(internal::random(1,EIGEN_TEST_MAX_SIZE), internal::random(1,EIGEN_TEST_MAX_SIZE))) ); CALL_SUBTEST_6( resize(MatrixXi(internal::random(1,EIGEN_TEST_MAX_SIZE), internal::random(1,EIGEN_TEST_MAX_SIZE))) ); } + CALL_SUBTEST_6( regression_bug_654() ); } diff --git a/ground/gcs/src/libs/eigen/test/block.cpp b/ground/gcs/src/libs/eigen/test/block.cpp index 189fa5aba..9ed5d7bc5 100644 --- a/ground/gcs/src/libs/eigen/test/block.cpp +++ b/ground/gcs/src/libs/eigen/test/block.cpp @@ -10,6 +10,26 @@ #define EIGEN_NO_STATIC_ASSERT // otherwise we fail at compile time on unused paths #include "main.h" +template +typename Eigen::internal::enable_if::IsComplex,typename MatrixType::Scalar>::type +block_real_only(const MatrixType &m1, Index r1, Index r2, Index c1, Index c2, const Scalar& s1) { + // check cwise-Functions: + VERIFY_IS_APPROX(m1.row(r1).cwiseMax(s1), m1.cwiseMax(s1).row(r1)); + VERIFY_IS_APPROX(m1.col(c1).cwiseMin(s1), m1.cwiseMin(s1).col(c1)); + + VERIFY_IS_APPROX(m1.block(r1,c1,r2-r1+1,c2-c1+1).cwiseMin(s1), m1.cwiseMin(s1).block(r1,c1,r2-r1+1,c2-c1+1)); + VERIFY_IS_APPROX(m1.block(r1,c1,r2-r1+1,c2-c1+1).cwiseMax(s1), m1.cwiseMax(s1).block(r1,c1,r2-r1+1,c2-c1+1)); + + return Scalar(0); +} + +template +typename Eigen::internal::enable_if::IsComplex,typename MatrixType::Scalar>::type +block_real_only(const MatrixType &, Index, Index, Index, Index, const Scalar&) { + return Scalar(0); +} + + template void block(const MatrixType& m) { typedef typename MatrixType::Index Index; @@ -37,6 +57,8 @@ template void block(const MatrixType& m) Index c1 = internal::random(0,cols-1); Index c2 = internal::random(c1,cols-1); + block_real_only(m1, r1, r2, c1, c1, s1); + //check row() and col() VERIFY_IS_EQUAL(m1.col(c1).transpose(), m1.transpose().row(c1)); //check operator(), both constant and non-constant, on row() and col() @@ -51,7 +73,8 @@ template void block(const MatrixType& m) VERIFY_IS_APPROX(m1.col(c1), m1_copy.col(c1) + s1 * m1_copy.col(c2)); m1.col(c1).col(0) += s1 * m1_copy.col(c2); VERIFY_IS_APPROX(m1.col(c1), m1_copy.col(c1) + Scalar(2) * s1 * m1_copy.col(c2)); - + + //check block() Matrix b1(1,1); b1(0,0) = m1(r1,c1); diff --git a/ground/gcs/src/libs/eigen/test/cholesky.cpp b/ground/gcs/src/libs/eigen/test/cholesky.cpp index 378525a83..56885deb7 100644 --- a/ground/gcs/src/libs/eigen/test/cholesky.cpp +++ b/ground/gcs/src/libs/eigen/test/cholesky.cpp @@ -68,6 +68,7 @@ template void cholesky(const MatrixType& m) Index cols = m.cols(); typedef typename MatrixType::Scalar Scalar; + typedef typename NumTraits::Real RealScalar; typedef Matrix SquareMatrixType; typedef Matrix VectorType; @@ -179,6 +180,57 @@ template void cholesky(const MatrixType& m) // restore if(sign == -1) symm = -symm; + + // check matrices coming from linear constraints with Lagrange multipliers + if(rows>=3) + { + SquareMatrixType A = symm; + int c = internal::random(0,rows-2); + A.bottomRightCorner(c,c).setZero(); + // Make sure a solution exists: + vecX.setRandom(); + vecB = A * vecX; + vecX.setZero(); + ldltlo.compute(A); + VERIFY_IS_APPROX(A, ldltlo.reconstructedMatrix()); + vecX = ldltlo.solve(vecB); + VERIFY_IS_APPROX(A * vecX, vecB); + } + + // check non-full rank matrices + if(rows>=3) + { + int r = internal::random(1,rows-1); + Matrix a = Matrix::Random(rows,r); + SquareMatrixType A = a * a.adjoint(); + // Make sure a solution exists: + vecX.setRandom(); + vecB = A * vecX; + vecX.setZero(); + ldltlo.compute(A); + VERIFY_IS_APPROX(A, ldltlo.reconstructedMatrix()); + vecX = ldltlo.solve(vecB); + VERIFY_IS_APPROX(A * vecX, vecB); + } + + // check matrices with a wide spectrum + if(rows>=3) + { + RealScalar s = (std::min)(16,std::numeric_limits::max_exponent10/8); + Matrix a = Matrix::Random(rows,rows); + Matrix d = Matrix::Random(rows); + for(int k=0; k(-s,s)); + SquareMatrixType A = a * d.asDiagonal() * a.adjoint(); + // Make sure a solution exists: + vecX.setRandom(); + vecB = A * vecX; + vecX.setZero(); + ldltlo.compute(A); + VERIFY_IS_APPROX(A, ldltlo.reconstructedMatrix()); + vecX = ldltlo.solve(vecB); + VERIFY_IS_APPROX(A * vecX, vecB); + } } // update/downdate @@ -263,23 +315,43 @@ template void cholesky_bug241(const MatrixType& m) // LDLT is not guaranteed to work for indefinite matrices, but happens to work fine if matrix is diagonal. // This test checks that LDLT reports correctly that matrix is indefinite. -// See http://forum.kde.org/viewtopic.php?f=74&t=106942 -template void cholesky_indefinite(const MatrixType& m) +// See http://forum.kde.org/viewtopic.php?f=74&t=106942 and bug 736 +template void cholesky_definiteness(const MatrixType& m) { eigen_assert(m.rows() == 2 && m.cols() == 2); MatrixType mat; + LDLT ldlt(2); + { mat << 1, 0, 0, -1; - LDLT ldlt(mat); + ldlt.compute(mat); VERIFY(!ldlt.isNegative()); VERIFY(!ldlt.isPositive()); } { mat << 1, 2, 2, 1; - LDLT ldlt(mat); + ldlt.compute(mat); VERIFY(!ldlt.isNegative()); VERIFY(!ldlt.isPositive()); } + { + mat << 0, 0, 0, 0; + ldlt.compute(mat); + VERIFY(ldlt.isNegative()); + VERIFY(ldlt.isPositive()); + } + { + mat << 0, 0, 0, 1; + ldlt.compute(mat); + VERIFY(!ldlt.isNegative()); + VERIFY(ldlt.isPositive()); + } + { + mat << -1, 0, 0, 0; + ldlt.compute(mat); + VERIFY(ldlt.isNegative()); + VERIFY(!ldlt.isPositive()); + } } template void cholesky_verify_assert() @@ -309,7 +381,7 @@ void test_cholesky() CALL_SUBTEST_1( cholesky(Matrix()) ); CALL_SUBTEST_3( cholesky(Matrix2d()) ); CALL_SUBTEST_3( cholesky_bug241(Matrix2d()) ); - CALL_SUBTEST_3( cholesky_indefinite(Matrix2d()) ); + CALL_SUBTEST_3( cholesky_definiteness(Matrix2d()) ); CALL_SUBTEST_4( cholesky(Matrix3f()) ); CALL_SUBTEST_5( cholesky(Matrix4d()) ); s = internal::random(1,EIGEN_TEST_MAX_SIZE); diff --git a/ground/gcs/src/libs/eigen/test/conjugate_gradient.cpp b/ground/gcs/src/libs/eigen/test/conjugate_gradient.cpp index 869051b31..019cc4d64 100644 --- a/ground/gcs/src/libs/eigen/test/conjugate_gradient.cpp +++ b/ground/gcs/src/libs/eigen/test/conjugate_gradient.cpp @@ -12,13 +12,15 @@ template void test_conjugate_gradient_T() { - ConjugateGradient, Lower> cg_colmajor_lower_diag; - ConjugateGradient, Upper> cg_colmajor_upper_diag; + ConjugateGradient, Lower > cg_colmajor_lower_diag; + ConjugateGradient, Upper > cg_colmajor_upper_diag; + ConjugateGradient, Lower|Upper> cg_colmajor_loup_diag; ConjugateGradient, Lower, IdentityPreconditioner> cg_colmajor_lower_I; ConjugateGradient, Upper, IdentityPreconditioner> cg_colmajor_upper_I; CALL_SUBTEST( check_sparse_spd_solving(cg_colmajor_lower_diag) ); CALL_SUBTEST( check_sparse_spd_solving(cg_colmajor_upper_diag) ); + CALL_SUBTEST( check_sparse_spd_solving(cg_colmajor_loup_diag) ); CALL_SUBTEST( check_sparse_spd_solving(cg_colmajor_lower_I) ); CALL_SUBTEST( check_sparse_spd_solving(cg_colmajor_upper_I) ); } diff --git a/ground/gcs/src/libs/eigen/test/conservative_resize.cpp b/ground/gcs/src/libs/eigen/test/conservative_resize.cpp index 2d1ab3f03..498421b4c 100644 --- a/ground/gcs/src/libs/eigen/test/conservative_resize.cpp +++ b/ground/gcs/src/libs/eigen/test/conservative_resize.cpp @@ -60,34 +60,51 @@ void run_matrix_tests() template void run_vector_tests() { - typedef Matrix MatrixType; + typedef Matrix VectorType; - MatrixType m, n; + VectorType m, n; // boundary cases ... - m = n = MatrixType::Random(50); + m = n = VectorType::Random(50); m.conservativeResize(1); VERIFY_IS_APPROX(m, n.segment(0,1)); - m = n = MatrixType::Random(50); + m = n = VectorType::Random(50); m.conservativeResize(50); VERIFY_IS_APPROX(m, n.segment(0,50)); + + m = n = VectorType::Random(50); + m.conservativeResize(m.rows(),1); + VERIFY_IS_APPROX(m, n.segment(0,1)); + + m = n = VectorType::Random(50); + m.conservativeResize(m.rows(),50); + VERIFY_IS_APPROX(m, n.segment(0,50)); // random shrinking ... for (int i=0; i<50; ++i) { const int size = internal::random(1,50); - m = n = MatrixType::Random(50); + m = n = VectorType::Random(50); m.conservativeResize(size); VERIFY_IS_APPROX(m, n.segment(0,size)); + + m = n = VectorType::Random(50); + m.conservativeResize(m.rows(), size); + VERIFY_IS_APPROX(m, n.segment(0,size)); } // random growing with zeroing ... for (int i=0; i<50; ++i) { const int size = internal::random(50,100); - m = n = MatrixType::Random(50); - m.conservativeResizeLike(MatrixType::Zero(size)); + m = n = VectorType::Random(50); + m.conservativeResizeLike(VectorType::Zero(size)); + VERIFY_IS_APPROX(m.segment(0,50), n); + VERIFY( size<=50 || m.segment(50,size-50).sum() == Scalar(0) ); + + m = n = VectorType::Random(50); + m.conservativeResizeLike(Matrix::Zero(1,size)); VERIFY_IS_APPROX(m.segment(0,50), n); VERIFY( size<=50 || m.segment(50,size-50).sum() == Scalar(0) ); } diff --git a/ground/gcs/src/libs/eigen/test/cwiseop.cpp b/ground/gcs/src/libs/eigen/test/cwiseop.cpp index 247fa2a09..e3361da17 100644 --- a/ground/gcs/src/libs/eigen/test/cwiseop.cpp +++ b/ground/gcs/src/libs/eigen/test/cwiseop.cpp @@ -9,6 +9,8 @@ // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #define EIGEN2_SUPPORT +#define EIGEN_NO_EIGEN2_DEPRECATED_WARNING + #define EIGEN_NO_STATIC_ASSERT #include "main.h" #include diff --git a/ground/gcs/src/libs/eigen/test/dynalloc.cpp b/ground/gcs/src/libs/eigen/test/dynalloc.cpp index 8bbda1c94..ef92c0507 100644 --- a/ground/gcs/src/libs/eigen/test/dynalloc.cpp +++ b/ground/gcs/src/libs/eigen/test/dynalloc.cpp @@ -53,7 +53,7 @@ void check_aligned_new() void check_aligned_stack_alloc() { - for(int i = 1; i < 1000; i++) + for(int i = 1; i < 400; i++) { ei_declare_aligned_stack_constructed_variable(float,p,i,0); VERIFY(size_t(p)%ALIGNMENT==0); @@ -87,6 +87,32 @@ template void check_dynaligned() delete obj; } +template void check_custom_new_delete() +{ + { + T* t = new T; + delete t; + } + + { + std::size_t N = internal::random(1,10); + T* t = new T[N]; + delete[] t; + } + +#ifdef EIGEN_ALIGN + { + T* t = static_cast((T::operator new)(sizeof(T))); + (T::operator delete)(t, sizeof(T)); + } + + { + T* t = static_cast((T::operator new)(sizeof(T))); + (T::operator delete)(t); + } +#endif +} + void test_dynalloc() { // low level dynamic memory allocation @@ -94,7 +120,9 @@ void test_dynalloc() CALL_SUBTEST(check_aligned_malloc()); CALL_SUBTEST(check_aligned_new()); CALL_SUBTEST(check_aligned_stack_alloc()); - + + // check static allocation, who knows ? + #if EIGEN_ALIGN_STATICALLY for (int i=0; i() ); @@ -102,10 +130,13 @@ void test_dynalloc() CALL_SUBTEST(check_dynaligned() ); CALL_SUBTEST(check_dynaligned() ); CALL_SUBTEST(check_dynaligned() ); + + CALL_SUBTEST( check_custom_new_delete() ); + CALL_SUBTEST( check_custom_new_delete() ); + CALL_SUBTEST( check_custom_new_delete() ); + CALL_SUBTEST( check_custom_new_delete() ); } - - // check static allocation, who knows ? - #if EIGEN_ALIGN_STATICALLY + { MyStruct foo0; VERIFY(size_t(foo0.avec.data())%ALIGNMENT==0); MyClassA fooA; VERIFY(size_t(fooA.avec.data())%ALIGNMENT==0); diff --git a/ground/gcs/src/libs/eigen/test/eigen2/CMakeLists.txt b/ground/gcs/src/libs/eigen/test/eigen2/CMakeLists.txt index 84931e037..9615a6026 100644 --- a/ground/gcs/src/libs/eigen/test/eigen2/CMakeLists.txt +++ b/ground/gcs/src/libs/eigen/test/eigen2/CMakeLists.txt @@ -4,6 +4,7 @@ add_dependencies(eigen2_check eigen2_buildtests) add_dependencies(buildtests eigen2_buildtests) add_definitions("-DEIGEN2_SUPPORT_STAGE10_FULL_EIGEN2_API") +add_definitions("-DEIGEN_NO_EIGEN2_DEPRECATED_WARNING") ei_add_test(eigen2_meta) ei_add_test(eigen2_sizeof) diff --git a/ground/gcs/src/libs/eigen/test/eigen2/eigen2_adjoint.cpp b/ground/gcs/src/libs/eigen/test/eigen2/eigen2_adjoint.cpp index 8ec9c9202..c0f811459 100644 --- a/ground/gcs/src/libs/eigen/test/eigen2/eigen2_adjoint.cpp +++ b/ground/gcs/src/libs/eigen/test/eigen2/eigen2_adjoint.cpp @@ -29,8 +29,6 @@ template void adjoint(const MatrixType& m) MatrixType m1 = MatrixType::Random(rows, cols), m2 = MatrixType::Random(rows, cols), m3(rows, cols), - mzero = MatrixType::Zero(rows, cols), - identity = SquareMatrixType::Identity(rows, rows), square = SquareMatrixType::Random(rows, rows); VectorType v1 = VectorType::Random(rows), v2 = VectorType::Random(rows), diff --git a/ground/gcs/src/libs/eigen/test/eigen2/eigen2_basicstuff.cpp b/ground/gcs/src/libs/eigen/test/eigen2/eigen2_basicstuff.cpp index 4fa16d5ae..dd2dec1ef 100644 --- a/ground/gcs/src/libs/eigen/test/eigen2/eigen2_basicstuff.cpp +++ b/ground/gcs/src/libs/eigen/test/eigen2/eigen2_basicstuff.cpp @@ -23,11 +23,8 @@ template void basicStuff(const MatrixType& m) m2 = MatrixType::Random(rows, cols), m3(rows, cols), mzero = MatrixType::Zero(rows, cols), - identity = Matrix - ::Identity(rows, rows), square = Matrix::Random(rows, rows); VectorType v1 = VectorType::Random(rows), - v2 = VectorType::Random(rows), vzero = VectorType::Zero(rows); Scalar x = ei_random(); diff --git a/ground/gcs/src/libs/eigen/test/eigen2/eigen2_cwiseop.cpp b/ground/gcs/src/libs/eigen/test/eigen2/eigen2_cwiseop.cpp index 4391d19b4..22e1cc342 100644 --- a/ground/gcs/src/libs/eigen/test/eigen2/eigen2_cwiseop.cpp +++ b/ground/gcs/src/libs/eigen/test/eigen2/eigen2_cwiseop.cpp @@ -35,11 +35,8 @@ template void cwiseops(const MatrixType& m) mzero = MatrixType::Zero(rows, cols), mones = MatrixType::Ones(rows, cols), identity = Matrix - ::Identity(rows, rows), - square = Matrix::Random(rows, rows); - VectorType v1 = VectorType::Random(rows), - v2 = VectorType::Random(rows), - vzero = VectorType::Zero(rows), + ::Identity(rows, rows); + VectorType vzero = VectorType::Zero(rows), vones = VectorType::Ones(rows), v3(rows); diff --git a/ground/gcs/src/libs/eigen/test/eigen2/eigen2_geometry.cpp b/ground/gcs/src/libs/eigen/test/eigen2/eigen2_geometry.cpp index faf1d7fdb..514040774 100644 --- a/ground/gcs/src/libs/eigen/test/eigen2/eigen2_geometry.cpp +++ b/ground/gcs/src/libs/eigen/test/eigen2/eigen2_geometry.cpp @@ -147,7 +147,7 @@ template void geometry(void) t1.setIdentity(); t1.linear() = q1.toRotationMatrix(); - v0 << 50, 2, 1; // = ei_random_matrix().cwiseProduct(Vector3(10,2,0.5)); + v0 << 50, 2, 1;//= ei_random_matrix().cwiseProduct(Vector3(10,2,0.5)); t0.scale(v0); t1.prescale(v0); @@ -392,6 +392,7 @@ template void geometry(void) #define VERIFY_EULER(I,J,K, X,Y,Z) { \ Vector3 ea = m.eulerAngles(I,J,K); \ Matrix3 m1 = Matrix3(AngleAxisx(ea[0], Vector3::Unit##X()) * AngleAxisx(ea[1], Vector3::Unit##Y()) * AngleAxisx(ea[2], Vector3::Unit##Z())); \ + VERIFY_IS_APPROX(m, m1); \ VERIFY_IS_APPROX(m, Matrix3(AngleAxisx(ea[0], Vector3::Unit##X()) * AngleAxisx(ea[1], Vector3::Unit##Y()) * AngleAxisx(ea[2], Vector3::Unit##Z()))); \ } VERIFY_EULER(0,1,2, X,Y,Z); diff --git a/ground/gcs/src/libs/eigen/test/eigen2/eigen2_geometry_with_eigen2_prefix.cpp b/ground/gcs/src/libs/eigen/test/eigen2/eigen2_geometry_with_eigen2_prefix.cpp index 9ff9f4026..12d4a71c3 100644 --- a/ground/gcs/src/libs/eigen/test/eigen2/eigen2_geometry_with_eigen2_prefix.cpp +++ b/ground/gcs/src/libs/eigen/test/eigen2/eigen2_geometry_with_eigen2_prefix.cpp @@ -149,7 +149,7 @@ template void geometry(void) t1.setIdentity(); t1.linear() = q1.toRotationMatrix(); - v0 << 50, 2, 1; // = ei_random_matrix().cwiseProduct(Vector3(10,2,0.5)); + v0 << 50, 2, 1;//= ei_random_matrix().cwiseProduct(Vector3(10,2,0.5)); t0.scale(v0); t1.prescale(v0); @@ -394,6 +394,7 @@ template void geometry(void) #define VERIFY_EULER(I,J,K, X,Y,Z) { \ Vector3 ea = m.eulerAngles(I,J,K); \ Matrix3 m1 = Matrix3(AngleAxisx(ea[0], Vector3::Unit##X()) * AngleAxisx(ea[1], Vector3::Unit##Y()) * AngleAxisx(ea[2], Vector3::Unit##Z())); \ + VERIFY_IS_APPROX(m, m1); \ VERIFY_IS_APPROX(m, Matrix3(AngleAxisx(ea[0], Vector3::Unit##X()) * AngleAxisx(ea[1], Vector3::Unit##Y()) * AngleAxisx(ea[2], Vector3::Unit##Z()))); \ } VERIFY_EULER(0,1,2, X,Y,Z); diff --git a/ground/gcs/src/libs/eigen/test/eigen2/eigen2_inverse.cpp b/ground/gcs/src/libs/eigen/test/eigen2/eigen2_inverse.cpp index 5de1dfefa..ccd24a194 100644 --- a/ground/gcs/src/libs/eigen/test/eigen2/eigen2_inverse.cpp +++ b/ground/gcs/src/libs/eigen/test/eigen2/eigen2_inverse.cpp @@ -25,7 +25,6 @@ template void inverse(const MatrixType& m) MatrixType m1 = MatrixType::Random(rows, cols), m2(rows, cols), - mzero = MatrixType::Zero(rows, cols), identity = MatrixType::Identity(rows, rows); while(ei_abs(m1.determinant()) < RealScalar(0.1) && rows <= 8) diff --git a/ground/gcs/src/libs/eigen/test/eigen2/eigen2_linearstructure.cpp b/ground/gcs/src/libs/eigen/test/eigen2/eigen2_linearstructure.cpp index 22f02c396..488f4c485 100644 --- a/ground/gcs/src/libs/eigen/test/eigen2/eigen2_linearstructure.cpp +++ b/ground/gcs/src/libs/eigen/test/eigen2/eigen2_linearstructure.cpp @@ -25,8 +25,7 @@ template void linearStructure(const MatrixType& m) // to test it, hence I consider that we will have tested Random.h MatrixType m1 = MatrixType::Random(rows, cols), m2 = MatrixType::Random(rows, cols), - m3(rows, cols), - mzero = MatrixType::Zero(rows, cols); + m3(rows, cols); Scalar s1 = ei_random(); while (ei_abs(s1)<1e-3) s1 = ei_random(); diff --git a/ground/gcs/src/libs/eigen/test/eigen2/eigen2_nomalloc.cpp b/ground/gcs/src/libs/eigen/test/eigen2/eigen2_nomalloc.cpp index e234abe4b..d34a69999 100644 --- a/ground/gcs/src/libs/eigen/test/eigen2/eigen2_nomalloc.cpp +++ b/ground/gcs/src/libs/eigen/test/eigen2/eigen2_nomalloc.cpp @@ -25,22 +25,12 @@ template void nomalloc(const MatrixType& m) */ typedef typename MatrixType::Scalar Scalar; - typedef Matrix VectorType; int rows = m.rows(); int cols = m.cols(); MatrixType m1 = MatrixType::Random(rows, cols), - m2 = MatrixType::Random(rows, cols), - m3(rows, cols), - mzero = MatrixType::Zero(rows, cols), - identity = Matrix - ::Identity(rows, rows), - square = Matrix - ::Random(rows, rows); - VectorType v1 = VectorType::Random(rows), - v2 = VectorType::Random(rows), - vzero = VectorType::Zero(rows); + m2 = MatrixType::Random(rows, cols); Scalar s1 = ei_random(); diff --git a/ground/gcs/src/libs/eigen/test/eigen2/eigen2_submatrices.cpp b/ground/gcs/src/libs/eigen/test/eigen2/eigen2_submatrices.cpp index c5d3f243d..dee970b63 100644 --- a/ground/gcs/src/libs/eigen/test/eigen2/eigen2_submatrices.cpp +++ b/ground/gcs/src/libs/eigen/test/eigen2/eigen2_submatrices.cpp @@ -51,16 +51,10 @@ template void submatrices(const MatrixType& m) MatrixType m1 = MatrixType::Random(rows, cols), m2 = MatrixType::Random(rows, cols), m3(rows, cols), - mzero = MatrixType::Zero(rows, cols), ones = MatrixType::Ones(rows, cols), - identity = Matrix - ::Identity(rows, rows), square = Matrix ::Random(rows, rows); - VectorType v1 = VectorType::Random(rows), - v2 = VectorType::Random(rows), - v3 = VectorType::Random(rows), - vzero = VectorType::Zero(rows); + VectorType v1 = VectorType::Random(rows); Scalar s1 = ei_random(); diff --git a/ground/gcs/src/libs/eigen/test/eigen2/eigen2_triangular.cpp b/ground/gcs/src/libs/eigen/test/eigen2/eigen2_triangular.cpp index 3748c7d71..6f17b7dff 100644 --- a/ground/gcs/src/libs/eigen/test/eigen2/eigen2_triangular.cpp +++ b/ground/gcs/src/libs/eigen/test/eigen2/eigen2_triangular.cpp @@ -13,7 +13,6 @@ template void triangular(const MatrixType& m) { typedef typename MatrixType::Scalar Scalar; typedef typename NumTraits::Real RealScalar; - typedef Matrix VectorType; RealScalar largerEps = 10*test_precision(); @@ -25,16 +24,7 @@ template void triangular(const MatrixType& m) m3(rows, cols), m4(rows, cols), r1(rows, cols), - r2(rows, cols), - mzero = MatrixType::Zero(rows, cols), - mones = MatrixType::Ones(rows, cols), - identity = Matrix - ::Identity(rows, rows), - square = Matrix - ::Random(rows, rows); - VectorType v1 = VectorType::Random(rows), - v2 = VectorType::Random(rows), - vzero = VectorType::Zero(rows); + r2(rows, cols); MatrixType m1up = m1.template part(); MatrixType m2up = m2.template part(); diff --git a/ground/gcs/src/libs/eigen/test/eigen2/product.h b/ground/gcs/src/libs/eigen/test/eigen2/product.h index 2c9604d9a..ae1b4bae4 100644 --- a/ground/gcs/src/libs/eigen/test/eigen2/product.h +++ b/ground/gcs/src/libs/eigen/test/eigen2/product.h @@ -40,8 +40,7 @@ template void product(const MatrixType& m) // to test it, hence I consider that we will have tested Random.h MatrixType m1 = MatrixType::Random(rows, cols), m2 = MatrixType::Random(rows, cols), - m3(rows, cols), - mzero = MatrixType::Zero(rows, cols); + m3(rows, cols); RowSquareMatrixType identity = RowSquareMatrixType::Identity(rows, rows), square = RowSquareMatrixType::Random(rows, rows), @@ -49,9 +48,7 @@ template void product(const MatrixType& m) ColSquareMatrixType square2 = ColSquareMatrixType::Random(cols, cols), res2 = ColSquareMatrixType::Random(cols, cols); - RowVectorType v1 = RowVectorType::Random(rows), - v2 = RowVectorType::Random(rows), - vzero = RowVectorType::Zero(rows); + RowVectorType v1 = RowVectorType::Random(rows); ColVectorType vc2 = ColVectorType::Random(cols), vcres(cols); OtherMajorMatrixType tm1 = m1; diff --git a/ground/gcs/src/libs/eigen/test/eigen2support.cpp b/ground/gcs/src/libs/eigen/test/eigen2support.cpp index ad1d98091..1fa49a8c8 100644 --- a/ground/gcs/src/libs/eigen/test/eigen2support.cpp +++ b/ground/gcs/src/libs/eigen/test/eigen2support.cpp @@ -8,6 +8,7 @@ // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #define EIGEN2_SUPPORT +#define EIGEN_NO_EIGEN2_DEPRECATED_WARNING #include "main.h" diff --git a/ground/gcs/src/libs/eigen/test/eigensolver_selfadjoint.cpp b/ground/gcs/src/libs/eigen/test/eigensolver_selfadjoint.cpp index 5c6ecd875..38689cfbf 100644 --- a/ground/gcs/src/libs/eigen/test/eigensolver_selfadjoint.cpp +++ b/ground/gcs/src/libs/eigen/test/eigensolver_selfadjoint.cpp @@ -29,7 +29,21 @@ template void selfadjointeigensolver(const MatrixType& m) MatrixType a = MatrixType::Random(rows,cols); MatrixType a1 = MatrixType::Random(rows,cols); MatrixType symmA = a.adjoint() * a + a1.adjoint() * a1; + MatrixType symmC = symmA; + + // randomly nullify some rows/columns + { + Index count = 1;//internal::random(-cols,cols); + for(Index k=0; k(0,cols-1); + symmA.row(i).setZero(); + symmA.col(i).setZero(); + } + } + symmA.template triangularView().setZero(); + symmC.template triangularView().setZero(); MatrixType b = MatrixType::Random(rows,cols); MatrixType b1 = MatrixType::Random(rows,cols); @@ -40,7 +54,7 @@ template void selfadjointeigensolver(const MatrixType& m) SelfAdjointEigenSolver eiDirect; eiDirect.computeDirect(symmA); // generalized eigen pb - GeneralizedSelfAdjointEigenSolver eiSymmGen(symmA, symmB); + GeneralizedSelfAdjointEigenSolver eiSymmGen(symmC, symmB); VERIFY_IS_EQUAL(eiSymm.info(), Success); VERIFY((symmA.template selfadjointView() * eiSymm.eigenvectors()).isApprox( @@ -57,27 +71,28 @@ template void selfadjointeigensolver(const MatrixType& m) VERIFY_IS_APPROX(eiSymm.eigenvalues(), eiSymmNoEivecs.eigenvalues()); // generalized eigen problem Ax = lBx - eiSymmGen.compute(symmA, symmB,Ax_lBx); + eiSymmGen.compute(symmC, symmB,Ax_lBx); VERIFY_IS_EQUAL(eiSymmGen.info(), Success); - VERIFY((symmA.template selfadjointView() * eiSymmGen.eigenvectors()).isApprox( + VERIFY((symmC.template selfadjointView() * eiSymmGen.eigenvectors()).isApprox( symmB.template selfadjointView() * (eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()), largerEps)); // generalized eigen problem BAx = lx - eiSymmGen.compute(symmA, symmB,BAx_lx); + eiSymmGen.compute(symmC, symmB,BAx_lx); VERIFY_IS_EQUAL(eiSymmGen.info(), Success); - VERIFY((symmB.template selfadjointView() * (symmA.template selfadjointView() * eiSymmGen.eigenvectors())).isApprox( + VERIFY((symmB.template selfadjointView() * (symmC.template selfadjointView() * eiSymmGen.eigenvectors())).isApprox( (eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()), largerEps)); // generalized eigen problem ABx = lx - eiSymmGen.compute(symmA, symmB,ABx_lx); + eiSymmGen.compute(symmC, symmB,ABx_lx); VERIFY_IS_EQUAL(eiSymmGen.info(), Success); - VERIFY((symmA.template selfadjointView() * (symmB.template selfadjointView() * eiSymmGen.eigenvectors())).isApprox( + VERIFY((symmC.template selfadjointView() * (symmB.template selfadjointView() * eiSymmGen.eigenvectors())).isApprox( (eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()), largerEps)); + eiSymm.compute(symmC); MatrixType sqrtSymmA = eiSymm.operatorSqrt(); - VERIFY_IS_APPROX(MatrixType(symmA.template selfadjointView()), sqrtSymmA*sqrtSymmA); - VERIFY_IS_APPROX(sqrtSymmA, symmA.template selfadjointView()*eiSymm.operatorInverseSqrt()); + VERIFY_IS_APPROX(MatrixType(symmC.template selfadjointView()), sqrtSymmA*sqrtSymmA); + VERIFY_IS_APPROX(sqrtSymmA, symmC.template selfadjointView()*eiSymm.operatorInverseSqrt()); MatrixType id = MatrixType::Identity(rows, cols); VERIFY_IS_APPROX(id.template selfadjointView().operatorNorm(), RealScalar(1)); @@ -95,15 +110,15 @@ template void selfadjointeigensolver(const MatrixType& m) VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorInverseSqrt()); // test Tridiagonalization's methods - Tridiagonalization tridiag(symmA); + Tridiagonalization tridiag(symmC); // FIXME tridiag.matrixQ().adjoint() does not work - VERIFY_IS_APPROX(MatrixType(symmA.template selfadjointView()), tridiag.matrixQ() * tridiag.matrixT().eval() * MatrixType(tridiag.matrixQ()).adjoint()); + VERIFY_IS_APPROX(MatrixType(symmC.template selfadjointView()), tridiag.matrixQ() * tridiag.matrixT().eval() * MatrixType(tridiag.matrixQ()).adjoint()); if (rows > 1) { // Test matrix with NaN - symmA(0,0) = std::numeric_limits::quiet_NaN(); - SelfAdjointEigenSolver eiSymmNaN(symmA); + symmC(0,0) = std::numeric_limits::quiet_NaN(); + SelfAdjointEigenSolver eiSymmNaN(symmC); VERIFY_IS_EQUAL(eiSymmNaN.info(), NoConvergence); } } @@ -113,8 +128,10 @@ void test_eigensolver_selfadjoint() int s = 0; for(int i = 0; i < g_repeat; i++) { // very important to test 3x3 and 2x2 matrices since we provide special paths for them + CALL_SUBTEST_1( selfadjointeigensolver(Matrix2f()) ); CALL_SUBTEST_1( selfadjointeigensolver(Matrix2d()) ); CALL_SUBTEST_1( selfadjointeigensolver(Matrix3f()) ); + CALL_SUBTEST_1( selfadjointeigensolver(Matrix3d()) ); CALL_SUBTEST_2( selfadjointeigensolver(Matrix4d()) ); s = internal::random(1,EIGEN_TEST_MAX_SIZE/4); CALL_SUBTEST_3( selfadjointeigensolver(MatrixXf(s,s)) ); diff --git a/ground/gcs/src/libs/eigen/test/geo_alignedbox.cpp b/ground/gcs/src/libs/eigen/test/geo_alignedbox.cpp index 8e36adbe3..84663ad1f 100644 --- a/ground/gcs/src/libs/eigen/test/geo_alignedbox.cpp +++ b/ground/gcs/src/libs/eigen/test/geo_alignedbox.cpp @@ -172,6 +172,8 @@ void test_geo_alignedbox() CALL_SUBTEST_9( alignedbox(AlignedBox1i()) ); CALL_SUBTEST_10( alignedbox(AlignedBox2i()) ); CALL_SUBTEST_11( alignedbox(AlignedBox3i()) ); + + CALL_SUBTEST_14( alignedbox(AlignedBox(4)) ); } CALL_SUBTEST_12( specificTest1() ); CALL_SUBTEST_13( specificTest2() ); diff --git a/ground/gcs/src/libs/eigen/test/geo_eulerangles.cpp b/ground/gcs/src/libs/eigen/test/geo_eulerangles.cpp index 5445cd81a..b4830bd41 100644 --- a/ground/gcs/src/libs/eigen/test/geo_eulerangles.cpp +++ b/ground/gcs/src/libs/eigen/test/geo_eulerangles.cpp @@ -12,36 +12,48 @@ #include #include -template void check_all_var(const Matrix& ea) + +template +void verify_euler(const Matrix& ea, int i, int j, int k) { typedef Matrix Matrix3; typedef Matrix Vector3; typedef AngleAxis AngleAxisx; using std::abs; + Matrix3 m(AngleAxisx(ea[0], Vector3::Unit(i)) * AngleAxisx(ea[1], Vector3::Unit(j)) * AngleAxisx(ea[2], Vector3::Unit(k))); + Vector3 eabis = m.eulerAngles(i, j, k); + Matrix3 mbis(AngleAxisx(eabis[0], Vector3::Unit(i)) * AngleAxisx(eabis[1], Vector3::Unit(j)) * AngleAxisx(eabis[2], Vector3::Unit(k))); + VERIFY_IS_APPROX(m, mbis); + /* If I==K, and ea[1]==0, then there no unique solution. */ + /* The remark apply in the case where I!=K, and |ea[1]| is close to pi/2. */ + if( (i!=k || ea[1]!=0) && (i==k || !internal::isApprox(abs(ea[1]),Scalar(M_PI/2),test_precision())) ) + VERIFY((ea-eabis).norm() <= test_precision()); - #define VERIFY_EULER(I,J,K, X,Y,Z) { \ - Matrix3 m(AngleAxisx(ea[0], Vector3::Unit##X()) * AngleAxisx(ea[1], Vector3::Unit##Y()) * AngleAxisx(ea[2], Vector3::Unit##Z())); \ - Vector3 eabis = m.eulerAngles(I,J,K); \ - Matrix3 mbis(AngleAxisx(eabis[0], Vector3::Unit##X()) * AngleAxisx(eabis[1], Vector3::Unit##Y()) * AngleAxisx(eabis[2], Vector3::Unit##Z())); \ - VERIFY_IS_APPROX(m, mbis); \ - /* If I==K, and ea[1]==0, then there no unique solution. */ \ - /* The remark apply in the case where I!=K, and |ea[1]| is close to pi/2. */ \ - if( (I!=K || ea[1]!=0) && (I==K || !internal::isApprox(abs(ea[1]),Scalar(M_PI/2),test_precision())) ) VERIFY((ea-eabis).norm() <= test_precision()); \ - } - VERIFY_EULER(0,1,2, X,Y,Z); - VERIFY_EULER(0,1,0, X,Y,X); - VERIFY_EULER(0,2,1, X,Z,Y); - VERIFY_EULER(0,2,0, X,Z,X); + // approx_or_less_than does not work for 0 + VERIFY(0 < eabis[0] || test_isMuchSmallerThan(eabis[0], Scalar(1))); + VERIFY_IS_APPROX_OR_LESS_THAN(eabis[0], Scalar(M_PI)); + VERIFY_IS_APPROX_OR_LESS_THAN(-Scalar(M_PI), eabis[1]); + VERIFY_IS_APPROX_OR_LESS_THAN(eabis[1], Scalar(M_PI)); + VERIFY_IS_APPROX_OR_LESS_THAN(-Scalar(M_PI), eabis[2]); + VERIFY_IS_APPROX_OR_LESS_THAN(eabis[2], Scalar(M_PI)); +} - VERIFY_EULER(1,2,0, Y,Z,X); - VERIFY_EULER(1,2,1, Y,Z,Y); - VERIFY_EULER(1,0,2, Y,X,Z); - VERIFY_EULER(1,0,1, Y,X,Y); +template void check_all_var(const Matrix& ea) +{ + verify_euler(ea, 0,1,2); + verify_euler(ea, 0,1,0); + verify_euler(ea, 0,2,1); + verify_euler(ea, 0,2,0); - VERIFY_EULER(2,0,1, Z,X,Y); - VERIFY_EULER(2,0,2, Z,X,Z); - VERIFY_EULER(2,1,0, Z,Y,X); - VERIFY_EULER(2,1,2, Z,Y,Z); + verify_euler(ea, 1,2,0); + verify_euler(ea, 1,2,1); + verify_euler(ea, 1,0,2); + verify_euler(ea, 1,0,1); + + verify_euler(ea, 2,0,1); + verify_euler(ea, 2,0,2); + verify_euler(ea, 2,1,0); + verify_euler(ea, 2,1,2); } template void eulerangles() @@ -63,7 +75,16 @@ template void eulerangles() ea = m.eulerAngles(0,1,0); check_all_var(ea); - ea = (Array3::Random() + Array3(1,1,0))*Scalar(M_PI)*Array3(0.5,0.5,1); + // Check with purely random Quaternion: + q1.coeffs() = Quaternionx::Coefficients::Random().normalized(); + m = q1; + ea = m.eulerAngles(0,1,2); + check_all_var(ea); + ea = m.eulerAngles(0,1,0); + check_all_var(ea); + + // Check with random angles in range [0:pi]x[-pi:pi]x[-pi:pi]. + ea = (Array3::Random() + Array3(1,0,0))*Scalar(M_PI)*Array3(0.5,1,1); check_all_var(ea); ea[2] = ea[0] = internal::random(0,Scalar(M_PI)); diff --git a/ground/gcs/src/libs/eigen/test/geo_hyperplane.cpp b/ground/gcs/src/libs/eigen/test/geo_hyperplane.cpp index f26fc1329..327537801 100644 --- a/ground/gcs/src/libs/eigen/test/geo_hyperplane.cpp +++ b/ground/gcs/src/libs/eigen/test/geo_hyperplane.cpp @@ -114,6 +114,32 @@ template void lines() } } +template void planes() +{ + using std::abs; + typedef Hyperplane Plane; + typedef Matrix Vector; + + for(int i = 0; i < 10; i++) + { + Vector v0 = Vector::Random(); + Vector v1(v0), v2(v0); + if(internal::random(0,1)>0.25) + v1 += Vector::Random(); + if(internal::random(0,1)>0.25) + v2 += v1 * std::pow(internal::random(0,1),internal::random(1,16)); + if(internal::random(0,1)>0.25) + v2 += Vector::Random() * std::pow(internal::random(0,1),internal::random(1,16)); + + Plane p0 = Plane::Through(v0, v1, v2); + + VERIFY_IS_APPROX(p0.normal().norm(), Scalar(1)); + VERIFY_IS_MUCH_SMALLER_THAN(p0.absDistance(v0), Scalar(1)); + VERIFY_IS_MUCH_SMALLER_THAN(p0.absDistance(v1), Scalar(1)); + VERIFY_IS_MUCH_SMALLER_THAN(p0.absDistance(v2), Scalar(1)); + } +} + template void hyperplane_alignment() { typedef Hyperplane Plane3a; @@ -153,5 +179,7 @@ void test_geo_hyperplane() CALL_SUBTEST_4( hyperplane(Hyperplane,5>()) ); CALL_SUBTEST_1( lines() ); CALL_SUBTEST_3( lines() ); + CALL_SUBTEST_2( planes() ); + CALL_SUBTEST_5( planes() ); } } diff --git a/ground/gcs/src/libs/eigen/test/geo_transformations.cpp b/ground/gcs/src/libs/eigen/test/geo_transformations.cpp index 35ae67ebe..547765714 100644 --- a/ground/gcs/src/libs/eigen/test/geo_transformations.cpp +++ b/ground/gcs/src/libs/eigen/test/geo_transformations.cpp @@ -98,11 +98,19 @@ template void transformations() Matrix3 matrot1, m; Scalar a = internal::random(-Scalar(M_PI), Scalar(M_PI)); - Scalar s0 = internal::random(); + Scalar s0 = internal::random(), + s1 = internal::random(); + + while(v0.norm() < test_precision()) v0 = Vector3::Random(); + while(v1.norm() < test_precision()) v1 = Vector3::Random(); + VERIFY_IS_APPROX(v0, AngleAxisx(a, v0.normalized()) * v0); VERIFY_IS_APPROX(-v0, AngleAxisx(Scalar(M_PI), v0.unitOrthogonal()) * v0); - VERIFY_IS_APPROX(cos(a)*v0.squaredNorm(), v0.dot(AngleAxisx(a, v0.unitOrthogonal()) * v0)); + if(abs(cos(a)) > test_precision()) + { + VERIFY_IS_APPROX(cos(a)*v0.squaredNorm(), v0.dot(AngleAxisx(a, v0.unitOrthogonal()) * v0)); + } m = AngleAxisx(a, v0.normalized()).toRotationMatrix().adjoint(); VERIFY_IS_APPROX(Matrix3::Identity(), m * AngleAxisx(a, v0.normalized())); VERIFY_IS_APPROX(Matrix3::Identity(), AngleAxisx(a, v0.normalized()) * m); @@ -123,11 +131,18 @@ template void transformations() // angle-axis conversion AngleAxisx aa = AngleAxisx(q1); VERIFY_IS_APPROX(q1 * v1, Quaternionx(aa) * v1); - VERIFY_IS_NOT_APPROX(q1 * v1, Quaternionx(AngleAxisx(aa.angle()*2,aa.axis())) * v1); + + if(abs(aa.angle()) > NumTraits::dummy_precision()) + { + VERIFY( !(q1 * v1).isApprox(Quaternionx(AngleAxisx(aa.angle()*2,aa.axis())) * v1) ); + } aa.fromRotationMatrix(aa.toRotationMatrix()); VERIFY_IS_APPROX(q1 * v1, Quaternionx(aa) * v1); - VERIFY_IS_NOT_APPROX(q1 * v1, Quaternionx(AngleAxisx(aa.angle()*2,aa.axis())) * v1); + if(abs(aa.angle()) > NumTraits::dummy_precision()) + { + VERIFY( !(q1 * v1).isApprox(Quaternionx(AngleAxisx(aa.angle()*2,aa.axis())) * v1) ); + } // AngleAxis VERIFY_IS_APPROX(AngleAxisx(a,v1.normalized()).toRotationMatrix(), @@ -279,6 +294,13 @@ template void transformations() t1 = Eigen::Scaling(s0,s0,s0) * t1; VERIFY_IS_APPROX(t0.matrix(), t1.matrix()); + t0 = t3; + t0.scale(s0); + t1 = t3 * Eigen::Scaling(s0); + VERIFY_IS_APPROX(t0.matrix(), t1.matrix()); + t0.prescale(s0); + t1 = Eigen::Scaling(s0) * t1; + VERIFY_IS_APPROX(t0.matrix(), t1.matrix()); t0.setIdentity(); t0.prerotate(q1).prescale(v0).pretranslate(v0); @@ -340,7 +362,9 @@ template void transformations() // test transform inversion t0.setIdentity(); t0.translate(v0); - t0.linear().setRandom(); + do { + t0.linear().setRandom(); + } while(t0.linear().jacobiSvd().singularValues()(2)()); Matrix4 t044 = Matrix4::Zero(); t044(3,3) = 1; t044.block(0,0,t0.matrix().rows(),4) = t0.matrix(); @@ -390,6 +414,29 @@ template void transformations() t20 = Translation2(v20) * (Rotation2D(s0) * Eigen::Scaling(s0)); t21 = Translation2(v20) * Rotation2D(s0) * Eigen::Scaling(s0); VERIFY_IS_APPROX(t20,t21); + + Rotation2D R0(s0), R1(s1); + t20 = Translation2(v20) * (R0 * Eigen::Scaling(s0)); + t21 = Translation2(v20) * R0 * Eigen::Scaling(s0); + VERIFY_IS_APPROX(t20,t21); + + t20 = Translation2(v20) * (R0 * R0.inverse() * Eigen::Scaling(s0)); + t21 = Translation2(v20) * Eigen::Scaling(s0); + VERIFY_IS_APPROX(t20,t21); + + VERIFY_IS_APPROX(s0, (R0.slerp(0, R1)).angle()); + VERIFY_IS_APPROX(s1, (R0.slerp(1, R1)).angle()); + VERIFY_IS_APPROX(s0, (R0.slerp(0.5, R0)).angle()); + VERIFY_IS_APPROX(Scalar(0), (R0.slerp(0.5, R0.inverse())).angle()); + + // check basic features + { + Rotation2D r1; // default ctor + r1 = Rotation2D(s0); // copy assignment + VERIFY_IS_APPROX(r1.angle(),s0); + Rotation2D r2(r1); // copy ctor + VERIFY_IS_APPROX(r2.angle(),s0); + } } template void transform_alignment() diff --git a/ground/gcs/src/libs/eigen/test/jacobisvd.cpp b/ground/gcs/src/libs/eigen/test/jacobisvd.cpp index 76157c30f..12c556e59 100644 --- a/ground/gcs/src/libs/eigen/test/jacobisvd.cpp +++ b/ground/gcs/src/libs/eigen/test/jacobisvd.cpp @@ -67,6 +67,7 @@ template void jacobisvd_solve(const MatrixType& m, unsigned int computationOptions) { typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; typedef typename MatrixType::Index Index; Index rows = m.rows(); Index cols = m.cols(); @@ -81,9 +82,90 @@ void jacobisvd_solve(const MatrixType& m, unsigned int computationOptions) RhsType rhs = RhsType::Random(rows, internal::random(1, cols)); JacobiSVD svd(m, computationOptions); + + if(internal::is_same::value) svd.setThreshold(1e-8); + else if(internal::is_same::value) svd.setThreshold(1e-4); + SolutionType x = svd.solve(rhs); + + RealScalar residual = (m*x-rhs).norm(); + // Check that there is no significantly better solution in the neighborhood of x + if(!test_isMuchSmallerThan(residual,rhs.norm())) + { + // If the residual is very small, then we have an exact solution, so we are already good. + for(int k=0;k::epsilon(); + RealScalar residual_y = (m*y-rhs).norm(); + VERIFY( test_isApprox(residual_y,residual) || residual < residual_y ); + + y.row(k) = x.row(k).array() - 2*NumTraits::epsilon(); + residual_y = (m*y-rhs).norm(); + VERIFY( test_isApprox(residual_y,residual) || residual < residual_y ); + } + } + // evaluate normal equation which works also for least-squares solutions - VERIFY_IS_APPROX(m.adjoint()*m*x,m.adjoint()*rhs); + if(internal::is_same::value) + { + // This test is not stable with single precision. + // This is probably because squaring m signicantly affects the precision. + VERIFY_IS_APPROX(m.adjoint()*m*x,m.adjoint()*rhs); + } + + // check minimal norm solutions + { + // generate a full-rank m x n problem with m MatrixType2; + typedef Matrix RhsType2; + typedef Matrix MatrixType2T; + Index rank = RankAtCompileTime2==Dynamic ? internal::random(1,cols) : Index(RankAtCompileTime2); + MatrixType2 m2(rank,cols); + int guard = 0; + do { + m2.setRandom(); + } while(m2.jacobiSvd().setThreshold(test_precision()).rank()!=rank && (++guard)<10); + VERIFY(guard<10); + RhsType2 rhs2 = RhsType2::Random(rank); + // use QR to find a reference minimal norm solution + HouseholderQR qr(m2.adjoint()); + Matrix tmp = qr.matrixQR().topLeftCorner(rank,rank).template triangularView().adjoint().solve(rhs2); + tmp.conservativeResize(cols); + tmp.tail(cols-rank).setZero(); + SolutionType x21 = qr.householderQ() * tmp; + // now check with SVD + JacobiSVD svd2(m2, computationOptions); + SolutionType x22 = svd2.solve(rhs2); + VERIFY_IS_APPROX(m2*x21, rhs2); + VERIFY_IS_APPROX(m2*x22, rhs2); + VERIFY_IS_APPROX(x21, x22); + + // Now check with a rank deficient matrix + typedef Matrix MatrixType3; + typedef Matrix RhsType3; + Index rows3 = RowsAtCompileTime3==Dynamic ? internal::random(rank+1,2*cols) : Index(RowsAtCompileTime3); + Matrix C = Matrix::Random(rows3,rank); + MatrixType3 m3 = C * m2; + RhsType3 rhs3 = C * rhs2; + JacobiSVD svd3(m3, computationOptions); + SolutionType x3 = svd3.solve(rhs3); + if(svd3.rank()!=rank) { + std::cout << m3 << "\n\n"; + std::cout << svd3.singularValues().transpose() << "\n"; + std::cout << svd3.rank() << " == " << rank << "\n"; + std::cout << x21.norm() << " == " << x3.norm() << "\n"; + } +// VERIFY_IS_APPROX(m3*x3, rhs3); + VERIFY_IS_APPROX(m3*x21, rhs3); + VERIFY_IS_APPROX(m2*x3, rhs2); + + VERIFY_IS_APPROX(x21, x3); + } } template @@ -92,10 +174,9 @@ void jacobisvd_test_all_computation_options(const MatrixType& m) if (QRPreconditioner == NoQRPreconditioner && m.rows() != m.cols()) return; JacobiSVD fullSvd(m, ComputeFullU|ComputeFullV); - - jacobisvd_check_full(m, fullSvd); - jacobisvd_solve(m, ComputeFullU | ComputeFullV); - + CALL_SUBTEST(( jacobisvd_check_full(m, fullSvd) )); + CALL_SUBTEST(( jacobisvd_solve(m, ComputeFullU | ComputeFullV) )); + #if defined __INTEL_COMPILER // remark #111: statement is unreachable #pragma warning disable 111 @@ -103,20 +184,20 @@ void jacobisvd_test_all_computation_options(const MatrixType& m) if(QRPreconditioner == FullPivHouseholderQRPreconditioner) return; - jacobisvd_compare_to_full(m, ComputeFullU, fullSvd); - jacobisvd_compare_to_full(m, ComputeFullV, fullSvd); - jacobisvd_compare_to_full(m, 0, fullSvd); + CALL_SUBTEST(( jacobisvd_compare_to_full(m, ComputeFullU, fullSvd) )); + CALL_SUBTEST(( jacobisvd_compare_to_full(m, ComputeFullV, fullSvd) )); + CALL_SUBTEST(( jacobisvd_compare_to_full(m, 0, fullSvd) )); if (MatrixType::ColsAtCompileTime == Dynamic) { // thin U/V are only available with dynamic number of columns - jacobisvd_compare_to_full(m, ComputeFullU|ComputeThinV, fullSvd); - jacobisvd_compare_to_full(m, ComputeThinV, fullSvd); - jacobisvd_compare_to_full(m, ComputeThinU|ComputeFullV, fullSvd); - jacobisvd_compare_to_full(m, ComputeThinU , fullSvd); - jacobisvd_compare_to_full(m, ComputeThinU|ComputeThinV, fullSvd); - jacobisvd_solve(m, ComputeFullU | ComputeThinV); - jacobisvd_solve(m, ComputeThinU | ComputeFullV); - jacobisvd_solve(m, ComputeThinU | ComputeThinV); + CALL_SUBTEST(( jacobisvd_compare_to_full(m, ComputeFullU|ComputeThinV, fullSvd) )); + CALL_SUBTEST(( jacobisvd_compare_to_full(m, ComputeThinV, fullSvd) )); + CALL_SUBTEST(( jacobisvd_compare_to_full(m, ComputeThinU|ComputeFullV, fullSvd) )); + CALL_SUBTEST(( jacobisvd_compare_to_full(m, ComputeThinU , fullSvd) )); + CALL_SUBTEST(( jacobisvd_compare_to_full(m, ComputeThinU|ComputeThinV, fullSvd) )); + CALL_SUBTEST(( jacobisvd_solve(m, ComputeFullU | ComputeThinV) )); + CALL_SUBTEST(( jacobisvd_solve(m, ComputeThinU | ComputeFullV) )); + CALL_SUBTEST(( jacobisvd_solve(m, ComputeThinU | ComputeThinV) )); // test reconstruction typedef typename MatrixType::Index Index; @@ -129,12 +210,29 @@ void jacobisvd_test_all_computation_options(const MatrixType& m) template void jacobisvd(const MatrixType& a = MatrixType(), bool pickrandom = true) { - MatrixType m = pickrandom ? MatrixType::Random(a.rows(), a.cols()) : a; + MatrixType m = a; + if(pickrandom) + { + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef typename MatrixType::Index Index; + Index diagSize = (std::min)(a.rows(), a.cols()); + RealScalar s = std::numeric_limits::max_exponent10/4; + s = internal::random(1,s); + Matrix d = Matrix::Random(diagSize); + for(Index k=0; k(-s,s)); + m = Matrix::Random(a.rows(),diagSize) * d.asDiagonal() * Matrix::Random(diagSize,a.cols()); + // cancel some coeffs + Index n = internal::random(0,m.size()-1); + for(Index i=0; i(0,m.rows()-1), internal::random(0,m.cols()-1)) = Scalar(0); + } - jacobisvd_test_all_computation_options(m); - jacobisvd_test_all_computation_options(m); - jacobisvd_test_all_computation_options(m); - jacobisvd_test_all_computation_options(m); + CALL_SUBTEST(( jacobisvd_test_all_computation_options(m) )); + CALL_SUBTEST(( jacobisvd_test_all_computation_options(m) )); + CALL_SUBTEST(( jacobisvd_test_all_computation_options(m) )); + CALL_SUBTEST(( jacobisvd_test_all_computation_options(m) )); } template void jacobisvd_verify_assert(const MatrixType& m) @@ -223,16 +321,23 @@ void jacobisvd_inf_nan() VERIFY(sub(some_inf, some_inf) != sub(some_inf, some_inf)); svd.compute(MatrixType::Constant(10,10,some_inf), ComputeFullU | ComputeFullV); - Scalar some_nan = zero() / zero(); - VERIFY(some_nan != some_nan); - svd.compute(MatrixType::Constant(10,10,some_nan), ComputeFullU | ComputeFullV); + Scalar nan = std::numeric_limits::quiet_NaN(); + VERIFY(nan != nan); + svd.compute(MatrixType::Constant(10,10,nan), ComputeFullU | ComputeFullV); MatrixType m = MatrixType::Zero(10,10); m(internal::random(0,9), internal::random(0,9)) = some_inf; svd.compute(m, ComputeFullU | ComputeFullV); m = MatrixType::Zero(10,10); - m(internal::random(0,9), internal::random(0,9)) = some_nan; + m(internal::random(0,9), internal::random(0,9)) = nan; + svd.compute(m, ComputeFullU | ComputeFullV); + + // regression test for bug 791 + m.resize(3,3); + m << 0, 2*NumTraits::epsilon(), 0.5, + 0, -0.5, 0, + nan, 0, 0; svd.compute(m, ComputeFullU | ComputeFullV); } @@ -328,6 +433,7 @@ void test_jacobisvd() TEST_SET_BUT_UNUSED_VARIABLE(r) TEST_SET_BUT_UNUSED_VARIABLE(c) + CALL_SUBTEST_10(( jacobisvd(MatrixXd(r,c)) )); CALL_SUBTEST_7(( jacobisvd(MatrixXf(r,c)) )); CALL_SUBTEST_8(( jacobisvd(MatrixXcd(r,c)) )); (void) r; @@ -335,6 +441,7 @@ void test_jacobisvd() // Test on inf/nan matrix CALL_SUBTEST_7( jacobisvd_inf_nan() ); + CALL_SUBTEST_10( jacobisvd_inf_nan() ); } CALL_SUBTEST_7(( jacobisvd(MatrixXf(internal::random(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/2), internal::random(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/2))) )); diff --git a/ground/gcs/src/libs/eigen/test/lu.cpp b/ground/gcs/src/libs/eigen/test/lu.cpp index 25f86755a..374652694 100644 --- a/ground/gcs/src/libs/eigen/test/lu.cpp +++ b/ground/gcs/src/libs/eigen/test/lu.cpp @@ -100,7 +100,9 @@ template void lu_invertible() LU.h */ typedef typename NumTraits::Real RealScalar; - int size = internal::random(1,EIGEN_TEST_MAX_SIZE); + DenseIndex size = MatrixType::RowsAtCompileTime; + if( size==Dynamic) + size = internal::random(1,EIGEN_TEST_MAX_SIZE); MatrixType m1(size, size), m2(size, size), m3(size, size); FullPivLU lu; @@ -122,6 +124,10 @@ template void lu_invertible() m2 = lu.solve(m3); VERIFY_IS_APPROX(m3, m1*m2); VERIFY_IS_APPROX(m2, lu.inverse()*m3); + + // Regression test for Bug 302 + MatrixType m4 = MatrixType::Random(size,size); + VERIFY_IS_APPROX(lu.solve(m3*m4), lu.solve(m3)*m4); } template void lu_partial_piv() @@ -171,6 +177,7 @@ void test_lu() { for(int i = 0; i < g_repeat; i++) { CALL_SUBTEST_1( lu_non_invertible() ); + CALL_SUBTEST_1( lu_invertible() ); CALL_SUBTEST_1( lu_verify_assert() ); CALL_SUBTEST_2( (lu_non_invertible >()) ); diff --git a/ground/gcs/src/libs/eigen/test/main.h b/ground/gcs/src/libs/eigen/test/main.h index 14f0d2f78..664204866 100644 --- a/ground/gcs/src/libs/eigen/test/main.h +++ b/ground/gcs/src/libs/eigen/test/main.h @@ -17,13 +17,36 @@ #include #include #include + +// The following includes of STL headers have to be done _before_ the +// definition of macros min() and max(). The reason is that many STL +// implementations will not work properly as the min and max symbols collide +// with the STL functions std:min() and std::max(). The STL headers may check +// for the macro definition of min/max and issue a warning or undefine the +// macros. +// +// Still, Windows defines min() and max() in windef.h as part of the regular +// Windows system interfaces and many other Windows APIs depend on these +// macros being available. To prevent the macro expansion of min/max and to +// make Eigen compatible with the Windows environment all function calls of +// std::min() and std::max() have to be written with parenthesis around the +// function name. +// +// All STL headers used by Eigen should be included here. Because main.h is +// included before any Eigen header and because the STL headers are guarded +// against multiple inclusions, no STL header will see our own min/max macro +// definitions. #include #include -#include #include #include #include +#include +// To test that all calls from Eigen code to std::min() and std::max() are +// protected by parenthesis against macro expansion, the min()/max() macros +// are defined here and any not-parenthesized min/max call will cause a +// compiler error. #define min(A,B) please_protect_your_min_with_parentheses #define max(A,B) please_protect_your_max_with_parentheses @@ -383,6 +406,26 @@ void randomPermutationVector(PermutationVectorType& v, typename PermutationVecto } } +template bool isNotNaN(const T& x) +{ + return x==x; +} + +template bool isNaN(const T& x) +{ + return x!=x; +} + +template bool isInf(const T& x) +{ + return x > NumTraits::highest(); +} + +template bool isMinusInf(const T& x) +{ + return x < NumTraits::lowest(); +} + } // end namespace Eigen template struct GetDifferentType; diff --git a/ground/gcs/src/libs/eigen/test/mapped_matrix.cpp b/ground/gcs/src/libs/eigen/test/mapped_matrix.cpp index de9dbbde3..58904fa37 100644 --- a/ground/gcs/src/libs/eigen/test/mapped_matrix.cpp +++ b/ground/gcs/src/libs/eigen/test/mapped_matrix.cpp @@ -114,6 +114,28 @@ template void check_const_correctness(const PlainObjec VERIFY( !(Map::Flags & LvalueBit) ); } +template +void map_not_aligned_on_scalar() +{ + typedef Matrix MatrixType; + typedef typename MatrixType::Index Index; + Index size = 11; + Scalar* array1 = internal::aligned_new((size+1)*(size+1)+1); + Scalar* array2 = reinterpret_cast(sizeof(Scalar)/2+std::size_t(array1)); + Map > map2(array2, size, size, OuterStride<>(size+1)); + MatrixType m2 = MatrixType::Random(size,size); + map2 = m2; + VERIFY_IS_EQUAL(m2, map2); + + typedef Matrix VectorType; + Map map3(array2, size); + MatrixType v3 = VectorType::Random(size); + map3 = v3; + VERIFY_IS_EQUAL(v3, map3); + + internal::aligned_delete(array1, (size+1)*(size+1)+1); +} + void test_mapped_matrix() { for(int i = 0; i < g_repeat; i++) { @@ -137,5 +159,7 @@ void test_mapped_matrix() CALL_SUBTEST_8( map_static_methods(RowVector3d()) ); CALL_SUBTEST_9( map_static_methods(VectorXcd(8)) ); CALL_SUBTEST_10( map_static_methods(VectorXf(12)) ); + + CALL_SUBTEST_11( map_not_aligned_on_scalar() ); } } diff --git a/ground/gcs/src/libs/eigen/test/mpl2only.cpp b/ground/gcs/src/libs/eigen/test/mpl2only.cpp new file mode 100644 index 000000000..5ef0d2b2e --- /dev/null +++ b/ground/gcs/src/libs/eigen/test/mpl2only.cpp @@ -0,0 +1,20 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2015 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#define EIGEN_MPL2_ONLY +#include +#include +#include +#include +#include + +int main() +{ + return 0; +} diff --git a/ground/gcs/src/libs/eigen/test/nomalloc.cpp b/ground/gcs/src/libs/eigen/test/nomalloc.cpp index cbd02dd21..8e0402358 100644 --- a/ground/gcs/src/libs/eigen/test/nomalloc.cpp +++ b/ground/gcs/src/libs/eigen/test/nomalloc.cpp @@ -165,6 +165,38 @@ void ctms_decompositions() Eigen::JacobiSVD jSVD; jSVD.compute(A, ComputeFullU | ComputeFullV); } +void test_zerosized() { + // default constructors: + Eigen::MatrixXd A; + Eigen::VectorXd v; + // explicit zero-sized: + Eigen::ArrayXXd A0(0,0); + Eigen::ArrayXd v0(std::ptrdiff_t(0)); // FIXME ArrayXd(0) is ambiguous + + // assigning empty objects to each other: + A=A0; + v=v0; +} + +template void test_reference(const MatrixType& m) { + typedef typename MatrixType::Scalar Scalar; + enum { Flag = MatrixType::IsRowMajor ? Eigen::RowMajor : Eigen::ColMajor}; + enum { TransposeFlag = !MatrixType::IsRowMajor ? Eigen::RowMajor : Eigen::ColMajor}; + typename MatrixType::Index rows = m.rows(), cols=m.cols(); + // Dynamic reference: + typedef Eigen::Ref > Ref; + typedef Eigen::Ref > RefT; + + Ref r1(m); + Ref r2(m.block(rows/3, cols/4, rows/2, cols/2)); + RefT r3(m.transpose()); + RefT r4(m.topLeftCorner(rows/2, cols/2).transpose()); + + VERIFY_RAISES_ASSERT(RefT r5(m)); + VERIFY_RAISES_ASSERT(Ref r6(m.transpose())); + VERIFY_RAISES_ASSERT(Ref r7(Scalar(2) * m)); +} + void test_nomalloc() { // check that our operator new is indeed called: @@ -175,5 +207,6 @@ void test_nomalloc() // Check decomposition modules with dynamic matrices that have a known compile-time max size (ctms) CALL_SUBTEST_4(ctms_decompositions()); - + CALL_SUBTEST_5(test_zerosized()); + CALL_SUBTEST_6(test_reference(Matrix())); } diff --git a/ground/gcs/src/libs/eigen/test/nullary.cpp b/ground/gcs/src/libs/eigen/test/nullary.cpp index 5408d88b2..fbc721a1a 100644 --- a/ground/gcs/src/libs/eigen/test/nullary.cpp +++ b/ground/gcs/src/libs/eigen/test/nullary.cpp @@ -80,7 +80,9 @@ void testVectorType(const VectorType& base) Matrix col_vector(size); row_vector.setLinSpaced(size,low,high); col_vector.setLinSpaced(size,low,high); - VERIFY( row_vector.isApprox(col_vector.transpose(), NumTraits::epsilon())); + // when using the extended precision (e.g., FPU) the relative error might exceed 1 bit + // when computing the squared sum in isApprox, thus the 2x factor. + VERIFY( row_vector.isApprox(col_vector.transpose(), Scalar(2)*NumTraits::epsilon())); Matrix size_changer(size+50); size_changer.setLinSpaced(size,low,high); diff --git a/ground/gcs/src/libs/eigen/test/packetmath.cpp b/ground/gcs/src/libs/eigen/test/packetmath.cpp index 2c0519c41..38aa256ce 100644 --- a/ground/gcs/src/libs/eigen/test/packetmath.cpp +++ b/ground/gcs/src/libs/eigen/test/packetmath.cpp @@ -239,6 +239,12 @@ template void packetmath_real() data2[i] = internal::random(-87,88); } CHECK_CWISE1_IF(internal::packet_traits::HasExp, std::exp, internal::pexp); + { + data1[0] = std::numeric_limits::quiet_NaN(); + packet_helper::HasExp,Packet> h; + h.store(data2, internal::pexp(h.load(data1))); + VERIFY(isNaN(data2[0])); + } for (int i=0; i void packetmath_real() } if(internal::random(0,1)<0.1) data1[internal::random(0, PacketSize)] = 0; - CHECK_CWISE1_IF(internal::packet_traits::HasLog, std::log, internal::plog); CHECK_CWISE1_IF(internal::packet_traits::HasSqrt, std::sqrt, internal::psqrt); + CHECK_CWISE1_IF(internal::packet_traits::HasLog, std::log, internal::plog); + { + data1[0] = std::numeric_limits::quiet_NaN(); + packet_helper::HasLog,Packet> h; + h.store(data2, internal::plog(h.load(data1))); + VERIFY(isNaN(data2[0])); + data1[0] = -1.0f; + h.store(data2, internal::plog(h.load(data1))); + VERIFY(isNaN(data2[0])); +#if !EIGEN_FAST_MATH + h.store(data2, internal::psqrt(h.load(data1))); + VERIFY(isNaN(data2[0])); + VERIFY(isNaN(data2[1])); +#endif + } } template void packetmath_notcomplex() diff --git a/ground/gcs/src/libs/eigen/test/product.h b/ground/gcs/src/libs/eigen/test/product.h index 856b234ac..0d054ff46 100644 --- a/ground/gcs/src/libs/eigen/test/product.h +++ b/ground/gcs/src/libs/eigen/test/product.h @@ -136,7 +136,46 @@ template void product(const MatrixType& m) VERIFY_IS_APPROX(res.col(r).noalias() = square.adjoint() * square.col(r), (square.adjoint() * square.col(r)).eval()); VERIFY_IS_APPROX(res.col(r).noalias() = square * square.col(r), (square * square.col(r)).eval()); + // vector at runtime (see bug 1166) + { + RowSquareMatrixType ref(square); + ColSquareMatrixType ref2(square2); + ref = res = square; + VERIFY_IS_APPROX(res.block(0,0,1,rows).noalias() = m1.col(0).transpose() * square.transpose(), (ref.row(0) = m1.col(0).transpose() * square.transpose())); + VERIFY_IS_APPROX(res.block(0,0,1,rows).noalias() = m1.block(0,0,rows,1).transpose() * square.transpose(), (ref.row(0) = m1.col(0).transpose() * square.transpose())); + VERIFY_IS_APPROX(res.block(0,0,1,rows).noalias() = m1.col(0).transpose() * square, (ref.row(0) = m1.col(0).transpose() * square)); + VERIFY_IS_APPROX(res.block(0,0,1,rows).noalias() = m1.block(0,0,rows,1).transpose() * square, (ref.row(0) = m1.col(0).transpose() * square)); + ref2 = res2 = square2; + VERIFY_IS_APPROX(res2.block(0,0,1,cols).noalias() = m1.row(0) * square2.transpose(), (ref2.row(0) = m1.row(0) * square2.transpose())); + VERIFY_IS_APPROX(res2.block(0,0,1,cols).noalias() = m1.block(0,0,1,cols) * square2.transpose(), (ref2.row(0) = m1.row(0) * square2.transpose())); + VERIFY_IS_APPROX(res2.block(0,0,1,cols).noalias() = m1.row(0) * square2, (ref2.row(0) = m1.row(0) * square2)); + VERIFY_IS_APPROX(res2.block(0,0,1,cols).noalias() = m1.block(0,0,1,cols) * square2, (ref2.row(0) = m1.row(0) * square2)); + } + // inner product - Scalar x = square2.row(c) * square2.col(c2); - VERIFY_IS_APPROX(x, square2.row(c).transpose().cwiseProduct(square2.col(c2)).sum()); + { + Scalar x = square2.row(c) * square2.col(c2); + VERIFY_IS_APPROX(x, square2.row(c).transpose().cwiseProduct(square2.col(c2)).sum()); + } + + // outer product + VERIFY_IS_APPROX(m1.col(c) * m1.row(r), m1.block(0,c,rows,1) * m1.block(r,0,1,cols)); + VERIFY_IS_APPROX(m1.row(r).transpose() * m1.col(c).transpose(), m1.block(r,0,1,cols).transpose() * m1.block(0,c,rows,1).transpose()); + VERIFY_IS_APPROX(m1.block(0,c,rows,1) * m1.row(r), m1.block(0,c,rows,1) * m1.block(r,0,1,cols)); + VERIFY_IS_APPROX(m1.col(c) * m1.block(r,0,1,cols), m1.block(0,c,rows,1) * m1.block(r,0,1,cols)); + VERIFY_IS_APPROX(m1.leftCols(1) * m1.row(r), m1.block(0,0,rows,1) * m1.block(r,0,1,cols)); + VERIFY_IS_APPROX(m1.col(c) * m1.topRows(1), m1.block(0,c,rows,1) * m1.block(0,0,1,cols)); + + // Aliasing + { + ColVectorType x(cols); x.setRandom(); + ColVectorType z(x); + ColVectorType y(cols); y.setZero(); + ColSquareMatrixType A(cols,cols); A.setRandom(); + // CwiseBinaryOp + VERIFY_IS_APPROX(x = y + A*x, A*z); + x = z; + // CwiseUnaryOp + VERIFY_IS_APPROX(x = Scalar(1.)*(A*x), A*z); + } } diff --git a/ground/gcs/src/libs/eigen/test/product_extra.cpp b/ground/gcs/src/libs/eigen/test/product_extra.cpp index 744a1ef7f..ea2486937 100644 --- a/ground/gcs/src/libs/eigen/test/product_extra.cpp +++ b/ground/gcs/src/libs/eigen/test/product_extra.cpp @@ -109,8 +109,67 @@ void mat_mat_scalar_scalar_product() double det = 6.0, wt = 0.5; VERIFY_IS_APPROX(dNdxy.transpose()*dNdxy*det*wt, det*wt*dNdxy.transpose()*dNdxy); } + +template +void zero_sized_objects(const MatrixType& m) +{ + typedef typename MatrixType::Scalar Scalar; + const int PacketSize = internal::packet_traits::size; + const int PacketSize1 = PacketSize>1 ? PacketSize-1 : 1; + DenseIndex rows = m.rows(); + DenseIndex cols = m.cols(); -void zero_sized_objects() + { + MatrixType res, a(rows,0), b(0,cols); + VERIFY_IS_APPROX( (res=a*b), MatrixType::Zero(rows,cols) ); + VERIFY_IS_APPROX( (res=a*a.transpose()), MatrixType::Zero(rows,rows) ); + VERIFY_IS_APPROX( (res=b.transpose()*b), MatrixType::Zero(cols,cols) ); + VERIFY_IS_APPROX( (res=b.transpose()*a.transpose()), MatrixType::Zero(cols,rows) ); + } + + { + MatrixType res, a(rows,cols), b(cols,0); + res = a*b; + VERIFY(res.rows()==rows && res.cols()==0); + b.resize(0,rows); + res = b*a; + VERIFY(res.rows()==0 && res.cols()==cols); + } + + { + Matrix a; + Matrix b; + Matrix res; + VERIFY_IS_APPROX( (res=a*b), MatrixType::Zero(PacketSize,1) ); + VERIFY_IS_APPROX( (res=a.lazyProduct(b)), MatrixType::Zero(PacketSize,1) ); + } + + { + Matrix a; + Matrix b; + Matrix res; + VERIFY_IS_APPROX( (res=a*b), MatrixType::Zero(PacketSize1,1) ); + VERIFY_IS_APPROX( (res=a.lazyProduct(b)), MatrixType::Zero(PacketSize1,1) ); + } + + { + Matrix a(PacketSize,0); + Matrix b(0,1); + Matrix res; + VERIFY_IS_APPROX( (res=a*b), MatrixType::Zero(PacketSize,1) ); + VERIFY_IS_APPROX( (res=a.lazyProduct(b)), MatrixType::Zero(PacketSize,1) ); + } + + { + Matrix a(PacketSize1,0); + Matrix b(0,1); + Matrix res; + VERIFY_IS_APPROX( (res=a*b), MatrixType::Zero(PacketSize1,1) ); + VERIFY_IS_APPROX( (res=a.lazyProduct(b)), MatrixType::Zero(PacketSize1,1) ); + } +} + +void bug_127() { // Bug 127 // @@ -171,7 +230,8 @@ void test_product_extra() CALL_SUBTEST_2( mat_mat_scalar_scalar_product() ); CALL_SUBTEST_3( product_extra(MatrixXcf(internal::random(1,EIGEN_TEST_MAX_SIZE/2), internal::random(1,EIGEN_TEST_MAX_SIZE/2))) ); CALL_SUBTEST_4( product_extra(MatrixXcd(internal::random(1,EIGEN_TEST_MAX_SIZE/2), internal::random(1,EIGEN_TEST_MAX_SIZE/2))) ); + CALL_SUBTEST_1( zero_sized_objects(MatrixXf(internal::random(1,EIGEN_TEST_MAX_SIZE), internal::random(1,EIGEN_TEST_MAX_SIZE))) ); } - CALL_SUBTEST_5( zero_sized_objects() ); + CALL_SUBTEST_5( bug_127() ); CALL_SUBTEST_6( unaligned_objects() ); } diff --git a/ground/gcs/src/libs/eigen/test/product_large.cpp b/ground/gcs/src/libs/eigen/test/product_large.cpp index 03d7bd8ed..6bb4d1ad1 100644 --- a/ground/gcs/src/libs/eigen/test/product_large.cpp +++ b/ground/gcs/src/libs/eigen/test/product_large.cpp @@ -9,6 +9,27 @@ #include "product.h" +template +void test_aliasing() +{ + int rows = internal::random(1,12); + int cols = internal::random(1,12); + typedef Matrix MatrixType; + typedef Matrix VectorType; + VectorType x(cols); x.setRandom(); + VectorType z(x); + VectorType y(rows); y.setZero(); + MatrixType A(rows,cols); A.setRandom(); + // CwiseBinaryOp + VERIFY_IS_APPROX(x = y + A*x, A*z); + x = z; + // CwiseUnaryOp + VERIFY_IS_APPROX(x = T(1.)*(A*x), A*z); + x = z; + VERIFY_IS_APPROX(x = y+(-(A*x)), -A*z); + x = z; +} + void test_product_large() { for(int i = 0; i < g_repeat; i++) { @@ -17,6 +38,8 @@ void test_product_large() CALL_SUBTEST_3( product(MatrixXi(internal::random(1,EIGEN_TEST_MAX_SIZE), internal::random(1,EIGEN_TEST_MAX_SIZE))) ); CALL_SUBTEST_4( product(MatrixXcf(internal::random(1,EIGEN_TEST_MAX_SIZE/2), internal::random(1,EIGEN_TEST_MAX_SIZE/2))) ); CALL_SUBTEST_5( product(Matrix(internal::random(1,EIGEN_TEST_MAX_SIZE), internal::random(1,EIGEN_TEST_MAX_SIZE))) ); + + CALL_SUBTEST_1( test_aliasing() ); } #if defined EIGEN_TEST_PART_6 diff --git a/ground/gcs/src/libs/eigen/test/product_mmtr.cpp b/ground/gcs/src/libs/eigen/test/product_mmtr.cpp index 7d6746800..aeba009f4 100644 --- a/ground/gcs/src/libs/eigen/test/product_mmtr.cpp +++ b/ground/gcs/src/libs/eigen/test/product_mmtr.cpp @@ -24,8 +24,8 @@ template void mmtr(int size) DenseIndex othersize = internal::random(1,200); - MatrixColMaj matc(size, size); - MatrixRowMaj matr(size, size); + MatrixColMaj matc = MatrixColMaj::Zero(size, size); + MatrixRowMaj matr = MatrixRowMaj::Zero(size, size); MatrixColMaj ref1(size, size), ref2(size, size); MatrixColMaj soc(size,othersize); soc.setRandom(); diff --git a/ground/gcs/src/libs/eigen/test/product_notemporary.cpp b/ground/gcs/src/libs/eigen/test/product_notemporary.cpp index 258d238e2..5599d268d 100644 --- a/ground/gcs/src/libs/eigen/test/product_notemporary.cpp +++ b/ground/gcs/src/libs/eigen/test/product_notemporary.cpp @@ -58,10 +58,19 @@ template void product_notemporary(const MatrixType& m) r1 = internal::random(8,rows-r0); VERIFY_EVALUATION_COUNT( m3 = (m1 * m2.adjoint()), 1); + VERIFY_EVALUATION_COUNT( m3 = (m1 * m2.adjoint()).transpose(), 1); VERIFY_EVALUATION_COUNT( m3.noalias() = m1 * m2.adjoint(), 0); + VERIFY_EVALUATION_COUNT( m3 = s1 * (m1 * m2.transpose()), 1); + VERIFY_EVALUATION_COUNT( m3 = m3 + s1 * (m1 * m2.transpose()), 1); VERIFY_EVALUATION_COUNT( m3.noalias() = s1 * (m1 * m2.transpose()), 0); + VERIFY_EVALUATION_COUNT( m3 = m3 + (m1 * m2.adjoint()), 1); + VERIFY_EVALUATION_COUNT( m3 = m3 + (m1 * m2.adjoint()).transpose(), 1); + VERIFY_EVALUATION_COUNT( m3.noalias() = m3 + m1 * m2.transpose(), 1); // 0 in 3.3 + VERIFY_EVALUATION_COUNT( m3.noalias() += m3 + m1 * m2.transpose(), 1); // 0 in 3.3 + VERIFY_EVALUATION_COUNT( m3.noalias() -= m3 + m1 * m2.transpose(), 1); // 0 in 3.3 + VERIFY_EVALUATION_COUNT( m3.noalias() = s1 * m1 * s2 * m2.adjoint(), 0); VERIFY_EVALUATION_COUNT( m3.noalias() = s1 * m1 * s2 * (m1*s3+m2*s2).adjoint(), 1); VERIFY_EVALUATION_COUNT( m3.noalias() = (s1 * m1).adjoint() * s2 * m2, 0); diff --git a/ground/gcs/src/libs/eigen/test/product_trmm.cpp b/ground/gcs/src/libs/eigen/test/product_trmm.cpp index 506a1aeb9..d715b9a36 100644 --- a/ground/gcs/src/libs/eigen/test/product_trmm.cpp +++ b/ground/gcs/src/libs/eigen/test/product_trmm.cpp @@ -51,6 +51,7 @@ void trmm(int rows=internal::random(1,EIGEN_TEST_MAX_SIZE), ge_xs_save = ge_xs; VERIFY_IS_APPROX( (ge_xs_save + s1*triTr.conjugate() * (s2*ge_left.adjoint())).eval(), ge_xs.noalias() += (s1*mat.adjoint()).template triangularView() * (s2*ge_left.adjoint()) ); + ge_sx.setRandom(); ge_sx_save = ge_sx; VERIFY_IS_APPROX( ge_sx_save - (ge_right.adjoint() * (-s1 * triTr).conjugate()).eval(), ge_sx.noalias() -= (ge_right.adjoint() * (-s1 * mat).adjoint().template triangularView()).eval()); diff --git a/ground/gcs/src/libs/eigen/test/qr_fullpivoting.cpp b/ground/gcs/src/libs/eigen/test/qr_fullpivoting.cpp index 15d7299d7..511f2473f 100644 --- a/ground/gcs/src/libs/eigen/test/qr_fullpivoting.cpp +++ b/ground/gcs/src/libs/eigen/test/qr_fullpivoting.cpp @@ -130,4 +130,8 @@ void test_qr_fullpivoting() // Test problem size constructors CALL_SUBTEST_7(FullPivHouseholderQR(10, 20)); + CALL_SUBTEST_7((FullPivHouseholderQR >(10,20))); + CALL_SUBTEST_7((FullPivHouseholderQR >(Matrix::Random()))); + CALL_SUBTEST_7((FullPivHouseholderQR >(20,10))); + CALL_SUBTEST_7((FullPivHouseholderQR >(Matrix::Random()))); } diff --git a/ground/gcs/src/libs/eigen/test/real_qz.cpp b/ground/gcs/src/libs/eigen/test/real_qz.cpp index 7d743a734..a1766c6d9 100644 --- a/ground/gcs/src/libs/eigen/test/real_qz.cpp +++ b/ground/gcs/src/libs/eigen/test/real_qz.cpp @@ -25,6 +25,22 @@ template void real_qz(const MatrixType& m) MatrixType A = MatrixType::Random(dim,dim), B = MatrixType::Random(dim,dim); + + // Regression test for bug 985: Randomly set rows or columns to zero + Index k=internal::random(0, dim-1); + switch(internal::random(0,10)) { + case 0: + A.row(k).setZero(); break; + case 1: + A.col(k).setZero(); break; + case 2: + B.row(k).setZero(); break; + case 3: + B.col(k).setZero(); break; + default: + break; + } + RealQZ qz(A,B); VERIFY_IS_EQUAL(qz.info(), Success); diff --git a/ground/gcs/src/libs/eigen/test/redux.cpp b/ground/gcs/src/libs/eigen/test/redux.cpp index 0d176e500..50b473838 100644 --- a/ground/gcs/src/libs/eigen/test/redux.cpp +++ b/ground/gcs/src/libs/eigen/test/redux.cpp @@ -53,6 +53,14 @@ template void matrixRedux(const MatrixType& m) VERIFY_IS_APPROX(m1_for_prod.block(r0,c0,r1,c1).prod(), m1_for_prod.block(r0,c0,r1,c1).eval().prod()); VERIFY_IS_APPROX(m1.block(r0,c0,r1,c1).real().minCoeff(), m1.block(r0,c0,r1,c1).real().eval().minCoeff()); VERIFY_IS_APPROX(m1.block(r0,c0,r1,c1).real().maxCoeff(), m1.block(r0,c0,r1,c1).real().eval().maxCoeff()); + + // regression for bug 1090 + const int R1 = MatrixType::RowsAtCompileTime>=2 ? MatrixType::RowsAtCompileTime/2 : 6; + const int C1 = MatrixType::ColsAtCompileTime>=2 ? MatrixType::ColsAtCompileTime/2 : 6; + if(R1<=rows-r0 && C1<=cols-c0) + { + VERIFY_IS_APPROX( (m1.template block(r0,c0).sum()), m1.block(r0,c0,R1,C1).sum() ); + } // test empty objects VERIFY_IS_APPROX(m1.block(r0,c0,0,0).sum(), Scalar(0)); diff --git a/ground/gcs/src/libs/eigen/test/ref.cpp b/ground/gcs/src/libs/eigen/test/ref.cpp index 65b4f5a3e..8297e263a 100644 --- a/ground/gcs/src/libs/eigen/test/ref.cpp +++ b/ground/gcs/src/libs/eigen/test/ref.cpp @@ -14,9 +14,9 @@ static int nb_temporaries; -inline void on_temporary_creation(int size) { +inline void on_temporary_creation(int) { // here's a great place to set a breakpoint when debugging failures in this test! - if(size!=0) nb_temporaries++; + nb_temporaries++; } @@ -34,6 +34,18 @@ inline void on_temporary_creation(int size) { // test Ref.h +// Deal with i387 extended precision +#if EIGEN_ARCH_i386 && !(EIGEN_ARCH_x86_64) + +#if EIGEN_COMP_GNUC_STRICT && EIGEN_GNUC_AT_LEAST(4,4) +#pragma GCC optimize ("-ffloat-store") +#else +#undef VERIFY_IS_EQUAL +#define VERIFY_IS_EQUAL(X,Y) VERIFY_IS_APPROX(X,Y) +#endif + +#endif + template void ref_matrix(const MatrixType& m) { typedef typename MatrixType::Index Index; @@ -71,7 +83,6 @@ template void ref_matrix(const MatrixType& m) rm2 = m2.block(i,j,brows,bcols); VERIFY_IS_EQUAL(m1, m2); - ConstRefDynMat rm3 = m1.block(i,j,brows,bcols); m1.block(i,j,brows,bcols) *= 2; m2.block(i,j,brows,bcols) *= 2; @@ -154,59 +165,101 @@ template void check_const_correctness(const PlainObjec VERIFY( !(Ref::Flags & LvalueBit) ); } -EIGEN_DONT_INLINE void call_ref_1(Ref ) { } -EIGEN_DONT_INLINE void call_ref_2(const Ref& ) { } -EIGEN_DONT_INLINE void call_ref_3(Ref > ) { } -EIGEN_DONT_INLINE void call_ref_4(const Ref >& ) { } -EIGEN_DONT_INLINE void call_ref_5(Ref > ) { } -EIGEN_DONT_INLINE void call_ref_6(const Ref >& ) { } +template +EIGEN_DONT_INLINE void call_ref_1(Ref a, const B &b) { VERIFY_IS_EQUAL(a,b); } +template +EIGEN_DONT_INLINE void call_ref_2(const Ref& a, const B &b) { VERIFY_IS_EQUAL(a,b); } +template +EIGEN_DONT_INLINE void call_ref_3(Ref > a, const B &b) { VERIFY_IS_EQUAL(a,b); } +template +EIGEN_DONT_INLINE void call_ref_4(const Ref >& a, const B &b) { VERIFY_IS_EQUAL(a,b); } +template +EIGEN_DONT_INLINE void call_ref_5(Ref > a, const B &b) { VERIFY_IS_EQUAL(a,b); } +template +EIGEN_DONT_INLINE void call_ref_6(const Ref >& a, const B &b) { VERIFY_IS_EQUAL(a,b); } +template +EIGEN_DONT_INLINE void call_ref_7(Ref > a, const B &b) { VERIFY_IS_EQUAL(a,b); } void call_ref() { - VectorXcf ca(10); - VectorXf a(10); + VectorXcf ca = VectorXcf::Random(10); + VectorXf a = VectorXf::Random(10); + RowVectorXf b = RowVectorXf::Random(10); + MatrixXf A = MatrixXf::Random(10,10); + RowVector3f c = RowVector3f::Random(); const VectorXf& ac(a); VectorBlock ab(a,0,3); - MatrixXf A(10,10); const VectorBlock abc(a,0,3); + - VERIFY_EVALUATION_COUNT( call_ref_1(a), 0); - //call_ref_1(ac); // does not compile because ac is const - VERIFY_EVALUATION_COUNT( call_ref_1(ab), 0); - VERIFY_EVALUATION_COUNT( call_ref_1(a.head(4)), 0); - VERIFY_EVALUATION_COUNT( call_ref_1(abc), 0); - VERIFY_EVALUATION_COUNT( call_ref_1(A.col(3)), 0); - // call_ref_1(A.row(3)); // does not compile because innerstride!=1 - VERIFY_EVALUATION_COUNT( call_ref_3(A.row(3)), 0); - VERIFY_EVALUATION_COUNT( call_ref_4(A.row(3)), 0); - //call_ref_1(a+a); // does not compile for obvious reason + VERIFY_EVALUATION_COUNT( call_ref_1(a,a), 0); + VERIFY_EVALUATION_COUNT( call_ref_1(b,b.transpose()), 0); +// call_ref_1(ac,a RowMatrixXd; +int test_ref_overload_fun1(Ref ) { return 1; } +int test_ref_overload_fun1(Ref ) { return 2; } +int test_ref_overload_fun1(Ref ) { return 3; } + +int test_ref_overload_fun2(Ref ) { return 4; } +int test_ref_overload_fun2(Ref ) { return 5; } + +// See also bug 969 +void test_ref_overloads() +{ + MatrixXd Ad, Bd; + RowMatrixXd rAd, rBd; + VERIFY( test_ref_overload_fun1(Ad)==1 ); + VERIFY( test_ref_overload_fun1(rAd)==2 ); + + MatrixXf Af, Bf; + VERIFY( test_ref_overload_fun2(Ad)==4 ); + VERIFY( test_ref_overload_fun2(Ad+Bd)==4 ); + VERIFY( test_ref_overload_fun2(Af+Bf)==5 ); } void test_ref() @@ -229,4 +282,6 @@ void test_ref() CALL_SUBTEST_5( ref_matrix(MatrixXi(internal::random(1,10),internal::random(1,10))) ); CALL_SUBTEST_6( call_ref() ); } + + CALL_SUBTEST_7( test_ref_overloads() ); } diff --git a/ground/gcs/src/libs/eigen/test/rvalue_types.cpp b/ground/gcs/src/libs/eigen/test/rvalue_types.cpp new file mode 100644 index 000000000..b3c85652c --- /dev/null +++ b/ground/gcs/src/libs/eigen/test/rvalue_types.cpp @@ -0,0 +1,62 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2013 Hauke Heibel +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "main.h" + +#include + +#ifdef EIGEN_HAVE_RVALUE_REFERENCES +template +void rvalue_copyassign(const MatrixType& m) +{ + + typedef typename internal::traits::Scalar Scalar; + + // create a temporary which we are about to destroy by moving + MatrixType tmp = m; + long src_address = reinterpret_cast(tmp.data()); + + // move the temporary to n + MatrixType n = std::move(tmp); + long dst_address = reinterpret_cast(n.data()); + + if (MatrixType::RowsAtCompileTime==Dynamic|| MatrixType::ColsAtCompileTime==Dynamic) + { + // verify that we actually moved the guts + VERIFY_IS_EQUAL(src_address, dst_address); + } + + // verify that the content did not change + Scalar abs_diff = (m-n).array().abs().sum(); + VERIFY_IS_EQUAL(abs_diff, Scalar(0)); +} +#else +template +void rvalue_copyassign(const MatrixType&) {} +#endif + +void test_rvalue_types() +{ + CALL_SUBTEST_1(rvalue_copyassign( MatrixXf::Random(50,50).eval() )); + CALL_SUBTEST_1(rvalue_copyassign( ArrayXXf::Random(50,50).eval() )); + + CALL_SUBTEST_1(rvalue_copyassign( Matrix::Random(50).eval() )); + CALL_SUBTEST_1(rvalue_copyassign( Array::Random(50).eval() )); + + CALL_SUBTEST_1(rvalue_copyassign( Matrix::Random(50).eval() )); + CALL_SUBTEST_1(rvalue_copyassign( Array::Random(50).eval() )); + + CALL_SUBTEST_2(rvalue_copyassign( Array::Random().eval() )); + CALL_SUBTEST_2(rvalue_copyassign( Array::Random().eval() )); + CALL_SUBTEST_2(rvalue_copyassign( Array::Random().eval() )); + + CALL_SUBTEST_2(rvalue_copyassign( Array::Random().eval() )); + CALL_SUBTEST_2(rvalue_copyassign( Array::Random().eval() )); + CALL_SUBTEST_2(rvalue_copyassign( Array::Random().eval() )); +} diff --git a/ground/gcs/src/libs/eigen/test/simplicial_cholesky.cpp b/ground/gcs/src/libs/eigen/test/simplicial_cholesky.cpp index e93a52e9c..786468421 100644 --- a/ground/gcs/src/libs/eigen/test/simplicial_cholesky.cpp +++ b/ground/gcs/src/libs/eigen/test/simplicial_cholesky.cpp @@ -11,26 +11,31 @@ template void test_simplicial_cholesky_T() { - SimplicialCholesky, Lower> chol_colmajor_lower; - SimplicialCholesky, Upper> chol_colmajor_upper; - SimplicialLLT, Lower> llt_colmajor_lower; - SimplicialLDLT, Upper> llt_colmajor_upper; - SimplicialLDLT, Lower> ldlt_colmajor_lower; - SimplicialLDLT, Upper> ldlt_colmajor_upper; + SimplicialCholesky, Lower> chol_colmajor_lower_amd; + SimplicialCholesky, Upper> chol_colmajor_upper_amd; + SimplicialLLT, Lower> llt_colmajor_lower_amd; + SimplicialLLT, Upper> llt_colmajor_upper_amd; + SimplicialLDLT, Lower> ldlt_colmajor_lower_amd; + SimplicialLDLT, Upper> ldlt_colmajor_upper_amd; + SimplicialLDLT, Lower, NaturalOrdering > ldlt_colmajor_lower_nat; + SimplicialLDLT, Upper, NaturalOrdering > ldlt_colmajor_upper_nat; - check_sparse_spd_solving(chol_colmajor_lower); - check_sparse_spd_solving(chol_colmajor_upper); - check_sparse_spd_solving(llt_colmajor_lower); - check_sparse_spd_solving(llt_colmajor_upper); - check_sparse_spd_solving(ldlt_colmajor_lower); - check_sparse_spd_solving(ldlt_colmajor_upper); + check_sparse_spd_solving(chol_colmajor_lower_amd); + check_sparse_spd_solving(chol_colmajor_upper_amd); + check_sparse_spd_solving(llt_colmajor_lower_amd); + check_sparse_spd_solving(llt_colmajor_upper_amd); + check_sparse_spd_solving(ldlt_colmajor_lower_amd); + check_sparse_spd_solving(ldlt_colmajor_upper_amd); - check_sparse_spd_determinant(chol_colmajor_lower); - check_sparse_spd_determinant(chol_colmajor_upper); - check_sparse_spd_determinant(llt_colmajor_lower); - check_sparse_spd_determinant(llt_colmajor_upper); - check_sparse_spd_determinant(ldlt_colmajor_lower); - check_sparse_spd_determinant(ldlt_colmajor_upper); + check_sparse_spd_determinant(chol_colmajor_lower_amd); + check_sparse_spd_determinant(chol_colmajor_upper_amd); + check_sparse_spd_determinant(llt_colmajor_lower_amd); + check_sparse_spd_determinant(llt_colmajor_upper_amd); + check_sparse_spd_determinant(ldlt_colmajor_lower_amd); + check_sparse_spd_determinant(ldlt_colmajor_upper_amd); + + check_sparse_spd_solving(ldlt_colmajor_lower_nat); + check_sparse_spd_solving(ldlt_colmajor_upper_nat); } void test_simplicial_cholesky() diff --git a/ground/gcs/src/libs/eigen/test/sparse.h b/ground/gcs/src/libs/eigen/test/sparse.h index a09c65e5f..e19a76316 100644 --- a/ground/gcs/src/libs/eigen/test/sparse.h +++ b/ground/gcs/src/libs/eigen/test/sparse.h @@ -154,16 +154,16 @@ initSparse(double density, sparseMat.finalize(); } -template void +template void initSparse(double density, Matrix& refVec, - SparseVector& sparseVec, + SparseVector& sparseVec, std::vector* zeroCoords = 0, std::vector* nonzeroCoords = 0) { sparseVec.reserve(int(refVec.size()*density)); sparseVec.setZero(); - for(int i=0; i(0,1) < density) ? internal::random() : Scalar(0); if (v!=Scalar(0)) @@ -178,10 +178,10 @@ initSparse(double density, } } -template void +template void initSparse(double density, Matrix& refVec, - SparseVector& sparseVec, + SparseVector& sparseVec, std::vector* zeroCoords = 0, std::vector* nonzeroCoords = 0) { diff --git a/ground/gcs/src/libs/eigen/test/sparse_basic.cpp b/ground/gcs/src/libs/eigen/test/sparse_basic.cpp index 498ecfe29..abe6a9d14 100644 --- a/ground/gcs/src/libs/eigen/test/sparse_basic.cpp +++ b/ground/gcs/src/libs/eigen/test/sparse_basic.cpp @@ -24,6 +24,7 @@ template void sparse_basic(const SparseMatrixType& re double density = (std::max)(8./(rows*cols), 0.01); typedef Matrix DenseMatrix; typedef Matrix DenseVector; + typedef Matrix RowDenseVector; Scalar eps = 1e-6; Scalar s1 = internal::random(); @@ -52,7 +53,7 @@ template void sparse_basic(const SparseMatrixType& re refMat.coeffRef(nonzeroCoords[0].x(), nonzeroCoords[0].y()) = Scalar(5); VERIFY_IS_APPROX(m, refMat); - /* + // test InnerIterators and Block expressions for (int t=0; t<10; ++t) { @@ -61,23 +62,54 @@ template void sparse_basic(const SparseMatrixType& re int w = internal::random(1,cols-j-1); int h = internal::random(1,rows-i-1); - // VERIFY_IS_APPROX(m.block(i,j,h,w), refMat.block(i,j,h,w)); + VERIFY_IS_APPROX(m.block(i,j,h,w), refMat.block(i,j,h,w)); for(int c=0; c void sparse_basic(const SparseMatrixType& re VERIFY_IS_APPROX(m.row(r) + m.row(r), (m + m).row(r)); VERIFY_IS_APPROX(m.row(r) + m.row(r), refMat.row(r) + refMat.row(r)); } - */ + // test assertion VERIFY_RAISES_ASSERT( m.coeffRef(-1,1) = 0 ); @@ -274,6 +306,8 @@ template void sparse_basic(const SparseMatrixType& re refM4.setRandom(); // sparse cwise* dense VERIFY_IS_APPROX(m3.cwiseProduct(refM4), refM3.cwiseProduct(refM4)); + // dense cwise* sparse + VERIFY_IS_APPROX(refM4.cwiseProduct(m3), refM4.cwiseProduct(refM3)); // VERIFY_IS_APPROX(m3.cwise()/refM4, refM3.cwise()/refM4); // test aliasing @@ -326,6 +360,15 @@ template void sparse_basic(const SparseMatrixType& re refMat2.col(i) = refMat2.col(i) * s1; VERIFY_IS_APPROX(m2,refMat2); } + + VERIFY_IS_APPROX(DenseVector(m2.col(j0)), refMat2.col(j0)); + VERIFY_IS_APPROX(m2.col(j0), refMat2.col(j0)); + + VERIFY_IS_APPROX(RowDenseVector(m2.row(j0)), refMat2.row(j0)); + VERIFY_IS_APPROX(m2.row(j0), refMat2.row(j0)); + + VERIFY_IS_APPROX(m2.block(j0,j1,n0,n0), refMat2.block(j0,j1,n0,n0)); + VERIFY_IS_APPROX((2*m2).block(j0,j1,n0,n0), (2*refMat2).block(j0,j1,n0,n0)); } // test prune @@ -488,6 +531,20 @@ template void sparse_basic(const SparseMatrixType& re SparseMatrixType m1(rows, rows); m1.setIdentity(); VERIFY_IS_APPROX(m1, refMat1); + for(int k=0; k(0,rows-1); + Index j = internal::random(0,rows-1); + Scalar v = internal::random(); + m1.coeffRef(i,j) = v; + refMat1.coeffRef(i,j) = v; + VERIFY_IS_APPROX(m1, refMat1); + if(internal::random(0,10)<2) + m1.makeCompressed(); + } + m1.setIdentity(); + refMat1.setIdentity(); + VERIFY_IS_APPROX(m1, refMat1); } } diff --git a/ground/gcs/src/libs/eigen/test/sparse_product.cpp b/ground/gcs/src/libs/eigen/test/sparse_product.cpp index 664e33887..a2ea9d5b7 100644 --- a/ground/gcs/src/libs/eigen/test/sparse_product.cpp +++ b/ground/gcs/src/libs/eigen/test/sparse_product.cpp @@ -13,8 +13,9 @@ template struct test_outer { static void run(SparseMatrixType& m2, SparseMatrixType& m4, DenseMatrix& refMat2, DenseMatrix& refMat4) { - int c = internal::random(0,m2.cols()-1); - int c1 = internal::random(0,m2.cols()-1); + typedef typename SparseMatrixType::Index Index; + Index c = internal::random(0,m2.cols()-1); + Index c1 = internal::random(0,m2.cols()-1); VERIFY_IS_APPROX(m4=m2.col(c)*refMat2.col(c1).transpose(), refMat4=refMat2.col(c)*refMat2.col(c1).transpose()); VERIFY_IS_APPROX(m4=refMat2.col(c1)*m2.col(c).transpose(), refMat4=refMat2.col(c1)*refMat2.col(c).transpose()); } @@ -22,8 +23,9 @@ template struct test_outer struct test_outer { static void run(SparseMatrixType& m2, SparseMatrixType& m4, DenseMatrix& refMat2, DenseMatrix& refMat4) { - int r = internal::random(0,m2.rows()-1); - int c1 = internal::random(0,m2.cols()-1); + typedef typename SparseMatrixType::Index Index; + Index r = internal::random(0,m2.rows()-1); + Index c1 = internal::random(0,m2.cols()-1); VERIFY_IS_APPROX(m4=m2.row(r).transpose()*refMat2.col(c1).transpose(), refMat4=refMat2.row(r).transpose()*refMat2.col(c1).transpose()); VERIFY_IS_APPROX(m4=refMat2.col(c1)*m2.row(r), refMat4=refMat2.col(c1)*refMat2.row(r)); } @@ -37,9 +39,9 @@ template void sparse_product() { typedef typename SparseMatrixType::Index Index; Index n = 100; - const Index rows = internal::random(1,n); - const Index cols = internal::random(1,n); - const Index depth = internal::random(1,n); + const Index rows = internal::random(1,n); + const Index cols = internal::random(1,n); + const Index depth = internal::random(1,n); typedef typename SparseMatrixType::Scalar Scalar; enum { Flags = SparseMatrixType::Flags }; @@ -244,6 +246,7 @@ void test_sparse_product() CALL_SUBTEST_1( (sparse_product >()) ); CALL_SUBTEST_2( (sparse_product, ColMajor > >()) ); CALL_SUBTEST_2( (sparse_product, RowMajor > >()) ); + CALL_SUBTEST_3( (sparse_product >()) ); CALL_SUBTEST_4( (sparse_product_regression_test, Matrix >()) ); } } diff --git a/ground/gcs/src/libs/eigen/test/sparse_solver.h b/ground/gcs/src/libs/eigen/test/sparse_solver.h index d84aff070..e1619d62a 100644 --- a/ground/gcs/src/libs/eigen/test/sparse_solver.h +++ b/ground/gcs/src/libs/eigen/test/sparse_solver.h @@ -67,6 +67,22 @@ void check_sparse_solving(Solver& solver, const typename Solver::MatrixType& A, VERIFY(oldb.isApprox(db) && "sparse solver testing: the rhs should not be modified!"); VERIFY(x.isApprox(refX,test_precision())); } + + // if not too large, do some extra check: + if(A.rows()<2000) + { + + // test expression as input + { + solver.compute(0.5*(A+A)); + Rhs x = solver.solve(b); + VERIFY(x.isApprox(refX,test_precision())); + + Solver solver2(0.5*(A+A)); + Rhs x2 = solver2.solve(b); + VERIFY(x2.isApprox(refX,test_precision())); + } + } } template @@ -124,7 +140,23 @@ void check_sparse_determinant(Solver& solver, const typename Solver::MatrixType& Scalar refDet = dA.determinant(); VERIFY_IS_APPROX(refDet,solver.determinant()); } +template +void check_sparse_abs_determinant(Solver& solver, const typename Solver::MatrixType& A, const DenseMat& dA) +{ + using std::abs; + typedef typename Solver::MatrixType Mat; + typedef typename Mat::Scalar Scalar; + + solver.compute(A); + if (solver.info() != Success) + { + std::cerr << "sparse solver testing: factorization failed (check_sparse_abs_determinant)\n"; + return; + } + Scalar refDet = abs(dA.determinant()); + VERIFY_IS_APPROX(refDet,solver.absDeterminant()); +} template int generate_sparse_spd_problem(Solver& , typename Solver::MatrixType& A, typename Solver::MatrixType& halfA, DenseMat& dA, int maxSize = 300) @@ -145,7 +177,10 @@ int generate_sparse_spd_problem(Solver& , typename Solver::MatrixType& A, typena dA = dM * dM.adjoint(); halfA.resize(size,size); - halfA.template selfadjointView().rankUpdate(M); + if(Solver::UpLo==(Lower|Upper)) + halfA = A; + else + halfA.template selfadjointView().rankUpdate(M); return size; } @@ -258,7 +293,17 @@ int generate_sparse_square_problem(Solver&, typename Solver::MatrixType& A, Dens return size; } -template void check_sparse_square_solving(Solver& solver) + +struct prune_column { + int m_col; + prune_column(int col) : m_col(col) {} + template + bool operator()(int, int col, const Scalar&) const { + return col != m_col; + } +}; + +template void check_sparse_square_solving(Solver& solver, bool checkDeficient = false) { typedef typename Solver::MatrixType Mat; typedef typename Mat::Scalar Scalar; @@ -290,6 +335,13 @@ template void check_sparse_square_solving(Solver& solver) b = DenseVector::Zero(size); check_sparse_solving(solver, A, b, dA, b); } + // regression test for Bug 792 (structurally rank deficient matrices): + if(checkDeficient && size>1) { + int col = internal::random(0,size-1); + A.prune(prune_column(col)); + solver.compute(A); + VERIFY_IS_EQUAL(solver.info(), NumericalIssue); + } } // First, get the folder @@ -324,3 +376,20 @@ template void check_sparse_square_determinant(Solver& solver) check_sparse_determinant(solver, A, dA); } } + +template void check_sparse_square_abs_determinant(Solver& solver) +{ + typedef typename Solver::MatrixType Mat; + typedef typename Mat::Scalar Scalar; + typedef Matrix DenseMatrix; + + // generate the problem + Mat A; + DenseMatrix dA; + generate_sparse_square_problem(solver, A, dA, 30); + A.makeCompressed(); + for (int i = 0; i < g_repeat; i++) { + check_sparse_abs_determinant(solver, A, dA); + } +} + diff --git a/ground/gcs/src/libs/eigen/test/sparse_vector.cpp b/ground/gcs/src/libs/eigen/test/sparse_vector.cpp index ec5877b6a..0c9476803 100644 --- a/ground/gcs/src/libs/eigen/test/sparse_vector.cpp +++ b/ground/gcs/src/libs/eigen/test/sparse_vector.cpp @@ -9,14 +9,14 @@ #include "sparse.h" -template void sparse_vector(int rows, int cols) +template void sparse_vector(int rows, int cols) { double densityMat = (std::max)(8./(rows*cols), 0.01); double densityVec = (std::max)(8./float(rows), 0.1); typedef Matrix DenseMatrix; typedef Matrix DenseVector; - typedef SparseVector SparseVectorType; - typedef SparseMatrix SparseMatrixType; + typedef SparseVector SparseVectorType; + typedef SparseMatrix SparseMatrixType; Scalar eps = 1e-6; SparseMatrixType m1(rows,rows); @@ -101,9 +101,10 @@ template void sparse_vector(int rows, int cols) void test_sparse_vector() { for(int i = 0; i < g_repeat; i++) { - CALL_SUBTEST_1( sparse_vector(8, 8) ); - CALL_SUBTEST_2( sparse_vector >(16, 16) ); - CALL_SUBTEST_1( sparse_vector(299, 535) ); + CALL_SUBTEST_1(( sparse_vector(8, 8) )); + CALL_SUBTEST_2(( sparse_vector, int>(16, 16) )); + CALL_SUBTEST_1(( sparse_vector(299, 535) )); + CALL_SUBTEST_1(( sparse_vector(299, 535) )); } } diff --git a/ground/gcs/src/libs/eigen/test/sparselu.cpp b/ground/gcs/src/libs/eigen/test/sparselu.cpp index 37980defc..b3d67aea8 100644 --- a/ground/gcs/src/libs/eigen/test/sparselu.cpp +++ b/ground/gcs/src/libs/eigen/test/sparselu.cpp @@ -41,9 +41,15 @@ template void test_sparselu_T() SparseLU, AMDOrdering > sparselu_amd; SparseLU, NaturalOrdering > sparselu_natural; - check_sparse_square_solving(sparselu_colamd); - check_sparse_square_solving(sparselu_amd); - check_sparse_square_solving(sparselu_natural); + check_sparse_square_solving(sparselu_colamd, true); + check_sparse_square_solving(sparselu_amd, true); + check_sparse_square_solving(sparselu_natural,true); + + check_sparse_square_abs_determinant(sparselu_colamd); + check_sparse_square_abs_determinant(sparselu_amd); + + check_sparse_square_determinant(sparselu_colamd); + check_sparse_square_determinant(sparselu_amd); } void test_sparselu() diff --git a/ground/gcs/src/libs/eigen/test/sparseqr.cpp b/ground/gcs/src/libs/eigen/test/sparseqr.cpp index 6edba30b2..451c0e7f8 100644 --- a/ground/gcs/src/libs/eigen/test/sparseqr.cpp +++ b/ground/gcs/src/libs/eigen/test/sparseqr.cpp @@ -2,24 +2,23 @@ // for linear algebra. // // Copyright (C) 2012 Desire Nuentsa Wakam +// Copyright (C) 2014 Gael Guennebaud // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed #include "sparse.h" #include - template -int generate_sparse_rectangular_problem(MatrixType& A, DenseMat& dA, int maxRows = 300, int maxCols = 300) +int generate_sparse_rectangular_problem(MatrixType& A, DenseMat& dA, int maxRows = 300) { - eigen_assert(maxRows >= maxCols); typedef typename MatrixType::Scalar Scalar; int rows = internal::random(1,maxRows); int cols = internal::random(1,rows); double density = (std::max)(8./(rows*cols), 0.01); - A.resize(rows,rows); - dA.resize(rows,rows); + A.resize(rows,cols); + dA.resize(rows,cols); initSparse(density, dA, A,ForceNonZeroDiag); A.makeCompressed(); int nop = internal::random(0, internal::random(0,1) > 0.5 ? cols/2 : 0); @@ -31,6 +30,13 @@ int generate_sparse_rectangular_problem(MatrixType& A, DenseMat& dA, int maxRows A.col(j0) = s * A.col(j1); dA.col(j0) = s * dA.col(j1); } + +// if(rows void test_sparseqr_scalar() MatrixType A; DenseMat dA; DenseVector refX,x,b; - SparseQR > solver; + SparseQR > solver; generate_sparse_rectangular_problem(A,dA); - int n = A.cols(); - b = DenseVector::Random(n); + b = dA * DenseVector::Random(A.cols()); solver.compute(A); + if(internal::random(0,1)>0.5) + solver.factorize(A); // this checks that calling analyzePattern is not needed if the pattern do not change. if (solver.info() != Success) { std::cerr << "sparse QR factorization failed\n"; @@ -60,17 +67,19 @@ template void test_sparseqr_scalar() std::cerr << "sparse QR factorization failed\n"; exit(0); return; - } + } + + VERIFY_IS_APPROX(A * x, b); + //Compare with a dense QR solver ColPivHouseholderQR dqr(dA); refX = dqr.solve(b); VERIFY_IS_EQUAL(dqr.rank(), solver.rank()); - - if(solver.rank() (A * x - b).norm() ); - else + if(solver.rank()==A.cols()) // full rank VERIFY_IS_APPROX(x, refX); +// else +// VERIFY((dA * refX - b).norm() * 2 > (A * x - b).norm() ); // Compute explicitly the matrix Q MatrixType Q, QtQ, idM; @@ -88,3 +97,4 @@ void test_sparseqr() CALL_SUBTEST_2(test_sparseqr_scalar >()); } } + diff --git a/ground/gcs/src/libs/eigen/test/stable_norm.cpp b/ground/gcs/src/libs/eigen/test/stable_norm.cpp index c09fc17b7..231dd9189 100644 --- a/ground/gcs/src/libs/eigen/test/stable_norm.cpp +++ b/ground/gcs/src/libs/eigen/test/stable_norm.cpp @@ -9,11 +9,6 @@ #include "main.h" -template bool isNotNaN(const T& x) -{ - return x==x; -} - // workaround aggressive optimization in ICC template EIGEN_DONT_INLINE T sub(T a, T b) { return a - b; } @@ -55,8 +50,16 @@ template void stable_norm(const MatrixType& m) Index rows = m.rows(); Index cols = m.cols(); - Scalar big = internal::random() * ((std::numeric_limits::max)() * RealScalar(1e-4)); - Scalar small = internal::random() * ((std::numeric_limits::min)() * RealScalar(1e4)); + // get a non-zero random factor + Scalar factor = internal::random(); + while(numext::abs2(factor)(); + Scalar big = factor * ((std::numeric_limits::max)() * RealScalar(1e-4)); + + factor = internal::random(); + while(numext::abs2(factor)(); + Scalar small = factor * ((std::numeric_limits::min)() * RealScalar(1e4)); MatrixType vzero = MatrixType::Zero(rows, cols), vrand = MatrixType::Random(rows, cols), @@ -91,7 +94,7 @@ template void stable_norm(const MatrixType& m) VERIFY_IS_APPROX(vsmall.blueNorm(), sqrt(size)*abs(small)); VERIFY_IS_APPROX(vsmall.hypotNorm(), sqrt(size)*abs(small)); -// Test compilation of cwise() version + // Test compilation of cwise() version VERIFY_IS_APPROX(vrand.colwise().stableNorm(), vrand.colwise().norm()); VERIFY_IS_APPROX(vrand.colwise().blueNorm(), vrand.colwise().norm()); VERIFY_IS_APPROX(vrand.colwise().hypotNorm(), vrand.colwise().norm()); diff --git a/ground/gcs/src/libs/eigen/test/stddeque_overload.cpp b/ground/gcs/src/libs/eigen/test/stddeque_overload.cpp new file mode 100644 index 000000000..4da618bbf --- /dev/null +++ b/ground/gcs/src/libs/eigen/test/stddeque_overload.cpp @@ -0,0 +1,158 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Benoit Jacob +// Copyright (C) 2010 Hauke Heibel +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "main.h" + +#include +#include + +EIGEN_DEFINE_STL_DEQUE_SPECIALIZATION(Vector4f) + +EIGEN_DEFINE_STL_DEQUE_SPECIALIZATION(Matrix2f) +EIGEN_DEFINE_STL_DEQUE_SPECIALIZATION(Matrix4f) +EIGEN_DEFINE_STL_DEQUE_SPECIALIZATION(Matrix4d) + +EIGEN_DEFINE_STL_DEQUE_SPECIALIZATION(Affine3f) +EIGEN_DEFINE_STL_DEQUE_SPECIALIZATION(Affine3d) + +EIGEN_DEFINE_STL_DEQUE_SPECIALIZATION(Quaternionf) +EIGEN_DEFINE_STL_DEQUE_SPECIALIZATION(Quaterniond) + +template +void check_stddeque_matrix(const MatrixType& m) +{ + typename MatrixType::Index rows = m.rows(); + typename MatrixType::Index cols = m.cols(); + MatrixType x = MatrixType::Random(rows,cols), y = MatrixType::Random(rows,cols); + std::deque v(10, MatrixType(rows,cols)), w(20, y); + v[5] = x; + w[6] = v[5]; + VERIFY_IS_APPROX(w[6], v[5]); + v = w; + for(int i = 0; i < 20; i++) + { + VERIFY_IS_APPROX(w[i], v[i]); + } + + v.resize(21); + v[20] = x; + VERIFY_IS_APPROX(v[20], x); + v.resize(22,y); + VERIFY_IS_APPROX(v[21], y); + v.push_back(x); + VERIFY_IS_APPROX(v[22], x); + + // do a lot of push_back such that the deque gets internally resized + // (with memory reallocation) + MatrixType* ref = &w[0]; + for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i) + v.push_back(w[i%w.size()]); + for(unsigned int i=23; i +void check_stddeque_transform(const TransformType&) +{ + typedef typename TransformType::MatrixType MatrixType; + TransformType x(MatrixType::Random()), y(MatrixType::Random()); + std::deque v(10), w(20, y); + v[5] = x; + w[6] = v[5]; + VERIFY_IS_APPROX(w[6], v[5]); + v = w; + for(int i = 0; i < 20; i++) + { + VERIFY_IS_APPROX(w[i], v[i]); + } + + v.resize(21); + v[20] = x; + VERIFY_IS_APPROX(v[20], x); + v.resize(22,y); + VERIFY_IS_APPROX(v[21], y); + v.push_back(x); + VERIFY_IS_APPROX(v[22], x); + + // do a lot of push_back such that the deque gets internally resized + // (with memory reallocation) + TransformType* ref = &w[0]; + for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i) + v.push_back(w[i%w.size()]); + for(unsigned int i=23; i +void check_stddeque_quaternion(const QuaternionType&) +{ + typedef typename QuaternionType::Coefficients Coefficients; + QuaternionType x(Coefficients::Random()), y(Coefficients::Random()); + std::deque v(10), w(20, y); + v[5] = x; + w[6] = v[5]; + VERIFY_IS_APPROX(w[6], v[5]); + v = w; + for(int i = 0; i < 20; i++) + { + VERIFY_IS_APPROX(w[i], v[i]); + } + + v.resize(21); + v[20] = x; + VERIFY_IS_APPROX(v[20], x); + v.resize(22,y); + VERIFY_IS_APPROX(v[21], y); + v.push_back(x); + VERIFY_IS_APPROX(v[22], x); + + // do a lot of push_back such that the deque gets internally resized + // (with memory reallocation) + QuaternionType* ref = &w[0]; + for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i) + v.push_back(w[i%w.size()]); + for(unsigned int i=23; i +// Copyright (C) 2010 Hauke Heibel +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "main.h" + +#include +#include + +EIGEN_DEFINE_STL_LIST_SPECIALIZATION(Vector4f) + +EIGEN_DEFINE_STL_LIST_SPECIALIZATION(Matrix2f) +EIGEN_DEFINE_STL_LIST_SPECIALIZATION(Matrix4f) +EIGEN_DEFINE_STL_LIST_SPECIALIZATION(Matrix4d) + +EIGEN_DEFINE_STL_LIST_SPECIALIZATION(Affine3f) +EIGEN_DEFINE_STL_LIST_SPECIALIZATION(Affine3d) + +EIGEN_DEFINE_STL_LIST_SPECIALIZATION(Quaternionf) +EIGEN_DEFINE_STL_LIST_SPECIALIZATION(Quaterniond) + +template +typename Container::iterator get(Container & c, Position position) +{ + typename Container::iterator it = c.begin(); + std::advance(it, position); + return it; +} + +template +void set(Container & c, Position position, const Value & value) +{ + typename Container::iterator it = c.begin(); + std::advance(it, position); + *it = value; +} + +template +void check_stdlist_matrix(const MatrixType& m) +{ + typename MatrixType::Index rows = m.rows(); + typename MatrixType::Index cols = m.cols(); + MatrixType x = MatrixType::Random(rows,cols), y = MatrixType::Random(rows,cols); + std::list v(10, MatrixType(rows,cols)), w(20, y); + typename std::list::iterator itv = get(v, 5); + typename std::list::iterator itw = get(w, 6); + *itv = x; + *itw = *itv; + VERIFY_IS_APPROX(*itw, *itv); + v = w; + itv = v.begin(); + itw = w.begin(); + for(int i = 0; i < 20; i++) + { + VERIFY_IS_APPROX(*itw, *itv); + ++itv; + ++itw; + } + + v.resize(21); + set(v, 20, x); + VERIFY_IS_APPROX(*get(v, 20), x); + v.resize(22,y); + VERIFY_IS_APPROX(*get(v, 21), y); + v.push_back(x); + VERIFY_IS_APPROX(*get(v, 22), x); + + // do a lot of push_back such that the list gets internally resized + // (with memory reallocation) + MatrixType* ref = &(*get(w, 0)); + for(int i=0; i<30 || ((ref==&(*get(w, 0))) && i<300); ++i) + v.push_back(*get(w, i%w.size())); + for(unsigned int i=23; i +void check_stdlist_transform(const TransformType&) +{ + typedef typename TransformType::MatrixType MatrixType; + TransformType x(MatrixType::Random()), y(MatrixType::Random()); + std::list v(10), w(20, y); + typename std::list::iterator itv = get(v, 5); + typename std::list::iterator itw = get(w, 6); + *itv = x; + *itw = *itv; + VERIFY_IS_APPROX(*itw, *itv); + v = w; + itv = v.begin(); + itw = w.begin(); + for(int i = 0; i < 20; i++) + { + VERIFY_IS_APPROX(*itw, *itv); + ++itv; + ++itw; + } + + v.resize(21); + set(v, 20, x); + VERIFY_IS_APPROX(*get(v, 20), x); + v.resize(22,y); + VERIFY_IS_APPROX(*get(v, 21), y); + v.push_back(x); + VERIFY_IS_APPROX(*get(v, 22), x); + + // do a lot of push_back such that the list gets internally resized + // (with memory reallocation) + TransformType* ref = &(*get(w, 0)); + for(int i=0; i<30 || ((ref==&(*get(w, 0))) && i<300); ++i) + v.push_back(*get(w, i%w.size())); + for(unsigned int i=23; imatrix()==get(w, (i-23)%w.size())->matrix()); + } +} + +template +void check_stdlist_quaternion(const QuaternionType&) +{ + typedef typename QuaternionType::Coefficients Coefficients; + QuaternionType x(Coefficients::Random()), y(Coefficients::Random()); + std::list v(10), w(20, y); + typename std::list::iterator itv = get(v, 5); + typename std::list::iterator itw = get(w, 6); + *itv = x; + *itw = *itv; + VERIFY_IS_APPROX(*itw, *itv); + v = w; + itv = v.begin(); + itw = w.begin(); + for(int i = 0; i < 20; i++) + { + VERIFY_IS_APPROX(*itw, *itv); + ++itv; + ++itw; + } + + v.resize(21); + set(v, 20, x); + VERIFY_IS_APPROX(*get(v, 20), x); + v.resize(22,y); + VERIFY_IS_APPROX(*get(v, 21), y); + v.push_back(x); + VERIFY_IS_APPROX(*get(v, 22), x); + + // do a lot of push_back such that the list gets internally resized + // (with memory reallocation) + QuaternionType* ref = &(*get(w, 0)); + for(int i=0; i<30 || ((ref==&(*get(w, 0))) && i<300); ++i) + v.push_back(*get(w, i%w.size())); + for(unsigned int i=23; icoeffs()==get(w, (i-23)%w.size())->coeffs()); + } +} + +void test_stdlist_overload() +{ + // some non vectorizable fixed sizes + CALL_SUBTEST_1(check_stdlist_matrix(Vector2f())); + CALL_SUBTEST_1(check_stdlist_matrix(Matrix3f())); + CALL_SUBTEST_2(check_stdlist_matrix(Matrix3d())); + + // some vectorizable fixed sizes + CALL_SUBTEST_1(check_stdlist_matrix(Matrix2f())); + CALL_SUBTEST_1(check_stdlist_matrix(Vector4f())); + CALL_SUBTEST_1(check_stdlist_matrix(Matrix4f())); + CALL_SUBTEST_2(check_stdlist_matrix(Matrix4d())); + + // some dynamic sizes + CALL_SUBTEST_3(check_stdlist_matrix(MatrixXd(1,1))); + CALL_SUBTEST_3(check_stdlist_matrix(VectorXd(20))); + CALL_SUBTEST_3(check_stdlist_matrix(RowVectorXf(20))); + CALL_SUBTEST_3(check_stdlist_matrix(MatrixXcf(10,10))); + + // some Transform + CALL_SUBTEST_4(check_stdlist_transform(Affine2f())); // does not need the specialization (2+1)^2 = 9 + CALL_SUBTEST_4(check_stdlist_transform(Affine3f())); + CALL_SUBTEST_4(check_stdlist_transform(Affine3d())); + + // some Quaternion + CALL_SUBTEST_5(check_stdlist_quaternion(Quaternionf())); + CALL_SUBTEST_5(check_stdlist_quaternion(Quaterniond())); +} diff --git a/ground/gcs/src/libs/eigen/test/umeyama.cpp b/ground/gcs/src/libs/eigen/test/umeyama.cpp index 738d0af70..2e8092434 100644 --- a/ground/gcs/src/libs/eigen/test/umeyama.cpp +++ b/ground/gcs/src/libs/eigen/test/umeyama.cpp @@ -130,10 +130,11 @@ void run_fixed_size_test(int num_elements) // MUST be positive because in any other case det(cR_t) may become negative for // odd dimensions! - const Scalar c = abs(internal::random()); + // Also if c is to small compared to t.norm(), problem is ill-posed (cf. Bug 744) + const Scalar c = internal::random(0.5, 2.0); FixedMatrix R = randMatrixSpecialUnitary(dim); - FixedVector t = Scalar(50)*FixedVector::Random(dim,1); + FixedVector t = Scalar(32)*FixedVector::Random(dim,1); HomMatrix cR_t = HomMatrix::Identity(dim+1,dim+1); cR_t.block(0,0,dim,dim) = c*R; @@ -149,9 +150,9 @@ void run_fixed_size_test(int num_elements) HomMatrix cR_t_umeyama = umeyama(src_block, dst_block); - const Scalar error = ( cR_t_umeyama*src - dst ).array().square().sum(); + const Scalar error = ( cR_t_umeyama*src - dst ).squaredNorm(); - VERIFY(error < Scalar(10)*std::numeric_limits::epsilon()); + VERIFY(error < Scalar(16)*std::numeric_limits::epsilon()); } void test_umeyama() diff --git a/ground/gcs/src/libs/eigen/test/vectorwiseop.cpp b/ground/gcs/src/libs/eigen/test/vectorwiseop.cpp index 9d60b0388..d32fd10cc 100644 --- a/ground/gcs/src/libs/eigen/test/vectorwiseop.cpp +++ b/ground/gcs/src/libs/eigen/test/vectorwiseop.cpp @@ -101,6 +101,28 @@ template void vectorwiseop_array(const ArrayType& m) VERIFY_RAISES_ASSERT(m2.rowwise() /= rowvec.transpose()); VERIFY_RAISES_ASSERT(m1.rowwise() / rowvec.transpose()); + + m2 = m1; + // yes, there might be an aliasing issue there but ".rowwise() /=" + // is suppposed to evaluate " m2.colwise().sum()" into to temporary to avoid + // evaluating the reducions multiple times + if(ArrayType::RowsAtCompileTime>2 || ArrayType::RowsAtCompileTime==Dynamic) + { + m2.rowwise() /= m2.colwise().sum(); + VERIFY_IS_APPROX(m2, m1.rowwise() / m1.colwise().sum()); + } + + // all/any + Array mb(rows,cols); + mb = (m1.real()<=0.7).colwise().all(); + VERIFY( (mb.col(c) == (m1.real().col(c)<=0.7).all()).all() ); + mb = (m1.real()<=0.7).rowwise().all(); + VERIFY( (mb.row(r) == (m1.real().row(r)<=0.7).all()).all() ); + + mb = (m1.real()>=0.7).colwise().any(); + VERIFY( (mb.col(c) == (m1.real().col(c)>=0.7).any()).all() ); + mb = (m1.real()>=0.7).rowwise().any(); + VERIFY( (mb.row(r) == (m1.real().row(r)>=0.7).any()).all() ); } template void vectorwiseop_matrix(const MatrixType& m) diff --git a/ground/gcs/src/libs/eigen/test/visitor.cpp b/ground/gcs/src/libs/eigen/test/visitor.cpp index 39a5d6b5f..844170ec6 100644 --- a/ground/gcs/src/libs/eigen/test/visitor.cpp +++ b/ground/gcs/src/libs/eigen/test/visitor.cpp @@ -55,6 +55,11 @@ template void matrixVisitor(const MatrixType& p) VERIFY_IS_APPROX(maxc, eigen_maxc); VERIFY_IS_APPROX(minc, m.minCoeff()); VERIFY_IS_APPROX(maxc, m.maxCoeff()); + + eigen_maxc = (m.adjoint()*m).maxCoeff(&eigen_maxrow,&eigen_maxcol); + eigen_maxc = (m.adjoint()*m).eval().maxCoeff(&maxrow,&maxcol); + VERIFY(maxrow == eigen_maxrow); + VERIFY(maxcol == eigen_maxcol); } template void vectorVisitor(const VectorType& w) diff --git a/ground/gcs/src/libs/eigen/test/zerosized.cpp b/ground/gcs/src/libs/eigen/test/zerosized.cpp index 6905e584e..da7dd0481 100644 --- a/ground/gcs/src/libs/eigen/test/zerosized.cpp +++ b/ground/gcs/src/libs/eigen/test/zerosized.cpp @@ -9,12 +9,26 @@ #include "main.h" + +template void zeroReduction(const MatrixType& m) { + // Reductions that must hold for zero sized objects + VERIFY(m.all()); + VERIFY(!m.any()); + VERIFY(m.prod()==1); + VERIFY(m.sum()==0); + VERIFY(m.count()==0); + VERIFY(m.allFinite()); + VERIFY(!m.hasNaN()); +} + + template void zeroSizedMatrix() { MatrixType t1; - if (MatrixType::SizeAtCompileTime == Dynamic) + if (MatrixType::SizeAtCompileTime == Dynamic || MatrixType::SizeAtCompileTime == 0) { + zeroReduction(t1); if (MatrixType::RowsAtCompileTime == Dynamic) VERIFY(t1.rows() == 0); if (MatrixType::ColsAtCompileTime == Dynamic) @@ -22,9 +36,13 @@ template void zeroSizedMatrix() if (MatrixType::RowsAtCompileTime == Dynamic && MatrixType::ColsAtCompileTime == Dynamic) { + MatrixType t2(0, 0); VERIFY(t2.rows() == 0); VERIFY(t2.cols() == 0); + + zeroReduction(t2); + VERIFY(t1==t2); } } } @@ -33,11 +51,15 @@ template void zeroSizedVector() { VectorType t1; - if (VectorType::SizeAtCompileTime == Dynamic) + if (VectorType::SizeAtCompileTime == Dynamic || VectorType::SizeAtCompileTime==0) { + zeroReduction(t1); VERIFY(t1.size() == 0); VectorType t2(DenseIndex(0)); // DenseIndex disambiguates with 0-the-null-pointer (error with gcc 4.4 and MSVC8) VERIFY(t2.size() == 0); + zeroReduction(t2); + + VERIFY(t1==t2); } } @@ -51,9 +73,12 @@ void test_zerosized() zeroSizedMatrix >(); zeroSizedMatrix >(); zeroSizedMatrix >(); - + zeroSizedMatrix >(); + zeroSizedMatrix >(); + zeroSizedVector(); zeroSizedVector(); zeroSizedVector(); zeroSizedVector >(); + zeroSizedVector >(); } diff --git a/ground/gcs/src/libs/eigen/unsupported/Eigen/AlignedVector3 b/ground/gcs/src/libs/eigen/unsupported/Eigen/AlignedVector3 index 7b45e6cce..29d5c90fb 100644 --- a/ground/gcs/src/libs/eigen/unsupported/Eigen/AlignedVector3 +++ b/ground/gcs/src/libs/eigen/unsupported/Eigen/AlignedVector3 @@ -177,7 +177,7 @@ template class AlignedVector3 } template - inline bool isApprox(const MatrixBase& other, RealScalar eps=NumTraits::dummy_precision()) const + inline bool isApprox(const MatrixBase& other, const RealScalar& eps=NumTraits::dummy_precision()) const { return m_coeffs.template head<3>().isApprox(other,eps); } diff --git a/ground/gcs/src/libs/eigen/unsupported/Eigen/CMakeLists.txt b/ground/gcs/src/libs/eigen/unsupported/Eigen/CMakeLists.txt index e06f1238b..e1fbf97e2 100644 --- a/ground/gcs/src/libs/eigen/unsupported/Eigen/CMakeLists.txt +++ b/ground/gcs/src/libs/eigen/unsupported/Eigen/CMakeLists.txt @@ -1,6 +1,6 @@ -set(Eigen_HEADERS AdolcForward BVH IterativeSolvers MatrixFunctions MoreVectorization AutoDiff AlignedVector3 Polynomials - FFT NonLinearOptimization SparseExtra IterativeSolvers - NumericalDiff Skyline MPRealSupport OpenGLSupport KroneckerProduct Splines LevenbergMarquardt +set(Eigen_HEADERS AdolcForward AlignedVector3 ArpackSupport AutoDiff BVH FFT IterativeSolvers KroneckerProduct LevenbergMarquardt + MatrixFunctions MoreVectorization MPRealSupport NonLinearOptimization NumericalDiff OpenGLSupport Polynomials + Skyline SparseExtra Splines ) install(FILES diff --git a/ground/gcs/src/libs/eigen/unsupported/Eigen/OpenGLSupport b/ground/gcs/src/libs/eigen/unsupported/Eigen/OpenGLSupport index 4454bf820..e2769449c 100644 --- a/ground/gcs/src/libs/eigen/unsupported/Eigen/OpenGLSupport +++ b/ground/gcs/src/libs/eigen/unsupported/Eigen/OpenGLSupport @@ -11,7 +11,12 @@ #define EIGEN_OPENGL_MODULE #include -#include + +#if defined(__APPLE_CC__) + #include +#else + #include +#endif namespace Eigen { @@ -173,11 +178,11 @@ template void glLoadMatrix(const Transform& t) template void glLoadMatrix(const Transform& t) { glLoadMatrix(t.matrix()); } template void glLoadMatrix(const Transform& t) { glLoadMatrix(Transform(t).matrix()); } -static void glRotate(const Rotation2D& rot) +inline void glRotate(const Rotation2D& rot) { glRotatef(rot.angle()*180.f/float(M_PI), 0.f, 0.f, 1.f); } -static void glRotate(const Rotation2D& rot) +inline void glRotate(const Rotation2D& rot) { glRotated(rot.angle()*180.0/M_PI, 0.0, 0.0, 1.0); } @@ -241,18 +246,18 @@ EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glGet,GLenum,_,double, 4,4,Doublev) #ifdef GL_VERSION_2_0 -static void glUniform2fv_ei (GLint loc, const float* v) { glUniform2fv(loc,1,v); } -static void glUniform2iv_ei (GLint loc, const int* v) { glUniform2iv(loc,1,v); } +inline void glUniform2fv_ei (GLint loc, const float* v) { glUniform2fv(loc,1,v); } +inline void glUniform2iv_ei (GLint loc, const int* v) { glUniform2iv(loc,1,v); } -static void glUniform3fv_ei (GLint loc, const float* v) { glUniform3fv(loc,1,v); } -static void glUniform3iv_ei (GLint loc, const int* v) { glUniform3iv(loc,1,v); } +inline void glUniform3fv_ei (GLint loc, const float* v) { glUniform3fv(loc,1,v); } +inline void glUniform3iv_ei (GLint loc, const int* v) { glUniform3iv(loc,1,v); } -static void glUniform4fv_ei (GLint loc, const float* v) { glUniform4fv(loc,1,v); } -static void glUniform4iv_ei (GLint loc, const int* v) { glUniform4iv(loc,1,v); } +inline void glUniform4fv_ei (GLint loc, const float* v) { glUniform4fv(loc,1,v); } +inline void glUniform4iv_ei (GLint loc, const int* v) { glUniform4iv(loc,1,v); } -static void glUniformMatrix2fv_ei (GLint loc, const float* v) { glUniformMatrix2fv(loc,1,false,v); } -static void glUniformMatrix3fv_ei (GLint loc, const float* v) { glUniformMatrix3fv(loc,1,false,v); } -static void glUniformMatrix4fv_ei (GLint loc, const float* v) { glUniformMatrix4fv(loc,1,false,v); } +inline void glUniformMatrix2fv_ei (GLint loc, const float* v) { glUniformMatrix2fv(loc,1,false,v); } +inline void glUniformMatrix3fv_ei (GLint loc, const float* v) { glUniformMatrix3fv(loc,1,false,v); } +inline void glUniformMatrix4fv_ei (GLint loc, const float* v) { glUniformMatrix4fv(loc,1,false,v); } EIGEN_GL_FUNC1_DECLARATION (glUniform,GLint,const) @@ -289,9 +294,9 @@ EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float, 4,3,Matrix #ifdef GL_VERSION_3_0 -static void glUniform2uiv_ei (GLint loc, const unsigned int* v) { glUniform2uiv(loc,1,v); } -static void glUniform3uiv_ei (GLint loc, const unsigned int* v) { glUniform3uiv(loc,1,v); } -static void glUniform4uiv_ei (GLint loc, const unsigned int* v) { glUniform4uiv(loc,1,v); } +inline void glUniform2uiv_ei (GLint loc, const unsigned int* v) { glUniform2uiv(loc,1,v); } +inline void glUniform3uiv_ei (GLint loc, const unsigned int* v) { glUniform3uiv(loc,1,v); } +inline void glUniform4uiv_ei (GLint loc, const unsigned int* v) { glUniform4uiv(loc,1,v); } EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,unsigned int, 2,2uiv_ei) EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,unsigned int, 3,3uiv_ei) @@ -300,9 +305,9 @@ EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,unsigned int, 4,4uiv_ei) #endif #ifdef GL_ARB_gpu_shader_fp64 -static void glUniform2dv_ei (GLint loc, const double* v) { glUniform2dv(loc,1,v); } -static void glUniform3dv_ei (GLint loc, const double* v) { glUniform3dv(loc,1,v); } -static void glUniform4dv_ei (GLint loc, const double* v) { glUniform4dv(loc,1,v); } +inline void glUniform2dv_ei (GLint loc, const double* v) { glUniform2dv(loc,1,v); } +inline void glUniform3dv_ei (GLint loc, const double* v) { glUniform3dv(loc,1,v); } +inline void glUniform4dv_ei (GLint loc, const double* v) { glUniform4dv(loc,1,v); } EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,double, 2,2dv_ei) EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,double, 3,3dv_ei) diff --git a/ground/gcs/src/libs/eigen/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h b/ground/gcs/src/libs/eigen/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h index 8d42e69b9..fde3ff61a 100644 --- a/ground/gcs/src/libs/eigen/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h +++ b/ground/gcs/src/libs/eigen/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h @@ -631,7 +631,7 @@ template struct NumTraits > { typedef AutoDiffScalar::Real,DerType::RowsAtCompileTime,DerType::ColsAtCompileTime> > Real; typedef AutoDiffScalar NonInteger; - typedef AutoDiffScalar& Nested; + typedef AutoDiffScalar Nested; enum{ RequireInitialization = 1 }; diff --git a/ground/gcs/src/libs/eigen/unsupported/Eigen/src/CMakeLists.txt b/ground/gcs/src/libs/eigen/unsupported/Eigen/src/CMakeLists.txt index f3180b52b..d8b9f4068 100644 --- a/ground/gcs/src/libs/eigen/unsupported/Eigen/src/CMakeLists.txt +++ b/ground/gcs/src/libs/eigen/unsupported/Eigen/src/CMakeLists.txt @@ -1,7 +1,10 @@ ADD_SUBDIRECTORY(AutoDiff) ADD_SUBDIRECTORY(BVH) +ADD_SUBDIRECTORY(Eigenvalues) ADD_SUBDIRECTORY(FFT) ADD_SUBDIRECTORY(IterativeSolvers) +ADD_SUBDIRECTORY(KroneckerProduct) +ADD_SUBDIRECTORY(LevenbergMarquardt) ADD_SUBDIRECTORY(MatrixFunctions) ADD_SUBDIRECTORY(MoreVectorization) ADD_SUBDIRECTORY(NonLinearOptimization) @@ -9,5 +12,4 @@ ADD_SUBDIRECTORY(NumericalDiff) ADD_SUBDIRECTORY(Polynomials) ADD_SUBDIRECTORY(Skyline) ADD_SUBDIRECTORY(SparseExtra) -ADD_SUBDIRECTORY(KroneckerProduct) ADD_SUBDIRECTORY(Splines) diff --git a/ground/gcs/src/libs/eigen/unsupported/Eigen/src/Eigenvalues/CMakeLists.txt b/ground/gcs/src/libs/eigen/unsupported/Eigen/src/Eigenvalues/CMakeLists.txt new file mode 100644 index 000000000..1d4387c82 --- /dev/null +++ b/ground/gcs/src/libs/eigen/unsupported/Eigen/src/Eigenvalues/CMakeLists.txt @@ -0,0 +1,6 @@ +FILE(GLOB Eigen_Eigenvalues_SRCS "*.h") + +INSTALL(FILES + ${Eigen_Eigenvalues_SRCS} + DESTINATION ${INCLUDE_INSTALL_DIR}/unsupported/Eigen/src/Eigenvalues COMPONENT Devel + ) diff --git a/ground/gcs/src/libs/eigen/unsupported/Eigen/src/IterativeSolvers/ConstrainedConjGrad.h b/ground/gcs/src/libs/eigen/unsupported/Eigen/src/IterativeSolvers/ConstrainedConjGrad.h index 3f18beeeb..dc0093eb9 100644 --- a/ground/gcs/src/libs/eigen/unsupported/Eigen/src/IterativeSolvers/ConstrainedConjGrad.h +++ b/ground/gcs/src/libs/eigen/unsupported/Eigen/src/IterativeSolvers/ConstrainedConjGrad.h @@ -58,7 +58,9 @@ void pseudo_inverse(const CMatrix &C, CINVMatrix &CINV) Scalar rho, rho_1, alpha; d.setZero(); - CINV.startFill(); // FIXME estimate the number of non-zeros + typedef Triplet T; + std::vector tripletList; + for (Index i = 0; i < rows; ++i) { d[i] = 1.0; @@ -84,11 +86,12 @@ void pseudo_inverse(const CMatrix &C, CINVMatrix &CINV) // FIXME add a generic "prune/filter" expression for both dense and sparse object to sparse for (Index j=0; j TmpVec; diff --git a/ground/gcs/src/libs/eigen/unsupported/Eigen/src/IterativeSolvers/DGMRES.h b/ground/gcs/src/libs/eigen/unsupported/Eigen/src/IterativeSolvers/DGMRES.h index 9fcc8a8d9..68fc997f7 100644 --- a/ground/gcs/src/libs/eigen/unsupported/Eigen/src/IterativeSolvers/DGMRES.h +++ b/ground/gcs/src/libs/eigen/unsupported/Eigen/src/IterativeSolvers/DGMRES.h @@ -133,8 +133,8 @@ class DGMRES : public IterativeSolverBase > * this class becomes invalid. Call compute() to update it with the new * matrix A, or modify a copy of A. */ - DGMRES(const MatrixType& A) : Base(A),m_restart(30),m_neig(0),m_r(0),m_maxNeig(5),m_isDeflAllocated(false),m_isDeflInitialized(false) - {} + template + explicit DGMRES(const EigenBase& A) : Base(A.derived()), m_restart(30),m_neig(0),m_r(0),m_maxNeig(5),m_isDeflAllocated(false),m_isDeflInitialized(false) {} ~DGMRES() {} diff --git a/ground/gcs/src/libs/eigen/unsupported/Eigen/src/IterativeSolvers/GMRES.h b/ground/gcs/src/libs/eigen/unsupported/Eigen/src/IterativeSolvers/GMRES.h index 073367506..ea5deb26d 100644 --- a/ground/gcs/src/libs/eigen/unsupported/Eigen/src/IterativeSolvers/GMRES.h +++ b/ground/gcs/src/libs/eigen/unsupported/Eigen/src/IterativeSolvers/GMRES.h @@ -2,7 +2,7 @@ // for linear algebra. // // Copyright (C) 2011 Gael Guennebaud -// Copyright (C) 2012 Kolja Brix +// Copyright (C) 2012, 2014 Kolja Brix // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed @@ -72,16 +72,20 @@ bool gmres(const MatrixType & mat, const Rhs & rhs, Dest & x, const Precondition VectorType p0 = rhs - mat*x; VectorType r0 = precond.solve(p0); -// RealScalar r0_sqnorm = r0.squaredNorm(); + + // is initial guess already good enough? + if(abs(r0.norm()) < tol) { + return true; + } VectorType w = VectorType::Zero(restart + 1); - FMatrixType H = FMatrixType::Zero(m, restart + 1); + FMatrixType H = FMatrixType::Zero(m, restart + 1); // Hessenberg matrix VectorType tau = VectorType::Zero(restart + 1); std::vector < JacobiRotation < Scalar > > G(restart); // generate first Householder vector - VectorType e; + VectorType e(m-1); RealScalar beta; r0.makeHouseholder(e, tau.coeffRef(0), beta); w(0)=(Scalar) beta; @@ -242,20 +246,7 @@ struct traits > * \endcode * * By default the iterations start with x=0 as an initial guess of the solution. - * One can control the start using the solveWithGuess() method. Here is a step by - * step execution example starting with a random guess and printing the evolution - * of the estimated error: - * * \code - * x = VectorXd::Random(n); - * solver.setMaxIterations(1); - * int i = 0; - * do { - * x = solver.solveWithGuess(b,x); - * std::cout << i << " : " << solver.error() << std::endl; - * ++i; - * } while (solver.info()!=Success && i<100); - * \endcode - * Note that such a step by step excution is slightly slower. + * One can control the start using the solveWithGuess() method. * * \sa class SimplicialCholesky, DiagonalPreconditioner, IdentityPreconditioner */ @@ -294,7 +285,8 @@ public: * this class becomes invalid. Call compute() to update it with the new * matrix A, or modify a copy of A. */ - GMRES(const MatrixType& A) : Base(A), m_restart(30) {} + template + explicit GMRES(const EigenBase& A) : Base(A.derived()), m_restart(30) {} ~GMRES() {} diff --git a/ground/gcs/src/libs/eigen/unsupported/Eigen/src/IterativeSolvers/MINRES.h b/ground/gcs/src/libs/eigen/unsupported/Eigen/src/IterativeSolvers/MINRES.h index 0e56342a8..670f274bb 100644 --- a/ground/gcs/src/libs/eigen/unsupported/Eigen/src/IterativeSolvers/MINRES.h +++ b/ground/gcs/src/libs/eigen/unsupported/Eigen/src/IterativeSolvers/MINRES.h @@ -37,22 +37,31 @@ namespace Eigen { typedef typename Dest::Scalar Scalar; typedef Matrix VectorType; + // Check for zero rhs + const RealScalar rhsNorm2(rhs.squaredNorm()); + if(rhsNorm2 == 0) + { + x.setZero(); + iters = 0; + tol_error = 0; + return; + } + // initialize const int maxIters(iters); // initialize maxIters to iters const int N(mat.cols()); // the size of the matrix - const RealScalar rhsNorm2(rhs.squaredNorm()); const RealScalar threshold2(tol_error*tol_error*rhsNorm2); // convergence threshold (compared to residualNorm2) // Initialize preconditioned Lanczos -// VectorType v_old(N); // will be initialized inside loop + VectorType v_old(N); // will be initialized inside loop VectorType v( VectorType::Zero(N) ); //initialize v VectorType v_new(rhs-mat*x); //initialize v_new RealScalar residualNorm2(v_new.squaredNorm()); -// VectorType w(N); // will be initialized inside loop + VectorType w(N); // will be initialized inside loop VectorType w_new(precond.solve(v_new)); // initialize w_new // RealScalar beta; // will be initialized inside loop RealScalar beta_new2(v_new.dot(w_new)); - eigen_assert(beta_new2 >= 0 && "PRECONDITIONER IS NOT POSITIVE DEFINITE"); + eigen_assert(beta_new2 >= 0.0 && "PRECONDITIONER IS NOT POSITIVE DEFINITE"); RealScalar beta_new(sqrt(beta_new2)); const RealScalar beta_one(beta_new); v_new /= beta_new; @@ -62,14 +71,14 @@ namespace Eigen { RealScalar c_old(1.0); RealScalar s(0.0); // the sine of the Givens rotation RealScalar s_old(0.0); // the sine of the Givens rotation -// VectorType p_oold(N); // will be initialized in loop + VectorType p_oold(N); // will be initialized in loop VectorType p_old(VectorType::Zero(N)); // initialize p_old=0 VectorType p(p_old); // initialize p=0 RealScalar eta(1.0); iters = 0; // reset iters - while ( iters < maxIters ){ - + while ( iters < maxIters ) + { // Preconditioned Lanczos /* Note that there are 4 variants on the Lanczos algorithm. These are * described in Paige, C. C. (1972). Computational variants of @@ -81,17 +90,17 @@ namespace Eigen { * A. Greenbaum, Iterative Methods for Solving Linear Systems, SIAM (1987). */ const RealScalar beta(beta_new); -// v_old = v; // update: at first time step, this makes v_old = 0 so value of beta doesn't matter - const VectorType v_old(v); // NOT SURE IF CREATING v_old EVERY ITERATION IS EFFICIENT + v_old = v; // update: at first time step, this makes v_old = 0 so value of beta doesn't matter +// const VectorType v_old(v); // NOT SURE IF CREATING v_old EVERY ITERATION IS EFFICIENT v = v_new; // update -// w = w_new; // update - const VectorType w(w_new); // NOT SURE IF CREATING w EVERY ITERATION IS EFFICIENT + w = w_new; // update +// const VectorType w(w_new); // NOT SURE IF CREATING w EVERY ITERATION IS EFFICIENT v_new.noalias() = mat*w - beta*v_old; // compute v_new const RealScalar alpha = v_new.dot(w); v_new -= alpha*v; // overwrite v_new w_new = precond.solve(v_new); // overwrite w_new beta_new2 = v_new.dot(w_new); // compute beta_new - eigen_assert(beta_new2 >= 0 && "PRECONDITIONER IS NOT POSITIVE DEFINITE"); + eigen_assert(beta_new2 >= 0.0 && "PRECONDITIONER IS NOT POSITIVE DEFINITE"); beta_new = sqrt(beta_new2); // compute beta_new v_new /= beta_new; // overwrite v_new for next iteration w_new /= beta_new; // overwrite w_new for next iteration @@ -107,21 +116,28 @@ namespace Eigen { s=beta_new/r1; // new sine // Update solution -// p_oold = p_old; - const VectorType p_oold(p_old); // NOT SURE IF CREATING p_oold EVERY ITERATION IS EFFICIENT + p_oold = p_old; +// const VectorType p_oold(p_old); // NOT SURE IF CREATING p_oold EVERY ITERATION IS EFFICIENT p_old = p; p.noalias()=(w-r2*p_old-r3*p_oold) /r1; // IS NOALIAS REQUIRED? x += beta_one*c*eta*p; + + /* Update the squared residual. Note that this is the estimated residual. + The real residual |Ax-b|^2 may be slightly larger */ residualNorm2 *= s*s; - if ( residualNorm2 < threshold2){ + if ( residualNorm2 < threshold2) + { break; } eta=-s*eta; // update eta iters++; // increment iteration number (for output purposes) } - tol_error = std::sqrt(residualNorm2 / rhsNorm2); // return error. Note that this is the estimated error. The real error |Ax-b|/|b| may be slightly larger + + /* Compute error. Note that this is the estimated error. The real + error |Ax-b|/|b| may be slightly larger */ + tol_error = std::sqrt(residualNorm2 / rhsNorm2); } } @@ -174,20 +190,7 @@ namespace Eigen { * \endcode * * By default the iterations start with x=0 as an initial guess of the solution. - * One can control the start using the solveWithGuess() method. Here is a step by - * step execution example starting with a random guess and printing the evolution - * of the estimated error: - * * \code - * x = VectorXd::Random(n); - * mr.setMaxIterations(1); - * int i = 0; - * do { - * x = mr.solveWithGuess(b,x); - * std::cout << i << " : " << mr.error() << std::endl; - * ++i; - * } while (mr.info()!=Success && i<100); - * \endcode - * Note that such a step by step excution is slightly slower. + * One can control the start using the solveWithGuess() method. * * \sa class ConjugateGradient, BiCGSTAB, SimplicialCholesky, DiagonalPreconditioner, IdentityPreconditioner */ @@ -225,7 +228,8 @@ namespace Eigen { * this class becomes invalid. Call compute() to update it with the new * matrix A, or modify a copy of A. */ - MINRES(const MatrixType& A) : Base(A) {} + template + explicit MINRES(const EigenBase& A) : Base(A.derived()) {} /** Destructor. */ ~MINRES(){} @@ -250,6 +254,11 @@ namespace Eigen { template void _solveWithGuess(const Rhs& b, Dest& x) const { + typedef typename internal::conditional + >::type MatrixWrapperType; + m_iterations = Base::maxIterations(); m_error = Base::m_tolerance; @@ -259,7 +268,7 @@ namespace Eigen { m_error = Base::m_tolerance; typename Dest::ColXpr xj(x,j); - internal::minres(mp_matrix->template selfadjointView(), b.col(j), xj, + internal::minres(MatrixWrapperType(*mp_matrix), b.col(j), xj, Base::m_preconditioner, m_iterations, m_error); } diff --git a/ground/gcs/src/libs/eigen/unsupported/Eigen/src/LevenbergMarquardt/CMakeLists.txt b/ground/gcs/src/libs/eigen/unsupported/Eigen/src/LevenbergMarquardt/CMakeLists.txt index 8513803ce..d9690854d 100644 --- a/ground/gcs/src/libs/eigen/unsupported/Eigen/src/LevenbergMarquardt/CMakeLists.txt +++ b/ground/gcs/src/libs/eigen/unsupported/Eigen/src/LevenbergMarquardt/CMakeLists.txt @@ -2,5 +2,5 @@ FILE(GLOB Eigen_LevenbergMarquardt_SRCS "*.h") INSTALL(FILES ${Eigen_LevenbergMarquardt_SRCS} - DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/LevenbergMarquardt COMPONENT Devel + DESTINATION ${INCLUDE_INSTALL_DIR}/unsupported/Eigen/src/LevenbergMarquardt COMPONENT Devel ) diff --git a/ground/gcs/src/libs/eigen/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h b/ground/gcs/src/libs/eigen/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h index c32437281..78a307e96 100644 --- a/ground/gcs/src/libs/eigen/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h +++ b/ground/gcs/src/libs/eigen/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h @@ -110,7 +110,6 @@ void MatrixPowerAtomic::compute2x2(MatrixType& res, RealScalar p) co using std::abs; using std::pow; - ArrayType logTdiag = m_A.diagonal().array().log(); res.coeffRef(0,0) = pow(m_A.coeff(0,0), p); for (Index i=1; i < m_A.cols(); ++i) { diff --git a/ground/gcs/src/libs/eigen/unsupported/doc/examples/CMakeLists.txt b/ground/gcs/src/libs/eigen/unsupported/doc/examples/CMakeLists.txt index 978f9afd8..c47646dfc 100644 --- a/ground/gcs/src/libs/eigen/unsupported/doc/examples/CMakeLists.txt +++ b/ground/gcs/src/libs/eigen/unsupported/doc/examples/CMakeLists.txt @@ -10,12 +10,10 @@ FOREACH(example_src ${examples_SRCS}) if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO) target_link_libraries(example_${example} ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO}) endif() - GET_TARGET_PROPERTY(example_executable - example_${example} LOCATION) ADD_CUSTOM_COMMAND( TARGET example_${example} POST_BUILD - COMMAND ${example_executable} + COMMAND example_${example} ARGS >${CMAKE_CURRENT_BINARY_DIR}/${example}.out ) ADD_DEPENDENCIES(unsupported_examples example_${example}) diff --git a/ground/gcs/src/libs/eigen/unsupported/doc/snippets/CMakeLists.txt b/ground/gcs/src/libs/eigen/unsupported/doc/snippets/CMakeLists.txt index 4a4157933..f0c5cc2a8 100644 --- a/ground/gcs/src/libs/eigen/unsupported/doc/snippets/CMakeLists.txt +++ b/ground/gcs/src/libs/eigen/unsupported/doc/snippets/CMakeLists.txt @@ -14,12 +14,10 @@ FOREACH(snippet_src ${snippets_SRCS}) if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO) target_link_libraries(${compile_snippet_target} ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO}) endif() - GET_TARGET_PROPERTY(compile_snippet_executable - ${compile_snippet_target} LOCATION) ADD_CUSTOM_COMMAND( TARGET ${compile_snippet_target} POST_BUILD - COMMAND ${compile_snippet_executable} + COMMAND ${compile_snippet_target} ARGS >${CMAKE_CURRENT_BINARY_DIR}/${snippet}.out ) ADD_DEPENDENCIES(unsupported_snippets ${compile_snippet_target}) diff --git a/ground/gcs/src/libs/eigen/unsupported/test/CMakeLists.txt b/ground/gcs/src/libs/eigen/unsupported/test/CMakeLists.txt index a94a3b5e5..2e4cfdb2e 100644 --- a/ground/gcs/src/libs/eigen/unsupported/test/CMakeLists.txt +++ b/ground/gcs/src/libs/eigen/unsupported/test/CMakeLists.txt @@ -29,11 +29,7 @@ ei_add_test(NonLinearOptimization) ei_add_test(NumericalDiff) ei_add_test(autodiff) - -if (NOT CMAKE_CXX_COMPILER MATCHES "clang\\+\\+$") ei_add_test(BVH) -endif() - ei_add_test(matrix_exponential) ei_add_test(matrix_function) ei_add_test(matrix_power) @@ -73,8 +69,9 @@ if(NOT EIGEN_TEST_NO_OPENGL) find_package(GLUT) find_package(GLEW) if(OPENGL_FOUND AND GLUT_FOUND AND GLEW_FOUND) + include_directories(${OPENGL_INCLUDE_DIR} ${GLUT_INCLUDE_DIR} ${GLEW_INCLUDE_DIRS}) ei_add_property(EIGEN_TESTED_BACKENDS "OpenGL, ") - set(EIGEN_GL_LIB ${GLUT_LIBRARIES} ${GLEW_LIBRARIES}) + set(EIGEN_GL_LIB ${GLUT_LIBRARIES} ${GLEW_LIBRARIES} ${OPENGL_LIBRARIES}) ei_add_test(openglsupport "" "${EIGEN_GL_LIB}" ) else() ei_add_property(EIGEN_MISSING_BACKENDS "OpenGL, ") diff --git a/ground/gcs/src/libs/eigen/unsupported/test/FFTW.cpp b/ground/gcs/src/libs/eigen/unsupported/test/FFTW.cpp index a07bf274b..d3718e2d2 100644 --- a/ground/gcs/src/libs/eigen/unsupported/test/FFTW.cpp +++ b/ground/gcs/src/libs/eigen/unsupported/test/FFTW.cpp @@ -16,9 +16,6 @@ std::complex RandomCpx() { return std::complex( (T)(rand()/(T)RAND_MAX - . using namespace std; using namespace Eigen; -float norm(float x) {return x*x;} -double norm(double x) {return x*x;} -long double norm(long double x) {return x*x;} template < typename T> complex promote(complex x) { return complex(x.real(),x.imag()); } @@ -40,11 +37,11 @@ complex promote(long double x) { return complex( x); for (size_t k1=0;k1<(size_t)timebuf.size();++k1) { acc += promote( timebuf[k1] ) * exp( complex(0,k1*phinc) ); } - totalpower += norm(acc); + totalpower += numext::abs2(acc); complex x = promote(fftbuf[k0]); complex dif = acc - x; - difpower += norm(dif); - //cerr << k0 << "\t" << acc << "\t" << x << "\t" << sqrt(norm(dif)) << endl; + difpower += numext::abs2(dif); + //cerr << k0 << "\t" << acc << "\t" << x << "\t" << sqrt(numext::abs2(dif)) << endl; } cerr << "rmse:" << sqrt(difpower/totalpower) << endl; return sqrt(difpower/totalpower); @@ -57,8 +54,8 @@ complex promote(long double x) { return complex( x); long double difpower=0; size_t n = (min)( buf1.size(),buf2.size() ); for (size_t k=0;k void forward_jacobian(const Func& f) VERIFY_IS_APPROX(j, jref); } + +// TODO also check actual derivatives! void test_autodiff_scalar() { - std::cerr << foo(1,2) << "\n"; + Vector2f p = Vector2f::Random(); typedef AutoDiffScalar AD; - AD ax(1,Vector2f::UnitX()); - AD ay(2,Vector2f::UnitY()); + AD ax(p.x(),Vector2f::UnitX()); + AD ay(p.y(),Vector2f::UnitY()); AD res = foo(ax,ay); - std::cerr << res.value() << " <> " - << res.derivatives().transpose() << "\n\n"; + VERIFY_IS_APPROX(res.value(), foo(p.x(),p.y())); } +// TODO also check actual derivatives! void test_autodiff_vector() { - std::cerr << foo(Vector2f(1,2)) << "\n"; + Vector2f p = Vector2f::Random(); typedef AutoDiffScalar AD; typedef Matrix VectorAD; - VectorAD p(AD(1),AD(-1)); - p.x().derivatives() = Vector2f::UnitX(); - p.y().derivatives() = Vector2f::UnitY(); + VectorAD ap = p.cast(); + ap.x().derivatives() = Vector2f::UnitX(); + ap.y().derivatives() = Vector2f::UnitY(); - AD res = foo(p); - std::cerr << res.value() << " <> " - << res.derivatives().transpose() << "\n\n"; + AD res = foo(ap); + VERIFY_IS_APPROX(res.value(), foo(p)); } void test_autodiff_jacobian() { - for(int i = 0; i < g_repeat; i++) { - CALL_SUBTEST(( forward_jacobian(TestFunc1()) )); - CALL_SUBTEST(( forward_jacobian(TestFunc1()) )); - CALL_SUBTEST(( forward_jacobian(TestFunc1()) )); - CALL_SUBTEST(( forward_jacobian(TestFunc1()) )); - CALL_SUBTEST(( forward_jacobian(TestFunc1(3,3)) )); - } + CALL_SUBTEST(( forward_jacobian(TestFunc1()) )); + CALL_SUBTEST(( forward_jacobian(TestFunc1()) )); + CALL_SUBTEST(( forward_jacobian(TestFunc1()) )); + CALL_SUBTEST(( forward_jacobian(TestFunc1()) )); + CALL_SUBTEST(( forward_jacobian(TestFunc1(3,3)) )); } void test_autodiff() { - test_autodiff_scalar(); - test_autodiff_vector(); -// test_autodiff_jacobian(); + for(int i = 0; i < g_repeat; i++) { + CALL_SUBTEST_1( test_autodiff_scalar() ); + CALL_SUBTEST_2( test_autodiff_vector() ); + CALL_SUBTEST_3( test_autodiff_jacobian() ); + } } diff --git a/ground/gcs/src/libs/eigen/unsupported/test/minres.cpp b/ground/gcs/src/libs/eigen/unsupported/test/minres.cpp index fd12da548..509ebe09a 100644 --- a/ground/gcs/src/libs/eigen/unsupported/test/minres.cpp +++ b/ground/gcs/src/libs/eigen/unsupported/test/minres.cpp @@ -14,15 +14,32 @@ template void test_minres_T() { - MINRES, Lower, DiagonalPreconditioner > minres_colmajor_diag; - MINRES, Lower, IdentityPreconditioner > minres_colmajor_I; + MINRES, Lower|Upper, DiagonalPreconditioner > minres_colmajor_diag; + MINRES, Lower, IdentityPreconditioner > minres_colmajor_lower_I; + MINRES, Upper, IdentityPreconditioner > minres_colmajor_upper_I; // MINRES, Lower, IncompleteLUT > minres_colmajor_ilut; //minres, SSORPreconditioner > minres_colmajor_ssor; - CALL_SUBTEST( check_sparse_square_solving(minres_colmajor_diag) ); - CALL_SUBTEST( check_sparse_spd_solving(minres_colmajor_I) ); + +// CALL_SUBTEST( check_sparse_square_solving(minres_colmajor_diag) ); // CALL_SUBTEST( check_sparse_square_solving(minres_colmajor_ilut) ); //CALL_SUBTEST( check_sparse_square_solving(minres_colmajor_ssor) ); + + // Diagonal preconditioner + MINRES, Lower, DiagonalPreconditioner > minres_colmajor_lower_diag; + MINRES, Upper, DiagonalPreconditioner > minres_colmajor_upper_diag; + MINRES, Upper|Lower, DiagonalPreconditioner > minres_colmajor_uplo_diag; + + // call tests for SPD matrix + CALL_SUBTEST( check_sparse_spd_solving(minres_colmajor_lower_I) ); + CALL_SUBTEST( check_sparse_spd_solving(minres_colmajor_upper_I) ); + + CALL_SUBTEST( check_sparse_spd_solving(minres_colmajor_lower_diag) ); + CALL_SUBTEST( check_sparse_spd_solving(minres_colmajor_upper_diag) ); +// CALL_SUBTEST( check_sparse_spd_solving(minres_colmajor_uplo_diag) ); + + // TO DO: symmetric semi-definite matrix + // TO DO: symmetric indefinite matrix } void test_minres() diff --git a/ground/gcs/src/libs/eigen/unsupported/test/mpreal/mpreal.h b/ground/gcs/src/libs/eigen/unsupported/test/mpreal/mpreal.h index 0a31dc1a8..f83e52d09 100644 --- a/ground/gcs/src/libs/eigen/unsupported/test/mpreal/mpreal.h +++ b/ground/gcs/src/libs/eigen/unsupported/test/mpreal/mpreal.h @@ -1,59 +1,47 @@ /* - Multi-precision floating point number class for C++. + MPFR C++: Multi-precision floating point number class for C++. Based on MPFR library: http://mpfr.org Project homepage: http://www.holoborodko.com/pavel/mpfr Contact e-mail: pavel@holoborodko.com - Copyright (c) 2008-2012 Pavel Holoborodko + Copyright (c) 2008-2014 Pavel Holoborodko Contributors: Dmitriy Gubanov, Konstantin Holoborodko, Brian Gladman, Helmut Jarausch, Fokko Beekhof, Ulrich Mutze, Heinz van Saanen, Pere Constans, Peter van Hoof, Gael Guennebaud, Tsai Chia Cheng, - Alexei Zubanov, Jauhien Piatlicki, Victor Berger, John Westwood. + Alexei Zubanov, Jauhien Piatlicki, Victor Berger, John Westwood, + Petr Aleksandrov, Orion Poplawski, Charles Karney. - **************************************************************************** - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + Licensing: + (A) MPFR C++ is under GNU General Public License ("GPL"). + + (B) Non-free licenses may also be purchased from the author, for users who + do not want their programs protected by the GPL. - This library is distributed in the hope that it will be useful, + The non-free licenses are for users that wish to use MPFR C++ in + their products but are unwilling to release their software + under the GPL (which would require them to release source code + and allow free redistribution). + + Such users can purchase an unlimited-use license from the author. + Contact us for more details. + + GNU General Public License ("GPL") copyright permissions statement: + ************************************************************************** + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - **************************************************************************** - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - SUCH DAMAGE. + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef __MPREAL_H__ @@ -65,11 +53,22 @@ #include #include #include +#include #include // Options -#define MPREAL_HAVE_INT64_SUPPORT // Enable int64_t support if possible. Available only for MSVC 2010 & GCC. +// FIXME HAVE_INT64_SUPPORT leads to clashes with long int and int64_t on some systems. +//#define MPREAL_HAVE_INT64_SUPPORT // Enable int64_t support if possible. Available only for MSVC 2010 & GCC. #define MPREAL_HAVE_MSVC_DEBUGVIEW // Enable Debugger Visualizer for "Debug" builds in MSVC. +#define MPREAL_HAVE_DYNAMIC_STD_NUMERIC_LIMITS // Enable extended std::numeric_limits specialization. + // Meaning that "digits", "round_style" and similar members are defined as functions, not constants. + // See std::numeric_limits at the end of the file for more information. + +// Library version +#define MPREAL_VERSION_MAJOR 3 +#define MPREAL_VERSION_MINOR 5 +#define MPREAL_VERSION_PATCHLEVEL 9 +#define MPREAL_VERSION_STRING "3.5.9" // Detect compiler using signatures from http://predef.sourceforge.net/ #if defined(__GNUC__) && defined(__INTEL_COMPILER) @@ -82,6 +81,32 @@ #define IsInf(x) std::isinf(x) // GNU C/C++ (and/or other compilers), just hope for C99 conformance #endif +// A Clang feature extension to determine compiler features. +#ifndef __has_feature + #define __has_feature(x) 0 +#endif + +// Detect support for r-value references (move semantic). Borrowed from Eigen. +#if (__has_feature(cxx_rvalue_references) || \ + defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L || \ + (defined(_MSC_VER) && _MSC_VER >= 1600)) + + #define MPREAL_HAVE_MOVE_SUPPORT + + // Use fields in mpfr_t structure to check if it was initialized / set dummy initialization + #define mpfr_is_initialized(x) (0 != (x)->_mpfr_d) + #define mpfr_set_uninitialized(x) ((x)->_mpfr_d = 0 ) +#endif + +// Detect support for explicit converters. +#if (__has_feature(cxx_explicit_conversions) || \ + defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L || \ + (defined(_MSC_VER) && _MSC_VER >= 1800)) + + #define MPREAL_HAVE_EXPLICIT_CONVERTERS +#endif + +// Detect available 64-bit capabilities #if defined(MPREAL_HAVE_INT64_SUPPORT) #define MPFR_USE_INTMAX_T // Should be defined before mpfr.h @@ -97,7 +122,7 @@ #endif #elif defined (__GNUC__) && defined(__linux__) - #if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(__ia64) || defined(__itanium__) || defined(_M_IA64) + #if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(__ia64) || defined(__itanium__) || defined(_M_IA64) || defined (__PPC64__) #undef MPREAL_HAVE_INT64_SUPPORT // Remove all shaman dances for x64 builds since #undef MPFR_USE_INTMAX_T // GCC already supports x64 as of "long int" is 64-bit integer, nothing left to do #else @@ -111,7 +136,7 @@ #endif #if defined(MPREAL_HAVE_MSVC_DEBUGVIEW) && defined(_MSC_VER) && defined(_DEBUG) -#define MPREAL_MSVC_DEBUGVIEW_CODE DebugView = toString(); + #define MPREAL_MSVC_DEBUGVIEW_CODE DebugView = toString(); #define MPREAL_MSVC_DEBUGVIEW_DATA std::string DebugView; #else #define MPREAL_MSVC_DEBUGVIEW_CODE @@ -149,7 +174,6 @@ public: // Constructors && type conversions mpreal(); mpreal(const mpreal& u); - mpreal(const mpfr_t u); mpreal(const mpf_t u); mpreal(const mpz_t u, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd()); mpreal(const mpq_t u, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd()); @@ -159,6 +183,10 @@ public: mpreal(const unsigned int u, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd()); mpreal(const long int u, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd()); mpreal(const int u, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd()); + + // Construct mpreal from mpfr_t structure. + // shared = true allows to avoid deep copy, so that mpreal and 'u' share the same data & pointers. + mpreal(const mpfr_t u, bool shared = false); #if defined (MPREAL_HAVE_INT64_SUPPORT) mpreal(const uint64_t u, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd()); @@ -170,6 +198,11 @@ public: ~mpreal(); +#ifdef MPREAL_HAVE_MOVE_SUPPORT + mpreal& operator=(mpreal&& v); + mpreal(mpreal&& u); +#endif + // Operations // = // +, -, *, /, ++, --, <<, >> @@ -292,14 +325,34 @@ public: friend bool operator == (const mpreal& a, const double b); // Type Conversion operators + bool toBool (mp_rnd_t mode = GMP_RNDZ) const; long toLong (mp_rnd_t mode = GMP_RNDZ) const; unsigned long toULong (mp_rnd_t mode = GMP_RNDZ) const; + float toFloat (mp_rnd_t mode = GMP_RNDN) const; double toDouble (mp_rnd_t mode = GMP_RNDN) const; long double toLDouble (mp_rnd_t mode = GMP_RNDN) const; +#if defined (MPREAL_HAVE_EXPLICIT_CONVERTERS) + explicit operator bool () const { return toBool(); } + explicit operator int () const { return toLong(); } + explicit operator long () const { return toLong(); } + explicit operator long long () const { return toLong(); } + explicit operator unsigned () const { return toULong(); } + explicit operator unsigned long () const { return toULong(); } + explicit operator unsigned long long () const { return toULong(); } + explicit operator float () const { return toFloat(); } + explicit operator double () const { return toDouble(); } + explicit operator long double () const { return toLDouble(); } +#endif + #if defined (MPREAL_HAVE_INT64_SUPPORT) int64_t toInt64 (mp_rnd_t mode = GMP_RNDZ) const; uint64_t toUInt64 (mp_rnd_t mode = GMP_RNDZ) const; + + #if defined (MPREAL_HAVE_EXPLICIT_CONVERTERS) + explicit operator int64_t () const { return toInt64(); } + explicit operator uint64_t () const { return toUInt64(); } + #endif #endif // Get raw pointers so that mpreal can be directly used in raw mpfr_* functions @@ -308,121 +361,125 @@ public: ::mpfr_srcptr mpfr_srcptr() const; // Convert mpreal to string with n significant digits in base b - // n = 0 -> convert with the maximum available digits - std::string toString(int n = 0, int b = 10, mp_rnd_t mode = mpreal::get_default_rnd()) const; + // n = -1 -> convert with the maximum available digits + std::string toString(int n = -1, int b = 10, mp_rnd_t mode = mpreal::get_default_rnd()) const; #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) - std::string toString(const std::string& format) const; + std::string toString(const std::string& format) const; #endif - // Math Functions - friend const mpreal sqr (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal sqrt(const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal sqrt(const unsigned long int v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal cbrt(const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal root(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal pow (const mpreal& a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal pow (const mpreal& a, const mpz_t b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal pow (const mpreal& a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal pow (const mpreal& a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal pow (const unsigned long int a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal pow (const unsigned long int a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal fabs(const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); + std::ostream& output(std::ostream& os) const; - friend const mpreal abs(const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal dim(const mpreal& a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend inline const mpreal mul_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend inline const mpreal mul_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend inline const mpreal div_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend inline const mpreal div_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); + // Math Functions + friend const mpreal sqr (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal sqrt(const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal sqrt(const unsigned long int v, mp_rnd_t rnd_mode); + friend const mpreal cbrt(const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal root(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode); + friend const mpreal pow (const mpreal& a, const mpreal& b, mp_rnd_t rnd_mode); + friend const mpreal pow (const mpreal& a, const mpz_t b, mp_rnd_t rnd_mode); + friend const mpreal pow (const mpreal& a, const unsigned long int b, mp_rnd_t rnd_mode); + friend const mpreal pow (const mpreal& a, const long int b, mp_rnd_t rnd_mode); + friend const mpreal pow (const unsigned long int a, const mpreal& b, mp_rnd_t rnd_mode); + friend const mpreal pow (const unsigned long int a, const unsigned long int b, mp_rnd_t rnd_mode); + friend const mpreal fabs(const mpreal& v, mp_rnd_t rnd_mode); + + friend const mpreal abs(const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal dim(const mpreal& a, const mpreal& b, mp_rnd_t rnd_mode); + friend inline const mpreal mul_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode); + friend inline const mpreal mul_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode); + friend inline const mpreal div_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode); + friend inline const mpreal div_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode); friend int cmpabs(const mpreal& a,const mpreal& b); - friend const mpreal log (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal log2 (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal log10(const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal exp (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal exp2 (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal exp10(const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal log1p(const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal expm1(const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); + friend const mpreal log (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal log2 (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal log10(const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal exp (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal exp2 (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal exp10(const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal log1p(const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal expm1(const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal cos(const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal sin(const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal tan(const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal sec(const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal csc(const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal cot(const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend int sin_cos(mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); + friend const mpreal cos(const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal sin(const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal tan(const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal sec(const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal csc(const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal cot(const mpreal& v, mp_rnd_t rnd_mode); + friend int sin_cos(mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal acos (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal asin (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal atan (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal atan2 (const mpreal& y, const mpreal& x, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal acot (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal asec (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal acsc (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); + friend const mpreal acos (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal asin (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal atan (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal atan2 (const mpreal& y, const mpreal& x, mp_rnd_t rnd_mode); + friend const mpreal acot (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal asec (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal acsc (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal cosh (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal sinh (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal tanh (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal sech (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal csch (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal coth (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal acosh (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal asinh (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal atanh (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal acoth (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal asech (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal acsch (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); + friend const mpreal cosh (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal sinh (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal tanh (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal sech (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal csch (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal coth (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal acosh (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal asinh (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal atanh (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal acoth (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal asech (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal acsch (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal hypot (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); + friend const mpreal hypot (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode); - friend const mpreal fac_ui (unsigned long int v, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal eint (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); + friend const mpreal fac_ui (unsigned long int v, mp_prec_t prec, mp_rnd_t rnd_mode); + friend const mpreal eint (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal gamma (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal lngamma (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal lgamma (const mpreal& v, int *signp = 0, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal zeta (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal erf (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal erfc (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal besselj0 (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal besselj1 (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal besseljn (long n, const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal bessely0 (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal bessely1 (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal besselyn (long n, const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal fma (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal fms (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal agm (const mpreal& v1, const mpreal& v2, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal sum (const mpreal tab[], unsigned long int n, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); + friend const mpreal gamma (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal lngamma (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal lgamma (const mpreal& v, int *signp, mp_rnd_t rnd_mode); + friend const mpreal zeta (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal erf (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal erfc (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal besselj0 (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal besselj1 (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal besseljn (long n, const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal bessely0 (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal bessely1 (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal besselyn (long n, const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal fma (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode); + friend const mpreal fms (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode); + friend const mpreal agm (const mpreal& v1, const mpreal& v2, mp_rnd_t rnd_mode); + friend const mpreal sum (const mpreal tab[], unsigned long int n, mp_rnd_t rnd_mode); friend int sgn(const mpreal& v); // returns -1 or +1 // MPFR 2.4.0 Specifics #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) - friend int sinh_cosh (mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal li2 (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal fmod (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal rec_sqrt (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); + friend int sinh_cosh (mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal li2 (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal fmod (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode); + friend const mpreal rec_sqrt (const mpreal& v, mp_rnd_t rnd_mode); // MATLAB's semantic equivalents - friend const mpreal rem (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); // Remainder after division - friend const mpreal mod (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); // Modulus after division + friend const mpreal rem (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode); // Remainder after division + friend const mpreal mod (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode); // Modulus after division #endif // MPFR 3.0.0 Specifics #if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0)) - friend const mpreal digamma (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal ai (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal urandom (gmp_randstate_t& state, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); // use gmp_randinit_default() to init state, gmp_randclear() to clear + friend const mpreal digamma (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal ai (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal urandom (gmp_randstate_t& state, mp_rnd_t rnd_mode); // use gmp_randinit_default() to init state, gmp_randclear() to clear + friend const mpreal grandom (gmp_randstate_t& state, mp_rnd_t rnd_mode); // use gmp_randinit_default() to init state, gmp_randclear() to clear + friend const mpreal grandom (unsigned int seed); #endif // Uniformly distributed random number generation in [0,1] using // Mersenne-Twister algorithm by default. // Use parameter to setup seed, e.g.: random((unsigned)time(NULL)) // Check urandom() for more precise control. - friend const mpreal random(unsigned int seed = 0); - + friend const mpreal random(unsigned int seed); + // Exponent and mantissa manipulation friend const mpreal frexp(const mpreal& v, mp_exp_t* exp); friend const mpreal ldexp(const mpreal& v, mp_exp_t exp); @@ -433,31 +490,31 @@ public: // Constants // don't forget to call mpfr_free_cache() for every thread where you are using const-functions - friend const mpreal const_log2 (mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal const_pi (mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal const_euler (mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal const_catalan (mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t rnd_mode = mpreal::get_default_rnd()); + friend const mpreal const_log2 (mp_prec_t prec, mp_rnd_t rnd_mode); + friend const mpreal const_pi (mp_prec_t prec, mp_rnd_t rnd_mode); + friend const mpreal const_euler (mp_prec_t prec, mp_rnd_t rnd_mode); + friend const mpreal const_catalan (mp_prec_t prec, mp_rnd_t rnd_mode); // returns +inf iff sign>=0 otherwise -inf - friend const mpreal const_infinity(int sign = 1, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t rnd_mode = mpreal::get_default_rnd()); + friend const mpreal const_infinity(int sign, mp_prec_t prec); // Output/ Input friend std::ostream& operator<<(std::ostream& os, const mpreal& v); friend std::istream& operator>>(std::istream& is, mpreal& v); // Integer Related Functions - friend const mpreal rint (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); + friend const mpreal rint (const mpreal& v, mp_rnd_t rnd_mode); friend const mpreal ceil (const mpreal& v); friend const mpreal floor(const mpreal& v); friend const mpreal round(const mpreal& v); friend const mpreal trunc(const mpreal& v); - friend const mpreal rint_ceil (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal rint_floor (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal rint_round (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal rint_trunc (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal frac (const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal remainder ( const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal remquo (long* q, const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); + friend const mpreal rint_ceil (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal rint_floor (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal rint_round (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal rint_trunc (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal frac (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal remainder ( const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode); + friend const mpreal remquo (long* q, const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode); // Miscellaneous Functions friend const mpreal nexttoward (const mpreal& x, const mpreal& y); @@ -524,19 +581,22 @@ public: // Efficient swapping of two mpreal values - needed for std algorithms friend void swap(mpreal& x, mpreal& y); - friend const mpreal fmax(const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - friend const mpreal fmin(const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); + friend const mpreal fmax(const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode); + friend const mpreal fmin(const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode); private: // Human friendly Debug Preview in Visual Studio. // Put one of these lines: // - // mpfr::mpreal= ; Show value only + // mpfr::mpreal= ; Show value only // mpfr::mpreal=, bits ; Show value & precision // // at the beginning of // [Visual Studio Installation Folder]\Common7\Packages\Debugger\autoexp.dat MPREAL_MSVC_DEBUGVIEW_DATA + + // "Smart" resources deallocation. Checks if instance initialized before deletion. + void clear(::mpfr_ptr); }; ////////////////////////////////////////////////////////////////////////// @@ -551,64 +611,89 @@ public: // Default constructor: creates mp number and initializes it to 0. inline mpreal::mpreal() { - mpfr_init2(mp,mpreal::get_default_prec()); - mpfr_set_ui(mp,0,mpreal::get_default_rnd()); + mpfr_init2 (mpfr_ptr(), mpreal::get_default_prec()); + mpfr_set_ui(mpfr_ptr(), 0, mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; } inline mpreal::mpreal(const mpreal& u) { - mpfr_init2(mp,mpfr_get_prec(u.mp)); - mpfr_set(mp,u.mp,mpreal::get_default_rnd()); + mpfr_init2(mpfr_ptr(),mpfr_get_prec(u.mpfr_srcptr())); + mpfr_set (mpfr_ptr(),u.mpfr_srcptr(),mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; } -inline mpreal::mpreal(const mpfr_t u) +#ifdef MPREAL_HAVE_MOVE_SUPPORT +inline mpreal::mpreal(mpreal&& other) { - mpfr_init2(mp,mpfr_get_prec(u)); - mpfr_set(mp,u,mpreal::get_default_rnd()); + mpfr_set_uninitialized(mpfr_ptr()); // make sure "other" holds no pinter to actual data + mpfr_swap(mpfr_ptr(), other.mpfr_ptr()); + + MPREAL_MSVC_DEBUGVIEW_CODE; +} + +inline mpreal& mpreal::operator=(mpreal&& other) +{ + mpfr_swap(mpfr_ptr(), other.mpfr_ptr()); + + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} +#endif + +inline mpreal::mpreal(const mpfr_t u, bool shared) +{ + if(shared) + { + std::memcpy(mpfr_ptr(), u, sizeof(mpfr_t)); + } + else + { + mpfr_init2(mpfr_ptr(), mpfr_get_prec(u)); + mpfr_set (mpfr_ptr(), u, mpreal::get_default_rnd()); + } MPREAL_MSVC_DEBUGVIEW_CODE; } inline mpreal::mpreal(const mpf_t u) { - mpfr_init2(mp,(mp_prec_t) mpf_get_prec(u)); // (gmp: mp_bitcnt_t) unsigned long -> long (mpfr: mp_prec_t) - mpfr_set_f(mp,u,mpreal::get_default_rnd()); + mpfr_init2(mpfr_ptr(),(mp_prec_t) mpf_get_prec(u)); // (gmp: mp_bitcnt_t) unsigned long -> long (mpfr: mp_prec_t) + mpfr_set_f(mpfr_ptr(),u,mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; } inline mpreal::mpreal(const mpz_t u, mp_prec_t prec, mp_rnd_t mode) { - mpfr_init2(mp,prec); - mpfr_set_z(mp,u,mode); + mpfr_init2(mpfr_ptr(), prec); + mpfr_set_z(mpfr_ptr(), u, mode); MPREAL_MSVC_DEBUGVIEW_CODE; } inline mpreal::mpreal(const mpq_t u, mp_prec_t prec, mp_rnd_t mode) { - mpfr_init2(mp,prec); - mpfr_set_q(mp,u,mode); + mpfr_init2(mpfr_ptr(), prec); + mpfr_set_q(mpfr_ptr(), u, mode); MPREAL_MSVC_DEBUGVIEW_CODE; } inline mpreal::mpreal(const double u, mp_prec_t prec, mp_rnd_t mode) { - mpfr_init2(mp, prec); + mpfr_init2(mpfr_ptr(), prec); #if (MPREAL_DOUBLE_BITS_OVERFLOW > -1) - if(fits_in_bits(u, MPREAL_DOUBLE_BITS_OVERFLOW)) - { - mpfr_set_d(mp, u, mode); - }else - throw conversion_overflow(); + if(fits_in_bits(u, MPREAL_DOUBLE_BITS_OVERFLOW)) + { + mpfr_set_d(mpfr_ptr(), u, mode); + }else + throw conversion_overflow(); #else - mpfr_set_d(mp, u, mode); + mpfr_set_d(mpfr_ptr(), u, mode); #endif MPREAL_MSVC_DEBUGVIEW_CODE; @@ -616,40 +701,40 @@ inline mpreal::mpreal(const double u, mp_prec_t prec, mp_rnd_t mode) inline mpreal::mpreal(const long double u, mp_prec_t prec, mp_rnd_t mode) { - mpfr_init2(mp,prec); - mpfr_set_ld(mp,u,mode); + mpfr_init2 (mpfr_ptr(), prec); + mpfr_set_ld(mpfr_ptr(), u, mode); MPREAL_MSVC_DEBUGVIEW_CODE; } inline mpreal::mpreal(const unsigned long int u, mp_prec_t prec, mp_rnd_t mode) { - mpfr_init2(mp,prec); - mpfr_set_ui(mp,u,mode); + mpfr_init2 (mpfr_ptr(), prec); + mpfr_set_ui(mpfr_ptr(), u, mode); MPREAL_MSVC_DEBUGVIEW_CODE; } inline mpreal::mpreal(const unsigned int u, mp_prec_t prec, mp_rnd_t mode) { - mpfr_init2(mp,prec); - mpfr_set_ui(mp,u,mode); + mpfr_init2 (mpfr_ptr(), prec); + mpfr_set_ui(mpfr_ptr(), u, mode); MPREAL_MSVC_DEBUGVIEW_CODE; } inline mpreal::mpreal(const long int u, mp_prec_t prec, mp_rnd_t mode) { - mpfr_init2(mp,prec); - mpfr_set_si(mp,u,mode); + mpfr_init2 (mpfr_ptr(), prec); + mpfr_set_si(mpfr_ptr(), u, mode); MPREAL_MSVC_DEBUGVIEW_CODE; } inline mpreal::mpreal(const int u, mp_prec_t prec, mp_rnd_t mode) { - mpfr_init2(mp,prec); - mpfr_set_si(mp,u,mode); + mpfr_init2 (mpfr_ptr(), prec); + mpfr_set_si(mpfr_ptr(), u, mode); MPREAL_MSVC_DEBUGVIEW_CODE; } @@ -657,16 +742,16 @@ inline mpreal::mpreal(const int u, mp_prec_t prec, mp_rnd_t mode) #if defined (MPREAL_HAVE_INT64_SUPPORT) inline mpreal::mpreal(const uint64_t u, mp_prec_t prec, mp_rnd_t mode) { - mpfr_init2(mp,prec); - mpfr_set_uj(mp, u, mode); + mpfr_init2 (mpfr_ptr(), prec); + mpfr_set_uj(mpfr_ptr(), u, mode); MPREAL_MSVC_DEBUGVIEW_CODE; } inline mpreal::mpreal(const int64_t u, mp_prec_t prec, mp_rnd_t mode) { - mpfr_init2(mp,prec); - mpfr_set_sj(mp, u, mode); + mpfr_init2 (mpfr_ptr(), prec); + mpfr_set_sj(mpfr_ptr(), u, mode); MPREAL_MSVC_DEBUGVIEW_CODE; } @@ -674,23 +759,31 @@ inline mpreal::mpreal(const int64_t u, mp_prec_t prec, mp_rnd_t mode) inline mpreal::mpreal(const char* s, mp_prec_t prec, int base, mp_rnd_t mode) { - mpfr_init2(mp, prec); - mpfr_set_str(mp, s, base, mode); + mpfr_init2 (mpfr_ptr(), prec); + mpfr_set_str(mpfr_ptr(), s, base, mode); MPREAL_MSVC_DEBUGVIEW_CODE; } inline mpreal::mpreal(const std::string& s, mp_prec_t prec, int base, mp_rnd_t mode) { - mpfr_init2(mp, prec); - mpfr_set_str(mp, s.c_str(), base, mode); + mpfr_init2 (mpfr_ptr(), prec); + mpfr_set_str(mpfr_ptr(), s.c_str(), base, mode); MPREAL_MSVC_DEBUGVIEW_CODE; } +inline void mpreal::clear(::mpfr_ptr x) +{ +#ifdef MPREAL_HAVE_MOVE_SUPPORT + if(mpfr_is_initialized(x)) +#endif + mpfr_clear(x); +} + inline mpreal::~mpreal() { - mpfr_clear(mp); + clear(mpfr_ptr()); } // internal namespace needed for template magic @@ -761,6 +854,9 @@ const mpreal sqrt(const int v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); const mpreal sqrt(const long double v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); const mpreal sqrt(const double v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +// abs +inline const mpreal abs(const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()); + ////////////////////////////////////////////////////////////////////////// // pow const mpreal pow(const mpreal& a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); @@ -813,6 +909,11 @@ const mpreal pow(const double a, const unsigned int b, mp_rnd_t rnd_mode = mprea const mpreal pow(const double a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); const mpreal pow(const double a, const int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +inline const mpreal mul_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +inline const mpreal mul_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +inline const mpreal div_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +inline const mpreal div_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); + ////////////////////////////////////////////////////////////////////////// // Estimate machine epsilon for the given precision // Returns smallest eps such that 1.0 + eps != 1.0 @@ -860,15 +961,15 @@ inline mpreal& mpreal::operator=(const mpreal& v) { if (this != &v) { - mp_prec_t tp = mpfr_get_prec(mp); - mp_prec_t vp = mpfr_get_prec(v.mp); + mp_prec_t tp = mpfr_get_prec( mpfr_srcptr()); + mp_prec_t vp = mpfr_get_prec(v.mpfr_srcptr()); - if(tp != vp){ - mpfr_clear(mp); - mpfr_init2(mp, vp); - } + if(tp != vp){ + clear(mpfr_ptr()); + mpfr_init2(mpfr_ptr(), vp); + } - mpfr_set(mp, v.mp, mpreal::get_default_rnd()); + mpfr_set(mpfr_ptr(), v.mpfr_srcptr(), mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; } @@ -877,7 +978,7 @@ inline mpreal& mpreal::operator=(const mpreal& v) inline mpreal& mpreal::operator=(const mpf_t v) { - mpfr_set_f(mp, v, mpreal::get_default_rnd()); + mpfr_set_f(mpfr_ptr(), v, mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; @@ -885,7 +986,7 @@ inline mpreal& mpreal::operator=(const mpf_t v) inline mpreal& mpreal::operator=(const mpz_t v) { - mpfr_set_z(mp, v, mpreal::get_default_rnd()); + mpfr_set_z(mpfr_ptr(), v, mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; @@ -893,7 +994,7 @@ inline mpreal& mpreal::operator=(const mpz_t v) inline mpreal& mpreal::operator=(const mpq_t v) { - mpfr_set_q(mp, v, mpreal::get_default_rnd()); + mpfr_set_q(mpfr_ptr(), v, mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; @@ -901,7 +1002,7 @@ inline mpreal& mpreal::operator=(const mpq_t v) inline mpreal& mpreal::operator=(const long double v) { - mpfr_set_ld(mp, v, mpreal::get_default_rnd()); + mpfr_set_ld(mpfr_ptr(), v, mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; @@ -910,22 +1011,22 @@ inline mpreal& mpreal::operator=(const long double v) inline mpreal& mpreal::operator=(const double v) { #if (MPREAL_DOUBLE_BITS_OVERFLOW > -1) - if(fits_in_bits(v, MPREAL_DOUBLE_BITS_OVERFLOW)) - { - mpfr_set_d(mp,v,mpreal::get_default_rnd()); - }else - throw conversion_overflow(); + if(fits_in_bits(v, MPREAL_DOUBLE_BITS_OVERFLOW)) + { + mpfr_set_d(mpfr_ptr(),v,mpreal::get_default_rnd()); + }else + throw conversion_overflow(); #else - mpfr_set_d(mp,v,mpreal::get_default_rnd()); + mpfr_set_d(mpfr_ptr(),v,mpreal::get_default_rnd()); #endif - MPREAL_MSVC_DEBUGVIEW_CODE; + MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline mpreal& mpreal::operator=(const unsigned long int v) { - mpfr_set_ui(mp, v, mpreal::get_default_rnd()); + mpfr_set_ui(mpfr_ptr(), v, mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; @@ -933,7 +1034,7 @@ inline mpreal& mpreal::operator=(const unsigned long int v) inline mpreal& mpreal::operator=(const unsigned int v) { - mpfr_set_ui(mp, v, mpreal::get_default_rnd()); + mpfr_set_ui(mpfr_ptr(), v, mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; @@ -941,7 +1042,7 @@ inline mpreal& mpreal::operator=(const unsigned int v) inline mpreal& mpreal::operator=(const long int v) { - mpfr_set_si(mp, v, mpreal::get_default_rnd()); + mpfr_set_si(mpfr_ptr(), v, mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; @@ -949,7 +1050,7 @@ inline mpreal& mpreal::operator=(const long int v) inline mpreal& mpreal::operator=(const int v) { - mpfr_set_si(mp, v, mpreal::get_default_rnd()); + mpfr_set_si(mpfr_ptr(), v, mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; @@ -966,15 +1067,15 @@ inline mpreal& mpreal::operator=(const char* s) mpfr_t t; - mpfr_init2(t, mpfr_get_prec(mp)); + mpfr_init2(t, mpfr_get_prec(mpfr_srcptr())); if(0 == mpfr_set_str(t, s, 10, mpreal::get_default_rnd())) { - mpfr_set(mp, t, mpreal::get_default_rnd()); + mpfr_set(mpfr_ptr(), t, mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; } - mpfr_clear(t); + clear(t); return *this; } @@ -989,15 +1090,15 @@ inline mpreal& mpreal::operator=(const std::string& s) mpfr_t t; - mpfr_init2(t, mpfr_get_prec(mp)); + mpfr_init2(t, mpfr_get_prec(mpfr_srcptr())); if(0 == mpfr_set_str(t, s.c_str(), 10, mpreal::get_default_rnd())) { - mpfr_set(mp, t, mpreal::get_default_rnd()); + mpfr_set(mpfr_ptr(), t, mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; } - mpfr_clear(t); + clear(t); return *this; } @@ -1006,7 +1107,7 @@ inline mpreal& mpreal::operator=(const std::string& s) // + Addition inline mpreal& mpreal::operator+=(const mpreal& v) { - mpfr_add(mp,mp,v.mp,mpreal::get_default_rnd()); + mpfr_add(mpfr_ptr(), mpfr_srcptr(), v.mpfr_srcptr(), mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } @@ -1020,14 +1121,14 @@ inline mpreal& mpreal::operator+=(const mpf_t u) inline mpreal& mpreal::operator+=(const mpz_t u) { - mpfr_add_z(mp,mp,u,mpreal::get_default_rnd()); + mpfr_add_z(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline mpreal& mpreal::operator+=(const mpq_t u) { - mpfr_add_q(mp,mp,u,mpreal::get_default_rnd()); + mpfr_add_q(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } @@ -1042,7 +1143,7 @@ inline mpreal& mpreal::operator+= (const long double u) inline mpreal& mpreal::operator+= (const double u) { #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) - mpfr_add_d(mp,mp,u,mpreal::get_default_rnd()); + mpfr_add_d(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); #else *this += mpreal(u); #endif @@ -1053,28 +1154,28 @@ inline mpreal& mpreal::operator+= (const double u) inline mpreal& mpreal::operator+=(const unsigned long int u) { - mpfr_add_ui(mp,mp,u,mpreal::get_default_rnd()); + mpfr_add_ui(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline mpreal& mpreal::operator+=(const unsigned int u) { - mpfr_add_ui(mp,mp,u,mpreal::get_default_rnd()); + mpfr_add_ui(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline mpreal& mpreal::operator+=(const long int u) { - mpfr_add_si(mp,mp,u,mpreal::get_default_rnd()); + mpfr_add_si(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline mpreal& mpreal::operator+=(const int u) { - mpfr_add_si(mp,mp,u,mpreal::get_default_rnd()); + mpfr_add_si(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } @@ -1094,9 +1195,9 @@ inline const mpreal mpreal::operator+()const { return mpreal(*this); } inline const mpreal operator+(const mpreal& a, const mpreal& b) { - mpreal c(0, (std::max)(mpfr_get_prec(a.mpfr_ptr()), mpfr_get_prec(b.mpfr_ptr()))); - mpfr_add(c.mpfr_ptr(), a.mpfr_srcptr(), b.mpfr_srcptr(), mpreal::get_default_rnd()); - return c; + mpreal c(0, (std::max)(mpfr_get_prec(a.mpfr_ptr()), mpfr_get_prec(b.mpfr_ptr()))); + mpfr_add(c.mpfr_ptr(), a.mpfr_srcptr(), b.mpfr_srcptr(), mpreal::get_default_rnd()); + return c; } inline mpreal& mpreal::operator++() @@ -1127,21 +1228,21 @@ inline const mpreal mpreal::operator-- (int) // - Subtraction inline mpreal& mpreal::operator-=(const mpreal& v) { - mpfr_sub(mp,mp,v.mp,mpreal::get_default_rnd()); + mpfr_sub(mpfr_ptr(),mpfr_srcptr(),v.mpfr_srcptr(),mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline mpreal& mpreal::operator-=(const mpz_t v) { - mpfr_sub_z(mp,mp,v,mpreal::get_default_rnd()); + mpfr_sub_z(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline mpreal& mpreal::operator-=(const mpq_t v) { - mpfr_sub_q(mp,mp,v,mpreal::get_default_rnd()); + mpfr_sub_q(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } @@ -1156,7 +1257,7 @@ inline mpreal& mpreal::operator-=(const long double v) inline mpreal& mpreal::operator-=(const double v) { #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) - mpfr_sub_d(mp,mp,v,mpreal::get_default_rnd()); + mpfr_sub_d(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); #else *this -= mpreal(v); #endif @@ -1167,28 +1268,28 @@ inline mpreal& mpreal::operator-=(const double v) inline mpreal& mpreal::operator-=(const unsigned long int v) { - mpfr_sub_ui(mp,mp,v,mpreal::get_default_rnd()); + mpfr_sub_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline mpreal& mpreal::operator-=(const unsigned int v) { - mpfr_sub_ui(mp,mp,v,mpreal::get_default_rnd()); + mpfr_sub_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline mpreal& mpreal::operator-=(const long int v) { - mpfr_sub_si(mp,mp,v,mpreal::get_default_rnd()); + mpfr_sub_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline mpreal& mpreal::operator-=(const int v) { - mpfr_sub_si(mp,mp,v,mpreal::get_default_rnd()); + mpfr_sub_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } @@ -1196,15 +1297,15 @@ inline mpreal& mpreal::operator-=(const int v) inline const mpreal mpreal::operator-()const { mpreal u(*this); - mpfr_neg(u.mp,u.mp,mpreal::get_default_rnd()); + mpfr_neg(u.mpfr_ptr(),u.mpfr_srcptr(),mpreal::get_default_rnd()); return u; } inline const mpreal operator-(const mpreal& a, const mpreal& b) { - mpreal c(0, (std::max)(mpfr_get_prec(a.mpfr_ptr()), mpfr_get_prec(b.mpfr_ptr()))); - mpfr_sub(c.mpfr_ptr(), a.mpfr_srcptr(), b.mpfr_srcptr(), mpreal::get_default_rnd()); - return c; + mpreal c(0, (std::max)(mpfr_get_prec(a.mpfr_ptr()), mpfr_get_prec(b.mpfr_ptr()))); + mpfr_sub(c.mpfr_ptr(), a.mpfr_srcptr(), b.mpfr_srcptr(), mpreal::get_default_rnd()); + return c; } inline const mpreal operator-(const double b, const mpreal& a) @@ -1252,21 +1353,21 @@ inline const mpreal operator-(const int b, const mpreal& a) // * Multiplication inline mpreal& mpreal::operator*= (const mpreal& v) { - mpfr_mul(mp,mp,v.mp,mpreal::get_default_rnd()); + mpfr_mul(mpfr_ptr(),mpfr_srcptr(),v.mpfr_srcptr(),mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline mpreal& mpreal::operator*=(const mpz_t v) { - mpfr_mul_z(mp,mp,v,mpreal::get_default_rnd()); + mpfr_mul_z(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline mpreal& mpreal::operator*=(const mpq_t v) { - mpfr_mul_q(mp,mp,v,mpreal::get_default_rnd()); + mpfr_mul_q(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } @@ -1281,7 +1382,7 @@ inline mpreal& mpreal::operator*=(const long double v) inline mpreal& mpreal::operator*=(const double v) { #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) - mpfr_mul_d(mp,mp,v,mpreal::get_default_rnd()); + mpfr_mul_d(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); #else *this *= mpreal(v); #endif @@ -1291,58 +1392,58 @@ inline mpreal& mpreal::operator*=(const double v) inline mpreal& mpreal::operator*=(const unsigned long int v) { - mpfr_mul_ui(mp,mp,v,mpreal::get_default_rnd()); + mpfr_mul_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline mpreal& mpreal::operator*=(const unsigned int v) { - mpfr_mul_ui(mp,mp,v,mpreal::get_default_rnd()); + mpfr_mul_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline mpreal& mpreal::operator*=(const long int v) { - mpfr_mul_si(mp,mp,v,mpreal::get_default_rnd()); + mpfr_mul_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline mpreal& mpreal::operator*=(const int v) { - mpfr_mul_si(mp,mp,v,mpreal::get_default_rnd()); + mpfr_mul_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline const mpreal operator*(const mpreal& a, const mpreal& b) { - mpreal c(0, (std::max)(mpfr_get_prec(a.mpfr_ptr()), mpfr_get_prec(b.mpfr_ptr()))); - mpfr_mul(c.mpfr_ptr(), a.mpfr_srcptr(), b.mpfr_srcptr(), mpreal::get_default_rnd()); - return c; + mpreal c(0, (std::max)(mpfr_get_prec(a.mpfr_ptr()), mpfr_get_prec(b.mpfr_ptr()))); + mpfr_mul(c.mpfr_ptr(), a.mpfr_srcptr(), b.mpfr_srcptr(), mpreal::get_default_rnd()); + return c; } ////////////////////////////////////////////////////////////////////////// // / Division inline mpreal& mpreal::operator/=(const mpreal& v) { - mpfr_div(mp,mp,v.mp,mpreal::get_default_rnd()); + mpfr_div(mpfr_ptr(),mpfr_srcptr(),v.mpfr_srcptr(),mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline mpreal& mpreal::operator/=(const mpz_t v) { - mpfr_div_z(mp,mp,v,mpreal::get_default_rnd()); + mpfr_div_z(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline mpreal& mpreal::operator/=(const mpq_t v) { - mpfr_div_q(mp,mp,v,mpreal::get_default_rnd()); + mpfr_div_q(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } @@ -1357,7 +1458,7 @@ inline mpreal& mpreal::operator/=(const long double v) inline mpreal& mpreal::operator/=(const double v) { #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) - mpfr_div_d(mp,mp,v,mpreal::get_default_rnd()); + mpfr_div_d(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); #else *this /= mpreal(v); #endif @@ -1367,72 +1468,72 @@ inline mpreal& mpreal::operator/=(const double v) inline mpreal& mpreal::operator/=(const unsigned long int v) { - mpfr_div_ui(mp,mp,v,mpreal::get_default_rnd()); + mpfr_div_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline mpreal& mpreal::operator/=(const unsigned int v) { - mpfr_div_ui(mp,mp,v,mpreal::get_default_rnd()); + mpfr_div_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline mpreal& mpreal::operator/=(const long int v) { - mpfr_div_si(mp,mp,v,mpreal::get_default_rnd()); + mpfr_div_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline mpreal& mpreal::operator/=(const int v) { - mpfr_div_si(mp,mp,v,mpreal::get_default_rnd()); + mpfr_div_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline const mpreal operator/(const mpreal& a, const mpreal& b) { - mpreal c(0, (std::max)(mpfr_get_prec(a.mpfr_ptr()), mpfr_get_prec(b.mpfr_ptr()))); - mpfr_div(c.mpfr_ptr(), a.mpfr_srcptr(), b.mpfr_srcptr(), mpreal::get_default_rnd()); - return c; + mpreal c(0, (std::max)(mpfr_get_prec(a.mpfr_srcptr()), mpfr_get_prec(b.mpfr_srcptr()))); + mpfr_div(c.mpfr_ptr(), a.mpfr_srcptr(), b.mpfr_srcptr(), mpreal::get_default_rnd()); + return c; } inline const mpreal operator/(const unsigned long int b, const mpreal& a) { - mpreal x(0, mpfr_get_prec(a.mpfr_ptr())); + mpreal x(0, mpfr_get_prec(a.mpfr_srcptr())); mpfr_ui_div(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd()); return x; } inline const mpreal operator/(const unsigned int b, const mpreal& a) { - mpreal x(0, mpfr_get_prec(a.mpfr_ptr())); + mpreal x(0, mpfr_get_prec(a.mpfr_srcptr())); mpfr_ui_div(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd()); return x; } inline const mpreal operator/(const long int b, const mpreal& a) { - mpreal x(0, mpfr_get_prec(a.mpfr_ptr())); - mpfr_si_div(x.mpfr_ptr(), b, a.mpfr_srcptr(),mpreal::get_default_rnd()); + mpreal x(0, mpfr_get_prec(a.mpfr_srcptr())); + mpfr_si_div(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd()); return x; } inline const mpreal operator/(const int b, const mpreal& a) { - mpreal x(0, mpfr_get_prec(a.mpfr_ptr())); - mpfr_si_div(x.mpfr_ptr(), b, a.mpfr_srcptr(),mpreal::get_default_rnd()); + mpreal x(0, mpfr_get_prec(a.mpfr_srcptr())); + mpfr_si_div(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd()); return x; } inline const mpreal operator/(const double b, const mpreal& a) { #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) - mpreal x(0, mpfr_get_prec(a.mpfr_ptr())); - mpfr_d_div(x.mpfr_ptr(), b, a.mpfr_srcptr(),mpreal::get_default_rnd()); + mpreal x(0, mpfr_get_prec(a.mpfr_srcptr())); + mpfr_d_div(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd()); return x; #else mpreal x(0, mpfr_get_prec(a.mpfr_ptr())); @@ -1445,56 +1546,56 @@ inline const mpreal operator/(const double b, const mpreal& a) // Shifts operators - Multiplication/Division by power of 2 inline mpreal& mpreal::operator<<=(const unsigned long int u) { - mpfr_mul_2ui(mp,mp,u,mpreal::get_default_rnd()); + mpfr_mul_2ui(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline mpreal& mpreal::operator<<=(const unsigned int u) { - mpfr_mul_2ui(mp,mp,static_cast(u),mpreal::get_default_rnd()); + mpfr_mul_2ui(mpfr_ptr(),mpfr_srcptr(),static_cast(u),mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline mpreal& mpreal::operator<<=(const long int u) { - mpfr_mul_2si(mp,mp,u,mpreal::get_default_rnd()); + mpfr_mul_2si(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline mpreal& mpreal::operator<<=(const int u) { - mpfr_mul_2si(mp,mp,static_cast(u),mpreal::get_default_rnd()); + mpfr_mul_2si(mpfr_ptr(),mpfr_srcptr(),static_cast(u),mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline mpreal& mpreal::operator>>=(const unsigned long int u) { - mpfr_div_2ui(mp,mp,u,mpreal::get_default_rnd()); + mpfr_div_2ui(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline mpreal& mpreal::operator>>=(const unsigned int u) { - mpfr_div_2ui(mp,mp,static_cast(u),mpreal::get_default_rnd()); + mpfr_div_2ui(mpfr_ptr(),mpfr_srcptr(),static_cast(u),mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline mpreal& mpreal::operator>>=(const long int u) { - mpfr_div_2si(mp,mp,u,mpreal::get_default_rnd()); + mpfr_div_2si(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline mpreal& mpreal::operator>>=(const int u) { - mpfr_div_2si(mp,mp,static_cast(u),mpreal::get_default_rnd()); + mpfr_div_2si(mpfr_ptr(),mpfr_srcptr(),static_cast(u),mpreal::get_default_rnd()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } @@ -1543,7 +1644,7 @@ inline const mpreal operator>>(const mpreal& v, const int k) inline const mpreal mul_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode) { mpreal x(v); - mpfr_mul_2ui(x.mp,v.mp,k,rnd_mode); + mpfr_mul_2ui(x.mpfr_ptr(),v.mpfr_srcptr(),k,rnd_mode); return x; } @@ -1551,61 +1652,63 @@ inline const mpreal mul_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_m inline const mpreal mul_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode) { mpreal x(v); - mpfr_mul_2si(x.mp,v.mp,k,rnd_mode); + mpfr_mul_2si(x.mpfr_ptr(),v.mpfr_srcptr(),k,rnd_mode); return x; } inline const mpreal div_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode) { mpreal x(v); - mpfr_div_2ui(x.mp,v.mp,k,rnd_mode); + mpfr_div_2ui(x.mpfr_ptr(),v.mpfr_srcptr(),k,rnd_mode); return x; } inline const mpreal div_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode) { mpreal x(v); - mpfr_div_2si(x.mp,v.mp,k,rnd_mode); + mpfr_div_2si(x.mpfr_ptr(),v.mpfr_srcptr(),k,rnd_mode); return x; } ////////////////////////////////////////////////////////////////////////// //Boolean operators -inline bool operator > (const mpreal& a, const mpreal& b){ return (mpfr_greater_p(a.mp,b.mp) !=0); } -inline bool operator >= (const mpreal& a, const mpreal& b){ return (mpfr_greaterequal_p(a.mp,b.mp) !=0); } -inline bool operator < (const mpreal& a, const mpreal& b){ return (mpfr_less_p(a.mp,b.mp) !=0); } -inline bool operator <= (const mpreal& a, const mpreal& b){ return (mpfr_lessequal_p(a.mp,b.mp) !=0); } -inline bool operator == (const mpreal& a, const mpreal& b){ return (mpfr_equal_p(a.mp,b.mp) !=0); } -inline bool operator != (const mpreal& a, const mpreal& b){ return (mpfr_lessgreater_p(a.mp,b.mp) !=0); } +inline bool operator > (const mpreal& a, const mpreal& b){ return (mpfr_greater_p (a.mpfr_srcptr(),b.mpfr_srcptr()) !=0 ); } +inline bool operator >= (const mpreal& a, const mpreal& b){ return (mpfr_greaterequal_p (a.mpfr_srcptr(),b.mpfr_srcptr()) !=0 ); } +inline bool operator < (const mpreal& a, const mpreal& b){ return (mpfr_less_p (a.mpfr_srcptr(),b.mpfr_srcptr()) !=0 ); } +inline bool operator <= (const mpreal& a, const mpreal& b){ return (mpfr_lessequal_p (a.mpfr_srcptr(),b.mpfr_srcptr()) !=0 ); } +inline bool operator == (const mpreal& a, const mpreal& b){ return (mpfr_equal_p (a.mpfr_srcptr(),b.mpfr_srcptr()) !=0 ); } +inline bool operator != (const mpreal& a, const mpreal& b){ return (mpfr_lessgreater_p (a.mpfr_srcptr(),b.mpfr_srcptr()) !=0 ); } -inline bool operator == (const mpreal& a, const unsigned long int b ){ return (mpfr_cmp_ui(a.mp,b) == 0); } -inline bool operator == (const mpreal& a, const unsigned int b ){ return (mpfr_cmp_ui(a.mp,b) == 0); } -inline bool operator == (const mpreal& a, const long int b ){ return (mpfr_cmp_si(a.mp,b) == 0); } -inline bool operator == (const mpreal& a, const int b ){ return (mpfr_cmp_si(a.mp,b) == 0); } -inline bool operator == (const mpreal& a, const long double b ){ return (mpfr_cmp_ld(a.mp,b) == 0); } -inline bool operator == (const mpreal& a, const double b ){ return (mpfr_cmp_d(a.mp,b) == 0); } +inline bool operator == (const mpreal& a, const unsigned long int b ){ return (mpfr_cmp_ui(a.mpfr_srcptr(),b) == 0 ); } +inline bool operator == (const mpreal& a, const unsigned int b ){ return (mpfr_cmp_ui(a.mpfr_srcptr(),b) == 0 ); } +inline bool operator == (const mpreal& a, const long int b ){ return (mpfr_cmp_si(a.mpfr_srcptr(),b) == 0 ); } +inline bool operator == (const mpreal& a, const int b ){ return (mpfr_cmp_si(a.mpfr_srcptr(),b) == 0 ); } +inline bool operator == (const mpreal& a, const long double b ){ return (mpfr_cmp_ld(a.mpfr_srcptr(),b) == 0 ); } +inline bool operator == (const mpreal& a, const double b ){ return (mpfr_cmp_d (a.mpfr_srcptr(),b) == 0 ); } -inline bool isnan (const mpreal& v){ return (mpfr_nan_p(v.mp) != 0); } -inline bool isinf (const mpreal& v){ return (mpfr_inf_p(v.mp) != 0); } -inline bool isfinite (const mpreal& v){ return (mpfr_number_p(v.mp) != 0); } -inline bool iszero (const mpreal& v){ return (mpfr_zero_p(v.mp) != 0); } -inline bool isint (const mpreal& v){ return (mpfr_integer_p(v.mp) != 0); } +inline bool isnan (const mpreal& op){ return (mpfr_nan_p (op.mpfr_srcptr()) != 0 ); } +inline bool isinf (const mpreal& op){ return (mpfr_inf_p (op.mpfr_srcptr()) != 0 ); } +inline bool isfinite (const mpreal& op){ return (mpfr_number_p (op.mpfr_srcptr()) != 0 ); } +inline bool iszero (const mpreal& op){ return (mpfr_zero_p (op.mpfr_srcptr()) != 0 ); } +inline bool isint (const mpreal& op){ return (mpfr_integer_p(op.mpfr_srcptr()) != 0 ); } #if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0)) -inline bool isregular(const mpreal& v){ return (mpfr_regular_p(v.mp));} +inline bool isregular(const mpreal& op){ return (mpfr_regular_p(op.mpfr_srcptr()));} #endif ////////////////////////////////////////////////////////////////////////// // Type Converters -inline long mpreal::toLong (mp_rnd_t mode) const { return mpfr_get_si(mp, mode); } -inline unsigned long mpreal::toULong (mp_rnd_t mode) const { return mpfr_get_ui(mp, mode); } -inline double mpreal::toDouble (mp_rnd_t mode) const { return mpfr_get_d (mp, mode); } -inline long double mpreal::toLDouble(mp_rnd_t mode) const { return mpfr_get_ld(mp, mode); } +inline bool mpreal::toBool (mp_rnd_t /*mode*/) const { return mpfr_zero_p (mpfr_srcptr()) == 0; } +inline long mpreal::toLong (mp_rnd_t mode) const { return mpfr_get_si (mpfr_srcptr(), mode); } +inline unsigned long mpreal::toULong (mp_rnd_t mode) const { return mpfr_get_ui (mpfr_srcptr(), mode); } +inline float mpreal::toFloat (mp_rnd_t mode) const { return mpfr_get_flt(mpfr_srcptr(), mode); } +inline double mpreal::toDouble (mp_rnd_t mode) const { return mpfr_get_d (mpfr_srcptr(), mode); } +inline long double mpreal::toLDouble(mp_rnd_t mode) const { return mpfr_get_ld (mpfr_srcptr(), mode); } #if defined (MPREAL_HAVE_INT64_SUPPORT) -inline int64_t mpreal::toInt64 (mp_rnd_t mode) const{ return mpfr_get_sj(mp, mode); } -inline uint64_t mpreal::toUInt64(mp_rnd_t mode) const{ return mpfr_get_uj(mp, mode); } +inline int64_t mpreal::toInt64 (mp_rnd_t mode) const{ return mpfr_get_sj(mpfr_srcptr(), mode); } +inline uint64_t mpreal::toUInt64(mp_rnd_t mode) const{ return mpfr_get_uj(mpfr_srcptr(), mode); } #endif inline ::mpfr_ptr mpreal::mpfr_ptr() { return mp; } @@ -1629,7 +1732,7 @@ inline std::string mpreal::toString(const std::string& format) const if( !format.empty() ) { - if(!(mpfr_asprintf(&s,format.c_str(),mp) < 0)) + if(!(mpfr_asprintf(&s, format.c_str(), mpfr_srcptr()) < 0)) { out = std::string(s); @@ -1644,20 +1747,19 @@ inline std::string mpreal::toString(const std::string& format) const inline std::string mpreal::toString(int n, int b, mp_rnd_t mode) const { + // TODO: Add extended format specification (f, e, rounding mode) as it done in output operator (void)b; (void)mode; #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) - // Use MPFR native function for output - char format[128]; - int digits; + std::ostringstream format; - digits = n > 0 ? n : bits2digits(mpfr_get_prec(mp)); + int digits = (n >= 0) ? n : bits2digits(mpfr_get_prec(mpfr_srcptr())); + + format << "%." << digits << "RNg"; - sprintf(format,"%%.%dRNg",digits); // Default format - - return toString(std::string(format)); + return toString(format.str()); #else @@ -1675,8 +1777,8 @@ inline std::string mpreal::toString(int n, int b, mp_rnd_t mode) const if(mpfr_zero_p(mp)) return "0"; if(mpfr_nan_p(mp)) return "NaN"; - s = mpfr_get_str(NULL,&exp,b,0,mp,mode); - ns = mpfr_get_str(NULL,&exp,b,n,mp,mode); + s = mpfr_get_str(NULL, &exp, b, 0, mp, mode); + ns = mpfr_get_str(NULL, &exp, b, (std::max)(0,n), mp, mode); if(s!=NULL && ns!=NULL) { @@ -1761,17 +1863,43 @@ inline std::string mpreal::toString(int n, int b, mp_rnd_t mode) const ////////////////////////////////////////////////////////////////////////// // I/O +inline std::ostream& mpreal::output(std::ostream& os) const +{ + std::ostringstream format; + const std::ios::fmtflags flags = os.flags(); + + format << ((flags & std::ios::showpos) ? "%+" : "%"); + if (os.precision() >= 0) + format << '.' << os.precision() << "R*" + << ((flags & std::ios::floatfield) == std::ios::fixed ? 'f' : + (flags & std::ios::floatfield) == std::ios::scientific ? 'e' : + 'g'); + else + format << "R*e"; + + char *s = NULL; + if(!(mpfr_asprintf(&s, format.str().c_str(), + mpfr::mpreal::get_default_rnd(), + mpfr_srcptr()) + < 0)) + { + os << std::string(s); + mpfr_free_str(s); + } + return os; +} + inline std::ostream& operator<<(std::ostream& os, const mpreal& v) { - return os<(os.precision())); + return v.output(os); } inline std::istream& operator>>(std::istream &is, mpreal& v) { - // ToDo, use cout::hexfloat and other flags to setup base + // TODO: use cout::hexfloat and other flags to setup base std::string tmp; is >> tmp; - mpfr_set_str(v.mp, tmp.c_str(), 10, mpreal::get_default_rnd()); + mpfr_set_str(v.mpfr_ptr(), tmp.c_str(), 10, mpreal::get_default_rnd()); return is; } @@ -1784,53 +1912,53 @@ inline mp_prec_t digits2bits(int d) { const double LOG2_10 = 3.3219280948873624; - return (mp_prec_t) std::ceil( d * LOG2_10 ); + return mp_prec_t(std::ceil( d * LOG2_10 )); } inline int bits2digits(mp_prec_t b) { const double LOG10_2 = 0.30102999566398119; - return (int) std::floor( b * LOG10_2 ); + return int(std::floor( b * LOG10_2 )); } ////////////////////////////////////////////////////////////////////////// // Set/Get number properties -inline int sgn(const mpreal& v) +inline int sgn(const mpreal& op) { - int r = mpfr_signbit(v.mp); - return (r>0?-1:1); + int r = mpfr_signbit(op.mpfr_srcptr()); + return (r > 0? -1 : 1); } inline mpreal& mpreal::setSign(int sign, mp_rnd_t RoundingMode) { - mpfr_setsign(mp,mp,(sign < 0 ? 1 : 0),RoundingMode); + mpfr_setsign(mpfr_ptr(), mpfr_srcptr(), (sign < 0 ? 1 : 0), RoundingMode); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline int mpreal::getPrecision() const { - return mpfr_get_prec(mp); + return int(mpfr_get_prec(mpfr_srcptr())); } inline mpreal& mpreal::setPrecision(int Precision, mp_rnd_t RoundingMode) { - mpfr_prec_round(mp, Precision, RoundingMode); + mpfr_prec_round(mpfr_ptr(), Precision, RoundingMode); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline mpreal& mpreal::setInf(int sign) { - mpfr_set_inf(mp,sign); + mpfr_set_inf(mpfr_ptr(), sign); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } inline mpreal& mpreal::setNan() { - mpfr_set_nan(mp); + mpfr_set_nan(mpfr_ptr()); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } @@ -1839,9 +1967,9 @@ inline mpreal& mpreal::setZero(int sign) { #if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0)) - mpfr_set_zero(mp, sign); + mpfr_set_zero(mpfr_ptr(), sign); #else - mpfr_set_si(mp, 0, (mpfr_get_default_rounding_mode)()); + mpfr_set_si(mpfr_ptr(), 0, (mpfr_get_default_rounding_mode)()); setSign(sign); #endif @@ -1851,23 +1979,23 @@ inline mpreal& mpreal::setZero(int sign) inline mp_prec_t mpreal::get_prec() const { - return mpfr_get_prec(mp); + return mpfr_get_prec(mpfr_srcptr()); } inline void mpreal::set_prec(mp_prec_t prec, mp_rnd_t rnd_mode) { - mpfr_prec_round(mp,prec,rnd_mode); + mpfr_prec_round(mpfr_ptr(),prec,rnd_mode); MPREAL_MSVC_DEBUGVIEW_CODE; } inline mp_exp_t mpreal::get_exp () { - return mpfr_get_exp(mp); + return mpfr_get_exp(mpfr_srcptr()); } inline int mpreal::set_exp (mp_exp_t e) { - int x = mpfr_set_exp(mp, e); + int x = mpfr_set_exp(mpfr_ptr(), e); MPREAL_MSVC_DEBUGVIEW_CODE; return x; } @@ -1885,7 +2013,7 @@ inline const mpreal ldexp(const mpreal& v, mp_exp_t exp) mpreal x(v); // rounding is not important since we just increasing the exponent - mpfr_mul_2si(x.mp,x.mp,exp,mpreal::get_default_rnd()); + mpfr_mul_2si(x.mpfr_ptr(), x.mpfr_srcptr(), exp, mpreal::get_default_rnd()); return x; } @@ -1900,9 +2028,9 @@ inline mpreal machine_epsilon(const mpreal& x) /* the smallest eps such that x + eps != x */ if( x < 0) { - return nextabove(-x)+x; + return nextabove(-x) + x; }else{ - return nextabove(x)-x; + return nextabove( x) - x; } } @@ -1922,37 +2050,37 @@ inline mpreal maxval(mp_prec_t prec) inline bool isEqualUlps(const mpreal& a, const mpreal& b, int maxUlps) { - return abs(a - b) <= machine_epsilon((max)(abs(a), abs(b))) * maxUlps; + return abs(a - b) <= machine_epsilon((max)(abs(a), abs(b))) * maxUlps; } inline bool isEqualFuzzy(const mpreal& a, const mpreal& b, const mpreal& eps) { - return abs(a - b) <= (min)(abs(a), abs(b)) * eps; + return abs(a - b) <= eps; } inline bool isEqualFuzzy(const mpreal& a, const mpreal& b) { - return isEqualFuzzy(a, b, machine_epsilon((min)(abs(a), abs(b)))); + return isEqualFuzzy(a, b, machine_epsilon((max)(1, (min)(abs(a), abs(b))))); } inline const mpreal modf(const mpreal& v, mpreal& n) { - mpreal frac(v); + mpreal f(v); // rounding is not important since we are using the same number - mpfr_frac(frac.mp,frac.mp,mpreal::get_default_rnd()); - mpfr_trunc(n.mp,v.mp); - return frac; + mpfr_frac (f.mpfr_ptr(),f.mpfr_srcptr(),mpreal::get_default_rnd()); + mpfr_trunc(n.mpfr_ptr(),v.mpfr_srcptr()); + return f; } inline int mpreal::check_range (int t, mp_rnd_t rnd_mode) { - return mpfr_check_range(mp,t,rnd_mode); + return mpfr_check_range(mpfr_ptr(),t,rnd_mode); } inline int mpreal::subnormalize (int t,mp_rnd_t rnd_mode) { - int r = mpfr_subnormalize(mp,t,rnd_mode); + int r = mpfr_subnormalize(mpfr_ptr(),t,rnd_mode); MPREAL_MSVC_DEBUGVIEW_CODE; return r; } @@ -2005,8 +2133,11 @@ inline mp_exp_t mpreal::get_emax_max (void) mpfr_##f(y.mpfr_ptr(), x.mpfr_srcptr(), r); \ return y; -inline const mpreal sqr (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(sqr ); } -inline const mpreal sqrt (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(sqrt); } +inline const mpreal sqr (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) +{ MPREAL_UNARY_MATH_FUNCTION_BODY(sqr ); } + +inline const mpreal sqrt (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) +{ MPREAL_UNARY_MATH_FUNCTION_BODY(sqrt); } inline const mpreal sqrt(const unsigned long int x, mp_rnd_t r) { @@ -2032,14 +2163,14 @@ inline const mpreal sqrt(const int v, mp_rnd_t rnd_mode) else return mpreal().setNan(); // NaN } -inline const mpreal root(const mpreal& x, unsigned long int k, mp_rnd_t r) +inline const mpreal root(const mpreal& x, unsigned long int k, mp_rnd_t r = mpreal::get_default_rnd()) { mpreal y(0, mpfr_get_prec(x.mpfr_srcptr())); mpfr_root(y.mpfr_ptr(), x.mpfr_srcptr(), k, r); return y; } -inline const mpreal dim(const mpreal& a, const mpreal& b, mp_rnd_t r) +inline const mpreal dim(const mpreal& a, const mpreal& b, mp_rnd_t r = mpreal::get_default_rnd()) { mpreal y(0, mpfr_get_prec(a.mpfr_srcptr())); mpfr_dim(y.mpfr_ptr(), a.mpfr_srcptr(), b.mpfr_srcptr(), r); @@ -2048,161 +2179,130 @@ inline const mpreal dim(const mpreal& a, const mpreal& b, mp_rnd_t r) inline int cmpabs(const mpreal& a,const mpreal& b) { - return mpfr_cmpabs(a.mp,b.mp); + return mpfr_cmpabs(a.mpfr_ptr(), b.mpfr_srcptr()); } -inline int sin_cos(mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode) +inline int sin_cos(mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) { - return mpfr_sin_cos(s.mp,c.mp,v.mp,rnd_mode); + return mpfr_sin_cos(s.mpfr_ptr(), c.mpfr_ptr(), v.mpfr_srcptr(), rnd_mode); } inline const mpreal sqrt (const long double v, mp_rnd_t rnd_mode) { return sqrt(mpreal(v),rnd_mode); } inline const mpreal sqrt (const double v, mp_rnd_t rnd_mode) { return sqrt(mpreal(v),rnd_mode); } -inline const mpreal cbrt (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(cbrt ); } -inline const mpreal fabs (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(abs ); } -inline const mpreal abs (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(abs ); } -inline const mpreal log (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(log ); } -inline const mpreal log2 (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(log2 ); } -inline const mpreal log10 (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(log10); } -inline const mpreal exp (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(exp ); } -inline const mpreal exp2 (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(exp2 ); } -inline const mpreal exp10 (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(exp10); } -inline const mpreal cos (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(cos ); } -inline const mpreal sin (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(sin ); } -inline const mpreal tan (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(tan ); } -inline const mpreal sec (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(sec ); } -inline const mpreal csc (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(csc ); } -inline const mpreal cot (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(cot ); } -inline const mpreal acos (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(acos); } -inline const mpreal asin (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(asin); } -inline const mpreal atan (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(atan); } +inline const mpreal cbrt (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(cbrt ); } +inline const mpreal fabs (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(abs ); } +inline const mpreal abs (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(abs ); } +inline const mpreal log (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(log ); } +inline const mpreal log2 (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(log2 ); } +inline const mpreal log10 (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(log10); } +inline const mpreal exp (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(exp ); } +inline const mpreal exp2 (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(exp2 ); } +inline const mpreal exp10 (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(exp10); } +inline const mpreal cos (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(cos ); } +inline const mpreal sin (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(sin ); } +inline const mpreal tan (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(tan ); } +inline const mpreal sec (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(sec ); } +inline const mpreal csc (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(csc ); } +inline const mpreal cot (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(cot ); } +inline const mpreal acos (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(acos ); } +inline const mpreal asin (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(asin ); } +inline const mpreal atan (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(atan ); } -inline const mpreal acot (const mpreal& v, mp_rnd_t r) { return atan (1/v, r); } -inline const mpreal asec (const mpreal& v, mp_rnd_t r) { return acos (1/v, r); } -inline const mpreal acsc (const mpreal& v, mp_rnd_t r) { return asin (1/v, r); } -inline const mpreal acoth (const mpreal& v, mp_rnd_t r) { return atanh(1/v, r); } -inline const mpreal asech (const mpreal& v, mp_rnd_t r) { return acosh(1/v, r); } -inline const mpreal acsch (const mpreal& v, mp_rnd_t r) { return asinh(1/v, r); } +inline const mpreal acot (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) { return atan (1/v, r); } +inline const mpreal asec (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) { return acos (1/v, r); } +inline const mpreal acsc (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) { return asin (1/v, r); } +inline const mpreal acoth (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) { return atanh(1/v, r); } +inline const mpreal asech (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) { return acosh(1/v, r); } +inline const mpreal acsch (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) { return asinh(1/v, r); } -inline const mpreal cosh (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(cosh ); } -inline const mpreal sinh (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(sinh ); } -inline const mpreal tanh (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(tanh ); } -inline const mpreal sech (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(sech ); } -inline const mpreal csch (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(csch ); } -inline const mpreal coth (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(coth ); } -inline const mpreal acosh (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(acosh); } -inline const mpreal asinh (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(asinh); } -inline const mpreal atanh (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(atanh); } +inline const mpreal cosh (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(cosh ); } +inline const mpreal sinh (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(sinh ); } +inline const mpreal tanh (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(tanh ); } +inline const mpreal sech (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(sech ); } +inline const mpreal csch (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(csch ); } +inline const mpreal coth (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(coth ); } +inline const mpreal acosh (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(acosh); } +inline const mpreal asinh (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(asinh); } +inline const mpreal atanh (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(atanh); } -inline const mpreal log1p (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(log1p ); } -inline const mpreal expm1 (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(expm1 ); } -inline const mpreal eint (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(eint ); } -inline const mpreal gamma (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(gamma ); } -inline const mpreal lngamma (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(lngamma); } -inline const mpreal zeta (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(zeta ); } -inline const mpreal erf (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(erf ); } -inline const mpreal erfc (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(erfc ); } -inline const mpreal besselj0(const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(j0 ); } -inline const mpreal besselj1(const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(j1 ); } -inline const mpreal bessely0(const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(y0 ); } -inline const mpreal bessely1(const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(y1 ); } +inline const mpreal log1p (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(log1p ); } +inline const mpreal expm1 (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(expm1 ); } +inline const mpreal eint (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(eint ); } +inline const mpreal gamma (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(gamma ); } +inline const mpreal lngamma (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(lngamma); } +inline const mpreal zeta (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(zeta ); } +inline const mpreal erf (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(erf ); } +inline const mpreal erfc (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(erfc ); } +inline const mpreal besselj0(const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(j0 ); } +inline const mpreal besselj1(const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(j1 ); } +inline const mpreal bessely0(const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(y0 ); } +inline const mpreal bessely1(const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(y1 ); } -inline const mpreal atan2 (const mpreal& y, const mpreal& x, mp_rnd_t rnd_mode) +inline const mpreal atan2 (const mpreal& y, const mpreal& x, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) { - mpreal a; - mp_prec_t yp, xp; - - yp = y.get_prec(); - xp = x.get_prec(); - - a.set_prec(yp>xp?yp:xp); - - mpfr_atan2(a.mp, y.mp, x.mp, rnd_mode); - + mpreal a(0,(std::max)(y.getPrecision(), x.getPrecision())); + mpfr_atan2(a.mpfr_ptr(), y.mpfr_srcptr(), x.mpfr_srcptr(), rnd_mode); return a; } -inline const mpreal hypot (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode) +inline const mpreal hypot (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) { - mpreal a; - mp_prec_t yp, xp; - - yp = y.get_prec(); - xp = x.get_prec(); - - a.set_prec(yp>xp?yp:xp); - - mpfr_hypot(a.mp, x.mp, y.mp, rnd_mode); - + mpreal a(0,(std::max)(y.getPrecision(), x.getPrecision())); + mpfr_hypot(a.mpfr_ptr(), x.mpfr_srcptr(), y.mpfr_srcptr(), rnd_mode); return a; } -inline const mpreal remainder (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode) +inline const mpreal remainder (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) { - mpreal a; - mp_prec_t yp, xp; - - yp = y.get_prec(); - xp = x.get_prec(); - - a.set_prec(yp>xp?yp:xp); - - mpfr_remainder(a.mp, x.mp, y.mp, rnd_mode); - + mpreal a(0,(std::max)(y.getPrecision(), x.getPrecision())); + mpfr_remainder(a.mpfr_ptr(), x.mpfr_srcptr(), y.mpfr_srcptr(), rnd_mode); return a; } -inline const mpreal remquo (long* q, const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode) +inline const mpreal remquo (long* q, const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) { - mpreal a; - mp_prec_t yp, xp; - - yp = y.get_prec(); - xp = x.get_prec(); - - a.set_prec(yp>xp?yp:xp); - - mpfr_remquo(a.mp,q, x.mp, y.mp, rnd_mode); - + mpreal a(0,(std::max)(y.getPrecision(), x.getPrecision())); + mpfr_remquo(a.mpfr_ptr(),q, x.mpfr_srcptr(), y.mpfr_srcptr(), rnd_mode); return a; } -inline const mpreal fac_ui (unsigned long int v, mp_prec_t prec, mp_rnd_t rnd_mode) +inline const mpreal fac_ui (unsigned long int v, mp_prec_t prec = mpreal::get_default_prec(), + mp_rnd_t rnd_mode = mpreal::get_default_rnd()) { mpreal x(0, prec); - mpfr_fac_ui(x.mp,v,rnd_mode); + mpfr_fac_ui(x.mpfr_ptr(),v,rnd_mode); return x; } -inline const mpreal lgamma (const mpreal& v, int *signp, mp_rnd_t rnd_mode) +inline const mpreal lgamma (const mpreal& v, int *signp = 0, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) { mpreal x(v); int tsignp; - if(signp) mpfr_lgamma(x.mp,signp,v.mp,rnd_mode); - else mpfr_lgamma(x.mp,&tsignp,v.mp,rnd_mode); + if(signp) mpfr_lgamma(x.mpfr_ptr(), signp,v.mpfr_srcptr(),rnd_mode); + else mpfr_lgamma(x.mpfr_ptr(),&tsignp,v.mpfr_srcptr(),rnd_mode); return x; } -inline const mpreal besseljn (long n, const mpreal& x, mp_rnd_t r) +inline const mpreal besseljn (long n, const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { - mpreal y(0, mpfr_get_prec(x.mpfr_srcptr())); + mpreal y(0, x.getPrecision()); mpfr_jn(y.mpfr_ptr(), n, x.mpfr_srcptr(), r); return y; } -inline const mpreal besselyn (long n, const mpreal& x, mp_rnd_t r) +inline const mpreal besselyn (long n, const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { - mpreal y(0, mpfr_get_prec(x.mpfr_srcptr())); + mpreal y(0, x.getPrecision()); mpfr_yn(y.mpfr_ptr(), n, x.mpfr_srcptr(), r); return y; } -inline const mpreal fma (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode) +inline const mpreal fma (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) { mpreal a; mp_prec_t p1, p2, p3; @@ -2217,7 +2317,7 @@ inline const mpreal fma (const mpreal& v1, const mpreal& v2, const mpreal& v3, m return a; } -inline const mpreal fms (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode) +inline const mpreal fms (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) { mpreal a; mp_prec_t p1, p2, p3; @@ -2232,7 +2332,7 @@ inline const mpreal fms (const mpreal& v1, const mpreal& v2, const mpreal& v3, m return a; } -inline const mpreal agm (const mpreal& v1, const mpreal& v2, mp_rnd_t rnd_mode) +inline const mpreal agm (const mpreal& v1, const mpreal& v2, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) { mpreal a; mp_prec_t p1, p2; @@ -2247,7 +2347,7 @@ inline const mpreal agm (const mpreal& v1, const mpreal& v2, mp_rnd_t rnd_mode) return a; } -inline const mpreal sum (const mpreal tab[], unsigned long int n, mp_rnd_t rnd_mode) +inline const mpreal sum (const mpreal tab[], unsigned long int n, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) { mpreal x; mpfr_ptr* t; @@ -2264,23 +2364,23 @@ inline const mpreal sum (const mpreal tab[], unsigned long int n, mp_rnd_t rnd_m // MPFR 2.4.0 Specifics #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) -inline int sinh_cosh(mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode) +inline int sinh_cosh(mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) { return mpfr_sinh_cosh(s.mp,c.mp,v.mp,rnd_mode); } -inline const mpreal li2 (const mpreal& x, mp_rnd_t r) +inline const mpreal li2 (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(li2); } -inline const mpreal rem (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode) +inline const mpreal rem (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) { /* R = rem(X,Y) if Y != 0, returns X - n * Y where n = trunc(X/Y). */ return fmod(x, y, rnd_mode); } -inline const mpreal mod (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode) +inline const mpreal mod (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) { (void)rnd_mode; @@ -2305,7 +2405,7 @@ inline const mpreal mod (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode) return m; } -inline const mpreal fmod (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode) +inline const mpreal fmod (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) { mpreal a; mp_prec_t yp, xp; @@ -2320,7 +2420,7 @@ inline const mpreal fmod (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode) return a; } -inline const mpreal rec_sqrt(const mpreal& v, mp_rnd_t rnd_mode) +inline const mpreal rec_sqrt(const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) { mpreal x(v); mpfr_rec_sqrt(x.mp,v.mp,rnd_mode); @@ -2331,41 +2431,41 @@ inline const mpreal rec_sqrt(const mpreal& v, mp_rnd_t rnd_mode) ////////////////////////////////////////////////////////////////////////// // MPFR 3.0.0 Specifics #if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0)) -inline const mpreal digamma (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(digamma); } -inline const mpreal ai (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(ai); } +inline const mpreal digamma (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(digamma); } +inline const mpreal ai (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(ai); } #endif // MPFR 3.0.0 Specifics ////////////////////////////////////////////////////////////////////////// // Constants -inline const mpreal const_log2 (mp_prec_t p, mp_rnd_t r) +inline const mpreal const_log2 (mp_prec_t p = mpreal::get_default_prec(), mp_rnd_t r = mpreal::get_default_rnd()) { mpreal x(0, p); mpfr_const_log2(x.mpfr_ptr(), r); return x; } -inline const mpreal const_pi (mp_prec_t p, mp_rnd_t r) +inline const mpreal const_pi (mp_prec_t p = mpreal::get_default_prec(), mp_rnd_t r = mpreal::get_default_rnd()) { mpreal x(0, p); mpfr_const_pi(x.mpfr_ptr(), r); return x; } -inline const mpreal const_euler (mp_prec_t p, mp_rnd_t r) +inline const mpreal const_euler (mp_prec_t p = mpreal::get_default_prec(), mp_rnd_t r = mpreal::get_default_rnd()) { mpreal x(0, p); mpfr_const_euler(x.mpfr_ptr(), r); return x; } -inline const mpreal const_catalan (mp_prec_t p, mp_rnd_t r) +inline const mpreal const_catalan (mp_prec_t p = mpreal::get_default_prec(), mp_rnd_t r = mpreal::get_default_rnd()) { mpreal x(0, p); mpfr_const_catalan(x.mpfr_ptr(), r); return x; } -inline const mpreal const_infinity (int sign, mp_prec_t p, mp_rnd_t /*r*/) +inline const mpreal const_infinity (int sign = 1, mp_prec_t p = mpreal::get_default_prec()) { mpreal x(0, p); mpfr_set_inf(x.mpfr_ptr(), sign); @@ -2402,12 +2502,12 @@ inline const mpreal trunc(const mpreal& v) return x; } -inline const mpreal rint (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(rint ); } -inline const mpreal rint_ceil (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(rint_ceil ); } -inline const mpreal rint_floor (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(rint_floor); } -inline const mpreal rint_round (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(rint_round); } -inline const mpreal rint_trunc (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(rint_trunc); } -inline const mpreal frac (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(frac ); } +inline const mpreal rint (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(rint ); } +inline const mpreal rint_ceil (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(rint_ceil ); } +inline const mpreal rint_floor (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(rint_floor); } +inline const mpreal rint_round (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(rint_round); } +inline const mpreal rint_trunc (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(rint_trunc); } +inline const mpreal frac (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(frac ); } ////////////////////////////////////////////////////////////////////////// // Miscellaneous Functions @@ -2415,14 +2515,14 @@ inline void swap (mpreal& a, mpreal& b) { mpfr_swap(a.mp,b inline const mpreal (max)(const mpreal& x, const mpreal& y){ return (x>y?x:y); } inline const mpreal (min)(const mpreal& x, const mpreal& y){ return (x= MPFR_VERSION_NUM(3,0,0)) +#if (MPFR_VERSION >= MPFR_VERSION_NUM(3,1,0)) // use gmp_randinit_default() to init state, gmp_randclear() to clear -inline const mpreal urandom (gmp_randstate_t& state, mp_rnd_t rnd_mode) +inline const mpreal urandom (gmp_randstate_t& state, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) { mpreal x; mpfr_urandom(x.mp,state,rnd_mode); return x; } + +inline const mpreal grandom (gmp_randstate_t& state, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) +{ + mpreal x; + mpfr_grandom(x.mp, NULL, state, rnd_mode); + return x; +} + #endif #if (MPFR_VERSION <= MPFR_VERSION_NUM(2,4,2)) @@ -2480,7 +2588,7 @@ inline const mpreal random2 (mp_size_t size, mp_exp_t exp) // a = random(seed); <- initialization & first random number generation // a = random(); <- next random numbers generation // seed != 0 -inline const mpreal random(unsigned int seed) +inline const mpreal random(unsigned int seed = 0) { #if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0)) @@ -2504,6 +2612,25 @@ inline const mpreal random(unsigned int seed) } +#if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0)) +inline const mpreal grandom(unsigned int seed = 0) +{ + static gmp_randstate_t state; + static bool isFirstTime = true; + + if(isFirstTime) + { + gmp_randinit_default(state); + gmp_randseed_ui(state,0); + isFirstTime = false; + } + + if(seed != 0) gmp_randseed_ui(state,seed); + + return mpfr::grandom(state); +} +#endif + ////////////////////////////////////////////////////////////////////////// // Set/Get global properties inline void mpreal::set_default_prec(mp_prec_t prec) @@ -2523,21 +2650,21 @@ inline bool mpreal::fits_in_bits(double x, int n) return IsInf(x) || (std::modf ( std::ldexp ( std::frexp ( x, &i ), n ), &t ) == 0.0); } -inline const mpreal pow(const mpreal& a, const mpreal& b, mp_rnd_t rnd_mode) +inline const mpreal pow(const mpreal& a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) { mpreal x(a); mpfr_pow(x.mp,x.mp,b.mp,rnd_mode); return x; } -inline const mpreal pow(const mpreal& a, const mpz_t b, mp_rnd_t rnd_mode) +inline const mpreal pow(const mpreal& a, const mpz_t b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) { mpreal x(a); mpfr_pow_z(x.mp,x.mp,b,rnd_mode); return x; } -inline const mpreal pow(const mpreal& a, const unsigned long int b, mp_rnd_t rnd_mode) +inline const mpreal pow(const mpreal& a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) { mpreal x(a); mpfr_pow_ui(x.mp,x.mp,b,rnd_mode); @@ -2549,7 +2676,7 @@ inline const mpreal pow(const mpreal& a, const unsigned int b, mp_rnd_t rnd_mode return pow(a,static_cast(b),rnd_mode); } -inline const mpreal pow(const mpreal& a, const long int b, mp_rnd_t rnd_mode) +inline const mpreal pow(const mpreal& a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) { mpreal x(a); mpfr_pow_si(x.mp,x.mp,b,rnd_mode); @@ -2571,7 +2698,7 @@ inline const mpreal pow(const mpreal& a, const double b, mp_rnd_t rnd_mode) return pow(a,mpreal(b),rnd_mode); } -inline const mpreal pow(const unsigned long int a, const mpreal& b, mp_rnd_t rnd_mode) +inline const mpreal pow(const unsigned long int a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) { mpreal x(a); mpfr_ui_pow(x.mp,a,b.mp,rnd_mode); @@ -2586,13 +2713,13 @@ inline const mpreal pow(const unsigned int a, const mpreal& b, mp_rnd_t rnd_mode inline const mpreal pow(const long int a, const mpreal& b, mp_rnd_t rnd_mode) { if (a>=0) return pow(static_cast(a),b,rnd_mode); - else return pow(mpreal(a),b,rnd_mode); + else return pow(mpreal(a),b,rnd_mode); } inline const mpreal pow(const int a, const mpreal& b, mp_rnd_t rnd_mode) { if (a>=0) return pow(static_cast(a),b,rnd_mode); - else return pow(mpreal(a),b,rnd_mode); + else return pow(mpreal(a),b,rnd_mode); } inline const mpreal pow(const long double a, const mpreal& b, mp_rnd_t rnd_mode) @@ -2621,13 +2748,13 @@ inline const mpreal pow(const unsigned long int a, const unsigned int b, mp_rnd_ inline const mpreal pow(const unsigned long int a, const long int b, mp_rnd_t rnd_mode) { if(b>0) return pow(a,static_cast(b),rnd_mode); //mpfr_ui_pow_ui - else return pow(a,mpreal(b),rnd_mode); //mpfr_ui_pow + else return pow(a,mpreal(b),rnd_mode); //mpfr_ui_pow } inline const mpreal pow(const unsigned long int a, const int b, mp_rnd_t rnd_mode) { if(b>0) return pow(a,static_cast(b),rnd_mode); //mpfr_ui_pow_ui - else return pow(a,mpreal(b),rnd_mode); //mpfr_ui_pow + else return pow(a,mpreal(b),rnd_mode); //mpfr_ui_pow } inline const mpreal pow(const unsigned long int a, const long double b, mp_rnd_t rnd_mode) @@ -2824,7 +2951,7 @@ inline const mpreal pow(const double a, const int b, mp_rnd_t rnd_mode) // Non-throwing swap C++ idiom: http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-throwing_swap namespace std { - // only allowed to extend namespace std with specializations + // we are allowed to extend namespace std with specializations only template <> inline void swap(mpfr::mpreal& x, mpfr::mpreal& y) { @@ -2852,20 +2979,6 @@ namespace std static const bool tinyness_before = true; static const float_denorm_style has_denorm = denorm_absent; - - inline static float_round_style round_style() - { - mp_rnd_t r = mpfr::mpreal::get_default_rnd(); - - switch (r) - { - case MPFR_RNDN: return round_to_nearest; - case MPFR_RNDZ: return round_toward_zero; - case MPFR_RNDU: return round_toward_infinity; - case MPFR_RNDD: return round_toward_neg_infinity; - default: return round_indeterminate; - } - } inline static mpfr::mpreal (min) (mp_prec_t precision = mpfr::mpreal::get_default_prec()) { return mpfr::minval(precision); } inline static mpfr::mpreal (max) (mp_prec_t precision = mpfr::mpreal::get_default_prec()) { return mpfr::maxval(precision); } @@ -2873,7 +2986,7 @@ namespace std // Returns smallest eps such that 1 + eps != 1 (classic machine epsilon) inline static mpfr::mpreal epsilon(mp_prec_t precision = mpfr::mpreal::get_default_prec()) { return mpfr::machine_epsilon(precision); } - + // Returns smallest eps such that x + eps != x (relative machine epsilon) inline static mpfr::mpreal epsilon(const mpfr::mpreal& x) { return mpfr::machine_epsilon(x); } @@ -2881,7 +2994,7 @@ namespace std { mp_rnd_t r = mpfr::mpreal::get_default_rnd(); - if(r == MPFR_RNDN) return mpfr::mpreal(0.5, precision); + if(r == GMP_RNDN) return mpfr::mpreal(0.5, precision); else return mpfr::mpreal(1.0, precision); } @@ -2896,10 +3009,30 @@ namespace std MPREAL_PERMISSIVE_EXPR static const int min_exponent10 = (int) (MPFR_EMIN_DEFAULT * 0.3010299956639811); MPREAL_PERMISSIVE_EXPR static const int max_exponent10 = (int) (MPFR_EMAX_DEFAULT * 0.3010299956639811); - // Should be constant according to standard, but 'digits' depends on precision in MPFR +#ifdef MPREAL_HAVE_DYNAMIC_STD_NUMERIC_LIMITS - inline static int digits() { return mpfr::mpreal::get_default_prec(); } - inline static int digits(const mpfr::mpreal& x) { return x.getPrecision(); } + // Following members should be constant according to standard, but they can be variable in MPFR + // So we define them as functions here. + // + // This is preferable way for std::numeric_limits specialization. + // But it is incompatible with standard std::numeric_limits and might not work with other libraries, e.g. boost. + // See below for compatible implementation. + inline static float_round_style round_style() + { + mp_rnd_t r = mpfr::mpreal::get_default_rnd(); + + switch (r) + { + case GMP_RNDN: return round_to_nearest; + case GMP_RNDZ: return round_toward_zero; + case GMP_RNDU: return round_toward_infinity; + case GMP_RNDD: return round_toward_neg_infinity; + default: return round_indeterminate; + } + } + + inline static int digits() { return int(mpfr::mpreal::get_default_prec()); } + inline static int digits(const mpfr::mpreal& x) { return x.getPrecision(); } inline static int digits10(mp_prec_t precision = mpfr::mpreal::get_default_prec()) { @@ -2915,6 +3048,25 @@ namespace std { return digits10(precision); } +#else + // Digits and round_style are NOT constants when it comes to mpreal. + // If possible, please use functions digits() and round_style() defined above. + // + // These (default) values are preserved for compatibility with existing libraries, e.g. boost. + // Change them accordingly to your application. + // + // For example, if you use 256 bits of precision uniformly in your program, then: + // digits = 256 + // digits10 = 77 + // max_digits10 = 78 + // + // Approximate formula for decimal digits is: digits10 = floor(log10(2) * digits). See bits2digits() for more details. + + static const std::float_round_style round_style = round_to_nearest; + static const int digits = 53; + static const int digits10 = 15; + static const int max_digits10 = 16; +#endif }; } diff --git a/ground/gcs/src/libs/eigen/unsupported/test/polynomialsolver.cpp b/ground/gcs/src/libs/eigen/unsupported/test/polynomialsolver.cpp index 13f92169e..de79f1538 100644 --- a/ground/gcs/src/libs/eigen/unsupported/test/polynomialsolver.cpp +++ b/ground/gcs/src/libs/eigen/unsupported/test/polynomialsolver.cpp @@ -104,9 +104,7 @@ void evalSolverSugarFunction( const POLYNOMIAL& pols, const ROOTS& roots, const // 1) the roots found are correct // 2) the roots have distinct moduli - typedef typename POLYNOMIAL::Scalar Scalar; typedef typename REAL_ROOTS::Scalar Real; - typedef PolynomialSolver PolynomialSolverType; //Test realRoots std::vector< Real > calc_realRoots; diff --git a/ground/gcs/src/libs/glc_lib/.gitignore b/ground/gcs/src/libs/glc_lib/.gitignore deleted file mode 100644 index e2f6ef3be..000000000 --- a/ground/gcs/src/libs/glc_lib/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/qrc_glc_lib.cpp diff --git a/ground/gcs/src/libs/glc_lib/.no-auto-format b/ground/gcs/src/libs/glc_lib/.no-auto-format deleted file mode 100644 index e69de29bb..000000000 diff --git a/ground/gcs/src/libs/glc_lib/3DWidget/glc_3dwidget.cpp b/ground/gcs/src/libs/glc_lib/3DWidget/glc_3dwidget.cpp deleted file mode 100644 index e2eca1630..000000000 --- a/ground/gcs/src/libs/glc_lib/3DWidget/glc_3dwidget.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_3dwidget.cpp Implementation of the GLC_3DWidget class. - -#include "glc_3dwidget.h" - - -GLC_3DWidget::GLC_3DWidget(GLC_3DWidgetManagerHandle* pWidgetManagerHandle) -: QObject() -, m_Uid(glc::GLC_Gen3DWidgetID()) -, m_pWidgetManagerHandle(pWidgetManagerHandle) -, m_InstanceIdList() -{ - -} - -GLC_3DWidget::GLC_3DWidget(const GLC_3DWidget& widget) -: QObject() -, m_Uid(glc::GLC_Gen3DWidgetID()) -, m_pWidgetManagerHandle(widget.m_pWidgetManagerHandle) -, m_InstanceIdList() -{ - // Copy the 3Dview instance of the widget - const int size= widget.m_InstanceIdList.size(); - for (int i= 0; i < size; ++i) - { - GLC_3DViewInstance newInstance(widget.m_pWidgetManagerHandle->instanceHandle(widget.m_InstanceIdList.at(i))->deepCopy()); - GLC_uint newId= newInstance.id(); - m_InstanceIdList.append(newId); - m_pWidgetManagerHandle->add3DViewInstance(newInstance, m_Uid); - } -} - -GLC_3DWidget::~GLC_3DWidget() -{ - remove3DViewInstance(); -} - -bool GLC_3DWidget::operator==(const GLC_3DWidget& widget) const -{ - return this == &widget; -} - -GLC_3DWidget& GLC_3DWidget::operator=(const GLC_3DWidget& widget) -{ - if (this != &widget) - { - remove3DViewInstance(); - - m_Uid= widget.m_Uid; - m_pWidgetManagerHandle= widget.m_pWidgetManagerHandle; - m_InstanceIdList= widget.m_InstanceIdList; - - // Copy the 3Dview instance of the widget - const int size= widget.m_InstanceIdList.size(); - for (int i= 0; i < size; ++i) - { - GLC_3DViewInstance newInstance(widget.m_pWidgetManagerHandle->instanceHandle(widget.m_InstanceIdList.at(i))->deepCopy()); - GLC_uint newId= newInstance.id(); - m_InstanceIdList.append(newId); - m_pWidgetManagerHandle->add3DViewInstance(newInstance, m_Uid); - } - } - return *this; -} - -void GLC_3DWidget::setWidgetManager(GLC_3DWidgetManagerHandle* pWidgetManagerHandle) -{ - if (NULL != m_pWidgetManagerHandle) - { - m_pWidgetManagerHandle->take(m_Uid); - remove3DViewInstance(); - } - m_pWidgetManagerHandle= pWidgetManagerHandle; - - create3DviewInstance(); -} - -void GLC_3DWidget::setVisible(bool visible) -{ - if (NULL != m_pWidgetManagerHandle) - { - const int instanceCount= m_InstanceIdList.size(); - for (int i= 0; i < instanceCount; ++i) - { - m_pWidgetManagerHandle->instanceHandle(m_InstanceIdList.at(i))->setVisibility(visible); - } - resetViewState(); - } -} -////////////////////////////////////////////////////////////////////// -// Interaction Functions -////////////////////////////////////////////////////////////////////// -glc::WidgetEventFlag GLC_3DWidget::select(const GLC_Point3d&, GLC_uint) -{ - return glc::IgnoreEvent; -} - -glc::WidgetEventFlag GLC_3DWidget::unselect(const GLC_Point3d&, GLC_uint) -{ - return glc::IgnoreEvent; -} - -glc::WidgetEventFlag GLC_3DWidget::mouseOver(const GLC_Point3d&, GLC_uint) -{ - return glc::IgnoreEvent; -} - -glc::WidgetEventFlag GLC_3DWidget::mousePressed(const GLC_Point3d&, Qt::MouseButton, GLC_uint) -{ - return glc::IgnoreEvent; -} - -glc::WidgetEventFlag GLC_3DWidget::mouseReleased(Qt::MouseButton) -{ - return glc::IgnoreEvent; -} - -glc::WidgetEventFlag GLC_3DWidget::mouseMove(const GLC_Point3d&, Qt::MouseButtons, GLC_uint) -{ - return glc::IgnoreEvent; -} - - -////////////////////////////////////////////////////////////////////// -// Protected services functions -////////////////////////////////////////////////////////////////////// -void GLC_3DWidget::add3DViewInstance(const GLC_3DViewInstance& instance) -{ - m_pWidgetManagerHandle->add3DViewInstance(instance, m_Uid); - const GLC_uint instanceId= instance.id(); - m_InstanceIdList.append(instanceId); -} - -void GLC_3DWidget::remove3DViewInstance() -{ - if (NULL != m_pWidgetManagerHandle) - { - const int size= m_InstanceIdList.size(); - for (int i= 0; i < size; ++i) - { - m_pWidgetManagerHandle->remove3DViewInstance(m_InstanceIdList.at(i)); - } - } -} - -void GLC_3DWidget::set3DViewInstanceVisibility(int index, bool visibility) -{ - m_pWidgetManagerHandle->instanceHandle(m_InstanceIdList[index])->setVisibility(visibility); -} - - diff --git a/ground/gcs/src/libs/glc_lib/3DWidget/glc_3dwidget.h b/ground/gcs/src/libs/glc_lib/3DWidget/glc_3dwidget.h deleted file mode 100644 index 071d978ff..000000000 --- a/ground/gcs/src/libs/glc_lib/3DWidget/glc_3dwidget.h +++ /dev/null @@ -1,192 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_3dwidget.h Interface for the GLC_3DWidget class. - -#ifndef GLC_3DWIDGET_H_ -#define GLC_3DWIDGET_H_ -#include -#include -#include "../glc_config.h" -#include "../glc_global.h" -#include "glc_3dwidgetmanagerhandle.h" - -class GLC_3DViewInstance; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_3DWidget -/*! \brief GLC_3DWidget : The base class for 3D user interface class */ - -/*! GLC_3DWidget The 3D widget has a 3d representation and react on user - * interactions*/ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_3DWidget : public QObject -{ - Q_OBJECT - - typedef QList InstanceIdList; - -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Construct a 3d widget with the given 3DWidget manager handle - GLC_3DWidget(GLC_3DWidgetManagerHandle* pWidgetManagerHandle= NULL); - - //! Construct a 3d widget form the given 3d widget - GLC_3DWidget(const GLC_3DWidget& widget); - - //! Destructor - virtual ~GLC_3DWidget(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return this widget id - inline GLC_uint id() const - {return m_Uid;} - - //! Return true if this 3d widget is equal to the given 3d widget - bool operator==(const GLC_3DWidget& widget) const; - - //! Return true if the given instance id belongs to this widget - inline bool instanceBelongTo(GLC_uint id) const - {return m_InstanceIdList.contains(id);} - - //! Return the widget manager of this 3d widget - inline const GLC_3DWidgetManagerHandle* widgetManagerHandle() const - {return m_pWidgetManagerHandle;} - - //! Return true if this widget has a 3DWidgetManager - inline bool has3DWidgetManager() const - {return (NULL == m_pWidgetManagerHandle);} - - //! Return true if otho is used - inline bool useOrtho() const - {return m_pWidgetManagerHandle->useOrtho();} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Copy the given widget in this widget and return a reference on this widget - virtual GLC_3DWidget& operator=(const GLC_3DWidget& widget); - - //! Set the given widgetManager to this widget - void setWidgetManager(GLC_3DWidgetManagerHandle* pWidgetManagerHandle); - - //! Update widget representation - virtual void updateWidgetRep(){}; - - //! Set the visibility of 3DView Instance of this widget - void setVisible(bool visible); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Interaction Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! This widget as been selected - virtual glc::WidgetEventFlag select(const GLC_Point3d&, GLC_uint id); - - //! This widget as been unselected - virtual glc::WidgetEventFlag unselect(const GLC_Point3d&, GLC_uint id); - - //! The mouse is over this widget - virtual glc::WidgetEventFlag mouseOver(const GLC_Point3d&, GLC_uint id); - - //! The mouse is over this widget and a mousse button is pressed - virtual glc::WidgetEventFlag mousePressed(const GLC_Point3d&, Qt::MouseButton, GLC_uint id); - - //! The mouse is over this widget and a mousse button is released - virtual glc::WidgetEventFlag mouseReleased(Qt::MouseButton); - - //! This widget is selected and the mousse move with a pressed buttons - virtual glc::WidgetEventFlag mouseMove(const GLC_Point3d&, Qt::MouseButtons, GLC_uint id); - -//@} - -signals: - //! Sub class must emit this signal if they changed - void asChanged(); - -////////////////////////////////////////////////////////////////////// -// Protected services function -////////////////////////////////////////////////////////////////////// -protected: - //! Create the 3DView instance of this 3d widget - virtual void create3DviewInstance()= 0; - - //! Return true if this 3DWidget hasen't 3d instance - inline bool isEmpty() const - {return m_InstanceIdList.isEmpty();} - - //! Add 3D view instance in the widget manager handle - void add3DViewInstance(const GLC_3DViewInstance& instance); - - //! Return the 3D view instance handle from the given index - inline GLC_3DViewInstance* instanceHandle(int index) - {return m_pWidgetManagerHandle->instanceHandle(m_InstanceIdList.at(index));} - - //! Remove instance of this 3d widget from the 3D widget manager handle - void remove3DViewInstance(); - - //! Set the specified 3D view instance visibility - void set3DViewInstanceVisibility(int index, bool visibility); - - //! Return the index of the given instance id - inline int indexOfIntsanceId(GLC_uint id) - {return m_InstanceIdList.indexOf(id);} - - //! Reset the view state of this 3DWidget - virtual void resetViewState()= 0; - -////////////////////////////////////////////////////////////////////// -// Private services function -////////////////////////////////////////////////////////////////////// -private: - -////////////////////////////////////////////////////////////////////// -// Private Member -////////////////////////////////////////////////////////////////////// -private: - //! The id of this 3d widget - /*! Generated on GLC_3DWidget construction*/ - GLC_uint m_Uid; - - //! Pointer to this widget manager handle - GLC_3DWidgetManagerHandle* m_pWidgetManagerHandle; - - //! The List of this widget instance id - QList m_InstanceIdList; - -}; - -#endif /* GLC_3DWIDGET_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/3DWidget/glc_3dwidgetmanager.cpp b/ground/gcs/src/libs/glc_lib/3DWidget/glc_3dwidgetmanager.cpp deleted file mode 100644 index 5b7edf3ed..000000000 --- a/ground/gcs/src/libs/glc_lib/3DWidget/glc_3dwidgetmanager.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_3dwidgetmanager.cpp Implementation of the GLC_3DWidgetManager class. - -#include "glc_3dwidgetmanager.h" - -GLC_3DWidgetManager::GLC_3DWidgetManager(GLC_Viewport* pViewport) -:m_pWidgetManagerHandle(new GLC_3DWidgetManagerHandle(pViewport)) -{ - -} - -GLC_3DWidgetManager::GLC_3DWidgetManager(const GLC_3DWidgetManager& widgetManager) -: m_pWidgetManagerHandle(widgetManager.m_pWidgetManagerHandle) -{ - m_pWidgetManagerHandle->increment(); -} - -GLC_3DWidgetManager::~GLC_3DWidgetManager() -{ - m_pWidgetManagerHandle->decrement(); - if (m_pWidgetManagerHandle->isOrphan()) - { - delete m_pWidgetManagerHandle; - } -} diff --git a/ground/gcs/src/libs/glc_lib/3DWidget/glc_3dwidgetmanager.h b/ground/gcs/src/libs/glc_lib/3DWidget/glc_3dwidgetmanager.h deleted file mode 100644 index 28fa7c42d..000000000 --- a/ground/gcs/src/libs/glc_lib/3DWidget/glc_3dwidgetmanager.h +++ /dev/null @@ -1,141 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_3dwidgetmanager.h Interface for the GLC_3DWidgetManager class. - -#ifndef GLC_3DWIDGETMANAGER_H_ -#define GLC_3DWIDGETMANAGER_H_ - -#include "glc_3dwidgetmanagerhandle.h" - -#include "../glc_config.h" - -class QMouseEvent; - -class GLC_LIB_EXPORT GLC_3DWidgetManager -{ - -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Construct the 3d widget manager associted to the given Viewport - GLC_3DWidgetManager(GLC_Viewport* pViewport); - - //! Construct a 3d widget manager from the given 3D widget manager - GLC_3DWidgetManager(const GLC_3DWidgetManager& widgetManager); - - //! Destructor - ~GLC_3DWidgetManager(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the boundingBox of 3dwidget - inline GLC_BoundingBox boundingBox() - {return m_pWidgetManagerHandle->boundingBox();} - - //! Return true if this manager contains the given widget id - inline bool contains3DWidget(GLC_uint id) const - {return m_pWidgetManagerHandle->contains3DWidget(id);} - - //! Return the 3DWidget of the given widget id - inline GLC_3DWidget* widget(GLC_uint id) const - {return m_pWidgetManagerHandle->widget(id);} - - //! Return true if this 3DWidget manager is empty - inline bool isEmpty() const - {return m_pWidgetManagerHandle->isEmpty();} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Add the given 3D widget into this manager - inline void add3DWidget(GLC_3DWidget* p3DWidget) - {m_pWidgetManagerHandle->add3DWidget(p3DWidget);} - - //! Remove the 3D widget with the given id from this manager - /*! Associated 3D view instance are removed*/ - inline void remove3DWidget(GLC_uint id) - {m_pWidgetManagerHandle->remove3DWidget(id);} - - //! Clear all widget from this manager - inline void clear() - {m_pWidgetManagerHandle->clear();} - - //! Set the visibility of the given 3D widget id - inline void setWidgetVisible(GLC_uint id, bool visible) - {m_pWidgetManagerHandle->setWidgetVisible(id, visible);} - -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Interaction Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Recieve Mouse double click event with the given instance id Return true if the event is catch - inline glc::WidgetEventFlag mouseDoubleClickEvent(QMouseEvent * pEvent) - {return m_pWidgetManagerHandle->mouseDoubleClickEvent(pEvent);} - - //! Recieve Mouse move event with the given instance id Return true if the event is catch - inline glc::WidgetEventFlag mouseMoveEvent(QMouseEvent * pEvent) - {return m_pWidgetManagerHandle->mouseMoveEvent(pEvent);} - - //! Recieve Mouse press event with the given instance id Return true if the event is catch - inline glc::WidgetEventFlag mousePressEvent(QMouseEvent * pEvent) - {return m_pWidgetManagerHandle->mousePressEvent(pEvent);} - - //! Recieve Mouse release event with the given instance id Return true if the event is catch - inline glc::WidgetEventFlag mouseReleaseEvent(QMouseEvent * pEvent) - {return m_pWidgetManagerHandle->mouseReleaseEvent(pEvent);} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Render the 3DWidget of this manager - inline void render() - {m_pWidgetManagerHandle->render();} - -//@} - -////////////////////////////////////////////////////////////////////// -// Private Member -////////////////////////////////////////////////////////////////////// -private: - //! The widget manager handle - GLC_3DWidgetManagerHandle* m_pWidgetManagerHandle; - -}; - -#endif /* GLC_3DWIDGETMANAGER_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/3DWidget/glc_3dwidgetmanagerhandle.cpp b/ground/gcs/src/libs/glc_lib/3DWidget/glc_3dwidgetmanagerhandle.cpp deleted file mode 100644 index 0dcb88876..000000000 --- a/ground/gcs/src/libs/glc_lib/3DWidget/glc_3dwidgetmanagerhandle.cpp +++ /dev/null @@ -1,257 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_3dwidgetmanagerhandle.cpp Implementation of the GLC_3DWidgetManagerHandle class. - -#include "glc_3dwidgetmanagerhandle.h" - -#include "../viewport/glc_viewport.h" -#include "../sceneGraph/glc_3dviewinstance.h" -#include "glc_3dwidget.h" -#include - -GLC_3DWidgetManagerHandle::GLC_3DWidgetManagerHandle(GLC_Viewport* pViewport) -: m_Collection() -, m_Count(1) -, m_3DWidgetHash() -, m_MapBetweenInstanceWidget() -, m_pViewport(pViewport) -, m_Active3DWidgetId(0) -, m_Preselected3DWidgetId(0) -{ - -} - -GLC_3DWidgetManagerHandle::~GLC_3DWidgetManagerHandle() -{ - QHash::iterator iWidget= m_3DWidgetHash.begin(); - while (m_3DWidgetHash.constEnd() != iWidget) - { - delete iWidget.value(); - ++iWidget; - } -} - -void GLC_3DWidgetManagerHandle::add3DWidget(GLC_3DWidget* p3DWidget) -{ - Q_ASSERT(!m_MapBetweenInstanceWidget.contains(p3DWidget->id())); - m_3DWidgetHash.insert(p3DWidget->id(), p3DWidget); - p3DWidget->setWidgetManager(this); -} - -void GLC_3DWidgetManagerHandle::remove3DWidget(GLC_uint id) -{ - Q_ASSERT(m_3DWidgetHash.contains(id)); - delete m_3DWidgetHash.take(id); - if (m_Active3DWidgetId == id) m_Active3DWidgetId= 0; - -} - -GLC_3DWidget* GLC_3DWidgetManagerHandle::take(GLC_uint id) -{ - Q_ASSERT(m_3DWidgetHash.contains(id)); - return m_3DWidgetHash.take(id); -} - -void GLC_3DWidgetManagerHandle::add3DViewInstance(const GLC_3DViewInstance& instance, GLC_uint widgetId) -{ - const GLC_uint instanceId= instance.id(); - Q_ASSERT(!m_MapBetweenInstanceWidget.contains(instanceId)); - Q_ASSERT(!m_Collection.contains(instanceId)); - - m_MapBetweenInstanceWidget.insert(instanceId, widgetId); - m_Collection.add(instance, 0); -} - -void GLC_3DWidgetManagerHandle::remove3DViewInstance(GLC_uint id) -{ - Q_ASSERT(m_MapBetweenInstanceWidget.contains(id)); - Q_ASSERT(m_Collection.contains(id)); - m_Collection.remove(id); - m_MapBetweenInstanceWidget.remove(id); -} - -void GLC_3DWidgetManagerHandle::clear() -{ - m_Active3DWidgetId= 0; - QHash::iterator iWidget= m_3DWidgetHash.begin(); - while (m_3DWidgetHash.constEnd() != iWidget) - { - delete iWidget.value(); - ++iWidget; - } - m_3DWidgetHash.clear(); - m_Collection.clear(); - m_MapBetweenInstanceWidget.clear(); -} - -void GLC_3DWidgetManagerHandle::setWidgetVisible(GLC_uint id, bool visible) -{ - if (id == m_Active3DWidgetId) m_Active3DWidgetId= 0; - Q_ASSERT(m_3DWidgetHash.contains(id)); - m_3DWidgetHash.value(id)->setVisible(visible); -} - -glc::WidgetEventFlag GLC_3DWidgetManagerHandle::mouseDoubleClickEvent(QMouseEvent *) -{ - - if (hasAnActiveWidget()) - { - - } - return glc::IgnoreEvent; -} - -glc::WidgetEventFlag GLC_3DWidgetManagerHandle::mouseMoveEvent(QMouseEvent * pEvent) -{ - glc::WidgetEventFlag eventFlag= glc::IgnoreEvent; - // Get the 3D cursor position and the id under - QPair cursorInfo= select(pEvent); - const GLC_uint selectedId= cursorInfo.first; - const GLC_Point3d pos(cursorInfo.second); - - if (hasAnActiveWidget()) - { - GLC_3DWidget* pActiveWidget= m_3DWidgetHash.value(m_Active3DWidgetId); - eventFlag= pActiveWidget->mouseMove(pos, pEvent->buttons(), selectedId); - } - else - { - if (m_MapBetweenInstanceWidget.contains(selectedId)) - { - const GLC_uint select3DWidgetId= m_MapBetweenInstanceWidget.value(selectedId); - - if (m_Preselected3DWidgetId != select3DWidgetId) - { - m_Preselected3DWidgetId= m_MapBetweenInstanceWidget.value(selectedId); - GLC_3DWidget* pActiveWidget= m_3DWidgetHash.value(m_Preselected3DWidgetId); - eventFlag= pActiveWidget->mouseOver(pos, selectedId); - } - else if (0 != m_Preselected3DWidgetId && (m_Preselected3DWidgetId != select3DWidgetId)) - { - eventFlag= m_3DWidgetHash.value(m_Preselected3DWidgetId)->unselect(pos, selectedId); - } - - } - else if (0 != m_Preselected3DWidgetId) - { - eventFlag= m_3DWidgetHash.value(m_Preselected3DWidgetId)->unselect(pos, selectedId); - m_Preselected3DWidgetId= 0; - } - } - return eventFlag; -} - -glc::WidgetEventFlag GLC_3DWidgetManagerHandle::mousePressEvent(QMouseEvent * pEvent) -{ - glc::WidgetEventFlag eventFlag= glc::IgnoreEvent; - - if (pEvent->button() == Qt::LeftButton) - { - // Get the 3D cursor position and the id under - QPair cursorInfo= select(pEvent); - const GLC_uint selectedId= cursorInfo.first; - const GLC_Point3d pos(cursorInfo.second); - - if (hasAnActiveWidget()) - { - GLC_3DWidget* pActiveWidget= m_3DWidgetHash.value(m_Active3DWidgetId); - const bool activeWidgetUnderMouse= pActiveWidget->instanceBelongTo(selectedId); - if (activeWidgetUnderMouse) - { - eventFlag= pActiveWidget->mousePressed(pos, pEvent->button(), selectedId); - } - else - { - eventFlag= pActiveWidget->unselect(pos, selectedId); - if (m_MapBetweenInstanceWidget.contains(selectedId)) - { - m_Active3DWidgetId= m_MapBetweenInstanceWidget.value(selectedId); - pActiveWidget= m_3DWidgetHash.value(m_Active3DWidgetId); - eventFlag= pActiveWidget->select(pos, selectedId); - } - else - { - m_Active3DWidgetId= 0; - } - } - - } - else - { - if (m_MapBetweenInstanceWidget.contains(selectedId)) - { - m_Active3DWidgetId= m_MapBetweenInstanceWidget.value(selectedId); - GLC_3DWidget* pActiveWidget= m_3DWidgetHash.value(m_Active3DWidgetId); - eventFlag= pActiveWidget->select(pos, selectedId); - } - } - } - - return eventFlag; -} - -glc::WidgetEventFlag GLC_3DWidgetManagerHandle::mouseReleaseEvent(QMouseEvent * pEvent) -{ - glc::WidgetEventFlag eventFlag= glc::IgnoreEvent; - if (hasAnActiveWidget() && (pEvent->button() == Qt::LeftButton)) - { - - GLC_3DWidget* pActiveWidget= m_3DWidgetHash.value(m_Active3DWidgetId); - - eventFlag= pActiveWidget->mouseReleased(pEvent->button()); - } - return eventFlag; -} - -void GLC_3DWidgetManagerHandle::render() -{ - // Signal 3DWidget that the view as changed - QHash::iterator iWidget= m_3DWidgetHash.begin(); - while (m_3DWidgetHash.constEnd() != iWidget) - { - iWidget.value()->updateWidgetRep(); - ++iWidget; - } - - // Render the 3D widget - m_Collection.render(0, glc::WireRenderFlag); - m_Collection.render(0, glc::TransparentRenderFlag); - m_Collection.render(1, glc::WireRenderFlag); - if (GLC_State::glslUsed()) - { - m_Collection.renderShaderGroup(glc::WireRenderFlag); - m_Collection.renderShaderGroup(glc::TransparentRenderFlag); - } -} - -QPair GLC_3DWidgetManagerHandle::select(QMouseEvent* event) -{ - - GLC_uint selectionId= m_pViewport->selectOnPreviousRender(event->x(), event->y()); - const GLC_Point3d selectedPoint(m_pViewport->unProject(event->x(), event->y())); - - QPair selection; - selection.first= selectionId; - selection.second= selectedPoint; - - return selection; -} diff --git a/ground/gcs/src/libs/glc_lib/3DWidget/glc_3dwidgetmanagerhandle.h b/ground/gcs/src/libs/glc_lib/3DWidget/glc_3dwidgetmanagerhandle.h deleted file mode 100644 index 1c7d4ce31..000000000 --- a/ground/gcs/src/libs/glc_lib/3DWidget/glc_3dwidgetmanagerhandle.h +++ /dev/null @@ -1,199 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_3dwidgetmanagerhandle.h Interface for the GLC_3DWidgetManagerHandle class. - -#ifndef GLC_3DWIDGETMANAGERHANDLE_H_ -#define GLC_3DWIDGETMANAGERHANDLE_H_ - -#include "../glc_config.h" -#include "../sceneGraph/glc_3dviewcollection.h" -#include "../viewport/glc_viewport.h" - -class GLC_3DVIewInstance; -class GLC_3DWidget; - -class GLC_LIB_EXPORT GLC_3DWidgetManagerHandle -{ - -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Construct a 3D widget manager attached to the given viewport - GLC_3DWidgetManagerHandle(GLC_Viewport* pViewport); - - //! Destructor - ~GLC_3DWidgetManagerHandle(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return true if there is only one widget manager associated to this handle - inline bool isOrphan() const - {return 0 == m_Count;} - - //! Return the 3DView instance of the given id - inline GLC_3DViewInstance* instanceHandle(GLC_uint id) - {return m_Collection.instanceHandle(id);} - - //! Return true if this 3DWidget manager has active widget - inline bool hasAnActiveWidget() const - {return 0 != m_Active3DWidgetId;} - - //! Return an handle to the camera of the viewport of this manager - inline const GLC_Camera* cameraHandle() const - {return m_pViewport->cameraHandle();} - - //! Return the boundingBox of 3dwidget - inline GLC_BoundingBox boundingBox() - {return m_Collection.boundingBox();} - - //! Return true if the viewport use orthographic projection - inline bool useOrtho() const - {return m_pViewport->useOrtho();} - - //! Return the tangent value of the viewport - double viewportTangent() const - {return m_pViewport->viewTangent();} - - //! Return the viewport of this manager - inline GLC_Viewport* viewport() const - {return m_pViewport;} - - //! Return true if this manager contains the given widget id - inline bool contains3DWidget(GLC_uint id) const - {return m_3DWidgetHash.contains(id);} - - //! Return the 3DWidget of the given widget id - inline GLC_3DWidget* widget(GLC_uint id) const - {return m_3DWidgetHash.value(id);} - - //! Return true if this 3DWidget manager is empty - inline bool isEmpty() const - {return m_3DWidgetHash.isEmpty();} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Increment the number of world - inline void increment() - {++m_Count;} - - //! Decrement the number of world - inline void decrement() - {--m_Count;} - - //! Add the given 3D widget into this manager - void add3DWidget(GLC_3DWidget* p3DWidget); - - //! Remove the 3D widget with the given id from this manager - /*! Associated 3D view instance are removed*/ - void remove3DWidget(GLC_uint id); - - //! Take the 3D widget with the given id from this manager - /*! Associated 3D view instance are NOT removed*/ - GLC_3DWidget* take(GLC_uint id); - - //! Add the given 3D view instance link to the given 3D widget into this manager - void add3DViewInstance(const GLC_3DViewInstance& instance, GLC_uint widgetId); - - //! Remove the 3D view instance with the given id from this manager collection - void remove3DViewInstance(GLC_uint id); - - //! Remove all 3D view instance from this manager - void clear(); - - //! Set the visibility of the given 3D widget id - void setWidgetVisible(GLC_uint id, bool visible); - -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Interaction Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Recieve Mouse double click event with the given instance id Return true if the event is catch - glc::WidgetEventFlag mouseDoubleClickEvent(QMouseEvent * pEvent); - - //! Recieve Mouse move event with the given instance id Return true if the event is catch - glc::WidgetEventFlag mouseMoveEvent(QMouseEvent * pEvent); - - //! Recieve Mouse press event with the given instance id Return true if the event is catch - glc::WidgetEventFlag mousePressEvent(QMouseEvent * pEvent); - - //! Recieve Mouse release event with the given instance id Return true if the event is catch - glc::WidgetEventFlag mouseReleaseEvent(QMouseEvent * pEvent); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Render the 3DWidget of this manager - void render(); - -//@} - -////////////////////////////////////////////////////////////////////// -// Private services function -////////////////////////////////////////////////////////////////////// -private: - //! Make selection according to the given mouse event - QPair select(QMouseEvent* event); - -////////////////////////////////////////////////////////////////////// -// Private Member -////////////////////////////////////////////////////////////////////// -private: - //! The Collection - GLC_3DViewCollection m_Collection; - - //! Widget manager count - int m_Count; - - //! The 3D widget hash table - QHash m_3DWidgetHash; - - //! The papping between 3D view instance and 3DWidget - QHash m_MapBetweenInstanceWidget; - - //! The viewport of this 3d widget manager handle - GLC_Viewport* m_pViewport; - - //! The active 3Dwidget id - GLC_uint m_Active3DWidgetId; - - //! The preselected 3DWidget - GLC_uint m_Preselected3DWidgetId; -}; - -#endif /* GLC_3DWIDGETMANAGERHANDLE_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/3DWidget/glc_abstractmanipulator.cpp b/ground/gcs/src/libs/glc_lib/3DWidget/glc_abstractmanipulator.cpp deleted file mode 100644 index b09f37b34..000000000 --- a/ground/gcs/src/libs/glc_lib/3DWidget/glc_abstractmanipulator.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -#include "glc_abstractmanipulator.h" -#include "../viewport/glc_viewport.h" -#include "../maths/glc_geomtools.h" - -#include - -GLC_AbstractManipulator::GLC_AbstractManipulator(GLC_Viewport* pViewport) -: m_pViewport(pViewport) -, m_SliddingPlane() -, m_PreviousPosition() -, m_IsInManipulateState(false) -{ - Q_ASSERT(NULL != m_pViewport); -} - -GLC_AbstractManipulator::GLC_AbstractManipulator(const GLC_AbstractManipulator& abstractManipulator) -: m_pViewport(abstractManipulator.m_pViewport) -, m_SliddingPlane(abstractManipulator.m_SliddingPlane) -, m_PreviousPosition(abstractManipulator.m_PreviousPosition) -, m_IsInManipulateState(abstractManipulator.m_IsInManipulateState) -{ - -} - -GLC_AbstractManipulator::~GLC_AbstractManipulator() -{ -} - -void GLC_AbstractManipulator::enterManipulateState(const GLC_Point3d& startPoint) -{ - m_SliddingPlane= GLC_Plane(m_pViewport->cameraHandle()->forward().normalize(), startPoint); - - m_PreviousPosition = startPoint; - m_IsInManipulateState= true; -} - -GLC_Matrix4x4 GLC_AbstractManipulator::manipulate(const GLC_Point3d& newPoint) -{ - Q_ASSERT(m_IsInManipulateState); - - // Select the projection direction - GLC_Vector3d projectionDirection; - if (m_pViewport->useOrtho()) - { - projectionDirection= m_pViewport->cameraHandle()->forward().normalize(); - } - else - { - projectionDirection= (newPoint - m_pViewport->cameraHandle()->eye()); - } - - // Use concrete class to compute matrix - GLC_Matrix4x4 transformation(doManipulate(newPoint, projectionDirection)); - - return transformation; -} diff --git a/ground/gcs/src/libs/glc_lib/3DWidget/glc_abstractmanipulator.h b/ground/gcs/src/libs/glc_lib/3DWidget/glc_abstractmanipulator.h deleted file mode 100644 index 52bd64dd9..000000000 --- a/ground/gcs/src/libs/glc_lib/3DWidget/glc_abstractmanipulator.h +++ /dev/null @@ -1,125 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -#ifndef GLC_ABSTRACTMANIPULATOR_H_ -#define GLC_ABSTRACTMANIPULATOR_H_ - -#include "../maths/glc_vector3d.h" -#include "../maths/glc_matrix4x4.h" -#include "../maths/glc_plane.h" - -#include "../glc_config.h" - -class GLC_Viewport; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_AbstractManipulator -/*! \brief GLC_AbstractManipulator : Base class for all manipulator*/ - -/*! GLC_AbstractManipulator */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_AbstractManipulator -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Construct an abstract manipulator with the given viewport - GLC_AbstractManipulator(GLC_Viewport* pViewport); - - //! Copy constructor - GLC_AbstractManipulator(const GLC_AbstractManipulator& abstractManipulator); - - //! Destructor - virtual ~GLC_AbstractManipulator(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return true if this manipulator is in manipulate state - inline bool isInManipulateState() const - {return m_IsInManipulateState;} - - //! Return a const reference on the previous position - const GLC_Point3d& previousPosition() const - {return m_PreviousPosition;} - - //! Return the viewport of this manipulator - inline GLC_Viewport* viewportHandle() const - {return m_pViewport;} - - //! Clone the concrete manipulator - virtual GLC_AbstractManipulator* clone() const= 0; - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Put this manipulator in manipulate state - void enterManipulateState(const GLC_Point3d& startPoint); - - //! Manipulate this manipulator and return the moving matrix - GLC_Matrix4x4 manipulate(const GLC_Point3d& newPoint); - - //! Exit this manipulator of manipulate state - inline void exitManipulateState() - {m_IsInManipulateState= false;} - - //! Set the viewport of this manipulator - inline void setViewport(GLC_Viewport* pViewport) - {m_pViewport= pViewport;} - -//@} - -////////////////////////////////////////////////////////////////////// -// Protected services function -////////////////////////////////////////////////////////////////////// -protected: - //! Manipulate the concret manipulator and return the moving matrix - virtual GLC_Matrix4x4 doManipulate(const GLC_Point3d& newPoint, const GLC_Vector3d& projectionDirection)= 0; - -////////////////////////////////////////////////////////////////////// -// protected Member -////////////////////////////////////////////////////////////////////// -protected: - //! The viewport associated with this manipulator - GLC_Viewport* m_pViewport; - - //! The currentSlidding plane - GLC_Plane m_SliddingPlane; - - //! The previous position - GLC_Point3d m_PreviousPosition; - - //! Flag to know if this manipulator is in manipulate state - bool m_IsInManipulateState; - -}; - -#endif /* GLC_ABSTRACTMANIPULATOR_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/3DWidget/glc_axis.cpp b/ground/gcs/src/libs/glc_lib/3DWidget/glc_axis.cpp deleted file mode 100644 index 21342f135..000000000 --- a/ground/gcs/src/libs/glc_lib/3DWidget/glc_axis.cpp +++ /dev/null @@ -1,315 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_axis.cpp Implementation of the GLC_Axis class. - -#include "glc_axis.h" -#include "../glc_factory.h" -#include "../maths/glc_line3d.h" -#include "../maths/glc_geomtools.h" -#include "../geometry/glc_cylinder.h" -#include "../geometry/glc_cone.h" -#include "glc_pullmanipulator.h" - -GLC_Axis::GLC_Axis(const GLC_Point3d& center, GLC_3DWidgetManagerHandle* pWidgetManagerHandle) -: GLC_3DWidget(pWidgetManagerHandle) -, m_Center(center) -, m_ScaleFactor(1.0) -, m_CurrentManipulator(NoneManipulator) -, m_pCurrentManipulator(NULL) -, m_AxisLength(1.0) -, m_AxisRadiusRatio(0.03) -{ - -} - -GLC_Axis::GLC_Axis(const GLC_Axis& axis) -: GLC_3DWidget(axis) -, m_Center(axis.m_Center) -, m_ScaleFactor(axis.m_ScaleFactor) -, m_CurrentManipulator(axis.m_CurrentManipulator) -, m_pCurrentManipulator(NULL) -, m_AxisLength(axis.m_AxisLength) -, m_AxisRadiusRatio(axis.m_AxisRadiusRatio) -{ - if (NULL != axis.m_pCurrentManipulator) - { - m_pCurrentManipulator= axis.m_pCurrentManipulator->clone(); - } -} - -GLC_Axis::~GLC_Axis() -{ - delete m_pCurrentManipulator; -} - -GLC_Axis& GLC_Axis::operator=(const GLC_Axis& axis) -{ - GLC_3DWidget::operator=(axis); - - m_Center= axis.m_Center; - delete m_pCurrentManipulator; - if (NULL != axis.m_pCurrentManipulator) - { - m_pCurrentManipulator= axis.m_pCurrentManipulator->clone(); - } - - return *this; -} - -void GLC_Axis::updateWidgetRep() -{ - const double viewTangent= GLC_3DWidget::widgetManagerHandle()->viewportTangent(); - const GLC_Point3d eye(GLC_3DWidget::widgetManagerHandle()->cameraHandle()->eye()); - const double distanceToNormal= (m_Center - eye).length(); - const double viewWidth= distanceToNormal * viewTangent; - - m_ScaleFactor= viewWidth * 0.1; - moveManipulatorRep(m_Center); -} - -void GLC_Axis::setAxisLength(double length) -{ - m_AxisLength= length; - if (!GLC_3DWidget::isEmpty()) - { - GLC_3DWidget::remove3DViewInstance(); - create3DviewInstance(); - } -} - -void GLC_Axis::setCenter(const GLC_Point3d& newCenter) -{ - m_Center= newCenter; - moveManipulatorRep(m_Center); -} - -glc::WidgetEventFlag GLC_Axis::select(const GLC_Point3d& pos, GLC_uint id) -{ - //qDebug() << "GLC_Axis::select"; - Q_ASSERT(NULL == m_pCurrentManipulator); - Q_ASSERT(NoneManipulator == m_CurrentManipulator); - - const int selectedInstanceIndex= GLC_3DWidget::indexOfIntsanceId(id); - //! Create the corresponding manipulator - GLC_Viewport* pViewport= GLC_3DWidget::widgetManagerHandle()->viewport(); - if (selectedInstanceIndex < 2) - { - m_pCurrentManipulator= new GLC_PullManipulator(pViewport, glc::X_AXIS); - m_CurrentManipulator= X_AxisManipulator; - GLC_3DWidget::instanceHandle(0)->geomAt(0)->firstMaterial()->setDiffuseColor(Qt::yellow); - } - else if (selectedInstanceIndex < 4) - { - m_pCurrentManipulator= new GLC_PullManipulator(pViewport, glc::Y_AXIS); - m_CurrentManipulator= Y_AxisManipulator; - GLC_3DWidget::instanceHandle(2)->geomAt(0)->firstMaterial()->setDiffuseColor(Qt::yellow); - } - else - { - Q_ASSERT((selectedInstanceIndex < 6) && (selectedInstanceIndex >= 4)); - m_pCurrentManipulator= new GLC_PullManipulator(pViewport, glc::Z_AXIS); - m_CurrentManipulator= Z_AxisManipulator; - GLC_3DWidget::instanceHandle(4)->geomAt(0)->firstMaterial()->setDiffuseColor(Qt::yellow); - } - - m_pCurrentManipulator->enterManipulateState(pos); - - updateWidgetRep(); - - return glc::BlockedEvent; -} - -glc::WidgetEventFlag GLC_Axis::mousePressed(const GLC_Point3d& pos, Qt::MouseButton button, GLC_uint id) -{ - //qDebug() << "GLC_Axis::mousePressed"; - glc::WidgetEventFlag returnFlag= glc::IgnoreEvent; - if (button == Qt::LeftButton) - { - returnFlag= select(pos, id); - } - - return returnFlag; -} - -glc::WidgetEventFlag GLC_Axis::mouseReleased(Qt::MouseButton button) -{ - //qDebug() << "GLC_Axis::mouseReleased"; - glc::WidgetEventFlag returnFlag= glc::IgnoreEvent; - if (button == Qt::LeftButton) - { - - // get selected instance index - - if (m_CurrentManipulator == X_AxisManipulator) - { - GLC_3DWidget::instanceHandle(0)->geomAt(0)->firstMaterial()->setDiffuseColor(Qt::red); - } - else if (m_CurrentManipulator == Y_AxisManipulator) - { - GLC_3DWidget::instanceHandle(2)->geomAt(0)->firstMaterial()->setDiffuseColor(Qt::green); - } - else if (m_CurrentManipulator == Z_AxisManipulator) - { - GLC_3DWidget::instanceHandle(4)->geomAt(0)->firstMaterial()->setDiffuseColor(Qt::blue); - } - - m_CurrentManipulator= NoneManipulator; - delete m_pCurrentManipulator; - m_pCurrentManipulator= NULL; - - returnFlag= glc::BlockedEvent; - } - return returnFlag; -} - -glc::WidgetEventFlag GLC_Axis::unselect(const GLC_Point3d&, GLC_uint) -{ - //qDebug() << "GLC_Axis::unselect"; - delete m_pCurrentManipulator; - m_pCurrentManipulator= NULL; - - m_CurrentManipulator= NoneManipulator; - - return glc::AcceptEvent; -} - -glc::WidgetEventFlag GLC_Axis::mouseMove(const GLC_Point3d& pos, Qt::MouseButtons button, GLC_uint) -{ - glc::WidgetEventFlag returnFlag= glc::IgnoreEvent; - if (button & Qt::LeftButton) - { - if (NULL != m_pCurrentManipulator) - { - GLC_Matrix4x4 moveMatrix(m_pCurrentManipulator->manipulate(pos)); - m_Center= moveMatrix * m_Center; - // Update the instance - for (int i= 0; i < 6; ++i) - { - GLC_3DWidget::instanceHandle(i)->multMatrix(moveMatrix); - } - - // Plane throw intersection and plane normal and camera up vector - m_pCurrentManipulator->enterManipulateState(m_pCurrentManipulator->previousPosition()); - - emit asChanged(); - returnFlag= glc::AcceptEvent; - } - } - - return returnFlag; -} -void GLC_Axis::create3DviewInstance() -{ - Q_ASSERT(GLC_3DWidget::isEmpty()); - const double axisRadius= m_AxisLength * m_AxisRadiusRatio; - const double arrowLength= m_AxisLength * 0.3; - const double arrowFactor= 2.5; - - { // Create X axis - // The X axis material - GLC_Material* pMaterial= new GLC_Material(Qt::red); - - GLC_3DViewInstance axisInstance= GLC_Factory::instance()->createCylinder(axisRadius, m_AxisLength); - axisInstance.representation().geomAt(0)->replaceMasterMaterial(pMaterial); - GLC_3DViewInstance arrowInstance= GLC_Factory::instance()->createCone(arrowFactor * axisRadius, arrowLength); - arrowInstance.representation().geomAt(0)->replaceMasterMaterial(pMaterial); - arrowInstance.translate(0.0, 0.0, m_AxisLength); - // Rotate the axis - GLC_Matrix4x4 rotation(glc::Y_AXIS, glc::PI / 2); - axisInstance.multMatrix(rotation); - arrowInstance.multMatrix(rotation); - - GLC_3DWidget::add3DViewInstance(axisInstance); - GLC_3DWidget::add3DViewInstance(arrowInstance); - } - { // Create Y axis - // The Y axis material - GLC_Material* pMaterial= new GLC_Material(Qt::green); - - GLC_3DViewInstance axisInstance= GLC_Factory::instance()->createCylinder(axisRadius, m_AxisLength); - axisInstance.representation().geomAt(0)->replaceMasterMaterial(pMaterial); - GLC_3DViewInstance arrowInstance= GLC_Factory::instance()->createCone(arrowFactor * axisRadius, arrowLength); - arrowInstance.representation().geomAt(0)->replaceMasterMaterial(pMaterial); - arrowInstance.translate(0.0, 0.0, m_AxisLength); - // Rotate the axis - GLC_Matrix4x4 rotation(glc::X_AXIS, - glc::PI / 2); - axisInstance.multMatrix(rotation); - arrowInstance.multMatrix(rotation); - - GLC_3DWidget::add3DViewInstance(axisInstance); - GLC_3DWidget::add3DViewInstance(arrowInstance); - } - { // Create Z axis - // The Z axis material - GLC_Material* pMaterial= new GLC_Material(Qt::blue); - - GLC_3DViewInstance axisInstance= GLC_Factory::instance()->createCylinder(axisRadius, m_AxisLength); - axisInstance.representation().geomAt(0)->replaceMasterMaterial(pMaterial); - GLC_3DViewInstance arrowInstance= GLC_Factory::instance()->createCone(arrowFactor * axisRadius, arrowLength); - arrowInstance.representation().geomAt(0)->replaceMasterMaterial(pMaterial); - arrowInstance.translate(0.0, 0.0, m_AxisLength); - - GLC_3DWidget::add3DViewInstance(axisInstance); - GLC_3DWidget::add3DViewInstance(arrowInstance); - } -} - -void GLC_Axis::resetViewState() -{ - -} - -void GLC_Axis::moveManipulatorRep(const GLC_Point3d& pos) -{ - - const GLC_Matrix4x4 translationMatrix(pos); - GLC_Matrix4x4 scaleMatrix; - scaleMatrix.setMatScaling(m_ScaleFactor, m_ScaleFactor, m_ScaleFactor); - for (int i= 0; i < 6; ++i) - { - GLC_Matrix4x4 rotationMatrix; - GLC_Matrix4x4 intTranslation; - if (i < 2) - { - rotationMatrix.setMatRot(glc::Y_AXIS, glc::PI / 2); - if (i == 1) - { - intTranslation.setMatTranslate(0.0, 0.0, m_AxisLength); - } - } - else if (i < 4) - { - rotationMatrix.setMatRot(glc::X_AXIS, - glc::PI / 2); - if (i == 3) - { - intTranslation.setMatTranslate(0.0, 0.0, m_AxisLength); - } - - } - else if (i == 5) - { - intTranslation.setMatTranslate(0.0, 0.0, m_AxisLength); - } - - GLC_3DWidget::instanceHandle(i)->setMatrix(translationMatrix * scaleMatrix * rotationMatrix * intTranslation); - } -} diff --git a/ground/gcs/src/libs/glc_lib/3DWidget/glc_axis.h b/ground/gcs/src/libs/glc_lib/3DWidget/glc_axis.h deleted file mode 100644 index 993b1c487..000000000 --- a/ground/gcs/src/libs/glc_lib/3DWidget/glc_axis.h +++ /dev/null @@ -1,160 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_axis.h Interface for the GLC_Axis class. - -#ifndef GLC_AXIS_H_ -#define GLC_AXIS_H_ - -#include "glc_3dwidget.h" -#include "../glc_config.h" - -class GLC_AbstractManipulator; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Axis -/*! \brief GLC_Axis : 3d Widget axis use to translate objects*/ - -/*! GLC_Axis */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_Axis : public GLC_3DWidget -{ - enum Manipulator - { - NoneManipulator, - X_AxisManipulator, - Y_AxisManipulator, - Z_AxisManipulator - }; - -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Construct a axis widget - GLC_Axis(const GLC_Point3d& center, GLC_3DWidgetManagerHandle* pWidgetManagerHandle= NULL); - - //! Copy constructor - GLC_Axis(const GLC_Axis& axis); - - //! Destructor - virtual ~GLC_Axis(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return this axis center - inline GLC_Point3d center() const - {return m_Center;} - - //! Return this axis length - inline double axisLength() const - {return m_AxisLength;} -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Copy the given cutting plane in this cutting plane and return a reference on this cutting plane - virtual GLC_Axis& operator=(const GLC_Axis& axis); - - //! Update widget representation - virtual void updateWidgetRep(); - - //! Set the axis length - void setAxisLength(double length); - - //! Set Axis center - void setCenter(const GLC_Point3d& newCenter); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Interaction Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! This widget as been selected - virtual glc::WidgetEventFlag select(const GLC_Point3d&, GLC_uint id); - - //! This widget as been unselected - virtual glc::WidgetEventFlag unselect(const GLC_Point3d&, GLC_uint id); - - //! The mouse is over this widget and a mousse button is pressed - virtual glc::WidgetEventFlag mousePressed(const GLC_Point3d&, Qt::MouseButton, GLC_uint id); - - //! The mouse is over this widget and a mousse button is released - virtual glc::WidgetEventFlag mouseReleased(Qt::MouseButton); - - //! This widget is selected and the mousse move with a pressed buttons - virtual glc::WidgetEventFlag mouseMove(const GLC_Point3d&, Qt::MouseButtons, GLC_uint id); - -//@} - -////////////////////////////////////////////////////////////////////// -// Protected services function -////////////////////////////////////////////////////////////////////// -protected: - //! Create the 3DView instance of this 3d widget - virtual void create3DviewInstance(); - - //! Reset the view state of this 3DWidget - virtual void resetViewState(); - -////////////////////////////////////////////////////////////////////// -// Private services function -////////////////////////////////////////////////////////////////////// -private: - //! Move the manipulator 3D representation - void moveManipulatorRep(const GLC_Point3d& pos); - -////////////////////////////////////////////////////////////////////// -// Private Member -////////////////////////////////////////////////////////////////////// -private: - //! The axis center - GLC_Point3d m_Center; - - //! The manipulator scale factor - double m_ScaleFactor; - - //! Current manipulator enum - Manipulator m_CurrentManipulator; - - //! The current manipulator of this cutting plane - GLC_AbstractManipulator* m_pCurrentManipulator; - - //! The axis length - double m_AxisLength; - - //! The axis radius Ratio : Radius / Length - double m_AxisRadiusRatio; - -}; - -#endif /* GLC_AXIS_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/3DWidget/glc_cuttingplane.cpp b/ground/gcs/src/libs/glc_lib/3DWidget/glc_cuttingplane.cpp deleted file mode 100644 index 6ab75f4b0..000000000 --- a/ground/gcs/src/libs/glc_lib/3DWidget/glc_cuttingplane.cpp +++ /dev/null @@ -1,403 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_cuttingplane.cpp Implementation of the GLC_CuttingPlane class. - -#include "glc_cuttingplane.h" -#include "../glc_factory.h" -#include "../maths/glc_line3d.h" -#include "../maths/glc_geomtools.h" -#include "../geometry/glc_arrow.h" -#include "../geometry/glc_disc.h" -#include "glc_pullmanipulator.h" -#include "glc_rotationmanipulator.h" - -GLC_CuttingPlane::GLC_CuttingPlane(const GLC_Point3d& center, const GLC_Vector3d& normal, double l1, double l2, GLC_3DWidgetManagerHandle* pWidgetManagerHandle) -: GLC_3DWidget(pWidgetManagerHandle) -, m_Center(center) -, m_Normal(normal) -, m_CompMatrix() -, m_L1(l1) -, m_L2(l2) -, m_Color(Qt::darkGreen) -, m_Opacity(0.3) -, m_ManipulatorOffsetFactor(1.0) -, m_ScaleFactor(1.0) -, m_SelectionIndex(-1) -, m_CurrentManipulator(TranslationManipulator) -, m_pCurrentManipulator(NULL) -, m_CurrentNavigatorPosition() -{ - if (NULL != pWidgetManagerHandle) - { - create3DviewInstance(); - } - - m_CompMatrix.setMatRot(glc::Z_AXIS, m_Normal); -} - -GLC_CuttingPlane::GLC_CuttingPlane(const GLC_CuttingPlane& cuttingPlane) -: GLC_3DWidget(cuttingPlane) -, m_Center(cuttingPlane.m_Center) -, m_Normal(cuttingPlane.m_Normal) -, m_CompMatrix(cuttingPlane.m_CompMatrix) -, m_L1(cuttingPlane.m_L1) -, m_L2(cuttingPlane.m_L2) -, m_Color(cuttingPlane.m_Color) -, m_Opacity(cuttingPlane.m_Opacity) -, m_ManipulatorOffsetFactor(cuttingPlane.m_ManipulatorOffsetFactor) -, m_ScaleFactor(cuttingPlane.m_ScaleFactor) -, m_SelectionIndex(cuttingPlane.m_SelectionIndex) -, m_CurrentManipulator(cuttingPlane.m_CurrentManipulator) -, m_pCurrentManipulator(NULL) -, m_CurrentNavigatorPosition(cuttingPlane.m_CurrentNavigatorPosition) -{ - if (NULL != cuttingPlane.m_pCurrentManipulator) - { - m_pCurrentManipulator= cuttingPlane.m_pCurrentManipulator->clone(); - } -} - -GLC_CuttingPlane::~GLC_CuttingPlane() -{ - delete m_pCurrentManipulator; -} - -GLC_CuttingPlane& GLC_CuttingPlane::operator=(const GLC_CuttingPlane& cuttingPlane) -{ - GLC_3DWidget::operator=(cuttingPlane); - - m_Center= cuttingPlane.m_Center; - m_Normal= cuttingPlane.m_Normal; - m_CompMatrix= cuttingPlane.m_CompMatrix; - m_L1= cuttingPlane.m_L1; - m_L2= cuttingPlane.m_L2; - m_Color= cuttingPlane.m_Color; - m_Opacity= cuttingPlane.m_Opacity; - m_CurrentNavigatorPosition= cuttingPlane.m_CurrentNavigatorPosition; - delete m_pCurrentManipulator; - if (NULL != cuttingPlane.m_pCurrentManipulator) - { - m_pCurrentManipulator= cuttingPlane.m_pCurrentManipulator->clone(); - } - - return *this; -} - -void GLC_CuttingPlane::updateLength(double l1, double l2) -{ - m_L1= l1; - m_L2= l2; - - if (GLC_3DWidget::has3DWidgetManager()) - { - GLC_3DWidget::remove3DViewInstance(); - create3DviewInstance(); - } -} - -void GLC_CuttingPlane::updateWidgetRep() -{ - const double viewTangent= GLC_3DWidget::widgetManagerHandle()->viewportTangent(); - const GLC_Point3d eye(GLC_3DWidget::widgetManagerHandle()->cameraHandle()->eye()); - const double distanceToNormal= (m_CurrentNavigatorPosition - eye).length(); - const double viewWidth= distanceToNormal * viewTangent; - - m_ScaleFactor= viewWidth * 0.1; - m_ManipulatorOffsetFactor= m_ScaleFactor * (-0.01); - - moveManipulatorRep(m_CurrentNavigatorPosition); -} - -glc::WidgetEventFlag GLC_CuttingPlane::select(const GLC_Point3d& pos, GLC_uint) -{ - Q_ASSERT(NULL == m_pCurrentManipulator); - Q_ASSERT(TranslationManipulator == m_CurrentManipulator); - - //! Create the default manipulator - GLC_Viewport* pViewport= GLC_3DWidget::widgetManagerHandle()->viewport(); - m_pCurrentManipulator= new GLC_PullManipulator(pViewport, m_Normal); - - m_pCurrentManipulator->enterManipulateState(pos); - m_CurrentNavigatorPosition= pos; - - GLC_3DWidget::set3DViewInstanceVisibility(1, true); - - updateWidgetRep(); - - return glc::BlockedEvent; -} - -glc::WidgetEventFlag GLC_CuttingPlane::mousePressed(const GLC_Point3d& pos, Qt::MouseButton button, GLC_uint id) -{ - glc::WidgetEventFlag returnFlag= glc::IgnoreEvent; - if (button == Qt::LeftButton) - { - const int selectedInstanceIndex= GLC_3DWidget::indexOfIntsanceId(id); - if (selectedInstanceIndex > 0) - { - m_SelectionIndex= selectedInstanceIndex; - if (m_CurrentManipulator == RotationManipulator) - { - delete m_pCurrentManipulator; - m_pCurrentManipulator= rotationNavigator(selectedInstanceIndex); - } - m_pCurrentManipulator->enterManipulateState(pos); - } - else - { - if (NULL != m_pCurrentManipulator) - { - if (m_CurrentManipulator == RotationManipulator) - { - delete m_pCurrentManipulator; - m_pCurrentManipulator= NULL; - } - else - { - m_pCurrentManipulator->enterManipulateState(pos); - } - - } - m_CurrentNavigatorPosition= pos; - updateWidgetRep(); - } - - returnFlag= glc::BlockedEvent; - } - - return returnFlag; -} - -glc::WidgetEventFlag GLC_CuttingPlane::mouseReleased(Qt::MouseButton button) -{ - glc::WidgetEventFlag returnFlag= glc::IgnoreEvent; - if ((button == Qt::LeftButton) && (m_SelectionIndex != -1)) - { - - // get selected instance index - - if (m_CurrentManipulator == TranslationManipulator) - { - GLC_3DWidget::set3DViewInstanceVisibility(1, false); - GLC_3DWidget::set3DViewInstanceVisibility(2, true); - GLC_3DWidget::set3DViewInstanceVisibility(3, true); - GLC_3DWidget::set3DViewInstanceVisibility(4, true); - - returnFlag= glc::BlockedEvent; - m_CurrentManipulator= RotationManipulator; - delete m_pCurrentManipulator; - m_pCurrentManipulator= NULL; - - moveManipulatorRep(m_CurrentNavigatorPosition); - } - else if (m_CurrentManipulator == RotationManipulator) - { - GLC_3DWidget::set3DViewInstanceVisibility(1, true); - GLC_3DWidget::set3DViewInstanceVisibility(2, false); - GLC_3DWidget::set3DViewInstanceVisibility(3, false); - GLC_3DWidget::set3DViewInstanceVisibility(4, false); - - returnFlag= glc::BlockedEvent; - m_CurrentManipulator= TranslationManipulator; - - delete m_pCurrentManipulator; - - GLC_Viewport* pViewport= GLC_3DWidget::widgetManagerHandle()->viewport(); - m_pCurrentManipulator= new GLC_PullManipulator(pViewport, m_Normal); - m_pCurrentManipulator->enterManipulateState(m_CurrentNavigatorPosition); - - moveManipulatorRep(m_CurrentNavigatorPosition); - } - m_SelectionIndex= -1; - } - return returnFlag; -} - -glc::WidgetEventFlag GLC_CuttingPlane::unselect(const GLC_Point3d&, GLC_uint) -{ - resetViewState(); - return glc::AcceptEvent; -} - -glc::WidgetEventFlag GLC_CuttingPlane::mouseMove(const GLC_Point3d& pos, Qt::MouseButtons button, GLC_uint) -{ - glc::WidgetEventFlag returnFlag= glc::IgnoreEvent; - if (button & Qt::LeftButton) - { - if (NULL != m_pCurrentManipulator) - { - if (m_SelectionIndex != -1) - { - moveManipulatorRep(m_CurrentNavigatorPosition); - m_SelectionIndex= -1; - } - GLC_Matrix4x4 moveMatrix(m_pCurrentManipulator->manipulate(pos)); - - // Update plane normal - if (m_CurrentManipulator == RotationManipulator) - { - m_Normal= moveMatrix.rotationMatrix() * m_Normal; - } - m_CompMatrix= moveMatrix * m_CompMatrix; - m_Center= moveMatrix * m_Center; - m_CurrentNavigatorPosition= moveMatrix * m_CurrentNavigatorPosition; - - // Update the instance - for (int i= 0; i < 5; ++i) - { - GLC_3DWidget::instanceHandle(i)->multMatrix(moveMatrix); - } - - // Plane throw intersection and plane normal and camera up vector - m_pCurrentManipulator->enterManipulateState(m_pCurrentManipulator->previousPosition()); - - emit asChanged(); - returnFlag= glc::AcceptEvent; - } - } - - return returnFlag; -} - -void GLC_CuttingPlane::create3DviewInstance() -{ - Q_ASSERT(GLC_3DWidget::isEmpty()); - // The cutting plane material - GLC_Material* pMaterial= new GLC_Material(m_Color); - pMaterial->setOpacity(m_Opacity); - - // Cutting plane 3Dview instance - GLC_3DViewInstance cuttingPlaneInstance= GLC_Factory::instance()->createCuttingPlane(m_Center, m_Normal, m_L1, m_L2, pMaterial); - GLC_3DWidget::add3DViewInstance(cuttingPlaneInstance); - - // Normal arrow geometry - GLC_Arrow* pArrow= new GLC_Arrow(GLC_Point3d(), -glc::Z_AXIS, GLC_3DWidget::widgetManagerHandle()->cameraHandle()->forward().normalize()); - pArrow->setLineWidth(4.5); - pArrow->setHeadLength(0.15); - QColor arrowColor(Qt::red); - arrowColor.setAlphaF(0.4); - pArrow->setWireColor(arrowColor); - - //Base arrow disc - pMaterial= new GLC_Material(Qt::red); - pMaterial->setOpacity(m_Opacity); - GLC_Disc* pDisc= new GLC_Disc(0.3); - pDisc->replaceMasterMaterial(pMaterial); - - // Normal arrow + base instance - GLC_3DRep normalLine(pArrow); - normalLine.addGeom(pDisc); - GLC_3DWidget::add3DViewInstance(GLC_3DViewInstance(normalLine)); - GLC_3DWidget::set3DViewInstanceVisibility(1, false); - - // Rotation manipulator - const double initRadius= 1; - // Arrond X axis - pDisc= new GLC_Disc(initRadius); - pMaterial= new GLC_Material(Qt::red); - pMaterial->setOpacity(m_Opacity); - pDisc->replaceMasterMaterial(pMaterial); - pDisc->setAngle(glc::PI); - GLC_3DWidget::add3DViewInstance(GLC_3DViewInstance(pDisc)); - GLC_3DWidget::set3DViewInstanceVisibility(2, false); - // Arround Y axis - pDisc= new GLC_Disc(initRadius); - pMaterial= new GLC_Material(Qt::green); - pMaterial->setOpacity(m_Opacity); - pDisc->replaceMasterMaterial(pMaterial); - pDisc->setAngle(glc::PI); - GLC_3DWidget::add3DViewInstance(GLC_3DViewInstance(pDisc)); - GLC_3DWidget::set3DViewInstanceVisibility(3, false); - // Arround Z axis - pDisc= new GLC_Disc(initRadius); - pMaterial= new GLC_Material(Qt::blue); - pMaterial->setOpacity(m_Opacity); - pDisc->replaceMasterMaterial(pMaterial); - //pDisc->setAngle(glc::PI / 2.0); - GLC_3DWidget::add3DViewInstance(GLC_3DViewInstance(pDisc)); - GLC_3DWidget::set3DViewInstanceVisibility(4, false); -} - -void GLC_CuttingPlane::resetViewState() -{ - Q_ASSERT(m_SelectionIndex == -1); - for (int i= 0; i < 4; ++i) - { - GLC_3DWidget::set3DViewInstanceVisibility(1 + i, false); - } - m_pCurrentManipulator= NULL; - - m_CurrentManipulator= TranslationManipulator; -} - -void GLC_CuttingPlane::moveManipulatorRep(const GLC_Point3d& pos) -{ - // Create the widget rotation matrix - const GLC_Matrix4x4 rotationMatrix(m_CompMatrix.rotationMatrix()); - - const GLC_Matrix4x4 translationMatrix(pos); - const GLC_Matrix4x4 offsetMatrix(m_Normal * m_ManipulatorOffsetFactor); - GLC_Matrix4x4 scaleMatrix; - scaleMatrix.setMatScaling(m_ScaleFactor, m_ScaleFactor, m_ScaleFactor); - GLC_3DWidget::instanceHandle(1)->setMatrix(offsetMatrix * translationMatrix * rotationMatrix *scaleMatrix); - - // Rotation manipulator - QVector rotations(3); - rotations[0].setMatRot(glc::Y_AXIS, glc::PI / 2.0); // X - rotations[0]= GLC_Matrix4x4(glc::X_AXIS, -glc::PI / 2.0) * rotations[0]; - rotations[1].setMatRot(glc::X_AXIS, -glc::PI / 2.0); // Y - // Z - for (int i= 0; i < 3; ++i) - { - GLC_3DWidget::instanceHandle(2 + i)->setMatrix(offsetMatrix * translationMatrix * rotationMatrix * rotations.at(i) * scaleMatrix); - } - - GLC_Arrow* pArrow= dynamic_cast(GLC_3DWidget::instanceHandle(1)->geomAt(0)); - Q_ASSERT(NULL != pArrow); - - pArrow->setViewDir(rotationMatrix * GLC_3DWidget::widgetManagerHandle()->cameraHandle()->forward().normalize()); -} - -GLC_AbstractManipulator* GLC_CuttingPlane::rotationNavigator(int index) -{ - index= index - 2; - Q_ASSERT((index > -1) && (index < 3)); - - const GLC_Matrix4x4 rotationMatrix(m_CompMatrix.rotationMatrix()); - GLC_Vector3d axis; - if (index == 0) - { - axis= rotationMatrix * glc::X_AXIS; - } - else if (index == 1) - { - axis= rotationMatrix * glc::Y_AXIS; - } - else - { - axis= rotationMatrix * glc::Z_AXIS; - } - GLC_AbstractManipulator* pManipulator= new GLC_RotationManipulator(GLC_3DWidget::widgetManagerHandle()->viewport(), GLC_Line3d(m_CurrentNavigatorPosition, axis)); - - return pManipulator; -} - diff --git a/ground/gcs/src/libs/glc_lib/3DWidget/glc_cuttingplane.h b/ground/gcs/src/libs/glc_lib/3DWidget/glc_cuttingplane.h deleted file mode 100644 index 08ad62c63..000000000 --- a/ground/gcs/src/libs/glc_lib/3DWidget/glc_cuttingplane.h +++ /dev/null @@ -1,193 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_cuttingplane.h Interface for the GLC_CuttingPlane class. - -#ifndef GLC_CUTTINGPLANE_H_ -#define GLC_CUTTINGPLANE_H_ - -#include "glc_3dwidget.h" -#include "../glc_config.h" - -class GLC_AbstractManipulator; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_CuttingPlane -/*! \brief GLC_CuttingPlane : 3d cutting plane widget*/ - -/*! GLC_CuttingPlane */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_CuttingPlane : public GLC_3DWidget -{ - enum Manipulator - { - TranslationManipulator, - RotationManipulator - }; -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Construct a 3d cutting plane widget - GLC_CuttingPlane(const GLC_Point3d& center, const GLC_Vector3d& normal, double l1, double l2, GLC_3DWidgetManagerHandle* pWidgetManagerHandle= NULL); - - //! Construct a 3d cutting plane with the given cutting plane - GLC_CuttingPlane(const GLC_CuttingPlane& cuttingPlane); - - //! Destructor - virtual ~GLC_CuttingPlane(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return this cutting plane center - inline GLC_Point3d center() const - {return m_Center;} - - //! Return this cutting plane normal - inline GLC_Vector3d normal() const - {return m_Normal;} - - //! Return this plane color - inline QColor color() const - {return m_Color;} - - //! Return this plane opacity - inline double opacity() const - {return m_Opacity;} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Copy the given cutting plane in this cutting plane and return a reference on this cutting plane - virtual GLC_CuttingPlane& operator=(const GLC_CuttingPlane& cuttingPlane); - - //! Update the lenght of this cutting plane - void updateLength(double l1, double l2); - - //! Set this plane color - inline void setColor(const QColor& color) - {m_Color= color;} - - //! Set this plane opacity - inline void setOpacity(double opacity) - {m_Opacity= opacity;} - - //! Update widget representation - virtual void updateWidgetRep(); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Interaction Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! This widget as been selected - virtual glc::WidgetEventFlag select(const GLC_Point3d&, GLC_uint id); - - //! This widget as been unselected - virtual glc::WidgetEventFlag unselect(const GLC_Point3d&, GLC_uint id); - - //! The mouse is over this widget and a mousse button is pressed - virtual glc::WidgetEventFlag mousePressed(const GLC_Point3d&, Qt::MouseButton, GLC_uint id); - - //! The mouse is over this widget and a mousse button is released - virtual glc::WidgetEventFlag mouseReleased(Qt::MouseButton); - - //! This widget is selected and the mousse move with a pressed buttons - virtual glc::WidgetEventFlag mouseMove(const GLC_Point3d&, Qt::MouseButtons, GLC_uint id); - -//@} - -////////////////////////////////////////////////////////////////////// -// Protected services function -////////////////////////////////////////////////////////////////////// -protected: - //! Create the 3DView instance of this 3d widget - virtual void create3DviewInstance(); - - //! Reset the view state of this 3DWidget - virtual void resetViewState(); - -////////////////////////////////////////////////////////////////////// -// Private services function -////////////////////////////////////////////////////////////////////// -private: - //! Move the manipulator 3D representation - void moveManipulatorRep(const GLC_Point3d& pos); - - //! Create the rotation navigator of the given instance index - GLC_AbstractManipulator* rotationNavigator(int index); - -////////////////////////////////////////////////////////////////////// -// Private Member -////////////////////////////////////////////////////////////////////// -private: - //! The cutting plane center - GLC_Point3d m_Center; - - //! The cutting plane Normal - GLC_Vector3d m_Normal; - - //! The cutting plane compostion matrix - GLC_Matrix4x4 m_CompMatrix; - - //! The cutting plane size - double m_L1, m_L2; - - //! The cutting plane color - QColor m_Color; - - //! The cutting plane opacity - double m_Opacity; - - //! The manipulator offset - double m_ManipulatorOffsetFactor; - - //! The manipulator scale factor - double m_ScaleFactor; - - //! Index of the instance in selection - int m_SelectionIndex; - - //! current manipulator enum - Manipulator m_CurrentManipulator; - - //! The current manipulator of this cutting plane - GLC_AbstractManipulator* m_pCurrentManipulator; - - //! The current manipulator position - GLC_Point3d m_CurrentNavigatorPosition; - - -}; - -#endif /* GLC_CUTTINGPLANE_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/3DWidget/glc_pullmanipulator.cpp b/ground/gcs/src/libs/glc_lib/3DWidget/glc_pullmanipulator.cpp deleted file mode 100644 index c19d6aef9..000000000 --- a/ground/gcs/src/libs/glc_lib/3DWidget/glc_pullmanipulator.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_pullmanipulator.cpp Implementation of the GLC_PullManipulator class. - -#include "glc_pullmanipulator.h" -#include "../maths/glc_line3d.h" -#include "../maths/glc_geomtools.h" -#include "../viewport/glc_viewport.h" - -#include - -GLC_PullManipulator::GLC_PullManipulator(GLC_Viewport* pViewport, const GLC_Vector3d& pullDirection) -: GLC_AbstractManipulator(pViewport) -, m_PullDirection(pullDirection) -{ - -} - -GLC_PullManipulator::GLC_PullManipulator(const GLC_PullManipulator& pullManipulator) -: GLC_AbstractManipulator(pullManipulator) -, m_PullDirection(pullManipulator.m_PullDirection) -{ - -} - -GLC_PullManipulator::~GLC_PullManipulator() -{ - -} - -GLC_AbstractManipulator* GLC_PullManipulator::clone() const -{ - return new GLC_PullManipulator(*this); -} - -void GLC_PullManipulator::setPullingDirection(const GLC_Vector3d& pullingDirection) -{ - Q_ASSERT(!GLC_AbstractManipulator::isInManipulateState()); - m_PullDirection= pullingDirection; -} - -GLC_Matrix4x4 GLC_PullManipulator::doManipulate(const GLC_Point3d& newPoint, const GLC_Vector3d& projectionDirection) -{ - // Project the given point on the sliding plane with the given direction - GLC_Point3d projectedPoint; - GLC_Line3d projectionLine(newPoint, projectionDirection); - glc::lineIntersectPlane(projectionLine, GLC_AbstractManipulator::m_SliddingPlane, &projectedPoint); - - // Project the point on the pulling direction - projectedPoint= glc::project(projectedPoint, GLC_Line3d(GLC_AbstractManipulator::previousPosition(), m_PullDirection)); - - // Compute the translation matrix - GLC_Matrix4x4 translationMatrix(projectedPoint - GLC_AbstractManipulator::m_PreviousPosition); - - // Update previous position to this position - GLC_AbstractManipulator::m_PreviousPosition= projectedPoint; - return translationMatrix; -} diff --git a/ground/gcs/src/libs/glc_lib/3DWidget/glc_pullmanipulator.h b/ground/gcs/src/libs/glc_lib/3DWidget/glc_pullmanipulator.h deleted file mode 100644 index a8d9d7356..000000000 --- a/ground/gcs/src/libs/glc_lib/3DWidget/glc_pullmanipulator.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_pullmanipulator.h Interface for the GLC_PullManipulator class. - -#ifndef GLC_PULLMANIPULATOR_H_ -#define GLC_PULLMANIPULATOR_H_ -#include "../glc_config.h" -#include "glc_abstractmanipulator.h" - -class GLC_Viewport; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_PullManipulator -/*! \brief GLC_PullManipulator : */ - -/*! GLC_PullManipulator */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_PullManipulator : public GLC_AbstractManipulator -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Construct pull manipulator with the given viewport and pulling direction - GLC_PullManipulator(GLC_Viewport* pViewport, const GLC_Vector3d& pullDirection); - - //! Copy constructor - GLC_PullManipulator(const GLC_PullManipulator& pullManipulator); - - //! Destructor - virtual ~GLC_PullManipulator(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the pulling direction of this pull manipulator - inline GLC_Vector3d pullingDirection() const - {return m_PullDirection;} - - //! Clone the concrete manipulator - virtual GLC_AbstractManipulator* clone() const; -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Set the pulling direction of this manipulator - void setPullingDirection(const GLC_Vector3d& pullingDirection); - -//@} - -////////////////////////////////////////////////////////////////////// -// Protected services function -////////////////////////////////////////////////////////////////////// -protected: - //! Manipulate this manipulator and return the moving matrix - virtual GLC_Matrix4x4 doManipulate(const GLC_Point3d& newPoint, const GLC_Vector3d& projectionDirection); - -////////////////////////////////////////////////////////////////////// -// Private Member -////////////////////////////////////////////////////////////////////// -private: - //! The pulling direction - GLC_Vector3d m_PullDirection; -}; - -#endif /* GLC_PULLMANIPULATOR_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/3DWidget/glc_rotationmanipulator.cpp b/ground/gcs/src/libs/glc_lib/3DWidget/glc_rotationmanipulator.cpp deleted file mode 100644 index a5da678c9..000000000 --- a/ground/gcs/src/libs/glc_lib/3DWidget/glc_rotationmanipulator.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_rotationmanipulator.cpp Implementation of the GLC_RotationManipulator class. - -#include "glc_rotationmanipulator.h" -#include "../maths/glc_geomtools.h" - -GLC_RotationManipulator::GLC_RotationManipulator(GLC_Viewport* pViewport, const GLC_Line3d& rotationLine) -: GLC_AbstractManipulator(pViewport) -, m_RotationLine(rotationLine) -{ - -} - -GLC_RotationManipulator::GLC_RotationManipulator(const GLC_RotationManipulator& rotationmanipulator) -: GLC_AbstractManipulator(rotationmanipulator) -, m_RotationLine(rotationmanipulator.m_RotationLine) -{ - -} - -GLC_RotationManipulator::~GLC_RotationManipulator() -{ - -} - -GLC_AbstractManipulator* GLC_RotationManipulator::clone() const -{ - return new GLC_RotationManipulator(*this); -} - -GLC_Matrix4x4 GLC_RotationManipulator::doManipulate(const GLC_Point3d& newPoint, const GLC_Vector3d& projectionDirection) -{ - // Project the given point on the sliding plane with the given direction - GLC_Point3d projectedPoint; - GLC_Line3d projectionLine1(GLC_AbstractManipulator::m_PreviousPosition, projectionDirection); - GLC_Line3d projectionLine(newPoint, projectionDirection); - - // create the rotation plane - const GLC_Point3d origine(m_RotationLine.startingPoint()); - GLC_Plane rotationPlane(m_RotationLine.direction(), origine); - // Project the point on the previous computed plane - glc::lineIntersectPlane(projectionLine1, rotationPlane, &(GLC_AbstractManipulator::m_PreviousPosition)); - glc::lineIntersectPlane(projectionLine, rotationPlane, &projectedPoint); - - // Compute the the to vector - GLC_Vector3d vector1((GLC_AbstractManipulator::m_PreviousPosition - origine).normalize()); - GLC_Vector3d vector2((projectedPoint - origine).normalize()); - - // Update previous position to this position - GLC_AbstractManipulator::m_PreviousPosition= projectedPoint; - - // Return the rotation matrix - const GLC_Matrix4x4 trans1(-origine); - const GLC_Matrix4x4 trans2(origine); - const GLC_Matrix4x4 rotation(vector1, vector2); - - return (trans2 * rotation * trans1); - -} diff --git a/ground/gcs/src/libs/glc_lib/3DWidget/glc_rotationmanipulator.h b/ground/gcs/src/libs/glc_lib/3DWidget/glc_rotationmanipulator.h deleted file mode 100644 index f808bb23e..000000000 --- a/ground/gcs/src/libs/glc_lib/3DWidget/glc_rotationmanipulator.h +++ /dev/null @@ -1,98 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_rotationmanipulator.h Interface for the GLC_RotationManipulator class. - -#ifndef GLC_ROTATIONMANIPULATOR_H_ -#define GLC_ROTATIONMANIPULATOR_H_ - -#include "../glc_config.h" -#include "glc_abstractmanipulator.h" -#include "../maths/glc_line3d.h" - -class GLC_Viewport; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_RotationManipulator -/*! \brief GLC_RotationManipulator : */ - -/*! GLC_RotationManipulator */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_RotationManipulator : public GLC_AbstractManipulator -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Construct a rotation manipulator with the given viewport and rotation line - GLC_RotationManipulator(GLC_Viewport* pViewport, const GLC_Line3d& rotationLine); - - //! Copy constructor - GLC_RotationManipulator(const GLC_RotationManipulator& rotationmanipulator); - - //! Destructor - virtual ~GLC_RotationManipulator(); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Clone the concrete manipulator - virtual GLC_AbstractManipulator* clone() const; - - //! Return the rotation line of this rotation manipulator - inline GLC_Line3d rotationLine() const - {return m_RotationLine;} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Set the rotation line of this rotation manipulator - void setRotationLine(const GLC_Line3d line) - {m_RotationLine= line;} - -//@} - -////////////////////////////////////////////////////////////////////// -// Protected services function -////////////////////////////////////////////////////////////////////// -protected: - //! Manipulate this manipulator and return the moving matrix - virtual GLC_Matrix4x4 doManipulate(const GLC_Point3d& newPoint, const GLC_Vector3d& projectionDirection); - -////////////////////////////////////////////////////////////////////// -// Private Member -////////////////////////////////////////////////////////////////////// -private: - //! The rotation line of this manipulator - GLC_Line3d m_RotationLine; - -}; - -#endif /* GLC_ROTATIONMANIPULATOR_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/glext/glext.h b/ground/gcs/src/libs/glc_lib/3rdparty/glext/glext.h deleted file mode 100644 index 6539a8399..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/glext/glext.h +++ /dev/null @@ -1,8403 +0,0 @@ -#ifndef __glext_h_ -#define __glext_h_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* -** Copyright (c) 2007 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ - -#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) -#define WIN32_LEAN_AND_MEAN 1 -#include -#endif - -#ifndef APIENTRY -#define APIENTRY -#endif -#ifndef APIENTRYP -#define APIENTRYP APIENTRY * -#endif -#ifndef GLAPI -#define GLAPI extern -#endif - -/*************************************************************/ - -/* Header file version number, required by OpenGL ABI for Linux */ -/* glext.h last updated 2008/08/16 */ -/* Current version at http://www.opengl.org/registry/ */ -#define GL_GLEXT_VERSION 42 - -#ifndef GL_VERSION_1_2 -#define GL_UNSIGNED_BYTE_3_3_2 0x8032 -#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 -#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 -#define GL_UNSIGNED_INT_8_8_8_8 0x8035 -#define GL_UNSIGNED_INT_10_10_10_2 0x8036 -#define GL_RESCALE_NORMAL 0x803A -#define GL_TEXTURE_BINDING_3D 0x806A -#define GL_PACK_SKIP_IMAGES 0x806B -#define GL_PACK_IMAGE_HEIGHT 0x806C -#define GL_UNPACK_SKIP_IMAGES 0x806D -#define GL_UNPACK_IMAGE_HEIGHT 0x806E -#define GL_TEXTURE_3D 0x806F -#define GL_PROXY_TEXTURE_3D 0x8070 -#define GL_TEXTURE_DEPTH 0x8071 -#define GL_TEXTURE_WRAP_R 0x8072 -#define GL_MAX_3D_TEXTURE_SIZE 0x8073 -#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 -#define GL_UNSIGNED_SHORT_5_6_5 0x8363 -#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 -#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 -#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 -#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 -#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 -#define GL_BGR 0x80E0 -#define GL_BGRA 0x80E1 -#define GL_MAX_ELEMENTS_VERTICES 0x80E8 -#define GL_MAX_ELEMENTS_INDICES 0x80E9 -#define GL_CLAMP_TO_EDGE 0x812F -#define GL_TEXTURE_MIN_LOD 0x813A -#define GL_TEXTURE_MAX_LOD 0x813B -#define GL_TEXTURE_BASE_LEVEL 0x813C -#define GL_TEXTURE_MAX_LEVEL 0x813D -#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 -#define GL_SINGLE_COLOR 0x81F9 -#define GL_SEPARATE_SPECULAR_COLOR 0x81FA -#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 -#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 -#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 -#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 -#define GL_ALIASED_POINT_SIZE_RANGE 0x846D -#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E -#endif - -#ifndef GL_ARB_imaging -#define GL_CONSTANT_COLOR 0x8001 -#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 -#define GL_CONSTANT_ALPHA 0x8003 -#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 -#define GL_BLEND_COLOR 0x8005 -#define GL_FUNC_ADD 0x8006 -#define GL_MIN 0x8007 -#define GL_MAX 0x8008 -#define GL_BLEND_EQUATION 0x8009 -#define GL_FUNC_SUBTRACT 0x800A -#define GL_FUNC_REVERSE_SUBTRACT 0x800B -#define GL_CONVOLUTION_1D 0x8010 -#define GL_CONVOLUTION_2D 0x8011 -#define GL_SEPARABLE_2D 0x8012 -#define GL_CONVOLUTION_BORDER_MODE 0x8013 -#define GL_CONVOLUTION_FILTER_SCALE 0x8014 -#define GL_CONVOLUTION_FILTER_BIAS 0x8015 -#define GL_REDUCE 0x8016 -#define GL_CONVOLUTION_FORMAT 0x8017 -#define GL_CONVOLUTION_WIDTH 0x8018 -#define GL_CONVOLUTION_HEIGHT 0x8019 -#define GL_MAX_CONVOLUTION_WIDTH 0x801A -#define GL_MAX_CONVOLUTION_HEIGHT 0x801B -#define GL_POST_CONVOLUTION_RED_SCALE 0x801C -#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D -#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E -#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F -#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 -#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 -#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 -#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 -#define GL_HISTOGRAM 0x8024 -#define GL_PROXY_HISTOGRAM 0x8025 -#define GL_HISTOGRAM_WIDTH 0x8026 -#define GL_HISTOGRAM_FORMAT 0x8027 -#define GL_HISTOGRAM_RED_SIZE 0x8028 -#define GL_HISTOGRAM_GREEN_SIZE 0x8029 -#define GL_HISTOGRAM_BLUE_SIZE 0x802A -#define GL_HISTOGRAM_ALPHA_SIZE 0x802B -#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C -#define GL_HISTOGRAM_SINK 0x802D -#define GL_MINMAX 0x802E -#define GL_MINMAX_FORMAT 0x802F -#define GL_MINMAX_SINK 0x8030 -#define GL_TABLE_TOO_LARGE 0x8031 -#define GL_COLOR_MATRIX 0x80B1 -#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 -#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 -#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 -#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 -#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 -#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 -#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 -#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 -#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA -#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB -#define GL_COLOR_TABLE 0x80D0 -#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 -#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 -#define GL_PROXY_COLOR_TABLE 0x80D3 -#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 -#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 -#define GL_COLOR_TABLE_SCALE 0x80D6 -#define GL_COLOR_TABLE_BIAS 0x80D7 -#define GL_COLOR_TABLE_FORMAT 0x80D8 -#define GL_COLOR_TABLE_WIDTH 0x80D9 -#define GL_COLOR_TABLE_RED_SIZE 0x80DA -#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB -#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC -#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD -#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE -#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF -#define GL_CONSTANT_BORDER 0x8151 -#define GL_REPLICATE_BORDER 0x8153 -#define GL_CONVOLUTION_BORDER_COLOR 0x8154 -#endif - -#ifndef GL_VERSION_1_3 -#define GL_TEXTURE0 0x84C0 -#define GL_TEXTURE1 0x84C1 -#define GL_TEXTURE2 0x84C2 -#define GL_TEXTURE3 0x84C3 -#define GL_TEXTURE4 0x84C4 -#define GL_TEXTURE5 0x84C5 -#define GL_TEXTURE6 0x84C6 -#define GL_TEXTURE7 0x84C7 -#define GL_TEXTURE8 0x84C8 -#define GL_TEXTURE9 0x84C9 -#define GL_TEXTURE10 0x84CA -#define GL_TEXTURE11 0x84CB -#define GL_TEXTURE12 0x84CC -#define GL_TEXTURE13 0x84CD -#define GL_TEXTURE14 0x84CE -#define GL_TEXTURE15 0x84CF -#define GL_TEXTURE16 0x84D0 -#define GL_TEXTURE17 0x84D1 -#define GL_TEXTURE18 0x84D2 -#define GL_TEXTURE19 0x84D3 -#define GL_TEXTURE20 0x84D4 -#define GL_TEXTURE21 0x84D5 -#define GL_TEXTURE22 0x84D6 -#define GL_TEXTURE23 0x84D7 -#define GL_TEXTURE24 0x84D8 -#define GL_TEXTURE25 0x84D9 -#define GL_TEXTURE26 0x84DA -#define GL_TEXTURE27 0x84DB -#define GL_TEXTURE28 0x84DC -#define GL_TEXTURE29 0x84DD -#define GL_TEXTURE30 0x84DE -#define GL_TEXTURE31 0x84DF -#define GL_ACTIVE_TEXTURE 0x84E0 -#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 -#define GL_MAX_TEXTURE_UNITS 0x84E2 -#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 -#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 -#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 -#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 -#define GL_MULTISAMPLE 0x809D -#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE 0x809F -#define GL_SAMPLE_COVERAGE 0x80A0 -#define GL_SAMPLE_BUFFERS 0x80A8 -#define GL_SAMPLES 0x80A9 -#define GL_SAMPLE_COVERAGE_VALUE 0x80AA -#define GL_SAMPLE_COVERAGE_INVERT 0x80AB -#define GL_MULTISAMPLE_BIT 0x20000000 -#define GL_NORMAL_MAP 0x8511 -#define GL_REFLECTION_MAP 0x8512 -#define GL_TEXTURE_CUBE_MAP 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A -#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C -#define GL_COMPRESSED_ALPHA 0x84E9 -#define GL_COMPRESSED_LUMINANCE 0x84EA -#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB -#define GL_COMPRESSED_INTENSITY 0x84EC -#define GL_COMPRESSED_RGB 0x84ED -#define GL_COMPRESSED_RGBA 0x84EE -#define GL_TEXTURE_COMPRESSION_HINT 0x84EF -#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 -#define GL_TEXTURE_COMPRESSED 0x86A1 -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 -#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 -#define GL_CLAMP_TO_BORDER 0x812D -#define GL_COMBINE 0x8570 -#define GL_COMBINE_RGB 0x8571 -#define GL_COMBINE_ALPHA 0x8572 -#define GL_SOURCE0_RGB 0x8580 -#define GL_SOURCE1_RGB 0x8581 -#define GL_SOURCE2_RGB 0x8582 -#define GL_SOURCE0_ALPHA 0x8588 -#define GL_SOURCE1_ALPHA 0x8589 -#define GL_SOURCE2_ALPHA 0x858A -#define GL_OPERAND0_RGB 0x8590 -#define GL_OPERAND1_RGB 0x8591 -#define GL_OPERAND2_RGB 0x8592 -#define GL_OPERAND0_ALPHA 0x8598 -#define GL_OPERAND1_ALPHA 0x8599 -#define GL_OPERAND2_ALPHA 0x859A -#define GL_RGB_SCALE 0x8573 -#define GL_ADD_SIGNED 0x8574 -#define GL_INTERPOLATE 0x8575 -#define GL_SUBTRACT 0x84E7 -#define GL_CONSTANT 0x8576 -#define GL_PRIMARY_COLOR 0x8577 -#define GL_PREVIOUS 0x8578 -#define GL_DOT3_RGB 0x86AE -#define GL_DOT3_RGBA 0x86AF -#endif - -#ifndef GL_VERSION_1_4 -#define GL_BLEND_DST_RGB 0x80C8 -#define GL_BLEND_SRC_RGB 0x80C9 -#define GL_BLEND_DST_ALPHA 0x80CA -#define GL_BLEND_SRC_ALPHA 0x80CB -#define GL_POINT_SIZE_MIN 0x8126 -#define GL_POINT_SIZE_MAX 0x8127 -#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 -#define GL_POINT_DISTANCE_ATTENUATION 0x8129 -#define GL_GENERATE_MIPMAP 0x8191 -#define GL_GENERATE_MIPMAP_HINT 0x8192 -#define GL_DEPTH_COMPONENT16 0x81A5 -#define GL_DEPTH_COMPONENT24 0x81A6 -#define GL_DEPTH_COMPONENT32 0x81A7 -#define GL_MIRRORED_REPEAT 0x8370 -#define GL_FOG_COORDINATE_SOURCE 0x8450 -#define GL_FOG_COORDINATE 0x8451 -#define GL_FRAGMENT_DEPTH 0x8452 -#define GL_CURRENT_FOG_COORDINATE 0x8453 -#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 -#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 -#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 -#define GL_FOG_COORDINATE_ARRAY 0x8457 -#define GL_COLOR_SUM 0x8458 -#define GL_CURRENT_SECONDARY_COLOR 0x8459 -#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A -#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B -#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C -#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D -#define GL_SECONDARY_COLOR_ARRAY 0x845E -#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD -#define GL_TEXTURE_FILTER_CONTROL 0x8500 -#define GL_TEXTURE_LOD_BIAS 0x8501 -#define GL_INCR_WRAP 0x8507 -#define GL_DECR_WRAP 0x8508 -#define GL_TEXTURE_DEPTH_SIZE 0x884A -#define GL_DEPTH_TEXTURE_MODE 0x884B -#define GL_TEXTURE_COMPARE_MODE 0x884C -#define GL_TEXTURE_COMPARE_FUNC 0x884D -#define GL_COMPARE_R_TO_TEXTURE 0x884E -#endif - -#ifndef GL_VERSION_1_5 -#define GL_BUFFER_SIZE 0x8764 -#define GL_BUFFER_USAGE 0x8765 -#define GL_QUERY_COUNTER_BITS 0x8864 -#define GL_CURRENT_QUERY 0x8865 -#define GL_QUERY_RESULT 0x8866 -#define GL_QUERY_RESULT_AVAILABLE 0x8867 -#define GL_ARRAY_BUFFER 0x8892 -#define GL_ELEMENT_ARRAY_BUFFER 0x8893 -#define GL_ARRAY_BUFFER_BINDING 0x8894 -#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 -#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 -#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 -#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 -#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 -#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A -#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B -#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C -#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D -#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E -#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F -#define GL_READ_ONLY 0x88B8 -#define GL_WRITE_ONLY 0x88B9 -#define GL_READ_WRITE 0x88BA -#define GL_BUFFER_ACCESS 0x88BB -#define GL_BUFFER_MAPPED 0x88BC -#define GL_BUFFER_MAP_POINTER 0x88BD -#define GL_STREAM_DRAW 0x88E0 -#define GL_STREAM_READ 0x88E1 -#define GL_STREAM_COPY 0x88E2 -#define GL_STATIC_DRAW 0x88E4 -#define GL_STATIC_READ 0x88E5 -#define GL_STATIC_COPY 0x88E6 -#define GL_DYNAMIC_DRAW 0x88E8 -#define GL_DYNAMIC_READ 0x88E9 -#define GL_DYNAMIC_COPY 0x88EA -#define GL_SAMPLES_PASSED 0x8914 -#define GL_FOG_COORD_SRC GL_FOG_COORDINATE_SOURCE -#define GL_FOG_COORD GL_FOG_COORDINATE -#define GL_CURRENT_FOG_COORD GL_CURRENT_FOG_COORDINATE -#define GL_FOG_COORD_ARRAY_TYPE GL_FOG_COORDINATE_ARRAY_TYPE -#define GL_FOG_COORD_ARRAY_STRIDE GL_FOG_COORDINATE_ARRAY_STRIDE -#define GL_FOG_COORD_ARRAY_POINTER GL_FOG_COORDINATE_ARRAY_POINTER -#define GL_FOG_COORD_ARRAY GL_FOG_COORDINATE_ARRAY -#define GL_FOG_COORD_ARRAY_BUFFER_BINDING GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING -#define GL_SRC0_RGB GL_SOURCE0_RGB -#define GL_SRC1_RGB GL_SOURCE1_RGB -#define GL_SRC2_RGB GL_SOURCE2_RGB -#define GL_SRC0_ALPHA GL_SOURCE0_ALPHA -#define GL_SRC1_ALPHA GL_SOURCE1_ALPHA -#define GL_SRC2_ALPHA GL_SOURCE2_ALPHA -#endif - -#ifndef GL_VERSION_2_0 - -#ifndef GL_BLEND_EQUATION_RGB -#define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION -#endif - -#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 -#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 -#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 -#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 -#define GL_CURRENT_VERTEX_ATTRIB 0x8626 -#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 -#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 -#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 -#define GL_STENCIL_BACK_FUNC 0x8800 -#define GL_STENCIL_BACK_FAIL 0x8801 -#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 -#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 -#define GL_MAX_DRAW_BUFFERS 0x8824 -#define GL_DRAW_BUFFER0 0x8825 -#define GL_DRAW_BUFFER1 0x8826 -#define GL_DRAW_BUFFER2 0x8827 -#define GL_DRAW_BUFFER3 0x8828 -#define GL_DRAW_BUFFER4 0x8829 -#define GL_DRAW_BUFFER5 0x882A -#define GL_DRAW_BUFFER6 0x882B -#define GL_DRAW_BUFFER7 0x882C -#define GL_DRAW_BUFFER8 0x882D -#define GL_DRAW_BUFFER9 0x882E -#define GL_DRAW_BUFFER10 0x882F -#define GL_DRAW_BUFFER11 0x8830 -#define GL_DRAW_BUFFER12 0x8831 -#define GL_DRAW_BUFFER13 0x8832 -#define GL_DRAW_BUFFER14 0x8833 -#define GL_DRAW_BUFFER15 0x8834 -#define GL_BLEND_EQUATION_ALPHA 0x883D -#define GL_POINT_SPRITE 0x8861 -#define GL_COORD_REPLACE 0x8862 -#define GL_MAX_VERTEX_ATTRIBS 0x8869 -#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A -#define GL_MAX_TEXTURE_COORDS 0x8871 -#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 -#define GL_FRAGMENT_SHADER 0x8B30 -#define GL_VERTEX_SHADER 0x8B31 -#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 -#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A -#define GL_MAX_VARYING_FLOATS 0x8B4B -#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C -#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D -#define GL_SHADER_TYPE 0x8B4F -#define GL_FLOAT_VEC2 0x8B50 -#define GL_FLOAT_VEC3 0x8B51 -#define GL_FLOAT_VEC4 0x8B52 -#define GL_INT_VEC2 0x8B53 -#define GL_INT_VEC3 0x8B54 -#define GL_INT_VEC4 0x8B55 -#define GL_BOOL 0x8B56 -#define GL_BOOL_VEC2 0x8B57 -#define GL_BOOL_VEC3 0x8B58 -#define GL_BOOL_VEC4 0x8B59 -#define GL_FLOAT_MAT2 0x8B5A -#define GL_FLOAT_MAT3 0x8B5B -#define GL_FLOAT_MAT4 0x8B5C -#define GL_SAMPLER_1D 0x8B5D -#define GL_SAMPLER_2D 0x8B5E -#define GL_SAMPLER_3D 0x8B5F -#define GL_SAMPLER_CUBE 0x8B60 -#define GL_SAMPLER_1D_SHADOW 0x8B61 -#define GL_SAMPLER_2D_SHADOW 0x8B62 -#define GL_DELETE_STATUS 0x8B80 -#define GL_COMPILE_STATUS 0x8B81 -#define GL_LINK_STATUS 0x8B82 -#define GL_VALIDATE_STATUS 0x8B83 -#define GL_INFO_LOG_LENGTH 0x8B84 -#define GL_ATTACHED_SHADERS 0x8B85 -#define GL_ACTIVE_UNIFORMS 0x8B86 -#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 -#define GL_SHADER_SOURCE_LENGTH 0x8B88 -#define GL_ACTIVE_ATTRIBUTES 0x8B89 -#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A -#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B -#define GL_SHADING_LANGUAGE_VERSION 0x8B8C -#define GL_CURRENT_PROGRAM 0x8B8D -#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 -#define GL_LOWER_LEFT 0x8CA1 -#define GL_UPPER_LEFT 0x8CA2 -#define GL_STENCIL_BACK_REF 0x8CA3 -#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 -#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 -#endif - -#ifndef GL_VERSION_2_1 -#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F -#define GL_PIXEL_PACK_BUFFER 0x88EB -#define GL_PIXEL_UNPACK_BUFFER 0x88EC -#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED -#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF -#define GL_FLOAT_MAT2x3 0x8B65 -#define GL_FLOAT_MAT2x4 0x8B66 -#define GL_FLOAT_MAT3x2 0x8B67 -#define GL_FLOAT_MAT3x4 0x8B68 -#define GL_FLOAT_MAT4x2 0x8B69 -#define GL_FLOAT_MAT4x3 0x8B6A -#define GL_SRGB 0x8C40 -#define GL_SRGB8 0x8C41 -#define GL_SRGB_ALPHA 0x8C42 -#define GL_SRGB8_ALPHA8 0x8C43 -#define GL_SLUMINANCE_ALPHA 0x8C44 -#define GL_SLUMINANCE8_ALPHA8 0x8C45 -#define GL_SLUMINANCE 0x8C46 -#define GL_SLUMINANCE8 0x8C47 -#define GL_COMPRESSED_SRGB 0x8C48 -#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 -#define GL_COMPRESSED_SLUMINANCE 0x8C4A -#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B -#endif - -#ifndef GL_VERSION_3_0 -#define GL_COMPARE_REF_TO_TEXTURE GL_COMPARE_R_TO_TEXTURE_ARB -#define GL_CLIP_DISTANCE0 GL_CLIP_PLANE0 -#define GL_CLIP_DISTANCE1 GL_CLIP_PLANE1 -#define GL_CLIP_DISTANCE2 GL_CLIP_PLANE2 -#define GL_CLIP_DISTANCE3 GL_CLIP_PLANE3 -#define GL_CLIP_DISTANCE4 GL_CLIP_PLANE4 -#define GL_CLIP_DISTANCE5 GL_CLIP_PLANE5 -#define GL_MAX_CLIP_DISTANCES GL_MAX_CLIP_PLANES -#define GL_MAJOR_VERSION 0x821B -#define GL_MINOR_VERSION 0x821C -#define GL_NUM_EXTENSIONS 0x821D -#define GL_CONTEXT_FLAGS 0x821E -#define GL_DEPTH_BUFFER 0x8223 -#define GL_STENCIL_BUFFER 0x8224 -#define GL_COMPRESSED_RED 0x8225 -#define GL_COMPRESSED_RG 0x8226 -#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001 -#define GL_RGBA32F 0x8814 -#define GL_RGB32F 0x8815 -#define GL_RGBA16F 0x881A -#define GL_RGB16F 0x881B -#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD -#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF -#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 -#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 -#define GL_CLAMP_VERTEX_COLOR 0x891A -#define GL_CLAMP_FRAGMENT_COLOR 0x891B -#define GL_CLAMP_READ_COLOR 0x891C -#define GL_FIXED_ONLY 0x891D -#define GL_MAX_VARYING_COMPONENTS GL_MAX_VARYING_FLOATS -#define GL_TEXTURE_RED_TYPE 0x8C10 -#define GL_TEXTURE_GREEN_TYPE 0x8C11 -#define GL_TEXTURE_BLUE_TYPE 0x8C12 -#define GL_TEXTURE_ALPHA_TYPE 0x8C13 -#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 -#define GL_TEXTURE_INTENSITY_TYPE 0x8C15 -#define GL_TEXTURE_DEPTH_TYPE 0x8C16 -#define GL_UNSIGNED_NORMALIZED 0x8C17 -#define GL_TEXTURE_1D_ARRAY 0x8C18 -#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 -#define GL_TEXTURE_2D_ARRAY 0x8C1A -#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B -#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C -#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D -#define GL_R11F_G11F_B10F 0x8C3A -#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B -#define GL_RGB9_E5 0x8C3D -#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E -#define GL_TEXTURE_SHARED_SIZE 0x8C3F -#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 -#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 -#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 -#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 -#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 -#define GL_PRIMITIVES_GENERATED 0x8C87 -#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 -#define GL_RASTERIZER_DISCARD 0x8C89 -#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B -#define GL_INTERLEAVED_ATTRIBS 0x8C8C -#define GL_SEPARATE_ATTRIBS 0x8C8D -#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E -#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F -#define GL_RGBA32UI 0x8D70 -#define GL_RGB32UI 0x8D71 -#define GL_RGBA16UI 0x8D76 -#define GL_RGB16UI 0x8D77 -#define GL_RGBA8UI 0x8D7C -#define GL_RGB8UI 0x8D7D -#define GL_RGBA32I 0x8D82 -#define GL_RGB32I 0x8D83 -#define GL_RGBA16I 0x8D88 -#define GL_RGB16I 0x8D89 -#define GL_RGBA8I 0x8D8E -#define GL_RGB8I 0x8D8F -#define GL_RED_INTEGER 0x8D94 -#define GL_GREEN_INTEGER 0x8D95 -#define GL_BLUE_INTEGER 0x8D96 -#define GL_ALPHA_INTEGER 0x8D97 -#define GL_RGB_INTEGER 0x8D98 -#define GL_RGBA_INTEGER 0x8D99 -#define GL_BGR_INTEGER 0x8D9A -#define GL_BGRA_INTEGER 0x8D9B -#define GL_SAMPLER_1D_ARRAY 0x8DC0 -#define GL_SAMPLER_2D_ARRAY 0x8DC1 -#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 -#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 -#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 -#define GL_UNSIGNED_INT_VEC2 0x8DC6 -#define GL_UNSIGNED_INT_VEC3 0x8DC7 -#define GL_UNSIGNED_INT_VEC4 0x8DC8 -#define GL_INT_SAMPLER_1D 0x8DC9 -#define GL_INT_SAMPLER_2D 0x8DCA -#define GL_INT_SAMPLER_3D 0x8DCB -#define GL_INT_SAMPLER_CUBE 0x8DCC -#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE -#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF -#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 -#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 -#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 -#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 -#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 -#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 -#define GL_QUERY_WAIT 0x8E13 -#define GL_QUERY_NO_WAIT 0x8E14 -#define GL_QUERY_BY_REGION_WAIT 0x8E15 -#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 -/* Reuse tokens from ARB_depth_buffer_float */ -/* reuse GL_DEPTH_COMPONENT32F */ -/* reuse GL_DEPTH32F_STENCIL8 */ -/* reuse GL_FLOAT_32_UNSIGNED_INT_24_8_REV */ -/* Reuse tokens from ARB_framebuffer_object */ -/* reuse GL_INVALID_FRAMEBUFFER_OPERATION */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE */ -/* reuse GL_FRAMEBUFFER_DEFAULT */ -/* reuse GL_FRAMEBUFFER_UNDEFINED */ -/* reuse GL_DEPTH_STENCIL_ATTACHMENT */ -/* reuse GL_INDEX */ -/* reuse GL_MAX_RENDERBUFFER_SIZE */ -/* reuse GL_DEPTH_STENCIL */ -/* reuse GL_UNSIGNED_INT_24_8 */ -/* reuse GL_DEPTH24_STENCIL8 */ -/* reuse GL_TEXTURE_STENCIL_SIZE */ -/* reuse GL_TEXTURE_RED_TYPE */ -/* reuse GL_TEXTURE_GREEN_TYPE */ -/* reuse GL_TEXTURE_BLUE_TYPE */ -/* reuse GL_TEXTURE_ALPHA_TYPE */ -/* reuse GL_TEXTURE_LUMINANCE_TYPE */ -/* reuse GL_TEXTURE_INTENSITY_TYPE */ -/* reuse GL_TEXTURE_DEPTH_TYPE */ -/* reuse GL_UNSIGNED_NORMALIZED */ -/* reuse GL_FRAMEBUFFER_BINDING */ -/* reuse GL_DRAW_FRAMEBUFFER_BINDING */ -/* reuse GL_RENDERBUFFER_BINDING */ -/* reuse GL_READ_FRAMEBUFFER */ -/* reuse GL_DRAW_FRAMEBUFFER */ -/* reuse GL_READ_FRAMEBUFFER_BINDING */ -/* reuse GL_RENDERBUFFER_SAMPLES */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */ -/* reuse GL_FRAMEBUFFER_COMPLETE */ -/* reuse GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT */ -/* reuse GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT */ -/* reuse GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER */ -/* reuse GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER */ -/* reuse GL_FRAMEBUFFER_UNSUPPORTED */ -/* reuse GL_MAX_COLOR_ATTACHMENTS */ -/* reuse GL_COLOR_ATTACHMENT0 */ -/* reuse GL_COLOR_ATTACHMENT1 */ -/* reuse GL_COLOR_ATTACHMENT2 */ -/* reuse GL_COLOR_ATTACHMENT3 */ -/* reuse GL_COLOR_ATTACHMENT4 */ -/* reuse GL_COLOR_ATTACHMENT5 */ -/* reuse GL_COLOR_ATTACHMENT6 */ -/* reuse GL_COLOR_ATTACHMENT7 */ -/* reuse GL_COLOR_ATTACHMENT8 */ -/* reuse GL_COLOR_ATTACHMENT9 */ -/* reuse GL_COLOR_ATTACHMENT10 */ -/* reuse GL_COLOR_ATTACHMENT11 */ -/* reuse GL_COLOR_ATTACHMENT12 */ -/* reuse GL_COLOR_ATTACHMENT13 */ -/* reuse GL_COLOR_ATTACHMENT14 */ -/* reuse GL_COLOR_ATTACHMENT15 */ -/* reuse GL_DEPTH_ATTACHMENT */ -/* reuse GL_STENCIL_ATTACHMENT */ -/* reuse GL_FRAMEBUFFER */ -/* reuse GL_RENDERBUFFER */ -/* reuse GL_RENDERBUFFER_WIDTH */ -/* reuse GL_RENDERBUFFER_HEIGHT */ -/* reuse GL_RENDERBUFFER_INTERNAL_FORMAT */ -/* reuse GL_STENCIL_INDEX1 */ -/* reuse GL_STENCIL_INDEX4 */ -/* reuse GL_STENCIL_INDEX8 */ -/* reuse GL_STENCIL_INDEX16 */ -/* reuse GL_RENDERBUFFER_RED_SIZE */ -/* reuse GL_RENDERBUFFER_GREEN_SIZE */ -/* reuse GL_RENDERBUFFER_BLUE_SIZE */ -/* reuse GL_RENDERBUFFER_ALPHA_SIZE */ -/* reuse GL_RENDERBUFFER_DEPTH_SIZE */ -/* reuse GL_RENDERBUFFER_STENCIL_SIZE */ -/* reuse GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE */ -/* reuse GL_MAX_SAMPLES */ -/* Reuse tokens from ARB_framebuffer_sRGB */ -/* reuse GL_FRAMEBUFFER_SRGB */ -/* Reuse tokens from ARB_half_float_vertex */ -/* reuse GL_HALF_FLOAT */ -/* Reuse tokens from ARB_map_buffer_range */ -/* reuse GL_MAP_READ_BIT */ -/* reuse GL_MAP_WRITE_BIT */ -/* reuse GL_MAP_INVALIDATE_RANGE_BIT */ -/* reuse GL_MAP_INVALIDATE_BUFFER_BIT */ -/* reuse GL_MAP_FLUSH_EXPLICIT_BIT */ -/* reuse GL_MAP_UNSYNCHRONIZED_BIT */ -/* Reuse tokens from ARB_texture_compression_rgtc */ -/* reuse GL_COMPRESSED_RED_RGTC1 */ -/* reuse GL_COMPRESSED_SIGNED_RED_RGTC1 */ -/* reuse GL_COMPRESSED_RG_RGTC2 */ -/* reuse GL_COMPRESSED_SIGNED_RG_RGTC2 */ -/* Reuse tokens from ARB_texture_rg */ -/* reuse GL_RG */ -/* reuse GL_RG_INTEGER */ -/* reuse GL_R8 */ -/* reuse GL_R16 */ -/* reuse GL_RG8 */ -/* reuse GL_RG16 */ -/* reuse GL_R16F */ -/* reuse GL_R32F */ -/* reuse GL_RG16F */ -/* reuse GL_RG32F */ -/* reuse GL_R8I */ -/* reuse GL_R8UI */ -/* reuse GL_R16I */ -/* reuse GL_R16UI */ -/* reuse GL_R32I */ -/* reuse GL_R32UI */ -/* reuse GL_RG8I */ -/* reuse GL_RG8UI */ -/* reuse GL_RG16I */ -/* reuse GL_RG16UI */ -/* reuse GL_RG32I */ -/* reuse GL_RG32UI */ -/* Reuse tokens from ARB_vertex_array_object */ -/* reuse GL_VERTEX_ARRAY_BINDING */ -#endif - -#ifndef GL_ARB_multitexture -#define GL_TEXTURE0_ARB 0x84C0 -#define GL_TEXTURE1_ARB 0x84C1 -#define GL_TEXTURE2_ARB 0x84C2 -#define GL_TEXTURE3_ARB 0x84C3 -#define GL_TEXTURE4_ARB 0x84C4 -#define GL_TEXTURE5_ARB 0x84C5 -#define GL_TEXTURE6_ARB 0x84C6 -#define GL_TEXTURE7_ARB 0x84C7 -#define GL_TEXTURE8_ARB 0x84C8 -#define GL_TEXTURE9_ARB 0x84C9 -#define GL_TEXTURE10_ARB 0x84CA -#define GL_TEXTURE11_ARB 0x84CB -#define GL_TEXTURE12_ARB 0x84CC -#define GL_TEXTURE13_ARB 0x84CD -#define GL_TEXTURE14_ARB 0x84CE -#define GL_TEXTURE15_ARB 0x84CF -#define GL_TEXTURE16_ARB 0x84D0 -#define GL_TEXTURE17_ARB 0x84D1 -#define GL_TEXTURE18_ARB 0x84D2 -#define GL_TEXTURE19_ARB 0x84D3 -#define GL_TEXTURE20_ARB 0x84D4 -#define GL_TEXTURE21_ARB 0x84D5 -#define GL_TEXTURE22_ARB 0x84D6 -#define GL_TEXTURE23_ARB 0x84D7 -#define GL_TEXTURE24_ARB 0x84D8 -#define GL_TEXTURE25_ARB 0x84D9 -#define GL_TEXTURE26_ARB 0x84DA -#define GL_TEXTURE27_ARB 0x84DB -#define GL_TEXTURE28_ARB 0x84DC -#define GL_TEXTURE29_ARB 0x84DD -#define GL_TEXTURE30_ARB 0x84DE -#define GL_TEXTURE31_ARB 0x84DF -#define GL_ACTIVE_TEXTURE_ARB 0x84E0 -#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 -#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 -#endif - -#ifndef GL_ARB_transpose_matrix -#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 -#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 -#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 -#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 -#endif - -#ifndef GL_ARB_multisample -#define GL_MULTISAMPLE_ARB 0x809D -#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F -#define GL_SAMPLE_COVERAGE_ARB 0x80A0 -#define GL_SAMPLE_BUFFERS_ARB 0x80A8 -#define GL_SAMPLES_ARB 0x80A9 -#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA -#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB -#define GL_MULTISAMPLE_BIT_ARB 0x20000000 -#endif - -#ifndef GL_ARB_texture_env_add -#endif - -#ifndef GL_ARB_texture_cube_map -#define GL_NORMAL_MAP_ARB 0x8511 -#define GL_REFLECTION_MAP_ARB 0x8512 -#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A -#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C -#endif - -#ifndef GL_ARB_texture_compression -#define GL_COMPRESSED_ALPHA_ARB 0x84E9 -#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA -#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB -#define GL_COMPRESSED_INTENSITY_ARB 0x84EC -#define GL_COMPRESSED_RGB_ARB 0x84ED -#define GL_COMPRESSED_RGBA_ARB 0x84EE -#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF -#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 -#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 -#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 -#endif - -#ifndef GL_ARB_texture_border_clamp -#define GL_CLAMP_TO_BORDER_ARB 0x812D -#endif - -#ifndef GL_ARB_point_parameters -#define GL_POINT_SIZE_MIN_ARB 0x8126 -#define GL_POINT_SIZE_MAX_ARB 0x8127 -#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 -#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 -#endif - -#ifndef GL_ARB_vertex_blend -#define GL_MAX_VERTEX_UNITS_ARB 0x86A4 -#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 -#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 -#define GL_VERTEX_BLEND_ARB 0x86A7 -#define GL_CURRENT_WEIGHT_ARB 0x86A8 -#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 -#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA -#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB -#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC -#define GL_WEIGHT_ARRAY_ARB 0x86AD -#define GL_MODELVIEW0_ARB 0x1700 -#define GL_MODELVIEW1_ARB 0x850A -#define GL_MODELVIEW2_ARB 0x8722 -#define GL_MODELVIEW3_ARB 0x8723 -#define GL_MODELVIEW4_ARB 0x8724 -#define GL_MODELVIEW5_ARB 0x8725 -#define GL_MODELVIEW6_ARB 0x8726 -#define GL_MODELVIEW7_ARB 0x8727 -#define GL_MODELVIEW8_ARB 0x8728 -#define GL_MODELVIEW9_ARB 0x8729 -#define GL_MODELVIEW10_ARB 0x872A -#define GL_MODELVIEW11_ARB 0x872B -#define GL_MODELVIEW12_ARB 0x872C -#define GL_MODELVIEW13_ARB 0x872D -#define GL_MODELVIEW14_ARB 0x872E -#define GL_MODELVIEW15_ARB 0x872F -#define GL_MODELVIEW16_ARB 0x8730 -#define GL_MODELVIEW17_ARB 0x8731 -#define GL_MODELVIEW18_ARB 0x8732 -#define GL_MODELVIEW19_ARB 0x8733 -#define GL_MODELVIEW20_ARB 0x8734 -#define GL_MODELVIEW21_ARB 0x8735 -#define GL_MODELVIEW22_ARB 0x8736 -#define GL_MODELVIEW23_ARB 0x8737 -#define GL_MODELVIEW24_ARB 0x8738 -#define GL_MODELVIEW25_ARB 0x8739 -#define GL_MODELVIEW26_ARB 0x873A -#define GL_MODELVIEW27_ARB 0x873B -#define GL_MODELVIEW28_ARB 0x873C -#define GL_MODELVIEW29_ARB 0x873D -#define GL_MODELVIEW30_ARB 0x873E -#define GL_MODELVIEW31_ARB 0x873F -#endif - -#ifndef GL_ARB_matrix_palette -#define GL_MATRIX_PALETTE_ARB 0x8840 -#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 -#define GL_MAX_PALETTE_MATRICES_ARB 0x8842 -#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 -#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 -#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 -#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 -#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 -#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 -#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 -#endif - -#ifndef GL_ARB_texture_env_combine -#define GL_COMBINE_ARB 0x8570 -#define GL_COMBINE_RGB_ARB 0x8571 -#define GL_COMBINE_ALPHA_ARB 0x8572 -#define GL_SOURCE0_RGB_ARB 0x8580 -#define GL_SOURCE1_RGB_ARB 0x8581 -#define GL_SOURCE2_RGB_ARB 0x8582 -#define GL_SOURCE0_ALPHA_ARB 0x8588 -#define GL_SOURCE1_ALPHA_ARB 0x8589 -#define GL_SOURCE2_ALPHA_ARB 0x858A -#define GL_OPERAND0_RGB_ARB 0x8590 -#define GL_OPERAND1_RGB_ARB 0x8591 -#define GL_OPERAND2_RGB_ARB 0x8592 -#define GL_OPERAND0_ALPHA_ARB 0x8598 -#define GL_OPERAND1_ALPHA_ARB 0x8599 -#define GL_OPERAND2_ALPHA_ARB 0x859A -#define GL_RGB_SCALE_ARB 0x8573 -#define GL_ADD_SIGNED_ARB 0x8574 -#define GL_INTERPOLATE_ARB 0x8575 -#define GL_SUBTRACT_ARB 0x84E7 -#define GL_CONSTANT_ARB 0x8576 -#define GL_PRIMARY_COLOR_ARB 0x8577 -#define GL_PREVIOUS_ARB 0x8578 -#endif - -#ifndef GL_ARB_texture_env_crossbar -#endif - -#ifndef GL_ARB_texture_env_dot3 -#define GL_DOT3_RGB_ARB 0x86AE -#define GL_DOT3_RGBA_ARB 0x86AF -#endif - -#ifndef GL_ARB_texture_mirrored_repeat -#define GL_MIRRORED_REPEAT_ARB 0x8370 -#endif - -#ifndef GL_ARB_depth_texture -#define GL_DEPTH_COMPONENT16_ARB 0x81A5 -#define GL_DEPTH_COMPONENT24_ARB 0x81A6 -#define GL_DEPTH_COMPONENT32_ARB 0x81A7 -#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A -#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B -#endif - -#ifndef GL_ARB_shadow -#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C -#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D -#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E -#endif - -#ifndef GL_ARB_shadow_ambient -#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF -#endif - -#ifndef GL_ARB_window_pos -#endif - -#ifndef GL_ARB_vertex_program -#define GL_COLOR_SUM_ARB 0x8458 -#define GL_VERTEX_PROGRAM_ARB 0x8620 -#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 -#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 -#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 -#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 -#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 -#define GL_PROGRAM_LENGTH_ARB 0x8627 -#define GL_PROGRAM_STRING_ARB 0x8628 -#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E -#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F -#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 -#define GL_CURRENT_MATRIX_ARB 0x8641 -#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 -#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 -#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 -#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B -#define GL_PROGRAM_BINDING_ARB 0x8677 -#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 -#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A -#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 -#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 -#define GL_PROGRAM_FORMAT_ARB 0x8876 -#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 -#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 -#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 -#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 -#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 -#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 -#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 -#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 -#define GL_PROGRAM_PARAMETERS_ARB 0x88A8 -#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 -#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA -#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB -#define GL_PROGRAM_ATTRIBS_ARB 0x88AC -#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD -#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE -#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF -#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 -#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 -#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 -#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 -#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 -#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 -#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 -#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 -#define GL_MATRIX0_ARB 0x88C0 -#define GL_MATRIX1_ARB 0x88C1 -#define GL_MATRIX2_ARB 0x88C2 -#define GL_MATRIX3_ARB 0x88C3 -#define GL_MATRIX4_ARB 0x88C4 -#define GL_MATRIX5_ARB 0x88C5 -#define GL_MATRIX6_ARB 0x88C6 -#define GL_MATRIX7_ARB 0x88C7 -#define GL_MATRIX8_ARB 0x88C8 -#define GL_MATRIX9_ARB 0x88C9 -#define GL_MATRIX10_ARB 0x88CA -#define GL_MATRIX11_ARB 0x88CB -#define GL_MATRIX12_ARB 0x88CC -#define GL_MATRIX13_ARB 0x88CD -#define GL_MATRIX14_ARB 0x88CE -#define GL_MATRIX15_ARB 0x88CF -#define GL_MATRIX16_ARB 0x88D0 -#define GL_MATRIX17_ARB 0x88D1 -#define GL_MATRIX18_ARB 0x88D2 -#define GL_MATRIX19_ARB 0x88D3 -#define GL_MATRIX20_ARB 0x88D4 -#define GL_MATRIX21_ARB 0x88D5 -#define GL_MATRIX22_ARB 0x88D6 -#define GL_MATRIX23_ARB 0x88D7 -#define GL_MATRIX24_ARB 0x88D8 -#define GL_MATRIX25_ARB 0x88D9 -#define GL_MATRIX26_ARB 0x88DA -#define GL_MATRIX27_ARB 0x88DB -#define GL_MATRIX28_ARB 0x88DC -#define GL_MATRIX29_ARB 0x88DD -#define GL_MATRIX30_ARB 0x88DE -#define GL_MATRIX31_ARB 0x88DF -#endif - -#ifndef GL_ARB_fragment_program -#define GL_FRAGMENT_PROGRAM_ARB 0x8804 -#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 -#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 -#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 -#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 -#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 -#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A -#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B -#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C -#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D -#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E -#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F -#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 -#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 -#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 -#endif - -#ifndef GL_ARB_vertex_buffer_object -#define GL_BUFFER_SIZE_ARB 0x8764 -#define GL_BUFFER_USAGE_ARB 0x8765 -#define GL_ARRAY_BUFFER_ARB 0x8892 -#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 -#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 -#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 -#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 -#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 -#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 -#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 -#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A -#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B -#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C -#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D -#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E -#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F -#define GL_READ_ONLY_ARB 0x88B8 -#define GL_WRITE_ONLY_ARB 0x88B9 -#define GL_READ_WRITE_ARB 0x88BA -#define GL_BUFFER_ACCESS_ARB 0x88BB -#define GL_BUFFER_MAPPED_ARB 0x88BC -#define GL_BUFFER_MAP_POINTER_ARB 0x88BD -#define GL_STREAM_DRAW_ARB 0x88E0 -#define GL_STREAM_READ_ARB 0x88E1 -#define GL_STREAM_COPY_ARB 0x88E2 -#define GL_STATIC_DRAW_ARB 0x88E4 -#define GL_STATIC_READ_ARB 0x88E5 -#define GL_STATIC_COPY_ARB 0x88E6 -#define GL_DYNAMIC_DRAW_ARB 0x88E8 -#define GL_DYNAMIC_READ_ARB 0x88E9 -#define GL_DYNAMIC_COPY_ARB 0x88EA -#endif - -#ifndef GL_ARB_occlusion_query -#define GL_QUERY_COUNTER_BITS_ARB 0x8864 -#define GL_CURRENT_QUERY_ARB 0x8865 -#define GL_QUERY_RESULT_ARB 0x8866 -#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 -#define GL_SAMPLES_PASSED_ARB 0x8914 -#endif - -#ifndef GL_ARB_shader_objects -#define GL_PROGRAM_OBJECT_ARB 0x8B40 -#define GL_SHADER_OBJECT_ARB 0x8B48 -#define GL_OBJECT_TYPE_ARB 0x8B4E -#define GL_OBJECT_SUBTYPE_ARB 0x8B4F -#define GL_FLOAT_VEC2_ARB 0x8B50 -#define GL_FLOAT_VEC3_ARB 0x8B51 -#define GL_FLOAT_VEC4_ARB 0x8B52 -#define GL_INT_VEC2_ARB 0x8B53 -#define GL_INT_VEC3_ARB 0x8B54 -#define GL_INT_VEC4_ARB 0x8B55 -#define GL_BOOL_ARB 0x8B56 -#define GL_BOOL_VEC2_ARB 0x8B57 -#define GL_BOOL_VEC3_ARB 0x8B58 -#define GL_BOOL_VEC4_ARB 0x8B59 -#define GL_FLOAT_MAT2_ARB 0x8B5A -#define GL_FLOAT_MAT3_ARB 0x8B5B -#define GL_FLOAT_MAT4_ARB 0x8B5C -#define GL_SAMPLER_1D_ARB 0x8B5D -#define GL_SAMPLER_2D_ARB 0x8B5E -#define GL_SAMPLER_3D_ARB 0x8B5F -#define GL_SAMPLER_CUBE_ARB 0x8B60 -#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 -#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 -#define GL_SAMPLER_2D_RECT_ARB 0x8B63 -#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 -#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 -#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 -#define GL_OBJECT_LINK_STATUS_ARB 0x8B82 -#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 -#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 -#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 -#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 -#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 -#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 -#endif - -#ifndef GL_ARB_vertex_shader -#define GL_VERTEX_SHADER_ARB 0x8B31 -#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A -#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B -#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C -#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D -#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 -#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A -#endif - -#ifndef GL_ARB_fragment_shader -#define GL_FRAGMENT_SHADER_ARB 0x8B30 -#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 -#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B -#endif - -#ifndef GL_ARB_shading_language_100 -#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C -#endif - -#ifndef GL_ARB_texture_non_power_of_two -#endif - -#ifndef GL_ARB_point_sprite -#define GL_POINT_SPRITE_ARB 0x8861 -#define GL_COORD_REPLACE_ARB 0x8862 -#endif - -#ifndef GL_ARB_fragment_program_shadow -#endif - -#ifndef GL_ARB_draw_buffers -#define GL_MAX_DRAW_BUFFERS_ARB 0x8824 -#define GL_DRAW_BUFFER0_ARB 0x8825 -#define GL_DRAW_BUFFER1_ARB 0x8826 -#define GL_DRAW_BUFFER2_ARB 0x8827 -#define GL_DRAW_BUFFER3_ARB 0x8828 -#define GL_DRAW_BUFFER4_ARB 0x8829 -#define GL_DRAW_BUFFER5_ARB 0x882A -#define GL_DRAW_BUFFER6_ARB 0x882B -#define GL_DRAW_BUFFER7_ARB 0x882C -#define GL_DRAW_BUFFER8_ARB 0x882D -#define GL_DRAW_BUFFER9_ARB 0x882E -#define GL_DRAW_BUFFER10_ARB 0x882F -#define GL_DRAW_BUFFER11_ARB 0x8830 -#define GL_DRAW_BUFFER12_ARB 0x8831 -#define GL_DRAW_BUFFER13_ARB 0x8832 -#define GL_DRAW_BUFFER14_ARB 0x8833 -#define GL_DRAW_BUFFER15_ARB 0x8834 -#endif - -#ifndef GL_ARB_texture_rectangle -#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 -#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 -#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 -#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 -#endif - -#ifndef GL_ARB_color_buffer_float -#define GL_RGBA_FLOAT_MODE_ARB 0x8820 -#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A -#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B -#define GL_CLAMP_READ_COLOR_ARB 0x891C -#define GL_FIXED_ONLY_ARB 0x891D -#endif - -#ifndef GL_ARB_half_float_pixel -#define GL_HALF_FLOAT_ARB 0x140B -#endif - -#ifndef GL_ARB_texture_float -#define GL_TEXTURE_RED_TYPE_ARB 0x8C10 -#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11 -#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12 -#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13 -#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 -#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15 -#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16 -#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17 -#define GL_RGBA32F_ARB 0x8814 -#define GL_RGB32F_ARB 0x8815 -#define GL_ALPHA32F_ARB 0x8816 -#define GL_INTENSITY32F_ARB 0x8817 -#define GL_LUMINANCE32F_ARB 0x8818 -#define GL_LUMINANCE_ALPHA32F_ARB 0x8819 -#define GL_RGBA16F_ARB 0x881A -#define GL_RGB16F_ARB 0x881B -#define GL_ALPHA16F_ARB 0x881C -#define GL_INTENSITY16F_ARB 0x881D -#define GL_LUMINANCE16F_ARB 0x881E -#define GL_LUMINANCE_ALPHA16F_ARB 0x881F -#endif - -#ifndef GL_ARB_pixel_buffer_object -#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB -#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC -#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED -#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF -#endif - -#ifndef GL_ARB_depth_buffer_float -#define GL_DEPTH_COMPONENT32F 0x8CAC -#define GL_DEPTH32F_STENCIL8 0x8CAD -#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD -#endif - -#ifndef GL_ARB_draw_instanced -#endif - -#ifndef GL_ARB_framebuffer_object -#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 -#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 -#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 -#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 -#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 -#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 -#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 -#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 -#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 -#define GL_FRAMEBUFFER_DEFAULT 0x8218 -#define GL_FRAMEBUFFER_UNDEFINED 0x8219 -#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A -#define GL_INDEX 0x8222 -#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 -#define GL_DEPTH_STENCIL 0x84F9 -#define GL_UNSIGNED_INT_24_8 0x84FA -#define GL_DEPTH24_STENCIL8 0x88F0 -#define GL_TEXTURE_STENCIL_SIZE 0x88F1 -#define GL_FRAMEBUFFER_BINDING 0x8CA6 -#define GL_DRAW_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING -#define GL_RENDERBUFFER_BINDING 0x8CA7 -#define GL_READ_FRAMEBUFFER 0x8CA8 -#define GL_DRAW_FRAMEBUFFER 0x8CA9 -#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA -#define GL_RENDERBUFFER_SAMPLES 0x8CAB -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 -#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 -#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB -#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC -#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD -#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF -#define GL_COLOR_ATTACHMENT0 0x8CE0 -#define GL_COLOR_ATTACHMENT1 0x8CE1 -#define GL_COLOR_ATTACHMENT2 0x8CE2 -#define GL_COLOR_ATTACHMENT3 0x8CE3 -#define GL_COLOR_ATTACHMENT4 0x8CE4 -#define GL_COLOR_ATTACHMENT5 0x8CE5 -#define GL_COLOR_ATTACHMENT6 0x8CE6 -#define GL_COLOR_ATTACHMENT7 0x8CE7 -#define GL_COLOR_ATTACHMENT8 0x8CE8 -#define GL_COLOR_ATTACHMENT9 0x8CE9 -#define GL_COLOR_ATTACHMENT10 0x8CEA -#define GL_COLOR_ATTACHMENT11 0x8CEB -#define GL_COLOR_ATTACHMENT12 0x8CEC -#define GL_COLOR_ATTACHMENT13 0x8CED -#define GL_COLOR_ATTACHMENT14 0x8CEE -#define GL_COLOR_ATTACHMENT15 0x8CEF -#define GL_DEPTH_ATTACHMENT 0x8D00 -#define GL_STENCIL_ATTACHMENT 0x8D20 -#define GL_FRAMEBUFFER 0x8D40 -#define GL_RENDERBUFFER 0x8D41 -#define GL_RENDERBUFFER_WIDTH 0x8D42 -#define GL_RENDERBUFFER_HEIGHT 0x8D43 -#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 -#define GL_STENCIL_INDEX1 0x8D46 -#define GL_STENCIL_INDEX4 0x8D47 -#define GL_STENCIL_INDEX8 0x8D48 -#define GL_STENCIL_INDEX16 0x8D49 -#define GL_RENDERBUFFER_RED_SIZE 0x8D50 -#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 -#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 -#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 -#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 -#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 -#define GL_MAX_SAMPLES 0x8D57 -#endif - -#ifndef GL_ARB_framebuffer_sRGB -#define GL_FRAMEBUFFER_SRGB 0x8DB9 -#endif - -#ifndef GL_ARB_geometry_shader4 -#define GL_LINES_ADJACENCY_ARB 0x000A -#define GL_LINE_STRIP_ADJACENCY_ARB 0x000B -#define GL_TRIANGLES_ADJACENCY_ARB 0x000C -#define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0x000D -#define GL_PROGRAM_POINT_SIZE_ARB 0x8642 -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9 -#define GL_GEOMETRY_SHADER_ARB 0x8DD9 -#define GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA -#define GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB -#define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC -#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD -#define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1 -/* reuse GL_MAX_VARYING_COMPONENTS */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */ -#endif - -#ifndef GL_ARB_half_float_vertex -#define GL_HALF_FLOAT 0x140B -#endif - -#ifndef GL_ARB_instanced_arrays -#endif - -#ifndef GL_ARB_map_buffer_range -#define GL_MAP_READ_BIT 0x0001 -#define GL_MAP_WRITE_BIT 0x0002 -#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 -#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 -#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 -#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 -#endif - -#ifndef GL_ARB_texture_buffer_object -#define GL_TEXTURE_BUFFER_ARB 0x8C2A -#define GL_MAX_TEXTURE_BUFFER_SIZE_ARB 0x8C2B -#define GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C -#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D -#define GL_TEXTURE_BUFFER_FORMAT_ARB 0x8C2E -#endif - -#ifndef GL_ARB_texture_compression_rgtc -#define GL_COMPRESSED_RED_RGTC1 0x8DBB -#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC -#define GL_COMPRESSED_RG_RGTC2 0x8DBD -#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE -#endif - -#ifndef GL_ARB_texture_rg -#define GL_RG 0x8227 -#define GL_RG_INTEGER 0x8228 -#define GL_R8 0x8229 -#define GL_R16 0x822A -#define GL_RG8 0x822B -#define GL_RG16 0x822C -#define GL_R16F 0x822D -#define GL_R32F 0x822E -#define GL_RG16F 0x822F -#define GL_RG32F 0x8230 -#define GL_R8I 0x8231 -#define GL_R8UI 0x8232 -#define GL_R16I 0x8233 -#define GL_R16UI 0x8234 -#define GL_R32I 0x8235 -#define GL_R32UI 0x8236 -#define GL_RG8I 0x8237 -#define GL_RG8UI 0x8238 -#define GL_RG16I 0x8239 -#define GL_RG16UI 0x823A -#define GL_RG32I 0x823B -#define GL_RG32UI 0x823C -#endif - -#ifndef GL_ARB_vertex_array_object -#define GL_VERTEX_ARRAY_BINDING 0x85B5 -#endif - -#ifndef GL_EXT_abgr -#define GL_ABGR_EXT 0x8000 -#endif - -#ifndef GL_EXT_blend_color -#define GL_CONSTANT_COLOR_EXT 0x8001 -#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 -#define GL_CONSTANT_ALPHA_EXT 0x8003 -#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 -#define GL_BLEND_COLOR_EXT 0x8005 -#endif - -#ifndef GL_EXT_polygon_offset -#define GL_POLYGON_OFFSET_EXT 0x8037 -#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 -#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 -#endif - -#ifndef GL_EXT_texture -#define GL_ALPHA4_EXT 0x803B -#define GL_ALPHA8_EXT 0x803C -#define GL_ALPHA12_EXT 0x803D -#define GL_ALPHA16_EXT 0x803E -#define GL_LUMINANCE4_EXT 0x803F -#define GL_LUMINANCE8_EXT 0x8040 -#define GL_LUMINANCE12_EXT 0x8041 -#define GL_LUMINANCE16_EXT 0x8042 -#define GL_LUMINANCE4_ALPHA4_EXT 0x8043 -#define GL_LUMINANCE6_ALPHA2_EXT 0x8044 -#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 -#define GL_LUMINANCE12_ALPHA4_EXT 0x8046 -#define GL_LUMINANCE12_ALPHA12_EXT 0x8047 -#define GL_LUMINANCE16_ALPHA16_EXT 0x8048 -#define GL_INTENSITY_EXT 0x8049 -#define GL_INTENSITY4_EXT 0x804A -#define GL_INTENSITY8_EXT 0x804B -#define GL_INTENSITY12_EXT 0x804C -#define GL_INTENSITY16_EXT 0x804D -#define GL_RGB2_EXT 0x804E -#define GL_RGB4_EXT 0x804F -#define GL_RGB5_EXT 0x8050 -#define GL_RGB8_EXT 0x8051 -#define GL_RGB10_EXT 0x8052 -#define GL_RGB12_EXT 0x8053 -#define GL_RGB16_EXT 0x8054 -#define GL_RGBA2_EXT 0x8055 -#define GL_RGBA4_EXT 0x8056 -#define GL_RGB5_A1_EXT 0x8057 -#define GL_RGBA8_EXT 0x8058 -#define GL_RGB10_A2_EXT 0x8059 -#define GL_RGBA12_EXT 0x805A -#define GL_RGBA16_EXT 0x805B -#define GL_TEXTURE_RED_SIZE_EXT 0x805C -#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D -#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E -#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F -#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 -#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 -#define GL_REPLACE_EXT 0x8062 -#define GL_PROXY_TEXTURE_1D_EXT 0x8063 -#define GL_PROXY_TEXTURE_2D_EXT 0x8064 -#define GL_TEXTURE_TOO_LARGE_EXT 0x8065 -#endif - -#ifndef GL_EXT_texture3D -#define GL_PACK_SKIP_IMAGES_EXT 0x806B -#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C -#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D -#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E -#define GL_TEXTURE_3D_EXT 0x806F -#define GL_PROXY_TEXTURE_3D_EXT 0x8070 -#define GL_TEXTURE_DEPTH_EXT 0x8071 -#define GL_TEXTURE_WRAP_R_EXT 0x8072 -#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 -#endif - -#ifndef GL_SGIS_texture_filter4 -#define GL_FILTER4_SGIS 0x8146 -#define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147 -#endif - -#ifndef GL_EXT_subtexture -#endif - -#ifndef GL_EXT_copy_texture -#endif - -#ifndef GL_EXT_histogram -#define GL_HISTOGRAM_EXT 0x8024 -#define GL_PROXY_HISTOGRAM_EXT 0x8025 -#define GL_HISTOGRAM_WIDTH_EXT 0x8026 -#define GL_HISTOGRAM_FORMAT_EXT 0x8027 -#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 -#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 -#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A -#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B -#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C -#define GL_HISTOGRAM_SINK_EXT 0x802D -#define GL_MINMAX_EXT 0x802E -#define GL_MINMAX_FORMAT_EXT 0x802F -#define GL_MINMAX_SINK_EXT 0x8030 -#define GL_TABLE_TOO_LARGE_EXT 0x8031 -#endif - -#ifndef GL_EXT_convolution -#define GL_CONVOLUTION_1D_EXT 0x8010 -#define GL_CONVOLUTION_2D_EXT 0x8011 -#define GL_SEPARABLE_2D_EXT 0x8012 -#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 -#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 -#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 -#define GL_REDUCE_EXT 0x8016 -#define GL_CONVOLUTION_FORMAT_EXT 0x8017 -#define GL_CONVOLUTION_WIDTH_EXT 0x8018 -#define GL_CONVOLUTION_HEIGHT_EXT 0x8019 -#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A -#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B -#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C -#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D -#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E -#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F -#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 -#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 -#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 -#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 -#endif - -#ifndef GL_SGI_color_matrix -#define GL_COLOR_MATRIX_SGI 0x80B1 -#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 -#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 -#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 -#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 -#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 -#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 -#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 -#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 -#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA -#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB -#endif - -#ifndef GL_SGI_color_table -#define GL_COLOR_TABLE_SGI 0x80D0 -#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 -#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 -#define GL_PROXY_COLOR_TABLE_SGI 0x80D3 -#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 -#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 -#define GL_COLOR_TABLE_SCALE_SGI 0x80D6 -#define GL_COLOR_TABLE_BIAS_SGI 0x80D7 -#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 -#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 -#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA -#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB -#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC -#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD -#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE -#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF -#endif - -#ifndef GL_SGIS_pixel_texture -#define GL_PIXEL_TEXTURE_SGIS 0x8353 -#define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354 -#define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355 -#define GL_PIXEL_GROUP_COLOR_SGIS 0x8356 -#endif - -#ifndef GL_SGIX_pixel_texture -#define GL_PIXEL_TEX_GEN_SGIX 0x8139 -#define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B -#endif - -#ifndef GL_SGIS_texture4D -#define GL_PACK_SKIP_VOLUMES_SGIS 0x8130 -#define GL_PACK_IMAGE_DEPTH_SGIS 0x8131 -#define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132 -#define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133 -#define GL_TEXTURE_4D_SGIS 0x8134 -#define GL_PROXY_TEXTURE_4D_SGIS 0x8135 -#define GL_TEXTURE_4DSIZE_SGIS 0x8136 -#define GL_TEXTURE_WRAP_Q_SGIS 0x8137 -#define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138 -#define GL_TEXTURE_4D_BINDING_SGIS 0x814F -#endif - -#ifndef GL_SGI_texture_color_table -#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC -#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD -#endif - -#ifndef GL_EXT_cmyka -#define GL_CMYK_EXT 0x800C -#define GL_CMYKA_EXT 0x800D -#define GL_PACK_CMYK_HINT_EXT 0x800E -#define GL_UNPACK_CMYK_HINT_EXT 0x800F -#endif - -#ifndef GL_EXT_texture_object -#define GL_TEXTURE_PRIORITY_EXT 0x8066 -#define GL_TEXTURE_RESIDENT_EXT 0x8067 -#define GL_TEXTURE_1D_BINDING_EXT 0x8068 -#define GL_TEXTURE_2D_BINDING_EXT 0x8069 -#define GL_TEXTURE_3D_BINDING_EXT 0x806A -#endif - -#ifndef GL_SGIS_detail_texture -#define GL_DETAIL_TEXTURE_2D_SGIS 0x8095 -#define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096 -#define GL_LINEAR_DETAIL_SGIS 0x8097 -#define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098 -#define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099 -#define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A -#define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B -#define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C -#endif - -#ifndef GL_SGIS_sharpen_texture -#define GL_LINEAR_SHARPEN_SGIS 0x80AD -#define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE -#define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF -#define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0 -#endif - -#ifndef GL_EXT_packed_pixels -#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 -#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 -#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 -#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 -#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 -#endif - -#ifndef GL_SGIS_texture_lod -#define GL_TEXTURE_MIN_LOD_SGIS 0x813A -#define GL_TEXTURE_MAX_LOD_SGIS 0x813B -#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C -#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D -#endif - -#ifndef GL_SGIS_multisample -#define GL_MULTISAMPLE_SGIS 0x809D -#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F -#define GL_SAMPLE_MASK_SGIS 0x80A0 -#define GL_1PASS_SGIS 0x80A1 -#define GL_2PASS_0_SGIS 0x80A2 -#define GL_2PASS_1_SGIS 0x80A3 -#define GL_4PASS_0_SGIS 0x80A4 -#define GL_4PASS_1_SGIS 0x80A5 -#define GL_4PASS_2_SGIS 0x80A6 -#define GL_4PASS_3_SGIS 0x80A7 -#define GL_SAMPLE_BUFFERS_SGIS 0x80A8 -#define GL_SAMPLES_SGIS 0x80A9 -#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA -#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB -#define GL_SAMPLE_PATTERN_SGIS 0x80AC -#endif - -#ifndef GL_EXT_rescale_normal -#define GL_RESCALE_NORMAL_EXT 0x803A -#endif - -#ifndef GL_EXT_vertex_array -#define GL_VERTEX_ARRAY_EXT 0x8074 -#define GL_NORMAL_ARRAY_EXT 0x8075 -#define GL_COLOR_ARRAY_EXT 0x8076 -#define GL_INDEX_ARRAY_EXT 0x8077 -#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 -#define GL_EDGE_FLAG_ARRAY_EXT 0x8079 -#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A -#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B -#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C -#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D -#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E -#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F -#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 -#define GL_COLOR_ARRAY_SIZE_EXT 0x8081 -#define GL_COLOR_ARRAY_TYPE_EXT 0x8082 -#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 -#define GL_COLOR_ARRAY_COUNT_EXT 0x8084 -#define GL_INDEX_ARRAY_TYPE_EXT 0x8085 -#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 -#define GL_INDEX_ARRAY_COUNT_EXT 0x8087 -#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 -#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 -#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A -#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B -#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C -#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D -#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E -#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F -#define GL_COLOR_ARRAY_POINTER_EXT 0x8090 -#define GL_INDEX_ARRAY_POINTER_EXT 0x8091 -#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 -#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 -#endif - -#ifndef GL_EXT_misc_attribute -#endif - -#ifndef GL_SGIS_generate_mipmap -#define GL_GENERATE_MIPMAP_SGIS 0x8191 -#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 -#endif - -#ifndef GL_SGIX_clipmap -#define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170 -#define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171 -#define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172 -#define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173 -#define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174 -#define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175 -#define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176 -#define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177 -#define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178 -#define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D -#define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E -#define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F -#endif - -#ifndef GL_SGIX_shadow -#define GL_TEXTURE_COMPARE_SGIX 0x819A -#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B -#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C -#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D -#endif - -#ifndef GL_SGIS_texture_edge_clamp -#define GL_CLAMP_TO_EDGE_SGIS 0x812F -#endif - -#ifndef GL_SGIS_texture_border_clamp -#define GL_CLAMP_TO_BORDER_SGIS 0x812D -#endif - -#ifndef GL_EXT_blend_minmax -#define GL_FUNC_ADD_EXT 0x8006 -#define GL_MIN_EXT 0x8007 -#define GL_MAX_EXT 0x8008 -#define GL_BLEND_EQUATION_EXT 0x8009 -#endif - -#ifndef GL_EXT_blend_subtract -#define GL_FUNC_SUBTRACT_EXT 0x800A -#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B -#endif - -#ifndef GL_EXT_blend_logic_op -#endif - -#ifndef GL_SGIX_interlace -#define GL_INTERLACE_SGIX 0x8094 -#endif - -#ifndef GL_SGIX_pixel_tiles -#define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E -#define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F -#define GL_PIXEL_TILE_WIDTH_SGIX 0x8140 -#define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141 -#define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142 -#define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143 -#define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144 -#define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145 -#endif - -#ifndef GL_SGIS_texture_select -#define GL_DUAL_ALPHA4_SGIS 0x8110 -#define GL_DUAL_ALPHA8_SGIS 0x8111 -#define GL_DUAL_ALPHA12_SGIS 0x8112 -#define GL_DUAL_ALPHA16_SGIS 0x8113 -#define GL_DUAL_LUMINANCE4_SGIS 0x8114 -#define GL_DUAL_LUMINANCE8_SGIS 0x8115 -#define GL_DUAL_LUMINANCE12_SGIS 0x8116 -#define GL_DUAL_LUMINANCE16_SGIS 0x8117 -#define GL_DUAL_INTENSITY4_SGIS 0x8118 -#define GL_DUAL_INTENSITY8_SGIS 0x8119 -#define GL_DUAL_INTENSITY12_SGIS 0x811A -#define GL_DUAL_INTENSITY16_SGIS 0x811B -#define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C -#define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D -#define GL_QUAD_ALPHA4_SGIS 0x811E -#define GL_QUAD_ALPHA8_SGIS 0x811F -#define GL_QUAD_LUMINANCE4_SGIS 0x8120 -#define GL_QUAD_LUMINANCE8_SGIS 0x8121 -#define GL_QUAD_INTENSITY4_SGIS 0x8122 -#define GL_QUAD_INTENSITY8_SGIS 0x8123 -#define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124 -#define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125 -#endif - -#ifndef GL_SGIX_sprite -#define GL_SPRITE_SGIX 0x8148 -#define GL_SPRITE_MODE_SGIX 0x8149 -#define GL_SPRITE_AXIS_SGIX 0x814A -#define GL_SPRITE_TRANSLATION_SGIX 0x814B -#define GL_SPRITE_AXIAL_SGIX 0x814C -#define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D -#define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E -#endif - -#ifndef GL_SGIX_texture_multi_buffer -#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E -#endif - -#ifndef GL_EXT_point_parameters -#define GL_POINT_SIZE_MIN_EXT 0x8126 -#define GL_POINT_SIZE_MAX_EXT 0x8127 -#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 -#define GL_DISTANCE_ATTENUATION_EXT 0x8129 -#endif - -#ifndef GL_SGIS_point_parameters -#define GL_POINT_SIZE_MIN_SGIS 0x8126 -#define GL_POINT_SIZE_MAX_SGIS 0x8127 -#define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128 -#define GL_DISTANCE_ATTENUATION_SGIS 0x8129 -#endif - -#ifndef GL_SGIX_instruments -#define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180 -#define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181 -#endif - -#ifndef GL_SGIX_texture_scale_bias -#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 -#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A -#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B -#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C -#endif - -#ifndef GL_SGIX_framezoom -#define GL_FRAMEZOOM_SGIX 0x818B -#define GL_FRAMEZOOM_FACTOR_SGIX 0x818C -#define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D -#endif - -#ifndef GL_SGIX_tag_sample_buffer -#endif - -#ifndef GL_FfdMaskSGIX -#define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001 -#define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002 -#endif - -#ifndef GL_SGIX_polynomial_ffd -#define GL_GEOMETRY_DEFORMATION_SGIX 0x8194 -#define GL_TEXTURE_DEFORMATION_SGIX 0x8195 -#define GL_DEFORMATIONS_MASK_SGIX 0x8196 -#define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197 -#endif - -#ifndef GL_SGIX_reference_plane -#define GL_REFERENCE_PLANE_SGIX 0x817D -#define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E -#endif - -#ifndef GL_SGIX_flush_raster -#endif - -#ifndef GL_SGIX_depth_texture -#define GL_DEPTH_COMPONENT16_SGIX 0x81A5 -#define GL_DEPTH_COMPONENT24_SGIX 0x81A6 -#define GL_DEPTH_COMPONENT32_SGIX 0x81A7 -#endif - -#ifndef GL_SGIS_fog_function -#define GL_FOG_FUNC_SGIS 0x812A -#define GL_FOG_FUNC_POINTS_SGIS 0x812B -#define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C -#endif - -#ifndef GL_SGIX_fog_offset -#define GL_FOG_OFFSET_SGIX 0x8198 -#define GL_FOG_OFFSET_VALUE_SGIX 0x8199 -#endif - -#ifndef GL_HP_image_transform -#define GL_IMAGE_SCALE_X_HP 0x8155 -#define GL_IMAGE_SCALE_Y_HP 0x8156 -#define GL_IMAGE_TRANSLATE_X_HP 0x8157 -#define GL_IMAGE_TRANSLATE_Y_HP 0x8158 -#define GL_IMAGE_ROTATE_ANGLE_HP 0x8159 -#define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A -#define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B -#define GL_IMAGE_MAG_FILTER_HP 0x815C -#define GL_IMAGE_MIN_FILTER_HP 0x815D -#define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E -#define GL_CUBIC_HP 0x815F -#define GL_AVERAGE_HP 0x8160 -#define GL_IMAGE_TRANSFORM_2D_HP 0x8161 -#define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162 -#define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163 -#endif - -#ifndef GL_HP_convolution_border_modes -#define GL_IGNORE_BORDER_HP 0x8150 -#define GL_CONSTANT_BORDER_HP 0x8151 -#define GL_REPLICATE_BORDER_HP 0x8153 -#define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154 -#endif - -#ifndef GL_INGR_palette_buffer -#endif - -#ifndef GL_SGIX_texture_add_env -#define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE -#endif - -#ifndef GL_EXT_color_subtable -#endif - -#ifndef GL_PGI_vertex_hints -#define GL_VERTEX_DATA_HINT_PGI 0x1A22A -#define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B -#define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C -#define GL_MAX_VERTEX_HINT_PGI 0x1A22D -#define GL_COLOR3_BIT_PGI 0x00010000 -#define GL_COLOR4_BIT_PGI 0x00020000 -#define GL_EDGEFLAG_BIT_PGI 0x00040000 -#define GL_INDEX_BIT_PGI 0x00080000 -#define GL_MAT_AMBIENT_BIT_PGI 0x00100000 -#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 -#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 -#define GL_MAT_EMISSION_BIT_PGI 0x00800000 -#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 -#define GL_MAT_SHININESS_BIT_PGI 0x02000000 -#define GL_MAT_SPECULAR_BIT_PGI 0x04000000 -#define GL_NORMAL_BIT_PGI 0x08000000 -#define GL_TEXCOORD1_BIT_PGI 0x10000000 -#define GL_TEXCOORD2_BIT_PGI 0x20000000 -#define GL_TEXCOORD3_BIT_PGI 0x40000000 -#define GL_TEXCOORD4_BIT_PGI 0x80000000 -#define GL_VERTEX23_BIT_PGI 0x00000004 -#define GL_VERTEX4_BIT_PGI 0x00000008 -#endif - -#ifndef GL_PGI_misc_hints -#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8 -#define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD -#define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE -#define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202 -#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203 -#define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204 -#define GL_ALWAYS_FAST_HINT_PGI 0x1A20C -#define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D -#define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E -#define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F -#define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210 -#define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211 -#define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216 -#define GL_STRICT_LIGHTING_HINT_PGI 0x1A217 -#define GL_STRICT_SCISSOR_HINT_PGI 0x1A218 -#define GL_FULL_STIPPLE_HINT_PGI 0x1A219 -#define GL_CLIP_NEAR_HINT_PGI 0x1A220 -#define GL_CLIP_FAR_HINT_PGI 0x1A221 -#define GL_WIDE_LINE_HINT_PGI 0x1A222 -#define GL_BACK_NORMALS_HINT_PGI 0x1A223 -#endif - -#ifndef GL_EXT_paletted_texture -#define GL_COLOR_INDEX1_EXT 0x80E2 -#define GL_COLOR_INDEX2_EXT 0x80E3 -#define GL_COLOR_INDEX4_EXT 0x80E4 -#define GL_COLOR_INDEX8_EXT 0x80E5 -#define GL_COLOR_INDEX12_EXT 0x80E6 -#define GL_COLOR_INDEX16_EXT 0x80E7 -#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED -#endif - -#ifndef GL_EXT_clip_volume_hint -#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 -#endif - -#ifndef GL_SGIX_list_priority -#define GL_LIST_PRIORITY_SGIX 0x8182 -#endif - -#ifndef GL_SGIX_ir_instrument1 -#define GL_IR_INSTRUMENT1_SGIX 0x817F -#endif - -#ifndef GL_SGIX_calligraphic_fragment -#define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183 -#endif - -#ifndef GL_SGIX_texture_lod_bias -#define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E -#define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F -#define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190 -#endif - -#ifndef GL_SGIX_shadow_ambient -#define GL_SHADOW_AMBIENT_SGIX 0x80BF -#endif - -#ifndef GL_EXT_index_texture -#endif - -#ifndef GL_EXT_index_material -#define GL_INDEX_MATERIAL_EXT 0x81B8 -#define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9 -#define GL_INDEX_MATERIAL_FACE_EXT 0x81BA -#endif - -#ifndef GL_EXT_index_func -#define GL_INDEX_TEST_EXT 0x81B5 -#define GL_INDEX_TEST_FUNC_EXT 0x81B6 -#define GL_INDEX_TEST_REF_EXT 0x81B7 -#endif - -#ifndef GL_EXT_index_array_formats -#define GL_IUI_V2F_EXT 0x81AD -#define GL_IUI_V3F_EXT 0x81AE -#define GL_IUI_N3F_V2F_EXT 0x81AF -#define GL_IUI_N3F_V3F_EXT 0x81B0 -#define GL_T2F_IUI_V2F_EXT 0x81B1 -#define GL_T2F_IUI_V3F_EXT 0x81B2 -#define GL_T2F_IUI_N3F_V2F_EXT 0x81B3 -#define GL_T2F_IUI_N3F_V3F_EXT 0x81B4 -#endif - -#ifndef GL_EXT_compiled_vertex_array -#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 -#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 -#endif - -#ifndef GL_EXT_cull_vertex -#define GL_CULL_VERTEX_EXT 0x81AA -#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB -#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC -#endif - -#ifndef GL_SGIX_ycrcb -#define GL_YCRCB_422_SGIX 0x81BB -#define GL_YCRCB_444_SGIX 0x81BC -#endif - -#ifndef GL_SGIX_fragment_lighting -#define GL_FRAGMENT_LIGHTING_SGIX 0x8400 -#define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401 -#define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402 -#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403 -#define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404 -#define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405 -#define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406 -#define GL_LIGHT_ENV_MODE_SGIX 0x8407 -#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408 -#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409 -#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A -#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B -#define GL_FRAGMENT_LIGHT0_SGIX 0x840C -#define GL_FRAGMENT_LIGHT1_SGIX 0x840D -#define GL_FRAGMENT_LIGHT2_SGIX 0x840E -#define GL_FRAGMENT_LIGHT3_SGIX 0x840F -#define GL_FRAGMENT_LIGHT4_SGIX 0x8410 -#define GL_FRAGMENT_LIGHT5_SGIX 0x8411 -#define GL_FRAGMENT_LIGHT6_SGIX 0x8412 -#define GL_FRAGMENT_LIGHT7_SGIX 0x8413 -#endif - -#ifndef GL_IBM_rasterpos_clip -#define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262 -#endif - -#ifndef GL_HP_texture_lighting -#define GL_TEXTURE_LIGHTING_MODE_HP 0x8167 -#define GL_TEXTURE_POST_SPECULAR_HP 0x8168 -#define GL_TEXTURE_PRE_SPECULAR_HP 0x8169 -#endif - -#ifndef GL_EXT_draw_range_elements -#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8 -#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9 -#endif - -#ifndef GL_WIN_phong_shading -#define GL_PHONG_WIN 0x80EA -#define GL_PHONG_HINT_WIN 0x80EB -#endif - -#ifndef GL_WIN_specular_fog -#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC -#endif - -#ifndef GL_EXT_light_texture -#define GL_FRAGMENT_MATERIAL_EXT 0x8349 -#define GL_FRAGMENT_NORMAL_EXT 0x834A -#define GL_FRAGMENT_COLOR_EXT 0x834C -#define GL_ATTENUATION_EXT 0x834D -#define GL_SHADOW_ATTENUATION_EXT 0x834E -#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F -#define GL_TEXTURE_LIGHT_EXT 0x8350 -#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 -#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 -/* reuse GL_FRAGMENT_DEPTH_EXT */ -#endif - -#ifndef GL_SGIX_blend_alpha_minmax -#define GL_ALPHA_MIN_SGIX 0x8320 -#define GL_ALPHA_MAX_SGIX 0x8321 -#endif - -#ifndef GL_SGIX_impact_pixel_texture -#define GL_PIXEL_TEX_GEN_Q_CEILING_SGIX 0x8184 -#define GL_PIXEL_TEX_GEN_Q_ROUND_SGIX 0x8185 -#define GL_PIXEL_TEX_GEN_Q_FLOOR_SGIX 0x8186 -#define GL_PIXEL_TEX_GEN_ALPHA_REPLACE_SGIX 0x8187 -#define GL_PIXEL_TEX_GEN_ALPHA_NO_REPLACE_SGIX 0x8188 -#define GL_PIXEL_TEX_GEN_ALPHA_LS_SGIX 0x8189 -#define GL_PIXEL_TEX_GEN_ALPHA_MS_SGIX 0x818A -#endif - -#ifndef GL_EXT_bgra -#define GL_BGR_EXT 0x80E0 -#define GL_BGRA_EXT 0x80E1 -#endif - -#ifndef GL_SGIX_async -#define GL_ASYNC_MARKER_SGIX 0x8329 -#endif - -#ifndef GL_SGIX_async_pixel -#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C -#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D -#define GL_ASYNC_READ_PIXELS_SGIX 0x835E -#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F -#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 -#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 -#endif - -#ifndef GL_SGIX_async_histogram -#define GL_ASYNC_HISTOGRAM_SGIX 0x832C -#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D -#endif - -#ifndef GL_INTEL_texture_scissor -#endif - -#ifndef GL_INTEL_parallel_arrays -#define GL_PARALLEL_ARRAYS_INTEL 0x83F4 -#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 -#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 -#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 -#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 -#endif - -#ifndef GL_HP_occlusion_test -#define GL_OCCLUSION_TEST_HP 0x8165 -#define GL_OCCLUSION_TEST_RESULT_HP 0x8166 -#endif - -#ifndef GL_EXT_pixel_transform -#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 -#define GL_PIXEL_MAG_FILTER_EXT 0x8331 -#define GL_PIXEL_MIN_FILTER_EXT 0x8332 -#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 -#define GL_CUBIC_EXT 0x8334 -#define GL_AVERAGE_EXT 0x8335 -#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 -#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 -#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 -#endif - -#ifndef GL_EXT_pixel_transform_color_table -#endif - -#ifndef GL_EXT_shared_texture_palette -#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB -#endif - -#ifndef GL_EXT_separate_specular_color -#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 -#define GL_SINGLE_COLOR_EXT 0x81F9 -#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA -#endif - -#ifndef GL_EXT_secondary_color -#define GL_COLOR_SUM_EXT 0x8458 -#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 -#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A -#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B -#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C -#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D -#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E -#endif - -#ifndef GL_EXT_texture_perturb_normal -#define GL_PERTURB_EXT 0x85AE -#define GL_TEXTURE_NORMAL_EXT 0x85AF -#endif - -#ifndef GL_EXT_multi_draw_arrays -#endif - -#ifndef GL_EXT_fog_coord -#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 -#define GL_FOG_COORDINATE_EXT 0x8451 -#define GL_FRAGMENT_DEPTH_EXT 0x8452 -#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 -#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 -#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 -#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 -#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 -#endif - -#ifndef GL_REND_screen_coordinates -#define GL_SCREEN_COORDINATES_REND 0x8490 -#define GL_INVERTED_SCREEN_W_REND 0x8491 -#endif - -#ifndef GL_EXT_coordinate_frame -#define GL_TANGENT_ARRAY_EXT 0x8439 -#define GL_BINORMAL_ARRAY_EXT 0x843A -#define GL_CURRENT_TANGENT_EXT 0x843B -#define GL_CURRENT_BINORMAL_EXT 0x843C -#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E -#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F -#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 -#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 -#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 -#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 -#define GL_MAP1_TANGENT_EXT 0x8444 -#define GL_MAP2_TANGENT_EXT 0x8445 -#define GL_MAP1_BINORMAL_EXT 0x8446 -#define GL_MAP2_BINORMAL_EXT 0x8447 -#endif - -#ifndef GL_EXT_texture_env_combine -#define GL_COMBINE_EXT 0x8570 -#define GL_COMBINE_RGB_EXT 0x8571 -#define GL_COMBINE_ALPHA_EXT 0x8572 -#define GL_RGB_SCALE_EXT 0x8573 -#define GL_ADD_SIGNED_EXT 0x8574 -#define GL_INTERPOLATE_EXT 0x8575 -#define GL_CONSTANT_EXT 0x8576 -#define GL_PRIMARY_COLOR_EXT 0x8577 -#define GL_PREVIOUS_EXT 0x8578 -#define GL_SOURCE0_RGB_EXT 0x8580 -#define GL_SOURCE1_RGB_EXT 0x8581 -#define GL_SOURCE2_RGB_EXT 0x8582 -#define GL_SOURCE0_ALPHA_EXT 0x8588 -#define GL_SOURCE1_ALPHA_EXT 0x8589 -#define GL_SOURCE2_ALPHA_EXT 0x858A -#define GL_OPERAND0_RGB_EXT 0x8590 -#define GL_OPERAND1_RGB_EXT 0x8591 -#define GL_OPERAND2_RGB_EXT 0x8592 -#define GL_OPERAND0_ALPHA_EXT 0x8598 -#define GL_OPERAND1_ALPHA_EXT 0x8599 -#define GL_OPERAND2_ALPHA_EXT 0x859A -#endif - -#ifndef GL_APPLE_specular_vector -#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 -#endif - -#ifndef GL_APPLE_transform_hint -#define GL_TRANSFORM_HINT_APPLE 0x85B1 -#endif - -#ifndef GL_SGIX_fog_scale -#define GL_FOG_SCALE_SGIX 0x81FC -#define GL_FOG_SCALE_VALUE_SGIX 0x81FD -#endif - -#ifndef GL_SUNX_constant_data -#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 -#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 -#endif - -#ifndef GL_SUN_global_alpha -#define GL_GLOBAL_ALPHA_SUN 0x81D9 -#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA -#endif - -#ifndef GL_SUN_triangle_list -#define GL_RESTART_SUN 0x0001 -#define GL_REPLACE_MIDDLE_SUN 0x0002 -#define GL_REPLACE_OLDEST_SUN 0x0003 -#define GL_TRIANGLE_LIST_SUN 0x81D7 -#define GL_REPLACEMENT_CODE_SUN 0x81D8 -#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 -#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 -#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 -#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 -#define GL_R1UI_V3F_SUN 0x85C4 -#define GL_R1UI_C4UB_V3F_SUN 0x85C5 -#define GL_R1UI_C3F_V3F_SUN 0x85C6 -#define GL_R1UI_N3F_V3F_SUN 0x85C7 -#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 -#define GL_R1UI_T2F_V3F_SUN 0x85C9 -#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA -#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB -#endif - -#ifndef GL_SUN_vertex -#endif - -#ifndef GL_EXT_blend_func_separate -#define GL_BLEND_DST_RGB_EXT 0x80C8 -#define GL_BLEND_SRC_RGB_EXT 0x80C9 -#define GL_BLEND_DST_ALPHA_EXT 0x80CA -#define GL_BLEND_SRC_ALPHA_EXT 0x80CB -#endif - -#ifndef GL_INGR_color_clamp -#define GL_RED_MIN_CLAMP_INGR 0x8560 -#define GL_GREEN_MIN_CLAMP_INGR 0x8561 -#define GL_BLUE_MIN_CLAMP_INGR 0x8562 -#define GL_ALPHA_MIN_CLAMP_INGR 0x8563 -#define GL_RED_MAX_CLAMP_INGR 0x8564 -#define GL_GREEN_MAX_CLAMP_INGR 0x8565 -#define GL_BLUE_MAX_CLAMP_INGR 0x8566 -#define GL_ALPHA_MAX_CLAMP_INGR 0x8567 -#endif - -#ifndef GL_INGR_interlace_read -#define GL_INTERLACE_READ_INGR 0x8568 -#endif - -#ifndef GL_EXT_stencil_wrap -#define GL_INCR_WRAP_EXT 0x8507 -#define GL_DECR_WRAP_EXT 0x8508 -#endif - -#ifndef GL_EXT_422_pixels -#define GL_422_EXT 0x80CC -#define GL_422_REV_EXT 0x80CD -#define GL_422_AVERAGE_EXT 0x80CE -#define GL_422_REV_AVERAGE_EXT 0x80CF -#endif - -#ifndef GL_NV_texgen_reflection -#define GL_NORMAL_MAP_NV 0x8511 -#define GL_REFLECTION_MAP_NV 0x8512 -#endif - -#ifndef GL_EXT_texture_cube_map -#define GL_NORMAL_MAP_EXT 0x8511 -#define GL_REFLECTION_MAP_EXT 0x8512 -#define GL_TEXTURE_CUBE_MAP_EXT 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A -#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C -#endif - -#ifndef GL_SUN_convolution_border_modes -#define GL_WRAP_BORDER_SUN 0x81D4 -#endif - -#ifndef GL_EXT_texture_env_add -#endif - -#ifndef GL_EXT_texture_lod_bias -#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD -#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 -#define GL_TEXTURE_LOD_BIAS_EXT 0x8501 -#endif - -#ifndef GL_EXT_texture_filter_anisotropic -#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE -#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF -#endif - -#ifndef GL_EXT_vertex_weighting -#define GL_MODELVIEW0_STACK_DEPTH_EXT GL_MODELVIEW_STACK_DEPTH -#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 -#define GL_MODELVIEW0_MATRIX_EXT GL_MODELVIEW_MATRIX -#define GL_MODELVIEW1_MATRIX_EXT 0x8506 -#define GL_VERTEX_WEIGHTING_EXT 0x8509 -#define GL_MODELVIEW0_EXT GL_MODELVIEW -#define GL_MODELVIEW1_EXT 0x850A -#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B -#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C -#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D -#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E -#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F -#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 -#endif - -#ifndef GL_NV_light_max_exponent -#define GL_MAX_SHININESS_NV 0x8504 -#define GL_MAX_SPOT_EXPONENT_NV 0x8505 -#endif - -#ifndef GL_NV_vertex_array_range -#define GL_VERTEX_ARRAY_RANGE_NV 0x851D -#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E -#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F -#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 -#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 -#endif - -#ifndef GL_NV_register_combiners -#define GL_REGISTER_COMBINERS_NV 0x8522 -#define GL_VARIABLE_A_NV 0x8523 -#define GL_VARIABLE_B_NV 0x8524 -#define GL_VARIABLE_C_NV 0x8525 -#define GL_VARIABLE_D_NV 0x8526 -#define GL_VARIABLE_E_NV 0x8527 -#define GL_VARIABLE_F_NV 0x8528 -#define GL_VARIABLE_G_NV 0x8529 -#define GL_CONSTANT_COLOR0_NV 0x852A -#define GL_CONSTANT_COLOR1_NV 0x852B -#define GL_PRIMARY_COLOR_NV 0x852C -#define GL_SECONDARY_COLOR_NV 0x852D -#define GL_SPARE0_NV 0x852E -#define GL_SPARE1_NV 0x852F -#define GL_DISCARD_NV 0x8530 -#define GL_E_TIMES_F_NV 0x8531 -#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 -#define GL_UNSIGNED_IDENTITY_NV 0x8536 -#define GL_UNSIGNED_INVERT_NV 0x8537 -#define GL_EXPAND_NORMAL_NV 0x8538 -#define GL_EXPAND_NEGATE_NV 0x8539 -#define GL_HALF_BIAS_NORMAL_NV 0x853A -#define GL_HALF_BIAS_NEGATE_NV 0x853B -#define GL_SIGNED_IDENTITY_NV 0x853C -#define GL_SIGNED_NEGATE_NV 0x853D -#define GL_SCALE_BY_TWO_NV 0x853E -#define GL_SCALE_BY_FOUR_NV 0x853F -#define GL_SCALE_BY_ONE_HALF_NV 0x8540 -#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 -#define GL_COMBINER_INPUT_NV 0x8542 -#define GL_COMBINER_MAPPING_NV 0x8543 -#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 -#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 -#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 -#define GL_COMBINER_MUX_SUM_NV 0x8547 -#define GL_COMBINER_SCALE_NV 0x8548 -#define GL_COMBINER_BIAS_NV 0x8549 -#define GL_COMBINER_AB_OUTPUT_NV 0x854A -#define GL_COMBINER_CD_OUTPUT_NV 0x854B -#define GL_COMBINER_SUM_OUTPUT_NV 0x854C -#define GL_MAX_GENERAL_COMBINERS_NV 0x854D -#define GL_NUM_GENERAL_COMBINERS_NV 0x854E -#define GL_COLOR_SUM_CLAMP_NV 0x854F -#define GL_COMBINER0_NV 0x8550 -#define GL_COMBINER1_NV 0x8551 -#define GL_COMBINER2_NV 0x8552 -#define GL_COMBINER3_NV 0x8553 -#define GL_COMBINER4_NV 0x8554 -#define GL_COMBINER5_NV 0x8555 -#define GL_COMBINER6_NV 0x8556 -#define GL_COMBINER7_NV 0x8557 -/* reuse GL_TEXTURE0_ARB */ -/* reuse GL_TEXTURE1_ARB */ -/* reuse GL_ZERO */ -/* reuse GL_NONE */ -/* reuse GL_FOG */ -#endif - -#ifndef GL_NV_fog_distance -#define GL_FOG_DISTANCE_MODE_NV 0x855A -#define GL_EYE_RADIAL_NV 0x855B -#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C -/* reuse GL_EYE_PLANE */ -#endif - -#ifndef GL_NV_texgen_emboss -#define GL_EMBOSS_LIGHT_NV 0x855D -#define GL_EMBOSS_CONSTANT_NV 0x855E -#define GL_EMBOSS_MAP_NV 0x855F -#endif - -#ifndef GL_NV_blend_square -#endif - -#ifndef GL_NV_texture_env_combine4 -#define GL_COMBINE4_NV 0x8503 -#define GL_SOURCE3_RGB_NV 0x8583 -#define GL_SOURCE3_ALPHA_NV 0x858B -#define GL_OPERAND3_RGB_NV 0x8593 -#define GL_OPERAND3_ALPHA_NV 0x859B -#endif - -#ifndef GL_MESA_resize_buffers -#endif - -#ifndef GL_MESA_window_pos -#endif - -#ifndef GL_EXT_texture_compression_s3tc -#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 -#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 -#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 -#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 -#endif - -#ifndef GL_IBM_cull_vertex -#define GL_CULL_VERTEX_IBM 103050 -#endif - -#ifndef GL_IBM_multimode_draw_arrays -#endif - -#ifndef GL_IBM_vertex_array_lists -#define GL_VERTEX_ARRAY_LIST_IBM 103070 -#define GL_NORMAL_ARRAY_LIST_IBM 103071 -#define GL_COLOR_ARRAY_LIST_IBM 103072 -#define GL_INDEX_ARRAY_LIST_IBM 103073 -#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 -#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 -#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 -#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 -#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 -#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 -#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 -#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 -#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 -#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 -#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 -#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 -#endif - -#ifndef GL_SGIX_subsample -#define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0 -#define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1 -#define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2 -#define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3 -#define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4 -#endif - -#ifndef GL_SGIX_ycrcb_subsample -#endif - -#ifndef GL_SGIX_ycrcba -#define GL_YCRCB_SGIX 0x8318 -#define GL_YCRCBA_SGIX 0x8319 -#endif - -#ifndef GL_SGI_depth_pass_instrument -#define GL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310 -#define GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311 -#define GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312 -#endif - -#ifndef GL_3DFX_texture_compression_FXT1 -#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 -#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 -#endif - -#ifndef GL_3DFX_multisample -#define GL_MULTISAMPLE_3DFX 0x86B2 -#define GL_SAMPLE_BUFFERS_3DFX 0x86B3 -#define GL_SAMPLES_3DFX 0x86B4 -#define GL_MULTISAMPLE_BIT_3DFX 0x20000000 -#endif - -#ifndef GL_3DFX_tbuffer -#endif - -#ifndef GL_EXT_multisample -#define GL_MULTISAMPLE_EXT 0x809D -#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F -#define GL_SAMPLE_MASK_EXT 0x80A0 -#define GL_1PASS_EXT 0x80A1 -#define GL_2PASS_0_EXT 0x80A2 -#define GL_2PASS_1_EXT 0x80A3 -#define GL_4PASS_0_EXT 0x80A4 -#define GL_4PASS_1_EXT 0x80A5 -#define GL_4PASS_2_EXT 0x80A6 -#define GL_4PASS_3_EXT 0x80A7 -#define GL_SAMPLE_BUFFERS_EXT 0x80A8 -#define GL_SAMPLES_EXT 0x80A9 -#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA -#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB -#define GL_SAMPLE_PATTERN_EXT 0x80AC -#define GL_MULTISAMPLE_BIT_EXT 0x20000000 -#endif - -#ifndef GL_SGIX_vertex_preclip -#define GL_VERTEX_PRECLIP_SGIX 0x83EE -#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF -#endif - -#ifndef GL_SGIX_convolution_accuracy -#define GL_CONVOLUTION_HINT_SGIX 0x8316 -#endif - -#ifndef GL_SGIX_resample -#define GL_PACK_RESAMPLE_SGIX 0x842C -#define GL_UNPACK_RESAMPLE_SGIX 0x842D -#define GL_RESAMPLE_REPLICATE_SGIX 0x842E -#define GL_RESAMPLE_ZERO_FILL_SGIX 0x842F -#define GL_RESAMPLE_DECIMATE_SGIX 0x8430 -#endif - -#ifndef GL_SGIS_point_line_texgen -#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 -#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 -#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 -#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 -#define GL_EYE_POINT_SGIS 0x81F4 -#define GL_OBJECT_POINT_SGIS 0x81F5 -#define GL_EYE_LINE_SGIS 0x81F6 -#define GL_OBJECT_LINE_SGIS 0x81F7 -#endif - -#ifndef GL_SGIS_texture_color_mask -#define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF -#endif - -#ifndef GL_EXT_texture_env_dot3 -#define GL_DOT3_RGB_EXT 0x8740 -#define GL_DOT3_RGBA_EXT 0x8741 -#endif - -#ifndef GL_ATI_texture_mirror_once -#define GL_MIRROR_CLAMP_ATI 0x8742 -#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 -#endif - -#ifndef GL_NV_fence -#define GL_ALL_COMPLETED_NV 0x84F2 -#define GL_FENCE_STATUS_NV 0x84F3 -#define GL_FENCE_CONDITION_NV 0x84F4 -#endif - -#ifndef GL_IBM_texture_mirrored_repeat -#define GL_MIRRORED_REPEAT_IBM 0x8370 -#endif - -#ifndef GL_NV_evaluators -#define GL_EVAL_2D_NV 0x86C0 -#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 -#define GL_MAP_TESSELLATION_NV 0x86C2 -#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 -#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 -#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 -#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 -#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 -#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 -#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 -#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA -#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB -#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC -#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD -#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE -#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF -#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 -#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 -#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 -#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 -#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 -#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 -#define GL_MAX_MAP_TESSELLATION_NV 0x86D6 -#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 -#endif - -#ifndef GL_NV_packed_depth_stencil -#define GL_DEPTH_STENCIL_NV 0x84F9 -#define GL_UNSIGNED_INT_24_8_NV 0x84FA -#endif - -#ifndef GL_NV_register_combiners2 -#define GL_PER_STAGE_CONSTANTS_NV 0x8535 -#endif - -#ifndef GL_NV_texture_compression_vtc -#endif - -#ifndef GL_NV_texture_rectangle -#define GL_TEXTURE_RECTANGLE_NV 0x84F5 -#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 -#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 -#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 -#endif - -#ifndef GL_NV_texture_shader -#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C -#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D -#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E -#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 -#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA -#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB -#define GL_DSDT_MAG_INTENSITY_NV 0x86DC -#define GL_SHADER_CONSISTENT_NV 0x86DD -#define GL_TEXTURE_SHADER_NV 0x86DE -#define GL_SHADER_OPERATION_NV 0x86DF -#define GL_CULL_MODES_NV 0x86E0 -#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 -#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 -#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 -#define GL_OFFSET_TEXTURE_2D_MATRIX_NV GL_OFFSET_TEXTURE_MATRIX_NV -#define GL_OFFSET_TEXTURE_2D_SCALE_NV GL_OFFSET_TEXTURE_SCALE_NV -#define GL_OFFSET_TEXTURE_2D_BIAS_NV GL_OFFSET_TEXTURE_BIAS_NV -#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 -#define GL_CONST_EYE_NV 0x86E5 -#define GL_PASS_THROUGH_NV 0x86E6 -#define GL_CULL_FRAGMENT_NV 0x86E7 -#define GL_OFFSET_TEXTURE_2D_NV 0x86E8 -#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 -#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA -#define GL_DOT_PRODUCT_NV 0x86EC -#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED -#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE -#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 -#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 -#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 -#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 -#define GL_HILO_NV 0x86F4 -#define GL_DSDT_NV 0x86F5 -#define GL_DSDT_MAG_NV 0x86F6 -#define GL_DSDT_MAG_VIB_NV 0x86F7 -#define GL_HILO16_NV 0x86F8 -#define GL_SIGNED_HILO_NV 0x86F9 -#define GL_SIGNED_HILO16_NV 0x86FA -#define GL_SIGNED_RGBA_NV 0x86FB -#define GL_SIGNED_RGBA8_NV 0x86FC -#define GL_SIGNED_RGB_NV 0x86FE -#define GL_SIGNED_RGB8_NV 0x86FF -#define GL_SIGNED_LUMINANCE_NV 0x8701 -#define GL_SIGNED_LUMINANCE8_NV 0x8702 -#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 -#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 -#define GL_SIGNED_ALPHA_NV 0x8705 -#define GL_SIGNED_ALPHA8_NV 0x8706 -#define GL_SIGNED_INTENSITY_NV 0x8707 -#define GL_SIGNED_INTENSITY8_NV 0x8708 -#define GL_DSDT8_NV 0x8709 -#define GL_DSDT8_MAG8_NV 0x870A -#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B -#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C -#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D -#define GL_HI_SCALE_NV 0x870E -#define GL_LO_SCALE_NV 0x870F -#define GL_DS_SCALE_NV 0x8710 -#define GL_DT_SCALE_NV 0x8711 -#define GL_MAGNITUDE_SCALE_NV 0x8712 -#define GL_VIBRANCE_SCALE_NV 0x8713 -#define GL_HI_BIAS_NV 0x8714 -#define GL_LO_BIAS_NV 0x8715 -#define GL_DS_BIAS_NV 0x8716 -#define GL_DT_BIAS_NV 0x8717 -#define GL_MAGNITUDE_BIAS_NV 0x8718 -#define GL_VIBRANCE_BIAS_NV 0x8719 -#define GL_TEXTURE_BORDER_VALUES_NV 0x871A -#define GL_TEXTURE_HI_SIZE_NV 0x871B -#define GL_TEXTURE_LO_SIZE_NV 0x871C -#define GL_TEXTURE_DS_SIZE_NV 0x871D -#define GL_TEXTURE_DT_SIZE_NV 0x871E -#define GL_TEXTURE_MAG_SIZE_NV 0x871F -#endif - -#ifndef GL_NV_texture_shader2 -#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF -#endif - -#ifndef GL_NV_vertex_array_range2 -#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 -#endif - -#ifndef GL_NV_vertex_program -#define GL_VERTEX_PROGRAM_NV 0x8620 -#define GL_VERTEX_STATE_PROGRAM_NV 0x8621 -#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 -#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 -#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 -#define GL_CURRENT_ATTRIB_NV 0x8626 -#define GL_PROGRAM_LENGTH_NV 0x8627 -#define GL_PROGRAM_STRING_NV 0x8628 -#define GL_MODELVIEW_PROJECTION_NV 0x8629 -#define GL_IDENTITY_NV 0x862A -#define GL_INVERSE_NV 0x862B -#define GL_TRANSPOSE_NV 0x862C -#define GL_INVERSE_TRANSPOSE_NV 0x862D -#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E -#define GL_MAX_TRACK_MATRICES_NV 0x862F -#define GL_MATRIX0_NV 0x8630 -#define GL_MATRIX1_NV 0x8631 -#define GL_MATRIX2_NV 0x8632 -#define GL_MATRIX3_NV 0x8633 -#define GL_MATRIX4_NV 0x8634 -#define GL_MATRIX5_NV 0x8635 -#define GL_MATRIX6_NV 0x8636 -#define GL_MATRIX7_NV 0x8637 -#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 -#define GL_CURRENT_MATRIX_NV 0x8641 -#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 -#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 -#define GL_PROGRAM_PARAMETER_NV 0x8644 -#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 -#define GL_PROGRAM_TARGET_NV 0x8646 -#define GL_PROGRAM_RESIDENT_NV 0x8647 -#define GL_TRACK_MATRIX_NV 0x8648 -#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 -#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A -#define GL_PROGRAM_ERROR_POSITION_NV 0x864B -#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 -#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 -#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 -#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 -#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 -#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 -#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 -#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 -#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 -#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 -#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A -#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B -#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C -#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D -#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E -#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F -#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 -#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 -#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 -#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 -#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 -#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 -#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 -#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 -#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 -#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 -#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A -#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B -#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C -#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D -#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E -#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F -#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 -#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 -#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 -#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 -#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 -#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 -#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 -#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 -#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 -#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 -#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A -#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B -#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C -#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D -#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E -#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F -#endif - -#ifndef GL_SGIX_texture_coordinate_clamp -#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 -#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A -#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B -#endif - -#ifndef GL_SGIX_scalebias_hint -#define GL_SCALEBIAS_HINT_SGIX 0x8322 -#endif - -#ifndef GL_OML_interlace -#define GL_INTERLACE_OML 0x8980 -#define GL_INTERLACE_READ_OML 0x8981 -#endif - -#ifndef GL_OML_subsample -#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 -#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 -#endif - -#ifndef GL_OML_resample -#define GL_PACK_RESAMPLE_OML 0x8984 -#define GL_UNPACK_RESAMPLE_OML 0x8985 -#define GL_RESAMPLE_REPLICATE_OML 0x8986 -#define GL_RESAMPLE_ZERO_FILL_OML 0x8987 -#define GL_RESAMPLE_AVERAGE_OML 0x8988 -#define GL_RESAMPLE_DECIMATE_OML 0x8989 -#endif - -#ifndef GL_NV_copy_depth_to_color -#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E -#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F -#endif - -#ifndef GL_ATI_envmap_bumpmap -#define GL_BUMP_ROT_MATRIX_ATI 0x8775 -#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 -#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 -#define GL_BUMP_TEX_UNITS_ATI 0x8778 -#define GL_DUDV_ATI 0x8779 -#define GL_DU8DV8_ATI 0x877A -#define GL_BUMP_ENVMAP_ATI 0x877B -#define GL_BUMP_TARGET_ATI 0x877C -#endif - -#ifndef GL_ATI_fragment_shader -#define GL_FRAGMENT_SHADER_ATI 0x8920 -#define GL_REG_0_ATI 0x8921 -#define GL_REG_1_ATI 0x8922 -#define GL_REG_2_ATI 0x8923 -#define GL_REG_3_ATI 0x8924 -#define GL_REG_4_ATI 0x8925 -#define GL_REG_5_ATI 0x8926 -#define GL_REG_6_ATI 0x8927 -#define GL_REG_7_ATI 0x8928 -#define GL_REG_8_ATI 0x8929 -#define GL_REG_9_ATI 0x892A -#define GL_REG_10_ATI 0x892B -#define GL_REG_11_ATI 0x892C -#define GL_REG_12_ATI 0x892D -#define GL_REG_13_ATI 0x892E -#define GL_REG_14_ATI 0x892F -#define GL_REG_15_ATI 0x8930 -#define GL_REG_16_ATI 0x8931 -#define GL_REG_17_ATI 0x8932 -#define GL_REG_18_ATI 0x8933 -#define GL_REG_19_ATI 0x8934 -#define GL_REG_20_ATI 0x8935 -#define GL_REG_21_ATI 0x8936 -#define GL_REG_22_ATI 0x8937 -#define GL_REG_23_ATI 0x8938 -#define GL_REG_24_ATI 0x8939 -#define GL_REG_25_ATI 0x893A -#define GL_REG_26_ATI 0x893B -#define GL_REG_27_ATI 0x893C -#define GL_REG_28_ATI 0x893D -#define GL_REG_29_ATI 0x893E -#define GL_REG_30_ATI 0x893F -#define GL_REG_31_ATI 0x8940 -#define GL_CON_0_ATI 0x8941 -#define GL_CON_1_ATI 0x8942 -#define GL_CON_2_ATI 0x8943 -#define GL_CON_3_ATI 0x8944 -#define GL_CON_4_ATI 0x8945 -#define GL_CON_5_ATI 0x8946 -#define GL_CON_6_ATI 0x8947 -#define GL_CON_7_ATI 0x8948 -#define GL_CON_8_ATI 0x8949 -#define GL_CON_9_ATI 0x894A -#define GL_CON_10_ATI 0x894B -#define GL_CON_11_ATI 0x894C -#define GL_CON_12_ATI 0x894D -#define GL_CON_13_ATI 0x894E -#define GL_CON_14_ATI 0x894F -#define GL_CON_15_ATI 0x8950 -#define GL_CON_16_ATI 0x8951 -#define GL_CON_17_ATI 0x8952 -#define GL_CON_18_ATI 0x8953 -#define GL_CON_19_ATI 0x8954 -#define GL_CON_20_ATI 0x8955 -#define GL_CON_21_ATI 0x8956 -#define GL_CON_22_ATI 0x8957 -#define GL_CON_23_ATI 0x8958 -#define GL_CON_24_ATI 0x8959 -#define GL_CON_25_ATI 0x895A -#define GL_CON_26_ATI 0x895B -#define GL_CON_27_ATI 0x895C -#define GL_CON_28_ATI 0x895D -#define GL_CON_29_ATI 0x895E -#define GL_CON_30_ATI 0x895F -#define GL_CON_31_ATI 0x8960 -#define GL_MOV_ATI 0x8961 -#define GL_ADD_ATI 0x8963 -#define GL_MUL_ATI 0x8964 -#define GL_SUB_ATI 0x8965 -#define GL_DOT3_ATI 0x8966 -#define GL_DOT4_ATI 0x8967 -#define GL_MAD_ATI 0x8968 -#define GL_LERP_ATI 0x8969 -#define GL_CND_ATI 0x896A -#define GL_CND0_ATI 0x896B -#define GL_DOT2_ADD_ATI 0x896C -#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D -#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E -#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F -#define GL_NUM_PASSES_ATI 0x8970 -#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 -#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 -#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 -#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 -#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 -#define GL_SWIZZLE_STR_ATI 0x8976 -#define GL_SWIZZLE_STQ_ATI 0x8977 -#define GL_SWIZZLE_STR_DR_ATI 0x8978 -#define GL_SWIZZLE_STQ_DQ_ATI 0x8979 -#define GL_SWIZZLE_STRQ_ATI 0x897A -#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B -#define GL_RED_BIT_ATI 0x00000001 -#define GL_GREEN_BIT_ATI 0x00000002 -#define GL_BLUE_BIT_ATI 0x00000004 -#define GL_2X_BIT_ATI 0x00000001 -#define GL_4X_BIT_ATI 0x00000002 -#define GL_8X_BIT_ATI 0x00000004 -#define GL_HALF_BIT_ATI 0x00000008 -#define GL_QUARTER_BIT_ATI 0x00000010 -#define GL_EIGHTH_BIT_ATI 0x00000020 -#define GL_SATURATE_BIT_ATI 0x00000040 -#define GL_COMP_BIT_ATI 0x00000002 -#define GL_NEGATE_BIT_ATI 0x00000004 -#define GL_BIAS_BIT_ATI 0x00000008 -#endif - -#ifndef GL_ATI_pn_triangles -#define GL_PN_TRIANGLES_ATI 0x87F0 -#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 -#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 -#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 -#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 -#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 -#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 -#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 -#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 -#endif - -#ifndef GL_ATI_vertex_array_object -#define GL_STATIC_ATI 0x8760 -#define GL_DYNAMIC_ATI 0x8761 -#define GL_PRESERVE_ATI 0x8762 -#define GL_DISCARD_ATI 0x8763 -#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 -#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 -#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 -#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 -#endif - -#ifndef GL_EXT_vertex_shader -#define GL_VERTEX_SHADER_EXT 0x8780 -#define GL_VERTEX_SHADER_BINDING_EXT 0x8781 -#define GL_OP_INDEX_EXT 0x8782 -#define GL_OP_NEGATE_EXT 0x8783 -#define GL_OP_DOT3_EXT 0x8784 -#define GL_OP_DOT4_EXT 0x8785 -#define GL_OP_MUL_EXT 0x8786 -#define GL_OP_ADD_EXT 0x8787 -#define GL_OP_MADD_EXT 0x8788 -#define GL_OP_FRAC_EXT 0x8789 -#define GL_OP_MAX_EXT 0x878A -#define GL_OP_MIN_EXT 0x878B -#define GL_OP_SET_GE_EXT 0x878C -#define GL_OP_SET_LT_EXT 0x878D -#define GL_OP_CLAMP_EXT 0x878E -#define GL_OP_FLOOR_EXT 0x878F -#define GL_OP_ROUND_EXT 0x8790 -#define GL_OP_EXP_BASE_2_EXT 0x8791 -#define GL_OP_LOG_BASE_2_EXT 0x8792 -#define GL_OP_POWER_EXT 0x8793 -#define GL_OP_RECIP_EXT 0x8794 -#define GL_OP_RECIP_SQRT_EXT 0x8795 -#define GL_OP_SUB_EXT 0x8796 -#define GL_OP_CROSS_PRODUCT_EXT 0x8797 -#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 -#define GL_OP_MOV_EXT 0x8799 -#define GL_OUTPUT_VERTEX_EXT 0x879A -#define GL_OUTPUT_COLOR0_EXT 0x879B -#define GL_OUTPUT_COLOR1_EXT 0x879C -#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D -#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E -#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F -#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 -#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 -#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 -#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 -#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 -#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 -#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 -#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 -#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 -#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 -#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA -#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB -#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC -#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD -#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE -#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF -#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 -#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 -#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 -#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 -#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 -#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 -#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 -#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 -#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 -#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 -#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA -#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB -#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC -#define GL_OUTPUT_FOG_EXT 0x87BD -#define GL_SCALAR_EXT 0x87BE -#define GL_VECTOR_EXT 0x87BF -#define GL_MATRIX_EXT 0x87C0 -#define GL_VARIANT_EXT 0x87C1 -#define GL_INVARIANT_EXT 0x87C2 -#define GL_LOCAL_CONSTANT_EXT 0x87C3 -#define GL_LOCAL_EXT 0x87C4 -#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 -#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 -#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 -#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 -#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE -#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF -#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 -#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 -#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 -#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 -#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 -#define GL_X_EXT 0x87D5 -#define GL_Y_EXT 0x87D6 -#define GL_Z_EXT 0x87D7 -#define GL_W_EXT 0x87D8 -#define GL_NEGATIVE_X_EXT 0x87D9 -#define GL_NEGATIVE_Y_EXT 0x87DA -#define GL_NEGATIVE_Z_EXT 0x87DB -#define GL_NEGATIVE_W_EXT 0x87DC -#define GL_ZERO_EXT 0x87DD -#define GL_ONE_EXT 0x87DE -#define GL_NEGATIVE_ONE_EXT 0x87DF -#define GL_NORMALIZED_RANGE_EXT 0x87E0 -#define GL_FULL_RANGE_EXT 0x87E1 -#define GL_CURRENT_VERTEX_EXT 0x87E2 -#define GL_MVP_MATRIX_EXT 0x87E3 -#define GL_VARIANT_VALUE_EXT 0x87E4 -#define GL_VARIANT_DATATYPE_EXT 0x87E5 -#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 -#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 -#define GL_VARIANT_ARRAY_EXT 0x87E8 -#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 -#define GL_INVARIANT_VALUE_EXT 0x87EA -#define GL_INVARIANT_DATATYPE_EXT 0x87EB -#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC -#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED -#endif - -#ifndef GL_ATI_vertex_streams -#define GL_MAX_VERTEX_STREAMS_ATI 0x876B -#define GL_VERTEX_STREAM0_ATI 0x876C -#define GL_VERTEX_STREAM1_ATI 0x876D -#define GL_VERTEX_STREAM2_ATI 0x876E -#define GL_VERTEX_STREAM3_ATI 0x876F -#define GL_VERTEX_STREAM4_ATI 0x8770 -#define GL_VERTEX_STREAM5_ATI 0x8771 -#define GL_VERTEX_STREAM6_ATI 0x8772 -#define GL_VERTEX_STREAM7_ATI 0x8773 -#define GL_VERTEX_SOURCE_ATI 0x8774 -#endif - -#ifndef GL_ATI_element_array -#define GL_ELEMENT_ARRAY_ATI 0x8768 -#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 -#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A -#endif - -#ifndef GL_SUN_mesh_array -#define GL_QUAD_MESH_SUN 0x8614 -#define GL_TRIANGLE_MESH_SUN 0x8615 -#endif - -#ifndef GL_SUN_slice_accum -#define GL_SLICE_ACCUM_SUN 0x85CC -#endif - -#ifndef GL_NV_multisample_filter_hint -#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 -#endif - -#ifndef GL_NV_depth_clamp -#define GL_DEPTH_CLAMP_NV 0x864F -#endif - -#ifndef GL_NV_occlusion_query -#define GL_PIXEL_COUNTER_BITS_NV 0x8864 -#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 -#define GL_PIXEL_COUNT_NV 0x8866 -#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 -#endif - -#ifndef GL_NV_point_sprite -#define GL_POINT_SPRITE_NV 0x8861 -#define GL_COORD_REPLACE_NV 0x8862 -#define GL_POINT_SPRITE_R_MODE_NV 0x8863 -#endif - -#ifndef GL_NV_texture_shader3 -#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 -#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 -#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 -#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 -#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 -#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 -#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 -#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 -#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 -#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 -#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A -#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B -#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C -#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D -#define GL_HILO8_NV 0x885E -#define GL_SIGNED_HILO8_NV 0x885F -#define GL_FORCE_BLUE_TO_ONE_NV 0x8860 -#endif - -#ifndef GL_NV_vertex_program1_1 -#endif - -#ifndef GL_EXT_shadow_funcs -#endif - -#ifndef GL_EXT_stencil_two_side -#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 -#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 -#endif - -#ifndef GL_ATI_text_fragment_shader -#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 -#endif - -#ifndef GL_APPLE_client_storage -#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 -#endif - -#ifndef GL_APPLE_element_array -#define GL_ELEMENT_ARRAY_APPLE 0x8768 -#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8769 -#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x876A -#endif - -#ifndef GL_APPLE_fence -#define GL_DRAW_PIXELS_APPLE 0x8A0A -#define GL_FENCE_APPLE 0x8A0B -#endif - -#ifndef GL_APPLE_vertex_array_object -#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 -#endif - -#ifndef GL_APPLE_vertex_array_range -#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D -#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E -#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F -#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 -#define GL_STORAGE_CACHED_APPLE 0x85BE -#define GL_STORAGE_SHARED_APPLE 0x85BF -#endif - -#ifndef GL_APPLE_ycbcr_422 -#define GL_YCBCR_422_APPLE 0x85B9 -#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA -#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB -#endif - -#ifndef GL_S3_s3tc -#define GL_RGB_S3TC 0x83A0 -#define GL_RGB4_S3TC 0x83A1 -#define GL_RGBA_S3TC 0x83A2 -#define GL_RGBA4_S3TC 0x83A3 -#endif - -#ifndef GL_ATI_draw_buffers -#define GL_MAX_DRAW_BUFFERS_ATI 0x8824 -#define GL_DRAW_BUFFER0_ATI 0x8825 -#define GL_DRAW_BUFFER1_ATI 0x8826 -#define GL_DRAW_BUFFER2_ATI 0x8827 -#define GL_DRAW_BUFFER3_ATI 0x8828 -#define GL_DRAW_BUFFER4_ATI 0x8829 -#define GL_DRAW_BUFFER5_ATI 0x882A -#define GL_DRAW_BUFFER6_ATI 0x882B -#define GL_DRAW_BUFFER7_ATI 0x882C -#define GL_DRAW_BUFFER8_ATI 0x882D -#define GL_DRAW_BUFFER9_ATI 0x882E -#define GL_DRAW_BUFFER10_ATI 0x882F -#define GL_DRAW_BUFFER11_ATI 0x8830 -#define GL_DRAW_BUFFER12_ATI 0x8831 -#define GL_DRAW_BUFFER13_ATI 0x8832 -#define GL_DRAW_BUFFER14_ATI 0x8833 -#define GL_DRAW_BUFFER15_ATI 0x8834 -#endif - -#ifndef GL_ATI_pixel_format_float -#define GL_TYPE_RGBA_FLOAT_ATI 0x8820 -#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 -#endif - -#ifndef GL_ATI_texture_env_combine3 -#define GL_MODULATE_ADD_ATI 0x8744 -#define GL_MODULATE_SIGNED_ADD_ATI 0x8745 -#define GL_MODULATE_SUBTRACT_ATI 0x8746 -#endif - -#ifndef GL_ATI_texture_float -#define GL_RGBA_FLOAT32_ATI 0x8814 -#define GL_RGB_FLOAT32_ATI 0x8815 -#define GL_ALPHA_FLOAT32_ATI 0x8816 -#define GL_INTENSITY_FLOAT32_ATI 0x8817 -#define GL_LUMINANCE_FLOAT32_ATI 0x8818 -#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 -#define GL_RGBA_FLOAT16_ATI 0x881A -#define GL_RGB_FLOAT16_ATI 0x881B -#define GL_ALPHA_FLOAT16_ATI 0x881C -#define GL_INTENSITY_FLOAT16_ATI 0x881D -#define GL_LUMINANCE_FLOAT16_ATI 0x881E -#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F -#endif - -#ifndef GL_NV_float_buffer -#define GL_FLOAT_R_NV 0x8880 -#define GL_FLOAT_RG_NV 0x8881 -#define GL_FLOAT_RGB_NV 0x8882 -#define GL_FLOAT_RGBA_NV 0x8883 -#define GL_FLOAT_R16_NV 0x8884 -#define GL_FLOAT_R32_NV 0x8885 -#define GL_FLOAT_RG16_NV 0x8886 -#define GL_FLOAT_RG32_NV 0x8887 -#define GL_FLOAT_RGB16_NV 0x8888 -#define GL_FLOAT_RGB32_NV 0x8889 -#define GL_FLOAT_RGBA16_NV 0x888A -#define GL_FLOAT_RGBA32_NV 0x888B -#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C -#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D -#define GL_FLOAT_RGBA_MODE_NV 0x888E -#endif - -#ifndef GL_NV_fragment_program -#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 -#define GL_FRAGMENT_PROGRAM_NV 0x8870 -#define GL_MAX_TEXTURE_COORDS_NV 0x8871 -#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 -#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 -#define GL_PROGRAM_ERROR_STRING_NV 0x8874 -#endif - -#ifndef GL_NV_half_float -#define GL_HALF_FLOAT_NV 0x140B -#endif - -#ifndef GL_NV_pixel_data_range -#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 -#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 -#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A -#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B -#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C -#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D -#endif - -#ifndef GL_NV_primitive_restart -#define GL_PRIMITIVE_RESTART_NV 0x8558 -#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 -#endif - -#ifndef GL_NV_texture_expand_normal -#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F -#endif - -#ifndef GL_NV_vertex_program2 -#endif - -#ifndef GL_ATI_map_object_buffer -#endif - -#ifndef GL_ATI_separate_stencil -#define GL_STENCIL_BACK_FUNC_ATI 0x8800 -#define GL_STENCIL_BACK_FAIL_ATI 0x8801 -#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 -#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 -#endif - -#ifndef GL_ATI_vertex_attrib_array_object -#endif - -#ifndef GL_OES_read_format -#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A -#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B -#endif - -#ifndef GL_EXT_depth_bounds_test -#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 -#define GL_DEPTH_BOUNDS_EXT 0x8891 -#endif - -#ifndef GL_EXT_texture_mirror_clamp -#define GL_MIRROR_CLAMP_EXT 0x8742 -#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 -#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 -#endif - -#ifndef GL_EXT_blend_equation_separate -#define GL_BLEND_EQUATION_RGB_EXT GL_BLEND_EQUATION -#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D -#endif - -#ifndef GL_MESA_pack_invert -#define GL_PACK_INVERT_MESA 0x8758 -#endif - -#ifndef GL_MESA_ycbcr_texture -#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA -#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB -#define GL_YCBCR_MESA 0x8757 -#endif - -#ifndef GL_EXT_pixel_buffer_object -#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB -#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC -#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED -#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF -#endif - -#ifndef GL_NV_fragment_program_option -#endif - -#ifndef GL_NV_fragment_program2 -#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 -#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 -#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6 -#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7 -#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8 -#endif - -#ifndef GL_NV_vertex_program2_option -/* reuse GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV */ -/* reuse GL_MAX_PROGRAM_CALL_DEPTH_NV */ -#endif - -#ifndef GL_NV_vertex_program3 -/* reuse GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB */ -#endif - -#ifndef GL_EXT_framebuffer_object -#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 -#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 -#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 -#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 -#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 -#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 -#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA -#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB -#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC -#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD -#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF -#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 -#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 -#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 -#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 -#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 -#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 -#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 -#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 -#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 -#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 -#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA -#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB -#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC -#define GL_COLOR_ATTACHMENT13_EXT 0x8CED -#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE -#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF -#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 -#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 -#define GL_FRAMEBUFFER_EXT 0x8D40 -#define GL_RENDERBUFFER_EXT 0x8D41 -#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 -#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 -#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 -#define GL_STENCIL_INDEX1_EXT 0x8D46 -#define GL_STENCIL_INDEX4_EXT 0x8D47 -#define GL_STENCIL_INDEX8_EXT 0x8D48 -#define GL_STENCIL_INDEX16_EXT 0x8D49 -#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 -#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 -#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 -#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 -#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 -#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 -#endif - -#ifndef GL_GREMEDY_string_marker -#endif - -#ifndef GL_EXT_packed_depth_stencil -#define GL_DEPTH_STENCIL_EXT 0x84F9 -#define GL_UNSIGNED_INT_24_8_EXT 0x84FA -#define GL_DEPTH24_STENCIL8_EXT 0x88F0 -#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1 -#endif - -#ifndef GL_EXT_stencil_clear_tag -#define GL_STENCIL_TAG_BITS_EXT 0x88F2 -#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3 -#endif - -#ifndef GL_EXT_texture_sRGB -#define GL_SRGB_EXT 0x8C40 -#define GL_SRGB8_EXT 0x8C41 -#define GL_SRGB_ALPHA_EXT 0x8C42 -#define GL_SRGB8_ALPHA8_EXT 0x8C43 -#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 -#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 -#define GL_SLUMINANCE_EXT 0x8C46 -#define GL_SLUMINANCE8_EXT 0x8C47 -#define GL_COMPRESSED_SRGB_EXT 0x8C48 -#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 -#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A -#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B -#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F -#endif - -#ifndef GL_EXT_framebuffer_blit -#define GL_READ_FRAMEBUFFER_EXT 0x8CA8 -#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 -#define GL_DRAW_FRAMEBUFFER_BINDING_EXT GL_FRAMEBUFFER_BINDING_EXT -#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA -#endif - -#ifndef GL_EXT_framebuffer_multisample -#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 -#define GL_MAX_SAMPLES_EXT 0x8D57 -#endif - -#ifndef GL_MESAX_texture_stack -#define GL_TEXTURE_1D_STACK_MESAX 0x8759 -#define GL_TEXTURE_2D_STACK_MESAX 0x875A -#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B -#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C -#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D -#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E -#endif - -#ifndef GL_EXT_timer_query -#define GL_TIME_ELAPSED_EXT 0x88BF -#endif - -#ifndef GL_EXT_gpu_program_parameters -#endif - -#ifndef GL_APPLE_flush_buffer_range -#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12 -#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13 -#endif - -#ifndef GL_NV_gpu_program4 -#define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904 -#define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905 -#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906 -#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907 -#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908 -#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909 -#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5 -#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6 -#endif - -/* Laumaya for GLC_lib compiler warning with QT 4.7 - * 10/12/2010 - * Swap reuse from ARB to NV - */ -#ifndef GL_NV_geometry_program4 -/* reuse GL_LINES_ADJACENCY_EXT */ -/* reuse GL_LINE_STRIP_ADJACENCY_EXT */ -/* reuse GL_TRIANGLES_ADJACENCY_EXT */ -/* reuse GL_TRIANGLE_STRIP_ADJACENCY_EXT */ -#define GL_GEOMETRY_PROGRAM_NV 0x8C26 -#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27 -#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 -#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA -#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB -#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 -/* reuse GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT */ -/* reuse GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT */ -/* reuse GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */ -/* reuse GL_PROGRAM_POINT_SIZE_EXT */ -#endif - -#ifndef GL_EXT_geometry_shader4 -#define GL_GEOMETRY_SHADER_EXT 0x8DD9 -/* reuse GL_GEOMETRY_VERTICES_OUT_EXT */ -/* reuse GL_GEOMETRY_INPUT_TYPE_EXT */ -/* reuse GL_GEOMETRY_OUTPUT_TYPE_EXT */ -/* reuse GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT */ -#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD -#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE -#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 -//#define GL_LINES_ADJACENCY_EXT 0x000A -//#define GL_LINE_STRIP_ADJACENCY_EXT 0x000B -//#define GL_TRIANGLES_ADJACENCY_EXT 0x000C -//#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0x000D -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 -#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 -#endif - -#ifndef GL_NV_vertex_program4 -#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD -#endif - -#ifndef GL_EXT_gpu_shader4 -#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 -#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 -#define GL_SAMPLER_BUFFER_EXT 0x8DC2 -#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 -#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 -#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5 -#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 -#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 -#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 -#define GL_INT_SAMPLER_1D_EXT 0x8DC9 -#define GL_INT_SAMPLER_2D_EXT 0x8DCA -#define GL_INT_SAMPLER_3D_EXT 0x8DCB -#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC -#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD -#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE -#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF -#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 -#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1 -#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2 -#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3 -#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4 -#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5 -#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6 -#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7 -#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 -#endif - -#ifndef GL_EXT_draw_instanced -#endif - -#ifndef GL_EXT_packed_float -#define GL_R11F_G11F_B10F_EXT 0x8C3A -#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B -#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C -#endif - -#ifndef GL_EXT_texture_array -#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18 -#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19 -#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A -#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B -#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C -#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D -#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF -#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E -/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */ -#endif - -#ifndef GL_EXT_texture_buffer_object -#define GL_TEXTURE_BUFFER_EXT 0x8C2A -#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B -#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C -#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D -#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E -#endif - -#ifndef GL_EXT_texture_compression_latc -#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 -#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 -#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 -#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 -#endif - -#ifndef GL_EXT_texture_compression_rgtc -#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB -#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC -#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD -#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE -#endif - -#ifndef GL_EXT_texture_shared_exponent -#define GL_RGB9_E5_EXT 0x8C3D -#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E -#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F -#endif - -#ifndef GL_NV_depth_buffer_float -#define GL_DEPTH_COMPONENT32F_NV 0x8DAB -#define GL_DEPTH32F_STENCIL8_NV 0x8DAC -#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD -#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF -#endif - -#ifndef GL_NV_fragment_program4 -#endif - -#ifndef GL_NV_framebuffer_multisample_coverage -#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB -#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10 -#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11 -#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12 -#endif - -#ifndef GL_EXT_framebuffer_sRGB -#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 -#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA -#endif - -#ifndef GL_NV_geometry_shader4 -#endif - -#ifndef GL_NV_parameter_buffer_object -#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0 -#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1 -#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2 -#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3 -#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4 -#endif - -#ifndef GL_EXT_draw_buffers2 -#endif - -#ifndef GL_NV_transform_feedback -#define GL_BACK_PRIMARY_COLOR_NV 0x8C77 -#define GL_BACK_SECONDARY_COLOR_NV 0x8C78 -#define GL_TEXTURE_COORD_NV 0x8C79 -#define GL_CLIP_DISTANCE_NV 0x8C7A -#define GL_VERTEX_ID_NV 0x8C7B -#define GL_PRIMITIVE_ID_NV 0x8C7C -#define GL_GENERIC_ATTRIB_NV 0x8C7D -#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E -#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80 -#define GL_ACTIVE_VARYINGS_NV 0x8C81 -#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82 -#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83 -#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84 -#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85 -#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86 -#define GL_PRIMITIVES_GENERATED_NV 0x8C87 -#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88 -#define GL_RASTERIZER_DISCARD_NV 0x8C89 -#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_ATTRIBS_NV 0x8C8A -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B -#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C -#define GL_SEPARATE_ATTRIBS_NV 0x8C8D -#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E -#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F -#endif - -#ifndef GL_EXT_bindable_uniform -#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2 -#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3 -#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4 -#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED -#define GL_UNIFORM_BUFFER_EXT 0x8DEE -#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF -#endif - -#ifndef GL_EXT_texture_integer -#define GL_RGBA32UI_EXT 0x8D70 -#define GL_RGB32UI_EXT 0x8D71 -#define GL_ALPHA32UI_EXT 0x8D72 -#define GL_INTENSITY32UI_EXT 0x8D73 -#define GL_LUMINANCE32UI_EXT 0x8D74 -#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75 -#define GL_RGBA16UI_EXT 0x8D76 -#define GL_RGB16UI_EXT 0x8D77 -#define GL_ALPHA16UI_EXT 0x8D78 -#define GL_INTENSITY16UI_EXT 0x8D79 -#define GL_LUMINANCE16UI_EXT 0x8D7A -#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B -#define GL_RGBA8UI_EXT 0x8D7C -#define GL_RGB8UI_EXT 0x8D7D -#define GL_ALPHA8UI_EXT 0x8D7E -#define GL_INTENSITY8UI_EXT 0x8D7F -#define GL_LUMINANCE8UI_EXT 0x8D80 -#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81 -#define GL_RGBA32I_EXT 0x8D82 -#define GL_RGB32I_EXT 0x8D83 -#define GL_ALPHA32I_EXT 0x8D84 -#define GL_INTENSITY32I_EXT 0x8D85 -#define GL_LUMINANCE32I_EXT 0x8D86 -#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87 -#define GL_RGBA16I_EXT 0x8D88 -#define GL_RGB16I_EXT 0x8D89 -#define GL_ALPHA16I_EXT 0x8D8A -#define GL_INTENSITY16I_EXT 0x8D8B -#define GL_LUMINANCE16I_EXT 0x8D8C -#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D -#define GL_RGBA8I_EXT 0x8D8E -#define GL_RGB8I_EXT 0x8D8F -#define GL_ALPHA8I_EXT 0x8D90 -#define GL_INTENSITY8I_EXT 0x8D91 -#define GL_LUMINANCE8I_EXT 0x8D92 -#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93 -#define GL_RED_INTEGER_EXT 0x8D94 -#define GL_GREEN_INTEGER_EXT 0x8D95 -#define GL_BLUE_INTEGER_EXT 0x8D96 -#define GL_ALPHA_INTEGER_EXT 0x8D97 -#define GL_RGB_INTEGER_EXT 0x8D98 -#define GL_RGBA_INTEGER_EXT 0x8D99 -#define GL_BGR_INTEGER_EXT 0x8D9A -#define GL_BGRA_INTEGER_EXT 0x8D9B -#define GL_LUMINANCE_INTEGER_EXT 0x8D9C -#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D -#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E -#endif - -#ifndef GL_GREMEDY_frame_terminator -#endif - -#ifndef GL_NV_conditional_render -#define GL_QUERY_WAIT_NV 0x8E13 -#define GL_QUERY_NO_WAIT_NV 0x8E14 -#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15 -#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16 -#endif - -#ifndef GL_NV_present_video -#define GL_FRAME_NV 0x8E26 -#define GL_FIELDS_NV 0x8E27 -#define GL_CURRENT_TIME_NV 0x8E28 -#define GL_NUM_FILL_STREAMS_NV 0x8E29 -#define GL_PRESENT_TIME_NV 0x8E2A -#define GL_PRESENT_DURATION_NV 0x8E2B -#endif - -#ifndef GL_EXT_transform_feedback -#define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E -#define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84 -#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85 -#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F -#define GL_INTERLEAVED_ATTRIBS_EXT 0x8C8C -#define GL_SEPARATE_ATTRIBS_EXT 0x8C8D -#define GL_PRIMITIVES_GENERATED_EXT 0x8C87 -#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88 -#define GL_RASTERIZER_DISCARD_EXT 0x8C89 -#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80 -#define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83 -#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F -#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76 -#endif - -#ifndef GL_EXT_direct_state_access -#define GL_PROGRAM_MATRIX_EXT 0x8E2D -#define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E -#define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F -#endif - -#ifndef GL_EXT_vertex_array_bgra -/* reuse GL_BGRA */ -#endif - - -/*************************************************************/ - -#include -#ifndef GL_VERSION_2_0 -/* GL type for program/shader text */ -typedef char GLchar; /* native character */ -#endif - -#ifndef GL_VERSION_1_5 -/* GL types for handling large vertex buffer objects */ -typedef ptrdiff_t GLintptr; -typedef ptrdiff_t GLsizeiptr; -#endif - -#ifndef GL_ARB_vertex_buffer_object -/* GL types for handling large vertex buffer objects */ -typedef ptrdiff_t GLintptrARB; -typedef ptrdiff_t GLsizeiptrARB; -#endif - -#ifndef GL_ARB_shader_objects -/* GL types for handling shader object handles and program/shader text */ -typedef char GLcharARB; /* native character */ -typedef unsigned int GLhandleARB; /* shader object handle */ -#endif - -/* GL types for "half" precision (s10e5) float data in host memory */ -#ifndef GL_ARB_half_float_pixel -typedef unsigned short GLhalfARB; -#endif - -#ifndef GL_NV_half_float -typedef unsigned short GLhalfNV; -#endif - -#ifndef GLEXT_64_TYPES_DEFINED -/* This code block is duplicated in glxext.h, so must be protected */ -#define GLEXT_64_TYPES_DEFINED -/* Define int32_t, int64_t, and uint64_t types for UST/MSC */ -/* (as used in the GL_EXT_timer_query extension). */ -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L -#include -#elif defined(__sun__) || defined(__digital__) -#include -#if defined(__STDC__) -#if defined(__arch64__) || defined(_LP64) -typedef long int int64_t; -typedef unsigned long int uint64_t; -#else -typedef long long int int64_t; -typedef unsigned long long int uint64_t; -#endif /* __arch64__ */ -#endif /* __STDC__ */ -#elif defined( __VMS ) || defined(__sgi) -#include -#elif defined(__SCO__) || defined(__USLC__) -#include -#elif defined(__UNIXOS2__) || defined(__SOL64__) -typedef long int int32_t; -typedef long long int int64_t; -typedef unsigned long long int uint64_t; -#elif defined(_WIN32) && defined(__GNUC__) -#include -#elif defined(_WIN32) -typedef __int32 int32_t; -typedef __int64 int64_t; -typedef unsigned __int64 uint64_t; -#else -#include /* Fallback option */ -#endif -#endif - -#ifndef GL_EXT_timer_query -typedef int64_t GLint64EXT; -typedef uint64_t GLuint64EXT; -#endif - -#ifndef GL_VERSION_1_2 -#define GL_VERSION_1_2 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendColor (GLclampf, GLclampf, GLclampf, GLclampf); -GLAPI void APIENTRY glBlendEquation (GLenum); -GLAPI void APIENTRY glDrawRangeElements (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *); -GLAPI void APIENTRY glColorTable (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glColorTableParameterfv (GLenum, GLenum, const GLfloat *); -GLAPI void APIENTRY glColorTableParameteriv (GLenum, GLenum, const GLint *); -GLAPI void APIENTRY glCopyColorTable (GLenum, GLenum, GLint, GLint, GLsizei); -GLAPI void APIENTRY glGetColorTable (GLenum, GLenum, GLenum, GLvoid *); -GLAPI void APIENTRY glGetColorTableParameterfv (GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetColorTableParameteriv (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glColorSubTable (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glCopyColorSubTable (GLenum, GLsizei, GLint, GLint, GLsizei); -GLAPI void APIENTRY glConvolutionFilter1D (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glConvolutionFilter2D (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glConvolutionParameterf (GLenum, GLenum, GLfloat); -GLAPI void APIENTRY glConvolutionParameterfv (GLenum, GLenum, const GLfloat *); -GLAPI void APIENTRY glConvolutionParameteri (GLenum, GLenum, GLint); -GLAPI void APIENTRY glConvolutionParameteriv (GLenum, GLenum, const GLint *); -GLAPI void APIENTRY glCopyConvolutionFilter1D (GLenum, GLenum, GLint, GLint, GLsizei); -GLAPI void APIENTRY glCopyConvolutionFilter2D (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei); -GLAPI void APIENTRY glGetConvolutionFilter (GLenum, GLenum, GLenum, GLvoid *); -GLAPI void APIENTRY glGetConvolutionParameterfv (GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetConvolutionParameteriv (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetSeparableFilter (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *); -GLAPI void APIENTRY glSeparableFilter2D (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *); -GLAPI void APIENTRY glGetHistogram (GLenum, GLboolean, GLenum, GLenum, GLvoid *); -GLAPI void APIENTRY glGetHistogramParameterfv (GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetHistogramParameteriv (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetMinmax (GLenum, GLboolean, GLenum, GLenum, GLvoid *); -GLAPI void APIENTRY glGetMinmaxParameterfv (GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetMinmaxParameteriv (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glHistogram (GLenum, GLsizei, GLenum, GLboolean); -GLAPI void APIENTRY glMinmax (GLenum, GLenum, GLboolean); -GLAPI void APIENTRY glResetHistogram (GLenum); -GLAPI void APIENTRY glResetMinmax (GLenum); -GLAPI void APIENTRY glTexImage3D (GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glCopyTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); -typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode); -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); -typedef void (APIENTRYP PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); -typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); -typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); -typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); -typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); -typedef void (APIENTRYP PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); -typedef void (APIENTRYP PFNGLRESETHISTOGRAMPROC) (GLenum target); -typedef void (APIENTRYP PFNGLRESETMINMAXPROC) (GLenum target); -typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -#endif - -#ifndef GL_VERSION_1_3 -#define GL_VERSION_1_3 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glActiveTexture (GLenum); -GLAPI void APIENTRY glClientActiveTexture (GLenum); -GLAPI void APIENTRY glMultiTexCoord1d (GLenum, GLdouble); -GLAPI void APIENTRY glMultiTexCoord1dv (GLenum, const GLdouble *); -GLAPI void APIENTRY glMultiTexCoord1f (GLenum, GLfloat); -GLAPI void APIENTRY glMultiTexCoord1fv (GLenum, const GLfloat *); -GLAPI void APIENTRY glMultiTexCoord1i (GLenum, GLint); -GLAPI void APIENTRY glMultiTexCoord1iv (GLenum, const GLint *); -GLAPI void APIENTRY glMultiTexCoord1s (GLenum, GLshort); -GLAPI void APIENTRY glMultiTexCoord1sv (GLenum, const GLshort *); -GLAPI void APIENTRY glMultiTexCoord2d (GLenum, GLdouble, GLdouble); -GLAPI void APIENTRY glMultiTexCoord2dv (GLenum, const GLdouble *); -GLAPI void APIENTRY glMultiTexCoord2f (GLenum, GLfloat, GLfloat); -GLAPI void APIENTRY glMultiTexCoord2fv (GLenum, const GLfloat *); -GLAPI void APIENTRY glMultiTexCoord2i (GLenum, GLint, GLint); -GLAPI void APIENTRY glMultiTexCoord2iv (GLenum, const GLint *); -GLAPI void APIENTRY glMultiTexCoord2s (GLenum, GLshort, GLshort); -GLAPI void APIENTRY glMultiTexCoord2sv (GLenum, const GLshort *); -GLAPI void APIENTRY glMultiTexCoord3d (GLenum, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glMultiTexCoord3dv (GLenum, const GLdouble *); -GLAPI void APIENTRY glMultiTexCoord3f (GLenum, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glMultiTexCoord3fv (GLenum, const GLfloat *); -GLAPI void APIENTRY glMultiTexCoord3i (GLenum, GLint, GLint, GLint); -GLAPI void APIENTRY glMultiTexCoord3iv (GLenum, const GLint *); -GLAPI void APIENTRY glMultiTexCoord3s (GLenum, GLshort, GLshort, GLshort); -GLAPI void APIENTRY glMultiTexCoord3sv (GLenum, const GLshort *); -GLAPI void APIENTRY glMultiTexCoord4d (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glMultiTexCoord4dv (GLenum, const GLdouble *); -GLAPI void APIENTRY glMultiTexCoord4f (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glMultiTexCoord4fv (GLenum, const GLfloat *); -GLAPI void APIENTRY glMultiTexCoord4i (GLenum, GLint, GLint, GLint, GLint); -GLAPI void APIENTRY glMultiTexCoord4iv (GLenum, const GLint *); -GLAPI void APIENTRY glMultiTexCoord4s (GLenum, GLshort, GLshort, GLshort, GLshort); -GLAPI void APIENTRY glMultiTexCoord4sv (GLenum, const GLshort *); -GLAPI void APIENTRY glLoadTransposeMatrixf (const GLfloat *); -GLAPI void APIENTRY glLoadTransposeMatrixd (const GLdouble *); -GLAPI void APIENTRY glMultTransposeMatrixf (const GLfloat *); -GLAPI void APIENTRY glMultTransposeMatrixd (const GLdouble *); -GLAPI void APIENTRY glSampleCoverage (GLclampf, GLboolean); -GLAPI void APIENTRY glCompressedTexImage3D (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedTexImage2D (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedTexImage1D (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedTexSubImage2D (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedTexSubImage1D (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glGetCompressedTexImage (GLenum, GLint, GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); -typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat *m); -typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble *m); -typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat *m); -typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble *m); -typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img); -#endif - -#ifndef GL_VERSION_1_4 -#define GL_VERSION_1_4 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendFuncSeparate (GLenum, GLenum, GLenum, GLenum); -GLAPI void APIENTRY glFogCoordf (GLfloat); -GLAPI void APIENTRY glFogCoordfv (const GLfloat *); -GLAPI void APIENTRY glFogCoordd (GLdouble); -GLAPI void APIENTRY glFogCoorddv (const GLdouble *); -GLAPI void APIENTRY glFogCoordPointer (GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glMultiDrawArrays (GLenum, GLint *, GLsizei *, GLsizei); -GLAPI void APIENTRY glMultiDrawElements (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei); -GLAPI void APIENTRY glPointParameterf (GLenum, GLfloat); -GLAPI void APIENTRY glPointParameterfv (GLenum, const GLfloat *); -GLAPI void APIENTRY glPointParameteri (GLenum, GLint); -GLAPI void APIENTRY glPointParameteriv (GLenum, const GLint *); -GLAPI void APIENTRY glSecondaryColor3b (GLbyte, GLbyte, GLbyte); -GLAPI void APIENTRY glSecondaryColor3bv (const GLbyte *); -GLAPI void APIENTRY glSecondaryColor3d (GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glSecondaryColor3dv (const GLdouble *); -GLAPI void APIENTRY glSecondaryColor3f (GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glSecondaryColor3fv (const GLfloat *); -GLAPI void APIENTRY glSecondaryColor3i (GLint, GLint, GLint); -GLAPI void APIENTRY glSecondaryColor3iv (const GLint *); -GLAPI void APIENTRY glSecondaryColor3s (GLshort, GLshort, GLshort); -GLAPI void APIENTRY glSecondaryColor3sv (const GLshort *); -GLAPI void APIENTRY glSecondaryColor3ub (GLubyte, GLubyte, GLubyte); -GLAPI void APIENTRY glSecondaryColor3ubv (const GLubyte *); -GLAPI void APIENTRY glSecondaryColor3ui (GLuint, GLuint, GLuint); -GLAPI void APIENTRY glSecondaryColor3uiv (const GLuint *); -GLAPI void APIENTRY glSecondaryColor3us (GLushort, GLushort, GLushort); -GLAPI void APIENTRY glSecondaryColor3usv (const GLushort *); -GLAPI void APIENTRY glSecondaryColorPointer (GLint, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glWindowPos2d (GLdouble, GLdouble); -GLAPI void APIENTRY glWindowPos2dv (const GLdouble *); -GLAPI void APIENTRY glWindowPos2f (GLfloat, GLfloat); -GLAPI void APIENTRY glWindowPos2fv (const GLfloat *); -GLAPI void APIENTRY glWindowPos2i (GLint, GLint); -GLAPI void APIENTRY glWindowPos2iv (const GLint *); -GLAPI void APIENTRY glWindowPos2s (GLshort, GLshort); -GLAPI void APIENTRY glWindowPos2sv (const GLshort *); -GLAPI void APIENTRY glWindowPos3d (GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glWindowPos3dv (const GLdouble *); -GLAPI void APIENTRY glWindowPos3f (GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glWindowPos3fv (const GLfloat *); -GLAPI void APIENTRY glWindowPos3i (GLint, GLint, GLint); -GLAPI void APIENTRY glWindowPos3iv (const GLint *); -GLAPI void APIENTRY glWindowPos3s (GLshort, GLshort, GLshort); -GLAPI void APIENTRY glWindowPos3sv (const GLshort *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -typedef void (APIENTRYP PFNGLFOGCOORDFPROC) (GLfloat coord); -typedef void (APIENTRYP PFNGLFOGCOORDFVPROC) (const GLfloat *coord); -typedef void (APIENTRYP PFNGLFOGCOORDDPROC) (GLdouble coord); -typedef void (APIENTRYP PFNGLFOGCOORDDVPROC) (const GLdouble *coord); -typedef void (APIENTRYP PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); -typedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLWINDOWPOS2DVPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLWINDOWPOS2FVPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2IPROC) (GLint x, GLint y); -typedef void (APIENTRYP PFNGLWINDOWPOS2IVPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLWINDOWPOS2SVPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLWINDOWPOS3DVPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLWINDOWPOS3FVPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLWINDOWPOS3IVPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLWINDOWPOS3SVPROC) (const GLshort *v); -#endif - -#ifndef GL_VERSION_1_5 -#define GL_VERSION_1_5 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGenQueries (GLsizei, GLuint *); -GLAPI void APIENTRY glDeleteQueries (GLsizei, const GLuint *); -GLAPI GLboolean APIENTRY glIsQuery (GLuint); -GLAPI void APIENTRY glBeginQuery (GLenum, GLuint); -GLAPI void APIENTRY glEndQuery (GLenum); -GLAPI void APIENTRY glGetQueryiv (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetQueryObjectiv (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetQueryObjectuiv (GLuint, GLenum, GLuint *); -GLAPI void APIENTRY glBindBuffer (GLenum, GLuint); -GLAPI void APIENTRY glDeleteBuffers (GLsizei, const GLuint *); -GLAPI void APIENTRY glGenBuffers (GLsizei, GLuint *); -GLAPI GLboolean APIENTRY glIsBuffer (GLuint); -GLAPI void APIENTRY glBufferData (GLenum, GLsizeiptr, const GLvoid *, GLenum); -GLAPI void APIENTRY glBufferSubData (GLenum, GLintptr, GLsizeiptr, const GLvoid *); -GLAPI void APIENTRY glGetBufferSubData (GLenum, GLintptr, GLsizeiptr, GLvoid *); -GLAPI GLvoid* APIENTRY glMapBuffer (GLenum, GLenum); -GLAPI GLboolean APIENTRY glUnmapBuffer (GLenum); -GLAPI void APIENTRY glGetBufferParameteriv (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetBufferPointerv (GLenum, GLenum, GLvoid* *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids); -typedef void (APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids); -typedef GLboolean (APIENTRYP PFNGLISQUERYPROC) (GLuint id); -typedef void (APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); -typedef void (APIENTRYP PFNGLENDQUERYPROC) (GLenum target); -typedef void (APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); -typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers); -typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers); -typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage); -typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data); -typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data); -typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); -typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target); -typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, GLvoid* *params); -#endif - -#ifndef GL_VERSION_2_0 -#define GL_VERSION_2_0 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendEquationSeparate (GLenum, GLenum); -GLAPI void APIENTRY glDrawBuffers (GLsizei, const GLenum *); -GLAPI void APIENTRY glStencilOpSeparate (GLenum, GLenum, GLenum, GLenum); -GLAPI void APIENTRY glStencilFuncSeparate (GLenum, GLenum, GLint, GLuint); -GLAPI void APIENTRY glStencilMaskSeparate (GLenum, GLuint); -GLAPI void APIENTRY glAttachShader (GLuint, GLuint); -GLAPI void APIENTRY glBindAttribLocation (GLuint, GLuint, const GLchar *); -GLAPI void APIENTRY glCompileShader (GLuint); -GLAPI GLuint APIENTRY glCreateProgram (void); -GLAPI GLuint APIENTRY glCreateShader (GLenum); -GLAPI void APIENTRY glDeleteProgram (GLuint); -GLAPI void APIENTRY glDeleteShader (GLuint); -GLAPI void APIENTRY glDetachShader (GLuint, GLuint); -GLAPI void APIENTRY glDisableVertexAttribArray (GLuint); -GLAPI void APIENTRY glEnableVertexAttribArray (GLuint); -GLAPI void APIENTRY glGetActiveAttrib (GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *); -GLAPI void APIENTRY glGetActiveUniform (GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *); -GLAPI void APIENTRY glGetAttachedShaders (GLuint, GLsizei, GLsizei *, GLuint *); -GLAPI GLint APIENTRY glGetAttribLocation (GLuint, const GLchar *); -GLAPI void APIENTRY glGetProgramiv (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetProgramInfoLog (GLuint, GLsizei, GLsizei *, GLchar *); -GLAPI void APIENTRY glGetShaderiv (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetShaderInfoLog (GLuint, GLsizei, GLsizei *, GLchar *); -GLAPI void APIENTRY glGetShaderSource (GLuint, GLsizei, GLsizei *, GLchar *); -GLAPI GLint APIENTRY glGetUniformLocation (GLuint, const GLchar *); -GLAPI void APIENTRY glGetUniformfv (GLuint, GLint, GLfloat *); -GLAPI void APIENTRY glGetUniformiv (GLuint, GLint, GLint *); -GLAPI void APIENTRY glGetVertexAttribdv (GLuint, GLenum, GLdouble *); -GLAPI void APIENTRY glGetVertexAttribfv (GLuint, GLenum, GLfloat *); -GLAPI void APIENTRY glGetVertexAttribiv (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetVertexAttribPointerv (GLuint, GLenum, GLvoid* *); -GLAPI GLboolean APIENTRY glIsProgram (GLuint); -GLAPI GLboolean APIENTRY glIsShader (GLuint); -GLAPI void APIENTRY glLinkProgram (GLuint); -GLAPI void APIENTRY glShaderSource (GLuint, GLsizei, const GLchar* *, const GLint *); -GLAPI void APIENTRY glUseProgram (GLuint); -GLAPI void APIENTRY glUniform1f (GLint, GLfloat); -GLAPI void APIENTRY glUniform2f (GLint, GLfloat, GLfloat); -GLAPI void APIENTRY glUniform3f (GLint, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glUniform4f (GLint, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glUniform1i (GLint, GLint); -GLAPI void APIENTRY glUniform2i (GLint, GLint, GLint); -GLAPI void APIENTRY glUniform3i (GLint, GLint, GLint, GLint); -GLAPI void APIENTRY glUniform4i (GLint, GLint, GLint, GLint, GLint); -GLAPI void APIENTRY glUniform1fv (GLint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glUniform2fv (GLint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glUniform3fv (GLint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glUniform4fv (GLint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glUniform1iv (GLint, GLsizei, const GLint *); -GLAPI void APIENTRY glUniform2iv (GLint, GLsizei, const GLint *); -GLAPI void APIENTRY glUniform3iv (GLint, GLsizei, const GLint *); -GLAPI void APIENTRY glUniform4iv (GLint, GLsizei, const GLint *); -GLAPI void APIENTRY glUniformMatrix2fv (GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glUniformMatrix3fv (GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glUniformMatrix4fv (GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glValidateProgram (GLuint); -GLAPI void APIENTRY glVertexAttrib1d (GLuint, GLdouble); -GLAPI void APIENTRY glVertexAttrib1dv (GLuint, const GLdouble *); -GLAPI void APIENTRY glVertexAttrib1f (GLuint, GLfloat); -GLAPI void APIENTRY glVertexAttrib1fv (GLuint, const GLfloat *); -GLAPI void APIENTRY glVertexAttrib1s (GLuint, GLshort); -GLAPI void APIENTRY glVertexAttrib1sv (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttrib2d (GLuint, GLdouble, GLdouble); -GLAPI void APIENTRY glVertexAttrib2dv (GLuint, const GLdouble *); -GLAPI void APIENTRY glVertexAttrib2f (GLuint, GLfloat, GLfloat); -GLAPI void APIENTRY glVertexAttrib2fv (GLuint, const GLfloat *); -GLAPI void APIENTRY glVertexAttrib2s (GLuint, GLshort, GLshort); -GLAPI void APIENTRY glVertexAttrib2sv (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttrib3d (GLuint, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glVertexAttrib3dv (GLuint, const GLdouble *); -GLAPI void APIENTRY glVertexAttrib3f (GLuint, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glVertexAttrib3fv (GLuint, const GLfloat *); -GLAPI void APIENTRY glVertexAttrib3s (GLuint, GLshort, GLshort, GLshort); -GLAPI void APIENTRY glVertexAttrib3sv (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttrib4Nbv (GLuint, const GLbyte *); -GLAPI void APIENTRY glVertexAttrib4Niv (GLuint, const GLint *); -GLAPI void APIENTRY glVertexAttrib4Nsv (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttrib4Nub (GLuint, GLubyte, GLubyte, GLubyte, GLubyte); -GLAPI void APIENTRY glVertexAttrib4Nubv (GLuint, const GLubyte *); -GLAPI void APIENTRY glVertexAttrib4Nuiv (GLuint, const GLuint *); -GLAPI void APIENTRY glVertexAttrib4Nusv (GLuint, const GLushort *); -GLAPI void APIENTRY glVertexAttrib4bv (GLuint, const GLbyte *); -GLAPI void APIENTRY glVertexAttrib4d (GLuint, GLdouble, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glVertexAttrib4dv (GLuint, const GLdouble *); -GLAPI void APIENTRY glVertexAttrib4f (GLuint, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glVertexAttrib4fv (GLuint, const GLfloat *); -GLAPI void APIENTRY glVertexAttrib4iv (GLuint, const GLint *); -GLAPI void APIENTRY glVertexAttrib4s (GLuint, GLshort, GLshort, GLshort, GLshort); -GLAPI void APIENTRY glVertexAttrib4sv (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttrib4ubv (GLuint, const GLubyte *); -GLAPI void APIENTRY glVertexAttrib4uiv (GLuint, const GLuint *); -GLAPI void APIENTRY glVertexAttrib4usv (GLuint, const GLushort *); -GLAPI void APIENTRY glVertexAttribPointer (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); -typedef void (APIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs); -typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); -typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); -typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask); -typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); -typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name); -typedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader); -typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void); -typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type); -typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program); -typedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader); -typedef void (APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); -typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); -typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); -typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); -typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj); -typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name); -typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -typedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); -typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name); -typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params); -typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, GLvoid* *pointer); -typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC) (GLuint program); -typedef GLboolean (APIENTRYP PFNGLISSHADERPROC) (GLuint shader); -typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program); -typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length); -typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program); -typedef void (APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); -typedef void (APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); -typedef void (APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -typedef void (APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -typedef void (APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0); -typedef void (APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); -typedef void (APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); -typedef void (APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -typedef void (APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); -#endif - -#ifndef GL_VERSION_2_1 -#define GL_VERSION_2_1 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glUniformMatrix2x3fv (GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glUniformMatrix3x2fv (GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glUniformMatrix2x4fv (GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glUniformMatrix4x2fv (GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glUniformMatrix3x4fv (GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glUniformMatrix4x3fv (GLint, GLsizei, GLboolean, const GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -#endif - -#ifndef GL_VERSION_3_0 -#define GL_VERSION_3_0 1 -/* OpenGL 3.0 also reuses entry points from these extensions: */ -/* ARB_framebuffer_object */ -/* ARB_map_buffer_range */ -/* ARB_vertex_array_object */ -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorMaski (GLuint, GLboolean, GLboolean, GLboolean, GLboolean); -GLAPI void APIENTRY glGetBooleani_v (GLenum, GLuint, GLboolean *); -GLAPI void APIENTRY glGetIntegeri_v (GLenum, GLuint, GLint *); -GLAPI void APIENTRY glEnablei (GLenum, GLuint); -GLAPI void APIENTRY glDisablei (GLenum, GLuint); -GLAPI GLboolean APIENTRY glIsEnabledi (GLenum, GLuint); -GLAPI void APIENTRY glBeginTransformFeedback (GLenum); -GLAPI void APIENTRY glEndTransformFeedback (void); -GLAPI void APIENTRY glBindBufferRange (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr); -GLAPI void APIENTRY glBindBufferBase (GLenum, GLuint, GLuint); -GLAPI void APIENTRY glTransformFeedbackVaryings (GLuint, GLsizei, const GLint *, GLenum); -GLAPI void APIENTRY glGetTransformFeedbackVarying (GLuint, GLuint, GLint *); -GLAPI void APIENTRY glClampColor (GLenum, GLenum); -GLAPI void APIENTRY glBeginConditionalRender (GLuint, GLenum); -GLAPI void APIENTRY glEndConditionalRender (void); -GLAPI void APIENTRY glVertexAttribI1i (GLuint, GLint); -GLAPI void APIENTRY glVertexAttribI2i (GLuint, GLint, GLint); -GLAPI void APIENTRY glVertexAttribI3i (GLuint, GLint, GLint, GLint); -GLAPI void APIENTRY glVertexAttribI4i (GLuint, GLint, GLint, GLint, GLint); -GLAPI void APIENTRY glVertexAttribI1ui (GLuint, GLuint); -GLAPI void APIENTRY glVertexAttribI2ui (GLuint, GLuint, GLuint); -GLAPI void APIENTRY glVertexAttribI3ui (GLuint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glVertexAttribI4ui (GLuint, GLuint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glVertexAttribI1iv (GLuint, const GLint *); -GLAPI void APIENTRY glVertexAttribI2iv (GLuint, const GLint *); -GLAPI void APIENTRY glVertexAttribI3iv (GLuint, const GLint *); -GLAPI void APIENTRY glVertexAttribI4iv (GLuint, const GLint *); -GLAPI void APIENTRY glVertexAttribI1uiv (GLuint, const GLuint *); -GLAPI void APIENTRY glVertexAttribI2uiv (GLuint, const GLuint *); -GLAPI void APIENTRY glVertexAttribI3uiv (GLuint, const GLuint *); -GLAPI void APIENTRY glVertexAttribI4uiv (GLuint, const GLuint *); -GLAPI void APIENTRY glVertexAttribI4bv (GLuint, const GLbyte *); -GLAPI void APIENTRY glVertexAttribI4sv (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttribI4ubv (GLuint, const GLubyte *); -GLAPI void APIENTRY glVertexAttribI4usv (GLuint, const GLushort *); -GLAPI void APIENTRY glVertexAttribIPointer (GLuint, GLint, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glGetVertexAttribIiv (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetVertexAttribIuiv (GLuint, GLenum, GLuint *); -GLAPI void APIENTRY glGetUniformuiv (GLuint, GLint, GLuint *); -GLAPI void APIENTRY glBindFragDataLocation (GLuint, GLuint, const GLchar *); -GLAPI GLint APIENTRY glGetFragDataLocation (GLuint, const GLchar *); -GLAPI void APIENTRY glUniform1ui (GLint, GLuint); -GLAPI void APIENTRY glUniform2ui (GLint, GLuint, GLuint); -GLAPI void APIENTRY glUniform3ui (GLint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glUniform4ui (GLint, GLuint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glUniform1uiv (GLint, GLsizei, const GLuint *); -GLAPI void APIENTRY glUniform2uiv (GLint, GLsizei, const GLuint *); -GLAPI void APIENTRY glUniform3uiv (GLint, GLsizei, const GLuint *); -GLAPI void APIENTRY glUniform4uiv (GLint, GLsizei, const GLuint *); -GLAPI void APIENTRY glTexParameterIiv (GLenum, GLenum, const GLint *); -GLAPI void APIENTRY glTexParameterIuiv (GLenum, GLenum, const GLuint *); -GLAPI void APIENTRY glGetTexParameterIiv (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetTexParameterIuiv (GLenum, GLenum, GLuint *); -GLAPI void APIENTRY glClearBufferiv (GLenum, const GLint *); -GLAPI void APIENTRY glClearBufferuiv (GLenum, const GLuint *); -GLAPI void APIENTRY glClearBufferfv (GLenum, const GLfloat *); -GLAPI void APIENTRY glClearBufferfi (GLenum, GLfloat, GLint); -GLAPI const GLubyte * APIENTRY glGetStringi (GLenum, GLuint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOLORMASKIPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); -typedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC) (GLenum target, GLuint index, GLboolean *data); -typedef void (APIENTRYP PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint *data); -typedef void (APIENTRYP PFNGLENABLEIPROC) (GLenum target, GLuint index); -typedef void (APIENTRYP PFNGLDISABLEIPROC) (GLenum target, GLuint index); -typedef GLboolean (APIENTRYP PFNGLISENABLEDIPROC) (GLenum target, GLuint index); -typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode); -typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC) (void); -typedef void (APIENTRYP PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (APIENTRYP PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer); -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); -typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLint *location); -typedef void (APIENTRYP PFNGLCLAMPCOLORPROC) (GLenum target, GLenum clamp); -typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERPROC) (GLuint id, GLenum mode); -typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERPROC) (void); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IPROC) (GLuint index, GLint x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IPROC) (GLuint index, GLint x, GLint y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IPROC) (GLuint index, GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIPROC) (GLuint index, GLuint x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIPROC) (GLuint index, GLuint x, GLuint y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint *params); -typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONPROC) (GLuint program, GLuint color, const GLchar *name); -typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar *name); -typedef void (APIENTRYP PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0); -typedef void (APIENTRYP PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1); -typedef void (APIENTRYP PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); -typedef void (APIENTRYP PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -typedef void (APIENTRYP PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, const GLuint *params); -typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLCLEARBUFFERIVPROC) (GLenum buffer, const GLint *value); -typedef void (APIENTRYP PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, const GLuint *value); -typedef void (APIENTRYP PFNGLCLEARBUFFERFVPROC) (GLenum buffer, const GLfloat *value); -typedef void (APIENTRYP PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLfloat depth, GLint stencil); -typedef const GLubyte * (APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index); -#endif - -#ifndef GL_ARB_multitexture -#define GL_ARB_multitexture 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glActiveTextureARB (GLenum); -GLAPI void APIENTRY glClientActiveTextureARB (GLenum); -GLAPI void APIENTRY glMultiTexCoord1dARB (GLenum, GLdouble); -GLAPI void APIENTRY glMultiTexCoord1dvARB (GLenum, const GLdouble *); -GLAPI void APIENTRY glMultiTexCoord1fARB (GLenum, GLfloat); -GLAPI void APIENTRY glMultiTexCoord1fvARB (GLenum, const GLfloat *); -GLAPI void APIENTRY glMultiTexCoord1iARB (GLenum, GLint); -GLAPI void APIENTRY glMultiTexCoord1ivARB (GLenum, const GLint *); -GLAPI void APIENTRY glMultiTexCoord1sARB (GLenum, GLshort); -GLAPI void APIENTRY glMultiTexCoord1svARB (GLenum, const GLshort *); -GLAPI void APIENTRY glMultiTexCoord2dARB (GLenum, GLdouble, GLdouble); -GLAPI void APIENTRY glMultiTexCoord2dvARB (GLenum, const GLdouble *); -GLAPI void APIENTRY glMultiTexCoord2fARB (GLenum, GLfloat, GLfloat); -GLAPI void APIENTRY glMultiTexCoord2fvARB (GLenum, const GLfloat *); -GLAPI void APIENTRY glMultiTexCoord2iARB (GLenum, GLint, GLint); -GLAPI void APIENTRY glMultiTexCoord2ivARB (GLenum, const GLint *); -GLAPI void APIENTRY glMultiTexCoord2sARB (GLenum, GLshort, GLshort); -GLAPI void APIENTRY glMultiTexCoord2svARB (GLenum, const GLshort *); -GLAPI void APIENTRY glMultiTexCoord3dARB (GLenum, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glMultiTexCoord3dvARB (GLenum, const GLdouble *); -GLAPI void APIENTRY glMultiTexCoord3fARB (GLenum, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glMultiTexCoord3fvARB (GLenum, const GLfloat *); -GLAPI void APIENTRY glMultiTexCoord3iARB (GLenum, GLint, GLint, GLint); -GLAPI void APIENTRY glMultiTexCoord3ivARB (GLenum, const GLint *); -GLAPI void APIENTRY glMultiTexCoord3sARB (GLenum, GLshort, GLshort, GLshort); -GLAPI void APIENTRY glMultiTexCoord3svARB (GLenum, const GLshort *); -GLAPI void APIENTRY glMultiTexCoord4dARB (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glMultiTexCoord4dvARB (GLenum, const GLdouble *); -GLAPI void APIENTRY glMultiTexCoord4fARB (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glMultiTexCoord4fvARB (GLenum, const GLfloat *); -GLAPI void APIENTRY glMultiTexCoord4iARB (GLenum, GLint, GLint, GLint, GLint); -GLAPI void APIENTRY glMultiTexCoord4ivARB (GLenum, const GLint *); -GLAPI void APIENTRY glMultiTexCoord4sARB (GLenum, GLshort, GLshort, GLshort, GLshort); -GLAPI void APIENTRY glMultiTexCoord4svARB (GLenum, const GLshort *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLACTIVETEXTUREARBPROC) (GLenum texture); -typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); -#endif - -#ifndef GL_ARB_transpose_matrix -#define GL_ARB_transpose_matrix 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glLoadTransposeMatrixfARB (const GLfloat *); -GLAPI void APIENTRY glLoadTransposeMatrixdARB (const GLdouble *); -GLAPI void APIENTRY glMultTransposeMatrixfARB (const GLfloat *); -GLAPI void APIENTRY glMultTransposeMatrixdARB (const GLdouble *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); -typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); -typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); -typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); -#endif - -#ifndef GL_ARB_multisample -#define GL_ARB_multisample 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSampleCoverageARB (GLclampf, GLboolean); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert); -#endif - -#ifndef GL_ARB_texture_env_add -#define GL_ARB_texture_env_add 1 -#endif - -#ifndef GL_ARB_texture_cube_map -#define GL_ARB_texture_cube_map 1 -#endif - -#ifndef GL_ARB_texture_compression -#define GL_ARB_texture_compression 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCompressedTexImage3DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedTexImage2DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedTexImage1DARB (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedTexSubImage3DARB (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedTexSubImage2DARB (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedTexSubImage1DARB (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glGetCompressedTexImageARB (GLenum, GLint, GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint level, GLvoid *img); -#endif - -#ifndef GL_ARB_texture_border_clamp -#define GL_ARB_texture_border_clamp 1 -#endif - -#ifndef GL_ARB_point_parameters -#define GL_ARB_point_parameters 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPointParameterfARB (GLenum, GLfloat); -GLAPI void APIENTRY glPointParameterfvARB (GLenum, const GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, const GLfloat *params); -#endif - -#ifndef GL_ARB_vertex_blend -#define GL_ARB_vertex_blend 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glWeightbvARB (GLint, const GLbyte *); -GLAPI void APIENTRY glWeightsvARB (GLint, const GLshort *); -GLAPI void APIENTRY glWeightivARB (GLint, const GLint *); -GLAPI void APIENTRY glWeightfvARB (GLint, const GLfloat *); -GLAPI void APIENTRY glWeightdvARB (GLint, const GLdouble *); -GLAPI void APIENTRY glWeightubvARB (GLint, const GLubyte *); -GLAPI void APIENTRY glWeightusvARB (GLint, const GLushort *); -GLAPI void APIENTRY glWeightuivARB (GLint, const GLuint *); -GLAPI void APIENTRY glWeightPointerARB (GLint, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glVertexBlendARB (GLint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLWEIGHTBVARBPROC) (GLint size, const GLbyte *weights); -typedef void (APIENTRYP PFNGLWEIGHTSVARBPROC) (GLint size, const GLshort *weights); -typedef void (APIENTRYP PFNGLWEIGHTIVARBPROC) (GLint size, const GLint *weights); -typedef void (APIENTRYP PFNGLWEIGHTFVARBPROC) (GLint size, const GLfloat *weights); -typedef void (APIENTRYP PFNGLWEIGHTDVARBPROC) (GLint size, const GLdouble *weights); -typedef void (APIENTRYP PFNGLWEIGHTUBVARBPROC) (GLint size, const GLubyte *weights); -typedef void (APIENTRYP PFNGLWEIGHTUSVARBPROC) (GLint size, const GLushort *weights); -typedef void (APIENTRYP PFNGLWEIGHTUIVARBPROC) (GLint size, const GLuint *weights); -typedef void (APIENTRYP PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLVERTEXBLENDARBPROC) (GLint count); -#endif - -#ifndef GL_ARB_matrix_palette -#define GL_ARB_matrix_palette 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCurrentPaletteMatrixARB (GLint); -GLAPI void APIENTRY glMatrixIndexubvARB (GLint, const GLubyte *); -GLAPI void APIENTRY glMatrixIndexusvARB (GLint, const GLushort *); -GLAPI void APIENTRY glMatrixIndexuivARB (GLint, const GLuint *); -GLAPI void APIENTRY glMatrixIndexPointerARB (GLint, GLenum, GLsizei, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index); -typedef void (APIENTRYP PFNGLMATRIXINDEXUBVARBPROC) (GLint size, const GLubyte *indices); -typedef void (APIENTRYP PFNGLMATRIXINDEXUSVARBPROC) (GLint size, const GLushort *indices); -typedef void (APIENTRYP PFNGLMATRIXINDEXUIVARBPROC) (GLint size, const GLuint *indices); -typedef void (APIENTRYP PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -#endif - -#ifndef GL_ARB_texture_env_combine -#define GL_ARB_texture_env_combine 1 -#endif - -#ifndef GL_ARB_texture_env_crossbar -#define GL_ARB_texture_env_crossbar 1 -#endif - -#ifndef GL_ARB_texture_env_dot3 -#define GL_ARB_texture_env_dot3 1 -#endif - -#ifndef GL_ARB_texture_mirrored_repeat -#define GL_ARB_texture_mirrored_repeat 1 -#endif - -#ifndef GL_ARB_depth_texture -#define GL_ARB_depth_texture 1 -#endif - -#ifndef GL_ARB_shadow -#define GL_ARB_shadow 1 -#endif - -#ifndef GL_ARB_shadow_ambient -#define GL_ARB_shadow_ambient 1 -#endif - -#ifndef GL_ARB_window_pos -#define GL_ARB_window_pos 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glWindowPos2dARB (GLdouble, GLdouble); -GLAPI void APIENTRY glWindowPos2dvARB (const GLdouble *); -GLAPI void APIENTRY glWindowPos2fARB (GLfloat, GLfloat); -GLAPI void APIENTRY glWindowPos2fvARB (const GLfloat *); -GLAPI void APIENTRY glWindowPos2iARB (GLint, GLint); -GLAPI void APIENTRY glWindowPos2ivARB (const GLint *); -GLAPI void APIENTRY glWindowPos2sARB (GLshort, GLshort); -GLAPI void APIENTRY glWindowPos2svARB (const GLshort *); -GLAPI void APIENTRY glWindowPos3dARB (GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glWindowPos3dvARB (const GLdouble *); -GLAPI void APIENTRY glWindowPos3fARB (GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glWindowPos3fvARB (const GLfloat *); -GLAPI void APIENTRY glWindowPos3iARB (GLint, GLint, GLint); -GLAPI void APIENTRY glWindowPos3ivARB (const GLint *); -GLAPI void APIENTRY glWindowPos3sARB (GLshort, GLshort, GLshort); -GLAPI void APIENTRY glWindowPos3svARB (const GLshort *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLWINDOWPOS2DVARBPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLWINDOWPOS2FVARBPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y); -typedef void (APIENTRYP PFNGLWINDOWPOS2IVARBPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLWINDOWPOS2SVARBPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLWINDOWPOS3DVARBPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLWINDOWPOS3FVARBPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLWINDOWPOS3IVARBPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLWINDOWPOS3SVARBPROC) (const GLshort *v); -#endif - -#ifndef GL_ARB_vertex_program -#define GL_ARB_vertex_program 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttrib1dARB (GLuint, GLdouble); -GLAPI void APIENTRY glVertexAttrib1dvARB (GLuint, const GLdouble *); -GLAPI void APIENTRY glVertexAttrib1fARB (GLuint, GLfloat); -GLAPI void APIENTRY glVertexAttrib1fvARB (GLuint, const GLfloat *); -GLAPI void APIENTRY glVertexAttrib1sARB (GLuint, GLshort); -GLAPI void APIENTRY glVertexAttrib1svARB (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttrib2dARB (GLuint, GLdouble, GLdouble); -GLAPI void APIENTRY glVertexAttrib2dvARB (GLuint, const GLdouble *); -GLAPI void APIENTRY glVertexAttrib2fARB (GLuint, GLfloat, GLfloat); -GLAPI void APIENTRY glVertexAttrib2fvARB (GLuint, const GLfloat *); -GLAPI void APIENTRY glVertexAttrib2sARB (GLuint, GLshort, GLshort); -GLAPI void APIENTRY glVertexAttrib2svARB (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttrib3dARB (GLuint, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glVertexAttrib3dvARB (GLuint, const GLdouble *); -GLAPI void APIENTRY glVertexAttrib3fARB (GLuint, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glVertexAttrib3fvARB (GLuint, const GLfloat *); -GLAPI void APIENTRY glVertexAttrib3sARB (GLuint, GLshort, GLshort, GLshort); -GLAPI void APIENTRY glVertexAttrib3svARB (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttrib4NbvARB (GLuint, const GLbyte *); -GLAPI void APIENTRY glVertexAttrib4NivARB (GLuint, const GLint *); -GLAPI void APIENTRY glVertexAttrib4NsvARB (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttrib4NubARB (GLuint, GLubyte, GLubyte, GLubyte, GLubyte); -GLAPI void APIENTRY glVertexAttrib4NubvARB (GLuint, const GLubyte *); -GLAPI void APIENTRY glVertexAttrib4NuivARB (GLuint, const GLuint *); -GLAPI void APIENTRY glVertexAttrib4NusvARB (GLuint, const GLushort *); -GLAPI void APIENTRY glVertexAttrib4bvARB (GLuint, const GLbyte *); -GLAPI void APIENTRY glVertexAttrib4dARB (GLuint, GLdouble, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glVertexAttrib4dvARB (GLuint, const GLdouble *); -GLAPI void APIENTRY glVertexAttrib4fARB (GLuint, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glVertexAttrib4fvARB (GLuint, const GLfloat *); -GLAPI void APIENTRY glVertexAttrib4ivARB (GLuint, const GLint *); -GLAPI void APIENTRY glVertexAttrib4sARB (GLuint, GLshort, GLshort, GLshort, GLshort); -GLAPI void APIENTRY glVertexAttrib4svARB (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttrib4ubvARB (GLuint, const GLubyte *); -GLAPI void APIENTRY glVertexAttrib4uivARB (GLuint, const GLuint *); -GLAPI void APIENTRY glVertexAttrib4usvARB (GLuint, const GLushort *); -GLAPI void APIENTRY glVertexAttribPointerARB (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *); -GLAPI void APIENTRY glEnableVertexAttribArrayARB (GLuint); -GLAPI void APIENTRY glDisableVertexAttribArrayARB (GLuint); -GLAPI void APIENTRY glProgramStringARB (GLenum, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glBindProgramARB (GLenum, GLuint); -GLAPI void APIENTRY glDeleteProgramsARB (GLsizei, const GLuint *); -GLAPI void APIENTRY glGenProgramsARB (GLsizei, GLuint *); -GLAPI void APIENTRY glProgramEnvParameter4dARB (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glProgramEnvParameter4dvARB (GLenum, GLuint, const GLdouble *); -GLAPI void APIENTRY glProgramEnvParameter4fARB (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glProgramEnvParameter4fvARB (GLenum, GLuint, const GLfloat *); -GLAPI void APIENTRY glProgramLocalParameter4dARB (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glProgramLocalParameter4dvARB (GLenum, GLuint, const GLdouble *); -GLAPI void APIENTRY glProgramLocalParameter4fARB (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glProgramLocalParameter4fvARB (GLenum, GLuint, const GLfloat *); -GLAPI void APIENTRY glGetProgramEnvParameterdvARB (GLenum, GLuint, GLdouble *); -GLAPI void APIENTRY glGetProgramEnvParameterfvARB (GLenum, GLuint, GLfloat *); -GLAPI void APIENTRY glGetProgramLocalParameterdvARB (GLenum, GLuint, GLdouble *); -GLAPI void APIENTRY glGetProgramLocalParameterfvARB (GLenum, GLuint, GLfloat *); -GLAPI void APIENTRY glGetProgramivARB (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetProgramStringARB (GLenum, GLenum, GLvoid *); -GLAPI void APIENTRY glGetVertexAttribdvARB (GLuint, GLenum, GLdouble *); -GLAPI void APIENTRY glGetVertexAttribfvARB (GLuint, GLenum, GLfloat *); -GLAPI void APIENTRY glGetVertexAttribivARB (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetVertexAttribPointervARB (GLuint, GLenum, GLvoid* *); -GLAPI GLboolean APIENTRY glIsProgramARB (GLuint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); -typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); -typedef void (APIENTRYP PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const GLvoid *string); -typedef void (APIENTRYP PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program); -typedef void (APIENTRYP PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint *programs); -typedef void (APIENTRYP PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint *programs); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); -typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); -typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); -typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); -typedef void (APIENTRYP PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, GLvoid *string); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, GLvoid* *pointer); -typedef GLboolean (APIENTRYP PFNGLISPROGRAMARBPROC) (GLuint program); -#endif - -#ifndef GL_ARB_fragment_program -#define GL_ARB_fragment_program 1 -/* All ARB_fragment_program entry points are shared with ARB_vertex_program. */ -#endif - -#ifndef GL_ARB_vertex_buffer_object -#define GL_ARB_vertex_buffer_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBindBufferARB (GLenum, GLuint); -GLAPI void APIENTRY glDeleteBuffersARB (GLsizei, const GLuint *); -GLAPI void APIENTRY glGenBuffersARB (GLsizei, GLuint *); -GLAPI GLboolean APIENTRY glIsBufferARB (GLuint); -GLAPI void APIENTRY glBufferDataARB (GLenum, GLsizeiptrARB, const GLvoid *, GLenum); -GLAPI void APIENTRY glBufferSubDataARB (GLenum, GLintptrARB, GLsizeiptrARB, const GLvoid *); -GLAPI void APIENTRY glGetBufferSubDataARB (GLenum, GLintptrARB, GLsizeiptrARB, GLvoid *); -GLAPI GLvoid* APIENTRY glMapBufferARB (GLenum, GLenum); -GLAPI GLboolean APIENTRY glUnmapBufferARB (GLenum); -GLAPI void APIENTRY glGetBufferParameterivARB (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetBufferPointervARB (GLenum, GLenum, GLvoid* *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); -typedef void (APIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers); -typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers); -typedef GLboolean (APIENTRYP PFNGLISBUFFERARBPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage); -typedef void (APIENTRYP PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data); -typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data); -typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access); -typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERARBPROC) (GLenum target); -typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, GLvoid* *params); -#endif - -#ifndef GL_ARB_occlusion_query -#define GL_ARB_occlusion_query 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGenQueriesARB (GLsizei, GLuint *); -GLAPI void APIENTRY glDeleteQueriesARB (GLsizei, const GLuint *); -GLAPI GLboolean APIENTRY glIsQueryARB (GLuint); -GLAPI void APIENTRY glBeginQueryARB (GLenum, GLuint); -GLAPI void APIENTRY glEndQueryARB (GLenum); -GLAPI void APIENTRY glGetQueryivARB (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetQueryObjectivARB (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetQueryObjectuivARB (GLuint, GLenum, GLuint *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint *ids); -typedef void (APIENTRYP PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint *ids); -typedef GLboolean (APIENTRYP PFNGLISQUERYARBPROC) (GLuint id); -typedef void (APIENTRYP PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id); -typedef void (APIENTRYP PFNGLENDQUERYARBPROC) (GLenum target); -typedef void (APIENTRYP PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint *params); -#endif - -#ifndef GL_ARB_shader_objects -#define GL_ARB_shader_objects 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDeleteObjectARB (GLhandleARB); -GLAPI GLhandleARB APIENTRY glGetHandleARB (GLenum); -GLAPI void APIENTRY glDetachObjectARB (GLhandleARB, GLhandleARB); -GLAPI GLhandleARB APIENTRY glCreateShaderObjectARB (GLenum); -GLAPI void APIENTRY glShaderSourceARB (GLhandleARB, GLsizei, const GLcharARB* *, const GLint *); -GLAPI void APIENTRY glCompileShaderARB (GLhandleARB); -GLAPI GLhandleARB APIENTRY glCreateProgramObjectARB (void); -GLAPI void APIENTRY glAttachObjectARB (GLhandleARB, GLhandleARB); -GLAPI void APIENTRY glLinkProgramARB (GLhandleARB); -GLAPI void APIENTRY glUseProgramObjectARB (GLhandleARB); -GLAPI void APIENTRY glValidateProgramARB (GLhandleARB); -GLAPI void APIENTRY glUniform1fARB (GLint, GLfloat); -GLAPI void APIENTRY glUniform2fARB (GLint, GLfloat, GLfloat); -GLAPI void APIENTRY glUniform3fARB (GLint, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glUniform4fARB (GLint, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glUniform1iARB (GLint, GLint); -GLAPI void APIENTRY glUniform2iARB (GLint, GLint, GLint); -GLAPI void APIENTRY glUniform3iARB (GLint, GLint, GLint, GLint); -GLAPI void APIENTRY glUniform4iARB (GLint, GLint, GLint, GLint, GLint); -GLAPI void APIENTRY glUniform1fvARB (GLint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glUniform2fvARB (GLint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glUniform3fvARB (GLint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glUniform4fvARB (GLint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glUniform1ivARB (GLint, GLsizei, const GLint *); -GLAPI void APIENTRY glUniform2ivARB (GLint, GLsizei, const GLint *); -GLAPI void APIENTRY glUniform3ivARB (GLint, GLsizei, const GLint *); -GLAPI void APIENTRY glUniform4ivARB (GLint, GLsizei, const GLint *); -GLAPI void APIENTRY glUniformMatrix2fvARB (GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glUniformMatrix3fvARB (GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glUniformMatrix4fvARB (GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glGetObjectParameterfvARB (GLhandleARB, GLenum, GLfloat *); -GLAPI void APIENTRY glGetObjectParameterivARB (GLhandleARB, GLenum, GLint *); -GLAPI void APIENTRY glGetInfoLogARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *); -GLAPI void APIENTRY glGetAttachedObjectsARB (GLhandleARB, GLsizei, GLsizei *, GLhandleARB *); -GLAPI GLint APIENTRY glGetUniformLocationARB (GLhandleARB, const GLcharARB *); -GLAPI void APIENTRY glGetActiveUniformARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *); -GLAPI void APIENTRY glGetUniformfvARB (GLhandleARB, GLint, GLfloat *); -GLAPI void APIENTRY glGetUniformivARB (GLhandleARB, GLint, GLint *); -GLAPI void APIENTRY glGetShaderSourceARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj); -typedef GLhandleARB (APIENTRYP PFNGLGETHANDLEARBPROC) (GLenum pname); -typedef void (APIENTRYP PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj); -typedef GLhandleARB (APIENTRYP PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); -typedef void (APIENTRYP PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length); -typedef void (APIENTRYP PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj); -typedef GLhandleARB (APIENTRYP PFNGLCREATEPROGRAMOBJECTARBPROC) (void); -typedef void (APIENTRYP PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); -typedef void (APIENTRYP PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); -typedef void (APIENTRYP PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj); -typedef void (APIENTRYP PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj); -typedef void (APIENTRYP PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0); -typedef void (APIENTRYP PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1); -typedef void (APIENTRYP PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -typedef void (APIENTRYP PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -typedef void (APIENTRYP PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0); -typedef void (APIENTRYP PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1); -typedef void (APIENTRYP PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2); -typedef void (APIENTRYP PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -typedef void (APIENTRYP PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); -typedef void (APIENTRYP PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj); -typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); -typedef void (APIENTRYP PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat *params); -typedef void (APIENTRYP PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint *params); -typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source); -#endif - -#ifndef GL_ARB_vertex_shader -#define GL_ARB_vertex_shader 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBindAttribLocationARB (GLhandleARB, GLuint, const GLcharARB *); -GLAPI void APIENTRY glGetActiveAttribARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *); -GLAPI GLint APIENTRY glGetAttribLocationARB (GLhandleARB, const GLcharARB *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB *name); -typedef void (APIENTRYP PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); -typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); -#endif - -#ifndef GL_ARB_fragment_shader -#define GL_ARB_fragment_shader 1 -#endif - -#ifndef GL_ARB_shading_language_100 -#define GL_ARB_shading_language_100 1 -#endif - -#ifndef GL_ARB_texture_non_power_of_two -#define GL_ARB_texture_non_power_of_two 1 -#endif - -#ifndef GL_ARB_point_sprite -#define GL_ARB_point_sprite 1 -#endif - -#ifndef GL_ARB_fragment_program_shadow -#define GL_ARB_fragment_program_shadow 1 -#endif - -#ifndef GL_ARB_draw_buffers -#define GL_ARB_draw_buffers 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawBuffersARB (GLsizei, const GLenum *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum *bufs); -#endif - -#ifndef GL_ARB_texture_rectangle -#define GL_ARB_texture_rectangle 1 -#endif - -#ifndef GL_ARB_color_buffer_float -#define GL_ARB_color_buffer_float 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glClampColorARB (GLenum, GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp); -#endif - -#ifndef GL_ARB_half_float_pixel -#define GL_ARB_half_float_pixel 1 -#endif - -#ifndef GL_ARB_texture_float -#define GL_ARB_texture_float 1 -#endif - -#ifndef GL_ARB_pixel_buffer_object -#define GL_ARB_pixel_buffer_object 1 -#endif - -#ifndef GL_ARB_depth_buffer_float -#define GL_ARB_depth_buffer_float 1 -#endif - -#ifndef GL_ARB_draw_instanced -#define GL_ARB_draw_instanced 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawArraysInstancedARB (GLenum, GLint, GLsizei, GLsizei); -GLAPI void APIENTRY glDrawElementsInstancedARB (GLenum, GLsizei, GLenum, const GLvoid *, GLsizei); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); -typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDARBPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); -#endif - -#ifndef GL_ARB_framebuffer_object -#define GL_ARB_framebuffer_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLboolean APIENTRY glIsRenderbuffer (GLuint); -GLAPI void APIENTRY glBindRenderbuffer (GLenum, GLuint); -GLAPI void APIENTRY glDeleteRenderbuffers (GLsizei, const GLuint *); -GLAPI void APIENTRY glGenRenderbuffers (GLsizei, GLuint *); -GLAPI void APIENTRY glRenderbufferStorage (GLenum, GLenum, GLsizei, GLsizei); -GLAPI void APIENTRY glGetRenderbufferParameteriv (GLenum, GLenum, GLint *); -GLAPI GLboolean APIENTRY glIsFramebuffer (GLuint); -GLAPI void APIENTRY glBindFramebuffer (GLenum, GLuint); -GLAPI void APIENTRY glDeleteFramebuffers (GLsizei, const GLuint *); -GLAPI void APIENTRY glGenFramebuffers (GLsizei, GLuint *); -GLAPI GLenum APIENTRY glCheckFramebufferStatus (GLenum); -GLAPI void APIENTRY glFramebufferTexture1D (GLenum, GLenum, GLenum, GLuint, GLint); -GLAPI void APIENTRY glFramebufferTexture2D (GLenum, GLenum, GLenum, GLuint, GLint); -GLAPI void APIENTRY glFramebufferTexture3D (GLenum, GLenum, GLenum, GLuint, GLint, GLint); -GLAPI void APIENTRY glFramebufferRenderbuffer (GLenum, GLenum, GLenum, GLuint); -GLAPI void APIENTRY glGetFramebufferAttachmentParameteriv (GLenum, GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGenerateMipmap (GLenum); -GLAPI void APIENTRY glBlitFramebuffer (GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum); -GLAPI void APIENTRY glRenderbufferStorageMultisample (GLenum, GLsizei, GLenum, GLsizei, GLsizei); -GLAPI void APIENTRY glFramebufferTextureLayer (GLenum, GLenum, GLuint, GLint, GLint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer); -typedef void (APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers); -typedef void (APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers); -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer); -typedef void (APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer); -typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers); -typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers); -typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target); -typedef void (APIENTRYP PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -#endif - -#ifndef GL_ARB_framebuffer_sRGB -#define GL_ARB_framebuffer_sRGB 1 -#endif - -#ifndef GL_ARB_geometry_shader4 -#define GL_ARB_geometry_shader4 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramParameteriARB (GLuint, GLenum, GLint); -GLAPI void APIENTRY glFramebufferTextureARB (GLenum, GLenum, GLuint, GLint); -GLAPI void APIENTRY glFramebufferTextureLayerARB (GLenum, GLenum, GLuint, GLint, GLint); -GLAPI void APIENTRY glFramebufferTextureFaceARB (GLenum, GLenum, GLuint, GLint, GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIARBPROC) (GLuint program, GLenum pname, GLint value); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); -#endif - -#ifndef GL_ARB_half_float_vertex -#define GL_ARB_half_float_vertex 1 -#endif - -#ifndef GL_ARB_instanced_arrays -#define GL_ARB_instanced_arrays 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttribDivisor (GLuint, GLuint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor); -#endif - -#ifndef GL_ARB_map_buffer_range -#define GL_ARB_map_buffer_range 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMapBufferRange (GLenum, GLintptr, GLsizeiptr, GLbitfield); -GLAPI void APIENTRY glFlushMappedBufferRange (GLenum, GLintptr, GLsizeiptr); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); -typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length); -#endif - -#ifndef GL_ARB_texture_buffer_object -#define GL_ARB_texture_buffer_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexBufferARB (GLenum, GLenum, GLuint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXBUFFERARBPROC) (GLenum target, GLenum internalformat, GLuint buffer); -#endif - -#ifndef GL_ARB_texture_compression_rgtc -#define GL_ARB_texture_compression_rgtc 1 -#endif - -#ifndef GL_ARB_texture_rg -#define GL_ARB_texture_rg 1 -#endif - -#ifndef GL_ARB_vertex_array_object -#define GL_ARB_vertex_array_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBindVertexArray (GLuint); -GLAPI void APIENTRY glDeleteVertexArrays (GLsizei, const GLuint *); -GLAPI void APIENTRY glGenVertexArrays (GLsizei, GLuint *); -GLAPI GLboolean APIENTRY glIsVertexArray (GLuint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array); -typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays); -typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays); -typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYPROC) (GLuint array); -#endif - -#ifndef GL_EXT_abgr -#define GL_EXT_abgr 1 -#endif - -#ifndef GL_EXT_blend_color -#define GL_EXT_blend_color 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendColorEXT (GLclampf, GLclampf, GLclampf, GLclampf); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); -#endif - -#ifndef GL_EXT_polygon_offset -#define GL_EXT_polygon_offset 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPolygonOffsetEXT (GLfloat, GLfloat); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias); -#endif - -#ifndef GL_EXT_texture -#define GL_EXT_texture 1 -#endif - -#ifndef GL_EXT_texture3D -#define GL_EXT_texture3D 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexImage3DEXT (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); -#endif - -#ifndef GL_SGIS_texture_filter4 -#define GL_SGIS_texture_filter4 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetTexFilterFuncSGIS (GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glTexFilterFuncSGIS (GLenum, GLenum, GLsizei, const GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat *weights); -typedef void (APIENTRYP PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights); -#endif - -#ifndef GL_EXT_subtexture -#define GL_EXT_subtexture 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexSubImage1DEXT (GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glTexSubImage2DEXT (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); -#endif - -#ifndef GL_EXT_copy_texture -#define GL_EXT_copy_texture 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCopyTexImage1DEXT (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint); -GLAPI void APIENTRY glCopyTexImage2DEXT (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint); -GLAPI void APIENTRY glCopyTexSubImage1DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei); -GLAPI void APIENTRY glCopyTexSubImage2DEXT (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); -GLAPI void APIENTRY glCopyTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -#endif - -#ifndef GL_EXT_histogram -#define GL_EXT_histogram 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetHistogramEXT (GLenum, GLboolean, GLenum, GLenum, GLvoid *); -GLAPI void APIENTRY glGetHistogramParameterfvEXT (GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetHistogramParameterivEXT (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetMinmaxEXT (GLenum, GLboolean, GLenum, GLenum, GLvoid *); -GLAPI void APIENTRY glGetMinmaxParameterfvEXT (GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetMinmaxParameterivEXT (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glHistogramEXT (GLenum, GLsizei, GLenum, GLboolean); -GLAPI void APIENTRY glMinmaxEXT (GLenum, GLenum, GLboolean); -GLAPI void APIENTRY glResetHistogramEXT (GLenum); -GLAPI void APIENTRY glResetMinmaxEXT (GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); -typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); -typedef void (APIENTRYP PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink); -typedef void (APIENTRYP PFNGLRESETHISTOGRAMEXTPROC) (GLenum target); -typedef void (APIENTRYP PFNGLRESETMINMAXEXTPROC) (GLenum target); -#endif - -#ifndef GL_EXT_convolution -#define GL_EXT_convolution 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glConvolutionFilter1DEXT (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glConvolutionFilter2DEXT (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glConvolutionParameterfEXT (GLenum, GLenum, GLfloat); -GLAPI void APIENTRY glConvolutionParameterfvEXT (GLenum, GLenum, const GLfloat *); -GLAPI void APIENTRY glConvolutionParameteriEXT (GLenum, GLenum, GLint); -GLAPI void APIENTRY glConvolutionParameterivEXT (GLenum, GLenum, const GLint *); -GLAPI void APIENTRY glCopyConvolutionFilter1DEXT (GLenum, GLenum, GLint, GLint, GLsizei); -GLAPI void APIENTRY glCopyConvolutionFilter2DEXT (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei); -GLAPI void APIENTRY glGetConvolutionFilterEXT (GLenum, GLenum, GLenum, GLvoid *); -GLAPI void APIENTRY glGetConvolutionParameterfvEXT (GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetConvolutionParameterivEXT (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetSeparableFilterEXT (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *); -GLAPI void APIENTRY glSeparableFilter2DEXT (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); -typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); -typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); -#endif - -#ifndef GL_SGI_color_matrix -#define GL_SGI_color_matrix 1 -#endif - -#ifndef GL_SGI_color_table -#define GL_SGI_color_table 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorTableSGI (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glColorTableParameterfvSGI (GLenum, GLenum, const GLfloat *); -GLAPI void APIENTRY glColorTableParameterivSGI (GLenum, GLenum, const GLint *); -GLAPI void APIENTRY glCopyColorTableSGI (GLenum, GLenum, GLint, GLint, GLsizei); -GLAPI void APIENTRY glGetColorTableSGI (GLenum, GLenum, GLenum, GLvoid *); -GLAPI void APIENTRY glGetColorTableParameterfvSGI (GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetColorTableParameterivSGI (GLenum, GLenum, GLint *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); -typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint *params); -#endif - -#ifndef GL_SGIX_pixel_texture -#define GL_SGIX_pixel_texture 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPixelTexGenSGIX (GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPIXELTEXGENSGIXPROC) (GLenum mode); -#endif - -#ifndef GL_SGIS_pixel_texture -#define GL_SGIS_pixel_texture 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPixelTexGenParameteriSGIS (GLenum, GLint); -GLAPI void APIENTRY glPixelTexGenParameterivSGIS (GLenum, const GLint *); -GLAPI void APIENTRY glPixelTexGenParameterfSGIS (GLenum, GLfloat); -GLAPI void APIENTRY glPixelTexGenParameterfvSGIS (GLenum, const GLfloat *); -GLAPI void APIENTRY glGetPixelTexGenParameterivSGIS (GLenum, GLint *); -GLAPI void APIENTRY glGetPixelTexGenParameterfvSGIS (GLenum, GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERISGISPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFSGISPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, GLfloat *params); -#endif - -#ifndef GL_SGIS_texture4D -#define GL_SGIS_texture4D 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexImage4DSGIS (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glTexSubImage4DSGIS (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid *pixels); -#endif - -#ifndef GL_SGI_texture_color_table -#define GL_SGI_texture_color_table 1 -#endif - -#ifndef GL_EXT_cmyka -#define GL_EXT_cmyka 1 -#endif - -#ifndef GL_EXT_texture_object -#define GL_EXT_texture_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLboolean APIENTRY glAreTexturesResidentEXT (GLsizei, const GLuint *, GLboolean *); -GLAPI void APIENTRY glBindTextureEXT (GLenum, GLuint); -GLAPI void APIENTRY glDeleteTexturesEXT (GLsizei, const GLuint *); -GLAPI void APIENTRY glGenTexturesEXT (GLsizei, GLuint *); -GLAPI GLboolean APIENTRY glIsTextureEXT (GLuint); -GLAPI void APIENTRY glPrioritizeTexturesEXT (GLsizei, const GLuint *, const GLclampf *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef GLboolean (APIENTRYP PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint *textures, GLboolean *residences); -typedef void (APIENTRYP PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture); -typedef void (APIENTRYP PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint *textures); -typedef void (APIENTRYP PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint *textures); -typedef GLboolean (APIENTRYP PFNGLISTEXTUREEXTPROC) (GLuint texture); -typedef void (APIENTRYP PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint *textures, const GLclampf *priorities); -#endif - -#ifndef GL_SGIS_detail_texture -#define GL_SGIS_detail_texture 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDetailTexFuncSGIS (GLenum, GLsizei, const GLfloat *); -GLAPI void APIENTRY glGetDetailTexFuncSGIS (GLenum, GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); -typedef void (APIENTRYP PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat *points); -#endif - -#ifndef GL_SGIS_sharpen_texture -#define GL_SGIS_sharpen_texture 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSharpenTexFuncSGIS (GLenum, GLsizei, const GLfloat *); -GLAPI void APIENTRY glGetSharpenTexFuncSGIS (GLenum, GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); -typedef void (APIENTRYP PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat *points); -#endif - -#ifndef GL_EXT_packed_pixels -#define GL_EXT_packed_pixels 1 -#endif - -#ifndef GL_SGIS_texture_lod -#define GL_SGIS_texture_lod 1 -#endif - -#ifndef GL_SGIS_multisample -#define GL_SGIS_multisample 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSampleMaskSGIS (GLclampf, GLboolean); -GLAPI void APIENTRY glSamplePatternSGIS (GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert); -typedef void (APIENTRYP PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern); -#endif - -#ifndef GL_EXT_rescale_normal -#define GL_EXT_rescale_normal 1 -#endif - -#ifndef GL_EXT_vertex_array -#define GL_EXT_vertex_array 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glArrayElementEXT (GLint); -GLAPI void APIENTRY glColorPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); -GLAPI void APIENTRY glDrawArraysEXT (GLenum, GLint, GLsizei); -GLAPI void APIENTRY glEdgeFlagPointerEXT (GLsizei, GLsizei, const GLboolean *); -GLAPI void APIENTRY glGetPointervEXT (GLenum, GLvoid* *); -GLAPI void APIENTRY glIndexPointerEXT (GLenum, GLsizei, GLsizei, const GLvoid *); -GLAPI void APIENTRY glNormalPointerEXT (GLenum, GLsizei, GLsizei, const GLvoid *); -GLAPI void APIENTRY glTexCoordPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); -GLAPI void APIENTRY glVertexPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLARRAYELEMENTEXTPROC) (GLint i); -typedef void (APIENTRYP PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count); -typedef void (APIENTRYP PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean *pointer); -typedef void (APIENTRYP PFNGLGETPOINTERVEXTPROC) (GLenum pname, GLvoid* *params); -typedef void (APIENTRYP PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); -#endif - -#ifndef GL_EXT_misc_attribute -#define GL_EXT_misc_attribute 1 -#endif - -#ifndef GL_SGIS_generate_mipmap -#define GL_SGIS_generate_mipmap 1 -#endif - -#ifndef GL_SGIX_clipmap -#define GL_SGIX_clipmap 1 -#endif - -#ifndef GL_SGIX_shadow -#define GL_SGIX_shadow 1 -#endif - -#ifndef GL_SGIS_texture_edge_clamp -#define GL_SGIS_texture_edge_clamp 1 -#endif - -#ifndef GL_SGIS_texture_border_clamp -#define GL_SGIS_texture_border_clamp 1 -#endif - -#ifndef GL_EXT_blend_minmax -#define GL_EXT_blend_minmax 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendEquationEXT (GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBLENDEQUATIONEXTPROC) (GLenum mode); -#endif - -#ifndef GL_EXT_blend_subtract -#define GL_EXT_blend_subtract 1 -#endif - -#ifndef GL_EXT_blend_logic_op -#define GL_EXT_blend_logic_op 1 -#endif - -#ifndef GL_SGIX_interlace -#define GL_SGIX_interlace 1 -#endif - -#ifndef GL_SGIX_pixel_tiles -#define GL_SGIX_pixel_tiles 1 -#endif - -#ifndef GL_SGIX_texture_select -#define GL_SGIX_texture_select 1 -#endif - -#ifndef GL_SGIX_sprite -#define GL_SGIX_sprite 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSpriteParameterfSGIX (GLenum, GLfloat); -GLAPI void APIENTRY glSpriteParameterfvSGIX (GLenum, const GLfloat *); -GLAPI void APIENTRY glSpriteParameteriSGIX (GLenum, GLint); -GLAPI void APIENTRY glSpriteParameterivSGIX (GLenum, const GLint *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, const GLint *params); -#endif - -#ifndef GL_SGIX_texture_multi_buffer -#define GL_SGIX_texture_multi_buffer 1 -#endif - -#ifndef GL_EXT_point_parameters -#define GL_EXT_point_parameters 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPointParameterfEXT (GLenum, GLfloat); -GLAPI void APIENTRY glPointParameterfvEXT (GLenum, const GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params); -#endif - -#ifndef GL_SGIS_point_parameters -#define GL_SGIS_point_parameters 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPointParameterfSGIS (GLenum, GLfloat); -GLAPI void APIENTRY glPointParameterfvSGIS (GLenum, const GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPOINTPARAMETERFSGISPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); -#endif - -#ifndef GL_SGIX_instruments -#define GL_SGIX_instruments 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLint APIENTRY glGetInstrumentsSGIX (void); -GLAPI void APIENTRY glInstrumentsBufferSGIX (GLsizei, GLint *); -GLAPI GLint APIENTRY glPollInstrumentsSGIX (GLint *); -GLAPI void APIENTRY glReadInstrumentsSGIX (GLint); -GLAPI void APIENTRY glStartInstrumentsSGIX (void); -GLAPI void APIENTRY glStopInstrumentsSGIX (GLint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef GLint (APIENTRYP PFNGLGETINSTRUMENTSSGIXPROC) (void); -typedef void (APIENTRYP PFNGLINSTRUMENTSBUFFERSGIXPROC) (GLsizei size, GLint *buffer); -typedef GLint (APIENTRYP PFNGLPOLLINSTRUMENTSSGIXPROC) (GLint *marker_p); -typedef void (APIENTRYP PFNGLREADINSTRUMENTSSGIXPROC) (GLint marker); -typedef void (APIENTRYP PFNGLSTARTINSTRUMENTSSGIXPROC) (void); -typedef void (APIENTRYP PFNGLSTOPINSTRUMENTSSGIXPROC) (GLint marker); -#endif - -#ifndef GL_SGIX_texture_scale_bias -#define GL_SGIX_texture_scale_bias 1 -#endif - -#ifndef GL_SGIX_framezoom -#define GL_SGIX_framezoom 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFrameZoomSGIX (GLint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLFRAMEZOOMSGIXPROC) (GLint factor); -#endif - -#ifndef GL_SGIX_tag_sample_buffer -#define GL_SGIX_tag_sample_buffer 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTagSampleBufferSGIX (void); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTAGSAMPLEBUFFERSGIXPROC) (void); -#endif - -#ifndef GL_SGIX_polynomial_ffd -#define GL_SGIX_polynomial_ffd 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDeformationMap3dSGIX (GLenum, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, const GLdouble *); -GLAPI void APIENTRY glDeformationMap3fSGIX (GLenum, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, const GLfloat *); -GLAPI void APIENTRY glDeformSGIX (GLbitfield); -GLAPI void APIENTRY glLoadIdentityDeformationMapSGIX (GLbitfield); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDEFORMATIONMAP3DSGIXPROC) (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points); -typedef void (APIENTRYP PFNGLDEFORMATIONMAP3FSGIXPROC) (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points); -typedef void (APIENTRYP PFNGLDEFORMSGIXPROC) (GLbitfield mask); -typedef void (APIENTRYP PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) (GLbitfield mask); -#endif - -#ifndef GL_SGIX_reference_plane -#define GL_SGIX_reference_plane 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glReferencePlaneSGIX (const GLdouble *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLREFERENCEPLANESGIXPROC) (const GLdouble *equation); -#endif - -#ifndef GL_SGIX_flush_raster -#define GL_SGIX_flush_raster 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFlushRasterSGIX (void); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLFLUSHRASTERSGIXPROC) (void); -#endif - -#ifndef GL_SGIX_depth_texture -#define GL_SGIX_depth_texture 1 -#endif - -#ifndef GL_SGIS_fog_function -#define GL_SGIS_fog_function 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFogFuncSGIS (GLsizei, const GLfloat *); -GLAPI void APIENTRY glGetFogFuncSGIS (GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat *points); -typedef void (APIENTRYP PFNGLGETFOGFUNCSGISPROC) (GLfloat *points); -#endif - -#ifndef GL_SGIX_fog_offset -#define GL_SGIX_fog_offset 1 -#endif - -#ifndef GL_HP_image_transform -#define GL_HP_image_transform 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glImageTransformParameteriHP (GLenum, GLenum, GLint); -GLAPI void APIENTRY glImageTransformParameterfHP (GLenum, GLenum, GLfloat); -GLAPI void APIENTRY glImageTransformParameterivHP (GLenum, GLenum, const GLint *); -GLAPI void APIENTRY glImageTransformParameterfvHP (GLenum, GLenum, const GLfloat *); -GLAPI void APIENTRY glGetImageTransformParameterivHP (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetImageTransformParameterfvHP (GLenum, GLenum, GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, GLfloat *params); -#endif - -#ifndef GL_HP_convolution_border_modes -#define GL_HP_convolution_border_modes 1 -#endif - -#ifndef GL_SGIX_texture_add_env -#define GL_SGIX_texture_add_env 1 -#endif - -#ifndef GL_EXT_color_subtable -#define GL_EXT_color_subtable 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorSubTableEXT (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glCopyColorSubTableEXT (GLenum, GLsizei, GLint, GLint, GLsizei); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); -#endif - -#ifndef GL_PGI_vertex_hints -#define GL_PGI_vertex_hints 1 -#endif - -#ifndef GL_PGI_misc_hints -#define GL_PGI_misc_hints 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glHintPGI (GLenum, GLint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLHINTPGIPROC) (GLenum target, GLint mode); -#endif - -#ifndef GL_EXT_paletted_texture -#define GL_EXT_paletted_texture 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorTableEXT (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glGetColorTableEXT (GLenum, GLenum, GLenum, GLvoid *); -GLAPI void APIENTRY glGetColorTableParameterivEXT (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetColorTableParameterfvEXT (GLenum, GLenum, GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); -typedef void (APIENTRYP PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *data); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); -#endif - -#ifndef GL_EXT_clip_volume_hint -#define GL_EXT_clip_volume_hint 1 -#endif - -#ifndef GL_SGIX_list_priority -#define GL_SGIX_list_priority 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetListParameterfvSGIX (GLuint, GLenum, GLfloat *); -GLAPI void APIENTRY glGetListParameterivSGIX (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glListParameterfSGIX (GLuint, GLenum, GLfloat); -GLAPI void APIENTRY glListParameterfvSGIX (GLuint, GLenum, const GLfloat *); -GLAPI void APIENTRY glListParameteriSGIX (GLuint, GLenum, GLint); -GLAPI void APIENTRY glListParameterivSGIX (GLuint, GLenum, const GLint *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGETLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLLISTPARAMETERFSGIXPROC) (GLuint list, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLLISTPARAMETERISGIXPROC) (GLuint list, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, const GLint *params); -#endif - -#ifndef GL_SGIX_ir_instrument1 -#define GL_SGIX_ir_instrument1 1 -#endif - -#ifndef GL_SGIX_calligraphic_fragment -#define GL_SGIX_calligraphic_fragment 1 -#endif - -#ifndef GL_SGIX_texture_lod_bias -#define GL_SGIX_texture_lod_bias 1 -#endif - -#ifndef GL_SGIX_shadow_ambient -#define GL_SGIX_shadow_ambient 1 -#endif - -#ifndef GL_EXT_index_texture -#define GL_EXT_index_texture 1 -#endif - -#ifndef GL_EXT_index_material -#define GL_EXT_index_material 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glIndexMaterialEXT (GLenum, GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode); -#endif - -#ifndef GL_EXT_index_func -#define GL_EXT_index_func 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glIndexFuncEXT (GLenum, GLclampf); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLINDEXFUNCEXTPROC) (GLenum func, GLclampf ref); -#endif - -#ifndef GL_EXT_index_array_formats -#define GL_EXT_index_array_formats 1 -#endif - -#ifndef GL_EXT_compiled_vertex_array -#define GL_EXT_compiled_vertex_array 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glLockArraysEXT (GLint, GLsizei); -GLAPI void APIENTRY glUnlockArraysEXT (void); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); -typedef void (APIENTRYP PFNGLUNLOCKARRAYSEXTPROC) (void); -#endif - -#ifndef GL_EXT_cull_vertex -#define GL_EXT_cull_vertex 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCullParameterdvEXT (GLenum, GLdouble *); -GLAPI void APIENTRY glCullParameterfvEXT (GLenum, GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat *params); -#endif - -#ifndef GL_SGIX_ycrcb -#define GL_SGIX_ycrcb 1 -#endif - -#ifndef GL_SGIX_fragment_lighting -#define GL_SGIX_fragment_lighting 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFragmentColorMaterialSGIX (GLenum, GLenum); -GLAPI void APIENTRY glFragmentLightfSGIX (GLenum, GLenum, GLfloat); -GLAPI void APIENTRY glFragmentLightfvSGIX (GLenum, GLenum, const GLfloat *); -GLAPI void APIENTRY glFragmentLightiSGIX (GLenum, GLenum, GLint); -GLAPI void APIENTRY glFragmentLightivSGIX (GLenum, GLenum, const GLint *); -GLAPI void APIENTRY glFragmentLightModelfSGIX (GLenum, GLfloat); -GLAPI void APIENTRY glFragmentLightModelfvSGIX (GLenum, const GLfloat *); -GLAPI void APIENTRY glFragmentLightModeliSGIX (GLenum, GLint); -GLAPI void APIENTRY glFragmentLightModelivSGIX (GLenum, const GLint *); -GLAPI void APIENTRY glFragmentMaterialfSGIX (GLenum, GLenum, GLfloat); -GLAPI void APIENTRY glFragmentMaterialfvSGIX (GLenum, GLenum, const GLfloat *); -GLAPI void APIENTRY glFragmentMaterialiSGIX (GLenum, GLenum, GLint); -GLAPI void APIENTRY glFragmentMaterialivSGIX (GLenum, GLenum, const GLint *); -GLAPI void APIENTRY glGetFragmentLightfvSGIX (GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetFragmentLightivSGIX (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetFragmentMaterialfvSGIX (GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetFragmentMaterialivSGIX (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glLightEnviSGIX (GLenum, GLint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLLIGHTENVISGIXPROC) (GLenum pname, GLint param); -#endif - -#ifndef GL_IBM_rasterpos_clip -#define GL_IBM_rasterpos_clip 1 -#endif - -#ifndef GL_HP_texture_lighting -#define GL_HP_texture_lighting 1 -#endif - -#ifndef GL_EXT_draw_range_elements -#define GL_EXT_draw_range_elements 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawRangeElementsEXT (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); -#endif - -#ifndef GL_WIN_phong_shading -#define GL_WIN_phong_shading 1 -#endif - -#ifndef GL_WIN_specular_fog -#define GL_WIN_specular_fog 1 -#endif - -#ifndef GL_EXT_light_texture -#define GL_EXT_light_texture 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glApplyTextureEXT (GLenum); -GLAPI void APIENTRY glTextureLightEXT (GLenum); -GLAPI void APIENTRY glTextureMaterialEXT (GLenum, GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode); -typedef void (APIENTRYP PFNGLTEXTURELIGHTEXTPROC) (GLenum pname); -typedef void (APIENTRYP PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode); -#endif - -#ifndef GL_SGIX_blend_alpha_minmax -#define GL_SGIX_blend_alpha_minmax 1 -#endif - -#ifndef GL_EXT_bgra -#define GL_EXT_bgra 1 -#endif - -#ifndef GL_SGIX_async -#define GL_SGIX_async 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glAsyncMarkerSGIX (GLuint); -GLAPI GLint APIENTRY glFinishAsyncSGIX (GLuint *); -GLAPI GLint APIENTRY glPollAsyncSGIX (GLuint *); -GLAPI GLuint APIENTRY glGenAsyncMarkersSGIX (GLsizei); -GLAPI void APIENTRY glDeleteAsyncMarkersSGIX (GLuint, GLsizei); -GLAPI GLboolean APIENTRY glIsAsyncMarkerSGIX (GLuint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLASYNCMARKERSGIXPROC) (GLuint marker); -typedef GLint (APIENTRYP PFNGLFINISHASYNCSGIXPROC) (GLuint *markerp); -typedef GLint (APIENTRYP PFNGLPOLLASYNCSGIXPROC) (GLuint *markerp); -typedef GLuint (APIENTRYP PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range); -typedef void (APIENTRYP PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range); -typedef GLboolean (APIENTRYP PFNGLISASYNCMARKERSGIXPROC) (GLuint marker); -#endif - -#ifndef GL_SGIX_async_pixel -#define GL_SGIX_async_pixel 1 -#endif - -#ifndef GL_SGIX_async_histogram -#define GL_SGIX_async_histogram 1 -#endif - -#ifndef GL_INTEL_parallel_arrays -#define GL_INTEL_parallel_arrays 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexPointervINTEL (GLint, GLenum, const GLvoid* *); -GLAPI void APIENTRY glNormalPointervINTEL (GLenum, const GLvoid* *); -GLAPI void APIENTRY glColorPointervINTEL (GLint, GLenum, const GLvoid* *); -GLAPI void APIENTRY glTexCoordPointervINTEL (GLint, GLenum, const GLvoid* *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); -typedef void (APIENTRYP PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const GLvoid* *pointer); -typedef void (APIENTRYP PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); -typedef void (APIENTRYP PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); -#endif - -#ifndef GL_HP_occlusion_test -#define GL_HP_occlusion_test 1 -#endif - -#ifndef GL_EXT_pixel_transform -#define GL_EXT_pixel_transform 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPixelTransformParameteriEXT (GLenum, GLenum, GLint); -GLAPI void APIENTRY glPixelTransformParameterfEXT (GLenum, GLenum, GLfloat); -GLAPI void APIENTRY glPixelTransformParameterivEXT (GLenum, GLenum, const GLint *); -GLAPI void APIENTRY glPixelTransformParameterfvEXT (GLenum, GLenum, const GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); -#endif - -#ifndef GL_EXT_pixel_transform_color_table -#define GL_EXT_pixel_transform_color_table 1 -#endif - -#ifndef GL_EXT_shared_texture_palette -#define GL_EXT_shared_texture_palette 1 -#endif - -#ifndef GL_EXT_separate_specular_color -#define GL_EXT_separate_specular_color 1 -#endif - -#ifndef GL_EXT_secondary_color -#define GL_EXT_secondary_color 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSecondaryColor3bEXT (GLbyte, GLbyte, GLbyte); -GLAPI void APIENTRY glSecondaryColor3bvEXT (const GLbyte *); -GLAPI void APIENTRY glSecondaryColor3dEXT (GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glSecondaryColor3dvEXT (const GLdouble *); -GLAPI void APIENTRY glSecondaryColor3fEXT (GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glSecondaryColor3fvEXT (const GLfloat *); -GLAPI void APIENTRY glSecondaryColor3iEXT (GLint, GLint, GLint); -GLAPI void APIENTRY glSecondaryColor3ivEXT (const GLint *); -GLAPI void APIENTRY glSecondaryColor3sEXT (GLshort, GLshort, GLshort); -GLAPI void APIENTRY glSecondaryColor3svEXT (const GLshort *); -GLAPI void APIENTRY glSecondaryColor3ubEXT (GLubyte, GLubyte, GLubyte); -GLAPI void APIENTRY glSecondaryColor3ubvEXT (const GLubyte *); -GLAPI void APIENTRY glSecondaryColor3uiEXT (GLuint, GLuint, GLuint); -GLAPI void APIENTRY glSecondaryColor3uivEXT (const GLuint *); -GLAPI void APIENTRY glSecondaryColor3usEXT (GLushort, GLushort, GLushort); -GLAPI void APIENTRY glSecondaryColor3usvEXT (const GLushort *); -GLAPI void APIENTRY glSecondaryColorPointerEXT (GLint, GLenum, GLsizei, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -#endif - -#ifndef GL_EXT_texture_perturb_normal -#define GL_EXT_texture_perturb_normal 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTextureNormalEXT (GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXTURENORMALEXTPROC) (GLenum mode); -#endif - -#ifndef GL_EXT_multi_draw_arrays -#define GL_EXT_multi_draw_arrays 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMultiDrawArraysEXT (GLenum, GLint *, GLsizei *, GLsizei); -GLAPI void APIENTRY glMultiDrawElementsEXT (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); -#endif - -#ifndef GL_EXT_fog_coord -#define GL_EXT_fog_coord 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFogCoordfEXT (GLfloat); -GLAPI void APIENTRY glFogCoordfvEXT (const GLfloat *); -GLAPI void APIENTRY glFogCoorddEXT (GLdouble); -GLAPI void APIENTRY glFogCoorddvEXT (const GLdouble *); -GLAPI void APIENTRY glFogCoordPointerEXT (GLenum, GLsizei, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLFOGCOORDFEXTPROC) (GLfloat coord); -typedef void (APIENTRYP PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord); -typedef void (APIENTRYP PFNGLFOGCOORDDEXTPROC) (GLdouble coord); -typedef void (APIENTRYP PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord); -typedef void (APIENTRYP PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); -#endif - -#ifndef GL_REND_screen_coordinates -#define GL_REND_screen_coordinates 1 -#endif - -#ifndef GL_EXT_coordinate_frame -#define GL_EXT_coordinate_frame 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTangent3bEXT (GLbyte, GLbyte, GLbyte); -GLAPI void APIENTRY glTangent3bvEXT (const GLbyte *); -GLAPI void APIENTRY glTangent3dEXT (GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glTangent3dvEXT (const GLdouble *); -GLAPI void APIENTRY glTangent3fEXT (GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glTangent3fvEXT (const GLfloat *); -GLAPI void APIENTRY glTangent3iEXT (GLint, GLint, GLint); -GLAPI void APIENTRY glTangent3ivEXT (const GLint *); -GLAPI void APIENTRY glTangent3sEXT (GLshort, GLshort, GLshort); -GLAPI void APIENTRY glTangent3svEXT (const GLshort *); -GLAPI void APIENTRY glBinormal3bEXT (GLbyte, GLbyte, GLbyte); -GLAPI void APIENTRY glBinormal3bvEXT (const GLbyte *); -GLAPI void APIENTRY glBinormal3dEXT (GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glBinormal3dvEXT (const GLdouble *); -GLAPI void APIENTRY glBinormal3fEXT (GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glBinormal3fvEXT (const GLfloat *); -GLAPI void APIENTRY glBinormal3iEXT (GLint, GLint, GLint); -GLAPI void APIENTRY glBinormal3ivEXT (const GLint *); -GLAPI void APIENTRY glBinormal3sEXT (GLshort, GLshort, GLshort); -GLAPI void APIENTRY glBinormal3svEXT (const GLshort *); -GLAPI void APIENTRY glTangentPointerEXT (GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glBinormalPointerEXT (GLenum, GLsizei, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTANGENT3BEXTPROC) (GLbyte tx, GLbyte ty, GLbyte tz); -typedef void (APIENTRYP PFNGLTANGENT3BVEXTPROC) (const GLbyte *v); -typedef void (APIENTRYP PFNGLTANGENT3DEXTPROC) (GLdouble tx, GLdouble ty, GLdouble tz); -typedef void (APIENTRYP PFNGLTANGENT3DVEXTPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLTANGENT3FEXTPROC) (GLfloat tx, GLfloat ty, GLfloat tz); -typedef void (APIENTRYP PFNGLTANGENT3FVEXTPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLTANGENT3IEXTPROC) (GLint tx, GLint ty, GLint tz); -typedef void (APIENTRYP PFNGLTANGENT3IVEXTPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLTANGENT3SEXTPROC) (GLshort tx, GLshort ty, GLshort tz); -typedef void (APIENTRYP PFNGLTANGENT3SVEXTPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLBINORMAL3BEXTPROC) (GLbyte bx, GLbyte by, GLbyte bz); -typedef void (APIENTRYP PFNGLBINORMAL3BVEXTPROC) (const GLbyte *v); -typedef void (APIENTRYP PFNGLBINORMAL3DEXTPROC) (GLdouble bx, GLdouble by, GLdouble bz); -typedef void (APIENTRYP PFNGLBINORMAL3DVEXTPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLBINORMAL3FEXTPROC) (GLfloat bx, GLfloat by, GLfloat bz); -typedef void (APIENTRYP PFNGLBINORMAL3FVEXTPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLBINORMAL3IEXTPROC) (GLint bx, GLint by, GLint bz); -typedef void (APIENTRYP PFNGLBINORMAL3IVEXTPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLBINORMAL3SEXTPROC) (GLshort bx, GLshort by, GLshort bz); -typedef void (APIENTRYP PFNGLBINORMAL3SVEXTPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); -#endif - -#ifndef GL_EXT_texture_env_combine -#define GL_EXT_texture_env_combine 1 -#endif - -#ifndef GL_APPLE_specular_vector -#define GL_APPLE_specular_vector 1 -#endif - -#ifndef GL_APPLE_transform_hint -#define GL_APPLE_transform_hint 1 -#endif - -#ifndef GL_SGIX_fog_scale -#define GL_SGIX_fog_scale 1 -#endif - -#ifndef GL_SUNX_constant_data -#define GL_SUNX_constant_data 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFinishTextureSUNX (void); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLFINISHTEXTURESUNXPROC) (void); -#endif - -#ifndef GL_SUN_global_alpha -#define GL_SUN_global_alpha 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGlobalAlphaFactorbSUN (GLbyte); -GLAPI void APIENTRY glGlobalAlphaFactorsSUN (GLshort); -GLAPI void APIENTRY glGlobalAlphaFactoriSUN (GLint); -GLAPI void APIENTRY glGlobalAlphaFactorfSUN (GLfloat); -GLAPI void APIENTRY glGlobalAlphaFactordSUN (GLdouble); -GLAPI void APIENTRY glGlobalAlphaFactorubSUN (GLubyte); -GLAPI void APIENTRY glGlobalAlphaFactorusSUN (GLushort); -GLAPI void APIENTRY glGlobalAlphaFactoruiSUN (GLuint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor); -#endif - -#ifndef GL_SUN_triangle_list -#define GL_SUN_triangle_list 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glReplacementCodeuiSUN (GLuint); -GLAPI void APIENTRY glReplacementCodeusSUN (GLushort); -GLAPI void APIENTRY glReplacementCodeubSUN (GLubyte); -GLAPI void APIENTRY glReplacementCodeuivSUN (const GLuint *); -GLAPI void APIENTRY glReplacementCodeusvSUN (const GLushort *); -GLAPI void APIENTRY glReplacementCodeubvSUN (const GLubyte *); -GLAPI void APIENTRY glReplacementCodePointerSUN (GLenum, GLsizei, const GLvoid* *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint *code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort *code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte *code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const GLvoid* *pointer); -#endif - -#ifndef GL_SUN_vertex -#define GL_SUN_vertex 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColor4ubVertex2fSUN (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat); -GLAPI void APIENTRY glColor4ubVertex2fvSUN (const GLubyte *, const GLfloat *); -GLAPI void APIENTRY glColor4ubVertex3fSUN (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glColor4ubVertex3fvSUN (const GLubyte *, const GLfloat *); -GLAPI void APIENTRY glColor3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glColor3fVertex3fvSUN (const GLfloat *, const GLfloat *); -GLAPI void APIENTRY glNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *); -GLAPI void APIENTRY glColor4fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glColor4fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); -GLAPI void APIENTRY glTexCoord2fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glTexCoord2fVertex3fvSUN (const GLfloat *, const GLfloat *); -GLAPI void APIENTRY glTexCoord4fVertex4fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glTexCoord4fVertex4fvSUN (const GLfloat *, const GLfloat *); -GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fSUN (GLfloat, GLfloat, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fvSUN (const GLfloat *, const GLubyte *, const GLfloat *); -GLAPI void APIENTRY glTexCoord2fColor3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glTexCoord2fColor3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); -GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); -GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); -GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fvSUN (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); -GLAPI void APIENTRY glReplacementCodeuiVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glReplacementCodeuiVertex3fvSUN (const GLuint *, const GLfloat *); -GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fSUN (GLuint, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fvSUN (const GLuint *, const GLubyte *, const GLfloat *); -GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); -GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); -GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat *tc, const GLubyte *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint *rc, const GLubyte *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -#endif - -#ifndef GL_EXT_blend_func_separate -#define GL_EXT_blend_func_separate 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendFuncSeparateEXT (GLenum, GLenum, GLenum, GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -#endif - -#ifndef GL_INGR_blend_func_separate -#define GL_INGR_blend_func_separate 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendFuncSeparateINGR (GLenum, GLenum, GLenum, GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINGRPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -#endif - -#ifndef GL_INGR_color_clamp -#define GL_INGR_color_clamp 1 -#endif - -#ifndef GL_INGR_interlace_read -#define GL_INGR_interlace_read 1 -#endif - -#ifndef GL_EXT_stencil_wrap -#define GL_EXT_stencil_wrap 1 -#endif - -#ifndef GL_EXT_422_pixels -#define GL_EXT_422_pixels 1 -#endif - -#ifndef GL_NV_texgen_reflection -#define GL_NV_texgen_reflection 1 -#endif - -#ifndef GL_SUN_convolution_border_modes -#define GL_SUN_convolution_border_modes 1 -#endif - -#ifndef GL_EXT_texture_env_add -#define GL_EXT_texture_env_add 1 -#endif - -#ifndef GL_EXT_texture_lod_bias -#define GL_EXT_texture_lod_bias 1 -#endif - -#ifndef GL_EXT_texture_filter_anisotropic -#define GL_EXT_texture_filter_anisotropic 1 -#endif - -#ifndef GL_EXT_vertex_weighting -#define GL_EXT_vertex_weighting 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexWeightfEXT (GLfloat); -GLAPI void APIENTRY glVertexWeightfvEXT (const GLfloat *); -GLAPI void APIENTRY glVertexWeightPointerEXT (GLsizei, GLenum, GLsizei, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight); -typedef void (APIENTRYP PFNGLVERTEXWEIGHTFVEXTPROC) (const GLfloat *weight); -typedef void (APIENTRYP PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLsizei size, GLenum type, GLsizei stride, const GLvoid *pointer); -#endif - -#ifndef GL_NV_light_max_exponent -#define GL_NV_light_max_exponent 1 -#endif - -#ifndef GL_NV_vertex_array_range -#define GL_NV_vertex_array_range 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFlushVertexArrayRangeNV (void); -GLAPI void APIENTRY glVertexArrayRangeNV (GLsizei, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void); -typedef void (APIENTRYP PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, const GLvoid *pointer); -#endif - -#ifndef GL_NV_register_combiners -#define GL_NV_register_combiners 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCombinerParameterfvNV (GLenum, const GLfloat *); -GLAPI void APIENTRY glCombinerParameterfNV (GLenum, GLfloat); -GLAPI void APIENTRY glCombinerParameterivNV (GLenum, const GLint *); -GLAPI void APIENTRY glCombinerParameteriNV (GLenum, GLint); -GLAPI void APIENTRY glCombinerInputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum); -GLAPI void APIENTRY glCombinerOutputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLboolean, GLboolean, GLboolean); -GLAPI void APIENTRY glFinalCombinerInputNV (GLenum, GLenum, GLenum, GLenum); -GLAPI void APIENTRY glGetCombinerInputParameterfvNV (GLenum, GLenum, GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetCombinerInputParameterivNV (GLenum, GLenum, GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetCombinerOutputParameterfvNV (GLenum, GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetCombinerOutputParameterivNV (GLenum, GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetFinalCombinerInputParameterfvNV (GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetFinalCombinerInputParameterivNV (GLenum, GLenum, GLint *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); -typedef void (APIENTRYP PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); -typedef void (APIENTRYP PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); -typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint *params); -#endif - -#ifndef GL_NV_fog_distance -#define GL_NV_fog_distance 1 -#endif - -#ifndef GL_NV_texgen_emboss -#define GL_NV_texgen_emboss 1 -#endif - -#ifndef GL_NV_blend_square -#define GL_NV_blend_square 1 -#endif - -#ifndef GL_NV_texture_env_combine4 -#define GL_NV_texture_env_combine4 1 -#endif - -#ifndef GL_MESA_resize_buffers -#define GL_MESA_resize_buffers 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glResizeBuffersMESA (void); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLRESIZEBUFFERSMESAPROC) (void); -#endif - -#ifndef GL_MESA_window_pos -#define GL_MESA_window_pos 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glWindowPos2dMESA (GLdouble, GLdouble); -GLAPI void APIENTRY glWindowPos2dvMESA (const GLdouble *); -GLAPI void APIENTRY glWindowPos2fMESA (GLfloat, GLfloat); -GLAPI void APIENTRY glWindowPos2fvMESA (const GLfloat *); -GLAPI void APIENTRY glWindowPos2iMESA (GLint, GLint); -GLAPI void APIENTRY glWindowPos2ivMESA (const GLint *); -GLAPI void APIENTRY glWindowPos2sMESA (GLshort, GLshort); -GLAPI void APIENTRY glWindowPos2svMESA (const GLshort *); -GLAPI void APIENTRY glWindowPos3dMESA (GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glWindowPos3dvMESA (const GLdouble *); -GLAPI void APIENTRY glWindowPos3fMESA (GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glWindowPos3fvMESA (const GLfloat *); -GLAPI void APIENTRY glWindowPos3iMESA (GLint, GLint, GLint); -GLAPI void APIENTRY glWindowPos3ivMESA (const GLint *); -GLAPI void APIENTRY glWindowPos3sMESA (GLshort, GLshort, GLshort); -GLAPI void APIENTRY glWindowPos3svMESA (const GLshort *); -GLAPI void APIENTRY glWindowPos4dMESA (GLdouble, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glWindowPos4dvMESA (const GLdouble *); -GLAPI void APIENTRY glWindowPos4fMESA (GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glWindowPos4fvMESA (const GLfloat *); -GLAPI void APIENTRY glWindowPos4iMESA (GLint, GLint, GLint, GLint); -GLAPI void APIENTRY glWindowPos4ivMESA (const GLint *); -GLAPI void APIENTRY glWindowPos4sMESA (GLshort, GLshort, GLshort, GLshort); -GLAPI void APIENTRY glWindowPos4svMESA (const GLshort *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y); -typedef void (APIENTRYP PFNGLWINDOWPOS2IVMESAPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLWINDOWPOS2SVMESAPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLWINDOWPOS3IVMESAPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLWINDOWPOS3SVMESAPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLWINDOWPOS4IVMESAPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (APIENTRYP PFNGLWINDOWPOS4SVMESAPROC) (const GLshort *v); -#endif - -#ifndef GL_IBM_cull_vertex -#define GL_IBM_cull_vertex 1 -#endif - -#ifndef GL_IBM_multimode_draw_arrays -#define GL_IBM_multimode_draw_arrays 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMultiModeDrawArraysIBM (const GLenum *, const GLint *, const GLsizei *, GLsizei, GLint); -GLAPI void APIENTRY glMultiModeDrawElementsIBM (const GLenum *, const GLsizei *, GLenum, const GLvoid* const *, GLsizei, GLint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); -typedef void (APIENTRYP PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum *mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei primcount, GLint modestride); -#endif - -#ifndef GL_IBM_vertex_array_lists -#define GL_IBM_vertex_array_lists 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); -GLAPI void APIENTRY glSecondaryColorPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); -GLAPI void APIENTRY glEdgeFlagPointerListIBM (GLint, const GLboolean* *, GLint); -GLAPI void APIENTRY glFogCoordPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); -GLAPI void APIENTRY glIndexPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); -GLAPI void APIENTRY glNormalPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); -GLAPI void APIENTRY glTexCoordPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); -GLAPI void APIENTRY glVertexPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean* *pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); -#endif - -#ifndef GL_SGIX_subsample -#define GL_SGIX_subsample 1 -#endif - -#ifndef GL_SGIX_ycrcba -#define GL_SGIX_ycrcba 1 -#endif - -#ifndef GL_SGIX_ycrcb_subsample -#define GL_SGIX_ycrcb_subsample 1 -#endif - -#ifndef GL_SGIX_depth_pass_instrument -#define GL_SGIX_depth_pass_instrument 1 -#endif - -#ifndef GL_3DFX_texture_compression_FXT1 -#define GL_3DFX_texture_compression_FXT1 1 -#endif - -#ifndef GL_3DFX_multisample -#define GL_3DFX_multisample 1 -#endif - -#ifndef GL_3DFX_tbuffer -#define GL_3DFX_tbuffer 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTbufferMask3DFX (GLuint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTBUFFERMASK3DFXPROC) (GLuint mask); -#endif - -#ifndef GL_EXT_multisample -#define GL_EXT_multisample 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSampleMaskEXT (GLclampf, GLboolean); -GLAPI void APIENTRY glSamplePatternEXT (GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert); -typedef void (APIENTRYP PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern); -#endif - -#ifndef GL_SGIX_vertex_preclip -#define GL_SGIX_vertex_preclip 1 -#endif - -#ifndef GL_SGIX_convolution_accuracy -#define GL_SGIX_convolution_accuracy 1 -#endif - -#ifndef GL_SGIX_resample -#define GL_SGIX_resample 1 -#endif - -#ifndef GL_SGIS_point_line_texgen -#define GL_SGIS_point_line_texgen 1 -#endif - -#ifndef GL_SGIS_texture_color_mask -#define GL_SGIS_texture_color_mask 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTextureColorMaskSGIS (GLboolean, GLboolean, GLboolean, GLboolean); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXTURECOLORMASKSGISPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); -#endif - -#ifndef GL_SGIX_igloo_interface -#define GL_SGIX_igloo_interface 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glIglooInterfaceSGIX (GLenum, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLIGLOOINTERFACESGIXPROC) (GLenum pname, const GLvoid *params); -#endif - -#ifndef GL_EXT_texture_env_dot3 -#define GL_EXT_texture_env_dot3 1 -#endif - -#ifndef GL_ATI_texture_mirror_once -#define GL_ATI_texture_mirror_once 1 -#endif - -#ifndef GL_NV_fence -#define GL_NV_fence 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDeleteFencesNV (GLsizei, const GLuint *); -GLAPI void APIENTRY glGenFencesNV (GLsizei, GLuint *); -GLAPI GLboolean APIENTRY glIsFenceNV (GLuint); -GLAPI GLboolean APIENTRY glTestFenceNV (GLuint); -GLAPI void APIENTRY glGetFenceivNV (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glFinishFenceNV (GLuint); -GLAPI void APIENTRY glSetFenceNV (GLuint, GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences); -typedef void (APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences); -typedef GLboolean (APIENTRYP PFNGLISFENCENVPROC) (GLuint fence); -typedef GLboolean (APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence); -typedef void (APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence); -typedef void (APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); -#endif - -#ifndef GL_NV_evaluators -#define GL_NV_evaluators 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMapControlPointsNV (GLenum, GLuint, GLenum, GLsizei, GLsizei, GLint, GLint, GLboolean, const GLvoid *); -GLAPI void APIENTRY glMapParameterivNV (GLenum, GLenum, const GLint *); -GLAPI void APIENTRY glMapParameterfvNV (GLenum, GLenum, const GLfloat *); -GLAPI void APIENTRY glGetMapControlPointsNV (GLenum, GLuint, GLenum, GLsizei, GLsizei, GLboolean, GLvoid *); -GLAPI void APIENTRY glGetMapParameterivNV (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetMapParameterfvNV (GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetMapAttribParameterivNV (GLenum, GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetMapAttribParameterfvNV (GLenum, GLuint, GLenum, GLfloat *); -GLAPI void APIENTRY glEvalMapsNV (GLenum, GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const GLvoid *points); -typedef void (APIENTRYP PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, GLvoid *points); -typedef void (APIENTRYP PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode); -#endif - -#ifndef GL_NV_packed_depth_stencil -#define GL_NV_packed_depth_stencil 1 -#endif - -#ifndef GL_NV_register_combiners2 -#define GL_NV_register_combiners2 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCombinerStageParameterfvNV (GLenum, GLenum, const GLfloat *); -GLAPI void APIENTRY glGetCombinerStageParameterfvNV (GLenum, GLenum, GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat *params); -#endif - -#ifndef GL_NV_texture_compression_vtc -#define GL_NV_texture_compression_vtc 1 -#endif - -#ifndef GL_NV_texture_rectangle -#define GL_NV_texture_rectangle 1 -#endif - -#ifndef GL_NV_texture_shader -#define GL_NV_texture_shader 1 -#endif - -#ifndef GL_NV_texture_shader2 -#define GL_NV_texture_shader2 1 -#endif - -#ifndef GL_NV_vertex_array_range2 -#define GL_NV_vertex_array_range2 1 -#endif - -#ifndef GL_NV_vertex_program -#define GL_NV_vertex_program 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLboolean APIENTRY glAreProgramsResidentNV (GLsizei, const GLuint *, GLboolean *); -GLAPI void APIENTRY glBindProgramNV (GLenum, GLuint); -GLAPI void APIENTRY glDeleteProgramsNV (GLsizei, const GLuint *); -GLAPI void APIENTRY glExecuteProgramNV (GLenum, GLuint, const GLfloat *); -GLAPI void APIENTRY glGenProgramsNV (GLsizei, GLuint *); -GLAPI void APIENTRY glGetProgramParameterdvNV (GLenum, GLuint, GLenum, GLdouble *); -GLAPI void APIENTRY glGetProgramParameterfvNV (GLenum, GLuint, GLenum, GLfloat *); -GLAPI void APIENTRY glGetProgramivNV (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetProgramStringNV (GLuint, GLenum, GLubyte *); -GLAPI void APIENTRY glGetTrackMatrixivNV (GLenum, GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetVertexAttribdvNV (GLuint, GLenum, GLdouble *); -GLAPI void APIENTRY glGetVertexAttribfvNV (GLuint, GLenum, GLfloat *); -GLAPI void APIENTRY glGetVertexAttribivNV (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetVertexAttribPointervNV (GLuint, GLenum, GLvoid* *); -GLAPI GLboolean APIENTRY glIsProgramNV (GLuint); -GLAPI void APIENTRY glLoadProgramNV (GLenum, GLuint, GLsizei, const GLubyte *); -GLAPI void APIENTRY glProgramParameter4dNV (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glProgramParameter4dvNV (GLenum, GLuint, const GLdouble *); -GLAPI void APIENTRY glProgramParameter4fNV (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glProgramParameter4fvNV (GLenum, GLuint, const GLfloat *); -GLAPI void APIENTRY glProgramParameters4dvNV (GLenum, GLuint, GLuint, const GLdouble *); -GLAPI void APIENTRY glProgramParameters4fvNV (GLenum, GLuint, GLuint, const GLfloat *); -GLAPI void APIENTRY glRequestResidentProgramsNV (GLsizei, const GLuint *); -GLAPI void APIENTRY glTrackMatrixNV (GLenum, GLuint, GLenum, GLenum); -GLAPI void APIENTRY glVertexAttribPointerNV (GLuint, GLint, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glVertexAttrib1dNV (GLuint, GLdouble); -GLAPI void APIENTRY glVertexAttrib1dvNV (GLuint, const GLdouble *); -GLAPI void APIENTRY glVertexAttrib1fNV (GLuint, GLfloat); -GLAPI void APIENTRY glVertexAttrib1fvNV (GLuint, const GLfloat *); -GLAPI void APIENTRY glVertexAttrib1sNV (GLuint, GLshort); -GLAPI void APIENTRY glVertexAttrib1svNV (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttrib2dNV (GLuint, GLdouble, GLdouble); -GLAPI void APIENTRY glVertexAttrib2dvNV (GLuint, const GLdouble *); -GLAPI void APIENTRY glVertexAttrib2fNV (GLuint, GLfloat, GLfloat); -GLAPI void APIENTRY glVertexAttrib2fvNV (GLuint, const GLfloat *); -GLAPI void APIENTRY glVertexAttrib2sNV (GLuint, GLshort, GLshort); -GLAPI void APIENTRY glVertexAttrib2svNV (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttrib3dNV (GLuint, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glVertexAttrib3dvNV (GLuint, const GLdouble *); -GLAPI void APIENTRY glVertexAttrib3fNV (GLuint, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glVertexAttrib3fvNV (GLuint, const GLfloat *); -GLAPI void APIENTRY glVertexAttrib3sNV (GLuint, GLshort, GLshort, GLshort); -GLAPI void APIENTRY glVertexAttrib3svNV (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttrib4dNV (GLuint, GLdouble, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glVertexAttrib4dvNV (GLuint, const GLdouble *); -GLAPI void APIENTRY glVertexAttrib4fNV (GLuint, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glVertexAttrib4fvNV (GLuint, const GLfloat *); -GLAPI void APIENTRY glVertexAttrib4sNV (GLuint, GLshort, GLshort, GLshort, GLshort); -GLAPI void APIENTRY glVertexAttrib4svNV (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttrib4ubNV (GLuint, GLubyte, GLubyte, GLubyte, GLubyte); -GLAPI void APIENTRY glVertexAttrib4ubvNV (GLuint, const GLubyte *); -GLAPI void APIENTRY glVertexAttribs1dvNV (GLuint, GLsizei, const GLdouble *); -GLAPI void APIENTRY glVertexAttribs1fvNV (GLuint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glVertexAttribs1svNV (GLuint, GLsizei, const GLshort *); -GLAPI void APIENTRY glVertexAttribs2dvNV (GLuint, GLsizei, const GLdouble *); -GLAPI void APIENTRY glVertexAttribs2fvNV (GLuint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glVertexAttribs2svNV (GLuint, GLsizei, const GLshort *); -GLAPI void APIENTRY glVertexAttribs3dvNV (GLuint, GLsizei, const GLdouble *); -GLAPI void APIENTRY glVertexAttribs3fvNV (GLuint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glVertexAttribs3svNV (GLuint, GLsizei, const GLshort *); -GLAPI void APIENTRY glVertexAttribs4dvNV (GLuint, GLsizei, const GLdouble *); -GLAPI void APIENTRY glVertexAttribs4fvNV (GLuint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glVertexAttribs4svNV (GLuint, GLsizei, const GLshort *); -GLAPI void APIENTRY glVertexAttribs4ubvNV (GLuint, GLsizei, const GLubyte *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef GLboolean (APIENTRYP PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint *programs, GLboolean *residences); -typedef void (APIENTRYP PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id); -typedef void (APIENTRYP PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); -typedef void (APIENTRYP PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat *params); -typedef void (APIENTRYP PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint *programs); -typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte *program); -typedef void (APIENTRYP PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, GLvoid* *pointer); -typedef GLboolean (APIENTRYP PFNGLISPROGRAMNVPROC) (GLuint id); -typedef void (APIENTRYP PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte *program); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLuint count, const GLdouble *v); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLuint count, const GLfloat *v); -typedef void (APIENTRYP PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); -typedef void (APIENTRYP PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform); -typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei count, const GLubyte *v); -#endif - -#ifndef GL_SGIX_texture_coordinate_clamp -#define GL_SGIX_texture_coordinate_clamp 1 -#endif - -#ifndef GL_SGIX_scalebias_hint -#define GL_SGIX_scalebias_hint 1 -#endif - -#ifndef GL_OML_interlace -#define GL_OML_interlace 1 -#endif - -#ifndef GL_OML_subsample -#define GL_OML_subsample 1 -#endif - -#ifndef GL_OML_resample -#define GL_OML_resample 1 -#endif - -#ifndef GL_NV_copy_depth_to_color -#define GL_NV_copy_depth_to_color 1 -#endif - -#ifndef GL_ATI_envmap_bumpmap -#define GL_ATI_envmap_bumpmap 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexBumpParameterivATI (GLenum, const GLint *); -GLAPI void APIENTRY glTexBumpParameterfvATI (GLenum, const GLfloat *); -GLAPI void APIENTRY glGetTexBumpParameterivATI (GLenum, GLint *); -GLAPI void APIENTRY glGetTexBumpParameterfvATI (GLenum, GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, const GLint *param); -typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, const GLfloat *param); -typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); -typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); -#endif - -#ifndef GL_ATI_fragment_shader -#define GL_ATI_fragment_shader 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLuint APIENTRY glGenFragmentShadersATI (GLuint); -GLAPI void APIENTRY glBindFragmentShaderATI (GLuint); -GLAPI void APIENTRY glDeleteFragmentShaderATI (GLuint); -GLAPI void APIENTRY glBeginFragmentShaderATI (void); -GLAPI void APIENTRY glEndFragmentShaderATI (void); -GLAPI void APIENTRY glPassTexCoordATI (GLuint, GLuint, GLenum); -GLAPI void APIENTRY glSampleMapATI (GLuint, GLuint, GLenum); -GLAPI void APIENTRY glColorFragmentOp1ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glColorFragmentOp2ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glColorFragmentOp3ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glAlphaFragmentOp1ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glAlphaFragmentOp2ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glAlphaFragmentOp3ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glSetFragmentShaderConstantATI (GLuint, const GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef GLuint (APIENTRYP PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range); -typedef void (APIENTRYP PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id); -typedef void (APIENTRYP PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id); -typedef void (APIENTRYP PFNGLBEGINFRAGMENTSHADERATIPROC) (void); -typedef void (APIENTRYP PFNGLENDFRAGMENTSHADERATIPROC) (void); -typedef void (APIENTRYP PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle); -typedef void (APIENTRYP PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle); -typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); -typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); -typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); -typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); -typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); -typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); -typedef void (APIENTRYP PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat *value); -#endif - -#ifndef GL_ATI_pn_triangles -#define GL_ATI_pn_triangles 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPNTrianglesiATI (GLenum, GLint); -GLAPI void APIENTRY glPNTrianglesfATI (GLenum, GLfloat); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param); -#endif - -#ifndef GL_ATI_vertex_array_object -#define GL_ATI_vertex_array_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLuint APIENTRY glNewObjectBufferATI (GLsizei, const GLvoid *, GLenum); -GLAPI GLboolean APIENTRY glIsObjectBufferATI (GLuint); -GLAPI void APIENTRY glUpdateObjectBufferATI (GLuint, GLuint, GLsizei, const GLvoid *, GLenum); -GLAPI void APIENTRY glGetObjectBufferfvATI (GLuint, GLenum, GLfloat *); -GLAPI void APIENTRY glGetObjectBufferivATI (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glFreeObjectBufferATI (GLuint); -GLAPI void APIENTRY glArrayObjectATI (GLenum, GLint, GLenum, GLsizei, GLuint, GLuint); -GLAPI void APIENTRY glGetArrayObjectfvATI (GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetArrayObjectivATI (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glVariantArrayObjectATI (GLuint, GLenum, GLsizei, GLuint, GLuint); -GLAPI void APIENTRY glGetVariantArrayObjectfvATI (GLuint, GLenum, GLfloat *); -GLAPI void APIENTRY glGetVariantArrayObjectivATI (GLuint, GLenum, GLint *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef GLuint (APIENTRYP PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const GLvoid *pointer, GLenum usage); -typedef GLboolean (APIENTRYP PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const GLvoid *pointer, GLenum preserve); -typedef void (APIENTRYP PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); -typedef void (APIENTRYP PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); -typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint *params); -#endif - -#ifndef GL_EXT_vertex_shader -#define GL_EXT_vertex_shader 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBeginVertexShaderEXT (void); -GLAPI void APIENTRY glEndVertexShaderEXT (void); -GLAPI void APIENTRY glBindVertexShaderEXT (GLuint); -GLAPI GLuint APIENTRY glGenVertexShadersEXT (GLuint); -GLAPI void APIENTRY glDeleteVertexShaderEXT (GLuint); -GLAPI void APIENTRY glShaderOp1EXT (GLenum, GLuint, GLuint); -GLAPI void APIENTRY glShaderOp2EXT (GLenum, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glShaderOp3EXT (GLenum, GLuint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glSwizzleEXT (GLuint, GLuint, GLenum, GLenum, GLenum, GLenum); -GLAPI void APIENTRY glWriteMaskEXT (GLuint, GLuint, GLenum, GLenum, GLenum, GLenum); -GLAPI void APIENTRY glInsertComponentEXT (GLuint, GLuint, GLuint); -GLAPI void APIENTRY glExtractComponentEXT (GLuint, GLuint, GLuint); -GLAPI GLuint APIENTRY glGenSymbolsEXT (GLenum, GLenum, GLenum, GLuint); -GLAPI void APIENTRY glSetInvariantEXT (GLuint, GLenum, const GLvoid *); -GLAPI void APIENTRY glSetLocalConstantEXT (GLuint, GLenum, const GLvoid *); -GLAPI void APIENTRY glVariantbvEXT (GLuint, const GLbyte *); -GLAPI void APIENTRY glVariantsvEXT (GLuint, const GLshort *); -GLAPI void APIENTRY glVariantivEXT (GLuint, const GLint *); -GLAPI void APIENTRY glVariantfvEXT (GLuint, const GLfloat *); -GLAPI void APIENTRY glVariantdvEXT (GLuint, const GLdouble *); -GLAPI void APIENTRY glVariantubvEXT (GLuint, const GLubyte *); -GLAPI void APIENTRY glVariantusvEXT (GLuint, const GLushort *); -GLAPI void APIENTRY glVariantuivEXT (GLuint, const GLuint *); -GLAPI void APIENTRY glVariantPointerEXT (GLuint, GLenum, GLuint, const GLvoid *); -GLAPI void APIENTRY glEnableVariantClientStateEXT (GLuint); -GLAPI void APIENTRY glDisableVariantClientStateEXT (GLuint); -GLAPI GLuint APIENTRY glBindLightParameterEXT (GLenum, GLenum); -GLAPI GLuint APIENTRY glBindMaterialParameterEXT (GLenum, GLenum); -GLAPI GLuint APIENTRY glBindTexGenParameterEXT (GLenum, GLenum, GLenum); -GLAPI GLuint APIENTRY glBindTextureUnitParameterEXT (GLenum, GLenum); -GLAPI GLuint APIENTRY glBindParameterEXT (GLenum); -GLAPI GLboolean APIENTRY glIsVariantEnabledEXT (GLuint, GLenum); -GLAPI void APIENTRY glGetVariantBooleanvEXT (GLuint, GLenum, GLboolean *); -GLAPI void APIENTRY glGetVariantIntegervEXT (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetVariantFloatvEXT (GLuint, GLenum, GLfloat *); -GLAPI void APIENTRY glGetVariantPointervEXT (GLuint, GLenum, GLvoid* *); -GLAPI void APIENTRY glGetInvariantBooleanvEXT (GLuint, GLenum, GLboolean *); -GLAPI void APIENTRY glGetInvariantIntegervEXT (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetInvariantFloatvEXT (GLuint, GLenum, GLfloat *); -GLAPI void APIENTRY glGetLocalConstantBooleanvEXT (GLuint, GLenum, GLboolean *); -GLAPI void APIENTRY glGetLocalConstantIntegervEXT (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetLocalConstantFloatvEXT (GLuint, GLenum, GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBEGINVERTEXSHADEREXTPROC) (void); -typedef void (APIENTRYP PFNGLENDVERTEXSHADEREXTPROC) (void); -typedef void (APIENTRYP PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id); -typedef GLuint (APIENTRYP PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range); -typedef void (APIENTRYP PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id); -typedef void (APIENTRYP PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1); -typedef void (APIENTRYP PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2); -typedef void (APIENTRYP PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); -typedef void (APIENTRYP PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); -typedef void (APIENTRYP PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); -typedef void (APIENTRYP PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); -typedef void (APIENTRYP PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); -typedef GLuint (APIENTRYP PFNGLGENSYMBOLSEXTPROC) (GLenum datatype, GLenum storagetype, GLenum range, GLuint components); -typedef void (APIENTRYP PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr); -typedef void (APIENTRYP PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr); -typedef void (APIENTRYP PFNGLVARIANTBVEXTPROC) (GLuint id, const GLbyte *addr); -typedef void (APIENTRYP PFNGLVARIANTSVEXTPROC) (GLuint id, const GLshort *addr); -typedef void (APIENTRYP PFNGLVARIANTIVEXTPROC) (GLuint id, const GLint *addr); -typedef void (APIENTRYP PFNGLVARIANTFVEXTPROC) (GLuint id, const GLfloat *addr); -typedef void (APIENTRYP PFNGLVARIANTDVEXTPROC) (GLuint id, const GLdouble *addr); -typedef void (APIENTRYP PFNGLVARIANTUBVEXTPROC) (GLuint id, const GLubyte *addr); -typedef void (APIENTRYP PFNGLVARIANTUSVEXTPROC) (GLuint id, const GLushort *addr); -typedef void (APIENTRYP PFNGLVARIANTUIVEXTPROC) (GLuint id, const GLuint *addr); -typedef void (APIENTRYP PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, const GLvoid *addr); -typedef void (APIENTRYP PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); -typedef void (APIENTRYP PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); -typedef GLuint (APIENTRYP PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value); -typedef GLuint (APIENTRYP PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value); -typedef GLuint (APIENTRYP PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value); -typedef GLuint (APIENTRYP PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value); -typedef GLuint (APIENTRYP PFNGLBINDPARAMETEREXTPROC) (GLenum value); -typedef GLboolean (APIENTRYP PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap); -typedef void (APIENTRYP PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); -typedef void (APIENTRYP PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); -typedef void (APIENTRYP PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); -typedef void (APIENTRYP PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, GLvoid* *data); -typedef void (APIENTRYP PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); -typedef void (APIENTRYP PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); -typedef void (APIENTRYP PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); -typedef void (APIENTRYP PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); -typedef void (APIENTRYP PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); -typedef void (APIENTRYP PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); -#endif - -#ifndef GL_ATI_vertex_streams -#define GL_ATI_vertex_streams 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexStream1sATI (GLenum, GLshort); -GLAPI void APIENTRY glVertexStream1svATI (GLenum, const GLshort *); -GLAPI void APIENTRY glVertexStream1iATI (GLenum, GLint); -GLAPI void APIENTRY glVertexStream1ivATI (GLenum, const GLint *); -GLAPI void APIENTRY glVertexStream1fATI (GLenum, GLfloat); -GLAPI void APIENTRY glVertexStream1fvATI (GLenum, const GLfloat *); -GLAPI void APIENTRY glVertexStream1dATI (GLenum, GLdouble); -GLAPI void APIENTRY glVertexStream1dvATI (GLenum, const GLdouble *); -GLAPI void APIENTRY glVertexStream2sATI (GLenum, GLshort, GLshort); -GLAPI void APIENTRY glVertexStream2svATI (GLenum, const GLshort *); -GLAPI void APIENTRY glVertexStream2iATI (GLenum, GLint, GLint); -GLAPI void APIENTRY glVertexStream2ivATI (GLenum, const GLint *); -GLAPI void APIENTRY glVertexStream2fATI (GLenum, GLfloat, GLfloat); -GLAPI void APIENTRY glVertexStream2fvATI (GLenum, const GLfloat *); -GLAPI void APIENTRY glVertexStream2dATI (GLenum, GLdouble, GLdouble); -GLAPI void APIENTRY glVertexStream2dvATI (GLenum, const GLdouble *); -GLAPI void APIENTRY glVertexStream3sATI (GLenum, GLshort, GLshort, GLshort); -GLAPI void APIENTRY glVertexStream3svATI (GLenum, const GLshort *); -GLAPI void APIENTRY glVertexStream3iATI (GLenum, GLint, GLint, GLint); -GLAPI void APIENTRY glVertexStream3ivATI (GLenum, const GLint *); -GLAPI void APIENTRY glVertexStream3fATI (GLenum, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glVertexStream3fvATI (GLenum, const GLfloat *); -GLAPI void APIENTRY glVertexStream3dATI (GLenum, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glVertexStream3dvATI (GLenum, const GLdouble *); -GLAPI void APIENTRY glVertexStream4sATI (GLenum, GLshort, GLshort, GLshort, GLshort); -GLAPI void APIENTRY glVertexStream4svATI (GLenum, const GLshort *); -GLAPI void APIENTRY glVertexStream4iATI (GLenum, GLint, GLint, GLint, GLint); -GLAPI void APIENTRY glVertexStream4ivATI (GLenum, const GLint *); -GLAPI void APIENTRY glVertexStream4fATI (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glVertexStream4fvATI (GLenum, const GLfloat *); -GLAPI void APIENTRY glVertexStream4dATI (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glVertexStream4dvATI (GLenum, const GLdouble *); -GLAPI void APIENTRY glNormalStream3bATI (GLenum, GLbyte, GLbyte, GLbyte); -GLAPI void APIENTRY glNormalStream3bvATI (GLenum, const GLbyte *); -GLAPI void APIENTRY glNormalStream3sATI (GLenum, GLshort, GLshort, GLshort); -GLAPI void APIENTRY glNormalStream3svATI (GLenum, const GLshort *); -GLAPI void APIENTRY glNormalStream3iATI (GLenum, GLint, GLint, GLint); -GLAPI void APIENTRY glNormalStream3ivATI (GLenum, const GLint *); -GLAPI void APIENTRY glNormalStream3fATI (GLenum, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glNormalStream3fvATI (GLenum, const GLfloat *); -GLAPI void APIENTRY glNormalStream3dATI (GLenum, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glNormalStream3dvATI (GLenum, const GLdouble *); -GLAPI void APIENTRY glClientActiveVertexStreamATI (GLenum); -GLAPI void APIENTRY glVertexBlendEnviATI (GLenum, GLint); -GLAPI void APIENTRY glVertexBlendEnvfATI (GLenum, GLfloat); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEXSTREAM1SATIPROC) (GLenum stream, GLshort x); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1SVATIPROC) (GLenum stream, const GLshort *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1IATIPROC) (GLenum stream, GLint x); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1FATIPROC) (GLenum stream, GLfloat x); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1DATIPROC) (GLenum stream, GLdouble x); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (APIENTRYP PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz); -typedef void (APIENTRYP PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *coords); -typedef void (APIENTRYP PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort nx, GLshort ny, GLshort nz); -typedef void (APIENTRYP PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); -typedef void (APIENTRYP PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint nx, GLint ny, GLint nz); -typedef void (APIENTRYP PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (APIENTRYP PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz); -typedef void (APIENTRYP PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (APIENTRYP PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz); -typedef void (APIENTRYP PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (APIENTRYP PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream); -typedef void (APIENTRYP PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param); -#endif - -#ifndef GL_ATI_element_array -#define GL_ATI_element_array 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glElementPointerATI (GLenum, const GLvoid *); -GLAPI void APIENTRY glDrawElementArrayATI (GLenum, GLsizei); -GLAPI void APIENTRY glDrawRangeElementArrayATI (GLenum, GLuint, GLuint, GLsizei); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLELEMENTPOINTERATIPROC) (GLenum type, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count); -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count); -#endif - -#ifndef GL_SUN_mesh_array -#define GL_SUN_mesh_array 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawMeshArraysSUN (GLenum, GLint, GLsizei, GLsizei); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDRAWMESHARRAYSSUNPROC) (GLenum mode, GLint first, GLsizei count, GLsizei width); -#endif - -#ifndef GL_SUN_slice_accum -#define GL_SUN_slice_accum 1 -#endif - -#ifndef GL_NV_multisample_filter_hint -#define GL_NV_multisample_filter_hint 1 -#endif - -#ifndef GL_NV_depth_clamp -#define GL_NV_depth_clamp 1 -#endif - -#ifndef GL_NV_occlusion_query -#define GL_NV_occlusion_query 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGenOcclusionQueriesNV (GLsizei, GLuint *); -GLAPI void APIENTRY glDeleteOcclusionQueriesNV (GLsizei, const GLuint *); -GLAPI GLboolean APIENTRY glIsOcclusionQueryNV (GLuint); -GLAPI void APIENTRY glBeginOcclusionQueryNV (GLuint); -GLAPI void APIENTRY glEndOcclusionQueryNV (void); -GLAPI void APIENTRY glGetOcclusionQueryivNV (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetOcclusionQueryuivNV (GLuint, GLenum, GLuint *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint *ids); -typedef void (APIENTRYP PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint *ids); -typedef GLboolean (APIENTRYP PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id); -typedef void (APIENTRYP PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id); -typedef void (APIENTRYP PFNGLENDOCCLUSIONQUERYNVPROC) (void); -typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint *params); -#endif - -#ifndef GL_NV_point_sprite -#define GL_NV_point_sprite 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPointParameteriNV (GLenum, GLint); -GLAPI void APIENTRY glPointParameterivNV (GLenum, const GLint *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint *params); -#endif - -#ifndef GL_NV_texture_shader3 -#define GL_NV_texture_shader3 1 -#endif - -#ifndef GL_NV_vertex_program1_1 -#define GL_NV_vertex_program1_1 1 -#endif - -#ifndef GL_EXT_shadow_funcs -#define GL_EXT_shadow_funcs 1 -#endif - -#ifndef GL_EXT_stencil_two_side -#define GL_EXT_stencil_two_side 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glActiveStencilFaceEXT (GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face); -#endif - -#ifndef GL_ATI_text_fragment_shader -#define GL_ATI_text_fragment_shader 1 -#endif - -#ifndef GL_APPLE_client_storage -#define GL_APPLE_client_storage 1 -#endif - -#ifndef GL_APPLE_element_array -#define GL_APPLE_element_array 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glElementPointerAPPLE (GLenum, const GLvoid *); -GLAPI void APIENTRY glDrawElementArrayAPPLE (GLenum, GLint, GLsizei); -GLAPI void APIENTRY glDrawRangeElementArrayAPPLE (GLenum, GLuint, GLuint, GLint, GLsizei); -GLAPI void APIENTRY glMultiDrawElementArrayAPPLE (GLenum, const GLint *, const GLsizei *, GLsizei); -GLAPI void APIENTRY glMultiDrawRangeElementArrayAPPLE (GLenum, GLuint, GLuint, const GLint *, const GLsizei *, GLsizei); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count); -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); -typedef void (APIENTRYP PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount); -#endif - -#ifndef GL_APPLE_fence -#define GL_APPLE_fence 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGenFencesAPPLE (GLsizei, GLuint *); -GLAPI void APIENTRY glDeleteFencesAPPLE (GLsizei, const GLuint *); -GLAPI void APIENTRY glSetFenceAPPLE (GLuint); -GLAPI GLboolean APIENTRY glIsFenceAPPLE (GLuint); -GLAPI GLboolean APIENTRY glTestFenceAPPLE (GLuint); -GLAPI void APIENTRY glFinishFenceAPPLE (GLuint); -GLAPI GLboolean APIENTRY glTestObjectAPPLE (GLenum, GLuint); -GLAPI void APIENTRY glFinishObjectAPPLE (GLenum, GLint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint *fences); -typedef void (APIENTRYP PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint *fences); -typedef void (APIENTRYP PFNGLSETFENCEAPPLEPROC) (GLuint fence); -typedef GLboolean (APIENTRYP PFNGLISFENCEAPPLEPROC) (GLuint fence); -typedef GLboolean (APIENTRYP PFNGLTESTFENCEAPPLEPROC) (GLuint fence); -typedef void (APIENTRYP PFNGLFINISHFENCEAPPLEPROC) (GLuint fence); -typedef GLboolean (APIENTRYP PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name); -typedef void (APIENTRYP PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name); -#endif - -#ifndef GL_APPLE_vertex_array_object -#define GL_APPLE_vertex_array_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBindVertexArrayAPPLE (GLuint); -GLAPI void APIENTRY glDeleteVertexArraysAPPLE (GLsizei, const GLuint *); -GLAPI void APIENTRY glGenVertexArraysAPPLE (GLsizei, GLuint *); -GLAPI GLboolean APIENTRY glIsVertexArrayAPPLE (GLuint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array); -typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint *arrays); -typedef void (APIENTRYP PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, GLuint *arrays); -typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array); -#endif - -#ifndef GL_APPLE_vertex_array_range -#define GL_APPLE_vertex_array_range 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexArrayRangeAPPLE (GLsizei, GLvoid *); -GLAPI void APIENTRY glFlushVertexArrayRangeAPPLE (GLsizei, GLvoid *); -GLAPI void APIENTRY glVertexArrayParameteriAPPLE (GLenum, GLint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer); -typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer); -typedef void (APIENTRYP PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param); -#endif - -#ifndef GL_APPLE_ycbcr_422 -#define GL_APPLE_ycbcr_422 1 -#endif - -#ifndef GL_S3_s3tc -#define GL_S3_s3tc 1 -#endif - -#ifndef GL_ATI_draw_buffers -#define GL_ATI_draw_buffers 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawBuffersATI (GLsizei, const GLenum *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum *bufs); -#endif - -#ifndef GL_ATI_pixel_format_float -#define GL_ATI_pixel_format_float 1 -/* This is really a WGL extension, but defines some associated GL enums. - * ATI does not export "GL_ATI_pixel_format_float" in the GL_EXTENSIONS string. - */ -#endif - -#ifndef GL_ATI_texture_env_combine3 -#define GL_ATI_texture_env_combine3 1 -#endif - -#ifndef GL_ATI_texture_float -#define GL_ATI_texture_float 1 -#endif - -#ifndef GL_NV_float_buffer -#define GL_NV_float_buffer 1 -#endif - -#ifndef GL_NV_fragment_program -#define GL_NV_fragment_program 1 -/* Some NV_fragment_program entry points are shared with ARB_vertex_program. */ -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramNamedParameter4fNV (GLuint, GLsizei, const GLubyte *, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glProgramNamedParameter4dNV (GLuint, GLsizei, const GLubyte *, GLdouble, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glProgramNamedParameter4fvNV (GLuint, GLsizei, const GLubyte *, const GLfloat *); -GLAPI void APIENTRY glProgramNamedParameter4dvNV (GLuint, GLsizei, const GLubyte *, const GLdouble *); -GLAPI void APIENTRY glGetProgramNamedParameterfvNV (GLuint, GLsizei, const GLubyte *, GLfloat *); -GLAPI void APIENTRY glGetProgramNamedParameterdvNV (GLuint, GLsizei, const GLubyte *, GLdouble *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v); -typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v); -typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params); -typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params); -#endif - -#ifndef GL_NV_half_float -#define GL_NV_half_float 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertex2hNV (GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glVertex2hvNV (const GLhalfNV *); -GLAPI void APIENTRY glVertex3hNV (GLhalfNV, GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glVertex3hvNV (const GLhalfNV *); -GLAPI void APIENTRY glVertex4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glVertex4hvNV (const GLhalfNV *); -GLAPI void APIENTRY glNormal3hNV (GLhalfNV, GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glNormal3hvNV (const GLhalfNV *); -GLAPI void APIENTRY glColor3hNV (GLhalfNV, GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glColor3hvNV (const GLhalfNV *); -GLAPI void APIENTRY glColor4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glColor4hvNV (const GLhalfNV *); -GLAPI void APIENTRY glTexCoord1hNV (GLhalfNV); -GLAPI void APIENTRY glTexCoord1hvNV (const GLhalfNV *); -GLAPI void APIENTRY glTexCoord2hNV (GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glTexCoord2hvNV (const GLhalfNV *); -GLAPI void APIENTRY glTexCoord3hNV (GLhalfNV, GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glTexCoord3hvNV (const GLhalfNV *); -GLAPI void APIENTRY glTexCoord4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glTexCoord4hvNV (const GLhalfNV *); -GLAPI void APIENTRY glMultiTexCoord1hNV (GLenum, GLhalfNV); -GLAPI void APIENTRY glMultiTexCoord1hvNV (GLenum, const GLhalfNV *); -GLAPI void APIENTRY glMultiTexCoord2hNV (GLenum, GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glMultiTexCoord2hvNV (GLenum, const GLhalfNV *); -GLAPI void APIENTRY glMultiTexCoord3hNV (GLenum, GLhalfNV, GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glMultiTexCoord3hvNV (GLenum, const GLhalfNV *); -GLAPI void APIENTRY glMultiTexCoord4hNV (GLenum, GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glMultiTexCoord4hvNV (GLenum, const GLhalfNV *); -GLAPI void APIENTRY glFogCoordhNV (GLhalfNV); -GLAPI void APIENTRY glFogCoordhvNV (const GLhalfNV *); -GLAPI void APIENTRY glSecondaryColor3hNV (GLhalfNV, GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glSecondaryColor3hvNV (const GLhalfNV *); -GLAPI void APIENTRY glVertexWeighthNV (GLhalfNV); -GLAPI void APIENTRY glVertexWeighthvNV (const GLhalfNV *); -GLAPI void APIENTRY glVertexAttrib1hNV (GLuint, GLhalfNV); -GLAPI void APIENTRY glVertexAttrib1hvNV (GLuint, const GLhalfNV *); -GLAPI void APIENTRY glVertexAttrib2hNV (GLuint, GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glVertexAttrib2hvNV (GLuint, const GLhalfNV *); -GLAPI void APIENTRY glVertexAttrib3hNV (GLuint, GLhalfNV, GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glVertexAttrib3hvNV (GLuint, const GLhalfNV *); -GLAPI void APIENTRY glVertexAttrib4hNV (GLuint, GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glVertexAttrib4hvNV (GLuint, const GLhalfNV *); -GLAPI void APIENTRY glVertexAttribs1hvNV (GLuint, GLsizei, const GLhalfNV *); -GLAPI void APIENTRY glVertexAttribs2hvNV (GLuint, GLsizei, const GLhalfNV *); -GLAPI void APIENTRY glVertexAttribs3hvNV (GLuint, GLsizei, const GLhalfNV *); -GLAPI void APIENTRY glVertexAttribs4hvNV (GLuint, GLsizei, const GLhalfNV *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEX2HNVPROC) (GLhalfNV x, GLhalfNV y); -typedef void (APIENTRYP PFNGLVERTEX2HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEX3HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z); -typedef void (APIENTRYP PFNGLVERTEX3HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEX4HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); -typedef void (APIENTRYP PFNGLVERTEX4HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLNORMAL3HNVPROC) (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz); -typedef void (APIENTRYP PFNGLNORMAL3HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); -typedef void (APIENTRYP PFNGLCOLOR3HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLCOLOR4HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha); -typedef void (APIENTRYP PFNGLCOLOR4HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLTEXCOORD1HNVPROC) (GLhalfNV s); -typedef void (APIENTRYP PFNGLTEXCOORD1HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLTEXCOORD2HNVPROC) (GLhalfNV s, GLhalfNV t); -typedef void (APIENTRYP PFNGLTEXCOORD2HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLTEXCOORD3HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r); -typedef void (APIENTRYP PFNGLTEXCOORD3HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLTEXCOORD4HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); -typedef void (APIENTRYP PFNGLTEXCOORD4HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalfNV s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLFOGCOORDHNVPROC) (GLhalfNV fog); -typedef void (APIENTRYP PFNGLFOGCOORDHVNVPROC) (const GLhalfNV *fog); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXWEIGHTHNVPROC) (GLhalfNV weight); -typedef void (APIENTRYP PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalfNV *weight); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalfNV x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); -#endif - -#ifndef GL_NV_pixel_data_range -#define GL_NV_pixel_data_range 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPixelDataRangeNV (GLenum, GLsizei, GLvoid *); -GLAPI void APIENTRY glFlushPixelDataRangeNV (GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, GLvoid *pointer); -typedef void (APIENTRYP PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); -#endif - -#ifndef GL_NV_primitive_restart -#define GL_NV_primitive_restart 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPrimitiveRestartNV (void); -GLAPI void APIENTRY glPrimitiveRestartIndexNV (GLuint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPRIMITIVERESTARTNVPROC) (void); -typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index); -#endif - -#ifndef GL_NV_texture_expand_normal -#define GL_NV_texture_expand_normal 1 -#endif - -#ifndef GL_NV_vertex_program2 -#define GL_NV_vertex_program2 1 -#endif - -#ifndef GL_ATI_map_object_buffer -#define GL_ATI_map_object_buffer 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLvoid* APIENTRY glMapObjectBufferATI (GLuint); -GLAPI void APIENTRY glUnmapObjectBufferATI (GLuint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef GLvoid* (APIENTRYP PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer); -#endif - -#ifndef GL_ATI_separate_stencil -#define GL_ATI_separate_stencil 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glStencilOpSeparateATI (GLenum, GLenum, GLenum, GLenum); -GLAPI void APIENTRY glStencilFuncSeparateATI (GLenum, GLenum, GLint, GLuint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); -typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); -#endif - -#ifndef GL_ATI_vertex_attrib_array_object -#define GL_ATI_vertex_attrib_array_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttribArrayObjectATI (GLuint, GLint, GLenum, GLboolean, GLsizei, GLuint, GLuint); -GLAPI void APIENTRY glGetVertexAttribArrayObjectfvATI (GLuint, GLenum, GLfloat *); -GLAPI void APIENTRY glGetVertexAttribArrayObjectivATI (GLuint, GLenum, GLint *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint *params); -#endif - -#ifndef GL_OES_read_format -#define GL_OES_read_format 1 -#endif - -#ifndef GL_EXT_depth_bounds_test -#define GL_EXT_depth_bounds_test 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDepthBoundsEXT (GLclampd, GLclampd); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax); -#endif - -#ifndef GL_EXT_texture_mirror_clamp -#define GL_EXT_texture_mirror_clamp 1 -#endif - -#ifndef GL_EXT_blend_equation_separate -#define GL_EXT_blend_equation_separate 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendEquationSeparateEXT (GLenum, GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha); -#endif - -#ifndef GL_MESA_pack_invert -#define GL_MESA_pack_invert 1 -#endif - -#ifndef GL_MESA_ycbcr_texture -#define GL_MESA_ycbcr_texture 1 -#endif - -#ifndef GL_EXT_pixel_buffer_object -#define GL_EXT_pixel_buffer_object 1 -#endif - -#ifndef GL_NV_fragment_program_option -#define GL_NV_fragment_program_option 1 -#endif - -#ifndef GL_NV_fragment_program2 -#define GL_NV_fragment_program2 1 -#endif - -#ifndef GL_NV_vertex_program2_option -#define GL_NV_vertex_program2_option 1 -#endif - -#ifndef GL_NV_vertex_program3 -#define GL_NV_vertex_program3 1 -#endif - -#ifndef GL_EXT_framebuffer_object -#define GL_EXT_framebuffer_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLboolean APIENTRY glIsRenderbufferEXT (GLuint); -GLAPI void APIENTRY glBindRenderbufferEXT (GLenum, GLuint); -GLAPI void APIENTRY glDeleteRenderbuffersEXT (GLsizei, const GLuint *); -GLAPI void APIENTRY glGenRenderbuffersEXT (GLsizei, GLuint *); -GLAPI void APIENTRY glRenderbufferStorageEXT (GLenum, GLenum, GLsizei, GLsizei); -GLAPI void APIENTRY glGetRenderbufferParameterivEXT (GLenum, GLenum, GLint *); -GLAPI GLboolean APIENTRY glIsFramebufferEXT (GLuint); -GLAPI void APIENTRY glBindFramebufferEXT (GLenum, GLuint); -GLAPI void APIENTRY glDeleteFramebuffersEXT (GLsizei, const GLuint *); -GLAPI void APIENTRY glGenFramebuffersEXT (GLsizei, GLuint *); -GLAPI GLenum APIENTRY glCheckFramebufferStatusEXT (GLenum); -GLAPI void APIENTRY glFramebufferTexture1DEXT (GLenum, GLenum, GLenum, GLuint, GLint); -GLAPI void APIENTRY glFramebufferTexture2DEXT (GLenum, GLenum, GLenum, GLuint, GLint); -GLAPI void APIENTRY glFramebufferTexture3DEXT (GLenum, GLenum, GLenum, GLuint, GLint, GLint); -GLAPI void APIENTRY glFramebufferRenderbufferEXT (GLenum, GLenum, GLenum, GLuint); -GLAPI void APIENTRY glGetFramebufferAttachmentParameterivEXT (GLenum, GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGenerateMipmapEXT (GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer); -typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers); -typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers); -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer); -typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer); -typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers); -typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers); -typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGENERATEMIPMAPEXTPROC) (GLenum target); -#endif - -#ifndef GL_GREMEDY_string_marker -#define GL_GREMEDY_string_marker 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glStringMarkerGREMEDY (GLsizei, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const GLvoid *string); -#endif - -#ifndef GL_EXT_packed_depth_stencil -#define GL_EXT_packed_depth_stencil 1 -#endif - -#ifndef GL_EXT_stencil_clear_tag -#define GL_EXT_stencil_clear_tag 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glStencilClearTagEXT (GLsizei, GLuint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLSTENCILCLEARTAGEXTPROC) (GLsizei stencilTagBits, GLuint stencilClearTag); -#endif - -#ifndef GL_EXT_texture_sRGB -#define GL_EXT_texture_sRGB 1 -#endif - -#ifndef GL_EXT_framebuffer_blit -#define GL_EXT_framebuffer_blit 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlitFramebufferEXT (GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -#endif - -#ifndef GL_EXT_framebuffer_multisample -#define GL_EXT_framebuffer_multisample 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glRenderbufferStorageMultisampleEXT (GLenum, GLsizei, GLenum, GLsizei, GLsizei); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -#endif - -#ifndef GL_MESAX_texture_stack -#define GL_MESAX_texture_stack 1 -#endif - -#ifndef GL_EXT_timer_query -#define GL_EXT_timer_query 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetQueryObjecti64vEXT (GLuint, GLenum, GLint64EXT *); -GLAPI void APIENTRY glGetQueryObjectui64vEXT (GLuint, GLenum, GLuint64EXT *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64EXT *params); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64EXT *params); -#endif - -#ifndef GL_EXT_gpu_program_parameters -#define GL_EXT_gpu_program_parameters 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramEnvParameters4fvEXT (GLenum, GLuint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glProgramLocalParameters4fvEXT (GLenum, GLuint, GLsizei, const GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params); -#endif - -#ifndef GL_APPLE_flush_buffer_range -#define GL_APPLE_flush_buffer_range 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBufferParameteriAPPLE (GLenum, GLenum, GLint); -GLAPI void APIENTRY glFlushMappedBufferRangeAPPLE (GLenum, GLintptr, GLsizeiptr); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBUFFERPARAMETERIAPPLEPROC) (GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) (GLenum target, GLintptr offset, GLsizeiptr size); -#endif - -#ifndef GL_NV_gpu_program4 -#define GL_NV_gpu_program4 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramLocalParameterI4iNV (GLenum, GLuint, GLint, GLint, GLint, GLint); -GLAPI void APIENTRY glProgramLocalParameterI4ivNV (GLenum, GLuint, const GLint *); -GLAPI void APIENTRY glProgramLocalParametersI4ivNV (GLenum, GLuint, GLsizei, const GLint *); -GLAPI void APIENTRY glProgramLocalParameterI4uiNV (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glProgramLocalParameterI4uivNV (GLenum, GLuint, const GLuint *); -GLAPI void APIENTRY glProgramLocalParametersI4uivNV (GLenum, GLuint, GLsizei, const GLuint *); -GLAPI void APIENTRY glProgramEnvParameterI4iNV (GLenum, GLuint, GLint, GLint, GLint, GLint); -GLAPI void APIENTRY glProgramEnvParameterI4ivNV (GLenum, GLuint, const GLint *); -GLAPI void APIENTRY glProgramEnvParametersI4ivNV (GLenum, GLuint, GLsizei, const GLint *); -GLAPI void APIENTRY glProgramEnvParameterI4uiNV (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glProgramEnvParameterI4uivNV (GLenum, GLuint, const GLuint *); -GLAPI void APIENTRY glProgramEnvParametersI4uivNV (GLenum, GLuint, GLsizei, const GLuint *); -GLAPI void APIENTRY glGetProgramLocalParameterIivNV (GLenum, GLuint, GLint *); -GLAPI void APIENTRY glGetProgramLocalParameterIuivNV (GLenum, GLuint, GLuint *); -GLAPI void APIENTRY glGetProgramEnvParameterIivNV (GLenum, GLuint, GLint *); -GLAPI void APIENTRY glGetProgramEnvParameterIuivNV (GLenum, GLuint, GLuint *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params); -#endif - -#ifndef GL_NV_geometry_program4 -#define GL_NV_geometry_program4 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramVertexLimitNV (GLenum, GLint); -GLAPI void APIENTRY glFramebufferTextureEXT (GLenum, GLenum, GLuint, GLint); -GLAPI void APIENTRY glFramebufferTextureLayerEXT (GLenum, GLenum, GLuint, GLint, GLint); -GLAPI void APIENTRY glFramebufferTextureFaceEXT (GLenum, GLenum, GLuint, GLint, GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); -#endif - -#ifndef GL_EXT_geometry_shader4 -#define GL_EXT_geometry_shader4 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramParameteriEXT (GLuint, GLenum, GLint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); -#endif - -#ifndef GL_NV_vertex_program4 -#define GL_NV_vertex_program4 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttribI1iEXT (GLuint, GLint); -GLAPI void APIENTRY glVertexAttribI2iEXT (GLuint, GLint, GLint); -GLAPI void APIENTRY glVertexAttribI3iEXT (GLuint, GLint, GLint, GLint); -GLAPI void APIENTRY glVertexAttribI4iEXT (GLuint, GLint, GLint, GLint, GLint); -GLAPI void APIENTRY glVertexAttribI1uiEXT (GLuint, GLuint); -GLAPI void APIENTRY glVertexAttribI2uiEXT (GLuint, GLuint, GLuint); -GLAPI void APIENTRY glVertexAttribI3uiEXT (GLuint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glVertexAttribI4uiEXT (GLuint, GLuint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glVertexAttribI1ivEXT (GLuint, const GLint *); -GLAPI void APIENTRY glVertexAttribI2ivEXT (GLuint, const GLint *); -GLAPI void APIENTRY glVertexAttribI3ivEXT (GLuint, const GLint *); -GLAPI void APIENTRY glVertexAttribI4ivEXT (GLuint, const GLint *); -GLAPI void APIENTRY glVertexAttribI1uivEXT (GLuint, const GLuint *); -GLAPI void APIENTRY glVertexAttribI2uivEXT (GLuint, const GLuint *); -GLAPI void APIENTRY glVertexAttribI3uivEXT (GLuint, const GLuint *); -GLAPI void APIENTRY glVertexAttribI4uivEXT (GLuint, const GLuint *); -GLAPI void APIENTRY glVertexAttribI4bvEXT (GLuint, const GLbyte *); -GLAPI void APIENTRY glVertexAttribI4svEXT (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttribI4ubvEXT (GLuint, const GLubyte *); -GLAPI void APIENTRY glVertexAttribI4usvEXT (GLuint, const GLushort *); -GLAPI void APIENTRY glVertexAttribIPointerEXT (GLuint, GLint, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glGetVertexAttribIivEXT (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetVertexAttribIuivEXT (GLuint, GLenum, GLuint *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params); -#endif - -#ifndef GL_EXT_gpu_shader4 -#define GL_EXT_gpu_shader4 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetUniformuivEXT (GLuint, GLint, GLuint *); -GLAPI void APIENTRY glBindFragDataLocationEXT (GLuint, GLuint, const GLchar *); -GLAPI GLint APIENTRY glGetFragDataLocationEXT (GLuint, const GLchar *); -GLAPI void APIENTRY glUniform1uiEXT (GLint, GLuint); -GLAPI void APIENTRY glUniform2uiEXT (GLint, GLuint, GLuint); -GLAPI void APIENTRY glUniform3uiEXT (GLint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glUniform4uiEXT (GLint, GLuint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glUniform1uivEXT (GLint, GLsizei, const GLuint *); -GLAPI void APIENTRY glUniform2uivEXT (GLint, GLsizei, const GLuint *); -GLAPI void APIENTRY glUniform3uivEXT (GLint, GLsizei, const GLuint *); -GLAPI void APIENTRY glUniform4uivEXT (GLint, GLsizei, const GLuint *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint *params); -typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name); -typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar *name); -typedef void (APIENTRYP PFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0); -typedef void (APIENTRYP PFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1); -typedef void (APIENTRYP PFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); -typedef void (APIENTRYP PFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -typedef void (APIENTRYP PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); -#endif - -#ifndef GL_EXT_draw_instanced -#define GL_EXT_draw_instanced 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawArraysInstancedEXT (GLenum, GLint, GLsizei, GLsizei); -GLAPI void APIENTRY glDrawElementsInstancedEXT (GLenum, GLsizei, GLenum, const GLvoid *, GLsizei); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); -typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); -#endif - -#ifndef GL_EXT_packed_float -#define GL_EXT_packed_float 1 -#endif - -#ifndef GL_EXT_texture_array -#define GL_EXT_texture_array 1 -#endif - -#ifndef GL_EXT_texture_buffer_object -#define GL_EXT_texture_buffer_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexBufferEXT (GLenum, GLenum, GLuint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer); -#endif - -#ifndef GL_EXT_texture_compression_latc -#define GL_EXT_texture_compression_latc 1 -#endif - -#ifndef GL_EXT_texture_compression_rgtc -#define GL_EXT_texture_compression_rgtc 1 -#endif - -#ifndef GL_EXT_texture_shared_exponent -#define GL_EXT_texture_shared_exponent 1 -#endif - -#ifndef GL_NV_depth_buffer_float -#define GL_NV_depth_buffer_float 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDepthRangedNV (GLdouble, GLdouble); -GLAPI void APIENTRY glClearDepthdNV (GLdouble); -GLAPI void APIENTRY glDepthBoundsdNV (GLdouble, GLdouble); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar); -typedef void (APIENTRYP PFNGLCLEARDEPTHDNVPROC) (GLdouble depth); -typedef void (APIENTRYP PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax); -#endif - -#ifndef GL_NV_fragment_program4 -#define GL_NV_fragment_program4 1 -#endif - -#ifndef GL_NV_framebuffer_multisample_coverage -#define GL_NV_framebuffer_multisample_coverage 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glRenderbufferStorageMultisampleCoverageNV (GLenum, GLsizei, GLsizei, GLenum, GLsizei, GLsizei); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); -#endif - -#ifndef GL_EXT_framebuffer_sRGB -#define GL_EXT_framebuffer_sRGB 1 -#endif - -#ifndef GL_NV_geometry_shader4 -#define GL_NV_geometry_shader4 1 -#endif - -#ifndef GL_NV_parameter_buffer_object -#define GL_NV_parameter_buffer_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramBufferParametersfvNV (GLenum, GLuint, GLuint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glProgramBufferParametersIivNV (GLenum, GLuint, GLuint, GLsizei, const GLint *); -GLAPI void APIENTRY glProgramBufferParametersIuivNV (GLenum, GLuint, GLuint, GLsizei, const GLuint *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params); -typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params); -#endif - -#ifndef GL_EXT_draw_buffers2 -#define GL_EXT_draw_buffers2 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorMaskIndexedEXT (GLuint, GLboolean, GLboolean, GLboolean, GLboolean); -GLAPI void APIENTRY glGetBooleanIndexedvEXT (GLenum, GLuint, GLboolean *); -GLAPI void APIENTRY glGetIntegerIndexedvEXT (GLenum, GLuint, GLint *); -GLAPI void APIENTRY glEnableIndexedEXT (GLenum, GLuint); -GLAPI void APIENTRY glDisableIndexedEXT (GLenum, GLuint); -GLAPI GLboolean APIENTRY glIsEnabledIndexedEXT (GLenum, GLuint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); -typedef void (APIENTRYP PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum target, GLuint index, GLboolean *data); -typedef void (APIENTRYP PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLint *data); -typedef void (APIENTRYP PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index); -typedef void (APIENTRYP PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index); -typedef GLboolean (APIENTRYP PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index); -#endif - -#ifndef GL_NV_transform_feedback -#define GL_NV_transform_feedback 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBeginTransformFeedbackNV (GLenum); -GLAPI void APIENTRY glEndTransformFeedbackNV (void); -GLAPI void APIENTRY glTransformFeedbackAttribsNV (GLuint, const GLint *, GLenum); -GLAPI void APIENTRY glBindBufferRangeNV (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr); -GLAPI void APIENTRY glBindBufferOffsetNV (GLenum, GLuint, GLuint, GLintptr); -GLAPI void APIENTRY glBindBufferBaseNV (GLenum, GLuint, GLuint); -GLAPI void APIENTRY glTransformFeedbackVaryingsNV (GLuint, GLsizei, const GLint *, GLenum); -GLAPI void APIENTRY glActiveVaryingNV (GLuint, const GLchar *); -GLAPI GLint APIENTRY glGetVaryingLocationNV (GLuint, const GLchar *); -GLAPI void APIENTRY glGetActiveVaryingNV (GLuint, GLuint, GLsizei, GLsizei *, GLsizei *, GLenum *, GLchar *); -GLAPI void APIENTRY glGetTransformFeedbackVaryingNV (GLuint, GLuint, GLint *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode); -typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKNVPROC) (void); -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLuint count, const GLint *attribs, GLenum bufferMode); -typedef void (APIENTRYP PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); -typedef void (APIENTRYP PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer); -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); -typedef void (APIENTRYP PFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar *name); -typedef GLint (APIENTRYP PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar *name); -typedef void (APIENTRYP PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); -typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint *location); -#endif - -#ifndef GL_EXT_bindable_uniform -#define GL_EXT_bindable_uniform 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glUniformBufferEXT (GLuint, GLint, GLuint); -GLAPI GLint APIENTRY glGetUniformBufferSizeEXT (GLuint, GLint); -GLAPI GLintptr APIENTRY glGetUniformOffsetEXT (GLuint, GLint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer); -typedef GLint (APIENTRYP PFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location); -typedef GLintptr (APIENTRYP PFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location); -#endif - -#ifndef GL_EXT_texture_integer -#define GL_EXT_texture_integer 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexParameterIivEXT (GLenum, GLenum, const GLint *); -GLAPI void APIENTRY glTexParameterIuivEXT (GLenum, GLenum, const GLuint *); -GLAPI void APIENTRY glGetTexParameterIivEXT (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetTexParameterIuivEXT (GLenum, GLenum, GLuint *); -GLAPI void APIENTRY glClearColorIiEXT (GLint, GLint, GLint, GLint); -GLAPI void APIENTRY glClearColorIuiEXT (GLuint, GLuint, GLuint, GLuint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params); -typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha); -typedef void (APIENTRYP PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha); -#endif - -#ifndef GL_GREMEDY_frame_terminator -#define GL_GREMEDY_frame_terminator 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFrameTerminatorGREMEDY (void); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLFRAMETERMINATORGREMEDYPROC) (void); -#endif - -#ifndef GL_NV_conditional_render -#define GL_NV_conditional_render 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBeginConditionalRenderNV (GLuint, GLenum); -GLAPI void APIENTRY glEndConditionalRenderNV (void); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode); -typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERNVPROC) (void); -#endif - -#ifndef GL_NV_present_video -#define GL_NV_present_video 1 -#endif - -#ifndef GL_EXT_transform_feedback -#define GL_EXT_transform_feedback 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBeginTransformFeedbackEXT (GLenum); -GLAPI void APIENTRY glEndTransformFeedbackEXT (void); -GLAPI void APIENTRY glBindBufferRangeEXT (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr); -GLAPI void APIENTRY glBindBufferOffsetEXT (GLenum, GLuint, GLuint, GLintptr); -GLAPI void APIENTRY glBindBufferBaseEXT (GLenum, GLuint, GLuint); -GLAPI void APIENTRY glTransformFeedbackVaryingsEXT (GLuint, GLsizei, const GLint *, GLenum); -GLAPI void APIENTRY glGetTransformFeedbackVaryingEXT (GLuint, GLuint, GLint *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKEXTPROC) (GLenum primitiveMode); -typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKEXTPROC) (void); -typedef void (APIENTRYP PFNGLBINDBUFFERRANGEEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); -typedef void (APIENTRYP PFNGLBINDBUFFERBASEEXTPROC) (GLenum target, GLuint index, GLuint buffer); -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); -typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC) (GLuint program, GLuint index, GLint *location); -#endif - -#ifndef GL_EXT_direct_state_access -#define GL_EXT_direct_state_access 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glClientAttribDefaultEXT (GLbitfield); -GLAPI void APIENTRY glPushClientAttribDefaultEXT (GLbitfield); -GLAPI void APIENTRY glMatrixLoadfEXT (GLenum, const GLfloat *); -GLAPI void APIENTRY glMatrixLoaddEXT (GLenum, const GLdouble *); -GLAPI void APIENTRY glMatrixMultfEXT (GLenum, const GLfloat *); -GLAPI void APIENTRY glMatrixMultdEXT (GLenum, const GLdouble *); -GLAPI void APIENTRY glMatrixLoadIdentityEXT (GLenum); -GLAPI void APIENTRY glMatrixRotatefEXT (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glMatrixRotatedEXT (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glMatrixScalefEXT (GLenum, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glMatrixScaledEXT (GLenum, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glMatrixTranslatefEXT (GLenum, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glMatrixTranslatedEXT (GLenum, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glMatrixFrustumEXT (GLenum, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glMatrixOrthoEXT (GLenum, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glMatrixPopEXT (GLenum); -GLAPI void APIENTRY glMatrixPushEXT (GLenum); -GLAPI void APIENTRY glMatrixLoadTransposefEXT (GLenum, const GLfloat *); -GLAPI void APIENTRY glMatrixLoadTransposedEXT (GLenum, const GLdouble *); -GLAPI void APIENTRY glMatrixMultTransposefEXT (GLenum, const GLfloat *); -GLAPI void APIENTRY glMatrixMultTransposedEXT (GLenum, const GLdouble *); -GLAPI void APIENTRY glTextureParameterfEXT (GLuint, GLenum, GLenum, GLfloat); -GLAPI void APIENTRY glTextureParameterfvEXT (GLuint, GLenum, GLenum, const GLfloat *); -GLAPI void APIENTRY glTextureParameteriEXT (GLuint, GLenum, GLenum, GLint); -GLAPI void APIENTRY glTextureParameterivEXT (GLuint, GLenum, GLenum, const GLint *); -GLAPI void APIENTRY glTextureImage1DEXT (GLuint, GLenum, GLint, GLenum, GLsizei, GLint, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glTextureImage2DEXT (GLuint, GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glTextureSubImage1DEXT (GLuint, GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glTextureSubImage2DEXT (GLuint, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glCopyTextureImage1DEXT (GLuint, GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint); -GLAPI void APIENTRY glCopyTextureImage2DEXT (GLuint, GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint); -GLAPI void APIENTRY glCopyTextureSubImage1DEXT (GLuint, GLenum, GLint, GLint, GLint, GLint, GLsizei); -GLAPI void APIENTRY glCopyTextureSubImage2DEXT (GLuint, GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); -GLAPI void APIENTRY glGetTextureImageEXT (GLuint, GLenum, GLint, GLenum, GLenum, GLvoid *); -GLAPI void APIENTRY glGetTextureParameterfvEXT (GLuint, GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetTextureParameterivEXT (GLuint, GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetTextureLevelParameterfvEXT (GLuint, GLenum, GLint, GLenum, GLfloat *); -GLAPI void APIENTRY glGetTextureLevelParameterivEXT (GLuint, GLenum, GLint, GLenum, GLint *); -GLAPI void APIENTRY glTextureImage3DEXT (GLuint, GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glTextureSubImage3DEXT (GLuint, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glCopyTextureSubImage3DEXT (GLuint, GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); -GLAPI void APIENTRY glMultiTexParameterfEXT (GLenum, GLenum, GLenum, GLfloat); -GLAPI void APIENTRY glMultiTexParameterfvEXT (GLenum, GLenum, GLenum, const GLfloat *); -GLAPI void APIENTRY glMultiTexParameteriEXT (GLenum, GLenum, GLenum, GLint); -GLAPI void APIENTRY glMultiTexParameterivEXT (GLenum, GLenum, GLenum, const GLint *); -GLAPI void APIENTRY glMultiTexImage1DEXT (GLenum, GLenum, GLint, GLenum, GLsizei, GLint, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glMultiTexImage2DEXT (GLenum, GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glMultiTexSubImage1DEXT (GLenum, GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glMultiTexSubImage2DEXT (GLenum, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glCopyMultiTexImage1DEXT (GLenum, GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint); -GLAPI void APIENTRY glCopyMultiTexImage2DEXT (GLenum, GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint); -GLAPI void APIENTRY glCopyMultiTexSubImage1DEXT (GLenum, GLenum, GLint, GLint, GLint, GLint, GLsizei); -GLAPI void APIENTRY glCopyMultiTexSubImage2DEXT (GLenum, GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); -GLAPI void APIENTRY glGetMultiTexImageEXT (GLenum, GLenum, GLint, GLenum, GLenum, GLvoid *); -GLAPI void APIENTRY glGetMultiTexParameterfvEXT (GLenum, GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetMultiTexParameterivEXT (GLenum, GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetMultiTexLevelParameterfvEXT (GLenum, GLenum, GLint, GLenum, GLfloat *); -GLAPI void APIENTRY glGetMultiTexLevelParameterivEXT (GLenum, GLenum, GLint, GLenum, GLint *); -GLAPI void APIENTRY glMultiTexImage3DEXT (GLenum, GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glMultiTexSubImage3DEXT (GLenum, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glCopyMultiTexSubImage3DEXT (GLenum, GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); -GLAPI void APIENTRY glBindMultiTextureEXT (GLenum, GLenum, GLuint); -GLAPI void APIENTRY glEnableClientStateIndexedEXT (GLenum, GLuint); -GLAPI void APIENTRY glDisableClientStateIndexedEXT (GLenum, GLuint); -GLAPI void APIENTRY glMultiTexCoordPointerEXT (GLenum, GLint, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glMultiTexEnvfEXT (GLenum, GLenum, GLenum, GLfloat); -GLAPI void APIENTRY glMultiTexEnvfvEXT (GLenum, GLenum, GLenum, const GLfloat *); -GLAPI void APIENTRY glMultiTexEnviEXT (GLenum, GLenum, GLenum, GLint); -GLAPI void APIENTRY glMultiTexEnvivEXT (GLenum, GLenum, GLenum, const GLint *); -GLAPI void APIENTRY glMultiTexGendEXT (GLenum, GLenum, GLenum, GLdouble); -GLAPI void APIENTRY glMultiTexGendvEXT (GLenum, GLenum, GLenum, const GLdouble *); -GLAPI void APIENTRY glMultiTexGenfEXT (GLenum, GLenum, GLenum, GLfloat); -GLAPI void APIENTRY glMultiTexGenfvEXT (GLenum, GLenum, GLenum, const GLfloat *); -GLAPI void APIENTRY glMultiTexGeniEXT (GLenum, GLenum, GLenum, GLint); -GLAPI void APIENTRY glMultiTexGenivEXT (GLenum, GLenum, GLenum, const GLint *); -GLAPI void APIENTRY glGetMultiTexEnvfvEXT (GLenum, GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetMultiTexEnvivEXT (GLenum, GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetMultiTexGendvEXT (GLenum, GLenum, GLenum, GLdouble *); -GLAPI void APIENTRY glGetMultiTexGenfvEXT (GLenum, GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetMultiTexGenivEXT (GLenum, GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetFloatIndexedvEXT (GLenum, GLuint, GLfloat *); -GLAPI void APIENTRY glGetDoubleIndexedvEXT (GLenum, GLuint, GLdouble *); -GLAPI void APIENTRY glGetPointerIndexedvEXT (GLenum, GLuint, GLvoid* *); -GLAPI void APIENTRY glCompressedTextureImage3DEXT (GLuint, GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedTextureImage2DEXT (GLuint, GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedTextureImage1DEXT (GLuint, GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedTextureSubImage3DEXT (GLuint, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedTextureSubImage2DEXT (GLuint, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedTextureSubImage1DEXT (GLuint, GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glGetCompressedTextureImageEXT (GLuint, GLenum, GLint, GLvoid *); -GLAPI void APIENTRY glCompressedMultiTexImage3DEXT (GLenum, GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedMultiTexImage2DEXT (GLenum, GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedMultiTexImage1DEXT (GLenum, GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedMultiTexSubImage3DEXT (GLenum, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedMultiTexSubImage2DEXT (GLenum, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedMultiTexSubImage1DEXT (GLenum, GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glGetCompressedMultiTexImageEXT (GLenum, GLenum, GLint, GLvoid *); -GLAPI void APIENTRY glNamedProgramStringEXT (GLuint, GLenum, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glNamedProgramLocalParameter4dEXT (GLuint, GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glNamedProgramLocalParameter4dvEXT (GLuint, GLenum, GLuint, const GLdouble *); -GLAPI void APIENTRY glNamedProgramLocalParameter4fEXT (GLuint, GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glNamedProgramLocalParameter4fvEXT (GLuint, GLenum, GLuint, const GLfloat *); -GLAPI void APIENTRY glGetNamedProgramLocalParameterdvEXT (GLuint, GLenum, GLuint, GLdouble *); -GLAPI void APIENTRY glGetNamedProgramLocalParameterfvEXT (GLuint, GLenum, GLuint, GLfloat *); -GLAPI void APIENTRY glGetNamedProgramivEXT (GLuint, GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetNamedProgramStringEXT (GLuint, GLenum, GLenum, GLvoid *); -GLAPI void APIENTRY glNamedProgramLocalParameters4fvEXT (GLuint, GLenum, GLuint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glNamedProgramLocalParameterI4iEXT (GLuint, GLenum, GLuint, GLint, GLint, GLint, GLint); -GLAPI void APIENTRY glNamedProgramLocalParameterI4ivEXT (GLuint, GLenum, GLuint, const GLint *); -GLAPI void APIENTRY glNamedProgramLocalParametersI4ivEXT (GLuint, GLenum, GLuint, GLsizei, const GLint *); -GLAPI void APIENTRY glNamedProgramLocalParameterI4uiEXT (GLuint, GLenum, GLuint, GLuint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glNamedProgramLocalParameterI4uivEXT (GLuint, GLenum, GLuint, const GLuint *); -GLAPI void APIENTRY glNamedProgramLocalParametersI4uivEXT (GLuint, GLenum, GLuint, GLsizei, const GLuint *); -GLAPI void APIENTRY glGetNamedProgramLocalParameterIivEXT (GLuint, GLenum, GLuint, GLint *); -GLAPI void APIENTRY glGetNamedProgramLocalParameterIuivEXT (GLuint, GLenum, GLuint, GLuint *); -GLAPI void APIENTRY glTextureParameterIivEXT (GLuint, GLenum, GLenum, const GLint *); -GLAPI void APIENTRY glTextureParameterIuivEXT (GLuint, GLenum, GLenum, const GLuint *); -GLAPI void APIENTRY glGetTextureParameterIivEXT (GLuint, GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetTextureParameterIuivEXT (GLuint, GLenum, GLenum, GLuint *); -GLAPI void APIENTRY glMultiTexParameterIivEXT (GLenum, GLenum, GLenum, const GLint *); -GLAPI void APIENTRY glMultiTexParameterIuivEXT (GLenum, GLenum, GLenum, const GLuint *); -GLAPI void APIENTRY glGetMultiTexParameterIivEXT (GLenum, GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetMultiTexParameterIuivEXT (GLenum, GLenum, GLenum, GLuint *); -GLAPI void APIENTRY glProgramUniform1fEXT (GLuint, GLint, GLfloat); -GLAPI void APIENTRY glProgramUniform2fEXT (GLuint, GLint, GLfloat, GLfloat); -GLAPI void APIENTRY glProgramUniform3fEXT (GLuint, GLint, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glProgramUniform4fEXT (GLuint, GLint, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glProgramUniform1iEXT (GLuint, GLint, GLint); -GLAPI void APIENTRY glProgramUniform2iEXT (GLuint, GLint, GLint, GLint); -GLAPI void APIENTRY glProgramUniform3iEXT (GLuint, GLint, GLint, GLint, GLint); -GLAPI void APIENTRY glProgramUniform4iEXT (GLuint, GLint, GLint, GLint, GLint, GLint); -GLAPI void APIENTRY glProgramUniform1fvEXT (GLuint, GLint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glProgramUniform2fvEXT (GLuint, GLint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glProgramUniform3fvEXT (GLuint, GLint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glProgramUniform4fvEXT (GLuint, GLint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glProgramUniform1ivEXT (GLuint, GLint, GLsizei, const GLint *); -GLAPI void APIENTRY glProgramUniform2ivEXT (GLuint, GLint, GLsizei, const GLint *); -GLAPI void APIENTRY glProgramUniform3ivEXT (GLuint, GLint, GLsizei, const GLint *); -GLAPI void APIENTRY glProgramUniform4ivEXT (GLuint, GLint, GLsizei, const GLint *); -GLAPI void APIENTRY glProgramUniformMatrix2fvEXT (GLuint, GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glProgramUniformMatrix3fvEXT (GLuint, GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glProgramUniformMatrix4fvEXT (GLuint, GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glProgramUniformMatrix2x3fvEXT (GLuint, GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glProgramUniformMatrix3x2fvEXT (GLuint, GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glProgramUniformMatrix2x4fvEXT (GLuint, GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glProgramUniformMatrix4x2fvEXT (GLuint, GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glProgramUniformMatrix3x4fvEXT (GLuint, GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glProgramUniformMatrix4x3fvEXT (GLuint, GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glProgramUniform1uiEXT (GLuint, GLint, GLuint); -GLAPI void APIENTRY glProgramUniform2uiEXT (GLuint, GLint, GLuint, GLuint); -GLAPI void APIENTRY glProgramUniform3uiEXT (GLuint, GLint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glProgramUniform4uiEXT (GLuint, GLint, GLuint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glProgramUniform1uivEXT (GLuint, GLint, GLsizei, const GLuint *); -GLAPI void APIENTRY glProgramUniform2uivEXT (GLuint, GLint, GLsizei, const GLuint *); -GLAPI void APIENTRY glProgramUniform3uivEXT (GLuint, GLint, GLsizei, const GLuint *); -GLAPI void APIENTRY glProgramUniform4uivEXT (GLuint, GLint, GLsizei, const GLuint *); -GLAPI void APIENTRY glNamedBufferDataEXT (GLuint, GLsizeiptr, const GLvoid *, GLenum); -GLAPI void APIENTRY glNamedBufferSubDataEXT (GLuint, GLintptr, GLsizeiptr, const GLvoid *); -GLAPI GLvoid* APIENTRY glMapNamedBufferEXT (GLuint, GLenum); -GLAPI GLboolean APIENTRY glUnmapNamedBufferEXT (GLuint); -GLAPI void APIENTRY glGetNamedBufferParameterivEXT (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetNamedBufferPointervEXT (GLuint, GLenum, GLvoid* *); -GLAPI void APIENTRY glGetNamedBufferSubDataEXT (GLuint, GLintptr, GLsizeiptr, GLvoid *); -GLAPI void APIENTRY glTextureBufferEXT (GLuint, GLenum, GLenum, GLuint); -GLAPI void APIENTRY glMultiTexBufferEXT (GLenum, GLenum, GLenum, GLuint); -GLAPI void APIENTRY glNamedRenderbufferStorageEXT (GLuint, GLenum, GLsizei, GLsizei); -GLAPI void APIENTRY glGetNamedRenderbufferParameterivEXT (GLuint, GLenum, GLint *); -GLAPI GLenum APIENTRY glCheckNamedFramebufferStatusEXT (GLuint, GLenum); -GLAPI void APIENTRY glNamedFramebufferTexture1DEXT (GLuint, GLenum, GLenum, GLuint, GLint); -GLAPI void APIENTRY glNamedFramebufferTexture2DEXT (GLuint, GLenum, GLenum, GLuint, GLint); -GLAPI void APIENTRY glNamedFramebufferTexture3DEXT (GLuint, GLenum, GLenum, GLuint, GLint, GLint); -GLAPI void APIENTRY glNamedFramebufferRenderbufferEXT (GLuint, GLenum, GLenum, GLuint); -GLAPI void APIENTRY glGetNamedFramebufferAttachmentParameterivEXT (GLuint, GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGenerateTextureMipmapEXT (GLuint, GLenum); -GLAPI void APIENTRY glGenerateMultiTexMipmapEXT (GLenum, GLenum); -GLAPI void APIENTRY glFramebufferDrawBufferEXT (GLuint, GLenum); -GLAPI void APIENTRY glFramebufferDrawBuffersEXT (GLuint, GLsizei, const GLenum *); -GLAPI void APIENTRY glFramebufferReadBufferEXT (GLuint, GLenum); -GLAPI void APIENTRY glGetFramebufferParameterivEXT (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glNamedRenderbufferStorageMultisampleEXT (GLuint, GLsizei, GLenum, GLsizei, GLsizei); -GLAPI void APIENTRY glNamedRenderbufferStorageMultisampleCoverageEXT (GLuint, GLsizei, GLsizei, GLenum, GLsizei, GLsizei); -GLAPI void APIENTRY glNamedFramebufferTextureEXT (GLuint, GLenum, GLuint, GLint); -GLAPI void APIENTRY glNamedFramebufferTextureLayerEXT (GLuint, GLenum, GLuint, GLint, GLint); -GLAPI void APIENTRY glNamedFramebufferTextureFaceEXT (GLuint, GLenum, GLuint, GLint, GLenum); -GLAPI void APIENTRY glTextureRenderbufferEXT (GLuint, GLenum, GLuint); -GLAPI void APIENTRY glMultiTexRenderbufferEXT (GLenum, GLenum, GLuint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); -typedef void (APIENTRYP PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); -typedef void (APIENTRYP PFNGLMATRIXLOADFEXTPROC) (GLenum mode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXLOADDEXTPROC) (GLenum mode, const GLdouble *m); -typedef void (APIENTRYP PFNGLMATRIXMULTFEXTPROC) (GLenum mode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXMULTDEXTPROC) (GLenum mode, const GLdouble *m); -typedef void (APIENTRYP PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum mode); -typedef void (APIENTRYP PFNGLMATRIXROTATEFEXTPROC) (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLMATRIXROTATEDEXTPROC) (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLMATRIXSCALEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLMATRIXSCALEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLMATRIXTRANSLATEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLMATRIXTRANSLATEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLMATRIXFRUSTUMEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); -typedef void (APIENTRYP PFNGLMATRIXORTHOEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); -typedef void (APIENTRYP PFNGLMATRIXPOPEXTPROC) (GLenum mode); -typedef void (APIENTRYP PFNGLMATRIXPUSHEXTPROC) (GLenum mode); -typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m); -typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLCOPYTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -typedef void (APIENTRYP PFNGLCOPYTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); -typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLMULTITEXPARAMETERFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLCOPYMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -typedef void (APIENTRYP PFNGLCOPYMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); -typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLBINDMULTITEXTUREEXTPROC) (GLenum texunit, GLenum target, GLuint texture); -typedef void (APIENTRYP PFNGLENABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); -typedef void (APIENTRYP PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); -typedef void (APIENTRYP PFNGLMULTITEXCOORDPOINTEREXTPROC) (GLenum texunit, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLMULTITEXENVFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLMULTITEXENVIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLMULTITEXGENDEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble param); -typedef void (APIENTRYP PFNGLMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params); -typedef void (APIENTRYP PFNGLMULTITEXGENFEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLMULTITEXGENIEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLGETMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLGETMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETFLOATINDEXEDVEXTPROC) (GLenum target, GLuint index, GLfloat *data); -typedef void (APIENTRYP PFNGLGETDOUBLEINDEXEDVEXTPROC) (GLenum target, GLuint index, GLdouble *data); -typedef void (APIENTRYP PFNGLGETPOINTERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLvoid* *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits); -typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint lod, GLvoid *img); -typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits); -typedef void (APIENTRYP PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint lod, GLvoid *img); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum format, GLsizei len, const GLvoid *string); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLdouble *params); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble *params); -typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat *params); -typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMIVEXTPROC) (GLuint program, GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum pname, GLvoid *string); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat *params); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC) (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLint *params); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint *params); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLuint *params); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint *params); -typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLint *params); -typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint *params); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLuint *params); -typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLuint *params); -typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLsizeiptr size, const GLvoid *data, GLenum usage); -typedef void (APIENTRYP PFNGLNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const GLvoid *data); -typedef GLvoid* (APIENTRYP PFNGLMAPNAMEDBUFFEREXTPROC) (GLuint buffer, GLenum access); -typedef GLboolean (APIENTRYP PFNGLUNMAPNAMEDBUFFEREXTPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC) (GLuint buffer, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPOINTERVEXTPROC) (GLuint buffer, GLenum pname, GLvoid* *params); -typedef void (APIENTRYP PFNGLGETNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLvoid *data); -typedef void (APIENTRYP PFNGLTEXTUREBUFFEREXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer); -typedef void (APIENTRYP PFNGLMULTITEXBUFFEREXTPROC) (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer); -typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC) (GLuint renderbuffer, GLenum pname, GLint *params); -typedef GLenum (APIENTRYP PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC) (GLuint framebuffer, GLenum target); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGENERATETEXTUREMIPMAPEXTPROC) (GLuint texture, GLenum target); -typedef void (APIENTRYP PFNGLGENERATEMULTITEXMIPMAPEXTPROC) (GLenum texunit, GLenum target); -typedef void (APIENTRYP PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); -typedef void (APIENTRYP PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC) (GLuint framebuffer, GLsizei n, const GLenum *bufs); -typedef void (APIENTRYP PFNGLFRAMEBUFFERREADBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); -typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC) (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face); -typedef void (APIENTRYP PFNGLTEXTURERENDERBUFFEREXTPROC) (GLuint texture, GLenum target, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLMULTITEXRENDERBUFFEREXTPROC) (GLenum texunit, GLenum target, GLuint renderbuffer); -#endif - -#ifndef GL_EXT_vertex_array_bgra -#define GL_EXT_vertex_array_bgra 1 -#endif - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/AUTHORS b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/AUTHORS deleted file mode 100644 index 56aa2f9bb..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/AUTHORS +++ /dev/null @@ -1,20 +0,0 @@ - -lib3ds was originally written by Jan Eric Kyprianidis - -The project is currently administered by Reed Hedges . -Please contact Reed with any inquiries. - -Since April, 2004, the following people have contributed additional -changes to lib3ds: - -David Rogers -Edward Falk -Gernot Zeigler -Haik Lorenz -Jean-Charles Quillet -Mike Frysinger -Miles Bader -Tomas Rapkauskas -Torsten Blank -Ralf Corsepius -Stephane Denis diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/ChangeLog b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/ChangeLog deleted file mode 100644 index 9539ada2a..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/ChangeLog +++ /dev/null @@ -1,304 +0,0 @@ -2007-06-20 Jan Eric Kyprianidis - - * Fixed loading of files without NODE_ID - * Updated Xcode projects - * Updated project files to improve doxygen output - -2007-06-15 Jan Eric Kyprianidis - - * Removed float.c/float.h to avoid conflicts with ISO header - * Removed LIB3DS_EXPORT define from files - -2007-06-14 Jan Eric Kyprianidis - - * Added support for object flags in meshes, cameras and lights - * Fixed bug #1240026: 3dsplay can't display files without keyframer section - * Fixed node eval if no scale track is present - * Fixed bug# 1231343: basketball assert - * Added lib3ds_file_bounding_box_of_objects/of_nodes to fix bug #1160806 - * Replaced lib3ds_matrix_mul by lib3ds_matrix_mult - * Updated Copyright information in files - * Created new Visual Studio 8 project files - * Renamed player.c to 3dsplay.c - * Removed out-dated examples (3ds2rib, 3ds2m) - * Revised configure.in and Makefile.am files Added support for shared and - static libs via libtool. Removed support to build 3dsplay to simplify - configuration - * Fixed bug #1691746: io.c has one more strict aliasing violation - * Fixed bug #1077795: incorrect orientation matrices - * Fixed bug #1581774: Lib3dsTextureMapFlags - * Fixed bug #1726844: memory leak in lib3ds_file_load - * Applied patch 1550343: Possible memory leak in lib3ds_file_free() - * Fixed bug #998502: automake parameters missed in autogen.sh - * Fixed bug #1433032: lib3ds on 64 bit platforms - * Use size_t for lib3ds_io_read/write - * Fixed type conversion warnings (Visual Studio 8) - * Removed Lib3dsFile::num_meshes - * Removed DMALLOC support - -2005-05-07 Reed Hedges - - * Prerelease 1.3.0-pre1. This release adds 'player' in the installation - as '3dsplayer' - -2004-11-20 Edward Falk - - * Fixed bugs in matrix.c and vector.c relating to degenerate cases. - * Added lots of doxygen comments to several files. - * Incorporated SELF_ILPCT patch by Lee Butler (Patch #787678) - * Incorporated texture matching patch by Gernot Ziegler - * Fixed mesh interpolation bug (first approximation) - * Major enhancements throughout player.c - * Added more dump functions. - * Added lib3ds_object_bounding_box() - * Added "rpm" target to Makefie.am - * Bumped to version 1.3.0 - -2004-06-04 Reed Hedges - - * Some fixes contributed by Stephane Denis were previously applied - * Added IDE project files for MSVC7 and XCode contributed by Stephane Denis. - -2002-09-19 Jan Eric Kyprianidis - - * matrix.c: lib3ds_matrix_dump, fixed lib3ds_matrix_camera. - * camera.c: lib3ds_camera_dump - -2002-01-14 Jan Eric Kyprianidis - - * Added configure and aclocal.m4 to CVS. - WARNING: Files may not be up to date !!! - * Removed libtool. Building shared libs using the GNU - build tools is no longer supported. - * material.c: Added default initializations for material - (including the texture maps) - * m4/glut.m4: Checking now for win32 GL/GLU/GLUT libraries - when compiling with cygwin. - Added -lobjc to LIBS for MacOS X. - -2001-11-14 Jan Eric Kyprianidis - - * glstub.h: Created as default glstub.h.in for MSVC. - -2001-10-14 Jan Eric Kyprianidis - - * viewport.c: Calling lib3ds_viewport_set_views with parameter - views == 0 will now be handled proper for the case that no - views are allocated. - -2001-09-16 Jan Eric Kyprianidis - - * mesh.c: Fixed bug in lib3ds_mesh_dump(). The face list loops on - mesh->points length - which should be mesh->faces.(Reported by - lib3ds@lee-morgan.net) - -2001-07-24 Jan Eric Kyprianidis - - * autogen.sh: Added a check in the search for `aclocal` support paths - such that the path is only included if aclocal is not installed in - that path (if aclocal is installed in /usr/bin/ then /usr/share is - skipped). Removed the break in the search so that again all search - paths are used. - * configure.in, Doxyfile: Changed version to 1.2.0. - -2001-07-23 Eric Sunshine - - * autogen.sh: Augmented the search for `aclocal' support files so that - only the first found-path is used (that is, only one `-I' directive - is added to the command line). Also altered the search path priority - so that /usr/local/share is preferred over /usr/share. Hopefully - this will fix the problem of `aclocal' complaining about duplicate - macro definitions on some installations where, presumably, - /usr/share/aclocal and /usr/local/share/aclocal both point at the - same physical directory or are at least copies of one another. - -2001-07-20 Eric Sunshine - - * autogen.sh: Augmented to work correctly despite absence of GNU - libtool and libtoolize on MacOS/X. The libtool program on - MacOS/X was developed independently and is a completely distinct - beast from the GNU libtool. If libtoolize is missing, - autogen.sh now manually grabs the needed support files - (config.sub, config.guess, ltconfig, and ltmain.sh). - -2001-07-19 Eric Sunshine - - * m4/glut.m4: Augmented CONFIGURE_GLUT() macro so that it now - checks for gl.h, glu.h, and glut.h in and in - addition to . Also now checks if `-framework GLUT' and - `-framework OpenGL' are required when linking an application. - These changes allow the example applications to build on - MacOS/X. - * configure.in: Now generates `examples/glstub.h' from the new - `examples/glstub.h.in'. This file imports the OpenGL and GLUT - headers using the paths determined by the CONFIGURE_GLUT() macro - (i.e. on MacOS/X; rather than for other - platforms). - * examples/player.c: Now includes "glstub.h" rather than - . - * m4/glut.m4: Fixed a bug in CONFIGURE_GLUT() where it ignored - user-supplied CFLAGS from --with-glut-cflags when checking for - the presence of gl.h, glu.h, and glut.h. - -2001-07-18 Jan Eric Kyprianidis - - * m4/glut.m4: Added GL/GLU/glut check. - * Retructured files. Create tools directory for tools that get - installed. Moved 3dsdump and 3ds2m to tools. Renamed 3dsplay - the examples directory into player (names which do not start - with a digit are much easier to handle with automake). - * tools/3ds2m: we do NOT need to multiply with the mesh matrix - (changed 2001-01-09 but 3ds2m has not been updated). - -2001-07-07 Jan Eric Kyprianidis - - * shaders: Added shaders directory. Contains Renderman shaders - to emulate the 3ds renderer (materials and lights). Only poor - results at the moment. - * examples/3ds2rib: Modified to use new shaders. - -2001-06-16 Jan Eric Kyprianidis - - * fixed spotlight reader/writer - * added lib3ds_light_dump, lib3ds_camera_dump - * updated lib3ds_material_dump - * added lib3ds_file_bounding_box - * Release 1.1.0 - -2001-06-07 Jan Eric Kyprianidis - - * write only necessary chunks to .3ds file - * file.h/file.c: renamed lib3ds_open to lib3ds_file_load - removed lib3ds_close (use lib3ds_file_free instead !!) - created lib3ds_file_save. - * Added msvc project file to create a dll. - * LIB3DS_KFHDR remains unchanged when saving a previously loaded - file. - -2001-06-05 Jan Eric Kyprianidis - - * node.h/node.c, file.h/file.c: renamed "id" to node_id - * recreated MSVC project files. Only static library creation - supported at the moment. - -2001-05-08 Michael Fink - - * in lib3ds_atmosphere_write() the two chunk id's were - accidentally swapped - * in lib3ds_mesh_write(), the chunks were reordered to enable a - successful import into AutoCAD 2000i and 3d Studio MAX 3.1 - * in the struct _Lib3dsMapData the "maptype" data member was - added, increasing the size of the chunk LIB3DS_MESH_TEXTURE_INFO - to 92 bytes (as seen in 3ds files from 3d Studio) - * the chunk LIB3DS_SHADOW_RANGE contains, according to the 3ds - file development kit (3ds-fdk) a dword chunk; reading and - writing the chunk should be fixed. - -2001-03-20 Jan Eric Kyprianidis - - * examples/3dsplay.c: new simples 3dsplayer example - using glut. msvc support only at the moment. - * lib3ds/mesh.c: started working on vertex normal support - (smoothing not supported at the moment, can't test them) - * Doxygen documentation files changed from *.doc to *.txt - to avoid collisions with MS-Word on windows platforms - -2001-01-15 Jan Eric Kyprianidis - - * lib3ds/material.c (lib3ds_material_dump): - Added dumping of ambient, diffuse, specular, shininess, - shin_strength, shading and texture1/texture2 properties - * examples/3dsdump.c (main): - Added suport for dumping the 3ds chunk structure - * lib3ds.spec: Updated - -2001-01-14 Jan Eric Kyprianidis - - * Removed Warnings (gcc & msvc++6.0) - * Cleaning up - * lib3ds.spec: Recreated - -2001-01-10 Jan Eric Kyprianidis - - * Wrote writing code for keyframer, background, atmosphere and - shadow settings. - -2001-01-09 Jan Eric Kyprianidis - - * lib3ds/mesh.c (lib3ds_mesh_write): - the point list is no loner retransformed to avoid numerical - problems. to use meshes with the keyframer all points must be - transformed by the inverse mesh-matrix manually. - * lib3ds/camera.c (lib3ds_camera_write): - bugfix LIB3DS_N_CAMERA (fov) - * lib3ds/light.c (lib3ds_light_write): - bugfix LIB3DS_DL_SPOTLIGHT - * lib3ds/material.c (texture_map_write): - write only chunks for maps with name != "" - (int_percentage_read), (int_percentage_write): - bugfix rounding error - -2001-01-04 Jan Eric Kyprianidis - - * lib3ds/readwrite.c: cpu independent endiness handling - as suggested by Daniel Richard G. - -2001-01-03 Jan Eric Kyprianidis - - * lib3ds/mesh.c: Added missing texture mapping handling - LIB3DS_TEX_VERTS - LIB3DS_MESH_TEXTURE_INFO - * lib3ds/matrix.c - (lib3ds_matrix_camera): Bug #124414 fixed - * lib3ds/material.c - (color_read): Bug #124399 fixed - (texture_map_read): texture percentage fixed - -2000-10-30 Jan Eric Kyprianidis - - * Renamed tools (examples) from lib3ds* -> 3ds* - * configure.in: Removed all non GCC compiler options, - leaving cflags untouched - -2000-10-27 Jan Eric Kyprianidis - - * doc/mainpage.doc: Added view3ds OpenGL realtime previewer example. - Avaiable as separate distributon. - No Changes to the library. - -2000-10-25 Jan Eric Kyprianidis - - * Release 0.9.1 - * Examples get installed now - * Man pages get installed now - -2000-10-24 Jan Eric Kyprianidis - - * lib3ds.spec: Created - -2000-10-19 Jan Eric Kyprianidis - - * CVSROOT/cvswrappers: created entries for msvc project files - * Created MSVC project files - * Setting up cvs commit logging - -2000-10-17 Jan Eric Kyprianidis - - * Release: 0.9.0 - -2000-10-09 Jan Eric Kyprianidis - - * Using now doxygen for documentation and webpage - -2000-10-05 Jan Eric Kyprianidis - - * Turned all double linked lists into single linked lists - * Added dmalloc support for memory leak tracking - * Added support to deallocate allocated memory - -2000-10-04 Jan Eric Kyprianidis - - * ANSI C fixes. Using now -ansi & -pedantic-errors for debug mode - * Improved little/endian checks & debug mode handling - * lib3ds/file.h: Added material lookup functions - * Starting ChangeLog diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/README b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/README deleted file mode 100644 index ba1092aab..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/README +++ /dev/null @@ -1,15 +0,0 @@ - -Lib3ds is a free toolkit for handling the "3DS" format for 3D model files. -Its main goal is to simplify the creation of 3DS import and export filters. - -This project is not related in any form to Autodesk Inc. The library is -based on unofficial information about the 3DS format found on the web. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -License for more details. - -The official Lib3ds Homepage can be found under: - http://lib3ds.sourceforge.net - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/atmosphere.c b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/atmosphere.c deleted file mode 100644 index 856eae06d..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/atmosphere.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: atmosphere.c,v 1.12 2007/06/20 17:04:08 jeh Exp $ - */ -#include "atmosphere.h" -#include "chunk.h" -#include "io.h" - - -/*! - * \defgroup atmosphere Atmosphere Settings - */ - - -static Lib3dsBool -fog_read(Lib3dsFog *fog, Lib3dsIo *io) -{ - Lib3dsChunk c; - Lib3dsWord chunk; - - if (!lib3ds_chunk_read_start(&c, LIB3DS_FOG, io)) { - return(LIB3DS_FALSE); - } - fog->near_plane = lib3ds_io_read_float(io); - fog->near_density=lib3ds_io_read_float(io); - fog->far_plane=lib3ds_io_read_float(io); - fog->far_density=lib3ds_io_read_float(io); - lib3ds_chunk_read_tell(&c, io); - - while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) { - switch (chunk) { - case LIB3DS_LIN_COLOR_F: - { - int i; - for (i=0; i<3; ++i) { - fog->col[i]=lib3ds_io_read_float(io); - } - } - break; - case LIB3DS_COLOR_F: - break; - case LIB3DS_FOG_BGND: - { - fog->fog_background=LIB3DS_TRUE; - } - break; - default: - lib3ds_chunk_unknown(chunk); - } - } - - lib3ds_chunk_read_end(&c, io); - return(LIB3DS_TRUE); -} - - -static Lib3dsBool -layer_fog_read(Lib3dsLayerFog *fog, Lib3dsIo *io) -{ - Lib3dsChunk c; - Lib3dsWord chunk; - Lib3dsBool have_lin=LIB3DS_FALSE; - - if (!lib3ds_chunk_read_start(&c, LIB3DS_LAYER_FOG, io)) { - return(LIB3DS_FALSE); - } - fog->near_y=lib3ds_io_read_float(io); - fog->far_y=lib3ds_io_read_float(io); - fog->density=lib3ds_io_read_float(io); - fog->flags=lib3ds_io_read_dword(io); - lib3ds_chunk_read_tell(&c, io); - - while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) { - switch (chunk) { - case LIB3DS_LIN_COLOR_F: - lib3ds_io_read_rgb(io, fog->col); - have_lin=LIB3DS_TRUE; - break; - case LIB3DS_COLOR_F: - lib3ds_io_read_rgb(io, fog->col); - break; - default: - lib3ds_chunk_unknown(chunk); - } - } - - lib3ds_chunk_read_end(&c, io); - return(LIB3DS_TRUE); -} - - -static Lib3dsBool -distance_cue_read(Lib3dsDistanceCue *cue, Lib3dsIo *io) -{ - Lib3dsChunk c; - Lib3dsWord chunk; - - if (!lib3ds_chunk_read_start(&c, LIB3DS_DISTANCE_CUE, io)) { - return(LIB3DS_FALSE); - } - cue->near_plane=lib3ds_io_read_float(io); - cue->near_dimming=lib3ds_io_read_float(io); - cue->far_plane=lib3ds_io_read_float(io); - cue->far_dimming=lib3ds_io_read_float(io); - lib3ds_chunk_read_tell(&c, io); - - while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) { - switch (chunk) { - case LIB3DS_DCUE_BGND: - { - cue->cue_background=LIB3DS_TRUE; - } - break; - default: - lib3ds_chunk_unknown(chunk); - } - } - - lib3ds_chunk_read_end(&c, io); - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup atmosphere - */ -Lib3dsBool -lib3ds_atmosphere_read(Lib3dsAtmosphere *atmosphere, Lib3dsIo *io) -{ - Lib3dsChunk c; - - if (!lib3ds_chunk_read(&c, io)) { - return(LIB3DS_FALSE); - } - - switch (c.chunk) { - case LIB3DS_FOG: - { - lib3ds_chunk_read_reset(&c, io); - if (!fog_read(&atmosphere->fog, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_LAYER_FOG: - { - lib3ds_chunk_read_reset(&c, io); - if (!layer_fog_read(&atmosphere->layer_fog, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_DISTANCE_CUE: - { - lib3ds_chunk_read_reset(&c, io); - if (!distance_cue_read(&atmosphere->dist_cue, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_USE_FOG: - { - atmosphere->fog.use=LIB3DS_TRUE; - } - break; - case LIB3DS_USE_LAYER_FOG: - { - atmosphere->fog.use=LIB3DS_TRUE; - } - break; - case LIB3DS_USE_DISTANCE_CUE: - { - atmosphere->dist_cue.use=LIB3DS_TRUE; - } - break; - } - - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup atmosphere - */ -Lib3dsBool -lib3ds_atmosphere_write(Lib3dsAtmosphere *atmosphere, Lib3dsIo *io) -{ - if (atmosphere->fog.use) { /*---- LIB3DS_FOG ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_FOG; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - lib3ds_io_write_float(io, atmosphere->fog.near_plane); - lib3ds_io_write_float(io, atmosphere->fog.near_density); - lib3ds_io_write_float(io, atmosphere->fog.far_plane); - lib3ds_io_write_float(io, atmosphere->fog.far_density); - { - Lib3dsChunk c; - c.chunk=LIB3DS_COLOR_F; - c.size=18; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_rgb(io, atmosphere->fog.col); - } - if (atmosphere->fog.fog_background) { - Lib3dsChunk c; - c.chunk=LIB3DS_FOG_BGND; - c.size=6; - lib3ds_chunk_write(&c,io); - } - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - } - - if (atmosphere->layer_fog.use) { /*---- LIB3DS_LAYER_FOG ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_LAYER_FOG; - c.size=40; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_float(io, atmosphere->layer_fog.near_y); - lib3ds_io_write_float(io, atmosphere->layer_fog.far_y); - lib3ds_io_write_float(io, atmosphere->layer_fog.near_y); - lib3ds_io_write_dword(io, atmosphere->layer_fog.flags); - { - Lib3dsChunk c; - c.chunk=LIB3DS_COLOR_F; - c.size=18; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_rgb(io, atmosphere->fog.col); - } - } - - if (atmosphere->dist_cue.use) { /*---- LIB3DS_DISTANCE_CUE ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_DISTANCE_CUE; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - lib3ds_io_write_float(io, atmosphere->dist_cue.near_plane); - lib3ds_io_write_float(io, atmosphere->dist_cue.near_dimming); - lib3ds_io_write_float(io, atmosphere->dist_cue.far_plane); - lib3ds_io_write_float(io, atmosphere->dist_cue.far_dimming); - if (atmosphere->dist_cue.cue_background) { - Lib3dsChunk c; - c.chunk=LIB3DS_DCUE_BGND; - c.size=6; - lib3ds_chunk_write(&c,io); - } - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - } - - if (atmosphere->fog.use) { /*---- LIB3DS_USE_FOG ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_USE_FOG; - c.size=6; - lib3ds_chunk_write(&c,io); - } - - if (atmosphere->layer_fog.use) { /*---- LIB3DS_USE_LAYER_FOG ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_USE_LAYER_FOG; - c.size=6; - lib3ds_chunk_write(&c,io); - } - - if (atmosphere->dist_cue.use) { /*---- LIB3DS_USE_DISTANCE_CUE ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_USE_V_GRADIENT; - c.size=6; - lib3ds_chunk_write(&c,io); - } - - return(LIB3DS_TRUE); -} - - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/atmosphere.h b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/atmosphere.h deleted file mode 100644 index 0d7307b44..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/atmosphere.h +++ /dev/null @@ -1,100 +0,0 @@ -/* -*- c -*- */ -#ifndef INCLUDED_LIB3DS_ATMOSPHERE_H -#define INCLUDED_LIB3DS_ATMOSPHERE_H -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: atmosphere.h,v 1.8 2007/06/20 17:04:08 jeh Exp $ - */ - -#ifndef INCLUDED_LIB3DS_TYPES_H -#include "types.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Fog atmosphere settings - * \ingroup atmosphere - */ -typedef struct Lib3dsFog { - Lib3dsBool use; - Lib3dsRgb col; - Lib3dsBool fog_background; - Lib3dsFloat near_plane; - Lib3dsFloat near_density; - Lib3dsFloat far_plane; - Lib3dsFloat far_density; -} Lib3dsFog; - -/** - * Layer fog atmosphere flags - * \ingroup atmosphere - */ -typedef enum Lib3dsLayerFogFlags { - LIB3DS_BOTTOM_FALL_OFF =0x00000001, - LIB3DS_TOP_FALL_OFF =0x00000002, - LIB3DS_FOG_BACKGROUND =0x00100000 -} Lib3dsLayerFogFlags; - -/** - * Layer fog atmosphere settings - * \ingroup atmosphere - */ -typedef struct Lib3dsLayerFog { - Lib3dsBool use; - Lib3dsDword flags; - Lib3dsRgb col; - Lib3dsFloat near_y; - Lib3dsFloat far_y; - Lib3dsFloat density; -} Lib3dsLayerFog; - -/** - * Distance cue atmosphere settings - * \ingroup atmosphere - */ -typedef struct Lib3dsDistanceCue { - Lib3dsBool use; - Lib3dsBool cue_background; - Lib3dsFloat near_plane; - Lib3dsFloat near_dimming; - Lib3dsFloat far_plane; - Lib3dsFloat far_dimming; -} Lib3dsDistanceCue; - -/** - * Atmosphere settings - * \ingroup atmosphere - */ -struct Lib3dsAtmosphere { - Lib3dsFog fog; - Lib3dsLayerFog layer_fog; - Lib3dsDistanceCue dist_cue; -}; - -extern LIB3DSAPI Lib3dsBool lib3ds_atmosphere_read(Lib3dsAtmosphere *atmosphere, Lib3dsIo *io); -extern LIB3DSAPI Lib3dsBool lib3ds_atmosphere_write(Lib3dsAtmosphere *atmosphere, Lib3dsIo *io); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/background.c b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/background.c deleted file mode 100644 index 9c3e52439..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/background.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: background.c,v 1.12 2007/06/20 17:04:08 jeh Exp $ - */ -#include "background.h" -#include "chunk.h" -#include "io.h" -#include -#include - - -/*! - * \defgroup background Background Settings - */ - - -static Lib3dsBool -solid_bgnd_read(Lib3dsBackground *background, Lib3dsIo *io) -{ - Lib3dsChunk c; - Lib3dsWord chunk; - Lib3dsBool have_lin=LIB3DS_FALSE; - - if (!lib3ds_chunk_read_start(&c, LIB3DS_SOLID_BGND, io)) { - return(LIB3DS_FALSE); - } - - while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) { - switch (chunk) { - case LIB3DS_LIN_COLOR_F: - lib3ds_io_read_rgb(io, background->solid.col); - have_lin=LIB3DS_TRUE; - break; - case LIB3DS_COLOR_F: - lib3ds_io_read_rgb(io, background->solid.col); - break; - default: - lib3ds_chunk_unknown(chunk); - } - } - - lib3ds_chunk_read_end(&c, io); - return(LIB3DS_TRUE); -} - - -static Lib3dsBool -v_gradient_read(Lib3dsBackground *background, Lib3dsIo *io) -{ - Lib3dsChunk c; - Lib3dsWord chunk; - int index[2]; - Lib3dsRgb col[2][3]; - int have_lin=0; - - - if (!lib3ds_chunk_read_start(&c, LIB3DS_V_GRADIENT, io)) { - return(LIB3DS_FALSE); - } - background->gradient.percent=lib3ds_io_read_float(io); - lib3ds_chunk_read_tell(&c, io); - - index[0]=index[1]=0; - while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) { - switch (chunk) { - case LIB3DS_COLOR_F: - lib3ds_io_read_rgb(io, col[0][index[0]]); - index[0]++; - break; - case LIB3DS_LIN_COLOR_F: - lib3ds_io_read_rgb(io, col[1][index[1]]); - index[1]++; - have_lin=1; - break; - default: - lib3ds_chunk_unknown(chunk); - } - } - { - int i; - for (i=0; i<3; ++i) { - background->gradient.top[i]=col[have_lin][0][i]; - background->gradient.middle[i]=col[have_lin][1][i]; - background->gradient.bottom[i]=col[have_lin][2][i]; - } - } - lib3ds_chunk_read_end(&c, io); - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup background - */ -Lib3dsBool -lib3ds_background_read(Lib3dsBackground *background, Lib3dsIo *io) -{ - Lib3dsChunk c; - - if (!lib3ds_chunk_read(&c, io)) { - return(LIB3DS_FALSE); - } - - switch (c.chunk) { - case LIB3DS_BIT_MAP: - { - if (!lib3ds_io_read_string(io, background->bitmap.name, 64)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_SOLID_BGND: - { - lib3ds_chunk_read_reset(&c, io); - if (!solid_bgnd_read(background, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_V_GRADIENT: - { - lib3ds_chunk_read_reset(&c, io); - if (!v_gradient_read(background, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_USE_BIT_MAP: - { - background->bitmap.use=LIB3DS_TRUE; - } - break; - case LIB3DS_USE_SOLID_BGND: - { - background->solid.use=LIB3DS_TRUE; - } - break; - case LIB3DS_USE_V_GRADIENT: - { - background->gradient.use=LIB3DS_TRUE; - } - break; - } - - return(LIB3DS_TRUE); -} - - -static Lib3dsBool -colorf_write(Lib3dsRgba rgb, Lib3dsIo *io) -{ - Lib3dsChunk c; - - c.chunk=LIB3DS_COLOR_F; - c.size=18; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_rgb(io, rgb); - - c.chunk=LIB3DS_LIN_COLOR_F; - c.size=18; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_rgb(io, rgb); - return(LIB3DS_TRUE); -} - - -static Lib3dsBool -colorf_defined(Lib3dsRgba rgb) -{ - int i; - for (i=0; i<3; ++i) { - if (fabs(rgb[i])>LIB3DS_EPSILON) { - break; - } - } - return(i<3); -} - - -/*! - * \ingroup background - */ -Lib3dsBool -lib3ds_background_write(Lib3dsBackground *background, Lib3dsIo *io) -{ - if (strlen(background->bitmap.name)) { /*---- LIB3DS_BIT_MAP ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_BIT_MAP; - c.size=6+1+(Lib3dsDword)strlen(background->bitmap.name); - lib3ds_chunk_write(&c,io); - lib3ds_io_write_string(io, background->bitmap.name); - } - - if (colorf_defined(background->solid.col)) { /*---- LIB3DS_SOLID_BGND ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_SOLID_BGND; - c.size=42; - lib3ds_chunk_write(&c,io); - colorf_write(background->solid.col, io); - } - - if (colorf_defined(background->gradient.top) || - colorf_defined(background->gradient.middle) || - colorf_defined(background->gradient.bottom)) { /*---- LIB3DS_V_GRADIENT ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_V_GRADIENT; - c.size=118; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_float(io, background->gradient.percent); - colorf_write(background->gradient.top,io); - colorf_write(background->gradient.middle,io); - colorf_write(background->gradient.bottom,io); - } - - if (background->bitmap.use) { /*---- LIB3DS_USE_BIT_MAP ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_USE_BIT_MAP; - c.size=6; - lib3ds_chunk_write(&c,io); - } - - if (background->solid.use) { /*---- LIB3DS_USE_SOLID_BGND ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_USE_SOLID_BGND; - c.size=6; - lib3ds_chunk_write(&c,io); - } - - if (background->gradient.use) { /*---- LIB3DS_USE_V_GRADIENT ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_USE_V_GRADIENT; - c.size=6; - lib3ds_chunk_write(&c,io); - } - - return(LIB3DS_TRUE); -} - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/background.h b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/background.h deleted file mode 100644 index b9c31c9bb..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/background.h +++ /dev/null @@ -1,85 +0,0 @@ -/* -*- c -*- */ -#ifndef INCLUDED_LIB3DS_BACKGROUND_H -#define INCLUDED_LIB3DS_BACKGROUND_H -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: background.h,v 1.8 2007/06/20 17:04:08 jeh Exp $ - */ - -#ifndef INCLUDED_LIB3DS_TYPES_H -#include "types.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Bitmap background settings - * \ingroup background - */ -typedef struct Lib3dsBitmap { - Lib3dsBool use; - char name[64]; -} Lib3dsBitmap; - -/** - * Solid color background settings - * \ingroup background - */ -typedef struct Lib3dsSolid { - Lib3dsBool use; - Lib3dsRgb col; -} Lib3dsSolid; - -/** - * Gradient background settings - * \ingroup background - */ -typedef struct Lib3dsGradient { - Lib3dsBool use; - Lib3dsFloat percent; - Lib3dsRgb top; - Lib3dsRgb middle; - Lib3dsRgb bottom; -} Lib3dsGradient; - -/** - * Background settings - * \ingroup background - */ -struct Lib3dsBackground { - Lib3dsBitmap bitmap; - Lib3dsSolid solid; - Lib3dsGradient gradient; -}; - -extern LIB3DSAPI Lib3dsBool lib3ds_background_read(Lib3dsBackground *background, Lib3dsIo *io); -extern LIB3DSAPI Lib3dsBool lib3ds_background_write(Lib3dsBackground *background, Lib3dsIo *io); - -#ifdef __cplusplus -} -#endif -#endif - - - - - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/camera.c b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/camera.c deleted file mode 100644 index beaaa0842..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/camera.c +++ /dev/null @@ -1,231 +0,0 @@ -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: camera.c,v 1.17 2007/06/20 17:04:08 jeh Exp $ - */ -#include "camera.h" -#include "chunk.h" -#include "io.h" -#include -#include -#include - - -/*! - * \defgroup camera Cameras - */ - - -/*! - * Return a new Lib3dsCamera object. - * - * Object is initialized with the given name and fov=45. All other - * values are 0. - * - * \param name Name of this camera. Must not be NULL. Must be < 64 characters. - * - * \return Lib3dsCamera object or NULL on failure. - * - * \ingroup camera - */ -Lib3dsCamera* -lib3ds_camera_new(const char *name) -{ - Lib3dsCamera *camera; - - ASSERT(name); - ASSERT(strlen(name)<64); - - camera=(Lib3dsCamera*)calloc(sizeof(Lib3dsCamera), 1); - if (!camera) { - return(0); - } - strcpy(camera->name, name); - camera->fov=45.0f; - return(camera); -} - - -/*! - * Free a Lib3dsCamera object and all of its resources. - * - * \param camera Lib3dsCamera object to be freed. - * - * \ingroup camera - */ -void -lib3ds_camera_free(Lib3dsCamera *camera) -{ - memset(camera, 0, sizeof(Lib3dsCamera)); - free(camera); -} - - -/*! - * Dump information about a Lib3dsCamera object to stdout. - * - * \param camera Object to be dumped. - * - * \see lib3ds_file_dump_cameras - * - * \ingroup camera - */ -void -lib3ds_camera_dump(Lib3dsCamera *camera) -{ - ASSERT(camera); - printf(" name: %s\n", camera->name); - printf(" position: (%f, %f, %f)\n", - camera->position[0], camera->position[1], camera->position[2]); - printf(" target (%f, %f, %f)\n", - camera->target[0], camera->target[1], camera->target[2]); - printf(" roll: %f\n", camera->roll); - printf(" fov: %f\n", camera->fov); - printf(" see_cone: %s\n", camera->see_cone ? "yes" : "no"); - printf(" near_range: %f\n", camera->near_range); - printf(" far_range: %f\n", camera->far_range); - printf("\n"); -} - - -/*! - * Read a camera definition from a file. - * - * This function is called by lib3ds_file_read(), and you probably - * don't want to call it directly. - * - * \param camera A Lib3dsCamera to be filled in. - * \param io A Lib3dsIo object previously set up by the caller. - * - * \return LIB3DS_TRUE on success, LIB3DS_FALSE on failure. - * - * \see lib3ds_file_read - * - * \ingroup camera - */ -Lib3dsBool -lib3ds_camera_read(Lib3dsCamera *camera, Lib3dsIo *io) -{ - Lib3dsChunk c; - Lib3dsWord chunk; - - if (!lib3ds_chunk_read_start(&c, LIB3DS_N_CAMERA, io)) { - return(LIB3DS_FALSE); - } - { - int i; - for (i=0; i<3; ++i) { - camera->position[i]=lib3ds_io_read_float(io); - } - for (i=0; i<3; ++i) { - camera->target[i]=lib3ds_io_read_float(io); - } - } - camera->roll=lib3ds_io_read_float(io); - { - float s; - s=lib3ds_io_read_float(io); - if (fabs(s)fov=45.0; - } - else { - camera->fov=2400.0f/s; - } - } - lib3ds_chunk_read_tell(&c, io); - - while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) { - switch (chunk) { - case LIB3DS_CAM_SEE_CONE: - { - camera->see_cone=LIB3DS_TRUE; - } - break; - case LIB3DS_CAM_RANGES: - { - camera->near_range=lib3ds_io_read_float(io); - camera->far_range=lib3ds_io_read_float(io); - } - break; - default: - lib3ds_chunk_unknown(chunk); - } - } - - lib3ds_chunk_read_end(&c, io); - return(LIB3DS_TRUE); -} - - -/*! - * Write a camera definition to a file. - * - * This function is called by lib3ds_file_write(), and you probably - * don't want to call it directly. - * - * \param camera A Lib3dsCamera to be written. - * \param io A Lib3dsIo object previously set up by the caller. - * - * \return LIB3DS_TRUE on success, LIB3DS_FALSE on failure. - * - * \see lib3ds_file_write - * - * \ingroup camera - */ -Lib3dsBool -lib3ds_camera_write(Lib3dsCamera *camera, Lib3dsIo *io) -{ - Lib3dsChunk c; - - c.chunk=LIB3DS_N_CAMERA; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - - lib3ds_io_write_vector(io, camera->position); - lib3ds_io_write_vector(io, camera->target); - lib3ds_io_write_float(io, camera->roll); - if (fabs(camera->fov)fov); - } - - if (camera->see_cone) { - Lib3dsChunk c; - c.chunk=LIB3DS_CAM_SEE_CONE; - c.size=6; - lib3ds_chunk_write(&c, io); - } - { - Lib3dsChunk c; - c.chunk=LIB3DS_CAM_RANGES; - c.size=14; - lib3ds_chunk_write(&c, io); - lib3ds_io_write_float(io, camera->near_range); - lib3ds_io_write_float(io, camera->far_range); - } - - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - return(LIB3DS_TRUE); -} - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/camera.h b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/camera.h deleted file mode 100644 index 29f0bf8a1..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/camera.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -*- c -*- */ -#ifndef INCLUDED_LIB3DS_CAMERA_H -#define INCLUDED_LIB3DS_CAMERA_H -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: camera.h,v 1.11 2007/06/20 17:04:08 jeh Exp $ - */ - -#ifndef INCLUDED_LIB3DS_TYPES_H -#include "types.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Camera object - * \ingroup camera - */ -struct Lib3dsCamera { - Lib3dsCamera *next; - char name[64]; - Lib3dsDword object_flags; /*< @see Lib3dsObjectFlags */ - Lib3dsVector position; - Lib3dsVector target; - Lib3dsFloat roll; - Lib3dsFloat fov; - Lib3dsBool see_cone; - Lib3dsFloat near_range; - Lib3dsFloat far_range; -}; - -extern LIB3DSAPI Lib3dsCamera* lib3ds_camera_new(const char *name); -extern LIB3DSAPI void lib3ds_camera_free(Lib3dsCamera *mesh); -extern LIB3DSAPI void lib3ds_camera_dump(Lib3dsCamera *camera); -extern LIB3DSAPI Lib3dsBool lib3ds_camera_read(Lib3dsCamera *camera, Lib3dsIo *io); -extern LIB3DSAPI Lib3dsBool lib3ds_camera_write(Lib3dsCamera *camera, Lib3dsIo *io); - -#ifdef __cplusplus -} -#endif -#endif - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/chunk.c b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/chunk.c deleted file mode 100644 index 30abed1a6..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/chunk.c +++ /dev/null @@ -1,317 +0,0 @@ -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: chunk.c,v 1.18 2007/06/20 17:04:08 jeh Exp $ - */ -#include "chunk.h" -#include "io.h" -#include "chunktable.h" -#include -#include - - -/*#define LIB3DS_CHUNK_DEBUG*/ -/*#define LIB3DS_CHUNK_WARNING*/ - - -/*! - * \defgroup chunk Chunk Handling - */ - - -static Lib3dsBool enable_dump=LIB3DS_FALSE; -static Lib3dsBool enable_unknown=LIB3DS_FALSE; -static char lib3ds_chunk_level[128]=""; - - -static void -lib3ds_chunk_debug_enter(Lib3dsChunk *c) -{ - strcat(lib3ds_chunk_level, " "); -} - - -static void -lib3ds_chunk_debug_leave(Lib3dsChunk *c) -{ - lib3ds_chunk_level[strlen(lib3ds_chunk_level)-2]=0; -} - - -static void -lib3ds_chunk_debug_dump(Lib3dsChunk *c) -{ - if (enable_dump) { - printf("%s%s (0x%X) size=%lu\n", - lib3ds_chunk_level, - lib3ds_chunk_name(c->chunk), - c->chunk, - c->size - ); - } -} - - -/*! - * \ingroup chunk - */ -void -lib3ds_chunk_enable_dump(Lib3dsBool enable, Lib3dsBool unknown) -{ - enable_dump=enable; - enable_unknown=unknown; -} - - -/*! - * \ingroup chunk - * - * Reads a 3d-Studio chunk header from a little endian file stream. - * - * \param c The chunk to store the data. - * \param io The file stream. - * - * \return True on success, False otherwise. - */ -Lib3dsBool -lib3ds_chunk_read(Lib3dsChunk *c, Lib3dsIo *io) -{ - ASSERT(c); - ASSERT(io); - c->cur=lib3ds_io_tell(io); - c->chunk=lib3ds_io_read_word(io); - c->size=lib3ds_io_read_dword(io); - c->end=c->cur+c->size; - c->cur+=6; - if (lib3ds_io_error(io) || (c->size<6)) { - return(LIB3DS_FALSE); - } - return(LIB3DS_TRUE); - -} - - -/*! - * \ingroup chunk - */ -Lib3dsBool -lib3ds_chunk_read_start(Lib3dsChunk *c, Lib3dsWord chunk, Lib3dsIo *io) -{ - ASSERT(c); - ASSERT(io); - if (!lib3ds_chunk_read(c, io)) { - return(LIB3DS_FALSE); - } - lib3ds_chunk_debug_enter(c); - return((chunk==0) || (c->chunk==chunk)); -} - - -/*! - * \ingroup chunk - */ -void -lib3ds_chunk_read_tell(Lib3dsChunk *c, Lib3dsIo *io) -{ - c->cur=lib3ds_io_tell(io); -} - - -/*! - * \ingroup chunk - */ -Lib3dsWord -lib3ds_chunk_read_next(Lib3dsChunk *c, Lib3dsIo *io) -{ - Lib3dsChunk d; - - if (c->cur>=c->end) { - ASSERT(c->cur==c->end); - return(0); - } - - lib3ds_io_seek(io, (long)c->cur, LIB3DS_SEEK_SET); - d.chunk=lib3ds_io_read_word(io); - d.size=lib3ds_io_read_dword(io); - lib3ds_chunk_debug_dump(&d); - c->cur+=d.size; - return(d.chunk); -} - - -/*! - * \ingroup chunk - */ -void -lib3ds_chunk_read_reset(Lib3dsChunk *c, Lib3dsIo *io) -{ - lib3ds_io_seek(io, -6, LIB3DS_SEEK_CUR); -} - - -/*! - * \ingroup chunk - */ -void -lib3ds_chunk_read_end(Lib3dsChunk *c, Lib3dsIo *io) -{ - lib3ds_chunk_debug_leave(c); - lib3ds_io_seek(io, c->end, LIB3DS_SEEK_SET); -} - - -/*! - * \ingroup chunk - * - * Writes a 3d-Studio chunk header into a little endian file stream. - * - * \param c The chunk to be written. - * \param io The file stream. - * - * \return True on success, False otherwise. - */ -Lib3dsBool -lib3ds_chunk_write(Lib3dsChunk *c, Lib3dsIo *io) -{ - ASSERT(c); - if (!lib3ds_io_write_word(io, c->chunk)) { - LIB3DS_ERROR_LOG; - return(LIB3DS_FALSE); - } - if (!lib3ds_io_write_dword(io, c->size)) { - LIB3DS_ERROR_LOG; - return(LIB3DS_FALSE); - } - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup chunk - */ -Lib3dsBool -lib3ds_chunk_write_start(Lib3dsChunk *c, Lib3dsIo *io) -{ - ASSERT(c); - c->size=0; - c->cur=lib3ds_io_tell(io); - if (!lib3ds_io_write_word(io, c->chunk)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_io_write_dword(io, c->size)) { - return(LIB3DS_FALSE); - } - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup chunk - */ -Lib3dsBool -lib3ds_chunk_write_end(Lib3dsChunk *c, Lib3dsIo *io) -{ - ASSERT(c); - c->size=lib3ds_io_tell(io) - c->cur; - lib3ds_io_seek(io, c->cur+2, LIB3DS_SEEK_SET); - if (!lib3ds_io_write_dword(io, c->size)) { - LIB3DS_ERROR_LOG; - return(LIB3DS_FALSE); - } - - c->cur+=c->size; - lib3ds_io_seek(io, c->cur, LIB3DS_SEEK_SET); - if (lib3ds_io_error(io)) { - LIB3DS_ERROR_LOG; - return(LIB3DS_FALSE); - } - return(LIB3DS_TRUE); -} - - -/*! -* \ingroup chunk -*/ -Lib3dsBool -lib3ds_chunk_write_switch(Lib3dsWord chunk, Lib3dsIo *io) -{ - Lib3dsChunk c; - c.chunk=chunk; - c.size=6; - return lib3ds_chunk_write(&c,io); -} - - -/*! - * \ingroup chunk - */ -const char* -lib3ds_chunk_name(Lib3dsWord chunk) -{ - Lib3dsChunkTable *p; - - for (p=lib3ds_chunk_table; p->name!=0; ++p) { - if (p->chunk==chunk) { - return(p->name); - } - } - return("***UNKNOWN***"); -} - - -/*! - * \ingroup chunk - */ -void -lib3ds_chunk_unknown(Lib3dsWord chunk) -{ - if (enable_unknown) { - printf("%s***WARNING*** Unknown Chunk: %s (0x%X)\n", - lib3ds_chunk_level, - lib3ds_chunk_name(chunk), - chunk - ); - } -} - - -/*! - * \ingroup chunk - */ -void -lib3ds_chunk_dump_info(const char *format, ...) -{ - if (enable_dump) { - char s[1024]; - va_list marker; - - va_start(marker, format); - vsprintf(s, format, marker); - va_end(marker); - - printf("%s%s\n", lib3ds_chunk_level, s); - } -} - - - - - - - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/chunk.h b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/chunk.h deleted file mode 100644 index 444725f60..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/chunk.h +++ /dev/null @@ -1,290 +0,0 @@ -/* -*- c -*- */ -#ifndef INCLUDED_LIB3DS_CHUNK_H -#define INCLUDED_LIB3DS_CHUNK_H -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: chunk.h,v 1.16 2007/06/20 17:04:08 jeh Exp $ - */ - -#ifndef INCLUDED_LIB3DS_TYPES_H -#include "types.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum _Lib3dsChunks { - LIB3DS_NULL_CHUNK =0x0000, - LIB3DS_M3DMAGIC =0x4D4D, /*3DS file*/ - LIB3DS_SMAGIC =0x2D2D, - LIB3DS_LMAGIC =0x2D3D, - LIB3DS_MLIBMAGIC =0x3DAA, /*MLI file*/ - LIB3DS_MATMAGIC =0x3DFF, - LIB3DS_CMAGIC =0xC23D, /*PRJ file*/ - LIB3DS_M3D_VERSION =0x0002, - LIB3DS_M3D_KFVERSION =0x0005, - - LIB3DS_COLOR_F =0x0010, - LIB3DS_COLOR_24 =0x0011, - LIB3DS_LIN_COLOR_24 =0x0012, - LIB3DS_LIN_COLOR_F =0x0013, - LIB3DS_INT_PERCENTAGE =0x0030, - LIB3DS_FLOAT_PERCENTAGE =0x0031, - - LIB3DS_MDATA =0x3D3D, - LIB3DS_MESH_VERSION =0x3D3E, - LIB3DS_MASTER_SCALE =0x0100, - LIB3DS_LO_SHADOW_BIAS =0x1400, - LIB3DS_HI_SHADOW_BIAS =0x1410, - LIB3DS_SHADOW_MAP_SIZE =0x1420, - LIB3DS_SHADOW_SAMPLES =0x1430, - LIB3DS_SHADOW_RANGE =0x1440, - LIB3DS_SHADOW_FILTER =0x1450, - LIB3DS_RAY_BIAS =0x1460, - LIB3DS_O_CONSTS =0x1500, - LIB3DS_AMBIENT_LIGHT =0x2100, - LIB3DS_BIT_MAP =0x1100, - LIB3DS_SOLID_BGND =0x1200, - LIB3DS_V_GRADIENT =0x1300, - LIB3DS_USE_BIT_MAP =0x1101, - LIB3DS_USE_SOLID_BGND =0x1201, - LIB3DS_USE_V_GRADIENT =0x1301, - LIB3DS_FOG =0x2200, - LIB3DS_FOG_BGND =0x2210, - LIB3DS_LAYER_FOG =0x2302, - LIB3DS_DISTANCE_CUE =0x2300, - LIB3DS_DCUE_BGND =0x2310, - LIB3DS_USE_FOG =0x2201, - LIB3DS_USE_LAYER_FOG =0x2303, - LIB3DS_USE_DISTANCE_CUE =0x2301, - - LIB3DS_MAT_ENTRY =0xAFFF, - LIB3DS_MAT_NAME =0xA000, - LIB3DS_MAT_AMBIENT =0xA010, - LIB3DS_MAT_DIFFUSE =0xA020, - LIB3DS_MAT_SPECULAR =0xA030, - LIB3DS_MAT_SHININESS =0xA040, - LIB3DS_MAT_SHIN2PCT =0xA041, - LIB3DS_MAT_TRANSPARENCY =0xA050, - LIB3DS_MAT_XPFALL =0xA052, - LIB3DS_MAT_USE_XPFALL =0xA240, - LIB3DS_MAT_REFBLUR =0xA053, - LIB3DS_MAT_SHADING =0xA100, - LIB3DS_MAT_USE_REFBLUR =0xA250, - LIB3DS_MAT_SELF_ILLUM =0xA080, - LIB3DS_MAT_TWO_SIDE =0xA081, - LIB3DS_MAT_DECAL =0xA082, - LIB3DS_MAT_ADDITIVE =0xA083, - LIB3DS_MAT_SELF_ILPCT =0xA084, - LIB3DS_MAT_WIRE =0xA085, - LIB3DS_MAT_FACEMAP =0xA088, - LIB3DS_MAT_PHONGSOFT =0xA08C, - LIB3DS_MAT_WIREABS =0xA08E, - LIB3DS_MAT_WIRE_SIZE =0xA087, - LIB3DS_MAT_TEXMAP =0xA200, - LIB3DS_MAT_SXP_TEXT_DATA =0xA320, - LIB3DS_MAT_TEXMASK =0xA33E, - LIB3DS_MAT_SXP_TEXTMASK_DATA =0xA32A, - LIB3DS_MAT_TEX2MAP =0xA33A, - LIB3DS_MAT_SXP_TEXT2_DATA =0xA321, - LIB3DS_MAT_TEX2MASK =0xA340, - LIB3DS_MAT_SXP_TEXT2MASK_DATA =0xA32C, - LIB3DS_MAT_OPACMAP =0xA210, - LIB3DS_MAT_SXP_OPAC_DATA =0xA322, - LIB3DS_MAT_OPACMASK =0xA342, - LIB3DS_MAT_SXP_OPACMASK_DATA =0xA32E, - LIB3DS_MAT_BUMPMAP =0xA230, - LIB3DS_MAT_SXP_BUMP_DATA =0xA324, - LIB3DS_MAT_BUMPMASK =0xA344, - LIB3DS_MAT_SXP_BUMPMASK_DATA =0xA330, - LIB3DS_MAT_SPECMAP =0xA204, - LIB3DS_MAT_SXP_SPEC_DATA =0xA325, - LIB3DS_MAT_SPECMASK =0xA348, - LIB3DS_MAT_SXP_SPECMASK_DATA =0xA332, - LIB3DS_MAT_SHINMAP =0xA33C, - LIB3DS_MAT_SXP_SHIN_DATA =0xA326, - LIB3DS_MAT_SHINMASK =0xA346, - LIB3DS_MAT_SXP_SHINMASK_DATA =0xA334, - LIB3DS_MAT_SELFIMAP =0xA33D, - LIB3DS_MAT_SXP_SELFI_DATA =0xA328, - LIB3DS_MAT_SELFIMASK =0xA34A, - LIB3DS_MAT_SXP_SELFIMASK_DATA =0xA336, - LIB3DS_MAT_REFLMAP =0xA220, - LIB3DS_MAT_REFLMASK =0xA34C, - LIB3DS_MAT_SXP_REFLMASK_DATA =0xA338, - LIB3DS_MAT_ACUBIC =0xA310, - LIB3DS_MAT_MAPNAME =0xA300, - LIB3DS_MAT_MAP_TILING =0xA351, - LIB3DS_MAT_MAP_TEXBLUR =0xA353, - LIB3DS_MAT_MAP_USCALE =0xA354, - LIB3DS_MAT_MAP_VSCALE =0xA356, - LIB3DS_MAT_MAP_UOFFSET =0xA358, - LIB3DS_MAT_MAP_VOFFSET =0xA35A, - LIB3DS_MAT_MAP_ANG =0xA35C, - LIB3DS_MAT_MAP_COL1 =0xA360, - LIB3DS_MAT_MAP_COL2 =0xA362, - LIB3DS_MAT_MAP_RCOL =0xA364, - LIB3DS_MAT_MAP_GCOL =0xA366, - LIB3DS_MAT_MAP_BCOL =0xA368, - - LIB3DS_NAMED_OBJECT =0x4000, - LIB3DS_N_DIRECT_LIGHT =0x4600, - LIB3DS_DL_OFF =0x4620, - LIB3DS_DL_OUTER_RANGE =0x465A, - LIB3DS_DL_INNER_RANGE =0x4659, - LIB3DS_DL_MULTIPLIER =0x465B, - LIB3DS_DL_EXCLUDE =0x4654, - LIB3DS_DL_ATTENUATE =0x4625, - LIB3DS_DL_SPOTLIGHT =0x4610, - LIB3DS_DL_SPOT_ROLL =0x4656, - LIB3DS_DL_SHADOWED =0x4630, - LIB3DS_DL_LOCAL_SHADOW2 =0x4641, - LIB3DS_DL_SEE_CONE =0x4650, - LIB3DS_DL_SPOT_RECTANGULAR =0x4651, - LIB3DS_DL_SPOT_ASPECT =0x4657, - LIB3DS_DL_SPOT_PROJECTOR =0x4653, - LIB3DS_DL_SPOT_OVERSHOOT =0x4652, - LIB3DS_DL_RAY_BIAS =0x4658, - LIB3DS_DL_RAYSHAD =0x4627, - LIB3DS_N_CAMERA =0x4700, - LIB3DS_CAM_SEE_CONE =0x4710, - LIB3DS_CAM_RANGES =0x4720, - LIB3DS_OBJ_HIDDEN =0x4010, - LIB3DS_OBJ_VIS_LOFTER =0x4011, - LIB3DS_OBJ_DOESNT_CAST =0x4012, - LIB3DS_OBJ_DONT_RCVSHADOW =0x4017, - LIB3DS_OBJ_MATTE =0x4013, - LIB3DS_OBJ_FAST =0x4014, - LIB3DS_OBJ_PROCEDURAL =0x4015, - LIB3DS_OBJ_FROZEN =0x4016, - LIB3DS_N_TRI_OBJECT =0x4100, - LIB3DS_POINT_ARRAY =0x4110, - LIB3DS_POINT_FLAG_ARRAY =0x4111, - LIB3DS_FACE_ARRAY =0x4120, - LIB3DS_MSH_MAT_GROUP =0x4130, - LIB3DS_SMOOTH_GROUP =0x4150, - LIB3DS_MSH_BOXMAP =0x4190, - LIB3DS_TEX_VERTS =0x4140, - LIB3DS_MESH_MATRIX =0x4160, - LIB3DS_MESH_COLOR =0x4165, - LIB3DS_MESH_TEXTURE_INFO =0x4170, - - LIB3DS_KFDATA =0xB000, - LIB3DS_KFHDR =0xB00A, - LIB3DS_KFSEG =0xB008, - LIB3DS_KFCURTIME =0xB009, - LIB3DS_AMBIENT_NODE_TAG =0xB001, - LIB3DS_OBJECT_NODE_TAG =0xB002, - LIB3DS_CAMERA_NODE_TAG =0xB003, - LIB3DS_TARGET_NODE_TAG =0xB004, - LIB3DS_LIGHT_NODE_TAG =0xB005, - LIB3DS_L_TARGET_NODE_TAG =0xB006, - LIB3DS_SPOTLIGHT_NODE_TAG =0xB007, - LIB3DS_NODE_ID =0xB030, - LIB3DS_NODE_HDR =0xB010, - LIB3DS_PIVOT =0xB013, - LIB3DS_INSTANCE_NAME =0xB011, - LIB3DS_MORPH_SMOOTH =0xB015, - LIB3DS_BOUNDBOX =0xB014, - LIB3DS_POS_TRACK_TAG =0xB020, - LIB3DS_COL_TRACK_TAG =0xB025, - LIB3DS_ROT_TRACK_TAG =0xB021, - LIB3DS_SCL_TRACK_TAG =0xB022, - LIB3DS_MORPH_TRACK_TAG =0xB026, - LIB3DS_FOV_TRACK_TAG =0xB023, - LIB3DS_ROLL_TRACK_TAG =0xB024, - LIB3DS_HOT_TRACK_TAG =0xB027, - LIB3DS_FALL_TRACK_TAG =0xB028, - LIB3DS_HIDE_TRACK_TAG =0xB029, - - LIB3DS_POLY_2D = 0x5000, - LIB3DS_SHAPE_OK = 0x5010, - LIB3DS_SHAPE_NOT_OK = 0x5011, - LIB3DS_SHAPE_HOOK = 0x5020, - LIB3DS_PATH_3D = 0x6000, - LIB3DS_PATH_MATRIX = 0x6005, - LIB3DS_SHAPE_2D = 0x6010, - LIB3DS_M_SCALE = 0x6020, - LIB3DS_M_TWIST = 0x6030, - LIB3DS_M_TEETER = 0x6040, - LIB3DS_M_FIT = 0x6050, - LIB3DS_M_BEVEL = 0x6060, - LIB3DS_XZ_CURVE = 0x6070, - LIB3DS_YZ_CURVE = 0x6080, - LIB3DS_INTERPCT = 0x6090, - LIB3DS_DEFORM_LIMIT = 0x60A0, - - LIB3DS_USE_CONTOUR = 0x6100, - LIB3DS_USE_TWEEN = 0x6110, - LIB3DS_USE_SCALE = 0x6120, - LIB3DS_USE_TWIST = 0x6130, - LIB3DS_USE_TEETER = 0x6140, - LIB3DS_USE_FIT = 0x6150, - LIB3DS_USE_BEVEL = 0x6160, - - LIB3DS_DEFAULT_VIEW = 0x3000, - LIB3DS_VIEW_TOP = 0x3010, - LIB3DS_VIEW_BOTTOM = 0x3020, - LIB3DS_VIEW_LEFT = 0x3030, - LIB3DS_VIEW_RIGHT = 0x3040, - LIB3DS_VIEW_FRONT = 0x3050, - LIB3DS_VIEW_BACK = 0x3060, - LIB3DS_VIEW_USER = 0x3070, - LIB3DS_VIEW_CAMERA = 0x3080, - LIB3DS_VIEW_WINDOW = 0x3090, - - LIB3DS_VIEWPORT_LAYOUT_OLD = 0x7000, - LIB3DS_VIEWPORT_DATA_OLD = 0x7010, - LIB3DS_VIEWPORT_LAYOUT = 0x7001, - LIB3DS_VIEWPORT_DATA = 0x7011, - LIB3DS_VIEWPORT_DATA_3 = 0x7012, - LIB3DS_VIEWPORT_SIZE = 0x7020, - LIB3DS_NETWORK_VIEW = 0x7030 -} Lib3dsChunks; - -typedef struct Lib3dsChunk { - Lib3dsWord chunk; - Lib3dsDword size; - Lib3dsDword end; - Lib3dsDword cur; -} Lib3dsChunk; - -extern LIB3DSAPI void lib3ds_chunk_enable_dump(Lib3dsBool enable, Lib3dsBool unknown); -extern LIB3DSAPI Lib3dsBool lib3ds_chunk_read(Lib3dsChunk *c, Lib3dsIo *io); -extern LIB3DSAPI Lib3dsBool lib3ds_chunk_read_start(Lib3dsChunk *c, Lib3dsWord chunk, Lib3dsIo *io); -extern LIB3DSAPI void lib3ds_chunk_read_tell(Lib3dsChunk *c, Lib3dsIo *io); -extern LIB3DSAPI Lib3dsWord lib3ds_chunk_read_next(Lib3dsChunk *c, Lib3dsIo *io); -extern LIB3DSAPI void lib3ds_chunk_read_reset(Lib3dsChunk *c, Lib3dsIo *io); -extern LIB3DSAPI void lib3ds_chunk_read_end(Lib3dsChunk *c, Lib3dsIo *io); -extern LIB3DSAPI Lib3dsBool lib3ds_chunk_write(Lib3dsChunk *c, Lib3dsIo *io); -extern LIB3DSAPI Lib3dsBool lib3ds_chunk_write_start(Lib3dsChunk *c, Lib3dsIo *io); -extern LIB3DSAPI Lib3dsBool lib3ds_chunk_write_end(Lib3dsChunk *c, Lib3dsIo *io); -extern LIB3DSAPI Lib3dsBool lib3ds_chunk_write_switch(Lib3dsWord chunk, Lib3dsIo *io); -extern LIB3DSAPI const char* lib3ds_chunk_name(Lib3dsWord chunk); -extern LIB3DSAPI void lib3ds_chunk_unknown(Lib3dsWord chunk); -extern LIB3DSAPI void lib3ds_chunk_dump_info(const char *format, ...); - -#ifdef __cplusplus -} -#endif -#endif - - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/chunktable.h b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/chunktable.h deleted file mode 100644 index dc71f708b..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/chunktable.h +++ /dev/null @@ -1,264 +0,0 @@ -/* -*- c -*- */ -#ifndef INCLUDED_LIB3DS_CHUNKTABLE_H -#define INCLUDED_LIB3DS_CHUNKTABLE_H -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: chunktable.h,v 1.16 2007/06/20 17:04:08 jeh Exp $ - */ - -#ifndef INCLUDED_LIB3DS_CHUNK_H -#include "chunk.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct Lib3dsChunkTable { - Lib3dsDword chunk; - const char* name; -} Lib3dsChunkTable; - -static Lib3dsChunkTable lib3ds_chunk_table[]={ - {LIB3DS_NULL_CHUNK, "LIB3DS_NULL_CHUNK"}, - {LIB3DS_M3DMAGIC, "LIB3DS_M3DMAGIC"}, - {LIB3DS_SMAGIC, "LIB3DS_SMAGIC"}, - {LIB3DS_LMAGIC, "LIB3DS_LMAGIC"}, - {LIB3DS_MLIBMAGIC, "LIB3DS_MLIBMAGIC"}, - {LIB3DS_MATMAGIC, "LIB3DS_MATMAGIC"}, - {LIB3DS_CMAGIC, "LIB3DS_CMAGIC"}, - {LIB3DS_M3D_VERSION, "LIB3DS_M3D_VERSION"}, - {LIB3DS_M3D_KFVERSION, "LIB3DS_M3D_KFVERSION"}, - {LIB3DS_COLOR_F, "LIB3DS_COLOR_F"}, - {LIB3DS_COLOR_24, "LIB3DS_COLOR_24"}, - {LIB3DS_LIN_COLOR_24, "LIB3DS_LIN_COLOR_24"}, - {LIB3DS_LIN_COLOR_F, "LIB3DS_LIN_COLOR_F"}, - {LIB3DS_INT_PERCENTAGE, "LIB3DS_INT_PERCENTAGE"}, - {LIB3DS_FLOAT_PERCENTAGE, "LIB3DS_FLOAT_PERCENTAGE"}, - {LIB3DS_MDATA, "LIB3DS_MDATA"}, - {LIB3DS_MESH_VERSION, "LIB3DS_MESH_VERSION"}, - {LIB3DS_MASTER_SCALE, "LIB3DS_MASTER_SCALE"}, - {LIB3DS_LO_SHADOW_BIAS, "LIB3DS_LO_SHADOW_BIAS"}, - {LIB3DS_HI_SHADOW_BIAS, "LIB3DS_HI_SHADOW_BIAS"}, - {LIB3DS_SHADOW_MAP_SIZE, "LIB3DS_SHADOW_MAP_SIZE"}, - {LIB3DS_SHADOW_SAMPLES, "LIB3DS_SHADOW_SAMPLES"}, - {LIB3DS_SHADOW_RANGE, "LIB3DS_SHADOW_RANGE"}, - {LIB3DS_SHADOW_FILTER, "LIB3DS_SHADOW_FILTER"}, - {LIB3DS_RAY_BIAS, "LIB3DS_RAY_BIAS"}, - {LIB3DS_O_CONSTS, "LIB3DS_O_CONSTS"}, - {LIB3DS_AMBIENT_LIGHT, "LIB3DS_AMBIENT_LIGHT"}, - {LIB3DS_BIT_MAP, "LIB3DS_BIT_MAP"}, - {LIB3DS_SOLID_BGND, "LIB3DS_SOLID_BGND"}, - {LIB3DS_V_GRADIENT, "LIB3DS_V_GRADIENT"}, - {LIB3DS_USE_BIT_MAP, "LIB3DS_USE_BIT_MAP"}, - {LIB3DS_USE_SOLID_BGND, "LIB3DS_USE_SOLID_BGND"}, - {LIB3DS_USE_V_GRADIENT, "LIB3DS_USE_V_GRADIENT"}, - {LIB3DS_FOG, "LIB3DS_FOG"}, - {LIB3DS_FOG_BGND, "LIB3DS_FOG_BGND"}, - {LIB3DS_LAYER_FOG, "LIB3DS_LAYER_FOG"}, - {LIB3DS_DISTANCE_CUE, "LIB3DS_DISTANCE_CUE"}, - {LIB3DS_DCUE_BGND, "LIB3DS_DCUE_BGND"}, - {LIB3DS_USE_FOG, "LIB3DS_USE_FOG"}, - {LIB3DS_USE_LAYER_FOG, "LIB3DS_USE_LAYER_FOG"}, - {LIB3DS_USE_DISTANCE_CUE, "LIB3DS_USE_DISTANCE_CUE"}, - {LIB3DS_MAT_ENTRY, "LIB3DS_MAT_ENTRY"}, - {LIB3DS_MAT_NAME, "LIB3DS_MAT_NAME"}, - {LIB3DS_MAT_AMBIENT, "LIB3DS_MAT_AMBIENT"}, - {LIB3DS_MAT_DIFFUSE, "LIB3DS_MAT_DIFFUSE"}, - {LIB3DS_MAT_SPECULAR, "LIB3DS_MAT_SPECULAR"}, - {LIB3DS_MAT_SHININESS, "LIB3DS_MAT_SHININESS"}, - {LIB3DS_MAT_SHIN2PCT, "LIB3DS_MAT_SHIN2PCT"}, - {LIB3DS_MAT_TRANSPARENCY, "LIB3DS_MAT_TRANSPARENCY"}, - {LIB3DS_MAT_XPFALL, "LIB3DS_MAT_XPFALL"}, - {LIB3DS_MAT_USE_XPFALL, "LIB3DS_MAT_USE_XPFALL"}, - {LIB3DS_MAT_REFBLUR, "LIB3DS_MAT_REFBLUR"}, - {LIB3DS_MAT_SHADING, "LIB3DS_MAT_SHADING"}, - {LIB3DS_MAT_USE_REFBLUR, "LIB3DS_MAT_USE_REFBLUR"}, - {LIB3DS_MAT_SELF_ILLUM, "LIB3DS_MAT_SELF_ILLUM"}, - {LIB3DS_MAT_TWO_SIDE, "LIB3DS_MAT_TWO_SIDE"}, - {LIB3DS_MAT_DECAL, "LIB3DS_MAT_DECAL"}, - {LIB3DS_MAT_ADDITIVE, "LIB3DS_MAT_ADDITIVE"}, - {LIB3DS_MAT_SELF_ILPCT, "LIB3DS_MAT_SELF_ILPCT"}, - {LIB3DS_MAT_WIRE, "LIB3DS_MAT_WIRE"}, - {LIB3DS_MAT_FACEMAP, "LIB3DS_MAT_FACEMAP"}, - {LIB3DS_MAT_PHONGSOFT, "LIB3DS_MAT_PHONGSOFT"}, - {LIB3DS_MAT_WIREABS, "LIB3DS_MAT_WIREABS"}, - {LIB3DS_MAT_WIRE_SIZE, "LIB3DS_MAT_WIRE_SIZE"}, - {LIB3DS_MAT_TEXMAP, "LIB3DS_MAT_TEXMAP"}, - {LIB3DS_MAT_SXP_TEXT_DATA, "LIB3DS_MAT_SXP_TEXT_DATA"}, - {LIB3DS_MAT_TEXMASK, "LIB3DS_MAT_TEXMASK"}, - {LIB3DS_MAT_SXP_TEXTMASK_DATA, "LIB3DS_MAT_SXP_TEXTMASK_DATA"}, - {LIB3DS_MAT_TEX2MAP, "LIB3DS_MAT_TEX2MAP"}, - {LIB3DS_MAT_SXP_TEXT2_DATA, "LIB3DS_MAT_SXP_TEXT2_DATA"}, - {LIB3DS_MAT_TEX2MASK, "LIB3DS_MAT_TEX2MASK"}, - {LIB3DS_MAT_SXP_TEXT2MASK_DATA, "LIB3DS_MAT_SXP_TEXT2MASK_DATA"}, - {LIB3DS_MAT_OPACMAP, "LIB3DS_MAT_OPACMAP"}, - {LIB3DS_MAT_SXP_OPAC_DATA, "LIB3DS_MAT_SXP_OPAC_DATA"}, - {LIB3DS_MAT_OPACMASK, "LIB3DS_MAT_OPACMASK"}, - {LIB3DS_MAT_SXP_OPACMASK_DATA, "LIB3DS_MAT_SXP_OPACMASK_DATA"}, - {LIB3DS_MAT_BUMPMAP, "LIB3DS_MAT_BUMPMAP"}, - {LIB3DS_MAT_SXP_BUMP_DATA, "LIB3DS_MAT_SXP_BUMP_DATA"}, - {LIB3DS_MAT_BUMPMASK, "LIB3DS_MAT_BUMPMASK"}, - {LIB3DS_MAT_SXP_BUMPMASK_DATA, "LIB3DS_MAT_SXP_BUMPMASK_DATA"}, - {LIB3DS_MAT_SPECMAP, "LIB3DS_MAT_SPECMAP"}, - {LIB3DS_MAT_SXP_SPEC_DATA, "LIB3DS_MAT_SXP_SPEC_DATA"}, - {LIB3DS_MAT_SPECMASK, "LIB3DS_MAT_SPECMASK"}, - {LIB3DS_MAT_SXP_SPECMASK_DATA, "LIB3DS_MAT_SXP_SPECMASK_DATA"}, - {LIB3DS_MAT_SHINMAP, "LIB3DS_MAT_SHINMAP"}, - {LIB3DS_MAT_SXP_SHIN_DATA, "LIB3DS_MAT_SXP_SHIN_DATA"}, - {LIB3DS_MAT_SHINMASK, "LIB3DS_MAT_SHINMASK"}, - {LIB3DS_MAT_SXP_SHINMASK_DATA, "LIB3DS_MAT_SXP_SHINMASK_DATA"}, - {LIB3DS_MAT_SELFIMAP, "LIB3DS_MAT_SELFIMAP"}, - {LIB3DS_MAT_SXP_SELFI_DATA, "LIB3DS_MAT_SXP_SELFI_DATA"}, - {LIB3DS_MAT_SELFIMASK, "LIB3DS_MAT_SELFIMASK"}, - {LIB3DS_MAT_SXP_SELFIMASK_DATA, "LIB3DS_MAT_SXP_SELFIMASK_DATA"}, - {LIB3DS_MAT_REFLMAP, "LIB3DS_MAT_REFLMAP"}, - {LIB3DS_MAT_REFLMASK, "LIB3DS_MAT_REFLMASK"}, - {LIB3DS_MAT_SXP_REFLMASK_DATA, "LIB3DS_MAT_SXP_REFLMASK_DATA"}, - {LIB3DS_MAT_ACUBIC, "LIB3DS_MAT_ACUBIC"}, - {LIB3DS_MAT_MAPNAME, "LIB3DS_MAT_MAPNAME"}, - {LIB3DS_MAT_MAP_TILING, "LIB3DS_MAT_MAP_TILING"}, - {LIB3DS_MAT_MAP_TEXBLUR, "LIB3DS_MAT_MAP_TEXBLUR"}, - {LIB3DS_MAT_MAP_USCALE, "LIB3DS_MAT_MAP_USCALE"}, - {LIB3DS_MAT_MAP_VSCALE, "LIB3DS_MAT_MAP_VSCALE"}, - {LIB3DS_MAT_MAP_UOFFSET, "LIB3DS_MAT_MAP_UOFFSET"}, - {LIB3DS_MAT_MAP_VOFFSET, "LIB3DS_MAT_MAP_VOFFSET"}, - {LIB3DS_MAT_MAP_ANG, "LIB3DS_MAT_MAP_ANG"}, - {LIB3DS_MAT_MAP_COL1, "LIB3DS_MAT_MAP_COL1"}, - {LIB3DS_MAT_MAP_COL2, "LIB3DS_MAT_MAP_COL2"}, - {LIB3DS_MAT_MAP_RCOL, "LIB3DS_MAT_MAP_RCOL"}, - {LIB3DS_MAT_MAP_GCOL, "LIB3DS_MAT_MAP_GCOL"}, - {LIB3DS_MAT_MAP_BCOL, "LIB3DS_MAT_MAP_BCOL"}, - {LIB3DS_NAMED_OBJECT, "LIB3DS_NAMED_OBJECT"}, - {LIB3DS_N_DIRECT_LIGHT, "LIB3DS_N_DIRECT_LIGHT"}, - {LIB3DS_DL_OFF, "LIB3DS_DL_OFF"}, - {LIB3DS_DL_OUTER_RANGE, "LIB3DS_DL_OUTER_RANGE"}, - {LIB3DS_DL_INNER_RANGE, "LIB3DS_DL_INNER_RANGE"}, - {LIB3DS_DL_MULTIPLIER, "LIB3DS_DL_MULTIPLIER"}, - {LIB3DS_DL_EXCLUDE, "LIB3DS_DL_EXCLUDE"}, - {LIB3DS_DL_ATTENUATE, "LIB3DS_DL_ATTENUATE"}, - {LIB3DS_DL_SPOTLIGHT, "LIB3DS_DL_SPOTLIGHT"}, - {LIB3DS_DL_SPOT_ROLL, "LIB3DS_DL_SPOT_ROLL"}, - {LIB3DS_DL_SHADOWED, "LIB3DS_DL_SHADOWED"}, - {LIB3DS_DL_LOCAL_SHADOW2, "LIB3DS_DL_LOCAL_SHADOW2"}, - {LIB3DS_DL_SEE_CONE, "LIB3DS_DL_SEE_CONE"}, - {LIB3DS_DL_SPOT_RECTANGULAR, "LIB3DS_DL_SPOT_RECTANGULAR"}, - {LIB3DS_DL_SPOT_ASPECT, "LIB3DS_DL_SPOT_ASPECT"}, - {LIB3DS_DL_SPOT_PROJECTOR, "LIB3DS_DL_SPOT_PROJECTOR"}, - {LIB3DS_DL_SPOT_OVERSHOOT, "LIB3DS_DL_SPOT_OVERSHOOT"}, - {LIB3DS_DL_RAY_BIAS, "LIB3DS_DL_RAY_BIAS"}, - {LIB3DS_DL_RAYSHAD, "LIB3DS_DL_RAYSHAD"}, - {LIB3DS_N_CAMERA, "LIB3DS_N_CAMERA"}, - {LIB3DS_CAM_SEE_CONE, "LIB3DS_CAM_SEE_CONE"}, - {LIB3DS_CAM_RANGES, "LIB3DS_CAM_RANGES"}, - {LIB3DS_OBJ_HIDDEN, "LIB3DS_OBJ_HIDDEN"}, - {LIB3DS_OBJ_VIS_LOFTER, "LIB3DS_OBJ_VIS_LOFTER"}, - {LIB3DS_OBJ_DOESNT_CAST, "LIB3DS_OBJ_DOESNT_CAST"}, - {LIB3DS_OBJ_DONT_RCVSHADOW, "LIB3DS_OBJ_DONT_RCVSHADOW"}, - {LIB3DS_OBJ_MATTE, "LIB3DS_OBJ_MATTE"}, - {LIB3DS_OBJ_FAST, "LIB3DS_OBJ_FAST"}, - {LIB3DS_OBJ_PROCEDURAL, "LIB3DS_OBJ_PROCEDURAL"}, - {LIB3DS_OBJ_FROZEN, "LIB3DS_OBJ_FROZEN"}, - {LIB3DS_N_TRI_OBJECT, "LIB3DS_N_TRI_OBJECT"}, - {LIB3DS_POINT_ARRAY, "LIB3DS_POINT_ARRAY"}, - {LIB3DS_POINT_FLAG_ARRAY, "LIB3DS_POINT_FLAG_ARRAY"}, - {LIB3DS_FACE_ARRAY, "LIB3DS_FACE_ARRAY"}, - {LIB3DS_MSH_MAT_GROUP, "LIB3DS_MSH_MAT_GROUP"}, - {LIB3DS_SMOOTH_GROUP, "LIB3DS_SMOOTH_GROUP"}, - {LIB3DS_MSH_BOXMAP, "LIB3DS_MSH_BOXMAP"}, - {LIB3DS_TEX_VERTS, "LIB3DS_TEX_VERTS"}, - {LIB3DS_MESH_MATRIX, "LIB3DS_MESH_MATRIX"}, - {LIB3DS_MESH_COLOR, "LIB3DS_MESH_COLOR"}, - {LIB3DS_MESH_TEXTURE_INFO, "LIB3DS_MESH_TEXTURE_INFO"}, - {LIB3DS_KFDATA, "LIB3DS_KFDATA"}, - {LIB3DS_KFHDR, "LIB3DS_KFHDR"}, - {LIB3DS_KFSEG, "LIB3DS_KFSEG"}, - {LIB3DS_KFCURTIME, "LIB3DS_KFCURTIME"}, - {LIB3DS_AMBIENT_NODE_TAG, "LIB3DS_AMBIENT_NODE_TAG"}, - {LIB3DS_OBJECT_NODE_TAG, "LIB3DS_OBJECT_NODE_TAG"}, - {LIB3DS_CAMERA_NODE_TAG, "LIB3DS_CAMERA_NODE_TAG"}, - {LIB3DS_TARGET_NODE_TAG, "LIB3DS_TARGET_NODE_TAG"}, - {LIB3DS_LIGHT_NODE_TAG, "LIB3DS_LIGHT_NODE_TAG"}, - {LIB3DS_L_TARGET_NODE_TAG, "LIB3DS_L_TARGET_NODE_TAG"}, - {LIB3DS_SPOTLIGHT_NODE_TAG, "LIB3DS_SPOTLIGHT_NODE_TAG"}, - {LIB3DS_NODE_ID, "LIB3DS_NODE_ID"}, - {LIB3DS_NODE_HDR, "LIB3DS_NODE_HDR"}, - {LIB3DS_PIVOT, "LIB3DS_PIVOT"}, - {LIB3DS_INSTANCE_NAME, "LIB3DS_INSTANCE_NAME"}, - {LIB3DS_MORPH_SMOOTH, "LIB3DS_MORPH_SMOOTH"}, - {LIB3DS_BOUNDBOX, "LIB3DS_BOUNDBOX"}, - {LIB3DS_POS_TRACK_TAG, "LIB3DS_POS_TRACK_TAG"}, - {LIB3DS_COL_TRACK_TAG, "LIB3DS_COL_TRACK_TAG"}, - {LIB3DS_ROT_TRACK_TAG, "LIB3DS_ROT_TRACK_TAG"}, - {LIB3DS_SCL_TRACK_TAG, "LIB3DS_SCL_TRACK_TAG"}, - {LIB3DS_MORPH_TRACK_TAG, "LIB3DS_MORPH_TRACK_TAG"}, - {LIB3DS_FOV_TRACK_TAG, "LIB3DS_FOV_TRACK_TAG"}, - {LIB3DS_ROLL_TRACK_TAG, "LIB3DS_ROLL_TRACK_TAG"}, - {LIB3DS_HOT_TRACK_TAG, "LIB3DS_HOT_TRACK_TAG"}, - {LIB3DS_FALL_TRACK_TAG, "LIB3DS_FALL_TRACK_TAG"}, - {LIB3DS_HIDE_TRACK_TAG, "LIB3DS_HIDE_TRACK_TAG"}, - {LIB3DS_POLY_2D, "LIB3DS_POLY_2D"}, - {LIB3DS_SHAPE_OK, "LIB3DS_SHAPE_OK"}, - {LIB3DS_SHAPE_NOT_OK, "LIB3DS_SHAPE_NOT_OK"}, - {LIB3DS_SHAPE_HOOK, "LIB3DS_SHAPE_HOOK"}, - {LIB3DS_PATH_3D, "LIB3DS_PATH_3D"}, - {LIB3DS_PATH_MATRIX, "LIB3DS_PATH_MATRIX"}, - {LIB3DS_SHAPE_2D, "LIB3DS_SHAPE_2D"}, - {LIB3DS_M_SCALE, "LIB3DS_M_SCALE"}, - {LIB3DS_M_TWIST, "LIB3DS_M_TWIST"}, - {LIB3DS_M_TEETER, "LIB3DS_M_TEETER"}, - {LIB3DS_M_FIT, "LIB3DS_M_FIT"}, - {LIB3DS_M_BEVEL, "LIB3DS_M_BEVEL"}, - {LIB3DS_XZ_CURVE, "LIB3DS_XZ_CURVE"}, - {LIB3DS_YZ_CURVE, "LIB3DS_YZ_CURVE"}, - {LIB3DS_INTERPCT, "LIB3DS_INTERPCT"}, - {LIB3DS_DEFORM_LIMIT, "LIB3DS_DEFORM_LIMIT"}, - {LIB3DS_USE_CONTOUR, "LIB3DS_USE_CONTOUR"}, - {LIB3DS_USE_TWEEN, "LIB3DS_USE_TWEEN"}, - {LIB3DS_USE_SCALE, "LIB3DS_USE_SCALE"}, - {LIB3DS_USE_TWIST, "LIB3DS_USE_TWIST"}, - {LIB3DS_USE_TEETER, "LIB3DS_USE_TEETER"}, - {LIB3DS_USE_FIT, "LIB3DS_USE_FIT"}, - {LIB3DS_USE_BEVEL, "LIB3DS_USE_BEVEL"}, - {LIB3DS_DEFAULT_VIEW, "LIB3DS_DEFAULT_VIEW"}, - {LIB3DS_VIEW_TOP, "LIB3DS_VIEW_TOP"}, - {LIB3DS_VIEW_BOTTOM, "LIB3DS_VIEW_BOTTOM"}, - {LIB3DS_VIEW_LEFT, "LIB3DS_VIEW_LEFT"}, - {LIB3DS_VIEW_RIGHT, "LIB3DS_VIEW_RIGHT"}, - {LIB3DS_VIEW_FRONT, "LIB3DS_VIEW_FRONT"}, - {LIB3DS_VIEW_BACK, "LIB3DS_VIEW_BACK"}, - {LIB3DS_VIEW_USER, "LIB3DS_VIEW_USER"}, - {LIB3DS_VIEW_CAMERA, "LIB3DS_VIEW_CAMERA"}, - {LIB3DS_VIEW_WINDOW, "LIB3DS_VIEW_WINDOW"}, - {LIB3DS_VIEWPORT_LAYOUT_OLD, "LIB3DS_VIEWPORT_LAYOUT_OLD"}, - {LIB3DS_VIEWPORT_DATA_OLD, "LIB3DS_VIEWPORT_DATA_OLD"}, - {LIB3DS_VIEWPORT_LAYOUT, "LIB3DS_VIEWPORT_LAYOUT"}, - {LIB3DS_VIEWPORT_DATA, "LIB3DS_VIEWPORT_DATA"}, - {LIB3DS_VIEWPORT_DATA_3, "LIB3DS_VIEWPORT_DATA_3"}, - {LIB3DS_VIEWPORT_SIZE, "LIB3DS_VIEWPORT_SIZE"}, - {LIB3DS_NETWORK_VIEW, "LIB3DS_NETWORK_VIEW"}, - {0,0} -}; - -#ifdef __cplusplus -} -#endif -#endif - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/ease.c b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/ease.c deleted file mode 100644 index 349900f5b..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/ease.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: ease.c,v 1.6 2007/06/15 09:33:19 jeh Exp $ - */ -#include "ease.h" - - -/*! - * \defgroup ease Ease - */ - - -/*! - * \ingroup ease - */ -Lib3dsFloat -lib3ds_ease(Lib3dsFloat fp, Lib3dsFloat fc, Lib3dsFloat fn, - Lib3dsFloat ease_from, Lib3dsFloat ease_to) -{ - Lib3dsDouble s,step; - Lib3dsDouble tofrom; - Lib3dsDouble a; - - s=step=(Lib3dsFloat)(fc-fp)/(fn-fp); - tofrom=ease_to+ease_from; - if (tofrom!=0.0) { - if (tofrom>1.0) { - ease_to=(Lib3dsFloat)(ease_to/tofrom); - ease_from=(Lib3dsFloat)(ease_from/tofrom); - } - a=1.0/(2.0-(ease_to+ease_from)); - - if (step - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: ease.h,v 1.6 2007/06/14 09:59:10 jeh Exp $ - */ - -#ifndef INCLUDED_LIB3DS_TYPES_H -#include "types.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -extern LIB3DSAPI Lib3dsFloat lib3ds_ease(Lib3dsFloat fp, Lib3dsFloat fc, - Lib3dsFloat fn, Lib3dsFloat ease_from, Lib3dsFloat ease_to); - -#ifdef __cplusplus -} -#endif -#endif - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/file.c b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/file.c deleted file mode 100644 index 97b052490..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/file.c +++ /dev/null @@ -1,2028 +0,0 @@ -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: file.c,v 1.34 2007/06/20 17:04:08 jeh Exp $ - */ -#include "file.h" -#include "chunk.h" -#include "io.h" -#include "material.h" -#include "mesh.h" -#include "camera.h" -#include "light.h" -#include "node.h" -#include "matrix.h" -#include "vector.h" -#include -#include -#include -#include - - -/*! - * \defgroup file Files - */ - - -static Lib3dsBool -fileio_error_func(void *self) -{ - FILE *f = (FILE*)self; - return(ferror(f)!=0); -} - - -static long -fileio_seek_func(void *self, long offset, Lib3dsIoSeek origin) -{ - FILE *f = (FILE*)self; - int o; - switch (origin) { - case LIB3DS_SEEK_SET: - o = SEEK_SET; - break; - case LIB3DS_SEEK_CUR: - o = SEEK_CUR; - break; - case LIB3DS_SEEK_END: - o = SEEK_END; - break; - default: - ASSERT(0); - return(0); - } - return (fseek(f, offset, o)); -} - - -static long -fileio_tell_func(void *self) -{ - FILE *f = (FILE*)self; - return(ftell(f)); -} - - -static size_t -fileio_read_func(void *self, void *buffer, size_t size) -{ - FILE *f = (FILE*)self; - return(fread(buffer, 1, size, f)); -} - - -static size_t -fileio_write_func(void *self, const void *buffer, size_t size) -{ - FILE *f = (FILE*)self; - return(fwrite(buffer, 1, size, f)); -} - - -/*! - * Loads a .3DS file from disk into memory. - * - * \param filename The filename of the .3DS file - * - * \return A pointer to the Lib3dsFile structure containing the - * data of the .3DS file. - * If the .3DS file can not be loaded NULL is returned. - * - * \note To free the returned structure use lib3ds_free. - * - * \see lib3ds_file_save - * \see lib3ds_file_new - * \see lib3ds_file_free - * - * \ingroup file - */ -Lib3dsFile* -lib3ds_file_load(const char *filename) -{ - FILE *f; - Lib3dsFile *file; - Lib3dsIo *io; - - f = fopen(filename, "rb"); - if (!f) { - return(0); - } - file = lib3ds_file_new(); - if (!file) { - fclose(f); - return(0); - } - - io = lib3ds_io_new( - f, - fileio_error_func, - fileio_seek_func, - fileio_tell_func, - fileio_read_func, - fileio_write_func - ); - if (!io) { - lib3ds_file_free(file); - fclose(f); - return(0); - } - - if (!lib3ds_file_read(file, io)) { - free(file); - lib3ds_io_free(io); - fclose(f); - return(0); - } - - lib3ds_io_free(io); - fclose(f); - return(file); -} - - -/*! - * Saves a .3DS file from memory to disk. - * - * \param file A pointer to a Lib3dsFile structure containing the - * the data that should be stored. - * \param filename The filename of the .3DS file to store the data in. - * - * \return TRUE on success, FALSE otherwise. - * - * \see lib3ds_file_load - * - * \ingroup file - */ -Lib3dsBool -lib3ds_file_save(Lib3dsFile *file, const char *filename) -{ - FILE *f; - Lib3dsIo *io; - Lib3dsBool result; - - f = fopen(filename, "wb"); - if (!f) { - return(LIB3DS_FALSE); - } - io = lib3ds_io_new( - f, - fileio_error_func, - fileio_seek_func, - fileio_tell_func, - fileio_read_func, - fileio_write_func - ); - if (!io) { - fclose(f); - return LIB3DS_FALSE; - } - - result = lib3ds_file_write(file, io); - - fclose(f); - - lib3ds_io_free(io); - return(result); -} - - -/*! - * Creates and returns a new, empty Lib3dsFile object. - * - * \return A pointer to the Lib3dsFile structure. - * If the structure cannot be allocated, NULL is returned. - * - * \ingroup file - */ -Lib3dsFile* -lib3ds_file_new() -{ - Lib3dsFile *file; - - file=(Lib3dsFile*)calloc(sizeof(Lib3dsFile),1); - if (!file) { - return(0); - } - file->mesh_version=3; - file->master_scale=1.0f; - file->keyf_revision=5; - strcpy(file->name, "LIB3DS"); - - file->frames=100; - file->segment_from=0; - file->segment_to=100; - file->current_frame=0; - - return(file); -} - - -/*! - * Free a Lib3dsFile object and all of its resources. - * - * \param file The Lib3dsFile object to be freed. - * - * \ingroup file - */ -void -lib3ds_file_free(Lib3dsFile* file) -{ - ASSERT(file); - lib3ds_viewport_set_views(&file->viewport,0); - lib3ds_viewport_set_views(&file->viewport_keyf,0); - { - Lib3dsMaterial *p,*q; - - for (p=file->materials; p; p=q) { - q=p->next; - lib3ds_material_free(p); - } - file->materials=0; - } - { - Lib3dsCamera *p,*q; - - for (p=file->cameras; p; p=q) { - q=p->next; - lib3ds_camera_free(p); - } - file->cameras=0; - } - { - Lib3dsLight *p,*q; - - for (p=file->lights; p; p=q) { - q=p->next; - lib3ds_light_free(p); - } - file->lights=0; - } - { - Lib3dsMesh *p,*q; - - for (p=file->meshes; p; p=q) { - q=p->next; - lib3ds_mesh_free(p); - } - file->meshes=0; - } - { - Lib3dsNode *p,*q; - - for (p=file->nodes; p; p=q) { - q=p->next; - lib3ds_node_free(p); - } - } - free(file); -} - - -/*! - * Evaluate all of the nodes in this Lib3dsFile object. - * - * \param file The Lib3dsFile object to be evaluated. - * \param t time value, between 0. and file->frames - * - * \see lib3ds_node_eval - * - * \ingroup file - */ -void -lib3ds_file_eval(Lib3dsFile *file, Lib3dsFloat t) -{ - Lib3dsNode *p; - - for (p=file->nodes; p!=0; p=p->next) { - lib3ds_node_eval(p, t); - } -} - - -static Lib3dsBool -named_object_read(Lib3dsFile *file, Lib3dsIo *io) -{ - Lib3dsChunk c; - char name[64]; - Lib3dsWord chunk; - Lib3dsMesh *mesh = NULL; - Lib3dsCamera *camera = NULL; - Lib3dsLight *light = NULL; - Lib3dsDword object_flags; - - if (!lib3ds_chunk_read_start(&c, LIB3DS_NAMED_OBJECT, io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_io_read_string(io, name, 64)) { - return(LIB3DS_FALSE); - } - lib3ds_chunk_dump_info(" NAME=%s", name); - lib3ds_chunk_read_tell(&c, io); - - object_flags = 0; - while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) { - switch (chunk) { - case LIB3DS_N_TRI_OBJECT: - { - mesh=lib3ds_mesh_new(name); - if (!mesh) { - return(LIB3DS_FALSE); - } - lib3ds_chunk_read_reset(&c, io); - if (!lib3ds_mesh_read(mesh, io)) { - return(LIB3DS_FALSE); - } - lib3ds_file_insert_mesh(file, mesh); - } - break; - - case LIB3DS_N_CAMERA: - { - camera=lib3ds_camera_new(name); - if (!camera) { - return(LIB3DS_FALSE); - } - lib3ds_chunk_read_reset(&c, io); - if (!lib3ds_camera_read(camera, io)) { - return(LIB3DS_FALSE); - } - lib3ds_file_insert_camera(file, camera); - } - break; - - case LIB3DS_N_DIRECT_LIGHT: - { - light=lib3ds_light_new(name); - if (!light) { - return(LIB3DS_FALSE); - } - lib3ds_chunk_read_reset(&c, io); - if (!lib3ds_light_read(light, io)) { - return(LIB3DS_FALSE); - } - lib3ds_file_insert_light(file, light); - } - break; - - case LIB3DS_OBJ_HIDDEN: - object_flags |= LIB3DS_OBJECT_HIDDEN; - break; - - case LIB3DS_OBJ_DOESNT_CAST: - object_flags |= LIB3DS_OBJECT_DOESNT_CAST; - break; - - case LIB3DS_OBJ_VIS_LOFTER: - object_flags |= LIB3DS_OBJECT_VIS_LOFTER; - break; - - case LIB3DS_OBJ_MATTE: - object_flags |= LIB3DS_OBJECT_MATTE; - break; - - case LIB3DS_OBJ_DONT_RCVSHADOW: - object_flags |= LIB3DS_OBJECT_DONT_RCVSHADOW; - break; - - case LIB3DS_OBJ_FAST: - object_flags |= LIB3DS_OBJECT_FAST; - break; - - case LIB3DS_OBJ_FROZEN: - object_flags |= LIB3DS_OBJECT_FROZEN; - break; - - default: - lib3ds_chunk_unknown(chunk); - } - } - - if (mesh) - mesh->object_flags = object_flags; - if (camera) - camera->object_flags = object_flags; - if (light) - light->object_flags = object_flags; - - lib3ds_chunk_read_end(&c, io); - return(LIB3DS_TRUE); -} - - -static Lib3dsBool -ambient_read(Lib3dsFile *file, Lib3dsIo *io) -{ - Lib3dsChunk c; - Lib3dsWord chunk; - Lib3dsBool have_lin=LIB3DS_FALSE; - - if (!lib3ds_chunk_read_start(&c, LIB3DS_AMBIENT_LIGHT, io)) { - return(LIB3DS_FALSE); - } - - while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) { - switch (chunk) { - case LIB3DS_LIN_COLOR_F: - { - int i; - for (i=0; i<3; ++i) { - file->ambient[i]=lib3ds_io_read_float(io); - } - } - have_lin=LIB3DS_TRUE; - break; - case LIB3DS_COLOR_F: - { - /* gamma corrected color chunk - replaced in 3ds R3 by LIN_COLOR_24 */ - if (!have_lin) { - int i; - for (i=0; i<3; ++i) { - file->ambient[i]=lib3ds_io_read_float(io); - } - } - } - break; - default: - lib3ds_chunk_unknown(chunk); - } - } - - lib3ds_chunk_read_end(&c, io); - return(LIB3DS_TRUE); -} - - -static Lib3dsBool -mdata_read(Lib3dsFile *file, Lib3dsIo *io) -{ - Lib3dsChunk c; - Lib3dsWord chunk; - - if (!lib3ds_chunk_read_start(&c, LIB3DS_MDATA, io)) { - return(LIB3DS_FALSE); - } - - while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) { - switch (chunk) { - case LIB3DS_MESH_VERSION: - { - file->mesh_version=lib3ds_io_read_intd(io); - } - break; - case LIB3DS_MASTER_SCALE: - { - file->master_scale=lib3ds_io_read_float(io); - } - break; - case LIB3DS_SHADOW_MAP_SIZE: - case LIB3DS_LO_SHADOW_BIAS: - case LIB3DS_HI_SHADOW_BIAS: - case LIB3DS_SHADOW_SAMPLES: - case LIB3DS_SHADOW_RANGE: - case LIB3DS_SHADOW_FILTER: - case LIB3DS_RAY_BIAS: - { - lib3ds_chunk_read_reset(&c, io); - if (!lib3ds_shadow_read(&file->shadow, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_VIEWPORT_LAYOUT: - case LIB3DS_DEFAULT_VIEW: - { - lib3ds_chunk_read_reset(&c, io); - if (!lib3ds_viewport_read(&file->viewport, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_O_CONSTS: - { - int i; - for (i=0; i<3; ++i) { - file->construction_plane[i]=lib3ds_io_read_float(io); - } - } - break; - case LIB3DS_AMBIENT_LIGHT: - { - lib3ds_chunk_read_reset(&c, io); - if (!ambient_read(file, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_BIT_MAP: - case LIB3DS_SOLID_BGND: - case LIB3DS_V_GRADIENT: - case LIB3DS_USE_BIT_MAP: - case LIB3DS_USE_SOLID_BGND: - case LIB3DS_USE_V_GRADIENT: - { - lib3ds_chunk_read_reset(&c, io); - if (!lib3ds_background_read(&file->background, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_FOG: - case LIB3DS_LAYER_FOG: - case LIB3DS_DISTANCE_CUE: - case LIB3DS_USE_FOG: - case LIB3DS_USE_LAYER_FOG: - case LIB3DS_USE_DISTANCE_CUE: - { - lib3ds_chunk_read_reset(&c, io); - if (!lib3ds_atmosphere_read(&file->atmosphere, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_MAT_ENTRY: - { - Lib3dsMaterial *material; - - material=lib3ds_material_new(); - if (!material) { - return(LIB3DS_FALSE); - } - lib3ds_chunk_read_reset(&c, io); - if (!lib3ds_material_read(material, io)) { - return(LIB3DS_FALSE); - } - lib3ds_file_insert_material(file, material); - } - break; - case LIB3DS_NAMED_OBJECT: - { - lib3ds_chunk_read_reset(&c, io); - if (!named_object_read(file, io)) { - return(LIB3DS_FALSE); - } - } - break; - default: - lib3ds_chunk_unknown(chunk); - } - } - - lib3ds_chunk_read_end(&c, io); - return(LIB3DS_TRUE); -} - - -static Lib3dsBool -kfdata_read(Lib3dsFile *file, Lib3dsIo *io) -{ - Lib3dsChunk c; - Lib3dsWord chunk; - Lib3dsDword node_number = 0; - - if (!lib3ds_chunk_read_start(&c, LIB3DS_KFDATA, io)) { - return(LIB3DS_FALSE); - } - - while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) { - switch (chunk) { - case LIB3DS_KFHDR: - { - file->keyf_revision=lib3ds_io_read_word(io); - if (!lib3ds_io_read_string(io, file->name, 12+1)) { - return(LIB3DS_FALSE); - } - file->frames=lib3ds_io_read_intd(io); - } - break; - case LIB3DS_KFSEG: - { - file->segment_from=lib3ds_io_read_intd(io); - file->segment_to=lib3ds_io_read_intd(io); - } - break; - case LIB3DS_KFCURTIME: - { - file->current_frame=lib3ds_io_read_intd(io); - } - break; - case LIB3DS_VIEWPORT_LAYOUT: - case LIB3DS_DEFAULT_VIEW: - { - lib3ds_chunk_read_reset(&c, io); - if (!lib3ds_viewport_read(&file->viewport_keyf, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_AMBIENT_NODE_TAG: - { - Lib3dsNode *node; - - node=lib3ds_node_new_ambient(); - if (!node) { - return(LIB3DS_FALSE); - } - node->node_id=node_number++; - lib3ds_chunk_read_reset(&c, io); - if (!lib3ds_node_read(node, file, io)) { - return(LIB3DS_FALSE); - } - lib3ds_file_insert_node(file, node); - } - break; - case LIB3DS_OBJECT_NODE_TAG: - { - Lib3dsNode *node; - - node=lib3ds_node_new_object(); - if (!node) { - return(LIB3DS_FALSE); - } - node->node_id=node_number++; - lib3ds_chunk_read_reset(&c, io); - if (!lib3ds_node_read(node, file, io)) { - return(LIB3DS_FALSE); - } - lib3ds_file_insert_node(file, node); - } - break; - case LIB3DS_CAMERA_NODE_TAG: - { - Lib3dsNode *node; - - node=lib3ds_node_new_camera(); - if (!node) { - return(LIB3DS_FALSE); - } - node->node_id=node_number++; - lib3ds_chunk_read_reset(&c, io); - if (!lib3ds_node_read(node, file, io)) { - return(LIB3DS_FALSE); - } - lib3ds_file_insert_node(file, node); - } - break; - case LIB3DS_TARGET_NODE_TAG: - { - Lib3dsNode *node; - - node=lib3ds_node_new_target(); - if (!node) { - return(LIB3DS_FALSE); - } - node->node_id=node_number++; - lib3ds_chunk_read_reset(&c, io); - if (!lib3ds_node_read(node, file, io)) { - return(LIB3DS_FALSE); - } - lib3ds_file_insert_node(file, node); - } - break; - case LIB3DS_LIGHT_NODE_TAG: - case LIB3DS_SPOTLIGHT_NODE_TAG: - { - Lib3dsNode *node; - - node=lib3ds_node_new_light(); - if (!node) { - return(LIB3DS_FALSE); - } - node->node_id=node_number++; - lib3ds_chunk_read_reset(&c, io); - if (!lib3ds_node_read(node, file, io)) { - return(LIB3DS_FALSE); - } - lib3ds_file_insert_node(file, node); - } - break; - case LIB3DS_L_TARGET_NODE_TAG: - { - Lib3dsNode *node; - - node=lib3ds_node_new_spot(); - if (!node) { - return(LIB3DS_FALSE); - } - node->node_id=node_number++; - lib3ds_chunk_read_reset(&c, io); - if (!lib3ds_node_read(node, file, io)) { - return(LIB3DS_FALSE); - } - lib3ds_file_insert_node(file, node); - } - break; - default: - lib3ds_chunk_unknown(chunk); - } - } - - lib3ds_chunk_read_end(&c, io); - return(LIB3DS_TRUE); -} - - -/*! - * Read 3ds file data into a Lib3dsFile object. - * - * \param file The Lib3dsFile object to be filled. - * \param io A Lib3dsIo object previously set up by the caller. - * - * \return LIB3DS_TRUE on success, LIB3DS_FALSE on failure. - * - * \ingroup file - */ -Lib3dsBool -lib3ds_file_read(Lib3dsFile *file, Lib3dsIo *io) -{ - Lib3dsChunk c; - Lib3dsWord chunk; - - if (!lib3ds_chunk_read_start(&c, 0, io)) { - return(LIB3DS_FALSE); - } - switch (c.chunk) { - case LIB3DS_MDATA: - { - lib3ds_chunk_read_reset(&c, io); - if (!mdata_read(file, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_M3DMAGIC: - case LIB3DS_MLIBMAGIC: - case LIB3DS_CMAGIC: - { - while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) { - switch (chunk) { - case LIB3DS_M3D_VERSION: - { - file->mesh_version=lib3ds_io_read_dword(io); - } - break; - case LIB3DS_MDATA: - { - lib3ds_chunk_read_reset(&c, io); - if (!mdata_read(file, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_KFDATA: - { - lib3ds_chunk_read_reset(&c, io); - if (!kfdata_read(file, io)) { - return(LIB3DS_FALSE); - } - } - break; - default: - lib3ds_chunk_unknown(chunk); - } - } - } - break; - default: - lib3ds_chunk_unknown(c.chunk); - return(LIB3DS_FALSE); - } - - lib3ds_chunk_read_end(&c, io); - return(LIB3DS_TRUE); -} - - -static Lib3dsBool -colorf_write(Lib3dsRgba rgb, Lib3dsIo *io) -{ - Lib3dsChunk c; - - c.chunk=LIB3DS_COLOR_F; - c.size=18; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_rgb(io, rgb); - - c.chunk=LIB3DS_LIN_COLOR_F; - c.size=18; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_rgb(io, rgb); - return(LIB3DS_TRUE); -} - - -static Lib3dsBool -object_flags_write(Lib3dsDword flags, Lib3dsIo *io) -{ - if (flags){ - if (flags & LIB3DS_OBJECT_HIDDEN) { - if (!lib3ds_chunk_write_switch(LIB3DS_OBJ_HIDDEN, io)) - return LIB3DS_FALSE; - } - if (flags & LIB3DS_OBJECT_VIS_LOFTER) { - if (!lib3ds_chunk_write_switch(LIB3DS_OBJ_VIS_LOFTER, io)) - return LIB3DS_FALSE; - } - if (flags & LIB3DS_OBJECT_DOESNT_CAST) { - if (!lib3ds_chunk_write_switch(LIB3DS_OBJ_DOESNT_CAST, io)) - return LIB3DS_FALSE; - } - if (flags & LIB3DS_OBJECT_MATTE) { - if (!lib3ds_chunk_write_switch(LIB3DS_OBJ_MATTE, io)) - return LIB3DS_FALSE; - } - if (flags & LIB3DS_OBJECT_DONT_RCVSHADOW) { - if (!lib3ds_chunk_write_switch(LIB3DS_OBJ_DOESNT_CAST, io)) - return LIB3DS_FALSE; - } - if (flags & LIB3DS_OBJECT_FAST) { - if (!lib3ds_chunk_write_switch(LIB3DS_OBJ_FAST, io)) - return LIB3DS_FALSE; - } - if (flags & LIB3DS_OBJECT_FROZEN) { - if (!lib3ds_chunk_write_switch(LIB3DS_OBJ_FROZEN, io)) - return LIB3DS_FALSE; - } - } - return LIB3DS_TRUE; -} - - -static Lib3dsBool -mdata_write(Lib3dsFile *file, Lib3dsIo *io) -{ - Lib3dsChunk c; - - c.chunk=LIB3DS_MDATA; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - - { /*---- LIB3DS_MESH_VERSION ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MESH_VERSION; - c.size=10; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_intd(io, file->mesh_version); - } - { /*---- LIB3DS_MASTER_SCALE ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MASTER_SCALE; - c.size=10; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_float(io, file->master_scale); - } - { /*---- LIB3DS_O_CONSTS ----*/ - int i; - for (i=0; i<3; ++i) { - if (fabs(file->construction_plane[i])>LIB3DS_EPSILON) { - break; - } - } - if (i<3) { - Lib3dsChunk c; - c.chunk=LIB3DS_O_CONSTS; - c.size=18; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_vector(io, file->construction_plane); - } - } - - { /*---- LIB3DS_AMBIENT_LIGHT ----*/ - int i; - for (i=0; i<3; ++i) { - if (fabs(file->ambient[i])>LIB3DS_EPSILON) { - break; - } - } - if (i<3) { - Lib3dsChunk c; - c.chunk=LIB3DS_AMBIENT_LIGHT; - c.size=42; - lib3ds_chunk_write(&c,io); - colorf_write(file->ambient,io); - } - } - lib3ds_background_write(&file->background, io); - lib3ds_atmosphere_write(&file->atmosphere, io); - lib3ds_shadow_write(&file->shadow, io); - lib3ds_viewport_write(&file->viewport, io); - { - Lib3dsMaterial *p; - for (p=file->materials; p!=0; p=p->next) { - if (!lib3ds_material_write(p,io)) { - return(LIB3DS_FALSE); - } - } - } - { - Lib3dsCamera *p; - Lib3dsChunk c; - - for (p=file->cameras; p!=0; p=p->next) { - c.chunk=LIB3DS_NAMED_OBJECT; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - lib3ds_io_write_string(io, p->name); - lib3ds_camera_write(p,io); - object_flags_write(p->object_flags,io); - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - } - } - { - Lib3dsLight *p; - Lib3dsChunk c; - - for (p=file->lights; p!=0; p=p->next) { - c.chunk=LIB3DS_NAMED_OBJECT; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - lib3ds_io_write_string(io,p->name); - lib3ds_light_write(p,io); - object_flags_write(p->object_flags,io); - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - } - } - { - Lib3dsMesh *p; - Lib3dsChunk c; - - for (p=file->meshes; p!=0; p=p->next) { - c.chunk=LIB3DS_NAMED_OBJECT; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - lib3ds_io_write_string(io, p->name); - lib3ds_mesh_write(p,io); - object_flags_write(p->object_flags,io); - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - } - } - - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - return(LIB3DS_TRUE); -} - - - -static Lib3dsBool -nodes_write(Lib3dsNode *node, Lib3dsFile *file, Lib3dsIo *io) -{ - { - Lib3dsNode *p; - for (p=node->childs; p!=0; p=p->next) { - if (!lib3ds_node_write(p, file, io)) { - return(LIB3DS_FALSE); - } - nodes_write(p, file, io); - } - } - return(LIB3DS_TRUE); -} - - -static Lib3dsBool -kfdata_write(Lib3dsFile *file, Lib3dsIo *io) -{ - Lib3dsChunk c; - - if (!file->nodes) { - return(LIB3DS_TRUE); - } - - c.chunk=LIB3DS_KFDATA; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - - { /*---- LIB3DS_KFHDR ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_KFHDR; - c.size=6 + 2 + (Lib3dsDword)strlen(file->name)+1 +4; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_intw(io, file->keyf_revision); - lib3ds_io_write_string(io, file->name); - lib3ds_io_write_intd(io, file->frames); - } - { /*---- LIB3DS_KFSEG ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_KFSEG; - c.size=14; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_intd(io, file->segment_from); - lib3ds_io_write_intd(io, file->segment_to); - } - { /*---- LIB3DS_KFCURTIME ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_KFCURTIME; - c.size=10; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_intd(io, file->current_frame); - } - lib3ds_viewport_write(&file->viewport_keyf, io); - - { - Lib3dsNode *p; - for (p=file->nodes; p!=0; p=p->next) { - if (!lib3ds_node_write(p, file, io)) { - return(LIB3DS_FALSE); - } - if (!nodes_write(p, file, io)) { - return(LIB3DS_FALSE); - } - } - } - - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - return(LIB3DS_TRUE); -} - - -/*! - * Write 3ds file data from a Lib3dsFile object to a file. - * - * \param file The Lib3dsFile object to be written. - * \param io A Lib3dsIo object previously set up by the caller. - * - * \return LIB3DS_TRUE on success, LIB3DS_FALSE on failure. - * - * \ingroup file - */ -Lib3dsBool -lib3ds_file_write(Lib3dsFile *file, Lib3dsIo *io) -{ - Lib3dsChunk c; - - c.chunk=LIB3DS_M3DMAGIC; - if (!lib3ds_chunk_write_start(&c,io)) { - LIB3DS_ERROR_LOG; - return(LIB3DS_FALSE); - } - - { /*---- LIB3DS_M3D_VERSION ----*/ - Lib3dsChunk c; - - c.chunk=LIB3DS_M3D_VERSION; - c.size=10; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_dword(io, file->mesh_version); - } - - if (!mdata_write(file, io)) { - return(LIB3DS_FALSE); - } - if (!kfdata_write(file, io)) { - return(LIB3DS_FALSE); - } - - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - return(LIB3DS_TRUE); -} - - -/*! - * Insert a new Lib3dsMaterial object into the materials list of - * a Lib3dsFile object. - * - * The new Lib3dsMaterial object is inserted into the materials list - * in alphabetic order by name. - * - * \param file The Lib3dsFile object to be modified. - * \param material The Lib3dsMaterial object to be inserted into file->materials - * - * \ingroup file - */ -void -lib3ds_file_insert_material(Lib3dsFile *file, Lib3dsMaterial *material) -{ - Lib3dsMaterial *p,*q; - - ASSERT(file); - ASSERT(material); - ASSERT(!material->next); - - q=0; - for (p=file->materials; p!=0; p=p->next) { - if (strcmp(material->name, p->name)<0) { - break; - } - q=p; - } - if (!q) { - material->next=file->materials; - file->materials=material; - } - else { - material->next=q->next; - q->next=material; - } -} - - -/*! - * Remove a Lib3dsMaterial object from the materials list of - * a Lib3dsFile object. - * - * If the Lib3dsMaterial is not found in the materials list, nothing is - * done (except that an error log message may be generated.) - * - * \param file The Lib3dsFile object to be modified. - * \param material The Lib3dsMaterial object to be removed from file->materials - * - * \ingroup file - */ -void -lib3ds_file_remove_material(Lib3dsFile *file, Lib3dsMaterial *material) -{ - Lib3dsMaterial *p,*q; - - ASSERT(file); - ASSERT(material); - ASSERT(file->materials); - for (p=0,q=file->materials; q; p=q,q=q->next) { - if (q==material) { - break; - } - } - if (!q) { - ASSERT(LIB3DS_FALSE); - return; - } - if (!p) { - file->materials=material->next; - } - else { - p->next=q->next; - } - material->next=0; -} - - -/*! - * Return a Lib3dsMaterial object by name. - * - * \param file Lib3dsFile object to be searched. - * \param name Name of the Lib3dsMaterial object to be searched for. - * - * \return A pointer to the named Lib3dsMaterial, or NULL if not found. - * - * \ingroup file - */ -Lib3dsMaterial* -lib3ds_file_material_by_name(Lib3dsFile *file, const char *name) -{ - Lib3dsMaterial *p; - - ASSERT(file); - for (p=file->materials; p!=0; p=p->next) { - if (strcmp(p->name,name)==0) { - return(p); - } - } - return(0); -} - - -/*! - * Dump all Lib3dsMaterial objects found in a Lib3dsFile object. - * - * \param file Lib3dsFile object to be dumped. - * - * \see lib3ds_material_dump - * - * \ingroup file - */ -void -lib3ds_file_dump_materials(Lib3dsFile *file) -{ - Lib3dsMaterial *p; - - ASSERT(file); - for (p=file->materials; p!=0; p=p->next) { - lib3ds_material_dump(p); - } -} - - -/*! - * Insert a new Lib3dsMesh object into the meshes list of - * a Lib3dsFile object. - * - * The new Lib3dsMesh object is inserted into the meshes list - * in alphabetic order by name. - * - * \param file The Lib3dsFile object to be modified. - * \param mesh The Lib3dsMesh object to be inserted into file->meshes - * - * \ingroup file - */ -void -lib3ds_file_insert_mesh(Lib3dsFile *file, Lib3dsMesh *mesh) -{ - Lib3dsMesh *p,*q; - - ASSERT(file); - ASSERT(mesh); - ASSERT(!mesh->next); - - q=0; - for (p=file->meshes; p!=0; p=p->next) { - if (strcmp(mesh->name, p->name)<0) { - break; - } - q=p; - } - if (!q) { - mesh->next=file->meshes; - file->meshes=mesh; - } - else { - mesh->next=q->next; - q->next=mesh; - } -} - - -/*! - * Remove a Lib3dsMesh object from the meshes list of - * a Lib3dsFile object. - * - * If the Lib3dsMesh is not found in the meshes list, nothing is done - * (except that an error log message may be generated.) - * - * \param file The Lib3dsFile object to be modified. - * \param mesh The Lib3dsMesh object to be removed from file->meshes - * - * \ingroup file - */ -void -lib3ds_file_remove_mesh(Lib3dsFile *file, Lib3dsMesh *mesh) -{ - Lib3dsMesh *p,*q; - - ASSERT(file); - ASSERT(mesh); - ASSERT(file->meshes); - for (p=0,q=file->meshes; q; p=q,q=q->next) { - if (q==mesh) { - break; - } - } - if (!q) { - ASSERT(LIB3DS_FALSE); - return; - } - if (!p) { - file->meshes=mesh->next; - } - else { - p->next=q->next; - } - mesh->next=0; -} - - -/*! - * Return a Lib3dsMesh object from a Lib3dsFile by name. - * - * \param file Lib3dsFile object to be searched. - * \param name Name of the Lib3dsMesh object to be searched for. - * - * \return A pointer to the named Lib3dsMesh, or NULL if not found. - * - * \ingroup file - */ -Lib3dsMesh* -lib3ds_file_mesh_by_name(Lib3dsFile *file, const char *name) -{ - Lib3dsMesh *p; - - ASSERT(file); - for (p=file->meshes; p!=0; p=p->next) { - if (strcmp(p->name,name)==0) { - return(p); - } - } - return(0); -} - - -/*! - * Dump all Lib3dsMesh objects found in a Lib3dsFile object. - * - * \param file Lib3dsFile object to be dumped. - * - * \see lib3ds_mesh_dump - * - * \ingroup file - */ -void -lib3ds_file_dump_meshes(Lib3dsFile *file) -{ - Lib3dsMesh *p; - - ASSERT(file); - for (p=file->meshes; p!=0; p=p->next) { - lib3ds_mesh_dump(p); - } -} - - -static void -dump_instances(Lib3dsNode *node, const char* parent) -{ - Lib3dsNode *p; - char name[255]; - - ASSERT(node); - ASSERT(parent); - strcpy(name, parent); - strcat(name, "."); - strcat(name, node->name); - if (node->type==LIB3DS_OBJECT_NODE) { - printf(" %s : %s\n", name, node->data.object.instance); - } - for (p=node->childs; p!=0; p=p->next) { - dump_instances(p, parent); - } -} - - -/*! - * Dump all Lib3dsNode object names found in a Lib3dsFile object. - * - * For each node of type OBJECT_NODE, its name and data.object.instance - * fields are printed to stdout. Consider using lib3ds_file_dump_nodes() - * instead, as that function dumps more information. - * - * Nodes are dumped recursively. - * - * \param file Lib3dsFile object to be dumped. - * - * \see lib3ds_file_dump_nodes - * - * \ingroup file - */ -void -lib3ds_file_dump_instances(Lib3dsFile *file) -{ - Lib3dsNode *p; - - ASSERT(file); - for (p=file->nodes; p!=0; p=p->next) { - dump_instances(p,""); - } -} - - -/*! - * Insert a new Lib3dsCamera object into the cameras list of - * a Lib3dsFile object. - * - * The new Lib3dsCamera object is inserted into the cameras list - * in alphabetic order by name. - * - * \param file The Lib3dsFile object to be modified. - * \param camera The Lib3dsCamera object to be inserted into file->cameras - * - * \ingroup file - */ -void -lib3ds_file_insert_camera(Lib3dsFile *file, Lib3dsCamera *camera) -{ - Lib3dsCamera *p,*q; - - ASSERT(file); - ASSERT(camera); - ASSERT(!camera->next); - - q=0; - for (p=file->cameras; p!=0; p=p->next) { - if (strcmp(camera->name, p->name)<0) { - break; - } - q=p; - } - if (!q) { - camera->next=file->cameras; - file->cameras=camera; - } - else { - camera->next=q->next; - q->next=camera; - } -} - - -/*! - * Remove a Lib3dsCamera object from the cameras list of - * a Lib3dsFile object. - * - * If the Lib3dsCamera is not found in the cameras list, nothing is done - * (except that an error log message may be generated.) - * - * \param file The Lib3dsFile object to be modified. - * \param camera The Lib3dsCamera object to be removed from file->cameras - * - * \ingroup file - */ -void -lib3ds_file_remove_camera(Lib3dsFile *file, Lib3dsCamera *camera) -{ - Lib3dsCamera *p,*q; - - ASSERT(file); - ASSERT(camera); - ASSERT(file->cameras); - for (p=0,q=file->cameras; q; p=q,q=q->next) { - if (q==camera) { - break; - } - } - if (!q) { - ASSERT(LIB3DS_FALSE); - return; - } - if (!p) { - file->cameras=camera->next; - } - else { - p->next=q->next; - } - camera->next=0; -} - - -/*! - * Return a Lib3dsCamera object from a Lib3dsFile by name. - * - * \param file Lib3dsFile object to be searched. - * \param name Name of the Lib3dsCamera object to be searched for. - * - * \return A pointer to the named Lib3dsCamera, or NULL if not found. - * - * \ingroup file - */ -Lib3dsCamera* -lib3ds_file_camera_by_name(Lib3dsFile *file, const char *name) -{ - Lib3dsCamera *p; - - ASSERT(file); - for (p=file->cameras; p!=0; p=p->next) { - if (strcmp(p->name,name)==0) { - return(p); - } - } - return(0); -} - - -/*! - * Dump all Lib3dsCamera objects found in a Lib3dsFile object. - * - * \param file Lib3dsFile object to be dumped. - * - * \see lib3ds_camera_dump - * - * \ingroup file - */ -void -lib3ds_file_dump_cameras(Lib3dsFile *file) -{ - Lib3dsCamera *p; - - ASSERT(file); - for (p=file->cameras; p!=0; p=p->next) { - lib3ds_camera_dump(p); - } -} - - -/*! - * Insert a new Lib3dsLight object into the lights list of - * a Lib3dsFile object. - * - * The new Lib3dsLight object is inserted into the lights list - * in alphabetic order by name. - * - * \param file The Lib3dsFile object to be modified. - * \param light The Lib3dsLight object to be inserted into file->lights - * - * \ingroup file - */ -void -lib3ds_file_insert_light(Lib3dsFile *file, Lib3dsLight *light) -{ - Lib3dsLight *p,*q; - - ASSERT(file); - ASSERT(light); - ASSERT(!light->next); - - q=0; - for (p=file->lights; p!=0; p=p->next) { - if (strcmp(light->name, p->name)<0) { - break; - } - q=p; - } - if (!q) { - light->next=file->lights; - file->lights=light; - } - else { - light->next=q->next; - q->next=light; - } -} - - -/*! - * Remove a Lib3dsLight object from the lights list of - * a Lib3dsFile object. - * - * If the Lib3dsLight is not found in the lights list, nothing is done - * (except that an error log message may be generated.) - * - * \param file The Lib3dsFile object to be modified. - * \param light The Lib3dsLight object to be removed from file->lights - * - * \ingroup file - */ -void -lib3ds_file_remove_light(Lib3dsFile *file, Lib3dsLight *light) -{ - Lib3dsLight *p,*q; - - ASSERT(file); - ASSERT(light); - ASSERT(file->lights); - for (p=0,q=file->lights; q; p=q,q=q->next) { - if (q==light) { - break; - } - } - if (!q) { - ASSERT(LIB3DS_FALSE); - return; - } - if (!p) { - file->lights=light->next; - } - else { - p->next=q->next; - } - light->next=0; -} - - -/*! - * Return a Lib3dsLight object from a Lib3dsFile by name. - * - * \param file Lib3dsFile object to be searched. - * \param name Name of the Lib3dsLight object to be searched for. - * - * \return A pointer to the named Lib3dsLight, or NULL if not found. - * - * \ingroup file - */ -Lib3dsLight* -lib3ds_file_light_by_name(Lib3dsFile *file, const char *name) -{ - Lib3dsLight *p; - - ASSERT(file); - for (p=file->lights; p!=0; p=p->next) { - if (strcmp(p->name,name)==0) { - return(p); - } - } - return(0); -} - - -/*! - * Dump all Lib3dsLight objects found in a Lib3dsFile object. - * - * \param file Lib3dsFile object to be dumped. - * - * \see lib3ds_light_dump - * - * \ingroup file - */ -void -lib3ds_file_dump_lights(Lib3dsFile *file) -{ - Lib3dsLight *p; - - ASSERT(file); - for (p=file->lights; p!=0; p=p->next) { - lib3ds_light_dump(p); - } -} - - -/*! - * Return a node object by name and type. - * - * This function performs a recursive search for the specified node. - * Both name and type must match. - * - * \param file The Lib3dsFile to be searched. - * \param name The target node name. - * \param type The target node type - * - * \return A pointer to the first matching node, or NULL if not found. - * - * \see lib3ds_node_by_name - * - * \ingroup file - */ -Lib3dsNode* -lib3ds_file_node_by_name(Lib3dsFile *file, const char* name, Lib3dsNodeTypes type) -{ - Lib3dsNode *p,*q; - - ASSERT(file); - for (p=file->nodes; p!=0; p=p->next) { - if ((p->type==type) && (strcmp(p->name, name)==0)) { - return(p); - } - q=lib3ds_node_by_name(p, name, type); - if (q) { - return(q); - } - } - return(0); -} - - -/*! - * Return a node object by id. - * - * This function performs a recursive search for the specified node. - * - * \param file The Lib3dsFile to be searched. - * \param node_id The target node id. - * - * \return A pointer to the first matching node, or NULL if not found. - * - * \see lib3ds_node_by_id - * - * \ingroup file - */ -Lib3dsNode* -lib3ds_file_node_by_id(Lib3dsFile *file, Lib3dsWord node_id) -{ - Lib3dsNode *p,*q; - - ASSERT(file); - for (p=file->nodes; p!=0; p=p->next) { - if (p->node_id==node_id) { - return(p); - } - q=lib3ds_node_by_id(p, node_id); - if (q) { - return(q); - } - } - return(0); -} - - -/*! - * Insert a new node into a Lib3dsFile object. - * - * If the node's parent_id structure is not LIB3DS_NO_PARENT and the - * specified parent is found inside the Lib3dsFile object, then the - * node is inserted as a child of that parent. If the parent_id - * structure is LIB3DS_NO_PARENT or the specified parent is not found, - * then the node is inserted at the top level. - * - * Node is inserted in alphabetic order by name. - * - * Finally, if any other top-level nodes in file specify this node as - * their parent, they are relocated as a child of this node. - * - * \param file The Lib3dsFile object to be modified. - * \param node The node to be inserted into file - * - * \ingroup file - */ -void -lib3ds_file_insert_node(Lib3dsFile *file, Lib3dsNode *node) -{ - Lib3dsNode *parent,*p,*n; - - ASSERT(node); - ASSERT(!node->next); - ASSERT(!node->parent); - - parent=0; - if (node->parent_id!=LIB3DS_NO_PARENT) { - parent=lib3ds_file_node_by_id(file, node->parent_id); - } - node->parent=parent; - - if (!parent) { - for (p=0,n=file->nodes; n!=0; p=n,n=n->next) { - if (strcmp(n->name, node->name)>0) { - break; - } - } - if (!p) { - node->next=file->nodes; - file->nodes=node; - } - else { - node->next=p->next; - p->next=node; - } - } - else { - for (p=0,n=parent->childs; n!=0; p=n,n=n->next) { - if (strcmp(n->name, node->name)>0) { - break; - } - } - if (!p) { - node->next=parent->childs; - parent->childs=node; - } - else { - node->next=p->next; - p->next=node; - } - } - - if (node->node_id!=LIB3DS_NO_PARENT) { - for (n=file->nodes; n!=0; n=p) { - p=n->next; - if (n->parent_id==node->node_id) { - lib3ds_file_remove_node(file, n); - lib3ds_file_insert_node(file, n); - } - } - } -} - - -/*! - * Remove a node from the a Lib3dsFile object. - * - * \param file The Lib3dsFile object to be modified. - * \param node The Lib3dsNode object to be removed from file - * - * \return LIB3DS_TRUE on success, LIB3DS_FALSE if node is not found in file - * - * \ingroup file - */ -Lib3dsBool -lib3ds_file_remove_node(Lib3dsFile *file, Lib3dsNode *node) -{ - Lib3dsNode *p,*n; - - if (node->parent) { - for (p=0,n=node->parent->childs; n; p=n,n=n->next) { - if (n==node) { - break; - } - } - if (!n) { - return(LIB3DS_FALSE); - } - - if (!p) { - node->parent->childs=n->next; - } - else { - p->next=n->next; - } - } - else { - for (p=0,n=file->nodes; n; p=n,n=n->next) { - if (n==node) { - break; - } - } - if (!n) { - return(LIB3DS_FALSE); - } - - if (!p) { - file->nodes=n->next; - } - else { - p->next=n->next; - } - } - return(LIB3DS_TRUE); -} - - -/*! - * This function computes the bounding box of meshes, cameras and lights - * defined in the 3D editor. - * - * \param file The Lib3dsFile object to be examined. - * \param include_meshes Include meshes in bounding box calculation. - * \param include_cameras Include cameras in bounding box calculation. - * \param include_lights Include lights in bounding box calculation. - * \param bmin Returned minimum x,y,z values. - * \param bmax Returned maximum x,y,z values. - * - * \ingroup file - */ -void -lib3ds_file_bounding_box_of_objects(Lib3dsFile *file, Lib3dsBool include_meshes, - Lib3dsBool include_cameras, Lib3dsBool include_lights, - Lib3dsVector bmin, Lib3dsVector bmax) -{ - bmin[0] = bmin[1] = bmin[2] = FLT_MAX; - bmax[0] = bmax[1] = bmax[2] = FLT_MIN; - - if (include_meshes) { - Lib3dsVector lmin, lmax; - Lib3dsMesh *p=file->meshes; - while (p) { - lib3ds_mesh_bounding_box(p, lmin, lmax); - lib3ds_vector_min(bmin, lmin); - lib3ds_vector_max(bmax, lmax); - p=p->next; - } - } - if (include_cameras) { - Lib3dsCamera *p=file->cameras; - while (p) { - lib3ds_vector_min(bmin, p->position); - lib3ds_vector_max(bmax, p->position); - lib3ds_vector_min(bmin, p->target); - lib3ds_vector_max(bmax, p->target); - p=p->next; - } - } - if (include_lights) { - Lib3dsLight *p=file->lights; - while (p) { - lib3ds_vector_min(bmin, p->position); - lib3ds_vector_max(bmax, p->position); - if (p->spot_light) { - lib3ds_vector_min(bmin, p->spot); - lib3ds_vector_max(bmax, p->spot); - } - p=p->next; - } - } -} - - -static void -file_bounding_box_of_nodes_impl(Lib3dsNode *node, Lib3dsFile *file, Lib3dsBool include_meshes, - Lib3dsBool include_cameras, Lib3dsBool include_lights, - Lib3dsVector bmin, Lib3dsVector bmax) -{ - switch (node->type) - { - case LIB3DS_OBJECT_NODE: - if (include_meshes) { - Lib3dsMesh *mesh; - - mesh = lib3ds_file_mesh_by_name(file, node->data.object.instance); - if (!mesh) - mesh = lib3ds_file_mesh_by_name(file, node->name); - if (mesh) { - Lib3dsMatrix inv_matrix, M; - Lib3dsVector v; - unsigned i; - - lib3ds_matrix_copy(inv_matrix, mesh->matrix); - lib3ds_matrix_inv(inv_matrix); - lib3ds_matrix_copy(M, node->matrix); - lib3ds_matrix_translate_xyz(M, -node->data.object.pivot[0], -node->data.object.pivot[1], -node->data.object.pivot[2]); - lib3ds_matrix_mult(M, inv_matrix); - - for (i=0; ipoints; ++i) { - lib3ds_vector_transform(v, M, mesh->pointL[i].pos); - lib3ds_vector_min(bmin, v); - lib3ds_vector_max(bmax, v); - } - } - } - break; - /* - case LIB3DS_CAMERA_NODE: - case LIB3DS_TARGET_NODE: - if (include_cameras) { - Lib3dsVector z,v; - lib3ds_vector_zero(z); - lib3ds_vector_transform(v, node->matrix, z); - lib3ds_vector_min(bmin, v); - lib3ds_vector_max(bmax, v); - } - break; - - case LIB3DS_LIGHT_NODE: - case LIB3DS_SPOT_NODE: - if (include_lights) { - Lib3dsVector z,v; - lib3ds_vector_zero(z); - lib3ds_vector_transform(v, node->matrix, z); - lib3ds_vector_min(bmin, v); - lib3ds_vector_max(bmax, v); - } - break; - */ - } - { - Lib3dsNode *p=node->childs; - while (p) { - file_bounding_box_of_nodes_impl(p, file, include_meshes, include_cameras, include_lights, bmin, bmax); - p=p->next; - } - } -} - - -/*! - * This function computes the bounding box of mesh, camera and light instances - * defined in the Keyframer. - * - * \param file The Lib3dsFile object to be examined. - * \param include_meshes Include meshes in bounding box calculation. - * \param include_cameras Include cameras in bounding box calculation. - * \param include_lights Include lights in bounding box calculation. - * \param bmin Returned minimum x,y,z values. - * \param bmax Returned maximum x,y,z values. - * - * \ingroup file - */ -void -lib3ds_file_bounding_box_of_nodes(Lib3dsFile *file, Lib3dsBool include_meshes, - Lib3dsBool include_cameras, Lib3dsBool include_lights, - Lib3dsVector bmin, Lib3dsVector bmax) -{ - Lib3dsNode *p; - - bmin[0] = bmin[1] = bmin[2] = FLT_MAX; - bmax[0] = bmax[1] = bmax[2] = FLT_MIN; - p=file->nodes; - while (p) { - file_bounding_box_of_nodes_impl(p, file, include_meshes, include_cameras, include_lights, bmin, bmax); - p=p->next; - } -} - - -/*! - * Dump all node objects found in a Lib3dsFile object. - * - * Nodes are dumped recursively. - * - * \param file Lib3dsFile object to be dumped. - * - * \see lib3ds_node_dump - * - * \ingroup file - */ -void -lib3ds_file_dump_nodes(Lib3dsFile *file) -{ - Lib3dsNode *p; - - ASSERT(file); - for (p=file->nodes; p!=0; p=p->next) { - lib3ds_node_dump(p,1); - } -} - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/file.h b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/file.h deleted file mode 100644 index ebe10e1c4..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/file.h +++ /dev/null @@ -1,106 +0,0 @@ -/* -*- c -*- */ -#ifndef INCLUDED_LIB3DS_FILE_H -#define INCLUDED_LIB3DS_FILE_H -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: file.h,v 1.24 2007/06/20 17:04:08 jeh Exp $ - */ - -#ifndef INCLUDED_LIB3DS_BACKGROUND_H -#include "background.h" -#endif -#ifndef INCLUDED_LIB3DS_ATMOSPHERE_H -#include "atmosphere.h" -#endif -#ifndef INCLUDED_LIB3DS_SHADOW_H -#include "shadow.h" -#endif -#ifndef INCLUDED_LIB3DS_VIEWPORT_H -#include "viewport.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * 3DS file structure - * \ingroup file - */ -struct Lib3dsFile { - Lib3dsDword mesh_version; - Lib3dsWord keyf_revision; - char name[12+1]; - Lib3dsFloat master_scale; - Lib3dsVector construction_plane; - Lib3dsRgb ambient; - Lib3dsShadow shadow; - Lib3dsBackground background; - Lib3dsAtmosphere atmosphere; - Lib3dsViewport viewport; - Lib3dsViewport viewport_keyf; - Lib3dsIntd frames; - Lib3dsIntd segment_from; - Lib3dsIntd segment_to; - Lib3dsIntd current_frame; - Lib3dsMaterial *materials; - Lib3dsMesh *meshes; - Lib3dsCamera *cameras; - Lib3dsLight *lights; - Lib3dsNode *nodes; -}; - -extern LIB3DSAPI Lib3dsFile* lib3ds_file_load(const char *filename); -extern LIB3DSAPI Lib3dsBool lib3ds_file_save(Lib3dsFile *file, const char *filename); -extern LIB3DSAPI Lib3dsFile* lib3ds_file_new(); -extern LIB3DSAPI void lib3ds_file_free(Lib3dsFile *file); -extern LIB3DSAPI void lib3ds_file_eval(Lib3dsFile *file, Lib3dsFloat t); -extern LIB3DSAPI Lib3dsBool lib3ds_file_read(Lib3dsFile *file, Lib3dsIo *io); -extern LIB3DSAPI Lib3dsBool lib3ds_file_write(Lib3dsFile *file, Lib3dsIo *io); -extern LIB3DSAPI void lib3ds_file_insert_material(Lib3dsFile *file, Lib3dsMaterial *material); -extern LIB3DSAPI void lib3ds_file_remove_material(Lib3dsFile *file, Lib3dsMaterial *material); -extern LIB3DSAPI Lib3dsMaterial* lib3ds_file_material_by_name(Lib3dsFile *file, const char *name); -extern LIB3DSAPI void lib3ds_file_dump_materials(Lib3dsFile *file); -extern LIB3DSAPI void lib3ds_file_insert_mesh(Lib3dsFile *file, Lib3dsMesh *mesh); -extern LIB3DSAPI void lib3ds_file_remove_mesh(Lib3dsFile *file, Lib3dsMesh *mesh); -extern LIB3DSAPI Lib3dsMesh* lib3ds_file_mesh_by_name(Lib3dsFile *file, const char *name); -extern LIB3DSAPI void lib3ds_file_dump_meshes(Lib3dsFile *file); -extern LIB3DSAPI void lib3ds_file_dump_instances(Lib3dsFile *file); -extern LIB3DSAPI void lib3ds_file_insert_camera(Lib3dsFile *file, Lib3dsCamera *camera); -extern LIB3DSAPI void lib3ds_file_remove_camera(Lib3dsFile *file, Lib3dsCamera *camera); -extern LIB3DSAPI Lib3dsCamera* lib3ds_file_camera_by_name(Lib3dsFile *file, const char *name); -extern LIB3DSAPI void lib3ds_file_dump_cameras(Lib3dsFile *file); -extern LIB3DSAPI void lib3ds_file_insert_light(Lib3dsFile *file, Lib3dsLight *light); -extern LIB3DSAPI void lib3ds_file_remove_light(Lib3dsFile *file, Lib3dsLight *light); -extern LIB3DSAPI Lib3dsLight* lib3ds_file_light_by_name(Lib3dsFile *file, const char *name); -extern LIB3DSAPI void lib3ds_file_dump_lights(Lib3dsFile *file); -extern LIB3DSAPI Lib3dsNode* lib3ds_file_node_by_name(Lib3dsFile *file, const char* name, Lib3dsNodeTypes type); -extern LIB3DSAPI Lib3dsNode* lib3ds_file_node_by_id(Lib3dsFile *file, Lib3dsWord node_id); -extern LIB3DSAPI void lib3ds_file_insert_node(Lib3dsFile *file, Lib3dsNode *node); -extern LIB3DSAPI Lib3dsBool lib3ds_file_remove_node(Lib3dsFile *file, Lib3dsNode *node); -extern LIB3DSAPI void lib3ds_file_bounding_box_of_objects(Lib3dsFile *file, Lib3dsBool include_meshes, Lib3dsBool include_cameras, Lib3dsBool include_lights, Lib3dsVector bmin, Lib3dsVector bmax); -extern LIB3DSAPI void lib3ds_file_bounding_box_of_nodes(Lib3dsFile *file, Lib3dsBool include_meshes, Lib3dsBool include_cameras, Lib3dsBool include_lights, Lib3dsVector bmin, Lib3dsVector bmax); -extern LIB3DSAPI void lib3ds_file_dump_nodes(Lib3dsFile *file); - -#ifdef __cplusplus -} -#endif -#endif - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/io.c b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/io.c deleted file mode 100644 index 8b7a8c219..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/io.c +++ /dev/null @@ -1,524 +0,0 @@ -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: io.c,v 1.9 2007/06/20 17:04:08 jeh Exp $ - */ -#include "io.h" -#include -#include - - -/*! - * \defgroup io Binary Input/Ouput Abstraction Layer - */ - -typedef union { - Lib3dsDword dword_value; - Lib3dsFloat float_value; -} Lib3dsDwordFloat; - - -struct Lib3dsIo { - void *self; - Lib3dsIoErrorFunc error_func; - Lib3dsIoSeekFunc seek_func; - Lib3dsIoTellFunc tell_func; - Lib3dsIoReadFunc read_func; - Lib3dsIoWriteFunc write_func; -}; - - -Lib3dsIo* -lib3ds_io_new(void *self, Lib3dsIoErrorFunc error_func, Lib3dsIoSeekFunc seek_func, - Lib3dsIoTellFunc tell_func, Lib3dsIoReadFunc read_func, Lib3dsIoWriteFunc write_func) -{ - Lib3dsIo *io = calloc(sizeof(Lib3dsIo),1); - ASSERT(io); - if (!io) { - return 0; - } - - io->self = self; - io->error_func = error_func; - io->seek_func = seek_func; - io->tell_func = tell_func; - io->read_func = read_func; - io->write_func = write_func; - - return io; -} - - -void -lib3ds_io_free(Lib3dsIo *io) -{ - ASSERT(io); - if (!io) { - return; - } - free(io); -} - - -Lib3dsBool -lib3ds_io_error(Lib3dsIo *io) -{ - ASSERT(io); - if (!io || !io->error_func) { - return 0; - } - return (*io->error_func)(io->self); -} - - -long -lib3ds_io_seek(Lib3dsIo *io, long offset, Lib3dsIoSeek origin) -{ - ASSERT(io); - if (!io || !io->seek_func) { - return 0; - } - return (*io->seek_func)(io->self, offset, origin); -} - - -long -lib3ds_io_tell(Lib3dsIo *io) -{ - ASSERT(io); - if (!io || !io->tell_func) { - return 0; - } - return (*io->tell_func)(io->self); -} - - -size_t -lib3ds_io_read(Lib3dsIo *io, void *buffer, size_t size) -{ - ASSERT(io); - if (!io || !io->read_func) { - return 0; - } - return (*io->read_func)(io->self, buffer, size); -} - - -size_t -lib3ds_io_write(Lib3dsIo *io, const void *buffer, size_t size) -{ - ASSERT(io); - if (!io || !io->write_func) { - return 0; - } - return (*io->write_func)(io->self, buffer, size); -} - - -/*! - * \ingroup io - * - * Read a byte from a file stream. - */ -Lib3dsByte -lib3ds_io_read_byte(Lib3dsIo *io) -{ - Lib3dsByte b; - - ASSERT(io); - lib3ds_io_read(io, &b, 1); - return(b); -} - - -/** - * Read a word from a file stream in little endian format. - */ -Lib3dsWord -lib3ds_io_read_word(Lib3dsIo *io) -{ - Lib3dsByte b[2]; - Lib3dsWord w; - - ASSERT(io); - lib3ds_io_read(io, b, 2); - w=((Lib3dsWord)b[1] << 8) | - ((Lib3dsWord)b[0]); - return(w); -} - - -/*! - * \ingroup io - * - * Read a dword from file a stream in little endian format. - */ -Lib3dsDword -lib3ds_io_read_dword(Lib3dsIo *io) -{ - Lib3dsByte b[4]; - Lib3dsDword d; - - ASSERT(io); - lib3ds_io_read(io, b, 4); - d=((Lib3dsDword)b[3] << 24) | - ((Lib3dsDword)b[2] << 16) | - ((Lib3dsDword)b[1] << 8) | - ((Lib3dsDword)b[0]); - return(d); -} - - -/*! - * \ingroup io - * - * Read a signed byte from a file stream. - */ -Lib3dsIntb -lib3ds_io_read_intb(Lib3dsIo *io) -{ - Lib3dsIntb b; - - ASSERT(io); - lib3ds_io_read(io, &b, 1); - return(b); -} - - -/*! - * \ingroup io - * - * Read a signed word from a file stream in little endian format. - */ -Lib3dsIntw -lib3ds_io_read_intw(Lib3dsIo *io) -{ - Lib3dsByte b[2]; - Lib3dsWord w; - - ASSERT(io); - lib3ds_io_read(io, b, 2); - w=((Lib3dsWord)b[1] << 8) | - ((Lib3dsWord)b[0]); - return((Lib3dsIntw)w); -} - - -/*! - * \ingroup io - * - * Read a signed dword a from file stream in little endian format. - */ -Lib3dsIntd -lib3ds_io_read_intd(Lib3dsIo *io) -{ - Lib3dsByte b[4]; - Lib3dsDword d; - - ASSERT(io); - lib3ds_io_read(io, b, 4); - d=((Lib3dsDword)b[3] << 24) | - ((Lib3dsDword)b[2] << 16) | - ((Lib3dsDword)b[1] << 8) | - ((Lib3dsDword)b[0]); - return((Lib3dsIntd)d); -} - - -/*! - * \ingroup io - * - * Read a float from a file stream in little endian format. - */ -Lib3dsFloat -lib3ds_io_read_float(Lib3dsIo *io) -{ - Lib3dsByte b[4]; - Lib3dsDwordFloat d; - - ASSERT(io); - lib3ds_io_read(io, b, 4); - d.dword_value=((Lib3dsDword)b[3] << 24) | - ((Lib3dsDword)b[2] << 16) | - ((Lib3dsDword)b[1] << 8) | - ((Lib3dsDword)b[0]); - return d.float_value; -} - - -/*! - * \ingroup io - * - * Read a vector from a file stream in little endian format. - * - * \param io IO input handle. - * \param v The vector to store the data. - */ -Lib3dsBool -lib3ds_io_read_vector(Lib3dsIo *io, Lib3dsVector v) -{ - ASSERT(io); - - v[0]=lib3ds_io_read_float(io); - v[1]=lib3ds_io_read_float(io); - v[2]=lib3ds_io_read_float(io); - - return(!lib3ds_io_error(io)); -} - - -/*! - * \ingroup io - */ -Lib3dsBool -lib3ds_io_read_rgb(Lib3dsIo *io, Lib3dsRgb rgb) -{ - ASSERT(io); - - rgb[0]=lib3ds_io_read_float(io); - rgb[1]=lib3ds_io_read_float(io); - rgb[2]=lib3ds_io_read_float(io); - - return(!lib3ds_io_error(io)); -} - - -/*! - * \ingroup io - * - * Read a zero-terminated string from a file stream. - * - * \param io IO input handle. - * \param s The buffer to store the read string. - * \param buflen Buffer length. - * - * \return True on success, False otherwise. - */ -Lib3dsBool -lib3ds_io_read_string(Lib3dsIo *io, char *s, int buflen) -{ - char c; - int k=0; - - ASSERT(io); - for (;;) { - if (lib3ds_io_read(io, &c, 1)!=1) { - return LIB3DS_FALSE; - } - *s++ = c; - if (!c) { - break; - } - ++k; - if (k>=buflen) { - return(LIB3DS_FALSE); - } - } - - return(!lib3ds_io_error(io)); -} - - -/*! - * \ingroup io - * - * Writes a byte into a file stream. - */ -Lib3dsBool -lib3ds_io_write_byte(Lib3dsIo *io, Lib3dsByte b) -{ - ASSERT(io); - if (lib3ds_io_write(io, &b, 1)!=1) { - return(LIB3DS_FALSE); - } - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup io - * - * Writes a word into a little endian file stream. - */ -Lib3dsBool -lib3ds_io_write_word(Lib3dsIo *io, Lib3dsWord w) -{ - Lib3dsByte b[2]; - - ASSERT(io); - b[1]=((Lib3dsWord)w & 0xFF00) >> 8; - b[0]=((Lib3dsWord)w & 0x00FF); - if (lib3ds_io_write(io, b, 2)!=2) { - return(LIB3DS_FALSE); - } - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup io - * - * Writes a dword into a little endian file stream. - */ -Lib3dsBool -lib3ds_io_write_dword(Lib3dsIo *io, Lib3dsDword d) -{ - Lib3dsByte b[4]; - - ASSERT(io); - b[3]=(Lib3dsByte)(((Lib3dsDword)d & 0xFF000000) >> 24); - b[2]=(Lib3dsByte)(((Lib3dsDword)d & 0x00FF0000) >> 16); - b[1]=(Lib3dsByte)(((Lib3dsDword)d & 0x0000FF00) >> 8); - b[0]=(Lib3dsByte)(((Lib3dsDword)d & 0x000000FF)); - if (lib3ds_io_write(io, b, 4)!=4) { - return(LIB3DS_FALSE); - } - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup io - * - * Writes a signed byte in a file stream. - */ -Lib3dsBool -lib3ds_io_write_intb(Lib3dsIo *io, Lib3dsIntb b) -{ - ASSERT(io); - if (lib3ds_io_write(io, &b, 1)!=1) { - return(LIB3DS_FALSE); - } - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup io - * - * Writes a signed word into a little endian file stream. - */ -Lib3dsBool -lib3ds_io_write_intw(Lib3dsIo *io, Lib3dsIntw w) -{ - Lib3dsByte b[2]; - - ASSERT(io); - b[1]=((Lib3dsWord)w & 0xFF00) >> 8; - b[0]=((Lib3dsWord)w & 0x00FF); - if (lib3ds_io_write(io, b, 2)!=2) { - return(LIB3DS_FALSE); - } - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup io - * - * Writes a signed dword into a little endian file stream. - */ -Lib3dsBool -lib3ds_io_write_intd(Lib3dsIo *io, Lib3dsIntd d) -{ - Lib3dsByte b[4]; - - ASSERT(io); - b[3]=(Lib3dsByte)(((Lib3dsDword)d & 0xFF000000) >> 24); - b[2]=(Lib3dsByte)(((Lib3dsDword)d & 0x00FF0000) >> 16); - b[1]=(Lib3dsByte)(((Lib3dsDword)d & 0x0000FF00) >> 8); - b[0]=(Lib3dsByte)(((Lib3dsDword)d & 0x000000FF)); - if (lib3ds_io_write(io, b, 4)!=4) { - return(LIB3DS_FALSE); - } - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup io - * - * Writes a float into a little endian file stream. - */ -Lib3dsBool -lib3ds_io_write_float(Lib3dsIo *io, Lib3dsFloat l) -{ - Lib3dsByte b[4]; - Lib3dsDwordFloat d; - - ASSERT(io); - d.float_value=l; - b[3]=(Lib3dsByte)(((Lib3dsDword)d.dword_value & 0xFF000000) >> 24); - b[2]=(Lib3dsByte)(((Lib3dsDword)d.dword_value & 0x00FF0000) >> 16); - b[1]=(Lib3dsByte)(((Lib3dsDword)d.dword_value & 0x0000FF00) >> 8); - b[0]=(Lib3dsByte)(((Lib3dsDword)d.dword_value & 0x000000FF)); - if (lib3ds_io_write(io, b, 4)!=4) { - return(LIB3DS_FALSE); - } - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup io - * - * Writes a vector into a file stream in little endian format. - */ -Lib3dsBool -lib3ds_io_write_vector(Lib3dsIo *io, Lib3dsVector v) -{ - int i; - for (i=0; i<3; ++i) { - if (!lib3ds_io_write_float(io, v[i])) { - return(LIB3DS_FALSE); - } - } - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup io - */ -Lib3dsBool -lib3ds_io_write_rgb(Lib3dsIo *io, Lib3dsRgb rgb) -{ - int i; - for (i=0; i<3; ++i) { - if (!lib3ds_io_write_float(io, rgb[i])) { - return(LIB3DS_FALSE); - } - } - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup io - * - * Writes a zero-terminated string into a file stream. - */ -Lib3dsBool -lib3ds_io_write_string(Lib3dsIo *io, const char *s) -{ - ASSERT(s); - ASSERT(io); - lib3ds_io_write(io, s, strlen(s)+1); - return(!lib3ds_io_error(io)); -} diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/io.h b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/io.h deleted file mode 100644 index dfbed72a4..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/io.h +++ /dev/null @@ -1,82 +0,0 @@ -/* -*- c -*- */ -#ifndef INCLUDED_LIB3DS_IO_H -#define INCLUDED_LIB3DS_IO_H -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: io.h,v 1.6 2007/06/20 17:04:08 jeh Exp $ - */ - -#ifndef INCLUDED_LIB3DS_TYPES_H -#include "types.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum Lib3dsIoSeek { - LIB3DS_SEEK_SET =0, - LIB3DS_SEEK_CUR =1, - LIB3DS_SEEK_END =2 -} Lib3dsIoSeek; - -typedef Lib3dsBool (*Lib3dsIoErrorFunc)(void *self); -typedef long (*Lib3dsIoSeekFunc)(void *self, long offset, Lib3dsIoSeek origin); -typedef long (*Lib3dsIoTellFunc)(void *self); -typedef size_t (*Lib3dsIoReadFunc)(void *self, void *buffer, size_t size); -typedef size_t (*Lib3dsIoWriteFunc)(void *self, const void *buffer, size_t size); - -extern LIB3DSAPI Lib3dsIo* lib3ds_io_new(void *self, Lib3dsIoErrorFunc error_func, - Lib3dsIoSeekFunc seek_func, Lib3dsIoTellFunc tell_func, - Lib3dsIoReadFunc read_func, Lib3dsIoWriteFunc write_func); -extern LIB3DSAPI void lib3ds_io_free(Lib3dsIo *io); -extern LIB3DSAPI Lib3dsBool lib3ds_io_error(Lib3dsIo *io); -extern LIB3DSAPI long lib3ds_io_seek(Lib3dsIo *io, long offset, Lib3dsIoSeek origin); -extern LIB3DSAPI long lib3ds_io_tell(Lib3dsIo *io); -extern LIB3DSAPI size_t lib3ds_io_read(Lib3dsIo *io, void *buffer, size_t size); -extern LIB3DSAPI size_t lib3ds_io_write(Lib3dsIo *io, const void *buffer, size_t size); - -extern LIB3DSAPI Lib3dsByte lib3ds_io_read_byte(Lib3dsIo *io); -extern LIB3DSAPI Lib3dsWord lib3ds_io_read_word(Lib3dsIo *io); -extern LIB3DSAPI Lib3dsDword lib3ds_io_read_dword(Lib3dsIo *io); -extern LIB3DSAPI Lib3dsIntb lib3ds_io_read_intb(Lib3dsIo *io); -extern LIB3DSAPI Lib3dsIntw lib3ds_io_read_intw(Lib3dsIo *io); -extern LIB3DSAPI Lib3dsIntd lib3ds_io_read_intd(Lib3dsIo *io); -extern LIB3DSAPI Lib3dsFloat lib3ds_io_read_float(Lib3dsIo *io); -extern LIB3DSAPI Lib3dsBool lib3ds_io_read_vector(Lib3dsIo *io, Lib3dsVector v); -extern LIB3DSAPI Lib3dsBool lib3ds_io_read_rgb(Lib3dsIo *io, Lib3dsRgb rgb); -extern LIB3DSAPI Lib3dsBool lib3ds_io_read_string(Lib3dsIo *io, char *s, int buflen); - -extern LIB3DSAPI Lib3dsBool lib3ds_io_write_byte(Lib3dsIo *io, Lib3dsByte b); -extern LIB3DSAPI Lib3dsBool lib3ds_io_write_word(Lib3dsIo *io, Lib3dsWord w); -extern LIB3DSAPI Lib3dsBool lib3ds_io_write_dword(Lib3dsIo *io, Lib3dsDword d); -extern LIB3DSAPI Lib3dsBool lib3ds_io_write_intb(Lib3dsIo *io, Lib3dsIntb b); -extern LIB3DSAPI Lib3dsBool lib3ds_io_write_intw(Lib3dsIo *io, Lib3dsIntw w); -extern LIB3DSAPI Lib3dsBool lib3ds_io_write_intd(Lib3dsIo *io, Lib3dsIntd d); -extern LIB3DSAPI Lib3dsBool lib3ds_io_write_float(Lib3dsIo *io, Lib3dsFloat l); -extern LIB3DSAPI Lib3dsBool lib3ds_io_write_vector(Lib3dsIo *io, Lib3dsVector v); -extern LIB3DSAPI Lib3dsBool lib3ds_io_write_rgb(Lib3dsIo *io, Lib3dsRgb rgb); -extern LIB3DSAPI Lib3dsBool lib3ds_io_write_string(Lib3dsIo *io, const char *s); - -#ifdef __cplusplus -} -#endif -#endif - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/light.c b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/light.c deleted file mode 100644 index 311f1d623..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/light.c +++ /dev/null @@ -1,415 +0,0 @@ -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: light.c,v 1.15 2007/06/20 17:04:08 jeh Exp $ - */ -#include "light.h" -#include "chunk.h" -#include "io.h" -#include -#include -#include - - -/*! - * \defgroup light Lights - */ -/*! - - -/*! - * \ingroup light - */ -Lib3dsLight* -lib3ds_light_new(const char *name) -{ - Lib3dsLight *light; - - ASSERT(name); - ASSERT(strlen(name)<64); - - light=(Lib3dsLight*)calloc(sizeof(Lib3dsLight), 1); - if (!light) { - return(0); - } - strcpy(light->name, name); - return(light); -} - - -/*! - * \ingroup light - */ -void -lib3ds_light_free(Lib3dsLight *light) -{ - memset(light, 0, sizeof(Lib3dsLight)); - free(light); -} - - -/*! - * \ingroup light - */ -void -lib3ds_light_dump(Lib3dsLight *light) -{ - ASSERT(light); - printf(" name: %s\n", light->name); - printf(" spot_light: %s\n", light->spot_light ? "yes" : "no"); - printf(" see_cone: %s\n", light->see_cone ? "yes" : "no"); - printf(" color: (%f, %f, %f)\n", - light->color[0], light->color[1], light->color[2]); - printf(" position (%f, %f, %f)\n", - light->position[0], light->position[1], light->position[2]); - printf(" spot (%f, %f, %f)\n", - light->spot[0], light->spot[1], light->spot[2]); - printf(" roll: %f\n", light->roll); - printf(" off: %s\n", light->off ? "yes" : "no"); - printf(" outer_range: %f\n", light->outer_range); - printf(" inner_range: %f\n", light->inner_range); - printf(" multiplier: %f\n", light->multiplier); - printf(" attenuation: %f\n", light->attenuation); - printf(" rectangular_spot: %s\n", light->rectangular_spot ? "yes" : "no"); - printf(" shadowed: %s\n", light->shadowed ? "yes" : "no"); - printf(" shadow_bias: %f\n", light->shadow_bias); - printf(" shadow_filter: %f\n", light->shadow_filter); - printf(" shadow_size: %d\n", light->shadow_size); - printf(" spot_aspect: %f\n", light->spot_aspect); - printf(" use_projector: %s\n", light->use_projector ? "yes" : "no"); - printf(" projector: %s\n", light->projector); - printf(" spot_overshoot: %d\n", (int)light->spot_overshoot); - printf(" ray_shadows: %s\n", light->ray_shadows ? "yes" : "no"); - printf(" ray_bias: %f\n", light->ray_bias); - printf(" hot_spot: %f\n", light->hot_spot); - printf(" fall_off: %f\n", light->fall_off); - printf("\n"); -} - - -/*! - * \ingroup light - */ -static Lib3dsBool -spotlight_read(Lib3dsLight *light, Lib3dsIo *io) -{ - Lib3dsChunk c; - Lib3dsWord chunk; - int i; - - if (!lib3ds_chunk_read_start(&c, LIB3DS_DL_SPOTLIGHT, io)) { - return(LIB3DS_FALSE); - } - light->spot_light=LIB3DS_TRUE; - for (i=0; i<3; ++i) { - light->spot[i]=lib3ds_io_read_float(io); - } - light->hot_spot = lib3ds_io_read_float(io); - light->fall_off = lib3ds_io_read_float(io); - lib3ds_chunk_read_tell(&c, io); - - while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) { - switch (chunk) { - case LIB3DS_DL_SPOT_ROLL: - { - light->roll=lib3ds_io_read_float(io); - } - break; - case LIB3DS_DL_SHADOWED: - { - light->shadowed=LIB3DS_TRUE; - } - break; - case LIB3DS_DL_LOCAL_SHADOW2: - { - light->shadow_bias=lib3ds_io_read_float(io); - light->shadow_filter=lib3ds_io_read_float(io); - light->shadow_size=lib3ds_io_read_intw(io); - } - break; - case LIB3DS_DL_SEE_CONE: - { - light->see_cone=LIB3DS_TRUE; - } - break; - case LIB3DS_DL_SPOT_RECTANGULAR: - { - light->rectangular_spot=LIB3DS_TRUE; - } - break; - case LIB3DS_DL_SPOT_ASPECT: - { - light->spot_aspect=lib3ds_io_read_float(io); - } - break; - case LIB3DS_DL_SPOT_PROJECTOR: - { - light->use_projector=LIB3DS_TRUE; - if (!lib3ds_io_read_string(io, light->projector, 64)) { - return(LIB3DS_FALSE); - } - } - case LIB3DS_DL_SPOT_OVERSHOOT: - { - light->spot_overshoot=LIB3DS_TRUE; - } - break; - case LIB3DS_DL_RAY_BIAS: - { - light->ray_bias=lib3ds_io_read_float(io); - } - break; - case LIB3DS_DL_RAYSHAD: - { - light->ray_shadows=LIB3DS_TRUE; - } - break; - default: - lib3ds_chunk_unknown(chunk); - } - } - - lib3ds_chunk_read_end(&c, io); - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup light - */ -Lib3dsBool -lib3ds_light_read(Lib3dsLight *light, Lib3dsIo *io) -{ - Lib3dsChunk c; - Lib3dsWord chunk; - - if (!lib3ds_chunk_read_start(&c, LIB3DS_N_DIRECT_LIGHT, io)) { - return(LIB3DS_FALSE); - } - { - int i; - for (i=0; i<3; ++i) { - light->position[i]=lib3ds_io_read_float(io); - } - } - lib3ds_chunk_read_tell(&c, io); - - while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) { - switch (chunk) { - case LIB3DS_COLOR_F: - { - int i; - for (i=0; i<3; ++i) { - light->color[i]=lib3ds_io_read_float(io); - } - } - break; - case LIB3DS_DL_OFF: - { - light->off=LIB3DS_TRUE; - } - break; - case LIB3DS_DL_OUTER_RANGE: - { - light->outer_range=lib3ds_io_read_float(io); - } - break; - case LIB3DS_DL_INNER_RANGE: - { - light->inner_range=lib3ds_io_read_float(io); - } - break; - case LIB3DS_DL_MULTIPLIER: - { - light->multiplier=lib3ds_io_read_float(io); - } - break; - case LIB3DS_DL_EXCLUDE: - { - /* FIXME: */ - lib3ds_chunk_unknown(chunk); - } - case LIB3DS_DL_ATTENUATE: - { - light->attenuation=lib3ds_io_read_float(io); - } - break; - case LIB3DS_DL_SPOTLIGHT: - { - lib3ds_chunk_read_reset(&c, io); - if (!spotlight_read(light, io)) { - return(LIB3DS_FALSE); - } - } - break; - default: - lib3ds_chunk_unknown(chunk); - } - } - - lib3ds_chunk_read_end(&c, io); - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup light - */ -Lib3dsBool -lib3ds_light_write(Lib3dsLight *light, Lib3dsIo *io) -{ - Lib3dsChunk c; - - c.chunk=LIB3DS_N_DIRECT_LIGHT; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - lib3ds_io_write_vector(io, light->position); - { /*---- LIB3DS_COLOR_F ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_COLOR_F; - c.size=18; - lib3ds_chunk_write(&c, io); - lib3ds_io_write_rgb(io, light->color); - } - if (light->off) { /*---- LIB3DS_DL_OFF ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_DL_OFF; - c.size=6; - lib3ds_chunk_write(&c, io); - } - { /*---- LIB3DS_DL_OUTER_RANGE ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_DL_OUTER_RANGE; - c.size=10; - lib3ds_chunk_write(&c, io); - lib3ds_io_write_float(io, light->outer_range); - } - { /*---- LIB3DS_DL_INNER_RANGE ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_DL_INNER_RANGE; - c.size=10; - lib3ds_chunk_write(&c, io); - lib3ds_io_write_float(io, light->inner_range); - } - { /*---- LIB3DS_DL_MULTIPLIER ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_DL_MULTIPLIER; - c.size=10; - lib3ds_chunk_write(&c, io); - lib3ds_io_write_float(io, light->multiplier); - } - if (light->attenuation) { /*---- LIB3DS_DL_ATTENUATE ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_DL_ATTENUATE; - c.size=6; - lib3ds_chunk_write(&c, io); - } - - if (light->spot_light) { - Lib3dsChunk c; - - c.chunk=LIB3DS_DL_SPOTLIGHT; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - lib3ds_io_write_vector(io, light->spot); - lib3ds_io_write_float(io, light->hot_spot); - lib3ds_io_write_float(io, light->fall_off); - - { /*---- LIB3DS_DL_SPOT_ROLL ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_DL_SPOT_ROLL; - c.size=10; - lib3ds_chunk_write(&c, io); - lib3ds_io_write_float(io, light->roll); - } - if (light->shadowed) { /*---- LIB3DS_DL_SHADOWED ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_DL_SHADOWED; - c.size=6; - lib3ds_chunk_write(&c, io); - } - if ((fabs(light->shadow_bias)>LIB3DS_EPSILON) || - (fabs(light->shadow_filter)>LIB3DS_EPSILON) || - (light->shadow_size!=0)) { /*---- LIB3DS_DL_LOCAL_SHADOW2 ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_DL_LOCAL_SHADOW2; - c.size=16; - lib3ds_chunk_write(&c, io); - lib3ds_io_write_float(io, light->shadow_bias); - lib3ds_io_write_float(io, light->shadow_filter); - lib3ds_io_write_intw(io, light->shadow_size); - } - if (light->see_cone) { /*---- LIB3DS_DL_SEE_CONE ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_DL_SEE_CONE; - c.size=6; - lib3ds_chunk_write(&c, io); - } - if (light->rectangular_spot) { /*---- LIB3DS_DL_SPOT_RECTANGULAR ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_DL_SPOT_RECTANGULAR; - c.size=6; - lib3ds_chunk_write(&c, io); - } - if (fabs(light->spot_aspect)>LIB3DS_EPSILON) { /*---- LIB3DS_DL_SPOT_ASPECT ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_DL_SPOT_ASPECT; - c.size=10; - lib3ds_chunk_write(&c, io); - lib3ds_io_write_float(io, light->spot_aspect); - } - if (light->use_projector) { /*---- LIB3DS_DL_SPOT_PROJECTOR ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_DL_SPOT_PROJECTOR; - c.size=10; - lib3ds_chunk_write(&c, io); - lib3ds_io_write_string(io, light->projector); - } - if (light->spot_overshoot) { /*---- LIB3DS_DL_SPOT_OVERSHOOT ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_DL_SPOT_OVERSHOOT; - c.size=6; - lib3ds_chunk_write(&c, io); - } - if (fabs(light->ray_bias)>LIB3DS_EPSILON) { /*---- LIB3DS_DL_RAY_BIAS ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_DL_RAY_BIAS; - c.size=10; - lib3ds_chunk_write(&c, io); - lib3ds_io_write_float(io, light->ray_bias); - } - if (light->ray_shadows) { /*---- LIB3DS_DL_RAYSHAD ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_DL_RAYSHAD; - c.size=6; - lib3ds_chunk_write(&c, io); - } - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - } - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - return(LIB3DS_TRUE); -} - - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/light.h b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/light.h deleted file mode 100644 index b86181ddc..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/light.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- c -*- */ -#ifndef INCLUDED_LIB3DS_LIGHT_H -#define INCLUDED_LIB3DS_LIGHT_H -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: light.h,v 1.13 2007/06/20 17:04:08 jeh Exp $ - */ - -#ifndef INCLUDED_LIB3DS_TYPES_H -#include "types.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Light - * \ingroup light - */ -struct Lib3dsLight { - Lib3dsLight *next; - char name[64]; - Lib3dsDword object_flags; /*< @see Lib3dsObjectFlags */ - Lib3dsBool spot_light; - Lib3dsBool see_cone; - Lib3dsRgb color; - Lib3dsVector position; - Lib3dsVector spot; - Lib3dsFloat roll; - Lib3dsBool off; - Lib3dsFloat outer_range; - Lib3dsFloat inner_range; - Lib3dsFloat multiplier; - /*const char** excludes;*/ - Lib3dsFloat attenuation; - Lib3dsBool rectangular_spot; - Lib3dsBool shadowed; - Lib3dsFloat shadow_bias; - Lib3dsFloat shadow_filter; - Lib3dsIntw shadow_size; - Lib3dsFloat spot_aspect; - Lib3dsBool use_projector; - char projector[64]; - Lib3dsIntd spot_overshoot; - Lib3dsBool ray_shadows; - Lib3dsFloat ray_bias; - Lib3dsFloat hot_spot; - Lib3dsFloat fall_off; -}; - -extern LIB3DSAPI Lib3dsLight* lib3ds_light_new(const char *name); -extern LIB3DSAPI void lib3ds_light_free(Lib3dsLight *mesh); -extern LIB3DSAPI void lib3ds_light_dump(Lib3dsLight *light); -extern LIB3DSAPI Lib3dsBool lib3ds_light_read(Lib3dsLight *light, Lib3dsIo *io); -extern LIB3DSAPI Lib3dsBool lib3ds_light_write(Lib3dsLight *light, Lib3dsIo *io); - -#ifdef __cplusplus -} -#endif -#endif - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/material.c b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/material.c deleted file mode 100644 index 181c93224..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/material.c +++ /dev/null @@ -1,1089 +0,0 @@ -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: material.c,v 1.24 2007/06/20 17:04:08 jeh Exp $ - */ -#include "material.h" -#include "chunk.h" -#include "io.h" -#include -#include -#include - - -/*! - * \defgroup material Materials - */ - - -static void -initialize_texture_map(Lib3dsTextureMap *map) -{ - map->flags = 0x10; - map->percent = 1.0f; - map->scale[0] = 1.0f; - map->scale[1] = 1.0f; -} - - -/*! - * Creates and returns a new, empty Lib3dsMaterial object. - * - * Initial value of the material is a shiny grey. - * - * \return A pointer to the Lib3dsMaterial structure. - * If the structure cannot be allocated, NULL is returned. - * - * \ingroup material - */ -Lib3dsMaterial* -lib3ds_material_new() -{ - Lib3dsMaterial *mat; - - mat = (Lib3dsMaterial*)calloc(sizeof(Lib3dsMaterial), 1); - if (!mat) { - return(0); - } - - mat->ambient[0] = mat->ambient[1] = mat->ambient[2] = 0.588235f; - mat->diffuse[0] = mat->diffuse[1] = mat->diffuse[2] = 0.588235f; - mat->specular[0] = mat->specular[1] = mat->specular[2] = 0.898039f; - mat->shininess = 0.1f; - mat->wire_size = 1.0f; - mat->shading = 3; - - initialize_texture_map(&mat->texture1_map); - initialize_texture_map(&mat->texture1_mask); - initialize_texture_map(&mat->texture2_map); - initialize_texture_map(&mat->texture2_mask); - initialize_texture_map(&mat->opacity_map); - initialize_texture_map(&mat->opacity_mask); - initialize_texture_map(&mat->bump_map); - initialize_texture_map(&mat->bump_mask); - initialize_texture_map(&mat->specular_map); - initialize_texture_map(&mat->specular_mask); - initialize_texture_map(&mat->shininess_map); - initialize_texture_map(&mat->shininess_mask); - initialize_texture_map(&mat->self_illum_map); - initialize_texture_map(&mat->self_illum_mask); - initialize_texture_map(&mat->reflection_map); - initialize_texture_map(&mat->reflection_mask); - - return(mat); -} - - -/*! - * \ingroup material - */ -void -lib3ds_material_free(Lib3dsMaterial *material) -{ - memset(material, 0, sizeof(Lib3dsMaterial)); - free(material); -} - - -static Lib3dsBool -color_read(Lib3dsRgba rgb, Lib3dsIo *io) -{ - Lib3dsChunk c; - Lib3dsWord chunk; - Lib3dsBool have_lin=LIB3DS_FALSE; - - if (!lib3ds_chunk_read_start(&c, 0, io)) { - return(LIB3DS_FALSE); - } - - while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) { - switch (chunk) { - case LIB3DS_LIN_COLOR_24: - { - int i; - for (i=0; i<3; ++i) { - rgb[i]=1.0f*lib3ds_io_read_byte(io)/255.0f; - } - rgb[3]=1.0f; - } - have_lin=LIB3DS_TRUE; - break; - case LIB3DS_COLOR_24: - /* gamma corrected color chunk - replaced in 3ds R3 by LIN_COLOR_24 */ - if (!have_lin) { - int i; - for (i=0; i<3; ++i) { - rgb[i]=1.0f*lib3ds_io_read_byte(io)/255.0f; - } - rgb[3]=1.0f; - } - break; - case LIB3DS_LIN_COLOR_F: - { - int i; - for (i=0; i<3; ++i) { - rgb[i]=lib3ds_io_read_float(io); - } - rgb[3]=1.0f; - } - have_lin=LIB3DS_TRUE; - break; - case LIB3DS_COLOR_F: - if (!have_lin) { - int i; - for (i=0; i<3; ++i) { - rgb[i]=lib3ds_io_read_float(io); - } - rgb[3]=1.0f; - } - break; - default: - lib3ds_chunk_unknown(chunk); - } - } - - lib3ds_chunk_read_end(&c, io); - return(LIB3DS_TRUE); -} - - -static Lib3dsBool -int_percentage_read(Lib3dsFloat *p, Lib3dsIo *io) -{ - Lib3dsChunk c; - Lib3dsWord chunk; - - if (!lib3ds_chunk_read_start(&c, 0, io)) { - return(LIB3DS_FALSE); - } - - while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) { - switch (chunk) { - case LIB3DS_INT_PERCENTAGE: - { - Lib3dsIntw i=lib3ds_io_read_intw(io); - *p=(Lib3dsFloat)(1.0*i/100.0); - } - break; - default: - lib3ds_chunk_unknown(chunk); - } - } - - lib3ds_chunk_read_end(&c, io); - return(LIB3DS_TRUE); -} - - -static Lib3dsBool -texture_map_read(Lib3dsTextureMap *map, Lib3dsIo *io) -{ - Lib3dsChunk c; - Lib3dsWord chunk; - - if (!lib3ds_chunk_read_start(&c, 0, io)) { - return(LIB3DS_FALSE); - } - - while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) { - switch (chunk) { - case LIB3DS_INT_PERCENTAGE: - { - map->percent=1.0f*lib3ds_io_read_intw(io)/100.0f; - } - break; - case LIB3DS_MAT_MAPNAME: - { - if (!lib3ds_io_read_string(io, map->name, 64)) { - return(LIB3DS_FALSE); - } - lib3ds_chunk_dump_info(" NAME=%s", map->name); - } - break; - case LIB3DS_MAT_MAP_TILING: - { - map->flags=lib3ds_io_read_word(io); - } - break; - case LIB3DS_MAT_MAP_TEXBLUR: - { - map->blur=lib3ds_io_read_float(io); - } - break; - case LIB3DS_MAT_MAP_USCALE: - { - map->scale[0]=lib3ds_io_read_float(io); - } - break; - case LIB3DS_MAT_MAP_VSCALE: - { - map->scale[1]=lib3ds_io_read_float(io); - } - break; - case LIB3DS_MAT_MAP_UOFFSET: - { - map->offset[0]=lib3ds_io_read_float(io); - } - break; - case LIB3DS_MAT_MAP_VOFFSET: - { - map->offset[1]=lib3ds_io_read_float(io); - } - break; - case LIB3DS_MAT_MAP_ANG: - { - map->rotation=lib3ds_io_read_float(io); - } - break; - case LIB3DS_MAT_MAP_COL1: - { - map->tint_1[0]=1.0f*lib3ds_io_read_byte(io)/255.0f; - map->tint_1[1]=1.0f*lib3ds_io_read_byte(io)/255.0f; - map->tint_1[2]=1.0f*lib3ds_io_read_byte(io)/255.0f; - } - break; - case LIB3DS_MAT_MAP_COL2: - { - map->tint_2[0]=1.0f*lib3ds_io_read_byte(io)/255.0f; - map->tint_2[1]=1.0f*lib3ds_io_read_byte(io)/255.0f; - map->tint_2[2]=1.0f*lib3ds_io_read_byte(io)/255.0f; - } - break; - case LIB3DS_MAT_MAP_RCOL: - { - map->tint_r[0]=1.0f*lib3ds_io_read_byte(io)/255.0f; - map->tint_r[1]=1.0f*lib3ds_io_read_byte(io)/255.0f; - map->tint_r[2]=1.0f*lib3ds_io_read_byte(io)/255.0f; - } - break; - case LIB3DS_MAT_MAP_GCOL: - { - map->tint_g[0]=1.0f*lib3ds_io_read_byte(io)/255.0f; - map->tint_g[1]=1.0f*lib3ds_io_read_byte(io)/255.0f; - map->tint_g[2]=1.0f*lib3ds_io_read_byte(io)/255.0f; - } - break; - case LIB3DS_MAT_MAP_BCOL: - { - map->tint_b[0]=1.0f*lib3ds_io_read_byte(io)/255.0f; - map->tint_b[1]=1.0f*lib3ds_io_read_byte(io)/255.0f; - map->tint_b[2]=1.0f*lib3ds_io_read_byte(io)/255.0f; - } - break; - default: - lib3ds_chunk_unknown(chunk); - } - } - - lib3ds_chunk_read_end(&c, io); - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup material - */ -static void -texture_dump(const char *maptype, Lib3dsTextureMap *texture) -{ - ASSERT(texture); - if (strlen(texture->name)==0) { - return; - } - printf(" %s:\n", maptype); - printf(" name: %s\n", texture->name); - printf(" flags: %X\n", (unsigned)texture->flags); - printf(" percent: %f\n", texture->percent); - printf(" blur: %f\n", texture->blur); - printf(" scale: (%f, %f)\n", texture->scale[0], texture->scale[1]); - printf(" offset: (%f, %f)\n", texture->offset[0], texture->offset[1]); - printf(" rotation: %f\n", texture->rotation); - printf(" tint_1: (%f, %f, %f)\n", - texture->tint_1[0], texture->tint_1[1], texture->tint_1[2]); - printf(" tint_2: (%f, %f, %f)\n", - texture->tint_2[0], texture->tint_2[1], texture->tint_2[2]); - printf(" tint_r: (%f, %f, %f)\n", - texture->tint_r[0], texture->tint_r[1], texture->tint_r[2]); - printf(" tint_g: (%f, %f, %f)\n", - texture->tint_g[0], texture->tint_g[1], texture->tint_g[2]); - printf(" tint_b: (%f, %f, %f)\n", - texture->tint_b[0], texture->tint_b[1], texture->tint_b[2]); -} - - -/*! - * \ingroup material - */ -void -lib3ds_material_dump(Lib3dsMaterial *material) -{ - ASSERT(material); - printf(" name: %s\n", material->name); - printf(" ambient: (%f, %f, %f)\n", - material->ambient[0], material->ambient[1], material->ambient[2]); - printf(" diffuse: (%f, %f, %f)\n", - material->diffuse[0], material->diffuse[1], material->diffuse[2]); - printf(" specular: (%f, %f, %f)\n", - material->specular[0], material->specular[1], material->specular[2]); - printf(" shininess: %f\n", material->shininess); - printf(" shin_strength: %f\n", material->shin_strength); - printf(" use_blur: %s\n", material->use_blur ? "yes" : "no"); - printf(" blur: %f\n", material->blur); - printf(" falloff: %f\n", material->falloff); - printf(" additive: %s\n", material->additive ? "yes" : "no"); - printf(" use_falloff: %s\n", material->use_falloff ? "yes" : "no"); - printf(" self_illum: %s\n", material->self_illum ? "yes" : "no"); - printf(" self_ilpct: %f\n", material->self_ilpct); - printf(" shading: %d\n", material->shading); - printf(" soften: %s\n", material->soften ? "yes" : "no"); - printf(" face_map: %s\n", material->face_map ? "yes" : "no"); - printf(" two_sided: %s\n", material->two_sided ? "yes" : "no"); - printf(" map_decal: %s\n", material->map_decal ? "yes" : "no"); - printf(" use_wire: %s\n", material->use_wire ? "yes" : "no"); - printf(" use_wire_abs: %s\n", material->use_wire_abs ? "yes" : "no"); - printf(" wire_size: %f\n", material->wire_size); - texture_dump("texture1_map", &material->texture1_map); - texture_dump("texture1_mask", &material->texture1_mask); - texture_dump("texture2_map", &material->texture2_map); - texture_dump("texture2_mask", &material->texture2_mask); - texture_dump("opacity_map", &material->opacity_map); - texture_dump("opacity_mask", &material->opacity_mask); - texture_dump("bump_map", &material->bump_map); - texture_dump("bump_mask", &material->bump_mask); - texture_dump("specular_map", &material->specular_map); - texture_dump("specular_mask", &material->specular_mask); - texture_dump("shininess_map", &material->shininess_map); - texture_dump("shininess_mask", &material->shininess_mask); - texture_dump("self_illum_map", &material->self_illum_map); - texture_dump("self_illum_mask", &material->self_illum_mask); - texture_dump("reflection_map", &material->reflection_map); - texture_dump("reflection_mask", &material->reflection_mask); - printf(" autorefl_map:\n"); - printf(" flags %X\n", (unsigned)material->autorefl_map.flags); - printf(" level %d\n", (int)material->autorefl_map.level); - printf(" size %d\n", (int)material->autorefl_map.size); - printf(" frame_step %d\n", (int)material->autorefl_map.frame_step); - printf("\n"); -} - - -/*! - * \ingroup material - */ -Lib3dsBool -lib3ds_material_read(Lib3dsMaterial *material, Lib3dsIo *io) -{ - Lib3dsChunk c; - Lib3dsWord chunk; - - ASSERT(material); - if (!lib3ds_chunk_read_start(&c, LIB3DS_MAT_ENTRY, io)) { - return(LIB3DS_FALSE); - } - - while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) { - switch (chunk) { - case LIB3DS_MAT_NAME: - { - if (!lib3ds_io_read_string(io, material->name, 64)) { - return(LIB3DS_FALSE); - } - lib3ds_chunk_dump_info(" NAME=%s", material->name); - } - break; - case LIB3DS_MAT_AMBIENT: - { - lib3ds_chunk_read_reset(&c, io); - if (!color_read(material->ambient, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_MAT_DIFFUSE: - { - lib3ds_chunk_read_reset(&c, io); - if (!color_read(material->diffuse, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_MAT_SPECULAR: - { - lib3ds_chunk_read_reset(&c, io); - if (!color_read(material->specular, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_MAT_SHININESS: - { - lib3ds_chunk_read_reset(&c, io); - if (!int_percentage_read(&material->shininess, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_MAT_SHIN2PCT: - { - lib3ds_chunk_read_reset(&c, io); - if (!int_percentage_read(&material->shin_strength, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_MAT_TRANSPARENCY: - { - lib3ds_chunk_read_reset(&c, io); - if (!int_percentage_read(&material->transparency, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_MAT_XPFALL: - { - lib3ds_chunk_read_reset(&c, io); - if (!int_percentage_read(&material->falloff, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_MAT_SELF_ILPCT: - { - lib3ds_chunk_read_reset(&c, io); - if (!int_percentage_read(&material->self_ilpct, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_MAT_USE_XPFALL: - { - material->use_falloff=LIB3DS_TRUE; - } - break; - case LIB3DS_MAT_REFBLUR: - { - lib3ds_chunk_read_reset(&c, io); - if (!int_percentage_read(&material->blur, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_MAT_USE_REFBLUR: - { - material->use_blur=LIB3DS_TRUE; - } - break; - case LIB3DS_MAT_SHADING: - { - material->shading=lib3ds_io_read_intw(io); - } - break; - case LIB3DS_MAT_SELF_ILLUM: - { - material->self_illum=LIB3DS_TRUE; - } - break; - case LIB3DS_MAT_TWO_SIDE: - { - material->two_sided=LIB3DS_TRUE; - } - break; - case LIB3DS_MAT_DECAL: - { - material->map_decal=LIB3DS_TRUE; - } - break; - case LIB3DS_MAT_ADDITIVE: - { - material->additive=LIB3DS_TRUE; - } - break; - case LIB3DS_MAT_FACEMAP: - { - material->face_map=LIB3DS_TRUE; - } - break; - case LIB3DS_MAT_PHONGSOFT: - { - material->soften=LIB3DS_TRUE; - } - break; - case LIB3DS_MAT_WIRE: - { - material->use_wire=LIB3DS_TRUE; - } - break; - case LIB3DS_MAT_WIREABS: - { - material->use_wire_abs=LIB3DS_TRUE; - } - break; - case LIB3DS_MAT_WIRE_SIZE: - { - material->wire_size=lib3ds_io_read_float(io); - } - break; - case LIB3DS_MAT_TEXMAP: - { - lib3ds_chunk_read_reset(&c, io); - if (!texture_map_read(&material->texture1_map, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_MAT_TEXMASK: - { - lib3ds_chunk_read_reset(&c, io); - if (!texture_map_read(&material->texture1_mask, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_MAT_TEX2MAP: - { - lib3ds_chunk_read_reset(&c, io); - if (!texture_map_read(&material->texture2_map, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_MAT_TEX2MASK: - { - lib3ds_chunk_read_reset(&c, io); - if (!texture_map_read(&material->texture2_mask, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_MAT_OPACMAP: - { - lib3ds_chunk_read_reset(&c, io); - if (!texture_map_read(&material->opacity_map, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_MAT_OPACMASK: - { - lib3ds_chunk_read_reset(&c, io); - if (!texture_map_read(&material->opacity_mask, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_MAT_BUMPMAP: - { - lib3ds_chunk_read_reset(&c, io); - if (!texture_map_read(&material->bump_map, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_MAT_BUMPMASK: - { - lib3ds_chunk_read_reset(&c, io); - if (!texture_map_read(&material->bump_mask, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_MAT_SPECMAP: - { - lib3ds_chunk_read_reset(&c, io); - if (!texture_map_read(&material->specular_map, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_MAT_SPECMASK: - { - lib3ds_chunk_read_reset(&c, io); - if (!texture_map_read(&material->specular_mask, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_MAT_SHINMAP: - { - lib3ds_chunk_read_reset(&c, io); - if (!texture_map_read(&material->shininess_map, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_MAT_SHINMASK: - { - lib3ds_chunk_read_reset(&c, io); - if (!texture_map_read(&material->shininess_mask, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_MAT_SELFIMAP: - { - lib3ds_chunk_read_reset(&c, io); - if (!texture_map_read(&material->self_illum_map, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_MAT_SELFIMASK: - { - lib3ds_chunk_read_reset(&c, io); - if (!texture_map_read(&material->self_illum_mask, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_MAT_REFLMAP: - { - lib3ds_chunk_read_reset(&c, io); - if (!texture_map_read(&material->reflection_map, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_MAT_REFLMASK: - { - lib3ds_chunk_read_reset(&c, io); - if (!texture_map_read(&material->reflection_mask, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_MAT_ACUBIC: - { - lib3ds_io_read_intb(io); - material->autorefl_map.level=lib3ds_io_read_intb(io); - material->autorefl_map.flags=lib3ds_io_read_intw(io); - material->autorefl_map.size=lib3ds_io_read_intd(io); - material->autorefl_map.frame_step=lib3ds_io_read_intd(io); - } - break; - default: - lib3ds_chunk_unknown(chunk); - } - } - - lib3ds_chunk_read_end(&c, io); - return(LIB3DS_TRUE); -} - - -static Lib3dsBool -color_write(Lib3dsRgba rgb, Lib3dsIo *io) -{ - Lib3dsChunk c; - - c.chunk=LIB3DS_COLOR_24; - c.size=9; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*rgb[0]+0.5)); - lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*rgb[1]+0.5)); - lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*rgb[2]+0.5)); - - c.chunk=LIB3DS_LIN_COLOR_24; - c.size=9; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*rgb[0]+0.5)); - lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*rgb[1]+0.5)); - lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*rgb[2]+0.5)); - - return(LIB3DS_TRUE); -} - - -static Lib3dsBool -int_percentage_write(Lib3dsFloat p, Lib3dsIo *io) -{ - Lib3dsChunk c; - - c.chunk=LIB3DS_INT_PERCENTAGE; - c.size=8; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_intw(io, (Lib3dsByte)floor(100.0*p+0.5)); - - return(LIB3DS_TRUE); -} - - -static Lib3dsBool -texture_map_write(Lib3dsWord chunk, Lib3dsTextureMap *map, Lib3dsIo *io) -{ - Lib3dsChunk c; - - if (strlen(map->name)==0) { - return(LIB3DS_TRUE); - } - c.chunk=chunk; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - - int_percentage_write(map->percent,io); - - { /*---- LIB3DS_MAT_MAPNAME ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_MAPNAME; - c.size=6+(Lib3dsDword)strlen(map->name)+1; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_string(io, map->name); - } - - { /*---- LIB3DS_MAT_MAP_TILING ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_MAP_TILING; - c.size=8; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_word(io, (Lib3dsWord)map->flags); - } - - { /*---- LIB3DS_MAT_MAP_TEXBLUR ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_MAP_TEXBLUR; - c.size=10; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_float(io, map->blur); - } - - { /*---- LIB3DS_MAT_MAP_USCALE ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_MAP_USCALE; - c.size=10; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_float(io, map->scale[0]); - } - - { /*---- LIB3DS_MAT_MAP_VSCALE ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_MAP_VSCALE; - c.size=10; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_float(io, map->scale[1]); - } - - { /*---- LIB3DS_MAT_MAP_UOFFSET ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_MAP_UOFFSET; - c.size=10; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_float(io, map->offset[0]); - } - - { /*---- LIB3DS_MAT_MAP_VOFFSET ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_MAP_VOFFSET; - c.size=10; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_float(io, map->offset[1]); - } - - { /*---- LIB3DS_MAT_MAP_ANG ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_MAP_ANG; - c.size=10; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_float(io, map->rotation); - } - - { /*---- LIB3DS_MAT_MAP_COL1 ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_MAP_COL1; - c.size=9; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_1[0]+0.5)); - lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_1[1]+0.5)); - lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_1[2]+0.5)); - } - - { /*---- LIB3DS_MAT_MAP_COL2 ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_MAP_COL2; - c.size=9; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_2[0]+0.5)); - lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_2[1]+0.5)); - lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_2[2]+0.5)); - } - - { /*---- LIB3DS_MAT_MAP_RCOL ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_MAP_RCOL; - c.size=9; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_r[0]+0.5)); - lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_r[1]+0.5)); - lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_r[2]+0.5)); - } - - { /*---- LIB3DS_MAT_MAP_GCOL ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_MAP_GCOL; - c.size=9; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_g[0]+0.5)); - lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_g[1]+0.5)); - lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_g[2]+0.5)); - } - - { /*---- LIB3DS_MAT_MAP_BCOL ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_MAP_BCOL; - c.size=9; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_b[0]+0.5)); - lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_b[1]+0.5)); - lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_b[2]+0.5)); - } - - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup material - */ -Lib3dsBool -lib3ds_material_write(Lib3dsMaterial *material, Lib3dsIo *io) -{ - Lib3dsChunk c; - - c.chunk=LIB3DS_MAT_ENTRY; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - - { /*---- LIB3DS_MAT_NAME ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_NAME; - c.size=6+(Lib3dsDword)strlen(material->name)+1; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_string(io, material->name); - } - - { /*---- LIB3DS_MAT_AMBIENT ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_AMBIENT; - c.size=24; - lib3ds_chunk_write(&c,io); - color_write(material->ambient,io); - } - - { /*---- LIB3DS_MAT_DIFFUSE ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_DIFFUSE; - c.size=24; - lib3ds_chunk_write(&c,io); - color_write(material->diffuse,io); - } - - { /*---- LIB3DS_MAT_SPECULAR ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_SPECULAR; - c.size=24; - lib3ds_chunk_write(&c,io); - color_write(material->specular,io); - } - - { /*---- LIB3DS_MAT_SHININESS ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_SHININESS; - c.size=14; - lib3ds_chunk_write(&c,io); - int_percentage_write(material->shininess,io); - } - - { /*---- LIB3DS_MAT_SHIN2PCT ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_SHIN2PCT; - c.size=14; - lib3ds_chunk_write(&c,io); - int_percentage_write(material->shin_strength,io); - } - - { /*---- LIB3DS_MAT_TRANSPARENCY ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_TRANSPARENCY; - c.size=14; - lib3ds_chunk_write(&c,io); - int_percentage_write(material->transparency,io); - } - - { /*---- LIB3DS_MAT_XPFALL ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_XPFALL; - c.size=14; - lib3ds_chunk_write(&c,io); - int_percentage_write(material->falloff,io); - } - - if (material->use_falloff) { /*---- LIB3DS_MAT_USE_XPFALL ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_USE_XPFALL; - c.size=6; - lib3ds_chunk_write(&c,io); - } - - { /*---- LIB3DS_MAT_SHADING ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_SHADING; - c.size=8; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_intw(io, material->shading); - } - - { /*---- LIB3DS_MAT_REFBLUR ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_REFBLUR; - c.size=14; - lib3ds_chunk_write(&c,io); - int_percentage_write(material->blur,io); - } - - if (material->use_blur) { /*---- LIB3DS_MAT_USE_REFBLUR ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_USE_REFBLUR; - c.size=6; - lib3ds_chunk_write(&c,io); - } - - if (material->self_illum) { /*---- LIB3DS_MAT_SELF_ILLUM ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_SELF_ILLUM; - c.size=6; - lib3ds_chunk_write(&c,io); - } - - if (material->two_sided) { /*---- LIB3DS_MAT_TWO_SIDE ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_TWO_SIDE; - c.size=6; - lib3ds_chunk_write(&c,io); - } - - if (material->map_decal) { /*---- LIB3DS_MAT_DECAL ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_DECAL; - c.size=6; - lib3ds_chunk_write(&c,io); - } - - if (material->additive) { /*---- LIB3DS_MAT_ADDITIVE ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_ADDITIVE; - c.size=6; - lib3ds_chunk_write(&c,io); - } - - if (material->use_wire) { /*---- LIB3DS_MAT_WIRE ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_WIRE; - c.size=6; - lib3ds_chunk_write(&c,io); - } - - if (material->use_wire_abs) { /*---- LIB3DS_MAT_WIREABS ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_WIREABS; - c.size=6; - lib3ds_chunk_write(&c,io); - } - - { /*---- LIB3DS_MAT_WIRE_SIZE ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_WIRE_SIZE; - c.size=10; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_float(io, material->wire_size); - } - - if (material->face_map) { /*---- LIB3DS_MAT_FACEMAP ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_FACEMAP; - c.size=6; - lib3ds_chunk_write(&c,io); - } - - if (material->soften) { /*---- LIB3DS_MAT_PHONGSOFT ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MAT_PHONGSOFT; - c.size=6; - lib3ds_chunk_write(&c,io); - } - - if (!texture_map_write(LIB3DS_MAT_TEXMAP, &material->texture1_map, io)) { - return(LIB3DS_FALSE); - } - if (!texture_map_write(LIB3DS_MAT_TEXMASK, &material->texture1_mask, io)) { - return(LIB3DS_FALSE); - } - if (!texture_map_write(LIB3DS_MAT_TEX2MAP, &material->texture2_map, io)) { - return(LIB3DS_FALSE); - } - if (!texture_map_write(LIB3DS_MAT_TEX2MASK, &material->texture2_mask, io)) { - return(LIB3DS_FALSE); - } - if (!texture_map_write(LIB3DS_MAT_OPACMAP, &material->opacity_map, io)) { - return(LIB3DS_FALSE); - } - if (!texture_map_write(LIB3DS_MAT_OPACMASK, &material->opacity_mask, io)) { - return(LIB3DS_FALSE); - } - if (!texture_map_write(LIB3DS_MAT_BUMPMAP, &material->bump_map, io)) { - return(LIB3DS_FALSE); - } - if (!texture_map_write(LIB3DS_MAT_BUMPMASK, &material->bump_mask, io)) { - return(LIB3DS_FALSE); - } - if (!texture_map_write(LIB3DS_MAT_SPECMAP, &material->specular_map, io)) { - return(LIB3DS_FALSE); - } - if (!texture_map_write(LIB3DS_MAT_SPECMASK, &material->specular_mask, io)) { - return(LIB3DS_FALSE); - } - if (!texture_map_write(LIB3DS_MAT_SHINMAP, &material->shininess_map, io)) { - return(LIB3DS_FALSE); - } - if (!texture_map_write(LIB3DS_MAT_SHINMASK, &material->shininess_mask, io)) { - return(LIB3DS_FALSE); - } - if (!texture_map_write(LIB3DS_MAT_SELFIMAP, &material->self_illum_map, io)) { - return(LIB3DS_FALSE); - } - if (!texture_map_write(LIB3DS_MAT_SELFIMASK, &material->self_illum_mask, io)) { - return(LIB3DS_FALSE); - } - if (!texture_map_write(LIB3DS_MAT_REFLMAP, &material->reflection_map, io)) { - return(LIB3DS_FALSE); - } - if (!texture_map_write(LIB3DS_MAT_REFLMASK, &material->reflection_mask, io)) { - return(LIB3DS_FALSE); - } - - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - return(LIB3DS_TRUE); -} - - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/material.h b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/material.h deleted file mode 100644 index abc11506d..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/material.h +++ /dev/null @@ -1,170 +0,0 @@ -/* -*- c -*- */ -#ifndef INCLUDED_LIB3DS_MATERIAL_H -#define INCLUDED_LIB3DS_MATERIAL_H -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: material.h,v 1.18 2007/06/20 17:04:08 jeh Exp $ - */ - -#ifndef INCLUDED_LIB3DS_TYPES_H -#include "types.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \ingroup material - */ -typedef enum Lib3dsTextureMapFlags { - LIB3DS_DECALE =0x0001, - LIB3DS_MIRROR =0x0002, - LIB3DS_NEGATE =0x0008, - LIB3DS_NO_TILE =0x0010, - LIB3DS_SUMMED_AREA =0x0020, - LIB3DS_ALPHA_SOURCE =0x0040, - LIB3DS_TINT =0x0080, - LIB3DS_IGNORE_ALPHA =0x0100, - LIB3DS_RGB_TINT =0x0200 -} Lib3dsTextureMapFlags; - -/** - * Mateial texture map - * \ingroup material - */ -typedef struct Lib3dsTextureMap { - Lib3dsUserData user; - char name[64]; - Lib3dsDword flags; - Lib3dsFloat percent; - Lib3dsFloat blur; - Lib3dsFloat scale[2]; - Lib3dsFloat offset[2]; - Lib3dsFloat rotation; - Lib3dsRgb tint_1; - Lib3dsRgb tint_2; - Lib3dsRgb tint_r; - Lib3dsRgb tint_g; - Lib3dsRgb tint_b; -} Lib3dsTextureMap; - -/** - * \ingroup material - */ -typedef enum Lib3dsAutoReflMapFlags { - LIB3DS_USE_REFL_MAP =0x0001, - LIB3DS_READ_FIRST_FRAME_ONLY =0x0004, - LIB3DS_FLAT_MIRROR =0x0008 -} Lib3dsAutoReflectionMapFlags; - -/** - * \ingroup material - */ -typedef enum Lib3dsAutoReflMapAntiAliasLevel { - LIB3DS_ANTI_ALIAS_NONE =0, - LIB3DS_ANTI_ALIAS_LOW =1, - LIB3DS_ANTI_ALIAS_MEDIUM =2, - LIB3DS_ANTI_ALIAS_HIGH =3 -} Lib3dsAutoReflMapAntiAliasLevel; - -/** - * Auto reflection map settings - * \ingroup material - */ -typedef struct Lib3dsAutoReflMap { - Lib3dsDword flags; - Lib3dsIntd level; - Lib3dsIntd size; - Lib3dsIntd frame_step; -} Lib3dsAutoReflMap; - -/** - * \ingroup material - */ -typedef enum Lib3dsMaterialShading { - LIB3DS_WIRE_FRAME =0, - LIB3DS_FLAT =1, - LIB3DS_GOURAUD =2, - LIB3DS_PHONG =3, - LIB3DS_METAL =4 -} Lib3dsMaterialShading; - -/** - * Material - * \ingroup material - */ -struct Lib3dsMaterial { - Lib3dsUserData user; /*! Arbitrary user data */ - Lib3dsMaterial *next; - char name[64]; /*! Material name */ - Lib3dsRgba ambient; /*! Material ambient reflectivity */ - Lib3dsRgba diffuse; /*! Material diffuse reflectivity */ - Lib3dsRgba specular; /*! Material specular reflectivity */ - Lib3dsFloat shininess; /*! Material specular exponent */ - Lib3dsFloat shin_strength; - Lib3dsBool use_blur; - Lib3dsFloat blur; - Lib3dsFloat transparency; - Lib3dsFloat falloff; - Lib3dsBool additive; - Lib3dsFloat self_ilpct; - Lib3dsBool use_falloff; - Lib3dsBool self_illum; - Lib3dsIntw shading; - Lib3dsBool soften; - Lib3dsBool face_map; - Lib3dsBool two_sided; /*! Material visible from back */ - Lib3dsBool map_decal; - Lib3dsBool use_wire; - Lib3dsBool use_wire_abs; - Lib3dsFloat wire_size; - Lib3dsTextureMap texture1_map; - Lib3dsTextureMap texture1_mask; - Lib3dsTextureMap texture2_map; - Lib3dsTextureMap texture2_mask; - Lib3dsTextureMap opacity_map; - Lib3dsTextureMap opacity_mask; - Lib3dsTextureMap bump_map; - Lib3dsTextureMap bump_mask; - Lib3dsTextureMap specular_map; - Lib3dsTextureMap specular_mask; - Lib3dsTextureMap shininess_map; - Lib3dsTextureMap shininess_mask; - Lib3dsTextureMap self_illum_map; - Lib3dsTextureMap self_illum_mask; - Lib3dsTextureMap reflection_map; - Lib3dsTextureMap reflection_mask; - Lib3dsAutoReflMap autorefl_map; -}; - -extern LIB3DSAPI Lib3dsMaterial* lib3ds_material_new(); -extern LIB3DSAPI void lib3ds_material_free(Lib3dsMaterial *material); -extern LIB3DSAPI void lib3ds_material_dump(Lib3dsMaterial *material); -extern LIB3DSAPI Lib3dsBool lib3ds_material_read(Lib3dsMaterial *material, Lib3dsIo *io); -extern LIB3DSAPI Lib3dsBool lib3ds_material_write(Lib3dsMaterial *material, Lib3dsIo *io); - -#ifdef __cplusplus -} -#endif -#endif - - - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/matrix.c b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/matrix.c deleted file mode 100644 index 223b2205d..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/matrix.c +++ /dev/null @@ -1,718 +0,0 @@ -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: matrix.c,v 1.14 2007/06/20 17:04:08 jeh Exp $ - */ -#include "matrix.h" -#include "quat.h" -#include "vector.h" -#include -#include - - -/*! - * \defgroup matrix Matrix Mathematics - */ - - -/*! -* \typedef Lib3dsMatrix -* \ingroup matrix -*/ - - -/*! - * Clear a matrix to all zeros. - * - * \param m Matrix to be cleared. - * - * \ingroup matrix - */ -void -lib3ds_matrix_zero(Lib3dsMatrix m) -{ - int i,j; - - for (i=0; i<4; i++) { - for (j=0; j<4; j++) m[i][j]=0.0f; - } -} - - -/*! - * Set a matrix to identity. - * - * \param m Matrix to be set. - * - * \ingroup matrix - */ -void -lib3ds_matrix_identity(Lib3dsMatrix m) -{ - int i,j; - - for (i=0; i<4; i++) { - for (j=0; j<4; j++) m[i][j]=0.0; - } - for (i=0; i<4; i++) m[i][i]=1.0; -} - - -/*! - * Copy a matrix. - * - * \ingroup matrix - */ -void -lib3ds_matrix_copy(Lib3dsMatrix dest, Lib3dsMatrix src) -{ - memcpy(dest, src, sizeof(Lib3dsMatrix)); -} - - -/*! - * Negate a matrix -- all elements negated. - * - * \ingroup matrix - */ -void -lib3ds_matrix_neg(Lib3dsMatrix m) -{ - int i,j; - - for (j=0; j<4; j++) { - for (i=0; i<4; i++) { - m[j][i]=-m[j][i]; - } - } -} - - -/*! - * Set all matrix elements to their absolute value. - * - * \ingroup matrix - */ -void -lib3ds_matrix_abs(Lib3dsMatrix m) -{ - int i,j; - - for (j=0; j<4; j++) { - for (i=0; i<4; i++) { - m[j][i]=(Lib3dsFloat)fabs(m[j][i]); - } - } -} - - -/*! - * Transpose a matrix in place. - * - * \ingroup matrix - */ -void -lib3ds_matrix_transpose(Lib3dsMatrix m) -{ - int i,j; - Lib3dsFloat swp; - - for (j=0; j<4; j++) { - for (i=j+1; i<4; i++) { - swp=m[j][i]; - m[j][i]=m[i][j]; - m[i][j]=swp; - } - } -} - - -/*! - * Add two matrices. - * - * \ingroup matrix - */ -void -_lib3ds_matrix_add(Lib3dsMatrix m, Lib3dsMatrix a, Lib3dsMatrix b) -{ - int i,j; - - for (j=0; j<4; j++) { - for (i=0; i<4; i++) { - m[j][i]=a[j][i]+b[j][i]; - } - } -} - - -/*! - * Subtract two matrices. - * - * \param m Result. - * \param a Addend. - * \param b Minuend. - * - * \ingroup matrix - */ -void -_lib3ds_matrix_sub(Lib3dsMatrix m, Lib3dsMatrix a, Lib3dsMatrix b) -{ - int i,j; - - for (j=0; j<4; j++) { - for (i=0; i<4; i++) { - m[j][i]=a[j][i]-b[j][i]; - } - } -} - - -/*! - * Multiplies a matrix by a second one (m = m * n). - * - * \ingroup matrix - */ -void -lib3ds_matrix_mult(Lib3dsMatrix m, Lib3dsMatrix n) -{ - Lib3dsMatrix tmp; - int i,j,k; - Lib3dsFloat ab; - - memcpy(tmp, m, sizeof(Lib3dsMatrix)); - for (j=0; j<4; j++) { - for (i=0; i<4; i++) { - ab=0.0f; - for (k=0; k<4; k++) ab+=tmp[k][i]*n[j][k]; - m[j][i]=ab; - } - } -} - - -/*! - * Multiply a matrix by a scalar. - * - * \param m Matrix to be set. - * \param k Scalar. - * - * \ingroup matrix - */ -void -lib3ds_matrix_scalar(Lib3dsMatrix m, Lib3dsFloat k) -{ - int i,j; - - for (j=0; j<4; j++) { - for (i=0; i<4; i++) { - m[j][i]*=k; - } - } -} - - -static Lib3dsFloat -det2x2( - Lib3dsFloat a, Lib3dsFloat b, - Lib3dsFloat c, Lib3dsFloat d) -{ - return((a)*(d)-(b)*(c)); -} - - -static Lib3dsFloat -det3x3( - Lib3dsFloat a1, Lib3dsFloat a2, Lib3dsFloat a3, - Lib3dsFloat b1, Lib3dsFloat b2, Lib3dsFloat b3, - Lib3dsFloat c1, Lib3dsFloat c2, Lib3dsFloat c3) -{ - return( - a1*det2x2(b2,b3,c2,c3)- - b1*det2x2(a2,a3,c2,c3)+ - c1*det2x2(a2,a3,b2,b3) - ); -} - - -/*! - * Find determinant of a matrix. - * - * \ingroup matrix - */ -Lib3dsFloat -lib3ds_matrix_det(Lib3dsMatrix m) -{ - Lib3dsFloat a1,a2,a3,a4,b1,b2,b3,b4,c1,c2,c3,c4,d1,d2,d3,d4; - - a1 = m[0][0]; - b1 = m[1][0]; - c1 = m[2][0]; - d1 = m[3][0]; - a2 = m[0][1]; - b2 = m[1][1]; - c2 = m[2][1]; - d2 = m[3][1]; - a3 = m[0][2]; - b3 = m[1][2]; - c3 = m[2][2]; - d3 = m[3][2]; - a4 = m[0][3]; - b4 = m[1][3]; - c4 = m[2][3]; - d4 = m[3][3]; - return( - a1 * det3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4)- - b1 * det3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4)+ - c1 * det3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4)- - d1 * det3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4) - ); -} - - -/*! - * Find the adjoint of a matrix. - * - * \ingroup matrix - */ -void -lib3ds_matrix_adjoint(Lib3dsMatrix m) -{ - Lib3dsFloat a1,a2,a3,a4,b1,b2,b3,b4,c1,c2,c3,c4,d1,d2,d3,d4; - - a1 = m[0][0]; - b1 = m[1][0]; - c1 = m[2][0]; - d1 = m[3][0]; - a2 = m[0][1]; - b2 = m[1][1]; - c2 = m[2][1]; - d2 = m[3][1]; - a3 = m[0][2]; - b3 = m[1][2]; - c3 = m[2][2]; - d3 = m[3][2]; - a4 = m[0][3]; - b4 = m[1][3]; - c4 = m[2][3]; - d4 = m[3][3]; - m[0][0]= det3x3 (b2, b3, b4, c2, c3, c4, d2, d3, d4); - m[0][1]= -det3x3 (a2, a3, a4, c2, c3, c4, d2, d3, d4); - m[0][2]= det3x3 (a2, a3, a4, b2, b3, b4, d2, d3, d4); - m[0][3]= -det3x3 (a2, a3, a4, b2, b3, b4, c2, c3, c4); - m[1][0]= -det3x3 (b1, b3, b4, c1, c3, c4, d1, d3, d4); - m[1][1]= det3x3 (a1, a3, a4, c1, c3, c4, d1, d3, d4); - m[1][2]= -det3x3 (a1, a3, a4, b1, b3, b4, d1, d3, d4); - m[1][3]= det3x3 (a1, a3, a4, b1, b3, b4, c1, c3, c4); - m[2][0]= det3x3 (b1, b2, b4, c1, c2, c4, d1, d2, d4); - m[2][1]= -det3x3 (a1, a2, a4, c1, c2, c4, d1, d2, d4); - m[2][2]= det3x3 (a1, a2, a4, b1, b2, b4, d1, d2, d4); - m[2][3]= -det3x3 (a1, a2, a4, b1, b2, b4, c1, c2, c4); - m[3][0]= -det3x3 (b1, b2, b3, c1, c2, c3, d1, d2, d3); - m[3][1]= det3x3 (a1, a2, a3, c1, c2, c3, d1, d2, d3); - m[3][2]= -det3x3 (a1, a2, a3, b1, b2, b3, d1, d2, d3); - m[3][3]= det3x3 (a1, a2, a3, b1, b2, b3, c1, c2, c3); -} - - -/*! - * Invert a matrix in place. - * - * \param m Matrix to invert. - * - * \return LIB3DS_TRUE on success, LIB3DS_FALSE on failure. - * \ingroup matrix - * - * GGemsII, K.Wu, Fast Matrix Inversion - */ -Lib3dsBool -lib3ds_matrix_inv(Lib3dsMatrix m) -{ - int i,j,k; - int pvt_i[4], pvt_j[4]; /* Locations of pivot elements */ - Lib3dsFloat pvt_val; /* Value of current pivot element */ - Lib3dsFloat hold; /* Temporary storage */ - Lib3dsFloat determinat; - - determinat = 1.0f; - for (k=0; k<4; k++) { - /* Locate k'th pivot element */ - pvt_val=m[k][k]; /* Initialize for search */ - pvt_i[k]=k; - pvt_j[k]=k; - for (i=k; i<4; i++) { - for (j=k; j<4; j++) { - if (fabs(m[i][j]) > fabs(pvt_val)) { - pvt_i[k]=i; - pvt_j[k]=j; - pvt_val=m[i][j]; - } - } - } - - /* Product of pivots, gives determinant when finished */ - determinat*=pvt_val; - if (fabs(determinat)=0; k--) { /* Don't need to work with 1 by 1 corner*/ - i=pvt_j[k]; /* Rows to swap correspond to pivot COLUMN */ - if (i!=k) { /* If rows are different */ - for(j=0; j<4; j++) { - hold = m[k][j]; - m[k][j]=-m[i][j]; - m[i][j]=hold; - } - } - - j=pvt_i[k]; /* Columns to swap correspond to pivot ROW */ - if (j!=k) /* If columns are different */ - for (i=0; i<4; i++) { - hold=m[i][k]; - m[i][k]=-m[i][j]; - m[i][j]=hold; - } - } - return(LIB3DS_TRUE); -} - - -/*! - * Apply a translation to a matrix. - * - * \ingroup matrix - */ -void -lib3ds_matrix_translate_xyz(Lib3dsMatrix m, Lib3dsFloat x, Lib3dsFloat y, Lib3dsFloat z) -{ - int i; - - for (i=0; i<3; i++) { - m[3][i]+= m[0][i]*x + m[1][i]*y + m[2][i]*z; - } -} - - -/*! - * Apply a translation to a matrix. - * - * \ingroup matrix - */ -void -lib3ds_matrix_translate(Lib3dsMatrix m, Lib3dsVector t) -{ - int i; - - for (i=0; i<3; i++) { - m[3][i]+= m[0][i]*t[0] + m[1][i]*t[1] + m[2][i]*t[2]; - } -} - - -/*! - * Apply scale factors to a matrix. - * - * \ingroup matrix - */ -void -lib3ds_matrix_scale_xyz(Lib3dsMatrix m, Lib3dsFloat x, Lib3dsFloat y, Lib3dsFloat z) -{ - int i; - - for (i=0; i<4; i++) { - m[0][i]*=x; - m[1][i]*=y; - m[2][i]*=z; - } -} - - -/*! - * Apply scale factors to a matrix. - * - * \ingroup matrix - */ -void -lib3ds_matrix_scale(Lib3dsMatrix m, Lib3dsVector s) -{ - int i; - - for (i=0; i<4; i++) { - m[0][i]*=s[0]; - m[1][i]*=s[1]; - m[2][i]*=s[2]; - } -} - - -/*! - * Apply a rotation about the x axis to a matrix. - * - * \ingroup matrix - */ -void -lib3ds_matrix_rotate_x(Lib3dsMatrix m, Lib3dsFloat phi) -{ - Lib3dsFloat SinPhi,CosPhi; - Lib3dsFloat a1[4],a2[4]; - - SinPhi=(Lib3dsFloat)sin(phi); - CosPhi=(Lib3dsFloat)cos(phi); - memcpy(a1,m[1],4*sizeof(Lib3dsFloat)); - memcpy(a2,m[2],4*sizeof(Lib3dsFloat)); - m[1][0]=CosPhi*a1[0]+SinPhi*a2[0]; - m[1][1]=CosPhi*a1[1]+SinPhi*a2[1]; - m[1][2]=CosPhi*a1[2]+SinPhi*a2[2]; - m[1][3]=CosPhi*a1[3]+SinPhi*a2[3]; - m[2][0]=-SinPhi*a1[0]+CosPhi*a2[0]; - m[2][1]=-SinPhi*a1[1]+CosPhi*a2[1]; - m[2][2]=-SinPhi*a1[2]+CosPhi*a2[2]; - m[2][3]=-SinPhi*a1[3]+CosPhi*a2[3]; -} - - -/*! - * Apply a rotation about the y axis to a matrix. - * - * \ingroup matrix - */ -void -lib3ds_matrix_rotate_y(Lib3dsMatrix m, Lib3dsFloat phi) -{ - Lib3dsFloat SinPhi,CosPhi; - Lib3dsFloat a0[4],a2[4]; - - SinPhi=(Lib3dsFloat)sin(phi); - CosPhi=(Lib3dsFloat)cos(phi); - memcpy(a0,m[0],4*sizeof(Lib3dsFloat)); - memcpy(a2,m[2],4*sizeof(Lib3dsFloat)); - m[0][0]=CosPhi*a0[0]-SinPhi*a2[0]; - m[0][1]=CosPhi*a0[1]-SinPhi*a2[1]; - m[0][2]=CosPhi*a0[2]-SinPhi*a2[2]; - m[0][3]=CosPhi*a0[3]-SinPhi*a2[3]; - m[2][0]=SinPhi*a0[0]+CosPhi*a2[0]; - m[2][1]=SinPhi*a0[1]+CosPhi*a2[1]; - m[2][2]=SinPhi*a0[2]+CosPhi*a2[2]; - m[2][3]=SinPhi*a0[3]+CosPhi*a2[3]; -} - - -/*! - * Apply a rotation about the z axis to a matrix. - * - * \ingroup matrix - */ -void -lib3ds_matrix_rotate_z(Lib3dsMatrix m, Lib3dsFloat phi) -{ - Lib3dsFloat SinPhi,CosPhi; - Lib3dsFloat a0[4],a1[4]; - - SinPhi=(Lib3dsFloat)sin(phi); - CosPhi=(Lib3dsFloat)cos(phi); - memcpy(a0,m[0],4*sizeof(Lib3dsFloat)); - memcpy(a1,m[1],4*sizeof(Lib3dsFloat)); - m[0][0]=CosPhi*a0[0]+SinPhi*a1[0]; - m[0][1]=CosPhi*a0[1]+SinPhi*a1[1]; - m[0][2]=CosPhi*a0[2]+SinPhi*a1[2]; - m[0][3]=CosPhi*a0[3]+SinPhi*a1[3]; - m[1][0]=-SinPhi*a0[0]+CosPhi*a1[0]; - m[1][1]=-SinPhi*a0[1]+CosPhi*a1[1]; - m[1][2]=-SinPhi*a0[2]+CosPhi*a1[2]; - m[1][3]=-SinPhi*a0[3]+CosPhi*a1[3]; -} - - -/*! - * Apply a rotation about an arbitrary axis to a matrix. - * - * \ingroup matrix - */ -void -lib3ds_matrix_rotate(Lib3dsMatrix m, Lib3dsQuat q) -{ - Lib3dsFloat s,xs,ys,zs,wx,wy,wz,xx,xy,xz,yy,yz,zz,l; - Lib3dsMatrix R; - - l=q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]; - if (fabs(l) - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: matrix.h,v 1.8 2007/06/18 06:11:32 jeh Exp $ - */ - -#ifndef INCLUDED_LIB3DS_TYPES_H -#include "types.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -extern LIB3DSAPI void lib3ds_matrix_zero(Lib3dsMatrix m); -extern LIB3DSAPI void lib3ds_matrix_identity(Lib3dsMatrix m); -extern LIB3DSAPI void lib3ds_matrix_copy(Lib3dsMatrix dest, Lib3dsMatrix src); -extern LIB3DSAPI void lib3ds_matrix_neg(Lib3dsMatrix m); -extern LIB3DSAPI void lib3ds_matrix_abs(Lib3dsMatrix m); -extern LIB3DSAPI void lib3ds_matrix_transpose(Lib3dsMatrix m); -extern LIB3DSAPI void _lib3ds_matrix_add(Lib3dsMatrix m, Lib3dsMatrix a, Lib3dsMatrix b); -extern LIB3DSAPI void _lib3ds_matrix_sub(Lib3dsMatrix m, Lib3dsMatrix a, Lib3dsMatrix b); -extern LIB3DSAPI void lib3ds_matrix_mult(Lib3dsMatrix m, Lib3dsMatrix n); -extern LIB3DSAPI void lib3ds_matrix_scalar(Lib3dsMatrix m, Lib3dsFloat k); -extern LIB3DSAPI Lib3dsFloat lib3ds_matrix_det(Lib3dsMatrix m); -extern LIB3DSAPI void lib3ds_matrix_adjoint(Lib3dsMatrix m); -extern LIB3DSAPI Lib3dsBool lib3ds_matrix_inv(Lib3dsMatrix m); -extern LIB3DSAPI void lib3ds_matrix_translate_xyz(Lib3dsMatrix m, Lib3dsFloat x, Lib3dsFloat y, Lib3dsFloat z); -extern LIB3DSAPI void lib3ds_matrix_translate(Lib3dsMatrix m, Lib3dsVector t); -extern LIB3DSAPI void lib3ds_matrix_scale_xyz(Lib3dsMatrix m, Lib3dsFloat x, Lib3dsFloat y, Lib3dsFloat z); -extern LIB3DSAPI void lib3ds_matrix_scale(Lib3dsMatrix m, Lib3dsVector s); -extern LIB3DSAPI void lib3ds_matrix_rotate_x(Lib3dsMatrix m, Lib3dsFloat phi); -extern LIB3DSAPI void lib3ds_matrix_rotate_y(Lib3dsMatrix m, Lib3dsFloat phi); -extern LIB3DSAPI void lib3ds_matrix_rotate_z(Lib3dsMatrix m, Lib3dsFloat phi); -extern LIB3DSAPI void lib3ds_matrix_rotate(Lib3dsMatrix m, Lib3dsQuat q); -extern LIB3DSAPI void lib3ds_matrix_rotate_axis(Lib3dsMatrix m, Lib3dsVector axis, Lib3dsFloat angle); -extern LIB3DSAPI void lib3ds_matrix_camera(Lib3dsMatrix matrix, Lib3dsVector pos, Lib3dsVector tgt, Lib3dsFloat roll); -extern LIB3DSAPI void lib3ds_matrix_dump(Lib3dsMatrix matrix); - -#ifdef __cplusplus -} -#endif -#endif - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/mesh.c b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/mesh.c deleted file mode 100644 index 55b1f0594..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/mesh.c +++ /dev/null @@ -1,1056 +0,0 @@ -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: mesh.c,v 1.29 2007/06/20 17:04:08 jeh Exp $ - */ -#include "mesh.h" -#include "io.h" -#include "chunk.h" -#include "vector.h" -#include "matrix.h" -#include -#include -#include -#include - - -/*! - * \defgroup mesh Meshes - */ - - -static Lib3dsBool -face_array_read(Lib3dsMesh *mesh, Lib3dsIo *io) -{ - Lib3dsChunk c; - Lib3dsWord chunk; - int i; - int faces; - - if (!lib3ds_chunk_read_start(&c, LIB3DS_FACE_ARRAY, io)) { - return(LIB3DS_FALSE); - } - lib3ds_mesh_free_face_list(mesh); - - faces=lib3ds_io_read_word(io); - if (faces) { - if (!lib3ds_mesh_new_face_list(mesh, faces)) { - LIB3DS_ERROR_LOG; - return(LIB3DS_FALSE); - } - for (i=0; ifaceL[i].material, ""); - mesh->faceL[i].points[0]=lib3ds_io_read_word(io); - mesh->faceL[i].points[1]=lib3ds_io_read_word(io); - mesh->faceL[i].points[2]=lib3ds_io_read_word(io); - mesh->faceL[i].flags=lib3ds_io_read_word(io); - } - lib3ds_chunk_read_tell(&c, io); - - while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) { - switch (chunk) { - case LIB3DS_SMOOTH_GROUP: - { - unsigned i; - - for (i=0; ifaces; ++i) { - mesh->faceL[i].smoothing=lib3ds_io_read_dword(io); - } - } - break; - case LIB3DS_MSH_MAT_GROUP: - { - char name[64]; - unsigned faces; - unsigned i; - unsigned index; - - if (!lib3ds_io_read_string(io, name, 64)) { - return(LIB3DS_FALSE); - } - faces=lib3ds_io_read_word(io); - for (i=0; ifaces); - strcpy(mesh->faceL[index].material, name); - } - } - break; - case LIB3DS_MSH_BOXMAP: - { - char name[64]; - - if (!lib3ds_io_read_string(io, name, 64)) { - return(LIB3DS_FALSE); - } - strcpy(mesh->box_map.front, name); - if (!lib3ds_io_read_string(io, name, 64)) { - return(LIB3DS_FALSE); - } - strcpy(mesh->box_map.back, name); - if (!lib3ds_io_read_string(io, name, 64)) { - return(LIB3DS_FALSE); - } - strcpy(mesh->box_map.left, name); - if (!lib3ds_io_read_string(io, name, 64)) { - return(LIB3DS_FALSE); - } - strcpy(mesh->box_map.right, name); - if (!lib3ds_io_read_string(io, name, 64)) { - return(LIB3DS_FALSE); - } - strcpy(mesh->box_map.top, name); - if (!lib3ds_io_read_string(io, name, 64)) { - return(LIB3DS_FALSE); - } - strcpy(mesh->box_map.bottom, name); - } - break; - default: - lib3ds_chunk_unknown(chunk); - } - } - - } - lib3ds_chunk_read_end(&c, io); - return(LIB3DS_TRUE); -} - - -/*! - * Create and return a new empty mesh object. - * - * Mesh is initialized with the name and an identity matrix; all - * other fields are zero. - * - * See Lib3dsFaceFlag for definitions of per-face flags. - * - * \param name Mesh name. Must not be NULL. Must be < 64 characters. - * - * \return mesh object or NULL on error. - * - * \ingroup mesh - */ -Lib3dsMesh* -lib3ds_mesh_new(const char *name) -{ - Lib3dsMesh *mesh; - - ASSERT(name); - ASSERT(strlen(name)<64); - - mesh=(Lib3dsMesh*)calloc(sizeof(Lib3dsMesh), 1); - if (!mesh) { - return(0); - } - strcpy(mesh->name, name); - lib3ds_matrix_identity(mesh->matrix); - mesh->map_data.maptype=LIB3DS_MAP_NONE; - return(mesh); -} - - -/*! - * Free a mesh object and all of its resources. - * - * \param mesh Mesh object to be freed. - * - * \ingroup mesh - */ -void -lib3ds_mesh_free(Lib3dsMesh *mesh) -{ - lib3ds_mesh_free_point_list(mesh); - lib3ds_mesh_free_flag_list(mesh); - lib3ds_mesh_free_texel_list(mesh); - lib3ds_mesh_free_face_list(mesh); - memset(mesh, 0, sizeof(Lib3dsMesh)); - free(mesh); -} - - -/*! - * Allocate point list in mesh object. - * - * This function frees the current point list, if any, and allocates - * a new one large enough to hold the specified number of points. - * - * \param mesh Mesh object for which points are to be allocated. - * \param points Number of points in the new point list. - * - * \return LIB3DS_TRUE on success, LIB3DS_FALSE on failure. - * - * \ingroup mesh - */ -Lib3dsBool -lib3ds_mesh_new_point_list(Lib3dsMesh *mesh, Lib3dsDword points) -{ - ASSERT(mesh); - if (mesh->pointL) { - ASSERT(mesh->points); - lib3ds_mesh_free_point_list(mesh); - } - ASSERT(!mesh->pointL && !mesh->points); - mesh->points=0; - mesh->pointL=calloc(sizeof(Lib3dsPoint)*points,1); - if (!mesh->pointL) { - LIB3DS_ERROR_LOG; - return(LIB3DS_FALSE); - } - mesh->points=points; - return(LIB3DS_TRUE); -} - - -/*! - * Free point list in mesh object. - * - * The current point list is freed and set to NULL. mesh->points is - * set to zero. - * - * \param mesh Mesh object to be modified. - * - * \ingroup mesh - */ -void -lib3ds_mesh_free_point_list(Lib3dsMesh *mesh) -{ - ASSERT(mesh); - if (mesh->pointL) { - ASSERT(mesh->points); - free(mesh->pointL); - mesh->pointL=0; - mesh->points=0; - } - else { - ASSERT(!mesh->points); - } -} - - -/*! - * Allocate flag list in mesh object. - * - * This function frees the current flag list, if any, and allocates - * a new one large enough to hold the specified number of flags. - * All flags are initialized to 0 - * - * \param mesh Mesh object for which points are to be allocated. - * \param flags Number of flags in the new flag list. - * - * \return LIB3DS_TRUE on success, LIB3DS_FALSE on failure. - * - * \ingroup mesh - */ -Lib3dsBool -lib3ds_mesh_new_flag_list(Lib3dsMesh *mesh, Lib3dsDword flags) -{ - ASSERT(mesh); - if (mesh->flagL) { - ASSERT(mesh->flags); - lib3ds_mesh_free_flag_list(mesh); - } - ASSERT(!mesh->flagL && !mesh->flags); - mesh->flags=0; - mesh->flagL=calloc(sizeof(Lib3dsWord)*flags,1); - if (!mesh->flagL) { - LIB3DS_ERROR_LOG; - return(LIB3DS_FALSE); - } - mesh->flags=flags; - return(LIB3DS_TRUE); -} - - -/*! - * Free flag list in mesh object. - * - * The current flag list is freed and set to NULL. mesh->flags is - * set to zero. - * - * \param mesh Mesh object to be modified. - * - * \ingroup mesh - */ -void -lib3ds_mesh_free_flag_list(Lib3dsMesh *mesh) -{ - ASSERT(mesh); - if (mesh->flagL) { - ASSERT(mesh->flags); - free(mesh->flagL); - mesh->flagL=0; - mesh->flags=0; - } - else { - ASSERT(!mesh->flags); - } -} - - -/*! - * Allocate texel list in mesh object. - * - * This function frees the current texel list, if any, and allocates - * a new one large enough to hold the specified number of texels. - * - * \param mesh Mesh object for which points are to be allocated. - * \param texels Number of texels in the new texel list. - * - * \return LIB3DS_TRUE on success, LIB3DS_FALSE on failure. - * - * \ingroup mesh - */ -Lib3dsBool -lib3ds_mesh_new_texel_list(Lib3dsMesh *mesh, Lib3dsDword texels) -{ - ASSERT(mesh); - if (mesh->texelL) { - ASSERT(mesh->texels); - lib3ds_mesh_free_texel_list(mesh); - } - ASSERT(!mesh->texelL && !mesh->texels); - mesh->texels=0; - mesh->texelL=calloc(sizeof(Lib3dsTexel)*texels,1); - if (!mesh->texelL) { - LIB3DS_ERROR_LOG; - return(LIB3DS_FALSE); - } - mesh->texels=texels; - return(LIB3DS_TRUE); -} - - -/*! - * Free texel list in mesh object. - * - * The current texel list is freed and set to NULL. mesh->texels is - * set to zero. - * - * \param mesh Mesh object to be modified. - * - * \ingroup mesh - */ -void -lib3ds_mesh_free_texel_list(Lib3dsMesh *mesh) -{ - ASSERT(mesh); - if (mesh->texelL) { - ASSERT(mesh->texels); - free(mesh->texelL); - mesh->texelL=0; - mesh->texels=0; - } - else { - ASSERT(!mesh->texels); - } -} - - -/*! - * Allocate face list in mesh object. - * - * This function frees the current face list, if any, and allocates - * a new one large enough to hold the specified number of faces. - * - * \param mesh Mesh object for which points are to be allocated. - * \param faces Number of faces in the new face list. - * - * \return LIB3DS_TRUE on success, LIB3DS_FALSE on failure. - * - * \ingroup mesh - */ -Lib3dsBool -lib3ds_mesh_new_face_list(Lib3dsMesh *mesh, Lib3dsDword faces) -{ - ASSERT(mesh); - if (mesh->faceL) { - ASSERT(mesh->faces); - lib3ds_mesh_free_face_list(mesh); - } - ASSERT(!mesh->faceL && !mesh->faces); - mesh->faces=0; - mesh->faceL=calloc(sizeof(Lib3dsFace)*faces,1); - if (!mesh->faceL) { - LIB3DS_ERROR_LOG; - return(LIB3DS_FALSE); - } - mesh->faces=faces; - return(LIB3DS_TRUE); -} - - -/*! - * Free face list in mesh object. - * - * The current face list is freed and set to NULL. mesh->faces is - * set to zero. - * - * \param mesh Mesh object to be modified. - * - * \ingroup mesh - */ -void -lib3ds_mesh_free_face_list(Lib3dsMesh *mesh) -{ - ASSERT(mesh); - if (mesh->faceL) { - ASSERT(mesh->faces); - free(mesh->faceL); - mesh->faceL=0; - mesh->faces=0; - } - else { - ASSERT(!mesh->faces); - } -} - - -/*! - * Find the bounding box of a mesh object. - * - * \param mesh The mesh object - * \param bmin Returned bounding box - * \param bmax Returned bounding box - * - * \ingroup mesh - */ -void -lib3ds_mesh_bounding_box(Lib3dsMesh *mesh, Lib3dsVector bmin, Lib3dsVector bmax) -{ - unsigned i; - bmin[0] = bmin[1] = bmin[2] = FLT_MAX; - bmax[0] = bmax[1] = bmax[2] = FLT_MIN; - - for (i=0; ipoints; ++i) { - lib3ds_vector_min(bmin, mesh->pointL[i].pos); - lib3ds_vector_max(bmax, mesh->pointL[i].pos); - } -} - - -typedef struct _Lib3dsFaces Lib3dsFaces; - -struct _Lib3dsFaces { - Lib3dsFaces *next; - Lib3dsFace *face; -}; - - -/*! - * Calculates the vertex normals corresponding to the smoothing group - * settings for each face of a mesh. - * - * \param mesh A pointer to the mesh to calculate the normals for. - * \param normalL A pointer to a buffer to store the calculated - * normals. The buffer must have the size: - * 3*sizeof(Lib3dsVector)*mesh->faces. - * - * To allocate the normal buffer do for example the following: - * \code - * Lib3dsVector *normalL = malloc(3*sizeof(Lib3dsVector)*mesh->faces); - * \endcode - * - * To access the normal of the i-th vertex of the j-th face do the - * following: - * \code - * normalL[3*j+i] - * \endcode - * - * \ingroup mesh - */ -void -lib3ds_mesh_calculate_normals(Lib3dsMesh *mesh, Lib3dsVector *normalL) -{ - Lib3dsFaces **fl; - Lib3dsFaces *fa; - unsigned i,j,k; - - if (!mesh->faces) { - return; - } - - fl=calloc(sizeof(Lib3dsFaces*),mesh->points); - ASSERT(fl); - fa=calloc(sizeof(Lib3dsFaces),3*mesh->faces); - ASSERT(fa); - k=0; - for (i=0; ifaces; ++i) { - Lib3dsFace *f=&mesh->faceL[i]; - for (j=0; j<3; ++j) { - Lib3dsFaces* l=&fa[k++]; - ASSERT(f->points[j]points); - l->face=f; - l->next=fl[f->points[j]]; - fl[f->points[j]]=l; - } - } - - for (i=0; ifaces; ++i) { - Lib3dsFace *f=&mesh->faceL[i]; - for (j=0; j<3; ++j) { - // FIXME: static array needs at least check!! - Lib3dsVector n,N[128]; - Lib3dsFaces *p; - int k,l; - int found; - - ASSERT(f->points[j]points); - - if (f->smoothing) { - lib3ds_vector_zero(n); - k=0; - for (p=fl[f->points[j]]; p; p=p->next) { - found=0; - for (l=0; l= 128 ) - printf("array N overflow: i=%d, j=%d, k=%d\n", i,j,k); - if (fabs(lib3ds_vector_dot(N[l], p->face->normal)-1.0)<1e-5) { - found=1; - break; - } - } - if (!found) { - if (f->smoothing & p->face->smoothing) { - lib3ds_vector_add(n,n, p->face->normal); - lib3ds_vector_copy(N[k], p->face->normal); - ++k; - } - } - } - } - else { - lib3ds_vector_copy(n, f->normal); - } - lib3ds_vector_normalize(n); - - lib3ds_vector_copy(normalL[3*i+j], n); - } - } - - free(fa); - free(fl); -} - - -/*! - * This function prints data associated with the specified mesh such as - * vertex and point lists. - * - * \param mesh Points to a mesh that you wish to view the data for. - * - * \return None - * - * \warning WIN32: Should only be used in a console window not in a GUI. - * - * \ingroup mesh - */ -void -lib3ds_mesh_dump(Lib3dsMesh *mesh) -{ - unsigned i; - Lib3dsVector p; - - ASSERT(mesh); - printf(" %s vertices=%ld faces=%ld\n", - mesh->name, - mesh->points, - mesh->faces - ); - printf(" matrix:\n"); - lib3ds_matrix_dump(mesh->matrix); - printf(" point list:\n"); - for (i=0; ipoints; ++i) { - lib3ds_vector_copy(p, mesh->pointL[i].pos); - printf (" %8f %8f %8f\n", p[0], p[1], p[2]); - } - printf(" facelist:\n"); - for (i=0; ifaces; ++i) { - printf (" %4d %4d %4d smoothing:%X flags:%X material:\"%s\"\n", - mesh->faceL[i].points[0], - mesh->faceL[i].points[1], - mesh->faceL[i].points[2], - (unsigned)mesh->faceL[i].smoothing, - mesh->faceL[i].flags, - mesh->faceL[i].material - ); - } -} - - -/*! - * \ingroup mesh - */ -Lib3dsBool -lib3ds_mesh_read(Lib3dsMesh *mesh, Lib3dsIo *io) -{ - Lib3dsChunk c; - Lib3dsWord chunk; - - if (!lib3ds_chunk_read_start(&c, LIB3DS_N_TRI_OBJECT, io)) { - return(LIB3DS_FALSE); - } - - while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) { - switch (chunk) { - case LIB3DS_MESH_MATRIX: - { - int i,j; - - lib3ds_matrix_identity(mesh->matrix); - for (i=0; i<4; i++) { - for (j=0; j<3; j++) { - mesh->matrix[i][j]=lib3ds_io_read_float(io); - } - } - } - break; - case LIB3DS_MESH_COLOR: - { - mesh->color=lib3ds_io_read_byte(io); - } - break; - case LIB3DS_POINT_ARRAY: - { - unsigned i,j; - unsigned points; - - lib3ds_mesh_free_point_list(mesh); - points=lib3ds_io_read_word(io); - if (points) { - if (!lib3ds_mesh_new_point_list(mesh, points)) { - LIB3DS_ERROR_LOG; - return(LIB3DS_FALSE); - } - for (i=0; ipoints; ++i) { - for (j=0; j<3; ++j) { - mesh->pointL[i].pos[j]=lib3ds_io_read_float(io); - } - } - ASSERT((!mesh->flags) || (mesh->points==mesh->flags)); - ASSERT((!mesh->texels) || (mesh->points==mesh->texels)); - } - } - break; - case LIB3DS_POINT_FLAG_ARRAY: - { - unsigned i; - unsigned flags; - - lib3ds_mesh_free_flag_list(mesh); - flags=lib3ds_io_read_word(io); - if (flags) { - if (!lib3ds_mesh_new_flag_list(mesh, flags)) { - LIB3DS_ERROR_LOG; - return(LIB3DS_FALSE); - } - for (i=0; iflags; ++i) { - mesh->flagL[i]=lib3ds_io_read_word(io); - } - ASSERT((!mesh->points) || (mesh->flags==mesh->points)); - ASSERT((!mesh->texels) || (mesh->flags==mesh->texels)); - } - } - break; - case LIB3DS_FACE_ARRAY: - { - lib3ds_chunk_read_reset(&c, io); - if (!face_array_read(mesh, io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_MESH_TEXTURE_INFO: - { - int i,j; - - for (i=0; i<2; ++i) { - mesh->map_data.tile[i]=lib3ds_io_read_float(io); - } - for (i=0; i<3; ++i) { - mesh->map_data.pos[i]=lib3ds_io_read_float(io); - } - mesh->map_data.scale=lib3ds_io_read_float(io); - - lib3ds_matrix_identity(mesh->map_data.matrix); - for (i=0; i<4; i++) { - for (j=0; j<3; j++) { - mesh->map_data.matrix[i][j]=lib3ds_io_read_float(io); - } - } - for (i=0; i<2; ++i) { - mesh->map_data.planar_size[i]=lib3ds_io_read_float(io); - } - mesh->map_data.cylinder_height=lib3ds_io_read_float(io); - } - break; - case LIB3DS_TEX_VERTS: - { - unsigned i; - unsigned texels; - - lib3ds_mesh_free_texel_list(mesh); - texels=lib3ds_io_read_word(io); - if (texels) { - if (!lib3ds_mesh_new_texel_list(mesh, texels)) { - LIB3DS_ERROR_LOG; - return(LIB3DS_FALSE); - } - for (i=0; itexels; ++i) { - mesh->texelL[i][0]=lib3ds_io_read_float(io); - mesh->texelL[i][1]=lib3ds_io_read_float(io); - } - ASSERT((!mesh->points) || (mesh->texels==mesh->points)); - ASSERT((!mesh->flags) || (mesh->texels==mesh->flags)); - } - } - break; - default: - lib3ds_chunk_unknown(chunk); - } - } - { - unsigned j; - - for (j=0; jfaces; ++j) { - ASSERT(mesh->faceL[j].points[0]points); - ASSERT(mesh->faceL[j].points[1]points); - ASSERT(mesh->faceL[j].points[2]points); - lib3ds_vector_normal( - mesh->faceL[j].normal, - mesh->pointL[mesh->faceL[j].points[0]].pos, - mesh->pointL[mesh->faceL[j].points[1]].pos, - mesh->pointL[mesh->faceL[j].points[2]].pos - ); - } - } - - if (lib3ds_matrix_det(mesh->matrix) < 0.0) - { - /* Flip X coordinate of vertices if mesh matrix - has negative determinant */ - Lib3dsMatrix inv_matrix, M; - Lib3dsVector tmp; - unsigned i; - - lib3ds_matrix_copy(inv_matrix, mesh->matrix); - lib3ds_matrix_inv(inv_matrix); - - lib3ds_matrix_copy(M, mesh->matrix); - lib3ds_matrix_scale_xyz(M, -1.0f, 1.0f, 1.0f); - lib3ds_matrix_mult(M, inv_matrix); - - for (i=0; ipoints; ++i) { - lib3ds_vector_transform(tmp, M, mesh->pointL[i].pos); - lib3ds_vector_copy(mesh->pointL[i].pos, tmp); - } - } - - lib3ds_chunk_read_end(&c, io); - - return(LIB3DS_TRUE); -} - - -static Lib3dsBool -point_array_write(Lib3dsMesh *mesh, Lib3dsIo *io) -{ - Lib3dsChunk c; - unsigned i; - - if (!mesh->points || !mesh->pointL) { - return(LIB3DS_TRUE); - } - ASSERT(mesh->points<0x10000); - c.chunk=LIB3DS_POINT_ARRAY; - c.size=8+12*mesh->points; - lib3ds_chunk_write(&c, io); - - lib3ds_io_write_word(io, (Lib3dsWord)mesh->points); - - if (lib3ds_matrix_det(mesh->matrix) >= 0.0f) { - for (i=0; ipoints; ++i) { - lib3ds_io_write_vector(io, mesh->pointL[i].pos); - } - } - else { - /* Flip X coordinate of vertices if mesh matrix - has negative determinant */ - Lib3dsMatrix inv_matrix, M; - Lib3dsVector tmp; - - lib3ds_matrix_copy(inv_matrix, mesh->matrix); - lib3ds_matrix_inv(inv_matrix); - lib3ds_matrix_copy(M, mesh->matrix); - lib3ds_matrix_scale_xyz(M, -1.0f, 1.0f, 1.0f); - lib3ds_matrix_mult(M, inv_matrix); - - for (i=0; ipoints; ++i) { - lib3ds_vector_transform(tmp, M, mesh->pointL[i].pos); - lib3ds_io_write_vector(io, tmp); - } - } - - return(LIB3DS_TRUE); -} - - -static Lib3dsBool -flag_array_write(Lib3dsMesh *mesh, Lib3dsIo *io) -{ - Lib3dsChunk c; - unsigned i; - - if (!mesh->flags || !mesh->flagL) { - return(LIB3DS_TRUE); - } - ASSERT(mesh->flags<0x10000); - c.chunk=LIB3DS_POINT_FLAG_ARRAY; - c.size=8+2*mesh->flags; - lib3ds_chunk_write(&c, io); - - lib3ds_io_write_word(io, (Lib3dsWord)mesh->flags); - for (i=0; iflags; ++i) { - lib3ds_io_write_word(io, mesh->flagL[i]); - } - return(LIB3DS_TRUE); -} - - -static Lib3dsBool -face_array_write(Lib3dsMesh *mesh, Lib3dsIo *io) -{ - Lib3dsChunk c; - - if (!mesh->faces || !mesh->faceL) { - return(LIB3DS_TRUE); - } - ASSERT(mesh->faces<0x10000); - c.chunk=LIB3DS_FACE_ARRAY; - if (!lib3ds_chunk_write_start(&c, io)) { - return(LIB3DS_FALSE); - } - { - unsigned i; - - lib3ds_io_write_word(io, (Lib3dsWord)mesh->faces); - for (i=0; ifaces; ++i) { - lib3ds_io_write_word(io, mesh->faceL[i].points[0]); - lib3ds_io_write_word(io, mesh->faceL[i].points[1]); - lib3ds_io_write_word(io, mesh->faceL[i].points[2]); - lib3ds_io_write_word(io, mesh->faceL[i].flags); - } - } - - { /*---- MSH_MAT_GROUP ----*/ - Lib3dsChunk c; - unsigned i,j; - Lib3dsWord num; - char *matf=calloc(sizeof(char), mesh->faces); - if (!matf) { - return(LIB3DS_FALSE); - } - - for (i=0; ifaces; ++i) { - if (!matf[i] && strlen(mesh->faceL[i].material)) { - matf[i]=1; - num=1; - - for (j=i+1; jfaces; ++j) { - if (strcmp(mesh->faceL[i].material, mesh->faceL[j].material)==0) ++num; - } - - c.chunk=LIB3DS_MSH_MAT_GROUP; - c.size=6+ (Lib3dsDword)strlen(mesh->faceL[i].material)+1 +2+2*num; - lib3ds_chunk_write(&c, io); - lib3ds_io_write_string(io, mesh->faceL[i].material); - lib3ds_io_write_word(io, num); - lib3ds_io_write_word(io, (Lib3dsWord)i); - - for (j=i+1; jfaces; ++j) { - if (strcmp(mesh->faceL[i].material, mesh->faceL[j].material)==0) { - lib3ds_io_write_word(io, (Lib3dsWord)j); - matf[j]=1; - } - } - } - } - free(matf); - } - - { /*---- SMOOTH_GROUP ----*/ - Lib3dsChunk c; - unsigned i; - - c.chunk=LIB3DS_SMOOTH_GROUP; - c.size=6+4*mesh->faces; - lib3ds_chunk_write(&c, io); - - for (i=0; ifaces; ++i) { - lib3ds_io_write_dword(io, mesh->faceL[i].smoothing); - } - } - - { /*---- MSH_BOXMAP ----*/ - Lib3dsChunk c; - - if (strlen(mesh->box_map.front) || - strlen(mesh->box_map.back) || - strlen(mesh->box_map.left) || - strlen(mesh->box_map.right) || - strlen(mesh->box_map.top) || - strlen(mesh->box_map.bottom)) { - - c.chunk=LIB3DS_MSH_BOXMAP; - if (!lib3ds_chunk_write_start(&c, io)) { - return(LIB3DS_FALSE); - } - - lib3ds_io_write_string(io, mesh->box_map.front); - lib3ds_io_write_string(io, mesh->box_map.back); - lib3ds_io_write_string(io, mesh->box_map.left); - lib3ds_io_write_string(io, mesh->box_map.right); - lib3ds_io_write_string(io, mesh->box_map.top); - lib3ds_io_write_string(io, mesh->box_map.bottom); - - if (!lib3ds_chunk_write_end(&c, io)) { - return(LIB3DS_FALSE); - } - } - } - - if (!lib3ds_chunk_write_end(&c, io)) { - return(LIB3DS_FALSE); - } - return(LIB3DS_TRUE); -} - - -static Lib3dsBool -texel_array_write(Lib3dsMesh *mesh, Lib3dsIo *io) -{ - Lib3dsChunk c; - unsigned i; - - if (!mesh->texels || !mesh->texelL) { - return(LIB3DS_TRUE); - } - ASSERT(mesh->texels<0x10000); - c.chunk=LIB3DS_TEX_VERTS; - c.size=8+8*mesh->texels; - lib3ds_chunk_write(&c, io); - - lib3ds_io_write_word(io, (Lib3dsWord)mesh->texels); - for (i=0; itexels; ++i) { - lib3ds_io_write_float(io, mesh->texelL[i][0]); - lib3ds_io_write_float(io, mesh->texelL[i][1]); - } - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup mesh - */ -Lib3dsBool -lib3ds_mesh_write(Lib3dsMesh *mesh, Lib3dsIo *io) -{ - Lib3dsChunk c; - - c.chunk=LIB3DS_N_TRI_OBJECT; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - if (!point_array_write(mesh, io)) { - return(LIB3DS_FALSE); - } - if (!texel_array_write(mesh, io)) { - return(LIB3DS_FALSE); - } - - if (mesh->map_data.maptype!=LIB3DS_MAP_NONE) { /*---- LIB3DS_MESH_TEXTURE_INFO ----*/ - Lib3dsChunk c; - int i,j; - - c.chunk=LIB3DS_MESH_TEXTURE_INFO; - c.size=92; - if (!lib3ds_chunk_write(&c,io)) { - return(LIB3DS_FALSE); - } - - lib3ds_io_write_word(io, mesh->map_data.maptype); - - for (i=0; i<2; ++i) { - lib3ds_io_write_float(io, mesh->map_data.tile[i]); - } - for (i=0; i<3; ++i) { - lib3ds_io_write_float(io, mesh->map_data.pos[i]); - } - lib3ds_io_write_float(io, mesh->map_data.scale); - - for (i=0; i<4; i++) { - for (j=0; j<3; j++) { - lib3ds_io_write_float(io, mesh->map_data.matrix[i][j]); - } - } - for (i=0; i<2; ++i) { - lib3ds_io_write_float(io, mesh->map_data.planar_size[i]); - } - lib3ds_io_write_float(io, mesh->map_data.cylinder_height); - } - - if (!flag_array_write(mesh, io)) { - return(LIB3DS_FALSE); - } - { /*---- LIB3DS_MESH_MATRIX ----*/ - Lib3dsChunk c; - int i,j; - - c.chunk=LIB3DS_MESH_MATRIX; - c.size=54; - if (!lib3ds_chunk_write(&c,io)) { - return(LIB3DS_FALSE); - } - for (i=0; i<4; i++) { - for (j=0; j<3; j++) { - lib3ds_io_write_float(io, mesh->matrix[i][j]); - } - } - } - - if (mesh->color) { /*---- LIB3DS_MESH_COLOR ----*/ - Lib3dsChunk c; - - c.chunk=LIB3DS_MESH_COLOR; - c.size=7; - if (!lib3ds_chunk_write(&c,io)) { - return(LIB3DS_FALSE); - } - lib3ds_io_write_byte(io, mesh->color); - } - if (!face_array_write(mesh, io)) { - return(LIB3DS_FALSE); - } - - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - return(LIB3DS_TRUE); -} - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/mesh.h b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/mesh.h deleted file mode 100644 index dd75399cc..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/mesh.h +++ /dev/null @@ -1,157 +0,0 @@ -/* -*- c -*- */ -#ifndef INCLUDED_LIB3DS_MESH_H -#define INCLUDED_LIB3DS_MESH_H -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: mesh.h,v 1.20 2007/06/20 17:04:08 jeh Exp $ - */ - -#ifndef INCLUDED_LIB3DS_TYPES_H -#include "types.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Triangular mesh point - * \ingroup mesh - */ -typedef struct Lib3dsPoint { - Lib3dsVector pos; -} Lib3dsPoint; - -/** - * Triangular mesh face - * \ingroup mesh - * \sa Lib3dsFaceFlag - */ -struct Lib3dsFace { - Lib3dsUserData user; /*! Arbitrary user data */ - char material[64]; /*! Material name */ - Lib3dsWord points[3]; /*! Indices into mesh points list */ - Lib3dsWord flags; /*! See Lib3dsFaceFlag, below */ - Lib3dsDword smoothing; /*! Bitmask; each bit identifies a group */ - Lib3dsVector normal; -}; - - -/** - * Vertex flags - * Meaning of _Lib3dsFace::flags. ABC are points of the current face - * (A: is 1st vertex, B is 2nd vertex, C is 3rd vertex) - */ -typedef enum { - LIB3DS_FACE_FLAG_VIS_AC = 0x1, /*!< Bit 0: Edge visibility AC */ - LIB3DS_FACE_FLAG_VIS_BC = 0x2, /*!< Bit 1: Edge visibility BC */ - LIB3DS_FACE_FLAG_VIS_AB = 0x4, /*!< Bit 2: Edge visibility AB */ - LIB3DS_FACE_FLAG_WRAP_U = 0x8, /*!< Bit 3: Face is at tex U wrap seam */ - LIB3DS_FACE_FLAG_WRAP_V = 0x10, /*!< Bit 4: Face is at tex V wrap seam */ - LIB3DS_FACE_FLAG_UNK7 = 0x80, /* Bit 5-8: Unused ? */ - LIB3DS_FACE_FLAG_UNK10 = 0x400, /* Bit 9-10: Random ? */ - /* Bit 11-12: Unused ? */ - LIB3DS_FACE_FLAG_SELECT_3 = (1<<13), /*!< Bit 13: Selection of the face in selection 3*/ - LIB3DS_FACE_FLAG_SELECT_2 = (1<<14), /*!< Bit 14: Selection of the face in selection 2*/ - LIB3DS_FACE_FLAG_SELECT_1 = (1<<15), /*!< Bit 15: Selection of the face in selection 1*/ -} Lib3dsFaceFlag; - -/** - * Triangular mesh box mapping settings - * \ingroup mesh - */ -struct Lib3dsBoxMap { - char front[64]; - char back[64]; - char left[64]; - char right[64]; - char top[64]; - char bottom[64]; -}; - -/** - * Texture projection type - * \ingroup tracks - */ -typedef enum { - LIB3DS_MAP_NONE =0xFFFF, - LIB3DS_MAP_PLANAR =0, - LIB3DS_MAP_CYLINDRICAL =1, - LIB3DS_MAP_SPHERICAL =2 -} Lib3dsMapType; - -/** - * Triangular mesh texture mapping data - * \ingroup mesh - */ -struct Lib3dsMapData { - Lib3dsWord maptype; - Lib3dsVector pos; - Lib3dsMatrix matrix; - Lib3dsFloat scale; - Lib3dsFloat tile[2]; - Lib3dsFloat planar_size[2]; - Lib3dsFloat cylinder_height; -}; - -/** - * Triangular mesh object - * \ingroup mesh - */ -struct Lib3dsMesh { - Lib3dsUserData user; /*< Arbitrary user data */ - Lib3dsMesh *next; - char name[64]; /*< Mesh name. Don't use more than 8 characters */ - Lib3dsDword object_flags; /*< @see Lib3dsObjectFlags */ - Lib3dsByte color; - Lib3dsMatrix matrix; /*< Transformation matrix for mesh data */ - Lib3dsDword points; /*< Number of points in point list */ - Lib3dsPoint *pointL; /*< Point list */ - Lib3dsDword flags; /*< Number of flags in per-point flags list */ - Lib3dsWord *flagL; /*< Per-point flags list */ - Lib3dsDword texels; /*< Number of U-V texture coordinates */ - Lib3dsTexel *texelL; /*< U-V texture coordinates */ - Lib3dsDword faces; /*< Number of faces in face list */ - Lib3dsFace *faceL; /*< Face list */ - Lib3dsBoxMap box_map; - Lib3dsMapData map_data; -}; - -extern LIB3DSAPI Lib3dsMesh* lib3ds_mesh_new(const char *name); -extern LIB3DSAPI void lib3ds_mesh_free(Lib3dsMesh *mesh); -extern LIB3DSAPI Lib3dsBool lib3ds_mesh_new_point_list(Lib3dsMesh *mesh, Lib3dsDword points); -extern LIB3DSAPI void lib3ds_mesh_free_point_list(Lib3dsMesh *mesh); -extern LIB3DSAPI Lib3dsBool lib3ds_mesh_new_flag_list(Lib3dsMesh *mesh, Lib3dsDword flags); -extern LIB3DSAPI void lib3ds_mesh_free_flag_list(Lib3dsMesh *mesh); -extern LIB3DSAPI Lib3dsBool lib3ds_mesh_new_texel_list(Lib3dsMesh *mesh, Lib3dsDword texels); -extern LIB3DSAPI void lib3ds_mesh_free_texel_list(Lib3dsMesh *mesh); -extern LIB3DSAPI Lib3dsBool lib3ds_mesh_new_face_list(Lib3dsMesh *mesh, Lib3dsDword flags); -extern LIB3DSAPI void lib3ds_mesh_free_face_list(Lib3dsMesh *mesh); -extern LIB3DSAPI void lib3ds_mesh_bounding_box(Lib3dsMesh *mesh, Lib3dsVector bmin, Lib3dsVector bmax); -extern LIB3DSAPI void lib3ds_mesh_calculate_normals(Lib3dsMesh *mesh, Lib3dsVector *normalL); -extern LIB3DSAPI void lib3ds_mesh_dump(Lib3dsMesh *mesh); -extern LIB3DSAPI Lib3dsBool lib3ds_mesh_read(Lib3dsMesh *mesh, Lib3dsIo *io); -extern LIB3DSAPI Lib3dsBool lib3ds_mesh_write(Lib3dsMesh *mesh, Lib3dsIo *io); - -#ifdef __cplusplus -} -#endif -#endif - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/node.c b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/node.c deleted file mode 100644 index 11faa0c5c..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/node.c +++ /dev/null @@ -1,1088 +0,0 @@ -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: node.c,v 1.20 2007/06/20 17:04:08 jeh Exp $ - */ -#include "node.h" -#include "file.h" -#include "io.h" -#include "chunk.h" -#include "matrix.h" -#include -#include -#include - - -/*! - * \defgroup node Animation Nodes - */ - - -/*! - * Create and return a new ambient node. - * - * The node is returned with an identity matrix. All other fields - * are zero. - * - * \return Lib3dsNode - * - * \ingroup node - */ -Lib3dsNode* -lib3ds_node_new_ambient() -{ - Lib3dsNode *node=(Lib3dsNode*)calloc(sizeof(Lib3dsNode), 1); - node->type=LIB3DS_AMBIENT_NODE; - lib3ds_matrix_identity(node->matrix); - return(node); -} - - -/*! - * Create and return a new object node. - * - * The node is returned with an identity matrix. All other fields - * are zero. - * - * \return Lib3dsNode - * - * \ingroup node - */ -Lib3dsNode* -lib3ds_node_new_object() -{ - Lib3dsNode *node=(Lib3dsNode*)calloc(sizeof(Lib3dsNode), 1); - node->type=LIB3DS_OBJECT_NODE; - lib3ds_matrix_identity(node->matrix); - return(node); -} - - -/*! - * Create and return a new camera node. - * - * The node is returned with an identity matrix. All other fields - * are zero. - * - * \return Lib3dsNode - * - * \ingroup node - */ -Lib3dsNode* -lib3ds_node_new_camera() -{ - Lib3dsNode *node=(Lib3dsNode*)calloc(sizeof(Lib3dsNode), 1); - node->type=LIB3DS_CAMERA_NODE; - lib3ds_matrix_identity(node->matrix); - return(node); -} - - -/*! - * Create and return a new target node. - * - * The node is returned with an identity matrix. All other fields - * are zero. - * - * \return Lib3dsNode - * - * \ingroup node - */ -Lib3dsNode* -lib3ds_node_new_target() -{ - Lib3dsNode *node=(Lib3dsNode*)calloc(sizeof(Lib3dsNode), 1); - node->type=LIB3DS_TARGET_NODE; - lib3ds_matrix_identity(node->matrix); - return(node); -} - - -/*! - * Create and return a new light node. - * - * The node is returned with an identity matrix. All other fields - * are zero. - * - * \return Lib3dsNode - * - * \ingroup node - */ -Lib3dsNode* -lib3ds_node_new_light() -{ - Lib3dsNode *node=(Lib3dsNode*)calloc(sizeof(Lib3dsNode), 1); - node->type=LIB3DS_LIGHT_NODE; - lib3ds_matrix_identity(node->matrix); - return(node); -} - - -/*! - * Create and return a new spot node. - * - * The node is returned with an identity matrix. All other fields - * are zero. - * - * \return Lib3dsNode - * - * \ingroup node - */ -Lib3dsNode* -lib3ds_node_new_spot() -{ - Lib3dsNode *node=(Lib3dsNode*)calloc(sizeof(Lib3dsNode), 1); - node->type=LIB3DS_SPOT_NODE; - lib3ds_matrix_identity(node->matrix); - return(node); -} - - -static void -free_node_and_childs(Lib3dsNode *node) -{ - ASSERT(node); - switch (node->type) { - case LIB3DS_UNKNOWN_NODE: - break; - case LIB3DS_AMBIENT_NODE: - { - Lib3dsAmbientData *n=&node->data.ambient; - lib3ds_lin3_track_free_keys(&n->col_track); - } - break; - case LIB3DS_OBJECT_NODE: - { - Lib3dsObjectData *n=&node->data.object; - - lib3ds_lin3_track_free_keys(&n->pos_track); - lib3ds_quat_track_free_keys(&n->rot_track); - lib3ds_lin3_track_free_keys(&n->scl_track); - lib3ds_bool_track_free_keys(&n->hide_track); - lib3ds_morph_track_free_keys(&n->morph_track); - } - break; - case LIB3DS_CAMERA_NODE: - { - Lib3dsCameraData *n=&node->data.camera; - lib3ds_lin3_track_free_keys(&n->pos_track); - lib3ds_lin1_track_free_keys(&n->fov_track); - lib3ds_lin1_track_free_keys(&n->roll_track); - } - break; - case LIB3DS_TARGET_NODE: - { - Lib3dsTargetData *n=&node->data.target; - lib3ds_lin3_track_free_keys(&n->pos_track); - } - break; - case LIB3DS_LIGHT_NODE: - { - Lib3dsLightData *n=&node->data.light; - lib3ds_lin3_track_free_keys(&n->pos_track); - lib3ds_lin3_track_free_keys(&n->col_track); - lib3ds_lin1_track_free_keys(&n->hotspot_track); - lib3ds_lin1_track_free_keys(&n->falloff_track); - lib3ds_lin1_track_free_keys(&n->roll_track); - } - break; - case LIB3DS_SPOT_NODE: - { - Lib3dsSpotData *n=&node->data.spot; - lib3ds_lin3_track_free_keys(&n->pos_track); - } - break; - } - { - Lib3dsNode *p,*q; - for (p=node->childs; p; p=q) { - q=p->next; - free_node_and_childs(p); - } - } - node->type=LIB3DS_UNKNOWN_NODE; - free(node); -} - - -/*! - * Free a node and all of its resources. - * - * \param node Lib3dsNode object to be freed. - * - * \ingroup node - */ -void -lib3ds_node_free(Lib3dsNode *node) -{ - ASSERT(node); - free_node_and_childs(node); -} - - -/*! - * Evaluate an animation node. - * - * Recursively sets node and its children to their appropriate values - * for this point in the animation. - * - * \param node Node to be evaluated. - * \param t time value, between 0. and file->frames - * - * \ingroup node - */ -void -lib3ds_node_eval(Lib3dsNode *node, Lib3dsFloat t) -{ - ASSERT(node); - switch (node->type) { - case LIB3DS_UNKNOWN_NODE: - { - ASSERT(LIB3DS_FALSE); - } - break; - case LIB3DS_AMBIENT_NODE: - { - Lib3dsAmbientData *n=&node->data.ambient; - if (node->parent) { - lib3ds_matrix_copy(node->matrix, node->parent->matrix); - } - else { - lib3ds_matrix_identity(node->matrix); - } - lib3ds_lin3_track_eval(&n->col_track, n->col, t); - } - break; - case LIB3DS_OBJECT_NODE: - { - Lib3dsMatrix M; - Lib3dsObjectData *n=&node->data.object; - - lib3ds_lin3_track_eval(&n->pos_track, n->pos, t); - lib3ds_quat_track_eval(&n->rot_track, n->rot, t); - if (n->scl_track.keyL) { - lib3ds_lin3_track_eval(&n->scl_track, n->scl, t); - } - else { - n->scl[0] = n->scl[1] = n->scl[2] = 1.0f; - } - lib3ds_bool_track_eval(&n->hide_track, &n->hide, t); - lib3ds_morph_track_eval(&n->morph_track, n->morph, t); - - lib3ds_matrix_identity(M); - lib3ds_matrix_translate(M, n->pos); - lib3ds_matrix_rotate(M, n->rot); - lib3ds_matrix_scale(M, n->scl); - - if (node->parent) { - lib3ds_matrix_copy(node->matrix, node->parent->matrix); - lib3ds_matrix_mult(node->matrix, M); - } - else { - lib3ds_matrix_copy(node->matrix, M); - } - } - break; - case LIB3DS_CAMERA_NODE: - { - Lib3dsCameraData *n=&node->data.camera; - lib3ds_lin3_track_eval(&n->pos_track, n->pos, t); - lib3ds_lin1_track_eval(&n->fov_track, &n->fov, t); - lib3ds_lin1_track_eval(&n->roll_track, &n->roll, t); - if (node->parent) { - lib3ds_matrix_copy(node->matrix, node->parent->matrix); - } - else { - lib3ds_matrix_identity(node->matrix); - } - lib3ds_matrix_translate(node->matrix, n->pos); - } - break; - case LIB3DS_TARGET_NODE: - { - Lib3dsTargetData *n=&node->data.target; - lib3ds_lin3_track_eval(&n->pos_track, n->pos, t); - if (node->parent) { - lib3ds_matrix_copy(node->matrix, node->parent->matrix); - } - else { - lib3ds_matrix_identity(node->matrix); - } - lib3ds_matrix_translate(node->matrix, n->pos); - } - break; - case LIB3DS_LIGHT_NODE: - { - Lib3dsLightData *n=&node->data.light; - lib3ds_lin3_track_eval(&n->pos_track, n->pos, t); - lib3ds_lin3_track_eval(&n->col_track, n->col, t); - lib3ds_lin1_track_eval(&n->hotspot_track, &n->hotspot, t); - lib3ds_lin1_track_eval(&n->falloff_track, &n->falloff, t); - lib3ds_lin1_track_eval(&n->roll_track, &n->roll, t); - if (node->parent) { - lib3ds_matrix_copy(node->matrix, node->parent->matrix); - } - else { - lib3ds_matrix_identity(node->matrix); - } - lib3ds_matrix_translate(node->matrix, n->pos); - } - break; - case LIB3DS_SPOT_NODE: - { - Lib3dsSpotData *n=&node->data.spot; - lib3ds_lin3_track_eval(&n->pos_track, n->pos, t); - if (node->parent) { - lib3ds_matrix_copy(node->matrix, node->parent->matrix); - } - else { - lib3ds_matrix_identity(node->matrix); - } - lib3ds_matrix_translate(node->matrix, n->pos); - } - break; - } - { - Lib3dsNode *p; - - for (p=node->childs; p!=0; p=p->next) { - lib3ds_node_eval(p, t); - } - } -} - - -/*! - * Return a node object by name and type. - * - * This function performs a recursive search for the specified node. - * Both name and type must match. - * - * \param node The parent node for the search - * \param name The target node name. - * \param type The target node type - * - * \return A pointer to the first matching node, or NULL if not found. - * - * \ingroup node - */ -Lib3dsNode* -lib3ds_node_by_name(Lib3dsNode *node, const char* name, Lib3dsNodeTypes type) -{ - Lib3dsNode *p,*q; - - for (p=node->childs; p!=0; p=p->next) { - if ((p->type==type) && (strcmp(p->name, name)==0)) { - return(p); - } - q=lib3ds_node_by_name(p, name, type); - if (q) { - return(q); - } - } - return(0); -} - - -/*! - * Return a node object by id. - * - * This function performs a recursive search for the specified node. - * - * \param node The parent node for the search - * \param node_id The target node id. - * - * \return A pointer to the first matching node, or NULL if not found. - * - * \ingroup node - */ -Lib3dsNode* -lib3ds_node_by_id(Lib3dsNode *node, Lib3dsWord node_id) -{ - Lib3dsNode *p,*q; - - for (p=node->childs; p!=0; p=p->next) { - if (p->node_id==node_id) { - return(p); - } - q=lib3ds_node_by_id(p, node_id); - if (q) { - return(q); - } - } - return(0); -} - - -static const char* node_names_table[]= { - "***Unknown***", - "Ambient", - "Object", - "Camera", - "Target", - "Light", - "Spot" -}; - - -/*! - * Dump node and all descendants recursively. - * - * \param node The top-level node to be dumped. - * \param level current recursion depth - * - * \ingroup node - */ -void -lib3ds_node_dump(Lib3dsNode *node, Lib3dsIntd level) -{ - Lib3dsNode *p; - char l[128]; - - ASSERT(node); - memset(l, ' ', 2*level); - l[2*level]=0; - - if (node->type==LIB3DS_OBJECT_NODE) { - printf("%s%s [%s] (%s)\n", - l, - node->name, - node->data.object.instance, - node_names_table[node->type] - ); - } - else { - printf("%s%s (%s)\n", - l, - node->name, - node_names_table[node->type] - ); - } - - for (p=node->childs; p!=0; p=p->next) { - lib3ds_node_dump(p, level+1); - } -} - - -/*! - * \ingroup node - */ -Lib3dsBool -lib3ds_node_read(Lib3dsNode *node, Lib3dsFile *file, Lib3dsIo *io) -{ - Lib3dsChunk c; - Lib3dsWord chunk; - - ASSERT(node); - if (!lib3ds_chunk_read_start(&c, 0, io)) { - return(LIB3DS_FALSE); - } - switch (c.chunk) { - case LIB3DS_AMBIENT_NODE_TAG: - case LIB3DS_OBJECT_NODE_TAG: - case LIB3DS_CAMERA_NODE_TAG: - case LIB3DS_TARGET_NODE_TAG: - case LIB3DS_LIGHT_NODE_TAG: - case LIB3DS_SPOTLIGHT_NODE_TAG: - case LIB3DS_L_TARGET_NODE_TAG: - break; - default: - return(LIB3DS_FALSE); - } - - while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) { - switch (chunk) { - case LIB3DS_NODE_ID: - { - node->node_id=lib3ds_io_read_word(io); - lib3ds_chunk_dump_info(" ID = %d", (short)node->node_id); - } - break; - case LIB3DS_NODE_HDR: - { - if (!lib3ds_io_read_string(io, node->name, 64)) { - return(LIB3DS_FALSE); - } - node->flags1=lib3ds_io_read_word(io); - node->flags2=lib3ds_io_read_word(io); - node->parent_id=lib3ds_io_read_word(io); - lib3ds_chunk_dump_info(" NAME =%s", node->name); - lib3ds_chunk_dump_info(" PARENT=%d", (short)node->parent_id); - } - break; - case LIB3DS_PIVOT: - { - if (node->type==LIB3DS_OBJECT_NODE) { - int i; - for (i=0; i<3; ++i) { - node->data.object.pivot[i]=lib3ds_io_read_float(io); - } - } - else { - lib3ds_chunk_unknown(chunk); - } - } - break; - case LIB3DS_INSTANCE_NAME: - { - if (node->type==LIB3DS_OBJECT_NODE) { - if (!lib3ds_io_read_string(io, node->data.object.instance, 64)) { - return(LIB3DS_FALSE); - } - } - else { - lib3ds_chunk_unknown(chunk); - } - } - break; - case LIB3DS_BOUNDBOX: - { - if (node->type==LIB3DS_OBJECT_NODE) { - int i; - for (i=0; i<3; ++i) { - node->data.object.bbox_min[i]=lib3ds_io_read_float(io); - } - for (i=0; i<3; ++i) { - node->data.object.bbox_max[i]=lib3ds_io_read_float(io); - } - } - else { - lib3ds_chunk_unknown(chunk); - } - } - break; - case LIB3DS_COL_TRACK_TAG: - { - Lib3dsBool result=LIB3DS_TRUE; - - switch (node->type) { - case LIB3DS_AMBIENT_NODE: - result=lib3ds_lin3_track_read(&node->data.ambient.col_track, io); - break; - case LIB3DS_LIGHT_NODE: - result=lib3ds_lin3_track_read(&node->data.light.col_track, io); - break; - default: - lib3ds_chunk_unknown(chunk); - } - if (!result) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_POS_TRACK_TAG: - { - Lib3dsBool result=LIB3DS_TRUE; - - switch (node->type) { - case LIB3DS_OBJECT_NODE: - result=lib3ds_lin3_track_read(&node->data.object.pos_track, io); - break; - case LIB3DS_CAMERA_NODE: - result=lib3ds_lin3_track_read(&node->data.camera.pos_track, io); - break; - case LIB3DS_TARGET_NODE: - result=lib3ds_lin3_track_read(&node->data.target.pos_track, io); - break; - case LIB3DS_LIGHT_NODE: - result=lib3ds_lin3_track_read(&node->data.light.pos_track, io); - break; - case LIB3DS_SPOT_NODE: - result=lib3ds_lin3_track_read(&node->data.spot.pos_track, io); - break; - default: - lib3ds_chunk_unknown(chunk); - } - if (!result) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_ROT_TRACK_TAG: - { - if (node->type==LIB3DS_OBJECT_NODE) { - if (!lib3ds_quat_track_read(&node->data.object.rot_track, io)) { - return(LIB3DS_FALSE); - } - } - else { - lib3ds_chunk_unknown(chunk); - } - } - break; - case LIB3DS_SCL_TRACK_TAG: - { - if (node->type==LIB3DS_OBJECT_NODE) { - if (!lib3ds_lin3_track_read(&node->data.object.scl_track, io)) { - return(LIB3DS_FALSE); - } - } - else { - lib3ds_chunk_unknown(chunk); - } - } - break; - case LIB3DS_FOV_TRACK_TAG: - { - if (node->type==LIB3DS_CAMERA_NODE) { - if (!lib3ds_lin1_track_read(&node->data.camera.fov_track, io)) { - return(LIB3DS_FALSE); - } - } - else { - lib3ds_chunk_unknown(chunk); - } - } - break; - case LIB3DS_HOT_TRACK_TAG: - { - if (node->type==LIB3DS_LIGHT_NODE) { - if (!lib3ds_lin1_track_read(&node->data.light.hotspot_track, io)) { - return(LIB3DS_FALSE); - } - } - else { - lib3ds_chunk_unknown(chunk); - } - } - break; - case LIB3DS_FALL_TRACK_TAG: - { - if (node->type==LIB3DS_LIGHT_NODE) { - if (!lib3ds_lin1_track_read(&node->data.light.falloff_track, io)) { - return(LIB3DS_FALSE); - } - } - else { - lib3ds_chunk_unknown(chunk); - } - } - break; - case LIB3DS_ROLL_TRACK_TAG: - { - Lib3dsBool result=LIB3DS_TRUE; - - switch (node->type) { - case LIB3DS_CAMERA_NODE: - result=lib3ds_lin1_track_read(&node->data.camera.roll_track, io); - break; - case LIB3DS_LIGHT_NODE: - result=lib3ds_lin1_track_read(&node->data.light.roll_track, io); - break; - default: - lib3ds_chunk_unknown(chunk); - } - if (!result) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_HIDE_TRACK_TAG: - { - if (node->type==LIB3DS_OBJECT_NODE) { - if (!lib3ds_bool_track_read(&node->data.object.hide_track, io)) { - return(LIB3DS_FALSE); - } - } - else { - lib3ds_chunk_unknown(chunk); - } - } - break; - case LIB3DS_MORPH_SMOOTH: - { - if (node->type==LIB3DS_OBJECT_NODE) { - node->data.object.morph_smooth=lib3ds_io_read_float(io); - } - else { - lib3ds_chunk_unknown(chunk); - } - } - break; - case LIB3DS_MORPH_TRACK_TAG: - { - if (node->type==LIB3DS_OBJECT_NODE) { - if (!lib3ds_morph_track_read(&node->data.object.morph_track, io)) { - return(LIB3DS_FALSE); - } - } - else { - lib3ds_chunk_unknown(chunk); - } - } - break; - default: - lib3ds_chunk_unknown(chunk); - } - } - - lib3ds_chunk_read_end(&c, io); - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup node - */ -Lib3dsBool -lib3ds_node_write(Lib3dsNode *node, Lib3dsFile *file, Lib3dsIo *io) -{ - Lib3dsChunk c; - - switch (node->type) { - case LIB3DS_AMBIENT_NODE: - c.chunk=LIB3DS_AMBIENT_NODE_TAG; - break; - case LIB3DS_OBJECT_NODE: - c.chunk=LIB3DS_OBJECT_NODE_TAG; - break; - case LIB3DS_CAMERA_NODE: - c.chunk=LIB3DS_CAMERA_NODE_TAG; - break; - case LIB3DS_TARGET_NODE: - c.chunk=LIB3DS_TARGET_NODE_TAG; - break; - case LIB3DS_LIGHT_NODE: - if (lib3ds_file_node_by_name(file, node->name, LIB3DS_SPOT_NODE)) { - c.chunk=LIB3DS_SPOTLIGHT_NODE_TAG; - } - else { - c.chunk=LIB3DS_LIGHT_NODE_TAG; - } - break; - case LIB3DS_SPOT_NODE: - c.chunk=LIB3DS_L_TARGET_NODE_TAG; - break; - default: - return(LIB3DS_FALSE); - } - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - - { /*---- LIB3DS_NODE_ID ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_NODE_ID; - c.size=8; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_intw(io, node->node_id); - } - - { /*---- LIB3DS_NODE_HDR ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_NODE_HDR; - c.size=6+ 1+(Lib3dsDword)strlen(node->name) +2+2+2; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_string(io, node->name); - lib3ds_io_write_word(io, node->flags1); - lib3ds_io_write_word(io, node->flags2); - lib3ds_io_write_word(io, node->parent_id); - } - - switch (c.chunk) { - case LIB3DS_AMBIENT_NODE_TAG: - { /*---- LIB3DS_COL_TRACK_TAG ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_COL_TRACK_TAG; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_lin3_track_write(&node->data.ambient.col_track,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_OBJECT_NODE_TAG: - { /*---- LIB3DS_PIVOT ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_PIVOT; - c.size=18; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_vector(io, node->data.object.pivot); - } - { /*---- LIB3DS_INSTANCE_NAME ----*/ - Lib3dsChunk c; - const char *name; - if (strlen(node->data.object.instance)) { - name=node->data.object.instance; - - c.chunk=LIB3DS_INSTANCE_NAME; - c.size=6+1+(Lib3dsDword)strlen(name); - lib3ds_chunk_write(&c,io); - lib3ds_io_write_string(io, name); - } - } - { - int i; - for (i=0; i<3; ++i) { - if ((fabs(node->data.object.bbox_min[i])>LIB3DS_EPSILON) || - (fabs(node->data.object.bbox_max[i])>LIB3DS_EPSILON)) { - break; - } - } - - if (i<3) { /*---- LIB3DS_BOUNDBOX ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_BOUNDBOX; - c.size=30; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_vector(io, node->data.object.bbox_min); - lib3ds_io_write_vector(io, node->data.object.bbox_max); - } - } - { /*---- LIB3DS_POS_TRACK_TAG ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_POS_TRACK_TAG; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_lin3_track_write(&node->data.object.pos_track,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - } - { /*---- LIB3DS_ROT_TRACK_TAG ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_ROT_TRACK_TAG; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_quat_track_write(&node->data.object.rot_track,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - } - { /*---- LIB3DS_SCL_TRACK_TAG ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_SCL_TRACK_TAG; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_lin3_track_write(&node->data.object.scl_track,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - } - if (node->data.object.hide_track.keyL) { /*---- LIB3DS_HIDE_TRACK_TAG ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_HIDE_TRACK_TAG; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_bool_track_write(&node->data.object.hide_track,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - } - if (fabs(node->data.object.morph_smooth)>LIB3DS_EPSILON){ /*---- LIB3DS_MORPH_SMOOTH ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_MORPH_SMOOTH; - c.size=10; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_float(io, node->data.object.morph_smooth); - } - break; - case LIB3DS_CAMERA_NODE_TAG: - { /*---- LIB3DS_POS_TRACK_TAG ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_POS_TRACK_TAG; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_lin3_track_write(&node->data.camera.pos_track,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - } - { /*---- LIB3DS_FOV_TRACK_TAG ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_FOV_TRACK_TAG; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_lin1_track_write(&node->data.camera.fov_track,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - } - { /*---- LIB3DS_ROLL_TRACK_TAG ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_ROLL_TRACK_TAG; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_lin1_track_write(&node->data.camera.roll_track,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_TARGET_NODE_TAG: - { /*---- LIB3DS_POS_TRACK_TAG ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_POS_TRACK_TAG; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_lin3_track_write(&node->data.target.pos_track,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_LIGHT_NODE_TAG: - { /*---- LIB3DS_POS_TRACK_TAG ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_POS_TRACK_TAG; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_lin3_track_write(&node->data.light.pos_track,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - } - { /*---- LIB3DS_COL_TRACK_TAG ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_COL_TRACK_TAG; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_lin3_track_write(&node->data.light.col_track,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_SPOTLIGHT_NODE_TAG: - { /*---- LIB3DS_POS_TRACK_TAG ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_POS_TRACK_TAG; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_lin3_track_write(&node->data.light.pos_track,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - } - { /*---- LIB3DS_COL_TRACK_TAG ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_COL_TRACK_TAG; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_lin3_track_write(&node->data.light.col_track,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - } - { /*---- LIB3DS_HOT_TRACK_TAG ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_HOT_TRACK_TAG; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_lin1_track_write(&node->data.light.hotspot_track,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - } - { /*---- LIB3DS_FALL_TRACK_TAG ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_FALL_TRACK_TAG; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_lin1_track_write(&node->data.light.falloff_track,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - } - { /*---- LIB3DS_ROLL_TRACK_TAG ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_ROLL_TRACK_TAG; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_lin1_track_write(&node->data.light.roll_track,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - } - break; - case LIB3DS_L_TARGET_NODE_TAG: - { /*---- LIB3DS_POS_TRACK_TAG ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_POS_TRACK_TAG; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_lin3_track_write(&node->data.spot.pos_track,io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - } - break; - default: - return(LIB3DS_FALSE); - } - - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - return(LIB3DS_TRUE); -} - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/node.h b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/node.h deleted file mode 100644 index 41197b203..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/node.h +++ /dev/null @@ -1,188 +0,0 @@ -/* -*- c -*- */ -#ifndef INCLUDED_LIB3DS_NODE_H -#define INCLUDED_LIB3DS_NODE_H -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: node.h,v 1.12 2007/06/20 17:04:09 jeh Exp $ - */ - -#ifndef INCLUDED_LIB3DS_TRACKS_H -#include "tracks.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Scene graph ambient color node data - * \ingroup node - */ -typedef struct Lib3dsAmbientData { - Lib3dsRgb col; - Lib3dsLin3Track col_track; -} Lib3dsAmbientData; - -/** - * Scene graph object instance node data - * \ingroup node - */ -typedef struct Lib3dsObjectData { - Lib3dsVector pivot; - char instance[64]; - Lib3dsVector bbox_min; - Lib3dsVector bbox_max; - Lib3dsVector pos; - Lib3dsLin3Track pos_track; - Lib3dsQuat rot; - Lib3dsQuatTrack rot_track; - Lib3dsVector scl; - Lib3dsLin3Track scl_track; - Lib3dsFloat morph_smooth; - char morph[64]; - Lib3dsMorphTrack morph_track; - Lib3dsBool hide; - Lib3dsBoolTrack hide_track; -} Lib3dsObjectData; - -/** - * Scene graph camera node data - * \ingroup node - */ -typedef struct Lib3dsCameraData { - Lib3dsVector pos; - Lib3dsLin3Track pos_track; - Lib3dsFloat fov; - Lib3dsLin1Track fov_track; - Lib3dsFloat roll; - Lib3dsLin1Track roll_track; -} Lib3dsCameraData; - -/** - * Scene graph camera target node data - * \ingroup node - */ -typedef struct Lib3dsTargetData { - Lib3dsVector pos; - Lib3dsLin3Track pos_track; -} Lib3dsTargetData; - -/** - * Scene graph light node data - * \ingroup node - */ -typedef struct Lib3dsLightData { - Lib3dsVector pos; - Lib3dsLin3Track pos_track; - Lib3dsRgb col; - Lib3dsLin3Track col_track; - Lib3dsFloat hotspot; - Lib3dsLin1Track hotspot_track; - Lib3dsFloat falloff; - Lib3dsLin1Track falloff_track; - Lib3dsFloat roll; - Lib3dsLin1Track roll_track; -} Lib3dsLightData; - -/** - * Scene graph spotlight target node data - * \ingroup node - */ -typedef struct Lib3dsSpotData { - Lib3dsVector pos; - Lib3dsLin3Track pos_track; -} Lib3dsSpotData; - -/** - * Scene graph node data union - * \ingroup node - */ -typedef union Lib3dsNodeData { - Lib3dsAmbientData ambient; - Lib3dsObjectData object; - Lib3dsCameraData camera; - Lib3dsTargetData target; - Lib3dsLightData light; - Lib3dsSpotData spot; -} Lib3dsNodeData; - -/*! - * \ingroup node - */ -#define LIB3DS_NO_PARENT 65535 - -/** - * Scene graph node - * \ingroup node - */ -struct Lib3dsNode { - Lib3dsUserData user; - Lib3dsNode *next; - Lib3dsNode *childs; - Lib3dsNode *parent; - Lib3dsNodeTypes type; - Lib3dsWord node_id; - char name[64]; - Lib3dsWord flags1; - Lib3dsWord flags2; - Lib3dsWord parent_id; - Lib3dsMatrix matrix; - Lib3dsNodeData data; -}; - -/** - * Node flags #1 - * \ingroup node - */ -typedef enum { - LIB3DS_HIDDEN = 0x800 -} Lib3dsNodeFlags1; - -/** - * Node flags #2 - * \ingroup node - */ -typedef enum { - LIB3DS_SHOW_PATH = 0x1, - LIB3DS_SMOOTHING = 0x2, - LIB3DS_MOTION_BLUR = 0x10, - LIB3DS_MORPH_MATERIALS = 0x40 -} Lib3dsNodeFlags2; - -extern LIB3DSAPI Lib3dsNode* lib3ds_node_new_ambient(); -extern LIB3DSAPI Lib3dsNode* lib3ds_node_new_object(); -extern LIB3DSAPI Lib3dsNode* lib3ds_node_new_camera(); -extern LIB3DSAPI Lib3dsNode* lib3ds_node_new_target(); -extern LIB3DSAPI Lib3dsNode* lib3ds_node_new_light(); -extern LIB3DSAPI Lib3dsNode* lib3ds_node_new_spot(); -extern LIB3DSAPI void lib3ds_node_free(Lib3dsNode *node); -extern LIB3DSAPI void lib3ds_node_eval(Lib3dsNode *node, Lib3dsFloat t); -extern LIB3DSAPI Lib3dsNode* lib3ds_node_by_name(Lib3dsNode *node, const char* name, - Lib3dsNodeTypes type); -extern LIB3DSAPI Lib3dsNode* lib3ds_node_by_id(Lib3dsNode *node, Lib3dsWord node_id); -extern LIB3DSAPI void lib3ds_node_dump(Lib3dsNode *node, Lib3dsIntd level); -extern LIB3DSAPI Lib3dsBool lib3ds_node_read(Lib3dsNode *node, Lib3dsFile *file, Lib3dsIo *io); -extern LIB3DSAPI Lib3dsBool lib3ds_node_write(Lib3dsNode *node, Lib3dsFile *file, Lib3dsIo *io); - -#ifdef __cplusplus -} -#endif -#endif - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/quat.c b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/quat.c deleted file mode 100644 index 15c82852e..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/quat.c +++ /dev/null @@ -1,418 +0,0 @@ -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: quat.c,v 1.9 2007/06/20 17:04:09 jeh Exp $ - */ -#include "quat.h" -#include - - -/*! - * \defgroup quat Quaternion Mathematics - */ - - -/*! -* \typedef Lib3dsQuat -* \ingroup quat -*/ - - -/*! - * Clear a quaternion. - * \ingroup quat - */ -void -lib3ds_quat_zero(Lib3dsQuat c) -{ - c[0]=c[1]=c[2]=c[3]=0.0f; -} - - -/*! - * Set a quaternion to Identity - * \ingroup quat - */ -void -lib3ds_quat_identity(Lib3dsQuat c) -{ - c[0]=c[1]=c[2]=0.0f; - c[3]=1.0f; -} - - -/*! - * Copy a quaternion. - * \ingroup quat - */ -void -lib3ds_quat_copy(Lib3dsQuat dest, Lib3dsQuat src) -{ - int i; - for (i=0; i<4; ++i) { - dest[i]=src[i]; - } -} - - -/*! - * Compute a quaternion from axis and angle. - * - * \param c Computed quaternion - * \param axis Rotation axis - * \param angle Angle of rotation, radians. - * - * \ingroup quat - */ -void -lib3ds_quat_axis_angle(Lib3dsQuat c, Lib3dsVector axis, Lib3dsFloat angle) -{ - Lib3dsDouble omega,s; - Lib3dsDouble l; - - l=sqrt(axis[0]*axis[0] + axis[1]*axis[1] + axis[2]*axis[2]); - if (lLIB3DS_EPSILON) { - if (fabs(l)>1.0f) l/=fabs(l); - om=acos(l); - sinom=sin(om); - if (fabs(sinom)>LIB3DS_EPSILON) { - sp=sin((1.0f-t)*om)/sinom; - sq=sin(t*om)/sinom; - } - else { - sp=1.0f-t; - sq=t; - } - c[0]=(Lib3dsFloat)(sp*a[0] + sq*b[0]); - c[1]=(Lib3dsFloat)(sp*a[1] + sq*b[1]); - c[2]=(Lib3dsFloat)(sp*a[2] + sq*b[2]); - c[3]=(Lib3dsFloat)(sp*a[3] + sq*b[3]); - } - else { - q[0]=-a[1]; - q[1]=a[0]; - q[2]=-a[3]; - q[3]=a[2]; - sp=sin((1.0-t)*LIB3DS_HALFPI); - sq=sin(t*LIB3DS_HALFPI); - c[0]=(Lib3dsFloat)(sp*a[0] + sq*q[0]); - c[1]=(Lib3dsFloat)(sp*a[1] + sq*q[1]); - c[2]=(Lib3dsFloat)(sp*a[2] + sq*q[2]); - c[3]=(Lib3dsFloat)(sp*a[3] + sq*q[3]); - } -} - - -/*! - * \ingroup quat - */ -void -lib3ds_quat_squad(Lib3dsQuat c, Lib3dsQuat a, Lib3dsQuat p, Lib3dsQuat q, - Lib3dsQuat b, Lib3dsFloat t) -{ - Lib3dsQuat ab; - Lib3dsQuat pq; - - lib3ds_quat_slerp(ab,a,b,t); - lib3ds_quat_slerp(pq,p,q,t); - lib3ds_quat_slerp(c,ab,pq,2*t*(1-t)); -} - - -/*! - * \ingroup quat - */ -void -lib3ds_quat_tangent(Lib3dsQuat c, Lib3dsQuat p, Lib3dsQuat q, Lib3dsQuat n) -{ - Lib3dsQuat dn,dp,x; - int i; - - lib3ds_quat_ln_dif(dn, q, n); - lib3ds_quat_ln_dif(dp, q, p); - - for (i=0; i<4; i++) { - x[i]=-1.0f/4.0f*(dn[i]+dp[i]); - } - lib3ds_quat_exp(x); - lib3ds_quat_mul(c,q,x); -} - - -/*! - * \ingroup quat - */ -void -lib3ds_quat_dump(Lib3dsQuat q) -{ - printf("%f %f %f %f\n", q[0], q[1], q[2], q[3]); -} - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/quat.h b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/quat.h deleted file mode 100644 index 8ae0c7420..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/quat.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -*- c -*- */ -#ifndef INCLUDED_LIB3DS_QUAT_H -#define INCLUDED_LIB3DS_QUAT_H -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: quat.h,v 1.7 2007/06/14 09:59:10 jeh Exp $ - */ - -#ifndef INCLUDED_LIB3DS_TYPES_H -#include "types.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -extern LIB3DSAPI void lib3ds_quat_zero(Lib3dsQuat c); -extern LIB3DSAPI void lib3ds_quat_identity(Lib3dsQuat c); -extern LIB3DSAPI void lib3ds_quat_copy(Lib3dsQuat dest, Lib3dsQuat src); -extern LIB3DSAPI void lib3ds_quat_axis_angle(Lib3dsQuat c, Lib3dsVector axis, Lib3dsFloat angle); -extern LIB3DSAPI void lib3ds_quat_neg(Lib3dsQuat c); -extern LIB3DSAPI void lib3ds_quat_abs(Lib3dsQuat c); -extern LIB3DSAPI void lib3ds_quat_cnj(Lib3dsQuat c); -extern LIB3DSAPI void lib3ds_quat_mul(Lib3dsQuat c, Lib3dsQuat a, Lib3dsQuat b); -extern LIB3DSAPI void lib3ds_quat_scalar(Lib3dsQuat c, Lib3dsFloat k); -extern LIB3DSAPI void lib3ds_quat_normalize(Lib3dsQuat c); -extern LIB3DSAPI void lib3ds_quat_inv(Lib3dsQuat c); -extern LIB3DSAPI Lib3dsFloat lib3ds_quat_dot(Lib3dsQuat a, Lib3dsQuat b); -extern LIB3DSAPI Lib3dsFloat lib3ds_quat_squared(Lib3dsQuat c); -extern LIB3DSAPI Lib3dsFloat lib3ds_quat_length(Lib3dsQuat c); -extern LIB3DSAPI void lib3ds_quat_ln(Lib3dsQuat c); -extern LIB3DSAPI void lib3ds_quat_ln_dif(Lib3dsQuat c, Lib3dsQuat a, Lib3dsQuat b); -extern LIB3DSAPI void lib3ds_quat_exp(Lib3dsQuat c); -extern LIB3DSAPI void lib3ds_quat_slerp(Lib3dsQuat c, Lib3dsQuat a, Lib3dsQuat b, Lib3dsFloat t); -extern LIB3DSAPI void lib3ds_quat_squad(Lib3dsQuat c, Lib3dsQuat a, Lib3dsQuat p, Lib3dsQuat q, - Lib3dsQuat b, Lib3dsFloat t); -extern LIB3DSAPI void lib3ds_quat_tangent(Lib3dsQuat c, Lib3dsQuat p, Lib3dsQuat q, Lib3dsQuat n); -extern LIB3DSAPI void lib3ds_quat_dump(Lib3dsQuat q); - -#ifdef __cplusplus -} -#endif -#endif - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/shadow.c b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/shadow.c deleted file mode 100644 index 7820af8e9..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/shadow.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: shadow.c,v 1.11 2007/06/20 17:04:09 jeh Exp $ - */ -#include "shadow.h" -#include "chunk.h" -#include "io.h" -#include - - -/*! - * \defgroup shadow Shadow Map Settings - */ - - -/*! - * \ingroup shadow - */ -Lib3dsBool -lib3ds_shadow_read(Lib3dsShadow *shadow, Lib3dsIo *io) -{ - Lib3dsChunk c; - - if (!lib3ds_chunk_read(&c, io)) { - return(LIB3DS_FALSE); - } - - switch (c.chunk) { - case LIB3DS_SHADOW_MAP_SIZE: - { - shadow->map_size=lib3ds_io_read_intw(io); - } - break; - case LIB3DS_LO_SHADOW_BIAS: - { - shadow->lo_bias=lib3ds_io_read_float(io); - } - break; - case LIB3DS_HI_SHADOW_BIAS: - { - shadow->hi_bias=lib3ds_io_read_float(io); - } - break; - case LIB3DS_SHADOW_SAMPLES: - { - shadow->samples=lib3ds_io_read_intw(io); - } - break; - case LIB3DS_SHADOW_RANGE: - { - shadow->range=lib3ds_io_read_intd(io); - } - break; - case LIB3DS_SHADOW_FILTER: - { - shadow->filter=lib3ds_io_read_float(io); - } - break; - case LIB3DS_RAY_BIAS: - { - shadow->ray_bias=lib3ds_io_read_float(io); - } - break; - } - - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup shadow - */ -Lib3dsBool -lib3ds_shadow_write(Lib3dsShadow *shadow, Lib3dsIo *io) -{ - if (fabs(shadow->lo_bias)>LIB3DS_EPSILON) { /*---- LIB3DS_LO_SHADOW_BIAS ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_LO_SHADOW_BIAS; - c.size=10; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_float(io, shadow->lo_bias); - } - - if (fabs(shadow->hi_bias)>LIB3DS_EPSILON) { /*---- LIB3DS_HI_SHADOW_BIAS ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_HI_SHADOW_BIAS; - c.size=10; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_float(io, shadow->hi_bias); - } - - if (shadow->map_size) { /*---- LIB3DS_SHADOW_MAP_SIZE ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_SHADOW_MAP_SIZE; - c.size=8; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_intw(io, shadow->map_size); - } - - if (shadow->samples) { /*---- LIB3DS_SHADOW_SAMPLES ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_SHADOW_SAMPLES; - c.size=8; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_intw(io, shadow->samples); - } - - if (shadow->range) { /*---- LIB3DS_SHADOW_RANGE ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_SHADOW_RANGE; - c.size=10; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_intd(io, shadow->range); - } - - if (fabs(shadow->filter)>LIB3DS_EPSILON) { /*---- LIB3DS_SHADOW_FILTER ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_SHADOW_FILTER; - c.size=10; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_float(io, shadow->filter); - } - if (fabs(shadow->ray_bias)>LIB3DS_EPSILON) { /*---- LIB3DS_RAY_BIAS ----*/ - Lib3dsChunk c; - c.chunk=LIB3DS_RAY_BIAS; - c.size=10; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_float(io, shadow->ray_bias); - } - return(LIB3DS_TRUE); -} - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/shadow.h b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/shadow.h deleted file mode 100644 index 4f28c8d58..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/shadow.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- c -*- */ -#ifndef INCLUDED_LIB3DS_SHADOW_H -#define INCLUDED_LIB3DS_SHADOW_H -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: shadow.h,v 1.11 2007/06/20 17:04:09 jeh Exp $ - */ - -#ifndef INCLUDED_LIB3DS_TYPES_H -#include "types.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Shadow map settings - * \ingroup shadow - */ -struct Lib3dsShadow { - Lib3dsIntw map_size; - Lib3dsFloat lo_bias; - Lib3dsFloat hi_bias; - Lib3dsIntw samples; - Lib3dsIntd range; - Lib3dsFloat filter; - Lib3dsFloat ray_bias; -}; - -extern LIB3DSAPI Lib3dsBool lib3ds_shadow_read(Lib3dsShadow *shadow, Lib3dsIo *io); -extern LIB3DSAPI Lib3dsBool lib3ds_shadow_write(Lib3dsShadow *shadow, Lib3dsIo *io); - -#ifdef __cplusplus -} -#endif -#endif - - - - - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/tcb.c b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/tcb.c deleted file mode 100644 index 505c96d1c..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/tcb.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: tcb.c,v 1.11 2007/06/15 09:33:19 jeh Exp $ - */ -#include "tcb.h" -#include "io.h" -#include - - -/*! - * \defgroup tcb Tension/Continuity/Bias Splines - */ - - -/*! - * \ingroup tcb - */ -void -lib3ds_tcb(Lib3dsTcb *p, Lib3dsTcb *pc, Lib3dsTcb *c, Lib3dsTcb *nc, Lib3dsTcb *n, - Lib3dsFloat *ksm, Lib3dsFloat *ksp, Lib3dsFloat *kdm, Lib3dsFloat *kdp) -{ - Lib3dsFloat tm,cm,cp,bm,bp,tmcm,tmcp,cc; - Lib3dsFloat dt,fp,fn; - - if (!pc) { - pc=c; - } - if (!nc) { - nc=c; - } - - fp=fn=1.0f; - if (p&&n) { - dt=0.5f*(Lib3dsFloat)(pc->frame-p->frame+n->frame-nc->frame); - fp=((Lib3dsFloat)(pc->frame-p->frame))/dt; - fn=((Lib3dsFloat)(n->frame-nc->frame))/dt; - cc=(Lib3dsFloat)fabs(c->cont); - fp=fp+cc-cc*fp; - fn=fn+cc-cc*fn; - } - - cm=1.0f-c->cont; - tm=0.5f*(1.0f-c->tens); - cp=2.0f-cm; - bm=1.0f-c->bias; - bp=2.0f-bm; - tmcm=tm*cm; - tmcp=tm*cp; - *ksm=tmcm*bp*fp; - *ksp=tmcp*bm*fp; - *kdm=tmcp*bp*fn; - *kdp=tmcm*bm*fn; -} - - -/*! - * \ingroup tcb - */ -Lib3dsBool -lib3ds_tcb_read(Lib3dsTcb *tcb, Lib3dsIo *io) -{ - Lib3dsWord flags; - - tcb->frame=lib3ds_io_read_intd(io); - tcb->flags=flags=lib3ds_io_read_word(io); - if (flags&LIB3DS_USE_TENSION) { - tcb->tens=lib3ds_io_read_float(io); - } - if (flags&LIB3DS_USE_CONTINUITY) { - tcb->cont=lib3ds_io_read_float(io); - } - if (flags&LIB3DS_USE_BIAS) { - tcb->bias=lib3ds_io_read_float(io); - } - if (flags&LIB3DS_USE_EASE_TO) { - tcb->ease_to=lib3ds_io_read_float(io); - } - if (flags&LIB3DS_USE_EASE_FROM) { - tcb->ease_from=lib3ds_io_read_float(io); - } - if (lib3ds_io_error(io)) { - return(LIB3DS_FALSE); - } - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup tcb - */ -Lib3dsBool -lib3ds_tcb_write(Lib3dsTcb *tcb, Lib3dsIo *io) -{ - lib3ds_io_write_intd(io, tcb->frame); - lib3ds_io_write_word(io, tcb->flags); - if (tcb->flags&LIB3DS_USE_TENSION) { - lib3ds_io_write_float(io, tcb->tens); - } - if (tcb->flags&LIB3DS_USE_CONTINUITY) { - lib3ds_io_write_float(io, tcb->cont); - } - if (tcb->flags&LIB3DS_USE_BIAS) { - lib3ds_io_write_float(io, tcb->bias); - } - if (tcb->flags&LIB3DS_USE_EASE_TO) { - lib3ds_io_write_float(io, tcb->ease_to); - } - if (tcb->flags&LIB3DS_USE_EASE_FROM) { - lib3ds_io_write_float(io, tcb->ease_from); - } - if (lib3ds_io_error(io)) { - return(LIB3DS_FALSE); - } - return(LIB3DS_TRUE); -} - - - - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/tcb.h b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/tcb.h deleted file mode 100644 index d125bc4ad..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/tcb.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -*- c -*- */ -#ifndef INCLUDED_LIB3DS_TCB_H -#define INCLUDED_LIB3DS_TCB_H -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: tcb.h,v 1.11 2007/06/20 17:04:09 jeh Exp $ - */ - -#ifndef INCLUDED_LIB3DS_TYPES_H -#include "types.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum Lib3dsTcbFlags{ - LIB3DS_USE_TENSION =0x0001, - LIB3DS_USE_CONTINUITY =0x0002, - LIB3DS_USE_BIAS =0x0004, - LIB3DS_USE_EASE_TO =0x0008, - LIB3DS_USE_EASE_FROM =0x0010 -} Lib3dsTcbFlags; - -typedef struct Lib3dsTcb { - Lib3dsIntd frame; - Lib3dsWord flags; - Lib3dsFloat tens; - Lib3dsFloat cont; - Lib3dsFloat bias; - Lib3dsFloat ease_to; - Lib3dsFloat ease_from; -} Lib3dsTcb; - -extern LIB3DSAPI void lib3ds_tcb(Lib3dsTcb *p, Lib3dsTcb *pc, Lib3dsTcb *c, - Lib3dsTcb *nc, Lib3dsTcb *n, Lib3dsFloat *ksm, Lib3dsFloat *ksp, - Lib3dsFloat *kdm, Lib3dsFloat *kdp); -extern LIB3DSAPI Lib3dsBool lib3ds_tcb_read(Lib3dsTcb *tcb, Lib3dsIo *io); -extern LIB3DSAPI Lib3dsBool lib3ds_tcb_write(Lib3dsTcb *tcb, Lib3dsIo *io); - -#ifdef __cplusplus -} -#endif -#endif - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/tracks.c b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/tracks.c deleted file mode 100644 index 6fd083c12..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/tracks.c +++ /dev/null @@ -1,1552 +0,0 @@ -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: tracks.c,v 1.20 2007/06/15 09:33:19 jeh Exp $ - */ -#include "tracks.h" -#include "io.h" -#include "chunk.h" -#include "vector.h" -#include "quat.h" -#include "node.h" -#include -#include -#include - - -/*! - * \defgroup tracks Keyframing Tracks - */ - - -/*! - * \ingroup tracks - */ -Lib3dsBoolKey* -lib3ds_bool_key_new() -{ - Lib3dsBoolKey* k; - k=(Lib3dsBoolKey*)calloc(sizeof(Lib3dsBoolKey), 1); - return(k); -} - - -/*! - * \ingroup tracks - */ -void -lib3ds_bool_key_free(Lib3dsBoolKey *key) -{ - ASSERT(key); - free(key); -} - - -/*! - * \ingroup tracks - */ -void -lib3ds_bool_track_free_keys(Lib3dsBoolTrack *track) -{ - Lib3dsBoolKey *p,*q; - - ASSERT(track); - for (p=track->keyL; p; p=q) { - q=p->next; - lib3ds_bool_key_free(p); - } -} - - -/*! - * \ingroup tracks - */ -void -lib3ds_bool_track_insert(Lib3dsBoolTrack *track, Lib3dsBoolKey *key) -{ - ASSERT(track); - ASSERT(key); - ASSERT(!key->next); - - if (!track->keyL) { - track->keyL=key; - key->next=0; - } - else { - Lib3dsBoolKey *k,*p; - - for (p=0,k=track->keyL; k!=0; p=k, k=k->next) { - if (k->tcb.frame>key->tcb.frame) { - break; - } - } - if (!p) { - key->next=track->keyL; - track->keyL=key; - } - else { - key->next=k; - p->next=key; - } - - if (k && (key->tcb.frame==k->tcb.frame)) { - key->next=k->next; - lib3ds_bool_key_free(k); - } - } -} - - -/*! - * \ingroup tracks - */ -void -lib3ds_bool_track_remove(Lib3dsBoolTrack *track, Lib3dsIntd frame) -{ - Lib3dsBoolKey *k,*p; - - ASSERT(track); - if (!track->keyL) { - return; - } - for (p=0,k=track->keyL; k!=0; p=k, k=k->next) { - if (k->tcb.frame==frame) { - if (!p) { - track->keyL=track->keyL->next; - } - else { - p->next=k->next; - } - lib3ds_bool_key_free(k); - break; - } - } -} - - -/*! - * \ingroup tracks - */ -void -lib3ds_bool_track_eval(Lib3dsBoolTrack *track, Lib3dsBool *p, Lib3dsFloat t) -{ - Lib3dsBoolKey *k; - Lib3dsBool result; - - ASSERT(p); - if (!track->keyL) { - *p=LIB3DS_FALSE; - return; - } - if (!track->keyL->next) { - *p = LIB3DS_TRUE; - return; - } - - result=LIB3DS_FALSE; - k=track->keyL; - while ((t<(Lib3dsFloat)k->tcb.frame) && (t>=(Lib3dsFloat)k->next->tcb.frame)) { - if (result) { - result=LIB3DS_FALSE; - } - else { - result=LIB3DS_TRUE; - } - if (!k->next) { - if (track->flags&LIB3DS_REPEAT) { - t-=(Lib3dsFloat)k->tcb.frame; - k=track->keyL; - } - else { - break; - } - } - else { - k=k->next; - } - } - *p=result; -} - - -/*! - * \ingroup tracks - */ -Lib3dsBool -lib3ds_bool_track_read(Lib3dsBoolTrack *track, Lib3dsIo *io) -{ - int keys; - int i; - Lib3dsBoolKey *k; - - track->flags=lib3ds_io_read_word(io); - lib3ds_io_read_dword(io); - lib3ds_io_read_dword(io); - keys=lib3ds_io_read_intd(io); - - for (i=0; itcb, io)) { - return(LIB3DS_FALSE); - } - lib3ds_bool_track_insert(track, k); - } - - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup tracks - */ -Lib3dsBool -lib3ds_bool_track_write(Lib3dsBoolTrack *track, Lib3dsIo *io) -{ - Lib3dsBoolKey *k; - Lib3dsDword num=0; - for (k=track->keyL; k; k=k->next) { - ++num; - } - lib3ds_io_write_word(io, (Lib3dsWord)track->flags); - lib3ds_io_write_dword(io, 0); - lib3ds_io_write_dword(io, 0); - lib3ds_io_write_dword(io, num); - - for (k=track->keyL; k; k=k->next) { - if (!lib3ds_tcb_write(&k->tcb,io)) { - return(LIB3DS_FALSE); - } - } - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup tracks - */ -Lib3dsLin1Key* -lib3ds_lin1_key_new() -{ - Lib3dsLin1Key* k; - k=(Lib3dsLin1Key*)calloc(sizeof(Lib3dsLin1Key), 1); - return(k); -} - - -/*! - * \ingroup tracks - */ -void -lib3ds_lin1_key_free(Lib3dsLin1Key *key) -{ - ASSERT(key); - free(key); -} - - -/*! - * \ingroup tracks - */ -void -lib3ds_lin1_track_free_keys(Lib3dsLin1Track *track) -{ - Lib3dsLin1Key *p,*q; - - ASSERT(track); - for (p=track->keyL; p; p=q) { - q=p->next; - lib3ds_lin1_key_free(p); - } -} - - -/*! - * \ingroup tracks - */ -void -lib3ds_lin1_key_setup(Lib3dsLin1Key *p, Lib3dsLin1Key *cp, Lib3dsLin1Key *c, - Lib3dsLin1Key *cn, Lib3dsLin1Key *n) -{ - Lib3dsFloat np,nn; - Lib3dsFloat ksm,ksp,kdm,kdp; - - ASSERT(c); - if (!cp) { - cp=c; - } - if (!cn) { - cn=c; - } - if (!p && !n) { - c->ds=0; - c->dd=0; - return; - } - - if (n && p) { - lib3ds_tcb(&p->tcb, &cp->tcb, &c->tcb, &cn->tcb, &n->tcb, &ksm, &ksp, &kdm, &kdp); - np = c->value - p->value; - nn = n->value - c->value; - - c->ds=ksm*np + ksp*nn; - c->dd=kdm*np + kdp*nn; - } - else { - if (p) { - np = c->value - p->value; - c->ds = np; - c->dd = np; - } - if (n) { - nn = n->value - c->value; - c->ds = nn; - c->dd = nn; - } - } -} - - -/*! - * \ingroup tracks - */ -void -lib3ds_lin1_track_setup(Lib3dsLin1Track *track) -{ - Lib3dsLin1Key *pp,*pc,*pn,*pl; - - ASSERT(track); - pc=track->keyL; - if (!pc) { - return; - } - if (!pc->next) { - pc->ds=0; - pc->dd=0; - return; - } - - if (track->flags&LIB3DS_SMOOTH) { - for (pl=track->keyL; pl->next->next; pl=pl->next); - lib3ds_lin1_key_setup(pl, pl->next, pc, 0, pc->next); - } - else { - lib3ds_lin1_key_setup(0, 0, pc, 0, pc->next); - } - for (;;) { - pp=pc; - pc=pc->next; - pn=pc->next; - if (!pn) { - break; - } - lib3ds_lin1_key_setup(pp, 0, pc, 0, pn); - } - - if (track->flags&LIB3DS_SMOOTH) { - lib3ds_lin1_key_setup(pp, 0, pc, track->keyL, track->keyL->next); - } - else { - lib3ds_lin1_key_setup(pp, 0, pc, 0, 0); - } -} - - -/*! - * \ingroup tracks - */ -void -lib3ds_lin1_track_insert(Lib3dsLin1Track *track, Lib3dsLin1Key *key) -{ - ASSERT(track); - ASSERT(key); - ASSERT(!key->next); - - if (!track->keyL) { - track->keyL=key; - key->next=0; - } - else { - Lib3dsLin1Key *k,*p; - - for (p=0,k=track->keyL; k!=0; p=k, k=k->next) { - if (k->tcb.frame>key->tcb.frame) { - break; - } - } - if (!p) { - key->next=track->keyL; - track->keyL=key; - } - else { - key->next=k; - p->next=key; - } - - if (k && (key->tcb.frame==k->tcb.frame)) { - key->next=k->next; - lib3ds_lin1_key_free(k); - } - } -} - - -/*! - * \ingroup tracks - */ -void -lib3ds_lin1_track_remove(Lib3dsLin1Track *track, Lib3dsIntd frame) -{ - Lib3dsLin1Key *k,*p; - - ASSERT(track); - if (!track->keyL) { - return; - } - for (p=0,k=track->keyL; k!=0; p=k, k=k->next) { - if (k->tcb.frame==frame) { - if (!p) { - track->keyL=track->keyL->next; - } - else { - p->next=k->next; - } - lib3ds_lin1_key_free(k); - break; - } - } -} - - -static Lib3dsFloat -lib3ds_float_cubic(Lib3dsFloat a, Lib3dsFloat p, Lib3dsFloat q, Lib3dsFloat b, Lib3dsFloat t) -{ - Lib3dsDouble x,y,z,w; - - x=2*t*t*t - 3*t*t + 1; - y=-2*t*t*t + 3*t*t; - z=t*t*t - 2*t*t + t; - w=t*t*t - t*t; - return((Lib3dsFloat)(x*a + y*b + z*p + w*q)); -} - - -/*! - * \ingroup tracks - */ -void -lib3ds_lin1_track_eval(Lib3dsLin1Track *track, Lib3dsFloat *p, Lib3dsFloat t) -{ - Lib3dsLin1Key *k; - Lib3dsFloat nt; - Lib3dsFloat u; - - ASSERT(p); - if (!track->keyL) { - *p=0; - return; - } - if (!track->keyL->next || ((tkeyL->tcb.frame) && ((track->flags&LIB3DS_REPEAT) != 0))) { - *p = track->keyL->value; - return; - } - - for (k=track->keyL; k->next!=0; k=k->next) { - if ((t>=(Lib3dsFloat)k->tcb.frame) && (t<(Lib3dsFloat)k->next->tcb.frame)) { - break; - } - } - if (!k->next) { - if (track->flags&LIB3DS_REPEAT) { - nt=(Lib3dsFloat)fmod(t - track->keyL->tcb.frame, k->tcb.frame - track->keyL->tcb.frame) + track->keyL->tcb.frame; - for (k=track->keyL; k->next!=0; k=k->next) { - if ((nt>=(Lib3dsFloat)k->tcb.frame) && (nt<(Lib3dsFloat)k->next->tcb.frame)) { - break; - } - } - ASSERT(k->next); - } - else { - *p = k->value; - return; - } - } - else { - nt=t; - } - u=nt - (Lib3dsFloat)k->tcb.frame; - u/=(Lib3dsFloat)(k->next->tcb.frame - k->tcb.frame); - - *p = lib3ds_float_cubic( - k->value, - k->dd, - k->next->ds, - k->next->value, - u - ); -} - - -/*! - * \ingroup tracks - */ -Lib3dsBool -lib3ds_lin1_track_read(Lib3dsLin1Track *track, Lib3dsIo *io) -{ - int keys; - int i; - Lib3dsLin1Key *k; - - track->flags=lib3ds_io_read_word(io); - lib3ds_io_read_dword(io); - lib3ds_io_read_dword(io); - keys=lib3ds_io_read_intd(io); - - for (i=0; itcb, io)) { - return(LIB3DS_FALSE); - } - k->value=lib3ds_io_read_float(io); - lib3ds_lin1_track_insert(track, k); - } - lib3ds_lin1_track_setup(track); - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup tracks - */ -Lib3dsBool -lib3ds_lin1_track_write(Lib3dsLin1Track *track, Lib3dsIo *io) -{ - Lib3dsLin1Key *k; - Lib3dsDword num=0; - for (k=track->keyL; k; k=k->next) { - ++num; - } - lib3ds_io_write_word(io, (Lib3dsWord)track->flags); - lib3ds_io_write_dword(io, 0); - lib3ds_io_write_dword(io, 0); - lib3ds_io_write_dword(io, num); - - for (k=track->keyL; k; k=k->next) { - if (!lib3ds_tcb_write(&k->tcb,io)) { - return(LIB3DS_FALSE); - } - lib3ds_io_write_float(io, k->value); - } - return(LIB3DS_TRUE); -} - - -/*! - * Create and return one keyframe in a Lin3 track. All values are - * initialized to zero. - * - * \ingroup tracks - */ -Lib3dsLin3Key* -lib3ds_lin3_key_new() -{ - Lib3dsLin3Key* k; - k=(Lib3dsLin3Key*)calloc(sizeof(Lib3dsLin3Key), 1); - return(k); -} - - -/*! - * Free a Lin3 keyframe. - * - * \ingroup tracks - */ -void -lib3ds_lin3_key_free(Lib3dsLin3Key *key) -{ - ASSERT(key); - free(key); -} - - -/*! - * Free all keyframes in a Lin3 track. - * - * \ingroup tracks - */ -void -lib3ds_lin3_track_free_keys(Lib3dsLin3Track *track) -{ - Lib3dsLin3Key *p,*q; - - ASSERT(track); - for (p=track->keyL; p; p=q) { - q=p->next; - lib3ds_lin3_key_free(p); - } -} - - -/*! - * \ingroup tracks - */ -void -lib3ds_lin3_key_setup(Lib3dsLin3Key *p, Lib3dsLin3Key *cp, Lib3dsLin3Key *c, - Lib3dsLin3Key *cn, Lib3dsLin3Key *n) -{ - Lib3dsVector np,nn; - Lib3dsFloat ksm,ksp,kdm,kdp; - int i; - - ASSERT(c); - if (!cp) { - cp=c; - } - if (!cn) { - cn=c; - } - if (!p && !n) { - lib3ds_vector_zero(c->ds); - lib3ds_vector_zero(c->dd); - return; - } - - if (n && p) { - lib3ds_tcb(&p->tcb, &cp->tcb, &c->tcb, &cn->tcb, &n->tcb, &ksm, &ksp, &kdm, &kdp); - lib3ds_vector_sub(np, c->value, p->value); - lib3ds_vector_sub(nn, n->value, c->value); - - for(i=0; i<3; ++i) { - c->ds[i]=ksm*np[i] + ksp*nn[i]; - c->dd[i]=kdm*np[i] + kdp*nn[i]; - } - } - else { - if (p) { - lib3ds_vector_sub(np, c->value, p->value); - lib3ds_vector_copy(c->ds, np); - lib3ds_vector_copy(c->dd, np); - } - if (n) { - lib3ds_vector_sub(nn, n->value, c->value); - lib3ds_vector_copy(c->ds, nn); - lib3ds_vector_copy(c->dd, nn); - } - } -} - - -/*! - * \ingroup tracks - */ -void -lib3ds_lin3_track_setup(Lib3dsLin3Track *track) -{ - Lib3dsLin3Key *pp,*pc,*pn,*pl; - - ASSERT(track); - pc=track->keyL; - if (!pc) { - return; - } - if (!pc->next) { - lib3ds_vector_zero(pc->ds); - lib3ds_vector_zero(pc->dd); - return; - } - - if (track->flags&LIB3DS_SMOOTH) { - for (pl=track->keyL; pl->next->next; pl=pl->next); - lib3ds_lin3_key_setup(pl, pl->next, pc, 0, pc->next); - } - else { - lib3ds_lin3_key_setup(0, 0, pc, 0, pc->next); - } - for (;;) { - pp=pc; - pc=pc->next; - pn=pc->next; - if (!pn) { - break; - } - lib3ds_lin3_key_setup(pp, 0, pc, 0, pn); - } - - if (track->flags&LIB3DS_SMOOTH) { - lib3ds_lin3_key_setup(pp, 0, pc, track->keyL, track->keyL->next); - } - else { - lib3ds_lin3_key_setup(pp, 0, pc, 0, 0); - } -} - - -/*! - * \ingroup tracks - */ -void -lib3ds_lin3_track_insert(Lib3dsLin3Track *track, Lib3dsLin3Key *key) -{ - ASSERT(track); - ASSERT(key); - ASSERT(!key->next); - - if (!track->keyL) { - track->keyL=key; - key->next=0; - } - else { - Lib3dsLin3Key *k,*p; - - for (p=0,k=track->keyL; k!=0; p=k, k=k->next) { - if (k->tcb.frame>key->tcb.frame) { - break; - } - } - if (!p) { - key->next=track->keyL; - track->keyL=key; - } - else { - key->next=k; - p->next=key; - } - - if (k && (key->tcb.frame==k->tcb.frame)) { - key->next=k->next; - lib3ds_lin3_key_free(k); - } - } -} - - -/*! - * \ingroup tracks - */ -void -lib3ds_lin3_track_remove(Lib3dsLin3Track *track, Lib3dsIntd frame) -{ - Lib3dsLin3Key *k,*p; - - ASSERT(track); - if (!track->keyL) { - return; - } - for (p=0,k=track->keyL; k!=0; p=k, k=k->next) { - if (k->tcb.frame==frame) { - if (!p) { - track->keyL=track->keyL->next; - } - else { - p->next=k->next; - } - lib3ds_lin3_key_free(k); - break; - } - } -} - - -/*! - * \ingroup tracks - */ -void -lib3ds_lin3_track_eval(Lib3dsLin3Track *track, Lib3dsVector p, Lib3dsFloat t) -{ - Lib3dsLin3Key *k; - Lib3dsFloat nt; - Lib3dsFloat u; - - if (!track->keyL) { - lib3ds_vector_zero(p); - return; - } - if (!track->keyL->next || ((tkeyL->tcb.frame) && ((track->flags&LIB3DS_REPEAT) != 0))) { - lib3ds_vector_copy(p, track->keyL->value); - return; - } - - for (k=track->keyL; k->next!=0; k=k->next) { - if ((t>=(Lib3dsFloat)k->tcb.frame) && (t<(Lib3dsFloat)k->next->tcb.frame)) { - break; - } - } - if (!k->next) { - if (track->flags&LIB3DS_REPEAT) { - nt=(Lib3dsFloat)fmod(t - track->keyL->tcb.frame, k->tcb.frame - track->keyL->tcb.frame) + track->keyL->tcb.frame; - for (k=track->keyL; k->next!=0; k=k->next) { - if ((nt>=(Lib3dsFloat)k->tcb.frame) && (nt<(Lib3dsFloat)k->next->tcb.frame)) { - break; - } - } - ASSERT(k->next); - } - else { - lib3ds_vector_copy(p, k->value); - return; - } - } - else { - nt=t; - } - u=nt - (Lib3dsFloat)k->tcb.frame; - u/=(Lib3dsFloat)(k->next->tcb.frame - k->tcb.frame); - - lib3ds_vector_cubic( - p, - k->value, - k->dd, - k->next->ds, - k->next->value, - u - ); -} - - -/*! - * \ingroup tracks - */ -Lib3dsBool -lib3ds_lin3_track_read(Lib3dsLin3Track *track, Lib3dsIo *io) -{ - int keys; - int i,j; - Lib3dsLin3Key *k; - - track->flags=lib3ds_io_read_word(io); - lib3ds_io_read_dword(io); - lib3ds_io_read_dword(io); - keys=lib3ds_io_read_intd(io); - - for (i=0; itcb, io)) { - return(LIB3DS_FALSE); - } - for (j=0; j<3; ++j) { - k->value[j]=lib3ds_io_read_float(io); - } - lib3ds_lin3_track_insert(track, k); - } - lib3ds_lin3_track_setup(track); - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup tracks - */ -Lib3dsBool -lib3ds_lin3_track_write(Lib3dsLin3Track *track, Lib3dsIo *io) -{ - Lib3dsLin3Key *k; - Lib3dsDword num=0; - for (k=track->keyL; k; k=k->next) { - ++num; - } - lib3ds_io_write_word(io, (Lib3dsWord)track->flags); - lib3ds_io_write_dword(io, 0); - lib3ds_io_write_dword(io, 0); - lib3ds_io_write_dword(io, num); - - for (k=track->keyL; k; k=k->next) { - if (!lib3ds_tcb_write(&k->tcb,io)) { - return(LIB3DS_FALSE); - } - lib3ds_io_write_vector(io, k->value); - } - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup tracks - */ -Lib3dsQuatKey* -lib3ds_quat_key_new() -{ - Lib3dsQuatKey* k; - k=(Lib3dsQuatKey*)calloc(sizeof(Lib3dsQuatKey), 1); - return(k); -} - - -/*! - * \ingroup tracks - */ -void -lib3ds_quat_key_free(Lib3dsQuatKey *key) -{ - ASSERT(key); - free(key); -} - - -/*! - * \ingroup tracks - */ -void -lib3ds_quat_track_free_keys(Lib3dsQuatTrack *track) -{ - Lib3dsQuatKey *p,*q; - - ASSERT(track); - for (p=track->keyL; p; p=q) { - q=p->next; - lib3ds_quat_key_free(p); - } -} - - -/*! - * \ingroup tracks - */ -void -lib3ds_quat_key_setup(Lib3dsQuatKey *p, Lib3dsQuatKey *cp, Lib3dsQuatKey *c, - Lib3dsQuatKey *cn, Lib3dsQuatKey *n) -{ - Lib3dsFloat ksm,ksp,kdm,kdp; - Lib3dsQuat q,qp,qn,qa,qb; - int i; - - ASSERT(c); - if (!cp) { - cp=c; - } - if (!cn) { - cn=c; - } - if (!p || !n) { - lib3ds_quat_copy(c->ds, c->q); - lib3ds_quat_copy(c->dd, c->q); - return; - } - - if (p) { - if (p->angle>LIB3DS_TWOPI-LIB3DS_EPSILON) { - lib3ds_quat_axis_angle(qp, p->axis, 0.0f); - lib3ds_quat_ln(qp); - } - else { - lib3ds_quat_copy(q, p->q); - if (lib3ds_quat_dot(q,c->q)<0) lib3ds_quat_neg(q); - - lib3ds_quat_ln_dif(qp, q, c->q); - } - } - if (n) { - if (n->angle>LIB3DS_TWOPI-LIB3DS_EPSILON) { - lib3ds_quat_axis_angle(qn, n->axis, 0.0f); - lib3ds_quat_ln(qn); - } - else { - lib3ds_quat_copy(q, n->q); - if (lib3ds_quat_dot(q,c->q)<0) lib3ds_quat_neg(q); - lib3ds_quat_ln_dif(qn, c->q, q); - } - } - - if (n && p) { - lib3ds_tcb(&p->tcb, &cp->tcb, &c->tcb, &cn->tcb, &n->tcb, &ksm, &ksp, &kdm, &kdp); - for(i=0; i<4; i++) { - qa[i]=0.5f*(kdm*qp[i]+(kdp-1.f)*qn[i]); - qb[i]=0.5f*((1.f-ksm)*qp[i]-ksp*qn[i]); - } - lib3ds_quat_exp(qa); - lib3ds_quat_exp(qb); - - lib3ds_quat_mul(c->ds, c->q, qb); - lib3ds_quat_mul(c->dd, c->q, qa); - } - else { - if (p) { - lib3ds_quat_exp(qp); - lib3ds_quat_mul(c->ds, c->q, qp); - lib3ds_quat_mul(c->dd, c->q, qp); - } - if (n) { - lib3ds_quat_exp(qn); - lib3ds_quat_mul(c->ds, c->q, qn); - lib3ds_quat_mul(c->dd, c->q, qn); - } - } -} - - -/*! - * \ingroup tracks - */ -void -lib3ds_quat_track_setup(Lib3dsQuatTrack *track) -{ - Lib3dsQuatKey *pp,*pc,*pn,*pl; - Lib3dsQuat q; - - ASSERT(track); - for (pp=0,pc=track->keyL; pc; pp=pc,pc=pc->next) { - lib3ds_quat_axis_angle(q, pc->axis, pc->angle); - if (pp) { - lib3ds_quat_mul(pc->q, q, pp->q); - } - else { - lib3ds_quat_copy(pc->q, q); - } - } - - pc=track->keyL; - if (!pc) { - return; - } - if (!pc->next) { - lib3ds_quat_copy(pc->ds, pc->q); - lib3ds_quat_copy(pc->dd, pc->q); - return; - } - - if (track->flags&LIB3DS_SMOOTH) { - for (pl=track->keyL; pl->next->next; pl=pl->next); - lib3ds_quat_key_setup(pl, pl->next, pc, 0, pc->next); - } - else { - lib3ds_quat_key_setup(0, 0, pc, 0, pc->next); - } - for (;;) { - pp=pc; - pc=pc->next; - pn=pc->next; - if (!pn) { - break; - } - lib3ds_quat_key_setup(pp, 0, pc, 0, pn); - } - - if (track->flags&LIB3DS_SMOOTH) { - lib3ds_quat_key_setup(pp, 0, pc, track->keyL, track->keyL->next); - } - else { - lib3ds_quat_key_setup(pp, 0, pc, 0, 0); - } -} - - -/*! - * \ingroup tracks - */ -void -lib3ds_quat_track_insert(Lib3dsQuatTrack *track, Lib3dsQuatKey *key) -{ - ASSERT(track); - ASSERT(key); - ASSERT(!key->next); - - if (!track->keyL) { - track->keyL=key; - key->next=0; - } - else { - Lib3dsQuatKey *k,*p; - - for (p=0,k=track->keyL; k!=0; p=k, k=k->next) { - if (k->tcb.frame>key->tcb.frame) { - break; - } - } - if (!p) { - key->next=track->keyL; - track->keyL=key; - } - else { - key->next=k; - p->next=key; - } - - if (k && (key->tcb.frame==k->tcb.frame)) { - key->next=k->next; - lib3ds_quat_key_free(k); - } - } -} - - -/*! - * \ingroup tracks - */ -void -lib3ds_quat_track_remove(Lib3dsQuatTrack *track, Lib3dsIntd frame) -{ - Lib3dsQuatKey *k,*p; - - ASSERT(track); - if (!track->keyL) { - return; - } - for (p=0,k=track->keyL; k!=0; p=k, k=k->next) { - if (k->tcb.frame==frame) { - if (!p) { - track->keyL=track->keyL->next; - } - else { - p->next=k->next; - } - lib3ds_quat_key_free(k); - break; - } - } -} - - -/*! - * \ingroup tracks - */ -void -lib3ds_quat_track_eval(Lib3dsQuatTrack *track, Lib3dsQuat q, Lib3dsFloat t) -{ - Lib3dsQuatKey *k; - Lib3dsFloat nt; - Lib3dsFloat u; - - if (!track->keyL) { - lib3ds_quat_identity(q); - return; - } - if (!track->keyL->next || ((tkeyL->tcb.frame) && ((track->flags&LIB3DS_REPEAT) != 0))) { - lib3ds_quat_copy(q, track->keyL->q); - return; - } - - for (k=track->keyL; k->next!=0; k=k->next) { - if ((t>=k->tcb.frame) && (tnext->tcb.frame)) { - break; - } - } - if (!k->next) { - if (track->flags&LIB3DS_REPEAT) { - nt=(Lib3dsFloat)fmod(t - track->keyL->tcb.frame, k->tcb.frame - track->keyL->tcb.frame) + track->keyL->tcb.frame; - for (k=track->keyL; k->next!=0; k=k->next) { - if ((nt>=k->tcb.frame) && (ntnext->tcb.frame)) { - break; - } - } - ASSERT(k->next); - } - else { - lib3ds_quat_copy(q, k->q); - return; - } - } - else { - nt=t; - } - u=nt - k->tcb.frame; - u/=(k->next->tcb.frame - k->tcb.frame); - - lib3ds_quat_squad( - q, - k->q, - k->dd, - k->next->ds, - k->next->q, - u - ); -} - - -/*! - * \ingroup tracks - */ -Lib3dsBool -lib3ds_quat_track_read(Lib3dsQuatTrack *track, Lib3dsIo *io) -{ - int keys; - int i,j; - Lib3dsQuatKey *p,*k; - - track->flags=lib3ds_io_read_word(io); - lib3ds_io_read_dword(io); - lib3ds_io_read_dword(io); - keys=lib3ds_io_read_intd(io); - - for (p=0,i=0; itcb, io)) { - return(LIB3DS_FALSE); - } - k->angle=lib3ds_io_read_float(io); - for (j=0; j<3; ++j) { - k->axis[j]=lib3ds_io_read_float(io); - } - lib3ds_quat_track_insert(track, k); - } - lib3ds_quat_track_setup(track); - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup tracks - */ -Lib3dsBool -lib3ds_quat_track_write(Lib3dsQuatTrack *track, Lib3dsIo *io) -{ - Lib3dsQuatKey *k; - Lib3dsDword num=0; - for (k=track->keyL; k; k=k->next) { - ++num; - } - lib3ds_io_write_word(io, (Lib3dsWord)track->flags); - lib3ds_io_write_dword(io, 0); - lib3ds_io_write_dword(io, 0); - lib3ds_io_write_dword(io, num); - - for (k=track->keyL; k; k=k->next) { - if (!lib3ds_tcb_write(&k->tcb,io)) { - return(LIB3DS_FALSE); - } - lib3ds_io_write_float(io, k->angle); - lib3ds_io_write_vector(io, k->axis); - } - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup tracks - */ -Lib3dsMorphKey* -lib3ds_morph_key_new() -{ - Lib3dsMorphKey* k; - k=(Lib3dsMorphKey*)calloc(sizeof(Lib3dsMorphKey), 1); - return(k); -} - - -/*! - * \ingroup tracks - */ -void -lib3ds_morph_key_free(Lib3dsMorphKey *key) -{ - ASSERT(key); - free(key); -} - - -/*! - * \ingroup tracks - */ -void -lib3ds_morph_track_free_keys(Lib3dsMorphTrack *track) -{ - Lib3dsMorphKey *p,*q; - - ASSERT(track); - for (p=track->keyL; p; p=q) { - q=p->next; - lib3ds_morph_key_free(p); - } -} - - -/*! - * \ingroup tracks - */ -void -lib3ds_morph_track_insert(Lib3dsMorphTrack *track, Lib3dsMorphKey *key) -{ - ASSERT(track); - ASSERT(key); - ASSERT(!key->next); - - if (!track->keyL) { - track->keyL=key; - key->next=0; - } - else { - Lib3dsMorphKey *k,*p; - - for (p=0,k=track->keyL; k!=0; p=k, k=k->next) { - if (k->tcb.frame>key->tcb.frame) { - break; - } - } - if (!p) { - key->next=track->keyL; - track->keyL=key; - } - else { - key->next=k; - p->next=key; - } - - if (k && (key->tcb.frame==k->tcb.frame)) { - key->next=k->next; - lib3ds_morph_key_free(k); - } - } -} - - -/*! - * \ingroup tracks - */ -void -lib3ds_morph_track_remove(Lib3dsMorphTrack *track, Lib3dsIntd frame) -{ - Lib3dsMorphKey *k,*p; - - ASSERT(track); - if (!track->keyL) { - return; - } - for (p=0,k=track->keyL; k!=0; p=k, k=k->next) { - if (k->tcb.frame==frame) { - if (!p) { - track->keyL=track->keyL->next; - } - else { - p->next=k->next; - } - lib3ds_morph_key_free(k); - break; - } - } -} - - -/*! - * \ingroup tracks - */ -void -lib3ds_morph_track_eval(Lib3dsMorphTrack *track, char *p, Lib3dsFloat t) -{ - Lib3dsMorphKey *k; - char* result; - - ASSERT(p); - if (!track->keyL) { - strcpy(p,""); - return; - } - if (!track->keyL->next) { - strcpy(p,track->keyL->name); - return; - } - - - /* TODO: this function finds the mesh frame that corresponds to this - * timeframe. It would be better to actually interpolate the mesh. - */ - - result=0; - - for(k = track->keyL; - k->next != NULL && t >= k->next->tcb.frame; - k = k->next); - - result=k->name; - - if (result) { - strcpy(p,result); - } - else { - strcpy(p,""); - } -} - - -/*! - * \ingroup tracks - */ -Lib3dsBool -lib3ds_morph_track_read(Lib3dsMorphTrack *track, Lib3dsIo *io) -{ - /* This function was written by Stephane Denis on 5-18-04 */ - int i; - Lib3dsMorphKey *k, *pk; - int keys; - track->flags=lib3ds_io_read_word(io); - lib3ds_io_read_dword(io); - lib3ds_io_read_dword(io); - keys=lib3ds_io_read_intd(io); - - for (i=0; itcb, io)) { - return(LIB3DS_FALSE); - } - if (!lib3ds_io_read_string(io, k->name, 11)) { - return(LIB3DS_FALSE); - } - if (!track->keyL) - track->keyL = k; - else - pk->next = k; - pk = k; - } - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup tracks - */ -Lib3dsBool -lib3ds_morph_track_write(Lib3dsMorphTrack *track, Lib3dsIo *io) -{ - /* FIXME: */ - ASSERT(0); - return(LIB3DS_FALSE); -} - - - -void -tcb_dump(Lib3dsTcb *tcb) -{ - printf(" tcb: frame=%d, flags=%04x, tens=%g, cont=%g, ", - tcb->frame, tcb->flags, tcb->tens, tcb->cont); - printf("bias=%g, ease_to=%g, ease_from=%g\n", - tcb->bias, tcb->ease_to, tcb->ease_from); -} - - -void -lib3ds_boolTrack_dump(Lib3dsBoolTrack *track) -{ - Lib3dsBoolKey *key; - printf("flags: %08x, keys:\n", track->flags); - for( key = track->keyL; key != NULL; key = key->next) - { - tcb_dump(&key->tcb); - } -} - - -void -lib3ds_lin1Track_dump(Lib3dsLin1Track *track) -{ - Lib3dsLin1Key *key; - printf("flags: %08x, keys:\n", track->flags); - for( key = track->keyL; key != NULL; key = key->next) - { - tcb_dump(&key->tcb); - printf(" value = %g, dd=%g, ds=%g\n", - key->value, key->dd, key->ds); - } -} - - -void -lib3ds_lin3Track_dump(Lib3dsLin3Track *track) -{ - Lib3dsLin3Key *key; - printf("flags: %08x, keys:\n", track->flags); - for( key = track->keyL; key != NULL; key = key->next) - { - tcb_dump(&key->tcb); - printf(" value = %g,%g,%g, dd=%g,%g,%g, ds=%g,%g,%g\n", - key->value[0], key->value[1], key->value[2], - key->dd[0], key->dd[1], key->dd[2], - key->ds[0], key->ds[1], key->ds[2]); - } -} - - -void -lib3ds_quatTrack_dump(Lib3dsQuatTrack *track) -{ - Lib3dsQuatKey *key; - printf("flags: %08x, keys:\n", track->flags); - for( key = track->keyL; key != NULL; key = key->next) - { - tcb_dump(&key->tcb); - printf(" axis = %g,%g,%g, angle=%g, q=%g,%g,%g,%g\n", - key->axis[0], key->axis[1], key->axis[2], key->angle, - key->q[0], key->q[1], key->q[2], key->q[3]); - printf(" dd = %g,%g,%g,%g, ds=%g,%g,%g,%g\n", - key->dd[0], key->dd[1], key->dd[2], key->dd[3], - key->ds[0], key->ds[1], key->ds[2], key->ds[3]); - } -} - - -void -lib3ds_morphTrack_dump(Lib3dsMorphTrack *track) -{ - Lib3dsMorphKey *key; - printf("flags: %08x, keys:\n", track->flags); - for( key = track->keyL; key != NULL; key = key->next) - { - tcb_dump(&key->tcb); - printf(" name = %s\n", key->name); - } -} - - - -void -lib3ds_dump_tracks(Lib3dsNode *node) -{ - switch( node->type ) { - case LIB3DS_AMBIENT_NODE: - printf("ambient: "); - lib3ds_lin3Track_dump(&node->data.ambient.col_track); - break; - case LIB3DS_OBJECT_NODE: - printf("pos: "); - lib3ds_lin3Track_dump(&node->data.object.pos_track); - printf("rot: "); - lib3ds_quatTrack_dump(&node->data.object.rot_track); - printf("scl: "); - lib3ds_lin3Track_dump(&node->data.object.scl_track); - printf("morph: "); - lib3ds_morphTrack_dump(&node->data.object.morph_track); - printf("hide: "); - lib3ds_boolTrack_dump(&node->data.object.hide_track); - break; - case LIB3DS_CAMERA_NODE: - printf("pos: "); - lib3ds_lin3Track_dump(&node->data.camera.pos_track); - printf("fov: "); - lib3ds_lin1Track_dump(&node->data.camera.fov_track); - printf("roll: "); - lib3ds_lin1Track_dump(&node->data.camera.roll_track); - break; - case LIB3DS_TARGET_NODE: - printf("pos: "); - lib3ds_lin3Track_dump(&node->data.target.pos_track); - break; - case LIB3DS_LIGHT_NODE: - printf("pos: "); - lib3ds_lin3Track_dump(&node->data.light.pos_track); - printf("col: "); - lib3ds_lin3Track_dump(&node->data.light.col_track); - printf("hotspot: "); - lib3ds_lin1Track_dump(&node->data.light.hotspot_track); - printf("falloff: "); - lib3ds_lin1Track_dump(&node->data.light.falloff_track); - printf("roll: "); - lib3ds_lin1Track_dump(&node->data.light.roll_track); - break; - case LIB3DS_SPOT_NODE: - printf("pos: "); - lib3ds_lin3Track_dump(&node->data.spot.pos_track); - break; - } -} diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/tracks.h b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/tracks.h deleted file mode 100644 index a5be8f5cf..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/tracks.h +++ /dev/null @@ -1,209 +0,0 @@ -/* -*- c -*- */ -#ifndef INCLUDED_LIB3DS_TRACKS_H -#define INCLUDED_LIB3DS_TRACKS_H -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: tracks.h,v 1.11 2007/06/20 17:04:09 jeh Exp $ - */ - -#ifndef INCLUDED_LIB3DS_TCB_H -#include "tcb.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Track flags - * \ingroup tracks - */ -typedef enum { - LIB3DS_REPEAT =0x0001, - LIB3DS_SMOOTH =0x0002, - LIB3DS_LOCK_X =0x0008, - LIB3DS_LOCK_Y =0x0010, - LIB3DS_LOCK_Z =0x0020, - LIB3DS_UNLINK_X =0x0100, - LIB3DS_UNLINK_Y =0x0200, - LIB3DS_UNLINK_Z =0x0400 -} Lib3dsTrackFlags; - -/** - * Boolean track key - * \ingroup tracks - */ -struct Lib3dsBoolKey { - Lib3dsTcb tcb; - Lib3dsBoolKey *next; -}; - -/** - * Boolean track - * \ingroup tracks - */ -struct Lib3dsBoolTrack { - Lib3dsDword flags; - Lib3dsBoolKey *keyL; -}; - -/** - * Floating-point track key - * \ingroup tracks - */ -struct Lib3dsLin1Key { - Lib3dsTcb tcb; - Lib3dsLin1Key *next; - Lib3dsFloat value; - Lib3dsFloat dd; - Lib3dsFloat ds; -}; - -/** - * Floating-point track - * \ingroup tracks - */ -struct Lib3dsLin1Track { - Lib3dsDword flags; - Lib3dsLin1Key *keyL; -}; - -/** - * Vector track key - * \ingroup tracks - */ -struct Lib3dsLin3Key { - Lib3dsTcb tcb; - Lib3dsLin3Key *next; - Lib3dsVector value; - Lib3dsVector dd; - Lib3dsVector ds; -}; - -/** - * Vector track - * \ingroup tracks - */ -struct Lib3dsLin3Track { - Lib3dsDword flags; - Lib3dsLin3Key *keyL; -}; - -/** - * Rotation track key - * \ingroup tracks - */ -struct Lib3dsQuatKey { - Lib3dsTcb tcb; - Lib3dsQuatKey *next; - Lib3dsVector axis; - Lib3dsFloat angle; - Lib3dsQuat q; - Lib3dsQuat dd; - Lib3dsQuat ds; -}; - -/** - * Rotation track - * \ingroup tracks - */ -struct Lib3dsQuatTrack { - Lib3dsDword flags; - Lib3dsQuatKey *keyL; -}; - -/** - * Morph track key - * \ingroup tracks - */ -struct Lib3dsMorphKey { - Lib3dsTcb tcb; - Lib3dsMorphKey *next; - char name[64]; -}; - -/** - * Morph track - * \ingroup tracks - */ -struct Lib3dsMorphTrack { - Lib3dsDword flags; - Lib3dsMorphKey *keyL; -}; - -extern LIB3DSAPI Lib3dsBoolKey* lib3ds_bool_key_new(); -extern LIB3DSAPI void lib3ds_bool_key_free(Lib3dsBoolKey* key); -extern LIB3DSAPI void lib3ds_bool_track_free_keys(Lib3dsBoolTrack *track); -extern LIB3DSAPI void lib3ds_bool_track_insert(Lib3dsBoolTrack *track, Lib3dsBoolKey* key); -extern LIB3DSAPI void lib3ds_bool_track_remove(Lib3dsBoolTrack *track, Lib3dsIntd frame); -extern LIB3DSAPI void lib3ds_bool_track_eval(Lib3dsBoolTrack *track, Lib3dsBool *p, Lib3dsFloat t); -extern LIB3DSAPI Lib3dsBool lib3ds_bool_track_read(Lib3dsBoolTrack *track, Lib3dsIo *io); -extern LIB3DSAPI Lib3dsBool lib3ds_bool_track_write(Lib3dsBoolTrack *track, Lib3dsIo *io); - -extern LIB3DSAPI Lib3dsLin1Key* lib3ds_lin1_key_new(); -extern LIB3DSAPI void lib3ds_lin1_key_free(Lib3dsLin1Key* key); -extern LIB3DSAPI void lib3ds_lin1_track_free_keys(Lib3dsLin1Track *track); -extern LIB3DSAPI void lib3ds_lin1_key_setup(Lib3dsLin1Key *p, Lib3dsLin1Key *cp, Lib3dsLin1Key *c, - Lib3dsLin1Key *cn, Lib3dsLin1Key *n); -extern LIB3DSAPI void lib3ds_lin1_track_setup(Lib3dsLin1Track *track); -extern LIB3DSAPI void lib3ds_lin1_track_insert(Lib3dsLin1Track *track, Lib3dsLin1Key *key); -extern LIB3DSAPI void lib3ds_lin1_track_remove(Lib3dsLin1Track *track, Lib3dsIntd frame); -extern LIB3DSAPI void lib3ds_lin1_track_eval(Lib3dsLin1Track *track, Lib3dsFloat *p, Lib3dsFloat t); -extern LIB3DSAPI Lib3dsBool lib3ds_lin1_track_read(Lib3dsLin1Track *track, Lib3dsIo *io); -extern LIB3DSAPI Lib3dsBool lib3ds_lin1_track_write(Lib3dsLin1Track *track, Lib3dsIo *io); - -extern LIB3DSAPI Lib3dsLin3Key* lib3ds_lin3_key_new(); -extern LIB3DSAPI void lib3ds_lin3_key_free(Lib3dsLin3Key* key); -extern LIB3DSAPI void lib3ds_lin3_track_free_keys(Lib3dsLin3Track *track); -extern LIB3DSAPI void lib3ds_lin3_key_setup(Lib3dsLin3Key *p, Lib3dsLin3Key *cp, Lib3dsLin3Key *c, - Lib3dsLin3Key *cn, Lib3dsLin3Key *n); -extern LIB3DSAPI void lib3ds_lin3_track_setup(Lib3dsLin3Track *track); -extern LIB3DSAPI void lib3ds_lin3_track_insert(Lib3dsLin3Track *track, Lib3dsLin3Key *key); -extern LIB3DSAPI void lib3ds_lin3_track_remove(Lib3dsLin3Track *track, Lib3dsIntd frame); -extern LIB3DSAPI void lib3ds_lin3_track_eval(Lib3dsLin3Track *track, Lib3dsVector p, Lib3dsFloat t); -extern LIB3DSAPI Lib3dsBool lib3ds_lin3_track_read(Lib3dsLin3Track *track, Lib3dsIo *io); -extern LIB3DSAPI Lib3dsBool lib3ds_lin3_track_write(Lib3dsLin3Track *track, Lib3dsIo *io); - -extern LIB3DSAPI Lib3dsQuatKey* lib3ds_quat_key_new(); -extern LIB3DSAPI void lib3ds_quat_key_free(Lib3dsQuatKey* key); -extern LIB3DSAPI void lib3ds_quat_track_free_keys(Lib3dsQuatTrack *track); -extern LIB3DSAPI void lib3ds_quat_key_setup(Lib3dsQuatKey *p, Lib3dsQuatKey *cp, Lib3dsQuatKey *c, - Lib3dsQuatKey *cn, Lib3dsQuatKey *n); -extern LIB3DSAPI void lib3ds_quat_track_setup(Lib3dsQuatTrack *track); -extern LIB3DSAPI void lib3ds_quat_track_insert(Lib3dsQuatTrack *track, Lib3dsQuatKey *key); -extern LIB3DSAPI void lib3ds_quat_track_remove(Lib3dsQuatTrack *track, Lib3dsIntd frame); -extern LIB3DSAPI void lib3ds_quat_track_eval(Lib3dsQuatTrack *track, Lib3dsQuat p, Lib3dsFloat t); -extern LIB3DSAPI Lib3dsBool lib3ds_quat_track_read(Lib3dsQuatTrack *track, Lib3dsIo *io); -extern LIB3DSAPI Lib3dsBool lib3ds_quat_track_write(Lib3dsQuatTrack *track, Lib3dsIo *io); - -extern LIB3DSAPI Lib3dsMorphKey* lib3ds_morph_key_new(); -extern LIB3DSAPI void lib3ds_morph_key_free(Lib3dsMorphKey* key); -extern LIB3DSAPI void lib3ds_morph_track_free_keys(Lib3dsMorphTrack *track); -extern LIB3DSAPI void lib3ds_morph_track_insert(Lib3dsMorphTrack *track, Lib3dsMorphKey *key); -extern LIB3DSAPI void lib3ds_morph_track_remove(Lib3dsMorphTrack *track, Lib3dsIntd frame); -extern LIB3DSAPI void lib3ds_morph_track_eval(Lib3dsMorphTrack *track, char *p, Lib3dsFloat t); -extern LIB3DSAPI Lib3dsBool lib3ds_morph_track_read(Lib3dsMorphTrack *track, Lib3dsIo *io); -extern LIB3DSAPI Lib3dsBool lib3ds_morph_track_write(Lib3dsMorphTrack *track, Lib3dsIo *io); - -#ifdef __cplusplus -} -#endif -#endif - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/types.h b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/types.h deleted file mode 100644 index 1aedd337f..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/types.h +++ /dev/null @@ -1,155 +0,0 @@ -/* -*- c -*- */ -#ifndef INCLUDED_LIB3DS_TYPES_H -#define INCLUDED_LIB3DS_TYPES_H -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: types.h,v 1.25 2007/06/21 08:36:41 jeh Exp $ - */ -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef _MSC_VER -#ifdef LIB3DS_EXPORTS -#define LIB3DSAPI __declspec(dllexport) -#else -#define LIB3DSAPI __declspec(dllimport) -#endif -#else -#define LIB3DSAPI -#endif - -#define LIB3DS_TRUE 1 -#define LIB3DS_FALSE 0 - -#ifdef _MSC_VER -typedef __int32 Lib3dsBool; -typedef unsigned __int8 Lib3dsByte; -typedef unsigned __int16 Lib3dsWord; -typedef unsigned __int32 Lib3dsDword; -typedef signed __int8 Lib3dsIntb; -typedef signed __int16 Lib3dsIntw; -typedef signed __int16 Lib3dsIntd; -#else -#include -typedef int32_t Lib3dsBool; -typedef uint8_t Lib3dsByte; -typedef uint16_t Lib3dsWord; -typedef uint32_t Lib3dsDword; -typedef int8_t Lib3dsIntb; -typedef int16_t Lib3dsIntw; -typedef int32_t Lib3dsIntd; -#endif - -typedef float Lib3dsFloat; -typedef double Lib3dsDouble; - -typedef float Lib3dsVector[3]; -typedef float Lib3dsTexel[2]; -typedef float Lib3dsQuat[4]; -typedef float Lib3dsMatrix[4][4]; -typedef float Lib3dsRgb[3]; -typedef float Lib3dsRgba[4]; - -#define LIB3DS_EPSILON (1e-8) -#define LIB3DS_PI 3.14159265358979323846 -#define LIB3DS_TWOPI (2.0*LIB3DS_PI) -#define LIB3DS_HALFPI (LIB3DS_PI/2.0) -#define LIB3DS_RAD_TO_DEG(x) ((180.0/LIB3DS_PI)*(x)) -#define LIB3DS_DEG_TO_RAD(x) ((LIB3DS_PI/180.0)*(x)) - -#include - -#ifdef _DEBUG - #ifndef ASSERT - #include - #define ASSERT(__expr) assert(__expr) - #endif - #define LIB3DS_ERROR_LOG \ - {printf("\t***LIB3DS_ERROR_LOG*** %s : %d\n", __FILE__, __LINE__);} -#else - #ifndef ASSERT - #define ASSERT(__expr) - #endif - #define LIB3DS_ERROR_LOG -#endif - -typedef struct Lib3dsIo Lib3dsIo; -typedef struct Lib3dsFile Lib3dsFile; -typedef struct Lib3dsBackground Lib3dsBackground; -typedef struct Lib3dsAtmosphere Lib3dsAtmosphere; -typedef struct Lib3dsShadow Lib3dsShadow; -typedef struct Lib3dsViewport Lib3dsViewport; -typedef struct Lib3dsMaterial Lib3dsMaterial; -typedef struct Lib3dsFace Lib3dsFace; -typedef struct Lib3dsBoxMap Lib3dsBoxMap; -typedef struct Lib3dsMapData Lib3dsMapData; -typedef struct Lib3dsMesh Lib3dsMesh; -typedef struct Lib3dsCamera Lib3dsCamera; -typedef struct Lib3dsLight Lib3dsLight; -typedef struct Lib3dsBoolKey Lib3dsBoolKey; -typedef struct Lib3dsBoolTrack Lib3dsBoolTrack; -typedef struct Lib3dsLin1Key Lib3dsLin1Key; -typedef struct Lib3dsLin1Track Lib3dsLin1Track; -typedef struct Lib3dsLin3Key Lib3dsLin3Key; -typedef struct Lib3dsLin3Track Lib3dsLin3Track; -typedef struct Lib3dsQuatKey Lib3dsQuatKey; -typedef struct Lib3dsQuatTrack Lib3dsQuatTrack; -typedef struct Lib3dsMorphKey Lib3dsMorphKey; -typedef struct Lib3dsMorphTrack Lib3dsMorphTrack; - -typedef enum Lib3dsNodeTypes { - LIB3DS_UNKNOWN_NODE =0, - LIB3DS_AMBIENT_NODE =1, - LIB3DS_OBJECT_NODE =2, - LIB3DS_CAMERA_NODE =3, - LIB3DS_TARGET_NODE =4, - LIB3DS_LIGHT_NODE =5, - LIB3DS_SPOT_NODE =6 -} Lib3dsNodeTypes; - -typedef struct Lib3dsNode Lib3dsNode; - -typedef enum Lib3dsObjectFlags { - LIB3DS_OBJECT_HIDDEN =0x01, - LIB3DS_OBJECT_VIS_LOFTER =0x02, - LIB3DS_OBJECT_DOESNT_CAST =0x04, - LIB3DS_OBJECT_MATTE =0x08, - LIB3DS_OBJECT_DONT_RCVSHADOW =0x10, - LIB3DS_OBJECT_FAST =0x20, - LIB3DS_OBJECT_FROZEN =0x40 -} Lib3dsObjectFlags; - -typedef union Lib3dsUserData { - void *p; - Lib3dsIntd i; - Lib3dsDword d; - Lib3dsFloat f; - Lib3dsMaterial *material; - Lib3dsMesh *mesh; - Lib3dsCamera *camera; - Lib3dsLight *light; - Lib3dsNode *node; -} Lib3dsUserData; - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/vector.c b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/vector.c deleted file mode 100644 index 6490d5476..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/vector.c +++ /dev/null @@ -1,376 +0,0 @@ -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: vector.c,v 1.12 2007/06/20 17:04:09 jeh Exp $ - */ -#include "vector.h" -#include - - -/*! - * \defgroup vector Vector Mathematics - */ - - -/*! - * \typedef Lib3dsVector - * \ingroup vector - */ - - -/*! - * Clear a vector to zero. - * - * \param c Vector to clear. - * - * \ingroup vector - */ -void -lib3ds_vector_zero(Lib3dsVector c) -{ - int i; - for (i=0; i<3; ++i) { - c[i]=0.0f; - } -} - - -/*! - * Copy a vector. - * - * \param dest Destination vector. - * \param src Source vector. - * - * \ingroup vector - */ -void -lib3ds_vector_copy(Lib3dsVector dest, Lib3dsVector src) -{ - int i; - for (i=0; i<3; ++i) { - dest[i]=src[i]; - } -} - - -/*! - * Negate a vector. - * - * \param c Vector to negate. - * - * \ingroup vector - */ -void -lib3ds_vector_neg(Lib3dsVector c) -{ - int i; - for (i=0; i<3; ++i) { - c[i]=-c[i]; - } -} - - -/*! - * Add two vectors. - * - * \param c Result. - * \param a First addend. - * \param b Second addend. - * - * \ingroup vector - */ -void -lib3ds_vector_add(Lib3dsVector c, Lib3dsVector a, Lib3dsVector b) -{ - int i; - for (i=0; i<3; ++i) { - c[i]=a[i]+b[i]; - } -} - - -/*! - * Subtract two vectors. - * - * \param c Result. - * \param a Addend. - * \param b Minuend. - * - * \ingroup vector - */ -void -lib3ds_vector_sub(Lib3dsVector c, Lib3dsVector a, Lib3dsVector b) -{ - int i; - for (i=0; i<3; ++i) { - c[i]=a[i]-b[i]; - } -} - - -/*! - * Multiply a vector by a scalar. - * - * \param c Vector to be multiplied. - * \param k Scalar. - * - * \ingroup vector - */ -void -lib3ds_vector_scalar(Lib3dsVector c, Lib3dsFloat k) -{ - int i; - for (i=0; i<3; ++i) { - c[i]*=k; - } -} - - -/*! - * Compute cross product. - * - * \param c Result. - * \param a First vector. - * \param b Second vector. - * - * \ingroup vector - */ -void -lib3ds_vector_cross(Lib3dsVector c, Lib3dsVector a, Lib3dsVector b) -{ - c[0]=a[1]*b[2] - a[2]*b[1]; - c[1]=a[2]*b[0] - a[0]*b[2]; - c[2]=a[0]*b[1] - a[1]*b[0]; -} - - -/*! - * Compute dot product. - * - * \param a First vector. - * \param b Second vector. - * - * \return Dot product. - * - * \ingroup vector - */ -Lib3dsFloat -lib3ds_vector_dot(Lib3dsVector a, Lib3dsVector b) -{ - return(a[0]*b[0] + a[1]*b[1] + a[2]*b[2]); -} - - -/*! - * Compute square of vector. - * - * Computes x*x + y*y + z*z. - * - * \param c Vector to square. - * - * \return Square of vector. - * - * \ingroup vector - */ -Lib3dsFloat -lib3ds_vector_squared(Lib3dsVector c) -{ - return(c[0]*c[0] + c[1]*c[1] + c[2]*c[2]); -} - - -/*! - * Compute length of vector. - * - * Computes |c| = sqrt(x*x + y*y + z*z) - * - * \param c Vector to compute. - * - * \return Length of vector. - * - * \ingroup vector - */ -Lib3dsFloat -lib3ds_vector_length(Lib3dsVector c) -{ - return((Lib3dsFloat)sqrt(c[0]*c[0] + c[1]*c[1] + c[2]*c[2])); -} - - -/*! - * Normalize a vector. - * - * Scales a vector so that its length is 1.0. - * - * \param c Vector to normalize. - * - * \ingroup vector - */ -void -lib3ds_vector_normalize(Lib3dsVector c) -{ - Lib3dsFloat l,m; - - l=(Lib3dsFloat)sqrt(c[0]*c[0] + c[1]*c[1] + c[2]*c[2]); - if (fabs(l)=c[1]) && (c[0]>=c[2])) { - c[0]=1.0f; - c[1]=c[2]=0.0f; - } - else - if (c[1]>=c[2]) { - c[1]=1.0f; - c[0]=c[2]=0.0f; - } - else { - c[2]=1.0f; - c[0]=c[1]=0.0f; - } - } - else { - m=1.0f/l; - c[0]*=m; - c[1]*=m; - c[2]*=m; - } -} - - -/*! - * Compute a vector normal to two line segments. - * - * Computes the normal vector to the lines b-a and b-c. - * - * \param n Returned normal vector. - * \param a Endpoint of first line. - * \param b Base point of both lines. - * \param c Endpoint of second line. - * - * \ingroup vector - */ -void -lib3ds_vector_normal(Lib3dsVector n, Lib3dsVector a, Lib3dsVector b, Lib3dsVector c) -{ - Lib3dsVector p,q; - - lib3ds_vector_sub(p,c,b); - lib3ds_vector_sub(q,a,b); - lib3ds_vector_cross(n,p,q); - lib3ds_vector_normalize(n); -} - - -/*! - * Multiply a point by a transformation matrix. - * - * Applies the given transformation matrix to the given point. With some - * transformation matrices, a vector may also be transformed. - * - * \param c Result. - * \param m Transformation matrix. - * \param a Input point. - * - * \ingroup vector - */ -void -lib3ds_vector_transform(Lib3dsVector c, Lib3dsMatrix m, Lib3dsVector a) -{ - c[0]= m[0][0]*a[0] + m[1][0]*a[1] + m[2][0]*a[2] + m[3][0]; - c[1]= m[0][1]*a[0] + m[1][1]*a[1] + m[2][1]*a[2] + m[3][1]; - c[2]= m[0][2]*a[0] + m[1][2]*a[1] + m[2][2]*a[2] + m[3][2]; -} - - -/*! - * Compute a point on a cubic spline. - * - * Computes a point on a parametric Bezier spline. - * - * \param c Result. - * \param a First endpoint of the spline. - * \param p First tangent vector of the spline. - * \param q Second tangent vector of the spline. - * \param b Second endpoint of the spline. - * \param t Spline parameter [0. 1.] - * - * \ingroup vector - */ -void -lib3ds_vector_cubic(Lib3dsVector c, Lib3dsVector a, Lib3dsVector p, Lib3dsVector q, - Lib3dsVector b, Lib3dsFloat t) -{ - Lib3dsDouble x,y,z,w; - - x=2*t*t*t - 3*t*t + 1; - y=-2*t*t*t + 3*t*t; - z=t*t*t - 2*t*t + t; - w=t*t*t - t*t; - c[0]=(Lib3dsFloat)(x*a[0] + y*b[0] + z*p[0] + w*q[0]); - c[1]=(Lib3dsFloat)(x*a[1] + y*b[1] + z*p[1] + w*q[1]); - c[2]=(Lib3dsFloat)(x*a[2] + y*b[2] + z*p[2] + w*q[2]); -} - - -/*! - * c[i] = min(c[i], a[i]); - * - * Computes minimum values of x,y,z independently. - * - * \ingroup vector - */ -void -lib3ds_vector_min(Lib3dsVector c, Lib3dsVector a) -{ - int i; - for (i=0; i<3; ++i) { - if (a[i]c[i]) { - c[i] = a[i]; - } - } -} - - -/*! - * \ingroup vector - */ -void -lib3ds_vector_dump(Lib3dsVector c) -{ - fprintf(stderr, "%f %f %f\n", c[0], c[1], c[2]); -} - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/vector.h b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/vector.h deleted file mode 100644 index 87347e2c8..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/vector.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -*- c -*- */ -#ifndef INCLUDED_LIB3DS_VECTOR_H -#define INCLUDED_LIB3DS_VECTOR_H -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: vector.h,v 1.7 2007/06/14 09:59:10 jeh Exp $ - */ - -#ifndef INCLUDED_LIB3DS_TYPES_H -#include "types.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -extern LIB3DSAPI void lib3ds_vector_zero(Lib3dsVector c); -extern LIB3DSAPI void lib3ds_vector_copy(Lib3dsVector dest, Lib3dsVector src); -extern LIB3DSAPI void lib3ds_vector_neg(Lib3dsVector c); -extern LIB3DSAPI void lib3ds_vector_add(Lib3dsVector c, Lib3dsVector a, Lib3dsVector b); -extern LIB3DSAPI void lib3ds_vector_sub(Lib3dsVector c, Lib3dsVector a, Lib3dsVector b); -extern LIB3DSAPI void lib3ds_vector_scalar(Lib3dsVector c, Lib3dsFloat k); -extern LIB3DSAPI void lib3ds_vector_cross(Lib3dsVector c, Lib3dsVector a, Lib3dsVector b); -extern LIB3DSAPI Lib3dsFloat lib3ds_vector_dot(Lib3dsVector a, Lib3dsVector b); -extern LIB3DSAPI Lib3dsFloat lib3ds_vector_squared(Lib3dsVector c); -extern LIB3DSAPI Lib3dsFloat lib3ds_vector_length(Lib3dsVector c); -extern LIB3DSAPI void lib3ds_vector_normalize(Lib3dsVector c); -extern LIB3DSAPI void lib3ds_vector_normal(Lib3dsVector n, Lib3dsVector a, - Lib3dsVector b, Lib3dsVector c); -extern LIB3DSAPI void lib3ds_vector_transform(Lib3dsVector c, Lib3dsMatrix m, Lib3dsVector a); -extern LIB3DSAPI void lib3ds_vector_cubic(Lib3dsVector c, Lib3dsVector a, Lib3dsVector p, - Lib3dsVector q, Lib3dsVector b, Lib3dsFloat t); -extern LIB3DSAPI void lib3ds_vector_min(Lib3dsVector c, Lib3dsVector a); -extern LIB3DSAPI void lib3ds_vector_max(Lib3dsVector c, Lib3dsVector a); -extern LIB3DSAPI void lib3ds_vector_dump(Lib3dsVector c); - -#ifdef __cplusplus -} -#endif -#endif - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/viewport.c b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/viewport.c deleted file mode 100644 index be99af3a1..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/viewport.c +++ /dev/null @@ -1,413 +0,0 @@ -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: viewport.c,v 1.11 2007/06/20 17:04:09 jeh Exp $ - */ -#include "viewport.h" -#include "chunk.h" -#include "io.h" -#include -#include - - -/*! - * \defgroup viewport Viewport and default view settings - */ - - -/*! - * \ingroup viewport - */ -Lib3dsBool -lib3ds_viewport_read(Lib3dsViewport *viewport, Lib3dsIo *io) -{ - Lib3dsChunk c; - Lib3dsWord chunk; - - if (!lib3ds_chunk_read_start(&c, 0, io)) { - return(LIB3DS_FALSE); - } - - switch (c.chunk) { - case LIB3DS_VIEWPORT_LAYOUT: - { - int cur=0; - viewport->layout.style=lib3ds_io_read_word(io); - viewport->layout.active=lib3ds_io_read_intw(io); - lib3ds_io_read_intw(io); - viewport->layout.swap=lib3ds_io_read_intw(io); - lib3ds_io_read_intw(io); - viewport->layout.swap_prior=lib3ds_io_read_intw(io); - viewport->layout.swap_view=lib3ds_io_read_intw(io); - lib3ds_chunk_read_tell(&c, io); - while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) { - switch (chunk) { - case LIB3DS_VIEWPORT_SIZE: - { - viewport->layout.position[0]=lib3ds_io_read_word(io); - viewport->layout.position[1]=lib3ds_io_read_word(io); - viewport->layout.size[0]=lib3ds_io_read_word(io); - viewport->layout.size[1]=lib3ds_io_read_word(io); - } - break; - case LIB3DS_VIEWPORT_DATA_3: - { - lib3ds_viewport_set_views(viewport,cur+1); - lib3ds_io_read_intw(io); - viewport->layout.viewL[cur].axis_lock=lib3ds_io_read_word(io); - viewport->layout.viewL[cur].position[0]=lib3ds_io_read_intw(io); - viewport->layout.viewL[cur].position[1]=lib3ds_io_read_intw(io); - viewport->layout.viewL[cur].size[0]=lib3ds_io_read_intw(io); - viewport->layout.viewL[cur].size[1]=lib3ds_io_read_intw(io); - viewport->layout.viewL[cur].type=lib3ds_io_read_word(io); - viewport->layout.viewL[cur].zoom=lib3ds_io_read_float(io); - lib3ds_io_read_vector(io, viewport->layout.viewL[cur].center); - viewport->layout.viewL[cur].horiz_angle=lib3ds_io_read_float(io); - viewport->layout.viewL[cur].vert_angle=lib3ds_io_read_float(io); - lib3ds_io_read(io, viewport->layout.viewL[cur].camera, 11); - ++cur; - } - break; - case LIB3DS_VIEWPORT_DATA: - /* 3DS R2 & R3 chunk - unsupported */ - break; - default: - lib3ds_chunk_unknown(chunk); - } - } - } - break; - case LIB3DS_DEFAULT_VIEW: - { - memset(&viewport->default_view,0,sizeof(Lib3dsDefaultView)); - while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) { - switch (chunk) { - case LIB3DS_VIEW_TOP: - { - viewport->default_view.type=LIB3DS_VIEW_TYPE_TOP; - lib3ds_io_read_vector(io, viewport->default_view.position); - viewport->default_view.width=lib3ds_io_read_float(io); - } - break; - case LIB3DS_VIEW_BOTTOM: - { - viewport->default_view.type=LIB3DS_VIEW_TYPE_BOTTOM; - lib3ds_io_read_vector(io, viewport->default_view.position); - viewport->default_view.width=lib3ds_io_read_float(io); - } - break; - case LIB3DS_VIEW_LEFT: - { - viewport->default_view.type=LIB3DS_VIEW_TYPE_LEFT; - lib3ds_io_read_vector(io, viewport->default_view.position); - viewport->default_view.width=lib3ds_io_read_float(io); - } - break; - case LIB3DS_VIEW_RIGHT: - { - viewport->default_view.type=LIB3DS_VIEW_TYPE_RIGHT; - lib3ds_io_read_vector(io, viewport->default_view.position); - viewport->default_view.width=lib3ds_io_read_float(io); - } - break; - case LIB3DS_VIEW_FRONT: - { - viewport->default_view.type=LIB3DS_VIEW_TYPE_FRONT; - lib3ds_io_read_vector(io, viewport->default_view.position); - viewport->default_view.width=lib3ds_io_read_float(io); - } - break; - case LIB3DS_VIEW_BACK: - { - viewport->default_view.type=LIB3DS_VIEW_TYPE_BACK; - lib3ds_io_read_vector(io, viewport->default_view.position); - viewport->default_view.width=lib3ds_io_read_float(io); - } - break; - case LIB3DS_VIEW_USER: - { - viewport->default_view.type=LIB3DS_VIEW_TYPE_USER; - lib3ds_io_read_vector(io, viewport->default_view.position); - viewport->default_view.width=lib3ds_io_read_float(io); - viewport->default_view.horiz_angle=lib3ds_io_read_float(io); - viewport->default_view.vert_angle=lib3ds_io_read_float(io); - viewport->default_view.roll_angle=lib3ds_io_read_float(io); - } - break; - case LIB3DS_VIEW_CAMERA: - { - viewport->default_view.type=LIB3DS_VIEW_TYPE_CAMERA; - lib3ds_io_read(io, viewport->default_view.camera, 11); - } - break; - default: - lib3ds_chunk_unknown(chunk); - } - } - } - break; - } - - lib3ds_chunk_read_end(&c, io); - return(LIB3DS_TRUE); -} - - -/*! - * \ingroup viewport - */ -void -lib3ds_viewport_set_views(Lib3dsViewport *viewport, Lib3dsDword views) -{ - ASSERT(viewport); - if (viewport->layout.views) { - if (views) { - viewport->layout.views=views; - viewport->layout.viewL=(Lib3dsView*)realloc(viewport->layout.viewL, sizeof(Lib3dsView)*views); - } - else { - free(viewport->layout.viewL); - viewport->layout.views=0; - viewport->layout.viewL=0; - } - } - else { - if (views) { - viewport->layout.views=views; - viewport->layout.viewL=(Lib3dsView*)calloc(sizeof(Lib3dsView),views); - } - } -} - - -/*! - * \ingroup viewport - */ -Lib3dsBool -lib3ds_viewport_write(Lib3dsViewport *viewport, Lib3dsIo *io) -{ - if (viewport->layout.views) { - Lib3dsChunk c; - unsigned i; - - c.chunk=LIB3DS_VIEWPORT_LAYOUT; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - - lib3ds_io_write_word(io, viewport->layout.style); - lib3ds_io_write_intw(io, viewport->layout.active); - lib3ds_io_write_intw(io, 0); - lib3ds_io_write_intw(io, viewport->layout.swap); - lib3ds_io_write_intw(io, 0); - lib3ds_io_write_intw(io, viewport->layout.swap_prior); - lib3ds_io_write_intw(io, viewport->layout.swap_view); - - { - Lib3dsChunk c; - c.chunk=LIB3DS_VIEWPORT_SIZE; - c.size=14; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_intw(io, viewport->layout.position[0]); - lib3ds_io_write_intw(io, viewport->layout.position[1]); - lib3ds_io_write_intw(io, viewport->layout.size[0]); - lib3ds_io_write_intw(io, viewport->layout.size[1]); - } - - for (i=0; ilayout.views; ++i) { - Lib3dsChunk c; - c.chunk=LIB3DS_VIEWPORT_DATA_3; - c.size=55; - lib3ds_chunk_write(&c,io); - - lib3ds_io_write_intw(io, 0); - lib3ds_io_write_word(io, viewport->layout.viewL[i].axis_lock); - lib3ds_io_write_intw(io, viewport->layout.viewL[i].position[0]); - lib3ds_io_write_intw(io, viewport->layout.viewL[i].position[1]); - lib3ds_io_write_intw(io, viewport->layout.viewL[i].size[0]); - lib3ds_io_write_intw(io, viewport->layout.viewL[i].size[1]); - lib3ds_io_write_word(io, viewport->layout.viewL[i].type); - lib3ds_io_write_float(io, viewport->layout.viewL[i].zoom); - lib3ds_io_write_vector(io, viewport->layout.viewL[i].center); - lib3ds_io_write_float(io, viewport->layout.viewL[i].horiz_angle); - lib3ds_io_write_float(io, viewport->layout.viewL[i].vert_angle); - lib3ds_io_write(io, viewport->layout.viewL[i].camera,11); - } - - if (!lib3ds_chunk_write_end(&c,io)) { - return(LIB3DS_FALSE); - } - } - - if (viewport->default_view.type) { - Lib3dsChunk c; - - c.chunk=LIB3DS_DEFAULT_VIEW; - if (!lib3ds_chunk_write_start(&c,io)) { - return(LIB3DS_FALSE); - } - - switch (viewport->default_view.type) { - case LIB3DS_VIEW_TYPE_TOP: - { - Lib3dsChunk c; - c.chunk=LIB3DS_VIEW_TOP; - c.size=22; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_vector(io, viewport->default_view.position); - lib3ds_io_write_float(io, viewport->default_view.width); - } - break; - case LIB3DS_VIEW_TYPE_BOTTOM: - { - Lib3dsChunk c; - c.chunk=LIB3DS_VIEW_BOTTOM; - c.size=22; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_vector(io, viewport->default_view.position); - lib3ds_io_write_float(io, viewport->default_view.width); - } - break; - case LIB3DS_VIEW_TYPE_LEFT: - { - Lib3dsChunk c; - c.chunk=LIB3DS_VIEW_LEFT; - c.size=22; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_vector(io, viewport->default_view.position); - lib3ds_io_write_float(io, viewport->default_view.width); - } - break; - case LIB3DS_VIEW_TYPE_RIGHT: - { - Lib3dsChunk c; - c.chunk=LIB3DS_VIEW_RIGHT; - c.size=22; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_vector(io, viewport->default_view.position); - lib3ds_io_write_float(io, viewport->default_view.width); - } - break; - case LIB3DS_VIEW_TYPE_FRONT: - { - Lib3dsChunk c; - c.chunk=LIB3DS_VIEW_FRONT; - c.size=22; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_vector(io, viewport->default_view.position); - lib3ds_io_write_float(io, viewport->default_view.width); - } - break; - case LIB3DS_VIEW_TYPE_BACK: - { - Lib3dsChunk c; - c.chunk=LIB3DS_VIEW_BACK; - c.size=22; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_vector(io, viewport->default_view.position); - lib3ds_io_write_float(io, viewport->default_view.width); - } - break; - case LIB3DS_VIEW_TYPE_USER: - { - Lib3dsChunk c; - c.chunk=LIB3DS_VIEW_USER; - c.size=34; - lib3ds_chunk_write(&c,io); - lib3ds_io_write_vector(io, viewport->default_view.position); - lib3ds_io_write_float(io, viewport->default_view.width); - lib3ds_io_write_float(io, viewport->default_view.horiz_angle); - lib3ds_io_write_float(io, viewport->default_view.vert_angle); - lib3ds_io_write_float(io, viewport->default_view.roll_angle); - } - break; - case LIB3DS_VIEW_TYPE_CAMERA: - { - Lib3dsChunk c; - c.chunk=LIB3DS_VIEW_CAMERA; - c.size=17; - lib3ds_chunk_write(&c, io); - lib3ds_io_write(io, viewport->default_view.camera, 11); - } - break; - } - - if (!lib3ds_chunk_write_end(&c, io)) { - return(LIB3DS_FALSE); - } - } - return(LIB3DS_TRUE); -} - - -/*! - * Dump viewport. - * - * \param vp The viewport to be dumped. - * - * \ingroup node - */ -void -lib3ds_viewport_dump(Lib3dsViewport *vp) -{ - Lib3dsView *view; - unsigned i; - ASSERT(vp); - - printf(" viewport:\n"); - printf(" layout:\n"); - printf(" style: %d\n", vp->layout.style); - printf(" active: %d\n", vp->layout.active); - printf(" swap: %d\n", vp->layout.swap); - printf(" swap_prior: %d\n", vp->layout.swap_prior); - printf(" position: %d,%d\n", - vp->layout.position[0], vp->layout.position[1]); - printf(" size: %d,%d\n", vp->layout.size[0], vp->layout.size[1]); - printf(" views: %ld\n", vp->layout.views); - if (vp->layout.views > 0 && vp->layout.viewL != NULL) { - for(i=0, view=vp->layout.viewL; i < vp->layout.views; ++i, ++view) { - printf(" view %d:\n", i); - printf(" type: %d\n", view->type); - printf(" axis_lock: %d\n", view->axis_lock); - printf(" position: (%d,%d)\n", - view->position[0], view->position[1]); - printf(" size: (%d,%d)\n", view->size[0], view->size[1]); - printf(" zoom: %g\n", view->zoom); - printf(" center: (%g,%g,%g)\n", - view->center[0], view->center[1], view->center[2]); - printf(" horiz_angle: %g\n", view->horiz_angle); - printf(" vert_angle: %g\n", view->vert_angle); - printf(" camera: %s\n", view->camera); - } - } - - printf(" default_view:\n"); - printf(" type: %d\n", vp->default_view.type); - printf(" position: (%g,%g,%g)\n", - vp->default_view.position[0], - vp->default_view.position[1], - vp->default_view.position[2]); - printf(" width: %g\n", vp->default_view.width); - printf(" horiz_angle: %g\n", vp->default_view.horiz_angle); - printf(" vert_angle: %g\n", vp->default_view.vert_angle); - printf(" roll_angle: %g\n", vp->default_view.roll_angle); - printf(" camera: %s\n", vp->default_view.camera); -} - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/viewport.h b/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/viewport.h deleted file mode 100644 index f1de433a0..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/lib3ds/viewport.h +++ /dev/null @@ -1,137 +0,0 @@ -/* -*- c -*- */ -#ifndef INCLUDED_LIB3DS_VIEWPORT_H -#define INCLUDED_LIB3DS_VIEWPORT_H -/* - * The 3D Studio File Format Library - * Copyright (C) 1996-2007 by Jan Eric Kyprianidis - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: viewport.h,v 1.8 2007/06/20 17:04:09 jeh Exp $ - */ - -#ifndef INCLUDED_LIB3DS_TYPES_H -#include "types.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Layout view types - * \ingroup viewport - */ -typedef enum Lib3dsViewType { - LIB3DS_VIEW_TYPE_NOT_USED =0, - LIB3DS_VIEW_TYPE_TOP =1, - LIB3DS_VIEW_TYPE_BOTTOM =2, - LIB3DS_VIEW_TYPE_LEFT =3, - LIB3DS_VIEW_TYPE_RIGHT =4, - LIB3DS_VIEW_TYPE_FRONT =5, - LIB3DS_VIEW_TYPE_BACK =6, - LIB3DS_VIEW_TYPE_USER =7, - LIB3DS_VIEW_TYPE_SPOTLIGHT =18, - LIB3DS_VIEW_TYPE_CAMERA =65535 -} Lib3dsViewType; - -/** - * Layout view settings - * \ingroup viewport - */ -typedef struct Lib3dsView { - Lib3dsWord type; - Lib3dsWord axis_lock; - Lib3dsIntw position[2]; - Lib3dsIntw size[2]; - Lib3dsFloat zoom; - Lib3dsVector center; - Lib3dsFloat horiz_angle; - Lib3dsFloat vert_angle; - char camera[11]; -} Lib3dsView; - -/** - * Layout styles - * \ingroup viewport - */ -typedef enum Lib3dsLayoutStyle { - LIB3DS_LAYOUT_SINGLE =0, - LIB3DS_LAYOUT_TWO_PANE_VERT_SPLIT =1, - LIB3DS_LAYOUT_TWO_PANE_HORIZ_SPLIT =2, - LIB3DS_LAYOUT_FOUR_PANE =3, - LIB3DS_LAYOUT_THREE_PANE_LEFT_SPLIT =4, - LIB3DS_LAYOUT_THREE_PANE_BOTTOM_SPLIT =5, - LIB3DS_LAYOUT_THREE_PANE_RIGHT_SPLIT =6, - LIB3DS_LAYOUT_THREE_PANE_TOP_SPLIT =7, - LIB3DS_LAYOUT_THREE_PANE_VERT_SPLIT =8, - LIB3DS_LAYOUT_THREE_PANE_HORIZ_SPLIT =9, - LIB3DS_LAYOUT_FOUR_PANE_LEFT_SPLIT =10, - LIB3DS_LAYOUT_FOUR_PANE_RIGHT_SPLIT =11 -} Lib3dsLayoutStyle; - -/** - * Viewport layout settings - * \ingroup viewport - */ -typedef struct Lib3dsLayout { - Lib3dsWord style; - Lib3dsIntw active; - Lib3dsIntw swap; - Lib3dsIntw swap_prior; - Lib3dsIntw swap_view; - Lib3dsWord position[2]; - Lib3dsWord size[2]; - Lib3dsDword views; - Lib3dsView *viewL; -} Lib3dsLayout; - -/** - * Default view settings - * \ingroup viewport - */ -typedef struct Lib3dsDefaultView { - Lib3dsWord type; - Lib3dsVector position; - Lib3dsFloat width; - Lib3dsFloat horiz_angle; - Lib3dsFloat vert_angle; - Lib3dsFloat roll_angle; - char camera[64]; -} Lib3dsDefaultView; - -/** - * Viewport and default view settings - * \ingroup viewport - */ -struct Lib3dsViewport { - Lib3dsLayout layout; - Lib3dsDefaultView default_view; -}; - -extern LIB3DSAPI Lib3dsBool lib3ds_viewport_read(Lib3dsViewport *viewport, Lib3dsIo *io); -extern LIB3DSAPI void lib3ds_viewport_set_views(Lib3dsViewport *viewport, Lib3dsDword views); -extern LIB3DSAPI Lib3dsBool lib3ds_viewport_write(Lib3dsViewport *viewport, Lib3dsIo *io); -extern LIB3DSAPI void lib3ds_viewport_dump(Lib3dsViewport *viewport); - -#ifdef __cplusplus -} -#endif -#endif - - - - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/quazip/crypt.h b/ground/gcs/src/libs/glc_lib/3rdparty/quazip/crypt.h deleted file mode 100644 index b6ff9e319..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/quazip/crypt.h +++ /dev/null @@ -1,133 +0,0 @@ -/* crypt.h -- base code for crypt/uncrypt ZIPfile - - - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant - - This code is a modified version of crypting code in Infozip distribution - - The encryption/decryption parts of this source code (as opposed to the - non-echoing password parts) were originally written in Europe. The - whole source package can be freely distributed, including from the USA. - (Prior to January 2000, re-export from the US was a violation of US law.) - - This encryption code is a direct transcription of the algorithm from - Roger Schlafly, described by Phil Katz in the file appnote.txt. This - file (appnote.txt) is distributed with the PKZIP program (even in the - version without encryption capabilities). - - If you don't need crypting in your application, just define symbols - NOCRYPT and NOUNCRYPT. - - This code support the "Traditional PKWARE Encryption". - - The new AES encryption added on Zip format by Winzip (see the page - http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong - Encryption is not supported. -*/ - -#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) - -/*********************************************************************** - * Return the next byte in the pseudo-random sequence - */ -static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab) -{ - //(void) pcrc_32_tab; /* avoid "unused parameter" warning */ - unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an - * unpredictable manner on 16-bit systems; not a problem - * with any known compiler so far, though */ - - temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2; - return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); -} - -/*********************************************************************** - * Update the encryption keys with the next byte of plain text - */ -static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c) -{ - (*(pkeys+0)) = CRC32((*(pkeys+0)), c); - (*(pkeys+1)) += (*(pkeys+0)) & 0xff; - (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; - { - register int keyshift = (int)((*(pkeys+1)) >> 24); - (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift); - } - return c; -} - - -/*********************************************************************** - * Initialize the encryption keys and the random header according to - * the given password. - */ -static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab) -{ - *(pkeys+0) = 305419896L; - *(pkeys+1) = 591751049L; - *(pkeys+2) = 878082192L; - while (*passwd != '\0') { - update_keys(pkeys,pcrc_32_tab,(int)*passwd); - passwd++; - } -} - -#define zdecode(pkeys,pcrc_32_tab,c) \ - (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) - -#define zencode(pkeys,pcrc_32_tab,c,t) \ - (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) - -#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED - -#define RAND_HEAD_LEN 12 - /* "last resort" source for second part of crypt seed pattern */ -# ifndef ZCR_SEED2 -# define ZCR_SEED2 3141592654UL /* use PI as default pattern */ -# endif - -static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting) - const char *passwd; /* password string */ - unsigned char *buf; /* where to write header */ - int bufSize; - unsigned long* pkeys; - const unsigned long* pcrc_32_tab; - unsigned long crcForCrypting; -{ - int n; /* index in random header */ - int t; /* temporary */ - int c; /* random byte */ - unsigned char header[RAND_HEAD_LEN-2]; /* random header */ - static unsigned calls = 0; /* ensure different random header each time */ - - if (bufSize> 7) & 0xff; - header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); - } - /* Encrypt random header (last two bytes is high word of crc) */ - init_keys(passwd, pkeys, pcrc_32_tab); - for (n = 0; n < RAND_HEAD_LEN-2; n++) - { - buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); - } - buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); - buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); - return n; -} - -#endif diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/quazip/ioapi.c b/ground/gcs/src/libs/glc_lib/3rdparty/quazip/ioapi.c deleted file mode 100644 index 22d3ddecd..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/quazip/ioapi.c +++ /dev/null @@ -1,184 +0,0 @@ -/* ioapi.c -- IO base function header for compress/uncompress .zip - files using zlib + zip or unzip API - - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant -*/ - -#include -#include -#include - -#include "zlib.h" -#include "ioapi.h" - - - -/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ - -#ifndef SEEK_CUR -#define SEEK_CUR 1 -#endif - -#ifndef SEEK_END -#define SEEK_END 2 -#endif - -#ifndef SEEK_SET -#define SEEK_SET 0 -#endif - -voidpf ZCALLBACK fopen_file_func OF(( - voidpf opaque, - const char* filename, - int mode)); - -uLong ZCALLBACK fread_file_func OF(( - voidpf opaque, - voidpf stream, - void* buf, - uLong size)); - -uLong ZCALLBACK fwrite_file_func OF(( - voidpf opaque, - voidpf stream, - const void* buf, - uLong size)); - -long ZCALLBACK ftell_file_func OF(( - voidpf opaque, - voidpf stream)); - -long ZCALLBACK fseek_file_func OF(( - voidpf opaque, - voidpf stream, - uLong offset, - int origin)); - -int ZCALLBACK fclose_file_func OF(( - voidpf opaque, - voidpf stream)); - -int ZCALLBACK ferror_file_func OF(( - voidpf opaque, - voidpf stream)); - - -voidpf ZCALLBACK fopen_file_func (opaque, filename, mode) - voidpf opaque; - const char* filename; - int mode; -{ - //(void) opaque; /* avoid "unused parameter" warning */ - FILE* file = NULL; - const char* mode_fopen = NULL; - if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) - mode_fopen = "rb"; - else - if (mode & ZLIB_FILEFUNC_MODE_EXISTING) - mode_fopen = "r+b"; - else - if (mode & ZLIB_FILEFUNC_MODE_CREATE) - mode_fopen = "wb"; - - if ((filename!=NULL) && (mode_fopen != NULL)) - file = fopen(filename, mode_fopen); - return file; -} - - -uLong ZCALLBACK fread_file_func (opaque, stream, buf, size) - voidpf opaque; - voidpf stream; - void* buf; - uLong size; -{ - //(void) opaque; /* avoid "unused parameter" warning */ - uLong ret; - ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); - return ret; -} - - -uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size) - voidpf opaque; - voidpf stream; - const void* buf; - uLong size; -{ - //(void) opaque; /* avoid "unused parameter" warning */ - uLong ret; - ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); - return ret; -} - -long ZCALLBACK ftell_file_func (opaque, stream) - voidpf opaque; - voidpf stream; -{ - //(void) opaque; /* avoid "unused parameter" warning */ - long ret; - ret = ftell((FILE *)stream); - return ret; -} - -long ZCALLBACK fseek_file_func (opaque, stream, offset, origin) - voidpf opaque; - voidpf stream; - uLong offset; - int origin; -{ - //(void) opaque; /* avoid "unused parameter" warning */ - int fseek_origin=0; - long ret; - switch (origin) - { - case ZLIB_FILEFUNC_SEEK_CUR : - fseek_origin = SEEK_CUR; - break; - case ZLIB_FILEFUNC_SEEK_END : - fseek_origin = SEEK_END; - break; - case ZLIB_FILEFUNC_SEEK_SET : - fseek_origin = SEEK_SET; - break; - default: return -1; - } - ret = 0; - fseek((FILE *)stream, offset, fseek_origin); - return ret; -} - -int ZCALLBACK fclose_file_func (opaque, stream) - voidpf opaque; - voidpf stream; -{ - //(void) opaque; /* avoid "unused parameter" warning */ - int ret; - ret = fclose((FILE *)stream); - return ret; -} - -int ZCALLBACK ferror_file_func (opaque, stream) - voidpf opaque; - voidpf stream; -{ - //(void) opaque; /* avoid "unused parameter" warning */ - int ret; - ret = ferror((FILE *)stream); - return ret; -} - -void fill_fopen_filefunc (pzlib_filefunc_def) - zlib_filefunc_def* pzlib_filefunc_def; -{ - pzlib_filefunc_def->zopen_file = fopen_file_func; - pzlib_filefunc_def->zread_file = fread_file_func; - pzlib_filefunc_def->zwrite_file = fwrite_file_func; - pzlib_filefunc_def->ztell_file = ftell_file_func; - pzlib_filefunc_def->zseek_file = fseek_file_func; - pzlib_filefunc_def->zclose_file = fclose_file_func; - pzlib_filefunc_def->zerror_file = ferror_file_func; - pzlib_filefunc_def->opaque = NULL; -} diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/quazip/ioapi.h b/ground/gcs/src/libs/glc_lib/3rdparty/quazip/ioapi.h deleted file mode 100644 index 7d457baab..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/quazip/ioapi.h +++ /dev/null @@ -1,75 +0,0 @@ -/* ioapi.h -- IO base function header for compress/uncompress .zip - files using zlib + zip or unzip API - - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant -*/ - -#ifndef _ZLIBIOAPI_H -#define _ZLIBIOAPI_H - - -#define ZLIB_FILEFUNC_SEEK_CUR (1) -#define ZLIB_FILEFUNC_SEEK_END (2) -#define ZLIB_FILEFUNC_SEEK_SET (0) - -#define ZLIB_FILEFUNC_MODE_READ (1) -#define ZLIB_FILEFUNC_MODE_WRITE (2) -#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) - -#define ZLIB_FILEFUNC_MODE_EXISTING (4) -#define ZLIB_FILEFUNC_MODE_CREATE (8) - - -#ifndef ZCALLBACK - -#if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) -#define ZCALLBACK CALLBACK -#else -#define ZCALLBACK -#endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); -typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); -typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); -typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); -typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); -typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); -typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); - -typedef struct zlib_filefunc_def_s -{ - open_file_func zopen_file; - read_file_func zread_file; - write_file_func zwrite_file; - tell_file_func ztell_file; - seek_file_func zseek_file; - close_file_func zclose_file; - testerror_file_func zerror_file; - voidpf opaque; -} zlib_filefunc_def; - - - -void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); - -#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size)) -#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size)) -#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream)) -#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode)) -#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream)) -#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream)) - - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/quazip/quazip.cpp b/ground/gcs/src/libs/glc_lib/3rdparty/quazip/quazip.cpp deleted file mode 100644 index 3f7314a43..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/quazip/quazip.cpp +++ /dev/null @@ -1,285 +0,0 @@ -/* --- A kind of "standard" GPL license statement -- -QuaZIP - a Qt/C++ wrapper for the ZIP/UNZIP package -Copyright (C) 2005-2007 Sergey A. Tachenov - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2 of the License, or (at your -option) any later version. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program; if not, write to the Free Software Foundation, Inc., -59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - --- A kind of "standard" GPL license statement ends here -- - -See COPYING file for GPL. - -You are also permitted to use QuaZIP under the terms of LGPL (see -COPYING.LGPL). You are free to choose either license, but please note -that QuaZIP makes use of Qt, which is not licensed under LGPL. So if -you are using Open Source edition of Qt, you therefore MUST use GPL for -your code based on QuaZIP, since it would be also based on Qt in this -case. If you are Qt commercial license owner, then you are free to use -QuaZIP as long as you respect either GPL or LGPL for QuaZIP code. - **/ - -#include - -#include "quazip.h" - -QuaZip::QuaZip(): - fileNameCodec(QTextCodec::codecForLocale()), - commentCodec(QTextCodec::codecForLocale()), - mode(mdNotOpen), hasCurrentFile_f(false), zipError(UNZ_OK) -{ -} - -QuaZip::QuaZip(const QString& zipName): - fileNameCodec(QTextCodec::codecForLocale()), - commentCodec(QTextCodec::codecForLocale()), - zipName(zipName), - mode(mdNotOpen), hasCurrentFile_f(false), zipError(UNZ_OK) -{ -} - -QuaZip::~QuaZip() -{ - if(isOpen()) close(); -} - -bool QuaZip::open(Mode mode, zlib_filefunc_def* ioApi) -{ - zipError=UNZ_OK; - if(isOpen()) { - qWarning("QuaZip::open(): ZIP already opened"); - return false; - } - switch(mode) { - case mdUnzip: - unzFile_f=unzOpen2(QFile::encodeName(zipName).constData(), ioApi); - if(unzFile_f!=NULL) { - this->mode=mode; - return true; - } else { - zipError=UNZ_OPENERROR; - return false; - } - case mdCreate: - case mdAppend: - case mdAdd: - zipFile_f=zipOpen2(QFile::encodeName(zipName).constData(), - mode==mdCreate?APPEND_STATUS_CREATE: - mode==mdAppend?APPEND_STATUS_CREATEAFTER: - APPEND_STATUS_ADDINZIP, - NULL, - ioApi); - if(zipFile_f!=NULL) { - this->mode=mode; - return true; - } else { - zipError=UNZ_OPENERROR; - return false; - } - default: - qWarning("QuaZip::open(): unknown mode: %d", (int)mode); - return false; - break; - } -} - -void QuaZip::close() -{ - zipError=UNZ_OK; - switch(mode) { - case mdNotOpen: - qWarning("QuaZip::close(): ZIP is not open"); - return; - case mdUnzip: - zipError=unzClose(unzFile_f); - break; - case mdCreate: - case mdAppend: - case mdAdd: - zipError=zipClose(zipFile_f, commentCodec->fromUnicode(comment).constData()); - break; - default: - qWarning("QuaZip::close(): unknown mode: %d", (int)mode); - return; - } - if(zipError==UNZ_OK) mode=mdNotOpen; -} - -void QuaZip::setZipName(const QString& zipName) -{ - if(isOpen()) { - qWarning("QuaZip::setZipName(): ZIP is already open!"); - return; - } - this->zipName=zipName; -} - -int QuaZip::getEntriesCount()const -{ - QuaZip *fakeThis=(QuaZip*)this; // non-const - fakeThis->zipError=UNZ_OK; - if(mode!=mdUnzip) { - qWarning("QuaZip::getEntriesCount(): ZIP is not open in mdUnzip mode"); - return -1; - } - unz_global_info globalInfo; - if((fakeThis->zipError=unzGetGlobalInfo(unzFile_f, &globalInfo))!=UNZ_OK) - return zipError; - return (int)globalInfo.number_entry; -} - -QString QuaZip::getComment()const -{ - QuaZip *fakeThis=(QuaZip*)this; // non-const - fakeThis->zipError=UNZ_OK; - if(mode!=mdUnzip) { - qWarning("QuaZip::getComment(): ZIP is not open in mdUnzip mode"); - return QString(); - } - unz_global_info globalInfo; - QByteArray comment; - if((fakeThis->zipError=unzGetGlobalInfo(unzFile_f, &globalInfo))!=UNZ_OK) - return QString(); - comment.resize(globalInfo.size_comment); - if((fakeThis->zipError=unzGetGlobalComment(unzFile_f, comment.data(), comment.size()))!=UNZ_OK) - return QString(); - return commentCodec->toUnicode(comment); -} - -bool QuaZip::setCurrentFile(const QString& fileName, CaseSensitivity cs) -{ - zipError=UNZ_OK; - if(mode!=mdUnzip) { - qWarning("QuaZip::setCurrentFile(): ZIP is not open in mdUnzip mode"); - return false; - } - if(fileName.isNull()) { - hasCurrentFile_f=false; - return true; - } - // Unicode-aware reimplementation of the unzLocateFile function - if(unzFile_f==NULL) { - zipError=UNZ_PARAMERROR; - return false; - } - if(fileName.length()>MAX_FILE_NAME_LENGTH) { - zipError=UNZ_PARAMERROR; - return false; - } - bool sens; - if(cs==csDefault) { -#ifdef Q_WS_WIN - sens=false; -#else - sens=true; -#endif - } else sens=cs==csSensitive; - QString lower, current; - if(!sens) lower=fileName.toLower(); - hasCurrentFile_f=false; - for(bool more=goToFirstFile(); more; more=goToNextFile()) { - current=getCurrentFileName(); - if(current.isNull()) return false; - if(sens) { - if(current==fileName) break; - } else { - if(current.toLower()==lower) break; - } - } - return hasCurrentFile_f; -} - -bool QuaZip::goToFirstFile() -{ - zipError=UNZ_OK; - if(mode!=mdUnzip) { - qWarning("QuaZip::goToFirstFile(): ZIP is not open in mdUnzip mode"); - return false; - } - zipError=unzGoToFirstFile(unzFile_f); - hasCurrentFile_f=zipError==UNZ_OK; - return hasCurrentFile_f; -} - -bool QuaZip::goToNextFile() -{ - zipError=UNZ_OK; - if(mode!=mdUnzip) { - qWarning("QuaZip::goToFirstFile(): ZIP is not open in mdUnzip mode"); - return false; - } - zipError=unzGoToNextFile(unzFile_f); - hasCurrentFile_f=zipError==UNZ_OK; - if(zipError==UNZ_END_OF_LIST_OF_FILE) zipError=UNZ_OK; - return hasCurrentFile_f; -} - -bool QuaZip::getCurrentFileInfo(QuaZipFileInfo *info)const -{ - QuaZip *fakeThis=(QuaZip*)this; // non-const - fakeThis->zipError=UNZ_OK; - if(mode!=mdUnzip) { - qWarning("QuaZip::getCurrentFileInfo(): ZIP is not open in mdUnzip mode"); - return false; - } - unz_file_info info_z; - QByteArray fileName; - QByteArray extra; - QByteArray comment; - if(info==NULL) return false; - if(!isOpen()||!hasCurrentFile()) return false; - if((fakeThis->zipError=unzGetCurrentFileInfo(unzFile_f, &info_z, NULL, 0, NULL, 0, NULL, 0))!=UNZ_OK) - return false; - fileName.resize(info_z.size_filename); - extra.resize(info_z.size_file_extra); - comment.resize(info_z.size_file_comment); - if((fakeThis->zipError=unzGetCurrentFileInfo(unzFile_f, NULL, - fileName.data(), fileName.size(), - extra.data(), extra.size(), - comment.data(), comment.size()))!=UNZ_OK) - return false; - info->versionCreated=info_z.version; - info->versionNeeded=info_z.version_needed; - info->flags=info_z.flag; - info->method=info_z.compression_method; - info->crc=info_z.crc; - info->compressedSize=info_z.compressed_size; - info->uncompressedSize=info_z.uncompressed_size; - info->diskNumberStart=info_z.disk_num_start; - info->internalAttr=info_z.internal_fa; - info->externalAttr=info_z.external_fa; - info->name=fileNameCodec->toUnicode(fileName); - info->comment=commentCodec->toUnicode(comment); - info->extra=extra; - info->dateTime=QDateTime( - QDate(info_z.tmu_date.tm_year, info_z.tmu_date.tm_mon+1, info_z.tmu_date.tm_mday), - QTime(info_z.tmu_date.tm_hour, info_z.tmu_date.tm_min, info_z.tmu_date.tm_sec)); - return true; -} - -QString QuaZip::getCurrentFileName()const -{ - QuaZip *fakeThis=(QuaZip*)this; // non-const - fakeThis->zipError=UNZ_OK; - if(mode!=mdUnzip) { - qWarning("QuaZip::getCurrentFileName(): ZIP is not open in mdUnzip mode"); - return QString(); - } - if(!isOpen()||!hasCurrentFile()) return QString(); - QByteArray fileName(MAX_FILE_NAME_LENGTH, 0); - if((fakeThis->zipError=unzGetCurrentFileInfo(unzFile_f, NULL, fileName.data(), fileName.size(), - NULL, 0, NULL, 0))!=UNZ_OK) - return QString(); - return fileNameCodec->toUnicode(fileName.constData()); -} diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/quazip/quazip.h b/ground/gcs/src/libs/glc_lib/3rdparty/quazip/quazip.h deleted file mode 100644 index ced1ea0f1..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/quazip/quazip.h +++ /dev/null @@ -1,346 +0,0 @@ -#ifndef QUA_ZIP_H -#define QUA_ZIP_H - -/* --- A kind of "standard" GPL license statement -- -QuaZIP - a Qt/C++ wrapper for the ZIP/UNZIP package -Copyright (C) 2005-2007 Sergey A. Tachenov - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2 of the License, or (at your -option) any later version. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program; if not, write to the Free Software Foundation, Inc., -59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - --- A kind of "standard" GPL license statement ends here -- - -See COPYING file for GPL. - -You are also permitted to use QuaZIP under the terms of LGPL (see -COPYING.LGPL). You are free to choose either license, but please note -that QuaZIP makes use of Qt, which is not licensed under LGPL. So if -you are using Open Source edition of Qt, you therefore MUST use GPL for -your code based on QuaZIP, since it would be also based on Qt in this -case. If you are Qt commercial license owner, then you are free to use -QuaZIP as long as you respect either GPL or LGPL for QuaZIP code. - **/ - -#include -#include - -#include "zip.h" -#include "unzip.h" - -#include "quazipfileinfo.h" - -// just in case it will be defined in the later versions of the ZIP/UNZIP -#ifndef UNZ_OPENERROR -// define additional error code -#define UNZ_OPENERROR -1000 -#endif - -/// ZIP archive. -/** \class QuaZip quazip.h - * This class implements basic interface to the ZIP archive. It can be - * used to read table contents of the ZIP archive and retreiving - * information about the files inside it. - * - * You can also use this class to open files inside archive by passing - * pointer to the instance of this class to the constructor of the - * QuaZipFile class. But see QuaZipFile::QuaZipFile(QuaZip*, QObject*) - * for the possible pitfalls. - * - * This class is indended to provide interface to the ZIP subpackage of - * the ZIP/UNZIP package as well as to the UNZIP subpackage. But - * currently it supports only UNZIP. - * - * The use of this class is simple - just create instance using - * constructor, then set ZIP archive file name using setFile() function - * (if you did not passed the name to the constructor), then open() and - * then use different functions to work with it! Well, if you are - * paranoid, you may also wish to call close before destructing the - * instance, to check for errors on close. - * - * You may also use getUnzFile() and getZipFile() functions to get the - * ZIP archive handle and use it with ZIP/UNZIP package API directly. - * - * This class supports localized file names inside ZIP archive, but you - * have to set up proper codec with setCodec() function. By default, - * locale codec will be used, which is probably ok for UNIX systems, but - * will almost certainly fail with ZIP archives created in Windows. This - * is because Windows ZIP programs have strange habit of using DOS - * encoding for file names in ZIP archives. For example, ZIP archive - * with cyrillic names created in Windows will have file names in \c - * IBM866 encoding instead of \c WINDOWS-1251. I think that calling one - * function is not much trouble, but for true platform independency it - * would be nice to have some mechanism for file name encoding auto - * detection using locale information. Does anyone know a good way to do - * it? - **/ -class QuaZip { - public: - /// Useful constants. - enum Constants { - MAX_FILE_NAME_LENGTH=256 /**< Maximum file name length. Taken from - \c UNZ_MAXFILENAMEINZIP constant in - unzip.c. */ - }; - /// Open mode of the ZIP file. - enum Mode { - mdNotOpen, ///< ZIP file is not open. This is the initial mode. - mdUnzip, ///< ZIP file is open for reading files inside it. - mdCreate, ///< ZIP file was created with open() call. - mdAppend, /**< ZIP file was opened in append mode. This refers to - * \c APPEND_STATUS_CREATEAFTER mode in ZIP/UNZIP package - * and means that zip is appended to some existing file - * what is useful when that file contains - * self-extractor code. This is obviously \em not what - * you whant to use to add files to the existing ZIP - * archive. - **/ - mdAdd ///< ZIP file was opened for adding files in the archive. - }; - /// Case sensitivity for the file names. - /** This is what you specify when accessing files in the archive. - * Works perfectly fine with any characters thanks to Qt's great - * unicode support. This is different from ZIP/UNZIP API, where - * only US-ASCII characters was supported. - **/ - enum CaseSensitivity { - csDefault=0, ///< Default for platform. Case sensitive for UNIX, not for Windows. - csSensitive=1, ///< Case sensitive. - csInsensitive=2 ///< Case insensitive. - }; - private: - QTextCodec *fileNameCodec, *commentCodec; - QString zipName; - QString comment; - Mode mode; - union { - unzFile unzFile_f; - zipFile zipFile_f; - }; - bool hasCurrentFile_f; - int zipError; - // not (and will not be) implemented - QuaZip(const QuaZip& that); - // not (and will not be) implemented - QuaZip& operator=(const QuaZip& that); - public: - /// Constructs QuaZip object. - /** Call setName() before opening constructed object. */ - QuaZip(); - /// Constructs QuaZip object associated with ZIP file \a zipName. - QuaZip(const QString& zipName); - /// Destroys QuaZip object. - /** Calls close() if necessary. */ - ~QuaZip(); - /// Opens ZIP file. - /** Argument \a ioApi specifies IO function set for ZIP/UNZIP - * package to use. See unzip.h, zip.h and ioapi.h for details. By - * passing NULL (the default) you just tell package to use the - * default API which works just fine on UNIX platforms. I have tried - * it on win32-g++ platform too and it seems it works fine there - * too, so I see no reason to use win32 IO API included in original - * ZIP/UNZIP package. - * - * ZIP archive file name will be converted to 8-bit encoding using - * Qt's QFile::encodeName() function before passing it to the - * ZIP/UNZIP package API. - * - * Returns \c true if successful, \c false otherwise. - * - * Argument \a mode specifies open mode of the ZIP archive. See Mode - * for details. Note that there is zipOpen2() function in the - * ZIP/UNZIP API which accepts \a globalcomment argument, but it - * does not use it anywhere, so this open() function does not have this - * argument. See setComment() if you need to set global comment. - * - * \note ZIP/UNZIP API open calls do not return error code - they - * just return \c NULL indicating an error. But to make things - * easier, quazip.h header defines additional error code \c - * UNZ_ERROROPEN and getZipError() will return it if the open call - * of the ZIP/UNZIP API returns \c NULL. - **/ - bool open(Mode mode, zlib_filefunc_def *ioApi =NULL); - /// Closes ZIP file. - /** Call getZipError() to determine if the close was successful. */ - void close(); - /// Sets the codec used to encode/decode file names inside archive. - /** This is necessary to access files in the ZIP archive created - * under Windows with non-latin characters in file names. For - * example, file names with cyrillic letters will be in \c IBM866 - * encoding. - **/ - void setFileNameCodec(QTextCodec *fileNameCodec) - {this->fileNameCodec=fileNameCodec;} - /// Sets the codec used to encode/decode file names inside archive. - /** \overload - * Equivalent to calling setFileNameCodec(QTextCodec::codecForName(codecName)); - **/ - void setFileNameCodec(const char *fileNameCodecName) - {fileNameCodec=QTextCodec::codecForName(fileNameCodecName);} - /// Returns the codec used to encode/decode comments inside archive. - QTextCodec* getFileNameCodec()const {return fileNameCodec;} - /// Sets the codec used to encode/decode comments inside archive. - /** This codec defaults to locale codec, which is probably ok. - **/ - void setCommentCodec(QTextCodec *commentCodec) - {this->commentCodec=commentCodec;} - /// Sets the codec used to encode/decode comments inside archive. - /** \overload - * Equivalent to calling setCommentCodec(QTextCodec::codecForName(codecName)); - **/ - void setCommentCodec(const char *commentCodecName) - {commentCodec=QTextCodec::codecForName(commentCodecName);} - /// Returns the codec used to encode/decode comments inside archive. - QTextCodec* getCommentCodec()const {return commentCodec;} - /// Returns the name of the ZIP file. - /** Returns null string if no ZIP file name has been set. - * \sa setZipName() - **/ - QString getZipName()const {return zipName;} - /// Sets the name of the ZIP file. - /** Does nothing if the ZIP file is open. - * - * Does not reset error code returned by getZipError(). - **/ - void setZipName(const QString& zipName); - /// Returns the mode in which ZIP file was opened. - Mode getMode()const {return mode;} - /// Returns \c true if ZIP file is open, \c false otherwise. - bool isOpen()const {return mode!=mdNotOpen;} - /// Returns the error code of the last operation. - /** Returns \c UNZ_OK if the last operation was successful. - * - * Error code resets to \c UNZ_OK every time you call any function - * that accesses something inside ZIP archive, even if it is \c - * const (like getEntriesCount()). open() and close() calls reset - * error code too. See documentation for the specific functions for - * details on error detection. - **/ - int getZipError()const {return zipError;} - /// Returns number of the entries in the ZIP central directory. - /** Returns negative error code in the case of error. The same error - * code will be returned by subsequent getZipError() call. - **/ - int getEntriesCount()const; - /// Returns global comment in the ZIP file. - QString getComment()const; - /// Sets global comment in the ZIP file. - /** Comment will be written to the archive on close operation. - * - * \sa open() - **/ - void setComment(const QString& comment) {this->comment=comment;} - /// Sets the current file to the first file in the archive. - /** Returns \c true on success, \c false otherwise. Call - * getZipError() to get the error code. - **/ - bool goToFirstFile(); - /// Sets the current file to the next file in the archive. - /** Returns \c true on success, \c false otherwise. Call - * getZipError() to determine if there was an error. - * - * Should be used only in QuaZip::mdUnzip mode. - * - * \note If the end of file was reached, getZipError() will return - * \c UNZ_OK instead of \c UNZ_END_OF_LIST_OF_FILE. This is to make - * things like this easier: - * \code - * for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile()) { - * // do something - * } - * if(zip.getZipError()==UNZ_OK) { - * // ok, there was no error - * } - * \endcode - **/ - bool goToNextFile(); - /// Sets current file by its name. - /** Returns \c true if successful, \c false otherwise. Argument \a - * cs specifies case sensitivity of the file name. Call - * getZipError() in the case of a failure to get error code. - * - * This is not a wrapper to unzLocateFile() function. That is - * because I had to implement locale-specific case-insensitive - * comparison. - * - * Here are the differences from the original implementation: - * - * - If the file was not found, error code is \c UNZ_OK, not \c - * UNZ_END_OF_LIST_OF_FILE (see also goToNextFile()). - * - If this function fails, it unsets the current file rather than - * resetting it back to what it was before the call. - * - * If \a fileName is null string then this function unsets the - * current file and return \c true. Note that you should close the - * file first if it is open! See - * QuaZipFile::QuaZipFile(QuaZip*,QObject*) for the details. - * - * Should be used only in QuaZip::mdUnzip mode. - * - * \sa setFileNameCodec(), CaseSensitivity - **/ - bool setCurrentFile(const QString& fileName, CaseSensitivity cs =csDefault); - /// Returns \c true if the current file has been set. - bool hasCurrentFile()const {return hasCurrentFile_f;} - /// Retrieves information about the current file. - /** Fills the structure pointed by \a info. Returns \c true on - * success, \c false otherwise. In the latter case structure pointed - * by \a info remains untouched. If there was an error, - * getZipError() returns error code. - * - * Should be used only in QuaZip::mdUnzip mode. - * - * Does nothing and returns \c false in any of the following cases. - * - ZIP is not open; - * - ZIP does not have current file; - * - \a info is \c NULL; - * - * In all these cases getZipError() returns \c UNZ_OK since there - * is no ZIP/UNZIP API call. - **/ - bool getCurrentFileInfo(QuaZipFileInfo* info)const; - /// Returns the current file name. - /** Equivalent to calling getCurrentFileInfo() and then getting \c - * name field of the QuaZipFileInfo structure, but faster and more - * convenient. - * - * Should be used only in QuaZip::mdUnzip mode. - **/ - QString getCurrentFileName()const; - /// Returns \c unzFile handle. - /** You can use this handle to directly call UNZIP part of the - * ZIP/UNZIP package functions (see unzip.h). - * - * \warning When using the handle returned by this function, please - * keep in mind that QuaZip class is unable to detect any changes - * you make in the ZIP file state (e. g. changing current file, or - * closing the handle). So please do not do anything with this - * handle that is possible to do with the functions of this class. - * Or at least return the handle in the original state before - * calling some another function of this class (including implicit - * destructor calls and calls from the QuaZipFile objects that refer - * to this QuaZip instance!). So if you have changed the current - * file in the ZIP archive - then change it back or you may - * experience some strange behavior or even crashes. - **/ - unzFile getUnzFile() {return unzFile_f;} - /// Returns \c zipFile handle. - /** You can use this handle to directly call ZIP part of the - * ZIP/UNZIP package functions (see zip.h). Warnings about the - * getUnzFile() function also apply to this function. - **/ - zipFile getZipFile() {return zipFile_f;} -}; - -#endif diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/quazip/quazipfile.cpp b/ground/gcs/src/libs/glc_lib/3rdparty/quazip/quazipfile.cpp deleted file mode 100644 index 0399d1dbd..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/quazip/quazipfile.cpp +++ /dev/null @@ -1,377 +0,0 @@ -/* --- A kind of "standard" GPL license statement -- -QuaZIP - a Qt/C++ wrapper for the ZIP/UNZIP package -Copyright (C) 2005-2007 Sergey A. Tachenov - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2 of the License, or (at your -option) any later version. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program; if not, write to the Free Software Foundation, Inc., -59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - --- A kind of "standard" GPL license statement ends here -- - -See COPYING file for GPL. - -You are also permitted to use QuaZIP under the terms of LGPL (see -COPYING.LGPL). You are free to choose either license, but please note -that QuaZIP makes use of Qt, which is not licensed under LGPL. So if -you are using Open Source edition of Qt, you therefore MUST use GPL for -your code based on QuaZIP, since it would be also based on Qt in this -case. If you are Qt commercial license owner, then you are free to use -QuaZIP as long as you respect either GPL or LGPL for QuaZIP code. - **/ - -#include "quazipfile.h" - -using namespace std; - -QuaZipFile::QuaZipFile(): - zip(NULL), internal(true), zipError(UNZ_OK) -{ -} - -QuaZipFile::QuaZipFile(QObject *parent): - QIODevice(parent), zip(NULL), internal(true), zipError(UNZ_OK) -{ -} - -QuaZipFile::QuaZipFile(const QString& zipName, QObject *parent): - QIODevice(parent), internal(true), zipError(UNZ_OK) -{ - zip=new QuaZip(zipName); - Q_CHECK_PTR(zip); -} - -QuaZipFile::QuaZipFile(const QString& zipName, const QString& fileName, - QuaZip::CaseSensitivity cs, QObject *parent): - QIODevice(parent), internal(true), zipError(UNZ_OK) -{ - zip=new QuaZip(zipName); - Q_CHECK_PTR(zip); - this->fileName=fileName; - this->caseSensitivity=cs; -} - -QuaZipFile::QuaZipFile(QuaZip *zip, QObject *parent): - QIODevice(parent), - zip(zip), internal(false), - zipError(UNZ_OK) -{ -} - -QuaZipFile::~QuaZipFile() -{ - if(isOpen()) close(); - if(internal) delete zip; -} - -QString QuaZipFile::getZipName()const -{ - return zip==NULL?QString():zip->getZipName(); -} - -QString QuaZipFile::getActualFileName()const -{ - setZipError(UNZ_OK); - if(zip==NULL||(openMode()&WriteOnly)) return QString(); - QString name=zip->getCurrentFileName(); - if(name.isNull()) - setZipError(zip->getZipError()); - return name; -} - -void QuaZipFile::setZipName(const QString& zipName) -{ - if(isOpen()) { - qWarning("QuaZipFile::setZipName(): file is already open - can not set ZIP name"); - return; - } - if(zip!=NULL&&internal) delete zip; - zip=new QuaZip(zipName); - Q_CHECK_PTR(zip); - internal=true; -} - -void QuaZipFile::setZip(QuaZip *zip) -{ - if(isOpen()) { - qWarning("QuaZipFile::setZip(): file is already open - can not set ZIP"); - return; - } - if(this->zip!=NULL&&internal) delete this->zip; - this->zip=zip; - this->fileName=QString(); - internal=false; -} - -void QuaZipFile::setFileName(const QString& fileName, QuaZip::CaseSensitivity cs) -{ - if(zip==NULL) { - qWarning("QuaZipFile::setFileName(): call setZipName() first"); - return; - } - if(!internal) { - qWarning("QuaZipFile::setFileName(): should not be used when not using internal QuaZip"); - return; - } - if(isOpen()) { - qWarning("QuaZipFile::setFileName(): can not set file name for already opened file"); - return; - } - this->fileName=fileName; - this->caseSensitivity=cs; -} - -void QuaZipFile::setZipError(int zipError)const -{ - QuaZipFile *fakeThis=(QuaZipFile*)this; // non-const - fakeThis->zipError=zipError; - if(zipError==UNZ_OK) - fakeThis->setErrorString(QString()); - else - fakeThis->setErrorString(tr("ZIP/UNZIP API error %1").arg(zipError)); -} - -bool QuaZipFile::open(OpenMode mode) -{ - return open(mode, NULL); -} - -bool QuaZipFile::open(OpenMode mode, int *method, int *level, bool raw, const char *password) -{ - resetZipError(); - if(isOpen()) { - qWarning("QuaZipFile::open(): already opened"); - return false; - } - if(mode&Unbuffered) { - qWarning("QuaZipFile::open(): Unbuffered mode is not supported"); - return false; - } - if((mode&ReadOnly)&&!(mode&WriteOnly)) { - if(internal) { - if(!zip->open(QuaZip::mdUnzip)) { - setZipError(zip->getZipError()); - return false; - } - if(!zip->setCurrentFile(fileName, caseSensitivity)) { - setZipError(zip->getZipError()); - zip->close(); - return false; - } - } else { - if(zip==NULL) { - qWarning("QuaZipFile::open(): zip is NULL"); - return false; - } - if(zip->getMode()!=QuaZip::mdUnzip) { - qWarning("QuaZipFile::open(): file open mode %d incompatible with ZIP open mode %d", - (int)mode, (int)zip->getMode()); - return false; - } - if(!zip->hasCurrentFile()) { - qWarning("QuaZipFile::open(): zip does not have current file"); - return false; - } - } - setZipError(unzOpenCurrentFile3(zip->getUnzFile(), method, level, (int)raw, password)); - if(zipError==UNZ_OK) { - setOpenMode(mode); - this->raw=raw; - return true; - } else - return false; - } - qWarning("QuaZipFile::open(): open mode %d not supported by this function", (int)mode); - return false; -} - -bool QuaZipFile::open(OpenMode mode, const QuaZipNewInfo& info, - const char *password, quint32 crc, - int method, int level, bool raw, - int windowBits, int memLevel, int strategy) -{ - zip_fileinfo info_z; - resetZipError(); - if(isOpen()) { - qWarning("QuaZipFile::open(): already opened"); - return false; - } - if((mode&WriteOnly)&&!(mode&ReadOnly)) { - if(internal) { - qWarning("QuaZipFile::open(): write mode is incompatible with internal QuaZip approach"); - return false; - } - if(zip==NULL) { - qWarning("QuaZipFile::open(): zip is NULL"); - return false; - } - if(zip->getMode()!=QuaZip::mdCreate&&zip->getMode()!=QuaZip::mdAppend&&zip->getMode()!=QuaZip::mdAdd) { - qWarning("QuaZipFile::open(): file open mode %d incompatible with ZIP open mode %d", - (int)mode, (int)zip->getMode()); - return false; - } - info_z.tmz_date.tm_year=info.dateTime.date().year(); - info_z.tmz_date.tm_mon=info.dateTime.date().month() - 1; - info_z.tmz_date.tm_mday=info.dateTime.date().day(); - info_z.tmz_date.tm_hour=info.dateTime.time().hour(); - info_z.tmz_date.tm_min=info.dateTime.time().minute(); - info_z.tmz_date.tm_sec=info.dateTime.time().second(); - info_z.dosDate = 0; - info_z.internal_fa=(uLong)info.internalAttr; - info_z.external_fa=(uLong)info.externalAttr; - setZipError(zipOpenNewFileInZip3(zip->getZipFile(), - zip->getFileNameCodec()->fromUnicode(info.name).constData(), &info_z, - info.extraLocal.constData(), info.extraLocal.length(), - info.extraGlobal.constData(), info.extraGlobal.length(), - zip->getCommentCodec()->fromUnicode(info.comment).constData(), - method, level, (int)raw, - windowBits, memLevel, strategy, - password, (uLong)crc)); - if(zipError==UNZ_OK) { - writePos=0; - setOpenMode(mode); - this->raw=raw; - if(raw) { - this->crc=crc; - this->uncompressedSize=info.uncompressedSize; - } - return true; - } else - return false; - } - qWarning("QuaZipFile::open(): open mode %d not supported by this function", (int)mode); - return false; -} - -bool QuaZipFile::isSequential()const -{ - return true; -} - -qint64 QuaZipFile::pos()const -{ - if(zip==NULL) { - qWarning("QuaZipFile::pos(): call setZipName() or setZip() first"); - return -1; - } - if(!isOpen()) { - qWarning("QuaZipFile::pos(): file is not open"); - return -1; - } - if(openMode()&ReadOnly) - return unztell(zip->getUnzFile()); - else - return writePos; -} - -bool QuaZipFile::atEnd()const -{ - if(zip==NULL) { - qWarning("QuaZipFile::atEnd(): call setZipName() or setZip() first"); - return false; - } - if(!isOpen()) { - qWarning("QuaZipFile::atEnd(): file is not open"); - return false; - } - if(openMode()&ReadOnly) - return unzeof(zip->getUnzFile())==1; - else - return true; -} - -qint64 QuaZipFile::size()const -{ - if(!isOpen()) { - qWarning("QuaZipFile::atEnd(): file is not open"); - return -1; - } - if(openMode()&ReadOnly) - return raw?csize():usize(); - else - return writePos; -} - -qint64 QuaZipFile::csize()const -{ - unz_file_info info_z; - setZipError(UNZ_OK); - if(zip==NULL||zip->getMode()!=QuaZip::mdUnzip) return -1; - setZipError(unzGetCurrentFileInfo(zip->getUnzFile(), &info_z, NULL, 0, NULL, 0, NULL, 0)); - if(zipError!=UNZ_OK) - return -1; - return info_z.compressed_size; -} - -qint64 QuaZipFile::usize()const -{ - unz_file_info info_z; - setZipError(UNZ_OK); - if(zip==NULL||zip->getMode()!=QuaZip::mdUnzip) return -1; - setZipError(unzGetCurrentFileInfo(zip->getUnzFile(), &info_z, NULL, 0, NULL, 0, NULL, 0)); - if(zipError!=UNZ_OK) - return -1; - return info_z.uncompressed_size; -} - -bool QuaZipFile::getFileInfo(QuaZipFileInfo *info) -{ - if(zip==NULL||zip->getMode()!=QuaZip::mdUnzip) return false; - zip->getCurrentFileInfo(info); - setZipError(zip->getZipError()); - return zipError==UNZ_OK; -} - -void QuaZipFile::close() -{ - resetZipError(); - if(zip==NULL||!zip->isOpen()) return; - if(!isOpen()) { - qWarning("QuaZipFile::close(): file isn't open"); - return; - } - if(openMode()&ReadOnly) - setZipError(unzCloseCurrentFile(zip->getUnzFile())); - else if(openMode()&WriteOnly) - if(isRaw()) setZipError(zipCloseFileInZipRaw(zip->getZipFile(), uncompressedSize, crc)); - else setZipError(zipCloseFileInZip(zip->getZipFile())); - else { - qWarning("Wrong open mode: %d", (int)openMode()); - return; - } - if(zipError==UNZ_OK) setOpenMode(QIODevice::NotOpen); - else return; - if(internal) { - zip->close(); - setZipError(zip->getZipError()); - } -} - -qint64 QuaZipFile::readData(char *data, qint64 maxSize) -{ - setZipError(UNZ_OK); - qint64 bytesRead=unzReadCurrentFile(zip->getUnzFile(), data, (unsigned)maxSize); - if(bytesRead<0) setZipError((int)bytesRead); - return bytesRead; -} - -qint64 QuaZipFile::writeData(const char* data, qint64 maxSize) -{ - setZipError(ZIP_OK); - setZipError(zipWriteInFileInZip(zip->getZipFile(), data, (uint)maxSize)); - if(zipError!=ZIP_OK) return -1; - else { - writePos+=maxSize; - return maxSize; - } -} diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/quazip/quazipfile.h b/ground/gcs/src/libs/glc_lib/3rdparty/quazip/quazipfile.h deleted file mode 100644 index 09af5bcec..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/quazip/quazipfile.h +++ /dev/null @@ -1,442 +0,0 @@ -#ifndef QUA_ZIPFILE_H -#define QUA_ZIPFILE_H - -/* --- A kind of "standard" GPL license statement -- -QuaZIP - a Qt/C++ wrapper for the ZIP/UNZIP package -Copyright (C) 2005-2008 Sergey A. Tachenov - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2 of the License, or (at your -option) any later version. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program; if not, write to the Free Software Foundation, Inc., -59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - --- A kind of "standard" GPL license statement ends here -- - -See COPYING file for GPL. - -You are also permitted to use QuaZIP under the terms of LGPL (see -COPYING.LGPL). You are free to choose either license, but please note -that QuaZIP makes use of Qt, which is not licensed under LGPL. So if -you are using Open Source edition of Qt, you therefore MUST use GPL for -your code based on QuaZIP, since it would be also based on Qt in this -case. If you are Qt commercial license owner, then you are free to use -QuaZIP as long as you respect either GPL or LGPL for QuaZIP code. - **/ - -#include - -#include "quazip.h" -#include "quazipnewinfo.h" - -/// A file inside ZIP archive. -/** \class QuaZipFile quazipfile.h - * This is the most interesting class. Not only it provides C++ - * interface to the ZIP/UNZIP package, but also integrates it with Qt by - * subclassing QIODevice. This makes possible to access files inside ZIP - * archive using QTextStream or QDataStream, for example. Actually, this - * is the main purpose of the whole QuaZIP library. - * - * You can either use existing QuaZip instance to create instance of - * this class or pass ZIP archive file name to this class, in which case - * it will create internal QuaZip object. See constructors' descriptions - * for details. Writing is only possible with the existing instance. - * - * \section quazipfile-sequential Sequential or random-access? - * - * At the first thought, QuaZipFile has fixed size, the start and the - * end and should be therefore considered random-access device. But - * there is one major obstacle to making it random-access: ZIP/UNZIP API - * does not support seek() operation and the only way to implement it is - * through reopening the file and re-reading to the required position, - * but this is prohibitely slow. - * - * Therefore, QuaZipFile is considered to be a sequential device. This - * has advantage of availability of the ungetChar() operation (QIODevice - * does not implement it properly for non-sequential devices unless they - * support seek()). Disadvantage is a somewhat strange behaviour of the - * size() and pos() functions. This should be kept in mind while using - * this class. - * - **/ -class QuaZipFile: public QIODevice { - Q_OBJECT - private: - QuaZip *zip; - QString fileName; - QuaZip::CaseSensitivity caseSensitivity; - bool raw; - qint64 writePos; - // these two are for writing raw files - ulong uncompressedSize; - quint32 crc; - bool internal; - int zipError; - // these are not supported nor implemented - QuaZipFile(const QuaZipFile& that); - QuaZipFile& operator=(const QuaZipFile& that); - void resetZipError()const {setZipError(UNZ_OK);} - // const, but sets zipError! - void setZipError(int zipError)const; - protected: - /// Implementation of the QIODevice::readData(). - qint64 readData(char *data, qint64 maxSize); - /// Implementation of the QIODevice::writeData(). - qint64 writeData(const char *data, qint64 maxSize); - public: - /// Constructs a QuaZipFile instance. - /** You should use setZipName() and setFileName() or setZip() before - * trying to call open() on the constructed object. - **/ - QuaZipFile(); - /// Constructs a QuaZipFile instance. - /** \a parent argument specifies this object's parent object. - * - * You should use setZipName() and setFileName() or setZip() before - * trying to call open() on the constructed object. - **/ - QuaZipFile(QObject *parent); - /// Constructs a QuaZipFile instance. - /** \a parent argument specifies this object's parent object and \a - * zipName specifies ZIP archive file name. - * - * You should use setFileName() before trying to call open() on the - * constructed object. - * - * QuaZipFile constructed by this constructor can be used for read - * only access. Use QuaZipFile(QuaZip*,QObject*) for writing. - **/ - QuaZipFile(const QString& zipName, QObject *parent =NULL); - /// Constructs a QuaZipFile instance. - /** \a parent argument specifies this object's parent object, \a - * zipName specifies ZIP archive file name and \a fileName and \a cs - * specify a name of the file to open inside archive. - * - * QuaZipFile constructed by this constructor can be used for read - * only access. Use QuaZipFile(QuaZip*,QObject*) for writing. - * - * \sa QuaZip::setCurrentFile() - **/ - QuaZipFile(const QString& zipName, const QString& fileName, - QuaZip::CaseSensitivity cs =QuaZip::csDefault, QObject *parent =NULL); - /// Constructs a QuaZipFile instance. - /** \a parent argument specifies this object's parent object. - * - * \a zip is the pointer to the existing QuaZip object. This - * QuaZipFile object then can be used to read current file in the - * \a zip or to write to the file inside it. - * - * \warning Using this constructor for reading current file can be - * tricky. Let's take the following example: - * \code - * QuaZip zip("archive.zip"); - * zip.open(QuaZip::mdUnzip); - * zip.setCurrentFile("file-in-archive"); - * QuaZipFile file(&zip); - * file.open(QIODevice::ReadOnly); - * // ok, now we can read from the file - * file.read(somewhere, some); - * zip.setCurrentFile("another-file-in-archive"); // oops... - * QuaZipFile anotherFile(&zip); - * anotherFile.open(QIODevice::ReadOnly); - * anotherFile.read(somewhere, some); // this is still ok... - * file.read(somewhere, some); // and this is NOT - * \endcode - * So, what exactly happens here? When we change current file in the - * \c zip archive, \c file that references it becomes invalid - * (actually, as far as I understand ZIP/UNZIP sources, it becomes - * closed, but QuaZipFile has no means to detect it). - * - * Summary: do not close \c zip object or change its current file as - * long as QuaZipFile is open. Even better - use another constructors - * which create internal QuaZip instances, one per object, and - * therefore do not cause unnecessary trouble. This constructor may - * be useful, though, if you already have a QuaZip instance and do - * not want to access several files at once. Good example: - * \code - * QuaZip zip("archive.zip"); - * zip.open(QuaZip::mdUnzip); - * // first, we need some information about archive itself - * QByteArray comment=zip.getComment(); - * // and now we are going to access files inside it - * QuaZipFile file(&zip); - * for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile()) { - * file.open(QIODevice::ReadOnly); - * // do something cool with file here - * file.close(); // do not forget to close! - * } - * zip.close(); - * \endcode - **/ - QuaZipFile(QuaZip *zip, QObject *parent =NULL); - /// Destroys a QuaZipFile instance. - /** Closes file if open, destructs internal QuaZip object (if it - * exists and \em is internal, of course). - **/ - virtual ~QuaZipFile(); - /// Returns the ZIP archive file name. - /** If this object was created by passing QuaZip pointer to the - * constructor, this function will return that QuaZip's file name - * (or null string if that object does not have file name yet). - * - * Otherwise, returns associated ZIP archive file name or null - * string if there are no name set yet. - * - * \sa setZipName() getFileName() - **/ - QString getZipName()const; - /// Returns a pointer to the associated QuaZip object. - /** Returns \c NULL if there is no associated QuaZip or it is - * internal (so you will not mess with it). - **/ - QuaZip* getZip()const; - /// Returns file name. - /** This function returns file name you passed to this object either - * by using - * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*) - * or by calling setFileName(). Real name of the file may differ in - * case if you used case-insensitivity. - * - * Returns null string if there is no file name set yet. This is the - * case when this QuaZipFile operates on the existing QuaZip object - * (constructor QuaZipFile(QuaZip*,QObject*) or setZip() was used). - * - * \sa getActualFileName - **/ - QString getFileName()const {return fileName;} - /// Returns case sensitivity of the file name. - /** This function returns case sensitivity argument you passed to - * this object either by using - * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*) - * or by calling setFileName(). - * - * Returns unpredictable value if getFileName() returns null string - * (this is the case when you did not used setFileName() or - * constructor above). - * - * \sa getFileName - **/ - QuaZip::CaseSensitivity getCaseSensitivity()const {return caseSensitivity;} - /// Returns the actual file name in the archive. - /** This is \em not a ZIP archive file name, but a name of file inside - * archive. It is not necessary the same name that you have passed - * to the - * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*), - * setFileName() or QuaZip::setCurrentFile() - this is the real file - * name inside archive, so it may differ in case if the file name - * search was case-insensitive. - * - * Equivalent to calling getCurrentFileName() on the associated - * QuaZip object. Returns null string if there is no associated - * QuaZip object or if it does not have a current file yet. And this - * is the case if you called setFileName() but did not open the - * file yet. So this is perfectly fine: - * \code - * QuaZipFile file("somezip.zip"); - * file.setFileName("somefile"); - * QString name=file.getName(); // name=="somefile" - * QString actual=file.getActualFileName(); // actual is null string - * file.open(QIODevice::ReadOnly); - * QString actual=file.getActualFileName(); // actual can be "SoMeFiLe" on Windows - * \endcode - * - * \sa getZipName(), getFileName(), QuaZip::CaseSensitivity - **/ - QString getActualFileName()const; - /// Sets the ZIP archive file name. - /** Automatically creates internal QuaZip object and destroys - * previously created internal QuaZip object, if any. - * - * Will do nothing if this file is already open. You must close() it - * first. - **/ - void setZipName(const QString& zipName); - /// Returns \c true if the file was opened in raw mode. - /** If the file is not open, the returned value is undefined. - * - * \sa open(OpenMode,int*,int*,bool,const char*) - **/ - bool isRaw()const {return raw;} - /// Binds to the existing QuaZip instance. - /** This function destroys internal QuaZip object, if any, and makes - * this QuaZipFile to use current file in the \a zip object for any - * further operations. See QuaZipFile(QuaZip*,QObject*) for the - * possible pitfalls. - * - * Will do nothing if the file is currently open. You must close() - * it first. - **/ - void setZip(QuaZip *zip); - /// Sets the file name. - /** Will do nothing if at least one of the following conditions is - * met: - * - ZIP name has not been set yet (getZipName() returns null - * string). - * - This QuaZipFile is associated with external QuaZip. In this - * case you should call that QuaZip's setCurrentFile() function - * instead! - * - File is already open so setting the name is meaningless. - * - * \sa QuaZip::setCurrentFile - **/ - void setFileName(const QString& fileName, QuaZip::CaseSensitivity cs =QuaZip::csDefault); - /// Opens a file for reading. - /** Returns \c true on success, \c false otherwise. - * Call getZipError() to get error code. - * - * \note Since ZIP/UNZIP API provides buffered reading only, - * QuaZipFile does not support unbuffered reading. So do not pass - * QIODevice::Unbuffered flag in \a mode, or open will fail. - **/ - virtual bool open(OpenMode mode); - /// Opens a file for reading. - /** \overload - * Argument \a password specifies a password to decrypt the file. If - * it is NULL then this function behaves just like open(OpenMode). - **/ - bool open(OpenMode mode, const char *password) - {return open(mode, NULL, NULL, false, password);} - /// Opens a file for reading. - /** \overload - * Argument \a password specifies a password to decrypt the file. - * - * An integers pointed by \a method and \a level will receive codes - * of the compression method and level used. See unzip.h. - * - * If raw is \c true then no decompression is performed. - * - * \a method should not be \c NULL. \a level can be \c NULL if you - * don't want to know the compression level. - **/ - bool open(OpenMode mode, int *method, int *level, bool raw, const char *password =NULL); - /// Opens a file for writing. - /** \a info argument specifies information about file. It should at - * least specify a correct file name. Also, it is a good idea to - * specify correct timestamp (by default, current time will be - * used). See QuaZipNewInfo. - * - * Arguments \a password and \a crc provide necessary information - * for crypting. Note that you should specify both of them if you - * need crypting. If you do not, pass \c NULL as password, but you - * still need to specify \a crc if you are going to use raw mode - * (see below). - * - * Arguments \a method and \a level specify compression method and - * level. - * - * If \a raw is \c true, no compression is performed. In this case, - * \a crc and uncompressedSize field of the \a info are required. - * - * Arguments \a windowBits, \a memLevel, \a strategy provide zlib - * algorithms tuning. See deflateInit2() in zlib. - **/ - bool open(OpenMode mode, const QuaZipNewInfo& info, - const char *password =NULL, quint32 crc =0, - int method =Z_DEFLATED, int level =Z_DEFAULT_COMPRESSION, bool raw =false, - int windowBits =-MAX_WBITS, int memLevel =DEF_MEM_LEVEL, int strategy =Z_DEFAULT_STRATEGY); - /// Returns \c true, but \ref quazipfile-sequential "beware"! - virtual bool isSequential()const; - /// Returns current position in the file. - /** Implementation of the QIODevice::pos(). When reading, this - * function is a wrapper to the ZIP/UNZIP unztell(), therefore it is - * unable to keep track of the ungetChar() calls (which is - * non-virtual and therefore is dangerous to reimplement). So if you - * are using ungetChar() feature of the QIODevice, this function - * reports incorrect value until you get back characters which you - * ungot. - * - * When writing, pos() returns number of bytes already written - * (uncompressed unless you use raw mode). - * - * \note Although - * \ref quazipfile-sequential "QuaZipFile is a sequential device" - * and therefore pos() should always return zero, it does not, - * because it would be misguiding. Keep this in mind. - * - * This function returns -1 if the file or archive is not open. - * - * Error code returned by getZipError() is not affected by this - * function call. - **/ - virtual qint64 pos()const; - /// Returns \c true if the end of file was reached. - /** This function returns \c false in the case of error. This means - * that you called this function on either not open file, or a file - * in the not open archive or even on a QuaZipFile instance that - * does not even have QuaZip instance associated. Do not do that - * because there is no means to determine whether \c false is - * returned because of error or because end of file was reached. - * Well, on the other side you may interpret \c false return value - * as "there is no file open to check for end of file and there is - * no end of file therefore". - * - * When writing, this function always returns \c true (because you - * are always writing to the end of file). - * - * Error code returned by getZipError() is not affected by this - * function call. - **/ - virtual bool atEnd()const; - /// Returns file size. - /** This function returns csize() if the file is open for reading in - * raw mode, usize() if it is open for reading in normal mode and - * pos() if it is open for writing. - * - * Returns -1 on error, call getZipError() to get error code. - * - * \note This function returns file size despite that - * \ref quazipfile-sequential "QuaZipFile is considered to be sequential device", - * for which size() should return bytesAvailable() instead. But its - * name would be very misguiding otherwise, so just keep in mind - * this inconsistence. - **/ - virtual qint64 size()const; - /// Returns compressed file size. - /** Equivalent to calling getFileInfo() and then getting - * compressedSize field, but more convenient and faster. - * - * File must be open for reading before calling this function. - * - * Returns -1 on error, call getZipError() to get error code. - **/ - qint64 csize()const; - /// Returns uncompressed file size. - /** Equivalent to calling getFileInfo() and then getting - * uncompressedSize field, but more convenient and faster. See - * getFileInfo() for a warning. - * - * File must be open for reading before calling this function. - * - * Returns -1 on error, call getZipError() to get error code. - **/ - qint64 usize()const; - /// Gets information about current file. - /** This function does the same thing as calling - * QuaZip::getCurrentFileInfo() on the associated QuaZip object, - * but you can not call getCurrentFileInfo() if the associated - * QuaZip is internal (because you do not have access to it), while - * you still can call this function in that case. - * - * File must be open for reading before calling this function. - * - * Returns \c false in the case of an error. - **/ - bool getFileInfo(QuaZipFileInfo *info); - /// Closes the file. - /** Call getZipError() to determine if the close was successful. - **/ - virtual void close(); - /// Returns the error code returned by the last ZIP/UNZIP API call. - int getZipError()const {return zipError;} -}; - -#endif diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/quazip/quazipfileinfo.h b/ground/gcs/src/libs/glc_lib/3rdparty/quazip/quazipfileinfo.h deleted file mode 100644 index 3216d776d..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/quazip/quazipfileinfo.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef QUA_ZIPFILEINFO_H -#define QUA_ZIPFILEINFO_H - -/* --- A kind of "standard" GPL license statement -- -QuaZIP - a Qt/C++ wrapper for the ZIP/UNZIP package -Copyright (C) 2005-2007 Sergey A. Tachenov - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2 of the License, or (at your -option) any later version. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program; if not, write to the Free Software Foundation, Inc., -59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - --- A kind of "standard" GPL license statement ends here -- - -See COPYING file for GPL. - -You are also permitted to use QuaZIP under the terms of LGPL (see -COPYING.LGPL). You are free to choose either license, but please note -that QuaZIP makes use of Qt, which is not licensed under LGPL. So if -you are using Open Source edition of Qt, you therefore MUST use GPL for -your code based on QuaZIP, since it would be also based on Qt in this -case. If you are Qt commercial license owner, then you are free to use -QuaZIP as long as you respect either GPL or LGPL for QuaZIP code. - **/ - -#include -#include - -/// Information about a file inside archive. -/** Call QuaZip::getCurrentFileInfo() or QuaZipFile::getFileInfo() to - * fill this structure. */ -struct QuaZipFileInfo { - /// File name. - QString name; - /// Version created by. - quint16 versionCreated; - /// Version needed to extract. - quint16 versionNeeded; - /// General purpose flags. - quint16 flags; - /// Compression method. - quint16 method; - /// Last modification date and time. - QDateTime dateTime; - /// CRC. - quint32 crc; - /// Compressed file size. - quint32 compressedSize; - /// Uncompressed file size. - quint32 uncompressedSize; - /// Disk number start. - quint16 diskNumberStart; - /// Internal file attributes. - quint16 internalAttr; - /// External file attributes. - quint32 externalAttr; - /// Comment. - QString comment; - /// Extra field. - QByteArray extra; -}; - -#endif diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/quazip/quazipnewinfo.cpp b/ground/gcs/src/libs/glc_lib/3rdparty/quazip/quazipnewinfo.cpp deleted file mode 100644 index 17571f2fc..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/quazip/quazipnewinfo.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* -- A kind of "standard" GPL license statement -- -QuaZIP - a Qt/C++ wrapper for the ZIP/UNZIP package -Copyright (C) 2005-2007 Sergey A. Tachenov - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2 of the License, or (at your -option) any later version. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program; if not, write to the Free Software Foundation, Inc., -59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - --- A kind of "standard" GPL license statement ends here -- - -See COPYING file for GPL. - -You are also permitted to use QuaZIP under the terms of LGPL (see -COPYING.LGPL). You are free to choose either license, but please note -that QuaZIP makes use of Qt, which is not licensed under LGPL. So if -you are using Open Source edition of Qt, you therefore MUST use GPL for -your code based on QuaZIP, since it would be also based on Qt in this -case. If you are Qt commercial license owner, then you are free to use -QuaZIP as long as you respect either GPL or LGPL for QuaZIP code. -*/ - -#include - -#include "quazipnewinfo.h" - - -QuaZipNewInfo::QuaZipNewInfo(const QString& name): - name(name), dateTime(QDateTime::currentDateTime()), internalAttr(0), externalAttr(0) -{ -} - -QuaZipNewInfo::QuaZipNewInfo(const QString& name, const QString& file): - name(name), internalAttr(0), externalAttr(0) -{ - QFileInfo info(file); - QDateTime lm = info.lastModified(); - if (!info.exists()) - dateTime = QDateTime::currentDateTime(); - else - dateTime = lm; -} - -void QuaZipNewInfo::setFileDateTime(const QString& file) -{ - QFileInfo info(file); - QDateTime lm = info.lastModified(); - if (info.exists()) - dateTime = lm; -} diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/quazip/quazipnewinfo.h b/ground/gcs/src/libs/glc_lib/3rdparty/quazip/quazipnewinfo.h deleted file mode 100644 index 93ff1a2fc..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/quazip/quazipnewinfo.h +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef QUA_ZIPNEWINFO_H -#define QUA_ZIPNEWINFO_H - -/* --- A kind of "standard" GPL license statement -- -QuaZIP - a Qt/C++ wrapper for the ZIP/UNZIP package -Copyright (C) 2005-2007 Sergey A. Tachenov - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2 of the License, or (at your -option) any later version. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program; if not, write to the Free Software Foundation, Inc., -59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - --- A kind of "standard" GPL license statement ends here -- - -See COPYING file for GPL. - -You are also permitted to use QuaZIP under the terms of LGPL (see -COPYING.LGPL). You are free to choose either license, but please note -that QuaZIP makes use of Qt, which is not licensed under LGPL. So if -you are using Open Source edition of Qt, you therefore MUST use GPL for -your code based on QuaZIP, since it would be also based on Qt in this -case. If you are Qt commercial license owner, then you are free to use -QuaZIP as long as you respect either GPL or LGPL for QuaZIP code. - **/ - -#include -#include - -/// Information about a file to be created. -/** This structure holds information about a file to be created inside - * ZIP archive. At least name should be set to something correct before - * passing this structure to - * QuaZipFile::open(OpenMode,const QuaZipNewInfo&,int,int,bool). - **/ -struct QuaZipNewInfo { - /// File name. - /** This field holds file name inside archive, including path relative - * to archive root. - **/ - QString name; - /// File timestamp. - /** This is the last file modification date and time. Will be stored - * in the archive central directory. It is a good practice to set it - * to the source file timestamp instead of archive creating time. Use - * setFileDateTime() or QuaZipNewInfo(const QString&, const QString&). - **/ - QDateTime dateTime; - /// File internal attributes. - quint16 internalAttr; - /// File external attributes. - quint32 externalAttr; - /// File comment. - /** Will be encoded using QuaZip::getCommentCodec(). - **/ - QString comment; - /// File local extra field. - QByteArray extraLocal; - /// File global extra field. - QByteArray extraGlobal; - /// Uncompressed file size. - /** This is only needed if you are using raw file zipping mode, i. e. - * adding precompressed file in the zip archive. - **/ - ulong uncompressedSize; - /// Constructs QuaZipNewInfo instance. - /** Initializes name with \a name, dateTime with current date and - * time. Attributes are initialized with zeros, comment and extra - * field with null values. - **/ - QuaZipNewInfo(const QString& name); - /// Constructs QuaZipNewInfo instance. - /** Initializes name with \a name and dateTime with timestamp of the - * file named \a file. If the \a file does not exists or its timestamp - * is inaccessible (e. g. you do not have read permission for the - * directory file in), uses current date and time. Attributes are - * initialized with zeros, comment and extra field with null values. - * - * \sa setFileDateTime() - **/ - QuaZipNewInfo(const QString& name, const QString& file); - /// Sets the file timestamp from the existing file. - /** Use this function to set the file timestamp from the existing - * file. Use it like this: - * \code - * QuaZipFile zipFile(&zip); - * QFile file("file-to-add"); - * file.open(QIODevice::ReadOnly); - * QuaZipNewInfo info("file-name-in-archive"); - * info.setFileDateTime("file-to-add"); // take the timestamp from file - * zipFile.open(QIODevice::WriteOnly, info); - * \endcode - * - * This function does not change dateTime if some error occured (e. g. - * file is inaccessible). - **/ - void setFileDateTime(const QString& file); -}; - -#endif diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/quazip/unzip.c b/ground/gcs/src/libs/glc_lib/3rdparty/quazip/unzip.c deleted file mode 100644 index ace7a0883..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/quazip/unzip.c +++ /dev/null @@ -1,1601 +0,0 @@ -/* unzip.c -- IO for uncompress .zip files using zlib - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant - - Read unzip.h for more info -*/ - -/* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of -compatibility with older software. The following is from the original crypt.c. Code -woven in by Terry Thorsen 1/2003. -*/ -/* - Copyright (c) 1990-2000 Info-ZIP. All rights reserved. - - See the accompanying file LICENSE, version 2000-Apr-09 or later - (the contents of which are also included in zip.h) for terms of use. - If, for some reason, all these files are missing, the Info-ZIP license - also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html -*/ -/* - crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] - - The encryption/decryption parts of this source code (as opposed to the - non-echoing password parts) were originally written in Europe. The - whole source package can be freely distributed, including from the USA. - (Prior to January 2000, re-export from the US was a violation of US law.) - */ - -/* - This encryption code is a direct transcription of the algorithm from - Roger Schlafly, described by Phil Katz in the file appnote.txt. This - file (appnote.txt) is distributed with the PKZIP program (even in the - version without encryption capabilities). - */ - - -#include -#include -#include -#include "zlib.h" -#include "unzip.h" - -#ifdef STDC -# include -# include -# include -#endif -#ifdef NO_ERRNO_H - extern int errno; -#else -# include -#endif - - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - - -#ifndef CASESENSITIVITYDEFAULT_NO -# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) -# define CASESENSITIVITYDEFAULT_NO -# endif -#endif - - -#ifndef UNZ_BUFSIZE -#define UNZ_BUFSIZE (16384) -#endif - -#ifndef UNZ_MAXFILENAMEINZIP -#define UNZ_MAXFILENAMEINZIP (256) -#endif - -#ifndef ALLOC -# define ALLOC(size) (malloc(size)) -#endif -#ifndef TRYFREE -# define TRYFREE(p) {if (p) free(p);} -#endif - -#define SIZECENTRALDIRITEM (0x2e) -#define SIZEZIPLOCALHEADER (0x1e) - - - - -const char unz_copyright[] = - " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; - -/* unz_file_info_interntal contain internal info about a file in zipfile*/ -typedef struct unz_file_info_internal_s -{ - uLong offset_curfile;/* relative offset of local header 4 bytes */ -} unz_file_info_internal; - - -/* file_in_zip_read_info_s contain internal information about a file in zipfile, - when reading and decompress it */ -typedef struct -{ - char *read_buffer; /* internal buffer for compressed data */ - z_stream stream; /* zLib stream structure for inflate */ - - uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ - uLong stream_initialised; /* flag set if stream structure is initialised*/ - - uLong offset_local_extrafield;/* offset of the local extra field */ - uInt size_local_extrafield;/* size of the local extra field */ - uLong pos_local_extrafield; /* position in the local extra field in read*/ - - uLong crc32; /* crc32 of all data uncompressed */ - uLong crc32_wait; /* crc32 we must obtain after decompress all */ - uLong rest_read_compressed; /* number of byte to be decompressed */ - uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/ - zlib_filefunc_def z_filefunc; - voidpf filestream; /* io structore of the zipfile */ - uLong compression_method; /* compression method (0==store) */ - uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ - int raw; -} file_in_zip_read_info_s; - - -/* unz_s contain internal information about the zipfile -*/ -typedef struct -{ - zlib_filefunc_def z_filefunc; - voidpf filestream; /* io structore of the zipfile */ - unz_global_info gi; /* public global information */ - uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ - uLong num_file; /* number of the current file in the zipfile*/ - uLong pos_in_central_dir; /* pos of the current file in the central dir*/ - uLong current_file_ok; /* flag about the usability of the current file*/ - uLong central_pos; /* position of the beginning of the central dir*/ - - uLong size_central_dir; /* size of the central directory */ - uLong offset_central_dir; /* offset of start of central directory with - respect to the starting disk number */ - - unz_file_info cur_file_info; /* public info about the current file in zip*/ - unz_file_info_internal cur_file_info_internal; /* private info about it*/ - file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current - file if we are decompressing it */ - int encrypted; -# ifndef NOUNCRYPT - unsigned long keys[3]; /* keys defining the pseudo-random sequence */ - const unsigned long* pcrc_32_tab; -# endif -} unz_s; - - -#ifndef NOUNCRYPT -#include "crypt.h" -#endif - -/* =========================================================================== - Read a byte from a gz_stream; update next_in and avail_in. Return EOF - for end of file. - IN assertion: the stream s has been sucessfully opened for reading. -*/ - - -local int unzlocal_getByte OF(( - const zlib_filefunc_def* pzlib_filefunc_def, - voidpf filestream, - int *pi)); - -local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi) - const zlib_filefunc_def* pzlib_filefunc_def; - voidpf filestream; - int *pi; -{ - unsigned char c; - int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1); - if (err==1) - { - *pi = (int)c; - return UNZ_OK; - } - else - { - if (ZERROR(*pzlib_filefunc_def,filestream)) - return UNZ_ERRNO; - else - return UNZ_EOF; - } -} - - -/* =========================================================================== - Reads a long in LSB order from the given gz_stream. Sets -*/ -local int unzlocal_getShort OF(( - const zlib_filefunc_def* pzlib_filefunc_def, - voidpf filestream, - uLong *pX)); - -local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX) - const zlib_filefunc_def* pzlib_filefunc_def; - voidpf filestream; - uLong *pX; -{ - uLong x ; - int i; - int err; - - err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); - x = (uLong)i; - - if (err==UNZ_OK) - err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<8; - - if (err==UNZ_OK) - *pX = x; - else - *pX = 0; - return err; -} - -local int unzlocal_getLong OF(( - const zlib_filefunc_def* pzlib_filefunc_def, - voidpf filestream, - uLong *pX)); - -local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX) - const zlib_filefunc_def* pzlib_filefunc_def; - voidpf filestream; - uLong *pX; -{ - uLong x ; - int i; - int err; - - err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); - x = (uLong)i; - - if (err==UNZ_OK) - err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<8; - - if (err==UNZ_OK) - err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<16; - - if (err==UNZ_OK) - err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<24; - - if (err==UNZ_OK) - *pX = x; - else - *pX = 0; - return err; -} - - -/* My own strcmpi / strcasecmp */ -local int strcmpcasenosensitive_internal (fileName1,fileName2) - const char* fileName1; - const char* fileName2; -{ - for (;;) - { - char c1=*(fileName1++); - char c2=*(fileName2++); - if ((c1>='a') && (c1<='z')) - c1 -= 0x20; - if ((c2>='a') && (c2<='z')) - c2 -= 0x20; - if (c1=='\0') - return ((c2=='\0') ? 0 : -1); - if (c2=='\0') - return 1; - if (c1c2) - return 1; - } -} - - -#ifdef CASESENSITIVITYDEFAULT_NO -#define CASESENSITIVITYDEFAULTVALUE 2 -#else -#define CASESENSITIVITYDEFAULTVALUE 1 -#endif - -#ifndef STRCMPCASENOSENTIVEFUNCTION -#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal -#endif - -/* - Compare two filename (fileName1,fileName2). - If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) - If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi - or strcasecmp) - If iCaseSenisivity = 0, case sensitivity is defaut of your operating system - (like 1 on Unix, 2 on Windows) - -*/ -extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity) - const char* fileName1; - const char* fileName2; - int iCaseSensitivity; -{ - if (iCaseSensitivity==0) - iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; - - if (iCaseSensitivity==1) - return strcmp(fileName1,fileName2); - - return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); -} - -#ifndef BUFREADCOMMENT -#define BUFREADCOMMENT (0x400) -#endif - -/* - Locate the Central directory of a zipfile (at the end, just before - the global comment) -*/ -local uLong unzlocal_SearchCentralDir OF(( - const zlib_filefunc_def* pzlib_filefunc_def, - voidpf filestream)); - -local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream) - const zlib_filefunc_def* pzlib_filefunc_def; - voidpf filestream; -{ - unsigned char* buf; - uLong uSizeFile; - uLong uBackRead; - uLong uMaxBack=0xffff; /* maximum size of global comment */ - uLong uPosFound=0; - - if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) - return 0; - - - uSizeFile = ZTELL(*pzlib_filefunc_def,filestream); - - if (uMaxBack>uSizeFile) - uMaxBack = uSizeFile; - - buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); - if (buf==NULL) - return 0; - - uBackRead = 4; - while (uBackReaduMaxBack) - uBackRead = uMaxBack; - else - uBackRead+=BUFREADCOMMENT; - uReadPos = uSizeFile-uBackRead ; - - uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? - (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); - if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) - break; - - if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) - break; - - for (i=(int)uReadSize-3; (i--)>0;) - if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && - ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) - { - uPosFound = uReadPos+i; - break; - } - - if (uPosFound!=0) - break; - } - TRYFREE(buf); - return uPosFound; -} - -/* - Open a Zip file. path contain the full pathname (by example, - on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer - "zlib/zlib114.zip". - If the zipfile cannot be opened (file doesn't exist or in not valid), the - return value is NULL. - Else, the return value is a unzFile Handle, usable with other function - of this unzip package. -*/ -extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def) - const char *path; - zlib_filefunc_def* pzlib_filefunc_def; -{ - unz_s us; - unz_s *s; - uLong central_pos,uL; - - uLong number_disk; /* number of the current dist, used for - spaning ZIP, unsupported, always 0*/ - uLong number_disk_with_CD; /* number the the disk with central dir, used - for spaning ZIP, unsupported, always 0*/ - uLong number_entry_CD; /* total number of entries in - the central dir - (same than number_entry on nospan) */ - - int err=UNZ_OK; - - if (unz_copyright[0]!=' ') - return NULL; - - if (pzlib_filefunc_def==NULL) - fill_fopen_filefunc(&us.z_filefunc); - else - us.z_filefunc = *pzlib_filefunc_def; - - us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque, - path, - ZLIB_FILEFUNC_MODE_READ | - ZLIB_FILEFUNC_MODE_EXISTING); - if (us.filestream==NULL) - return NULL; - - central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream); - if (central_pos==0) - err=UNZ_ERRNO; - - if (ZSEEK(us.z_filefunc, us.filestream, - central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) - err=UNZ_ERRNO; - - /* the signature, already checked */ - if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) - err=UNZ_ERRNO; - - /* number of this disk */ - if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) - err=UNZ_ERRNO; - - /* number of the disk with the start of the central directory */ - if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) - err=UNZ_ERRNO; - - /* total number of entries in the central dir on this disk */ - if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) - err=UNZ_ERRNO; - - /* total number of entries in the central dir */ - if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) - err=UNZ_ERRNO; - - if ((number_entry_CD!=us.gi.number_entry) || - (number_disk_with_CD!=0) || - (number_disk!=0)) - err=UNZ_BADZIPFILE; - - /* size of the central directory */ - if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) - err=UNZ_ERRNO; - - /* offset of start of central directory with respect to the - starting disk number */ - if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) - err=UNZ_ERRNO; - - /* zipfile comment length */ - if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) - err=UNZ_ERRNO; - - if ((central_pospfile_in_zip_read!=NULL) - unzCloseCurrentFile(file); - - ZCLOSE(s->z_filefunc, s->filestream); - TRYFREE(s); - return UNZ_OK; -} - - -/* - Write info about the ZipFile in the *pglobal_info structure. - No preparation of the structure is needed - return UNZ_OK if there is no problem. */ -extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info) - unzFile file; - unz_global_info *pglobal_info; -{ - unz_s* s; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - *pglobal_info=s->gi; - return UNZ_OK; -} - - -/* - Translate date/time from Dos format to tm_unz (readable more easilty) -*/ -local void unzlocal_DosDateToTmuDate (ulDosDate, ptm) - uLong ulDosDate; - tm_unz* ptm; -{ - uLong uDate; - uDate = (uLong)(ulDosDate>>16); - ptm->tm_mday = (uInt)(uDate&0x1f) ; - ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; - ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; - - ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); - ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; - ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; -} - -/* - Get Info about the current file in the zipfile, with internal only info -*/ -local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file, - unz_file_info *pfile_info, - unz_file_info_internal - *pfile_info_internal, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize)); - -local int unzlocal_GetCurrentFileInfoInternal (file, - pfile_info, - pfile_info_internal, - szFileName, fileNameBufferSize, - extraField, extraFieldBufferSize, - szComment, commentBufferSize) - unzFile file; - unz_file_info *pfile_info; - unz_file_info_internal *pfile_info_internal; - char *szFileName; - uLong fileNameBufferSize; - void *extraField; - uLong extraFieldBufferSize; - char *szComment; - uLong commentBufferSize; -{ - unz_s* s; - unz_file_info file_info; - unz_file_info_internal file_info_internal; - int err=UNZ_OK; - uLong uMagic; - long lSeek=0; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - if (ZSEEK(s->z_filefunc, s->filestream, - s->pos_in_central_dir+s->byte_before_the_zipfile, - ZLIB_FILEFUNC_SEEK_SET)!=0) - err=UNZ_ERRNO; - - - /* we check the magic */ - if (err==UNZ_OK) { - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) - err=UNZ_ERRNO; - else if (uMagic!=0x02014b50) - err=UNZ_BADZIPFILE; - } - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) - err=UNZ_ERRNO; - - unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) - err=UNZ_ERRNO; - - lSeek+=file_info.size_filename; - if ((err==UNZ_OK) && (szFileName!=NULL)) - { - uLong uSizeRead ; - if (file_info.size_filename0) && (fileNameBufferSize>0)) - if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) - err=UNZ_ERRNO; - lSeek -= uSizeRead; - } - - - if ((err==UNZ_OK) && (extraField!=NULL)) - { - uLong uSizeRead ; - if (file_info.size_file_extraz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) - lSeek=0; - else - err=UNZ_ERRNO; - } - if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) - if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead) - err=UNZ_ERRNO; - lSeek += file_info.size_file_extra - uSizeRead; - } - else - lSeek+=file_info.size_file_extra; - - - if ((err==UNZ_OK) && (szComment!=NULL)) - { - uLong uSizeRead ; - if (file_info.size_file_commentz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) - lSeek=0; - else - err=UNZ_ERRNO; - } - if ((file_info.size_file_comment>0) && (commentBufferSize>0)) - if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) - err=UNZ_ERRNO; - lSeek+=file_info.size_file_comment - uSizeRead; - } - else - lSeek+=file_info.size_file_comment; - - if ((err==UNZ_OK) && (pfile_info!=NULL)) - *pfile_info=file_info; - - if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) - *pfile_info_internal=file_info_internal; - - return err; -} - - - -/* - Write info about the ZipFile in the *pglobal_info structure. - No preparation of the structure is needed - return UNZ_OK if there is no problem. -*/ -extern int ZEXPORT unzGetCurrentFileInfo (file, - pfile_info, - szFileName, fileNameBufferSize, - extraField, extraFieldBufferSize, - szComment, commentBufferSize) - unzFile file; - unz_file_info *pfile_info; - char *szFileName; - uLong fileNameBufferSize; - void *extraField; - uLong extraFieldBufferSize; - char *szComment; - uLong commentBufferSize; -{ - return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL, - szFileName,fileNameBufferSize, - extraField,extraFieldBufferSize, - szComment,commentBufferSize); -} - -/* - Set the current file of the zipfile to the first file. - return UNZ_OK if there is no problem -*/ -extern int ZEXPORT unzGoToFirstFile (file) - unzFile file; -{ - int err=UNZ_OK; - unz_s* s; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - s->pos_in_central_dir=s->offset_central_dir; - s->num_file=0; - err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - s->current_file_ok = (err == UNZ_OK); - return err; -} - -/* - Set the current file of the zipfile to the next file. - return UNZ_OK if there is no problem - return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. -*/ -extern int ZEXPORT unzGoToNextFile (file) - unzFile file; -{ - unz_s* s; - int err; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - if (!s->current_file_ok) - return UNZ_END_OF_LIST_OF_FILE; - if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ - if (s->num_file+1==s->gi.number_entry) - return UNZ_END_OF_LIST_OF_FILE; - - s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + - s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; - s->num_file++; - err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - s->current_file_ok = (err == UNZ_OK); - return err; -} - - -/* - Try locate the file szFileName in the zipfile. - For the iCaseSensitivity signification, see unzipStringFileNameCompare - - return value : - UNZ_OK if the file is found. It becomes the current file. - UNZ_END_OF_LIST_OF_FILE if the file is not found -*/ -extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity) - unzFile file; - const char *szFileName; - int iCaseSensitivity; -{ - unz_s* s; - int err; - - /* We remember the 'current' position in the file so that we can jump - * back there if we fail. - */ - unz_file_info cur_file_infoSaved; - unz_file_info_internal cur_file_info_internalSaved; - uLong num_fileSaved; - uLong pos_in_central_dirSaved; - - - if (file==NULL) - return UNZ_PARAMERROR; - - if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) - return UNZ_PARAMERROR; - - s=(unz_s*)file; - if (!s->current_file_ok) - return UNZ_END_OF_LIST_OF_FILE; - - /* Save the current state */ - num_fileSaved = s->num_file; - pos_in_central_dirSaved = s->pos_in_central_dir; - cur_file_infoSaved = s->cur_file_info; - cur_file_info_internalSaved = s->cur_file_info_internal; - - err = unzGoToFirstFile(file); - - while (err == UNZ_OK) - { - char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; - err = unzGetCurrentFileInfo(file,NULL, - szCurrentFileName,sizeof(szCurrentFileName)-1, - NULL,0,NULL,0); - if (err == UNZ_OK) - { - if (unzStringFileNameCompare(szCurrentFileName, - szFileName,iCaseSensitivity)==0) - return UNZ_OK; - err = unzGoToNextFile(file); - } - } - - /* We failed, so restore the state of the 'current file' to where we - * were. - */ - s->num_file = num_fileSaved ; - s->pos_in_central_dir = pos_in_central_dirSaved ; - s->cur_file_info = cur_file_infoSaved; - s->cur_file_info_internal = cur_file_info_internalSaved; - return err; -} - - -/* -/////////////////////////////////////////// -// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) -// I need random access -// -// Further optimization could be realized by adding an ability -// to cache the directory in memory. The goal being a single -// comprehensive file read to put the file I need in a memory. -*/ - -/* -typedef struct unz_file_pos_s -{ - uLong pos_in_zip_directory; // offset in file - uLong num_of_file; // # of file -} unz_file_pos; -*/ - -extern int ZEXPORT unzGetFilePos(file, file_pos) - unzFile file; - unz_file_pos* file_pos; -{ - unz_s* s; - - if (file==NULL || file_pos==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - if (!s->current_file_ok) - return UNZ_END_OF_LIST_OF_FILE; - - file_pos->pos_in_zip_directory = s->pos_in_central_dir; - file_pos->num_of_file = s->num_file; - - return UNZ_OK; -} - -extern int ZEXPORT unzGoToFilePos(file, file_pos) - unzFile file; - unz_file_pos* file_pos; -{ - unz_s* s; - int err; - - if (file==NULL || file_pos==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - - /* jump to the right spot */ - s->pos_in_central_dir = file_pos->pos_in_zip_directory; - s->num_file = file_pos->num_of_file; - - /* set the current file */ - err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - /* return results */ - s->current_file_ok = (err == UNZ_OK); - return err; -} - -/* -// Unzip Helper Functions - should be here? -/////////////////////////////////////////// -*/ - -/* - Read the local header of the current zipfile - Check the coherency of the local header and info in the end of central - directory about this file - store in *piSizeVar the size of extra info in local header - (filename and size of extra field data) -*/ -local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar, - poffset_local_extrafield, - psize_local_extrafield) - unz_s* s; - uInt* piSizeVar; - uLong *poffset_local_extrafield; - uInt *psize_local_extrafield; -{ - uLong uMagic,uData,uFlags; - uLong size_filename; - uLong size_extra_field; - int err=UNZ_OK; - - *piSizeVar = 0; - *poffset_local_extrafield = 0; - *psize_local_extrafield = 0; - - if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + - s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) - return UNZ_ERRNO; - - - if (err==UNZ_OK) { - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) - err=UNZ_ERRNO; - else if (uMagic!=0x04034b50) - err=UNZ_BADZIPFILE; - } - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) - err=UNZ_ERRNO; -/* - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) - err=UNZ_BADZIPFILE; -*/ - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) - err=UNZ_BADZIPFILE; - - if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && - (s->cur_file_info.compression_method!=Z_DEFLATED)) - err=UNZ_BADZIPFILE; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ - err=UNZ_ERRNO; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && - ((uFlags & 8)==0)) - err=UNZ_BADZIPFILE; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && - ((uFlags & 8)==0)) - err=UNZ_BADZIPFILE; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && - ((uFlags & 8)==0)) - err=UNZ_BADZIPFILE; - - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) - err=UNZ_BADZIPFILE; - - *piSizeVar += (uInt)size_filename; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) - err=UNZ_ERRNO; - *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + - SIZEZIPLOCALHEADER + size_filename; - *psize_local_extrafield = (uInt)size_extra_field; - - *piSizeVar += (uInt)size_extra_field; - - return err; -} - -/* - Open for reading data the current file in the zipfile. - If there is no error and the file is opened, the return value is UNZ_OK. -*/ -extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password) - unzFile file; - int* method; - int* level; - int raw; - const char* password; -{ - int err=UNZ_OK; - uInt iSizeVar; - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - uLong offset_local_extrafield; /* offset of the local extra field */ - uInt size_local_extrafield; /* size of the local extra field */ -# ifndef NOUNCRYPT - char source[12]; -# else - if (password != NULL) - return UNZ_PARAMERROR; -# endif - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - if (!s->current_file_ok) - return UNZ_PARAMERROR; - - if (s->pfile_in_zip_read != NULL) - unzCloseCurrentFile(file); - - if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar, - &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) - return UNZ_BADZIPFILE; - - pfile_in_zip_read_info = (file_in_zip_read_info_s*) - ALLOC(sizeof(file_in_zip_read_info_s)); - if (pfile_in_zip_read_info==NULL) - return UNZ_INTERNALERROR; - - pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); - pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; - pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; - pfile_in_zip_read_info->pos_local_extrafield=0; - pfile_in_zip_read_info->raw=raw; - - if (pfile_in_zip_read_info->read_buffer==NULL) - { - TRYFREE(pfile_in_zip_read_info); - return UNZ_INTERNALERROR; - } - - pfile_in_zip_read_info->stream_initialised=0; - - if (method!=NULL) - *method = (int)s->cur_file_info.compression_method; - - if (level!=NULL) - { - *level = 6; - switch (s->cur_file_info.flag & 0x06) - { - case 6 : *level = 1; break; - case 4 : *level = 2; break; - case 2 : *level = 9; break; - } - } - - if ((s->cur_file_info.compression_method!=0) && - (s->cur_file_info.compression_method!=Z_DEFLATED)) - err=UNZ_BADZIPFILE; - - pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; - pfile_in_zip_read_info->crc32=0; - pfile_in_zip_read_info->compression_method = - s->cur_file_info.compression_method; - pfile_in_zip_read_info->filestream=s->filestream; - pfile_in_zip_read_info->z_filefunc=s->z_filefunc; - pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; - - pfile_in_zip_read_info->stream.total_out = 0; - - if ((s->cur_file_info.compression_method==Z_DEFLATED) && - (!raw)) - { - pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; - pfile_in_zip_read_info->stream.zfree = (free_func)0; - pfile_in_zip_read_info->stream.opaque = (voidpf)0; - pfile_in_zip_read_info->stream.next_in = (voidpf)0; - pfile_in_zip_read_info->stream.avail_in = 0; - - err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); - if (err == Z_OK) - pfile_in_zip_read_info->stream_initialised=1; - else - { - TRYFREE(pfile_in_zip_read_info); - return err; - } - /* windowBits is passed < 0 to tell that there is no zlib header. - * Note that in this case inflate *requires* an extra "dummy" byte - * after the compressed stream in order to complete decompression and - * return Z_STREAM_END. - * In unzip, i don't wait absolutely Z_STREAM_END because I known the - * size of both compressed and uncompressed data - */ - } - pfile_in_zip_read_info->rest_read_compressed = - s->cur_file_info.compressed_size ; - pfile_in_zip_read_info->rest_read_uncompressed = - s->cur_file_info.uncompressed_size ; - - - pfile_in_zip_read_info->pos_in_zipfile = - s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + - iSizeVar; - - pfile_in_zip_read_info->stream.avail_in = (uInt)0; - - s->pfile_in_zip_read = pfile_in_zip_read_info; - -# ifndef NOUNCRYPT - if (password != NULL) - { - int i; - s->pcrc_32_tab = get_crc_table(); - init_keys(password,s->keys,s->pcrc_32_tab); - if (ZSEEK(s->z_filefunc, s->filestream, - s->pfile_in_zip_read->pos_in_zipfile + - s->pfile_in_zip_read->byte_before_the_zipfile, - SEEK_SET)!=0) - return UNZ_INTERNALERROR; - if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12) - return UNZ_INTERNALERROR; - - for (i = 0; i<12; i++) - zdecode(s->keys,s->pcrc_32_tab,source[i]); - - s->pfile_in_zip_read->pos_in_zipfile+=12; - s->encrypted=1; - } -# endif - - - return UNZ_OK; -} - -extern int ZEXPORT unzOpenCurrentFile (file) - unzFile file; -{ - return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); -} - -extern int ZEXPORT unzOpenCurrentFilePassword (file, password) - unzFile file; - const char* password; -{ - return unzOpenCurrentFile3(file, NULL, NULL, 0, password); -} - -extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw) - unzFile file; - int* method; - int* level; - int raw; -{ - return unzOpenCurrentFile3(file, method, level, raw, NULL); -} - -/* - Read bytes from the current file. - buf contain buffer where data must be copied - len the size of buf. - - return the number of byte copied if somes bytes are copied - return 0 if the end of file was reached - return <0 with error code if there is an error - (UNZ_ERRNO for IO error, or zLib error for uncompress error) -*/ -extern int ZEXPORT unzReadCurrentFile (file, buf, len) - unzFile file; - voidp buf; - unsigned len; -{ - int err=UNZ_OK; - uInt iRead = 0; - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - - if ((pfile_in_zip_read_info->read_buffer == NULL)) - return UNZ_END_OF_LIST_OF_FILE; - if (len==0) - return 0; - - pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; - - pfile_in_zip_read_info->stream.avail_out = (uInt)len; - - if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && - (!(pfile_in_zip_read_info->raw))) - pfile_in_zip_read_info->stream.avail_out = - (uInt)pfile_in_zip_read_info->rest_read_uncompressed; - - if ((len>pfile_in_zip_read_info->rest_read_compressed+ - pfile_in_zip_read_info->stream.avail_in) && - (pfile_in_zip_read_info->raw)) - pfile_in_zip_read_info->stream.avail_out = - (uInt)pfile_in_zip_read_info->rest_read_compressed+ - pfile_in_zip_read_info->stream.avail_in; - - while (pfile_in_zip_read_info->stream.avail_out>0) - { - if ((pfile_in_zip_read_info->stream.avail_in==0) && - (pfile_in_zip_read_info->rest_read_compressed>0)) - { - uInt uReadThis = UNZ_BUFSIZE; - if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; - if (uReadThis == 0) - return UNZ_EOF; - if (ZSEEK(pfile_in_zip_read_info->z_filefunc, - pfile_in_zip_read_info->filestream, - pfile_in_zip_read_info->pos_in_zipfile + - pfile_in_zip_read_info->byte_before_the_zipfile, - ZLIB_FILEFUNC_SEEK_SET)!=0) - return UNZ_ERRNO; - if (ZREAD(pfile_in_zip_read_info->z_filefunc, - pfile_in_zip_read_info->filestream, - pfile_in_zip_read_info->read_buffer, - uReadThis)!=uReadThis) - return UNZ_ERRNO; - - -# ifndef NOUNCRYPT - if(s->encrypted) - { - uInt i; - for(i=0;iread_buffer[i] = - zdecode(s->keys,s->pcrc_32_tab, - pfile_in_zip_read_info->read_buffer[i]); - } -# endif - - - pfile_in_zip_read_info->pos_in_zipfile += uReadThis; - - pfile_in_zip_read_info->rest_read_compressed-=uReadThis; - - pfile_in_zip_read_info->stream.next_in = - (Bytef*)pfile_in_zip_read_info->read_buffer; - pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; - } - - if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) - { - uInt uDoCopy,i ; - - if ((pfile_in_zip_read_info->stream.avail_in == 0) && - (pfile_in_zip_read_info->rest_read_compressed == 0)) - return (iRead==0) ? UNZ_EOF : iRead; - - if (pfile_in_zip_read_info->stream.avail_out < - pfile_in_zip_read_info->stream.avail_in) - uDoCopy = pfile_in_zip_read_info->stream.avail_out ; - else - uDoCopy = pfile_in_zip_read_info->stream.avail_in ; - - for (i=0;istream.next_out+i) = - *(pfile_in_zip_read_info->stream.next_in+i); - - pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, - pfile_in_zip_read_info->stream.next_out, - uDoCopy); - pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; - pfile_in_zip_read_info->stream.avail_in -= uDoCopy; - pfile_in_zip_read_info->stream.avail_out -= uDoCopy; - pfile_in_zip_read_info->stream.next_out += uDoCopy; - pfile_in_zip_read_info->stream.next_in += uDoCopy; - pfile_in_zip_read_info->stream.total_out += uDoCopy; - iRead += uDoCopy; - } - else - { - uLong uTotalOutBefore,uTotalOutAfter; - const Bytef *bufBefore; - uLong uOutThis; - int flush=Z_SYNC_FLUSH; - - uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; - bufBefore = pfile_in_zip_read_info->stream.next_out; - - /* - if ((pfile_in_zip_read_info->rest_read_uncompressed == - pfile_in_zip_read_info->stream.avail_out) && - (pfile_in_zip_read_info->rest_read_compressed == 0)) - flush = Z_FINISH; - */ - err=inflate(&pfile_in_zip_read_info->stream,flush); - - if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) - err = Z_DATA_ERROR; - - uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; - uOutThis = uTotalOutAfter-uTotalOutBefore; - - pfile_in_zip_read_info->crc32 = - crc32(pfile_in_zip_read_info->crc32,bufBefore, - (uInt)(uOutThis)); - - pfile_in_zip_read_info->rest_read_uncompressed -= - uOutThis; - - iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); - - if (err==Z_STREAM_END) - return (iRead==0) ? UNZ_EOF : iRead; - if (err!=Z_OK) - break; - } - } - - if (err==Z_OK) - return iRead; - return err; -} - - -/* - Give the current position in uncompressed data -*/ -extern z_off_t ZEXPORT unztell (file) - unzFile file; -{ - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - return (z_off_t)pfile_in_zip_read_info->stream.total_out; -} - - -/* - return 1 if the end of file was reached, 0 elsewhere -*/ -extern int ZEXPORT unzeof (file) - unzFile file; -{ - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - if (pfile_in_zip_read_info->rest_read_uncompressed == 0) - return 1; - else - return 0; -} - - - -/* - Read extra field from the current file (opened by unzOpenCurrentFile) - This is the local-header version of the extra field (sometimes, there is - more info in the local-header version than in the central-header) - - if buf==NULL, it return the size of the local extra field that can be read - - if buf!=NULL, len is the size of the buffer, the extra header is copied in - buf. - the return value is the number of bytes copied in buf, or (if <0) - the error code -*/ -extern int ZEXPORT unzGetLocalExtrafield (file,buf,len) - unzFile file; - voidp buf; - unsigned len; -{ - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - uInt read_now; - uLong size_to_read; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - size_to_read = (pfile_in_zip_read_info->size_local_extrafield - - pfile_in_zip_read_info->pos_local_extrafield); - - if (buf==NULL) - return (int)size_to_read; - - if (len>size_to_read) - read_now = (uInt)size_to_read; - else - read_now = (uInt)len ; - - if (read_now==0) - return 0; - - if (ZSEEK(pfile_in_zip_read_info->z_filefunc, - pfile_in_zip_read_info->filestream, - pfile_in_zip_read_info->offset_local_extrafield + - pfile_in_zip_read_info->pos_local_extrafield, - ZLIB_FILEFUNC_SEEK_SET)!=0) - return UNZ_ERRNO; - - if (ZREAD(pfile_in_zip_read_info->z_filefunc, - pfile_in_zip_read_info->filestream, - buf,read_now)!=read_now) - return UNZ_ERRNO; - - return (int)read_now; -} - -/* - Close the file in zip opened with unzipOpenCurrentFile - Return UNZ_CRCERROR if all the file was read but the CRC is not good -*/ -extern int ZEXPORT unzCloseCurrentFile (file) - unzFile file; -{ - int err=UNZ_OK; - - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - - if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && - (!pfile_in_zip_read_info->raw)) - { - if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) - err=UNZ_CRCERROR; - } - - - TRYFREE(pfile_in_zip_read_info->read_buffer); - pfile_in_zip_read_info->read_buffer = NULL; - if (pfile_in_zip_read_info->stream_initialised) - inflateEnd(&pfile_in_zip_read_info->stream); - - pfile_in_zip_read_info->stream_initialised = 0; - TRYFREE(pfile_in_zip_read_info); - - s->pfile_in_zip_read=NULL; - - return err; -} - - -/* - Get the global comment string of the ZipFile, in the szComment buffer. - uSizeBuf is the size of the szComment buffer. - return the number of byte copied or an error code <0 -*/ -extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf) - unzFile file; - char *szComment; - uLong uSizeBuf; -{ - unz_s* s; - uLong uReadThis ; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - - uReadThis = uSizeBuf; - if (uReadThis>s->gi.size_comment) - uReadThis = s->gi.size_comment; - - if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) - return UNZ_ERRNO; - - if (uReadThis>0) - { - *szComment='\0'; - if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) - return UNZ_ERRNO; - } - - if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) - *(szComment+s->gi.size_comment)='\0'; - return (int)uReadThis; -} - -/* Additions by RX '2004 */ -extern uLong ZEXPORT unzGetOffset (file) - unzFile file; -{ - unz_s* s; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - if (!s->current_file_ok) - return 0; - if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) - if (s->num_file==s->gi.number_entry) - return 0; - return s->pos_in_central_dir; -} - -extern int ZEXPORT unzSetOffset (file, pos) - unzFile file; - uLong pos; -{ - unz_s* s; - int err; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - - s->pos_in_central_dir = pos; - s->num_file = s->gi.number_entry; /* hack */ - err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - s->current_file_ok = (err == UNZ_OK); - return err; -} diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/quazip/unzip.h b/ground/gcs/src/libs/glc_lib/3rdparty/quazip/unzip.h deleted file mode 100644 index b247937c8..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/quazip/unzip.h +++ /dev/null @@ -1,354 +0,0 @@ -/* unzip.h -- IO for uncompress .zip files using zlib - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant - - This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g - WinZip, InfoZip tools and compatible. - - Multi volume ZipFile (span) are not supported. - Encryption compatible with pkzip 2.04g only supported - Old compressions used by old PKZip 1.x are not supported - - - I WAIT FEEDBACK at mail info@winimage.com - Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution - - Condition of use and distribution are the same than zlib : - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - -*/ - -/* for more info about .ZIP format, see - http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip - http://www.info-zip.org/pub/infozip/doc/ - PkWare has also a specification at : - ftp://ftp.pkware.com/probdesc.zip -*/ - -#ifndef _unz_H -#define _unz_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _ZLIB_H -#include "zlib.h" -#endif - -#ifndef _ZLIBIOAPI_H -#include "ioapi.h" -#endif - -#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) -/* like the STRICT of WIN32, we define a pointer that cannot be converted - from (void*) without cast */ -typedef struct TagunzFile__ { int unused; } unzFile__; -typedef unzFile__ *unzFile; -#else -typedef voidp unzFile; -#endif - - -#define UNZ_OK (0) -#define UNZ_END_OF_LIST_OF_FILE (-100) -#define UNZ_ERRNO (Z_ERRNO) -#define UNZ_EOF (0) -#define UNZ_PARAMERROR (-102) -#define UNZ_BADZIPFILE (-103) -#define UNZ_INTERNALERROR (-104) -#define UNZ_CRCERROR (-105) - -/* tm_unz contain date/time info */ -typedef struct tm_unz_s -{ - uInt tm_sec; /* seconds after the minute - [0,59] */ - uInt tm_min; /* minutes after the hour - [0,59] */ - uInt tm_hour; /* hours since midnight - [0,23] */ - uInt tm_mday; /* day of the month - [1,31] */ - uInt tm_mon; /* months since January - [0,11] */ - uInt tm_year; /* years - [1980..2044] */ -} tm_unz; - -/* unz_global_info structure contain global data about the ZIPfile - These data comes from the end of central dir */ -typedef struct unz_global_info_s -{ - uLong number_entry; /* total number of entries in - the central dir on this disk */ - uLong size_comment; /* size of the global comment of the zipfile */ -} unz_global_info; - - -/* unz_file_info contain information about a file in the zipfile */ -typedef struct unz_file_info_s -{ - uLong version; /* version made by 2 bytes */ - uLong version_needed; /* version needed to extract 2 bytes */ - uLong flag; /* general purpose bit flag 2 bytes */ - uLong compression_method; /* compression method 2 bytes */ - uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ - uLong crc; /* crc-32 4 bytes */ - uLong compressed_size; /* compressed size 4 bytes */ - uLong uncompressed_size; /* uncompressed size 4 bytes */ - uLong size_filename; /* filename length 2 bytes */ - uLong size_file_extra; /* extra field length 2 bytes */ - uLong size_file_comment; /* file comment length 2 bytes */ - - uLong disk_num_start; /* disk number start 2 bytes */ - uLong internal_fa; /* internal file attributes 2 bytes */ - uLong external_fa; /* external file attributes 4 bytes */ - - tm_unz tmu_date; -} unz_file_info; - -extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, - const char* fileName2, - int iCaseSensitivity)); -/* - Compare two filename (fileName1,fileName2). - If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) - If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi - or strcasecmp) - If iCaseSenisivity = 0, case sensitivity is defaut of your operating system - (like 1 on Unix, 2 on Windows) -*/ - - -extern unzFile ZEXPORT unzOpen OF((const char *path)); -/* - Open a Zip file. path contain the full pathname (by example, - on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer - "zlib/zlib113.zip". - If the zipfile cannot be opened (file don't exist or in not valid), the - return value is NULL. - Else, the return value is a unzFile Handle, usable with other function - of this unzip package. -*/ - -extern unzFile ZEXPORT unzOpen2 OF((const char *path, - zlib_filefunc_def* pzlib_filefunc_def)); -/* - Open a Zip file, like unzOpen, but provide a set of file low level API - for read/write the zip file (see ioapi.h) -*/ - -extern int ZEXPORT unzClose OF((unzFile file)); -/* - Close a ZipFile opened with unzipOpen. - If there is files inside the .Zip opened with unzOpenCurrentFile (see later), - these files MUST be closed with unzipCloseCurrentFile before call unzipClose. - return UNZ_OK if there is no problem. */ - -extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, - unz_global_info *pglobal_info)); -/* - Write info about the ZipFile in the *pglobal_info structure. - No preparation of the structure is needed - return UNZ_OK if there is no problem. */ - - -extern int ZEXPORT unzGetGlobalComment OF((unzFile file, - char *szComment, - uLong uSizeBuf)); -/* - Get the global comment string of the ZipFile, in the szComment buffer. - uSizeBuf is the size of the szComment buffer. - return the number of byte copied or an error code <0 -*/ - - -/***************************************************************************/ -/* Unzip package allow you browse the directory of the zipfile */ - -extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); -/* - Set the current file of the zipfile to the first file. - return UNZ_OK if there is no problem -*/ - -extern int ZEXPORT unzGoToNextFile OF((unzFile file)); -/* - Set the current file of the zipfile to the next file. - return UNZ_OK if there is no problem - return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. -*/ - -extern int ZEXPORT unzLocateFile OF((unzFile file, - const char *szFileName, - int iCaseSensitivity)); -/* - Try locate the file szFileName in the zipfile. - For the iCaseSensitivity signification, see unzStringFileNameCompare - - return value : - UNZ_OK if the file is found. It becomes the current file. - UNZ_END_OF_LIST_OF_FILE if the file is not found -*/ - - -/* ****************************************** */ -/* Ryan supplied functions */ -/* unz_file_info contain information about a file in the zipfile */ -typedef struct unz_file_pos_s -{ - uLong pos_in_zip_directory; /* offset in zip file directory */ - uLong num_of_file; /* # of file */ -} unz_file_pos; - -extern int ZEXPORT unzGetFilePos( - unzFile file, - unz_file_pos* file_pos); - -extern int ZEXPORT unzGoToFilePos( - unzFile file, - unz_file_pos* file_pos); - -/* ****************************************** */ - -extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, - unz_file_info *pfile_info, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize)); -/* - Get Info about the current file - if pfile_info!=NULL, the *pfile_info structure will contain somes info about - the current file - if szFileName!=NULL, the filemane string will be copied in szFileName - (fileNameBufferSize is the size of the buffer) - if extraField!=NULL, the extra field information will be copied in extraField - (extraFieldBufferSize is the size of the buffer). - This is the Central-header version of the extra field - if szComment!=NULL, the comment string of the file will be copied in szComment - (commentBufferSize is the size of the buffer) -*/ - -/***************************************************************************/ -/* for reading the content of the current zipfile, you can open it, read data - from it, and close it (you can close it before reading all the file) - */ - -extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); -/* - Open for reading data the current file in the zipfile. - If there is no error, the return value is UNZ_OK. -*/ - -extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, - const char* password)); -/* - Open for reading data the current file in the zipfile. - password is a crypting password - If there is no error, the return value is UNZ_OK. -*/ - -extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, - int* method, - int* level, - int raw)); -/* - Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) - if raw==1 - *method will receive method of compression, *level will receive level of - compression - note : you can set level parameter as NULL (if you did not want known level, - but you CANNOT set method parameter as NULL -*/ - -extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, - int* method, - int* level, - int raw, - const char* password)); -/* - Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) - if raw==1 - *method will receive method of compression, *level will receive level of - compression - note : you can set level parameter as NULL (if you did not want known level, - but you CANNOT set method parameter as NULL -*/ - - -extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); -/* - Close the file in zip opened with unzOpenCurrentFile - Return UNZ_CRCERROR if all the file was read but the CRC is not good -*/ - -extern int ZEXPORT unzReadCurrentFile OF((unzFile file, - voidp buf, - unsigned len)); -/* - Read bytes from the current file (opened by unzOpenCurrentFile) - buf contain buffer where data must be copied - len the size of buf. - - return the number of byte copied if somes bytes are copied - return 0 if the end of file was reached - return <0 with error code if there is an error - (UNZ_ERRNO for IO error, or zLib error for uncompress error) -*/ - -extern z_off_t ZEXPORT unztell OF((unzFile file)); -/* - Give the current position in uncompressed data -*/ - -extern int ZEXPORT unzeof OF((unzFile file)); -/* - return 1 if the end of file was reached, 0 elsewhere -*/ - -extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, - voidp buf, - unsigned len)); -/* - Read extra field from the current file (opened by unzOpenCurrentFile) - This is the local-header version of the extra field (sometimes, there is - more info in the local-header version than in the central-header) - - if buf==NULL, it return the size of the local extra field - - if buf!=NULL, len is the size of the buffer, the extra header is copied in - buf. - the return value is the number of bytes copied in buf, or (if <0) - the error code -*/ - -/***************************************************************************/ - -/* Get the current file offset */ -extern uLong ZEXPORT unzGetOffset (unzFile file); - -/* Set the current file offset */ -extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); - - - -#ifdef __cplusplus -} -#endif - -#endif /* _unz_H */ diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/quazip/zip.c b/ground/gcs/src/libs/glc_lib/3rdparty/quazip/zip.c deleted file mode 100644 index 240660495..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/quazip/zip.c +++ /dev/null @@ -1,1221 +0,0 @@ -/* zip.c -- IO on .zip files using zlib - Version 1.01e, February 12th, 2005 - - 27 Dec 2004 Rolf Kalbermatter - Modification to zipOpen2 to support globalComment retrieval. - - Copyright (C) 1998-2005 Gilles Vollant - - Read zip.h for more info -*/ - - -#include -#include -#include -#include -#include "zlib.h" -#include "zip.h" - -#ifdef STDC -# include -# include -# include -#endif -#ifdef NO_ERRNO_H - extern int errno; -#else -# include -#endif - - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - -#ifndef VERSIONMADEBY -# define VERSIONMADEBY (0x0) /* platform depedent */ -#endif - -#ifndef Z_BUFSIZE -#define Z_BUFSIZE (16384) -#endif - -#ifndef Z_MAXFILENAMEINZIP -#define Z_MAXFILENAMEINZIP (256) -#endif - -#ifndef ALLOC -# define ALLOC(size) (malloc(size)) -#endif -#ifndef TRYFREE -# define TRYFREE(p) {if (p) free(p);} -#endif - -/* -#define SIZECENTRALDIRITEM (0x2e) -#define SIZEZIPLOCALHEADER (0x1e) -*/ - -/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ - -#ifndef SEEK_CUR -#define SEEK_CUR 1 -#endif - -#ifndef SEEK_END -#define SEEK_END 2 -#endif - -#ifndef SEEK_SET -#define SEEK_SET 0 -#endif - -#ifndef DEF_MEM_LEVEL -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -#endif -const char zip_copyright[] = - " zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; - - -#define SIZEDATA_INDATABLOCK (4096-(4*4)) - -#define LOCALHEADERMAGIC (0x04034b50) -#define CENTRALHEADERMAGIC (0x02014b50) -#define ENDHEADERMAGIC (0x06054b50) - -#define FLAG_LOCALHEADER_OFFSET (0x06) -#define CRC_LOCALHEADER_OFFSET (0x0e) - -#define SIZECENTRALHEADER (0x2e) /* 46 */ - -typedef struct linkedlist_datablock_internal_s -{ - struct linkedlist_datablock_internal_s* next_datablock; - uLong avail_in_this_block; - uLong filled_in_this_block; - uLong unused; /* for future use and alignement */ - unsigned char data[SIZEDATA_INDATABLOCK]; -} linkedlist_datablock_internal; - -typedef struct linkedlist_data_s -{ - linkedlist_datablock_internal* first_block; - linkedlist_datablock_internal* last_block; -} linkedlist_data; - - -typedef struct -{ - z_stream stream; /* zLib stream structure for inflate */ - int stream_initialised; /* 1 is stream is initialised */ - uInt pos_in_buffered_data; /* last written byte in buffered_data */ - - uLong pos_local_header; /* offset of the local header of the file - currenty writing */ - char* central_header; /* central header data for the current file */ - uLong size_centralheader; /* size of the central header for cur file */ - uLong flag; /* flag of the file currently writing */ - - int method; /* compression method of file currenty wr.*/ - int raw; /* 1 for directly writing raw data */ - Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/ - uLong dosDate; - uLong crc32; - int encrypt; -#ifndef NOCRYPT - unsigned long keys[3]; /* keys defining the pseudo-random sequence */ - const unsigned long* pcrc_32_tab; - int crypt_header_size; -#endif -} curfile_info; - -typedef struct -{ - zlib_filefunc_def z_filefunc; - voidpf filestream; /* io structore of the zipfile */ - linkedlist_data central_dir;/* datablock with central dir in construction*/ - int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ - curfile_info ci; /* info on the file curretly writing */ - - uLong begin_pos; /* position of the beginning of the zipfile */ - uLong add_position_when_writting_offset; - uLong number_entry; -#ifndef NO_ADDFILEINEXISTINGZIP - char *globalcomment; -#endif -} zip_internal; - - - -#ifndef NOCRYPT -#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED -#include "crypt.h" -#endif - -local linkedlist_datablock_internal* allocate_new_datablock() -{ - linkedlist_datablock_internal* ldi; - ldi = (linkedlist_datablock_internal*) - ALLOC(sizeof(linkedlist_datablock_internal)); - if (ldi!=NULL) - { - ldi->next_datablock = NULL ; - ldi->filled_in_this_block = 0 ; - ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ; - } - return ldi; -} - -local void free_datablock(ldi) - linkedlist_datablock_internal* ldi; -{ - while (ldi!=NULL) - { - linkedlist_datablock_internal* ldinext = ldi->next_datablock; - TRYFREE(ldi); - ldi = ldinext; - } -} - -local void init_linkedlist(ll) - linkedlist_data* ll; -{ - ll->first_block = ll->last_block = NULL; -} - -#if 0 // unused -local void free_linkedlist(ll) - linkedlist_data* ll; -{ - free_datablock(ll->first_block); - ll->first_block = ll->last_block = NULL; -} -#endif - -local int add_data_in_datablock(ll,buf,len) - linkedlist_data* ll; - const void* buf; - uLong len; -{ - linkedlist_datablock_internal* ldi; - const unsigned char* from_copy; - - if (ll==NULL) - return ZIP_INTERNALERROR; - - if (ll->last_block == NULL) - { - ll->first_block = ll->last_block = allocate_new_datablock(); - if (ll->first_block == NULL) - return ZIP_INTERNALERROR; - } - - ldi = ll->last_block; - from_copy = (unsigned char*)buf; - - while (len>0) - { - uInt copy_this; - uInt i; - unsigned char* to_copy; - - if (ldi->avail_in_this_block==0) - { - ldi->next_datablock = allocate_new_datablock(); - if (ldi->next_datablock == NULL) - return ZIP_INTERNALERROR; - ldi = ldi->next_datablock ; - ll->last_block = ldi; - } - - if (ldi->avail_in_this_block < len) - copy_this = (uInt)ldi->avail_in_this_block; - else - copy_this = (uInt)len; - - to_copy = &(ldi->data[ldi->filled_in_this_block]); - - for (i=0;ifilled_in_this_block += copy_this; - ldi->avail_in_this_block -= copy_this; - from_copy += copy_this ; - len -= copy_this; - } - return ZIP_OK; -} - - - -/****************************************************************************/ - -#ifndef NO_ADDFILEINEXISTINGZIP -/* =========================================================================== - Inputs a long in LSB order to the given file - nbByte == 1, 2 or 4 (byte, short or long) -*/ - -local int ziplocal_putValue OF((const zlib_filefunc_def* pzlib_filefunc_def, - voidpf filestream, uLong x, int nbByte)); -local int ziplocal_putValue (pzlib_filefunc_def, filestream, x, nbByte) - const zlib_filefunc_def* pzlib_filefunc_def; - voidpf filestream; - uLong x; - int nbByte; -{ - unsigned char buf[4]; - int n; - for (n = 0; n < nbByte; n++) - { - buf[n] = (unsigned char)(x & 0xff); - x >>= 8; - } - if (x != 0) - { /* data overflow - hack for ZIP64 (X Roche) */ - for (n = 0; n < nbByte; n++) - { - buf[n] = 0xff; - } - } - - if (ZWRITE(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte) - return ZIP_ERRNO; - else - return ZIP_OK; -} - -local void ziplocal_putValue_inmemory OF((void* dest, uLong x, int nbByte)); -local void ziplocal_putValue_inmemory (dest, x, nbByte) - void* dest; - uLong x; - int nbByte; -{ - unsigned char* buf=(unsigned char*)dest; - int n; - for (n = 0; n < nbByte; n++) { - buf[n] = (unsigned char)(x & 0xff); - x >>= 8; - } - - if (x != 0) - { /* data overflow - hack for ZIP64 */ - for (n = 0; n < nbByte; n++) - { - buf[n] = 0xff; - } - } -} - -/****************************************************************************/ - - -local uLong ziplocal_TmzDateToDosDate(ptm,dosDate) - const tm_zip* ptm; - uLong dosDate; -{ - //(void) dosDate; /* avoid "unused parameter" warning */ - uLong year = (uLong)ptm->tm_year; - if (year>1980) - year-=1980; - else if (year>80) - year-=80; - return - (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) | - ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour)); -} - - -/****************************************************************************/ - -local int ziplocal_getByte OF(( - const zlib_filefunc_def* pzlib_filefunc_def, - voidpf filestream, - int *pi)); - -local int ziplocal_getByte(pzlib_filefunc_def,filestream,pi) - const zlib_filefunc_def* pzlib_filefunc_def; - voidpf filestream; - int *pi; -{ - unsigned char c; - int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1); - if (err==1) - { - *pi = (int)c; - return ZIP_OK; - } - else - { - if (ZERROR(*pzlib_filefunc_def,filestream)) - return ZIP_ERRNO; - else - return ZIP_EOF; - } -} - - -/* =========================================================================== - Reads a long in LSB order from the given gz_stream. Sets -*/ -local int ziplocal_getShort OF(( - const zlib_filefunc_def* pzlib_filefunc_def, - voidpf filestream, - uLong *pX)); - -local int ziplocal_getShort (pzlib_filefunc_def,filestream,pX) - const zlib_filefunc_def* pzlib_filefunc_def; - voidpf filestream; - uLong *pX; -{ - uLong x ; - int i; - int err; - - err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); - x = (uLong)i; - - if (err==ZIP_OK) - err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<8; - - if (err==ZIP_OK) - *pX = x; - else - *pX = 0; - return err; -} - -local int ziplocal_getLong OF(( - const zlib_filefunc_def* pzlib_filefunc_def, - voidpf filestream, - uLong *pX)); - -local int ziplocal_getLong (pzlib_filefunc_def,filestream,pX) - const zlib_filefunc_def* pzlib_filefunc_def; - voidpf filestream; - uLong *pX; -{ - uLong x ; - int i; - int err; - - err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); - x = (uLong)i; - - if (err==ZIP_OK) - err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<8; - - if (err==ZIP_OK) - err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<16; - - if (err==ZIP_OK) - err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<24; - - if (err==ZIP_OK) - *pX = x; - else - *pX = 0; - return err; -} - -#ifndef BUFREADCOMMENT -#define BUFREADCOMMENT (0x400) -#endif -/* - Locate the Central directory of a zipfile (at the end, just before - the global comment) -*/ -local uLong ziplocal_SearchCentralDir OF(( - const zlib_filefunc_def* pzlib_filefunc_def, - voidpf filestream)); - -local uLong ziplocal_SearchCentralDir(pzlib_filefunc_def,filestream) - const zlib_filefunc_def* pzlib_filefunc_def; - voidpf filestream; -{ - unsigned char* buf; - uLong uSizeFile; - uLong uBackRead; - uLong uMaxBack=0xffff; /* maximum size of global comment */ - uLong uPosFound=0; - - if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) - return 0; - - - uSizeFile = ZTELL(*pzlib_filefunc_def,filestream); - - if (uMaxBack>uSizeFile) - uMaxBack = uSizeFile; - - buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); - if (buf==NULL) - return 0; - - uBackRead = 4; - while (uBackReaduMaxBack) - uBackRead = uMaxBack; - else - uBackRead+=BUFREADCOMMENT; - uReadPos = uSizeFile-uBackRead ; - - uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? - (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); - if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) - break; - - if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) - break; - - for (i=(int)uReadSize-3; (i--)>0;) - if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && - ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) - { - uPosFound = uReadPos+i; - break; - } - - if (uPosFound!=0) - break; - } - TRYFREE(buf); - return uPosFound; -} -#endif /* !NO_ADDFILEINEXISTINGZIP*/ - -/************************************************************/ -extern zipFile ZEXPORT zipOpen2 (pathname, append, globalcomment, pzlib_filefunc_def) - const char *pathname; - int append; - zipcharpc* globalcomment; - zlib_filefunc_def* pzlib_filefunc_def; -{ - zip_internal ziinit; - zip_internal* zi; - int err=ZIP_OK; - - - if (pzlib_filefunc_def==NULL) - fill_fopen_filefunc(&ziinit.z_filefunc); - else - ziinit.z_filefunc = *pzlib_filefunc_def; - - ziinit.filestream = (*(ziinit.z_filefunc.zopen_file)) - (ziinit.z_filefunc.opaque, - pathname, - (append == APPEND_STATUS_CREATE) ? - (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) : - (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING)); - - if (ziinit.filestream == NULL) - return NULL; - ziinit.begin_pos = ZTELL(ziinit.z_filefunc,ziinit.filestream); - ziinit.in_opened_file_inzip = 0; - ziinit.ci.stream_initialised = 0; - ziinit.number_entry = 0; - ziinit.add_position_when_writting_offset = 0; - init_linkedlist(&(ziinit.central_dir)); - - - zi = (zip_internal*)ALLOC(sizeof(zip_internal)); - if (zi==NULL) - { - ZCLOSE(ziinit.z_filefunc,ziinit.filestream); - return NULL; - } - - /* now we add file in a zipfile */ -# ifndef NO_ADDFILEINEXISTINGZIP - ziinit.globalcomment = NULL; - if (append == APPEND_STATUS_ADDINZIP) - { - uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ - - uLong size_central_dir; /* size of the central directory */ - uLong offset_central_dir; /* offset of start of central directory */ - uLong central_pos,uL; - - uLong number_disk; /* number of the current dist, used for - spaning ZIP, unsupported, always 0*/ - uLong number_disk_with_CD; /* number the the disk with central dir, used - for spaning ZIP, unsupported, always 0*/ - uLong number_entry; - uLong number_entry_CD; /* total number of entries in - the central dir - (same than number_entry on nospan) */ - uLong size_comment; - - central_pos = ziplocal_SearchCentralDir(&ziinit.z_filefunc,ziinit.filestream); - if (central_pos==0) - err=ZIP_ERRNO; - - if (ZSEEK(ziinit.z_filefunc, ziinit.filestream, - central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) - err=ZIP_ERRNO; - - /* the signature, already checked */ - if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&uL)!=ZIP_OK) - err=ZIP_ERRNO; - - /* number of this disk */ - if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk)!=ZIP_OK) - err=ZIP_ERRNO; - - /* number of the disk with the start of the central directory */ - if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk_with_CD)!=ZIP_OK) - err=ZIP_ERRNO; - - /* total number of entries in the central dir on this disk */ - if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry)!=ZIP_OK) - err=ZIP_ERRNO; - - /* total number of entries in the central dir */ - if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry_CD)!=ZIP_OK) - err=ZIP_ERRNO; - - if ((number_entry_CD!=number_entry) || - (number_disk_with_CD!=0) || - (number_disk!=0)) - err=ZIP_BADZIPFILE; - - /* size of the central directory */ - if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&size_central_dir)!=ZIP_OK) - err=ZIP_ERRNO; - - /* offset of start of central directory with respect to the - starting disk number */ - if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&offset_central_dir)!=ZIP_OK) - err=ZIP_ERRNO; - - /* zipfile global comment length */ - if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&size_comment)!=ZIP_OK) - err=ZIP_ERRNO; - - if ((central_pos0) - { - ziinit.globalcomment = ALLOC(size_comment+1); - if (ziinit.globalcomment) - { - size_comment = ZREAD(ziinit.z_filefunc, ziinit.filestream,ziinit.globalcomment,size_comment); - ziinit.globalcomment[size_comment]=0; - } - } - - byte_before_the_zipfile = central_pos - - (offset_central_dir+size_central_dir); - ziinit.add_position_when_writting_offset = byte_before_the_zipfile; - - { - uLong size_central_dir_to_read = size_central_dir; - size_t buf_size = SIZEDATA_INDATABLOCK; - void* buf_read = (void*)ALLOC(buf_size); - if (ZSEEK(ziinit.z_filefunc, ziinit.filestream, - offset_central_dir + byte_before_the_zipfile, - ZLIB_FILEFUNC_SEEK_SET) != 0) - err=ZIP_ERRNO; - - while ((size_central_dir_to_read>0) && (err==ZIP_OK)) - { - uLong read_this = SIZEDATA_INDATABLOCK; - if (read_this > size_central_dir_to_read) - read_this = size_central_dir_to_read; - if (ZREAD(ziinit.z_filefunc, ziinit.filestream,buf_read,read_this) != read_this) - err=ZIP_ERRNO; - - if (err==ZIP_OK) - err = add_data_in_datablock(&ziinit.central_dir,buf_read, - (uLong)read_this); - size_central_dir_to_read-=read_this; - } - TRYFREE(buf_read); - } - ziinit.begin_pos = byte_before_the_zipfile; - ziinit.number_entry = number_entry_CD; - - if (ZSEEK(ziinit.z_filefunc, ziinit.filestream, - offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) - err=ZIP_ERRNO; - } - - if (globalcomment) - { - *globalcomment = ziinit.globalcomment; - } -# endif /* !NO_ADDFILEINEXISTINGZIP*/ - - if (err != ZIP_OK) - { -# ifndef NO_ADDFILEINEXISTINGZIP - TRYFREE(ziinit.globalcomment); -# endif /* !NO_ADDFILEINEXISTINGZIP*/ - TRYFREE(zi); - return NULL; - } - else - { - *zi = ziinit; - return (zipFile)zi; - } -} - -extern zipFile ZEXPORT zipOpen (pathname, append) - const char *pathname; - int append; -{ - return zipOpen2(pathname,append,NULL,NULL); -} - -extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, raw, - windowBits, memLevel, strategy, - password, crcForCrypting) - zipFile file; - const char* filename; - const zip_fileinfo* zipfi; - const void* extrafield_local; - uInt size_extrafield_local; - const void* extrafield_global; - uInt size_extrafield_global; - const char* comment; - int method; - int level; - int raw; - int windowBits; - int memLevel; - int strategy; - const char* password; - uLong crcForCrypting; -{ - zip_internal* zi; - uInt size_filename; - uInt size_comment; - uInt i; - int err = ZIP_OK; - -# ifdef NOCRYPT - if (password != NULL) - return ZIP_PARAMERROR; -# endif - - if (file == NULL) - return ZIP_PARAMERROR; - if ((method!=0) && (method!=Z_DEFLATED)) - return ZIP_PARAMERROR; - - zi = (zip_internal*)file; - - if (zi->in_opened_file_inzip == 1) - { - err = zipCloseFileInZip (file); - if (err != ZIP_OK) - return err; - } - - - if (filename==NULL) - filename="-"; - - if (comment==NULL) - size_comment = 0; - else - size_comment = (uInt)strlen(comment); - - size_filename = (uInt)strlen(filename); - - if (zipfi == NULL) - zi->ci.dosDate = 0; - else - { - if (zipfi->dosDate != 0) - zi->ci.dosDate = zipfi->dosDate; - else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate); - } - - zi->ci.flag = 0; - if ((level==8) || (level==9)) - zi->ci.flag |= 2; - if ((level==2)) - zi->ci.flag |= 4; - if ((level==1)) - zi->ci.flag |= 6; - if (password != NULL) - zi->ci.flag |= 1; - - zi->ci.crc32 = 0; - zi->ci.method = method; - zi->ci.encrypt = 0; - zi->ci.stream_initialised = 0; - zi->ci.pos_in_buffered_data = 0; - zi->ci.raw = raw; - zi->ci.pos_local_header = ZTELL(zi->z_filefunc,zi->filestream) ; - zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + - size_extrafield_global + size_comment; - zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader); - - ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4); - /* version info */ - ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2); - ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2); - ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2); - ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2); - ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4); - ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/ - ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/ - ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/ - ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2); - ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2); - ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2); - ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/ - - if (zipfi==NULL) - ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2); - else - ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2); - - if (zipfi==NULL) - ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4); - else - ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4); - - ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header- zi->add_position_when_writting_offset,4); - - for (i=0;ici.central_header+SIZECENTRALHEADER+i) = *(filename+i); - - for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+i) = - *(((const char*)extrafield_global)+i); - - for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+ - size_extrafield_global+i) = *(comment+i); - if (zi->ci.central_header == NULL) - return ZIP_INTERNALERROR; - - /* write the local header */ - err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC,4); - - if (err==ZIP_OK) - err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */ - if (err==ZIP_OK) - err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2); - - if (err==ZIP_OK) - err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2); - - if (err==ZIP_OK) - err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4); - - if (err==ZIP_OK) - err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */ - if (err==ZIP_OK) - err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */ - if (err==ZIP_OK) - err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */ - - if (err==ZIP_OK) - err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2); - - if (err==ZIP_OK) - err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield_local,2); - - if ((err==ZIP_OK) && (size_filename>0)) - if (ZWRITE(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename) - err = ZIP_ERRNO; - - if ((err==ZIP_OK) && (size_extrafield_local>0)) - if (ZWRITE(zi->z_filefunc,zi->filestream,extrafield_local,size_extrafield_local) - !=size_extrafield_local) - err = ZIP_ERRNO; - - zi->ci.stream.avail_in = (uInt)0; - zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; - zi->ci.stream.next_out = zi->ci.buffered_data; - zi->ci.stream.total_in = 0; - zi->ci.stream.total_out = 0; - - if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) - { - zi->ci.stream.zalloc = (alloc_func)0; - zi->ci.stream.zfree = (free_func)0; - zi->ci.stream.opaque = (voidpf)0; - - if (windowBits>0) - windowBits = -windowBits; - - err = deflateInit2(&zi->ci.stream, level, - Z_DEFLATED, windowBits, memLevel, strategy); - - if (err==Z_OK) - zi->ci.stream_initialised = 1; - } -# ifndef NOCRYPT - zi->ci.crypt_header_size = 0; - if ((err==Z_OK) && (password != NULL)) - { - unsigned char bufHead[RAND_HEAD_LEN]; - unsigned int sizeHead; - zi->ci.encrypt = 1; - zi->ci.pcrc_32_tab = get_crc_table(); - /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/ - - sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting); - zi->ci.crypt_header_size = sizeHead; - - if (ZWRITE(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead) - err = ZIP_ERRNO; - } -# endif - - if (err==Z_OK) - zi->in_opened_file_inzip = 1; - return err; -} - -extern int ZEXPORT zipOpenNewFileInZip2(file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, raw) - zipFile file; - const char* filename; - const zip_fileinfo* zipfi; - const void* extrafield_local; - uInt size_extrafield_local; - const void* extrafield_global; - uInt size_extrafield_global; - const char* comment; - int method; - int level; - int raw; -{ - return zipOpenNewFileInZip3 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, raw, - -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, - NULL, 0); -} - -extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level) - zipFile file; - const char* filename; - const zip_fileinfo* zipfi; - const void* extrafield_local; - uInt size_extrafield_local; - const void* extrafield_global; - uInt size_extrafield_global; - const char* comment; - int method; - int level; -{ - return zipOpenNewFileInZip2 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, 0); -} - -local int zipFlushWriteBuffer(zi) - zip_internal* zi; -{ - int err=ZIP_OK; - - if (zi->ci.encrypt != 0) - { -#ifndef NOCRYPT - uInt i; - int t; - for (i=0;ici.pos_in_buffered_data;i++) - zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, - zi->ci.buffered_data[i],t); -#endif - } - if (ZWRITE(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) - !=zi->ci.pos_in_buffered_data) - err = ZIP_ERRNO; - zi->ci.pos_in_buffered_data = 0; - return err; -} - -extern int ZEXPORT zipWriteInFileInZip (file, buf, len) - zipFile file; - const void* buf; - unsigned len; -{ - zip_internal* zi; - int err=ZIP_OK; - - if (file == NULL) - return ZIP_PARAMERROR; - zi = (zip_internal*)file; - - if (zi->in_opened_file_inzip == 0) - return ZIP_PARAMERROR; - - zi->ci.stream.next_in = (void*)buf; - zi->ci.stream.avail_in = len; - zi->ci.crc32 = crc32(zi->ci.crc32,buf,len); - - while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) - { - if (zi->ci.stream.avail_out == 0) - { - if (zipFlushWriteBuffer(zi) == ZIP_ERRNO) - err = ZIP_ERRNO; - zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; - zi->ci.stream.next_out = zi->ci.buffered_data; - } - - - if(err != ZIP_OK) - break; - - if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) - { - uLong uTotalOutBefore = zi->ci.stream.total_out; - err=deflate(&zi->ci.stream, Z_NO_FLUSH); - zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; - - } - else - { - uInt copy_this,i; - if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) - copy_this = zi->ci.stream.avail_in; - else - copy_this = zi->ci.stream.avail_out; - for (i=0;ici.stream.next_out)+i) = - *(((const char*)zi->ci.stream.next_in)+i); - { - zi->ci.stream.avail_in -= copy_this; - zi->ci.stream.avail_out-= copy_this; - zi->ci.stream.next_in+= copy_this; - zi->ci.stream.next_out+= copy_this; - zi->ci.stream.total_in+= copy_this; - zi->ci.stream.total_out+= copy_this; - zi->ci.pos_in_buffered_data += copy_this; - } - } - } - - return err; -} - -extern int ZEXPORT zipCloseFileInZipRaw (file, uncompressed_size, crc32) - zipFile file; - uLong uncompressed_size; - uLong crc32; -{ - zip_internal* zi; - uLong compressed_size; - int err=ZIP_OK; - - if (file == NULL) - return ZIP_PARAMERROR; - zi = (zip_internal*)file; - - if (zi->in_opened_file_inzip == 0) - return ZIP_PARAMERROR; - zi->ci.stream.avail_in = 0; - - if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) - while (err==ZIP_OK) - { - uLong uTotalOutBefore; - if (zi->ci.stream.avail_out == 0) - { - if (zipFlushWriteBuffer(zi) == ZIP_ERRNO) - err = ZIP_ERRNO; - zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; - zi->ci.stream.next_out = zi->ci.buffered_data; - } - uTotalOutBefore = zi->ci.stream.total_out; - err=deflate(&zi->ci.stream, Z_FINISH); - zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; - } - - if (err==Z_STREAM_END) - err=ZIP_OK; /* this is normal */ - - if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK)) - if (zipFlushWriteBuffer(zi)==ZIP_ERRNO) - err = ZIP_ERRNO; - - if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) - { - err=deflateEnd(&zi->ci.stream); - zi->ci.stream_initialised = 0; - } - - if (!zi->ci.raw) - { - crc32 = (uLong)zi->ci.crc32; - uncompressed_size = (uLong)zi->ci.stream.total_in; - } - compressed_size = (uLong)zi->ci.stream.total_out; -# ifndef NOCRYPT - compressed_size += zi->ci.crypt_header_size; -# endif - - ziplocal_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/ - ziplocal_putValue_inmemory(zi->ci.central_header+20, - compressed_size,4); /*compr size*/ - if (zi->ci.stream.data_type == Z_ASCII) - ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2); - ziplocal_putValue_inmemory(zi->ci.central_header+24, - uncompressed_size,4); /*uncompr size*/ - - if (err==ZIP_OK) - err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header, - (uLong)zi->ci.size_centralheader); - free(zi->ci.central_header); - - if (err==ZIP_OK) - { - long cur_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream); - if (ZSEEK(zi->z_filefunc,zi->filestream, - zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0) - err = ZIP_ERRNO; - - if (err==ZIP_OK) - err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */ - - if (err==ZIP_OK) /* compressed size, unknown */ - err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4); - - if (err==ZIP_OK) /* uncompressed size, unknown */ - err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4); - - if (ZSEEK(zi->z_filefunc,zi->filestream, - cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0) - err = ZIP_ERRNO; - } - - zi->number_entry ++; - zi->in_opened_file_inzip = 0; - - return err; -} - -extern int ZEXPORT zipCloseFileInZip (file) - zipFile file; -{ - return zipCloseFileInZipRaw (file,0,0); -} - -extern int ZEXPORT zipClose (file, global_comment) - zipFile file; - const char* global_comment; -{ - zip_internal* zi; - int err = 0; - uLong size_centraldir = 0; - uLong centraldir_pos_inzip; - uInt size_global_comment; - if (file == NULL) - return ZIP_PARAMERROR; - zi = (zip_internal*)file; - - if (zi->in_opened_file_inzip == 1) - { - err = zipCloseFileInZip (file); - } - -#ifndef NO_ADDFILEINEXISTINGZIP - if (global_comment==NULL) - global_comment = zi->globalcomment; -#endif - if (global_comment==NULL) - size_global_comment = 0; - else - size_global_comment = (uInt)strlen(global_comment); - - centraldir_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream); - if (err==ZIP_OK) - { - linkedlist_datablock_internal* ldi = zi->central_dir.first_block ; - while (ldi!=NULL) - { - if ((err==ZIP_OK) && (ldi->filled_in_this_block>0)) - if (ZWRITE(zi->z_filefunc,zi->filestream, - ldi->data,ldi->filled_in_this_block) - !=ldi->filled_in_this_block ) - err = ZIP_ERRNO; - - size_centraldir += ldi->filled_in_this_block; - ldi = ldi->next_datablock; - } - } - free_datablock(zi->central_dir.first_block); - - if (err==ZIP_OK) /* Magic End */ - err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4); - - if (err==ZIP_OK) /* number of this disk */ - err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); - - if (err==ZIP_OK) /* number of the disk with the start of the central directory */ - err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); - - if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ - err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); - - if (err==ZIP_OK) /* total number of entries in the central dir */ - err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); - - if (err==ZIP_OK) /* size of the central directory */ - err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4); - - if (err==ZIP_OK) /* offset of start of central directory with respect to the - starting disk number */ - err = ziplocal_putValue(&zi->z_filefunc,zi->filestream, - (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4); - - if (err==ZIP_OK) /* zipfile comment length */ - err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2); - - if ((err==ZIP_OK) && (size_global_comment>0)) - if (ZWRITE(zi->z_filefunc,zi->filestream, - global_comment,size_global_comment) != size_global_comment) - err = ZIP_ERRNO; - - if (ZCLOSE(zi->z_filefunc,zi->filestream) != 0) - if (err == ZIP_OK) - err = ZIP_ERRNO; - -#ifndef NO_ADDFILEINEXISTINGZIP - TRYFREE(zi->globalcomment); -#endif - TRYFREE(zi); - - return err; -} diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/quazip/zip.h b/ground/gcs/src/libs/glc_lib/3rdparty/quazip/zip.h deleted file mode 100644 index acacce83b..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/quazip/zip.h +++ /dev/null @@ -1,235 +0,0 @@ -/* zip.h -- IO for compress .zip files using zlib - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant - - This unzip package allow creates .ZIP file, compatible with PKZip 2.04g - WinZip, InfoZip tools and compatible. - Multi volume ZipFile (span) are not supported. - Encryption compatible with pkzip 2.04g only supported - Old compressions used by old PKZip 1.x are not supported - - For uncompress .zip file, look at unzip.h - - - I WAIT FEEDBACK at mail info@winimage.com - Visit also http://www.winimage.com/zLibDll/unzip.html for evolution - - Condition of use and distribution are the same than zlib : - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - -*/ - -/* for more info about .ZIP format, see - http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip - http://www.info-zip.org/pub/infozip/doc/ - PkWare has also a specification at : - ftp://ftp.pkware.com/probdesc.zip -*/ - -#ifndef _zip_H -#define _zip_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _ZLIB_H -#include "zlib.h" -#endif - -#ifndef _ZLIBIOAPI_H -#include "ioapi.h" -#endif - -#if defined(STRICTZIP) || defined(STRICTZIPUNZIP) -/* like the STRICT of WIN32, we define a pointer that cannot be converted - from (void*) without cast */ -typedef struct TagzipFile__ { int unused; } zipFile__; -typedef zipFile__ *zipFile; -#else -typedef voidp zipFile; -#endif - -#define ZIP_OK (0) -#define ZIP_EOF (0) -#define ZIP_ERRNO (Z_ERRNO) -#define ZIP_PARAMERROR (-102) -#define ZIP_BADZIPFILE (-103) -#define ZIP_INTERNALERROR (-104) - -#ifndef DEF_MEM_LEVEL -# if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -# else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -# endif -#endif -/* default memLevel */ - -/* tm_zip contain date/time info */ -typedef struct tm_zip_s -{ - uInt tm_sec; /* seconds after the minute - [0,59] */ - uInt tm_min; /* minutes after the hour - [0,59] */ - uInt tm_hour; /* hours since midnight - [0,23] */ - uInt tm_mday; /* day of the month - [1,31] */ - uInt tm_mon; /* months since January - [0,11] */ - uInt tm_year; /* years - [1980..2044] */ -} tm_zip; - -typedef struct -{ - tm_zip tmz_date; /* date in understandable format */ - uLong dosDate; /* if dos_date == 0, tmu_date is used */ -/* uLong flag; */ /* general purpose bit flag 2 bytes */ - - uLong internal_fa; /* internal file attributes 2 bytes */ - uLong external_fa; /* external file attributes 4 bytes */ -} zip_fileinfo; - -typedef const char* zipcharpc; - - -#define APPEND_STATUS_CREATE (0) -#define APPEND_STATUS_CREATEAFTER (1) -#define APPEND_STATUS_ADDINZIP (2) - -extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append)); -/* - Create a zipfile. - pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on - an Unix computer "zlib/zlib113.zip". - if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip - will be created at the end of the file. - (useful if the file contain a self extractor code) - if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will - add files in existing zip (be sure you don't add file that doesn't exist) - If the zipfile cannot be opened, the return value is NULL. - Else, the return value is a zipFile Handle, usable with other function - of this zip package. -*/ - -/* Note : there is no delete function into a zipfile. - If you want delete file into a zipfile, you must open a zipfile, and create another - Of couse, you can use RAW reading and writing to copy the file you did not want delte -*/ - -extern zipFile ZEXPORT zipOpen2 OF((const char *pathname, - int append, - zipcharpc* globalcomment, - zlib_filefunc_def* pzlib_filefunc_def)); - -extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level)); -/* - Open a file in the ZIP for writing. - filename : the filename in zip (if NULL, '-' without quote will be used - *zipfi contain supplemental information - if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local - contains the extrafield data the the local header - if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global - contains the extrafield data the the local header - if comment != NULL, comment contain the comment string - method contain the compression method (0 for store, Z_DEFLATED for deflate) - level contain the level of compression (can be Z_DEFAULT_COMPRESSION) -*/ - - -extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw)); - -/* - Same than zipOpenNewFileInZip, except if raw=1, we write raw file - */ - -extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw, - int windowBits, - int memLevel, - int strategy, - const char* password, - uLong crcForCtypting)); - -/* - Same than zipOpenNewFileInZip2, except - windowBits,memLevel,,strategy : see parameter strategy in deflateInit2 - password : crypting password (NULL for no crypting) - crcForCtypting : crc of file to compress (needed for crypting) - */ - - -extern int ZEXPORT zipWriteInFileInZip OF((zipFile file, - const void* buf, - unsigned len)); -/* - Write data in the zipfile -*/ - -extern int ZEXPORT zipCloseFileInZip OF((zipFile file)); -/* - Close the current file in the zipfile -*/ - -extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, - uLong uncompressed_size, - uLong crc32)); -/* - Close the current file in the zipfile, for fiel opened with - parameter raw=1 in zipOpenNewFileInZip2 - uncompressed_size and crc32 are value for the uncompressed size -*/ - -extern int ZEXPORT zipClose OF((zipFile file, - const char* global_comment)); -/* - Close the zipfile -*/ - -#ifdef __cplusplus -} -#endif - -#endif /* _zip_H */ diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/ChangeLog b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/ChangeLog deleted file mode 100644 index 1ac946309..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/ChangeLog +++ /dev/null @@ -1,855 +0,0 @@ - - ChangeLog file for zlib - -Changes in 1.2.3 (18 July 2005) -- Apply security vulnerability fixes to contrib/infback9 as well -- Clean up some text files (carriage returns, trailing space) -- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant] - -Changes in 1.2.2.4 (11 July 2005) -- Add inflatePrime() function for starting inflation at bit boundary -- Avoid some Visual C warnings in deflate.c -- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit - compile -- Fix some spelling errors in comments [Betts] -- Correct inflateInit2() error return documentation in zlib.h -- Added zran.c example of compressed data random access to examples - directory, shows use of inflatePrime() -- Fix cast for assignments to strm->state in inflate.c and infback.c -- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer] -- Move declarations of gf2 functions to right place in crc32.c [Oberhumer] -- Add cast in trees.c t avoid a warning [Oberhumer] -- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer] -- Update make_vms.com [Zinser] -- Initialize state->write in inflateReset() since copied in inflate_fast() -- Be more strict on incomplete code sets in inflate_table() and increase - ENOUGH and MAXD -- this repairs a possible security vulnerability for - invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for - discovering the vulnerability and providing test cases. -- Add ia64 support to configure for HP-UX [Smith] -- Add error return to gzread() for format or i/o error [Levin] -- Use malloc.h for OS/2 [Necasek] - -Changes in 1.2.2.3 (27 May 2005) -- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile -- Typecast fread() return values in gzio.c [Vollant] -- Remove trailing space in minigzip.c outmode (VC++ can't deal with it) -- Fix crc check bug in gzread() after gzungetc() [Heiner] -- Add the deflateTune() function to adjust internal compression parameters -- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack) -- Remove an incorrect assertion in examples/zpipe.c -- Add C++ wrapper in infback9.h [Donais] -- Fix bug in inflateCopy() when decoding fixed codes -- Note in zlib.h how much deflateSetDictionary() actually uses -- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used) -- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer] -- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer] -- Add gzdirect() function to indicate transparent reads -- Update contrib/minizip [Vollant] -- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer] -- Add casts in crc32.c to avoid warnings [Oberhumer] -- Add contrib/masmx64 [Vollant] -- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant] - -Changes in 1.2.2.2 (30 December 2004) -- Replace structure assignments in deflate.c and inflate.c with zmemcpy to - avoid implicit memcpy calls (portability for no-library compilation) -- Increase sprintf() buffer size in gzdopen() to allow for large numbers -- Add INFLATE_STRICT to check distances against zlib header -- Improve WinCE errno handling and comments [Chang] -- Remove comment about no gzip header processing in FAQ -- Add Z_FIXED strategy option to deflateInit2() to force fixed trees -- Add updated make_vms.com [Coghlan], update README -- Create a new "examples" directory, move gzappend.c there, add zpipe.c, - fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html. -- Add FAQ entry and comments in deflate.c on uninitialized memory access -- Add Solaris 9 make options in configure [Gilbert] -- Allow strerror() usage in gzio.c for STDC -- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer] -- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant] -- Use z_off_t for adler32_combine() and crc32_combine() lengths -- Make adler32() much faster for small len -- Use OS_CODE in deflate() default gzip header - -Changes in 1.2.2.1 (31 October 2004) -- Allow inflateSetDictionary() call for raw inflate -- Fix inflate header crc check bug for file names and comments -- Add deflateSetHeader() and gz_header structure for custom gzip headers -- Add inflateGetheader() to retrieve gzip headers -- Add crc32_combine() and adler32_combine() functions -- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list -- Use zstreamp consistently in zlib.h (inflate_back functions) -- Remove GUNZIP condition from definition of inflate_mode in inflate.h - and in contrib/inflate86/inffast.S [Truta, Anderson] -- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson] -- Update projects/README.projects and projects/visualc6 [Truta] -- Update win32/DLL_FAQ.txt [Truta] -- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta] -- Deprecate Z_ASCII; use Z_TEXT instead [Truta] -- Use a new algorithm for setting strm->data_type in trees.c [Truta] -- Do not define an exit() prototype in zutil.c unless DEBUG defined -- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta] -- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate() -- Fix Darwin build version identification [Peterson] - -Changes in 1.2.2 (3 October 2004) -- Update zlib.h comments on gzip in-memory processing -- Set adler to 1 in inflateReset() to support Java test suite [Walles] -- Add contrib/dotzlib [Ravn] -- Update win32/DLL_FAQ.txt [Truta] -- Update contrib/minizip [Vollant] -- Move contrib/visual-basic.txt to old/ [Truta] -- Fix assembler builds in projects/visualc6/ [Truta] - -Changes in 1.2.1.2 (9 September 2004) -- Update INDEX file -- Fix trees.c to update strm->data_type (no one ever noticed!) -- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown] -- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE) -- Add limited multitasking protection to DYNAMIC_CRC_TABLE -- Add NO_vsnprintf for VMS in zutil.h [Mozilla] -- Don't declare strerror() under VMS [Mozilla] -- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize -- Update contrib/ada [Anisimkov] -- Update contrib/minizip [Vollant] -- Fix configure to not hardcode directories for Darwin [Peterson] -- Fix gzio.c to not return error on empty files [Brown] -- Fix indentation; update version in contrib/delphi/ZLib.pas and - contrib/pascal/zlibpas.pas [Truta] -- Update mkasm.bat in contrib/masmx86 [Truta] -- Update contrib/untgz [Truta] -- Add projects/README.projects [Truta] -- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta] -- Update win32/DLL_FAQ.txt [Truta] -- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta] -- Remove an unnecessary assignment to curr in inftrees.c [Truta] -- Add OS/2 to exe builds in configure [Poltorak] -- Remove err dummy parameter in zlib.h [Kientzle] - -Changes in 1.2.1.1 (9 January 2004) -- Update email address in README -- Several FAQ updates -- Fix a big fat bug in inftrees.c that prevented decoding valid - dynamic blocks with only literals and no distance codes -- - Thanks to "Hot Emu" for the bug report and sample file -- Add a note to puff.c on no distance codes case. - -Changes in 1.2.1 (17 November 2003) -- Remove a tab in contrib/gzappend/gzappend.c -- Update some interfaces in contrib for new zlib functions -- Update zlib version number in some contrib entries -- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta] -- Support shared libraries on Hurd and KFreeBSD [Brown] -- Fix error in NO_DIVIDE option of adler32.c - -Changes in 1.2.0.8 (4 November 2003) -- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas -- Add experimental NO_DIVIDE #define in adler32.c - - Possibly faster on some processors (let me know if it is) -- Correct Z_BLOCK to not return on first inflate call if no wrap -- Fix strm->data_type on inflate() return to correctly indicate EOB -- Add deflatePrime() function for appending in the middle of a byte -- Add contrib/gzappend for an example of appending to a stream -- Update win32/DLL_FAQ.txt [Truta] -- Delete Turbo C comment in README [Truta] -- Improve some indentation in zconf.h [Truta] -- Fix infinite loop on bad input in configure script [Church] -- Fix gzeof() for concatenated gzip files [Johnson] -- Add example to contrib/visual-basic.txt [Michael B.] -- Add -p to mkdir's in Makefile.in [vda] -- Fix configure to properly detect presence or lack of printf functions -- Add AS400 support [Monnerat] -- Add a little Cygwin support [Wilson] - -Changes in 1.2.0.7 (21 September 2003) -- Correct some debug formats in contrib/infback9 -- Cast a type in a debug statement in trees.c -- Change search and replace delimiter in configure from % to # [Beebe] -- Update contrib/untgz to 0.2 with various fixes [Truta] -- Add build support for Amiga [Nikl] -- Remove some directories in old that have been updated to 1.2 -- Add dylib building for Mac OS X in configure and Makefile.in -- Remove old distribution stuff from Makefile -- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X -- Update links in README - -Changes in 1.2.0.6 (13 September 2003) -- Minor FAQ updates -- Update contrib/minizip to 1.00 [Vollant] -- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta] -- Update POSTINC comment for 68060 [Nikl] -- Add contrib/infback9 with deflate64 decoding (unsupported) -- For MVS define NO_vsnprintf and undefine FAR [van Burik] -- Add pragma for fdopen on MVS [van Burik] - -Changes in 1.2.0.5 (8 September 2003) -- Add OF to inflateBackEnd() declaration in zlib.h -- Remember start when using gzdopen in the middle of a file -- Use internal off_t counters in gz* functions to properly handle seeks -- Perform more rigorous check for distance-too-far in inffast.c -- Add Z_BLOCK flush option to return from inflate at block boundary -- Set strm->data_type on return from inflate - - Indicate bits unused, if at block boundary, and if in last block -- Replace size_t with ptrdiff_t in crc32.c, and check for correct size -- Add condition so old NO_DEFLATE define still works for compatibility -- FAQ update regarding the Windows DLL [Truta] -- INDEX update: add qnx entry, remove aix entry [Truta] -- Install zlib.3 into mandir [Wilson] -- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta] -- Adapt the zlib interface to the new DLL convention guidelines [Truta] -- Introduce ZLIB_WINAPI macro to allow the export of functions using - the WINAPI calling convention, for Visual Basic [Vollant, Truta] -- Update msdos and win32 scripts and makefiles [Truta] -- Export symbols by name, not by ordinal, in win32/zlib.def [Truta] -- Add contrib/ada [Anisimkov] -- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta] -- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant] -- Add contrib/masm686 [Truta] -- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm - [Truta, Vollant] -- Update contrib/delphi; rename to contrib/pascal; add example [Truta] -- Remove contrib/delphi2; add a new contrib/delphi [Truta] -- Avoid inclusion of the nonstandard in contrib/iostream, - and fix some method prototypes [Truta] -- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip - [Truta] -- Avoid the use of backslash (\) in contrib/minizip [Vollant] -- Fix file time handling in contrib/untgz; update makefiles [Truta] -- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines - [Vollant] -- Remove contrib/vstudio/vc15_16 [Vollant] -- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta] -- Update README.contrib [Truta] -- Invert the assignment order of match_head and s->prev[...] in - INSERT_STRING [Truta] -- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings - [Truta] -- Compare function pointers with 0, not with NULL or Z_NULL [Truta] -- Fix prototype of syncsearch in inflate.c [Truta] -- Introduce ASMINF macro to be enabled when using an ASM implementation - of inflate_fast [Truta] -- Change NO_DEFLATE to NO_GZCOMPRESS [Truta] -- Modify test_gzio in example.c to take a single file name as a - parameter [Truta] -- Exit the example.c program if gzopen fails [Truta] -- Add type casts around strlen in example.c [Truta] -- Remove casting to sizeof in minigzip.c; give a proper type - to the variable compared with SUFFIX_LEN [Truta] -- Update definitions of STDC and STDC99 in zconf.h [Truta] -- Synchronize zconf.h with the new Windows DLL interface [Truta] -- Use SYS16BIT instead of __32BIT__ to distinguish between - 16- and 32-bit platforms [Truta] -- Use far memory allocators in small 16-bit memory models for - Turbo C [Truta] -- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in - zlibCompileFlags [Truta] -- Cygwin has vsnprintf [Wilson] -- In Windows16, OS_CODE is 0, as in MSDOS [Truta] -- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson] - -Changes in 1.2.0.4 (10 August 2003) -- Minor FAQ updates -- Be more strict when checking inflateInit2's windowBits parameter -- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well -- Add gzip wrapper option to deflateInit2 using windowBits -- Add updated QNX rule in configure and qnx directory [Bonnefoy] -- Make inflate distance-too-far checks more rigorous -- Clean up FAR usage in inflate -- Add casting to sizeof() in gzio.c and minigzip.c - -Changes in 1.2.0.3 (19 July 2003) -- Fix silly error in gzungetc() implementation [Vollant] -- Update contrib/minizip and contrib/vstudio [Vollant] -- Fix printf format in example.c -- Correct cdecl support in zconf.in.h [Anisimkov] -- Minor FAQ updates - -Changes in 1.2.0.2 (13 July 2003) -- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons -- Attempt to avoid warnings in crc32.c for pointer-int conversion -- Add AIX to configure, remove aix directory [Bakker] -- Add some casts to minigzip.c -- Improve checking after insecure sprintf() or vsprintf() calls -- Remove #elif's from crc32.c -- Change leave label to inf_leave in inflate.c and infback.c to avoid - library conflicts -- Remove inflate gzip decoding by default--only enable gzip decoding by - special request for stricter backward compatibility -- Add zlibCompileFlags() function to return compilation information -- More typecasting in deflate.c to avoid warnings -- Remove leading underscore from _Capital #defines [Truta] -- Fix configure to link shared library when testing -- Add some Windows CE target adjustments [Mai] -- Remove #define ZLIB_DLL in zconf.h [Vollant] -- Add zlib.3 [Rodgers] -- Update RFC URL in deflate.c and algorithm.txt [Mai] -- Add zlib_dll_FAQ.txt to contrib [Truta] -- Add UL to some constants [Truta] -- Update minizip and vstudio [Vollant] -- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h -- Expand use of NO_DUMMY_DECL to avoid all dummy structures -- Added iostream3 to contrib [Schwardt] -- Replace rewind() with fseek() for WinCE [Truta] -- Improve setting of zlib format compression level flags - - Report 0 for huffman and rle strategies and for level == 0 or 1 - - Report 2 only for level == 6 -- Only deal with 64K limit when necessary at compile time [Truta] -- Allow TOO_FAR check to be turned off at compile time [Truta] -- Add gzclearerr() function [Souza] -- Add gzungetc() function - -Changes in 1.2.0.1 (17 March 2003) -- Add Z_RLE strategy for run-length encoding [Truta] - - When Z_RLE requested, restrict matches to distance one - - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE -- Correct FASTEST compilation to allow level == 0 -- Clean up what gets compiled for FASTEST -- Incorporate changes to zconf.in.h [Vollant] - - Refine detection of Turbo C need for dummy returns - - Refine ZLIB_DLL compilation - - Include additional header file on VMS for off_t typedef -- Try to use _vsnprintf where it supplants vsprintf [Vollant] -- Add some casts in inffast.c -- Enchance comments in zlib.h on what happens if gzprintf() tries to - write more than 4095 bytes before compression -- Remove unused state from inflateBackEnd() -- Remove exit(0) from minigzip.c, example.c -- Get rid of all those darn tabs -- Add "check" target to Makefile.in that does the same thing as "test" -- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in -- Update contrib/inflate86 [Anderson] -- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant] -- Add msdos and win32 directories with makefiles [Truta] -- More additions and improvements to the FAQ - -Changes in 1.2.0 (9 March 2003) -- New and improved inflate code - - About 20% faster - - Does not allocate 32K window unless and until needed - - Automatically detects and decompresses gzip streams - - Raw inflate no longer needs an extra dummy byte at end - - Added inflateBack functions using a callback interface--even faster - than inflate, useful for file utilities (gzip, zip) - - Added inflateCopy() function to record state for random access on - externally generated deflate streams (e.g. in gzip files) - - More readable code (I hope) -- New and improved crc32() - - About 50% faster, thanks to suggestions from Rodney Brown -- Add deflateBound() and compressBound() functions -- Fix memory leak in deflateInit2() -- Permit setting dictionary for raw deflate (for parallel deflate) -- Fix const declaration for gzwrite() -- Check for some malloc() failures in gzio.c -- Fix bug in gzopen() on single-byte file 0x1f -- Fix bug in gzread() on concatenated file with 0x1f at end of buffer - and next buffer doesn't start with 0x8b -- Fix uncompress() to return Z_DATA_ERROR on truncated input -- Free memory at end of example.c -- Remove MAX #define in trees.c (conflicted with some libraries) -- Fix static const's in deflate.c, gzio.c, and zutil.[ch] -- Declare malloc() and free() in gzio.c if STDC not defined -- Use malloc() instead of calloc() in zutil.c if int big enough -- Define STDC for AIX -- Add aix/ with approach for compiling shared library on AIX -- Add HP-UX support for shared libraries in configure -- Add OpenUNIX support for shared libraries in configure -- Use $cc instead of gcc to build shared library -- Make prefix directory if needed when installing -- Correct Macintosh avoidance of typedef Byte in zconf.h -- Correct Turbo C memory allocation when under Linux -- Use libz.a instead of -lz in Makefile (assure use of compiled library) -- Update configure to check for snprintf or vsnprintf functions and their - return value, warn during make if using an insecure function -- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that - is lost when library is used--resolution is to build new zconf.h -- Documentation improvements (in zlib.h): - - Document raw deflate and inflate - - Update RFCs URL - - Point out that zlib and gzip formats are different - - Note that Z_BUF_ERROR is not fatal - - Document string limit for gzprintf() and possible buffer overflow - - Note requirement on avail_out when flushing - - Note permitted values of flush parameter of inflate() -- Add some FAQs (and even answers) to the FAQ -- Add contrib/inflate86/ for x86 faster inflate -- Add contrib/blast/ for PKWare Data Compression Library decompression -- Add contrib/puff/ simple inflate for deflate format description - -Changes in 1.1.4 (11 March 2002) -- ZFREE was repeated on same allocation on some error conditions. - This creates a security problem described in - http://www.zlib.org/advisory-2002-03-11.txt -- Returned incorrect error (Z_MEM_ERROR) on some invalid data -- Avoid accesses before window for invalid distances with inflate window - less than 32K. -- force windowBits > 8 to avoid a bug in the encoder for a window size - of 256 bytes. (A complete fix will be available in 1.1.5). - -Changes in 1.1.3 (9 July 1998) -- fix "an inflate input buffer bug that shows up on rare but persistent - occasions" (Mark) -- fix gzread and gztell for concatenated .gz files (Didier Le Botlan) -- fix gzseek(..., SEEK_SET) in write mode -- fix crc check after a gzeek (Frank Faubert) -- fix miniunzip when the last entry in a zip file is itself a zip file - (J Lillge) -- add contrib/asm586 and contrib/asm686 (Brian Raiter) - See http://www.muppetlabs.com/~breadbox/software/assembly.html -- add support for Delphi 3 in contrib/delphi (Bob Dellaca) -- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti) -- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren) -- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks) -- added a FAQ file - -- Support gzdopen on Mac with Metrowerks (Jason Linhart) -- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart) -- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young) -- avoid some warnings with Borland C (Tom Tanner) -- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant) -- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant) -- allow several arguments to configure (Tim Mooney, Frodo Looijaard) -- use libdir and includedir in Makefile.in (Tim Mooney) -- support shared libraries on OSF1 V4 (Tim Mooney) -- remove so_locations in "make clean" (Tim Mooney) -- fix maketree.c compilation error (Glenn, Mark) -- Python interface to zlib now in Python 1.5 (Jeremy Hylton) -- new Makefile.riscos (Rich Walker) -- initialize static descriptors in trees.c for embedded targets (Nick Smith) -- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith) -- add the OS/2 files in Makefile.in too (Andrew Zabolotny) -- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane) -- fix maketree.c to allow clean compilation of inffixed.h (Mark) -- fix parameter check in deflateCopy (Gunther Nikl) -- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler) -- Many portability patches by Christian Spieler: - . zutil.c, zutil.h: added "const" for zmem* - . Make_vms.com: fixed some typos - . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists - . msdos/Makefile.msc: remove "default rtl link library" info from obj files - . msdos/Makefile.*: use model-dependent name for the built zlib library - . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc: - new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT) -- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane) -- replace __far with _far for better portability (Christian Spieler, Tom Lane) -- fix test for errno.h in configure (Tim Newsham) - -Changes in 1.1.2 (19 March 98) -- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant) - See http://www.winimage.com/zLibDll/unzip.html -- preinitialize the inflate tables for fixed codes, to make the code - completely thread safe (Mark) -- some simplifications and slight speed-up to the inflate code (Mark) -- fix gzeof on non-compressed files (Allan Schrum) -- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs) -- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn) -- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny) -- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori) -- do not wrap extern "C" around system includes (Tom Lane) -- mention zlib binding for TCL in README (Andreas Kupries) -- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert) -- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson) -- allow "configure --prefix $HOME" (Tim Mooney) -- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson) -- move Makefile.sas to amiga/Makefile.sas - -Changes in 1.1.1 (27 Feb 98) -- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson) -- remove block truncation heuristic which had very marginal effect for zlib - (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the - compression ratio on some files. This also allows inlining _tr_tally for - matches in deflate_slow. -- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier) - -Changes in 1.1.0 (24 Feb 98) -- do not return STREAM_END prematurely in inflate (John Bowler) -- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler) -- compile with -DFASTEST to get compression code optimized for speed only -- in minigzip, try mmap'ing the input file first (Miguel Albrecht) -- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain - on Sun but significant on HP) - -- add a pointer to experimental unzip library in README (Gilles Vollant) -- initialize variable gcc in configure (Chris Herborth) - -Changes in 1.0.9 (17 Feb 1998) -- added gzputs and gzgets functions -- do not clear eof flag in gzseek (Mark Diekhans) -- fix gzseek for files in transparent mode (Mark Diekhans) -- do not assume that vsprintf returns the number of bytes written (Jens Krinke) -- replace EXPORT with ZEXPORT to avoid conflict with other programs -- added compress2 in zconf.h, zlib.def, zlib.dnt -- new asm code from Gilles Vollant in contrib/asm386 -- simplify the inflate code (Mark): - . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new() - . ZALLOC the length list in inflate_trees_fixed() instead of using stack - . ZALLOC the value area for huft_build() instead of using stack - . Simplify Z_FINISH check in inflate() - -- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8 -- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi) -- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with - the declaration of FAR (Gilles VOllant) -- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann) -- read_buf buf parameter of type Bytef* instead of charf* -- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout) -- do not redeclare unlink in minigzip.c for WIN32 (John Bowler) -- fix check for presence of directories in "make install" (Ian Willis) - -Changes in 1.0.8 (27 Jan 1998) -- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant) -- fix gzgetc and gzputc for big endian systems (Markus Oberhumer) -- added compress2() to allow setting the compression level -- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong) -- use constant arrays for the static trees in trees.c instead of computing - them at run time (thanks to Ken Raeburn for this suggestion). To create - trees.h, compile with GEN_TREES_H and run "make test". -- check return code of example in "make test" and display result -- pass minigzip command line options to file_compress -- simplifying code of inflateSync to avoid gcc 2.8 bug - -- support CC="gcc -Wall" in configure -s (QingLong) -- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn) -- fix test for shared library support to avoid compiler warnings -- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant) -- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit) -- do not use fdopen for Metrowerks on Mac (Brad Pettit)) -- add checks for gzputc and gzputc in example.c -- avoid warnings in gzio.c and deflate.c (Andreas Kleinert) -- use const for the CRC table (Ken Raeburn) -- fixed "make uninstall" for shared libraries -- use Tracev instead of Trace in infblock.c -- in example.c use correct compressed length for test_sync -- suppress +vnocompatwarnings in configure for HPUX (not always supported) - -Changes in 1.0.7 (20 Jan 1998) -- fix gzseek which was broken in write mode -- return error for gzseek to negative absolute position -- fix configure for Linux (Chun-Chung Chen) -- increase stack space for MSC (Tim Wegner) -- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant) -- define EXPORTVA for gzprintf (Gilles Vollant) -- added man page zlib.3 (Rick Rodgers) -- for contrib/untgz, fix makedir() and improve Makefile - -- check gzseek in write mode in example.c -- allocate extra buffer for seeks only if gzseek is actually called -- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant) -- add inflateSyncPoint in zconf.h -- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def - -Changes in 1.0.6 (19 Jan 1998) -- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and - gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code) -- Fix a deflate bug occurring only with compression level 0 (thanks to - Andy Buckler for finding this one). -- In minigzip, pass transparently also the first byte for .Z files. -- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress() -- check Z_FINISH in inflate (thanks to Marc Schluper) -- Implement deflateCopy (thanks to Adam Costello) -- make static libraries by default in configure, add --shared option. -- move MSDOS or Windows specific files to directory msdos -- suppress the notion of partial flush to simplify the interface - (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4) -- suppress history buffer provided by application to simplify the interface - (this feature was not implemented anyway in 1.0.4) -- next_in and avail_in must be initialized before calling inflateInit or - inflateInit2 -- add EXPORT in all exported functions (for Windows DLL) -- added Makefile.nt (thanks to Stephen Williams) -- added the unsupported "contrib" directory: - contrib/asm386/ by Gilles Vollant - 386 asm code replacing longest_match(). - contrib/iostream/ by Kevin Ruland - A C++ I/O streams interface to the zlib gz* functions - contrib/iostream2/ by Tyge Lvset - Another C++ I/O streams interface - contrib/untgz/ by "Pedro A. Aranda Guti\irrez" - A very simple tar.gz file extractor using zlib - contrib/visual-basic.txt by Carlos Rios - How to use compress(), uncompress() and the gz* functions from VB. -- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression - level) in minigzip (thanks to Tom Lane) - -- use const for rommable constants in deflate -- added test for gzseek and gztell in example.c -- add undocumented function inflateSyncPoint() (hack for Paul Mackerras) -- add undocumented function zError to convert error code to string - (for Tim Smithers) -- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code. -- Use default memcpy for Symantec MSDOS compiler. -- Add EXPORT keyword for check_func (needed for Windows DLL) -- add current directory to LD_LIBRARY_PATH for "make test" -- create also a link for libz.so.1 -- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura) -- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX) -- added -soname for Linux in configure (Chun-Chung Chen, -- assign numbers to the exported functions in zlib.def (for Windows DLL) -- add advice in zlib.h for best usage of deflateSetDictionary -- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn) -- allow compilation with ANSI keywords only enabled for TurboC in large model -- avoid "versionString"[0] (Borland bug) -- add NEED_DUMMY_RETURN for Borland -- use variable z_verbose for tracing in debug mode (L. Peter Deutsch). -- allow compilation with CC -- defined STDC for OS/2 (David Charlap) -- limit external names to 8 chars for MVS (Thomas Lund) -- in minigzip.c, use static buffers only for 16-bit systems -- fix suffix check for "minigzip -d foo.gz" -- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee) -- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau) -- added makelcc.bat for lcc-win32 (Tom St Denis) -- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe) -- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion. -- check for unistd.h in configure (for off_t) -- remove useless check parameter in inflate_blocks_free -- avoid useless assignment of s->check to itself in inflate_blocks_new -- do not flush twice in gzclose (thanks to Ken Raeburn) -- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h -- use NO_ERRNO_H instead of enumeration of operating systems with errno.h -- work around buggy fclose on pipes for HP/UX -- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson) -- fix configure if CC is already equal to gcc - -Changes in 1.0.5 (3 Jan 98) -- Fix inflate to terminate gracefully when fed corrupted or invalid data -- Use const for rommable constants in inflate -- Eliminate memory leaks on error conditions in inflate -- Removed some vestigial code in inflate -- Update web address in README - -Changes in 1.0.4 (24 Jul 96) -- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF - bit, so the decompressor could decompress all the correct data but went - on to attempt decompressing extra garbage data. This affected minigzip too. -- zlibVersion and gzerror return const char* (needed for DLL) -- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno) -- use z_error only for DEBUG (avoid problem with DLLs) - -Changes in 1.0.3 (2 Jul 96) -- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS - small and medium models; this makes the library incompatible with previous - versions for these models. (No effect in large model or on other systems.) -- return OK instead of BUF_ERROR if previous deflate call returned with - avail_out as zero but there is nothing to do -- added memcmp for non STDC compilers -- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly) -- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO) -- better check for 16-bit mode MSC (avoids problem with Symantec) - -Changes in 1.0.2 (23 May 96) -- added Windows DLL support -- added a function zlibVersion (for the DLL support) -- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model) -- Bytef is define's instead of typedef'd only for Borland C -- avoid reading uninitialized memory in example.c -- mention in README that the zlib format is now RFC1950 -- updated Makefile.dj2 -- added algorithm.doc - -Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion] -- fix array overlay in deflate.c which sometimes caused bad compressed data -- fix inflate bug with empty stored block -- fix MSDOS medium model which was broken in 0.99 -- fix deflateParams() which could generated bad compressed data. -- Bytef is define'd instead of typedef'ed (work around Borland bug) -- added an INDEX file -- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32), - Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas) -- speed up adler32 for modern machines without auto-increment -- added -ansi for IRIX in configure -- static_init_done in trees.c is an int -- define unlink as delete for VMS -- fix configure for QNX -- add configure branch for SCO and HPUX -- avoid many warnings (unused variables, dead assignments, etc...) -- no fdopen for BeOS -- fix the Watcom fix for 32 bit mode (define FAR as empty) -- removed redefinition of Byte for MKWERKS -- work around an MWKERKS bug (incorrect merge of all .h files) - -Changes in 0.99 (27 Jan 96) -- allow preset dictionary shared between compressor and decompressor -- allow compression level 0 (no compression) -- add deflateParams in zlib.h: allow dynamic change of compression level - and compression strategy. -- test large buffers and deflateParams in example.c -- add optional "configure" to build zlib as a shared library -- suppress Makefile.qnx, use configure instead -- fixed deflate for 64-bit systems (detected on Cray) -- fixed inflate_blocks for 64-bit systems (detected on Alpha) -- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2) -- always return Z_BUF_ERROR when deflate() has nothing to do -- deflateInit and inflateInit are now macros to allow version checking -- prefix all global functions and types with z_ with -DZ_PREFIX -- make falloc completely reentrant (inftrees.c) -- fixed very unlikely race condition in ct_static_init -- free in reverse order of allocation to help memory manager -- use zlib-1.0/* instead of zlib/* inside the tar.gz -- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith - -Wconversion -Wstrict-prototypes -Wmissing-prototypes" -- allow gzread on concatenated .gz files -- deflateEnd now returns Z_DATA_ERROR if it was premature -- deflate is finally (?) fully deterministic (no matches beyond end of input) -- Document Z_SYNC_FLUSH -- add uninstall in Makefile -- Check for __cpluplus in zlib.h -- Better test in ct_align for partial flush -- avoid harmless warnings for Borland C++ -- initialize hash_head in deflate.c -- avoid warning on fdopen (gzio.c) for HP cc -Aa -- include stdlib.h for STDC compilers -- include errno.h for Cray -- ignore error if ranlib doesn't exist -- call ranlib twice for NeXTSTEP -- use exec_prefix instead of prefix for libz.a -- renamed ct_* as _tr_* to avoid conflict with applications -- clear z->msg in inflateInit2 before any error return -- initialize opaque in example.c, gzio.c, deflate.c and inflate.c -- fixed typo in zconf.h (_GNUC__ => __GNUC__) -- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode) -- fix typo in Make_vms.com (f$trnlnm -> f$getsyi) -- in fcalloc, normalize pointer if size > 65520 bytes -- don't use special fcalloc for 32 bit Borland C++ -- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc... -- use Z_BINARY instead of BINARY -- document that gzclose after gzdopen will close the file -- allow "a" as mode in gzopen. -- fix error checking in gzread -- allow skipping .gz extra-field on pipes -- added reference to Perl interface in README -- put the crc table in FAR data (I dislike more and more the medium model :) -- added get_crc_table -- added a dimension to all arrays (Borland C can't count). -- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast -- guard against multiple inclusion of *.h (for precompiled header on Mac) -- Watcom C pretends to be Microsoft C small model even in 32 bit mode. -- don't use unsized arrays to avoid silly warnings by Visual C++: - warning C4746: 'inflate_mask' : unsized array treated as '__far' - (what's wrong with far data in far model?). -- define enum out of inflate_blocks_state to allow compilation with C++ - -Changes in 0.95 (16 Aug 95) -- fix MSDOS small and medium model (now easier to adapt to any compiler) -- inlined send_bits -- fix the final (:-) bug for deflate with flush (output was correct but - not completely flushed in rare occasions). -- default window size is same for compression and decompression - (it's now sufficient to set MAX_WBITS in zconf.h). -- voidp -> voidpf and voidnp -> voidp (for consistency with other - typedefs and because voidnp was not near in large model). - -Changes in 0.94 (13 Aug 95) -- support MSDOS medium model -- fix deflate with flush (could sometimes generate bad output) -- fix deflateReset (zlib header was incorrectly suppressed) -- added support for VMS -- allow a compression level in gzopen() -- gzflush now calls fflush -- For deflate with flush, flush even if no more input is provided. -- rename libgz.a as libz.a -- avoid complex expression in infcodes.c triggering Turbo C bug -- work around a problem with gcc on Alpha (in INSERT_STRING) -- don't use inline functions (problem with some gcc versions) -- allow renaming of Byte, uInt, etc... with #define. -- avoid warning about (unused) pointer before start of array in deflate.c -- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c -- avoid reserved word 'new' in trees.c - -Changes in 0.93 (25 June 95) -- temporarily disable inline functions -- make deflate deterministic -- give enough lookahead for PARTIAL_FLUSH -- Set binary mode for stdin/stdout in minigzip.c for OS/2 -- don't even use signed char in inflate (not portable enough) -- fix inflate memory leak for segmented architectures - -Changes in 0.92 (3 May 95) -- don't assume that char is signed (problem on SGI) -- Clear bit buffer when starting a stored block -- no memcpy on Pyramid -- suppressed inftest.c -- optimized fill_window, put longest_match inline for gcc -- optimized inflate on stored blocks. -- untabify all sources to simplify patches - -Changes in 0.91 (2 May 95) -- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h -- Document the memory requirements in zconf.h -- added "make install" -- fix sync search logic in inflateSync -- deflate(Z_FULL_FLUSH) now works even if output buffer too short -- after inflateSync, don't scare people with just "lo world" -- added support for DJGPP - -Changes in 0.9 (1 May 95) -- don't assume that zalloc clears the allocated memory (the TurboC bug - was Mark's bug after all :) -- let again gzread copy uncompressed data unchanged (was working in 0.71) -- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented -- added a test of inflateSync in example.c -- moved MAX_WBITS to zconf.h because users might want to change that. -- document explicitly that zalloc(64K) on MSDOS must return a normalized - pointer (zero offset) -- added Makefiles for Microsoft C, Turbo C, Borland C++ -- faster crc32() - -Changes in 0.8 (29 April 95) -- added fast inflate (inffast.c) -- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this - is incompatible with previous versions of zlib which returned Z_OK. -- work around a TurboC compiler bug (bad code for b << 0, see infutil.h) - (actually that was not a compiler bug, see 0.81 above) -- gzread no longer reads one extra byte in certain cases -- In gzio destroy(), don't reference a freed structure -- avoid many warnings for MSDOS -- avoid the ERROR symbol which is used by MS Windows - -Changes in 0.71 (14 April 95) -- Fixed more MSDOS compilation problems :( There is still a bug with - TurboC large model. - -Changes in 0.7 (14 April 95) -- Added full inflate support. -- Simplified the crc32() interface. The pre- and post-conditioning - (one's complement) is now done inside crc32(). WARNING: this is - incompatible with previous versions; see zlib.h for the new usage. - -Changes in 0.61 (12 April 95) -- workaround for a bug in TurboC. example and minigzip now work on MSDOS. - -Changes in 0.6 (11 April 95) -- added minigzip.c -- added gzdopen to reopen a file descriptor as gzFile -- added transparent reading of non-gziped files in gzread. -- fixed bug in gzread (don't read crc as data) -- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose). -- don't allocate big arrays in the stack (for MSDOS) -- fix some MSDOS compilation problems - -Changes in 0.5: -- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but - not yet Z_FULL_FLUSH. -- support decompression but only in a single step (forced Z_FINISH) -- added opaque object for zalloc and zfree. -- added deflateReset and inflateReset -- added a variable zlib_version for consistency checking. -- renamed the 'filter' parameter of deflateInit2 as 'strategy'. - Added Z_FILTERED and Z_HUFFMAN_ONLY constants. - -Changes in 0.4: -- avoid "zip" everywhere, use zlib instead of ziplib. -- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush - if compression method == 8. -- added adler32 and crc32 -- renamed deflateOptions as deflateInit2, call one or the other but not both -- added the method parameter for deflateInit2. -- added inflateInit2 -- simplied considerably deflateInit and inflateInit by not supporting - user-provided history buffer. This is supported only in deflateInit2 - and inflateInit2. - -Changes in 0.3: -- prefix all macro names with Z_ -- use Z_FINISH instead of deflateEnd to finish compression. -- added Z_HUFFMAN_ONLY -- added gzerror() diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/FAQ b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/FAQ deleted file mode 100644 index 15d043615..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/FAQ +++ /dev/null @@ -1,339 +0,0 @@ - - Frequently Asked Questions about zlib - - -If your question is not there, please check the zlib home page -http://www.zlib.org which may have more recent information. -The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html - - - 1. Is zlib Y2K-compliant? - - Yes. zlib doesn't handle dates. - - 2. Where can I get a Windows DLL version? - - The zlib sources can be compiled without change to produce a DLL. - See the file win32/DLL_FAQ.txt in the zlib distribution. - Pointers to the precompiled DLL are found in the zlib web site at - http://www.zlib.org. - - 3. Where can I get a Visual Basic interface to zlib? - - See - * http://www.dogma.net/markn/articles/zlibtool/zlibtool.htm - * contrib/visual-basic.txt in the zlib distribution - * win32/DLL_FAQ.txt in the zlib distribution - - 4. compress() returns Z_BUF_ERROR. - - Make sure that before the call of compress, the length of the compressed - buffer is equal to the total size of the compressed buffer and not - zero. For Visual Basic, check that this parameter is passed by reference - ("as any"), not by value ("as long"). - - 5. deflate() or inflate() returns Z_BUF_ERROR. - - Before making the call, make sure that avail_in and avail_out are not - zero. When setting the parameter flush equal to Z_FINISH, also make sure - that avail_out is big enough to allow processing all pending input. - Note that a Z_BUF_ERROR is not fatal--another call to deflate() or - inflate() can be made with more input or output space. A Z_BUF_ERROR - may in fact be unavoidable depending on how the functions are used, since - it is not possible to tell whether or not there is more output pending - when strm.avail_out returns with zero. - - 6. Where's the zlib documentation (man pages, etc.)? - - It's in zlib.h for the moment, and Francis S. Lin has converted it to a - web page zlib.html. Volunteers to transform this to Unix-style man pages, - please contact us (zlib@gzip.org). Examples of zlib usage are in the files - example.c and minigzip.c. - - 7. Why don't you use GNU autoconf or libtool or ...? - - Because we would like to keep zlib as a very small and simple - package. zlib is rather portable and doesn't need much configuration. - - 8. I found a bug in zlib. - - Most of the time, such problems are due to an incorrect usage of - zlib. Please try to reproduce the problem with a small program and send - the corresponding source to us at zlib@gzip.org . Do not send - multi-megabyte data files without prior agreement. - - 9. Why do I get "undefined reference to gzputc"? - - If "make test" produces something like - - example.o(.text+0x154): undefined reference to `gzputc' - - check that you don't have old files libz.* in /usr/lib, /usr/local/lib or - /usr/X11R6/lib. Remove any old versions, then do "make install". - -10. I need a Delphi interface to zlib. - - See the contrib/delphi directory in the zlib distribution. - -11. Can zlib handle .zip archives? - - Not by itself, no. See the directory contrib/minizip in the zlib - distribution. - -12. Can zlib handle .Z files? - - No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt - the code of uncompress on your own. - -13. How can I make a Unix shared library? - - make clean - ./configure -s - make - -14. How do I install a shared zlib library on Unix? - - After the above, then: - - make install - - However, many flavors of Unix come with a shared zlib already installed. - Before going to the trouble of compiling a shared version of zlib and - trying to install it, you may want to check if it's already there! If you - can #include , it's there. The -lz option will probably link to it. - -15. I have a question about OttoPDF. - - We are not the authors of OttoPDF. The real author is on the OttoPDF web - site: Joel Hainley, jhainley@myndkryme.com. - -16. Can zlib decode Flate data in an Adobe PDF file? - - Yes. See http://www.fastio.com/ (ClibPDF), or http://www.pdflib.com/ . - To modify PDF forms, see http://sourceforge.net/projects/acroformtool/ . - -17. Why am I getting this "register_frame_info not found" error on Solaris? - - After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib - generates an error such as: - - ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so: - symbol __register_frame_info: referenced symbol not found - - The symbol __register_frame_info is not part of zlib, it is generated by - the C compiler (cc or gcc). You must recompile applications using zlib - which have this problem. This problem is specific to Solaris. See - http://www.sunfreeware.com for Solaris versions of zlib and applications - using zlib. - -18. Why does gzip give an error on a file I make with compress/deflate? - - The compress and deflate functions produce data in the zlib format, which - is different and incompatible with the gzip format. The gz* functions in - zlib on the other hand use the gzip format. Both the zlib and gzip - formats use the same compressed data format internally, but have different - headers and trailers around the compressed data. - -19. Ok, so why are there two different formats? - - The gzip format was designed to retain the directory information about - a single file, such as the name and last modification date. The zlib - format on the other hand was designed for in-memory and communication - channel applications, and has a much more compact header and trailer and - uses a faster integrity check than gzip. - -20. Well that's nice, but how do I make a gzip file in memory? - - You can request that deflate write the gzip format instead of the zlib - format using deflateInit2(). You can also request that inflate decode - the gzip format using inflateInit2(). Read zlib.h for more details. - -21. Is zlib thread-safe? - - Yes. However any library routines that zlib uses and any application- - provided memory allocation routines must also be thread-safe. zlib's gz* - functions use stdio library routines, and most of zlib's functions use the - library memory allocation routines by default. zlib's Init functions allow - for the application to provide custom memory allocation routines. - - Of course, you should only operate on any given zlib or gzip stream from a - single thread at a time. - -22. Can I use zlib in my commercial application? - - Yes. Please read the license in zlib.h. - -23. Is zlib under the GNU license? - - No. Please read the license in zlib.h. - -24. The license says that altered source versions must be "plainly marked". So - what exactly do I need to do to meet that requirement? - - You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In - particular, the final version number needs to be changed to "f", and an - identification string should be appended to ZLIB_VERSION. Version numbers - x.x.x.f are reserved for modifications to zlib by others than the zlib - maintainers. For example, if the version of the base zlib you are altering - is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and - ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also - update the version strings in deflate.c and inftrees.c. - - For altered source distributions, you should also note the origin and - nature of the changes in zlib.h, as well as in ChangeLog and README, along - with the dates of the alterations. The origin should include at least your - name (or your company's name), and an email address to contact for help or - issues with the library. - - Note that distributing a compiled zlib library along with zlib.h and - zconf.h is also a source distribution, and so you should change - ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes - in zlib.h as you would for a full source distribution. - -25. Will zlib work on a big-endian or little-endian architecture, and can I - exchange compressed data between them? - - Yes and yes. - -26. Will zlib work on a 64-bit machine? - - It should. It has been tested on 64-bit machines, and has no dependence - on any data types being limited to 32-bits in length. If you have any - difficulties, please provide a complete problem report to zlib@gzip.org - -27. Will zlib decompress data from the PKWare Data Compression Library? - - No. The PKWare DCL uses a completely different compressed data format - than does PKZIP and zlib. However, you can look in zlib's contrib/blast - directory for a possible solution to your problem. - -28. Can I access data randomly in a compressed stream? - - No, not without some preparation. If when compressing you periodically - use Z_FULL_FLUSH, carefully write all the pending data at those points, - and keep an index of those locations, then you can start decompression - at those points. You have to be careful to not use Z_FULL_FLUSH too - often, since it can significantly degrade compression. - -29. Does zlib work on MVS, OS/390, CICS, etc.? - - We don't know for sure. We have heard occasional reports of success on - these systems. If you do use it on one of these, please provide us with - a report, instructions, and patches that we can reference when we get - these questions. Thanks. - -30. Is there some simpler, easier to read version of inflate I can look at - to understand the deflate format? - - First off, you should read RFC 1951. Second, yes. Look in zlib's - contrib/puff directory. - -31. Does zlib infringe on any patents? - - As far as we know, no. In fact, that was originally the whole point behind - zlib. Look here for some more information: - - http://www.gzip.org/#faq11 - -32. Can zlib work with greater than 4 GB of data? - - Yes. inflate() and deflate() will process any amount of data correctly. - Each call of inflate() or deflate() is limited to input and output chunks - of the maximum value that can be stored in the compiler's "unsigned int" - type, but there is no limit to the number of chunks. Note however that the - strm.total_in and strm_total_out counters may be limited to 4 GB. These - counters are provided as a convenience and are not used internally by - inflate() or deflate(). The application can easily set up its own counters - updated after each call of inflate() or deflate() to count beyond 4 GB. - compress() and uncompress() may be limited to 4 GB, since they operate in a - single call. gzseek() and gztell() may be limited to 4 GB depending on how - zlib is compiled. See the zlibCompileFlags() function in zlib.h. - - The word "may" appears several times above since there is a 4 GB limit - only if the compiler's "long" type is 32 bits. If the compiler's "long" - type is 64 bits, then the limit is 16 exabytes. - -33. Does zlib have any security vulnerabilities? - - The only one that we are aware of is potentially in gzprintf(). If zlib - is compiled to use sprintf() or vsprintf(), then there is no protection - against a buffer overflow of a 4K string space, other than the caller of - gzprintf() assuring that the output will not exceed 4K. On the other - hand, if zlib is compiled to use snprintf() or vsnprintf(), which should - normally be the case, then there is no vulnerability. The ./configure - script will display warnings if an insecure variation of sprintf() will - be used by gzprintf(). Also the zlibCompileFlags() function will return - information on what variant of sprintf() is used by gzprintf(). - - If you don't have snprintf() or vsnprintf() and would like one, you can - find a portable implementation here: - - http://www.ijs.si/software/snprintf/ - - Note that you should be using the most recent version of zlib. Versions - 1.1.3 and before were subject to a double-free vulnerability. - -34. Is there a Java version of zlib? - - Probably what you want is to use zlib in Java. zlib is already included - as part of the Java SDK in the java.util.zip package. If you really want - a version of zlib written in the Java language, look on the zlib home - page for links: http://www.zlib.org/ - -35. I get this or that compiler or source-code scanner warning when I crank it - up to maximally-pedantic. Can't you guys write proper code? - - Many years ago, we gave up attempting to avoid warnings on every compiler - in the universe. It just got to be a waste of time, and some compilers - were downright silly. So now, we simply make sure that the code always - works. - -36. Valgrind (or some similar memory access checker) says that deflate is - performing a conditional jump that depends on an uninitialized value. - Isn't that a bug? - - No. That is intentional for performance reasons, and the output of - deflate is not affected. This only started showing up recently since - zlib 1.2.x uses malloc() by default for allocations, whereas earlier - versions used calloc(), which zeros out the allocated memory. - -37. Will zlib read the (insert any ancient or arcane format here) compressed - data format? - - Probably not. Look in the comp.compression FAQ for pointers to various - formats and associated software. - -38. How can I encrypt/decrypt zip files with zlib? - - zlib doesn't support encryption. The original PKZIP encryption is very weak - and can be broken with freely available programs. To get strong encryption, - use GnuPG, http://www.gnupg.org/ , which already includes zlib compression. - For PKZIP compatible "encryption", look at http://www.info-zip.org/ - -39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings? - - "gzip" is the gzip format, and "deflate" is the zlib format. They should - probably have called the second one "zlib" instead to avoid confusion - with the raw deflate compressed data format. While the HTTP 1.1 RFC 2616 - correctly points to the zlib specification in RFC 1950 for the "deflate" - transfer encoding, there have been reports of servers and browsers that - incorrectly produce or expect raw deflate data per the deflate - specficiation in RFC 1951, most notably Microsoft. So even though the - "deflate" transfer encoding using the zlib format would be the more - efficient approach (and in fact exactly what the zlib format was designed - for), using the "gzip" transfer encoding is probably more reliable due to - an unfortunate choice of name on the part of the HTTP 1.1 authors. - - Bottom line: use the gzip format for HTTP 1.1 encoding. - -40. Does zlib support the new "Deflate64" format introduced by PKWare? - - No. PKWare has apparently decided to keep that format proprietary, since - they have not documented it as they have previous compression formats. - In any case, the compression improvements are so modest compared to other - more modern approaches, that it's not worth the effort to implement. - -41. Can you please sign these lengthy legal documents and fax them back to us - so that we can use your software in our product? - - No. Go away. Shoo. diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/INDEX b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/INDEX deleted file mode 100644 index 4d7eac44b..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/INDEX +++ /dev/null @@ -1,51 +0,0 @@ -ChangeLog history of changes -FAQ Frequently Asked Questions about zlib -INDEX this file -Makefile makefile for Unix (generated by configure) -Makefile.in makefile for Unix (template for configure) -README guess what -algorithm.txt description of the (de)compression algorithm -configure configure script for Unix -zconf.in.h template for zconf.h (used by configure) - -amiga/ makefiles for Amiga SAS C -as400/ makefiles for IBM AS/400 -msdos/ makefiles for MSDOS -old/ makefiles for various architectures and zlib documentation - files that have not yet been updated for zlib 1.2.x -projects/ projects for various Integrated Development Environments -qnx/ makefiles for QNX -win32/ makefiles for Windows - - zlib public header files (must be kept): -zconf.h -zlib.h - - private source files used to build the zlib library: -adler32.c -compress.c -crc32.c -crc32.h -deflate.c -deflate.h -gzio.c -infback.c -inffast.c -inffast.h -inffixed.h -inflate.c -inflate.h -inftrees.c -inftrees.h -trees.c -trees.h -uncompr.c -zutil.c -zutil.h - - source files for sample programs: -example.c -minigzip.c - - unsupported contribution by third parties -See contrib/README.contrib diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/Makefile b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/Makefile deleted file mode 100644 index a4954c8f9..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/Makefile +++ /dev/null @@ -1,154 +0,0 @@ -# Makefile for zlib -# Copyright (C) 1995-2005 Jean-loup Gailly. -# For conditions of distribution and use, see copyright notice in zlib.h - -# To compile and test, type: -# ./configure; make test -# The call of configure is optional if you don't have special requirements -# If you wish to build zlib as a shared library, use: ./configure -s - -# To use the asm code, type: -# cp contrib/asm?86/match.S ./match.S -# make LOC=-DASMV OBJA=match.o - -# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type: -# make install -# To install in $HOME instead of /usr/local, use: -# make install prefix=$HOME - -CC=cc - -CFLAGS=-O -#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 -#CFLAGS=-g -DDEBUG -#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ -# -Wstrict-prototypes -Wmissing-prototypes - -LDFLAGS=libz.a -LDSHARED=$(CC) -CPP=$(CC) -E - -LIBS=libz.a -SHAREDLIB=libz.so -SHAREDLIBV=libz.so.1.2.3 -SHAREDLIBM=libz.so.1 - -AR=ar rc -RANLIB=ranlib -TAR=tar -SHELL=/bin/sh -EXE= - -prefix = /usr/local -exec_prefix = ${prefix} -libdir = ${exec_prefix}/lib -includedir = ${prefix}/include -mandir = ${prefix}/share/man -man3dir = ${mandir}/man3 - -OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ - zutil.o inflate.o infback.o inftrees.o inffast.o - -OBJA = -# to use the asm code: make OBJA=match.o - -TEST_OBJS = example.o minigzip.o - -all: example$(EXE) minigzip$(EXE) - -check: test -test: all - @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ - echo hello world | ./minigzip | ./minigzip -d || \ - echo ' *** minigzip test FAILED ***' ; \ - if ./example; then \ - echo ' *** zlib test OK ***'; \ - else \ - echo ' *** zlib test FAILED ***'; \ - fi - -libz.a: $(OBJS) $(OBJA) - $(AR) $@ $(OBJS) $(OBJA) - -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 - -match.o: match.S - $(CPP) match.S > _match.s - $(CC) -c _match.s - mv _match.o match.o - rm -f _match.s - -$(SHAREDLIBV): $(OBJS) - $(LDSHARED) -o $@ $(OBJS) - rm -f $(SHAREDLIB) $(SHAREDLIBM) - ln -s $@ $(SHAREDLIB) - ln -s $@ $(SHAREDLIBM) - -example$(EXE): example.o $(LIBS) - $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) - -minigzip$(EXE): minigzip.o $(LIBS) - $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) - -install: $(LIBS) - -@if [ ! -d $(exec_prefix) ]; then mkdir -p $(exec_prefix); fi - -@if [ ! -d $(includedir) ]; then mkdir -p $(includedir); fi - -@if [ ! -d $(libdir) ]; then mkdir -p $(libdir); fi - -@if [ ! -d $(man3dir) ]; then mkdir -p $(man3dir); fi - cp zlib.h zconf.h $(includedir) - chmod 644 $(includedir)/zlib.h $(includedir)/zconf.h - cp $(LIBS) $(libdir) - cd $(libdir); chmod 755 $(LIBS) - -@(cd $(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1 - cd $(libdir); if test -f $(SHAREDLIBV); then \ - rm -f $(SHAREDLIB) $(SHAREDLIBM); \ - ln -s $(SHAREDLIBV) $(SHAREDLIB); \ - ln -s $(SHAREDLIBV) $(SHAREDLIBM); \ - (ldconfig || true) >/dev/null 2>&1; \ - fi - cp zlib.3 $(man3dir) - chmod 644 $(man3dir)/zlib.3 -# The ranlib in install is needed on NeXTSTEP which checks file times -# ldconfig is for Linux - -uninstall: - cd $(includedir); \ - cd $(libdir); rm -f libz.a; \ - if test -f $(SHAREDLIBV); then \ - rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \ - fi - cd $(man3dir); rm -f zlib.3 - -mostlyclean: clean -clean: - rm -f *.o *~ example$(EXE) minigzip$(EXE) \ - libz.* foo.gz so_locations \ - _match.s maketree contrib/infback9/*.o - -maintainer-clean: distclean -distclean: clean - cp -p Makefile.in Makefile - cp -p zconf.in.h zconf.h - rm -f .DS_Store - -tags: - etags *.[ch] - -depend: - makedepend -- $(CFLAGS) -- *.[ch] - -# DO NOT DELETE THIS LINE -- make depend depends on it. - -adler32.o: zlib.h zconf.h -compress.o: zlib.h zconf.h -crc32.o: crc32.h zlib.h zconf.h -deflate.o: deflate.h zutil.h zlib.h zconf.h -example.o: zlib.h zconf.h -gzio.o: zutil.h zlib.h zconf.h -inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -inftrees.o: zutil.h zlib.h zconf.h inftrees.h -minigzip.o: zlib.h zconf.h -trees.o: deflate.h zutil.h zlib.h zconf.h trees.h -uncompr.o: zlib.h zconf.h -zutil.o: zutil.h zlib.h zconf.h diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/Makefile.in b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/Makefile.in deleted file mode 100644 index a4954c8f9..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/Makefile.in +++ /dev/null @@ -1,154 +0,0 @@ -# Makefile for zlib -# Copyright (C) 1995-2005 Jean-loup Gailly. -# For conditions of distribution and use, see copyright notice in zlib.h - -# To compile and test, type: -# ./configure; make test -# The call of configure is optional if you don't have special requirements -# If you wish to build zlib as a shared library, use: ./configure -s - -# To use the asm code, type: -# cp contrib/asm?86/match.S ./match.S -# make LOC=-DASMV OBJA=match.o - -# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type: -# make install -# To install in $HOME instead of /usr/local, use: -# make install prefix=$HOME - -CC=cc - -CFLAGS=-O -#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 -#CFLAGS=-g -DDEBUG -#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ -# -Wstrict-prototypes -Wmissing-prototypes - -LDFLAGS=libz.a -LDSHARED=$(CC) -CPP=$(CC) -E - -LIBS=libz.a -SHAREDLIB=libz.so -SHAREDLIBV=libz.so.1.2.3 -SHAREDLIBM=libz.so.1 - -AR=ar rc -RANLIB=ranlib -TAR=tar -SHELL=/bin/sh -EXE= - -prefix = /usr/local -exec_prefix = ${prefix} -libdir = ${exec_prefix}/lib -includedir = ${prefix}/include -mandir = ${prefix}/share/man -man3dir = ${mandir}/man3 - -OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ - zutil.o inflate.o infback.o inftrees.o inffast.o - -OBJA = -# to use the asm code: make OBJA=match.o - -TEST_OBJS = example.o minigzip.o - -all: example$(EXE) minigzip$(EXE) - -check: test -test: all - @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ - echo hello world | ./minigzip | ./minigzip -d || \ - echo ' *** minigzip test FAILED ***' ; \ - if ./example; then \ - echo ' *** zlib test OK ***'; \ - else \ - echo ' *** zlib test FAILED ***'; \ - fi - -libz.a: $(OBJS) $(OBJA) - $(AR) $@ $(OBJS) $(OBJA) - -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 - -match.o: match.S - $(CPP) match.S > _match.s - $(CC) -c _match.s - mv _match.o match.o - rm -f _match.s - -$(SHAREDLIBV): $(OBJS) - $(LDSHARED) -o $@ $(OBJS) - rm -f $(SHAREDLIB) $(SHAREDLIBM) - ln -s $@ $(SHAREDLIB) - ln -s $@ $(SHAREDLIBM) - -example$(EXE): example.o $(LIBS) - $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) - -minigzip$(EXE): minigzip.o $(LIBS) - $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) - -install: $(LIBS) - -@if [ ! -d $(exec_prefix) ]; then mkdir -p $(exec_prefix); fi - -@if [ ! -d $(includedir) ]; then mkdir -p $(includedir); fi - -@if [ ! -d $(libdir) ]; then mkdir -p $(libdir); fi - -@if [ ! -d $(man3dir) ]; then mkdir -p $(man3dir); fi - cp zlib.h zconf.h $(includedir) - chmod 644 $(includedir)/zlib.h $(includedir)/zconf.h - cp $(LIBS) $(libdir) - cd $(libdir); chmod 755 $(LIBS) - -@(cd $(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1 - cd $(libdir); if test -f $(SHAREDLIBV); then \ - rm -f $(SHAREDLIB) $(SHAREDLIBM); \ - ln -s $(SHAREDLIBV) $(SHAREDLIB); \ - ln -s $(SHAREDLIBV) $(SHAREDLIBM); \ - (ldconfig || true) >/dev/null 2>&1; \ - fi - cp zlib.3 $(man3dir) - chmod 644 $(man3dir)/zlib.3 -# The ranlib in install is needed on NeXTSTEP which checks file times -# ldconfig is for Linux - -uninstall: - cd $(includedir); \ - cd $(libdir); rm -f libz.a; \ - if test -f $(SHAREDLIBV); then \ - rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \ - fi - cd $(man3dir); rm -f zlib.3 - -mostlyclean: clean -clean: - rm -f *.o *~ example$(EXE) minigzip$(EXE) \ - libz.* foo.gz so_locations \ - _match.s maketree contrib/infback9/*.o - -maintainer-clean: distclean -distclean: clean - cp -p Makefile.in Makefile - cp -p zconf.in.h zconf.h - rm -f .DS_Store - -tags: - etags *.[ch] - -depend: - makedepend -- $(CFLAGS) -- *.[ch] - -# DO NOT DELETE THIS LINE -- make depend depends on it. - -adler32.o: zlib.h zconf.h -compress.o: zlib.h zconf.h -crc32.o: crc32.h zlib.h zconf.h -deflate.o: deflate.h zutil.h zlib.h zconf.h -example.o: zlib.h zconf.h -gzio.o: zutil.h zlib.h zconf.h -inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -inftrees.o: zutil.h zlib.h zconf.h inftrees.h -minigzip.o: zlib.h zconf.h -trees.o: deflate.h zutil.h zlib.h zconf.h trees.h -uncompr.o: zlib.h zconf.h -zutil.o: zutil.h zlib.h zconf.h diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/README b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/README deleted file mode 100644 index 80f71ae85..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/README +++ /dev/null @@ -1,125 +0,0 @@ -ZLIB DATA COMPRESSION LIBRARY - -zlib 1.2.3 is a general purpose data compression library. All the code is -thread safe. The data format used by the zlib library is described by RFCs -(Request for Comments) 1950 to 1952 in the files -http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) -and rfc1952.txt (gzip format). These documents are also available in other -formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html - -All functions of the compression library are documented in the file zlib.h -(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example -of the library is given in the file example.c which also tests that the library -is working correctly. Another example is given in the file minigzip.c. The -compression library itself is composed of all source files except example.c and -minigzip.c. - -To compile all files and run the test program, follow the instructions given at -the top of Makefile. In short "make test; make install" should work for most -machines. For Unix: "./configure; make test; make install". For MSDOS, use one -of the special makefiles such as Makefile.msc. For VMS, use make_vms.com. - -Questions about zlib should be sent to , or to Gilles Vollant - for the Windows DLL version. The zlib home page is -http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem, -please check this site to verify that you have the latest version of zlib; -otherwise get the latest version and check whether the problem still exists or -not. - -PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking -for help. - -Mark Nelson wrote an article about zlib for the Jan. 1997 -issue of Dr. Dobb's Journal; a copy of the article is available in -http://dogma.net/markn/articles/zlibtool/zlibtool.htm - -The changes made in version 1.2.3 are documented in the file ChangeLog. - -Unsupported third party contributions are provided in directory "contrib". - -A Java implementation of zlib is available in the Java Development Kit -http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html -See the zlib home page http://www.zlib.org for details. - -A Perl interface to zlib written by Paul Marquess is in the -CPAN (Comprehensive Perl Archive Network) sites -http://www.cpan.org/modules/by-module/Compress/ - -A Python interface to zlib written by A.M. Kuchling is -available in Python 1.5 and later versions, see -http://www.python.org/doc/lib/module-zlib.html - -A zlib binding for TCL written by Andreas Kupries is -availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html - -An experimental package to read and write files in .zip format, written on top -of zlib by Gilles Vollant , is available in the -contrib/minizip directory of zlib. - - -Notes for some targets: - -- For Windows DLL versions, please see win32/DLL_FAQ.txt - -- For 64-bit Irix, deflate.c must be compiled without any optimization. With - -O, one libpng test fails. The test works in 32 bit mode (with the -n32 - compiler flag). The compiler bug has been reported to SGI. - -- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works - when compiled with cc. - -- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is - necessary to get gzprintf working correctly. This is done by configure. - -- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with - other compilers. Use "make test" to check your compiler. - -- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers. - -- For PalmOs, see http://palmzlib.sourceforge.net/ - -- When building a shared, i.e. dynamic library on Mac OS X, the library must be - installed before testing (do "make install" before "make test"), since the - library location is specified in the library. - - -Acknowledgments: - - The deflate format used by zlib was defined by Phil Katz. The deflate - and zlib specifications were written by L. Peter Deutsch. Thanks to all the - people who reported problems and suggested various improvements in zlib; - they are too numerous to cite here. - -Copyright notice: - - (C) 1995-2004 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - -If you use the zlib library in a product, we would appreciate *not* -receiving lengthy legal documents to sign. The sources are provided -for free but without warranty of any kind. The library has been -entirely written by Jean-loup Gailly and Mark Adler; it does not -include third-party code. - -If you redistribute modified sources, we would appreciate that you include -in the file ChangeLog history information documenting your changes. Please -read the FAQ for more information on the distribution of modified source -versions. diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/adler32.c b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/adler32.c deleted file mode 100644 index 007ba2627..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/adler32.c +++ /dev/null @@ -1,149 +0,0 @@ -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-2004 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -#define BASE 65521UL /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} -#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); -#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); -#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); -#define DO16(buf) DO8(buf,0); DO8(buf,8); - -/* use NO_DIVIDE if your processor does not do division in hardware */ -#ifdef NO_DIVIDE -# define MOD(a) \ - do { \ - if (a >= (BASE << 16)) a -= (BASE << 16); \ - if (a >= (BASE << 15)) a -= (BASE << 15); \ - if (a >= (BASE << 14)) a -= (BASE << 14); \ - if (a >= (BASE << 13)) a -= (BASE << 13); \ - if (a >= (BASE << 12)) a -= (BASE << 12); \ - if (a >= (BASE << 11)) a -= (BASE << 11); \ - if (a >= (BASE << 10)) a -= (BASE << 10); \ - if (a >= (BASE << 9)) a -= (BASE << 9); \ - if (a >= (BASE << 8)) a -= (BASE << 8); \ - if (a >= (BASE << 7)) a -= (BASE << 7); \ - if (a >= (BASE << 6)) a -= (BASE << 6); \ - if (a >= (BASE << 5)) a -= (BASE << 5); \ - if (a >= (BASE << 4)) a -= (BASE << 4); \ - if (a >= (BASE << 3)) a -= (BASE << 3); \ - if (a >= (BASE << 2)) a -= (BASE << 2); \ - if (a >= (BASE << 1)) a -= (BASE << 1); \ - if (a >= BASE) a -= BASE; \ - } while (0) -# define MOD4(a) \ - do { \ - if (a >= (BASE << 4)) a -= (BASE << 4); \ - if (a >= (BASE << 3)) a -= (BASE << 3); \ - if (a >= (BASE << 2)) a -= (BASE << 2); \ - if (a >= (BASE << 1)) a -= (BASE << 1); \ - if (a >= BASE) a -= BASE; \ - } while (0) -#else -# define MOD(a) a %= BASE -# define MOD4(a) a %= BASE -#endif - -/* ========================================================================= */ -uLong ZEXPORT adler32(adler, buf, len) - uLong adler; - const Bytef *buf; - uInt len; -{ - unsigned long sum2; - unsigned n; - - /* split Adler-32 into component sums */ - sum2 = (adler >> 16) & 0xffff; - adler &= 0xffff; - - /* in case user likes doing a byte at a time, keep it fast */ - if (len == 1) { - adler += buf[0]; - if (adler >= BASE) - adler -= BASE; - sum2 += adler; - if (sum2 >= BASE) - sum2 -= BASE; - return adler | (sum2 << 16); - } - - /* initial Adler-32 value (deferred check for len == 1 speed) */ - if (buf == Z_NULL) - return 1L; - - /* in case short lengths are provided, keep it somewhat fast */ - if (len < 16) { - while (len--) { - adler += *buf++; - sum2 += adler; - } - if (adler >= BASE) - adler -= BASE; - MOD4(sum2); /* only added so many BASE's */ - return adler | (sum2 << 16); - } - - /* do length NMAX blocks -- requires just one modulo operation */ - while (len >= NMAX) { - len -= NMAX; - n = NMAX / 16; /* NMAX is divisible by 16 */ - do { - DO16(buf); /* 16 sums unrolled */ - buf += 16; - } while (--n); - MOD(adler); - MOD(sum2); - } - - /* do remaining bytes (less than NMAX, still just one modulo) */ - if (len) { /* avoid modulos if none remaining */ - while (len >= 16) { - len -= 16; - DO16(buf); - buf += 16; - } - while (len--) { - adler += *buf++; - sum2 += adler; - } - MOD(adler); - MOD(sum2); - } - - /* return recombined sums */ - return adler | (sum2 << 16); -} - -/* ========================================================================= */ -uLong ZEXPORT adler32_combine(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off_t len2; -{ - unsigned long sum1; - unsigned long sum2; - unsigned rem; - - /* the derivation of this formula is left as an exercise for the reader */ - rem = (unsigned)(len2 % BASE); - sum1 = adler1 & 0xffff; - sum2 = rem * sum1; - MOD(sum2); - sum1 += (adler2 & 0xffff) + BASE - 1; - sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; - if (sum1 > BASE) sum1 -= BASE; - if (sum1 > BASE) sum1 -= BASE; - if (sum2 > (BASE << 1)) sum2 -= (BASE << 1); - if (sum2 > BASE) sum2 -= BASE; - return sum1 | (sum2 << 16); -} diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/algorithm.txt b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/algorithm.txt deleted file mode 100644 index 9f6b06808..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/algorithm.txt +++ /dev/null @@ -1,209 +0,0 @@ -1. Compression algorithm (deflate) - -The deflation algorithm used by gzip (also zip and zlib) is a variation of -LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in -the input data. The second occurrence of a string is replaced by a -pointer to the previous string, in the form of a pair (distance, -length). Distances are limited to 32K bytes, and lengths are limited -to 258 bytes. When a string does not occur anywhere in the previous -32K bytes, it is emitted as a sequence of literal bytes. (In this -description, `string' must be taken as an arbitrary sequence of bytes, -and is not restricted to printable characters.) - -Literals or match lengths are compressed with one Huffman tree, and -match distances are compressed with another tree. The trees are stored -in a compact form at the start of each block. The blocks can have any -size (except that the compressed data for one block must fit in -available memory). A block is terminated when deflate() determines that -it would be useful to start another block with fresh trees. (This is -somewhat similar to the behavior of LZW-based _compress_.) - -Duplicated strings are found using a hash table. All input strings of -length 3 are inserted in the hash table. A hash index is computed for -the next 3 bytes. If the hash chain for this index is not empty, all -strings in the chain are compared with the current input string, and -the longest match is selected. - -The hash chains are searched starting with the most recent strings, to -favor small distances and thus take advantage of the Huffman encoding. -The hash chains are singly linked. There are no deletions from the -hash chains, the algorithm simply discards matches that are too old. - -To avoid a worst-case situation, very long hash chains are arbitrarily -truncated at a certain length, determined by a runtime option (level -parameter of deflateInit). So deflate() does not always find the longest -possible match but generally finds a match which is long enough. - -deflate() also defers the selection of matches with a lazy evaluation -mechanism. After a match of length N has been found, deflate() searches for -a longer match at the next input byte. If a longer match is found, the -previous match is truncated to a length of one (thus producing a single -literal byte) and the process of lazy evaluation begins again. Otherwise, -the original match is kept, and the next match search is attempted only N -steps later. - -The lazy match evaluation is also subject to a runtime parameter. If -the current match is long enough, deflate() reduces the search for a longer -match, thus speeding up the whole process. If compression ratio is more -important than speed, deflate() attempts a complete second search even if -the first match is already long enough. - -The lazy match evaluation is not performed for the fastest compression -modes (level parameter 1 to 3). For these fast modes, new strings -are inserted in the hash table only when no match was found, or -when the match is not too long. This degrades the compression ratio -but saves time since there are both fewer insertions and fewer searches. - - -2. Decompression algorithm (inflate) - -2.1 Introduction - -The key question is how to represent a Huffman code (or any prefix code) so -that you can decode fast. The most important characteristic is that shorter -codes are much more common than longer codes, so pay attention to decoding the -short codes fast, and let the long codes take longer to decode. - -inflate() sets up a first level table that covers some number of bits of -input less than the length of longest code. It gets that many bits from the -stream, and looks it up in the table. The table will tell if the next -code is that many bits or less and how many, and if it is, it will tell -the value, else it will point to the next level table for which inflate() -grabs more bits and tries to decode a longer code. - -How many bits to make the first lookup is a tradeoff between the time it -takes to decode and the time it takes to build the table. If building the -table took no time (and if you had infinite memory), then there would only -be a first level table to cover all the way to the longest code. However, -building the table ends up taking a lot longer for more bits since short -codes are replicated many times in such a table. What inflate() does is -simply to make the number of bits in the first table a variable, and then -to set that variable for the maximum speed. - -For inflate, which has 286 possible codes for the literal/length tree, the size -of the first table is nine bits. Also the distance trees have 30 possible -values, and the size of the first table is six bits. Note that for each of -those cases, the table ended up one bit longer than the ``average'' code -length, i.e. the code length of an approximately flat code which would be a -little more than eight bits for 286 symbols and a little less than five bits -for 30 symbols. - - -2.2 More details on the inflate table lookup - -Ok, you want to know what this cleverly obfuscated inflate tree actually -looks like. You are correct that it's not a Huffman tree. It is simply a -lookup table for the first, let's say, nine bits of a Huffman symbol. The -symbol could be as short as one bit or as long as 15 bits. If a particular -symbol is shorter than nine bits, then that symbol's translation is duplicated -in all those entries that start with that symbol's bits. For example, if the -symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a -symbol is nine bits long, it appears in the table once. - -If the symbol is longer than nine bits, then that entry in the table points -to another similar table for the remaining bits. Again, there are duplicated -entries as needed. The idea is that most of the time the symbol will be short -and there will only be one table look up. (That's whole idea behind data -compression in the first place.) For the less frequent long symbols, there -will be two lookups. If you had a compression method with really long -symbols, you could have as many levels of lookups as is efficient. For -inflate, two is enough. - -So a table entry either points to another table (in which case nine bits in -the above example are gobbled), or it contains the translation for the symbol -and the number of bits to gobble. Then you start again with the next -ungobbled bit. - -You may wonder: why not just have one lookup table for how ever many bits the -longest symbol is? The reason is that if you do that, you end up spending -more time filling in duplicate symbol entries than you do actually decoding. -At least for deflate's output that generates new trees every several 10's of -kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code -would take too long if you're only decoding several thousand symbols. At the -other extreme, you could make a new table for every bit in the code. In fact, -that's essentially a Huffman tree. But then you spend two much time -traversing the tree while decoding, even for short symbols. - -So the number of bits for the first lookup table is a trade of the time to -fill out the table vs. the time spent looking at the second level and above of -the table. - -Here is an example, scaled down: - -The code being decoded, with 10 symbols, from 1 to 6 bits long: - -A: 0 -B: 10 -C: 1100 -D: 11010 -E: 11011 -F: 11100 -G: 11101 -H: 11110 -I: 111110 -J: 111111 - -Let's make the first table three bits long (eight entries): - -000: A,1 -001: A,1 -010: A,1 -011: A,1 -100: B,2 -101: B,2 -110: -> table X (gobble 3 bits) -111: -> table Y (gobble 3 bits) - -Each entry is what the bits decode as and how many bits that is, i.e. how -many bits to gobble. Or the entry points to another table, with the number of -bits to gobble implicit in the size of the table. - -Table X is two bits long since the longest code starting with 110 is five bits -long: - -00: C,1 -01: C,1 -10: D,2 -11: E,2 - -Table Y is three bits long since the longest code starting with 111 is six -bits long: - -000: F,2 -001: F,2 -010: G,2 -011: G,2 -100: H,2 -101: H,2 -110: I,3 -111: J,3 - -So what we have here are three tables with a total of 20 entries that had to -be constructed. That's compared to 64 entries for a single table. Or -compared to 16 entries for a Huffman tree (six two entry tables and one four -entry table). Assuming that the code ideally represents the probability of -the symbols, it takes on the average 1.25 lookups per symbol. That's compared -to one lookup for the single table, or 1.66 lookups per symbol for the -Huffman tree. - -There, I think that gives you a picture of what's going on. For inflate, the -meaning of a particular symbol is often more than just a letter. It can be a -byte (a "literal"), or it can be either a length or a distance which -indicates a base value and a number of bits to fetch after the code that is -added to the base value. Or it might be the special end-of-block code. The -data structures created in inftrees.c try to encode all that information -compactly in the tables. - - -Jean-loup Gailly Mark Adler -jloup@gzip.org madler@alumni.caltech.edu - - -References: - -[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data -Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3, -pp. 337-343. - -``DEFLATE Compressed Data Format Specification'' available in -http://www.ietf.org/rfc/rfc1951.txt diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/compress.c b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/compress.c deleted file mode 100644 index df8013419..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/compress.c +++ /dev/null @@ -1,79 +0,0 @@ -/* compress.c -- compress a memory buffer - * Copyright (C) 1995-2003 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -/* =========================================================================== - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least 0.1% larger than sourceLen plus - 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ -int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; - int level; -{ - z_stream stream; - int err; - - stream.next_in = (Bytef*)source; - stream.avail_in = (uInt)sourceLen; -#ifdef MAXSEG_64K - /* Check for source > 64K on 16-bit machine: */ - if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; -#endif - stream.next_out = dest; - stream.avail_out = (uInt)*destLen; - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; - - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = (voidpf)0; - - err = deflateInit(&stream, level); - if (err != Z_OK) return err; - - err = deflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - deflateEnd(&stream); - return err == Z_OK ? Z_BUF_ERROR : err; - } - *destLen = stream.total_out; - - err = deflateEnd(&stream); - return err; -} - -/* =========================================================================== - */ -int Q_ZEXPORT compress (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ - return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); -} - -/* =========================================================================== - If the default memLevel or windowBits for deflateInit() is changed, then - this function needs to be updated. - */ -uLong ZEXPORT compressBound (sourceLen) - uLong sourceLen; -{ - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11; -} diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/configure b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/configure deleted file mode 100644 index 212e92ed2..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/configure +++ /dev/null @@ -1,459 +0,0 @@ -#!/bin/sh -# configure script for zlib. This script is needed only if -# you wish to build a shared library and your system supports them, -# of if you need special compiler, flags or install directory. -# Otherwise, you can just use directly "make test; make install" -# -# To create a shared library, use "configure --shared"; by default a static -# library is created. If the primitive shared library support provided here -# does not work, use ftp://prep.ai.mit.edu/pub/gnu/libtool-*.tar.gz -# -# To impose specific compiler or flags or install directory, use for example: -# prefix=$HOME CC=cc CFLAGS="-O4" ./configure -# or for csh/tcsh users: -# (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure) -# LDSHARED is the command to be used to create a shared library - -# Incorrect settings of CC or CFLAGS may prevent creating a shared library. -# If you have problems, try without defining CC and CFLAGS before reporting -# an error. - -LIBS=libz.a -LDFLAGS="-L. ${LIBS}" -VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h` -VER2=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\)\\..*/\1/p' < zlib.h` -VER1=`sed -n -e '/VERSION "/s/.*"\([0-9]*\)\\..*/\1/p' < zlib.h` -AR=${AR-"ar rc"} -RANLIB=${RANLIB-"ranlib"} -prefix=${prefix-/usr/local} -exec_prefix=${exec_prefix-'${prefix}'} -libdir=${libdir-'${exec_prefix}/lib'} -includedir=${includedir-'${prefix}/include'} -mandir=${mandir-'${prefix}/share/man'} -shared_ext='.so' -shared=0 -gcc=0 -old_cc="$CC" -old_cflags="$CFLAGS" - -while test $# -ge 1 -do -case "$1" in - -h* | --h*) - echo 'usage:' - echo ' configure [--shared] [--prefix=PREFIX] [--exec_prefix=EXPREFIX]' - echo ' [--libdir=LIBDIR] [--includedir=INCLUDEDIR]' - exit 0;; - -p*=* | --p*=*) prefix=`echo $1 | sed 's/[-a-z_]*=//'`; shift;; - -e*=* | --e*=*) exec_prefix=`echo $1 | sed 's/[-a-z_]*=//'`; shift;; - -l*=* | --libdir=*) libdir=`echo $1 | sed 's/[-a-z_]*=//'`; shift;; - -i*=* | --includedir=*) includedir=`echo $1 | sed 's/[-a-z_]*=//'`;shift;; - -p* | --p*) prefix="$2"; shift; shift;; - -e* | --e*) exec_prefix="$2"; shift; shift;; - -l* | --l*) libdir="$2"; shift; shift;; - -i* | --i*) includedir="$2"; shift; shift;; - -s* | --s*) shared=1; shift;; - *) echo "unknown option: $1"; echo "$0 --help for help"; exit 1;; - esac -done - -test=ztest$$ -cat > $test.c </dev/null; then - CC="$cc" - SFLAGS=${CFLAGS-"-fPIC -O3"} - CFLAGS="$cflags" - case `(uname -s || echo unknown) 2>/dev/null` in - Linux | linux | GNU | GNU/*) LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1"};; - CYGWIN* | Cygwin* | cygwin* | OS/2* ) - EXE='.exe';; - QNX*) # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4 - # (alain.bonnefoy@icbt.com) - LDSHARED=${LDSHARED-"$cc -shared -Wl,-hlibz.so.1"};; - HP-UX*) - LDSHARED=${LDSHARED-"$cc -shared $SFLAGS"} - case `(uname -m || echo unknown) 2>/dev/null` in - ia64) - shared_ext='.so' - SHAREDLIB='libz.so';; - *) - shared_ext='.sl' - SHAREDLIB='libz.sl';; - esac;; - Darwin*) shared_ext='.dylib' - SHAREDLIB=libz$shared_ext - SHAREDLIBV=libz.$VER$shared_ext - SHAREDLIBM=libz.$VER1$shared_ext - LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER"};; - *) LDSHARED=${LDSHARED-"$cc -shared"};; - esac -else - # find system name and corresponding cc options - CC=${CC-cc} - case `(uname -sr || echo unknown) 2>/dev/null` in - HP-UX*) SFLAGS=${CFLAGS-"-O +z"} - CFLAGS=${CFLAGS-"-O"} -# LDSHARED=${LDSHARED-"ld -b +vnocompatwarnings"} - LDSHARED=${LDSHARED-"ld -b"} - case `(uname -m || echo unknown) 2>/dev/null` in - ia64) - shared_ext='.so' - SHAREDLIB='libz.so';; - *) - shared_ext='.sl' - SHAREDLIB='libz.sl';; - esac;; - IRIX*) SFLAGS=${CFLAGS-"-ansi -O2 -rpath ."} - CFLAGS=${CFLAGS-"-ansi -O2"} - LDSHARED=${LDSHARED-"cc -shared"};; - OSF1\ V4*) SFLAGS=${CFLAGS-"-O -std1"} - CFLAGS=${CFLAGS-"-O -std1"} - LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so -Wl,-msym -Wl,-rpath,$(libdir) -Wl,-set_version,${VER}:1.0"};; - OSF1*) SFLAGS=${CFLAGS-"-O -std1"} - CFLAGS=${CFLAGS-"-O -std1"} - LDSHARED=${LDSHARED-"cc -shared"};; - QNX*) SFLAGS=${CFLAGS-"-4 -O"} - CFLAGS=${CFLAGS-"-4 -O"} - LDSHARED=${LDSHARED-"cc"} - RANLIB=${RANLIB-"true"} - AR="cc -A";; - SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "} - CFLAGS=${CFLAGS-"-O3"} - LDSHARED=${LDSHARED-"cc -dy -KPIC -G"};; - SunOS\ 5*) SFLAGS=${CFLAGS-"-fast -xcg89 -KPIC -R."} - CFLAGS=${CFLAGS-"-fast -xcg89"} - LDSHARED=${LDSHARED-"cc -G"};; - SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"} - CFLAGS=${CFLAGS-"-O2"} - LDSHARED=${LDSHARED-"ld"};; - SunStudio\ 9*) SFLAGS=${CFLAGS-"-DUSE_MMAP -fast -xcode=pic32 -xtarget=ultra3 -xarch=v9b"} - CFLAGS=${CFLAGS-"-DUSE_MMAP -fast -xtarget=ultra3 -xarch=v9b"} - LDSHARED=${LDSHARED-"cc -xarch=v9b"};; - UNIX_System_V\ 4.2.0) - SFLAGS=${CFLAGS-"-KPIC -O"} - CFLAGS=${CFLAGS-"-O"} - LDSHARED=${LDSHARED-"cc -G"};; - UNIX_SV\ 4.2MP) - SFLAGS=${CFLAGS-"-Kconform_pic -O"} - CFLAGS=${CFLAGS-"-O"} - LDSHARED=${LDSHARED-"cc -G"};; - OpenUNIX\ 5) - SFLAGS=${CFLAGS-"-KPIC -O"} - CFLAGS=${CFLAGS-"-O"} - LDSHARED=${LDSHARED-"cc -G"};; - AIX*) # Courtesy of dbakker@arrayasolutions.com - SFLAGS=${CFLAGS-"-O -qmaxmem=8192"} - CFLAGS=${CFLAGS-"-O -qmaxmem=8192"} - LDSHARED=${LDSHARED-"xlc -G"};; - # send working options for other systems to support@gzip.org - *) SFLAGS=${CFLAGS-"-O"} - CFLAGS=${CFLAGS-"-O"} - LDSHARED=${LDSHARED-"cc -shared"};; - esac -fi - -SHAREDLIB=${SHAREDLIB-"libz$shared_ext"} -SHAREDLIBV=${SHAREDLIBV-"libz$shared_ext.$VER"} -SHAREDLIBM=${SHAREDLIBM-"libz$shared_ext.$VER1"} - -if test $shared -eq 1; then - echo Checking for shared library support... - # we must test in two steps (cc then ld), required at least on SunOS 4.x - if test "`($CC -c $SFLAGS $test.c) 2>&1`" = "" && - test "`($LDSHARED -o $test$shared_ext $test.o) 2>&1`" = ""; then - CFLAGS="$SFLAGS" - LIBS="$SHAREDLIBV" - echo Building shared library $SHAREDLIBV with $CC. - elif test -z "$old_cc" -a -z "$old_cflags"; then - echo No shared library support. - shared=0; - else - echo 'No shared library support; try without defining CC and CFLAGS' - shared=0; - fi -fi -if test $shared -eq 0; then - LDSHARED="$CC" - echo Building static library $LIBS version $VER with $CC. -else - LDFLAGS="-L. ${SHAREDLIBV}" -fi - -cat > $test.c < -int main() { return 0; } -EOF -if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then - sed < zconf.in.h "/HAVE_UNISTD_H/s%0%1%" > zconf.h - echo "Checking for unistd.h... Yes." -else - cp -p zconf.in.h zconf.h - echo "Checking for unistd.h... No." -fi - -cat > $test.c < -#include -#include "zconf.h" - -int main() -{ -#ifndef STDC - choke me -#endif - - return 0; -} -EOF - -if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then - echo "Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf()" - - cat > $test.c < -#include - -int mytest(char *fmt, ...) -{ - char buf[20]; - va_list ap; - - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - return 0; -} - -int main() -{ - return (mytest("Hello%d\n", 1)); -} -EOF - - if test "`($CC $CFLAGS -o $test $test.c) 2>&1`" = ""; then - echo "Checking for vsnprintf() in stdio.h... Yes." - - cat >$test.c < -#include - -int mytest(char *fmt, ...) -{ - int n; - char buf[20]; - va_list ap; - - va_start(ap, fmt); - n = vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - return n; -} - -int main() -{ - return (mytest("Hello%d\n", 1)); -} -EOF - - if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then - echo "Checking for return value of vsnprintf()... Yes." - else - CFLAGS="$CFLAGS -DHAS_vsnprintf_void" - echo "Checking for return value of vsnprintf()... No." - echo " WARNING: apparently vsnprintf() does not return a value. zlib" - echo " can build but will be open to possible string-format security" - echo " vulnerabilities." - fi - else - CFLAGS="$CFLAGS -DNO_vsnprintf" - echo "Checking for vsnprintf() in stdio.h... No." - echo " WARNING: vsnprintf() not found, falling back to vsprintf(). zlib" - echo " can build but will be open to possible buffer-overflow security" - echo " vulnerabilities." - - cat >$test.c < -#include - -int mytest(char *fmt, ...) -{ - int n; - char buf[20]; - va_list ap; - - va_start(ap, fmt); - n = vsprintf(buf, fmt, ap); - va_end(ap); - return n; -} - -int main() -{ - return (mytest("Hello%d\n", 1)); -} -EOF - - if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then - echo "Checking for return value of vsprintf()... Yes." - else - CFLAGS="$CFLAGS -DHAS_vsprintf_void" - echo "Checking for return value of vsprintf()... No." - echo " WARNING: apparently vsprintf() does not return a value. zlib" - echo " can build but will be open to possible string-format security" - echo " vulnerabilities." - fi - fi -else - echo "Checking whether to use vs[n]printf() or s[n]printf()... using s[n]printf()" - - cat >$test.c < - -int mytest() -{ - char buf[20]; - - snprintf(buf, sizeof(buf), "%s", "foo"); - return 0; -} - -int main() -{ - return (mytest()); -} -EOF - - if test "`($CC $CFLAGS -o $test $test.c) 2>&1`" = ""; then - echo "Checking for snprintf() in stdio.h... Yes." - - cat >$test.c < - -int mytest() -{ - char buf[20]; - - return snprintf(buf, sizeof(buf), "%s", "foo"); -} - -int main() -{ - return (mytest()); -} -EOF - - if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then - echo "Checking for return value of snprintf()... Yes." - else - CFLAGS="$CFLAGS -DHAS_snprintf_void" - echo "Checking for return value of snprintf()... No." - echo " WARNING: apparently snprintf() does not return a value. zlib" - echo " can build but will be open to possible string-format security" - echo " vulnerabilities." - fi - else - CFLAGS="$CFLAGS -DNO_snprintf" - echo "Checking for snprintf() in stdio.h... No." - echo " WARNING: snprintf() not found, falling back to sprintf(). zlib" - echo " can build but will be open to possible buffer-overflow security" - echo " vulnerabilities." - - cat >$test.c < - -int mytest() -{ - char buf[20]; - - return sprintf(buf, "%s", "foo"); -} - -int main() -{ - return (mytest()); -} -EOF - - if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then - echo "Checking for return value of sprintf()... Yes." - else - CFLAGS="$CFLAGS -DHAS_sprintf_void" - echo "Checking for return value of sprintf()... No." - echo " WARNING: apparently sprintf() does not return a value. zlib" - echo " can build but will be open to possible string-format security" - echo " vulnerabilities." - fi - fi -fi - -cat >$test.c < -int main() { return 0; } -EOF -if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then - echo "Checking for errno.h... Yes." -else - echo "Checking for errno.h... No." - CFLAGS="$CFLAGS -DNO_ERRNO_H" -fi - -cat > $test.c < -#include -#include -caddr_t hello() { - return mmap((caddr_t)0, (off_t)0, PROT_READ, MAP_SHARED, 0, (off_t)0); -} -EOF -if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then - CFLAGS="$CFLAGS -DUSE_MMAP" - echo Checking for mmap support... Yes. -else - echo Checking for mmap support... No. -fi - -CPP=${CPP-"$CC -E"} -case $CFLAGS in - *ASMV*) - if test "`nm $test.o | grep _hello`" = ""; then - CPP="$CPP -DNO_UNDERLINE" - echo Checking for underline in external names... No. - else - echo Checking for underline in external names... Yes. - fi;; -esac - -rm -f $test.[co] $test $test$shared_ext - -# udpate Makefile -sed < Makefile.in " -/^CC *=/s#=.*#=$CC# -/^CFLAGS *=/s#=.*#=$CFLAGS# -/^CPP *=/s#=.*#=$CPP# -/^LDSHARED *=/s#=.*#=$LDSHARED# -/^LIBS *=/s#=.*#=$LIBS# -/^SHAREDLIB *=/s#=.*#=$SHAREDLIB# -/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV# -/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM# -/^AR *=/s#=.*#=$AR# -/^RANLIB *=/s#=.*#=$RANLIB# -/^EXE *=/s#=.*#=$EXE# -/^prefix *=/s#=.*#=$prefix# -/^exec_prefix *=/s#=.*#=$exec_prefix# -/^libdir *=/s#=.*#=$libdir# -/^includedir *=/s#=.*#=$includedir# -/^mandir *=/s#=.*#=$mandir# -/^LDFLAGS *=/s#=.*#=$LDFLAGS# -" > Makefile diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/crc32.c b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/crc32.c deleted file mode 100644 index f658a9ef5..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/crc32.c +++ /dev/null @@ -1,423 +0,0 @@ -/* crc32.c -- compute the CRC-32 of a data stream - * Copyright (C) 1995-2005 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - * - * Thanks to Rodney Brown for his contribution of faster - * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing - * tables for updating the shift register in one step with three exclusive-ors - * instead of four steps with four exclusive-ors. This results in about a - * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. - */ - -/* @(#) $Id$ */ - -/* - Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore - protection on the static variables used to control the first-use generation - of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should - first call get_crc_table() to initialize the tables before allowing more than - one thread to use crc32(). - */ - -#ifdef MAKECRCH -# include -# ifndef DYNAMIC_CRC_TABLE -# define DYNAMIC_CRC_TABLE -# endif /* !DYNAMIC_CRC_TABLE */ -#endif /* MAKECRCH */ - -#include "zutil.h" /* for STDC and FAR definitions */ - -#define local static - -/* Find a four-byte integer type for crc32_little() and crc32_big(). */ -#ifndef NOBYFOUR -# ifdef STDC /* need ANSI C limits.h to determine sizes */ -# include -# define BYFOUR -# if (UINT_MAX == 0xffffffffUL) - typedef unsigned int u4; -# else -# if (ULONG_MAX == 0xffffffffUL) - typedef unsigned long u4; -# else -# if (USHRT_MAX == 0xffffffffUL) - typedef unsigned short u4; -# else -# undef BYFOUR /* can't find a four-byte integer type! */ -# endif -# endif -# endif -# endif /* STDC */ -#endif /* !NOBYFOUR */ - -/* Definitions for doing the crc four data bytes at a time. */ -#ifdef BYFOUR -# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \ - (((w)&0xff00)<<8)+(((w)&0xff)<<24)) - local unsigned long crc32_little OF((unsigned long, - const unsigned char FAR *, unsigned)); - local unsigned long crc32_big OF((unsigned long, - const unsigned char FAR *, unsigned)); -# define TBLS 8 -#else -# define TBLS 1 -#endif /* BYFOUR */ - -/* Local functions for crc concatenation */ -local unsigned long gf2_matrix_times OF((unsigned long *mat, - unsigned long vec)); -local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); - -#ifdef DYNAMIC_CRC_TABLE - -local volatile int crc_table_empty = 1; -local unsigned long FAR crc_table[TBLS][256]; -local void make_crc_table OF((void)); -#ifdef MAKECRCH - local void write_table OF((FILE *, const unsigned long FAR *)); -#endif /* MAKECRCH */ -/* - Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: - x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. - - Polynomials over GF(2) are represented in binary, one bit per coefficient, - with the lowest powers in the most significant bit. Then adding polynomials - is just exclusive-or, and multiplying a polynomial by x is a right shift by - one. If we call the above polynomial p, and represent a byte as the - polynomial q, also with the lowest power in the most significant bit (so the - byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, - where a mod b means the remainder after dividing a by b. - - This calculation is done using the shift-register method of multiplying and - taking the remainder. The register is initialized to zero, and for each - incoming bit, x^32 is added mod p to the register if the bit is a one (where - x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by - x (which is shifting right by one and adding x^32 mod p if the bit shifted - out is a one). We start with the highest power (least significant bit) of - q and repeat for all eight bits of q. - - The first table is simply the CRC of all possible eight bit values. This is - all the information needed to generate CRCs on data a byte at a time for all - combinations of CRC register values and incoming bytes. The remaining tables - allow for word-at-a-time CRC calculation for both big-endian and little- - endian machines, where a word is four bytes. -*/ -local void make_crc_table() -{ - unsigned long c; - int n, k; - unsigned long poly; /* polynomial exclusive-or pattern */ - /* terms of polynomial defining this crc (except x^32): */ - static volatile int first = 1; /* flag to limit concurrent making */ - static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; - - /* See if another task is already doing this (not thread-safe, but better - than nothing -- significantly reduces duration of vulnerability in - case the advice about DYNAMIC_CRC_TABLE is ignored) */ - if (first) { - first = 0; - - /* make exclusive-or pattern from polynomial (0xedb88320UL) */ - poly = 0UL; - for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) - poly |= 1UL << (31 - p[n]); - - /* generate a crc for every 8-bit value */ - for (n = 0; n < 256; n++) { - c = (unsigned long)n; - for (k = 0; k < 8; k++) - c = c & 1 ? poly ^ (c >> 1) : c >> 1; - crc_table[0][n] = c; - } - -#ifdef BYFOUR - /* generate crc for each value followed by one, two, and three zeros, - and then the byte reversal of those as well as the first table */ - for (n = 0; n < 256; n++) { - c = crc_table[0][n]; - crc_table[4][n] = REV(c); - for (k = 1; k < 4; k++) { - c = crc_table[0][c & 0xff] ^ (c >> 8); - crc_table[k][n] = c; - crc_table[k + 4][n] = REV(c); - } - } -#endif /* BYFOUR */ - - crc_table_empty = 0; - } - else { /* not first */ - /* wait for the other guy to finish (not efficient, but rare) */ - while (crc_table_empty) - ; - } - -#ifdef MAKECRCH - /* write out CRC tables to crc32.h */ - { - FILE *out; - - out = fopen("crc32.h", "w"); - if (out == NULL) return; - fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); - fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); - fprintf(out, "local const unsigned long FAR "); - fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); - write_table(out, crc_table[0]); -# ifdef BYFOUR - fprintf(out, "#ifdef BYFOUR\n"); - for (k = 1; k < 8; k++) { - fprintf(out, " },\n {\n"); - write_table(out, crc_table[k]); - } - fprintf(out, "#endif\n"); -# endif /* BYFOUR */ - fprintf(out, " }\n};\n"); - fclose(out); - } -#endif /* MAKECRCH */ -} - -#ifdef MAKECRCH -local void write_table(out, table) - FILE *out; - const unsigned long FAR *table; -{ - int n; - - for (n = 0; n < 256; n++) - fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n], - n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); -} -#endif /* MAKECRCH */ - -#else /* !DYNAMIC_CRC_TABLE */ -/* ======================================================================== - * Tables of CRC-32s of all single-byte values, made by make_crc_table(). - */ -#include "crc32.h" -#endif /* DYNAMIC_CRC_TABLE */ - -/* ========================================================================= - * This function can be used by asm versions of crc32() - */ -const unsigned long FAR * ZEXPORT get_crc_table() -{ -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); -#endif /* DYNAMIC_CRC_TABLE */ - return (const unsigned long FAR *)crc_table; -} - -/* ========================================================================= */ -#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) -#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 - -/* ========================================================================= */ -unsigned long ZEXPORT crc32(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - unsigned len; -{ - if (buf == Z_NULL) return 0UL; - -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); -#endif /* DYNAMIC_CRC_TABLE */ - -#ifdef BYFOUR - if (sizeof(void *) == sizeof(ptrdiff_t)) { - u4 endian; - - endian = 1; - if (*((unsigned char *)(&endian))) - return crc32_little(crc, buf, len); - else - return crc32_big(crc, buf, len); - } -#endif /* BYFOUR */ - crc = crc ^ 0xffffffffUL; - while (len >= 8) { - DO8; - len -= 8; - } - if (len) do { - DO1; - } while (--len); - return crc ^ 0xffffffffUL; -} - -#ifdef BYFOUR - -/* ========================================================================= */ -#define DOLIT4 c ^= *buf4++; \ - c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ - crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] -#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 - -/* ========================================================================= */ -local unsigned long crc32_little(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - unsigned len; -{ - register u4 c; - register const u4 FAR *buf4; - - c = (u4)crc; - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); - len--; - } - - buf4 = (const u4 FAR *)(const void FAR *)buf; - while (len >= 32) { - DOLIT32; - len -= 32; - } - while (len >= 4) { - DOLIT4; - len -= 4; - } - buf = (const unsigned char FAR *)buf4; - - if (len) do { - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); - } while (--len); - c = ~c; - return (unsigned long)c; -} - -/* ========================================================================= */ -#define DOBIG4 c ^= *++buf4; \ - c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ - crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] -#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 - -/* ========================================================================= */ -local unsigned long crc32_big(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - unsigned len; -{ - register u4 c; - register const u4 FAR *buf4; - - c = REV((u4)crc); - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); - len--; - } - - buf4 = (const u4 FAR *)(const void FAR *)buf; - buf4--; - while (len >= 32) { - DOBIG32; - len -= 32; - } - while (len >= 4) { - DOBIG4; - len -= 4; - } - buf4++; - buf = (const unsigned char FAR *)buf4; - - if (len) do { - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); - } while (--len); - c = ~c; - return (unsigned long)(REV(c)); -} - -#endif /* BYFOUR */ - -#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ - -/* ========================================================================= */ -local unsigned long gf2_matrix_times(mat, vec) - unsigned long *mat; - unsigned long vec; -{ - unsigned long sum; - - sum = 0; - while (vec) { - if (vec & 1) - sum ^= *mat; - vec >>= 1; - mat++; - } - return sum; -} - -/* ========================================================================= */ -local void gf2_matrix_square(square, mat) - unsigned long *square; - unsigned long *mat; -{ - int n; - - for (n = 0; n < GF2_DIM; n++) - square[n] = gf2_matrix_times(mat, mat[n]); -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off_t len2; -{ - int n; - unsigned long row; - unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ - unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ - - /* degenerate case */ - if (len2 == 0) - return crc1; - - /* put operator for one zero bit in odd */ - odd[0] = 0xedb88320L; /* CRC-32 polynomial */ - row = 1; - for (n = 1; n < GF2_DIM; n++) { - odd[n] = row; - row <<= 1; - } - - /* put operator for two zero bits in even */ - gf2_matrix_square(even, odd); - - /* put operator for four zero bits in odd */ - gf2_matrix_square(odd, even); - - /* apply len2 zeros to crc1 (first square will put the operator for one - zero byte, eight zero bits, in even) */ - do { - /* apply zeros operator for this bit of len2 */ - gf2_matrix_square(even, odd); - if (len2 & 1) - crc1 = gf2_matrix_times(even, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - if (len2 == 0) - break; - - /* another iteration of the loop with odd and even swapped */ - gf2_matrix_square(odd, even); - if (len2 & 1) - crc1 = gf2_matrix_times(odd, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - } while (len2 != 0); - - /* return combined crc */ - crc1 ^= crc2; - return crc1; -} diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/crc32.h b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/crc32.h deleted file mode 100644 index 8053b6117..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/crc32.h +++ /dev/null @@ -1,441 +0,0 @@ -/* crc32.h -- tables for rapid CRC calculation - * Generated automatically by crc32.c - */ - -local const unsigned long FAR crc_table[TBLS][256] = -{ - { - 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, - 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, - 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, - 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, - 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, - 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, - 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, - 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, - 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, - 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, - 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, - 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, - 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, - 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, - 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, - 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, - 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, - 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, - 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, - 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, - 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, - 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, - 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, - 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, - 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, - 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, - 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, - 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, - 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, - 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, - 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, - 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, - 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, - 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, - 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, - 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, - 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, - 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, - 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, - 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, - 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, - 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, - 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, - 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, - 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, - 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, - 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, - 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, - 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, - 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, - 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, - 0x2d02ef8dUL -#ifdef BYFOUR - }, - { - 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, - 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, - 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, - 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, - 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, - 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, - 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, - 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, - 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, - 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, - 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, - 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, - 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, - 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, - 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, - 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, - 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, - 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, - 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, - 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, - 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, - 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, - 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, - 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, - 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, - 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, - 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, - 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, - 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, - 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, - 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, - 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, - 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, - 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, - 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, - 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, - 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, - 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, - 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, - 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, - 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, - 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, - 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, - 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, - 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, - 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, - 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, - 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, - 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, - 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, - 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, - 0x9324fd72UL - }, - { - 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, - 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, - 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, - 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, - 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, - 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, - 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, - 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, - 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, - 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, - 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, - 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, - 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, - 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, - 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, - 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, - 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, - 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, - 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, - 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, - 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, - 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, - 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, - 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, - 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, - 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, - 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, - 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, - 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, - 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, - 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, - 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, - 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, - 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, - 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, - 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, - 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, - 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, - 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, - 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, - 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, - 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, - 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, - 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, - 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, - 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, - 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, - 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, - 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, - 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, - 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, - 0xbe9834edUL - }, - { - 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, - 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, - 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, - 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, - 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, - 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, - 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, - 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, - 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, - 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, - 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, - 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, - 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, - 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, - 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, - 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, - 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, - 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, - 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, - 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, - 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, - 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, - 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, - 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, - 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, - 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, - 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, - 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, - 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, - 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, - 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, - 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, - 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, - 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, - 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, - 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, - 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, - 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, - 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, - 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, - 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, - 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, - 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, - 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, - 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, - 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, - 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, - 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, - 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, - 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, - 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, - 0xde0506f1UL - }, - { - 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, - 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, - 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, - 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, - 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, - 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, - 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, - 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, - 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, - 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, - 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, - 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, - 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, - 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, - 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, - 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, - 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, - 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, - 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, - 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, - 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, - 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, - 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, - 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, - 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, - 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, - 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, - 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, - 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, - 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, - 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, - 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, - 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, - 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, - 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, - 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, - 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, - 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, - 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, - 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, - 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, - 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, - 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, - 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, - 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, - 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, - 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, - 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, - 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, - 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, - 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, - 0x8def022dUL - }, - { - 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, - 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, - 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, - 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, - 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, - 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, - 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, - 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, - 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, - 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, - 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, - 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, - 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, - 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, - 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, - 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, - 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, - 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, - 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, - 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, - 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, - 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, - 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, - 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, - 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, - 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, - 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, - 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, - 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, - 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, - 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, - 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, - 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, - 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, - 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, - 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, - 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, - 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, - 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, - 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, - 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, - 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, - 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, - 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, - 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, - 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, - 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, - 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, - 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, - 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, - 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, - 0x72fd2493UL - }, - { - 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, - 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, - 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, - 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, - 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, - 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, - 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, - 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, - 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, - 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, - 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, - 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, - 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, - 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, - 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, - 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, - 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, - 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, - 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, - 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, - 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, - 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, - 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, - 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, - 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, - 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, - 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, - 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, - 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, - 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, - 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, - 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, - 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, - 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, - 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, - 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, - 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, - 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, - 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, - 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, - 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, - 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, - 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, - 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, - 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, - 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, - 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, - 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, - 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, - 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, - 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, - 0xed3498beUL - }, - { - 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, - 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, - 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, - 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, - 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, - 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, - 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, - 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, - 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, - 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, - 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, - 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, - 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, - 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, - 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, - 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, - 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, - 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, - 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, - 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, - 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, - 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, - 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, - 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, - 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, - 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, - 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, - 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, - 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, - 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, - 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, - 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, - 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, - 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, - 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, - 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, - 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, - 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, - 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, - 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, - 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, - 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, - 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, - 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, - 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, - 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, - 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, - 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, - 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, - 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, - 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, - 0xf10605deUL -#endif - } -}; diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/deflate.c b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/deflate.c deleted file mode 100644 index 29ce1f64a..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/deflate.c +++ /dev/null @@ -1,1736 +0,0 @@ -/* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process depends on being able to identify portions - * of the input text which are identical to earlier input (within a - * sliding window trailing behind the input currently being processed). - * - * The most straightforward technique turns out to be the fastest for - * most input files: try all possible matches and select the longest. - * The key feature of this algorithm is that insertions into the string - * dictionary are very simple and thus fast, and deletions are avoided - * completely. Insertions are performed at each input character, whereas - * string matches are performed only when the previous match ends. So it - * is preferable to spend more time in matches to allow very fast string - * insertions and avoid deletions. The matching algorithm for small - * strings is inspired from that of Rabin & Karp. A brute force approach - * is used to find longer strings when a small match has been found. - * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze - * (by Leonid Broukhis). - * A previous version of this file used a more sophisticated algorithm - * (by Fiala and Greene) which is guaranteed to run in linear amortized - * time, but has a larger average cost, uses more memory and is patented. - * However the F&G algorithm may be faster for some highly redundant - * files if the parameter max_chain_length (described below) is too large. - * - * ACKNOWLEDGEMENTS - * - * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and - * I found it in 'freeze' written by Leonid Broukhis. - * Thanks to many people for bug reports and testing. - * - * REFERENCES - * - * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". - * Available in http://www.ietf.org/rfc/rfc1951.txt - * - * A description of the Rabin and Karp algorithm is given in the book - * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. - * - * Fiala,E.R., and Greene,D.H. - * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 - * - */ - -/* @(#) $Id$ */ - -#include "deflate.h" - -const char deflate_copyright[] = - " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* =========================================================================== - * Function prototypes. - */ -typedef enum { - need_more, /* block not completed, need more input or more output */ - block_done, /* block flush performed */ - finish_started, /* finish started, need only more output at next deflate */ - finish_done /* finish done, accept no more input or output */ -} block_state; - -typedef block_state (*compress_func) OF((deflate_state *s, int flush)); -/* Compression function. Returns the block state after the call. */ - -local void fill_window OF((deflate_state *s)); -local block_state deflate_stored OF((deflate_state *s, int flush)); -local block_state deflate_fast OF((deflate_state *s, int flush)); -#ifndef FASTEST -local block_state deflate_slow OF((deflate_state *s, int flush)); -#endif -local void lm_init OF((deflate_state *s)); -local void putShortMSB OF((deflate_state *s, uInt b)); -local void flush_pending OF((z_streamp strm)); -local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); -#ifndef FASTEST -#ifdef ASMV - void match_init OF((void)); /* asm code initialization */ - uInt longest_match OF((deflate_state *s, IPos cur_match)); -#else -local uInt longest_match OF((deflate_state *s, IPos cur_match)); -#endif -#endif -local uInt longest_match_fast OF((deflate_state *s, IPos cur_match)); - -#ifdef DEBUG -local void check_match OF((deflate_state *s, IPos start, IPos match, - int length)); -#endif - -/* =========================================================================== - * Local data - */ - -#define NIL 0 -/* Tail of hash chains */ - -#ifndef TOO_FAR -# define TOO_FAR 4096 -#endif -/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -/* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ -typedef struct config_s { - ush good_length; /* reduce lazy search above this match length */ - ush max_lazy; /* do not perform lazy search above this match length */ - ush nice_length; /* quit search above this match length */ - ush max_chain; - compress_func func; -} config; - -#ifdef FASTEST -local const config configuration_table[2] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ -#else -local const config configuration_table[10] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ -/* 2 */ {4, 5, 16, 8, deflate_fast}, -/* 3 */ {4, 6, 32, 32, deflate_fast}, - -/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ -/* 5 */ {8, 16, 32, 32, deflate_slow}, -/* 6 */ {8, 16, 128, 128, deflate_slow}, -/* 7 */ {8, 32, 128, 256, deflate_slow}, -/* 8 */ {32, 128, 258, 1024, deflate_slow}, -/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ -#endif - -/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 - * For deflate_fast() (levels <= 3) good is ignored and lazy has a different - * meaning. - */ - -#define EQUAL 0 -/* result of memcmp for equal strings */ - -#ifndef NO_DUMMY_DECL -struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ -#endif - -/* =========================================================================== - * Update a hash value with the given input byte - * IN assertion: all calls to to UPDATE_HASH are made with consecutive - * input characters, so that a running hash key can be computed from the - * previous key instead of complete recalculation each time. - */ -#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) - - -/* =========================================================================== - * Insert string str in the dictionary and set match_head to the previous head - * of the hash chain (the most recent string with same hash key). Return - * the previous length of the hash chain. - * If this file is compiled with -DFASTEST, the compression level is forced - * to 1, and no hash chains are maintained. - * IN assertion: all calls to to INSERT_STRING are made with consecutive - * input characters and the first MIN_MATCH bytes of str are valid - * (except for the last MIN_MATCH-1 bytes of the input file). - */ -#ifdef FASTEST -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#else -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#endif - -/* =========================================================================== - * Initialize the hash table (avoiding 64K overflow for 16 bit systems). - * prev[] will be initialized on the fly. - */ -#define CLEAR_HASH(s) \ - s->head[s->hash_size-1] = NIL; \ - zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); - -/* ========================================================================= */ -int ZEXPORT deflateInit_(strm, level, version, stream_size) - z_streamp strm; - int level; - const char *version; - int stream_size; -{ - return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, - Z_DEFAULT_STRATEGY, version, stream_size); - /* To do: ignore strm->next_in if we use it as window */ -} - -/* ========================================================================= */ -int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, - version, stream_size) - z_streamp strm; - int level; - int method; - int windowBits; - int memLevel; - int strategy; - const char *version; - int stream_size; -{ - deflate_state *s; - int wrap = 1; - static const char my_version[] = ZLIB_VERSION; - - ushf *overlay; - /* We overlay pending_buf and d_buf+l_buf. This works since the average - * output size for (length,distance) codes is <= 24 bits. - */ - - if (version == Z_NULL || version[0] != my_version[0] || - stream_size != sizeof(z_stream)) { - return Z_VERSION_ERROR; - } - if (strm == Z_NULL) return Z_STREAM_ERROR; - - strm->msg = Z_NULL; - if (strm->zalloc == (alloc_func)0) { - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; - } - if (strm->zfree == (free_func)0) strm->zfree = zcfree; - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - - if (windowBits < 0) { /* suppress zlib wrapper */ - wrap = 0; - windowBits = -windowBits; - } -#ifdef GZIP - else if (windowBits > 15) { - wrap = 2; /* write gzip wrapper instead */ - windowBits -= 16; - } -#endif - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } - if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ - s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); - if (s == Z_NULL) return Z_MEM_ERROR; - strm->state = (struct internal_state FAR *)s; - s->strm = strm; - - s->wrap = wrap; - s->gzhead = Z_NULL; - s->w_bits = windowBits; - s->w_size = 1 << s->w_bits; - s->w_mask = s->w_size - 1; - - s->hash_bits = memLevel + 7; - s->hash_size = 1 << s->hash_bits; - s->hash_mask = s->hash_size - 1; - s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); - - s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); - s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); - s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); - - s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - - overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); - s->pending_buf = (uchf *) overlay; - s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); - - if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || - s->pending_buf == Z_NULL) { - s->status = FINISH_STATE; - strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); - deflateEnd (strm); - return Z_MEM_ERROR; - } - s->d_buf = overlay + s->lit_bufsize/sizeof(ush); - s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; - - s->level = level; - s->strategy = strategy; - s->method = (Byte)method; - - return deflateReset(strm); -} - -/* ========================================================================= */ -int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) - z_streamp strm; - const Bytef *dictionary; - uInt dictLength; -{ - deflate_state *s; - uInt length = dictLength; - uInt n; - IPos hash_head = 0; - - if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || - strm->state->wrap == 2 || - (strm->state->wrap == 1 && strm->state->status != INIT_STATE)) - return Z_STREAM_ERROR; - - s = strm->state; - if (s->wrap) - strm->adler = adler32(strm->adler, dictionary, dictLength); - - if (length < MIN_MATCH) return Z_OK; - if (length > MAX_DIST(s)) { - length = MAX_DIST(s); - dictionary += dictLength - length; /* use the tail of the dictionary */ - } - zmemcpy(s->window, dictionary, length); - s->strstart = length; - s->block_start = (long)length; - - /* Insert all strings in the hash table (except for the last two bytes). - * s->lookahead stays null, so s->ins_h will be recomputed at the next - * call of fill_window. - */ - s->ins_h = s->window[0]; - UPDATE_HASH(s, s->ins_h, s->window[1]); - for (n = 0; n <= length - MIN_MATCH; n++) { - INSERT_STRING(s, n, hash_head); - } - if (hash_head) hash_head = 0; /* to make compiler happy */ - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateReset (strm) - z_streamp strm; -{ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL || - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { - return Z_STREAM_ERROR; - } - - strm->total_in = strm->total_out = 0; - strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ - strm->data_type = Z_UNKNOWN; - - s = (deflate_state *)strm->state; - s->pending = 0; - s->pending_out = s->pending_buf; - - if (s->wrap < 0) { - s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ - } - s->status = s->wrap ? INIT_STATE : BUSY_STATE; - strm->adler = -#ifdef GZIP - s->wrap == 2 ? crc32(0L, Z_NULL, 0) : -#endif - adler32(0L, Z_NULL, 0); - s->last_flush = Z_NO_FLUSH; - - _tr_init(s); - lm_init(s); - - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateSetHeader (strm, head) - z_streamp strm; - gz_headerp head; -{ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - if (strm->state->wrap != 2) return Z_STREAM_ERROR; - strm->state->gzhead = head; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflatePrime (strm, bits, value) - z_streamp strm; - int bits; - int value; -{ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - strm->state->bi_valid = bits; - strm->state->bi_buf = (ush)(value & ((1 << bits) - 1)); - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateParams(strm, level, strategy) - z_streamp strm; - int level; - int strategy; -{ - deflate_state *s; - compress_func func; - int err = Z_OK; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = strm->state; - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } - func = configuration_table[s->level].func; - - if (func != configuration_table[level].func && strm->total_in != 0) { - /* Flush the last buffer: */ - err = deflate(strm, Z_PARTIAL_FLUSH); - } - if (s->level != level) { - s->level = level; - s->max_lazy_match = configuration_table[level].max_lazy; - s->good_match = configuration_table[level].good_length; - s->nice_match = configuration_table[level].nice_length; - s->max_chain_length = configuration_table[level].max_chain; - } - s->strategy = strategy; - return err; -} - -/* ========================================================================= */ -int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) - z_streamp strm; - int good_length; - int max_lazy; - int nice_length; - int max_chain; -{ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = strm->state; - s->good_match = good_length; - s->max_lazy_match = max_lazy; - s->nice_match = nice_length; - s->max_chain_length = max_chain; - return Z_OK; -} - -/* ========================================================================= - * For the default windowBits of 15 and memLevel of 8, this function returns - * a close to exact, as well as small, upper bound on the compressed size. - * They are coded as constants here for a reason--if the #define's are - * changed, then this function needs to be changed as well. The return - * value for 15 and 8 only works for those exact settings. - * - * For any setting other than those defaults for windowBits and memLevel, - * the value returned is a conservative worst case for the maximum expansion - * resulting from using fixed blocks instead of stored blocks, which deflate - * can emit on compressed data for some combinations of the parameters. - * - * This function could be more sophisticated to provide closer upper bounds - * for every combination of windowBits and memLevel, as well as wrap. - * But even the conservative upper bound of about 14% expansion does not - * seem onerous for output buffer allocation. - */ -uLong ZEXPORT deflateBound(strm, sourceLen) - z_streamp strm; - uLong sourceLen; -{ - deflate_state *s; - uLong destLen; - - /* conservative upper bound */ - destLen = sourceLen + - ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11; - - /* if can't get parameters, return conservative bound */ - if (strm == Z_NULL || strm->state == Z_NULL) - return destLen; - - /* if not default parameters, return conservative bound */ - s = strm->state; - if (s->w_bits != 15 || s->hash_bits != 8 + 7) - return destLen; - - /* default settings: return tight bound for that case */ - return compressBound(sourceLen); -} - -/* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. - */ -local void putShortMSB (s, b) - deflate_state *s; - uInt b; -{ - put_byte(s, (Byte)(b >> 8)); - put_byte(s, (Byte)(b & 0xff)); -} - -/* ========================================================================= - * Flush as much pending output as possible. All deflate() output goes - * through this function so some applications may wish to modify it - * to avoid allocating a large strm->next_out buffer and copying into it. - * (See also read_buf()). - */ -local void flush_pending(strm) - z_streamp strm; -{ - unsigned len = strm->state->pending; - - if (len > strm->avail_out) len = strm->avail_out; - if (len == 0) return; - - zmemcpy(strm->next_out, strm->state->pending_out, len); - strm->next_out += len; - strm->state->pending_out += len; - strm->total_out += len; - strm->avail_out -= len; - strm->state->pending -= len; - if (strm->state->pending == 0) { - strm->state->pending_out = strm->state->pending_buf; - } -} - -/* ========================================================================= */ -int ZEXPORT deflate (strm, flush) - z_streamp strm; - int flush; -{ - int old_flush; /* value of flush param for previous deflate call */ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL || - flush > Z_FINISH || flush < 0) { - return Z_STREAM_ERROR; - } - s = strm->state; - - if (strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0) || - (s->status == FINISH_STATE && flush != Z_FINISH)) { - ERR_RETURN(strm, Z_STREAM_ERROR); - } - if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); - - s->strm = strm; /* just in case */ - old_flush = s->last_flush; - s->last_flush = flush; - - /* Write the header */ - if (s->status == INIT_STATE) { -#ifdef GZIP - if (s->wrap == 2) { - strm->adler = crc32(0L, Z_NULL, 0); - put_byte(s, 31); - put_byte(s, 139); - put_byte(s, 8); - if (s->gzhead == NULL) { - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, OS_CODE); - s->status = BUSY_STATE; - } - else { - put_byte(s, (s->gzhead->text ? 1 : 0) + - (s->gzhead->hcrc ? 2 : 0) + - (s->gzhead->extra == Z_NULL ? 0 : 4) + - (s->gzhead->name == Z_NULL ? 0 : 8) + - (s->gzhead->comment == Z_NULL ? 0 : 16) - ); - put_byte(s, (Byte)(s->gzhead->time & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, s->gzhead->os & 0xff); - if (s->gzhead->extra != NULL) { - put_byte(s, s->gzhead->extra_len & 0xff); - put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); - } - if (s->gzhead->hcrc) - strm->adler = crc32(strm->adler, s->pending_buf, - s->pending); - s->gzindex = 0; - s->status = EXTRA_STATE; - } - } - else -#endif - { - uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; - uInt level_flags; - - if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) - level_flags = 0; - else if (s->level < 6) - level_flags = 1; - else if (s->level == 6) - level_flags = 2; - else - level_flags = 3; - header |= (level_flags << 6); - if (s->strstart != 0) header |= PRESET_DICT; - header += 31 - (header % 31); - - s->status = BUSY_STATE; - putShortMSB(s, header); - - /* Save the adler32 of the preset dictionary: */ - if (s->strstart != 0) { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - strm->adler = adler32(0L, Z_NULL, 0); - } - } -#ifdef GZIP - if (s->status == EXTRA_STATE) { - if (s->gzhead->extra != NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - - while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) - break; - } - put_byte(s, s->gzhead->extra[s->gzindex]); - s->gzindex++; - } - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (s->gzindex == s->gzhead->extra_len) { - s->gzindex = 0; - s->status = NAME_STATE; - } - } - else - s->status = NAME_STATE; - } - if (s->status == NAME_STATE) { - if (s->gzhead->name != NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - int val; - - do { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) { - val = 1; - break; - } - } - val = s->gzhead->name[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (val == 0) { - s->gzindex = 0; - s->status = COMMENT_STATE; - } - } - else - s->status = COMMENT_STATE; - } - if (s->status == COMMENT_STATE) { - if (s->gzhead->comment != NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - int val; - - do { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) { - val = 1; - break; - } - } - val = s->gzhead->comment[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (val == 0) - s->status = HCRC_STATE; - } - else - s->status = HCRC_STATE; - } - if (s->status == HCRC_STATE) { - if (s->gzhead->hcrc) { - if (s->pending + 2 > s->pending_buf_size) - flush_pending(strm); - if (s->pending + 2 <= s->pending_buf_size) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - strm->adler = crc32(0L, Z_NULL, 0); - s->status = BUSY_STATE; - } - } - else - s->status = BUSY_STATE; - } -#endif - - /* Flush as much pending output as possible */ - if (s->pending != 0) { - flush_pending(strm); - if (strm->avail_out == 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ - s->last_flush = -1; - return Z_OK; - } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUF_ERROR. - */ - } else if (strm->avail_in == 0 && flush <= old_flush && - flush != Z_FINISH) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* User must not provide more input after the first FINISH: */ - if (s->status == FINISH_STATE && strm->avail_in != 0) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* Start a new block or continue the current one. - */ - if (strm->avail_in != 0 || s->lookahead != 0 || - (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { - block_state bstate; - - bstate = (*(configuration_table[s->level].func))(s, flush); - - if (bstate == finish_started || bstate == finish_done) { - s->status = FINISH_STATE; - } - if (bstate == need_more || bstate == finish_started) { - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ - } - return Z_OK; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } - if (bstate == block_done) { - if (flush == Z_PARTIAL_FLUSH) { - _tr_align(s); - } else { /* FULL_FLUSH or SYNC_FLUSH */ - _tr_stored_block(s, (char*)0, 0L, 0); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush == Z_FULL_FLUSH) { - CLEAR_HASH(s); /* forget history */ - } - } - flush_pending(strm); - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK; - } - } - } - Assert(strm->avail_out > 0, "bug2"); - - if (flush != Z_FINISH) return Z_OK; - if (s->wrap <= 0) return Z_STREAM_END; - - /* Write the trailer */ -#ifdef GZIP - if (s->wrap == 2) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); - put_byte(s, (Byte)(strm->total_in & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); - } - else -#endif - { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - flush_pending(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ - return s->pending != 0 ? Z_OK : Z_STREAM_END; -} - -/* ========================================================================= */ -int ZEXPORT deflateEnd (strm) - z_streamp strm; -{ - int status; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - - status = strm->state->status; - if (status != INIT_STATE && - status != EXTRA_STATE && - status != NAME_STATE && - status != COMMENT_STATE && - status != HCRC_STATE && - status != BUSY_STATE && - status != FINISH_STATE) { - return Z_STREAM_ERROR; - } - - /* Deallocate in reverse order of allocations: */ - TRY_FREE(strm, strm->state->pending_buf); - TRY_FREE(strm, strm->state->head); - TRY_FREE(strm, strm->state->prev); - TRY_FREE(strm, strm->state->window); - - ZFREE(strm, strm->state); - strm->state = Z_NULL; - - return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; -} - -/* ========================================================================= - * Copy the source state to the destination state. - * To simplify the source, this is not supported for 16-bit MSDOS (which - * doesn't have enough memory anyway to duplicate compression states). - */ -int ZEXPORT deflateCopy (dest, source) - z_streamp dest; - z_streamp source; -{ -#ifdef MAXSEG_64K - return Z_STREAM_ERROR; -#else - deflate_state *ds; - deflate_state *ss; - ushf *overlay; - - - if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { - return Z_STREAM_ERROR; - } - - ss = source->state; - - zmemcpy(dest, source, sizeof(z_stream)); - - ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); - if (ds == Z_NULL) return Z_MEM_ERROR; - dest->state = (struct internal_state FAR *) ds; - zmemcpy(ds, ss, sizeof(deflate_state)); - ds->strm = dest; - - ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); - ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); - ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); - ds->pending_buf = (uchf *) overlay; - - if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || - ds->pending_buf == Z_NULL) { - deflateEnd (dest); - return Z_MEM_ERROR; - } - /* following zmemcpy do not work for 16-bit MSDOS */ - zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); - zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); - zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); - - ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); - ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); - ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; - - ds->l_desc.dyn_tree = ds->dyn_ltree; - ds->d_desc.dyn_tree = ds->dyn_dtree; - ds->bl_desc.dyn_tree = ds->bl_tree; - - return Z_OK; -#endif /* MAXSEG_64K */ -} - -/* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->next_in buffer and copying from it. - * (See also flush_pending()). - */ -local int read_buf(strm, buf, size) - z_streamp strm; - Bytef *buf; - unsigned size; -{ - unsigned len = strm->avail_in; - - if (len > size) len = size; - if (len == 0) return 0; - - strm->avail_in -= len; - - if (strm->state->wrap == 1) { - strm->adler = adler32(strm->adler, strm->next_in, len); - } -#ifdef GZIP - else if (strm->state->wrap == 2) { - strm->adler = crc32(strm->adler, strm->next_in, len); - } -#endif - zmemcpy(buf, strm->next_in, len); - strm->next_in += len; - strm->total_in += len; - - return (int)len; -} - -/* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ -local void lm_init (s) - deflate_state *s; -{ - s->window_size = (ulg)2L*s->w_size; - - CLEAR_HASH(s); - - /* Set the default configuration parameters: - */ - s->max_lazy_match = configuration_table[s->level].max_lazy; - s->good_match = configuration_table[s->level].good_length; - s->nice_match = configuration_table[s->level].nice_length; - s->max_chain_length = configuration_table[s->level].max_chain; - - s->strstart = 0; - s->block_start = 0L; - s->lookahead = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - s->ins_h = 0; -#ifndef FASTEST -#ifdef ASMV - match_init(); /* initialize the asm code */ -#endif -#endif -} - -#ifndef FASTEST -/* =========================================================================== - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is - * garbage. - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 - * OUT assertion: the match length is not greater than s->lookahead. - */ -#ifndef ASMV -/* For 80x86 and 680x0, an optimized version will be provided in match.asm or - * match.S. The code will be functionally equivalent. - */ -local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ - unsigned chain_length = s->max_chain_length;/* max hash chain length */ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - int best_len = s->prev_length; /* best match length so far */ - int nice_match = s->nice_match; /* stop if match long enough */ - IPos limit = s->strstart > (IPos)MAX_DIST(s) ? - s->strstart - (IPos)MAX_DIST(s) : NIL; - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - Posf *prev = s->prev; - uInt wmask = s->w_mask; - -#ifdef UNALIGNED_OK - /* Compare two bytes at a time. Note: this is not always beneficial. - * Try with and without -DUNALIGNED_OK to check. - */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; - register ush scan_start = *(ushf*)scan; - register ush scan_end = *(ushf*)(scan+best_len-1); -#else - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - register Byte scan_end1 = scan[best_len-1]; - register Byte scan_end = scan[best_len]; -#endif - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* Do not waste too much time if we already have a good match: */ - if (s->prev_length >= s->good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. - */ - if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; - - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - do { - Assert(cur_match < s->strstart, "no future"); - match = s->window + cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2. Note that the checks below - * for insufficient lookahead only occur occasionally for performance - * reasons. Therefore uninitialized memory will be accessed, and - * conditional jumps will be made that depend on those values. - * However the length of the match is limited to the lookahead, so - * the output of deflate is not affected by the uninitialized values. - */ -#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) - /* This code assumes sizeof(unsigned short) == 2. Do not use - * UNALIGNED_OK if your compiler uses a different size. - */ - if (*(ushf*)(match+best_len-1) != scan_end || - *(ushf*)match != scan_start) continue; - - /* It is not necessary to compare scan[2] and match[2] since they are - * always equal when the other bytes match, given that the hash keys - * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at - * strstart+3, +5, ... up to strstart+257. We check for insufficient - * lookahead only every 4th comparison; the 128th check will be made - * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is - * necessary to put more guard bytes at the end of the window, or - * to check more often for insufficient lookahead. - */ - Assert(scan[2] == match[2], "scan[2]?"); - scan++, match++; - do { - } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - scan < strend); - /* The funny "do {}" generates better code on most compilers */ - - /* Here, scan <= window+strstart+257 */ - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - if (*scan == *match) scan++; - - len = (MAX_MATCH - 1) - (int)(strend-scan); - scan = strend - (MAX_MATCH-1); - -#else /* UNALIGNED_OK */ - - if (match[best_len] != scan_end || - match[best_len-1] != scan_end1 || - *match != *scan || - *++match != scan[1]) continue; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match++; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - scan = strend - MAX_MATCH; - -#endif /* UNALIGNED_OK */ - - if (len > best_len) { - s->match_start = cur_match; - best_len = len; - if (len >= nice_match) break; -#ifdef UNALIGNED_OK - scan_end = *(ushf*)(scan+best_len-1); -#else - scan_end1 = scan[best_len-1]; - scan_end = scan[best_len]; -#endif - } - } while ((cur_match = prev[cur_match & wmask]) > limit - && --chain_length != 0); - - if ((uInt)best_len <= s->lookahead) return (uInt)best_len; - return s->lookahead; -} -#endif /* ASMV */ -#endif /* FASTEST */ - -/* --------------------------------------------------------------------------- - * Optimized version for level == 1 or strategy == Z_RLE only - */ -local uInt longest_match_fast(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - Assert(cur_match < s->strstart, "no future"); - - match = s->window + cur_match; - - /* Return failure if the match length is less than 2: - */ - if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match += 2; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - - if (len < MIN_MATCH) return MIN_MATCH - 1; - - s->match_start = cur_match; - return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; -} - -#ifdef DEBUG -/* =========================================================================== - * Check that the match at match_start is indeed a match. - */ -local void check_match(s, start, match, length) - deflate_state *s; - IPos start, match; - int length; -{ - /* check that the match is indeed a match */ - if (zmemcmp(s->window + match, - s->window + start, length) != EQUAL) { - fprintf(stderr, " start %u, match %u, length %d\n", - start, match, length); - do { - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); - } while (--length != 0); - z_error("invalid match"); - } - if (z_verbose > 1) { - fprintf(stderr,"\\[%d,%d]", start-match, length); - do { putc(s->window[start++], stderr); } while (--length != 0); - } -} -#else -# define check_match(s, start, match, length) -#endif /* DEBUG */ - -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ -local void fill_window(s) - deflate_state *s; -{ - register unsigned n, m; - register Posf *p; - unsigned more; /* Amount of free space at the end of the window. */ - uInt wsize = s->w_size; - - do { - more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); - - /* Deal with !@#$% 64K limit: */ - if (sizeof(int) <= 2) { - if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - more = wsize; - - } else if (more == (unsigned)(-1)) { - /* Very unlikely, but possible on 16 bit machine if - * strstart == 0 && lookahead == 1 (input done a byte at time) - */ - more--; - } - } - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s->strstart >= wsize+MAX_DIST(s)) { - - zmemcpy(s->window, s->window+wsize, (unsigned)wsize); - s->match_start -= wsize; - s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ - s->block_start -= (long) wsize; - - /* Slide the hash table (could be avoided with 32 bit values - at the expense of memory usage). We slide even when level == 0 - to keep the hash table consistent if we switch back to level > 0 - later. (Using level 0 permanently is not an optimal usage of - zlib, so we don't care about this pathological case.) - */ - /* %%% avoid this when Z_RLE */ - n = s->hash_size; - p = &s->head[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - } while (--n); - - n = wsize; -#ifndef FASTEST - p = &s->prev[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); -#endif - more += wsize; - } - if (s->strm->avail_in == 0) return; - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - Assert(more >= 2, "more < 2"); - - n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); - s->lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s->lookahead >= MIN_MATCH) { - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); -} - -/* =========================================================================== - * Flush the current block, with given end-of-file flag. - * IN assertion: strstart is set to the end of the current match. - */ -#define FLUSH_BLOCK_ONLY(s, eof) { \ - _tr_flush_block(s, (s->block_start >= 0L ? \ - (charf *)&s->window[(unsigned)s->block_start] : \ - (charf *)Z_NULL), \ - (ulg)((long)s->strstart - s->block_start), \ - (eof)); \ - s->block_start = s->strstart; \ - flush_pending(s->strm); \ - Tracev((stderr,"[FLUSH]")); \ -} - -/* Same but force premature exit if necessary. */ -#define FLUSH_BLOCK(s, eof) { \ - FLUSH_BLOCK_ONLY(s, eof); \ - if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ -} - -/* =========================================================================== - * Copy without compression as much as possible from the input stream, return - * the current block state. - * This function does not insert new strings in the dictionary since - * uncompressible data is probably not useful. This function is used - * only for the level=0 compression option. - * NOTE: this function should be optimized to avoid extra copying from - * window to pending_buf. - */ -local block_state deflate_stored(s, flush) - deflate_state *s; - int flush; -{ - /* Stored blocks are limited to 0xffff bytes, pending_buf is limited - * to pending_buf_size, and each stored block has a 5 byte header: - */ - ulg max_block_size = 0xffff; - ulg max_start; - - if (max_block_size > s->pending_buf_size - 5) { - max_block_size = s->pending_buf_size - 5; - } - - /* Copy as much as possible from input to output: */ - for (;;) { - /* Fill the window as much as possible: */ - if (s->lookahead <= 1) { - - Assert(s->strstart < s->w_size+MAX_DIST(s) || - s->block_start >= (long)s->w_size, "slide too late"); - - fill_window(s); - if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; - - if (s->lookahead == 0) break; /* flush the current block */ - } - Assert(s->block_start >= 0L, "block gone"); - - s->strstart += s->lookahead; - s->lookahead = 0; - - /* Emit a stored block if pending_buf will be full: */ - max_start = s->block_start + max_block_size; - if (s->strstart == 0 || (ulg)s->strstart >= max_start) { - /* strstart == 0 is possible when wraparound on 16-bit machine */ - s->lookahead = (uInt)(s->strstart - max_start); - s->strstart = (uInt)max_start; - FLUSH_BLOCK(s, 0); - } - /* Flush if we may have to slide, otherwise block_start may become - * negative and the data will be gone: - */ - if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { - FLUSH_BLOCK(s, 0); - } - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} - -/* =========================================================================== - * Compress as much as possible from the input stream, return the current - * block state. - * This function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ -local block_state deflate_fast(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head = NIL; /* head of the hash chain */ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ -#ifdef FASTEST - if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) || - (s->strategy == Z_RLE && s->strstart - hash_head == 1)) { - s->match_length = longest_match_fast (s, hash_head); - } -#else - if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { - s->match_length = longest_match (s, hash_head); - } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { - s->match_length = longest_match_fast (s, hash_head); - } -#endif - /* longest_match() or longest_match_fast() sets match_start */ - } - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->match_start, s->match_length); - - _tr_tally_dist(s, s->strstart - s->match_start, - s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ -#ifndef FASTEST - if (s->match_length <= s->max_insert_length && - s->lookahead >= MIN_MATCH) { - s->match_length--; /* string at strstart already in table */ - do { - s->strstart++; - INSERT_STRING(s, s->strstart, hash_head); - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s->match_length != 0); - s->strstart++; - } else -#endif - { - s->strstart += s->match_length; - s->match_length = 0; - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} - -#ifndef FASTEST -/* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ -local block_state deflate_slow(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head = NIL; /* head of hash chain */ - int bflush; /* set if current block must be flushed */ - - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - */ - s->prev_length = s->match_length, s->prev_match = s->match_start; - s->match_length = MIN_MATCH-1; - - if (hash_head != NIL && s->prev_length < s->max_lazy_match && - s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { - s->match_length = longest_match (s, hash_head); - } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { - s->match_length = longest_match_fast (s, hash_head); - } - /* longest_match() or longest_match_fast() sets match_start */ - - if (s->match_length <= 5 && (s->strategy == Z_FILTERED -#if TOO_FAR <= 32767 - || (s->match_length == MIN_MATCH && - s->strstart - s->match_start > TOO_FAR) -#endif - )) { - - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s->match_length = MIN_MATCH-1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { - uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; - /* Do not insert strings in hash table beyond this. */ - - check_match(s, s->strstart-1, s->prev_match, s->prev_length); - - _tr_tally_dist(s, s->strstart -1 - s->prev_match, - s->prev_length - MIN_MATCH, bflush); - - /* Insert in hash table all strings up to the end of the match. - * strstart-1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. - */ - s->lookahead -= s->prev_length-1; - s->prev_length -= 2; - do { - if (++s->strstart <= max_insert) { - INSERT_STRING(s, s->strstart, hash_head); - } - } while (--s->prev_length != 0); - s->match_available = 0; - s->match_length = MIN_MATCH-1; - s->strstart++; - - if (bflush) FLUSH_BLOCK(s, 0); - - } else if (s->match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - if (bflush) { - FLUSH_BLOCK_ONLY(s, 0); - } - s->strstart++; - s->lookahead--; - if (s->strm->avail_out == 0) return need_more; - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s->match_available = 1; - s->strstart++; - s->lookahead--; - } - } - Assert (flush != Z_NO_FLUSH, "no flush?"); - if (s->match_available) { - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - s->match_available = 0; - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} -#endif /* FASTEST */ - -#if 0 -/* =========================================================================== - * For Z_RLE, simply look for runs of bytes, generate matches only of distance - * one. Do not maintain a hash table. (It will be regenerated if this run of - * deflate switches away from Z_RLE.) - */ -local block_state deflate_rle(s, flush) - deflate_state *s; - int flush; -{ - int bflush; /* set if current block must be flushed */ - uInt run; /* length of run */ - uInt max; /* maximum length of run */ - uInt prev; /* byte at distance one to match */ - Bytef *scan; /* scan for end of run */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the longest encodable run. - */ - if (s->lookahead < MAX_MATCH) { - fill_window(s); - if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* See how many times the previous byte repeats */ - run = 0; - if (s->strstart > 0) { /* if there is a previous byte, that is */ - max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH; - scan = s->window + s->strstart - 1; - prev = *scan++; - do { - if (*scan++ != prev) - break; - } while (++run < max); - } - - /* Emit match if have run of MIN_MATCH or longer, else emit literal */ - if (run >= MIN_MATCH) { - check_match(s, s->strstart, s->strstart - 1, run); - _tr_tally_dist(s, 1, run - MIN_MATCH, bflush); - s->lookahead -= run; - s->strstart += run; - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} -#endif diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/deflate.h b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/deflate.h deleted file mode 100644 index 05a5ab3a2..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/deflate.h +++ /dev/null @@ -1,331 +0,0 @@ -/* deflate.h -- internal compression state - * Copyright (C) 1995-2004 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#ifndef DEFLATE_H -#define DEFLATE_H - -#include "zutil.h" - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer creation by deflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip encoding - should be left enabled. */ -#ifndef NO_GZIP -# define GZIP -#endif - -/* =========================================================================== - * Internal compression state. - */ - -#define LENGTH_CODES 29 -/* number of length codes, not counting the special END_BLOCK code */ - -#define LITERALS 256 -/* number of literal bytes 0..255 */ - -#define L_CODES (LITERALS+1+LENGTH_CODES) -/* number of Literal or Length codes, including the END_BLOCK code */ - -#define D_CODES 30 -/* number of distance codes */ - -#define BL_CODES 19 -/* number of codes used to transfer the bit lengths */ - -#define HEAP_SIZE (2*L_CODES+1) -/* maximum heap size */ - -#define MAX_BITS 15 -/* All codes must not exceed MAX_BITS bits */ - -#define INIT_STATE 42 -#define EXTRA_STATE 69 -#define NAME_STATE 73 -#define COMMENT_STATE 91 -#define HCRC_STATE 103 -#define BUSY_STATE 113 -#define FINISH_STATE 666 -/* Stream status */ - - -/* Data structure describing a single value and its code string. */ -typedef struct ct_data_s { - union { - ush freq; /* frequency count */ - ush code; /* bit string */ - } fc; - union { - ush dad; /* father node in Huffman tree */ - ush len; /* length of bit string */ - } dl; -} FAR ct_data; - -#define Freq fc.freq -#define Code fc.code -#define Dad dl.dad -#define Len dl.len - -typedef struct static_tree_desc_s static_tree_desc; - -typedef struct tree_desc_s { - ct_data *dyn_tree; /* the dynamic tree */ - int max_code; /* largest code with non zero frequency */ - static_tree_desc *stat_desc; /* the corresponding static tree */ -} FAR tree_desc; - -typedef ush Pos; -typedef Pos FAR Posf; -typedef unsigned IPos; - -/* A Pos is an index in the character window. We use short instead of int to - * save space in the various tables. IPos is used only for parameter passing. - */ - -typedef struct internal_state { - z_streamp strm; /* pointer back to this zlib stream */ - int status; /* as the name implies */ - Bytef *pending_buf; /* output still pending */ - ulg pending_buf_size; /* size of pending_buf */ - Bytef *pending_out; /* next pending byte to output to the stream */ - uInt pending; /* nb of bytes in the pending buffer */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - gz_headerp gzhead; /* gzip header information to write */ - uInt gzindex; /* where in extra, name, or comment */ - Byte method; /* STORED (for zip only) or DEFLATED */ - int last_flush; /* value of flush param for previous deflate call */ - - /* used by deflate.c: */ - - uInt w_size; /* LZ77 window size (32K by default) */ - uInt w_bits; /* log2(w_size) (8..16) */ - uInt w_mask; /* w_size - 1 */ - - Bytef *window; - /* Sliding window. Input bytes are read into the second half of the window, - * and move to the first half later to keep a dictionary of at least wSize - * bytes. With this organization, matches are limited to a distance of - * wSize-MAX_MATCH bytes, but this ensures that IO is always - * performed with a length multiple of the block size. Also, it limits - * the window size to 64K, which is quite useful on MSDOS. - * To do: use the user input buffer as sliding window. - */ - - ulg window_size; - /* Actual size of window: 2*wSize, except when the user input buffer - * is directly used as sliding window. - */ - - Posf *prev; - /* Link to older string with same hash index. To limit the size of this - * array to 64K, this link is maintained only for the last 32K strings. - * An index in this array is thus a window index modulo 32K. - */ - - Posf *head; /* Heads of the hash chains or NIL. */ - - uInt ins_h; /* hash index of string to be inserted */ - uInt hash_size; /* number of elements in hash table */ - uInt hash_bits; /* log2(hash_size) */ - uInt hash_mask; /* hash_size-1 */ - - uInt hash_shift; - /* Number of bits by which ins_h must be shifted at each input - * step. It must be such that after MIN_MATCH steps, the oldest - * byte no longer takes part in the hash key, that is: - * hash_shift * MIN_MATCH >= hash_bits - */ - - long block_start; - /* Window position at the beginning of the current output block. Gets - * negative when the window is moved backwards. - */ - - uInt match_length; /* length of best match */ - IPos prev_match; /* previous match */ - int match_available; /* set if previous match exists */ - uInt strstart; /* start of string to insert */ - uInt match_start; /* start of matching string */ - uInt lookahead; /* number of valid bytes ahead in window */ - - uInt prev_length; - /* Length of the best match at previous step. Matches not greater than this - * are discarded. This is used in the lazy match evaluation. - */ - - uInt max_chain_length; - /* To speed up deflation, hash chains are never searched beyond this - * length. A higher limit improves compression ratio but degrades the - * speed. - */ - - uInt max_lazy_match; - /* Attempt to find a better match only when the current match is strictly - * smaller than this value. This mechanism is used only for compression - * levels >= 4. - */ -# define max_insert_length max_lazy_match - /* Insert new strings in the hash table only if the match length is not - * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. - */ - - int level; /* compression level (1..9) */ - int strategy; /* favor or force Huffman coding*/ - - uInt good_match; - /* Use a faster search when the previous match is longer than this */ - - int nice_match; /* Stop searching when current match exceeds this */ - - /* used by trees.c: */ - /* Didn't use ct_data typedef below to supress compiler warning */ - struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ - struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ - - struct tree_desc_s l_desc; /* desc. for literal tree */ - struct tree_desc_s d_desc; /* desc. for distance tree */ - struct tree_desc_s bl_desc; /* desc. for bit length tree */ - - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - int heap_len; /* number of elements in the heap */ - int heap_max; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - * The same heap array is used to build all trees. - */ - - uch depth[2*L_CODES+1]; - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ - - uchf *l_buf; /* buffer for literals or lengths */ - - uInt lit_bufsize; - /* Size of match buffer for literals/lengths. There are 4 reasons for - * limiting lit_bufsize to 64K: - * - frequencies can be kept in 16 bit counters - * - if compression is not successful for the first block, all input - * data is still in the window so we can still emit a stored block even - * when input comes from standard input. (This can also be done for - * all blocks if lit_bufsize is not greater than 32K.) - * - if compression is not successful for a file smaller than 64K, we can - * even emit a stored file instead of a stored block (saving 5 bytes). - * This is applicable only for zip (not gzip or zlib). - * - creating new Huffman trees less frequently may not provide fast - * adaptation to changes in the input data statistics. (Take for - * example a binary file with poorly compressible code followed by - * a highly compressible string table.) Smaller buffer sizes give - * fast adaptation but have of course the overhead of transmitting - * trees more frequently. - * - I can't count above 4 - */ - - uInt last_lit; /* running index in l_buf */ - - ushf *d_buf; - /* Buffer for distances. To simplify the code, d_buf and l_buf have - * the same number of elements. To use different lengths, an extra flag - * array would be necessary. - */ - - ulg opt_len; /* bit length of current block with optimal trees */ - ulg static_len; /* bit length of current block with static trees */ - uInt matches; /* number of string matches in current block */ - int last_eob_len; /* bit length of EOB code for last block */ - -#ifdef DEBUG - ulg compressed_len; /* total bit length of compressed file mod 2^32 */ - ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ -#endif - - ush bi_buf; - /* Output buffer. bits are inserted starting at the bottom (least - * significant bits). - */ - int bi_valid; - /* Number of valid bits in bi_buf. All bits above the last valid bit - * are always zero. - */ - -} FAR deflate_state; - -/* Output a byte on the stream. - * IN assertion: there is enough room in pending_buf. - */ -#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} - - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) -/* In order to simplify the code, particularly on 16 bit machines, match - * distances are limited to MAX_DIST instead of WSIZE. - */ - - /* in trees.c */ -void _tr_init OF((deflate_state *s)); -int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); -void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, - int eof)); -void _tr_align OF((deflate_state *s)); -void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, - int eof)); - -#define d_code(dist) \ - ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) -/* Mapping from a distance to a distance code. dist is the distance - 1 and - * must not have side effects. _dist_code[256] and _dist_code[257] are never - * used. - */ - -#ifndef DEBUG -/* Inline versions of _tr_tally for speed: */ - -#if defined(GEN_TREES_H) || !defined(STDC) - extern uch _length_code[]; - extern uch _dist_code[]; -#else - extern const uch _length_code[]; - extern const uch _dist_code[]; -#endif - -# define _tr_tally_lit(s, c, flush) \ - { uch cc = (c); \ - s->d_buf[s->last_lit] = 0; \ - s->l_buf[s->last_lit++] = cc; \ - s->dyn_ltree[cc].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } -# define _tr_tally_dist(s, distance, length, flush) \ - { uch len = (length); \ - ush dist = (distance); \ - s->d_buf[s->last_lit] = dist; \ - s->l_buf[s->last_lit++] = len; \ - dist--; \ - s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ - s->dyn_dtree[d_code(dist)].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } -#else -# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) -# define _tr_tally_dist(s, distance, length, flush) \ - flush = _tr_tally(s, distance, length) -#endif - -#endif /* DEFLATE_H */ diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/example.c b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/example.c deleted file mode 100644 index 6c8a0ee76..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/example.c +++ /dev/null @@ -1,565 +0,0 @@ -/* example.c -- usage example of the zlib compression library - * Copyright (C) 1995-2004 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include -#include "zlib.h" - -#ifdef STDC -# include -# include -#endif - -#if defined(VMS) || defined(RISCOS) -# define TESTFILE "foo-gz" -#else -# define TESTFILE "foo.gz" -#endif - -#define CHECK_ERR(err, msg) { \ - if (err != Z_OK) { \ - fprintf(stderr, "%s error: %d\n", msg, err); \ - exit(1); \ - } \ -} - -const char hello[] = "hello, hello!"; -/* "hello world" would be more standard, but the repeated "hello" - * stresses the compression code better, sorry... - */ - -const char dictionary[] = "hello"; -uLong dictId; /* Adler32 value of the dictionary */ - -void test_compress OF((Byte *compr, uLong comprLen, - Byte *uncompr, uLong uncomprLen)); -void test_gzio OF((const char *fname, - Byte *uncompr, uLong uncomprLen)); -void test_deflate OF((Byte *compr, uLong comprLen)); -void test_inflate OF((Byte *compr, uLong comprLen, - Byte *uncompr, uLong uncomprLen)); -void test_large_deflate OF((Byte *compr, uLong comprLen, - Byte *uncompr, uLong uncomprLen)); -void test_large_inflate OF((Byte *compr, uLong comprLen, - Byte *uncompr, uLong uncomprLen)); -void test_flush OF((Byte *compr, uLong *comprLen)); -void test_sync OF((Byte *compr, uLong comprLen, - Byte *uncompr, uLong uncomprLen)); -void test_dict_deflate OF((Byte *compr, uLong comprLen)); -void test_dict_inflate OF((Byte *compr, uLong comprLen, - Byte *uncompr, uLong uncomprLen)); -int main OF((int argc, char *argv[])); - -/* =========================================================================== - * Test compress() and uncompress() - */ -void test_compress(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; -{ - int err; - uLong len = (uLong)strlen(hello)+1; - - err = compress(compr, &comprLen, (const Bytef*)hello, len); - CHECK_ERR(err, "compress"); - - strcpy((char*)uncompr, "garbage"); - - err = uncompress(uncompr, &uncomprLen, compr, comprLen); - CHECK_ERR(err, "uncompress"); - - if (strcmp((char*)uncompr, hello)) { - fprintf(stderr, "bad uncompress\n"); - exit(1); - } else { - printf("uncompress(): %s\n", (char *)uncompr); - } -} - -/* =========================================================================== - * Test read/write of .gz files - */ -void test_gzio(fname, uncompr, uncomprLen) - const char *fname; /* compressed file name */ - Byte *uncompr; - uLong uncomprLen; -{ -#ifdef NO_GZCOMPRESS - fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n"); -#else - int err; - int len = (int)strlen(hello)+1; - gzFile file; - z_off_t pos; - - file = gzopen(fname, "wb"); - if (file == NULL) { - fprintf(stderr, "gzopen error\n"); - exit(1); - } - gzputc(file, 'h'); - if (gzputs(file, "ello") != 4) { - fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err)); - exit(1); - } - if (gzprintf(file, ", %s!", "hello") != 8) { - fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err)); - exit(1); - } - gzseek(file, 1L, SEEK_CUR); /* add one zero byte */ - gzclose(file); - - file = gzopen(fname, "rb"); - if (file == NULL) { - fprintf(stderr, "gzopen error\n"); - exit(1); - } - strcpy((char*)uncompr, "garbage"); - - if (gzread(file, uncompr, (unsigned)uncomprLen) != len) { - fprintf(stderr, "gzread err: %s\n", gzerror(file, &err)); - exit(1); - } - if (strcmp((char*)uncompr, hello)) { - fprintf(stderr, "bad gzread: %s\n", (char*)uncompr); - exit(1); - } else { - printf("gzread(): %s\n", (char*)uncompr); - } - - pos = gzseek(file, -8L, SEEK_CUR); - if (pos != 6 || gztell(file) != pos) { - fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n", - (long)pos, (long)gztell(file)); - exit(1); - } - - if (gzgetc(file) != ' ') { - fprintf(stderr, "gzgetc error\n"); - exit(1); - } - - if (gzungetc(' ', file) != ' ') { - fprintf(stderr, "gzungetc error\n"); - exit(1); - } - - gzgets(file, (char*)uncompr, (int)uncomprLen); - if (strlen((char*)uncompr) != 7) { /* " hello!" */ - fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err)); - exit(1); - } - if (strcmp((char*)uncompr, hello + 6)) { - fprintf(stderr, "bad gzgets after gzseek\n"); - exit(1); - } else { - printf("gzgets() after gzseek: %s\n", (char*)uncompr); - } - - gzclose(file); -#endif -} - -/* =========================================================================== - * Test deflate() with small buffers - */ -void test_deflate(compr, comprLen) - Byte *compr; - uLong comprLen; -{ - z_stream c_stream; /* compression stream */ - int err; - uLong len = (uLong)strlen(hello)+1; - - c_stream.zalloc = (alloc_func)0; - c_stream.zfree = (free_func)0; - c_stream.opaque = (voidpf)0; - - err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); - CHECK_ERR(err, "deflateInit"); - - c_stream.next_in = (Bytef*)hello; - c_stream.next_out = compr; - - while (c_stream.total_in != len && c_stream.total_out < comprLen) { - c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ - err = deflate(&c_stream, Z_NO_FLUSH); - CHECK_ERR(err, "deflate"); - } - /* Finish the stream, still forcing small buffers: */ - for (;;) { - c_stream.avail_out = 1; - err = deflate(&c_stream, Z_FINISH); - if (err == Z_STREAM_END) break; - CHECK_ERR(err, "deflate"); - } - - err = deflateEnd(&c_stream); - CHECK_ERR(err, "deflateEnd"); -} - -/* =========================================================================== - * Test inflate() with small buffers - */ -void test_inflate(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; -{ - int err; - z_stream d_stream; /* decompression stream */ - - strcpy((char*)uncompr, "garbage"); - - d_stream.zalloc = (alloc_func)0; - d_stream.zfree = (free_func)0; - d_stream.opaque = (voidpf)0; - - d_stream.next_in = compr; - d_stream.avail_in = 0; - d_stream.next_out = uncompr; - - err = inflateInit(&d_stream); - CHECK_ERR(err, "inflateInit"); - - while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) { - d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ - err = inflate(&d_stream, Z_NO_FLUSH); - if (err == Z_STREAM_END) break; - CHECK_ERR(err, "inflate"); - } - - err = inflateEnd(&d_stream); - CHECK_ERR(err, "inflateEnd"); - - if (strcmp((char*)uncompr, hello)) { - fprintf(stderr, "bad inflate\n"); - exit(1); - } else { - printf("inflate(): %s\n", (char *)uncompr); - } -} - -/* =========================================================================== - * Test deflate() with large buffers and dynamic change of compression level - */ -void test_large_deflate(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; -{ - z_stream c_stream; /* compression stream */ - int err; - - c_stream.zalloc = (alloc_func)0; - c_stream.zfree = (free_func)0; - c_stream.opaque = (voidpf)0; - - err = deflateInit(&c_stream, Z_BEST_SPEED); - CHECK_ERR(err, "deflateInit"); - - c_stream.next_out = compr; - c_stream.avail_out = (uInt)comprLen; - - /* At this point, uncompr is still mostly zeroes, so it should compress - * very well: - */ - c_stream.next_in = uncompr; - c_stream.avail_in = (uInt)uncomprLen; - err = deflate(&c_stream, Z_NO_FLUSH); - CHECK_ERR(err, "deflate"); - if (c_stream.avail_in != 0) { - fprintf(stderr, "deflate not greedy\n"); - exit(1); - } - - /* Feed in already compressed data and switch to no compression: */ - deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); - c_stream.next_in = compr; - c_stream.avail_in = (uInt)comprLen/2; - err = deflate(&c_stream, Z_NO_FLUSH); - CHECK_ERR(err, "deflate"); - - /* Switch back to compressing mode: */ - deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED); - c_stream.next_in = uncompr; - c_stream.avail_in = (uInt)uncomprLen; - err = deflate(&c_stream, Z_NO_FLUSH); - CHECK_ERR(err, "deflate"); - - err = deflate(&c_stream, Z_FINISH); - if (err != Z_STREAM_END) { - fprintf(stderr, "deflate should report Z_STREAM_END\n"); - exit(1); - } - err = deflateEnd(&c_stream); - CHECK_ERR(err, "deflateEnd"); -} - -/* =========================================================================== - * Test inflate() with large buffers - */ -void test_large_inflate(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; -{ - int err; - z_stream d_stream; /* decompression stream */ - - strcpy((char*)uncompr, "garbage"); - - d_stream.zalloc = (alloc_func)0; - d_stream.zfree = (free_func)0; - d_stream.opaque = (voidpf)0; - - d_stream.next_in = compr; - d_stream.avail_in = (uInt)comprLen; - - err = inflateInit(&d_stream); - CHECK_ERR(err, "inflateInit"); - - for (;;) { - d_stream.next_out = uncompr; /* discard the output */ - d_stream.avail_out = (uInt)uncomprLen; - err = inflate(&d_stream, Z_NO_FLUSH); - if (err == Z_STREAM_END) break; - CHECK_ERR(err, "large inflate"); - } - - err = inflateEnd(&d_stream); - CHECK_ERR(err, "inflateEnd"); - - if (d_stream.total_out != 2*uncomprLen + comprLen/2) { - fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out); - exit(1); - } else { - printf("large_inflate(): OK\n"); - } -} - -/* =========================================================================== - * Test deflate() with full flush - */ -void test_flush(compr, comprLen) - Byte *compr; - uLong *comprLen; -{ - z_stream c_stream; /* compression stream */ - int err; - uInt len = (uInt)strlen(hello)+1; - - c_stream.zalloc = (alloc_func)0; - c_stream.zfree = (free_func)0; - c_stream.opaque = (voidpf)0; - - err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); - CHECK_ERR(err, "deflateInit"); - - c_stream.next_in = (Bytef*)hello; - c_stream.next_out = compr; - c_stream.avail_in = 3; - c_stream.avail_out = (uInt)*comprLen; - err = deflate(&c_stream, Z_FULL_FLUSH); - CHECK_ERR(err, "deflate"); - - compr[3]++; /* force an error in first compressed block */ - c_stream.avail_in = len - 3; - - err = deflate(&c_stream, Z_FINISH); - if (err != Z_STREAM_END) { - CHECK_ERR(err, "deflate"); - } - err = deflateEnd(&c_stream); - CHECK_ERR(err, "deflateEnd"); - - *comprLen = c_stream.total_out; -} - -/* =========================================================================== - * Test inflateSync() - */ -void test_sync(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; -{ - int err; - z_stream d_stream; /* decompression stream */ - - strcpy((char*)uncompr, "garbage"); - - d_stream.zalloc = (alloc_func)0; - d_stream.zfree = (free_func)0; - d_stream.opaque = (voidpf)0; - - d_stream.next_in = compr; - d_stream.avail_in = 2; /* just read the zlib header */ - - err = inflateInit(&d_stream); - CHECK_ERR(err, "inflateInit"); - - d_stream.next_out = uncompr; - d_stream.avail_out = (uInt)uncomprLen; - - inflate(&d_stream, Z_NO_FLUSH); - CHECK_ERR(err, "inflate"); - - d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */ - err = inflateSync(&d_stream); /* but skip the damaged part */ - CHECK_ERR(err, "inflateSync"); - - err = inflate(&d_stream, Z_FINISH); - if (err != Z_DATA_ERROR) { - fprintf(stderr, "inflate should report DATA_ERROR\n"); - /* Because of incorrect adler32 */ - exit(1); - } - err = inflateEnd(&d_stream); - CHECK_ERR(err, "inflateEnd"); - - printf("after inflateSync(): hel%s\n", (char *)uncompr); -} - -/* =========================================================================== - * Test deflate() with preset dictionary - */ -void test_dict_deflate(compr, comprLen) - Byte *compr; - uLong comprLen; -{ - z_stream c_stream; /* compression stream */ - int err; - - c_stream.zalloc = (alloc_func)0; - c_stream.zfree = (free_func)0; - c_stream.opaque = (voidpf)0; - - err = deflateInit(&c_stream, Z_BEST_COMPRESSION); - CHECK_ERR(err, "deflateInit"); - - err = deflateSetDictionary(&c_stream, - (const Bytef*)dictionary, sizeof(dictionary)); - CHECK_ERR(err, "deflateSetDictionary"); - - dictId = c_stream.adler; - c_stream.next_out = compr; - c_stream.avail_out = (uInt)comprLen; - - c_stream.next_in = (Bytef*)hello; - c_stream.avail_in = (uInt)strlen(hello)+1; - - err = deflate(&c_stream, Z_FINISH); - if (err != Z_STREAM_END) { - fprintf(stderr, "deflate should report Z_STREAM_END\n"); - exit(1); - } - err = deflateEnd(&c_stream); - CHECK_ERR(err, "deflateEnd"); -} - -/* =========================================================================== - * Test inflate() with a preset dictionary - */ -void test_dict_inflate(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; -{ - int err; - z_stream d_stream; /* decompression stream */ - - strcpy((char*)uncompr, "garbage"); - - d_stream.zalloc = (alloc_func)0; - d_stream.zfree = (free_func)0; - d_stream.opaque = (voidpf)0; - - d_stream.next_in = compr; - d_stream.avail_in = (uInt)comprLen; - - err = inflateInit(&d_stream); - CHECK_ERR(err, "inflateInit"); - - d_stream.next_out = uncompr; - d_stream.avail_out = (uInt)uncomprLen; - - for (;;) { - err = inflate(&d_stream, Z_NO_FLUSH); - if (err == Z_STREAM_END) break; - if (err == Z_NEED_DICT) { - if (d_stream.adler != dictId) { - fprintf(stderr, "unexpected dictionary"); - exit(1); - } - err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary, - sizeof(dictionary)); - } - CHECK_ERR(err, "inflate with dict"); - } - - err = inflateEnd(&d_stream); - CHECK_ERR(err, "inflateEnd"); - - if (strcmp((char*)uncompr, hello)) { - fprintf(stderr, "bad inflate with dict\n"); - exit(1); - } else { - printf("inflate with dictionary: %s\n", (char *)uncompr); - } -} - -/* =========================================================================== - * Usage: example [output.gz [input.gz]] - */ - -int main(argc, argv) - int argc; - char *argv[]; -{ - Byte *compr, *uncompr; - uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */ - uLong uncomprLen = comprLen; - static const char* myVersion = ZLIB_VERSION; - - if (zlibVersion()[0] != myVersion[0]) { - fprintf(stderr, "incompatible zlib version\n"); - exit(1); - - } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) { - fprintf(stderr, "warning: different zlib version\n"); - } - - printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n", - ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags()); - - compr = (Byte*)calloc((uInt)comprLen, 1); - uncompr = (Byte*)calloc((uInt)uncomprLen, 1); - /* compr and uncompr are cleared to avoid reading uninitialized - * data and to ensure that uncompr compresses well. - */ - if (compr == Z_NULL || uncompr == Z_NULL) { - printf("out of memory\n"); - exit(1); - } - test_compress(compr, comprLen, uncompr, uncomprLen); - - test_gzio((argc > 1 ? argv[1] : TESTFILE), - uncompr, uncomprLen); - - test_deflate(compr, comprLen); - test_inflate(compr, comprLen, uncompr, uncomprLen); - - test_large_deflate(compr, comprLen, uncompr, uncomprLen); - test_large_inflate(compr, comprLen, uncompr, uncomprLen); - - test_flush(compr, &comprLen); - test_sync(compr, comprLen, uncompr, uncomprLen); - comprLen = uncomprLen; - - test_dict_deflate(compr, comprLen); - test_dict_inflate(compr, comprLen, uncompr, uncomprLen); - - free(compr); - free(uncompr); - - return 0; -} diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/gzio.c b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/gzio.c deleted file mode 100644 index 25850ad1d..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/gzio.c +++ /dev/null @@ -1,1026 +0,0 @@ -/* gzio.c -- IO on .gz files - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - * - * Compile this file with -DNO_GZCOMPRESS to avoid the compression code. - */ - -/* @(#) $Id$ */ - -#include - -#include "zutil.h" - -#ifdef NO_DEFLATE /* for compatibility with old definition */ -# define NO_GZCOMPRESS -#endif - -#ifndef NO_DUMMY_DECL -struct internal_state {int dummy;}; /* for buggy compilers */ -#endif - -#ifndef Z_BUFSIZE -# ifdef MAXSEG_64K -# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */ -# else -# define Z_BUFSIZE 16384 -# endif -#endif -#ifndef Z_PRINTF_BUFSIZE -# define Z_PRINTF_BUFSIZE 4096 -#endif - -#ifdef __MVS__ -# pragma map (fdopen , "\174\174FDOPEN") - FILE *fdopen(int, const char *); -#endif - -#ifndef STDC -extern voidp malloc OF((uInt size)); -extern void free OF((voidpf ptr)); -#endif - -#define ALLOC(size) malloc(size) -#define TRYFREE(p) {if (p) free(p);} - -static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ - -/* gzip flag byte */ -#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ -#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ -#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ -#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ -#define COMMENT 0x10 /* bit 4 set: file comment present */ -#define RESERVED 0xE0 /* bits 5..7: reserved */ - -typedef struct gz_stream { - z_stream stream; - int z_err; /* error code for last stream operation */ - int z_eof; /* set if end of input file */ - FILE *file; /* .gz file */ - Byte *inbuf; /* input buffer */ - Byte *outbuf; /* output buffer */ - uLong crc; /* crc32 of uncompressed data */ - char *msg; /* error message */ - char *path; /* path name for debugging only */ - int transparent; /* 1 if input file is not a .gz file */ - char mode; /* 'w' or 'r' */ - z_off_t start; /* start of compressed data in file (header skipped) */ - z_off_t in; /* bytes into deflate or inflate */ - z_off_t out; /* bytes out of deflate or inflate */ - int back; /* one character push-back */ - int last; /* true if push-back is last character */ -} gz_stream; - - -local gzFile gz_open OF((const char *path, const char *mode, int fd)); -local int do_flush OF((gzFile file, int flush)); -local int get_byte OF((gz_stream *s)); -local void check_header OF((gz_stream *s)); -local int destroy OF((gz_stream *s)); -local void putLong OF((FILE *file, uLong x)); -local uLong getLong OF((gz_stream *s)); - -/* =========================================================================== - Opens a gzip (.gz) file for reading or writing. The mode parameter - is as in fopen ("rb" or "wb"). The file is given either by file descriptor - or path name (if fd == -1). - gz_open returns NULL if the file could not be opened or if there was - insufficient memory to allocate the (de)compression state; errno - can be checked to distinguish the two cases (if errno is zero, the - zlib error is Z_MEM_ERROR). -*/ -local gzFile gz_open (path, mode, fd) - const char *path; - const char *mode; - int fd; -{ - int err; - int level = Z_DEFAULT_COMPRESSION; /* compression level */ - int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */ - char *p = (char*)mode; - gz_stream *s; - char fmode[80]; /* copy of mode, without the compression level */ - char *m = fmode; - - if (!path || !mode) return Z_NULL; - - s = (gz_stream *)ALLOC(sizeof(gz_stream)); - if (!s) return Z_NULL; - - s->stream.zalloc = (alloc_func)0; - s->stream.zfree = (free_func)0; - s->stream.opaque = (voidpf)0; - s->stream.next_in = s->inbuf = Z_NULL; - s->stream.next_out = s->outbuf = Z_NULL; - s->stream.avail_in = s->stream.avail_out = 0; - s->file = NULL; - s->z_err = Z_OK; - s->z_eof = 0; - s->in = 0; - s->out = 0; - s->back = EOF; - s->crc = crc32(0L, Z_NULL, 0); - s->msg = NULL; - s->transparent = 0; - - s->path = (char*)ALLOC(strlen(path)+1); - if (s->path == NULL) { - return destroy(s), (gzFile)Z_NULL; - } - strcpy(s->path, path); /* do this early for debugging */ - - s->mode = '\0'; - do { - if (*p == 'r') s->mode = 'r'; - if (*p == 'w' || *p == 'a') s->mode = 'w'; - if (*p >= '0' && *p <= '9') { - level = *p - '0'; - } else if (*p == 'f') { - strategy = Z_FILTERED; - } else if (*p == 'h') { - strategy = Z_HUFFMAN_ONLY; - } else if (*p == 'R') { - strategy = Z_RLE; - } else { - *m++ = *p; /* copy the mode */ - } - } while (*p++ && m != fmode + sizeof(fmode)); - if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; - - if (s->mode == 'w') { -#ifdef NO_GZCOMPRESS - err = Z_STREAM_ERROR; -#else - err = deflateInit2(&(s->stream), level, - Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy); - /* windowBits is passed < 0 to suppress zlib header */ - - s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); -#endif - if (err != Z_OK || s->outbuf == Z_NULL) { - return destroy(s), (gzFile)Z_NULL; - } - } else { - s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); - - err = inflateInit2(&(s->stream), -MAX_WBITS); - /* windowBits is passed < 0 to tell that there is no zlib header. - * Note that in this case inflate *requires* an extra "dummy" byte - * after the compressed stream in order to complete decompression and - * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are - * present after the compressed stream. - */ - if (err != Z_OK || s->inbuf == Z_NULL) { - return destroy(s), (gzFile)Z_NULL; - } - } - s->stream.avail_out = Z_BUFSIZE; - - errno = 0; - s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode); - - if (s->file == NULL) { - return destroy(s), (gzFile)Z_NULL; - } - if (s->mode == 'w') { - /* Write a very simple .gz header: - */ - fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], - Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); - s->start = 10L; - /* We use 10L instead of ftell(s->file) to because ftell causes an - * fflush on some systems. This version of the library doesn't use - * start anyway in write mode, so this initialization is not - * necessary. - */ - } else { - check_header(s); /* skip the .gz header */ - s->start = ftell(s->file) - s->stream.avail_in; - } - - return (gzFile)s; -} - -/* =========================================================================== - Opens a gzip (.gz) file for reading or writing. -*/ -gzFile Q_ZEXPORT gzopen (path, mode) - const char *path; - const char *mode; -{ - return gz_open (path, mode, -1); -} - -/* =========================================================================== - Associate a gzFile with the file descriptor fd. fd is not dup'ed here - to mimic the behavio(u)r of fdopen. -*/ -gzFile ZEXPORT gzdopen (fd, mode) - int fd; - const char *mode; -{ - char name[46]; /* allow for up to 128-bit integers */ - - if (fd < 0) return (gzFile)Z_NULL; - sprintf(name, "", fd); /* for debugging */ - - return gz_open (name, mode, fd); -} - -/* =========================================================================== - * Update the compression level and strategy - */ -int ZEXPORT gzsetparams (file, level, strategy) - gzFile file; - int level; - int strategy; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; - - /* Make room to allow flushing */ - if (s->stream.avail_out == 0) { - - s->stream.next_out = s->outbuf; - if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { - s->z_err = Z_ERRNO; - } - s->stream.avail_out = Z_BUFSIZE; - } - - return deflateParams (&(s->stream), level, strategy); -} - -/* =========================================================================== - Read a byte from a gz_stream; update next_in and avail_in. Return EOF - for end of file. - IN assertion: the stream s has been sucessfully opened for reading. -*/ -local int get_byte(s) - gz_stream *s; -{ - if (s->z_eof) return EOF; - if (s->stream.avail_in == 0) { - errno = 0; - s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file); - if (s->stream.avail_in == 0) { - s->z_eof = 1; - if (ferror(s->file)) s->z_err = Z_ERRNO; - return EOF; - } - s->stream.next_in = s->inbuf; - } - s->stream.avail_in--; - return *(s->stream.next_in)++; -} - -/* =========================================================================== - Check the gzip header of a gz_stream opened for reading. Set the stream - mode to transparent if the gzip magic header is not present; set s->err - to Z_DATA_ERROR if the magic header is present but the rest of the header - is incorrect. - IN assertion: the stream s has already been created sucessfully; - s->stream.avail_in is zero for the first time, but may be non-zero - for concatenated .gz files. -*/ -local void check_header(s) - gz_stream *s; -{ - int method; /* method byte */ - int flags; /* flags byte */ - uInt len; - int c; - - /* Assure two bytes in the buffer so we can peek ahead -- handle case - where first byte of header is at the end of the buffer after the last - gzip segment */ - len = s->stream.avail_in; - if (len < 2) { - if (len) s->inbuf[0] = s->stream.next_in[0]; - errno = 0; - len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file); - if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO; - s->stream.avail_in += len; - s->stream.next_in = s->inbuf; - if (s->stream.avail_in < 2) { - s->transparent = s->stream.avail_in; - return; - } - } - - /* Peek ahead to check the gzip magic header */ - if (s->stream.next_in[0] != gz_magic[0] || - s->stream.next_in[1] != gz_magic[1]) { - s->transparent = 1; - return; - } - s->stream.avail_in -= 2; - s->stream.next_in += 2; - - /* Check the rest of the gzip header */ - method = get_byte(s); - flags = get_byte(s); - if (method != Z_DEFLATED || (flags & RESERVED) != 0) { - s->z_err = Z_DATA_ERROR; - return; - } - - /* Discard time, xflags and OS code: */ - for (len = 0; len < 6; len++) (void)get_byte(s); - - if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ - len = (uInt)get_byte(s); - len += ((uInt)get_byte(s))<<8; - /* len is garbage if EOF but the loop below will quit anyway */ - while (len-- != 0 && get_byte(s) != EOF) ; - } - if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ - while ((c = get_byte(s)) != 0 && c != EOF) ; - } - if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ - while ((c = get_byte(s)) != 0 && c != EOF) ; - } - if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ - for (len = 0; len < 2; len++) (void)get_byte(s); - } - s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; -} - - /* =========================================================================== - * Cleanup then free the given gz_stream. Return a zlib error code. - Try freeing in the reverse order of allocations. - */ -local int destroy (s) - gz_stream *s; -{ - int err = Z_OK; - - if (!s) return Z_STREAM_ERROR; - - TRYFREE(s->msg); - - if (s->stream.state != NULL) { - if (s->mode == 'w') { -#ifdef NO_GZCOMPRESS - err = Z_STREAM_ERROR; -#else - err = deflateEnd(&(s->stream)); -#endif - } else if (s->mode == 'r') { - err = inflateEnd(&(s->stream)); - } - } - if (s->file != NULL && fclose(s->file)) { -#ifdef ESPIPE - if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */ -#endif - err = Z_ERRNO; - } - if (s->z_err < 0) err = s->z_err; - - TRYFREE(s->inbuf); - TRYFREE(s->outbuf); - TRYFREE(s->path); - TRYFREE(s); - return err; -} - -/* =========================================================================== - Reads the given number of uncompressed bytes from the compressed file. - gzread returns the number of bytes actually read (0 for end of file). -*/ -int Q_ZEXPORT gzread (file, buf, len) - gzFile file; - voidp buf; - unsigned len; -{ - gz_stream *s = (gz_stream*)file; - Bytef *start = (Bytef*)buf; /* starting point for crc computation */ - Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */ - - if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; - - if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; - if (s->z_err == Z_STREAM_END) return 0; /* EOF */ - - next_out = (Byte*)buf; - s->stream.next_out = (Bytef*)buf; - s->stream.avail_out = len; - - if (s->stream.avail_out && s->back != EOF) { - *next_out++ = s->back; - s->stream.next_out++; - s->stream.avail_out--; - s->back = EOF; - s->out++; - start++; - if (s->last) { - s->z_err = Z_STREAM_END; - return 1; - } - } - - while (s->stream.avail_out != 0) { - - if (s->transparent) { - /* Copy first the lookahead bytes: */ - uInt n = s->stream.avail_in; - if (n > s->stream.avail_out) n = s->stream.avail_out; - if (n > 0) { - zmemcpy(s->stream.next_out, s->stream.next_in, n); - next_out += n; - s->stream.next_out = next_out; - s->stream.next_in += n; - s->stream.avail_out -= n; - s->stream.avail_in -= n; - } - if (s->stream.avail_out > 0) { - s->stream.avail_out -= - (uInt)fread(next_out, 1, s->stream.avail_out, s->file); - } - len -= s->stream.avail_out; - s->in += len; - s->out += len; - if (len == 0) s->z_eof = 1; - return (int)len; - } - if (s->stream.avail_in == 0 && !s->z_eof) { - - errno = 0; - s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file); - if (s->stream.avail_in == 0) { - s->z_eof = 1; - if (ferror(s->file)) { - s->z_err = Z_ERRNO; - break; - } - } - s->stream.next_in = s->inbuf; - } - s->in += s->stream.avail_in; - s->out += s->stream.avail_out; - s->z_err = inflate(&(s->stream), Z_NO_FLUSH); - s->in -= s->stream.avail_in; - s->out -= s->stream.avail_out; - - if (s->z_err == Z_STREAM_END) { - /* Check CRC and original size */ - s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); - start = s->stream.next_out; - - if (getLong(s) != s->crc) { - s->z_err = Z_DATA_ERROR; - } else { - (void)getLong(s); - /* The uncompressed length returned by above getlong() may be - * different from s->out in case of concatenated .gz files. - * Check for such files: - */ - check_header(s); - if (s->z_err == Z_OK) { - inflateReset(&(s->stream)); - s->crc = crc32(0L, Z_NULL, 0); - } - } - } - if (s->z_err != Z_OK || s->z_eof) break; - } - s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); - - if (len == s->stream.avail_out && - (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO)) - return -1; - return (int)(len - s->stream.avail_out); -} - - -/* =========================================================================== - Reads one byte from the compressed file. gzgetc returns this byte - or -1 in case of end of file or error. -*/ -int ZEXPORT gzgetc(file) - gzFile file; -{ - unsigned char c; - - return gzread(file, &c, 1) == 1 ? c : -1; -} - - -/* =========================================================================== - Push one byte back onto the stream. -*/ -int ZEXPORT gzungetc(c, file) - int c; - gzFile file; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF; - s->back = c; - s->out--; - s->last = (s->z_err == Z_STREAM_END); - if (s->last) s->z_err = Z_OK; - s->z_eof = 0; - return c; -} - - -/* =========================================================================== - Reads bytes from the compressed file until len-1 characters are - read, or a newline character is read and transferred to buf, or an - end-of-file condition is encountered. The string is then terminated - with a null character. - gzgets returns buf, or Z_NULL in case of error. - - The current implementation is not optimized at all. -*/ -char * ZEXPORT gzgets(file, buf, len) - gzFile file; - char *buf; - int len; -{ - char *b = buf; - if (buf == Z_NULL || len <= 0) return Z_NULL; - - while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ; - *buf = '\0'; - return b == buf && len > 0 ? Z_NULL : b; -} - - -#ifndef NO_GZCOMPRESS -/* =========================================================================== - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of bytes actually written (0 in case of error). -*/ -int ZEXPORT gzwrite (file, buf, len) - gzFile file; - voidpc buf; - unsigned len; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; - - s->stream.next_in = (Bytef*)buf; - s->stream.avail_in = len; - - while (s->stream.avail_in != 0) { - - if (s->stream.avail_out == 0) { - - s->stream.next_out = s->outbuf; - if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { - s->z_err = Z_ERRNO; - break; - } - s->stream.avail_out = Z_BUFSIZE; - } - s->in += s->stream.avail_in; - s->out += s->stream.avail_out; - s->z_err = deflate(&(s->stream), Z_NO_FLUSH); - s->in -= s->stream.avail_in; - s->out -= s->stream.avail_out; - if (s->z_err != Z_OK) break; - } - s->crc = crc32(s->crc, (const Bytef *)buf, len); - - return (int)(len - s->stream.avail_in); -} - - -/* =========================================================================== - Converts, formats, and writes the args to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written (0 in case of error). -*/ -#ifdef STDC -#include - -int Q_ZEXPORT gzprintf (gzFile file, const char *format, /* args */ ...) -{ - char buf[Z_PRINTF_BUFSIZE]; - va_list va; - int len; - - buf[sizeof(buf) - 1] = 0; - va_start(va, format); -#ifdef NO_vsnprintf -# ifdef HAS_vsprintf_void - (void)vsprintf(buf, format, va); - va_end(va); - for (len = 0; len < sizeof(buf); len++) - if (buf[len] == 0) break; -# else - len = vsprintf(buf, format, va); - va_end(va); -# endif -#else -# ifdef HAS_vsnprintf_void - (void)vsnprintf(buf, sizeof(buf), format, va); - va_end(va); - len = strlen(buf); -# else - len = vsnprintf(buf, sizeof(buf), format, va); - va_end(va); -# endif -#endif - if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0) - return 0; - return gzwrite(file, buf, (unsigned)len); -} -#else /* not ANSI C */ - -int Q_ZEXPORT gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) - gzFile file; - const char *format; - int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; -{ - char buf[Z_PRINTF_BUFSIZE]; - int len; - - buf[sizeof(buf) - 1] = 0; -#ifdef NO_snprintf -# ifdef HAS_sprintf_void - sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); - for (len = 0; len < sizeof(buf); len++) - if (buf[len] == 0) break; -# else - len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); -# endif -#else -# ifdef HAS_snprintf_void - snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); - len = strlen(buf); -# else - len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); -# endif -#endif - if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0) - return 0; - return gzwrite(file, buf, len); -} -#endif - -/* =========================================================================== - Writes c, converted to an unsigned char, into the compressed file. - gzputc returns the value that was written, or -1 in case of error. -*/ -int ZEXPORT gzputc(file, c) - gzFile file; - int c; -{ - unsigned char cc = (unsigned char) c; /* required for big endian systems */ - - return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1; -} - - -/* =========================================================================== - Writes the given null-terminated string to the compressed file, excluding - the terminating null character. - gzputs returns the number of characters written, or -1 in case of error. -*/ -int ZEXPORT gzputs(file, s) - gzFile file; - const char *s; -{ - return gzwrite(file, (char*)s, (unsigned)strlen(s)); -} - - -/* =========================================================================== - Flushes all pending output into the compressed file. The parameter - flush is as in the deflate() function. -*/ -local int do_flush (file, flush) - gzFile file; - int flush; -{ - uInt len; - int done = 0; - gz_stream *s = (gz_stream*)file; - - if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; - - s->stream.avail_in = 0; /* should be zero already anyway */ - - for (;;) { - len = Z_BUFSIZE - s->stream.avail_out; - - if (len != 0) { - if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) { - s->z_err = Z_ERRNO; - return Z_ERRNO; - } - s->stream.next_out = s->outbuf; - s->stream.avail_out = Z_BUFSIZE; - } - if (done) break; - s->out += s->stream.avail_out; - s->z_err = deflate(&(s->stream), flush); - s->out -= s->stream.avail_out; - - /* Ignore the second of two consecutive flushes: */ - if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK; - - /* deflate has finished flushing only when it hasn't used up - * all the available space in the output buffer: - */ - done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); - - if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; - } - return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; -} - -int ZEXPORT gzflush (file, flush) - gzFile file; - int flush; -{ - gz_stream *s = (gz_stream*)file; - int err = do_flush (file, flush); - - if (err) return err; - fflush(s->file); - return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; -} -#endif /* NO_GZCOMPRESS */ - -/* =========================================================================== - Sets the starting position for the next gzread or gzwrite on the given - compressed file. The offset represents a number of bytes in the - gzseek returns the resulting offset location as measured in bytes from - the beginning of the uncompressed stream, or -1 in case of error. - SEEK_END is not implemented, returns error. - In this version of the library, gzseek can be extremely slow. -*/ -z_off_t ZEXPORT gzseek (file, offset, whence) - gzFile file; - z_off_t offset; - int whence; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL || whence == SEEK_END || - s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) { - return -1L; - } - - if (s->mode == 'w') { -#ifdef NO_GZCOMPRESS - return -1L; -#else - if (whence == SEEK_SET) { - offset -= s->in; - } - if (offset < 0) return -1L; - - /* At this point, offset is the number of zero bytes to write. */ - if (s->inbuf == Z_NULL) { - s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */ - if (s->inbuf == Z_NULL) return -1L; - zmemzero(s->inbuf, Z_BUFSIZE); - } - while (offset > 0) { - uInt size = Z_BUFSIZE; - if (offset < Z_BUFSIZE) size = (uInt)offset; - - size = gzwrite(file, s->inbuf, size); - if (size == 0) return -1L; - - offset -= size; - } - return s->in; -#endif - } - /* Rest of function is for reading only */ - - /* compute absolute position */ - if (whence == SEEK_CUR) { - offset += s->out; - } - if (offset < 0) return -1L; - - if (s->transparent) { - /* map to fseek */ - s->back = EOF; - s->stream.avail_in = 0; - s->stream.next_in = s->inbuf; - if (fseek(s->file, offset, SEEK_SET) < 0) return -1L; - - s->in = s->out = offset; - return offset; - } - - /* For a negative seek, rewind and use positive seek */ - if (offset >= s->out) { - offset -= s->out; - } else if (gzrewind(file) < 0) { - return -1L; - } - /* offset is now the number of bytes to skip. */ - - if (offset != 0 && s->outbuf == Z_NULL) { - s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); - if (s->outbuf == Z_NULL) return -1L; - } - if (offset && s->back != EOF) { - s->back = EOF; - s->out++; - offset--; - if (s->last) s->z_err = Z_STREAM_END; - } - while (offset > 0) { - int size = Z_BUFSIZE; - if (offset < Z_BUFSIZE) size = (int)offset; - - size = gzread(file, s->outbuf, (uInt)size); - if (size <= 0) return -1L; - offset -= size; - } - return s->out; -} - -/* =========================================================================== - Rewinds input file. -*/ -int ZEXPORT gzrewind (file) - gzFile file; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL || s->mode != 'r') return -1; - - s->z_err = Z_OK; - s->z_eof = 0; - s->back = EOF; - s->stream.avail_in = 0; - s->stream.next_in = s->inbuf; - s->crc = crc32(0L, Z_NULL, 0); - if (!s->transparent) (void)inflateReset(&s->stream); - s->in = 0; - s->out = 0; - return fseek(s->file, s->start, SEEK_SET); -} - -/* =========================================================================== - Returns the starting position for the next gzread or gzwrite on the - given compressed file. This position represents a number of bytes in the - uncompressed data stream. -*/ -z_off_t ZEXPORT gztell (file) - gzFile file; -{ - return gzseek(file, 0L, SEEK_CUR); -} - -/* =========================================================================== - Returns 1 when EOF has previously been detected reading the given - input stream, otherwise zero. -*/ -int ZEXPORT gzeof (file) - gzFile file; -{ - gz_stream *s = (gz_stream*)file; - - /* With concatenated compressed files that can have embedded - * crc trailers, z_eof is no longer the only/best indicator of EOF - * on a gz_stream. Handle end-of-stream error explicitly here. - */ - if (s == NULL || s->mode != 'r') return 0; - if (s->z_eof) return 1; - return s->z_err == Z_STREAM_END; -} - -/* =========================================================================== - Returns 1 if reading and doing so transparently, otherwise zero. -*/ -int ZEXPORT gzdirect (file) - gzFile file; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL || s->mode != 'r') return 0; - return s->transparent; -} - -/* =========================================================================== - Outputs a long in LSB order to the given file -*/ -local void putLong (file, x) - FILE *file; - uLong x; -{ - int n; - for (n = 0; n < 4; n++) { - fputc((int)(x & 0xff), file); - x >>= 8; - } -} - -/* =========================================================================== - Reads a long in LSB order from the given gz_stream. Sets z_err in case - of error. -*/ -local uLong getLong (s) - gz_stream *s; -{ - uLong x = (uLong)get_byte(s); - int c; - - x += ((uLong)get_byte(s))<<8; - x += ((uLong)get_byte(s))<<16; - c = get_byte(s); - if (c == EOF) s->z_err = Z_DATA_ERROR; - x += ((uLong)c)<<24; - return x; -} - -/* =========================================================================== - Flushes all pending output if necessary, closes the compressed file - and deallocates all the (de)compression state. -*/ -int Q_ZEXPORT gzclose (file) - gzFile file; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL) return Z_STREAM_ERROR; - - if (s->mode == 'w') { -#ifdef NO_GZCOMPRESS - return Z_STREAM_ERROR; -#else - if (do_flush (file, Z_FINISH) != Z_OK) - return destroy((gz_stream*)file); - - putLong (s->file, s->crc); - putLong (s->file, (uLong)(s->in & 0xffffffff)); -#endif - } - return destroy((gz_stream*)file); -} - -#if defined(STDC) && !defined(_WIN32_WCE) -# define zstrerror(errnum) strerror(errnum) -#else -# define zstrerror(errnum) "" -#endif - -/* =========================================================================== - Returns the error message for the last error which occurred on the - given compressed file. errnum is set to zlib error number. If an - error occurred in the file system and not in the compression library, - errnum is set to Z_ERRNO and the application may consult errno - to get the exact error code. -*/ -const char * ZEXPORT gzerror (file, errnum) - gzFile file; - int *errnum; -{ - char *m; - gz_stream *s = (gz_stream*)file; - - if (s == NULL) { - *errnum = Z_STREAM_ERROR; - return (const char*)ERR_MSG(Z_STREAM_ERROR); - } - *errnum = s->z_err; - if (*errnum == Z_OK) return (const char*)""; - - m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg); - - if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err); - - TRYFREE(s->msg); - s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3); - if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR); - strcpy(s->msg, s->path); - strcat(s->msg, ": "); - strcat(s->msg, m); - return (const char*)s->msg; -} - -/* =========================================================================== - Clear the error and end-of-file flags, and do the same for the real file. -*/ -void ZEXPORT gzclearerr (file) - gzFile file; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL) return; - if (s->z_err != Z_STREAM_END) s->z_err = Z_OK; - s->z_eof = 0; - clearerr(s->file); -} diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/infback.c b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/infback.c deleted file mode 100644 index 455dbc9ee..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/infback.c +++ /dev/null @@ -1,623 +0,0 @@ -/* infback.c -- inflate using a call-back interface - * Copyright (C) 1995-2005 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - This code is largely copied from inflate.c. Normally either infback.o or - inflate.o would be linked into an application--not both. The interface - with inffast.c is retained so that optimized assembler-coded versions of - inflate_fast() can be used with either inflate.c or infback.c. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -/* function prototypes */ -local void fixedtables OF((struct inflate_state FAR *state)); - -/* - strm provides memory allocation functions in zalloc and zfree, or - Z_NULL to use the library memory allocation functions. - - windowBits is in the range 8..15, and window is a user-supplied - window and output buffer that is 2**windowBits bytes. - */ -int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) -z_streamp strm; -int windowBits; -unsigned char FAR *window; -const char *version; -int stream_size; -{ - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL || window == Z_NULL || - windowBits < 8 || windowBits > 15) - return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; - } - if (strm->zfree == (free_func)0) strm->zfree = zcfree; - state = (struct inflate_state FAR *)ZALLOC(strm, 1, - sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->dmax = 32768U; - state->wbits = windowBits; - state->wsize = 1U << windowBits; - state->window = window; - state->write = 0; - state->whave = 0; - return Z_OK; -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(state) -struct inflate_state FAR *state; -{ -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -/* Macros for inflateBack(): */ - -/* Load returned state from inflate_fast() */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Set state from registers for inflate_fast() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Assure that some input is available. If input is requested, but denied, - then return a Z_BUF_ERROR from inflateBack(). */ -#define PULL() \ - do { \ - if (have == 0) { \ - have = in(in_desc, &next); \ - if (have == 0) { \ - next = Z_NULL; \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflateBack() - with an error if there is no input available. */ -#define PULLBYTE() \ - do { \ - PULL(); \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflateBack() with - an error. */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* Assure that some output space is available, by writing out the window - if it's full. If the write fails, return from inflateBack() with a - Z_BUF_ERROR. */ -#define ROOM() \ - do { \ - if (left == 0) { \ - put = state->window; \ - left = state->wsize; \ - state->whave = left; \ - if (out(out_desc, put, left)) { \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* - strm provides the memory allocation functions and window buffer on input, - and provides information on the unused input on return. For Z_DATA_ERROR - returns, strm will also provide an error message. - - in() and out() are the call-back input and output functions. When - inflateBack() needs more input, it calls in(). When inflateBack() has - filled the window with output, or when it completes with data in the - window, it calls out() to write out the data. The application must not - change the provided input until in() is called again or inflateBack() - returns. The application must not change the window/output buffer until - inflateBack() returns. - - in() and out() are called with a descriptor parameter provided in the - inflateBack() call. This parameter can be a structure that provides the - information required to do the read or write, as well as accumulated - information on the input and output such as totals and check values. - - in() should return zero on failure. out() should return non-zero on - failure. If either in() or out() fails, than inflateBack() returns a - Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it - was in() or out() that caused in the error. Otherwise, inflateBack() - returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format - error, or Z_MEM_ERROR if it could not allocate memory for the state. - inflateBack() can also return Z_STREAM_ERROR if the input parameters - are not correct, i.e. strm is Z_NULL or the state was not initialized. - */ -int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) -z_streamp strm; -in_func in; -void FAR *in_desc; -out_func out; -void FAR *out_desc; -{ - struct inflate_state FAR *state; - unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code this; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - /* Check that the strm exists and that the state was initialized */ - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* Reset the state */ - strm->msg = Z_NULL; - state->mode = TYPE; - state->last = 0; - state->whave = 0; - next = strm->next_in; - have = next != Z_NULL ? strm->avail_in : 0; - hold = 0; - bits = 0; - put = state->window; - left = state->wsize; - - /* Inflate until end of block marked as last */ - for (;;) - switch (state->mode) { - case TYPE: - /* determine and dispatch block type */ - if (state->last) { - BYTEBITS(); - state->mode = DONE; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN; /* decode codes */ - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - - case STORED: - /* get and verify stored block length */ - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - - /* copy stored block from input to output */ - while (state->length != 0) { - copy = state->length; - PULL(); - ROOM(); - if (copy > have) copy = have; - if (copy > left) copy = left; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - - case TABLE: - /* get dynamic table entries descriptor */ - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - - /* get code length code lengths (not a typo) */ - state->have = 0; - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - - /* get length and distance code code lengths */ - state->have = 0; - while (state->have < state->nlen + state->ndist) { - for (;;) { - this = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(this.bits) <= bits) break; - PULLBYTE(); - } - if (this.val < 16) { - NEEDBITS(this.bits); - DROPBITS(this.bits); - state->lens[state->have++] = this.val; - } - else { - if (this.val == 16) { - NEEDBITS(this.bits + 2); - DROPBITS(this.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = (unsigned)(state->lens[state->have - 1]); - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (this.val == 17) { - NEEDBITS(this.bits + 3); - DROPBITS(this.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(this.bits + 7); - DROPBITS(this.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* build code tables */ - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (code const FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN; - - case LEN: - /* use inflate_fast() if we have enough input and output */ - if (have >= 6 && left >= 258) { - RESTORE(); - if (state->whave < state->wsize) - state->whave = state->wsize - left; - inflate_fast(strm, state->wsize); - LOAD(); - break; - } - - /* get a literal, length, or end-of-block code */ - for (;;) { - this = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(this.bits) <= bits) break; - PULLBYTE(); - } - if (this.op && (this.op & 0xf0) == 0) { - last = this; - for (;;) { - this = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + this.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(this.bits); - state->length = (unsigned)this.val; - - /* process literal */ - if (this.op == 0) { - Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", this.val)); - ROOM(); - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - } - - /* process end of block */ - if (this.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - - /* invalid code */ - if (this.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - - /* length code -- get extra bits, if any */ - state->extra = (unsigned)(this.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - - /* get distance code */ - for (;;) { - this = state->distcode[BITS(state->distbits)]; - if ((unsigned)(this.bits) <= bits) break; - PULLBYTE(); - } - if ((this.op & 0xf0) == 0) { - last = this; - for (;;) { - this = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + this.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(this.bits); - if (this.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)this.val; - - /* get distance extra bits, if any */ - state->extra = (unsigned)(this.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - } - if (state->offset > state->wsize - (state->whave < state->wsize ? - left : 0)) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - - /* copy match from window to output */ - do { - ROOM(); - copy = state->wsize - state->offset; - if (copy < left) { - from = put + copy; - copy = left - copy; - } - else { - from = put - state->offset; - copy = left; - } - if (copy > state->length) copy = state->length; - state->length -= copy; - left -= copy; - do { - *put++ = *from++; - } while (--copy); - } while (state->length != 0); - break; - - case DONE: - /* inflate stream terminated properly -- write leftover output */ - ret = Z_STREAM_END; - if (left < state->wsize) { - if (out(out_desc, state->window, state->wsize - left)) - ret = Z_BUF_ERROR; - } - goto inf_leave; - - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - - default: /* can't happen, but makes compilers happy */ - ret = Z_STREAM_ERROR; - goto inf_leave; - } - - /* Return unused input */ - inf_leave: - strm->next_in = next; - strm->avail_in = have; - return ret; -} - -int ZEXPORT inflateBackEnd(strm) -z_streamp strm; -{ - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/inffast.c b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/inffast.c deleted file mode 100644 index bbee92ed1..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/inffast.c +++ /dev/null @@ -1,318 +0,0 @@ -/* inffast.c -- fast decoding - * Copyright (C) 1995-2004 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifndef ASMINF - -/* Allow machine dependent optimization for post-increment or pre-increment. - Based on testing to date, - Pre-increment preferred for: - - PowerPC G3 (Adler) - - MIPS R5000 (Randers-Pehrson) - Post-increment preferred for: - - none - No measurable difference: - - Pentium III (Anderson) - - M68060 (Nikl) - */ -#ifdef POSTINC -# define OFF 0 -# define PUP(a) *(a)++ -#else -# define OFF 1 -# define PUP(a) *++(a) -#endif - -/* - Decode literal, length, and distance codes and write out the resulting - literal and match bytes until either not enough input or output is - available, an end-of-block is encountered, or a data error is encountered. - When large enough input and output buffers are supplied to inflate(), for - example, a 16K input buffer and a 64K output buffer, more than 95% of the - inflate execution time is spent in this routine. - - Entry assumptions: - - state->mode == LEN - strm->avail_in >= 6 - strm->avail_out >= 258 - start >= strm->avail_out - state->bits < 8 - - On return, state->mode is one of: - - LEN -- ran out of enough output space or enough available input - TYPE -- reached end of block code, inflate() to interpret next block - BAD -- error in block data - - Notes: - - - The maximum input bits used by a length/distance pair is 15 bits for the - length code, 5 bits for the length extra, 15 bits for the distance code, - and 13 bits for the distance extra. This totals 48 bits, or six bytes. - Therefore if strm->avail_in >= 6, then there is enough input to avoid - checking for available input while decoding. - - - The maximum bytes that a single length/distance pair can output is 258 - bytes, which is the maximum length that can be coded. inflate_fast() - requires strm->avail_out >= 258 for each loop to avoid checking for - output space. - */ -void inflate_fast(strm, start) -z_streamp strm; -unsigned start; /* inflate()'s starting value for strm->avail_out */ -{ - struct inflate_state FAR *state; - unsigned char FAR *in; /* local strm->next_in */ - unsigned char FAR *last; /* while in < last, enough input available */ - unsigned char FAR *out; /* local strm->next_out */ - unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ - unsigned char FAR *end; /* while out < end, enough space available */ -#ifdef INFLATE_STRICT - unsigned dmax; /* maximum distance from zlib header */ -#endif - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned write; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ - unsigned long hold; /* local strm->hold */ - unsigned bits; /* local strm->bits */ - code const FAR *lcode; /* local strm->lencode */ - code const FAR *dcode; /* local strm->distcode */ - unsigned lmask; /* mask for first level of length codes */ - unsigned dmask; /* mask for first level of distance codes */ - code this; /* retrieved table entry */ - unsigned op; /* code bits, operation, extra bits, or */ - /* window position, window bytes to copy */ - unsigned len; /* match length, unused bytes */ - unsigned dist; /* match distance */ - unsigned char FAR *from; /* where to copy match from */ - - /* copy state to local variables */ - state = (struct inflate_state FAR *)strm->state; - in = strm->next_in - OFF; - last = in + (strm->avail_in - 5); - out = strm->next_out - OFF; - beg = out - (start - strm->avail_out); - end = out + (strm->avail_out - 257); -#ifdef INFLATE_STRICT - dmax = state->dmax; -#endif - wsize = state->wsize; - whave = state->whave; - write = state->write; - window = state->window; - hold = state->hold; - bits = state->bits; - lcode = state->lencode; - dcode = state->distcode; - lmask = (1U << state->lenbits) - 1; - dmask = (1U << state->distbits) - 1; - - /* decode literals and length/distances until end-of-block or not enough - input data or output space */ - do { - if (bits < 15) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - this = lcode[hold & lmask]; - dolen: - op = (unsigned)(this.bits); - hold >>= op; - bits -= op; - op = (unsigned)(this.op); - if (op == 0) { /* literal */ - Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", this.val)); - PUP(out) = (unsigned char)(this.val); - } - else if (op & 16) { /* length base */ - len = (unsigned)(this.val); - op &= 15; /* number of extra bits */ - if (op) { - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - len += (unsigned)hold & ((1U << op) - 1); - hold >>= op; - bits -= op; - } - Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < 15) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - this = dcode[hold & dmask]; - dodist: - op = (unsigned)(this.bits); - hold >>= op; - bits -= op; - op = (unsigned)(this.op); - if (op & 16) { /* distance base */ - dist = (unsigned)(this.val); - op &= 15; /* number of extra bits */ - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - } - dist += (unsigned)hold & ((1U << op) - 1); -#ifdef INFLATE_STRICT - if (dist > dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - hold >>= op; - bits -= op; - Tracevv((stderr, "inflate: distance %u\n", dist)); - op = (unsigned)(out - beg); /* max distance in output */ - if (dist > op) { /* see if copy from window */ - op = dist - op; /* distance back in window */ - if (op > whave) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } - from = window - OFF; - if (write == 0) { /* very common case */ - from += wsize - op; - if (op < len) { /* some from window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - else if (write < op) { /* wrap around window */ - from += wsize + write - op; - op -= write; - if (op < len) { /* some from end of window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = window - OFF; - if (write < len) { /* some from start of window */ - op = write; - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - } - else { /* contiguous in window */ - from += write - op; - if (op < len) { /* some from window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - while (len > 2) { - PUP(out) = PUP(from); - PUP(out) = PUP(from); - PUP(out) = PUP(from); - len -= 3; - } - if (len) { - PUP(out) = PUP(from); - if (len > 1) - PUP(out) = PUP(from); - } - } - else { - from = out - dist; /* copy direct from output */ - do { /* minimum length is three */ - PUP(out) = PUP(from); - PUP(out) = PUP(from); - PUP(out) = PUP(from); - len -= 3; - } while (len > 2); - if (len) { - PUP(out) = PUP(from); - if (len > 1) - PUP(out) = PUP(from); - } - } - } - else if ((op & 64) == 0) { /* 2nd level distance code */ - this = dcode[this.val + (hold & ((1U << op) - 1))]; - goto dodist; - } - else { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - } - else if ((op & 64) == 0) { /* 2nd level length code */ - this = lcode[this.val + (hold & ((1U << op) - 1))]; - goto dolen; - } - else if (op & 32) { /* end-of-block */ - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - else { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - } while (in < last && out < end); - - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ - len = bits >> 3; - in -= len; - bits -= len << 3; - hold &= (1U << bits) - 1; - - /* update state and return */ - strm->next_in = in + OFF; - strm->next_out = out + OFF; - strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); - strm->avail_out = (unsigned)(out < end ? - 257 + (end - out) : 257 - (out - end)); - state->hold = hold; - state->bits = bits; - return; -} - -/* - inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): - - Using bit fields for code structure - - Different op definition to avoid & for extra bits (do & for table bits) - - Three separate decoding do-loops for direct, window, and write == 0 - - Special case for distance > 1 copies to do overlapped load and store copy - - Explicit branch predictions (based on measured branch probabilities) - - Deferring match copy and interspersed it with decoding subsequent codes - - Swapping literal/length else - - Swapping window/direct else - - Larger unrolled copy loops (three is about right) - - Moving len -= 3 statement into middle of loop - */ - -#endif /* !ASMINF */ diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/inffast.h b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/inffast.h deleted file mode 100644 index 1e88d2d97..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/inffast.h +++ /dev/null @@ -1,11 +0,0 @@ -/* inffast.h -- header to use inffast.c - * Copyright (C) 1995-2003 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -void inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/inffixed.h b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/inffixed.h deleted file mode 100644 index 75ed4b597..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/inffixed.h +++ /dev/null @@ -1,94 +0,0 @@ - /* inffixed.h -- table for decoding fixed codes - * Generated automatically by makefixed(). - */ - - /* WARNING: this file should *not* be used by applications. It - is part of the implementation of the compression library and - is subject to change. Applications should only use zlib.h. - */ - - static const code lenfix[512] = { - {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, - {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, - {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, - {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, - {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, - {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, - {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, - {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, - {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, - {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, - {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, - {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, - {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, - {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, - {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, - {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, - {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, - {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, - {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, - {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, - {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, - {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, - {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, - {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, - {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, - {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, - {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, - {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, - {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, - {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, - {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, - {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, - {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, - {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, - {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, - {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, - {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, - {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, - {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, - {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, - {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, - {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, - {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, - {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, - {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, - {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, - {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, - {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, - {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, - {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, - {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, - {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, - {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, - {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, - {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, - {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, - {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, - {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, - {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, - {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, - {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, - {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, - {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, - {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, - {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, - {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, - {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, - {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, - {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, - {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, - {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, - {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, - {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, - {0,9,255} - }; - - static const code distfix[32] = { - {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, - {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, - {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, - {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, - {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, - {22,5,193},{64,5,0} - }; diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/inflate.c b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/inflate.c deleted file mode 100644 index 792fdee8e..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/inflate.c +++ /dev/null @@ -1,1368 +0,0 @@ -/* inflate.c -- zlib decompression - * Copyright (C) 1995-2005 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * Change history: - * - * 1.2.beta0 24 Nov 2002 - * - First version -- complete rewrite of inflate to simplify code, avoid - * creation of window when not needed, minimize use of window when it is - * needed, make inffast.c even faster, implement gzip decoding, and to - * improve code readability and style over the previous zlib inflate code - * - * 1.2.beta1 25 Nov 2002 - * - Use pointers for available input and output checking in inffast.c - * - Remove input and output counters in inffast.c - * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 - * - Remove unnecessary second byte pull from length extra in inffast.c - * - Unroll direct copy to three copies per loop in inffast.c - * - * 1.2.beta2 4 Dec 2002 - * - Change external routine names to reduce potential conflicts - * - Correct filename to inffixed.h for fixed tables in inflate.c - * - Make hbuf[] unsigned char to match parameter type in inflate.c - * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) - * to avoid negation problem on Alphas (64 bit) in inflate.c - * - * 1.2.beta3 22 Dec 2002 - * - Add comments on state->bits assertion in inffast.c - * - Add comments on op field in inftrees.h - * - Fix bug in reuse of allocated window after inflateReset() - * - Remove bit fields--back to byte structure for speed - * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths - * - Change post-increments to pre-increments in inflate_fast(), PPC biased? - * - Add compile time option, POSTINC, to use post-increments instead (Intel?) - * - Make MATCH copy in inflate() much faster for when inflate_fast() not used - * - Use local copies of stream next and avail values, as well as local bit - * buffer and bit count in inflate()--for speed when inflate_fast() not used - * - * 1.2.beta4 1 Jan 2003 - * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings - * - Move a comment on output buffer sizes from inffast.c to inflate.c - * - Add comments in inffast.c to introduce the inflate_fast() routine - * - Rearrange window copies in inflate_fast() for speed and simplification - * - Unroll last copy for window match in inflate_fast() - * - Use local copies of window variables in inflate_fast() for speed - * - Pull out common write == 0 case for speed in inflate_fast() - * - Make op and len in inflate_fast() unsigned for consistency - * - Add FAR to lcode and dcode declarations in inflate_fast() - * - Simplified bad distance check in inflate_fast() - * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new - * source file infback.c to provide a call-back interface to inflate for - * programs like gzip and unzip -- uses window as output buffer to avoid - * window copying - * - * 1.2.beta5 1 Jan 2003 - * - Improved inflateBack() interface to allow the caller to provide initial - * input in strm. - * - Fixed stored blocks bug in inflateBack() - * - * 1.2.beta6 4 Jan 2003 - * - Added comments in inffast.c on effectiveness of POSTINC - * - Typecasting all around to reduce compiler warnings - * - Changed loops from while (1) or do {} while (1) to for (;;), again to - * make compilers happy - * - Changed type of window in inflateBackInit() to unsigned char * - * - * 1.2.beta7 27 Jan 2003 - * - Changed many types to unsigned or unsigned short to avoid warnings - * - Added inflateCopy() function - * - * 1.2.0 9 Mar 2003 - * - Changed inflateBack() interface to provide separate opaque descriptors - * for the in() and out() functions - * - Changed inflateBack() argument and in_func typedef to swap the length - * and buffer address return values for the input function - * - Check next_in and next_out for Z_NULL on entry to inflate() - * - * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifdef MAKEFIXED -# ifndef BUILDFIXED -# define BUILDFIXED -# endif -#endif - -/* function prototypes */ -local void fixedtables OF((struct inflate_state FAR *state)); -local int updatewindow OF((z_streamp strm, unsigned out)); -#ifdef BUILDFIXED - void makefixed OF((void)); -#endif -local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, - unsigned len)); - -int ZEXPORT inflateReset(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - strm->total_in = strm->total_out = state->total = 0; - strm->msg = Z_NULL; - strm->adler = 1; /* to support ill-conceived Java test suite */ - state->mode = HEAD; - state->last = 0; - state->havedict = 0; - state->dmax = 32768U; - state->head = Z_NULL; - state->wsize = 0; - state->whave = 0; - state->write = 0; - state->hold = 0; - state->bits = 0; - state->lencode = state->distcode = state->next = state->codes; - Tracev((stderr, "inflate: reset\n")); - return Z_OK; -} - -int ZEXPORT inflatePrime(strm, bits, value) -z_streamp strm; -int bits; -int value; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; - value &= (1L << bits) - 1; - state->hold += value << state->bits; - state->bits += bits; - return Z_OK; -} - -int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) -z_streamp strm; -int windowBits; -const char *version; -int stream_size; -{ - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL) return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; - } - if (strm->zfree == (free_func)0) strm->zfree = zcfree; - state = (struct inflate_state FAR *) - ZALLOC(strm, 1, sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - if (windowBits < 0) { - state->wrap = 0; - windowBits = -windowBits; - } - else { - state->wrap = (windowBits >> 4) + 1; -#ifdef GUNZIP - if (windowBits < 48) windowBits &= 15; -#endif - } - if (windowBits < 8 || windowBits > 15) { - ZFREE(strm, state); - strm->state = Z_NULL; - return Z_STREAM_ERROR; - } - state->wbits = (unsigned)windowBits; - state->window = Z_NULL; - return inflateReset(strm); -} - -int ZEXPORT inflateInit_(strm, version, stream_size) -z_streamp strm; -const char *version; -int stream_size; -{ - return inflateInit2_(strm, DEF_WBITS, version, stream_size); -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(state) -struct inflate_state FAR *state; -{ -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -#ifdef MAKEFIXED -#include - -/* - Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also - defines BUILDFIXED, so the tables are built on the fly. makefixed() writes - those tables to stdout, which would be piped to inffixed.h. A small program - can simply call makefixed to do this: - - void makefixed(void); - - int main(void) - { - makefixed(); - return 0; - } - - Then that can be linked with zlib built with MAKEFIXED defined and run: - - a.out > inffixed.h - */ -void makefixed() -{ - unsigned low, size; - struct inflate_state state; - - fixedtables(&state); - puts(" /* inffixed.h -- table for decoding fixed codes"); - puts(" * Generated automatically by makefixed()."); - puts(" */"); - puts(""); - puts(" /* WARNING: this file should *not* be used by applications."); - puts(" It is part of the implementation of this library and is"); - puts(" subject to change. Applications should only use zlib.h."); - puts(" */"); - puts(""); - size = 1U << 9; - printf(" static const code lenfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 7) == 0) printf("\n "); - printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits, - state.lencode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); - size = 1U << 5; - printf("\n static const code distfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 6) == 0) printf("\n "); - printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, - state.distcode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); -} -#endif /* MAKEFIXED */ - -/* - Update the window with the last wsize (normally 32K) bytes written before - returning. If window does not exist yet, create it. This is only called - when a window is already in use, or when output has been written during this - inflate call, but the end of the deflate stream has not been reached yet. - It is also called to create a window for dictionary data when a dictionary - is loaded. - - Providing output buffers larger than 32K to inflate() should provide a speed - advantage, since only the last 32K of output is copied to the sliding window - upon return from inflate(), and since all distances after the first 32K of - output will fall in the output data, making match copies simpler and faster. - The advantage may be dependent on the size of the processor's data caches. - */ -local int updatewindow(strm, out) -z_streamp strm; -unsigned out; -{ - struct inflate_state FAR *state; - unsigned copy, dist; - - state = (struct inflate_state FAR *)strm->state; - - /* if it hasn't been done already, allocate space for the window */ - if (state->window == Z_NULL) { - state->window = (unsigned char FAR *) - ZALLOC(strm, 1U << state->wbits, - sizeof(unsigned char)); - if (state->window == Z_NULL) return 1; - } - - /* if window not in use yet, initialize */ - if (state->wsize == 0) { - state->wsize = 1U << state->wbits; - state->write = 0; - state->whave = 0; - } - - /* copy state->wsize or less output bytes into the circular window */ - copy = out - strm->avail_out; - if (copy >= state->wsize) { - zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); - state->write = 0; - state->whave = state->wsize; - } - else { - dist = state->wsize - state->write; - if (dist > copy) dist = copy; - zmemcpy(state->window + state->write, strm->next_out - copy, dist); - copy -= dist; - if (copy) { - zmemcpy(state->window, strm->next_out - copy, copy); - state->write = copy; - state->whave = state->wsize; - } - else { - state->write += dist; - if (state->write == state->wsize) state->write = 0; - if (state->whave < state->wsize) state->whave += dist; - } - } - return 0; -} - -/* Macros for inflate(): */ - -/* check function to use adler32() for zlib or crc32() for gzip */ -#ifdef GUNZIP -# define UPDATE(check, buf, len) \ - (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) -#else -# define UPDATE(check, buf, len) adler32(check, buf, len) -#endif - -/* check macros for header crc */ -#ifdef GUNZIP -# define CRC2(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - check = crc32(check, hbuf, 2); \ - } while (0) - -# define CRC4(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - hbuf[2] = (unsigned char)((word) >> 16); \ - hbuf[3] = (unsigned char)((word) >> 24); \ - check = crc32(check, hbuf, 4); \ - } while (0) -#endif - -/* Load registers with state in inflate() for speed */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Restore state from registers in inflate() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflate() - if there is no input available. */ -#define PULLBYTE() \ - do { \ - if (have == 0) goto inf_leave; \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflate(). */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* Reverse the bytes in a 32-bit value */ -#define REVERSE(q) \ - ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ - (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) - -/* - inflate() uses a state machine to process as much input data and generate as - much output data as possible before returning. The state machine is - structured roughly as follows: - - for (;;) switch (state) { - ... - case STATEn: - if (not enough input data or output space to make progress) - return; - ... make progress ... - state = STATEm; - break; - ... - } - - so when inflate() is called again, the same case is attempted again, and - if the appropriate resources are provided, the machine proceeds to the - next state. The NEEDBITS() macro is usually the way the state evaluates - whether it can proceed or should return. NEEDBITS() does the return if - the requested bits are not available. The typical use of the BITS macros - is: - - NEEDBITS(n); - ... do something with BITS(n) ... - DROPBITS(n); - - where NEEDBITS(n) either returns from inflate() if there isn't enough - input left to load n bits into the accumulator, or it continues. BITS(n) - gives the low n bits in the accumulator. When done, DROPBITS(n) drops - the low n bits off the accumulator. INITBITS() clears the accumulator - and sets the number of available bits to zero. BYTEBITS() discards just - enough bits to put the accumulator on a byte boundary. After BYTEBITS() - and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. - - NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return - if there is no input available. The decoding of variable length codes uses - PULLBYTE() directly in order to pull just enough bytes to decode the next - code, and no more. - - Some states loop until they get enough input, making sure that enough - state information is maintained to continue the loop where it left off - if NEEDBITS() returns in the loop. For example, want, need, and keep - would all have to actually be part of the saved state in case NEEDBITS() - returns: - - case STATEw: - while (want < need) { - NEEDBITS(n); - keep[want++] = BITS(n); - DROPBITS(n); - } - state = STATEx; - case STATEx: - - As shown above, if the next state is also the next case, then the break - is omitted. - - A state may also return if there is not enough output space available to - complete that state. Those states are copying stored data, writing a - literal byte, and copying a matching string. - - When returning, a "goto inf_leave" is used to update the total counters, - update the check value, and determine whether any progress has been made - during that inflate() call in order to return the proper return code. - Progress is defined as a change in either strm->avail_in or strm->avail_out. - When there is a window, goto inf_leave will update the window with the last - output written. If a goto inf_leave occurs in the middle of decompression - and there is no window currently, goto inf_leave will create one and copy - output to the window for the next call of inflate(). - - In this implementation, the flush parameter of inflate() only affects the - return code (per zlib.h). inflate() always writes as much as possible to - strm->next_out, given the space available and the provided input--the effect - documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers - the allocation of and copying into a sliding window until necessary, which - provides the effect documented in zlib.h for Z_FINISH when the entire input - stream available. So the only thing the flush parameter actually does is: - when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it - will return Z_BUF_ERROR if it has not reached the end of the stream. - */ - -int ZEXPORT inflate(strm, flush) -z_streamp strm; -int flush; -{ - struct inflate_state FAR *state; - unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned in, out; /* save starting available input and output */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code this; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ -#ifdef GUNZIP - unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ -#endif - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0)) - return Z_STREAM_ERROR; - - state = (struct inflate_state FAR *)strm->state; - if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ - LOAD(); - in = have; - out = left; - ret = Z_OK; - for (;;) - switch (state->mode) { - case HEAD: - if (state->wrap == 0) { - state->mode = TYPEDO; - break; - } - NEEDBITS(16); -#ifdef GUNZIP - if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ - state->check = crc32(0L, Z_NULL, 0); - CRC2(state->check, hold); - INITBITS(); - state->mode = FLAGS; - break; - } - state->flags = 0; /* expect zlib header */ - if (state->head != Z_NULL) - state->head->done = -1; - if (!(state->wrap & 1) || /* check if zlib header allowed */ -#else - if ( -#endif - ((BITS(8) << 8) + (hold >> 8)) % 31) { - strm->msg = (char *)"incorrect header check"; - state->mode = BAD; - break; - } - if (BITS(4) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - DROPBITS(4); - len = BITS(4) + 8; - if (len > state->wbits) { - strm->msg = (char *)"invalid window size"; - state->mode = BAD; - break; - } - state->dmax = 1U << len; - Tracev((stderr, "inflate: zlib header ok\n")); - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = hold & 0x200 ? DICTID : TYPE; - INITBITS(); - break; -#ifdef GUNZIP - case FLAGS: - NEEDBITS(16); - state->flags = (int)(hold); - if ((state->flags & 0xff) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - if (state->flags & 0xe000) { - strm->msg = (char *)"unknown header flags set"; - state->mode = BAD; - break; - } - if (state->head != Z_NULL) - state->head->text = (int)((hold >> 8) & 1); - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - state->mode = TIME; - case TIME: - NEEDBITS(32); - if (state->head != Z_NULL) - state->head->time = hold; - if (state->flags & 0x0200) CRC4(state->check, hold); - INITBITS(); - state->mode = OS; - case OS: - NEEDBITS(16); - if (state->head != Z_NULL) { - state->head->xflags = (int)(hold & 0xff); - state->head->os = (int)(hold >> 8); - } - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - state->mode = EXLEN; - case EXLEN: - if (state->flags & 0x0400) { - NEEDBITS(16); - state->length = (unsigned)(hold); - if (state->head != Z_NULL) - state->head->extra_len = (unsigned)hold; - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - } - else if (state->head != Z_NULL) - state->head->extra = Z_NULL; - state->mode = EXTRA; - case EXTRA: - if (state->flags & 0x0400) { - copy = state->length; - if (copy > have) copy = have; - if (copy) { - if (state->head != Z_NULL && - state->head->extra != Z_NULL) { - len = state->head->extra_len - state->length; - zmemcpy(state->head->extra + len, next, - len + copy > state->head->extra_max ? - state->head->extra_max - len : copy); - } - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - state->length -= copy; - } - if (state->length) goto inf_leave; - } - state->length = 0; - state->mode = NAME; - case NAME: - if (state->flags & 0x0800) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->name != Z_NULL && - state->length < state->head->name_max) - state->head->name[state->length++] = len; - } while (len && copy < have); - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->name = Z_NULL; - state->length = 0; - state->mode = COMMENT; - case COMMENT: - if (state->flags & 0x1000) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->comment != Z_NULL && - state->length < state->head->comm_max) - state->head->comment[state->length++] = len; - } while (len && copy < have); - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->comment = Z_NULL; - state->mode = HCRC; - case HCRC: - if (state->flags & 0x0200) { - NEEDBITS(16); - if (hold != (state->check & 0xffff)) { - strm->msg = (char *)"header crc mismatch"; - state->mode = BAD; - break; - } - INITBITS(); - } - if (state->head != Z_NULL) { - state->head->hcrc = (int)((state->flags >> 9) & 1); - state->head->done = 1; - } - strm->adler = state->check = crc32(0L, Z_NULL, 0); - state->mode = TYPE; - break; -#endif - case DICTID: - NEEDBITS(32); - strm->adler = state->check = REVERSE(hold); - INITBITS(); - state->mode = DICT; - case DICT: - if (state->havedict == 0) { - RESTORE(); - return Z_NEED_DICT; - } - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = TYPE; - case TYPE: - if (flush == Z_BLOCK) goto inf_leave; - case TYPEDO: - if (state->last) { - BYTEBITS(); - state->mode = CHECK; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN; /* decode codes */ - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - case STORED: - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - state->mode = COPY; - case COPY: - copy = state->length; - if (copy) { - if (copy > have) copy = have; - if (copy > left) copy = left; - if (copy == 0) goto inf_leave; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - break; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - case TABLE: - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - state->have = 0; - state->mode = LENLENS; - case LENLENS: - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - state->have = 0; - state->mode = CODELENS; - case CODELENS: - while (state->have < state->nlen + state->ndist) { - for (;;) { - this = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(this.bits) <= bits) break; - PULLBYTE(); - } - if (this.val < 16) { - NEEDBITS(this.bits); - DROPBITS(this.bits); - state->lens[state->have++] = this.val; - } - else { - if (this.val == 16) { - NEEDBITS(this.bits + 2); - DROPBITS(this.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = state->lens[state->have - 1]; - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (this.val == 17) { - NEEDBITS(this.bits + 3); - DROPBITS(this.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(this.bits + 7); - DROPBITS(this.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* build code tables */ - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (code const FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN; - case LEN: - if (have >= 6 && left >= 258) { - RESTORE(); - inflate_fast(strm, out); - LOAD(); - break; - } - for (;;) { - this = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(this.bits) <= bits) break; - PULLBYTE(); - } - if (this.op && (this.op & 0xf0) == 0) { - last = this; - for (;;) { - this = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + this.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(this.bits); - state->length = (unsigned)this.val; - if ((int)(this.op) == 0) { - Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", this.val)); - state->mode = LIT; - break; - } - if (this.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - if (this.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - state->extra = (unsigned)(this.op) & 15; - state->mode = LENEXT; - case LENEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - state->mode = DIST; - case DIST: - for (;;) { - this = state->distcode[BITS(state->distbits)]; - if ((unsigned)(this.bits) <= bits) break; - PULLBYTE(); - } - if ((this.op & 0xf0) == 0) { - last = this; - for (;;) { - this = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + this.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(this.bits); - if (this.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)this.val; - state->extra = (unsigned)(this.op) & 15; - state->mode = DISTEXT; - case DISTEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - } -#ifdef INFLATE_STRICT - if (state->offset > state->dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - if (state->offset > state->whave + out - left) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - state->mode = MATCH; - case MATCH: - if (left == 0) goto inf_leave; - copy = out - left; - if (state->offset > copy) { /* copy from window */ - copy = state->offset - copy; - if (copy > state->write) { - copy -= state->write; - from = state->window + (state->wsize - copy); - } - else - from = state->window + (state->write - copy); - if (copy > state->length) copy = state->length; - } - else { /* copy from output */ - from = put - state->offset; - copy = state->length; - } - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = *from++; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; - case LIT: - if (left == 0) goto inf_leave; - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - case CHECK: - if (state->wrap) { - NEEDBITS(32); - out -= left; - strm->total_out += out; - state->total += out; - if (out) - strm->adler = state->check = - UPDATE(state->check, put - out, out); - out = left; - if (( -#ifdef GUNZIP - state->flags ? hold : -#endif - REVERSE(hold)) != state->check) { - strm->msg = (char *)"incorrect data check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: check matches trailer\n")); - } -#ifdef GUNZIP - state->mode = LENGTH; - case LENGTH: - if (state->wrap && state->flags) { - NEEDBITS(32); - if (hold != (state->total & 0xffffffffUL)) { - strm->msg = (char *)"incorrect length check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: length matches trailer\n")); - } -#endif - state->mode = DONE; - case DONE: - ret = Z_STREAM_END; - goto inf_leave; - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - case MEM: - return Z_MEM_ERROR; - case SYNC: - default: - return Z_STREAM_ERROR; - } - - /* - Return from inflate(), updating the total counts and the check value. - If there was no progress during the inflate() call, return a buffer - error. Call updatewindow() to create and/or update the window state. - Note: a memory error from inflate() is non-recoverable. - */ - inf_leave: - RESTORE(); - if (state->wsize || (state->mode < CHECK && out != strm->avail_out)) - if (updatewindow(strm, out)) { - state->mode = MEM; - return Z_MEM_ERROR; - } - in -= strm->avail_in; - out -= strm->avail_out; - strm->total_in += in; - strm->total_out += out; - state->total += out; - if (state->wrap && out) - strm->adler = state->check = - UPDATE(state->check, strm->next_out - out, out); - strm->data_type = state->bits + (state->last ? 64 : 0) + - (state->mode == TYPE ? 128 : 0); - if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) - ret = Z_BUF_ERROR; - return ret; -} - -int ZEXPORT inflateEnd(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->window != Z_NULL) ZFREE(strm, state->window); - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} - -int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) -z_streamp strm; -const Bytef *dictionary; -uInt dictLength; -{ - struct inflate_state FAR *state; - unsigned long id; - - /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->wrap != 0 && state->mode != DICT) - return Z_STREAM_ERROR; - - /* check for correct dictionary id */ - if (state->mode == DICT) { - id = adler32(0L, Z_NULL, 0); - id = adler32(id, dictionary, dictLength); - if (id != state->check) - return Z_DATA_ERROR; - } - - /* copy dictionary to window */ - if (updatewindow(strm, strm->avail_out)) { - state->mode = MEM; - return Z_MEM_ERROR; - } - if (dictLength > state->wsize) { - zmemcpy(state->window, dictionary + dictLength - state->wsize, - state->wsize); - state->whave = state->wsize; - } - else { - zmemcpy(state->window + state->wsize - dictLength, dictionary, - dictLength); - state->whave = dictLength; - } - state->havedict = 1; - Tracev((stderr, "inflate: dictionary set\n")); - return Z_OK; -} - -int ZEXPORT inflateGetHeader(strm, head) -z_streamp strm; -gz_headerp head; -{ - struct inflate_state FAR *state; - - /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; - - /* save header structure */ - state->head = head; - head->done = 0; - return Z_OK; -} - -/* - Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found - or when out of input. When called, *have is the number of pattern bytes - found in order so far, in 0..3. On return *have is updated to the new - state. If on return *have equals four, then the pattern was found and the - return value is how many bytes were read including the last byte of the - pattern. If *have is less than four, then the pattern has not been found - yet and the return value is len. In the latter case, syncsearch() can be - called again with more data and the *have state. *have is initialized to - zero for the first call. - */ -local unsigned syncsearch(have, buf, len) -unsigned FAR *have; -unsigned char FAR *buf; -unsigned len; -{ - unsigned got; - unsigned next; - - got = *have; - next = 0; - while (next < len && got < 4) { - if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) - got++; - else if (buf[next]) - got = 0; - else - got = 4 - got; - next++; - } - *have = got; - return next; -} - -int ZEXPORT inflateSync(strm) -z_streamp strm; -{ - unsigned len; /* number of bytes to look at or looked at */ - unsigned long in, out; /* temporary to save total_in and total_out */ - unsigned char buf[4]; /* to restore bit buffer to byte string */ - struct inflate_state FAR *state; - - /* check parameters */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; - - /* if first time, start search in bit buffer */ - if (state->mode != SYNC) { - state->mode = SYNC; - state->hold <<= state->bits & 7; - state->bits -= state->bits & 7; - len = 0; - while (state->bits >= 8) { - buf[len++] = (unsigned char)(state->hold); - state->hold >>= 8; - state->bits -= 8; - } - state->have = 0; - syncsearch(&(state->have), buf, len); - } - - /* search available input */ - len = syncsearch(&(state->have), strm->next_in, strm->avail_in); - strm->avail_in -= len; - strm->next_in += len; - strm->total_in += len; - - /* return no joy or set up to restart inflate() on a new block */ - if (state->have != 4) return Z_DATA_ERROR; - in = strm->total_in; out = strm->total_out; - inflateReset(strm); - strm->total_in = in; strm->total_out = out; - state->mode = TYPE; - return Z_OK; -} - -/* - Returns true if inflate is currently at the end of a block generated by - Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP - implementation to provide an additional safety check. PPP uses - Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored - block. When decompressing, PPP checks that at the end of input packet, - inflate is waiting for these length bytes. - */ -int ZEXPORT inflateSyncPoint(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - return state->mode == STORED && state->bits == 0; -} - -int ZEXPORT inflateCopy(dest, source) -z_streamp dest; -z_streamp source; -{ - struct inflate_state FAR *state; - struct inflate_state FAR *copy; - unsigned char FAR *window; - unsigned wsize; - - /* check input */ - if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || - source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)source->state; - - /* allocate space */ - copy = (struct inflate_state FAR *) - ZALLOC(source, 1, sizeof(struct inflate_state)); - if (copy == Z_NULL) return Z_MEM_ERROR; - window = Z_NULL; - if (state->window != Z_NULL) { - window = (unsigned char FAR *) - ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); - if (window == Z_NULL) { - ZFREE(source, copy); - return Z_MEM_ERROR; - } - } - - /* copy state */ - zmemcpy(dest, source, sizeof(z_stream)); - zmemcpy(copy, state, sizeof(struct inflate_state)); - if (state->lencode >= state->codes && - state->lencode <= state->codes + ENOUGH - 1) { - copy->lencode = copy->codes + (state->lencode - state->codes); - copy->distcode = copy->codes + (state->distcode - state->codes); - } - copy->next = copy->codes + (state->next - state->codes); - if (window != Z_NULL) { - wsize = 1U << state->wbits; - zmemcpy(window, state->window, wsize); - } - copy->window = window; - dest->state = (struct internal_state FAR *)copy; - return Z_OK; -} diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/inflate.h b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/inflate.h deleted file mode 100644 index 07bd3e78a..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/inflate.h +++ /dev/null @@ -1,115 +0,0 @@ -/* inflate.h -- internal inflate state definition - * Copyright (C) 1995-2004 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer decoding by inflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip decoding - should be left enabled. */ -#ifndef NO_GZIP -# define GUNZIP -#endif - -/* Possible inflate modes between inflate() calls */ -typedef enum { - HEAD, /* i: waiting for magic header */ - FLAGS, /* i: waiting for method and flags (gzip) */ - TIME, /* i: waiting for modification time (gzip) */ - OS, /* i: waiting for extra flags and operating system (gzip) */ - EXLEN, /* i: waiting for extra length (gzip) */ - EXTRA, /* i: waiting for extra bytes (gzip) */ - NAME, /* i: waiting for end of file name (gzip) */ - COMMENT, /* i: waiting for end of comment (gzip) */ - HCRC, /* i: waiting for header crc (gzip) */ - DICTID, /* i: waiting for dictionary check value */ - DICT, /* waiting for inflateSetDictionary() call */ - TYPE, /* i: waiting for type bits, including last-flag bit */ - TYPEDO, /* i: same, but skip check to exit inflate on new block */ - STORED, /* i: waiting for stored size (length and complement) */ - COPY, /* i/o: waiting for input or output to copy stored block */ - TABLE, /* i: waiting for dynamic block table lengths */ - LENLENS, /* i: waiting for code length code lengths */ - CODELENS, /* i: waiting for length/lit and distance code lengths */ - LEN, /* i: waiting for length/lit code */ - LENEXT, /* i: waiting for length extra bits */ - DIST, /* i: waiting for distance code */ - DISTEXT, /* i: waiting for distance extra bits */ - MATCH, /* o: waiting for output space to copy string */ - LIT, /* o: waiting for output space to write literal */ - CHECK, /* i: waiting for 32-bit check value */ - LENGTH, /* i: waiting for 32-bit length (gzip) */ - DONE, /* finished check, done -- remain here until reset */ - BAD, /* got a data error -- remain here until reset */ - MEM, /* got an inflate() memory error -- remain here until reset */ - SYNC /* looking for synchronization bytes to restart inflate() */ -} inflate_mode; - -/* - State transitions between above modes - - - (most modes can go to the BAD or MEM mode -- not shown for clarity) - - Process header: - HEAD -> (gzip) or (zlib) - (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME - NAME -> COMMENT -> HCRC -> TYPE - (zlib) -> DICTID or TYPE - DICTID -> DICT -> TYPE - Read deflate blocks: - TYPE -> STORED or TABLE or LEN or CHECK - STORED -> COPY -> TYPE - TABLE -> LENLENS -> CODELENS -> LEN - Read deflate codes: - LEN -> LENEXT or LIT or TYPE - LENEXT -> DIST -> DISTEXT -> MATCH -> LEN - LIT -> LEN - Process trailer: - CHECK -> LENGTH -> DONE - */ - -/* state maintained between inflate() calls. Approximately 7K bytes. */ -struct inflate_state { - inflate_mode mode; /* current inflate mode */ - int last; /* true if processing last block */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - int havedict; /* true if dictionary provided */ - int flags; /* gzip header method and flags (0 if zlib) */ - unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ - unsigned long check; /* protected copy of check value */ - unsigned long total; /* protected copy of output count */ - gz_headerp head; /* where to save gzip header information */ - /* sliding window */ - unsigned wbits; /* log base 2 of requested window size */ - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned write; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if needed */ - /* bit accumulator */ - unsigned long hold; /* input bit accumulator */ - unsigned bits; /* number of bits in "in" */ - /* for string and stored block copying */ - unsigned length; /* literal or length of data to copy */ - unsigned offset; /* distance back to copy string from */ - /* for table and code decoding */ - unsigned extra; /* extra bits needed */ - /* fixed and dynamic code tables */ - code const FAR *lencode; /* starting table for length/literal codes */ - code const FAR *distcode; /* starting table for distance codes */ - unsigned lenbits; /* index bits for lencode */ - unsigned distbits; /* index bits for distcode */ - /* dynamic table building */ - unsigned ncode; /* number of code length code lengths */ - unsigned nlen; /* number of length code lengths */ - unsigned ndist; /* number of distance code lengths */ - unsigned have; /* number of code lengths in lens[] */ - code FAR *next; /* next available space in codes[] */ - unsigned short lens[320]; /* temporary storage for code lengths */ - unsigned short work[288]; /* work area for code table building */ - code codes[ENOUGH]; /* space for code tables */ -}; diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/inftrees.c b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/inftrees.c deleted file mode 100644 index 8a9c13ff0..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/inftrees.c +++ /dev/null @@ -1,329 +0,0 @@ -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2005 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" - -#define MAXBITS 15 - -const char inflate_copyright[] = - " inflate 1.2.3 Copyright 1995-2005 Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* - Build a set of tables to decode the provided canonical Huffman code. - The code lengths are lens[0..codes-1]. The result starts at *table, - whose indices are 0..2^bits-1. work is a writable array of at least - lens shorts, which is used as a work area. type is the type of code - to be generated, CODES, LENS, or DISTS. On return, zero is success, - -1 is an invalid code, and +1 means that ENOUGH isn't enough. table - on return points to the next available entry's address. bits is the - requested root table index bits, and on return it is the actual root - table index bits. It will differ if the request is greater than the - longest code or if it is less than the shortest code. - */ -int inflate_table(type, lens, codes, table, bits, work) -codetype type; -unsigned short FAR *lens; -unsigned codes; -code FAR * FAR *table; -unsigned FAR *bits; -unsigned short FAR *work; -{ - unsigned len; /* a code's length in bits */ - unsigned sym; /* index of code symbols */ - unsigned min, max; /* minimum and maximum code lengths */ - unsigned root; /* number of index bits for root table */ - unsigned curr; /* number of index bits for current table */ - unsigned drop; /* code bits to drop for sub-table */ - int left; /* number of prefix codes available */ - unsigned used; /* code entries in table used */ - unsigned huff; /* Huffman code */ - unsigned incr; /* for incrementing code, index */ - unsigned fill; /* index for replicating entries */ - unsigned low; /* low bits for current root entry */ - unsigned mask; /* mask for low root bits */ - code this; /* table entry for duplication */ - code FAR *next; /* next available space in table */ - const unsigned short FAR *base; /* base value table to use */ - const unsigned short FAR *extra; /* extra bits table to use */ - int end; /* use base and extra for symbol > end */ - unsigned short count[MAXBITS+1]; /* number of codes of each length */ - unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ - static const unsigned short lbase[31] = { /* Length codes 257..285 base */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - static const unsigned short lext[31] = { /* Length codes 257..285 extra */ - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196}; - static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577, 0, 0}; - static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, - 28, 28, 29, 29, 64, 64}; - - /* - Process a set of code lengths to create a canonical Huffman code. The - code lengths are lens[0..codes-1]. Each length corresponds to the - symbols 0..codes-1. The Huffman code is generated by first sorting the - symbols by length from short to long, and retaining the symbol order - for codes with equal lengths. Then the code starts with all zero bits - for the first code of the shortest length, and the codes are integer - increments for the same length, and zeros are appended as the length - increases. For the deflate format, these bits are stored backwards - from their more natural integer increment ordering, and so when the - decoding tables are built in the large loop below, the integer codes - are incremented backwards. - - This routine assumes, but does not check, that all of the entries in - lens[] are in the range 0..MAXBITS. The caller must assure this. - 1..MAXBITS is interpreted as that code length. zero means that that - symbol does not occur in this code. - - The codes are sorted by computing a count of codes for each length, - creating from that a table of starting indices for each length in the - sorted table, and then entering the symbols in order in the sorted - table. The sorted table is work[], with that space being provided by - the caller. - - The length counts are used for other purposes as well, i.e. finding - the minimum and maximum length codes, determining if there are any - codes at all, checking for a valid set of lengths, and looking ahead - at length counts to determine sub-table sizes when building the - decoding tables. - */ - - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ - for (len = 0; len <= MAXBITS; len++) - count[len] = 0; - for (sym = 0; sym < codes; sym++) - count[lens[sym]]++; - - /* bound code lengths, force root to be within code lengths */ - root = *bits; - for (max = MAXBITS; max >= 1; max--) - if (count[max] != 0) break; - if (root > max) root = max; - if (max == 0) { /* no symbols to code at all */ - this.op = (unsigned char)64; /* invalid code marker */ - this.bits = (unsigned char)1; - this.val = (unsigned short)0; - *(*table)++ = this; /* make a table to force an error */ - *(*table)++ = this; - *bits = 1; - return 0; /* no symbols, but wait for decoding to report error */ - } - for (min = 1; min <= MAXBITS; min++) - if (count[min] != 0) break; - if (root < min) root = min; - - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; - for (len = 1; len <= MAXBITS; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) return -1; /* over-subscribed */ - } - if (left > 0 && (type == CODES || max != 1)) - return -1; /* incomplete set */ - - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS; len++) - offs[len + 1] = offs[len] + count[len]; - - /* sort symbols by length, by symbol order within each length */ - for (sym = 0; sym < codes; sym++) - if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; - - /* - Create and fill in decoding tables. In this loop, the table being - filled is at next and has curr index bits. The code being used is huff - with length len. That code is converted to an index by dropping drop - bits off of the bottom. For codes where len is less than drop + curr, - those top drop + curr - len bits are incremented through all values to - fill the table with replicated entries. - - root is the number of index bits for the root table. When len exceeds - root, sub-tables are created pointed to by the root entry with an index - of the low root bits of huff. This is saved in low to check for when a - new sub-table should be started. drop is zero when the root table is - being filled, and drop is root when sub-tables are being filled. - - When a new sub-table is needed, it is necessary to look ahead in the - code lengths to determine what size sub-table is needed. The length - counts are used for this, and so count[] is decremented as codes are - entered in the tables. - - used keeps track of how many table entries have been allocated from the - provided *table space. It is checked when a LENS table is being made - against the space in *table, ENOUGH, minus the maximum space needed by - the worst case distance code, MAXD. This should never happen, but the - sufficiency of ENOUGH has not been proven exhaustively, hence the check. - This assumes that when type == LENS, bits == 9. - - sym increments through all symbols, and the loop terminates when - all codes of length max, i.e. all codes, have been processed. This - routine permits incomplete codes, so another loop after this one fills - in the rest of the decoding tables with invalid code markers. - */ - - /* set up for code type */ - switch (type) { - case CODES: - base = extra = work; /* dummy value--not used */ - end = 19; - break; - case LENS: - base = lbase; - base -= 257; - extra = lext; - extra -= 257; - end = 256; - break; - default: /* DISTS */ - base = dbase; - extra = dext; - end = -1; - } - - /* initialize state for loop */ - huff = 0; /* starting code */ - sym = 0; /* starting code symbol */ - len = min; /* starting code length */ - next = *table; /* current table to fill in */ - curr = root; /* current table index bits */ - drop = 0; /* current bits to drop from code for index */ - low = (unsigned)(-1); /* trigger new sub-table when len > root */ - used = 1U << root; /* use root table entries */ - mask = used - 1; /* mask for comparing low */ - - /* check available table space */ - if (type == LENS && used >= ENOUGH - MAXD) - return 1; - - /* process all codes and make table entries */ - for (;;) { - /* create table entry */ - this.bits = (unsigned char)(len - drop); - if ((int)(work[sym]) < end) { - this.op = (unsigned char)0; - this.val = work[sym]; - } - else if ((int)(work[sym]) > end) { - this.op = (unsigned char)(extra[work[sym]]); - this.val = base[work[sym]]; - } - else { - this.op = (unsigned char)(32 + 64); /* end of block */ - this.val = 0; - } - - /* replicate for those indices with low len bits equal to huff */ - incr = 1U << (len - drop); - fill = 1U << curr; - min = fill; /* save offset to next table */ - do { - fill -= incr; - next[(huff >> drop) + fill] = this; - } while (fill != 0); - - /* backwards increment the len-bit code huff */ - incr = 1U << (len - 1); - while (huff & incr) - incr >>= 1; - if (incr != 0) { - huff &= incr - 1; - huff += incr; - } - else - huff = 0; - - /* go to next symbol, update count, len */ - sym++; - if (--(count[len]) == 0) { - if (len == max) break; - len = lens[work[sym]]; - } - - /* create new sub-table if needed */ - if (len > root && (huff & mask) != low) { - /* if first time, transition to sub-tables */ - if (drop == 0) - drop = root; - - /* increment past last table */ - next += min; /* here min is 1 << curr */ - - /* determine length of next table */ - curr = len - drop; - left = (int)(1 << curr); - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) break; - curr++; - left <<= 1; - } - - /* check for enough space */ - used += 1U << curr; - if (type == LENS && used >= ENOUGH - MAXD) - return 1; - - /* point entry in root table to sub-table */ - low = huff & mask; - (*table)[low].op = (unsigned char)curr; - (*table)[low].bits = (unsigned char)root; - (*table)[low].val = (unsigned short)(next - *table); - } - } - - /* - Fill in rest of table for incomplete codes. This loop is similar to the - loop above in incrementing huff for table indices. It is assumed that - len is equal to curr + drop, so there is no loop needed to increment - through high index bits. When the current sub-table is filled, the loop - drops back to the root table to fill in any remaining entries there. - */ - this.op = (unsigned char)64; /* invalid code marker */ - this.bits = (unsigned char)(len - drop); - this.val = (unsigned short)0; - while (huff != 0) { - /* when done with sub-table, drop back to root table */ - if (drop != 0 && (huff & mask) != low) { - drop = 0; - len = root; - next = *table; - this.bits = (unsigned char)len; - } - - /* put invalid code marker in table */ - next[huff >> drop] = this; - - /* backwards increment the len-bit code huff */ - incr = 1U << (len - 1); - while (huff & incr) - incr >>= 1; - if (incr != 0) { - huff &= incr - 1; - huff += incr; - } - else - huff = 0; - } - - /* set return parameters */ - *table += used; - *bits = root; - return 0; -} diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/inftrees.h b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/inftrees.h deleted file mode 100644 index b1104c87e..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/inftrees.h +++ /dev/null @@ -1,55 +0,0 @@ -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995-2005 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Structure for decoding tables. Each entry provides either the - information needed to do the operation requested by the code that - indexed that table entry, or it provides a pointer to another - table that indexes more bits of the code. op indicates whether - the entry is a pointer to another table, a literal, a length or - distance, an end-of-block, or an invalid code. For a table - pointer, the low four bits of op is the number of index bits of - that table. For a length or distance, the low four bits of op - is the number of extra bits to get after the code. bits is - the number of bits in this code or part of the code to drop off - of the bit buffer. val is the actual byte to output in the case - of a literal, the base length or distance, or the offset from - the current table to the next table. Each entry is four bytes. */ -typedef struct { - unsigned char op; /* operation, extra bits, table bits */ - unsigned char bits; /* bits in this part of the code */ - unsigned short val; /* offset in table or code value */ -} code; - -/* op values as set by inflate_table(): - 00000000 - literal - 0000tttt - table link, tttt != 0 is the number of table index bits - 0001eeee - length or distance, eeee is the number of extra bits - 01100000 - end of block - 01000000 - invalid code - */ - -/* Maximum size of dynamic tree. The maximum found in a long but non- - exhaustive search was 1444 code structures (852 for length/literals - and 592 for distances, the latter actually the result of an - exhaustive search). The true maximum is not known, but the value - below is more than safe. */ -#define ENOUGH 2048 -#define MAXD 592 - -/* Type of code to build for inftable() */ -typedef enum { - CODES, - LENS, - DISTS -} codetype; - -extern int inflate_table OF((codetype type, unsigned short FAR *lens, - unsigned codes, code FAR * FAR *table, - unsigned FAR *bits, unsigned short FAR *work)); diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/make_vms.com b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/make_vms.com deleted file mode 100644 index 93174bbc8..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/make_vms.com +++ /dev/null @@ -1,461 +0,0 @@ -$! make libz under VMS written by -$! Martin P.J. Zinser -$! -$! -$ on error then goto err_exit -$! -$! -$! Just some general constants... -$! -$ true = 1 -$ false = 0 -$ tmpnam = "temp_" + f$getjpi("","pid") -$ SAY = "WRITE SYS$OUTPUT" -$! -$! Setup variables holding "config" information -$! -$ Make = "" -$ name = "Zlib" -$ version = "?.?.?" -$ v_string = "ZLIB_VERSION" -$ v_file = "zlib.h" -$ ccopt = "" -$ lopts = "" -$ linkonly = false -$ optfile = name + ".opt" -$ its_decc = false -$ its_vaxc = false -$ its_gnuc = false -$ axp = f$getsyi("HW_MODEL").ge.1024 -$ s_case = false -$! Check for MMK/MMS -$! -$ If F$Search ("Sys$System:MMS.EXE") .nes. "" Then Make = "MMS" -$ If F$Type (MMK) .eqs. "STRING" Then Make = "MMK" -$! -$! -$ gosub find_version -$! -$ gosub check_opts -$! -$! Look for the compiler used -$! -$ gosub check_compiler -$ if its_decc -$ then -$ ccopt = "/prefix=all" + ccopt -$ if f$trnlnm("SYS") .eqs. "" -$ then -$ if axp -$ then -$ define sys sys$library: -$ else -$ ccopt = "/decc" + ccopt -$ define sys decc$library_include: -$ endif -$ endif -$ endif -$ if its_vaxc .or. its_gnuc -$ then -$ if f$trnlnm("SYS").eqs."" then define sys sys$library: -$ endif -$! -$! Build the thing plain or with mms -$! -$ write sys$output "Compiling Zlib sources ..." -$ if make.eqs."" -$ then -$ dele example.obj;*,minigzip.obj;* -$ CALL MAKE adler32.OBJ "CC ''CCOPT' adler32" - - adler32.c zlib.h zconf.h -$ CALL MAKE compress.OBJ "CC ''CCOPT' compress" - - compress.c zlib.h zconf.h -$ CALL MAKE crc32.OBJ "CC ''CCOPT' crc32" - - crc32.c zlib.h zconf.h -$ CALL MAKE deflate.OBJ "CC ''CCOPT' deflate" - - deflate.c deflate.h zutil.h zlib.h zconf.h -$ CALL MAKE gzio.OBJ "CC ''CCOPT' gzio" - - gzio.c zutil.h zlib.h zconf.h -$ CALL MAKE infback.OBJ "CC ''CCOPT' infback" - - infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h -$ CALL MAKE inffast.OBJ "CC ''CCOPT' inffast" - - inffast.c zutil.h zlib.h zconf.h inffast.h -$ CALL MAKE inflate.OBJ "CC ''CCOPT' inflate" - - inflate.c zutil.h zlib.h zconf.h infblock.h -$ CALL MAKE inftrees.OBJ "CC ''CCOPT' inftrees" - - inftrees.c zutil.h zlib.h zconf.h inftrees.h -$ CALL MAKE trees.OBJ "CC ''CCOPT' trees" - - trees.c deflate.h zutil.h zlib.h zconf.h -$ CALL MAKE uncompr.OBJ "CC ''CCOPT' uncompr" - - uncompr.c zlib.h zconf.h -$ CALL MAKE zutil.OBJ "CC ''CCOPT' zutil" - - zutil.c zutil.h zlib.h zconf.h -$ write sys$output "Building Zlib ..." -$ CALL MAKE libz.OLB "lib/crea libz.olb *.obj" *.OBJ -$ write sys$output "Building example..." -$ CALL MAKE example.OBJ "CC ''CCOPT' example" - - example.c zlib.h zconf.h -$ call make example.exe "LINK example,libz.olb/lib" example.obj libz.olb -$ if f$search("x11vms:xvmsutils.olb") .nes. "" -$ then -$ write sys$output "Building minigzip..." -$ CALL MAKE minigzip.OBJ "CC ''CCOPT' minigzip" - - minigzip.c zlib.h zconf.h -$ call make minigzip.exe - - "LINK minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib" - - minigzip.obj libz.olb -$ endif -$ else -$ gosub crea_mms -$ SAY "Make ''name' ''version' with ''Make' " -$ 'make' -$ endif -$! -$! Alpha gets a shareable image -$! -$ If axp -$ Then -$ gosub crea_olist -$ write sys$output "Creating libzshr.exe" -$ call anal_obj_axp modules.opt _link.opt -$ if s_case -$ then -$ open/append optf modules.opt -$ write optf "case_sensitive=YES" -$ close optf -$ endif -$ LINK_'lopts'/SHARE=libzshr.exe modules.opt/opt,_link.opt/opt -$ endif -$ write sys$output "Zlib build completed" -$ exit -$CC_ERR: -$ write sys$output "C compiler required to build ''name'" -$ goto err_exit -$ERR_EXIT: -$ set message/facil/ident/sever/text -$ write sys$output "Exiting..." -$ exit 2 -$! -$! -$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES -$ V = 'F$Verify(0) -$! P1 = What we are trying to make -$! P2 = Command to make it -$! P3 - P8 What it depends on -$ -$ If F$Search(P1) .Eqs. "" Then Goto Makeit -$ Time = F$CvTime(F$File(P1,"RDT")) -$arg=3 -$Loop: -$ Argument = P'arg -$ If Argument .Eqs. "" Then Goto Exit -$ El=0 -$Loop2: -$ File = F$Element(El," ",Argument) -$ If File .Eqs. " " Then Goto Endl -$ AFile = "" -$Loop3: -$ OFile = AFile -$ AFile = F$Search(File) -$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl -$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit -$ Goto Loop3 -$NextEL: -$ El = El + 1 -$ Goto Loop2 -$EndL: -$ arg=arg+1 -$ If arg .Le. 8 Then Goto Loop -$ Goto Exit -$ -$Makeit: -$ VV=F$VERIFY(0) -$ write sys$output P2 -$ 'P2 -$ VV='F$Verify(VV) -$Exit: -$ If V Then Set Verify -$ENDSUBROUTINE -$!------------------------------------------------------------------------------ -$! -$! Check command line options and set symbols accordingly -$! -$ CHECK_OPTS: -$ i = 1 -$ OPT_LOOP: -$ if i .lt. 9 -$ then -$ cparm = f$edit(p'i',"upcase") -$ if cparm .eqs. "DEBUG" -$ then -$ ccopt = ccopt + "/noopt/deb" -$ lopts = lopts + "/deb" -$ endif -$ if f$locate("CCOPT=",cparm) .lt. f$length(cparm) -$ then -$ start = f$locate("=",cparm) + 1 -$ len = f$length(cparm) - start -$ ccopt = ccopt + f$extract(start,len,cparm) -$ if f$locate("AS_IS",f$edit(ccopt,"UPCASE")) .lt. f$length(ccopt) - - then s_case = true -$ endif -$ if cparm .eqs. "LINK" then linkonly = true -$ if f$locate("LOPTS=",cparm) .lt. f$length(cparm) -$ then -$ start = f$locate("=",cparm) + 1 -$ len = f$length(cparm) - start -$ lopts = lopts + f$extract(start,len,cparm) -$ endif -$ if f$locate("CC=",cparm) .lt. f$length(cparm) -$ then -$ start = f$locate("=",cparm) + 1 -$ len = f$length(cparm) - start -$ cc_com = f$extract(start,len,cparm) - if (cc_com .nes. "DECC") .and. - - (cc_com .nes. "VAXC") .and. - - (cc_com .nes. "GNUC") -$ then -$ write sys$output "Unsupported compiler choice ''cc_com' ignored" -$ write sys$output "Use DECC, VAXC, or GNUC instead" -$ else -$ if cc_com .eqs. "DECC" then its_decc = true -$ if cc_com .eqs. "VAXC" then its_vaxc = true -$ if cc_com .eqs. "GNUC" then its_gnuc = true -$ endif -$ endif -$ if f$locate("MAKE=",cparm) .lt. f$length(cparm) -$ then -$ start = f$locate("=",cparm) + 1 -$ len = f$length(cparm) - start -$ mmks = f$extract(start,len,cparm) -$ if (mmks .eqs. "MMK") .or. (mmks .eqs. "MMS") -$ then -$ make = mmks -$ else -$ write sys$output "Unsupported make choice ''mmks' ignored" -$ write sys$output "Use MMK or MMS instead" -$ endif -$ endif -$ i = i + 1 -$ goto opt_loop -$ endif -$ return -$!------------------------------------------------------------------------------ -$! -$! Look for the compiler used -$! -$CHECK_COMPILER: -$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc)) -$ then -$ its_decc = (f$search("SYS$SYSTEM:DECC$COMPILER.EXE") .nes. "") -$ its_vaxc = .not. its_decc .and. (F$Search("SYS$System:VAXC.Exe") .nes. "") -$ its_gnuc = .not. (its_decc .or. its_vaxc) .and. (f$trnlnm("gnu_cc") .nes. "") -$ endif -$! -$! Exit if no compiler available -$! -$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc)) -$ then goto CC_ERR -$ else -$ if its_decc then write sys$output "CC compiler check ... Compaq C" -$ if its_vaxc then write sys$output "CC compiler check ... VAX C" -$ if its_gnuc then write sys$output "CC compiler check ... GNU C" -$ endif -$ return -$!------------------------------------------------------------------------------ -$! -$! If MMS/MMK are available dump out the descrip.mms if required -$! -$CREA_MMS: -$ write sys$output "Creating descrip.mms..." -$ create descrip.mms -$ open/append out descrip.mms -$ copy sys$input: out -$ deck -# descrip.mms: MMS description file for building zlib on VMS -# written by Martin P.J. Zinser -# - -OBJS = adler32.obj, compress.obj, crc32.obj, gzio.obj, uncompr.obj, infback.obj\ - deflate.obj, trees.obj, zutil.obj, inflate.obj, \ - inftrees.obj, inffast.obj - -$ eod -$ write out "CFLAGS=", ccopt -$ write out "LOPTS=", lopts -$ copy sys$input: out -$ deck - -all : example.exe minigzip.exe libz.olb - @ write sys$output " Example applications available" - -libz.olb : libz.olb($(OBJS)) - @ write sys$output " libz available" - -example.exe : example.obj libz.olb - link $(LOPTS) example,libz.olb/lib - -minigzip.exe : minigzip.obj libz.olb - link $(LOPTS) minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib - -clean : - delete *.obj;*,libz.olb;*,*.opt;*,*.exe;* - - -# Other dependencies. -adler32.obj : adler32.c zutil.h zlib.h zconf.h -compress.obj : compress.c zlib.h zconf.h -crc32.obj : crc32.c zutil.h zlib.h zconf.h -deflate.obj : deflate.c deflate.h zutil.h zlib.h zconf.h -example.obj : example.c zlib.h zconf.h -gzio.obj : gzio.c zutil.h zlib.h zconf.h -inffast.obj : inffast.c zutil.h zlib.h zconf.h inftrees.h inffast.h -inflate.obj : inflate.c zutil.h zlib.h zconf.h -inftrees.obj : inftrees.c zutil.h zlib.h zconf.h inftrees.h -minigzip.obj : minigzip.c zlib.h zconf.h -trees.obj : trees.c deflate.h zutil.h zlib.h zconf.h -uncompr.obj : uncompr.c zlib.h zconf.h -zutil.obj : zutil.c zutil.h zlib.h zconf.h -infback.obj : infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h -$ eod -$ close out -$ return -$!------------------------------------------------------------------------------ -$! -$! Read list of core library sources from makefile.in and create options -$! needed to build shareable image -$! -$CREA_OLIST: -$ open/read min makefile.in -$ open/write mod modules.opt -$ src_check = "OBJS =" -$MRLOOP: -$ read/end=mrdone min rec -$ if (f$extract(0,6,rec) .nes. src_check) then goto mrloop -$ rec = rec - src_check -$ gosub extra_filnam -$ if (f$element(1,"\",rec) .eqs. "\") then goto mrdone -$MRSLOOP: -$ read/end=mrdone min rec -$ gosub extra_filnam -$ if (f$element(1,"\",rec) .nes. "\") then goto mrsloop -$MRDONE: -$ close min -$ close mod -$ return -$!------------------------------------------------------------------------------ -$! -$! Take record extracted in crea_olist and split it into single filenames -$! -$EXTRA_FILNAM: -$ myrec = f$edit(rec - "\", "trim,compress") -$ i = 0 -$FELOOP: -$ srcfil = f$element(i," ", myrec) -$ if (srcfil .nes. " ") -$ then -$ write mod f$parse(srcfil,,,"NAME"), ".obj" -$ i = i + 1 -$ goto feloop -$ endif -$ return -$!------------------------------------------------------------------------------ -$! -$! Find current Zlib version number -$! -$FIND_VERSION: -$ open/read h_in 'v_file' -$hloop: -$ read/end=hdone h_in rec -$ rec = f$edit(rec,"TRIM") -$ if (f$extract(0,1,rec) .nes. "#") then goto hloop -$ rec = f$edit(rec - "#", "TRIM") -$ if f$element(0," ",rec) .nes. "define" then goto hloop -$ if f$element(1," ",rec) .eqs. v_string -$ then -$ version = 'f$element(2," ",rec)' -$ goto hdone -$ endif -$ goto hloop -$hdone: -$ close h_in -$ return -$!------------------------------------------------------------------------------ -$! -$! Analyze Object files for OpenVMS AXP to extract Procedure and Data -$! information to build a symbol vector for a shareable image -$! All the "brains" of this logic was suggested by Hartmut Becker -$! (Hartmut.Becker@compaq.com). All the bugs were introduced by me -$! (zinser@decus.de), so if you do have problem reports please do not -$! bother Hartmut/HP, but get in touch with me -$! -$ ANAL_OBJ_AXP: Subroutine -$ V = 'F$Verify(0) -$ SAY := "WRITE_ SYS$OUTPUT" -$ -$ IF F$SEARCH("''P1'") .EQS. "" -$ THEN -$ SAY "ANAL_OBJ_AXP-E-NOSUCHFILE: Error, inputfile ''p1' not available" -$ goto exit_aa -$ ENDIF -$ IF "''P2'" .EQS. "" -$ THEN -$ SAY "ANAL_OBJ_AXP: Error, no output file provided" -$ goto exit_aa -$ ENDIF -$ -$ open/read in 'p1 -$ create a.tmp -$ open/append atmp a.tmp -$ loop: -$ read/end=end_loop in line -$ f= f$search(line) -$ if f .eqs. "" -$ then -$ write sys$output "ANAL_OBJ_AXP-w-nosuchfile, ''line'" -$ goto loop -$ endif -$ define/user sys$output nl: -$ define/user sys$error nl: -$ anal/obj/gsd 'f /out=x.tmp -$ open/read xtmp x.tmp -$ XLOOP: -$ read/end=end_xloop xtmp xline -$ xline = f$edit(xline,"compress") -$ write atmp xline -$ goto xloop -$ END_XLOOP: -$ close xtmp -$ goto loop -$ end_loop: -$ close in -$ close atmp -$ if f$search("a.tmp") .eqs. "" - - then $ exit -$ ! all global definitions -$ search a.tmp "symbol:","EGSY$V_DEF 1","EGSY$V_NORM 1"/out=b.tmp -$ ! all procedures -$ search b.tmp "EGSY$V_NORM 1"/wind=(0,1) /out=c.tmp -$ search c.tmp "symbol:"/out=d.tmp -$ define/user sys$output nl: -$ edito/edt/command=sys$input d.tmp -sub/symbol: "/symbol_vector=(/whole -sub/"/=PROCEDURE)/whole -exit -$ ! all data -$ search b.tmp "EGSY$V_DEF 1"/wind=(0,1) /out=e.tmp -$ search e.tmp "symbol:"/out=f.tmp -$ define/user sys$output nl: -$ edito/edt/command=sys$input f.tmp -sub/symbol: "/symbol_vector=(/whole -sub/"/=DATA)/whole -exit -$ sort/nodupl d.tmp,f.tmp 'p2' -$ delete a.tmp;*,b.tmp;*,c.tmp;*,d.tmp;*,e.tmp;*,f.tmp;* -$ if f$search("x.tmp") .nes. "" - - then $ delete x.tmp;* -$! -$ EXIT_AA: -$ if V then set verify -$ endsubroutine -$!------------------------------------------------------------------------------ diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/minigzip.c b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/minigzip.c deleted file mode 100644 index 4524b96a1..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/minigzip.c +++ /dev/null @@ -1,322 +0,0 @@ -/* minigzip.c -- simulate gzip using the zlib compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * minigzip is a minimal implementation of the gzip utility. This is - * only an example of using zlib and isn't meant to replace the - * full-featured gzip. No attempt is made to deal with file systems - * limiting names to 14 or 8+3 characters, etc... Error checking is - * very limited. So use minigzip only for testing; use gzip for the - * real thing. On MSDOS, use only on file names without extension - * or in pipe mode. - */ - -/* @(#) $Id$ */ - -#include -#include "zlib.h" - -#ifdef STDC -# include -# include -#endif - -#ifdef USE_MMAP -# include -# include -# include -#endif - -#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__) -# include -# include -# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) -#else -# define SET_BINARY_MODE(file) -#endif - -#ifdef VMS -# define unlink delete -# define GZ_SUFFIX "-gz" -#endif -#ifdef RISCOS -# define unlink remove -# define GZ_SUFFIX "-gz" -# define fileno(file) file->__file -#endif -#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os -# include /* for fileno */ -#endif - -#ifndef WIN32 /* unlink already in stdio.h for WIN32 */ - extern int unlink OF((const char *)); -#endif - -#ifndef GZ_SUFFIX -# define GZ_SUFFIX ".gz" -#endif -#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) - -#define BUFLEN 16384 -#define MAX_NAME_LEN 1024 - -#ifdef MAXSEG_64K -# define local static - /* Needed for systems with limitation on stack size. */ -#else -# define local -#endif - -char *prog; - -void error OF((const char *msg)); -void gz_compress OF((FILE *in, gzFile out)); -#ifdef USE_MMAP -int gz_compress_mmap OF((FILE *in, gzFile out)); -#endif -void gz_uncompress OF((gzFile in, FILE *out)); -void file_compress OF((char *file, char *mode)); -void file_uncompress OF((char *file)); -int main OF((int argc, char *argv[])); - -/* =========================================================================== - * Display error message and exit - */ -void error(msg) - const char *msg; -{ - fprintf(stderr, "%s: %s\n", prog, msg); - exit(1); -} - -/* =========================================================================== - * Compress input to output then close both files. - */ - -void gz_compress(in, out) - FILE *in; - gzFile out; -{ - local char buf[BUFLEN]; - int len; - int err; - -#ifdef USE_MMAP - /* Try first compressing with mmap. If mmap fails (minigzip used in a - * pipe), use the normal fread loop. - */ - if (gz_compress_mmap(in, out) == Z_OK) return; -#endif - for (;;) { - len = (int)fread(buf, 1, sizeof(buf), in); - if (ferror(in)) { - perror("fread"); - exit(1); - } - if (len == 0) break; - - if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err)); - } - fclose(in); - if (gzclose(out) != Z_OK) error("failed gzclose"); -} - -#ifdef USE_MMAP /* MMAP version, Miguel Albrecht */ - -/* Try compressing the input file at once using mmap. Return Z_OK if - * if success, Z_ERRNO otherwise. - */ -int gz_compress_mmap(in, out) - FILE *in; - gzFile out; -{ - int len; - int err; - int ifd = fileno(in); - caddr_t buf; /* mmap'ed buffer for the entire input file */ - off_t buf_len; /* length of the input file */ - struct stat sb; - - /* Determine the size of the file, needed for mmap: */ - if (fstat(ifd, &sb) < 0) return Z_ERRNO; - buf_len = sb.st_size; - if (buf_len <= 0) return Z_ERRNO; - - /* Now do the actual mmap: */ - buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0); - if (buf == (caddr_t)(-1)) return Z_ERRNO; - - /* Compress the whole file at once: */ - len = gzwrite(out, (char *)buf, (unsigned)buf_len); - - if (len != (int)buf_len) error(gzerror(out, &err)); - - munmap(buf, buf_len); - fclose(in); - if (gzclose(out) != Z_OK) error("failed gzclose"); - return Z_OK; -} -#endif /* USE_MMAP */ - -/* =========================================================================== - * Uncompress input to output then close both files. - */ -void gz_uncompress(in, out) - gzFile in; - FILE *out; -{ - local char buf[BUFLEN]; - int len; - int err; - - for (;;) { - len = gzread(in, buf, sizeof(buf)); - if (len < 0) error (gzerror(in, &err)); - if (len == 0) break; - - if ((int)fwrite(buf, 1, (unsigned)len, out) != len) { - error("failed fwrite"); - } - } - if (fclose(out)) error("failed fclose"); - - if (gzclose(in) != Z_OK) error("failed gzclose"); -} - - -/* =========================================================================== - * Compress the given file: create a corresponding .gz file and remove the - * original. - */ -void file_compress(file, mode) - char *file; - char *mode; -{ - local char outfile[MAX_NAME_LEN]; - FILE *in; - gzFile out; - - strcpy(outfile, file); - strcat(outfile, GZ_SUFFIX); - - in = fopen(file, "rb"); - if (in == NULL) { - perror(file); - exit(1); - } - out = gzopen(outfile, mode); - if (out == NULL) { - fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile); - exit(1); - } - gz_compress(in, out); - - unlink(file); -} - - -/* =========================================================================== - * Uncompress the given file and remove the original. - */ -void file_uncompress(file) - char *file; -{ - local char buf[MAX_NAME_LEN]; - char *infile, *outfile; - FILE *out; - gzFile in; - uInt len = (uInt)strlen(file); - - strcpy(buf, file); - - if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) { - infile = file; - outfile = buf; - outfile[len-3] = '\0'; - } else { - outfile = file; - infile = buf; - strcat(infile, GZ_SUFFIX); - } - in = gzopen(infile, "rb"); - if (in == NULL) { - fprintf(stderr, "%s: can't gzopen %s\n", prog, infile); - exit(1); - } - out = fopen(outfile, "wb"); - if (out == NULL) { - perror(file); - exit(1); - } - - gz_uncompress(in, out); - - unlink(infile); -} - - -/* =========================================================================== - * Usage: minigzip [-d] [-f] [-h] [-r] [-1 to -9] [files...] - * -d : decompress - * -f : compress with Z_FILTERED - * -h : compress with Z_HUFFMAN_ONLY - * -r : compress with Z_RLE - * -1 to -9 : compression level - */ - -int main(argc, argv) - int argc; - char *argv[]; -{ - int uncompr = 0; - gzFile file; - char outmode[20]; - - strcpy(outmode, "wb6 "); - - prog = argv[0]; - argc--, argv++; - - while (argc > 0) { - if (strcmp(*argv, "-d") == 0) - uncompr = 1; - else if (strcmp(*argv, "-f") == 0) - outmode[3] = 'f'; - else if (strcmp(*argv, "-h") == 0) - outmode[3] = 'h'; - else if (strcmp(*argv, "-r") == 0) - outmode[3] = 'R'; - else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' && - (*argv)[2] == 0) - outmode[2] = (*argv)[1]; - else - break; - argc--, argv++; - } - if (outmode[3] == ' ') - outmode[3] = 0; - if (argc == 0) { - SET_BINARY_MODE(stdin); - SET_BINARY_MODE(stdout); - if (uncompr) { - file = gzdopen(fileno(stdin), "rb"); - if (file == NULL) error("can't gzdopen stdin"); - gz_uncompress(file, stdout); - } else { - file = gzdopen(fileno(stdout), outmode); - if (file == NULL) error("can't gzdopen stdout"); - gz_compress(stdin, file); - } - } else { - do { - if (uncompr) { - file_uncompress(*argv); - } else { - file_compress(*argv, outmode); - } - } while (argv++, --argc); - } - return 0; -} diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/trees.c b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/trees.c deleted file mode 100644 index 395e4e168..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/trees.c +++ /dev/null @@ -1,1219 +0,0 @@ -/* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2005 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process uses several Huffman trees. The more - * common source values are represented by shorter bit sequences. - * - * Each code tree is stored in a compressed form which is itself - * a Huffman encoding of the lengths of all the code strings (in - * ascending order by source values). The actual code strings are - * reconstructed from the lengths in the inflate process, as described - * in the deflate specification. - * - * REFERENCES - * - * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". - * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc - * - * Storer, James A. - * Data Compression: Methods and Theory, pp. 49-50. - * Computer Science Press, 1988. ISBN 0-7167-8156-5. - * - * Sedgewick, R. - * Algorithms, p290. - * Addison-Wesley, 1983. ISBN 0-201-06672-6. - */ - -/* @(#) $Id$ */ - -/* #define GEN_TREES_H */ - -#include "deflate.h" - -#ifdef DEBUG -# include -#endif - -/* =========================================================================== - * Constants - */ - -#define MAX_BL_BITS 7 -/* Bit length codes must not exceed MAX_BL_BITS bits */ - -#define END_BLOCK 256 -/* end of block literal code */ - -#define REP_3_6 16 -/* repeat previous bit length 3-6 times (2 bits of repeat count) */ - -#define REPZ_3_10 17 -/* repeat a zero length 3-10 times (3 bits of repeat count) */ - -#define REPZ_11_138 18 -/* repeat a zero length 11-138 times (7 bits of repeat count) */ - -local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ - = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; - -local const int extra_dbits[D_CODES] /* extra bits for each distance code */ - = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; - -local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ - = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; - -local const uch bl_order[BL_CODES] - = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; -/* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - -#define Buf_size (8 * 2*sizeof(char)) -/* Number of bits used within bi_buf. (bi_buf might be implemented on - * more than 16 bits on some systems.) - */ - -/* =========================================================================== - * Local data. These are initialized only once. - */ - -#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ - -#if defined(GEN_TREES_H) || !defined(STDC) -/* non ANSI compilers may not accept trees.h */ - -local ct_data static_ltree[L_CODES+2]; -/* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - -local ct_data static_dtree[D_CODES]; -/* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - -uch _dist_code[DIST_CODE_LEN]; -/* Distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - -uch _length_code[MAX_MATCH-MIN_MATCH+1]; -/* length code for each normalized match length (0 == MIN_MATCH) */ - -local int base_length[LENGTH_CODES]; -/* First normalized length for each code (0 = MIN_MATCH) */ - -local int base_dist[D_CODES]; -/* First normalized distance for each code (0 = distance of 1) */ - -#else -# include "trees.h" -#endif /* GEN_TREES_H */ - -struct static_tree_desc_s { - const ct_data *static_tree; /* static tree or NULL */ - const intf *extra_bits; /* extra bits for each code or NULL */ - int extra_base; /* base index for extra_bits */ - int elems; /* max number of elements in the tree */ - int max_length; /* max bit length for the codes */ -}; - -local static_tree_desc static_l_desc = -{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; - -local static_tree_desc static_d_desc = -{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; - -local static_tree_desc static_bl_desc = -{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; - -/* =========================================================================== - * Local (static) routines in this file. - */ - -local void tr_static_init OF((void)); -local void init_block OF((deflate_state *s)); -local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); -local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); -local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); -local void build_tree OF((deflate_state *s, tree_desc *desc)); -local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local int build_bl_tree OF((deflate_state *s)); -local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, - int blcodes)); -local void compress_block OF((deflate_state *s, ct_data *ltree, - ct_data *dtree)); -local void set_data_type OF((deflate_state *s)); -local unsigned bi_reverse OF((unsigned value, int length)); -local void bi_windup OF((deflate_state *s)); -local void bi_flush OF((deflate_state *s)); -local void copy_block OF((deflate_state *s, charf *buf, unsigned len, - int header)); - -#ifdef GEN_TREES_H -local void gen_trees_header OF((void)); -#endif - -#ifndef DEBUG -# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) - /* Send a code of the given tree. c and tree must not have side effects */ - -#else /* DEBUG */ -# define send_code(s, c, tree) \ - { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ - send_bits(s, tree[c].Code, tree[c].Len); } -#endif - -/* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ -#define put_short(s, w) { \ - put_byte(s, (uch)((w) & 0xff)); \ - put_byte(s, (uch)((ush)(w) >> 8)); \ -} - -/* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ -#ifdef DEBUG -local void send_bits OF((deflate_state *s, int value, int length)); - -local void send_bits(s, value, length) - deflate_state *s; - int value; /* value to send */ - int length; /* number of bits */ -{ - Tracevv((stderr," l %2d v %4x ", length, value)); - Assert(length > 0 && length <= 15, "invalid length"); - s->bits_sent += (ulg)length; - - /* If not enough room in bi_buf, use (valid) bits from bi_buf and - * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) - * unused bits in value. - */ - if (s->bi_valid > (int)Buf_size - length) { - s->bi_buf |= (value << s->bi_valid); - put_short(s, s->bi_buf); - s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); - s->bi_valid += length - Buf_size; - } else { - s->bi_buf |= value << s->bi_valid; - s->bi_valid += length; - } -} -#else /* !DEBUG */ - -#define send_bits(s, value, length) \ -{ int len = length;\ - if (s->bi_valid > (int)Buf_size - len) {\ - int val = value;\ - s->bi_buf |= (val << s->bi_valid);\ - put_short(s, s->bi_buf);\ - s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ - s->bi_valid += len - Buf_size;\ - } else {\ - s->bi_buf |= (value) << s->bi_valid;\ - s->bi_valid += len;\ - }\ -} -#endif /* DEBUG */ - - -/* the arguments must not have side effects */ - -/* =========================================================================== - * Initialize the various 'constant' tables. - */ -local void tr_static_init() -{ -#if defined(GEN_TREES_H) || !defined(STDC) - static int static_init_done = 0; - int n; /* iterates over tree elements */ - int bits; /* bit counter */ - int length; /* length value */ - int code; /* code value */ - int dist; /* distance index */ - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - if (static_init_done) return; - - /* For some embedded targets, global variables are not initialized: */ - static_l_desc.static_tree = static_ltree; - static_l_desc.extra_bits = extra_lbits; - static_d_desc.static_tree = static_dtree; - static_d_desc.extra_bits = extra_dbits; - static_bl_desc.extra_bits = extra_blbits; - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES-1; code++) { - base_length[code] = length; - for (n = 0; n < (1< dist code (0..29) */ - dist = 0; - for (code = 0 ; code < 16; code++) { - base_dist[code] = dist; - for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ - for ( ; code < D_CODES; code++) { - base_dist[code] = dist << 7; - for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { - _dist_code[256 + dist++] = (uch)code; - } - } - Assert (dist == 256, "tr_static_init: 256+dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; - n = 0; - while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; - while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; - while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; - while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES; n++) { - static_dtree[n].Len = 5; - static_dtree[n].Code = bi_reverse((unsigned)n, 5); - } - static_init_done = 1; - -# ifdef GEN_TREES_H - gen_trees_header(); -# endif -#endif /* defined(GEN_TREES_H) || !defined(STDC) */ -} - -/* =========================================================================== - * Genererate the file trees.h describing the static trees. - */ -#ifdef GEN_TREES_H -# ifndef DEBUG -# include -# endif - -# define SEPARATOR(i, last, width) \ - ((i) == (last)? "\n};\n\n" : \ - ((i) % (width) == (width)-1 ? ",\n" : ", ")) - -void gen_trees_header() -{ - FILE *header = fopen("trees.h", "w"); - int i; - - Assert (header != NULL, "Can't open trees.h"); - fprintf(header, - "/* header created automatically with -DGEN_TREES_H */\n\n"); - - fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); - for (i = 0; i < L_CODES+2; i++) { - fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, - static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); - } - - fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, - static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); - } - - fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n"); - for (i = 0; i < DIST_CODE_LEN; i++) { - fprintf(header, "%2u%s", _dist_code[i], - SEPARATOR(i, DIST_CODE_LEN-1, 20)); - } - - fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); - for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { - fprintf(header, "%2u%s", _length_code[i], - SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); - } - - fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); - for (i = 0; i < LENGTH_CODES; i++) { - fprintf(header, "%1u%s", base_length[i], - SEPARATOR(i, LENGTH_CODES-1, 20)); - } - - fprintf(header, "local const int base_dist[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "%5u%s", base_dist[i], - SEPARATOR(i, D_CODES-1, 10)); - } - - fclose(header); -} -#endif /* GEN_TREES_H */ - -/* =========================================================================== - * Initialize the tree data structures for a new zlib stream. - */ -void _tr_init(s) - deflate_state *s; -{ - tr_static_init(); - - s->l_desc.dyn_tree = s->dyn_ltree; - s->l_desc.stat_desc = &static_l_desc; - - s->d_desc.dyn_tree = s->dyn_dtree; - s->d_desc.stat_desc = &static_d_desc; - - s->bl_desc.dyn_tree = s->bl_tree; - s->bl_desc.stat_desc = &static_bl_desc; - - s->bi_buf = 0; - s->bi_valid = 0; - s->last_eob_len = 8; /* enough lookahead for inflate */ -#ifdef DEBUG - s->compressed_len = 0L; - s->bits_sent = 0L; -#endif - - /* Initialize the first block of the first file: */ - init_block(s); -} - -/* =========================================================================== - * Initialize a new block. - */ -local void init_block(s) - deflate_state *s; -{ - int n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; - for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; - for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; - - s->dyn_ltree[END_BLOCK].Freq = 1; - s->opt_len = s->static_len = 0L; - s->last_lit = s->matches = 0; -} - -#define SMALLEST 1 -/* Index within the heap array of least frequent node in the Huffman tree */ - - -/* =========================================================================== - * Remove the smallest element from the heap and recreate the heap with - * one less element. Updates heap and heap_len. - */ -#define pqremove(s, tree, top) \ -{\ - top = s->heap[SMALLEST]; \ - s->heap[SMALLEST] = s->heap[s->heap_len--]; \ - pqdownheap(s, tree, SMALLEST); \ -} - -/* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ -#define smaller(tree, n, m, depth) \ - (tree[n].Freq < tree[m].Freq || \ - (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) - -/* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ -local void pqdownheap(s, tree, k) - deflate_state *s; - ct_data *tree; /* the tree to restore */ - int k; /* node to move down */ -{ - int v = s->heap[k]; - int j = k << 1; /* left son of k */ - while (j <= s->heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s->heap_len && - smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller(tree, v, s->heap[j], s->depth)) break; - - /* Exchange v with the smallest son */ - s->heap[k] = s->heap[j]; k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s->heap[k] = v; -} - -/* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ -local void gen_bitlen(s, desc) - deflate_state *s; - tree_desc *desc; /* the tree descriptor */ -{ - ct_data *tree = desc->dyn_tree; - int max_code = desc->max_code; - const ct_data *stree = desc->stat_desc->static_tree; - const intf *extra = desc->stat_desc->extra_bits; - int base = desc->stat_desc->extra_base; - int max_length = desc->stat_desc->max_length; - int h; /* heap index */ - int n, m; /* iterate over the tree elements */ - int bits; /* bit length */ - int xbits; /* extra bits */ - ush f; /* frequency */ - int overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ - - for (h = s->heap_max+1; h < HEAP_SIZE; h++) { - n = s->heap[h]; - bits = tree[tree[n].Dad].Len + 1; - if (bits > max_length) bits = max_length, overflow++; - tree[n].Len = (ush)bits; - /* We overwrite tree[n].Dad which is no longer needed */ - - if (n > max_code) continue; /* not a leaf node */ - - s->bl_count[bits]++; - xbits = 0; - if (n >= base) xbits = extra[n-base]; - f = tree[n].Freq; - s->opt_len += (ulg)f * (bits + xbits); - if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); - } - if (overflow == 0) return; - - Trace((stderr,"\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length-1; - while (s->bl_count[bits] == 0) bits--; - s->bl_count[bits]--; /* move one leaf down the tree */ - s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ - s->bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits != 0; bits--) { - n = s->bl_count[bits]; - while (n != 0) { - m = s->heap[--h]; - if (m > max_code) continue; - if ((unsigned) tree[m].Len != (unsigned) bits) { - Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s->opt_len += ((long)bits - (long)tree[m].Len) - *(long)tree[m].Freq; - tree[m].Len = (ush)bits; - } - n--; - } - } -} - -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -local void gen_codes (tree, max_code, bl_count) - ct_data *tree; /* the tree to decorate */ - int max_code; /* largest code with non zero frequency */ - ushf *bl_count; /* number of codes at each bit length */ -{ - ush next_code[MAX_BITS+1]; /* next code value for each bit length */ - ush code = 0; /* running code value */ - int bits; /* bit index */ - int n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS; bits++) { - next_code[bits] = code = (code + bl_count[bits-1]) << 1; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; - const ct_data *stree = desc->stat_desc->static_tree; - int elems = desc->stat_desc->elems; - int n, m; /* iterate over heap elements */ - int max_code = -1; /* largest code with non zero frequency */ - int node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - * heap[0] is not used. - */ - s->heap_len = 0, s->heap_max = HEAP_SIZE; - - for (n = 0; n < elems; n++) { - if (tree[n].Freq != 0) { - s->heap[++(s->heap_len)] = max_code = n; - s->depth[n] = 0; - } else { - tree[n].Len = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s->heap_len < 2) { - node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); - tree[node].Freq = 1; - s->depth[node] = 0; - s->opt_len--; if (stree) s->static_len -= stree[node].Len; - /* node is 0 or 1 so it does not have extra bits */ - } - desc->max_code = max_code; - - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - pqremove(s, tree, n); /* n = node of least frequency */ - m = s->heap[SMALLEST]; /* m = node of next least frequency */ - - s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ - s->heap[--(s->heap_max)] = m; - - /* Create a new node father of n and m */ - tree[node].Freq = tree[n].Freq + tree[m].Freq; - s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? - s->depth[n] : s->depth[m]) + 1); - tree[n].Dad = tree[m].Dad = (ush)node; -#ifdef DUMP_BL_TREE - if (tree == s->bl_tree) { - fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", - node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); - } -#endif - /* and insert the new node in the heap */ - s->heap[SMALLEST] = node++; - pqdownheap(s, tree, SMALLEST); - - } while (s->heap_len >= 2); - - s->heap[--(s->heap_max)] = s->heap[SMALLEST]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen(s, (tree_desc *)desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes ((ct_data *)tree, max_code, s->bl_count); -} - -/* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ -local void scan_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - if (nextlen == 0) max_count = 138, min_count = 3; - tree[max_code+1].Len = (ush)0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - s->bl_tree[curlen].Freq += count; - } else if (curlen != 0) { - if (curlen != prevlen) s->bl_tree[curlen].Freq++; - s->bl_tree[REP_3_6].Freq++; - } else if (count <= 10) { - s->bl_tree[REPZ_3_10].Freq++; - } else { - s->bl_tree[REPZ_11_138].Freq++; - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ -local void send_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - /* tree[max_code+1].Len = -1; */ /* guard already set */ - if (nextlen == 0) max_count = 138, min_count = 3; - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - do { send_code(s, curlen, s->bl_tree); } while (--count != 0); - - } else if (curlen != 0) { - if (curlen != prevlen) { - send_code(s, curlen, s->bl_tree); count--; - } - Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); - - } else if (count <= 10) { - send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); - - } else { - send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ -local int build_bl_tree(s) - deflate_state *s; -{ - int max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); - scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); - - /* Build the bit length tree: */ - build_tree(s, (tree_desc *)(&(s->bl_desc))); - /* opt_len now includes the length of the tree representations, except - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { - if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; - } - /* Update opt_len to include the bit length tree and counts */ - s->opt_len += 3*(max_blindex+1) + 5+5+4; - Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", - s->opt_len, s->static_len)); - - return max_blindex; -} - -/* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ -local void send_all_trees(s, lcodes, dcodes, blcodes) - deflate_state *s; - int lcodes, dcodes, blcodes; /* number of codes for each tree */ -{ - int rank; /* index in bl_order */ - - Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - "too many codes"); - Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes-1, 5); - send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); - } - Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ - Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ - Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); -} - -/* =========================================================================== - * Send a stored block - */ -void _tr_stored_block(s, buf, stored_len, eof) - deflate_state *s; - charf *buf; /* input block */ - ulg stored_len; /* length of input block */ - int eof; /* true if this is the last block for a file */ -{ - send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ -#ifdef DEBUG - s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; - s->compressed_len += (stored_len + 4) << 3; -#endif - copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ -} - -/* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - * The current inflate code requires 9 bits of lookahead. If the - * last two codes for the previous block (real code plus EOB) were coded - * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode - * the last real code. In this case we send two empty static blocks instead - * of one. (There are no problems if the previous block is stored or fixed.) - * To simplify the code, we assume the worst case of last real code encoded - * on one bit only. - */ -void _tr_align(s) - deflate_state *s; -{ - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); -#ifdef DEBUG - s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ -#endif - bi_flush(s); - /* Of the 10 bits for the empty block, we have already sent - * (10 - bi_valid) bits. The lookahead for the last real code (before - * the EOB of the previous block) was thus at least one plus the length - * of the EOB plus what we have just sent of the empty static block. - */ - if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); -#ifdef DEBUG - s->compressed_len += 10L; -#endif - bi_flush(s); - } - s->last_eob_len = 7; -} - -/* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and output the encoded block to the zip file. - */ -void _tr_flush_block(s, buf, stored_len, eof) - deflate_state *s; - charf *buf; /* input block, or NULL if too old */ - ulg stored_len; /* length of input block */ - int eof; /* true if this is the last block for a file */ -{ - ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - int max_blindex = 0; /* index of last bit length code of non zero freq */ - - /* Build the Huffman trees unless a stored block is forced */ - if (s->level > 0) { - - /* Check if the file is binary or text */ - if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN) - set_data_type(s); - - /* Construct the literal and distance trees */ - build_tree(s, (tree_desc *)(&(s->l_desc))); - Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - - build_tree(s, (tree_desc *)(&(s->d_desc))); - Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(s); - - /* Determine the best encoding. Compute the block lengths in bytes. */ - opt_lenb = (s->opt_len+3+7)>>3; - static_lenb = (s->static_len+3+7)>>3; - - Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - s->last_lit)); - - if (static_lenb <= opt_lenb) opt_lenb = static_lenb; - - } else { - Assert(buf != (char*)0, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } - -#ifdef FORCE_STORED - if (buf != (char*)0) { /* force stored block */ -#else - if (stored_len+4 <= opt_lenb && buf != (char*)0) { - /* 4: two words for the lengths */ -#endif - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - _tr_stored_block(s, buf, stored_len, eof); - -#ifdef FORCE_STATIC - } else if (static_lenb >= 0) { /* force static trees */ -#else - } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { -#endif - send_bits(s, (STATIC_TREES<<1)+eof, 3); - compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); -#ifdef DEBUG - s->compressed_len += 3 + s->static_len; -#endif - } else { - send_bits(s, (DYN_TREES<<1)+eof, 3); - send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, - max_blindex+1); - compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); -#ifdef DEBUG - s->compressed_len += 3 + s->opt_len; -#endif - } - Assert (s->compressed_len == s->bits_sent, "bad compressed size"); - /* The above check is made mod 2^32, for files larger than 512 MB - * and uLong implemented on 32 bits. - */ - init_block(s); - - if (eof) { - bi_windup(s); -#ifdef DEBUG - s->compressed_len += 7; /* align on byte boundary */ -#endif - } - Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, - s->compressed_len-7*eof)); -} - -/* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ -int _tr_tally (s, dist, lc) - deflate_state *s; - unsigned dist; /* distance of matched string */ - unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ -{ - s->d_buf[s->last_lit] = (ush)dist; - s->l_buf[s->last_lit++] = (uch)lc; - if (dist == 0) { - /* lc is the unmatched char */ - s->dyn_ltree[lc].Freq++; - } else { - s->matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - Assert((ush)dist < (ush)MAX_DIST(s) && - (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); - - s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; - s->dyn_dtree[d_code(dist)].Freq++; - } - -#ifdef TRUNCATE_BLOCK - /* Try to guess if it is profitable to stop the current block here */ - if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { - /* Compute an upper bound for the compressed length */ - ulg out_length = (ulg)s->last_lit*8L; - ulg in_length = (ulg)((long)s->strstart - s->block_start); - int dcode; - for (dcode = 0; dcode < D_CODES; dcode++) { - out_length += (ulg)s->dyn_dtree[dcode].Freq * - (5L+extra_dbits[dcode]); - } - out_length >>= 3; - Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", - s->last_lit, in_length, out_length, - 100L - out_length*100L/in_length)); - if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; - } -#endif - return (s->last_lit == s->lit_bufsize-1); - /* We avoid equality with lit_bufsize because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ -} - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -local void compress_block(s, ltree, dtree) - deflate_state *s; - ct_data *ltree; /* literal tree */ - ct_data *dtree; /* distance tree */ -{ - unsigned dist; /* distance of matched string */ - int lc; /* match length or unmatched char (if dist == 0) */ - unsigned lx = 0; /* running index in l_buf */ - unsigned code; /* the code to send */ - int extra; /* number of extra bits to send */ - - if (s->last_lit != 0) do { - dist = s->d_buf[lx]; - lc = s->l_buf[lx++]; - if (dist == 0) { - send_code(s, lc, ltree); /* send a literal byte */ - Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = _length_code[lc]; - send_code(s, code+LITERALS+1, ltree); /* send the length code */ - extra = extra_lbits[code]; - if (extra != 0) { - lc -= base_length[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - Assert (code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra != 0) { - dist -= base_dist[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ - Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, - "pendingBuf overflow"); - - } while (lx < s->last_lit); - - send_code(s, END_BLOCK, ltree); - s->last_eob_len = ltree[END_BLOCK].Len; -} - -/* =========================================================================== - * Set the data type to BINARY or TEXT, using a crude approximation: - * set it to Z_TEXT if all symbols are either printable characters (33 to 255) - * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise. - * IN assertion: the fields Freq of dyn_ltree are set. - */ -local void set_data_type(s) - deflate_state *s; -{ - int n; - - for (n = 0; n < 9; n++) - if (s->dyn_ltree[n].Freq != 0) - break; - if (n == 9) - for (n = 14; n < 32; n++) - if (s->dyn_ltree[n].Freq != 0) - break; - s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY; -} - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -local unsigned bi_reverse(code, len) - unsigned code; /* the value to invert */ - int len; /* its bit length */ -{ - register unsigned res = 0; - do { - res |= code & 1; - code >>= 1, res <<= 1; - } while (--len > 0); - return res >> 1; -} - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -local void bi_flush(s) - deflate_state *s; -{ - if (s->bi_valid == 16) { - put_short(s, s->bi_buf); - s->bi_buf = 0; - s->bi_valid = 0; - } else if (s->bi_valid >= 8) { - put_byte(s, (Byte)s->bi_buf); - s->bi_buf >>= 8; - s->bi_valid -= 8; - } -} - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -local void bi_windup(s) - deflate_state *s; -{ - if (s->bi_valid > 8) { - put_short(s, s->bi_buf); - } else if (s->bi_valid > 0) { - put_byte(s, (Byte)s->bi_buf); - } - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef DEBUG - s->bits_sent = (s->bits_sent+7) & ~7; -#endif -} - -/* =========================================================================== - * Copy a stored block, storing first the length and its - * one's complement if requested. - */ -local void copy_block(s, buf, len, header) - deflate_state *s; - charf *buf; /* the input data */ - unsigned len; /* its length */ - int header; /* true if block header must be written */ -{ - bi_windup(s); /* align on byte boundary */ - s->last_eob_len = 8; /* enough lookahead for inflate */ - - if (header) { - put_short(s, (ush)len); - put_short(s, (ush)~len); -#ifdef DEBUG - s->bits_sent += 2*16; -#endif - } -#ifdef DEBUG - s->bits_sent += (ulg)len<<3; -#endif - while (len--) { - put_byte(s, *buf++); - } -} diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/trees.h b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/trees.h deleted file mode 100644 index 72facf900..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/trees.h +++ /dev/null @@ -1,128 +0,0 @@ -/* header created automatically with -DGEN_TREES_H */ - -local const ct_data static_ltree[L_CODES+2] = { -{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, -{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, -{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, -{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, -{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, -{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, -{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, -{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, -{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, -{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, -{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, -{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, -{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, -{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, -{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, -{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, -{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, -{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, -{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, -{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, -{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, -{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, -{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, -{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, -{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, -{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, -{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, -{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, -{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, -{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, -{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, -{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, -{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, -{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, -{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, -{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, -{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, -{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, -{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, -{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, -{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, -{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, -{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, -{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, -{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, -{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, -{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, -{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, -{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, -{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, -{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, -{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, -{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, -{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, -{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, -{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, -{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, -{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} -}; - -local const ct_data static_dtree[D_CODES] = { -{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, -{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, -{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, -{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, -{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, -{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} -}; - -const uch _dist_code[DIST_CODE_LEN] = { - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, -10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, -11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, -12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, -18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 -}; - -const uch _length_code[MAX_MATCH-MIN_MATCH+1]= { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, -13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, -17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, -19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, -21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, -22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 -}; - -local const int base_length[LENGTH_CODES] = { -0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, -64, 80, 96, 112, 128, 160, 192, 224, 0 -}; - -local const int base_dist[D_CODES] = { - 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, - 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, - 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 -}; - diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/uncompr.c b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/uncompr.c deleted file mode 100644 index 9304b9d1f..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/uncompr.c +++ /dev/null @@ -1,61 +0,0 @@ -/* uncompr.c -- decompress a memory buffer - * Copyright (C) 1995-2003 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -/* =========================================================================== - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be large enough to hold the - entire uncompressed data. (The size of the uncompressed data must have - been saved previously by the compressor and transmitted to the decompressor - by some mechanism outside the scope of this compression library.) - Upon exit, destLen is the actual size of the compressed buffer. - This function can be used to decompress a whole file at once if the - input file is mmap'ed. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted. -*/ -int Q_ZEXPORT uncompress (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ - z_stream stream; - int err; - - stream.next_in = (Bytef*)source; - stream.avail_in = (uInt)sourceLen; - /* Check for source > 64K on 16-bit machine: */ - if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; - - stream.next_out = dest; - stream.avail_out = (uInt)*destLen; - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; - - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - - err = inflateInit(&stream); - if (err != Z_OK) return err; - - err = inflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - inflateEnd(&stream); - if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) - return Z_DATA_ERROR; - return err; - } - *destLen = stream.total_out; - - err = inflateEnd(&stream); - return err; -} diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/zconf.h b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/zconf.h deleted file mode 100644 index 03a9431c8..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/zconf.h +++ /dev/null @@ -1,332 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - */ -#ifdef Z_PREFIX -# define deflateInit_ z_deflateInit_ -# define deflate z_deflate -# define deflateEnd z_deflateEnd -# define inflateInit_ z_inflateInit_ -# define inflate z_inflate -# define inflateEnd z_inflateEnd -# define deflateInit2_ z_deflateInit2_ -# define deflateSetDictionary z_deflateSetDictionary -# define deflateCopy z_deflateCopy -# define deflateReset z_deflateReset -# define deflateParams z_deflateParams -# define deflateBound z_deflateBound -# define deflatePrime z_deflatePrime -# define inflateInit2_ z_inflateInit2_ -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateCopy z_inflateCopy -# define inflateReset z_inflateReset -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# define uncompress z_uncompress -# define adler32 z_adler32 -# define crc32 z_crc32 -# define get_crc_table z_get_crc_table -# define zError z_zError - -# define alloc_func z_alloc_func -# define free_func z_free_func -# define in_func z_in_func -# define out_func z_out_func -# define Byte z_Byte -# define uInt z_uInt -# define uLong z_uLong -# define Bytef z_Bytef -# define charf z_charf -# define intf z_intf -# define uIntf z_uIntf -# define uLongf z_uLongf -# define voidpf z_voidpf -# define voidp z_voidp -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -/* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) -# define NO_DUMMY_DECL -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# include - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ -# include /* for off_t */ -# include /* for SEEK_* and off_t */ -# ifdef VMS -# include /* for off_t */ -# endif -# define z_off_t off_t -#endif -#ifndef SEEK_SET -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif -#ifndef z_off_t -# define z_off_t long -#endif - -#if defined(__OS400__) -# define NO_vsnprintf -#endif - -#if defined(__MVS__) -# define NO_vsnprintf -# ifdef FAR -# undef FAR -# endif -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) -# pragma map(deflateInit_,"DEIN") -# pragma map(deflateInit2_,"DEIN2") -# pragma map(deflateEnd,"DEEND") -# pragma map(deflateBound,"DEBND") -# pragma map(inflateInit_,"ININ") -# pragma map(inflateInit2_,"ININ2") -# pragma map(inflateEnd,"INEND") -# pragma map(inflateSync,"INSY") -# pragma map(inflateSetDictionary,"INSEDI") -# pragma map(compressBound,"CMBND") -# pragma map(inflate_table,"INTABL") -# pragma map(inflate_fast,"INFA") -# pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/zconf.in.h b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/zconf.in.h deleted file mode 100644 index 03a9431c8..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/zconf.in.h +++ /dev/null @@ -1,332 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - */ -#ifdef Z_PREFIX -# define deflateInit_ z_deflateInit_ -# define deflate z_deflate -# define deflateEnd z_deflateEnd -# define inflateInit_ z_inflateInit_ -# define inflate z_inflate -# define inflateEnd z_inflateEnd -# define deflateInit2_ z_deflateInit2_ -# define deflateSetDictionary z_deflateSetDictionary -# define deflateCopy z_deflateCopy -# define deflateReset z_deflateReset -# define deflateParams z_deflateParams -# define deflateBound z_deflateBound -# define deflatePrime z_deflatePrime -# define inflateInit2_ z_inflateInit2_ -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateCopy z_inflateCopy -# define inflateReset z_inflateReset -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# define uncompress z_uncompress -# define adler32 z_adler32 -# define crc32 z_crc32 -# define get_crc_table z_get_crc_table -# define zError z_zError - -# define alloc_func z_alloc_func -# define free_func z_free_func -# define in_func z_in_func -# define out_func z_out_func -# define Byte z_Byte -# define uInt z_uInt -# define uLong z_uLong -# define Bytef z_Bytef -# define charf z_charf -# define intf z_intf -# define uIntf z_uIntf -# define uLongf z_uLongf -# define voidpf z_voidpf -# define voidp z_voidp -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -/* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) -# define NO_DUMMY_DECL -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# include - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ -# include /* for off_t */ -# include /* for SEEK_* and off_t */ -# ifdef VMS -# include /* for off_t */ -# endif -# define z_off_t off_t -#endif -#ifndef SEEK_SET -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif -#ifndef z_off_t -# define z_off_t long -#endif - -#if defined(__OS400__) -# define NO_vsnprintf -#endif - -#if defined(__MVS__) -# define NO_vsnprintf -# ifdef FAR -# undef FAR -# endif -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) -# pragma map(deflateInit_,"DEIN") -# pragma map(deflateInit2_,"DEIN2") -# pragma map(deflateEnd,"DEEND") -# pragma map(deflateBound,"DEBND") -# pragma map(inflateInit_,"ININ") -# pragma map(inflateInit2_,"ININ2") -# pragma map(inflateEnd,"INEND") -# pragma map(inflateSync,"INSY") -# pragma map(inflateSetDictionary,"INSEDI") -# pragma map(compressBound,"CMBND") -# pragma map(inflate_table,"INTABL") -# pragma map(inflate_fast,"INFA") -# pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/zlib.3 b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/zlib.3 deleted file mode 100644 index f6b0da117..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/zlib.3 +++ /dev/null @@ -1,159 +0,0 @@ -.TH ZLIB 3 "18 July 2005" -.SH NAME -zlib \- compression/decompression library -.SH SYNOPSIS -[see -.I zlib.h -for full description] -.SH DESCRIPTION -The -.I zlib -library is a general purpose data compression library. -The code is thread safe. -It provides in-memory compression and decompression functions, -including integrity checks of the uncompressed data. -This version of the library supports only one compression method (deflation) -but other algorithms will be added later -and will have the same stream interface. -.LP -Compression can be done in a single step if the buffers are large enough -(for example if an input file is mmap'ed), -or can be done by repeated calls of the compression function. -In the latter case, -the application must provide more input and/or consume the output -(providing more output space) before each call. -.LP -The library also supports reading and writing files in -.IR gzip (1) -(.gz) format -with an interface similar to that of stdio. -.LP -The library does not install any signal handler. -The decoder checks the consistency of the compressed data, -so the library should never crash even in case of corrupted input. -.LP -All functions of the compression library are documented in the file -.IR zlib.h . -The distribution source includes examples of use of the library -in the files -.I example.c -and -.IR minigzip.c . -.LP -Changes to this version are documented in the file -.I ChangeLog -that accompanies the source, -and are concerned primarily with bug fixes and portability enhancements. -.LP -A Java implementation of -.I zlib -is available in the Java Development Kit 1.1: -.IP -http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html -.LP -A Perl interface to -.IR zlib , -written by Paul Marquess (pmqs@cpan.org), -is available at CPAN (Comprehensive Perl Archive Network) sites, -including: -.IP -http://www.cpan.org/modules/by-module/Compress/ -.LP -A Python interface to -.IR zlib , -written by A.M. Kuchling (amk@magnet.com), -is available in Python 1.5 and later versions: -.IP -http://www.python.org/doc/lib/module-zlib.html -.LP -A -.I zlib -binding for -.IR tcl (1), -written by Andreas Kupries (a.kupries@westend.com), -is availlable at: -.IP -http://www.westend.com/~kupries/doc/trf/man/man.html -.LP -An experimental package to read and write files in .zip format, -written on top of -.I zlib -by Gilles Vollant (info@winimage.com), -is available at: -.IP -http://www.winimage.com/zLibDll/unzip.html -and also in the -.I contrib/minizip -directory of the main -.I zlib -web site. -.SH "SEE ALSO" -The -.I zlib -web site can be found at either of these locations: -.IP -http://www.zlib.org -.br -http://www.gzip.org/zlib/ -.LP -The data format used by the zlib library is described by RFC -(Request for Comments) 1950 to 1952 in the files: -.IP -http://www.ietf.org/rfc/rfc1950.txt (concerning zlib format) -.br -http://www.ietf.org/rfc/rfc1951.txt (concerning deflate format) -.br -http://www.ietf.org/rfc/rfc1952.txt (concerning gzip format) -.LP -These documents are also available in other formats from: -.IP -ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html -.LP -Mark Nelson (markn@ieee.org) wrote an article about -.I zlib -for the Jan. 1997 issue of Dr. Dobb's Journal; -a copy of the article is available at: -.IP -http://dogma.net/markn/articles/zlibtool/zlibtool.htm -.SH "REPORTING PROBLEMS" -Before reporting a problem, -please check the -.I zlib -web site to verify that you have the latest version of -.IR zlib ; -otherwise, -obtain the latest version and see if the problem still exists. -Please read the -.I zlib -FAQ at: -.IP -http://www.gzip.org/zlib/zlib_faq.html -.LP -before asking for help. -Send questions and/or comments to zlib@gzip.org, -or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). -.SH AUTHORS -Version 1.2.3 -Copyright (C) 1995-2005 Jean-loup Gailly (jloup@gzip.org) -and Mark Adler (madler@alumni.caltech.edu). -.LP -This software is provided "as-is," -without any express or implied warranty. -In no event will the authors be held liable for any damages -arising from the use of this software. -See the distribution directory with respect to requirements -governing redistribution. -The deflate format used by -.I zlib -was defined by Phil Katz. -The deflate and -.I zlib -specifications were written by L. Peter Deutsch. -Thanks to all the people who reported problems and suggested various -improvements in -.IR zlib ; -who are too numerous to cite here. -.LP -UNIX manual page by R. P. C. Rodgers, -U.S. National Library of Medicine (rodgers@nlm.nih.gov). -.\" end of man page diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/zlib.h b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/zlib.h deleted file mode 100644 index 9e5b46727..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/zlib.h +++ /dev/null @@ -1,1368 +0,0 @@ -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.3, July 18th, 2005 - - Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - - - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt - (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). -*/ - -#ifndef ZLIB_H -#define ZLIB_H - -#include "zconf.h" -#include "qconfig.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define ZLIB_VERSION "1.2.3" -#define ZLIB_VERNUM 0x1230 - -#if defined(QT_VISIBILITY_AVAILABLE) -# define Q_ZEXPORT __attribute__((visibility("default"))) -#else -# ifdef QT_MAKEDLL -# define Q_ZEXPORT __declspec(dllexport) -# else -# define Q_ZEXPORT ZEXPORT -# endif -#endif - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed - data. This version of the library supports only one compression method - (deflation) but other algorithms will be added later and will have the same - stream interface. - - Compression can be done in a single step if the buffers are large - enough (for example if an input file is mmap'ed), or can be done by - repeated calls of the compression function. In the latter case, the - application must provide more input and/or consume the output - (providing more output space) before each call. - - The compressed data format used by default by the in-memory functions is - the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped - around a deflate stream, which is itself documented in RFC 1951. - - The library also supports reading and writing files in gzip (.gz) format - with an interface similar to that of stdio using the functions that start - with "gz". The gzip format is different from the zlib format. gzip is a - gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. - - This library can optionally read and write gzip streams in memory as well. - - The zlib format was designed to be compact and fast for use in memory - and on communications channels. The gzip format was designed for single- - file compression on file systems, has a larger header than zlib to maintain - directory information, and uses a different, slower check method than zlib. - - The library does not install any signal handler. The decoder checks - the consistency of the compressed data, so the library should never - crash even in case of corrupted input. -*/ - -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address)); - -struct internal_state; - -typedef struct z_stream_s { - Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total nb of input bytes read so far */ - - Bytef *next_out; /* next output byte should be put there */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total nb of bytes output so far */ - - char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidpf opaque; /* private data object passed to zalloc and zfree */ - - int data_type; /* best guess about the data type: binary or text */ - uLong adler; /* adler32 value of the uncompressed data */ - uLong reserved; /* reserved for future use */ -} z_stream; - -typedef z_stream FAR *z_streamp; - -/* - gzip header information passed to and from zlib routines. See RFC 1952 - for more details on the meanings of these fields. -*/ -typedef struct gz_header_s { - int text; /* true if compressed data believed to be text */ - uLong time; /* modification time */ - int xflags; /* extra flags (not used when writing a gzip file) */ - int os; /* operating system */ - Bytef *extra; /* pointer to extra field or Z_NULL if none */ - uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ - uInt extra_max; /* space at extra (only when reading header) */ - Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ - uInt name_max; /* space at name (only when reading header) */ - Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ - uInt comm_max; /* space at comment (only when reading header) */ - int hcrc; /* true if there was or will be a header crc */ - int done; /* true when done reading gzip header (not used - when writing a gzip file) */ -} gz_header; - -typedef gz_header FAR *gz_headerp; - -/* - The application must update next_in and avail_in when avail_in has - dropped to zero. It must update next_out and avail_out when avail_out - has dropped to zero. The application must initialize zalloc, zfree and - opaque before calling the init function. All other fields are set by the - compression library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - If zlib is used in a multi-threaded application, zalloc and zfree must be - thread safe. - - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this - if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, - pointers returned by zalloc for objects of exactly 65536 bytes *must* - have their offset normalized to zero. The default allocation function - provided by this library ensures this (see zutil.c). To reduce memory - requirements and avoid any allocation of 64K objects, at the expense of - compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or - progress reports. After compression, total_in holds the total size of - the uncompressed data and may be saved for use in the decompressor - (particularly if the decompressor wants to decompress everything in - a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ -#define Z_SYNC_FLUSH 2 -#define Z_FULL_FLUSH 3 -#define Z_FINISH 4 -#define Z_BLOCK 5 -/* Allowed flush values; see deflate() and inflate() below for details */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_NEED_DICT 2 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -#define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative - * values are errors, positive values are used for special but normal events. - */ - -#define Z_NO_COMPRESSION 0 -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_RLE 3 -#define Z_FIXED 4 -#define Z_DEFAULT_STRATEGY 0 -/* compression strategy; see deflateInit2() below for details */ - -#define Z_BINARY 0 -#define Z_TEXT 1 -#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ -#define Z_UNKNOWN 2 -/* Possible values of the data_type field (though see inflate()) */ - -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported in this version) */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -#define zlib_version zlibVersion() -/* for compatibility with versions < 1.0.2 */ - - /* basic functions */ - -ZEXTERN Q_ZEXPORT const char * zlibVersion OF((void)); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is - not compatible with the zlib.h header file used by the application. - This check is automatically made by deflateInit and inflateInit. - */ - -/* -ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); - - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. - If zalloc and zfree are set to Z_NULL, deflateInit updates them to - use default allocation functions. - - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at - all (the input data is simply copied a block at a time). - Z_DEFAULT_COMPRESSION requests a default compromise between speed and - compression (currently equivalent to level 6). - - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if level is not a valid compression level, - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). - msg is set to null if there is no error message. deflateInit does not - perform any compression: this will be done by deflate(). -*/ - - -ZEXTERN int Q_ZEXPORT deflate OF((z_streamp strm, int flush)); -/* - deflate compresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce some - output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. deflate performs one or both of the - following actions: - - - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in and avail_in are updated and - processing will resume at this point for the next call of deflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. - Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary (in interactive applications). - Some output may be provided even if flush is not set. - - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating avail_in or avail_out accordingly; avail_out - should never be zero before the call. The application can consume the - compressed output when it wants, for example when the output buffer is full - (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK - and with zero avail_out, it must be called again after making room in the - output buffer because there might be more output pending. - - Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to - decide how much data to accumualte before producing output, in order to - maximize compression. - - If the parameter flush is set to Z_SYNC_FLUSH, all pending output is - flushed to the output buffer and the output is aligned on a byte boundary, so - that the decompressor can get all input data available so far. (In particular - avail_in is zero after the call if enough output space has been provided - before the call.) Flushing may degrade compression for some compression - algorithms and so it should be used only when necessary. - - If flush is set to Z_FULL_FLUSH, all output is flushed as with - Z_SYNC_FLUSH, and the compression state is reset so that decompression can - restart from this point if previous compressed data has been damaged or if - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade - compression. - - If deflate returns with avail_out == 0, this function must be called again - with the same value of the flush parameter and more output space (updated - avail_out), until the flush is complete (deflate returns with non-zero - avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that - avail_out is greater than six to avoid repeated flush markers due to - avail_out == 0 on return. - - If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there - was enough output space; if deflate returns with Z_OK, this function must be - called again with Z_FINISH and more output space (updated avail_out) but no - more input data, until it returns with Z_STREAM_END or an error. After - deflate has returned Z_STREAM_END, the only possible operations on the - stream are deflateReset or deflateEnd. - - Z_FINISH can be used immediately after deflateInit if all the compression - is to be done in a single step. In this case, avail_out must be at least - the value returned by deflateBound (see below). If deflate does not return - Z_STREAM_END, then it must be called again as described above. - - deflate() sets strm->adler to the adler32 checksum of all input read - so far (that is, total_in bytes). - - deflate() may update strm->data_type if it can make a good guess about - the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered - binary. This field is only for information purposes and does not affect - the compression algorithm in any manner. - - deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible - (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not - fatal, and deflate() can be called again with more input and more output - space to continue compressing. -*/ - - -ZEXTERN int Q_ZEXPORT deflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, - msg may be set but then points to a static string (which must not be - deallocated). -*/ - - -/* -ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); - - Initializes the internal stream state for decompression. The fields - next_in, avail_in, zalloc, zfree and opaque must be initialized before by - the caller. If next_in is not Z_NULL and avail_in is large enough (the exact - value depends on the compression method), inflateInit determines the - compression method from the zlib header and allocates all data structures - accordingly; otherwise the allocation will be deferred to the first call of - inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to - use default allocation functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller. msg is set to null if there is no error - message. inflateInit does not perform any decompression apart from reading - the zlib header if present: this will be done by inflate(). (So next_in and - avail_in may be modified, but next_out and avail_out are unchanged.) -*/ - - -ZEXTERN int Q_ZEXPORT inflate OF((z_streamp strm, int flush)); -/* - inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. inflate performs one or both of the - following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing - will resume at this point for the next call of inflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there - is no more input data or no more space in the output buffer (see below - about the flush parameter). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating the next_* and avail_* values accordingly. - The application can consume the uncompressed output when it wants, for - example when the output buffer is full (avail_out == 0), or after each - call of inflate(). If inflate returns Z_OK and with zero avail_out, it - must be called again after making room in the output buffer because there - might be more output pending. - - The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, - Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much - output as possible to the output buffer. Z_BLOCK requests that inflate() stop - if and when it gets to the next deflate block boundary. When decoding the - zlib or gzip format, this will cause inflate() to return immediately after - the header and before the first block. When doing a raw inflate, inflate() - will go ahead and process the first block, and will return when it gets to - the end of that block, or when it runs out of data. - - The Z_BLOCK option assists in appending to or combining deflate streams. - Also to assist in this, on return inflate() will set strm->data_type to the - number of unused bits in the last byte taken from strm->next_in, plus 64 - if inflate() is currently decoding the last block in the deflate stream, - plus 128 if inflate() returned immediately after decoding an end-of-block - code or decoding the complete header up to just before the first byte of the - deflate stream. The end-of-block will not be indicated until all of the - uncompressed data from that block has been written to strm->next_out. The - number of unused bits may in general be greater than seven, except when - bit 7 of data_type is set, in which case the number of unused bits will be - less than eight. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step - (a single call of inflate), the parameter flush should be set to - Z_FINISH. In this case all pending input is processed and all pending - output is flushed; avail_out must be large enough to hold all the - uncompressed data. (The size of the uncompressed data may have been saved - by the compressor for this purpose.) The next operation on this stream must - be inflateEnd to deallocate the decompression state. The use of Z_FINISH - is never required, but can be used to inform inflate that a faster approach - may be used for the single inflate() call. - - In this implementation, inflate() always flushes as much output as - possible to the output buffer, and always uses the faster approach on the - first call. So the only effect of the flush parameter in this implementation - is on the return value of inflate(), as noted below, or when it returns early - because Z_BLOCK is used. - - If a preset dictionary is needed after this call (see inflateSetDictionary - below), inflate sets strm->adler to the adler32 checksum of the dictionary - chosen by the compressor and returns Z_NEED_DICT; otherwise it sets - strm->adler to the adler32 checksum of all output produced so far (that is, - total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described - below. At the end of the stream, inflate() checks that its computed adler32 - checksum is equal to that saved by the compressor and returns Z_STREAM_END - only if the checksum is correct. - - inflate() will decompress and check either zlib-wrapped or gzip-wrapped - deflate data. The header type is detected automatically. Any information - contained in the gzip header is not retained, so applications that need that - information should instead use raw inflate, see inflateInit2() below, or - inflateBack() and perform their own processing of the gzip header and - trailer. - - inflate() returns Z_OK if some progress has been made (more input processed - or more output produced), Z_STREAM_END if the end of the compressed data has - been reached and all uncompressed output has been produced, Z_NEED_DICT if a - preset dictionary is needed at this point, Z_DATA_ERROR if the input data was - corrupted (input stream not conforming to the zlib format or incorrect check - value), Z_STREAM_ERROR if the stream structure was inconsistent (for example - if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, - Z_BUF_ERROR if no progress is possible or if there was not enough room in the - output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and - inflate() can be called again with more input and more output space to - continue decompressing. If Z_DATA_ERROR is returned, the application may then - call inflateSync() to look for a good compression block if a partial recovery - of the data is desired. -*/ - - -ZEXTERN int Q_ZEXPORT inflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a - static string (which must not be deallocated). -*/ - - /* Advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -/* -ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy)); - - This is another version of deflateInit with more compression options. The - fields next_in, zalloc, zfree and opaque must be initialized before by - the caller. - - The method parameter is the compression method. It must be Z_DEFLATED in - this version of the library. - - The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library. Larger values of this parameter result in better - compression at the expense of memory usage. The default value is 15 if - deflateInit is used instead. - - windowBits can also be -8..-15 for raw deflate. In this case, -windowBits - determines the window size. deflate() will then generate raw deflate data - with no zlib header or trailer, and will not compute an adler32 check value. - - windowBits can also be greater than 15 for optional gzip encoding. Add - 16 to windowBits to write a simple gzip header and trailer around the - compressed data instead of a zlib wrapper. The gzip header will have no - file name, no extra data, no comment, no modification time (set to zero), - no header crc, and the operating system will be set to 255 (unknown). If a - gzip stream is being written, strm->adler is a crc32 instead of an adler32. - - The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but - is slow and reduces compression ratio; memLevel=9 uses maximum memory - for optimal speed. The default value is 8. See zconf.h for total memory - usage as a function of windowBits and memLevel. - - The strategy parameter is used to tune the compression algorithm. Use the - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a - filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no - string match), or Z_RLE to limit match distances to one (run-length - encoding). Filtered data consists mostly of small values with a somewhat - random distribution. In this case, the compression algorithm is tuned to - compress them better. The effect of Z_FILTERED is to force more Huffman - coding and less string matching; it is somewhat intermediate between - Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as - Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy - parameter only affects the compression ratio but not the correctness of the - compressed output even if it is not set appropriately. Z_FIXED prevents the - use of dynamic Huffman codes, allowing for a simpler decoder for special - applications. - - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid - method). msg is set to null if there is no error message. deflateInit2 does - not perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int Q_ZEXPORT deflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the compression dictionary from the given byte sequence - without producing any compressed output. This function must be called - immediately after deflateInit, deflateInit2 or deflateReset, before any - call of deflate. The compressor and decompressor must use exactly the same - dictionary (see inflateSetDictionary). - - The dictionary should consist of strings (byte sequences) that are likely - to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a - dictionary is most useful when the data to be compressed is short and can be - predicted with good accuracy; the data can then be compressed better than - with the default empty dictionary. - - Depending on the size of the compression data structures selected by - deflateInit or deflateInit2, a part of the dictionary may in effect be - discarded, for example if the dictionary is larger than the window size in - deflate or deflate2. Thus the strings most likely to be useful should be - put at the end of the dictionary, not at the front. In addition, the - current implementation of deflate will use at most the window size minus - 262 bytes of the provided dictionary. - - Upon return of this function, strm->adler is set to the adler32 value - of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The adler32 value - applies to the whole dictionary even if only a subset of the dictionary is - actually used by the compressor.) If a raw deflate was requested, then the - adler32 value is not computed and strm->adler is not set. - - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (such as NULL dictionary) or the stream state is - inconsistent (for example if deflate has already been called for this stream - or if the compression method is bsort). deflateSetDictionary does not - perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int Q_ZEXPORT deflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when several compression strategies will be - tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed - by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and - can consume lots of memory. - - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int Q_ZEXPORT deflateReset OF((z_streamp strm)); -/* - This function is equivalent to deflateEnd followed by deflateInit, - but does not free and reallocate all the internal compression state. - The stream will keep the same compression level and any other attributes - that may have been set by deflateInit2. - - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). -*/ - -ZEXTERN int Q_ZEXPORT deflateParams OF((z_streamp strm, - int level, - int strategy)); -/* - Dynamically update the compression level and compression strategy. The - interpretation of level and strategy is as in deflateInit2. This can be - used to switch between compression and straight copy of the input data, or - to switch to a different kind of input data requiring a different - strategy. If the compression level is changed, the input available so far - is compressed with the old level (and may be flushed); the new level will - take effect only at the next call of deflate(). - - Before the call of deflateParams, the stream state must be set as for - a call of deflate(), since the currently available input may have to - be compressed and flushed. In particular, strm->avail_out must be non-zero. - - deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source - stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR - if strm->avail_out was zero. -*/ - -ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, - int good_length, - int max_lazy, - int nice_length, - int max_chain)); -/* - Fine tune deflate's internal compression parameters. This should only be - used by someone who understands the algorithm used by zlib's deflate for - searching for the best matching string, and even then only by the most - fanatic optimizer trying to squeeze out the last compressed bit for their - specific input data. Read the deflate.c source code for the meaning of the - max_lazy, good_length, nice_length, and max_chain parameters. - - deflateTune() can be called after deflateInit() or deflateInit2(), and - returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. - */ - -ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, - uLong sourceLen)); -/* - deflateBound() returns an upper bound on the compressed size after - deflation of sourceLen bytes. It must be called after deflateInit() - or deflateInit2(). This would be used to allocate an output buffer - for deflation in a single pass, and so would be called before deflate(). -*/ - -ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - deflatePrime() inserts bits in the deflate output stream. The intent - is that this function is used to start off the deflate output with the - bits leftover from a previous deflate stream when appending to it. As such, - this function can only be used for raw deflate, and must be used before the - first deflate() call after a deflateInit2() or deflateReset(). bits must be - less than or equal to 16, and that many of the least significant bits of - value will be inserted in the output. - - deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, - gz_headerp head)); -/* - deflateSetHeader() provides gzip header information for when a gzip - stream is requested by deflateInit2(). deflateSetHeader() may be called - after deflateInit2() or deflateReset() and before the first call of - deflate(). The text, time, os, extra field, name, and comment information - in the provided gz_header structure are written to the gzip header (xflag is - ignored -- the extra flags are set according to the compression level). The - caller must assure that, if not Z_NULL, name and comment are terminated with - a zero byte, and that if extra is not Z_NULL, that extra_len bytes are - available there. If hcrc is true, a gzip header crc is included. Note that - the current versions of the command-line version of gzip (up through version - 1.3.x) do not support header crc's, and will report that it is a "multi-part - gzip file" and give up. - - If deflateSetHeader is not used, the default gzip header has text false, - the time set to zero, and os set to 255, with no extra, name, or comment - fields. The gzip header is returned to the default state by deflateReset(). - - deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, - int windowBits)); - - This is another version of inflateInit with an extra parameter. The - fields next_in, avail_in, zalloc, zfree and opaque must be initialized - before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library. The default value is 15 if inflateInit is used - instead. windowBits must be greater than or equal to the windowBits value - provided to deflateInit2() while compressing, or it must be equal to 15 if - deflateInit2() was not used. If a compressed stream with a larger window - size is given as input, inflate() will return with the error code - Z_DATA_ERROR instead of trying to allocate a larger window. - - windowBits can also be -8..-15 for raw inflate. In this case, -windowBits - determines the window size. inflate() will then process raw deflate data, - not looking for a zlib or gzip header, not generating a check value, and not - looking for any check values for comparison at the end of the stream. This - is for use with other formats that use the deflate compressed data format - such as zip. Those formats provide their own check values. If a custom - format is developed using the raw deflate format for compressed data, it is - recommended that a check value such as an adler32 or a crc32 be applied to - the uncompressed data as is done in the zlib, gzip, and zip formats. For - most applications, the zlib format should be used as is. Note that comments - above on the use in deflateInit2() applies to the magnitude of windowBits. - - windowBits can also be greater than 15 for optional gzip decoding. Add - 32 to windowBits to enable zlib and gzip decoding with automatic header - detection, or add 16 to decode only the gzip format (the zlib format will - return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is - a crc32 instead of an adler32. - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg - is set to null if there is no error message. inflateInit2 does not perform - any decompression apart from reading the zlib header if present: this will - be done by inflate(). (So next_in and avail_in may be modified, but next_out - and avail_out are unchanged.) -*/ - -ZEXTERN int Q_ZEXPORT inflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the decompression dictionary from the given uncompressed byte - sequence. This function must be called immediately after a call of inflate, - if that call returned Z_NEED_DICT. The dictionary chosen by the compressor - can be determined from the adler32 value returned by that call of inflate. - The compressor and decompressor must use exactly the same dictionary (see - deflateSetDictionary). For raw inflate, this function can be called - immediately after inflateInit2() or inflateReset() and before any call of - inflate() to set the dictionary. The application must insure that the - dictionary that was used for compression is provided. - - inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a - parameter is invalid (such as NULL dictionary) or the stream state is - inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect adler32 value). inflateSetDictionary does not - perform any decompression: this will be done by subsequent calls of - inflate(). -*/ - -ZEXTERN int Q_ZEXPORT inflateSync OF((z_streamp strm)); -/* - Skips invalid compressed data until a full flush point (see above the - description of deflate with Z_FULL_FLUSH) can be found, or until all - available input is skipped. No output is provided. - - inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR - if no more input was provided, Z_DATA_ERROR if no flush point has been found, - or Z_STREAM_ERROR if the stream structure was inconsistent. In the success - case, the application may save the current current value of total_in which - indicates where valid compressed data was found. In the error case, the - application may repeatedly call inflateSync, providing more input each time, - until success or end of the input data. -*/ - -ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when randomly accessing a large stream. The - first pass through the stream can periodically record the inflate state, - allowing restarting inflate at those points when randomly accessing the - stream. - - inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int Q_ZEXPORT inflateReset OF((z_streamp strm)); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate all the internal decompression state. - The stream will keep attributes that may have been set by inflateInit2. - - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). -*/ - -ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - This function inserts bits in the inflate input stream. The intent is - that this function is used to start inflating at a bit position in the - middle of a byte. The provided bits will be used before any bytes are used - from next_in. This function should only be used with raw inflate, and - should be used before the first inflate() call after inflateInit2() or - inflateReset(). bits must be less than or equal to 16, and that many of the - least significant bits of value will be inserted in the input. - - inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, - gz_headerp head)); -/* - inflateGetHeader() requests that gzip header information be stored in the - provided gz_header structure. inflateGetHeader() may be called after - inflateInit2() or inflateReset(), and before the first call of inflate(). - As inflate() processes the gzip stream, head->done is zero until the header - is completed, at which time head->done is set to one. If a zlib stream is - being decoded, then head->done is set to -1 to indicate that there will be - no gzip header information forthcoming. Note that Z_BLOCK can be used to - force inflate() to return immediately after header processing is complete - and before any actual data is decompressed. - - The text, time, xflags, and os fields are filled in with the gzip header - contents. hcrc is set to true if there is a header CRC. (The header CRC - was valid if done is set to one.) If extra is not Z_NULL, then extra_max - contains the maximum number of bytes to write to extra. Once done is true, - extra_len contains the actual extra field length, and extra contains the - extra field, or that field truncated if extra_max is less than extra_len. - If name is not Z_NULL, then up to name_max characters are written there, - terminated with a zero unless the length is greater than name_max. If - comment is not Z_NULL, then up to comm_max characters are written there, - terminated with a zero unless the length is greater than comm_max. When - any of extra, name, or comment are not Z_NULL and the respective field is - not present in the header, then that field is set to Z_NULL to signal its - absence. This allows the use of deflateSetHeader() with the returned - structure to duplicate the header. However if those fields are set to - allocated memory, then the application will need to save those pointers - elsewhere so that they can be eventually freed. - - If inflateGetHeader is not used, then the header information is simply - discarded. The header is always checked for validity, including the header - CRC if present. inflateReset() will reset the process to discard the header - information. The application would need to call inflateGetHeader() again to - retrieve the header from the next gzip stream. - - inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, - unsigned char FAR *window)); - - Initialize the internal stream state for decompression using inflateBack() - calls. The fields zalloc, zfree and opaque in strm must be initialized - before the call. If zalloc and zfree are Z_NULL, then the default library- - derived memory allocation routines are used. windowBits is the base two - logarithm of the window size, in the range 8..15. window is a caller - supplied buffer of that size. Except for special applications where it is - assured that deflate was used with small window sizes, windowBits must be 15 - and a 32K byte window must be supplied to be able to decompress general - deflate streams. - - See inflateBack() for the usage of these routines. - - inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of - the paramaters are invalid, Z_MEM_ERROR if the internal state could not - be allocated, or Z_VERSION_ERROR if the version of the library does not - match the version of the header file. -*/ - -typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); -typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); - -ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, - in_func in, void FAR *in_desc, - out_func out, void FAR *out_desc)); -/* - inflateBack() does a raw inflate with a single call using a call-back - interface for input and output. This is more efficient than inflate() for - file i/o applications in that it avoids copying between the output and the - sliding window by simply making the window itself the output buffer. This - function trusts the application to not change the output buffer passed by - the output function, at least until inflateBack() returns. - - inflateBackInit() must be called first to allocate the internal state - and to initialize the state with the user-provided window buffer. - inflateBack() may then be used multiple times to inflate a complete, raw - deflate stream with each call. inflateBackEnd() is then called to free - the allocated state. - - A raw deflate stream is one with no zlib or gzip header or trailer. - This routine would normally be used in a utility that reads zip or gzip - files and writes out uncompressed files. The utility would decode the - header and process the trailer on its own, hence this routine expects - only the raw deflate stream to decompress. This is different from the - normal behavior of inflate(), which expects either a zlib or gzip header and - trailer around the deflate stream. - - inflateBack() uses two subroutines supplied by the caller that are then - called by inflateBack() for input and output. inflateBack() calls those - routines until it reads a complete deflate stream and writes out all of the - uncompressed data, or until it encounters an error. The function's - parameters and return types are defined above in the in_func and out_func - typedefs. inflateBack() will call in(in_desc, &buf) which should return the - number of bytes of provided input, and a pointer to that input in buf. If - there is no input available, in() must return zero--buf is ignored in that - case--and inflateBack() will return a buffer error. inflateBack() will call - out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() - should return zero on success, or non-zero on failure. If out() returns - non-zero, inflateBack() will return with an error. Neither in() nor out() - are permitted to change the contents of the window provided to - inflateBackInit(), which is also the buffer that out() uses to write from. - The length written by out() will be at most the window size. Any non-zero - amount of input may be provided by in(). - - For convenience, inflateBack() can be provided input on the first call by - setting strm->next_in and strm->avail_in. If that input is exhausted, then - in() will be called. Therefore strm->next_in must be initialized before - calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called - immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in - must also be initialized, and then if strm->avail_in is not zero, input will - initially be taken from strm->next_in[0 .. strm->avail_in - 1]. - - The in_desc and out_desc parameters of inflateBack() is passed as the - first parameter of in() and out() respectively when they are called. These - descriptors can be optionally used to pass any information that the caller- - supplied in() and out() functions need to do their job. - - On return, inflateBack() will set strm->next_in and strm->avail_in to - pass back any unused input that was provided by the last in() call. The - return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR - if in() or out() returned an error, Z_DATA_ERROR if there was a format - error in the deflate stream (in which case strm->msg is set to indicate the - nature of the error), or Z_STREAM_ERROR if the stream was not properly - initialized. In the case of Z_BUF_ERROR, an input or output error can be - distinguished using strm->next_in which will be Z_NULL only if in() returned - an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to - out() returning non-zero. (in() will always be called before out(), so - strm->next_in is assured to be defined if out() returns non-zero.) Note - that inflateBack() cannot return Z_OK. -*/ - -ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); -/* - All memory allocated by inflateBackInit() is freed. - - inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream - state was inconsistent. -*/ - -ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); -/* Return flags indicating compile-time options. - - Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: - 1.0: size of uInt - 3.2: size of uLong - 5.4: size of voidpf (pointer) - 7.6: size of z_off_t - - Compiler, assembler, and debug options: - 8: DEBUG - 9: ASMV or ASMINF -- use ASM code - 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention - 11: 0 (reserved) - - One-time table building (smaller code, but not thread-safe if true): - 12: BUILDFIXED -- build static block decoding tables when needed - 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed - 14,15: 0 (reserved) - - Library content (indicates missing functionality): - 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking - deflate code when not needed) - 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect - and decode gzip streams (to avoid linking crc code) - 18-19: 0 (reserved) - - Operation variations (changes in library functionality): - 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate - 21: FASTEST -- deflate algorithm with only one, lowest compression level - 22,23: 0 (reserved) - - The sprintf variant used by gzprintf (zero is best): - 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format - 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! - 26: 0 = returns value, 1 = void -- 1 means inferred string length returned - - Remainder: - 27-31: 0 (reserved) - */ - - - /* utility functions */ - -/* - The following utility functions are implemented on top of the - basic stream-oriented functions. To simplify the interface, some - default options are assumed (compression level and memory usage, - standard memory allocation functions). The source code of these - utility functions can easily be modified if you need special options. -*/ - -ZEXTERN int Q_ZEXPORT compress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Compresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be at least the value returned - by compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - This function can be used to compress a whole file at once if the - input file is mmap'ed. - compress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer. -*/ - -ZEXTERN int Q_ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen, - int level)); -/* - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ - -ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); -/* - compressBound() returns an upper bound on the compressed size after - compress() or compress2() on sourceLen bytes. It would be used before - a compress() or compress2() call to allocate the destination buffer. -*/ - -ZEXTERN int Q_ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be large enough to hold the - entire uncompressed data. (The size of the uncompressed data must have - been saved previously by the compressor and transmitted to the decompressor - by some mechanism outside the scope of this compression library.) - Upon exit, destLen is the actual size of the compressed buffer. - This function can be used to decompress a whole file at once if the - input file is mmap'ed. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. -*/ - - -typedef voidp gzFile; - -ZEXTERN gzFile Q_ZEXPORT gzopen OF((const char *path, const char *mode)); -/* - Opens a gzip (.gz) file for reading or writing. The mode parameter - is as in fopen ("rb" or "wb") but can also include a compression level - ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for - Huffman only compression as in "wb1h", or 'R' for run-length encoding - as in "wb1R". (See the description of deflateInit2 for more information - about the strategy parameter.) - - gzopen can be used to read a file which is not in gzip format; in this - case gzread will directly read from the file without decompression. - - gzopen returns NULL if the file could not be opened or if there was - insufficient memory to allocate the (de)compression state; errno - can be checked to distinguish the two cases (if errno is zero, the - zlib error is Z_MEM_ERROR). */ - -ZEXTERN gzFile Q_ZEXPORT gzdopen OF((int fd, const char *mode)); -/* - gzdopen() associates a gzFile with the file descriptor fd. File - descriptors are obtained from calls like open, dup, creat, pipe or - fileno (in the file has been previously opened with fopen). - The mode parameter is as in gzopen. - The next call of gzclose on the returned gzFile will also close the - file descriptor fd, just like fclose(fdopen(fd), mode) closes the file - descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). - gzdopen returns NULL if there was insufficient memory to allocate - the (de)compression state. -*/ - -ZEXTERN int Q_ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); -/* - Dynamically update the compression level or strategy. See the description - of deflateInit2 for the meaning of these parameters. - gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not - opened for writing. -*/ - -ZEXTERN int Q_ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); -/* - Reads the given number of uncompressed bytes from the compressed file. - If the input file was not in gzip format, gzread copies the given number - of bytes into the buffer. - gzread returns the number of uncompressed bytes actually read (0 for - end of file, -1 for error). */ - -ZEXTERN int Q_ZEXPORT gzwrite OF((gzFile file, - voidpc buf, unsigned len)); -/* - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of uncompressed bytes actually written - (0 in case of error). -*/ - -ZEXTERN int Q_ZEXPORT gzprintf OF((gzFile file, const char *format, ...)); -/* - Converts, formats, and writes the args to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written (0 in case of error). The number of - uncompressed bytes written is limited to 4095. The caller should assure that - this limit is not exceeded. If it is exceeded, then gzprintf() will return - return an error (0) with nothing written. In this case, there may also be a - buffer overflow with unpredictable consequences, which is possible only if - zlib was compiled with the insecure functions sprintf() or vsprintf() - because the secure snprintf() or vsnprintf() functions were not available. -*/ - -ZEXTERN int Q_ZEXPORT gzputs OF((gzFile file, const char *s)); -/* - Writes the given null-terminated string to the compressed file, excluding - the terminating null character. - gzputs returns the number of characters written, or -1 in case of error. -*/ - -ZEXTERN Q_ZEXPORT char * gzgets OF((gzFile file, char *buf, int len)); -/* - Reads bytes from the compressed file until len-1 characters are read, or - a newline character is read and transferred to buf, or an end-of-file - condition is encountered. The string is then terminated with a null - character. - gzgets returns buf, or Z_NULL in case of error. -*/ - -ZEXTERN int Q_ZEXPORT gzputc OF((gzFile file, int c)); -/* - Writes c, converted to an unsigned char, into the compressed file. - gzputc returns the value that was written, or -1 in case of error. -*/ - -ZEXTERN int Q_ZEXPORT gzgetc OF((gzFile file)); -/* - Reads one byte from the compressed file. gzgetc returns this byte - or -1 in case of end of file or error. -*/ - -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); -/* - Push one character back onto the stream to be read again later. - Only one character of push-back is allowed. gzungetc() returns the - character pushed, or -1 on failure. gzungetc() will fail if a - character has been pushed but not read yet, or if c is -1. The pushed - character will be discarded if the stream is repositioned with gzseek() - or gzrewind(). -*/ - -ZEXTERN int Q_ZEXPORT gzflush OF((gzFile file, int flush)); -/* - Flushes all pending output into the compressed file. The parameter - flush is as in the deflate() function. The return value is the zlib - error number (see function gzerror below). gzflush returns Z_OK if - the flush parameter is Z_FINISH and all output could be flushed. - gzflush should be called only when strictly necessary because it can - degrade compression. -*/ - -ZEXTERN z_off_t Q_ZEXPORT gzseek OF((gzFile file, - z_off_t offset, int whence)); -/* - Sets the starting position for the next gzread or gzwrite on the - given compressed file. The offset represents a number of bytes in the - uncompressed data stream. The whence parameter is defined as in lseek(2); - the value SEEK_END is not supported. - If the file is opened for reading, this function is emulated but can be - extremely slow. If the file is opened for writing, only forward seeks are - supported; gzseek then compresses a sequence of zeroes up to the new - starting position. - - gzseek returns the resulting offset location as measured in bytes from - the beginning of the uncompressed stream, or -1 in case of error, in - particular if the file is opened for writing and the new starting position - would be before the current position. -*/ - -ZEXTERN int Q_ZEXPORT gzrewind OF((gzFile file)); -/* - Rewinds the given file. This function is supported only for reading. - - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) -*/ - -ZEXTERN z_off_t Q_ZEXPORT gztell OF((gzFile file)); -/* - Returns the starting position for the next gzread or gzwrite on the - given compressed file. This position represents a number of bytes in the - uncompressed data stream. - - gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) -*/ - -ZEXTERN int Q_ZEXPORT gzeof OF((gzFile file)); -/* - Returns 1 when EOF has previously been detected reading the given - input stream, otherwise zero. -*/ - -ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); -/* - Returns 1 if file is being read directly without decompression, otherwise - zero. -*/ - -ZEXTERN int Q_ZEXPORT gzclose OF((gzFile file)); -/* - Flushes all pending output if necessary, closes the compressed file - and deallocates all the (de)compression state. The return value is the zlib - error number (see function gzerror below). -*/ - -ZEXTERN Q_ZEXPORT const char * gzerror OF((gzFile file, int *errnum)); -/* - Returns the error message for the last error which occurred on the - given compressed file. errnum is set to zlib error number. If an - error occurred in the file system and not in the compression library, - errnum is set to Z_ERRNO and the application may consult errno - to get the exact error code. -*/ - -ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); -/* - Clears the error and end-of-file flags for file. This is analogous to the - clearerr() function in stdio. This is useful for continuing to read a gzip - file that is being written concurrently. -*/ - - /* checksum functions */ - -/* - These functions are not related to compression but are exported - anyway because they might be useful in applications using the - compression library. -*/ - -ZEXTERN uLong Q_ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); -/* - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is NULL, this function returns - the required initial value for the checksum. - An Adler-32 checksum is almost as reliable as a CRC32 but can be computed - much faster. Usage example: - - uLong adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); -*/ - -ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, - z_off_t len2)); -/* - Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 - and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for - each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of - seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. -*/ - -ZEXTERN uLong Q_ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); -/* - Update a running CRC-32 with the bytes buf[0..len-1] and return the - updated CRC-32. If buf is NULL, this function returns the required initial - value for the for the crc. Pre- and post-conditioning (one's complement) is - performed within this function so it shouldn't be done by the application. - Usage example: - - uLong crc = crc32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - crc = crc32(crc, buffer, length); - } - if (crc != original_crc) error(); -*/ - -ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); - -/* - Combine two CRC-32 check values into one. For two sequences of bytes, - seq1 and seq2 with lengths len1 and len2, CRC-32 check values were - calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 - check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. -*/ - - - /* various hacks, don't look :) */ - -/* deflateInit and inflateInit are macros to allow checking the zlib version - * and the compiler's view of z_stream: - */ -ZEXTERN int Q_ZEXPORT deflateInit_ OF((z_streamp strm, int level, - const char *version, int stream_size)); -ZEXTERN int Q_ZEXPORT inflateInit_ OF((z_streamp strm, - const char *version, int stream_size)); -ZEXTERN int Q_ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size)); -ZEXTERN int Q_ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, - unsigned char FAR *window, - const char *version, - int stream_size)); -#define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) -#define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) -#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, sizeof(z_stream)) -#define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) -#define inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, sizeof(z_stream)) - - -#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) - struct internal_state {int dummy;}; /* hack for buggy compilers */ -#endif - -ZEXTERN Q_ZEXPORT const char * zError OF((int)); -ZEXTERN int Q_ZEXPORT inflateSyncPoint OF((z_streamp z)); -ZEXTERN Q_ZEXPORT const uLongf * get_crc_table OF((void)); - -#ifdef __cplusplus -} -#endif - -#endif /* ZLIB_H */ diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/zutil.c b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/zutil.c deleted file mode 100644 index d55f5948a..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/zutil.c +++ /dev/null @@ -1,318 +0,0 @@ -/* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" - -#ifndef NO_DUMMY_DECL -struct internal_state {int dummy;}; /* for buggy compilers */ -#endif - -const char * const z_errmsg[10] = { -"need dictionary", /* Z_NEED_DICT 2 */ -"stream end", /* Z_STREAM_END 1 */ -"", /* Z_OK 0 */ -"file error", /* Z_ERRNO (-1) */ -"stream error", /* Z_STREAM_ERROR (-2) */ -"data error", /* Z_DATA_ERROR (-3) */ -"insufficient memory", /* Z_MEM_ERROR (-4) */ -"buffer error", /* Z_BUF_ERROR (-5) */ -"incompatible version",/* Z_VERSION_ERROR (-6) */ -""}; - - -const char * ZEXPORT zlibVersion() -{ - return ZLIB_VERSION; -} - -uLong ZEXPORT zlibCompileFlags() -{ - uLong flags; - - flags = 0; - switch (sizeof(uInt)) { - case 2: break; - case 4: flags += 1; break; - case 8: flags += 2; break; - default: flags += 3; - } - switch (sizeof(uLong)) { - case 2: break; - case 4: flags += 1 << 2; break; - case 8: flags += 2 << 2; break; - default: flags += 3 << 2; - } - switch (sizeof(voidpf)) { - case 2: break; - case 4: flags += 1 << 4; break; - case 8: flags += 2 << 4; break; - default: flags += 3 << 4; - } - switch (sizeof(z_off_t)) { - case 2: break; - case 4: flags += 1 << 6; break; - case 8: flags += 2 << 6; break; - default: flags += 3 << 6; - } -#ifdef DEBUG - flags += 1 << 8; -#endif -#if defined(ASMV) || defined(ASMINF) - flags += 1 << 9; -#endif -#ifdef ZLIB_WINAPI - flags += 1 << 10; -#endif -#ifdef BUILDFIXED - flags += 1 << 12; -#endif -#ifdef DYNAMIC_CRC_TABLE - flags += 1 << 13; -#endif -#ifdef NO_GZCOMPRESS - flags += 1L << 16; -#endif -#ifdef NO_GZIP - flags += 1L << 17; -#endif -#ifdef PKZIP_BUG_WORKAROUND - flags += 1L << 20; -#endif -#ifdef FASTEST - flags += 1L << 21; -#endif -#ifdef STDC -# ifdef NO_vsnprintf - flags += 1L << 25; -# ifdef HAS_vsprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_vsnprintf_void - flags += 1L << 26; -# endif -# endif -#else - flags += 1L << 24; -# ifdef NO_snprintf - flags += 1L << 25; -# ifdef HAS_sprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_snprintf_void - flags += 1L << 26; -# endif -# endif -#endif - return flags; -} - -#ifdef DEBUG - -# ifndef verbose -# define verbose 0 -# endif -int z_verbose = verbose; - -void z_error (m) - char *m; -{ - fprintf(stderr, "%s\n", m); - exit(1); -} -#endif - -/* exported to allow conversion of error code to string for compress() and - * uncompress() - */ -const char * ZEXPORT zError(err) - int err; -{ - return ERR_MSG(err); -} - -#if defined(_WIN32_WCE) - /* The Microsoft C Run-Time Library for Windows CE doesn't have - * errno. We define it as a global variable to simplify porting. - * Its value is always 0 and should not be used. - */ - int errno = 0; -#endif - -#ifndef HAVE_MEMCPY - -void zmemcpy(dest, source, len) - Bytef* dest; - const Bytef* source; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = *source++; /* ??? to be unrolled */ - } while (--len != 0); -} - -int zmemcmp(s1, s2, len) - const Bytef* s1; - const Bytef* s2; - uInt len; -{ - uInt j; - - for (j = 0; j < len; j++) { - if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; - } - return 0; -} - -void zmemzero(dest, len) - Bytef* dest; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = 0; /* ??? to be unrolled */ - } while (--len != 0); -} -#endif - - -#ifdef SYS16BIT - -#ifdef __TURBOC__ -/* Turbo C in 16-bit mode */ - -# define MY_ZCALLOC - -/* Turbo C malloc() does not allow dynamic allocation of 64K bytes - * and farmalloc(64K) returns a pointer with an offset of 8, so we - * must fix the pointer. Warning: the pointer must be put back to its - * original form in order to free it, use zcfree(). - */ - -#define MAX_PTR 10 -/* 10*64K = 640K */ - -local int next_ptr = 0; - -typedef struct ptr_table_s { - voidpf org_ptr; - voidpf new_ptr; -} ptr_table; - -local ptr_table table[MAX_PTR]; -/* This table is used to remember the original form of pointers - * to large buffers (64K). Such pointers are normalized with a zero offset. - * Since MSDOS is not a preemptive multitasking OS, this table is not - * protected from concurrent access. This hack doesn't work anyway on - * a protected system like OS/2. Use Microsoft C instead. - */ - -voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) -{ - voidpf buf = opaque; /* just to make some compilers happy */ - ulg bsize = (ulg)items*size; - - /* If we allocate less than 65520 bytes, we assume that farmalloc - * will return a usable pointer which doesn't have to be normalized. - */ - if (bsize < 65520L) { - buf = farmalloc(bsize); - if (*(ush*)&buf != 0) return buf; - } else { - buf = farmalloc(bsize + 16L); - } - if (buf == NULL || next_ptr >= MAX_PTR) return NULL; - table[next_ptr].org_ptr = buf; - - /* Normalize the pointer to seg:0 */ - *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; - *(ush*)&buf = 0; - table[next_ptr++].new_ptr = buf; - return buf; -} - -void zcfree (voidpf opaque, voidpf ptr) -{ - int n; - if (*(ush*)&ptr != 0) { /* object < 64K */ - farfree(ptr); - return; - } - /* Find the original pointer */ - for (n = 0; n < next_ptr; n++) { - if (ptr != table[n].new_ptr) continue; - - farfree(table[n].org_ptr); - while (++n < next_ptr) { - table[n-1] = table[n]; - } - next_ptr--; - return; - } - ptr = opaque; /* just to make some compilers happy */ - Assert(0, "zcfree: ptr not found"); -} - -#endif /* __TURBOC__ */ - - -#ifdef M_I86 -/* Microsoft C in 16-bit mode */ - -# define MY_ZCALLOC - -#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) -# define _halloc halloc -# define _hfree hfree -#endif - -voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) -{ - if (opaque) opaque = 0; /* to make compiler happy */ - return _halloc((long)items, size); -} - -void zcfree (voidpf opaque, voidpf ptr) -{ - if (opaque) opaque = 0; /* to make compiler happy */ - _hfree(ptr); -} - -#endif /* M_I86 */ - -#endif /* SYS16BIT */ - - -#ifndef MY_ZCALLOC /* Any system without a special alloc function */ - -#ifndef STDC -extern voidp malloc OF((uInt size)); -extern voidp calloc OF((uInt items, uInt size)); -extern void free OF((voidpf ptr)); -#endif - -voidpf zcalloc (opaque, items, size) - voidpf opaque; - unsigned items; - unsigned size; -{ - if (opaque) items += size - size; /* make compiler happy */ - return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : - (voidpf)calloc(items, size); -} - -void zcfree (opaque, ptr) - voidpf opaque; - voidpf ptr; -{ - free(ptr); - if (opaque) return; /* make compiler happy */ -} - -#endif /* MY_ZCALLOC */ diff --git a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/zutil.h b/ground/gcs/src/libs/glc_lib/3rdparty/zlib/zutil.h deleted file mode 100644 index b7d5eff81..000000000 --- a/ground/gcs/src/libs/glc_lib/3rdparty/zlib/zutil.h +++ /dev/null @@ -1,269 +0,0 @@ -/* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#ifndef ZUTIL_H -#define ZUTIL_H - -#define ZLIB_INTERNAL -#include "zlib.h" - -#ifdef STDC -# ifndef _WIN32_WCE -# include -# endif -# include -# include -#endif -#ifdef NO_ERRNO_H -# ifdef _WIN32_WCE - /* The Microsoft C Run-Time Library for Windows CE doesn't have - * errno. We define it as a global variable to simplify porting. - * Its value is always 0 and should not be used. We rename it to - * avoid conflict with other libraries that use the same workaround. - */ -# define errno z_errno -# endif - extern int errno; -#else -# ifndef _WIN32_WCE -# include -# endif -#endif - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - -typedef unsigned char uch; -typedef uch FAR uchf; -typedef unsigned short ush; -typedef ush FAR ushf; -typedef unsigned long ulg; - -extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ -/* (size given to avoid silly warnings with Visual C++) */ - -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] - -#define ERR_RETURN(strm,err) \ - return (strm->msg = (char*)ERR_MSG(err), (err)) -/* To be used only when the state is known to be valid */ - - /* common constants */ - -#ifndef DEF_WBITS -# define DEF_WBITS MAX_WBITS -#endif -/* default windowBits for decompression. MAX_WBITS is for compression only */ - -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -/* default memLevel */ - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 -/* The three kinds of block type */ - -#define MIN_MATCH 3 -#define MAX_MATCH 258 -/* The minimum and maximum match lengths */ - -#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ - - /* target dependencies */ - -#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) -# define OS_CODE 0x00 -# if defined(__TURBOC__) || defined(__BORLANDC__) -# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) - /* Allow compilation with ANSI keywords only enabled */ - void _Cdecl farfree( void *block ); - void *_Cdecl farmalloc( unsigned long nbytes ); -# else -# include -# endif -# else /* MSC or DJGPP */ -# include -# endif -#endif - -#ifdef AMIGA -# define OS_CODE 0x01 -#endif - -#if defined(VAXC) || defined(VMS) -# define OS_CODE 0x02 -# define F_OPEN(name, mode) \ - fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") -#endif - -#if defined(ATARI) || defined(atarist) -# define OS_CODE 0x05 -#endif - -#ifdef OS2 -# define OS_CODE 0x06 -# ifdef M_I86 - #include -# endif -#endif - -#if defined(MACOS) || defined(TARGET_OS_MAC) -# define OS_CODE 0x07 -# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os -# include /* for fdopen */ -# else -# ifndef fdopen -# define fdopen(fd,mode) NULL /* No fdopen() */ -# endif -# endif -#endif - -#ifdef TOPS20 -# define OS_CODE 0x0a -#endif - -#ifdef WIN32 -# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ -# define OS_CODE 0x0b -# endif -#endif - -#ifdef __50SERIES /* Prime/PRIMOS */ -# define OS_CODE 0x0f -#endif - -#if defined(_BEOS_) || defined(RISCOS) -# define fdopen(fd,mode) NULL /* No fdopen() */ -#endif - -#if (defined(_MSC_VER) && (_MSC_VER > 600)) -# if defined(_WIN32_WCE) -# define fdopen(fd,mode) NULL /* No fdopen() */ -# ifndef _PTRDIFF_T_DEFINED - typedef int ptrdiff_t; -# define _PTRDIFF_T_DEFINED -# endif -# else -# define fdopen(fd,type) _fdopen(fd,type) -# endif -#endif - - /* common defaults */ - -#ifndef OS_CODE -# define OS_CODE 0x03 /* assume Unix */ -#endif - -#ifndef F_OPEN -# define F_OPEN(name, mode) fopen((name), (mode)) -#endif - - /* functions */ - -#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif -#if defined(__CYGWIN__) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif -#ifndef HAVE_VSNPRINTF -# ifdef MSDOS - /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), - but for now we just assume it doesn't. */ -# define NO_vsnprintf -# endif -# ifdef __TURBOC__ -# define NO_vsnprintf -# endif -# ifdef WIN32 - /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ -# if !defined(vsnprintf) && !defined(NO_vsnprintf) -# define vsnprintf _vsnprintf -# endif -# endif -# ifdef __SASC -# define NO_vsnprintf -# endif -#endif -#ifdef VMS -# define NO_vsnprintf -#endif - -#if defined(pyr) -# define NO_MEMCPY -#endif -#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) - /* Use our own functions for small and medium model with MSC <= 5.0. - * You may have to use the same strategy for Borland C (untested). - * The __SC__ check is for Symantec. - */ -# define NO_MEMCPY -#endif -#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) -# define HAVE_MEMCPY -#endif -#ifdef HAVE_MEMCPY -# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ -# define zmemcpy _fmemcpy -# define zmemcmp _fmemcmp -# define zmemzero(dest, len) _fmemset(dest, 0, len) -# else -# define zmemcpy memcpy -# define zmemcmp memcmp -# define zmemzero(dest, len) memset(dest, 0, len) -# endif -#else - extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); - extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); - extern void zmemzero OF((Bytef* dest, uInt len)); -#endif - -/* Diagnostic functions */ -#ifdef DEBUG -# include - extern int z_verbose; - extern void z_error OF((char *m)); -# define Assert(cond,msg) {if(!(cond)) z_error(msg);} -# define Trace(x) {if (z_verbose>=0) fprintf x ;} -# define Tracev(x) {if (z_verbose>0) fprintf x ;} -# define Tracevv(x) {if (z_verbose>1) fprintf x ;} -# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} -# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} -#else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) -#endif - - -voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); -void zcfree OF((voidpf opaque, voidpf ptr)); - -#define ZALLOC(strm, items, size) \ - (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) -#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} - -#endif /* ZUTIL_H */ diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_3drep.cpp b/ground/gcs/src/libs/glc_lib/geometry/glc_3drep.cpp deleted file mode 100644 index 431cff1df..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_3drep.cpp +++ /dev/null @@ -1,504 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -#include "glc_3drep.h" -#include "../glc_factory.h" -#include "glc_mesh.h" -#include "glc_errorlog.h" - -// Class chunk id -quint32 GLC_3DRep::m_ChunkId= 0xA702; - -GLC_3DRep::GLC_3DRep() -: GLC_Rep() -, m_pGeomList(new QList) -, m_pType(new int(GLC_Rep::GLC_VBOGEOM)) -{ - -} - -GLC_3DRep::GLC_3DRep(GLC_Geometry* pGeom) -: GLC_Rep() -, m_pGeomList(new QList) -, m_pType(new int(GLC_Rep::GLC_VBOGEOM)) -{ - m_pGeomList->append(pGeom); - *m_pIsLoaded= true; - setName(pGeom->name()); -} - -GLC_3DRep::GLC_3DRep(const GLC_3DRep& rep) -: GLC_Rep(rep) -, m_pGeomList(rep.m_pGeomList) -, m_pType(rep.m_pType) -{ - -} - -GLC_3DRep& GLC_3DRep::operator=(const GLC_Rep& rep) -{ - const GLC_3DRep* p3DRep= dynamic_cast(&rep); - Q_ASSERT(NULL != p3DRep); - if (this != &rep) - { - clear3DRepGeom(); - GLC_Rep::operator=(rep); - m_pGeomList= p3DRep->m_pGeomList; - m_pType= p3DRep->m_pType; - } - - return *this; -} - -GLC_Rep* GLC_3DRep::clone() const -{ - return new GLC_3DRep(*this); -} - -GLC_Rep* GLC_3DRep::deepCopy() const -{ - GLC_3DRep* pCloneRep= new GLC_3DRep; - // Copy fields of the base class - pCloneRep->setFileName(fileName()); - pCloneRep->setName(name()); - // Copy representation geometries - const int size= m_pGeomList->size(); - for (int i= 0; i < size; ++i) - { - pCloneRep->addGeom(m_pGeomList->at(i)->clone()); - } - return pCloneRep; -} - -GLC_3DRep::~GLC_3DRep() -{ - if (isTheLast()) - { - clear3DRepGeom(); - - delete m_pGeomList; - m_pGeomList= NULL; - - delete m_pType; - m_pType= NULL; - } -} - -////////////////////////////////////////////////////////////////////// -// Get functions -////////////////////////////////////////////////////////////////////// -quint32 GLC_3DRep::chunckID() -{ - return m_ChunkId; -} - -int GLC_3DRep::type() const -{ - return (*m_pType); -} - -////////////////////////////////////////////////////////////////////// -// Get functions -////////////////////////////////////////////////////////////////////// - -bool GLC_3DRep::boundingBoxIsValid() const -{ - bool result= !m_pGeomList->isEmpty(); - const int max= m_pGeomList->size(); - int index= 0; - while (result && (index < max)) - { - result= result && m_pGeomList->at(index)->boundingBoxIsValid(); - ++index; - } - return result; -} - -GLC_BoundingBox GLC_3DRep::boundingBox() const -{ - GLC_BoundingBox resultBox; - const int size= m_pGeomList->size(); - for (int i= 0; i < size; ++i) - { - resultBox.combine(m_pGeomList->at(i)->boundingBox()); - } - return resultBox; -} - -unsigned int GLC_3DRep::faceCount() const -{ - unsigned int result= 0; - if (!m_pGeomList->isEmpty()) - { - const int size= m_pGeomList->size(); - for (int i= 0; i < size; ++i) - { - result+= m_pGeomList->at(i)->faceCount(); - } - } - - return result; -} - -unsigned int GLC_3DRep::vertexCount() const -{ - unsigned int result= 0; - if (!m_pGeomList->isEmpty()) - { - const int size= m_pGeomList->size(); - for (int i= 0; i < size; ++i) - { - result+= m_pGeomList->at(i)->VertexCount(); - } - } - - return result; -} - -unsigned int GLC_3DRep::materialCount() const -{ - unsigned int result= 0; - if (!m_pGeomList->isEmpty()) - { - const int size= m_pGeomList->size(); - for (int i= 0; i < size; ++i) - { - result+= m_pGeomList->at(i)->materialCount(); - } - } - - return result; -} - -QSet GLC_3DRep::materialSet() const -{ - QSet result; - if (!m_pGeomList->isEmpty()) - { - const int size= m_pGeomList->size(); - for (int i= 0; i < size; ++i) - { - result.unite(m_pGeomList->at(i)->materialSet()); - } - } - - return result; -} - -double GLC_3DRep::volume() const -{ - double resultVolume= 0.0; - const int geomCount= m_pGeomList->count(); - for (int i= 0; i < geomCount; ++i) - { - resultVolume+= m_pGeomList->at(i)->volume(); - } - - return resultVolume; -} - -void GLC_3DRep::clean() -{ - QList::iterator iGeomList= m_pGeomList->begin(); - while(iGeomList != m_pGeomList->constEnd()) - { - if ((*iGeomList)->VertexCount() == 0) - { - qDebug() << "Delete empty geom--------------------"; - delete (*iGeomList); - iGeomList= m_pGeomList->erase(iGeomList); - } - else - { - ++iGeomList; - } - } -} - -void GLC_3DRep::reverseNormals() -{ - const int size= m_pGeomList->size(); - for (int i= 0; i < size; ++i) - { - (*m_pGeomList)[i]->reverseNormals(); - } -} - -bool GLC_3DRep::load() -{ - bool loadSucces= false; - - if(!(*m_pIsLoaded)) - { - Q_ASSERT(m_pGeomList->isEmpty()); - if (fileName().isEmpty()) - { - QStringList stringList("GLC_3DRep::load"); - stringList.append("Representation : " + GLC_Rep::name()); - stringList.append("Empty File Name"); - GLC_ErrorLog::addError(stringList); - } - else - { - GLC_3DRep newRep= GLC_Factory::instance()->create3DRepFromFile(fileName()); - if (!newRep.isEmpty()) - { - const int size= newRep.m_pGeomList->size(); - for (int i= 0; i < size; ++i) - { - m_pGeomList->append(newRep.m_pGeomList->at(i)); - } - newRep.m_pGeomList->clear(); - (*m_pIsLoaded)= true; - loadSucces= true; - } - } - } - - return loadSucces; - -} - -void GLC_3DRep::replace(GLC_Rep* pRep) -{ - GLC_3DRep* p3DRep= dynamic_cast(pRep); - Q_ASSERT(NULL != p3DRep); - - (*m_pType)= *(p3DRep->m_pType); - - clear3DRepGeom(); - setFileName(p3DRep->fileName()); - setName(p3DRep->name()); - - if (!p3DRep->isEmpty()) - { - const int size= p3DRep->m_pGeomList->size(); - for (int i= 0; i < size; ++i) - { - m_pGeomList->append(p3DRep->m_pGeomList->at(i)); - } - p3DRep->m_pGeomList->clear(); - (*m_pIsLoaded)= true; - } -} - -void GLC_3DRep::replaceMaterial(GLC_uint oldId, GLC_Material* pNewMaterial) -{ - //qDebug() << "GLC_3DRep::replaceMaterial"; - const int size= m_pGeomList->size(); - for (int i= 0; i < size; ++i) - { - GLC_Geometry* pGeom= m_pGeomList->at(i); - if (pGeom->containsMaterial(oldId)) - { - Q_ASSERT(!pGeom->containsMaterial(pNewMaterial->id())); - GLC_Mesh* pMesh= dynamic_cast(m_pGeomList->at(i)); - if (NULL != pMesh) - { - pMesh->replaceMaterial(oldId, pNewMaterial); - } - } - } -} - -void GLC_3DRep::merge(const GLC_3DRep* pRep) -{ - // Get the number of geometry of pRep - const int pRepSize= pRep->m_pGeomList->size(); - for (int i= 0; i < pRepSize; ++i) - { - addGeom(pRep->geomAt(i)->clone()); - } -} - -void GLC_3DRep::take(GLC_3DRep* pSource) -{ - // Get the number of geometry of pRep - const int pRepSize= pSource->m_pGeomList->size(); - for (int i= 0; i < pRepSize; ++i) - { - addGeom(pSource->geomAt(i)); - } - pSource->m_pGeomList->clear(); -} - -void GLC_3DRep::copyVboToClientSide() -{ - // Get the number of geometry of pRep - const int pRepSize= m_pGeomList->size(); - for (int i= 0; i < pRepSize; ++i) - { - geomAt(i)->copyVboToClientSide(); - } -} - -void GLC_3DRep::releaseVboClientSide(bool update) -{ - // Get the number of geometry of pRep - const int pRepSize= m_pGeomList->size(); - for (int i= 0; i < pRepSize; ++i) - { - geomAt(i)->releaseVboClientSide(update); - } -} - -void GLC_3DRep::transformSubGeometries(const GLC_Matrix4x4& matrix) -{ - // Get the number of geometry of pRep - const int repCount= m_pGeomList->size(); - for (int i= 0; i < repCount; ++i) - { - GLC_Mesh* pCurrentMesh= dynamic_cast(geomAt(i)); - if (NULL != pCurrentMesh) - { - pCurrentMesh->transformVertice(matrix); - } - } -} - -void GLC_3DRep::setVboUsage(bool usage) -{ - // Get the number of geometry of pRep - const int repCount= m_pGeomList->size(); - for (int i= 0; i < repCount; ++i) - { - m_pGeomList->at(i)->setVboUsage(usage); - } -} - -bool GLC_3DRep::unload() -{ - bool unloadSucess= false; - if ((NULL != m_pGeomList) && !m_pGeomList->isEmpty()) - { - if (fileName().isEmpty()) - { - QStringList stringList("GLC_3DRep::unload()"); - stringList.append("Cannot unload rep without filename"); - GLC_ErrorLog::addError(stringList); - } - else - { - const int size= m_pGeomList->size(); - for (int i= 0; i < size; ++i) - { - delete (*m_pGeomList)[i]; - } - m_pGeomList->clear(); - - (*m_pIsLoaded)= false; - unloadSucess= true; - } - } - return unloadSucess; -} - -////////////////////////////////////////////////////////////////////// -// private services functions -////////////////////////////////////////////////////////////////////// - -void GLC_3DRep::clear3DRepGeom() -{ - const int size= m_pGeomList->size(); - for (int i= 0; i < size; ++i) - { - delete (*m_pGeomList)[i]; - } - m_pGeomList->clear(); -} - -// Non Member methods -QDataStream &operator<<(QDataStream & stream, const GLC_3DRep & rep) -{ - quint32 chunckId= GLC_3DRep::m_ChunkId; - stream << chunckId; - - // The representation name - stream << rep.name(); - - // Save the list of 3DRep materials - QList materialsList; - QList sourceMaterialsList= rep.materialSet().toList(); - const int materialNumber= sourceMaterialsList.size(); - for (int i= 0; i < materialNumber; ++i) - { - materialsList.append(*(sourceMaterialsList.at(i))); - materialsList[i].setId(sourceMaterialsList.at(i)->id()); - } - // Save the list of materials - stream << materialsList; - - // Save the list of mesh - const int meshNumber= rep.m_pGeomList->size(); - stream << meshNumber; - for (int i= 0; i < meshNumber; ++i) - { - GLC_Mesh* pMesh= dynamic_cast(rep.m_pGeomList->at(i)); - if (NULL != pMesh) - { - pMesh->saveToDataStream(stream); - } - } - - return stream; -} - -QDataStream &operator>>(QDataStream & stream, GLC_3DRep & rep) -{ - Q_ASSERT(rep.isEmpty()); - - quint32 chunckId; - stream >> chunckId; - Q_ASSERT(chunckId == GLC_3DRep::m_ChunkId); - - // The rep name - QString name; - stream >> name; - rep.setName(name); - - // Retrieve the list of rep materials - QList materialsList; - stream >> materialsList; - MaterialHash materialHash; - // Update mesh materials hash table - QHash materialIdMap; - const int materialsCount= materialsList.size(); - for (int i= 0; i < materialsCount; ++i) - { - GLC_Material* pMaterial= new GLC_Material(materialsList.at(i)); - pMaterial->setId(glc::GLC_GenID()); - materialIdMap.insert(materialsList.at(i).id(), pMaterial->id()); - materialHash.insert(pMaterial->id(), pMaterial); - } - - int meshNumber; - stream >> meshNumber; - for (int i= 0; i < meshNumber; ++i) - { - GLC_Mesh* pMesh= new GLC_Mesh(); - pMesh->loadFromDataStream(stream, materialHash, materialIdMap); - - rep.addGeom(pMesh); - } - - return stream; -} diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_3drep.h b/ground/gcs/src/libs/glc_lib/geometry/glc_3drep.h deleted file mode 100644 index 7d4c635a3..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_3drep.h +++ /dev/null @@ -1,205 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_3drep.h interface for the GLC_3DRep class. - -#ifndef GLC_3DREP_H_ -#define GLC_3DREP_H_ - -#include "glc_geometry.h" -#include "glc_rep.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_3DRep -/*! \brief GLC_3DRep : A referrence 3D Representation*/ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_3DRep : public GLC_Rep -{ - friend GLC_LIB_EXPORT QDataStream &operator<<(QDataStream &, const GLC_3DRep &); - friend GLC_LIB_EXPORT QDataStream &operator>>(QDataStream &, GLC_3DRep &); - -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Default Constructor - GLC_3DRep(); - - //! Construct a 3DRep with a geometry - GLC_3DRep(GLC_Geometry*); - - //! Copy Constructor - GLC_3DRep(const GLC_3DRep&); - - //! Assignement operator - virtual GLC_3DRep &operator=(const GLC_Rep&); - - //! Clone the representation - virtual GLC_Rep* clone() const; - - //! Make a deep copy of the 3DRep - virtual GLC_Rep* deepCopy() const; - - //! Destructor - virtual ~GLC_3DRep(); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the class Chunk ID - static quint32 chunckID(); - - //! Return the type of representation - virtual int type() const; - - //! Get Geometry - inline GLC_Geometry* geomAt(int index) const - { - Q_ASSERT(NULL != m_pGeomList); - Q_ASSERT(m_pGeomList->size() > index); - return m_pGeomList->at(index); - } - - //! Return the number of body - inline int numberOfBody() const - { - Q_ASSERT(NULL != m_pGeomList); - return m_pGeomList->size(); - } - - //! Return true if the representation is empty - inline virtual bool isEmpty() const - { - Q_ASSERT(NULL != m_pGeomList); - return m_pGeomList->isEmpty(); - } - - //! Return true if the rep bounding box is valid - bool boundingBoxIsValid() const; - - //! Return the 3DRep bounding Box - GLC_BoundingBox boundingBox() const; - - //! Return true if the 3DRep contains the geometry - inline bool contains(GLC_Geometry* pGeom) - {return m_pGeomList->contains(pGeom);} - - //! Return the number of faces of this 3DRep - unsigned int faceCount() const; - - //! Return number of vertex of this 3DRep - unsigned int vertexCount() const; - - //! Return number of materials of this 3DRep - unsigned int materialCount() const; - - //! Return materials Set of this 3DRep - QSet materialSet() const; - - //! Return the volume of this 3DRep - double volume() const; - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Add Geometry to the 3DRep - inline void addGeom(GLC_Geometry* pGeom) - { - m_pGeomList->append(pGeom); - *m_pIsLoaded= true; - } - - //! Remove empty geometries and factorise materials - void clean(); - - //! Reverse geometries normals - void reverseNormals(); - - //! Load the representation and return true if success - virtual bool load(); - - //! UnLoad the representation and return true if success - virtual bool unload(); - - //! Replace the representation - virtual void replace(GLC_Rep*); - - //! Replace the specified material by a new one - void replaceMaterial(GLC_uint, GLC_Material*); - - //! Merge this 3Drep with another 3DRep - void merge(const GLC_3DRep*); - - //! Take the geometry of another 3DRep - void take(GLC_3DRep* pSource); - - //! Copy VBO to the Client Side - void copyVboToClientSide(); - - //! Release client VBO - void releaseVboClientSide(bool update= false); - - //! Transform 3DRep sub mesh vertice with the given matrix - void transformSubGeometries(const GLC_Matrix4x4& matrix); - - //! Set VBO usage - void setVboUsage(bool usage); - -//@} - -////////////////////////////////////////////////////////////////////// -// private services functions -////////////////////////////////////////////////////////////////////// -private: - //! Clear current representation geometries - void clear3DRepGeom(); - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - //! Geometries of the 3D representation - QList* m_pGeomList; - - //! The Type of representation - int* m_pType; - - //! Class chunk id - static quint32 m_ChunkId; - -}; - -//! Non-member stream operator -GLC_LIB_EXPORT QDataStream &operator<<(QDataStream &, const GLC_3DRep &); -GLC_LIB_EXPORT QDataStream &operator>>(QDataStream &, GLC_3DRep &); - -#endif /* GLC_3DREP_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_arrow.cpp b/ground/gcs/src/libs/glc_lib/geometry/glc_arrow.cpp deleted file mode 100644 index f0739b4ab..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_arrow.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_arrow.cpp implementation of the GLC_Arrow class. - -#include -#include "../maths/glc_utils_maths.h" -#include "glc_arrow.h" - - -GLC_Arrow::GLC_Arrow(const GLC_Point3d& startPoint, const GLC_Point3d& endPoint, const GLC_Vector3d& viewDir) -: GLC_Geometry("Arrow", true) -, m_StartPoint(startPoint) -, m_EndPoint(endPoint) -, m_HeadLenght((m_EndPoint - m_StartPoint).length() / 10.0) -, m_HeadAngle(glc::toRadian(30.0)) -, m_ViewDir(GLC_Vector3d(viewDir).normalize()) -{ - -} - -GLC_Arrow::GLC_Arrow(const GLC_Arrow& arrow) -: GLC_Geometry(arrow) -, m_StartPoint(arrow.m_StartPoint) -, m_EndPoint(arrow.m_EndPoint) -, m_HeadLenght(arrow.m_HeadLenght) -, m_HeadAngle(arrow.m_HeadAngle) -, m_ViewDir(arrow.m_ViewDir) -{ - -} - -GLC_Arrow::~GLC_Arrow() -{ - -} -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// -const GLC_BoundingBox& GLC_Arrow::boundingBox() -{ - if (NULL == m_pBoundingBox) - { - m_pBoundingBox= new GLC_BoundingBox(); - if (m_WireData.isEmpty()) createWire(); - m_pBoundingBox->combine(m_WireData.boundingBox()); - } - return *m_pBoundingBox; -} - -GLC_Geometry* GLC_Arrow::clone() const -{ - return new GLC_Arrow(*this); -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// -GLC_Arrow& GLC_Arrow::operator=(const GLC_Arrow& arrow) -{ - if (this != &arrow) - { - GLC_Geometry::operator=(arrow); - m_StartPoint= arrow.m_StartPoint; - m_EndPoint= arrow.m_EndPoint; - m_HeadLenght= arrow.m_HeadLenght; - m_HeadAngle= arrow.m_HeadAngle; - m_ViewDir= arrow.m_ViewDir; - } - return *this; -} - -void GLC_Arrow::setStartPoint(const GLC_Point3d& startPoint) -{ - if (startPoint != m_StartPoint) - { - m_StartPoint= startPoint; - GLC_Geometry::clearWireAndBoundingBox(); - } -} - -void GLC_Arrow::setEndPoint(const GLC_Point3d& endPoint) -{ - if (endPoint != m_EndPoint) - { - m_EndPoint= endPoint; - GLC_Geometry::clearWireAndBoundingBox(); - } -} - -void GLC_Arrow::setHeadLength(double headLenght) -{ - if (!qFuzzyCompare(m_HeadLenght, headLenght)) - { - m_HeadLenght= headLenght; - GLC_Geometry::clearWireAndBoundingBox(); - } -} - -void GLC_Arrow::setHeadAngle(double headAngle) -{ - if (!qFuzzyCompare(m_HeadAngle, headAngle)) - { - m_HeadAngle= headAngle; - GLC_Geometry::clearWireAndBoundingBox(); - } -} - -void GLC_Arrow::setViewDir(const GLC_Vector3d& viewDir) -{ - - if (viewDir != m_ViewDir) - { - m_ViewDir= GLC_Vector3d(viewDir).normalize(); - GLC_Geometry::clearWireAndBoundingBox(); - } -} - -////////////////////////////////////////////////////////////////////// -// OpenGL Functions -////////////////////////////////////////////////////////////////////// -void GLC_Arrow::glDraw(const GLC_RenderProperties& renderProperties) -{ - if (m_WireData.isEmpty()) - { - createWire(); - } - - m_WireData.glDraw(renderProperties, GL_LINE_STRIP); -} - -void GLC_Arrow::createWire() -{ - Q_ASSERT(m_WireData.isEmpty()); - GLfloatVector floatVector; - floatVector.append(static_cast(m_StartPoint.x())); - floatVector.append(static_cast(m_StartPoint.y())); - floatVector.append(static_cast(m_StartPoint.z())); - floatVector.append(static_cast(m_EndPoint.x())); - floatVector.append(static_cast(m_EndPoint.y())); - floatVector.append(static_cast(m_EndPoint.z())); - - GLC_Geometry::addVerticeGroup(floatVector); - - // Arrow Head - GLC_Point3d headPoint1(-m_HeadLenght, m_HeadLenght * tan(m_HeadAngle / 2.0), 0.0); - GLC_Point3d headPoint2(headPoint1.x(), -(headPoint1.y()), headPoint1.z()); - - // Arrow frame - GLC_Vector3d xArrow= (m_EndPoint - m_StartPoint).normalize(); - GLC_Vector3d yArrow= ((-m_ViewDir) ^ xArrow).normalize(); - GLC_Vector3d zArrow= (xArrow ^ yArrow).normalize(); - - GLC_Matrix4x4 headMatrix; - headMatrix.setColumn(0, xArrow); - headMatrix.setColumn(1, yArrow); - headMatrix.setColumn(2, zArrow); - GLC_Matrix4x4 translate(m_EndPoint); - headPoint1= translate * headMatrix * headPoint1; - headPoint2= translate * headMatrix * headPoint2; - - // add head data - floatVector.clear(); - floatVector.append(static_cast(headPoint1.x())); - floatVector.append(static_cast(headPoint1.y())); - floatVector.append(static_cast(headPoint1.z())); - - floatVector.append(static_cast(m_EndPoint.x())); - floatVector.append(static_cast(m_EndPoint.y())); - floatVector.append(static_cast(m_EndPoint.z())); - - floatVector.append(static_cast(headPoint2.x())); - floatVector.append(static_cast(headPoint2.y())); - floatVector.append(static_cast(headPoint2.z())); - - GLC_Geometry::addVerticeGroup(floatVector); - -} diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_arrow.h b/ground/gcs/src/libs/glc_lib/geometry/glc_arrow.h deleted file mode 100644 index 3f57ff69f..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_arrow.h +++ /dev/null @@ -1,156 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_arrow.h interface for the GLC_Arrow class. - -#ifndef GLC_ARROW_H_ -#define GLC_ARROW_H_ - -#include -#include "../maths/glc_vector3d.h" -#include "glc_geometry.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Arrow -/*! \brief GLC_Arrow : OpenGL 3D Arrow*/ - -/*! An GLC_Arrow is a wire Simple Arrow*/ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_Arrow : public GLC_Geometry -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Construct an arrow with the given points and view direction - GLC_Arrow(const GLC_Point3d& startPoint, const GLC_Point3d& endPoint, const GLC_Vector3d& viewDir); - - //! Copy constructor - GLC_Arrow(const GLC_Arrow& arrow); - - //! Destructor - virtual ~GLC_Arrow(); -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the arrow bounding box - const GLC_BoundingBox& boundingBox(); - - //! Return the start point of this arrow - inline GLC_Point3d startPoint() const - {return m_StartPoint;} - - //! Return the end point of this arrow - inline GLC_Point3d endPoint() const - {return m_EndPoint;} - - //! Return the lenght of the head of this arrow - inline double headLenght() const - {return m_HeadLenght;} - - //! Return the angle in radians of the head of this arrow - inline double headAngle() const - {return m_HeadAngle;} - - //! Return the viewing direction of this arrow - inline GLC_Vector3d viewDir() const - {return m_ViewDir;} - - //! Return a copy of the geometry - virtual GLC_Geometry* clone() const; - -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Set this arrow from the given arrow - GLC_Arrow& operator=(const GLC_Arrow& arrow); - - //! Set the start point of this arrow - void setStartPoint(const GLC_Point3d& startPoint); - - //! Set the end point of this arrow - void setEndPoint(const GLC_Point3d& endPoint); - - //! Set the length of the head of this arrow to the given lenght - void setHeadLength(double headLenght); - - //! Set the angle of the head of this arrow to the given angle in radians - void setHeadAngle(double headAngle); - - //! Set the view dir of this arrow to the given vector 3d - void setViewDir(const GLC_Vector3d& viewDir); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -private: - - //! Virtual interface for OpenGL Geometry set up. - /*! This Virtual function is implemented here.\n - * Throw GLC_OpenGlException*/ - virtual void glDraw(const GLC_RenderProperties&); - - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Private services Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -private: - //! Create the wire - void createWire(); - -//@} - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - //! Start point - GLC_Point3d m_StartPoint; - - //! End point - GLC_Point3d m_EndPoint; - - //! Head lenght - double m_HeadLenght; - - //! Head angle - double m_HeadAngle; - - //! The arrow viewing dir - GLC_Vector3d m_ViewDir; -}; - -#endif /* GLC_ARROW_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_box.cpp b/ground/gcs/src/libs/glc_lib/geometry/glc_box.cpp deleted file mode 100644 index 2b6e510a2..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_box.cpp +++ /dev/null @@ -1,329 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_box.cpp implementation of the GLC_Box class. - -#include "glc_box.h" -#include "../glc_openglexception.h" -#include "../glc_state.h" - -////////////////////////////////////////////////////////////////////// -// Constructor Destructor -////////////////////////////////////////////////////////////////////// - -GLC_Box::GLC_Box(double dLx, double dLy, double dlz) -:GLC_Mesh() -, m_dLgX(dLx) -, m_dLgY(dLy) -, m_dLgZ(dlz) -{ - createMeshAndWire(); -} -// Copy constructor -GLC_Box::GLC_Box(const GLC_Box& box) -:GLC_Mesh(box) -, m_dLgX(box.m_dLgX) -, m_dLgY(box.m_dLgY) -, m_dLgZ(box.m_dLgZ) -{ - createMeshAndWire(); -} -GLC_Box::~GLC_Box() -{ - -} - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -// return the box bounding box -const GLC_BoundingBox& GLC_Box::boundingBox(void) -{ - if (GLC_Mesh::isEmpty()) - { - createMeshAndWire(); - } - return GLC_Mesh::boundingBox(); -} - -// Return a copy of the current geometry -GLC_Geometry* GLC_Box::clone() const -{ - return new GLC_Box(*this); -} - - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -// Set X length -void GLC_Box::setLgX(double LgX) -{ - Q_ASSERT(LgX > 0); - m_dLgX= LgX; - - GLC_Mesh::clearMeshWireAndBoundingBox(); -} - -// Set Y length -void GLC_Box::setLgY(double LgY) -{ - Q_ASSERT(LgY > 0); - m_dLgY= LgY; - - GLC_Mesh::clearMeshWireAndBoundingBox(); -} - -// Set Z length -void GLC_Box::setLgZ(double LgZ) -{ - Q_ASSERT(LgZ > 0); - m_dLgZ= LgZ; - - GLC_Mesh::clearMeshWireAndBoundingBox(); -} - -////////////////////////////////////////////////////////////////////// -// Private OpenGL functions -////////////////////////////////////////////////////////////////////// - -// Box Set Up -void GLC_Box::glDraw(const GLC_RenderProperties& renderProperties) -{ - if (GLC_Mesh::isEmpty()) - { - createMeshAndWire(); - } - - GLC_Mesh::glDraw(renderProperties); -} -// Create the box mesh -void GLC_Box::createMeshAndWire() -{ - Q_ASSERT(GLC_Mesh::isEmpty()); - createWire(); - - const GLfloat lgX= static_cast(m_dLgX / 2.0); - const GLfloat lgY= static_cast(m_dLgY / 2.0); - const GLfloat lgZ= static_cast(m_dLgZ / 2.0); - - GLfloatVector verticeVector; - GLfloatVector normalsVector; - GLfloatVector texelVector; - - // Face 1 - verticeVector << -lgX; verticeVector << -lgY; verticeVector << lgZ; - normalsVector << 0.0f; normalsVector << 0.0f; normalsVector << 1.0f; - texelVector << 0.0f; texelVector << 0.0f; - - verticeVector << lgX; verticeVector << -lgY; verticeVector << lgZ; - normalsVector << 0.0f; normalsVector << 0.0f; normalsVector << 1.0f; - texelVector << 1.0f; texelVector << 0.0f; - - verticeVector << lgX; verticeVector << lgY; verticeVector << lgZ; - normalsVector << 0.0f; normalsVector << 0.0f; normalsVector << 1.0f; - texelVector << 1.0f; texelVector << 1.0f; - - verticeVector << -lgX; verticeVector << lgY; verticeVector << lgZ; - normalsVector << 0.0f; normalsVector << 0.0f; normalsVector << 1.0f; - texelVector << 0.0f; texelVector << 1.0f; - - // Face 2 - verticeVector << lgX; verticeVector << -lgY; verticeVector << lgZ; - normalsVector << 1.0f; normalsVector << 0.0f; normalsVector << 0.0f; - texelVector << 0.0f; texelVector << 0.0f; - - verticeVector << lgX; verticeVector << -lgY; verticeVector << -lgZ; - normalsVector << 1.0f; normalsVector << 0.0f; normalsVector << 0.0f; - texelVector << 1.0f; texelVector << 0.0f; - - verticeVector << lgX; verticeVector << lgY; verticeVector << -lgZ; - normalsVector << 1.0f; normalsVector << 0.0f; normalsVector << 0.0f; - texelVector << 1.0f; texelVector << 1.0f; - - verticeVector << lgX; verticeVector << lgY; verticeVector << lgZ; - normalsVector << 1.0f; normalsVector << 0.0f; normalsVector << 0.0f; - texelVector << 0.0f; texelVector << 1.0f; - - // Face 3 - verticeVector << -lgX; verticeVector << -lgY; verticeVector << -lgZ; - normalsVector << -1.0f; normalsVector << 0.0f; normalsVector << 0.0f; - texelVector << 0.0f; texelVector << 0.0f; - - verticeVector << -lgX; verticeVector << -lgY; verticeVector << lgZ; - normalsVector << -1.0f; normalsVector << 0.0f; normalsVector << 0.0f; - texelVector << 1.0f; texelVector << 0.0f; - - verticeVector << -lgX; verticeVector << lgY; verticeVector << lgZ; - normalsVector << -1.0f; normalsVector << 0.0f; normalsVector << 0.0f; - texelVector << 1.0f; texelVector << 1.0f; - - verticeVector << -lgX; verticeVector << lgY; verticeVector << -lgZ; - normalsVector << -1.0f; normalsVector << 0.0f; normalsVector << 0.0f; - texelVector << 0.0f; texelVector << 1.0f; - - // Face 4 - verticeVector << lgX; verticeVector << -lgY; verticeVector << -lgZ; - normalsVector << 0.0f; normalsVector << 0.0f; normalsVector << -1.0f; - texelVector << 0.0f; texelVector << 0.0f; - - verticeVector << -lgX; verticeVector << -lgY; verticeVector << -lgZ; - normalsVector << 0.0f; normalsVector << 0.0f; normalsVector << -1.0f; - texelVector << 1.0f; texelVector << 0.0f; - - verticeVector << -lgX; verticeVector << lgY; verticeVector << -lgZ; - normalsVector << 0.0f; normalsVector << 0.0f; normalsVector << -1.0f; - texelVector << 1.0f; texelVector << 1.0f; - - verticeVector << lgX; verticeVector << lgY; verticeVector << -lgZ; - normalsVector << 0.0f; normalsVector << 0.0f; normalsVector << -1.0f; - texelVector << 0.0f; texelVector << 1.0f; - - // Face 5 - verticeVector << -lgX; verticeVector << lgY; verticeVector << lgZ; - normalsVector << 0.0f; normalsVector << 1.0f; normalsVector << 0.0f; - texelVector << 0.0f; texelVector << 0.0f; - - verticeVector << lgX; verticeVector << lgY; verticeVector << lgZ; - normalsVector << 0.0f; normalsVector << 1.0f; normalsVector << 0.0f; - texelVector << 1.0f; texelVector << 0.0f; - - verticeVector << lgX; verticeVector << lgY; verticeVector << -lgZ; - normalsVector << 0.0f; normalsVector << 1.0f; normalsVector << 0.0f; - texelVector << 1.0f; texelVector << 1.0f; - - verticeVector << -lgX; verticeVector << lgY; verticeVector << -lgZ; - normalsVector << 0.0f; normalsVector << 1.0f; normalsVector << 0.0f; - texelVector << 0.0f; texelVector << 1.0f; - - // Face 6 - verticeVector << -lgX; verticeVector << -lgY; verticeVector << -lgZ; - normalsVector << 0.0f; normalsVector << -1.0f; normalsVector << 0.0f; - texelVector << 0.0f; texelVector << 0.0f; - - verticeVector << lgX; verticeVector << -lgY; verticeVector << -lgZ; - normalsVector << 0.0f; normalsVector << -1.0f; normalsVector << 0.0f; - texelVector << 1.0f; texelVector << 0.0f; - - verticeVector << lgX; verticeVector << -lgY; verticeVector << lgZ; - normalsVector << 0.0f; normalsVector << -1.0f; normalsVector << 0.0f; - texelVector << 1.0f; texelVector << 1.0f; - - verticeVector << -lgX; verticeVector << -lgY; verticeVector << lgZ; - normalsVector << 0.0f; normalsVector << -1.0f; normalsVector << 0.0f; - texelVector << 0.0f; texelVector << 1.0f; - - // Add bulk data in to the mesh - GLC_Mesh::addVertice(verticeVector); - GLC_Mesh::addNormals(normalsVector); - GLC_Mesh::addTexels(texelVector); - - // Set the material to use - GLC_Material* pMaterial; - if (hasMaterial()) - { - pMaterial= this->firstMaterial(); - } - else - { - pMaterial= new GLC_Material(); - } - - IndexList index; - // Face 1 - index << 0 << 1 << 3 << 2; - GLC_Mesh::addTrianglesStrip(pMaterial, index); - index.clear(); - // Face 2 - index << 4 << 5 << 7 << 6; - GLC_Mesh::addTrianglesStrip(pMaterial, index); - index.clear(); - // Face 3 - index << 8 << 9 << 11 << 10; - GLC_Mesh::addTrianglesStrip(pMaterial, index); - index.clear(); - // Face 4 - index << 12 << 13 << 15 << 14; - GLC_Mesh::addTrianglesStrip(pMaterial, index); - index.clear(); - // Face 5 - index << 16 << 17 << 19 << 18; - GLC_Mesh::addTrianglesStrip(pMaterial, index); - index.clear(); - // Face 6 - index << 20 << 21 << 23 << 22; - GLC_Mesh::addTrianglesStrip(pMaterial, index); - index.clear(); - - GLC_Mesh::finish(); -} - -// Create the wire of the mesh -void GLC_Box::createWire() -{ - Q_ASSERT(m_WireData.isEmpty()); - - const GLfloat lgX= static_cast(m_dLgX / 2.0); - const GLfloat lgY= static_cast(m_dLgY / 2.0); - const GLfloat lgZ= static_cast(m_dLgZ / 2.0); - - // Float vector - GLfloatVector floatVector; - floatVector << lgX << lgY << lgZ; - floatVector << lgX << lgY << -lgZ; - floatVector << -lgX << lgY << -lgZ; - floatVector << -lgX << lgY << lgZ; - floatVector << lgX << lgY << lgZ; - GLC_Geometry::addVerticeGroup(floatVector); - floatVector.clear(); - - floatVector << lgX << -lgY << lgZ; - floatVector << lgX << -lgY << -lgZ; - floatVector << -lgX << -lgY << -lgZ; - floatVector << -lgX << -lgY << lgZ; - floatVector << lgX << -lgY << lgZ; - GLC_Geometry::addVerticeGroup(floatVector); - floatVector.clear(); - - floatVector << lgX << lgY << lgZ; - floatVector << lgX << -lgY << lgZ; - GLC_Geometry::addVerticeGroup(floatVector); - floatVector.clear(); - - floatVector << lgX << lgY << -lgZ; - floatVector << lgX << -lgY << -lgZ; - GLC_Geometry::addVerticeGroup(floatVector); - floatVector.clear(); - - floatVector << -lgX << lgY << -lgZ; - floatVector << -lgX << -lgY << -lgZ; - GLC_Geometry::addVerticeGroup(floatVector); - floatVector.clear(); - - floatVector << -lgX << lgY << lgZ; - floatVector << -lgX << -lgY << lgZ; - GLC_Geometry::addVerticeGroup(floatVector); - floatVector.clear(); -} - diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_box.h b/ground/gcs/src/libs/glc_lib/geometry/glc_box.h deleted file mode 100644 index 24e9f8e7e..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_box.h +++ /dev/null @@ -1,147 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_box.h interface for the GLC_Box class. - -#ifndef GLC_BOX_H_ -#define GLC_BOX_H_ - - -#include "glc_mesh.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Box -/*! \brief GLC_Box : OpenGL Box*/ - -/*! An GLC_Box is a polygonal geometry\n - * It's a rectangular parallelepiped box centred at (0, 0, 0)*/ - - -////////////////////////////////////////////////////////////////////// - -class GLC_LIB_EXPORT GLC_Box : public GLC_Mesh -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Construct an GLC_Box - /*! By default, discretion is set to #GLC_POLYDISCRET*/ - GLC_Box(double, double, double); - - //! Copy constructor - GLC_Box(const GLC_Box&); - - //! Destructor - virtual ~GLC_Box(); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Get X length - inline double getLgX(void) const - {return m_dLgX;} - - //! Get Y length - inline double getLgY(void) const - {return m_dLgY;} - - //! Get Z length - inline double getLgZ(void) const - {return m_dLgZ;} - - //! return the box bounding box - virtual const GLC_BoundingBox& boundingBox(void); - - //! Return a copy of the geometry - virtual GLC_Geometry* clone() const; - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Set X length - /*! This Function invalid OpenGL display list - * LgX must be > 0*/ - void setLgX(double LgX); - - //! Set Y length - /*! This Function invalid OpenGL display list - * LgY must be > 0*/ - void setLgY(double LgY); - - //! Set Z length - /*! This Function invalid OpenGL display list - * LgZ must be > 0*/ - void setLgZ(double LgZ); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -private: - //! Virtual interface for OpenGL Geometry set up. - /*! This Virtual function is implemented here.\n - * Throw GLC_OpenGlException*/ - virtual void glDraw(const GLC_RenderProperties&); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Private services Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -private: - //! Create the box mesh - void createMeshAndWire(); - - //! Create the wire of the mesh - void createWire(); - -//@} - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - - //! X Length - double m_dLgX; - - //! Y Length - double m_dLgY; - - //! Z Length - double m_dLgZ; -}; -#endif //GLC_BOX_H_ diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_bsrep.cpp b/ground/gcs/src/libs/glc_lib/geometry/glc_bsrep.cpp deleted file mode 100644 index edfc9ffb9..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_bsrep.cpp +++ /dev/null @@ -1,348 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_bsrep.cpp implementation for the GLC_BSRep class. - -#include "glc_bsrep.h" -#include "../glc_fileformatexception.h" -#include "../glc_tracelog.h" - -// The binary rep suffix -const QString GLC_BSRep::m_Suffix("BSRep"); - -// The binary rep magic number -const QUuid GLC_BSRep::m_Uuid("{d6f97789-36a9-4c2e-b667-0e66c27f839f}"); - -// The binary rep version -const quint32 GLC_BSRep::m_Version= 103; - -// Mutex used by compression -QMutex GLC_BSRep::m_CompressionMutex; - -// Default constructor -GLC_BSRep::GLC_BSRep(const QString& fileName, bool useCompression) -: m_FileInfo() -, m_pFile(NULL) -, m_DataStream() -, m_UseCompression(useCompression) -, m_CompressionLevel(-1) -{ - setAbsoluteFileName(fileName); - m_DataStream.setVersion(QDataStream::Qt_4_6); - m_DataStream.setFloatingPointPrecision(QDataStream::SinglePrecision); -} - -// Copy constructor -GLC_BSRep::GLC_BSRep(const GLC_BSRep& binaryRep) -: m_FileInfo(binaryRep.m_FileInfo) -, m_pFile(NULL) -, m_DataStream() -, m_UseCompression(binaryRep.m_UseCompression) -, m_CompressionLevel(binaryRep.m_CompressionLevel) -{ - m_DataStream.setVersion(QDataStream::Qt_4_6); - m_DataStream.setFloatingPointPrecision(binaryRep.m_DataStream.floatingPointPrecision()); -} - -GLC_BSRep::~GLC_BSRep() -{ - delete m_pFile; -} - -// Return true if the binary rep is up to date -bool GLC_BSRep::isUsable(const QDateTime& timeStamp) -{ - bool isUpToDate= false; - if (open(QIODevice::ReadOnly)) - { - if (headerIsOk()) - { - isUpToDate= timeStampOk(timeStamp); - isUpToDate= isUpToDate && close(); - } - } - else - { - QString message(QString("GLC_BSRep::loadRep Enable to open the file ") + m_FileInfo.fileName()); - GLC_FileFormatException fileFormatException(message, m_FileInfo.fileName(), GLC_FileFormatException::FileNotFound); - close(); - throw(fileFormatException); - } - - if (!isUpToDate && GLC_TraceLog::isEnable()) - { - QStringList stringList("GLC_BSRep::isUsable"); - stringList.append("File " + m_FileInfo.filePath() + " not Usable"); - GLC_TraceLog::addTrace(stringList); - } - return isUpToDate; -} - -////////////////////////////////////////////////////////////////////// -// name Get Functions -////////////////////////////////////////////////////////////////////// -// Load the binary rep -GLC_3DRep GLC_BSRep::loadRep() -{ - GLC_3DRep loadedRep; - - if (open(QIODevice::ReadOnly)) - { - if (headerIsOk()) - { - timeStampOk(QDateTime()); - GLC_BoundingBox boundingBox; - m_DataStream >> boundingBox; - bool useCompression; - m_DataStream >> useCompression; - if (useCompression) - { - QByteArray CompresseBuffer; - m_DataStream >> CompresseBuffer; - QByteArray uncompressedBuffer= qUncompress(CompresseBuffer); - uncompressedBuffer.squeeze(); - CompresseBuffer.clear(); - CompresseBuffer.squeeze(); - QDataStream bufferStream(uncompressedBuffer); - bufferStream >> loadedRep; - } - else - { - m_DataStream >> loadedRep; - } - loadedRep.setFileName(m_FileInfo.filePath()); - - if (!close()) - { - QString message(QString("GLC_BSRep::loadRep An error occur when loading file ") + m_FileInfo.fileName()); - GLC_FileFormatException fileFormatException(message, m_FileInfo.fileName(), GLC_FileFormatException::WrongFileFormat); - throw(fileFormatException); - } - } - else - { - QString message(QString("GLC_BSRep::loadRep File not supported ") + m_FileInfo.fileName()); - GLC_FileFormatException fileFormatException(message, m_FileInfo.fileName(), GLC_FileFormatException::FileNotSupported); - close(); - throw(fileFormatException); - } - } - else - { - QString message(QString("GLC_BSRep::loadRep Enable to open the file ") + m_FileInfo.fileName()); - GLC_FileFormatException fileFormatException(message, m_FileInfo.fileName(), GLC_FileFormatException::FileNotFound); - close(); - throw(fileFormatException); - } - - - return loadedRep; -} - -// Return the bounding box of the binary representation -GLC_BoundingBox GLC_BSRep::boundingBox() -{ - GLC_BoundingBox boundingBox; - - if (open(QIODevice::ReadOnly)) - { - if (headerIsOk()) - { - timeStampOk(QDateTime()); - - m_DataStream >> boundingBox; - } - close(); - } - return boundingBox; -} - -// Return bsrep suffix -QString GLC_BSRep::suffix() -{ - return m_Suffix; -} - -quint32 GLC_BSRep::version() -{ - return m_Version; -} - -////////////////////////////////////////////////////////////////////// -//name Set Functions -////////////////////////////////////////////////////////////////////// -// Set the binary representation file name -void GLC_BSRep::setAbsoluteFileName(const QString& fileName) -{ - m_FileInfo.setFile(fileName); - if (m_FileInfo.suffix() != m_Suffix) - { - m_FileInfo.setFile(fileName + '.' + m_Suffix); - } - -} - -// Save the GLC_3DRep in serialised binary -bool GLC_BSRep::save(const GLC_3DRep& rep) -{ - - //! Check if the currentFileInfo is valid and writable - bool saveOk= open(QIODevice::WriteOnly); - if (saveOk) - { - writeHeader(rep.lastModified()); - - // Representation Bounding Box - m_DataStream << rep.boundingBox(); - - // Compression usage - - if (m_UseCompression && (rep.faceCount() < 1000000)) - { - m_DataStream << true; - QByteArray uncompressedBuffer; - { - QBuffer buffer(&uncompressedBuffer); - buffer.open(QIODevice::WriteOnly); - QDataStream bufferStream(&buffer); - bufferStream << rep; - } - m_DataStream << qCompress(uncompressedBuffer, m_CompressionLevel); - } - else - { - m_DataStream << false; - // Binary representation geometry - // Add the rep - m_DataStream << rep; - } - - // Flag the file - qint64 offset= sizeof(QUuid); - offset+= sizeof(quint32); - - m_pFile->seek(offset); - bool writeOk= true; - m_DataStream << writeOk; - // Close the file - saveOk= close(); - } - return saveOk; -} - - -// Open the file -bool GLC_BSRep::open(QIODevice::OpenMode mode) -{ - bool openOk= m_FileInfo.exists(); - if (openOk || (mode == QIODevice::WriteOnly)) - { - m_DataStream.setDevice(NULL); - delete m_pFile; - m_pFile= new QFile(m_FileInfo.filePath()); - openOk= m_pFile->open(mode); - if (openOk) - { - m_DataStream.setDevice(m_pFile); - } - } - else if (GLC_TraceLog::isEnable()) - { - QStringList stringList("GLC_BSRep::open"); - stringList.append("File " + m_FileInfo.filePath() + " doesn't exists"); - GLC_TraceLog::addTrace(stringList); - } - - return openOk; -} - -// Close the file -bool GLC_BSRep::close() -{ - Q_ASSERT(m_pFile != NULL); - Q_ASSERT(m_DataStream.device() != NULL); - bool closeOk= m_DataStream.status() == QDataStream::Ok; - m_DataStream.setDevice(NULL); - m_pFile->close(); - delete m_pFile; - m_pFile= NULL; - - return closeOk; -} - -// Write the header -void GLC_BSRep::writeHeader(const QDateTime& dateTime) -{ - Q_ASSERT(m_pFile != NULL); - Q_ASSERT(m_DataStream.device() != NULL); - - // Binary representation Header - // Add the magic number - m_DataStream << m_Uuid; - // Add the version - m_DataStream << m_Version; - bool writeFinished= false; - m_DataStream << writeFinished; - - // Set the version of the data stream - m_DataStream.setVersion(QDataStream::Qt_4_6); - - // Add the time stamp - m_DataStream << dateTime; -} - -// Check the header -bool GLC_BSRep::headerIsOk() -{ - Q_ASSERT(m_pFile != NULL); - Q_ASSERT(m_DataStream.device() != NULL); - Q_ASSERT(m_pFile->openMode() == QIODevice::ReadOnly); - - QUuid uuid; - quint32 version; - bool writeFinished; - - m_DataStream >> uuid; - m_DataStream >> version; - m_DataStream >> writeFinished; - - // Set the version of the data stream - m_DataStream.setVersion(QDataStream::Qt_4_6); - - bool headerOk= (uuid == m_Uuid) && (version <= m_Version) && (version > 101) && writeFinished; - - return headerOk; -} - -// Check the time Stamp -bool GLC_BSRep::timeStampOk(const QDateTime& timeStamp) -{ - Q_ASSERT(m_pFile != NULL); - Q_ASSERT(m_DataStream.device() != NULL); - Q_ASSERT(m_pFile->openMode() == QIODevice::ReadOnly); - - QDateTime dateTime; - m_DataStream >> dateTime; - - bool timeStampOk= !timeStamp.isValid() || (dateTime == timeStamp); - return timeStampOk; -} - diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_bsrep.h b/ground/gcs/src/libs/glc_lib/geometry/glc_bsrep.h deleted file mode 100644 index f1dbe4955..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_bsrep.h +++ /dev/null @@ -1,157 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_bsrep.h interface for the GLC_BSRep class. - -#ifndef GLC_BSREP_H_ -#define GLC_BSREP_H_ - -#include -#include -#include -#include -#include -#include - -#include "../glc_config.h" -#include "glc_3drep.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_BSRep -/*! \brief GLC_BSRep : The 3D Binary serialised representation*/ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_BSRep -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Default constructor - GLC_BSRep(const QString& absoluteFileName= QString(), bool useCompression= true); - - //! Copy constructor - GLC_BSRep(const GLC_BSRep&); - - //! Destructor - virtual ~GLC_BSRep(); -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Return the binary representation file name - inline QString absoluteFileName() const - {return m_FileInfo.fileName();} - - //! Return true if the binary rep is usable - bool isUsable(const QDateTime&); - - //! Load the binary rep - GLC_3DRep loadRep(); - - //! Return the bounding box of the binary representation - GLC_BoundingBox boundingBox(); - - //! Return bsrep suffix - static QString suffix(); - - //! Return bsrep version - static quint32 version(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Set the binary representation file name - void setAbsoluteFileName(const QString&); - - //! Save the GLC_3DRep in serialised binary - bool save(const GLC_3DRep&); - - //! Set the compression usage for saving a 3DREP in binary format - inline void setCompressionUsage(bool usage) - {m_UseCompression= usage;} - - //! Set the compression level if compression is used when saving in binary format - inline void setCompressionLevel(int level) - {m_CompressionLevel= level;} - -//@} - -private: -////////////////////////////////////////////////////////////////////// -// Private services function -////////////////////////////////////////////////////////////////////// - - //! Open the file - bool open(QIODevice::OpenMode); - - //! Close the file - bool close(); - - //! Write the header - void writeHeader(const QDateTime&); - - //! Check the header - bool headerIsOk(); - - //! Check the time Stamp - bool timeStampOk(const QDateTime&); - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - //! The binary rep suffix - static const QString m_Suffix; - - //! The binary rep magic number - static const QUuid m_Uuid; - - //! The binary rep version - static const quint32 m_Version; - - //! the Binary representation file informations - QFileInfo m_FileInfo; - - //! The brep file - QFile* m_pFile; - - //! The Data stream - QDataStream m_DataStream; - - //! Compress Data - bool m_UseCompression; - - //! The compression level - int m_CompressionLevel; - - //! Compression Mutex - static QMutex m_CompressionMutex; - -}; - -#endif /* GLC_BSREP_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_circle.cpp b/ground/gcs/src/libs/glc_lib/geometry/glc_circle.cpp deleted file mode 100644 index 94a4e3f81..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_circle.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_circle.cpp implementation of the GLC_Circle class. - -#include "glc_circle.h" -#include "../glc_openglexception.h" -#include "../glc_state.h" - -using namespace glc; -////////////////////////////////////////////////////////////////////// -// Constructor destructor -////////////////////////////////////////////////////////////////////// - -GLC_Circle::GLC_Circle(const double &dRadius, double Angle) -:GLC_Geometry("Circle", true) -, m_Radius(dRadius) -, m_Discret(GLC_DISCRET) -, m_Angle(Angle) -, m_Step(0) -{ - -} - -GLC_Circle::GLC_Circle(const GLC_Circle& sourceCircle) -:GLC_Geometry(sourceCircle) -, m_Radius(sourceCircle.m_Radius) -, m_Discret(sourceCircle.m_Discret) -, m_Angle(sourceCircle.m_Angle) -, m_Step(sourceCircle.m_Step) -{ - -} -GLC_Circle::~GLC_Circle() -{ - -} -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -// return the circle bounding box -const GLC_BoundingBox& GLC_Circle::boundingBox(void) -{ - if (NULL == m_pBoundingBox) - { - //qDebug() << "GLC_Mesh2::boundingBox create boundingBox"; - m_pBoundingBox= new GLC_BoundingBox(); - if (m_WireData.isEmpty()) createWire(); - m_pBoundingBox->combine(m_WireData.boundingBox()); - m_pBoundingBox->combine(GLC_Vector3d(0.0, 0.0, -2 * glc::EPSILON)); - } - return *m_pBoundingBox; -} - -// Return a copy of the current geometry -GLC_Geometry* GLC_Circle::clone() const -{ - return new GLC_Circle(*this); -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -// Set Circle diameter -void GLC_Circle::setDiameter(double D) -{ - Q_ASSERT(!qFuzzyCompare(D, 0.0)); - setRadius(D / 2); -} - -// Set Circle Radius -void GLC_Circle::setRadius(double R) -{ - Q_ASSERT(!qFuzzyCompare(R, 0.0)); - if (!qFuzzyCompare(R - m_Radius, 0.0)) - { // Radius is changing - m_Radius= R; - - GLC_Geometry::clearWireAndBoundingBox(); - } -} - -// Set Circle discret -void GLC_Circle::setDiscretion(int TargetDiscret) -{ - Q_ASSERT(TargetDiscret > 0); - if (TargetDiscret != m_Discret) - { - m_Discret= TargetDiscret; - if (m_Discret < 6) m_Discret= 6; - - GLC_Geometry::clearWireAndBoundingBox(); - } -} - -// Set Circle Angle -void GLC_Circle::setAngle(double AngleRadians) // Angle in Radians -{ - Q_ASSERT((!qFuzzyCompare(AngleRadians, 0.0)) && (AngleRadians < 2 * PI)); - if (!qFuzzyCompare(AngleRadians - m_Angle, 0.0)) - { // Angle is changing - m_Angle= AngleRadians; - - GLC_Geometry::clearWireAndBoundingBox(); - } -} - -////////////////////////////////////////////////////////////////////// -// OpenGL Functions -////////////////////////////////////////////////////////////////////// - -// Circle drawing -void GLC_Circle::glDraw(const GLC_RenderProperties& renderProperties) -{ - if (m_WireData.isEmpty()) - { - createWire(); - } - - m_WireData.glDraw(renderProperties, GL_LINE_STRIP); -} - -// Create the wire -void GLC_Circle::createWire() -{ - Q_ASSERT(m_WireData.isEmpty()); - - m_Step= static_cast(static_cast(m_Discret) * (m_Angle / (2 * glc::PI))); - if (m_Step < 2) m_Step= 2; - - // Float vector - GLfloatVector floatVector; - - // Resize the Vertex vector - const int size= (m_Step + 1) * 3; - floatVector.resize(size); - // Fill Vertex Vector - const double angleOnStep= m_Angle / static_cast(m_Step); - for (GLuint i= 0; i <= m_Step; ++i) - { - floatVector[(i * 3)]= static_cast(m_Radius * cos(static_cast(i) * angleOnStep)); - floatVector[(i * 3) + 1]= static_cast(m_Radius * sin(static_cast(i) * angleOnStep)); - floatVector[(i * 3) + 2]= 0.0f; - } - GLC_Geometry::addVerticeGroup(floatVector); -} diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_circle.h b/ground/gcs/src/libs/glc_lib/geometry/glc_circle.h deleted file mode 100644 index 9b0eb5538..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_circle.h +++ /dev/null @@ -1,148 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_circle.h interface for the GLC_Circle class. - -#ifndef GLC_CIRCLE_H_ -#define GLC_CIRCLE_H_ - -#include "glc_geometry.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Circle -/*! \brief GLC_Circle : OpenGL 3D Circle*/ - -/*! An GLC_Circle is a wire geometry composed of 3d lines \n - * It can be an entire circle or an arc. - * */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_Circle : public GLC_Geometry -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Construct an GLC_Circle - /*! By default, discretion is set to #GLC_DISCRET*/ - GLC_Circle(const double &dRadius, double Angle= 2.0 * glc::PI); - - //! Copy constructor - GLC_Circle(const GLC_Circle& sourceCircle); - - //! Destructor - virtual ~GLC_Circle(); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Return Circle Discretion - inline int discretion() const - { return m_Discret;} - - //! Return Circle radius - inline double radius() const - {return m_Radius;} - - //! return Circle diameter - inline double diameter() const - {return m_Radius * 2.0;} - - //! return the circle bounding box - virtual const GLC_BoundingBox& boundingBox(); - - //! Return a copy of the geometry - virtual GLC_Geometry* clone() const; -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Set Circle diameter - /*! Diameter must be > 2 * EPSILON*/ - void setDiameter(double D); - - //! Set Circle Radius - /*! Radius must be > EPSILON*/ - void setRadius(double R); - - //! Set Circle discret - /*! TargetDiscret must be > 0 - * if TargetDiscret < 6 discretion is set to 6*/ - void setDiscretion(int TargetDiscret); - - //! Set Circle Angle - /*! AngleRadians must be > EPSILON and < 2 PI*/ - void setAngle(double AngleRadians); // Angle in Radians - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -private: - - //! Virtual interface for OpenGL Geometry set up. - /*! This Virtual function is implemented here.\n - * Throw GLC_OpenGlException*/ - virtual void glDraw(const GLC_RenderProperties&); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Private services Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -private: - //! Create the wire - void createWire(); - -//@} - -////////////////////////////////////////////////////////////////////// -// private members -////////////////////////////////////////////////////////////////////// -private: - //! Circle Radius - double m_Radius; - - //! Circle Discretion - int m_Discret; - - //! Angle of circle in radians - double m_Angle; - - //! Circle Step - GLuint m_Step; - -}; -#endif //GLC_CIRCLE_H_ diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_cone.cpp b/ground/gcs/src/libs/glc_lib/geometry/glc_cone.cpp deleted file mode 100644 index 94476ef19..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_cone.cpp +++ /dev/null @@ -1,269 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_cone.cpp implementation of the GLC_Cone class. - -#include "glc_cone.h" - -// Class chunk id -quint32 GLC_Cone::m_ChunkId= 0xA709; - -GLC_Cone::GLC_Cone(double dRadius, double dLength, int discretization) -:GLC_Mesh() -, m_Radius(dRadius) -, m_Length(dLength) -, m_Discret(discretization) // Default discretion -{ - Q_ASSERT((m_Radius > 0.0) && (m_Length > 0.0)); - createMeshAndWire(); -} - -GLC_Cone::GLC_Cone(const GLC_Cone& sourceCone) -:GLC_Mesh(sourceCone) -, m_Radius(sourceCone.m_Radius) -, m_Length(sourceCone.m_Length) -, m_Discret(sourceCone.m_Discret) -{ - createMeshAndWire(); -} - -GLC_Cone::~GLC_Cone() -{ - -} - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -quint32 GLC_Cone::chunckID() -{ - return m_ChunkId; -} - - -GLC_Geometry* GLC_Cone::clone() const -{ - return new GLC_Cone(*this); -} - - -const GLC_BoundingBox& GLC_Cone::boundingBox() -{ - if (GLC_Mesh::isEmpty()) - { - createMeshAndWire(); - } - return GLC_Mesh::boundingBox(); -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -void GLC_Cone::setLength(double Length) -{ - Q_ASSERT(Length > 0.0); - m_Length= Length; - - GLC_Mesh::clearMeshWireAndBoundingBox(); -} - - -void GLC_Cone::setRadius(double Radius) -{ - Q_ASSERT(Radius > 0.0); - m_Radius= Radius; - - GLC_Mesh::clearMeshWireAndBoundingBox(); -} - - -void GLC_Cone::setDiscretion(int TargetDiscret) -{ - Q_ASSERT(TargetDiscret > 0); - if (TargetDiscret != m_Discret) - { - m_Discret= TargetDiscret; - if (m_Discret < 6) m_Discret= 6; - - GLC_Mesh::clearMeshWireAndBoundingBox(); - } -} - -////////////////////////////////////////////////////////////////////// -// Private Opengl functions -////////////////////////////////////////////////////////////////////// - -void GLC_Cone::glDraw(const GLC_RenderProperties& renderProperties) -{ - - if (GLC_Mesh::isEmpty()) - { - createMeshAndWire(); - } - - GLC_Mesh::glDraw(renderProperties); -} - - -void GLC_Cone::createMeshAndWire() -{ - Q_ASSERT(GLC_Mesh::isEmpty()); - Q_ASSERT(m_WireData.isEmpty()); - - // Create cosinus and sinus array according to the discretion and radius - const int vertexNumber= m_Discret + 1; - // Normals values - QVector cosNormalArray(vertexNumber); - QVector sinNormalArray(vertexNumber); - - QVector cosArray(vertexNumber); - QVector sinArray(vertexNumber); - - const double angle= (2.0 * glc::PI) / static_cast(m_Discret); - - // Normal Z value - GLC_Vector3d normalVector(1.0, 0.0, 0.0); - GLC_Matrix4x4 rotation(glc::Y_AXIS, -atan(m_Radius / m_Length)); - normalVector= rotation * normalVector; - const float normalZ= static_cast(normalVector.z()); - const double factor= normalVector.x(); // Normailsation factor - - for (int i= 0; i < vertexNumber; ++i) - { - const double cosValue= cos(static_cast(i) * angle); - const double sinValue= sin(static_cast(i) * angle); - - cosNormalArray[i]= static_cast(factor * cosValue); - sinNormalArray[i]= static_cast(factor * sinValue); - - cosArray[i]= static_cast(m_Radius * cosValue); - sinArray[i]= static_cast(m_Radius * sinValue); - } - - - // Mesh Data - GLfloatVector verticeVector; - GLfloatVector normalsVector; - GLfloatVector texelVector; - - // Wire Data - GLfloatVector bottomWireData(vertexNumber * 3); - - const int size= vertexNumber * 3; - verticeVector.resize(3 * size); - normalsVector.resize(3 * size); - texelVector.resize(2 * size); - - for (int i= 0; i < vertexNumber; ++i) - { - // Bottom Mesh - verticeVector[3 * i]= cosArray[i]; - verticeVector[3 * i + 1]= sinArray[i]; - verticeVector[3 * i + 2]= 0.0f; - - normalsVector[3 * i]= cosNormalArray[i]; - normalsVector[3 * i + 1]= sinNormalArray[i]; - normalsVector[3 * i + 2]= normalZ; - - texelVector[2 * i]= static_cast(i) / static_cast(m_Discret); - texelVector[2 * i + 1]= 0.0f; - - // Bottom Wire - bottomWireData[3 * i]= cosArray[i]; - bottomWireData[3 * i + 1]= sinArray[i]; - bottomWireData[3 * i + 2]= 0.0f; - - // Top - verticeVector[3 * i + 3 * vertexNumber]= 0.0f; - verticeVector[3 * i + 1 + 3 * vertexNumber]= 0.0f; - verticeVector[3 * i + 2 + 3 * vertexNumber]= static_cast(m_Length); - - normalsVector[3 * i + 3 * vertexNumber]= cosNormalArray[i]; - normalsVector[3 * i + 1 + 3 * vertexNumber]= sinNormalArray[i]; - normalsVector[3 * i + 2 + 3 * vertexNumber]= normalZ; - - texelVector[2 * i + 2 * vertexNumber]= texelVector[i]; - texelVector[2 * i + 1 + 2 * vertexNumber]= 1.0f; - - // Bottom Cap ends - verticeVector[3 * i + 2 * 3 * vertexNumber]= cosArray[i]; - verticeVector[3 * i + 1 + 2 * 3 * vertexNumber]= sinArray[i]; - verticeVector[3 * i + 2 + 2 * 3 * vertexNumber]= 0.0f; - - normalsVector[3 * i + 2 * 3 * vertexNumber]= 0.0f; - normalsVector[3 * i + 1 + 2 * 3 * vertexNumber]= 0.0f; - normalsVector[3 * i + 2 + 2 * 3 * vertexNumber]= -1.0f; - - texelVector[2 * i + 2 * 2 * vertexNumber]= texelVector[i]; - texelVector[2 * i + 1 + 2 * 2 * vertexNumber]= 0.0f; - - } - - // Add bulk data in to the mesh - GLC_Mesh::addVertice(verticeVector); - GLC_Mesh::addNormals(normalsVector); - GLC_Mesh::addTexels(texelVector); - - // Add polyline to wire data - GLC_Geometry::addVerticeGroup(bottomWireData); - - // Set the material to use - GLC_Material* pCylinderMaterial; - if (hasMaterial()) - { - pCylinderMaterial= this->firstMaterial(); - } - else - { - pCylinderMaterial= new GLC_Material(); - } - - IndexList circumferenceStrips; - // Create the index - for (int i= 0; i < vertexNumber; ++i) - { - circumferenceStrips.append(i + vertexNumber); - circumferenceStrips.append(i); - } - addTrianglesStrip(pCylinderMaterial, circumferenceStrips); - - { - IndexList bottomCap; - IndexList topCap; - int id1= 0; - int id2= m_Discret - 1; - const int size= m_Discret / 2 + (m_Discret % 2); - for (int i= 0; i < size; ++i) - { - bottomCap.append(id1 + 2 * vertexNumber); - bottomCap.append(id2 + 2 * vertexNumber); - - id1+= 1; - id2-= 1; - } - addTrianglesStrip(pCylinderMaterial, bottomCap); - } - - finish(); -} - diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_cone.h b/ground/gcs/src/libs/glc_lib/geometry/glc_cone.h deleted file mode 100644 index 4df74d5e7..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_cone.h +++ /dev/null @@ -1,145 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_cone.h interface for the GLC_Cone class. - -#ifndef GLC_CONE_H_ -#define GLC_CONE_H_ - -#include "glc_mesh.h" -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Cone -/*! \brief GLC_Cone : OpenGL 3D Cone*/ - -/*! An GLC_Cone is a polygonnal geometry */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_Cone : public GLC_Mesh -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Construct an GLC_Cone - /*! By default, discretion is set to #GLC_POLYDISCRET \n - * By default, Axis of Cylinder is Z Axis - * dRadius must be > 0 - * dLength must be > 0*/ - GLC_Cone(double dRadius, double dLength, int discretization= glc::GLC_POLYDISCRET); - - //! Copy contructor - GLC_Cone(const GLC_Cone& sourceCone); - - //! Destructor - virtual ~GLC_Cone(); -//@} - - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the class Chunk ID - static quint32 chunckID(); - - //! Get Lenght of the Cone - inline double length(void) const - {return m_Length;} - - //! Get Radius of cone - inline double radius(void) const - {return m_Radius;} - - //! Get Cone discretion - inline int discretion(void) const - {return m_Discret;} - - //! Return a copy of the Cone - virtual GLC_Geometry* clone() const; - - //! Return the cone bounding box - virtual const GLC_BoundingBox& boundingBox(void); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Set Cone length - /*! Length must be > 0*/ - void setLength(double Length); - - //! Set Cone radius - /*! Radius must be > 0*/ - void setRadius(double Radius); - - //! Set Discretion - /*! Discretion must be > 0*/ - void setDiscretion(int TargetDiscret); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -private: - //! Virtual interface for OpenGL Geometry set up. - /*! This Virtual function is implemented here.\n - * Throw GLC_OpenGlException*/ - virtual void glDraw(const GLC_RenderProperties&); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Private services Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -private: - //! Create the cylinder mesh and wire - void createMeshAndWire(); - -//@} - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - - //! Cone's radius - double m_Radius; - - //! Cone length (Z Axis direction) - double m_Length; - - //! Cone polygon discretisation - int m_Discret; - - //! Class chunk id - static quint32 m_ChunkId; - -}; - -#endif /* GLC_CONE_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_cylinder.cpp b/ground/gcs/src/libs/glc_lib/geometry/glc_cylinder.cpp deleted file mode 100644 index d364c8a30..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_cylinder.cpp +++ /dev/null @@ -1,320 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_cylinder.cpp implementation of the GLC_Cylinder class. - -#include "glc_cylinder.h" -#include "../glc_openglexception.h" -#include "../shading/glc_selectionmaterial.h" -#include "../glc_state.h" - -#include - -// Class chunk id -quint32 GLC_Cylinder::m_ChunkId= 0xA705; - -////////////////////////////////////////////////////////////////////// -// Constructor destructor -////////////////////////////////////////////////////////////////////// - -GLC_Cylinder::GLC_Cylinder(double dRadius, double dLength, int discretization) -:GLC_Mesh() -, m_Radius(dRadius) -, m_Length(dLength) -, m_Discret(discretization) // Default discretion -, m_EndedIsCaped(true) // Cylinder ended are closed -{ - Q_ASSERT((m_Radius > 0.0) && (m_Length > 0.0)); - createMeshAndWire(); -} - -GLC_Cylinder::GLC_Cylinder(const GLC_Cylinder& sourceCylinder) -:GLC_Mesh(sourceCylinder) -, m_Radius(sourceCylinder.m_Radius) -, m_Length(sourceCylinder.m_Length) -, m_Discret(sourceCylinder.m_Discret) -, m_EndedIsCaped(sourceCylinder.m_EndedIsCaped) -{ - Q_ASSERT((m_Radius > 0.0) && (m_Length > 0.0) && (m_Discret > 0)); - if (isEmpty()) createMeshAndWire(); -} - -GLC_Cylinder::~GLC_Cylinder() -{ - -} - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -quint32 GLC_Cylinder::chunckID() -{ - return m_ChunkId; -} - - -GLC_Geometry* GLC_Cylinder::clone() const -{ - return new GLC_Cylinder(*this); -} - - -const GLC_BoundingBox& GLC_Cylinder::boundingBox() -{ - if (GLC_Mesh::isEmpty()) - { - createMeshAndWire(); - } - return GLC_Mesh::boundingBox(); -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -void GLC_Cylinder::setLength(double Length) -{ - Q_ASSERT(Length > 0.0); - m_Length= Length; - - GLC_Mesh::clearMeshWireAndBoundingBox(); -} - - -void GLC_Cylinder::setRadius(double Radius) -{ - Q_ASSERT(Radius > 0.0); - m_Radius= Radius; - - GLC_Mesh::clearMeshWireAndBoundingBox(); -} - - -void GLC_Cylinder::setDiscretion(int TargetDiscret) -{ - Q_ASSERT(TargetDiscret > 0); - if (TargetDiscret != m_Discret) - { - m_Discret= TargetDiscret; - if (m_Discret < 6) m_Discret= 6; - - GLC_Mesh::clearMeshWireAndBoundingBox(); - } -} - - -void GLC_Cylinder::setEndedCaps(bool CapsEnded) -{ - if (m_EndedIsCaped != CapsEnded) - { - m_EndedIsCaped= CapsEnded; - - GLC_Mesh::clearMeshWireAndBoundingBox(); - } -} - -////////////////////////////////////////////////////////////////////// -// Private Opengl functions -////////////////////////////////////////////////////////////////////// - - -void GLC_Cylinder::glDraw(const GLC_RenderProperties& renderProperties) -{ - - if (GLC_Mesh::isEmpty()) - { - createMeshAndWire(); - } - - GLC_Mesh::glDraw(renderProperties); -} - - -void GLC_Cylinder::createMeshAndWire() -{ - Q_ASSERT(GLC_Mesh::isEmpty()); - Q_ASSERT(m_WireData.isEmpty()); - - // Create cosinus and sinus array according to the discretion and radius - const int vertexNumber= m_Discret + 1; - // Normals values - QVector cosNormalArray(vertexNumber); - QVector sinNormalArray(vertexNumber); - - QVector cosArray(vertexNumber); - QVector sinArray(vertexNumber); - - const double angle= (2.0 * glc::PI) / static_cast(m_Discret); - - for (int i= 0; i < vertexNumber; ++i) - { - const double cosValue= cos(static_cast(i) * angle); - const double sinValue= sin(static_cast(i) * angle); - - cosNormalArray[i]= static_cast(cosValue); - sinNormalArray[i]= static_cast(sinValue); - - cosArray[i]= static_cast(m_Radius * cosValue); - sinArray[i]= static_cast(m_Radius * sinValue); - } - - // Mesh Data - GLfloatVector verticeVector; - GLfloatVector normalsVector; - GLfloatVector texelVector; - - // Wire Data - GLfloatVector bottomWireData(vertexNumber * 3); - GLfloatVector topWireData(vertexNumber * 3); - - if (m_EndedIsCaped) - { - const int size= vertexNumber * 4; - verticeVector.resize(3 * size); - normalsVector.resize(3 * size); - texelVector.resize(2 * size); - } - else - { - const int size= vertexNumber * 2; - verticeVector.resize(3 * size); - normalsVector.resize(3 * size); - texelVector.resize(2 * size); - } - for (int i= 0; i < vertexNumber; ++i) - { - // Bottom Mesh - verticeVector[3 * i]= cosArray[i]; - verticeVector[3 * i + 1]= sinArray[i]; - verticeVector[3 * i + 2]= 0.0f; - - normalsVector[3 * i]= cosNormalArray[i]; - normalsVector[3 * i + 1]= sinNormalArray[i]; - normalsVector[3 * i + 2]= 0.0f; - - texelVector[2 * i]= static_cast(i) / static_cast(m_Discret); - texelVector[2 * i + 1]= 0.0f; - - // Bottom Wire - bottomWireData[3 * i]= cosArray[i]; - bottomWireData[3 * i + 1]= sinArray[i]; - bottomWireData[3 * i + 2]= 0.0f; - - // Top - verticeVector[3 * i + 3 * vertexNumber]= cosArray[i]; - verticeVector[3 * i + 1 + 3 * vertexNumber]= sinArray[i]; - verticeVector[3 * i + 2 + 3 * vertexNumber]= static_cast(m_Length); - - normalsVector[3 * i + 3 * vertexNumber]= cosNormalArray[i]; - normalsVector[3 * i + 1 + 3 * vertexNumber]= sinNormalArray[i]; - normalsVector[3 * i + 2 + 3 * vertexNumber]= 0.0f; - - texelVector[2 * i + 2 * vertexNumber]= texelVector[2 * i]; - texelVector[2 * i + 1 + 2 * vertexNumber]= 1.0f; - - // Top Wire - topWireData[3 * i]= cosArray[i]; - topWireData[3 * i + 1]= sinArray[i]; - topWireData[3 * i + 2]= static_cast(m_Length); - - if (m_EndedIsCaped) - { - // Bottom Cap ends - verticeVector[3 * i + 2 * 3 * vertexNumber]= cosArray[i]; - verticeVector[3 * i + 1 + 2 * 3 * vertexNumber]= sinArray[i]; - verticeVector[3 * i + 2 + 2 * 3 * vertexNumber]= 0.0f; - - normalsVector[3 * i + 2 * 3 * vertexNumber]= 0.0f; - normalsVector[3 * i + 1 + 2 * 3 * vertexNumber]= 0.0f; - normalsVector[3 * i + 2 + 2 * 3 * vertexNumber]= -1.0f; - - texelVector[2 * i + 2 * 2 * vertexNumber]= texelVector[2 * i]; - texelVector[2 * i + 1 + 2 * 2 * vertexNumber]= 0.0f; - - // Top Cap ends - verticeVector[3 * i + 3 * 3 * vertexNumber]= cosArray[i]; - verticeVector[3 * i + 1 + 3 * 3 * vertexNumber]= sinArray[i]; - verticeVector[3 * i + 2 + 3 * 3 * vertexNumber]= static_cast(m_Length); - - normalsVector[3 * i + 3 * 3 * vertexNumber]= 0.0f; - normalsVector[3 * i + 1 + 3 * 3 * vertexNumber]= 0.0f; - normalsVector[3 * i + 2 + 3 * 3 * vertexNumber]= 1.0f; - - texelVector[2 * i + 3 * 2 * vertexNumber]= texelVector[2 * i]; - texelVector[2 * i + 1 + 3 * 2 * vertexNumber]= 1.0f; - } - } - - // Add bulk data in to the mesh - GLC_Mesh::addVertice(verticeVector); - GLC_Mesh::addNormals(normalsVector); - GLC_Mesh::addTexels(texelVector); - - // Add polyline to wire data - GLC_Geometry::addVerticeGroup(bottomWireData); - GLC_Geometry::addVerticeGroup(topWireData); - - // Set the material to use - GLC_Material* pCylinderMaterial; - if (hasMaterial()) - { - pCylinderMaterial= this->firstMaterial(); - } - else - { - pCylinderMaterial= new GLC_Material(); - } - - IndexList circumferenceStrips; - // Create the index - for (int i= 0; i < vertexNumber; ++i) - { - circumferenceStrips.append(i + vertexNumber); - circumferenceStrips.append(i); - } - addTrianglesStrip(pCylinderMaterial, circumferenceStrips); - - if (m_EndedIsCaped) - { - IndexList bottomCap; - IndexList topCap; - int id1= 0; - int id2= m_Discret - 1; - const int size= m_Discret / 2 + (m_Discret % 2); - for (int i= 0; i < size; ++i) - { - bottomCap.append(id1 + 2 * vertexNumber); - topCap.append(id2 + 3 * vertexNumber); - - bottomCap.append(id2 + 2 * vertexNumber); - topCap.append(id1 + 3 * vertexNumber); - - id1+= 1; - id2-= 1; - } - addTrianglesStrip(pCylinderMaterial, bottomCap); - addTrianglesStrip(pCylinderMaterial, topCap); - } - - finish(); -} diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_cylinder.h b/ground/gcs/src/libs/glc_lib/geometry/glc_cylinder.h deleted file mode 100644 index 37a538972..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_cylinder.h +++ /dev/null @@ -1,157 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_cylinder.h interface for the GLC_Cylinder class. - -#ifndef GLC_CYLINDER_H_ -#define GLC_CYLINDER_H_ - -#include "glc_mesh.h" -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Cylinder -/*! \brief GLC_Cylinder : OpenGL 3D Cylinder*/ - -/*! An GLC_Cylinder is a polygonnal geometry \n - * It can be capped or not - * */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_Cylinder : public GLC_Mesh -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Construct an GLC_Cylinder - /*! By default, discretion is set to #GLC_POLYDISCRET \n - * By default, Axis of Cylinder is Z Axis - * dRadius must be > 0 - * dLength must be > 0*/ - GLC_Cylinder(double dRadius, double dLength, int discretization= glc::GLC_POLYDISCRET); - - //! Copy contructor - GLC_Cylinder(const GLC_Cylinder& sourceCylinder); - - //! Destructor - virtual ~GLC_Cylinder(); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the class Chunk ID - static quint32 chunckID(); - - //! Get Lenght of the Cylinder - inline double length(void) const - {return m_Length;} - - //! Get Radius of cylinder - inline double radius(void) const - {return m_Radius;} - - //! Get Cylinder discretion - inline int discretion(void) const - {return m_Discret;} - - //! Return a copy of the Cylinder - virtual GLC_Geometry* clone() const; - - //! return true if cylinder's ended are capped - bool EndedIsCaped() const {return m_EndedIsCaped;} - - //! return the cylinder bounding box - virtual const GLC_BoundingBox& boundingBox(void); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Set Cylinder length - /*! Length must be > 0*/ - void setLength(double Length); - - //! Set Cylinder radius - /*! Radius must be > 0*/ - void setRadius(double Radius); - - //! Set Discretion - /*! Discretion must be > 0*/ - void setDiscretion(int TargetDiscret); - - //! End Caps - void setEndedCaps(bool CapsEnded); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -private: - //! Virtual interface for OpenGL Geometry set up. - /*! This Virtual function is implemented here.\n - * Throw GLC_OpenGlException*/ - virtual void glDraw(const GLC_RenderProperties&); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Private services Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -private: - //! Create the cylinder mesh and wire - void createMeshAndWire(); - -//@} - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - - //! Cylinder's radius - double m_Radius; - - //! Cylinder length (Z Axis direction) - double m_Length; - - //! Cylinder polygon discretisation - int m_Discret; - - //! Cylinder is capped - bool m_EndedIsCaped; - - //! Class chunk id - static quint32 m_ChunkId; - -}; -#endif //GLC_CYLINDER_H_ diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_disc.cpp b/ground/gcs/src/libs/glc_lib/geometry/glc_disc.cpp deleted file mode 100644 index c9d76e584..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_disc.cpp +++ /dev/null @@ -1,217 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_disc.cpp implementation of the GLC_Disc class. - -#include "glc_disc.h" - -GLC_Disc::GLC_Disc(double radius, double angle, int discretization) -: GLC_Mesh() -, m_Radius(radius) -, m_Discret(discretization) -, m_Angle(angle) -, m_Step(0) -{ - createMeshAndWire(); -} - -GLC_Disc::GLC_Disc(const GLC_Disc& disc) -: GLC_Mesh(disc) -, m_Radius(disc.m_Radius) -, m_Discret(disc.m_Discret) -, m_Angle(disc.m_Angle) -, m_Step(disc.m_Step) -{ - createMeshAndWire(); -} - -GLC_Disc::~GLC_Disc() -{ - -} - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -const GLC_BoundingBox& GLC_Disc::boundingBox() -{ - if (GLC_Mesh::isEmpty()) - { - createMeshAndWire(); - } - return GLC_Mesh::boundingBox(); -} - -GLC_Geometry* GLC_Disc::clone() const -{ - return new GLC_Disc(*this); -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// -GLC_Disc& GLC_Disc::operator=(const GLC_Disc& disc) -{ - if (this != &disc) - { - // Call the operator of the super class - GLC_Mesh::operator=(disc); - - m_Radius= disc.m_Radius; - m_Discret= disc.m_Discret; - m_Angle= disc.m_Angle; - m_Step= disc.m_Step; - } - return *this; -} - -void GLC_Disc::setRadius(double radius) -{ - Q_ASSERT(radius > 0.0); - m_Radius= radius; - - GLC_Mesh::clearMeshWireAndBoundingBox(); -} - -void GLC_Disc::setDiscretion(int targetDiscret) -{ - Q_ASSERT(targetDiscret > 0); - if (targetDiscret != m_Discret) - { - m_Discret= targetDiscret; - if (m_Discret < 6) m_Discret= 6; - - GLC_Mesh::clearMeshWireAndBoundingBox(); - } -} - -void GLC_Disc::setAngle(double angle) -{ - Q_ASSERT(angle > 0.0); - m_Angle= angle; - - GLC_Mesh::clearMeshWireAndBoundingBox(); -} -////////////////////////////////////////////////////////////////////// -// Private Opengl functions -////////////////////////////////////////////////////////////////////// -void GLC_Disc::glDraw(const GLC_RenderProperties& renderProperties) -{ - - if (GLC_Mesh::isEmpty()) - { - createMeshAndWire(); - } - GLC_Mesh::glDraw(renderProperties); -} - -// Create the cylinder mesh -void GLC_Disc::createMeshAndWire() -{ - Q_ASSERT(GLC_Mesh::isEmpty()); - Q_ASSERT(m_WireData.isEmpty()); - - m_Step= static_cast(static_cast(m_Discret) * (m_Angle / (2 * glc::PI))); - if (m_Step < 2) m_Step= 2; - - // Create cosinus and sinus array according to the discretion and radius - const int vertexNumber= m_Step + 1; - - QVector cosArray(vertexNumber); - QVector sinArray(vertexNumber); - - const double angle= m_Angle / static_cast(m_Step); - for (int i= 0; i < vertexNumber; ++i) - { - const double cosValue= cos(static_cast(i) * angle); - const double sinValue= sin(static_cast(i) * angle); - - cosArray[i]= static_cast(m_Radius * cosValue); - sinArray[i]= static_cast(m_Radius * sinValue); - } - - // Mesh Data - GLfloatVector verticeVector(vertexNumber * 3); - GLfloatVector normalsVector(vertexNumber * 3); - GLfloatVector texelVector(vertexNumber * 2); - - // Wire Data - GLfloatVector wireData(vertexNumber * 3); - - for (int i= 0; i < vertexNumber; ++i) - { - verticeVector[3 * i]= cosArray[i]; - verticeVector[3 * i + 1]= sinArray[i]; - verticeVector[3 * i + 2]= 0.0f; - - normalsVector[3 * i]= 0.0f; - normalsVector[3 * i + 1]= 0.0f; - normalsVector[3 * i + 2]= 1.0f; - - texelVector[2 * i]= texelVector[i]; - texelVector[2 * i + 1]= 0.0f; - - wireData[3 * i]= cosArray[i]; - wireData[3 * i + 1]= sinArray[i]; - wireData[3 * i + 2]= 0.0f; - } - // Center Point - verticeVector << 0.0f << 0.0f << 0.0f; - normalsVector << 0.0f << 0.0f << 1.0f; - texelVector << 0.5f << 0.5f; - - if (!qFuzzyCompare(m_Angle, (2.0 * glc::PI))) - { - wireData << 0.0f << 0.0f << 0.0f; - wireData << wireData[0] << wireData[1] << wireData[2]; - } - - // Add bulk data in to the mesh - GLC_Mesh::addVertice(verticeVector); - GLC_Mesh::addNormals(normalsVector); - GLC_Mesh::addTexels(texelVector); - - // Add polyline to wire data - GLC_Geometry::addVerticeGroup(wireData); - - // Set the material to use - GLC_Material* pDiscMaterial; - if (hasMaterial()) - { - pDiscMaterial= this->firstMaterial(); - } - else - { - pDiscMaterial= new GLC_Material(); - } - - IndexList discIndex; - discIndex << vertexNumber; - for (int i= 0; i < vertexNumber; ++i) - { - discIndex << i; - } - - addTrianglesFan(pDiscMaterial, discIndex); - - finish(); -} diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_disc.h b/ground/gcs/src/libs/glc_lib/geometry/glc_disc.h deleted file mode 100644 index 91d372eda..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_disc.h +++ /dev/null @@ -1,137 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_disc.h interface for the GLC_Disc class. - -#ifndef GLC_DISC_H_ -#define GLC_DISC_H_ - -#include "glc_mesh.h" -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Disc -/*! \brief GLC_Disc : OpenGL 3D Disc*/ - -/*! An GLC_Disc is a polygonnal disc */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_Disc : public GLC_Mesh -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Construct a disc with the given radius - GLC_Disc(double radius, double angle= 2.0 * glc::PI, int discretization= glc::GLC_POLYDISCRET); - - //! Copy constructor - GLC_Disc(const GLC_Disc& disc); - - //! Destructor - virtual ~GLC_Disc(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return this disc bounding box - virtual const GLC_BoundingBox& boundingBox(void); - - //! Return a copy of this Disc - virtual GLC_Geometry* clone() const; - - //! Return the radius of this disc - inline double radius() const - {return m_Radius;} - - //! Return the discretion of this disc - inline int discretion() const - {return m_Discret;} - - //! Return the angle of this disc - inline double angle() const - {return m_Angle;} - - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Set this disc from the given disc and return a reference of this disc - GLC_Disc& operator=(const GLC_Disc& disc); - - //! Set this disc radius to the given radius - void setRadius(double radius); - - //! Set this disc discretion to the given discretion - void setDiscretion(int targetDiscret); - - //! Set this disc angle in radians - void setAngle(double angle); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -private: - //! Virtual interface for OpenGL Geometry set up. - /*! This Virtual function is implemented here.\n - * Throw GLC_OpenGlException*/ - virtual void glDraw(const GLC_RenderProperties&); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Private services Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -private: - //! Create the cylinder mesh and wire - void createMeshAndWire(); - -//@} - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - //! Disc radius - double m_Radius; - - //! Disc polygon discretisation - int m_Discret; - - //! Angle of disc in radians - double m_Angle; - - //! Disc Step - GLuint m_Step; - -}; - -#endif /* GLC_DISC_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_extrudedmesh.cpp b/ground/gcs/src/libs/glc_lib/geometry/glc_extrudedmesh.cpp deleted file mode 100644 index 1b3dafaee..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_extrudedmesh.cpp +++ /dev/null @@ -1,535 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2013 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_extrudedmesh.cpp Implementation of the GLC_ExtrudedMesh class. - -#include - -#include "glc_extrudedmesh.h" -#include "../maths/glc_plane.h" -#include "../maths/glc_geomtools.h" - -// Class chunk id -quint32 GLC_ExtrudedMesh::m_ChunkId= 0xA712; - -GLC_ExtrudedMesh::GLC_ExtrudedMesh(const QList &points, const GLC_Vector3d &dir, double lenght) - :GLC_Mesh() - , m_Points(points) - , m_ExtrusionVector(GLC_Vector3d(dir).normalize()) - , m_ExtrusionLenght(lenght) - , m_GivenFaceNormal() -{ - Q_ASSERT(m_Points.size() > 2); - Q_ASSERT(pointsLieOnAPlane()); - Q_ASSERT(!glc::compare(m_Points.first(), m_Points.last(), glc::EPSILON)); - - computeGivenFaceNormal(); - createMeshAndWire(); -} - -GLC_ExtrudedMesh::GLC_ExtrudedMesh(const GLC_ExtrudedMesh &other) - :GLC_Mesh(other) - , m_Points(other.m_Points) - , m_ExtrusionVector(other.m_ExtrusionVector) - , m_ExtrusionLenght(other.m_ExtrusionLenght) - , m_GivenFaceNormal(other.m_GivenFaceNormal) -{ - if (GLC_Mesh::isEmpty()) - { - createMeshAndWire(); - } -} - -GLC_ExtrudedMesh::~GLC_ExtrudedMesh() -{ - -} - -quint32 GLC_ExtrudedMesh::chunckID() -{ - return m_ChunkId; -} - -GLC_Geometry *GLC_ExtrudedMesh::clone() const -{ - return new GLC_ExtrudedMesh(*this); -} - -const GLC_BoundingBox &GLC_ExtrudedMesh::boundingBox() -{ - if (GLC_Mesh::isEmpty()) - { - createMeshAndWire(); - } - return GLC_Mesh::boundingBox(); -} - -GLC_ExtrudedMesh &GLC_ExtrudedMesh::operator =(const GLC_ExtrudedMesh &other) -{ - if (this != &other) - { - GLC_Mesh::operator =(other); - m_Points= other.m_Points; - m_ExtrusionVector= other.m_ExtrusionVector; - m_ExtrusionLenght= other.m_ExtrusionLenght; - m_GivenFaceNormal= other.m_GivenFaceNormal; - } - - return *this; -} - -void GLC_ExtrudedMesh::setGeometry(const QList &points, const GLC_Vector3d &extrudedVector, double lenght) -{ - m_Points= points; - m_ExtrusionVector= extrudedVector; - m_ExtrusionLenght= lenght; - - GLC_Mesh::clearMeshWireAndBoundingBox(); - createMeshAndWire(); -} - -void GLC_ExtrudedMesh::setPoints(const QList &points) -{ - m_Points= points; - - GLC_Mesh::clearMeshWireAndBoundingBox(); - createMeshAndWire(); -} - -void GLC_ExtrudedMesh::setExtrudedVector(const GLC_Vector3d &extrudedVector) -{ - m_ExtrusionVector= extrudedVector; - - GLC_Mesh::clearMeshWireAndBoundingBox(); - createMeshAndWire(); -} - -void GLC_ExtrudedMesh::setExtrudedLenght(double lenght) -{ - m_ExtrusionLenght= lenght; - - GLC_Mesh::clearMeshWireAndBoundingBox(); - createMeshAndWire(); -} - -void GLC_ExtrudedMesh::createMeshAndWire() -{ - Q_ASSERT(GLC_Mesh::isEmpty()); - Q_ASSERT(m_WireData.isEmpty()); - - createMesh(); - createWire(); - - finish(); -} - -void GLC_ExtrudedMesh::createMesh() -{ - // Bulk data - GLfloatVector vertices; - GLfloatVector normals; - GLfloatVector texels= baseFaceTexels() + createdFaceTexels() + basedOutlineFacesTexels() + createdOutlineFacesTexels(); - GLC_Mesh::addTexels(texels); - - // Set the material to use - GLC_Material* pMaterial; - if (hasMaterial()) pMaterial= this->firstMaterial(); - else pMaterial= new GLC_Material(); - - { - // Given face (Face 1) - GLfloatVector face1Vertices= baseFaceVertices(); - GLfloatVector face1Normals= baseFaceNormals(); - IndexList face1Index; - const GLuint count= m_Points.count(); - for (GLuint i= 0; i < (count + 1); ++i) - { - face1Index.append(i % count); - } - vertices+= face1Vertices; - normals+= face1Normals; - Q_ASSERT(vertices.size() == normals.size()); - glc::triangulatePolygon(&face1Index, vertices.toList()); - addTriangles(pMaterial, face1Index); - } - - { - // Created face (Face2) - GLfloatVector face2Vertices= createdFaceVertices(); - GLfloatVector face2Normals= createdFaceNormals(); - IndexList face2Index; - const int offset= vertices.size() / 3; - const GLuint count= m_Points.count(); - for (GLuint i= 0; i < (count + 1); ++i) - { - face2Index.append(offset + (i % count)); - } - vertices+= face2Vertices; - normals+= face2Normals; - Q_ASSERT(vertices.size() == normals.size()); - glc::triangulatePolygon(&face2Index, vertices.toList()); - addTriangles(pMaterial, face2Index); - } - - - { - // Add outline faces - const GLuint count= m_Points.count(); - GLuint offset1= vertices.size() / 3; - GLfloatVector facesNormals= baseOutlineNormals(); - GLuint indexLenght= (facesNormals.size() / 3); - GLuint offset2= offset1 + indexLenght; - facesNormals= facesNormals + createdOutlineNormals(); - GLfloatVector facesVertices= baseOutlineFacesVertices() + createdOutlineFacesVertices(); - vertices+= facesVertices; - normals+= facesNormals; - - for (GLuint face= 0; face < count; ++face) - { - IndexList faceIndex; - GLuint startIndex1= offset1 + (face * 2); - GLuint startIndex2= offset2 + (indexLenght -1) - (face * 2); - faceIndex << startIndex1 << startIndex2 << (startIndex1 + 1) << (startIndex2 - 1); - addTrianglesStrip(pMaterial, faceIndex); - } - } - - // Add bulk data in to the mesh - GLC_Mesh::addVertice(vertices); - GLC_Mesh::addNormals(normals); - -} - -void GLC_ExtrudedMesh::createWire() -{ - GLfloatVector baseFaceWire= baseFaceVertices(); - baseFaceWire << baseFaceWire.at(0) << baseFaceWire.at(1) << baseFaceWire.at(2); - GLC_Geometry::addVerticeGroup(baseFaceWire); - - GLfloatVector createdFaceWire= createdFaceVertices(); - createdFaceWire << createdFaceWire.at(0) << createdFaceWire.at(1) << createdFaceWire.at(2); - GLC_Geometry::addVerticeGroup(createdFaceWire); - - // Outline edges - const int count= m_Points.count(); - for (int i= 0; i < count; ++i) - { - GLfloatVector edge(6); // the edge is a line - edge[0]= baseFaceWire.at(i * 3); - edge[1]= baseFaceWire.at(i * 3 + 1); - edge[2]= baseFaceWire.at(i * 3 + 2); - - edge[3]= createdFaceWire.at(((count - i) % count) * 3); - edge[4]= createdFaceWire.at(((count - i) % count) * 3 + 1); - edge[5]= createdFaceWire.at(((count - i) % count) * 3 + 2); - - GLC_Geometry::addVerticeGroup(edge); - } -} - -void GLC_ExtrudedMesh::computeGivenFaceNormal() -{ - Q_ASSERT(m_Points.count() > 2); - - const GLC_Vector3d edge1(GLC_Vector3d(m_Points.at(1) - m_Points.at(0)).normalize()); - const GLC_Vector3d edge2(GLC_Vector3d(m_Points.at(2) - m_Points.at(1)).normalize()); - - m_GivenFaceNormal= edge1 ^ edge2; -} - -bool GLC_ExtrudedMesh::pointsLieOnAPlane() const -{ - bool subject= true; - const int count= m_Points.count(); - Q_ASSERT(count > 2); - if (count > 3) - { - // Create a plane on the first 3 points - GLC_Plane plane(m_Points.at(0), m_Points.at(1), m_Points.at(2)); - - // Check if others points lie on the plane - for (int i= 3; i < count; ++i) - { - subject= plane.lieOnThisPlane(m_Points.at(i)); - if (!subject) break; - } - } - - return subject; -} - -GLfloatVector GLC_ExtrudedMesh::baseOutlineNormals() const -{ - const int count= m_Points.count(); - GLfloatVector subject(count * 6); // 2 normals by vertex and 3 components pear normal => 6 - for (int i= 0; i < count; ++i) - { - GLC_Vector3d vect(m_Points.at((i + 1) % count) - m_Points.at(i)); - GLC_Vector3d normal= GLC_Vector3d(m_ExtrusionVector ^ vect).normalize(); - - // First segment point - subject[(6 * i)]= static_cast(normal.x()); - subject[(6 * i) + 1]= static_cast(normal.y()); - subject[(6 * i) + 2]= static_cast(normal.z()); - - // Second segment point - subject[(6 * i) + 3]= static_cast(normal.x()); - subject[(6 * i) + 4]= static_cast(normal.y()); - subject[(6 * i) + 5]= static_cast(normal.z()); - } - - return subject; -} - -GLfloatVector GLC_ExtrudedMesh::createdOutlineNormals() const -{ - const int count= m_Points.count(); - GLfloatVector subject(count * 6); // 2 normals by vertex and 3 components pear normal => 6 - int index= 0.0; - for (int i= count; i > 0; --i) - { - GLC_Vector3d vect(m_Points.at(i % count) - m_Points.at(i - 1)); - GLC_Vector3d normal= GLC_Vector3d(m_ExtrusionVector ^ vect).normalize(); - - // First segment point - subject[(6 * index)]= static_cast(normal.x()); - subject[(6 * index) + 1]= static_cast(normal.y()); - subject[(6 * index) + 2]= static_cast(normal.z()); - - // Second segment point - subject[(6 * index) + 3]= static_cast(normal.x()); - subject[(6 * index) + 4]= static_cast(normal.y()); - subject[(6 * index) + 5]= static_cast(normal.z()); - ++index; - } - - return subject; -} - -GLfloatVector GLC_ExtrudedMesh::baseFaceVertices() const -{ - const int count= m_Points.count(); - GLfloatVector subject(count * 3); // 3 components pear vertice - for (int i= 0; i < count; ++i) - { - GLC_Point3d point= m_Points.at(i); - subject[(3 * i)]= static_cast(point.x()); - subject[(3 * i) + 1]= static_cast(point.y()); - subject[(3 * i) + 2]= static_cast(point.z()); - } - - return subject; -} - -GLfloatVector GLC_ExtrudedMesh::baseFaceTexels() const -{ - const int count= m_Points.count(); - GLfloatVector subject(count * 2); - - QList baseFace2DPolygon= glc::polygonIn2d(m_Points); - QList normalizePolygon= glc::normalyzePolygon(baseFace2DPolygon); - - for (int i= 0; i < count; ++i) - { - GLC_Point2d texel= normalizePolygon.at(i); - subject[i * 2]= static_cast(texel.x()); - subject[i * 2 + 1]= static_cast(texel.y()); - } - - return subject; -} - -GLfloatVector GLC_ExtrudedMesh::baseOutlineFacesVertices() const -{ - const int count= m_Points.count(); - GLfloatVector subject(count * 6); // 3 components pear vertice * 2 - for (int i= 0; i < count; ++i) - { - GLC_Point3d point1= m_Points.at(i); - subject[(6 * i)]= static_cast(point1.x()); - subject[(6 * i) + 1]= static_cast(point1.y()); - subject[(6 * i) + 2]= static_cast(point1.z()); - - GLC_Point3d point2= m_Points.at((i + 1) % count); - subject[(6 * i) + 3]= static_cast(point2.x()); - subject[(6 * i) + 4]= static_cast(point2.y()); - subject[(6 * i) + 5]= static_cast(point2.z()); - } - - return subject; -} - -GLfloatVector GLC_ExtrudedMesh::basedOutlineFacesTexels() const -{ - const int count= m_Points.count(); - GLfloatVector subject(count * 4); - - QList baseFace2DPolygon= glc::polygonIn2d(m_Points); - QList normalizePolygon= glc::normalyzePolygon(baseFace2DPolygon); - - for (int i= 0; i < count; ++i) - { - GLC_Point2d texel1= normalizePolygon.at(i); - subject[i * 4]= static_cast(texel1.x()); - subject[i * 4 + 1]= static_cast(texel1.y()); - - GLC_Point2d texel2= normalizePolygon.at((i + 1) % count); - subject[i * 4 + 2]= static_cast(texel2.x()); - subject[i * 4 + 3]= static_cast(texel2.y()); - } - - return subject; -} - -GLfloatVector GLC_ExtrudedMesh::baseFaceNormals() const -{ - const int count= m_Points.count(); - GLfloatVector subject(count * 3); // 3 components pear normal - for (int i= 0; i < count; ++i) - { - subject[(3 * i)]= static_cast(m_GivenFaceNormal.x()); - subject[(3 * i) + 1]= static_cast(m_GivenFaceNormal.y()); - subject[(3 * i) + 2]= static_cast(m_GivenFaceNormal.z()); - } - - return subject; -} - -QList GLC_ExtrudedMesh::createdFacePoints() const -{ - // The order is inverted to preserve face counterclockwise order - const GLC_Vector3d offset(m_ExtrusionVector * m_ExtrusionLenght); - const int count= m_Points.count(); - QList subject; - for (int i= 0; i < count; ++i) - { - subject.append(m_Points.at((count -i) % count) + offset); - } - - return subject; -} - -GLfloatVector GLC_ExtrudedMesh::createdFaceNormals() const -{ - const GLC_Vector3d normal= m_GivenFaceNormal.inverted(); - - const int count= m_Points.count(); - GLfloatVector subject(count * 3); // 3 components pear normal - for (int i= 0; i < count; ++i) - { - subject[(3 * i)]= static_cast(normal.x()); - subject[(3 * i) + 1]= static_cast(normal.y()); - subject[(3 * i) + 2]= static_cast(normal.z()); - } - - return subject; -} - -GLfloatVector GLC_ExtrudedMesh::createdFaceVertices() const -{ - QList points= createdFacePoints(); - - const int count= points.count(); - GLfloatVector subject(count * 3); // 3 components pear normal - for (int i= 0; i < count; ++i) - { - GLC_Point3d point= points.at(i); - subject[(3 * i)]= static_cast(point.x()); - subject[(3 * i) + 1]= static_cast(point.y()); - subject[(3 * i) + 2]= static_cast(point.z()); - } - - return subject; -} - -GLfloatVector GLC_ExtrudedMesh::createdFaceTexels() const -{ - const int count= m_Points.count(); - GLfloatVector subject(count * 2); - - QList baseFace2DPolygon= glc::polygonIn2d(createdFacePoints()); - QList normalizePolygon= glc::normalyzePolygon(baseFace2DPolygon); - - for (int i= 0; i < count; ++i) - { - GLC_Point2d texel= normalizePolygon.at(i); - subject[i * 2]= static_cast(texel.x()); - subject[i * 2 + 1]= static_cast(texel.y()); - } - - return subject; - -} - -GLfloatVector GLC_ExtrudedMesh::createdOutlineFacesVertices() const -{ - QList points= createdFacePoints(); - const int count= points.count(); - GLfloatVector subject(count * 6); // 3 components pear vertice * 2 - for (int i= 0; i < count; ++i) - { - GLC_Point3d point1= points.at(i); - subject[(6 * i)]= static_cast(point1.x()); - subject[(6 * i) + 1]= static_cast(point1.y()); - subject[(6 * i) + 2]= static_cast(point1.z()); - - GLC_Point3d point2= points.at((i + 1) % count); - subject[(6 * i) + 3]= static_cast(point2.x()); - subject[(6 * i) + 4]= static_cast(point2.y()); - subject[(6 * i) + 5]= static_cast(point2.z()); - } - - return subject; - -} - -GLfloatVector GLC_ExtrudedMesh::createdOutlineFacesTexels() const -{ - const int count= m_Points.count(); - GLfloatVector subject(count * 4); - - QList baseFace2DPolygon= glc::polygonIn2d(createdFacePoints()); - QList normalizePolygon= glc::normalyzePolygon(baseFace2DPolygon); - - for (int i= 0; i < count; ++i) - { - GLC_Point2d texel1= normalizePolygon.at(i); - subject[i * 4]= static_cast(texel1.x()); - subject[i * 4 + 1]= static_cast(texel1.y()); - - GLC_Point2d texel2= normalizePolygon.at((i + 1) % count); - subject[i * 4 + 2]= static_cast(texel2.x()); - subject[i * 4 + 3]= static_cast(texel2.y()); - } - - return subject; -} - -void GLC_ExtrudedMesh::glDraw(const GLC_RenderProperties& renderProperties) -{ - if (GLC_Mesh::isEmpty()) - { - createMeshAndWire(); - } - - GLC_Mesh::glDraw(renderProperties); -} diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_extrudedmesh.h b/ground/gcs/src/libs/glc_lib/geometry/glc_extrudedmesh.h deleted file mode 100644 index 9c4b1dc46..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_extrudedmesh.h +++ /dev/null @@ -1,203 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2013 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_extrudedmesh.h Interface for the GLC_ExtrudedMesh class. - -#ifndef GLC_EXTRUDEDMESH_H -#define GLC_EXTRUDEDMESH_H - -#include -#include "glc_mesh.h" -#include "../maths/glc_vector3d.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_ExtrudedMesh -/*! \brief GLC_ExtrudedMesh : An Extruded mesh defined by a list of points, - *a direction and a distance*/ -////////////////////////////////////////////////////////////////////// - -class GLC_LIB_EXPORT GLC_ExtrudedMesh : public GLC_Mesh -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// - -public: - //! Default constructor - /*! The points list must be in counterclockwise order*/ - GLC_ExtrudedMesh(const QList& points, const GLC_Vector3d& dir, double lenght); - - //! Copy constructor - GLC_ExtrudedMesh(const GLC_ExtrudedMesh& other); - - //! Destructor - virtual ~GLC_ExtrudedMesh(); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the class Chunk ID - static quint32 chunckID(); - - //! Return the list of points which defined the face to extrude - inline QList facePoints() const - {return m_Points;} - - //! Return the extrusion vector - inline GLC_Vector3d extrusionVector() const - {return m_ExtrusionVector;} - - //! Return the extrusion lenght - inline double extrusionLenght() const - {return m_ExtrusionLenght;} - - //! Return a copy of the extruded mesh - virtual GLC_Geometry* clone() const; - - //! Return the extruded mesh bounding box - virtual const GLC_BoundingBox& boundingBox(void); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Assignement operator overload - GLC_ExtrudedMesh& operator=(const GLC_ExtrudedMesh& other); - - //! Set the mesh from the given points, vector and lenght - void setGeometry(const QList& points, const GLC_Vector3d& extrudedVector, double lenght); - - //! Set the mesh points list - void setPoints(const QList& points); - - //! Set the mesh extruded vector - void setExtrudedVector(const GLC_Vector3d& extrudedVector); - - //! Set the mesh extruded lenght - void setExtrudedLenght(double lenght); - - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -protected: - //! Virtual interface for OpenGL Geometry set up. - /*! This Virtual function have to be implemented in concrete class.*/ - virtual void glDraw(const GLC_RenderProperties& renderProperties); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Private services Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -private: - //! Create the extruded mesh mesh and wire - void createMeshAndWire(); - - //! Create the extruded mesh mesh - void createMesh(); - - //! Create the extruded mesh wire - void createWire(); - - //! compute the given face normal - void computeGivenFaceNormal(); - - //! Return true if the list of points lie on a plane - bool pointsLieOnAPlane() const; - - //! Return base outline normmals - GLfloatVector baseOutlineNormals() const; - - //! Return created outline normmals - GLfloatVector createdOutlineNormals() const; - - //! Return base face vertices - GLfloatVector baseFaceVertices() const; - - //! Return base face texel - GLfloatVector baseFaceTexels() const; - - //! Return base outline faces vertices - GLfloatVector baseOutlineFacesVertices() const; - - //! Return base outline faces texels - GLfloatVector basedOutlineFacesTexels() const; - - //! Return the base face normals - GLfloatVector baseFaceNormals() const; - - //! Return the list of points of the created face - QList createdFacePoints() const; - - //! Return the created face normals - GLfloatVector createdFaceNormals() const; - - //! Return created face vertices - GLfloatVector createdFaceVertices() const; - - //! Return created face texels - GLfloatVector createdFaceTexels() const; - - //! Return created outline faces vertices - GLfloatVector createdOutlineFacesVertices() const; - - //! Return created outline faces texels - GLfloatVector createdOutlineFacesTexels() const; - -//@} - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - //! The list of point which define the face to extrude - QList m_Points; - - //! The direction of extrusion - GLC_Vector3d m_ExtrusionVector; - - //! The extrusion lenght - double m_ExtrusionLenght; - - //! The normal of the given face - GLC_Vector3d m_GivenFaceNormal; - - //! Class chunk id - static quint32 m_ChunkId; -}; - -#endif // GLC_EXTRUDEDMESH_H diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_geometry.cpp b/ground/gcs/src/libs/glc_lib/geometry/glc_geometry.cpp deleted file mode 100644 index 77880818c..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_geometry.cpp +++ /dev/null @@ -1,394 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_geometry.cpp Implementation of the GLC_Geometry class. - -#include "../shading/glc_selectionmaterial.h" -#include "../glc_openglexception.h" -#include "../glc_state.h" -#include "../glc_context.h" -#include "glc_geometry.h" - -////////////////////////////////////////////////////////////////////// -// Constructor destructor -////////////////////////////////////////////////////////////////////// -// Default constructor -GLC_Geometry::GLC_Geometry(const QString& name, const bool typeIsWire) -: m_GeometryIsValid(false) // By default geometry is invalid -, m_pBoundingBox(NULL) -, m_MaterialHash() -, m_UseColorPerVertex(false) -, m_IsSelected(false) -, m_WireData() -, m_WireColor(Qt::black) -, m_LineWidth(1.0f) -, m_IsWire(typeIsWire) // the geometry type -, m_TransparentMaterialNumber(0) -, m_Id(glc::GLC_GenGeomID()) -, m_Name(name) -, m_UseVbo(false) -{ - -} -// Copy constructor -GLC_Geometry::GLC_Geometry(const GLC_Geometry& sourceGeom) -: m_GeometryIsValid(false) // By default geometry is invalid -, m_pBoundingBox(NULL) -, m_MaterialHash(sourceGeom.m_MaterialHash) -, m_UseColorPerVertex(sourceGeom.m_UseColorPerVertex) -, m_IsSelected(false) -, m_WireData(sourceGeom.m_WireData) -, m_WireColor(sourceGeom.m_WireColor) -, m_LineWidth(sourceGeom.m_LineWidth) -, m_IsWire(sourceGeom.m_IsWire) -, m_TransparentMaterialNumber(sourceGeom.m_TransparentMaterialNumber) -, m_Id(glc::GLC_GenGeomID()) -, m_Name(sourceGeom.m_Name) -, m_UseVbo(sourceGeom.m_UseVbo) -{ - // Add this mesh to inner material - MaterialHash::const_iterator i= sourceGeom.m_MaterialHash.constBegin(); - while (i != sourceGeom.m_MaterialHash.constEnd()) - { - // update inner material use table - i.value()->addGLC_Geom(this); - ++i; - } - - if (NULL != sourceGeom.m_pBoundingBox) - { - m_pBoundingBox= new GLC_BoundingBox(*sourceGeom.m_pBoundingBox); - } -} - -// Overload "=" operator -GLC_Geometry& GLC_Geometry::operator=(const GLC_Geometry& sourceGeom) -{ - if (this != &sourceGeom) - { - clear(); - m_GeometryIsValid= false; - m_pBoundingBox= NULL; - m_MaterialHash= sourceGeom.m_MaterialHash; - m_UseColorPerVertex= sourceGeom.m_UseColorPerVertex; - m_IsSelected= false; - m_WireData= sourceGeom.m_WireData; - m_WireColor= sourceGeom.m_WireColor; - m_LineWidth= sourceGeom.m_LineWidth; - m_IsWire= sourceGeom.m_IsWire; - m_TransparentMaterialNumber= sourceGeom.m_TransparentMaterialNumber; - m_Id= glc::GLC_GenGeomID(); - m_Name= sourceGeom.m_Name; - m_UseVbo= sourceGeom.m_UseVbo; - } - return *this; -} - -GLC_Geometry::~GLC_Geometry() -{ - // delete mesh inner material - { - MaterialHash::const_iterator i= m_MaterialHash.begin(); - while (i != m_MaterialHash.constEnd()) - { - // delete the material if necessary - i.value()->delGLC_Geom(id()); - if (i.value()->isUnused()) delete i.value(); - ++i; - } - } - m_MaterialHash.clear(); - - delete m_pBoundingBox; - -} - -///////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -// Get number of faces -unsigned int GLC_Geometry::faceCount(int) const -{ - return 0; -} - -// Get number of vertex -unsigned int GLC_Geometry::VertexCount() const -{ - return 0; -} - -double GLC_Geometry::volume() -{ - return 0.0; -} - -///////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// -// Clear the content of the geometry and makes it empty -void GLC_Geometry::clear() -{ - clearGeometry(); -} - -// Replace the Master material -void GLC_Geometry::replaceMasterMaterial(GLC_Material* pMaterial) -{ - Q_ASSERT(!m_IsWire); - if (!m_MaterialHash.isEmpty()) - { - if (pMaterial != firstMaterial()) - { - // Remove the first material - MaterialHash::iterator iMaterial= m_MaterialHash.begin(); - removeMaterial(iMaterial.value()->id()); - - // Add the new material - addMaterial(pMaterial); - } - } - else - { - addMaterial(pMaterial); - } -} -//! Update the transparent material number -void GLC_Geometry::updateTransparentMaterialNumber() -{ - m_TransparentMaterialNumber= 0; - MaterialHash::const_iterator iMat= m_MaterialHash.constBegin(); - while (iMat != m_MaterialHash.constEnd()) - { - if (iMat.value()->isTransparent()) - { - ++m_TransparentMaterialNumber; - } - ++iMat; - } - if (m_WireColor.alpha() != 255) - { - ++m_TransparentMaterialNumber; - } -} - -// Add material to mesh -void GLC_Geometry::addMaterial(GLC_Material* pMaterial) -{ - if (pMaterial != NULL) - { - const GLC_uint materialID= pMaterial->id(); - MaterialHash::const_iterator iMaterial= m_MaterialHash.find(materialID); - // Check if there is a material at specified index - Q_ASSERT(iMaterial == m_MaterialHash.end()); - - // Add this geometry in the material use table - pMaterial->addGLC_Geom(this); - // Add the Material to Material hash table - m_MaterialHash.insert(materialID, pMaterial); - - // Test if the material is transparent - if (pMaterial->isTransparent()) - { - //qDebug() << "Add transparent material"; - ++m_TransparentMaterialNumber; - } - } -} - -void GLC_Geometry::setWireColor(const QColor& color) -{ - bool previousColorIsTransparent= (m_WireColor.alpha() != 255); - bool newColorIsTransparent= (color.alpha() != 255); - - if (previousColorIsTransparent != newColorIsTransparent) - { - if (newColorIsTransparent) ++m_TransparentMaterialNumber; - else if (previousColorIsTransparent) --m_TransparentMaterialNumber; - } - - m_WireColor= color; -} - -void GLC_Geometry::copyVboToClientSide() -{ - m_WireData.copyVboToClientSide(); -} - -void GLC_Geometry::releaseVboClientSide(bool update) -{ - m_WireData.releaseVboClientSide(update); -} - -void GLC_Geometry::setVboUsage(bool usage) -{ - m_UseVbo= usage; - if (!usage || (usage && GLC_State::vboSupported())) - { - m_WireData.setVboUsage(m_UseVbo); - } -} - -////////////////////////////////////////////////////////////////////// -// OpenGL Functions -////////////////////////////////////////////////////////////////////// - -// if the geometry have a texture, load it -void GLC_Geometry::glLoadTexture(void) -{ - MaterialHash::iterator iMaterial= m_MaterialHash.begin(); - - while (iMaterial != m_MaterialHash.constEnd()) - { - // Load texture of mesh materials - iMaterial.value()->glLoadTexture(); - ++iMaterial; - } -} - -// Geometry display -void GLC_Geometry::render(const GLC_RenderProperties& renderProperties) -{ - Q_ASSERT(!m_IsWire || (m_IsWire && m_MaterialHash.isEmpty())); - bool renderWire= (renderProperties.renderingFlag() == glc::TransparentRenderFlag) && isTransparent(); - renderWire= renderWire || ((renderProperties.renderingFlag() != glc::TransparentRenderFlag) && !isTransparent()); - if (!m_IsWire || renderWire) - { - if (m_MaterialHash.isEmpty() && !m_IsWire) - { - GLC_Material* pMaterial= new GLC_Material(); - pMaterial->setName(name()); - addMaterial(pMaterial); - } - - m_IsSelected= renderProperties.isSelected(); - - // Define Geometry's property - if(!GLC_State::isInSelectionMode()) - { - glPropGeom(renderProperties); - } - - glDraw(renderProperties); - - m_IsSelected= false; - m_GeometryIsValid= true; - - // OpenGL error handler - GLenum error= glGetError(); - if (error != GL_NO_ERROR) - { - GLC_OpenGlException OpenGlException("GLC_Geometry::render " + name(), error); - throw(OpenGlException); - } - } -} - -// Virtual interface for OpenGL Geometry properties. -void GLC_Geometry::glPropGeom(const GLC_RenderProperties& renderProperties) -{ - glLineWidth(lineWidth()); - - if(m_IsWire) - { - glLineWidth(m_LineWidth); - GLC_Context::current()->glcEnableLighting(false);; - if (!renderProperties.isSelected()) - { - // Set polyline colors - GLfloat color[4]= {static_cast(m_WireColor.redF()), - static_cast(m_WireColor.greenF()), - static_cast(m_WireColor.blueF()), - static_cast(m_WireColor.alphaF())}; - - glColor4fv(color); - } - else - { - GLC_SelectionMaterial::glExecute(); - } - } - else if (m_MaterialHash.size() == 1) - { - GLC_Material* pCurrentMaterial= m_MaterialHash.begin().value(); - if (pCurrentMaterial->hasTexture()) - { - GLC_Context::current()->glcEnableLighting(true); - pCurrentMaterial->glExecute(); - if (renderProperties.isSelected()) GLC_SelectionMaterial::glExecute(); - } - else - { - GLC_Context::current()->glcEnableLighting(true); - if (renderProperties.isSelected()) GLC_SelectionMaterial::glExecute(); - else pCurrentMaterial->glExecute(); - } - } -} - -// Remove the specified material from the geometry -void GLC_Geometry::removeMaterial(GLC_uint id) -{ - Q_ASSERT(containsMaterial(id)); - // Remove the first material - GLC_Material* pMaterial= m_MaterialHash.value(id); - // delete the material if necessary - pMaterial->delGLC_Geom(this->id()); - if (pMaterial->isTransparent()) - { - --m_TransparentMaterialNumber; - } - if (pMaterial->isUnused()) delete pMaterial; - m_MaterialHash.remove(id); - -} - -// Clear the content of this object and makes it empty -void GLC_Geometry::clearGeometry() -{ - m_GeometryIsValid= false; - - delete m_pBoundingBox; - m_pBoundingBox= NULL; - - // delete mesh inner material - { - MaterialHash::const_iterator i= m_MaterialHash.begin(); - while (i != m_MaterialHash.constEnd()) - { - // delete the material if necessary - i.value()->delGLC_Geom(id()); - if (i.value()->isUnused()) delete i.value(); - ++i; - } - } - m_MaterialHash.clear(); - - m_UseColorPerVertex= false; - m_IsSelected= false; - m_WireData.clear(); - m_IsWire= false; - m_TransparentMaterialNumber= 0; - m_Name.clear(); - -} diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_geometry.h b/ground/gcs/src/libs/glc_lib/geometry/glc_geometry.h deleted file mode 100644 index ee35cba5b..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_geometry.h +++ /dev/null @@ -1,369 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_geometry.h Interface for the GLC_Geometry class. - -#ifndef GLC_GEOMETRY_H_ -#define GLC_GEOMETRY_H_ -#include "../shading/glc_material.h" -#include "../shading/glc_renderproperties.h" -#include "glc_wiredata.h" -#include "../glc_boundingbox.h" - -#include "../glc_config.h" - -typedef QHash MaterialHash; -typedef QHash MaterialHashMap; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Geometry -/*! \brief GLC_Geometry : parent class for all geometry*/ - -/*! GLC_Geometry is a abstract class. \n \n - * Main attributes of GLC_Geometry: - * - Materials Hash table : QHash - * - * GLC_Geometry provides : - * - Method to draw Geometry : GLC_Geometry::glExecute() - * - Virtual method to overload for visual property : GLC_Geometry::glPropGeom() - * - Virtual method to load and generate Opengl textures for each materials : GLC_Geometry::glLoadTexture() - * - Virtual method to clear the content of the geometry and makes it empty : GLC_Geometry::clear() - * - * - Pure virtual method to overload for Object topology : GLC_Geometry::glDraw() - * - Pure virtual Clone method : GLC_Geometry::clone() - * - Pure virtual method to get geometry bounding box : GLC_Geometry::boundingBox() - * - * - Empty virtual method for reversing normals : GLC_Geometry::reverseNormals() - * - Empty virtual method for setting the current level of detail (between 0 and 100) : GLC_Geometry::setCurrentLod() - * - Empty virtual method to get the number of vertex : GLC_Geometry::numberOfVertex() - * - Empty virtual method to get the number of faces : GLC_Geoetry::numberOfFaces() - * - */ -////////////////////////////////////////////////////////////////////// - -class GLC_LIB_EXPORT GLC_Geometry -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Default constructor - GLC_Geometry(const QString &name, const bool type); - - //! Copy constructor - GLC_Geometry(const GLC_Geometry& sourceGeom); - - //! Overload "=" operator - GLC_Geometry& operator=(const GLC_Geometry& sourceGeom); - - //! Destructor - virtual ~GLC_Geometry(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Get Object ID - inline GLC_uint id() const - {return m_Id;} - - //! Get Object Name - inline QString name() const - {return m_Name;} - - //! Return true if the geometry is valid - inline bool isValid(void) const - {return m_GeometryIsValid;} - - //! Return true if the geometry has material - inline bool hasMaterial() const - {return !m_MaterialHash.isEmpty();} - - //! Return first material of geometry - inline GLC_Material* firstMaterial(void) const - { - if (!m_MaterialHash.isEmpty()) - { - return m_MaterialHash.begin().value(); - } - else return NULL; - } - - //! Return the number of materials - inline int materialCount() const - {return m_MaterialHash.size();} - - //! Return the specified mesh sub material - inline GLC_Material* material(const GLC_uint key) const - {return m_MaterialHash[key];} - - //! Get materials Set - inline QSet materialSet() const - {return m_MaterialHash.values().toSet();} - - //! Get materials ID List - inline QList materialIds() const - {return m_MaterialHash.keys();} - - //! Return true if Material key is in the mesh - inline bool containsMaterial(const GLC_uint key) const - {return m_MaterialHash.contains(key);} - - //! Return the geometry bounding box - virtual const GLC_BoundingBox& boundingBox(void) = 0; - - //! Return true if the bounding box is valid - inline bool boundingBoxIsValid() const - {return NULL != m_pBoundingBox;} - - //! Clone the geometry - virtual GLC_Geometry* clone() const = 0; - - //! Get the geometry transparency - inline bool isTransparent() const - {return (m_TransparentMaterialNumber >= m_MaterialHash.size()) && hasTransparentMaterials();} - - //! Return true if the geometry contains transparent materials - inline bool hasTransparentMaterials() const - {return m_TransparentMaterialNumber > 0;} - - //! Return true if color per vertex is used - inline bool usedColorPerVertex() const - {return m_UseColorPerVertex;} - - //! Return true if the geometry type is wireframe - inline bool typeIsWire() const - {return m_IsWire;} - - //! Get the number of faces - virtual unsigned int faceCount(int lod=0) const; - - //! Get the number of vertex - virtual unsigned int VertexCount() const; - - //! Return the line width - GLfloat lineWidth() const - {return m_LineWidth;} - - //! Return this geometry wire color - inline QColor wireColor() const - {return m_WireColor;} - - //! Return true if wire data is empty - inline bool wireDataIsEmpty() const - {return m_WireData.isEmpty();} - - //! Return the wire position vector - inline GLfloatVector wirePositionVector() const - {return m_WireData.positionVector();} - - //! Return the number of wire polylines - inline int wirePolylineCount() const - {return m_WireData.verticeGroupCount();} - - //! Return the polyline offset from the given index - inline GLuint wirePolylineOffset(int index) const - {return m_WireData.verticeGroupOffset(index);} - - //! Return the polyline size from the given index - inline GLsizei wirePolylineSize(int index) const - {return m_WireData.verticeGroupSize(index);} - - //! Return the volume of this geometry - virtual double volume(); - - //! Return true if this geometry will try to use VBO - inline bool vboIsUsed() const - {return m_UseVbo;} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Clear the content of the geometry and makes it empty - virtual void clear(); - - //! Replace the Master material - virtual void replaceMasterMaterial(GLC_Material*); - - //! Add material to the geometry - void addMaterial(GLC_Material *); - - //! Set the color per vertex usage - inline void colorPerVertex(const bool colorPerVertex) - { - if (m_UseColorPerVertex != colorPerVertex) - { - m_UseColorPerVertex= colorPerVertex; - m_GeometryIsValid= false; - } - } - - //! Update the transparent material number - void updateTransparentMaterialNumber(); - - //! Reverse normal - virtual void reverseNormals() {} - - //! Set the lod Index - /*! The value must be between 0 and 100*/ - virtual void setCurrentLod(const int) {} - - //! Set Geometry Id - inline void setId(const GLC_uint id) - {m_Id= id;} - - //! Set geometry name - inline void setName(const QString name) - {m_Name= name;} - - //! Add a vertice group to the geometry and returns its id - inline GLC_uint addVerticeGroup(const GLfloatVector& vector) - {return m_WireData.addVerticeGroup(vector);} - - //! Set Line width - inline void setLineWidth(GLfloat lineWidth) - {m_LineWidth= lineWidth;} - - //! Set this geometry wire color - void setWireColor(const QColor& color); - - //! Copy VBO to the Client Side - virtual void copyVboToClientSide(); - - //! Release client VBO - virtual void releaseVboClientSide(bool update= false); - - //! Set VBO usage - virtual void setVboUsage(bool usage); - -//@} -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Load each textures of materials - virtual void glLoadTexture(void); - - //! Virtual interface for OpenGL execution. - virtual void render(const GLC_RenderProperties&); - - -protected: - //! Virtual interface for OpenGL Geometry set up. - /*! This Virtual function have to be implemented in concrete class.*/ - virtual void glDraw(const GLC_RenderProperties&) = 0; - - //! Virtual interface for OpenGL Geometry properties. - virtual void glPropGeom(const GLC_RenderProperties&); - -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Protected services Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -protected: - //! Remove the specified material from the geometry - void removeMaterial(GLC_uint); - - //! Clear the wire data and the bounding box of this geometry - inline void clearWireAndBoundingBox() - { - delete m_pBoundingBox; - m_pBoundingBox= NULL; - m_WireData.clear(); - m_GeometryIsValid= false; - } - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Private services Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -private: - //! Clear the content of this object and makes it empty - void clearGeometry(); - -//@} - -////////////////////////////////////////////////////////////////////// -// Protected members -////////////////////////////////////////////////////////////////////// -protected: - - //! Geometry validity - bool m_GeometryIsValid; - - //! Bounding box - GLC_BoundingBox* m_pBoundingBox; - - //! Material Hash table - MaterialHash m_MaterialHash; - - //! Color per vertex usage - bool m_UseColorPerVertex; - - //! Selection state - bool m_IsSelected; - - //! Wire Data - GLC_WireData m_WireData; - - //! The wire color - QColor m_WireColor; - - //! The line width - GLfloat m_LineWidth; - - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - - //! Geometry type is wire - bool m_IsWire; - - //! The number of transparent materials - int m_TransparentMaterialNumber; - - //! The Unique id of an Geometry - /*! Generated on creation*/ - GLC_uint m_Id; - - //! Name of geometry - QString m_Name; - - //! VBO usage flag - bool m_UseVbo; -}; - -#endif /*GLC_GEOMETRY_H_*/ diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_line.cpp b/ground/gcs/src/libs/glc_lib/geometry/glc_line.cpp deleted file mode 100644 index 78c0d32b8..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_line.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -#include "glc_line.h" -#include "../glc_openglexception.h" - -////////////////////////////////////////////////////////////////////// -// Constructor Destructor -////////////////////////////////////////////////////////////////////// - -GLC_Line::GLC_Line(const GLC_Point3d & point1, const GLC_Point3d & point2) -: GLC_Polylines() -, m_Point1(point1) -, m_Point2(point2) -{ - createWire(); -} - -GLC_Line::GLC_Line(const GLC_Line& line) -: GLC_Polylines(line) -, m_Point1(line.m_Point1) -, m_Point2(line.m_Point2) -{ - createWire(); -} - -GLC_Line::~GLC_Line() -{ - -} - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -const GLC_BoundingBox& GLC_Line::boundingBox(void) -{ - return GLC_Polylines::boundingBox(); -} - -GLC_Geometry* GLC_Line::clone() const -{ - return new GLC_Line(*this); -} - - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// -void GLC_Line::setCoordinate(const GLC_Point3d &point1, const GLC_Point3d &point2) -{ - m_Point1= point1; - m_Point2= point2; - clear(); - createWire(); -} - -GLC_Line& GLC_Line::operator=(const GLC_Line& line) -{ - if (this != &line) - { - m_Point1= line.m_Point1; - m_Point2= line.m_Point2; - GLC_Polylines::operator=(line); - } - return *this; -} - -////////////////////////////////////////////////////////////////////// -// OpenGL Functions -////////////////////////////////////////////////////////////////////// - -void GLC_Line::glDraw(const GLC_RenderProperties& renderProperties) -{ - GLC_Polylines::glDraw(renderProperties); -} - - -////////////////////////////////////////////////////////////////////// -// Private services Functions -////////////////////////////////////////////////////////////////////// -void GLC_Line::createWire() -{ - QList points; - points.append(m_Point1); - points.append(m_Point2); - GLC_Polylines::addPolyline(points); -} - - diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_line.h b/ground/gcs/src/libs/glc_lib/geometry/glc_line.h deleted file mode 100644 index 7091d6e0a..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_line.h +++ /dev/null @@ -1,129 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -#ifndef GLC_LINE_H_ -#define GLC_LINE_H_ - -#include "glc_polylines.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Line -/*! \brief GLC_Line : OpenGL 3D Line*/ - -/*! An GLC_Line is just a simple renderable 3D Line*/ -////////////////////////////////////////////////////////////////////// - -class GLC_LIB_EXPORT GLC_Line : public GLC_Polylines -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Construct an GLC_Line by to point - GLC_Line(const GLC_Point3d &, const GLC_Point3d &); - - //! Copy constructor - GLC_Line(const GLC_Line&); - - //!Default dstructor - virtual ~GLC_Line(); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Return the point1 coordinate - inline GLC_Point3d point1(void) const - {return m_Point1;} - - //! Return the point2 coordinate - inline GLC_Point3d point2(void) const - {return m_Point2;} - - //! Return the point bounding box - virtual const GLC_BoundingBox& boundingBox(void); - - //! Return a copy of the geometry - virtual GLC_Geometry* clone() const; - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Set Line coordinate by 3D point - void setCoordinate(const GLC_Point3d &point1, const GLC_Point3d &point2); - - //! Clear the content of this line Data and makes it empty - inline void clear() - {GLC_Polylines::clear();} - - //! Set this line from the given line and return a reference of this line - GLC_Line& operator=(const GLC_Line& line); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// - -private: - //! Virtual interface for OpenGL Geometry set up. - /*! This Virtual function is implemented here.\n*/ - virtual void glDraw(const GLC_RenderProperties&); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Private services Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -private: - //! Create the wire - void createWire(); - -//@} - -////////////////////////////////////////////////////////////////////// -// Private Member -////////////////////////////////////////////////////////////////////// - -private: - //! First point of the line - GLC_Point3d m_Point1; - - //! First point of the line - GLC_Point3d m_Point2; - -}; - -#endif /* GLC_LINE_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_lod.cpp b/ground/gcs/src/libs/glc_lib/geometry/glc_lod.cpp deleted file mode 100644 index 050ff1a09..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_lod.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_lod.cpp implementation of the GLC_Lod class. - -#include "../glc_exception.h" -#include "glc_lod.h" - -// Class chunk id -quint32 GLC_Lod::m_ChunkId= 0xA708; - - -GLC_Lod::GLC_Lod() -: m_Accuracy(0.0) -, m_IndexBuffer(QGLBuffer::IndexBuffer) -, m_IndexVector() -, m_IndexSize(0) -, m_TrianglesCount(0) -{ - -} - - -GLC_Lod::GLC_Lod(double accuracy) -: m_Accuracy(accuracy) -, m_IndexBuffer(QGLBuffer::IndexBuffer) -, m_IndexVector() -, m_IndexSize(0) -, m_TrianglesCount(0) -{ - -} - - -GLC_Lod::GLC_Lod(const GLC_Lod& lod) -: m_Accuracy(lod.m_Accuracy) -, m_IndexBuffer(QGLBuffer::IndexBuffer) -, m_IndexVector(lod.indexVector()) -, m_IndexSize(lod.m_IndexSize) -, m_TrianglesCount(lod.m_TrianglesCount) -{ - - -} - - -GLC_Lod& GLC_Lod::operator=(const GLC_Lod& lod) -{ - if (this != &lod) - { - m_Accuracy= lod.m_Accuracy; - m_IndexBuffer.destroy(); - m_IndexVector= lod.indexVector(); - m_IndexSize= lod.m_IndexSize; - m_TrianglesCount= lod.m_TrianglesCount; - } - - return *this; -} - -GLC_Lod::~GLC_Lod() -{ - -} - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -quint32 GLC_Lod::chunckID() -{ - return m_ChunkId; -} - - -QVector GLC_Lod::indexVector() const -{ - if (m_IndexBuffer.isCreated()) - { - // VBO created get data from VBO - const int sizeOfIbo= m_IndexSize; - const GLsizeiptr dataSize= sizeOfIbo * sizeof(GLuint); - QVector indexVector(sizeOfIbo); - - const_cast(m_IndexBuffer).bind(); - GLvoid* pIbo = const_cast(m_IndexBuffer).map(QGLBuffer::ReadOnly); - memcpy(indexVector.data(), pIbo, dataSize); - const_cast(m_IndexBuffer).unmap(); - const_cast(m_IndexBuffer).release(); - return indexVector; - } - else - { - return m_IndexVector; - } -} - - -void GLC_Lod::copyIboToClientSide() -{ - if (m_IndexBuffer.isCreated() && (m_IndexVector.isEmpty())) - { - m_IndexVector= indexVector(); - } -} - - -void GLC_Lod::releaseIboClientSide(bool update) -{ - if(m_IndexBuffer.isCreated() && !m_IndexVector.isEmpty()) - { - if (update) - { - // Copy index from client side to serveur - m_IndexBuffer.bind(); - - const GLsizei indexNbr= static_cast(m_IndexVector.size()); - const GLsizeiptr indexSize = indexNbr * sizeof(GLuint); - m_IndexBuffer.allocate(m_IndexVector.data(), indexSize); - m_IndexBuffer.release(); - } - m_IndexSize= m_IndexVector.size(); - m_IndexVector.clear(); - } -} - -void GLC_Lod::setIboUsage(bool usage) -{ - if (usage && !m_IndexVector.isEmpty()) - { - createIBO(); - // Copy index from client side to serveur - m_IndexBuffer.bind(); - - const GLsizei indexNbr= static_cast(m_IndexVector.size()); - const GLsizeiptr indexSize = indexNbr * sizeof(GLuint); - m_IndexBuffer.allocate(m_IndexVector.data(), indexSize); - m_IndexBuffer.release(); - - m_IndexSize= m_IndexVector.size(); - m_IndexVector.clear(); - - } - else if (!usage && m_IndexBuffer.isCreated()) - { - m_IndexVector= indexVector(); - m_IndexBuffer.destroy(); - } -} - -void GLC_Lod::useIBO() const -{ - Q_ASSERT(m_IndexBuffer.isCreated()); - if (!const_cast(m_IndexBuffer).bind()) - { - GLC_Exception exception("GLC_Lod::useIBO Failed to bind index buffer"); - throw(exception); - } -} - - -QDataStream &operator<<(QDataStream &stream, const GLC_Lod &lod) -{ - quint32 chunckId= GLC_Lod::m_ChunkId; - stream << chunckId; - - stream << lod.m_Accuracy; - stream << lod.indexVector(); - stream << lod.m_TrianglesCount; - - return stream; -} -QDataStream &operator>>(QDataStream &stream, GLC_Lod &lod) -{ - quint32 chunckId; - stream >> chunckId; - Q_ASSERT(chunckId == GLC_Lod::m_ChunkId); - - stream >> lod.m_Accuracy; - stream >> lod.m_IndexVector; - stream >> lod.m_TrianglesCount; - - return stream; -} - diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_lod.h b/ground/gcs/src/libs/glc_lib/geometry/glc_lod.h deleted file mode 100644 index 02856a737..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_lod.h +++ /dev/null @@ -1,184 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_lod.h interface for the GLC_Lod class. - -#ifndef GLC_LOD_H_ -#define GLC_LOD_H_ - -#include -#include - -#include "../glc_ext.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Lod -/*! \brief GLC_Lod is a Level of detail index and accuracy*/ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_Lod -{ - friend GLC_LIB_EXPORT QDataStream &operator<<(QDataStream &, const GLC_Lod &); - friend GLC_LIB_EXPORT QDataStream &operator>>(QDataStream &, GLC_Lod &); - -public: -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Default Constructor - GLC_Lod(); - - //! Construct a Lod with the specified accuracy - GLC_Lod(double accuracy); - - //! Copy constructor - GLC_Lod(const GLC_Lod&); - - //! Overload "=" operator - GLC_Lod& operator=(const GLC_Lod&); - - //!Destructor - virtual ~GLC_Lod(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the class Chunk ID - static quint32 chunckID(); - - //! Return the accuracy of the LOD - inline double accuracy() const - {return m_Accuracy;} - - //! Return The unique index Vector which contains : - /*! - * - Triangles index - * - Triangles Strips index - * - Triangles Fans index - */ - QVector indexVector() const; - - //! Return The unique index Vector handle which contains : - /*! - * - Triangles index - * - Triangles Strips index - * - Triangles Fans index - */ - inline QVector* indexVectorHandle() - {return &m_IndexVector;} - - //! Return the size of the index Vector - inline int indexVectorSize() const - {return m_IndexVector.size();} - - //! Return this lod triangle count - inline unsigned int trianglesCount() const - {return m_TrianglesCount;} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Copy IBO to the Client Side - void copyIboToClientSide(); - - //! Release client IBO - void releaseIboClientSide(bool update= false); - - //! Set accuracy of the LOD - inline void setAccuracy(const double& accuracy) - {m_Accuracy= accuracy;} - - //! Given number of triangles added - inline void trianglesAdded(unsigned int count) - { - m_TrianglesCount+= count; - } - - //! Set IBO usage - void setIboUsage(bool usage); - - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! IBO creation - inline void createIBO() - { - if (!m_IndexBuffer.isCreated() && !m_IndexVector.isEmpty()) - { - m_IndexBuffer.create(); - } - } - - //! Ibo Usage - void useIBO() const; - - //! Fill IBO - inline void fillIbo() - {releaseIboClientSide(true);} - -//@} - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - - //! The accuracy of the LOD - double m_Accuracy; - - //! The Index Buffer - QGLBuffer m_IndexBuffer; - - //! The Index Vector - QVector m_IndexVector; - - //! The Index vector size - int m_IndexSize; - - //! Lod number of faces - unsigned int m_TrianglesCount; - - //! Class chunk id - static quint32 m_ChunkId; - -}; - -//! Non-member stream operator -GLC_LIB_EXPORT QDataStream &operator<<(QDataStream &, const GLC_Lod &); -GLC_LIB_EXPORT QDataStream &operator>>(QDataStream &, GLC_Lod &); - -#endif /* GLC_LOD_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_mesh.cpp b/ground/gcs/src/libs/glc_lib/geometry/glc_mesh.cpp deleted file mode 100644 index 8354fd9cc..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_mesh.cpp +++ /dev/null @@ -1,1697 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_mesh.cpp Implementation for the GLC_Mesh class. - -#include "glc_mesh.h" -#include "../glc_renderstatistics.h" -#include "../glc_context.h" - -// Class chunk id -quint32 GLC_Mesh::m_ChunkId= 0xA701; - -GLC_Mesh::GLC_Mesh() -:GLC_Geometry("Mesh", false) -, m_NextPrimitiveLocalId(1) -, m_PrimitiveGroups() -, m_DefaultMaterialId(0) -, m_NumberOfVertice(0) -, m_NumberOfNormals(0) -, m_ColorPearVertex(false) -, m_MeshData() -, m_CurrentLod(0) -{ - -} - -GLC_Mesh::GLC_Mesh(const GLC_Mesh& mesh) -:GLC_Geometry(mesh) -, m_NextPrimitiveLocalId(mesh.m_NextPrimitiveLocalId) -, m_PrimitiveGroups(mesh.m_PrimitiveGroups) -, m_DefaultMaterialId(mesh.m_DefaultMaterialId) -, m_NumberOfVertice(mesh.m_NumberOfVertice) -, m_NumberOfNormals(mesh.m_NumberOfNormals) -, m_ColorPearVertex(mesh.m_ColorPearVertex) -, m_MeshData(mesh.m_MeshData) -, m_CurrentLod(0) -{ - // Make a copy of m_PrimitiveGroups with new material id - PrimitiveGroupsHash::const_iterator iPrimitiveGroups= mesh.m_PrimitiveGroups.constBegin(); - while (mesh.m_PrimitiveGroups.constEnd() != iPrimitiveGroups) - { - LodPrimitiveGroups* pPrimitiveGroups= new LodPrimitiveGroups(); - m_PrimitiveGroups.insert(iPrimitiveGroups.key(), pPrimitiveGroups); - - LodPrimitiveGroups::const_iterator iPrimitiveGroup= iPrimitiveGroups.value()->constBegin(); - while (iPrimitiveGroups.value()->constEnd() != iPrimitiveGroup) - { - GLC_PrimitiveGroup* pPrimitiveGroup= new GLC_PrimitiveGroup(*(iPrimitiveGroup.value()), iPrimitiveGroup.key()); - pPrimitiveGroups->insert(iPrimitiveGroup.key(), pPrimitiveGroup); - - ++iPrimitiveGroup; - } - - ++iPrimitiveGroups; - } - -} - -// Overload "=" operator -GLC_Mesh& GLC_Mesh::operator=(const GLC_Mesh& mesh) -{ - if (this != &mesh) - { - // Call the operator of the super class - GLC_Geometry::operator=(mesh); - - // Clear the mesh - clearMeshWireAndBoundingBox(); - - // Copy members - m_NextPrimitiveLocalId= mesh.m_NextPrimitiveLocalId; - m_PrimitiveGroups= mesh.m_PrimitiveGroups; - m_DefaultMaterialId= mesh.m_DefaultMaterialId; - m_NumberOfVertice= mesh.m_NumberOfVertice; - m_NumberOfNormals= mesh.m_NumberOfNormals; - m_ColorPearVertex= mesh.m_ColorPearVertex; - m_MeshData= mesh.m_MeshData; - m_CurrentLod= 0; - - // Make a copy of m_PrimitiveGroups with new material id - PrimitiveGroupsHash::const_iterator iPrimitiveGroups= mesh.m_PrimitiveGroups.constBegin(); - while (mesh.m_PrimitiveGroups.constEnd() != iPrimitiveGroups) - { - LodPrimitiveGroups* pPrimitiveGroups= new LodPrimitiveGroups(); - m_PrimitiveGroups.insert(iPrimitiveGroups.key(), pPrimitiveGroups); - - LodPrimitiveGroups::const_iterator iPrimitiveGroup= iPrimitiveGroups.value()->constBegin(); - while (iPrimitiveGroups.value()->constEnd() != iPrimitiveGroup) - { - GLC_PrimitiveGroup* pPrimitiveGroup= new GLC_PrimitiveGroup(*(iPrimitiveGroup.value()), iPrimitiveGroup.key()); - pPrimitiveGroups->insert(iPrimitiveGroup.key(), pPrimitiveGroup); - - ++iPrimitiveGroup; - } - - ++iPrimitiveGroups; - } - } - - return *this; -} - -// Destructor -GLC_Mesh::~GLC_Mesh() -{ - PrimitiveGroupsHash::iterator iGroups= m_PrimitiveGroups.begin(); - while (iGroups != m_PrimitiveGroups.constEnd()) - { - LodPrimitiveGroups::iterator iGroup= iGroups.value()->begin(); - while (iGroup != iGroups.value()->constEnd()) - { - delete iGroup.value(); - - ++iGroup; - } - delete iGroups.value(); - ++iGroups; - } -} - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// -// Return the class Chunk ID -quint32 GLC_Mesh::chunckID() -{ - return m_ChunkId; -} - -// Get number of faces -unsigned int GLC_Mesh::faceCount(int lod) const -{ - return m_MeshData.trianglesCount(lod); -} - -// Get number of vertex -unsigned int GLC_Mesh::VertexCount() const -{ - return m_NumberOfVertice; -} - -// return the mesh bounding box -const GLC_BoundingBox& GLC_Mesh::boundingBox() -{ - if (NULL == m_pBoundingBox) - { - //qDebug() << "GLC_Mesh2::boundingBox create boundingBox"; - m_pBoundingBox= new GLC_BoundingBox(); - - if (m_MeshData.positionVectorHandle()->isEmpty()) - { - qDebug() << "GLC_Mesh::boundingBox empty m_Positions"; - } - else - { - GLfloatVector* pVertexVector= m_MeshData.positionVectorHandle(); - const int max= pVertexVector->size(); - for (int i= 0; i < max; i= i + 3) - { - GLC_Vector3d vector((*pVertexVector)[i], (*pVertexVector)[i + 1], (*pVertexVector)[i + 2]); - m_pBoundingBox->combine(vector); - } - } - // Combine with the wiredata bounding box - m_pBoundingBox->combine(m_WireData.boundingBox()); - } - return *m_pBoundingBox; - -} - -// Return a copy of the Mesh as GLC_Geometry pointer -GLC_Geometry* GLC_Mesh::clone() const -{ - return new GLC_Mesh(*this); -} - -// Return true if the mesh contains triangles -bool GLC_Mesh::containsTriangles(int lod, GLC_uint materialId) const -{ - // Check if the lod exist and material exists - Q_ASSERT(m_PrimitiveGroups.contains(lod)); - if (!m_PrimitiveGroups.value(lod)->contains(materialId)) return false; - else return m_PrimitiveGroups.value(lod)->value(materialId)->containsTriangles(); -} - -// Return the specified index -QVector GLC_Mesh::getTrianglesIndex(int lod, GLC_uint materialId) const -{ - // Check if the mesh contains triangles - Q_ASSERT(containsTriangles(lod, materialId)); - - GLC_PrimitiveGroup* pPrimitiveGroup= m_PrimitiveGroups.value(lod)->value(materialId); - - int offset= 0; - if (vboIsUsed()) - { - offset= static_cast(reinterpret_cast(pPrimitiveGroup->trianglesIndexOffset()) / sizeof(GLuint)); - } - else - { - offset= pPrimitiveGroup->trianglesIndexOffseti(); - } - const int size= pPrimitiveGroup->trianglesIndexSize(); - - QVector resultIndex(size); - - memcpy((void*)resultIndex.data(), &(m_MeshData.indexVector(lod).data())[offset], size * sizeof(GLuint)); - - return resultIndex; -} - -IndexList GLC_Mesh::getEquivalentTrianglesStripsFansIndex(int lod, GLC_uint materialId) -{ - IndexList subject; - if (containsTriangles(lod, materialId)) - { - subject= getTrianglesIndex(lod, materialId).toList(); - } - - if (containsStrips(lod, materialId)) - { - subject.append(equivalentTrianglesIndexOfstripsIndex(lod, materialId)); - } - - if (containsFans(lod, materialId)) - { - subject.append(equivalentTrianglesIndexOfFansIndex(lod, materialId)); - } - - Q_ASSERT((subject.count() % 3) == 0); - - return subject; -} - -// Return the number of triangles -int GLC_Mesh::numberOfTriangles(int lod, GLC_uint materialId) const -{ - // Check if the lod exist and material exists - if (!m_PrimitiveGroups.contains(lod))return 0; - else if (!m_PrimitiveGroups.value(lod)->contains(materialId)) return 0; - else return m_PrimitiveGroups.value(lod)->value(materialId)->trianglesIndexSize(); -} - -// Return true if the mesh contains trips -bool GLC_Mesh::containsStrips(int lod, GLC_uint materialId) const -{ - // Check if the lod exist and material exists - if (!m_PrimitiveGroups.contains(lod))return false; - else if (!m_PrimitiveGroups.value(lod)->contains(materialId)) return false; - else return m_PrimitiveGroups.value(lod)->value(materialId)->containsStrip(); - -} - -// Return the strips index -QList > GLC_Mesh::getStripsIndex(int lod, GLC_uint materialId) const -{ - // Check if the mesh contains trips - Q_ASSERT(containsStrips(lod, materialId)); - - GLC_PrimitiveGroup* pPrimitiveGroup= m_PrimitiveGroups.value(lod)->value(materialId); - - QList offsets; - QList sizes; - int stripsCount; - - if (vboIsUsed()) - { - stripsCount= pPrimitiveGroup->stripsOffset().size(); - for (int i= 0; i < stripsCount; ++i) - { - offsets.append(static_cast(reinterpret_cast(pPrimitiveGroup->stripsOffset().at(i)) / sizeof(GLuint))); - sizes.append(static_cast(pPrimitiveGroup->stripsSizes().at(i))); - } - } - else - { - stripsCount= pPrimitiveGroup->stripsOffseti().size(); - for (int i= 0; i < stripsCount; ++i) - { - offsets.append(static_cast(pPrimitiveGroup->stripsOffseti().at(i))); - sizes.append(static_cast(pPrimitiveGroup->stripsSizes().at(i))); - } - - } - // The result list of vector - QList > result; - // The copy of the mesh Data LOD index vector - QVector SourceIndex(m_MeshData.indexVector(lod)); - for (int i= 0; i < stripsCount; ++i) - { - QVector currentStrip(sizes.at(i)); - memcpy((void*)currentStrip.data(), &(SourceIndex.data())[offsets.at(i)], sizes.at(i) * sizeof(GLuint)); - result.append(currentStrip); - } - - return result; -} - -// Return the number of strips -int GLC_Mesh::numberOfStrips(int lod, GLC_uint materialId) const -{ - // Check if the lod exist and material exists - if (!m_PrimitiveGroups.contains(lod))return 0; - else if (!m_PrimitiveGroups.value(lod)->contains(materialId)) return 0; - else return m_PrimitiveGroups.value(lod)->value(materialId)->stripsSizes().size(); -} - -// Return true if the mesh contains fans -bool GLC_Mesh::containsFans(int lod, GLC_uint materialId) const -{ - // Check if the lod exist and material exists - if (!m_PrimitiveGroups.contains(lod))return false; - else if (!m_PrimitiveGroups.value(lod)->contains(materialId)) return false; - else return m_PrimitiveGroups.value(lod)->value(materialId)->containsFan(); - -} - -//! Return the number of fans -int GLC_Mesh::numberOfFans(int lod, GLC_uint materialId) const -{ - // Check if the lod exist and material exists - if(!m_PrimitiveGroups.contains(lod))return 0; - else if (!m_PrimitiveGroups.value(lod)->contains(materialId)) return 0; - else return m_PrimitiveGroups.value(lod)->value(materialId)->fansSizes().size(); -} - -GLC_Material *GLC_Mesh::MaterialOfPrimitiveId(GLC_uint id, int lod) const -{ - GLC_Material* pSubject= NULL; - - if (!m_PrimitiveGroups.isEmpty()) - { - LodPrimitiveGroups* pMasterLodPrimitiveGroup= m_PrimitiveGroups.value(lod); - LodPrimitiveGroups::const_iterator iGroup= pMasterLodPrimitiveGroup->constBegin(); - while (iGroup != pMasterLodPrimitiveGroup->constEnd()) - { - GLC_PrimitiveGroup* pCurrentGroup= iGroup.value(); - QList listOfId; - - listOfId.append(pCurrentGroup->triangleGroupId()); - listOfId.append(pCurrentGroup->stripGroupId()); - listOfId.append(pCurrentGroup->fanGroupId()); - if (listOfId.contains(id)) - { - const GLC_uint materialId= pCurrentGroup->id(); - pSubject= this->material(materialId); - iGroup= pMasterLodPrimitiveGroup->constEnd(); - } - else - { - ++iGroup; - } - } - } - - return pSubject; -} - -// Return the strips index -QList > GLC_Mesh::getFansIndex(int lod, GLC_uint materialId) const -{ - // Check if the mesh contains trips - Q_ASSERT(containsFans(lod, materialId)); - - GLC_PrimitiveGroup* pPrimitiveGroup= m_PrimitiveGroups.value(lod)->value(materialId); - - QList offsets; - QList sizes; - int fansCount; - - if (vboIsUsed()) - { - fansCount= pPrimitiveGroup->fansOffset().size(); - for (int i= 0; i < fansCount; ++i) - { - offsets.append(static_cast(reinterpret_cast(pPrimitiveGroup->fansOffset().at(i)) / sizeof(GLuint))); - sizes.append(static_cast(pPrimitiveGroup->fansSizes().at(i))); - } - } - else - { - fansCount= pPrimitiveGroup->fansOffseti().size(); - for (int i= 0; i < fansCount; ++i) - { - offsets.append(static_cast(pPrimitiveGroup->fansOffseti().at(i))); - sizes.append(static_cast(pPrimitiveGroup->fansSizes().at(i))); - } - - } - // The result list of vector - QList > result; - // The copy of the mesh Data LOD index vector - QVector SourceIndex(m_MeshData.indexVector(lod)); - for (int i= 0; i < fansCount; ++i) - { - QVector currentFan(sizes.at(i)); - memcpy((void*)currentFan.data(), &(SourceIndex.data())[offsets.at(i)], sizes.at(i) * sizeof(GLuint)); - result.append(currentFan); - } - - return result; -} - -QSet GLC_Mesh::setOfPrimitiveId() const -{ - QList subject; - if (!m_PrimitiveGroups.isEmpty()) - { - LodPrimitiveGroups* pMasterLodPrimitiveGroup= m_PrimitiveGroups.value(0); - LodPrimitiveGroups::const_iterator iGroup= pMasterLodPrimitiveGroup->constBegin(); - while (iGroup != pMasterLodPrimitiveGroup->constEnd()) - { - GLC_PrimitiveGroup* pCurrentGroup= iGroup.value(); - subject.append(pCurrentGroup->triangleGroupId()); - subject.append(pCurrentGroup->stripGroupId()); - subject.append(pCurrentGroup->fanGroupId()); - ++iGroup; - } - } - - return QSet::fromList(subject); -} - -GLC_Mesh* GLC_Mesh::createMeshOfGivenLod(int lodIndex) -{ - Q_ASSERT(m_MeshData.lodCount() > lodIndex); - - copyVboToClientSide(); - GLC_Mesh* pLodMesh= new GLC_Mesh; - pLodMesh->setName(this->name() + "-LOD-" + QString::number(lodIndex)); - QHash sourceToTargetIndexMap; - QHash tagetToSourceIndexMap; - int maxIndex= -1; - - int targetLod= 0; - copyIndex(lodIndex, pLodMesh, sourceToTargetIndexMap, tagetToSourceIndexMap, maxIndex, targetLod); - - copyBulkData(pLodMesh, tagetToSourceIndexMap, maxIndex); - - pLodMesh->finish(); - - releaseVboClientSide(false); - - return pLodMesh; -} - -GLC_Mesh* GLC_Mesh::createMeshFromGivenLod(int lodIndex) -{ - const int lodCount= m_MeshData.lodCount(); - Q_ASSERT(lodCount > lodIndex); - - copyVboToClientSide(); - GLC_Mesh* pLodMesh= new GLC_Mesh; - pLodMesh->setName(this->name() + "-LOD-" + QString::number(lodIndex)); - QHash sourceToTargetIndexMap; - QHash tagetToSourceIndexMap; - int maxIndex= -1; - - if ((lodCount - lodIndex) > 1) - { - int targetLod= 1; - for (int i= lodIndex + 1; i < lodCount; ++i) - { - copyIndex(i, pLodMesh, sourceToTargetIndexMap, tagetToSourceIndexMap, maxIndex, targetLod); - ++targetLod; - } - copyIndex(lodIndex, pLodMesh, sourceToTargetIndexMap, tagetToSourceIndexMap, maxIndex, 0); - } - else - { - copyIndex(lodIndex, pLodMesh, sourceToTargetIndexMap, tagetToSourceIndexMap, maxIndex, 0); - } - - - copyBulkData(pLodMesh, tagetToSourceIndexMap, maxIndex); - - pLodMesh->finish(); - - releaseVboClientSide(false); - - return pLodMesh; -} -GLC_Mesh& GLC_Mesh::transformVertice(const GLC_Matrix4x4& matrix) -{ - if (matrix.type() != GLC_Matrix4x4::Identity) - { - delete m_pBoundingBox; - m_pBoundingBox= NULL; - copyVboToClientSide(); - const int stride= 3; - GLfloatVector* pVectPos= m_MeshData.positionVectorHandle(); - const GLC_Matrix4x4 rotationMatrix= matrix.rotationMatrix(); - GLfloatVector* pVectNormal= m_MeshData.normalVectorHandle(); - const int verticeCount= pVectPos->size() / stride; - for (int i= 0; i < verticeCount; ++i) - { - GLC_Vector3d newPos(pVectPos->at(stride * i), pVectPos->at(stride * i + 1), pVectPos->at(stride * i + 2)); - newPos= matrix * newPos; - pVectPos->operator[](stride * i)= static_cast(newPos.x()); - pVectPos->operator[](stride * i + 1)= static_cast(newPos.y()); - pVectPos->operator[](stride * i + 2)= static_cast(newPos.z()); - - GLC_Vector3d newNormal(pVectNormal->at(stride * i), pVectNormal->at(stride * i + 1), pVectNormal->at(stride * i + 2)); - newNormal= rotationMatrix * newNormal; - pVectNormal->operator[](stride * i)= static_cast(newNormal.x()); - pVectNormal->operator[](stride * i + 1)= static_cast(newNormal.y()); - pVectNormal->operator[](stride * i + 2)= static_cast(newNormal.z()); - } - releaseVboClientSide(true); - } - - return *this; -} - -double GLC_Mesh::volume() -{ - double resultVolume= 0.0; - - if (!m_MeshData.isEmpty()) - { - IndexList triangleIndex; - QList materials= materialSet().toList(); - const int materialsCount= materials.count(); - for (int i= 0; i < materialsCount; ++i) - { - GLC_uint materialId= materials.at(i)->id(); - if (containsTriangles(0, materialId)) - { - triangleIndex.append(getTrianglesIndex(0, materialId).toList()); - } - if (containsStrips(0, materialId)) - { - triangleIndex.append(equivalentTrianglesIndexOfstripsIndex(0, materialId)); - } - if (containsFans(0, materialId)) - { - triangleIndex.append(equivalentTrianglesIndexOfFansIndex(0, materialId)); - } - } - - GLfloatVector vertices= m_MeshData.positionVector(); - Q_ASSERT((triangleIndex.count() % 3) == 0); - const int triangleCount= triangleIndex.count() / 3; - for (int i= 0; i < triangleCount; ++i) - { - const int index= i * 3; - const double v1x= vertices.at(triangleIndex.at(index) * 3); - const double v1y= vertices.at(triangleIndex.at(index) * 3 + 1); - const double v1z= vertices.at(triangleIndex.at(index) * 3 + 2); - - const double v2x= vertices.at(triangleIndex.at(index + 1) * 3); - const double v2y= vertices.at(triangleIndex.at(index + 1) * 3 + 1); - const double v2z= vertices.at(triangleIndex.at(index + 1) * 3 + 2); - - const double v3x= vertices.at(triangleIndex.at(index + 2) * 3); - const double v3y= vertices.at(triangleIndex.at(index + 2) * 3 + 1); - const double v3z= vertices.at(triangleIndex.at(index + 2) * 3 + 2); - - resultVolume+= ((v2y - v1y) * (v3z - v1z) - (v2z - v1z) * (v3y - v1y)) * (v1x + v2x + v3x); - } - - resultVolume= resultVolume / 6.0; - } - - return resultVolume; -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -// Clear the content of the mesh and super class GLC_Geometry -void GLC_Mesh::clear() -{ - // Clear the mesh content - clearMeshWireAndBoundingBox(); - - // Clear the super class GLC_Geometry - GLC_Geometry::clear(); -} - - -// Clear the content off the mesh and makes it empty -void GLC_Mesh::clearMeshWireAndBoundingBox() -{ - // Reset primitive local id - m_NextPrimitiveLocalId= 1; - - // Remove all primitive groups - PrimitiveGroupsHash::iterator iGroups= m_PrimitiveGroups.begin(); - while (iGroups != m_PrimitiveGroups.constEnd()) - { - LodPrimitiveGroups::iterator iGroup= iGroups.value()->begin(); - while (iGroup != iGroups.value()->constEnd()) - { - delete iGroup.value(); - - ++iGroup; - } - delete iGroups.value(); - ++iGroups; - } - m_PrimitiveGroups.clear(); - - m_DefaultMaterialId= 0; - m_NumberOfVertice= 0; - m_NumberOfNormals= 0; - m_IsSelected= false; - m_ColorPearVertex= false; - // Clear data of the mesh - m_MeshData.clear(); - m_CurrentLod= 0; - - GLC_Geometry::clearWireAndBoundingBox(); -} - -// Add triangles -GLC_uint GLC_Mesh::addTriangles(GLC_Material* pMaterial, const IndexList& indexList, const int lod, double accuracy) -{ - GLC_uint groupId= setCurrentMaterial(pMaterial, lod, accuracy); - Q_ASSERT(m_PrimitiveGroups.value(lod)->contains(groupId)); - Q_ASSERT(!indexList.isEmpty()); - - GLC_uint id= 0; - if (0 == lod) - { - id= m_NextPrimitiveLocalId++; - } - m_MeshData.trianglesAdded(lod, indexList.size() / 3); - - m_PrimitiveGroups.value(lod)->value(groupId)->addTriangles(indexList, id); - - // Invalid the geometry - m_GeometryIsValid = false; - - return id; -} - -// Add triangles Strip ans return his id -GLC_uint GLC_Mesh::addTrianglesStrip(GLC_Material* pMaterial, const IndexList& indexList, const int lod, double accuracy) -{ - GLC_uint groupId= setCurrentMaterial(pMaterial, lod, accuracy); - Q_ASSERT(m_PrimitiveGroups.value(lod)->contains(groupId)); - Q_ASSERT(!indexList.isEmpty()); - - GLC_uint id= 0; - if (0 == lod) - { - id= m_NextPrimitiveLocalId++; - } - m_MeshData.trianglesAdded(lod, indexList.size() - 2); - - m_PrimitiveGroups.value(lod)->value(groupId)->addTrianglesStrip(indexList, id); - - // Invalid the geometry - m_GeometryIsValid = false; - - return id; -} -// Add triangles Fan -GLC_uint GLC_Mesh::addTrianglesFan(GLC_Material* pMaterial, const IndexList& indexList, const int lod, double accuracy) -{ - GLC_uint groupId= setCurrentMaterial(pMaterial, lod, accuracy); - Q_ASSERT(m_PrimitiveGroups.value(lod)->contains(groupId)); - Q_ASSERT(!indexList.isEmpty()); - - GLC_uint id= 0; - if (0 == lod) - { - id= m_NextPrimitiveLocalId++; - } - m_MeshData.trianglesAdded(lod, indexList.size() - 2); - m_PrimitiveGroups.value(lod)->value(groupId)->addTrianglesFan(indexList, id); - - // Invalid the geometry - m_GeometryIsValid = false; - - return id; -} - -// Reverse mesh normal -void GLC_Mesh::reverseNormals() -{ - GLfloatVector* pNormalVector= m_MeshData.normalVectorHandle(); - if (pNormalVector->isEmpty()) - { - (*m_MeshData.normalVectorHandle())= m_MeshData.normalVector(); - } - const int size= pNormalVector->size(); - for (int i= 0; i < size; ++i) - { - (*pNormalVector)[i]= - pNormalVector->at(i); - } - if (vboIsUsed()) - { - m_MeshData.fillVbo(GLC_MeshData::GLC_Normal); - m_MeshData.useVBO(false, GLC_MeshData::GLC_Normal); - } -} - -// Copy index list in a vector for Vertex Array Use -void GLC_Mesh::finish() -{ - if (m_MeshData.lodCount() > 0) - { - boundingBox(); - - m_MeshData.finishLod(); - - moveIndexToMeshDataLod(); - } - else - { - clear(); - } - - //qDebug() << "Mesh mem size= " << memmorySize(); -} - - -// Set the lod Index -void GLC_Mesh::setCurrentLod(const int value) -{ - if (value) - { - const int numberOfLod= m_MeshData.lodCount() - 1; - // Clamp value to number of load - m_CurrentLod= static_cast((static_cast(value) / 100.0) * numberOfLod); - } - else - { - m_CurrentLod= 0; - } -} -// Replace the Master material -void GLC_Mesh::replaceMasterMaterial(GLC_Material* pMat) -{ - if (hasMaterial()) - { - GLC_uint oldId= firstMaterial()->id(); - replaceMaterial(oldId, pMat); - } - else - { - addMaterial(pMat); - } -} - -// Replace the material specified by id with another one -void GLC_Mesh::replaceMaterial(const GLC_uint oldId, GLC_Material* pMat) -{ - Q_ASSERT(containsMaterial(oldId)); - Q_ASSERT(!containsMaterial(pMat->id()) || (pMat->id() == oldId)); - - if (pMat->id() != oldId) - { - // Iterate over Level of detail - PrimitiveGroupsHash::const_iterator iGroups= m_PrimitiveGroups.constBegin(); - while (m_PrimitiveGroups.constEnd() != iGroups) - { - LodPrimitiveGroups* pPrimitiveGroups= iGroups.value(); - // Iterate over material group - LodPrimitiveGroups::iterator iGroup= pPrimitiveGroups->begin(); - while (pPrimitiveGroups->constEnd() != iGroup) - { - if (iGroup.key() == oldId) - { - GLC_PrimitiveGroup* pGroup= iGroup.value(); - // Erase old group pointer - pPrimitiveGroups->erase(iGroup); - // Change the group ID - pGroup->setId(pMat->id()); - // Add the group with new ID - pPrimitiveGroups->insert(pMat->id(), pGroup); - iGroup= pPrimitiveGroups->end(); - } - else - { - ++iGroup; - } - } - ++iGroups; - } - } - - if (pMat != m_MaterialHash.value(oldId)) - { - // Remove old material - removeMaterial(oldId); - - addMaterial(pMat); - } - -} - -void GLC_Mesh::copyVboToClientSide() -{ - m_MeshData.copyVboToClientSide(); - GLC_Geometry::copyVboToClientSide(); -} - -void GLC_Mesh::releaseVboClientSide(bool update) -{ - m_MeshData.releaseVboClientSide(update); - GLC_Geometry::releaseVboClientSide(update); -} - -void GLC_Mesh::setVboUsage(bool usage) -{ - if (!isEmpty()) - { - GLC_Geometry::setVboUsage(usage); - m_MeshData.setVboUsage(usage); - } -} - -// Load the mesh from binary data stream -void GLC_Mesh::loadFromDataStream(QDataStream& stream, const MaterialHash& materialHash, const QHash& materialIdMap) -{ - quint32 chunckId; - stream >> chunckId; - Q_ASSERT(chunckId == m_ChunkId); - - // The mesh name - QString meshName; - stream >> meshName; - setName(meshName); - - // The wire data - stream >> GLC_Geometry::m_WireData; - - // The mesh next primitive local id - GLC_uint localId; - stream >> localId; - setNextPrimitiveLocalId(localId); - - // Retrieve geom mesh data - stream >> m_MeshData; - - // Retrieve primitiveGroupLodList - QList primitiveGroupLodList; - stream >> primitiveGroupLodList; - - // Retrieve primitiveGroup list - QList > primitiveListOfGroupList; - stream >> primitiveListOfGroupList; - - // Construct mesh primitiveGroupHash - const int lodCount= primitiveGroupLodList.size(); - for (int i= 0; i < lodCount; ++i) - { - GLC_Mesh::LodPrimitiveGroups* pCurrentPrimitiveGroup= new GLC_Mesh::LodPrimitiveGroups(); - m_PrimitiveGroups.insert(primitiveGroupLodList.at(i), pCurrentPrimitiveGroup); - const int groupCount= primitiveListOfGroupList.at(i).size(); - for (int iGroup= 0; iGroup < groupCount; ++iGroup) - { - Q_ASSERT(materialIdMap.contains(primitiveListOfGroupList.at(i).at(iGroup).id())); - const GLC_uint newId= materialIdMap.value(primitiveListOfGroupList.at(i).at(iGroup).id()); - // Test if the mesh contains the material - if (!containsMaterial(newId)) - { - addMaterial(materialHash.value(newId)); - } - GLC_PrimitiveGroup* pGroup= new GLC_PrimitiveGroup(primitiveListOfGroupList.at(i).at(iGroup), newId); - - Q_ASSERT(! m_PrimitiveGroups.value(primitiveGroupLodList.at(i))->contains(newId)); - m_PrimitiveGroups.value(primitiveGroupLodList.at(i))->insert(newId, pGroup); - } - } - stream >> m_NumberOfVertice; - stream >> m_NumberOfNormals; - - finishSerialized(); -} - -// Save the mesh to binary data stream -void GLC_Mesh::saveToDataStream(QDataStream& stream) const -{ - quint32 chunckId= m_ChunkId; - stream << chunckId; - - // The mesh name - stream << name(); - - // The wire data - stream << m_WireData; - - // The mesh next primitive local id - stream << nextPrimitiveLocalId(); - - // Mesh data serialisation - stream << m_MeshData; - - // Primitive groups serialisation - QList primitiveGroupLodList; - QList > primitiveListOfGroupList; - - GLC_Mesh::PrimitiveGroupsHash::const_iterator iGroupsHash= m_PrimitiveGroups.constBegin(); - while (m_PrimitiveGroups.constEnd() != iGroupsHash) - { - primitiveGroupLodList.append(iGroupsHash.key()); - QList primitiveGroupList; - GLC_Mesh::LodPrimitiveGroups::const_iterator iGroups= iGroupsHash.value()->constBegin(); - while (iGroupsHash.value()->constEnd() != iGroups) - { - primitiveGroupList.append(*(iGroups.value())); - ++iGroups; - } - primitiveListOfGroupList.append(primitiveGroupList); - ++iGroupsHash; - } - stream << primitiveGroupLodList; - stream << primitiveListOfGroupList; - - stream << m_NumberOfVertice; - stream << m_NumberOfNormals; -} - -////////////////////////////////////////////////////////////////////// -// OpenGL Functions -////////////////////////////////////////////////////////////////////// - -// Virtual interface for OpenGL Geometry set up. -void GLC_Mesh::glDraw(const GLC_RenderProperties& renderProperties) -{ - - Q_ASSERT(m_GeometryIsValid || !m_MeshData.positionSizeIsSet()); - - const bool vboIsUsed= GLC_Geometry::vboIsUsed() && GLC_State::vboSupported(); - - if (m_IsSelected && (renderProperties.renderingMode() == glc::PrimitiveSelected) && !GLC_State::isInSelectionMode() - && !renderProperties.setOfSelectedPrimitiveIdIsEmpty()) - { - m_CurrentLod= 0; - } - - if (vboIsUsed) - { - m_MeshData.createVBOs(); - - // Create VBO and IBO - if (!m_GeometryIsValid && !m_MeshData.positionSizeIsSet()) - { - fillVbosAndIbos(); - } - - // Activate mesh VBOs and IBO of the current LOD - activateVboAndIbo(); - } - else - { - if (!m_GeometryIsValid) - { - m_MeshData.initPositionSize(); - } - activateVertexArray(); - } - - if (GLC_State::isInSelectionMode()) - { - if (renderProperties.renderingMode() == glc::PrimitiveSelection) - { - primitiveSelectionRenderLoop(vboIsUsed); - } - else if (renderProperties.renderingMode() == glc::BodySelection) - { - bodySelectionRenderLoop(vboIsUsed); - } - else - { - normalRenderLoop(renderProperties, vboIsUsed); - } - } - else if (m_IsSelected) - { - if (renderProperties.renderingMode() == glc::PrimitiveSelected) - { - if (!renderProperties.setOfSelectedPrimitiveIdIsEmpty()) - { - primitiveSelectedRenderLoop(renderProperties, vboIsUsed); - } - else - { - m_IsSelected= false; - if ((m_CurrentLod == 0) && (renderProperties.savedRenderingMode() == glc::OverwritePrimitiveMaterial) && !renderProperties.hashOfOverwritePrimitiveMaterialsIsEmpty()) - primitiveRenderLoop(renderProperties, vboIsUsed); - else - normalRenderLoop(renderProperties, vboIsUsed); - m_IsSelected= true; - } - } - else - { - normalRenderLoop(renderProperties, vboIsUsed); - } - } - else - { - // Choose the accurate render loop - switch (renderProperties.renderingMode()) - { - case glc::NormalRenderMode: - normalRenderLoop(renderProperties, vboIsUsed); - break; - case glc::OverwriteMaterial: - OverwriteMaterialRenderLoop(renderProperties, vboIsUsed); - break; - case glc::OverwriteTransparency: - OverwriteTransparencyRenderLoop(renderProperties, vboIsUsed); - break; - case glc::OverwriteTransparencyAndMaterial: - OverwriteTransparencyAndMaterialRenderLoop(renderProperties, vboIsUsed); - break; - case glc::OverwritePrimitiveMaterial: - if ((m_CurrentLod == 0) && !renderProperties.hashOfOverwritePrimitiveMaterialsIsEmpty()) - primitiveRenderLoop(renderProperties, vboIsUsed); - else - normalRenderLoop(renderProperties, vboIsUsed); - break; - default: - Q_ASSERT(false); - break; - } - } - - - // Restore client state - - if (m_ColorPearVertex && !m_IsSelected && !GLC_State::isInSelectionMode()) - { - glDisableClientState(GL_COLOR_ARRAY); - glDisable(GL_COLOR_MATERIAL); - } - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - - if (vboIsUsed) - { - QGLBuffer::release(QGLBuffer::IndexBuffer); - QGLBuffer::release(QGLBuffer::VertexBuffer); - } - - // Draw mesh's wire if necessary - if ((renderProperties.renderingFlag() == glc::WireRenderFlag) && !m_WireData.isEmpty() && !GLC_Geometry::typeIsWire()) - { - if (!GLC_State::isInSelectionMode()) - { - GLC_Context::current()->glcEnableLighting(false); - // Set polyline colors - GLfloat color[4]= {static_cast(m_WireColor.redF()), - static_cast(m_WireColor.greenF()), - static_cast(m_WireColor.blueF()), - static_cast(m_WireColor.alphaF())}; - - glColor4fv(color); - m_WireData.glDraw(renderProperties, GL_LINE_STRIP); - GLC_Context::current()->glcEnableLighting(true); - } - else - { - m_WireData.glDraw(renderProperties, GL_LINE_STRIP); - } - } - - // Update statistics - GLC_RenderStatistics::addBodies(1); - GLC_RenderStatistics::addTriangles(m_MeshData.trianglesCount(m_CurrentLod)); -} - -////////////////////////////////////////////////////////////////////// -// Private services Functions -////////////////////////////////////////////////////////////////////// - -// Set the current material -GLC_uint GLC_Mesh::setCurrentMaterial(GLC_Material* pMaterial, int lod, double accuracy) -{ - - // Test if a primitive group hash exists for the specified lod - if (!m_PrimitiveGroups.contains(lod)) - { - m_PrimitiveGroups.insert(lod, new LodPrimitiveGroups()); - - m_MeshData.appendLod(accuracy); - } - - GLC_uint returnId; - if (NULL == pMaterial) - { - returnId= m_DefaultMaterialId; // Default material id - - // Test if the material has been already load - if (m_DefaultMaterialId == 0) - { - pMaterial= new GLC_Material(); - // Add the material to the mesh - addMaterial(pMaterial); - m_DefaultMaterialId= pMaterial->id(); - returnId= m_DefaultMaterialId; - - } - // Test if a primitive group for this material exist - if (!m_PrimitiveGroups.value(lod)->contains(returnId)) - { - m_PrimitiveGroups.value(lod)->insert(returnId, new GLC_PrimitiveGroup(returnId)); - } - } - else - { - returnId= pMaterial->id(); - // Test if the material has been already load - if (!containsMaterial(returnId)) - { - // Add the material to the mesh - addMaterial(pMaterial); - m_PrimitiveGroups.value(lod)->insert(returnId, new GLC_PrimitiveGroup(returnId)); - - } - else if (!m_PrimitiveGroups.value(lod)->contains(returnId)) - { - // Add the material to the group - m_PrimitiveGroups.value(lod)->insert(returnId, new GLC_PrimitiveGroup(returnId)); - } - } - - return returnId; -} - -// Fill VBOs and IBOs -void GLC_Mesh::fillVbosAndIbos() -{ - // Fill VBO of vertices - m_MeshData.fillVbo(GLC_MeshData::GLC_Vertex); - - // Fill VBO of normals - m_MeshData.fillVbo(GLC_MeshData::GLC_Normal); - - // Fill VBO of texel if needed - m_MeshData.fillVbo(GLC_MeshData::GLC_Texel); - - // Fill VBO of color if needed - m_MeshData.fillVbo(GLC_MeshData::GLC_Color); - - // Fill a lod IBO - m_MeshData.fillLodIbo(); - -} -// set primitive group offset -void GLC_Mesh::finishSerialized() -{ - PrimitiveGroupsHash::iterator iGroups= m_PrimitiveGroups.begin(); - while (iGroups != m_PrimitiveGroups.constEnd()) - { - LodPrimitiveGroups::iterator iGroup= iGroups.value()->begin(); - while (iGroup != iGroups.value()->constEnd()) - { - iGroup.value()->computeVboOffset(); - ++iGroup; - } - ++iGroups; - } -} -/* -// Move Indexs from the primitive groups to the mesh Data LOD and Set IBOs offsets -void GLC_Mesh::finishVbo() -{ - PrimitiveGroupsHash::iterator iGroups= m_PrimitiveGroups.begin(); - while (iGroups != m_PrimitiveGroups.constEnd()) - { - int currentLod= iGroups.key(); - LodPrimitiveGroups::iterator iGroup= iGroups.value()->begin(); - while (iGroup != iGroups.value()->constEnd()) - { - // Add group triangles index to mesh Data LOD triangles index vector - if (iGroup.value()->containsTriangles()) - { - iGroup.value()->setTrianglesOffset(BUFFER_OFFSET(m_MeshData.indexVectorSize(currentLod) * sizeof(GLuint))); - (*m_MeshData.indexVectorHandle(currentLod))+= iGroup.value()->trianglesIndex().toVector(); - } - - // Add group strip index to mesh Data LOD strip index vector - if (iGroup.value()->containsStrip()) - { - iGroup.value()->setBaseTrianglesStripOffset(BUFFER_OFFSET(m_MeshData.indexVectorSize(currentLod) * sizeof(GLuint))); - (*m_MeshData.indexVectorHandle(currentLod))+= iGroup.value()->stripsIndex().toVector(); - } - - // Add group fan index to mesh Data LOD fan index vector - if (iGroup.value()->containsFan()) - { - iGroup.value()->setBaseTrianglesFanOffset(BUFFER_OFFSET(m_MeshData.indexVectorSize(currentLod) * sizeof(GLuint))); - (*m_MeshData.indexVectorHandle(currentLod))+= iGroup.value()->fansIndex().toVector(); - } - - iGroup.value()->finish(); - ++iGroup; - } - ++iGroups; - - } -} -*/ - -// Move Indexs from the primitive groups to the mesh Data LOD and Set Index offsets -void GLC_Mesh::moveIndexToMeshDataLod() -{ - //qDebug() << "GLC_Mesh::moveIndexToMeshDataLod()"; - PrimitiveGroupsHash::iterator iGroups= m_PrimitiveGroups.begin(); - while (iGroups != m_PrimitiveGroups.constEnd()) - { - int currentLod= iGroups.key(); - LodPrimitiveGroups::iterator iGroup= iGroups.value()->begin(); - while (iGroup != iGroups.value()->constEnd()) - { - // Add group triangles index to mesh Data LOD triangles index vector - if (iGroup.value()->containsTriangles()) - { - iGroup.value()->setTrianglesOffseti(m_MeshData.indexVectorSize(currentLod)); - (*m_MeshData.indexVectorHandle(currentLod))+= iGroup.value()->trianglesIndex().toVector(); - } - - // Add group strip index to mesh Data LOD strip index vector - if (iGroup.value()->containsStrip()) - { - iGroup.value()->setBaseTrianglesStripOffseti(m_MeshData.indexVectorSize(currentLod)); - (*m_MeshData.indexVectorHandle(currentLod))+= iGroup.value()->stripsIndex().toVector(); - } - - // Add group fan index to mesh Data LOD fan index vector - if (iGroup.value()->containsFan()) - { - iGroup.value()->setBaseTrianglesFanOffseti(m_MeshData.indexVectorSize(currentLod)); - (*m_MeshData.indexVectorHandle(currentLod))+= iGroup.value()->fansIndex().toVector(); - } - - iGroup.value()->computeVboOffset(); - iGroup.value()->finish(); - ++iGroup; - } - ++iGroups; - } -} - -// The normal display loop -void GLC_Mesh::normalRenderLoop(const GLC_RenderProperties& renderProperties, bool vboIsUsed) -{ - const bool isTransparent= (renderProperties.renderingFlag() == glc::TransparentRenderFlag); - if ((!m_IsSelected || !isTransparent) || GLC_State::isInSelectionMode()) - { - LodPrimitiveGroups::iterator iGroup= m_PrimitiveGroups.value(m_CurrentLod)->begin(); - while (iGroup != m_PrimitiveGroups.value(m_CurrentLod)->constEnd()) - { - GLC_PrimitiveGroup* pCurrentGroup= iGroup.value(); - GLC_Material* pCurrentMaterial= m_MaterialHash.value(pCurrentGroup->id()); - - // Test if the current material is renderable - bool materialIsrenderable = (pCurrentMaterial->isTransparent() == isTransparent); - - // Choose the material to render - if ((materialIsrenderable || m_IsSelected) && !GLC_State::isInSelectionMode()) - { - // Execute current material - pCurrentMaterial->glExecute(); - - if (m_IsSelected) GLC_SelectionMaterial::glExecute(); - } - - // Choose the primitives to render - if (m_IsSelected || GLC_State::isInSelectionMode() || materialIsrenderable) - { - - if (vboIsUsed) - { - vboDrawPrimitivesOf(pCurrentGroup); - } - else - { - vertexArrayDrawPrimitivesOf(pCurrentGroup); - } - } - - ++iGroup; - } - } -} - -// The overwrite material render loop -void GLC_Mesh::OverwriteMaterialRenderLoop(const GLC_RenderProperties& renderProperties, bool vboIsUsed) -{ - // Get the overwrite material - GLC_Material* pOverwriteMaterial= renderProperties.overwriteMaterial(); - Q_ASSERT(NULL != pOverwriteMaterial); - pOverwriteMaterial->glExecute(); - if (m_IsSelected) GLC_SelectionMaterial::glExecute(); - - LodPrimitiveGroups::iterator iGroup= m_PrimitiveGroups.value(m_CurrentLod)->begin(); - while (iGroup != m_PrimitiveGroups.value(m_CurrentLod)->constEnd()) - { - GLC_PrimitiveGroup* pCurrentGroup= iGroup.value(); - - // Test if the current material is renderable - bool materialIsrenderable = (pOverwriteMaterial->isTransparent() == (renderProperties.renderingFlag() == glc::TransparentRenderFlag)); - - // Choose the primitives to render - if (m_IsSelected || materialIsrenderable) - { - - if (vboIsUsed) - vboDrawPrimitivesOf(pCurrentGroup); - else - vertexArrayDrawPrimitivesOf(pCurrentGroup); - } - - ++iGroup; - } -} -// The overwrite transparency render loop -void GLC_Mesh::OverwriteTransparencyRenderLoop(const GLC_RenderProperties& renderProperties, bool vboIsUsed) -{ - // Get transparency value - const float alpha= renderProperties.overwriteTransparency(); - Q_ASSERT(-1.0f != alpha); - - // Test if the current material is renderable - bool materialIsrenderable = (renderProperties.renderingFlag() == glc::TransparentRenderFlag); - - if (materialIsrenderable || m_IsSelected) - { - LodPrimitiveGroups::iterator iGroup= m_PrimitiveGroups.value(m_CurrentLod)->begin(); - while (iGroup != m_PrimitiveGroups.value(m_CurrentLod)->constEnd()) - { - GLC_PrimitiveGroup* pCurrentGroup= iGroup.value(); - GLC_Material* pCurrentMaterial= m_MaterialHash.value(pCurrentGroup->id()); - - // Execute current material - pCurrentMaterial->glExecute(alpha); - - if (m_IsSelected) GLC_SelectionMaterial::glExecute(); - - // Choose the primitives to render - if (m_IsSelected || materialIsrenderable) - { - - if (vboIsUsed) - vboDrawPrimitivesOf(pCurrentGroup); - else - vertexArrayDrawPrimitivesOf(pCurrentGroup); - } - ++iGroup; - } - } -} - -void GLC_Mesh::OverwriteTransparencyAndMaterialRenderLoop(const GLC_RenderProperties& renderProperties, bool vboIsUsed) -{ - // Get transparency value - const float alpha= renderProperties.overwriteTransparency(); - Q_ASSERT(-1.0f != alpha); - - // Get the overwrite material - GLC_Material* pOverwriteMaterial= renderProperties.overwriteMaterial(); - Q_ASSERT(NULL != pOverwriteMaterial); - pOverwriteMaterial->glExecute(alpha); - if (m_IsSelected) GLC_SelectionMaterial::glExecute(); - - LodPrimitiveGroups::iterator iGroup= m_PrimitiveGroups.value(m_CurrentLod)->begin(); - while (iGroup != m_PrimitiveGroups.value(m_CurrentLod)->constEnd()) - { - GLC_PrimitiveGroup* pCurrentGroup= iGroup.value(); - - // Test if the current material is renderable - bool materialIsrenderable = (renderProperties.renderingFlag() == glc::TransparentRenderFlag); - - // Choose the primitives to render - if (m_IsSelected || materialIsrenderable) - { - - if (vboIsUsed) - vboDrawPrimitivesOf(pCurrentGroup); - else - vertexArrayDrawPrimitivesOf(pCurrentGroup); - } - - ++iGroup; - } -} - -// The body selection render loop -void GLC_Mesh::bodySelectionRenderLoop(bool vboIsUsed) -{ - Q_ASSERT(GLC_State::isInSelectionMode()); - - LodPrimitiveGroups::iterator iGroup= m_PrimitiveGroups.value(m_CurrentLod)->begin(); - while (iGroup != m_PrimitiveGroups.value(m_CurrentLod)->constEnd()) - { - GLC_PrimitiveGroup* pCurrentGroup= iGroup.value(); - - if (vboIsUsed) - vboDrawPrimitivesOf(pCurrentGroup); - else - vertexArrayDrawPrimitivesOf(pCurrentGroup); - - ++iGroup; - } -} - -// The primitive selection render loop -void GLC_Mesh::primitiveSelectionRenderLoop(bool vboIsUsed) -{ - Q_ASSERT(GLC_State::isInSelectionMode()); - - LodPrimitiveGroups::iterator iGroup= m_PrimitiveGroups.value(m_CurrentLod)->begin(); - - while (iGroup != m_PrimitiveGroups.value(m_CurrentLod)->constEnd()) - { - GLC_PrimitiveGroup* pCurrentGroup= iGroup.value(); - - if (vboIsUsed) - vboDrawInSelectionModePrimitivesOf(pCurrentGroup); - else - vertexArrayDrawInSelectionModePrimitivesOf(pCurrentGroup); - - ++iGroup; - } -} - -// The primitive rendeder loop -void GLC_Mesh::primitiveRenderLoop(const GLC_RenderProperties& renderProperties, bool vboIsUsed) -{ - const bool isTransparent= (renderProperties.renderingFlag() == glc::TransparentRenderFlag); - LodPrimitiveGroups::iterator iGroup= m_PrimitiveGroups.value(m_CurrentLod)->begin(); - while (iGroup != m_PrimitiveGroups.value(m_CurrentLod)->constEnd()) - { - GLC_PrimitiveGroup* pCurrentGroup= iGroup.value(); - GLC_Material* pCurrentMaterial= m_MaterialHash.value(pCurrentGroup->id()); - - // Test if the current material is renderable - const bool materialIsrenderable = (pCurrentMaterial->isTransparent() == isTransparent); - - if (materialIsrenderable) - { - pCurrentMaterial->glExecute(); - } - if (vboIsUsed) - vboDrawPrimitivesGroupOf(pCurrentGroup, pCurrentMaterial, materialIsrenderable, isTransparent, renderProperties.hashOfOverwritePrimitiveMaterials()); - else - vertexArrayDrawPrimitivesGroupOf(pCurrentGroup, pCurrentMaterial, materialIsrenderable, isTransparent, renderProperties.hashOfOverwritePrimitiveMaterials()); - - ++iGroup; - } -} - -// The primitive Selected render loop -void GLC_Mesh::primitiveSelectedRenderLoop(const GLC_RenderProperties& renderProperties, bool vboIsUsed) -{ - const bool isTransparent= (renderProperties.renderingFlag() == glc::TransparentRenderFlag); - LodPrimitiveGroups::iterator iGroup= m_PrimitiveGroups.value(m_CurrentLod)->begin(); - while (iGroup != m_PrimitiveGroups.value(m_CurrentLod)->constEnd()) - { - GLC_PrimitiveGroup* pCurrentGroup= iGroup.value(); - GLC_Material* pCurrentMaterial= m_MaterialHash.value(pCurrentGroup->id()); - - // Test if the current material is renderable - const bool materialIsrenderable = (pCurrentMaterial->isTransparent() == isTransparent); - - if (materialIsrenderable) - { - pCurrentMaterial->glExecute(); - } - - if (vboIsUsed) - vboDrawSelectedPrimitivesGroupOf(pCurrentGroup, pCurrentMaterial, materialIsrenderable, isTransparent, renderProperties); - else - vertexArrayDrawSelectedPrimitivesGroupOf(pCurrentGroup, pCurrentMaterial, materialIsrenderable, isTransparent, renderProperties); - - ++iGroup; - } -} - -void GLC_Mesh::copyIndex(int lodIndex, GLC_Mesh* pLodMesh, QHash& sourceToTargetIndexMap, QHash& tagetToSourceIndexMap, int& maxIndex, int targetLod) -{ - //! The list of LOD material ID - QList materialId= m_PrimitiveGroups.value(lodIndex)->keys(); - - const int materialCount= materialId.size(); - for (int i= 0; i < materialCount; ++i) - { - GLuint currentMaterialId= materialId.at(i); - GLC_Material* pCurrentMaterial= GLC_Geometry::material(currentMaterialId); - - // Triangles - if (containsTriangles(lodIndex, currentMaterialId)) - { - QVector sourceTriangleIndex= getTrianglesIndex(lodIndex, currentMaterialId); - QList targetTriangleIndex; - const int triangleIndexCount= sourceTriangleIndex.size(); - for (int i= 0; i < triangleIndexCount; ++i) - { - const GLuint currentIndex= sourceTriangleIndex.at(i); - if (!sourceToTargetIndexMap.contains(currentIndex)) - { - sourceToTargetIndexMap.insert(currentIndex, ++maxIndex); - tagetToSourceIndexMap.insert(maxIndex, currentIndex); - targetTriangleIndex.append(maxIndex); - } - else - { - targetTriangleIndex.append(sourceToTargetIndexMap.value(currentIndex)); - } - } - pLodMesh->addTriangles(pCurrentMaterial, targetTriangleIndex, targetLod, m_MeshData.getLod(lodIndex)->accuracy()); - } - - //Triangles strips - if (containsStrips(lodIndex, currentMaterialId)) - { - QList > sourceStripIndex= getStripsIndex(lodIndex, currentMaterialId); - const int stripCount= sourceStripIndex.size(); - for (int stripIndex= 0; stripIndex < stripCount; ++stripIndex) - { - - QVector sourceTriangleStripIndex= sourceStripIndex.at(stripIndex); - QList targetTriangleStripIndex; - const int triangleStripIndexCount= sourceTriangleStripIndex.size(); - for (int i= 0; i < triangleStripIndexCount; ++i) - { - const GLuint currentIndex= sourceTriangleStripIndex.at(i); - if (!sourceToTargetIndexMap.contains(currentIndex)) - { - sourceToTargetIndexMap.insert(currentIndex, ++maxIndex); - tagetToSourceIndexMap.insert(maxIndex, currentIndex); - targetTriangleStripIndex.append(maxIndex); - } - else - { - targetTriangleStripIndex.append(sourceToTargetIndexMap.value(currentIndex)); - } - } - pLodMesh->addTrianglesStrip(pCurrentMaterial, targetTriangleStripIndex, targetLod, m_MeshData.getLod(lodIndex)->accuracy()); - } - } - //Triangles fans - if (containsFans(lodIndex, currentMaterialId)) - { - QList > sourceFanIndex= getFansIndex(lodIndex, currentMaterialId); - const int fanCount= sourceFanIndex.size(); - for (int fanIndex= 0; fanIndex < fanCount; ++fanIndex) - { - - QVector sourceTriangleFanIndex= sourceFanIndex.at(fanIndex); - QList targetTriangleFanIndex; - const int triangleFanIndexCount= sourceTriangleFanIndex.size(); - for (int i= 0; i < triangleFanIndexCount; ++i) - { - const GLuint currentIndex= sourceTriangleFanIndex.at(i); - if (!sourceToTargetIndexMap.contains(currentIndex)) - { - sourceToTargetIndexMap.insert(currentIndex, ++maxIndex); - tagetToSourceIndexMap.insert(maxIndex, currentIndex); - targetTriangleFanIndex.append(maxIndex); - } - else - { - targetTriangleFanIndex.append(sourceToTargetIndexMap.value(currentIndex)); - } - } - pLodMesh->addTrianglesFan(pCurrentMaterial, targetTriangleFanIndex, targetLod, m_MeshData.getLod(lodIndex)->accuracy()); - } - } - } -} - -void GLC_Mesh::copyBulkData(GLC_Mesh* pLodMesh, const QHash& tagetToSourceIndexMap, int maxIndex) -{ - GLfloatVector tempFloatVector; - int stride= 3; - // Extract position bulk data - Q_ASSERT(!m_MeshData.positionVectorHandle()->isEmpty()); - tempFloatVector.resize(stride * (maxIndex + 1)); - for (int i= 0; i < maxIndex + 1; ++i) - { - GLfloat* pTarget= &(tempFloatVector.data()[i * stride]); - GLfloat* pSource= &(m_MeshData.positionVectorHandle()->data()[tagetToSourceIndexMap.value(i) * stride]); - - memcpy(pTarget, pSource, sizeof(GLfloat) * stride); - } - pLodMesh->addVertice(tempFloatVector); - tempFloatVector.clear(); - - // Extract normal bulk data - Q_ASSERT(!m_MeshData.normalVectorHandle()->isEmpty()); - tempFloatVector.resize(stride * (maxIndex + 1)); - for (int i= 0; i < maxIndex + 1; ++i) - { - GLfloat* pTarget= &(tempFloatVector.data()[i * stride]); - GLfloat* pSource= &(m_MeshData.normalVectorHandle()->data()[tagetToSourceIndexMap.value(i) * stride]); - - memcpy(pTarget, pSource, sizeof(GLfloat) * stride); - } - pLodMesh->addNormals(tempFloatVector); - tempFloatVector.clear(); - - if (!m_MeshData.texelVectorHandle()->isEmpty()) - { - // Extract texel bulk data - stride= 2; - tempFloatVector.resize(stride * (maxIndex + 1)); - - for (int i= 0; i < maxIndex + 1; ++i) - { - GLfloat* pTarget= &(tempFloatVector.data()[i * stride]); - GLfloat* pSource= &(m_MeshData.texelVectorHandle()->data()[tagetToSourceIndexMap.value(i) * stride]); - - memcpy(pTarget, pSource, sizeof(GLfloat) * stride); - } - pLodMesh->addTexels(tempFloatVector); - tempFloatVector.clear(); - } -} - -IndexList GLC_Mesh::equivalentTrianglesIndexOfstripsIndex(int lodIndex, GLC_uint materialId) -{ - IndexList trianglesIndex; - if (containsStrips(lodIndex, materialId)) - { - const QList > stripsIndex= getStripsIndex(lodIndex, materialId); - const int stripCount= stripsIndex.count(); - for (int i= 0; i < stripCount; ++i) - { - const QVector currentStripIndex= stripsIndex.at(i); - - trianglesIndex.append(currentStripIndex.at(0)); - trianglesIndex.append(currentStripIndex.at(1)); - trianglesIndex.append(currentStripIndex.at(2)); - const int stripSize= currentStripIndex.size(); - for (int j= 3; j < stripSize; ++j) - { - if ((j % 2) != 0) - { - trianglesIndex.append(currentStripIndex.at(j)); - trianglesIndex.append(currentStripIndex.at(j - 1)); - trianglesIndex.append(currentStripIndex.at(j - 2)); - } - else - { - trianglesIndex.append(currentStripIndex.at(j)); - trianglesIndex.append(currentStripIndex.at(j - 2)); - trianglesIndex.append(currentStripIndex.at(j - 1)); - } - } - } - } - return trianglesIndex; -} - -IndexList GLC_Mesh::equivalentTrianglesIndexOfFansIndex(int lodIndex, GLC_uint materialId) -{ - IndexList trianglesIndex; - if (containsFans(lodIndex, materialId)) - { - const QList > fanIndex= getFansIndex(lodIndex, materialId); - const int fanCount= fanIndex.count(); - for (int i= 0; i < fanCount; ++i) - { - const QVector currentFanIndex= fanIndex.at(i); - const int size= currentFanIndex.size(); - for (int j= 1; j < size - 1; ++j) - { - trianglesIndex.append(currentFanIndex.first()); - trianglesIndex.append(currentFanIndex.at(j)); - trianglesIndex.append(currentFanIndex.at(j + 1)); - } - } - } - return trianglesIndex; -} - diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_mesh.h b/ground/gcs/src/libs/glc_lib/geometry/glc_mesh.h deleted file mode 100644 index 8a295a4d5..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_mesh.h +++ /dev/null @@ -1,1136 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_mesh.h interface for the GLC_Mesh class. - -#ifndef GLC_MESH_H_ -#define GLC_MESH_H_ - -#include -#include -#include "../maths/glc_vector2df.h" -#include "../maths/glc_vector3df.h" -#include "../glc_global.h" -#include "../shading/glc_material.h" -#include "glc_meshdata.h" -#include "glc_geometry.h" -#include "glc_primitivegroup.h" -#include "../glc_state.h" -#include "../shading/glc_selectionmaterial.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Mesh -/*! \brief GLC_Mesh : OpenGL 3D Mesh*/ - -/*! An GLC_Mesh is Mesh composed of triangles, strips and fan -*/ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_Mesh : public GLC_Geometry -{ - friend QDataStream &operator<<(QDataStream &, const GLC_Mesh &); - friend QDataStream &operator>>(QDataStream &, GLC_Mesh &); - -public: - typedef QHash LodPrimitiveGroups; - typedef QHash PrimitiveGroupsHash; - -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Default constructor - GLC_Mesh(); - - //! Copy constructor - GLC_Mesh(const GLC_Mesh&); - - //! Overload "=" operator - GLC_Mesh& operator=(const GLC_Mesh&); - - //! Destructor - virtual ~GLC_Mesh(); -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the class Chunk ID - static quint32 chunckID(); - - //! Get number of faces - virtual unsigned int faceCount(int lod) const; - - //! Get number of vertex - virtual unsigned int VertexCount() const; - - //! Get number of normals - inline unsigned int numberOfNormals() const - { return m_NumberOfNormals;} - - //! return the mesh bounding box - virtual const GLC_BoundingBox& boundingBox(void); - - //! Return a copy of the Mesh as GLC_Geometry pointer - virtual GLC_Geometry* clone() const; - - //! Return true if color pear vertex is activated - inline bool ColorPearVertexIsAcivated() const - {return m_ColorPearVertex;} - - //! Return the number of lod - inline int lodCount() const - {return m_MeshData.lodCount();} - - //! Return the Position Vector - inline GLfloatVector positionVector() const - {return m_MeshData.positionVector();} - - //! Return the normal Vector - inline GLfloatVector normalVector() const - {return m_MeshData.normalVector();} - - //! Return the texel Vector - inline GLfloatVector texelVector() const - {return m_MeshData.texelVector();} - - //! Return true if the mesh contains triangles in the specified LOD - bool containsTriangles(int lod, GLC_uint materialId) const; - - //! Return the triangle index - /*! The specified LOD must exists and uses the specified material id*/ - QVector getTrianglesIndex(int lod, GLC_uint materialId) const; - - //! Return the equivalent triangle index of (triangle, strip and fan) - IndexList getEquivalentTrianglesStripsFansIndex(int lod, GLC_uint materialId); - - //! Return the number of triangles in the specified LOD - int numberOfTriangles(int lod, GLC_uint materialId) const; - - //! Return true if the mesh contains trips in the specified LOD with the specified material id - bool containsStrips(int lod, GLC_uint materialId) const; - - //! Return the strips index - /*! The specified LOD must exists and uses the specified material id*/ - QList > getStripsIndex(int lod, GLC_uint materialId) const; - - //! Return the number of strips in the specified LOD with the specified material id - int numberOfStrips(int lod, GLC_uint materialId) const; - - //! Return true if the mesh contains fans in the specified LOD with the specified material id - bool containsFans(int lod, GLC_uint materialId) const; - - //! Return the fans index - /*! The specified LOD must exists and uses the specified material id*/ - QList > getFansIndex(int lod, GLC_uint materialId) const; - - //! Return the number of fans in the specified LOD with the specified material id - int numberOfFans(int lod, GLC_uint materialId) const; - - //! Return true if the mesh contains the specified LOD - inline bool containsLod(int lod) const - {return (NULL != m_MeshData.getLod(lod));} - - //! Return true if the specified LOD contains the specified material - inline bool lodContainsMaterial(int lod, GLC_uint materialId) const - { - if (!m_PrimitiveGroups.contains(lod))return false; - else return m_PrimitiveGroups.value(lod)->contains(materialId); - } - - //! Return the specified LOD accuracy - /*! The specified LOD must exists*/ - inline double getLodAccuracy(int lod) const - { - Q_ASSERT(containsLod(lod)); - return m_MeshData.getLod(lod)->accuracy(); - } - - //! Return the next primitive local id - inline GLC_uint nextPrimitiveLocalId() const - {return m_NextPrimitiveLocalId;} - - //! Return the GLC_Material applyed on the given primitive id of the given lod - GLC_Material* MaterialOfPrimitiveId(GLC_uint id, int lod= 0) const; - - //! Return the set of primitives id - QSet setOfPrimitiveId() const; - - //! Return true if the mesh position data is empty - inline bool isEmpty() const - {return m_MeshData.isEmpty();} - - //! Return the mesh wire color - inline QColor wireColor() const - {return m_WireColor;} - - //! Create a mesh of the given LOD index - GLC_Mesh* createMeshOfGivenLod(int lodIndex); - - //! Create a mesh from the given LOD index - GLC_Mesh* createMeshFromGivenLod(int lodIndex); - - //! Transform mesh vertice by the given matrix - GLC_Mesh& transformVertice(const GLC_Matrix4x4& matrix); - - //! Return the volume of this mesh - virtual double volume(); - -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Clear the content of the mesh and super class and makes them empty - virtual void clear(); - - //! Clear only the content off the mesh and makes it empty - void clearMeshWireAndBoundingBox(); - - //! Add vertices coordinate - inline void addVertice(const GLfloatVector& vertices) - { - *(m_MeshData.positionVectorHandle())+= vertices; - m_NumberOfVertice+= vertices.size() / 3; - } - - //! Add Normals - inline void addNormals(const GLfloatVector& normals) - { - *(m_MeshData.normalVectorHandle())+= normals; - m_NumberOfNormals+= normals.size() / 3; - } - - //! Add texel - inline void addTexels(const GLfloatVector& texels) - {*(m_MeshData.texelVectorHandle())+= texels;} - - //! Add Colors - inline void addColors(const GLfloatVector& colors) - {*(m_MeshData.colorVectorHandle())+= colors;} - - //! Add triangles - GLC_uint addTriangles(GLC_Material*, const IndexList&, const int lod= 0, double accuracy= 0.0); - - //! Add triangles Strip and return his id - GLC_uint addTrianglesStrip(GLC_Material*, const IndexList&, const int lod= 0, double accuracy= 0.0); - - //! Add triangles Fan and return his id - GLC_uint addTrianglesFan(GLC_Material*, const IndexList&, const int lod= 0, double accuracy= 0.0); - - //! Reverse mesh normal - void reverseNormals(); - - //! Set color per vertex flag to use indexed color - inline void setColorPearVertex(bool flag) - {m_ColorPearVertex= flag;} - - //! Copy vertex list in a vector list for Vertex Array Use - void finish(); - - //! Set the lod Index - virtual void setCurrentLod(const int); - - //! Replace the Master material - virtual void replaceMasterMaterial(GLC_Material*); - - //! Replace the material specified by id with another one - void replaceMaterial(const GLC_uint, GLC_Material*); - - //! Set the mesh next primitive local id - inline void setNextPrimitiveLocalId(GLC_uint id) - {m_NextPrimitiveLocalId= id;} - - //! Set the mesh wire color - inline void setWireColor(const QColor& color) - {m_WireColor= color;} - - //! Copy VBO to the Client Side - virtual void copyVboToClientSide(); - - //! Release client VBO - virtual void releaseVboClientSide(bool update); - - //! Set VBO usage - virtual void setVboUsage(bool usage); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Binary serialisation Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Load the mesh from binary data stream - /*! The MaterialHash contains a hash table of GLC_Material that the mesh can use - * The QHash is used to map serialised material ID to the new - * constructed materials - */ - void loadFromDataStream(QDataStream&, const MaterialHash&, const QHash&); - - //! Save the mesh to binary data stream - void saveToDataStream(QDataStream&) const; - -//@} -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -protected: - - //! Virtual interface for OpenGL Geometry set up. - /*! This Virtual function is implemented here.*/ - virtual void glDraw(const GLC_RenderProperties&); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Private services Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -private: - //! Set the current material - GLC_uint setCurrentMaterial(GLC_Material*, const int, double); - - //! Fill VBOs and IBOs - void fillVbosAndIbos(); - - //! Set primitive group offset after loading mesh from binary - void finishSerialized(); - - //! Move Indexs from the primitive groups to the mesh Data LOD and Set IBOs offsets - //void finishVbo(); - - //! Move Indexs from the primitive groups to the mesh Data LOD and Set Index offsets - void moveIndexToMeshDataLod(); - - //! Use VBO to Draw primitives from the specified GLC_PrimitiveGroup - inline void vboDrawPrimitivesOf(GLC_PrimitiveGroup*); - - //! Use Vertex Array to Draw primitives from the specified GLC_PrimitiveGroup - inline void vertexArrayDrawPrimitivesOf(GLC_PrimitiveGroup*); - - //! Use VBO to Draw primitives in selection mode from the specified GLC_PrimitiveGroup - inline void vboDrawInSelectionModePrimitivesOf(GLC_PrimitiveGroup*); - - //! Use Vertex Array to Draw primitives in selection mode from the specified GLC_PrimitiveGroup - inline void vertexArrayDrawInSelectionModePrimitivesOf(GLC_PrimitiveGroup*); - - //! Use VBO to Draw primitives with specific materials from the specified GLC_PrimitiveGroup - inline void vboDrawPrimitivesGroupOf(GLC_PrimitiveGroup*, GLC_Material*, bool, bool, QHash*); - - //! Use Vertex Array to Draw primitives with specific materials from the specified GLC_PrimitiveGroup - inline void vertexArrayDrawPrimitivesGroupOf(GLC_PrimitiveGroup*, GLC_Material*, bool, bool, QHash*); - - //! Use VBO to Draw primitives with selection materials from the specified GLC_PrimitiveGroup - inline void vboDrawSelectedPrimitivesGroupOf(GLC_PrimitiveGroup*, GLC_Material*, bool, bool, const GLC_RenderProperties&); - - //! Use Vertex Array to Draw primitives with selection materials from the specified GLC_PrimitiveGroup - inline void vertexArrayDrawSelectedPrimitivesGroupOf(GLC_PrimitiveGroup*, GLC_Material*, bool, bool, const GLC_RenderProperties&); - - //! Activate mesh VBOs and IBO of the current LOD - inline void activateVboAndIbo(); - - //! Activate vertex Array - inline void activateVertexArray(); - - //! The normal display loop - void normalRenderLoop(const GLC_RenderProperties&, bool); - - //! The overwrite material render loop - void OverwriteMaterialRenderLoop(const GLC_RenderProperties&, bool); - - //! The overwrite transparency render loop - void OverwriteTransparencyRenderLoop(const GLC_RenderProperties&, bool); - - //! The overwrite transparency and material render loop - void OverwriteTransparencyAndMaterialRenderLoop(const GLC_RenderProperties&, bool); - - //! The body selection render loop - void bodySelectionRenderLoop(bool); - - //! The primitive selection render loop - void primitiveSelectionRenderLoop(bool); - - //! The primitive render loop - void primitiveRenderLoop(const GLC_RenderProperties&, bool); - - //! The primitive Selected render loop - void primitiveSelectedRenderLoop(const GLC_RenderProperties&, bool); - - //! Copy index of this mesh from the given LOD into the given mesh - void copyIndex(int lod, GLC_Mesh* pLodMesh, QHash& sourceToTargetIndexMap, QHash& tagetToSourceIndexMap, int& maxIndex, int targetLod); - - //! Copy Bulk data - void copyBulkData(GLC_Mesh* pLodMesh, const QHash& tagetToSourceIndexMap, int maxIndex); - - //! Return the equivalent triangles index of the strips index of given LOD and material ID - IndexList equivalentTrianglesIndexOfstripsIndex(int lodIndex, GLC_uint materialId); - - //! Return the equivalent triangles index of the fan index of given LOD and material ID - IndexList equivalentTrianglesIndexOfFansIndex(int lodIndex, GLC_uint materialId); - - -//@} - - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - //! The next primitive local id - GLC_uint m_NextPrimitiveLocalId; - - //! The hash table of Hash table of primitive group - PrimitiveGroupsHash m_PrimitiveGroups; - - //! The default material Id - GLC_uint m_DefaultMaterialId; - - //! Mesh number of vertice - unsigned int m_NumberOfVertice; - - //! Mesh number of normals - unsigned int m_NumberOfNormals; - - //! Color pear vertex - bool m_ColorPearVertex; - - //! Data of the mesh (Bulk Data + LOD with indexs) - GLC_MeshData m_MeshData; - - //! The current LOD index - int m_CurrentLod; - - //! Class chunk id - static quint32 m_ChunkId; - -}; - -// Inline functions - -// Use VBO to Draw triangles from the specified GLC_PrimitiveGroup -void GLC_Mesh::vboDrawPrimitivesOf(GLC_PrimitiveGroup* pCurrentGroup) -{ - // Draw triangles - if (pCurrentGroup->containsTriangles()) - { - glDrawElements(GL_TRIANGLES, pCurrentGroup->trianglesIndexSize(), GL_UNSIGNED_INT, pCurrentGroup->trianglesIndexOffset()); - } - - // Draw Triangles strip - if (pCurrentGroup->containsStrip()) - { - const GLsizei stripsCount= static_cast(pCurrentGroup->stripsOffset().size()); - for (GLint i= 0; i < stripsCount; ++i) - { - glDrawElements(GL_TRIANGLE_STRIP, pCurrentGroup->stripsSizes().at(i), GL_UNSIGNED_INT, pCurrentGroup->stripsOffset().at(i)); - } - } - - // Draw Triangles fan - if (pCurrentGroup->containsFan()) - { - const GLsizei fansCount= static_cast(pCurrentGroup->fansOffset().size()); - for (GLint i= 0; i < fansCount; ++i) - { - glDrawElements(GL_TRIANGLE_FAN, pCurrentGroup->fansSizes().at(i), GL_UNSIGNED_INT, pCurrentGroup->fansOffset().at(i)); - } - } -} -// Use Vertex Array to Draw triangles from the specified GLC_PrimitiveGroup -void GLC_Mesh::vertexArrayDrawPrimitivesOf(GLC_PrimitiveGroup* pCurrentGroup) -{ - // Draw triangles - if (pCurrentGroup->containsTriangles()) - { - GLvoid* pOffset= &(m_MeshData.indexVectorHandle(m_CurrentLod)->data()[pCurrentGroup->trianglesIndexOffseti()]); - glDrawElements(GL_TRIANGLES, pCurrentGroup->trianglesIndexSize(), GL_UNSIGNED_INT, pOffset); - } - - // Draw Triangles strip - if (pCurrentGroup->containsStrip()) - { - const GLsizei stripsCount= static_cast(pCurrentGroup->stripsOffseti().size()); - for (GLint i= 0; i < stripsCount; ++i) - { - GLvoid* pOffset= &m_MeshData.indexVectorHandle(m_CurrentLod)->data()[pCurrentGroup->stripsOffseti().at(i)]; - glDrawElements(GL_TRIANGLE_STRIP, pCurrentGroup->stripsSizes().at(i), GL_UNSIGNED_INT, pOffset); - } - } - - // Draw Triangles fan - if (pCurrentGroup->containsFan()) - { - const GLsizei fansCount= static_cast(pCurrentGroup->fansOffseti().size()); - for (GLint i= 0; i < fansCount; ++i) - { - GLvoid* pOffset= &m_MeshData.indexVectorHandle(m_CurrentLod)->data()[pCurrentGroup->fansOffseti().at(i)]; - glDrawElements(GL_TRIANGLE_FAN, pCurrentGroup->fansSizes().at(i), GL_UNSIGNED_INT, pOffset); - } - } -} - -// Use VBO to Draw primitives in selection mode from the specified GLC_PrimitiveGroup -void GLC_Mesh::vboDrawInSelectionModePrimitivesOf(GLC_PrimitiveGroup* pCurrentGroup) -{ - GLubyte colorId[4]; - // Draw triangles - if (pCurrentGroup->containsTrianglesGroupId()) - { - const GLsizei trianglesGroupCount= static_cast(pCurrentGroup->trianglesGroupOffset().size()); - for (GLint i= 0; i < trianglesGroupCount; ++i) - { - glc::encodeRgbId(pCurrentGroup->triangleGroupId(i), colorId); - glColor3ubv(colorId); - glDrawElements(GL_TRIANGLES, pCurrentGroup->trianglesIndexSizes().at(i), GL_UNSIGNED_INT, pCurrentGroup->trianglesGroupOffset().at(i)); - } - } - - // Draw Triangles strip - if (pCurrentGroup->containsStripGroupId()) - { - const GLsizei stripsCount= static_cast(pCurrentGroup->stripsOffset().size()); - for (GLint i= 0; i < stripsCount; ++i) - { - glc::encodeRgbId(pCurrentGroup->stripGroupId(i), colorId); - glColor3ubv(colorId); - glDrawElements(GL_TRIANGLE_STRIP, pCurrentGroup->stripsSizes().at(i), GL_UNSIGNED_INT, pCurrentGroup->stripsOffset().at(i)); - } - } - - // Draw Triangles fan - if (pCurrentGroup->containsFanGroupId()) - { - const GLsizei fansCount= static_cast(pCurrentGroup->fansOffset().size()); - for (GLint i= 0; i < fansCount; ++i) - { - glc::encodeRgbId(pCurrentGroup->fanGroupId(i), colorId); - glColor3ubv(colorId); - - glDrawElements(GL_TRIANGLE_FAN, pCurrentGroup->fansSizes().at(i), GL_UNSIGNED_INT, pCurrentGroup->fansOffset().at(i)); - } - } - -} - -// Use Vertex Array to Draw primitives in selection mode from the specified GLC_PrimitiveGroup -void GLC_Mesh::vertexArrayDrawInSelectionModePrimitivesOf(GLC_PrimitiveGroup* pCurrentGroup) -{ - GLubyte colorId[4]; - // Draw triangles - if (pCurrentGroup->containsTrianglesGroupId()) - { - const GLsizei trianglesGroupCount= static_cast(pCurrentGroup->trianglesGroupOffseti().size()); - for (GLint i= 0; i < trianglesGroupCount; ++i) - { - glc::encodeRgbId(pCurrentGroup->triangleGroupId(i), colorId); - glColor3ubv(colorId); - - GLvoid* pOffset= &m_MeshData.indexVectorHandle(m_CurrentLod)->data()[pCurrentGroup->trianglesGroupOffseti().at(i)]; - glDrawElements(GL_TRIANGLES, pCurrentGroup->trianglesIndexSizes().at(i), GL_UNSIGNED_INT, pOffset); - } - - GLvoid* pOffset= &(m_MeshData.indexVectorHandle(m_CurrentLod)->data()[pCurrentGroup->trianglesIndexOffseti()]); - glDrawElements(GL_TRIANGLES, pCurrentGroup->trianglesIndexSize(), GL_UNSIGNED_INT, pOffset); - } - - // Draw Triangles strip - if (pCurrentGroup->containsStripGroupId()) - { - const GLsizei stripsCount= static_cast(pCurrentGroup->stripsOffseti().size()); - for (GLint i= 0; i < stripsCount; ++i) - { - glc::encodeRgbId(pCurrentGroup->stripGroupId(i), colorId); - glColor3ubv(colorId); - - GLvoid* pOffset= &m_MeshData.indexVectorHandle(m_CurrentLod)->data()[pCurrentGroup->stripsOffseti().at(i)]; - glDrawElements(GL_TRIANGLE_STRIP, pCurrentGroup->stripsSizes().at(i), GL_UNSIGNED_INT, pOffset); - } - } - - // Draw Triangles fan - if (pCurrentGroup->containsFanGroupId()) - { - const GLsizei fansCount= static_cast(pCurrentGroup->fansOffseti().size()); - for (GLint i= 0; i < fansCount; ++i) - { - glc::encodeRgbId(pCurrentGroup->fanGroupId(i), colorId); - glColor3ubv(colorId); - - GLvoid* pOffset= &m_MeshData.indexVectorHandle(m_CurrentLod)->data()[pCurrentGroup->fansOffseti().at(i)]; - glDrawElements(GL_TRIANGLE_FAN, pCurrentGroup->fansSizes().at(i), GL_UNSIGNED_INT, pOffset); - } - } -} - -// Use VBO to Draw primitives with specific materials from the specified GLC_PrimitiveGroup -void GLC_Mesh::vboDrawPrimitivesGroupOf(GLC_PrimitiveGroup* pCurrentGroup, GLC_Material* pCurrentMaterial, bool materialIsRenderable - , bool isTransparent, QHash* pMaterialHash) -{ - GLC_Material* pCurrentLocalMaterial= pCurrentMaterial; - // Draw triangles - if (pCurrentGroup->containsTriangles()) - { - Q_ASSERT(pCurrentGroup->containsTrianglesGroupId()); - const GLsizei trianglesGroupCount= static_cast(pCurrentGroup->trianglesGroupOffset().size()); - for (GLint i= 0; i < trianglesGroupCount; ++i) - { - GLC_uint currentPrimitiveId= pCurrentGroup->triangleGroupId(i); - if (pMaterialHash->contains(currentPrimitiveId)) - { - if (pCurrentLocalMaterial != pMaterialHash->value(currentPrimitiveId)) - { - pCurrentLocalMaterial= pMaterialHash->value(currentPrimitiveId); - if (pCurrentLocalMaterial->isTransparent() == isTransparent) pCurrentLocalMaterial->glExecute(); - } - } - else if (pCurrentLocalMaterial != pCurrentMaterial) - { - pCurrentLocalMaterial= pCurrentMaterial; - if (materialIsRenderable) pCurrentLocalMaterial->glExecute(); - } - if (pCurrentLocalMaterial->isTransparent() == isTransparent) - { - glDrawElements(GL_TRIANGLES, pCurrentGroup->trianglesIndexSizes().at(i), GL_UNSIGNED_INT, pCurrentGroup->trianglesGroupOffset().at(i)); - } - } - } - - // Draw Triangles strip - if (pCurrentGroup->containsStrip()) - { - Q_ASSERT(pCurrentGroup->containsStripGroupId()); - const GLsizei stripsCount= static_cast(pCurrentGroup->stripsOffset().size()); - for (GLint i= 0; i < stripsCount; ++i) - { - GLC_uint currentPrimitiveId= pCurrentGroup->stripGroupId(i); - if (pMaterialHash->contains(currentPrimitiveId)) - { - if (pCurrentLocalMaterial != pMaterialHash->value(currentPrimitiveId)) - { - pCurrentLocalMaterial= pMaterialHash->value(currentPrimitiveId); - if (pCurrentLocalMaterial->isTransparent() == isTransparent) pCurrentLocalMaterial->glExecute(); - } - } - else if (pCurrentLocalMaterial != pCurrentMaterial) - { - pCurrentLocalMaterial= pCurrentMaterial; - if (materialIsRenderable) pCurrentLocalMaterial->glExecute(); - } - if (pCurrentLocalMaterial->isTransparent() == isTransparent) - { - glDrawElements(GL_TRIANGLE_STRIP, pCurrentGroup->stripsSizes().at(i), GL_UNSIGNED_INT, pCurrentGroup->stripsOffset().at(i)); - } - } - } - - // Draw Triangles fan - if (pCurrentGroup->containsFan()) - { - Q_ASSERT(pCurrentGroup->containsFanGroupId()); - const GLsizei fansCount= static_cast(pCurrentGroup->fansOffset().size()); - for (GLint i= 0; i < fansCount; ++i) - { - GLC_uint currentPrimitiveId= pCurrentGroup->fanGroupId(i); - if (pMaterialHash->contains(currentPrimitiveId)) - { - if (pCurrentLocalMaterial != pMaterialHash->value(currentPrimitiveId)) - { - pCurrentLocalMaterial= pMaterialHash->value(currentPrimitiveId); - if (pCurrentLocalMaterial->isTransparent() == isTransparent) pCurrentLocalMaterial->glExecute(); - } - } - else if (pCurrentLocalMaterial != pCurrentMaterial) - { - pCurrentLocalMaterial= pCurrentMaterial; - if (materialIsRenderable) pCurrentLocalMaterial->glExecute(); - } - if (pCurrentLocalMaterial->isTransparent() == isTransparent) - { - glDrawElements(GL_TRIANGLE_FAN, pCurrentGroup->fansSizes().at(i), GL_UNSIGNED_INT, pCurrentGroup->fansOffset().at(i)); - } - } - } - -} - -// Use Vertex Array to Draw primitives with specific materials from the specified GLC_PrimitiveGroup -void GLC_Mesh::vertexArrayDrawPrimitivesGroupOf(GLC_PrimitiveGroup* pCurrentGroup, GLC_Material* pCurrentMaterial, bool materialIsRenderable - , bool isTransparent, QHash* pMaterialHash) -{ - GLC_Material* pCurrentLocalMaterial= pCurrentMaterial; - // Draw triangles - if (pCurrentGroup->containsTriangles()) - { - Q_ASSERT(pCurrentGroup->containsTrianglesGroupId()); - const GLsizei trianglesGroupCount= static_cast(pCurrentGroup->trianglesGroupOffseti().size()); - for (GLint i= 0; i < trianglesGroupCount; ++i) - { - GLC_uint currentPrimitiveId= pCurrentGroup->triangleGroupId(i); - if (pMaterialHash->contains(currentPrimitiveId)) - { - if (pCurrentLocalMaterial != pMaterialHash->value(currentPrimitiveId)) - { - pCurrentLocalMaterial= pMaterialHash->value(currentPrimitiveId); - if (pCurrentLocalMaterial->isTransparent() == isTransparent) pCurrentLocalMaterial->glExecute(); - } - } - else if (pCurrentLocalMaterial != pCurrentMaterial) - { - pCurrentLocalMaterial= pCurrentMaterial; - if (materialIsRenderable) pCurrentLocalMaterial->glExecute(); - } - if (pCurrentLocalMaterial->isTransparent() == isTransparent) - { - GLvoid* pOffset= &m_MeshData.indexVectorHandle(m_CurrentLod)->data()[pCurrentGroup->trianglesGroupOffseti().at(i)]; - glDrawElements(GL_TRIANGLES, pCurrentGroup->trianglesIndexSizes().at(i), GL_UNSIGNED_INT, pOffset); - } - } - } - - // Draw Triangles strip - if (pCurrentGroup->containsStrip()) - { - Q_ASSERT(pCurrentGroup->containsStripGroupId()); - const GLsizei stripsCount= static_cast(pCurrentGroup->stripsOffseti().size()); - for (GLint i= 0; i < stripsCount; ++i) - { - GLC_uint currentPrimitiveId= pCurrentGroup->stripGroupId(i); - if (pMaterialHash->contains(currentPrimitiveId)) - { - if (pCurrentLocalMaterial != pMaterialHash->value(currentPrimitiveId)) - { - pCurrentLocalMaterial= pMaterialHash->value(currentPrimitiveId); - if (pCurrentLocalMaterial->isTransparent() == isTransparent) pCurrentLocalMaterial->glExecute(); - } - } - else if (pCurrentLocalMaterial != pCurrentMaterial) - { - pCurrentLocalMaterial= pCurrentMaterial; - if (materialIsRenderable) pCurrentLocalMaterial->glExecute(); - } - if (pCurrentLocalMaterial->isTransparent() == isTransparent) - { - GLvoid* pOffset= &m_MeshData.indexVectorHandle(m_CurrentLod)->data()[pCurrentGroup->stripsOffseti().at(i)]; - glDrawElements(GL_TRIANGLE_STRIP, pCurrentGroup->stripsSizes().at(i), GL_UNSIGNED_INT, pOffset); - } - } - } - - // Draw Triangles fan - if (pCurrentGroup->containsFan()) - { - Q_ASSERT(pCurrentGroup->containsFanGroupId()); - const GLsizei fansCount= static_cast(pCurrentGroup->fansOffseti().size()); - for (GLint i= 0; i < fansCount; ++i) - { - GLC_uint currentPrimitiveId= pCurrentGroup->fanGroupId(i); - if (pMaterialHash->contains(currentPrimitiveId)) - { - if (pCurrentLocalMaterial != pMaterialHash->value(currentPrimitiveId)) - { - pCurrentLocalMaterial= pMaterialHash->value(currentPrimitiveId); - if (pCurrentLocalMaterial->isTransparent() == isTransparent) pCurrentLocalMaterial->glExecute(); - } - } - else if (pCurrentLocalMaterial != pCurrentMaterial) - { - pCurrentLocalMaterial= pCurrentMaterial; - if (materialIsRenderable) pCurrentLocalMaterial->glExecute(); - } - if (pCurrentLocalMaterial->isTransparent() == isTransparent) - { - GLvoid* pOffset= &m_MeshData.indexVectorHandle(m_CurrentLod)->data()[pCurrentGroup->fansOffseti().at(i)]; - glDrawElements(GL_TRIANGLE_FAN, pCurrentGroup->fansSizes().at(i), GL_UNSIGNED_INT, pOffset); - } - } - } - -} - -// Use VBO to Draw primitives with specific materials from the specified GLC_PrimitiveGroup -void GLC_Mesh::vboDrawSelectedPrimitivesGroupOf(GLC_PrimitiveGroup* pCurrentGroup, GLC_Material* pCurrentMaterial, bool materialIsRenderable - , bool isTransparent, const GLC_RenderProperties& renderProperties) -{ - QSet* pSelectedPrimitive= renderProperties.setOfSelectedPrimitivesId(); - Q_ASSERT(NULL != pSelectedPrimitive); - - QHash* pMaterialHash= NULL; - if (!renderProperties.hashOfOverwritePrimitiveMaterialsIsEmpty()) - { - pMaterialHash= renderProperties.hashOfOverwritePrimitiveMaterials(); - } - - GLC_Material* pCurrentLocalMaterial= pCurrentMaterial; - // Draw triangles - if (pCurrentGroup->containsTriangles()) - { - Q_ASSERT(pCurrentGroup->containsTrianglesGroupId()); - const GLsizei trianglesGroupCount= static_cast(pCurrentGroup->trianglesGroupOffset().size()); - for (GLint i= 0; i < trianglesGroupCount; ++i) - { - GLC_uint currentPrimitiveId= pCurrentGroup->triangleGroupId(i); - if (pSelectedPrimitive->contains(currentPrimitiveId)) - { - if (!isTransparent) - { - GLC_SelectionMaterial::glExecute(); - pCurrentLocalMaterial= NULL; - glDrawElements(GL_TRIANGLES, pCurrentGroup->trianglesIndexSizes().at(i), GL_UNSIGNED_INT, pCurrentGroup->trianglesGroupOffset().at(i)); - } - } - else if ((NULL != pMaterialHash) && pMaterialHash->contains(currentPrimitiveId)) - { - if (pMaterialHash->value(currentPrimitiveId)->isTransparent() == isTransparent) - { - GLC_Material* pMat= pMaterialHash->value(currentPrimitiveId); - if (pMat != pCurrentLocalMaterial) - { - pCurrentLocalMaterial= pMat; - pCurrentLocalMaterial->glExecute(); - } - glDrawElements(GL_TRIANGLES, pCurrentGroup->trianglesIndexSizes().at(i), GL_UNSIGNED_INT, pCurrentGroup->trianglesGroupOffset().at(i)); - } - - } - else if (materialIsRenderable) - { - if (pCurrentLocalMaterial != pCurrentMaterial) - { - pCurrentLocalMaterial= pCurrentMaterial; - pCurrentLocalMaterial->glExecute(); - } - glDrawElements(GL_TRIANGLES, pCurrentGroup->trianglesIndexSizes().at(i), GL_UNSIGNED_INT, pCurrentGroup->trianglesGroupOffset().at(i)); - } - } - } - - // Draw Triangles strip - if (pCurrentGroup->containsStrip()) - { - Q_ASSERT(pCurrentGroup->containsStripGroupId()); - const GLsizei stripsCount= static_cast(pCurrentGroup->stripsOffset().size()); - for (GLint i= 0; i < stripsCount; ++i) - { - GLC_uint currentPrimitiveId= pCurrentGroup->stripGroupId(i); - if (pSelectedPrimitive->contains(currentPrimitiveId)) - { - if (!isTransparent) - { - GLC_SelectionMaterial::glExecute(); - pCurrentLocalMaterial= NULL; - glDrawElements(GL_TRIANGLE_STRIP, pCurrentGroup->stripsSizes().at(i), GL_UNSIGNED_INT, pCurrentGroup->stripsOffset().at(i)); - } - } - else if ((NULL != pMaterialHash) && pMaterialHash->contains(currentPrimitiveId)) - { - if (pMaterialHash->value(currentPrimitiveId)->isTransparent() == isTransparent) - { - GLC_Material* pMat= pMaterialHash->value(currentPrimitiveId); - if (pMat != pCurrentLocalMaterial) - { - pCurrentLocalMaterial= pMat; - pCurrentLocalMaterial->glExecute(); - } - glDrawElements(GL_TRIANGLE_STRIP, pCurrentGroup->stripsSizes().at(i), GL_UNSIGNED_INT, pCurrentGroup->stripsOffset().at(i)); - } - - } - else if (materialIsRenderable) - { - if (pCurrentLocalMaterial != pCurrentMaterial) - { - pCurrentLocalMaterial= pCurrentMaterial; - pCurrentLocalMaterial->glExecute(); - } - glDrawElements(GL_TRIANGLE_STRIP, pCurrentGroup->stripsSizes().at(i), GL_UNSIGNED_INT, pCurrentGroup->stripsOffset().at(i)); - } - } - } - - // Draw Triangles fan - if (pCurrentGroup->containsFan()) - { - Q_ASSERT(pCurrentGroup->containsFanGroupId()); - const GLsizei fansCount= static_cast(pCurrentGroup->fansOffset().size()); - for (GLint i= 0; i < fansCount; ++i) - { - GLC_uint currentPrimitiveId= pCurrentGroup->fanGroupId(i); - if (pSelectedPrimitive->contains(currentPrimitiveId)) - { - if (!isTransparent) - { - GLC_SelectionMaterial::glExecute(); - pCurrentLocalMaterial= NULL; - glDrawElements(GL_TRIANGLE_FAN, pCurrentGroup->fansSizes().at(i), GL_UNSIGNED_INT, pCurrentGroup->fansOffset().at(i)); - } - } - else if ((NULL != pMaterialHash) && pMaterialHash->contains(currentPrimitiveId)) - { - if (pMaterialHash->value(currentPrimitiveId)->isTransparent() == isTransparent) - { - GLC_Material* pMat= pMaterialHash->value(currentPrimitiveId); - if (pMat != pCurrentLocalMaterial) - { - pCurrentLocalMaterial= pMat; - pCurrentLocalMaterial->glExecute(); - } - glDrawElements(GL_TRIANGLE_FAN, pCurrentGroup->fansSizes().at(i), GL_UNSIGNED_INT, pCurrentGroup->fansOffset().at(i)); - } - - } - else if (materialIsRenderable) - { - if (pCurrentLocalMaterial != pCurrentMaterial) - { - pCurrentLocalMaterial= pCurrentMaterial; - pCurrentLocalMaterial->glExecute(); - } - glDrawElements(GL_TRIANGLE_FAN, pCurrentGroup->fansSizes().at(i), GL_UNSIGNED_INT, pCurrentGroup->fansOffset().at(i)); - } - } - } - -} - -// Use Vertex Array to Draw primitives with specific materials from the specified GLC_PrimitiveGroup -void GLC_Mesh::vertexArrayDrawSelectedPrimitivesGroupOf(GLC_PrimitiveGroup* pCurrentGroup, GLC_Material* pCurrentMaterial, bool materialIsRenderable - , bool isTransparent, const GLC_RenderProperties& renderProperties) -{ - QSet* pSelectedPrimitive= renderProperties.setOfSelectedPrimitivesId(); - Q_ASSERT(NULL != pSelectedPrimitive); - - QHash* pMaterialHash= NULL; - if (!renderProperties.hashOfOverwritePrimitiveMaterialsIsEmpty()) - { - pMaterialHash= renderProperties.hashOfOverwritePrimitiveMaterials(); - } - - GLC_Material* pCurrentLocalMaterial= pCurrentMaterial; - // Draw triangles - if (pCurrentGroup->containsTriangles()) - { - Q_ASSERT(pCurrentGroup->containsTrianglesGroupId()); - const GLsizei trianglesGroupCount= static_cast(pCurrentGroup->trianglesGroupOffseti().size()); - for (GLint i= 0; i < trianglesGroupCount; ++i) - { - GLC_uint currentPrimitiveId= pCurrentGroup->triangleGroupId(i); - if (pSelectedPrimitive->contains(currentPrimitiveId)) - { - if (!isTransparent) - { - GLC_SelectionMaterial::glExecute(); - pCurrentLocalMaterial= NULL; - GLvoid* pOffset= &m_MeshData.indexVectorHandle(m_CurrentLod)->data()[pCurrentGroup->trianglesGroupOffseti().at(i)]; - glDrawElements(GL_TRIANGLES, pCurrentGroup->trianglesIndexSizes().at(i), GL_UNSIGNED_INT, pOffset); - } - } - else if ((NULL != pMaterialHash) && pMaterialHash->contains(currentPrimitiveId)) - { - if (pMaterialHash->value(currentPrimitiveId)->isTransparent() == isTransparent) - { - GLC_Material* pMat= pMaterialHash->value(currentPrimitiveId); - if (pMat != pCurrentLocalMaterial) - { - pCurrentLocalMaterial= pMat; - pCurrentLocalMaterial->glExecute(); - } - GLvoid* pOffset= &m_MeshData.indexVectorHandle(m_CurrentLod)->data()[pCurrentGroup->trianglesGroupOffseti().at(i)]; - glDrawElements(GL_TRIANGLES, pCurrentGroup->trianglesIndexSizes().at(i), GL_UNSIGNED_INT, pOffset); - } - - } - else if (materialIsRenderable) - { - if (pCurrentLocalMaterial != pCurrentMaterial) - { - pCurrentLocalMaterial= pCurrentMaterial; - pCurrentLocalMaterial->glExecute(); - } - GLvoid* pOffset= &m_MeshData.indexVectorHandle(m_CurrentLod)->data()[pCurrentGroup->trianglesGroupOffseti().at(i)]; - glDrawElements(GL_TRIANGLES, pCurrentGroup->trianglesIndexSizes().at(i), GL_UNSIGNED_INT, pOffset); - } - } - } - - // Draw Triangles strip - if (pCurrentGroup->containsStrip()) - { - Q_ASSERT(pCurrentGroup->containsStripGroupId()); - const GLsizei stripsCount= static_cast(pCurrentGroup->stripsOffseti().size()); - for (GLint i= 0; i < stripsCount; ++i) - { - GLC_uint currentPrimitiveId= pCurrentGroup->stripGroupId(i); - if (pSelectedPrimitive->contains(currentPrimitiveId)) - { - if (!isTransparent) - { - GLC_SelectionMaterial::glExecute(); - pCurrentLocalMaterial= NULL; - GLvoid* pOffset= &m_MeshData.indexVectorHandle(m_CurrentLod)->data()[pCurrentGroup->stripsOffseti().at(i)]; - glDrawElements(GL_TRIANGLE_STRIP, pCurrentGroup->stripsSizes().at(i), GL_UNSIGNED_INT, pOffset); - } - } - else if ((NULL != pMaterialHash) && pMaterialHash->contains(currentPrimitiveId)) - { - if (pMaterialHash->value(currentPrimitiveId)->isTransparent() == isTransparent) - { - GLC_Material* pMat= pMaterialHash->value(currentPrimitiveId); - if (pMat != pCurrentLocalMaterial) - { - pCurrentLocalMaterial= pMat; - pCurrentLocalMaterial->glExecute(); - } - GLvoid* pOffset= &m_MeshData.indexVectorHandle(m_CurrentLod)->data()[pCurrentGroup->stripsOffseti().at(i)]; - glDrawElements(GL_TRIANGLE_STRIP, pCurrentGroup->stripsSizes().at(i), GL_UNSIGNED_INT, pOffset); - } - - } - else if (materialIsRenderable) - { - if (pCurrentLocalMaterial != pCurrentMaterial) - { - pCurrentLocalMaterial= pCurrentMaterial; - pCurrentLocalMaterial->glExecute(); - } - GLvoid* pOffset= &m_MeshData.indexVectorHandle(m_CurrentLod)->data()[pCurrentGroup->stripsOffseti().at(i)]; - glDrawElements(GL_TRIANGLE_STRIP, pCurrentGroup->stripsSizes().at(i), GL_UNSIGNED_INT, pOffset); - } - } - } - - // Draw Triangles fan - if (pCurrentGroup->containsFan()) - { - Q_ASSERT(pCurrentGroup->containsFanGroupId()); - const GLsizei fansCount= static_cast(pCurrentGroup->fansOffseti().size()); - for (GLint i= 0; i < fansCount; ++i) - { - GLC_uint currentPrimitiveId= pCurrentGroup->fanGroupId(i); - if (pSelectedPrimitive->contains(currentPrimitiveId)) - { - if (!isTransparent) - { - GLC_SelectionMaterial::glExecute(); - pCurrentLocalMaterial= NULL; - GLvoid* pOffset= &m_MeshData.indexVectorHandle(m_CurrentLod)->data()[pCurrentGroup->fansOffseti().at(i)]; - glDrawElements(GL_TRIANGLE_FAN, pCurrentGroup->fansSizes().at(i), GL_UNSIGNED_INT, pOffset); - } - } - else if ((NULL != pMaterialHash) && pMaterialHash->contains(currentPrimitiveId)) - { - if (pMaterialHash->value(currentPrimitiveId)->isTransparent() == isTransparent) - { - GLC_Material* pMat= pMaterialHash->value(currentPrimitiveId); - if (pMat != pCurrentLocalMaterial) - { - pCurrentLocalMaterial= pMat; - pCurrentLocalMaterial->glExecute(); - } - GLvoid* pOffset= &m_MeshData.indexVectorHandle(m_CurrentLod)->data()[pCurrentGroup->fansOffseti().at(i)]; - glDrawElements(GL_TRIANGLE_FAN, pCurrentGroup->fansSizes().at(i), GL_UNSIGNED_INT, pOffset); - } - - } - else if (materialIsRenderable) - { - if (pCurrentLocalMaterial != pCurrentMaterial) - { - pCurrentLocalMaterial= pCurrentMaterial; - pCurrentLocalMaterial->glExecute(); - } - GLvoid* pOffset= &m_MeshData.indexVectorHandle(m_CurrentLod)->data()[pCurrentGroup->fansOffseti().at(i)]; - glDrawElements(GL_TRIANGLE_FAN, pCurrentGroup->fansSizes().at(i), GL_UNSIGNED_INT, pOffset); - } - } - } - -} - -// Activate mesh VBOs and IBO of the current LOD -void GLC_Mesh::activateVboAndIbo() -{ - // Activate Vertices VBO - m_MeshData.useVBO(true, GLC_MeshData::GLC_Vertex); - glVertexPointer(3, GL_FLOAT, 0, 0); - glEnableClientState(GL_VERTEX_ARRAY); - - // Activate Normals VBO - m_MeshData.useVBO(true, GLC_MeshData::GLC_Normal); - glNormalPointer(GL_FLOAT, 0, 0); - glEnableClientState(GL_NORMAL_ARRAY); - - // Activate texel VBO if needed - if (m_MeshData.useVBO(true, GLC_MeshData::GLC_Texel)) - { - glTexCoordPointer(2, GL_FLOAT, 0, 0); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - } - - // Activate Color VBO if needed - if ((m_ColorPearVertex && !m_IsSelected && !GLC_State::isInSelectionMode()) && m_MeshData.useVBO(true, GLC_MeshData::GLC_Color)) - { - glEnable(GL_COLOR_MATERIAL); - glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); - glColorPointer(4, GL_FLOAT, 0, 0); - glEnableClientState(GL_COLOR_ARRAY); - } - - m_MeshData.useIBO(true, m_CurrentLod); -} - -// Activate vertex Array -void GLC_Mesh::activateVertexArray() -{ - // Use Vertex Array - glVertexPointer(3, GL_FLOAT, 0, m_MeshData.positionVectorHandle()->data()); - glEnableClientState(GL_VERTEX_ARRAY); - - glNormalPointer(GL_FLOAT, 0, m_MeshData.normalVectorHandle()->data()); - glEnableClientState(GL_NORMAL_ARRAY); - - // Activate texel if needed - if (!m_MeshData.texelVectorHandle()->isEmpty()) - { - glTexCoordPointer(2, GL_FLOAT, 0, m_MeshData.texelVectorHandle()->data()); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - } - - // Activate Color array if needed - if ((m_ColorPearVertex && !m_IsSelected && !GLC_State::isInSelectionMode()) && !m_MeshData.colorVectorHandle()->isEmpty()) - { - glEnable(GL_COLOR_MATERIAL); - glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); - glColorPointer(4, GL_FLOAT, 0, m_MeshData.colorVectorHandle()->data()); - glEnableClientState(GL_COLOR_ARRAY); - } -} - - - -#endif /* GLC_MESH_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_meshdata.cpp b/ground/gcs/src/libs/glc_lib/geometry/glc_meshdata.cpp deleted file mode 100644 index 2c96c1a74..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_meshdata.cpp +++ /dev/null @@ -1,550 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_meshdata.cpp Implementation for the GLC_MeshData class. - -#include "../glc_exception.h" -#include "glc_meshdata.h" -#include "../glc_state.h" - -// Class chunk id -quint32 GLC_MeshData::m_ChunkId= 0xA704; - -// Default constructor -GLC_MeshData::GLC_MeshData() -: m_VertexBuffer() -, m_Positions() -, m_Normals() -, m_Texels() -, m_Colors() -, m_NormalBuffer() -, m_TexelBuffer() -, m_ColorBuffer() -, m_LodList() -, m_PositionSize(-1) -, m_TexelsSize(-1) -, m_ColorSize(-1) -, m_UseVbo(false) -{ - -} - -// Copy constructor -GLC_MeshData::GLC_MeshData(const GLC_MeshData& meshData) -: m_VertexBuffer() -, m_Positions(meshData.positionVector()) -, m_Normals(meshData.normalVector()) -, m_Texels(meshData.texelVector()) -, m_Colors(meshData.colorVector()) -, m_NormalBuffer() -, m_TexelBuffer() -, m_ColorBuffer() -, m_LodList() -, m_PositionSize(meshData.m_PositionSize) -, m_TexelsSize(meshData.m_TexelsSize) -, m_ColorSize(meshData.m_ColorSize) -, m_UseVbo(meshData.m_UseVbo) -{ - // Copy meshData LOD list - const int size= meshData.m_LodList.size(); - for (int i= 0; i < size; ++i) - { - m_LodList.append(new GLC_Lod(*meshData.m_LodList.at(i))); - } -} - -// Overload "=" operator -GLC_MeshData& GLC_MeshData::operator=(const GLC_MeshData& meshData) -{ - if (this != &meshData) - { - // Clear the content of the mesh Data - clear(); - - // Copy mesh Data members - m_Positions= meshData.positionVector(); - m_Normals= meshData.normalVector(); - m_Texels= meshData.texelVector(); - m_Colors= meshData.colorVector(); - m_PositionSize= meshData.m_PositionSize; - m_TexelsSize= meshData.m_TexelsSize; - m_ColorSize= meshData.m_ColorSize; - m_UseVbo= meshData.m_UseVbo; - - // Copy meshData LOD list - const int size= meshData.m_LodList.size(); - for (int i= 0; i < size; ++i) - { - m_LodList.append(new GLC_Lod(*meshData.m_LodList.at(i))); - } - } - return *this; -} - -GLC_MeshData::~GLC_MeshData() -{ - clear(); -} -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// -// Return the class Chunk ID -quint32 GLC_MeshData::chunckID() -{ - return m_ChunkId; -} - -// Return the Position Vector -GLfloatVector GLC_MeshData::positionVector() const -{ - if (m_VertexBuffer.isCreated()) - { - // VBO created get data from VBO - const int sizeOfVbo= m_PositionSize; - const GLsizeiptr dataSize= sizeOfVbo * sizeof(float); - GLfloatVector positionVector(sizeOfVbo); - - if (!const_cast(m_VertexBuffer).bind()) - { - GLC_Exception exception("GLC_MeshData::positionVector() Failed to bind vertex buffer"); - throw(exception); - } - GLvoid* pVbo = const_cast(m_VertexBuffer).map(QGLBuffer::ReadOnly); - memcpy(positionVector.data(), pVbo, dataSize); - const_cast(m_VertexBuffer).unmap(); - const_cast(m_VertexBuffer).release(); - return positionVector; - } - else - { - return m_Positions; - } -} - -// Return the normal Vector -GLfloatVector GLC_MeshData::normalVector() const -{ - if (m_NormalBuffer.isCreated()) - { - // VBO created get data from VBO - const int sizeOfVbo= m_PositionSize; - const GLsizeiptr dataSize= sizeOfVbo * sizeof(GLfloat); - GLfloatVector normalVector(sizeOfVbo); - - const_cast(m_NormalBuffer).bind(); - GLvoid* pVbo = const_cast(m_NormalBuffer).map(QGLBuffer::ReadOnly); - memcpy(normalVector.data(), pVbo, dataSize); - const_cast(m_NormalBuffer).unmap(); - const_cast(m_NormalBuffer).release(); - return normalVector; - } - else - { - return m_Normals; - } -} - -// Return the texel Vector -GLfloatVector GLC_MeshData::texelVector() const -{ - if (m_TexelBuffer.isCreated()) - { - // VBO created get data from VBO - const int sizeOfVbo= m_TexelsSize; - const GLsizeiptr dataSize= sizeOfVbo * sizeof(GLfloat); - GLfloatVector texelVector(sizeOfVbo); - - const_cast(m_TexelBuffer).bind(); - GLvoid* pVbo = const_cast(m_TexelBuffer).map(QGLBuffer::ReadOnly); - memcpy(texelVector.data(), pVbo, dataSize); - const_cast(m_TexelBuffer).unmap(); - const_cast(m_TexelBuffer).release(); - return texelVector; - } - else - { - return m_Texels; - } -} - -// Return the color Vector -GLfloatVector GLC_MeshData::colorVector() const -{ - if (m_ColorBuffer.isCreated()) - { - // VBO created get data from VBO - const int sizeOfVbo= m_ColorSize; - const GLsizeiptr dataSize= sizeOfVbo * sizeof(GLfloat); - GLfloatVector normalVector(sizeOfVbo); - - const_cast(m_ColorBuffer).bind(); - GLvoid* pVbo = const_cast(m_ColorBuffer).map(QGLBuffer::ReadOnly); - memcpy(normalVector.data(), pVbo, dataSize); - const_cast(m_ColorBuffer).unmap(); - const_cast(m_ColorBuffer).release(); - return normalVector; - } - else - { - return m_Colors; - } -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -// If the there is more than 2 LOD Swap the first and last -void GLC_MeshData::finishLod() -{ - // PLace the master LOD at the beginning of the list - const int size= m_LodList.size(); - if (size > 1) - { - GLC_Lod* PMasterLod= m_LodList.at(size - 1); - m_LodList.removeAt(size - 1); - m_LodList.prepend(PMasterLod); - } -} - -// Clear the content of the meshData and makes it empty -void GLC_MeshData::clear() -{ - m_Positions.clear(); - m_Normals.clear(); - m_Texels.clear(); - m_Colors.clear(); - m_PositionSize= -1; - m_TexelsSize= -1; - m_ColorSize= -1; - - // Delete Main Vbo ID - if (m_VertexBuffer.isCreated()) - { - m_VertexBuffer.destroy(); - } - - // Delete Normal VBO - if (m_NormalBuffer.isCreated()) - { - m_NormalBuffer.destroy(); - } - - // Delete Texel VBO - if (m_TexelBuffer.isCreated()) - { - m_TexelBuffer.destroy(); - } - // Delete color index - if (m_ColorBuffer.isCreated()) - { - m_ColorBuffer.destroy(); - } - - const int size= m_LodList.size(); - for (int i= 0; i < size; ++i) - { - delete m_LodList.at(i); - } - m_LodList.clear(); -} - -void GLC_MeshData::copyVboToClientSide() -{ - - if (m_VertexBuffer.isCreated() && m_Positions.isEmpty()) - { - Q_ASSERT(m_NormalBuffer.isCreated()); - m_Positions= positionVector(); - m_Normals= normalVector(); - if (m_TexelBuffer.isCreated()) - { - m_Texels= texelVector(); - } - if (m_ColorBuffer.isCreated()) - { - m_Colors= colorVector(); - } - } -} - -void GLC_MeshData::releaseVboClientSide(bool update) -{ - if (m_VertexBuffer.isCreated() && !m_Positions.isEmpty()) - { - if (update) - { - fillVbo(GLC_MeshData::GLC_Vertex); - fillVbo(GLC_MeshData::GLC_Normal); - fillVbo(GLC_MeshData::GLC_Texel); - fillVbo(GLC_MeshData::GLC_Color); - useVBO(false, GLC_MeshData::GLC_Color); - } - m_PositionSize= m_Positions.size(); - m_Positions.clear(); - m_Normals.clear(); - m_TexelsSize= m_Texels.size(); - m_Texels.clear(); - m_ColorSize= m_Colors.size(); - m_Colors.clear(); - } -} - -void GLC_MeshData::setVboUsage(bool usage) -{ - if (usage && (m_PositionSize != -1) && (!m_Positions.isEmpty()) && (!m_VertexBuffer.isCreated())) - { - createVBOs(); - - fillVbo(GLC_MeshData::GLC_Vertex); - fillVbo(GLC_MeshData::GLC_Normal); - fillVbo(GLC_MeshData::GLC_Texel); - fillVbo(GLC_MeshData::GLC_Color); - useVBO(false, GLC_MeshData::GLC_Color); - - const int lodCount= m_LodList.count(); - for (int i= 0; i < lodCount; ++i) - { - m_LodList.at(i)->setIboUsage(usage); - } - - } - else if (!usage && m_VertexBuffer.isCreated()) - { - m_Positions= positionVector(); - m_PositionSize= m_Positions.size(); - m_VertexBuffer.destroy(); - - m_Normals= normalVector(); - m_NormalBuffer.destroy(); - - if (m_TexelBuffer.isCreated()) - { - m_Texels= texelVector(); - m_TexelsSize= m_Texels.size(); - m_TexelBuffer.destroy(); - } - if (m_ColorBuffer.isCreated()) - { - m_Colors= colorVector(); - m_ColorSize= m_Colors.size(); - m_ColorBuffer.destroy(); - } - - const int lodCount= m_LodList.count(); - for (int i= 0; i < lodCount; ++i) - { - m_LodList.at(i)->setIboUsage(usage); - } - } - m_UseVbo= usage; - -} - -////////////////////////////////////////////////////////////////////// -// OpenGL Functions -////////////////////////////////////////////////////////////////////// -// Vbo creation -void GLC_MeshData::createVBOs() -{ - - // Create position VBO - if (!m_VertexBuffer.isCreated()) - { - Q_ASSERT((NULL != QGLContext::currentContext()) && QGLContext::currentContext()->isValid()); - - m_VertexBuffer.create(); - m_NormalBuffer.create(); - - // Create Texel VBO - if (!m_TexelBuffer.isCreated() && !m_Texels.isEmpty()) - { - m_TexelBuffer.create(); - } - - // Create Color VBO - if (!m_ColorBuffer.isCreated() && !m_Colors.isEmpty()) - { - m_ColorBuffer.create(); - } - - const int size= m_LodList.size(); - for (int i= 0; i < size; ++i) - { - m_LodList.at(i)->createIBO(); - } - } -} - -// Ibo Usage -bool GLC_MeshData::useVBO(bool use, GLC_MeshData::VboType type) -{ - bool result= true; - if (use) - { - // Chose the right VBO - if (type == GLC_MeshData::GLC_Vertex) - { - if (!m_VertexBuffer.bind()) - { - GLC_Exception exception("GLC_MeshData::useVBO Failed to bind vertex buffer"); - throw(exception); - } - } - else if (type == GLC_MeshData::GLC_Normal) - { - if (!m_NormalBuffer.bind()) - { - GLC_Exception exception("GLC_MeshData::useVBO Failed to bind normal buffer"); - throw(exception); - } - } - else if ((type == GLC_MeshData::GLC_Texel) && m_TexelBuffer.isCreated()) - { - if (!m_TexelBuffer.bind()) - { - GLC_Exception exception("GLC_MeshData::useVBO Failed to bind texel buffer"); - throw(exception); - } - } - else if ((type == GLC_MeshData::GLC_Color) && m_ColorBuffer.isCreated()) - { - if (!m_ColorBuffer.bind()) - { - GLC_Exception exception("GLC_MeshData::useVBO Failed to bind color buffer"); - throw(exception); - } - } - - else result= false; - } - else - { - // Unbind VBO - QGLBuffer::release(QGLBuffer::VertexBuffer); - } - return result; -} - -void GLC_MeshData::fillVbo(GLC_MeshData::VboType type) -{ - // Chose the right VBO - if (type == GLC_MeshData::GLC_Vertex) - { - useVBO(true, type); - const GLsizei dataNbr= static_cast(m_Positions.size()); - const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat); - m_VertexBuffer.allocate(m_Positions.data(), dataSize); - - m_PositionSize= m_Positions.size(); - m_Positions.clear(); - } - else if (type == GLC_MeshData::GLC_Normal) - { - useVBO(true, type); - const GLsizei dataNbr= static_cast(m_Normals.size()); - const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat); - m_NormalBuffer.allocate(m_Normals.data(), dataSize); - - m_Normals.clear(); - } - else if ((type == GLC_MeshData::GLC_Texel) && m_TexelBuffer.isCreated()) - { - useVBO(true, type); - const GLsizei dataNbr= static_cast(m_Texels.size()); - const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat); - m_TexelBuffer.allocate(m_Texels.data(), dataSize); - - m_TexelsSize= m_Texels.size(); - m_Texels.clear(); - } - else if ((type == GLC_MeshData::GLC_Color) && m_ColorBuffer.isCreated()) - { - useVBO(true, type); - const GLsizei dataNbr= static_cast(m_Colors.size()); - const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat); - m_ColorBuffer.allocate(m_Colors.data(), dataSize); - - m_ColorSize= m_Colors.size(); - m_Colors.clear(); - } -} - -void GLC_MeshData::fillLodIbo() -{ - const int lodCount= m_LodList.count(); - for (int i= 0; i < lodCount; ++i) - { - m_LodList.at(i)->fillIbo(); - } -} -// Non Member methods -// Non-member stream operator -QDataStream &operator<<(QDataStream &stream, const GLC_MeshData &meshData) -{ - quint32 chunckId= GLC_MeshData::m_ChunkId; - stream << chunckId; - - stream << meshData.positionVector(); - stream << meshData.normalVector(); - stream << meshData.texelVector(); - stream << meshData.colorVector(); - - // List of lod serialisation - const int lodCount= meshData.m_LodList.size(); - QList lodsList; - for (int i= 0; i < lodCount; ++i) - { - lodsList.append(*(meshData.m_LodList[i])); - } - stream << lodsList; - - return stream; -} - -QDataStream &operator>>(QDataStream &stream, GLC_MeshData &meshData) -{ - quint32 chunckId; - stream >> chunckId; - Q_ASSERT(chunckId == GLC_MeshData::m_ChunkId); - - meshData.clear(); - - GLfloatVector position, normal, texel, color; - - stream >> meshData.m_Positions; - stream >> meshData.m_Normals; - stream >> meshData.m_Texels; - stream >> meshData.m_Colors; - - // List of lod serialisation - QList lodsList; - stream >> lodsList; - const int lodCount= lodsList.size(); - for (int i= 0; i < lodCount; ++i) - { - meshData.m_LodList.append(new GLC_Lod(lodsList.at(i))); - } - - return stream; -} - diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_meshdata.h b/ground/gcs/src/libs/glc_lib/geometry/glc_meshdata.h deleted file mode 100644 index 6d5641bd9..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_meshdata.h +++ /dev/null @@ -1,280 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_meshdata.h Interface for the GLC_MeshData class. - -#ifndef GLC_MESHDATA_H_ -#define GLC_MESHDATA_H_ - -#include -#include - -#include "glc_lod.h" -#include "../glc_global.h" - -#include "../glc_config.h" - - -////////////////////////////////////////////////////////////////////// -//! \class GLC_MeshData -/*! \brief GLC_MeshData : Contains all data of the mesh - */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_MeshData -{ - friend GLC_LIB_EXPORT QDataStream &operator<<(QDataStream &, const GLC_MeshData &); - friend GLC_LIB_EXPORT QDataStream &operator>>(QDataStream &, GLC_MeshData &); - -public: - - //! Enum of VBO TYPE - enum VboType - { - GLC_Vertex= 30, - GLC_Normal, - GLC_Texel, - GLC_Color - }; - -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Default constructor - GLC_MeshData(); - - //! Copy constructor - GLC_MeshData(const GLC_MeshData&); - - //! Overload "=" operator - GLC_MeshData& operator=(const GLC_MeshData&); - - //! Destructor - virtual ~GLC_MeshData(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the class Chunk ID - static quint32 chunckID(); - - //! Return the number of lod - inline int lodCount() const - {return m_LodList.size();} - - //! Return the Position Vector - GLfloatVector positionVector() const; - - //! Return the normal Vector - GLfloatVector normalVector() const; - - //! Return the texel Vector - GLfloatVector texelVector() const; - - //! Return the color Vector - GLfloatVector colorVector() const; - - //! Return the Position Vector handle - inline GLfloatVector* positionVectorHandle() - { return &m_Positions;} - - //! Return the Normal Vector handle - inline GLfloatVector* normalVectorHandle() - { return &m_Normals;} - - //! Return the Texel Vector handle - inline GLfloatVector* texelVectorHandle() - { return &m_Texels;} - - //! Return the Color Vector handle - inline GLfloatVector* colorVectorHandle() - { return &m_Colors;} - - //! Return the Index Vector of the specified LOD - inline GLuintVector indexVector(const int i= 0) const - { - Q_ASSERT(i < m_LodList.size()); - return m_LodList.at(i)->indexVector(); - } - - //! Return the Index Vector handle of the specified LOD - inline GLuintVector* indexVectorHandle(const int i= 0) const - { - Q_ASSERT(i < m_LodList.size()); - return m_LodList.at(i)->indexVectorHandle(); - } - - //! Return the size of the triangles index Vector of the specified LOD - inline int indexVectorSize(const int i= 0) const - { - Q_ASSERT(i < m_LodList.size()); - return m_LodList.at(i)->indexVectorSize(); - } - //! Return the specified LOD if the LOD doesn't exists, return NULL - inline GLC_Lod* getLod(int index) const - { - return m_LodList.value(index); - } - - //! Return true if the mesh data doesn't contains vertice - inline bool isEmpty() const - {return (1 > m_PositionSize) && (0 == m_Positions.size());} - - //! Return the number of triangle from the given lod index - inline unsigned int trianglesCount(int lod) const - { - unsigned int subject= 0; - if (!m_LodList.isEmpty()) - { - Q_ASSERT(lod < m_LodList.size()); - subject= m_LodList.at(lod)->trianglesCount(); - } - return subject; - } - - //! Return true if the position size is set - inline bool positionSizeIsSet() const - {return m_PositionSize != -1;} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Add a empty Lod to the engine - inline void appendLod(double accuracy= 0.0) - {m_LodList.append(new GLC_Lod(accuracy));} - - //! If the there is more than 2 LOD Swap the first and last - void finishLod(); - - //! Clear the content of the meshData and makes it empty - void clear(); - - //! Copy VBO to the Client Side - void copyVboToClientSide(); - - //! Release client VBO - void releaseVboClientSide(bool update= false); - - //! Given number of triangles added to the given lod index - inline void trianglesAdded(int lod, int number) - { - if (lod != 0) lod-= 1; - else lod= m_LodList.size() - 1; - m_LodList.at(lod)->trianglesAdded(number); - } - - //! Set VBO usage - void setVboUsage(bool usage); - - //! Init the position size - inline void initPositionSize() - {m_PositionSize= m_Positions.size();} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Vbo creation - void createVBOs(); - - //! Ibo Usage - bool useVBO(bool, GLC_MeshData::VboType); - - //! Ibo Usage - inline void useIBO(bool use, const int currentLod= 0) - { - if (use) m_LodList.at(currentLod)->useIBO(); - else QGLBuffer::release(QGLBuffer::IndexBuffer); - } - - //! Fill all LOD IBO - void fillLodIbo(); - - //! Fill the VBO of the given type - void fillVbo(GLC_MeshData::VboType vboType); - -//@} - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - - //! The vertex Buffer - QGLBuffer m_VertexBuffer; - - //! Vertex Position Vector - GLfloatVector m_Positions; - - //! Vertex Normal Vector - GLfloatVector m_Normals; - - //! Vertex Texture coordinate - GLfloatVector m_Texels; - - //! Color index - GLfloatVector m_Colors; - - //! Normals Buffer - QGLBuffer m_NormalBuffer; - - //! Texture Buffer - QGLBuffer m_TexelBuffer; - - //! Color Buffer - QGLBuffer m_ColorBuffer; - - //! The list of LOD - QList m_LodList; - - //! The size of Position and normal VBO - int m_PositionSize; - - //! The size of texel VBO - int m_TexelsSize; - - //! The size of Color VBO - int m_ColorSize; - - //! Use VBO - bool m_UseVbo; - - //! Class chunk id - static quint32 m_ChunkId; -}; - -//! Non-member stream operator -GLC_LIB_EXPORT QDataStream &operator<<(QDataStream &, const GLC_MeshData &); -GLC_LIB_EXPORT QDataStream &operator>>(QDataStream &, GLC_MeshData &); - -#endif /* GLC_MESHDATA_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_point.cpp b/ground/gcs/src/libs/glc_lib/geometry/glc_point.cpp deleted file mode 100644 index a89dd6e25..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_point.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_point.cpp implementation of the GLC_Point class. - -#include "glc_point.h" -#include "../glc_openglexception.h" - -using namespace glc; -////////////////////////////////////////////////////////////////////// -// Constructor Destructor -////////////////////////////////////////////////////////////////////// - - -GLC_Point::GLC_Point(const GLC_Point3d &setCoord) -:GLC_PointCloud() -, m_Coordinate(setCoord) -, m_Size(1.0f) -{ - setCoordinate(m_Coordinate); -} - -GLC_Point::GLC_Point(double x, double y, double z) -:GLC_PointCloud() -, m_Coordinate(x, y, z) -, m_Size(1.0f) -{ - setCoordinate(m_Coordinate); -} - -GLC_Point::GLC_Point(const GLC_Point& point) -:GLC_PointCloud(point) -, m_Coordinate(point.m_Coordinate) -, m_Size(point.m_Size) -{ - -} - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -// Get a 4D point represent point coordinate -GLC_Point3d GLC_Point::coordinate(void) const -{ - return m_Coordinate; -} - -// Return a copy of the current geometry -GLC_Geometry* GLC_Point::clone() const -{ - return new GLC_Point(*this); -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -// Set Point coordinate by 4D Vector -void GLC_Point::setCoordinate(const GLC_Point3d &point) -{ - m_Coordinate= point; - GLC_PointCloud::clear(); - QList points; - points.append(m_Coordinate); - GLC_PointCloud::addPoint(points); - -} -// Set Point coordinate by 3 double -void GLC_Point::setCoordinate(double x, double y, double z) -{ - setCoordinate(GLC_Point3d(x, y, z)); -} - -////////////////////////////////////////////////////////////////////// -// OpenGL Functions -////////////////////////////////////////////////////////////////////// - -void GLC_Point::glDraw(const GLC_RenderProperties& renderProperties) -{ - glPointSize(m_Size); - // Point Display - GLC_PointCloud::glDraw(renderProperties); -} - diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_point.h b/ground/gcs/src/libs/glc_lib/geometry/glc_point.h deleted file mode 100644 index ba9bf6cfb..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_point.h +++ /dev/null @@ -1,116 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_point.h interface for the GLC_Point class. - -#ifndef GLC_POINT_H_ -#define GLC_POINT_H_ - -#include "glc_pointcloud.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Point -/*! \brief GLC_Point : OpenGL 3D Point*/ - -/*! An GLC_Point is just a simple 3D Point*/ -////////////////////////////////////////////////////////////////////// - -class GLC_LIB_EXPORT GLC_Point : public GLC_PointCloud -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Construct an GLC_Point - GLC_Point(const GLC_Point3d &); - - //! Construct an GLC_Point - GLC_Point(double, double, double); - - //! Copy constructor - GLC_Point(const GLC_Point& point); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Return a GLC_Point3d of coordinate - GLC_Point3d coordinate(void) const; - - //! Return a copy of the geometry - virtual GLC_Geometry* clone() const; - - //! Return the size of this point - inline GLfloat size() const - {return m_Size;} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Set Point coordinate by 4D point - void setCoordinate(const GLC_Point3d &); - - //! Set Point coordinate by 3 double - void setCoordinate(double x, double y, double z); - - //! Set the size of this point - void setSize(GLfloat size) - {m_Size= size;} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// - -private: - //! Virtual interface for OpenGL Geometry set up. - /*! This Virtual function is implemented here.\n*/ - virtual void glDraw(const GLC_RenderProperties&); - -//@} - -////////////////////////////////////////////////////////////////////// -// Private Member -////////////////////////////////////////////////////////////////////// - -private: - //! Point for point coordinate - GLC_Point3d m_Coordinate; - - //! Size of the point - GLfloat m_Size; - -}; -#endif //GLC_POINT_H_ diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_pointcloud.cpp b/ground/gcs/src/libs/glc_lib/geometry/glc_pointcloud.cpp deleted file mode 100644 index 2e8535102..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_pointcloud.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_pointcloud.cpp implementation of the GLC_PointCloud class. - -#include "glc_pointcloud.h" - -GLC_PointCloud::GLC_PointCloud() -: GLC_Geometry("Point Cloud", true) -{ - -} - -GLC_PointCloud::GLC_PointCloud(const GLC_PointCloud& pointCloud) -: GLC_Geometry(pointCloud) -{ - - -} - -GLC_PointCloud::~GLC_PointCloud() -{ - -} - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// -const GLC_BoundingBox& GLC_PointCloud::boundingBox() -{ - if (NULL == GLC_Geometry::m_pBoundingBox) - { - GLC_Geometry::m_pBoundingBox= new GLC_BoundingBox(); - if (! m_WireData.isEmpty()) - { - GLC_Geometry::m_pBoundingBox->combine(m_WireData.boundingBox()); - } - } - return *GLC_Geometry::m_pBoundingBox; -} - -GLC_Geometry* GLC_PointCloud::clone() const -{ - return new GLC_PointCloud(*this); -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -GLC_uint GLC_PointCloud::addPoint(const QList& pointsList) -{ - const int pointCount= pointsList.size(); - const int size= pointCount * 3; - GLfloatVector data(size); - for (int i= 0; i < pointCount; ++i) - { - const GLC_Point3d currentPoint(pointsList.at(i)); - data[i * 3]= static_cast(currentPoint.x()); - data[i * 3 + 1]= static_cast(currentPoint.y()); - data[i * 3 + 2]= static_cast(currentPoint.z()); - } - return GLC_Geometry::m_WireData.addVerticeGroup(data); -} - -GLC_uint GLC_PointCloud::addPoint(const QList& pointsList) -{ - const int pointCount= pointsList.size(); - const int size= pointCount * 3; - GLfloatVector data(size); - for (int i= 0; i < pointCount; ++i) - { - const GLC_Point3df currentPoint(pointsList.at(i)); - data[i * 3]= currentPoint.x(); - data[i * 3 + 1]= currentPoint.y(); - data[i * 3 + 2]= currentPoint.z(); - } - return GLC_Geometry::m_WireData.addVerticeGroup(data); -} - -void GLC_PointCloud::addColors(const QList& colors) -{ - const int colorCount= colors.count(); - const int size= colorCount * 4; - GLfloatVector data(size); - for (int i= 0; i < colorCount; ++i) - { - QColor color= colors.at(i); - data[i * 4]= static_cast(color.redF()); - data[i * 4 + 1]= static_cast(color.greenF()); - data[i * 4 + 2]= static_cast(color.blueF()); - data[i * 4 + 3]= static_cast(color.alphaF()); - } - - GLC_Geometry::m_WireData.addColors(data); -} - -GLC_PointCloud& GLC_PointCloud::operator=(const GLC_PointCloud& pointCloud) -{ - if (this != &pointCloud) - { - GLC_Geometry::operator=(pointCloud); - } - return *this; -} - -////////////////////////////////////////////////////////////////////// -// OpenGL Functions -////////////////////////////////////////////////////////////////////// -void GLC_PointCloud::glDraw(const GLC_RenderProperties& renderProperties) -{ - if (!GLC_Geometry::m_WireData.isEmpty()) - { - GLC_Geometry::m_WireData.glDraw(renderProperties, GL_POINTS); - } -} - diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_pointcloud.h b/ground/gcs/src/libs/glc_lib/geometry/glc_pointcloud.h deleted file mode 100644 index 41462957f..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_pointcloud.h +++ /dev/null @@ -1,120 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_pointcloud.h interface for the GLC_PointCloud class. - -#ifndef GLC_POINTCLOUD_H_ -#define GLC_POINTCLOUD_H_ - -#include "glc_geometry.h" -#include "../maths/glc_vector3d.h" -#include "../maths/glc_vector3df.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_PointCloud -/*! \brief GLC_PointCloud : OpenGL 3D cloud of points*/ - -/*! An GLC_PointCloud is a group of points - * All points of this class have the same color*/ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_PointCloud : public GLC_Geometry -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// - -public: - //! Construct an empty cloud of points - GLC_PointCloud(); - - //! Copy constructor - GLC_PointCloud(const GLC_PointCloud& pointCloud); - - //! Destructor - virtual ~GLC_PointCloud(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the point cloud bounding box - const GLC_BoundingBox& boundingBox(); - - //! Return a copy of the geometry - virtual GLC_Geometry* clone() const; - - //! Return true if this point cloud is empty - inline bool isEmpty() const - {return GLC_Geometry::m_WireData.isEmpty();} - -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Add a point to this wire and returns its id if id are managed - inline GLC_uint addPoint(const GLfloatVector& data) - {return GLC_Geometry::m_WireData.addVerticeGroup(data);} - - //! Add the given list of points to this cloud and returns its id if id are managed - GLC_uint addPoint(const QList& pointsList); - - //! Add the given list of points to this cloud and returns its id if id are managed - GLC_uint addPoint(const QList& pointsList); - - //! Add Colors - inline void addColors(const GLfloatVector& colors) - {GLC_Geometry::m_WireData.addColors(colors);} - - //! Add Colors - void addColors(const QList& colors); - - //! Set this point cloud from the given point cloud and return a reference of this point cloud - GLC_PointCloud& operator=(const GLC_PointCloud& pointcloud); - - //! Clear the content of this point cloud Data and makes it empty - inline void clear() - {GLC_Geometry::m_WireData.clear();} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -protected: - - //! Virtual interface for OpenGL Geometry set up. - /*! This Virtual function is implemented here.\n - * Throw GLC_OpenGlException*/ - virtual void glDraw(const GLC_RenderProperties&); - -//@} - -}; - -#endif /* GLC_POINTCLOUD_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_pointsprite.cpp b/ground/gcs/src/libs/glc_lib/geometry/glc_pointsprite.cpp deleted file mode 100644 index 560bb6048..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_pointsprite.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - Copyright (C) 2009 Laurent Bauer - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_pointsprite.cpp implementation of the GLC_PointSprite class. - -#include "glc_pointsprite.h" -#include "../glc_openglexception.h" -#include "../glc_state.h" -#include "../glc_ext.h" -#include "../shading/glc_selectionmaterial.h" -#include "../glc_context.h" - -// The maximum point size -float GLC_PointSprite::m_MaxSize= -1.0f; - -// Default constructor -GLC_PointSprite::GLC_PointSprite(float size, GLC_Material* pMaterial) -:GLC_PointCloud() -, m_Size(size) -, m_DistanceAttenuation(3) -, m_FadeThresoldSize(60.0f) -{ - Q_ASSERT(pMaterial != NULL); - Q_ASSERT(pMaterial->hasTexture()); - addMaterial(pMaterial); - - // Set Distance attenuation defaults values - m_DistanceAttenuation[0]= 1.0f; - m_DistanceAttenuation[1]= 0.0f; - m_DistanceAttenuation[2]= 0.0f; - - QList points; - points.append(GLC_Point3d(0.0, 0.0, 0.0)); - GLC_PointCloud::addPoint(points); -} - -GLC_PointSprite::GLC_PointSprite(const GLC_PointSprite& point) -: GLC_PointCloud(point) -, m_Size(point.m_Size) -, m_DistanceAttenuation(point.m_DistanceAttenuation) -, m_FadeThresoldSize(point.m_FadeThresoldSize) -{ - -} - -GLC_PointSprite::~GLC_PointSprite() -{ - -} - -// Return a copy of the current geometry -GLC_Geometry* GLC_PointSprite::clone() const -{ - return new GLC_PointSprite(*this); -} - -// Return the point size -void GLC_PointSprite::setSize(float size) -{ - m_GeometryIsValid= false; - m_Size= size; - // Clamp m_Size to m_MaxSize - if(qFuzzyCompare(-1.0f, m_MaxSize) && (m_MaxSize < m_Size)) - { - m_Size= m_MaxSize; - } -} - -// Set the point distance attenuation values -void GLC_PointSprite::setPointDistanceAttenuation(QVector parameters) -{ - Q_ASSERT(3 == parameters.size()); - m_DistanceAttenuation= parameters; -} - -////////////////////////////////////////////////////////////////////// -// OpenGL Functions -////////////////////////////////////////////////////////////////////// -// Specific glExecute method -void GLC_PointSprite::render(const GLC_RenderProperties& renderProperties) -{ - // Check if extension GL_ARB_point_parameters is present - if (!GLC_State::pointSpriteSupported()) return; - - glPushAttrib(GL_ALL_ATTRIB_BITS); - - if (!GLC_State::isInSelectionMode()) - { - glEnable( GL_BLEND ); - glDepthMask(GL_FALSE); - glEnable(GL_TEXTURE_2D); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_LIGHTING); - //GLC_Context::current()->glcEnableLighting(false); - - if(m_MaterialHash.size() == 1) - { - - if (renderProperties.isSelected()) - { - GLC_SelectionMaterial::glExecute(); - } - else - { - GLC_Material* pCurrentMaterial= m_MaterialHash.begin().value(); - const GLfloat red= pCurrentMaterial->diffuseColor().redF(); - const GLfloat green= pCurrentMaterial->diffuseColor().greenF(); - const GLfloat blue= pCurrentMaterial->diffuseColor().blueF(); - const GLfloat alpha= pCurrentMaterial->diffuseColor().alphaF(); - - glColor4f(red, green, blue, alpha); - pCurrentMaterial->glExecute(); - - } - } - } - else - { - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); - glDisable(GL_LIGHTING); - //GLC_Context::current()->glcEnableLighting(false); - } - - - // Executed only the first time - if (qFuzzyCompare(-1.0f, m_MaxSize)) - { - // Query for the max point size supported by the hardware - glGetFloatv(GL_POINT_SIZE_MAX, &m_MaxSize); - - // Clamp m_Size to m_MaxSize - if(m_MaxSize < m_Size) - m_Size= m_MaxSize; - } - - // This is how will our point sprite's size will be modified by - // distance from the viewer - glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, m_DistanceAttenuation.data()); - glPointSize(m_Size); - - // The alpha of a point is calculated to allow the fading of points - // instead of shrinking them past a defined threshold size. The threshold - // is defined by GL_POINT_FADE_THRESHOLD_SIZE_ARB and is not clamped to - // the minimum and maximum point sizes. - glPointParameterf(GL_POINT_FADE_THRESHOLD_SIZE, m_FadeThresoldSize); - - glPointParameterf(GL_POINT_SIZE_MIN, 1.0f); - glPointParameterf(GL_POINT_SIZE_MAX, m_Size); - - // Specify point sprite texture coordinate replacement mode for each - // texture unit - glTexEnvf(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); - - glEnable(GL_POINT_SPRITE); - glDraw(renderProperties); - - glPopAttrib(); - -} -// Point sprite set up -void GLC_PointSprite::glDraw(const GLC_RenderProperties& renderProperties) -{ - GLC_PointCloud::glDraw(renderProperties); -} - diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_pointsprite.h b/ground/gcs/src/libs/glc_lib/geometry/glc_pointsprite.h deleted file mode 100644 index fc74f05b9..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_pointsprite.h +++ /dev/null @@ -1,130 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - Copyright (C) 2009 Laurent Bauer - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_pointsprite.h interface for the GLC_PointSprite class. - -#include "glc_pointcloud.h" -#include - -#include "../glc_config.h" - -#ifndef GLC_POINTSPRITE_H_ -#define GLC_POINTSPRITE_H_ - -////////////////////////////////////////////////////////////////////// -//! \class GLC_PointSprite -/*! \brief GLC_PointSprite : OpenGL 3D Point Sprite Using extension : GL_ARB_point_parameters*/ - -/*! An GLC_PointSprite is just a simple 3D Sprite Point*/ -////////////////////////////////////////////////////////////////////// - -class GLC_LIB_EXPORT GLC_PointSprite : public GLC_PointCloud -{ -public: -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// - //! Default constructor - /*! The material must exist and had texture*/ - GLC_PointSprite(float, GLC_Material*); - - //! Copy constructor - GLC_PointSprite(const GLC_PointSprite& point); - - //! Default destructor - virtual ~GLC_PointSprite(); -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Return the point size - inline float size() const - {return m_Size;} - - //! Return a copy of the geometry - virtual GLC_Geometry* clone() const; - - //! Return the fade thresold size - inline float fadeThresoldSize() - {return m_FadeThresoldSize;} - - //! Return the maximum point size - /*! Return -1 if the size is unknown*/ - inline static float maximumPointSize() - {return m_MaxSize;} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Return the point size - void setSize(float size); - - //! Set the point distance attenuation values - /*! Vector size must be equal to 3*/ - void setPointDistanceAttenuation(QVector); - - //! Set the fade thresold size - inline void setFadeThresoldSize(float value) - {m_FadeThresoldSize= value;} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -private: - //! Specific glExecute method - virtual void render(const GLC_RenderProperties&); - - //! Virtual interface for OpenGL Geometry set up. - /*! This Virtual function is implemented here.\n*/ - virtual void glDraw(const GLC_RenderProperties&); -//@} -////////////////////////////////////////////////////////////////////// -// Private Member -////////////////////////////////////////////////////////////////////// - -private: - //! The point size - float m_Size; - - //! The Distance attenuation values - QVector m_DistanceAttenuation; - - //! The Fade Thresold Size - float m_FadeThresoldSize; - - //! The maximum point size - static float m_MaxSize; -}; - -#endif /* GLC_POINTSPRITE_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_polylines.cpp b/ground/gcs/src/libs/glc_lib/geometry/glc_polylines.cpp deleted file mode 100644 index 89e73e9ae..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_polylines.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_polyline.cpp implementation of the GLC_Polylines class. - -#include "glc_polylines.h" - -GLC_Polylines::GLC_Polylines() -: GLC_Geometry("Polyline", true) -{ - -} - -GLC_Polylines::GLC_Polylines(const GLC_Polylines& polyline) -: GLC_Geometry(polyline) -{ - -} - -GLC_Polylines::~GLC_Polylines() -{ - -} - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// -const GLC_BoundingBox& GLC_Polylines::boundingBox() -{ - if (NULL == GLC_Geometry::m_pBoundingBox) - { - GLC_Geometry::m_pBoundingBox= new GLC_BoundingBox(); - if (! m_WireData.isEmpty()) - { - GLC_Geometry::m_pBoundingBox->combine(m_WireData.boundingBox()); - } - } - return *GLC_Geometry::m_pBoundingBox; -} - -GLC_Geometry* GLC_Polylines::clone() const -{ - return new GLC_Polylines(*this); -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - - -GLC_uint GLC_Polylines::addPolyline(const QList& pointsList) -{ - const int pointCount= pointsList.size(); - const int size= pointCount * 3; - GLfloatVector data(size); - for (int i= 0; i < pointCount; ++i) - { - const GLC_Point3d currentPoint(pointsList.at(i)); - data[i * 3]= static_cast(currentPoint.x()); - data[i * 3 + 1]= static_cast(currentPoint.y()); - data[i * 3 + 2]= static_cast(currentPoint.z()); - } - return GLC_Geometry::m_WireData.addVerticeGroup(data); -} - -GLC_uint GLC_Polylines::addPolyline(const QList& pointsList) -{ - const int pointCount= pointsList.size(); - const int size= pointCount * 3; - GLfloatVector data(size); - for (int i= 0; i < pointCount; ++i) - { - const GLC_Point3df currentPoint(pointsList.at(i)); - data[i * 3]= currentPoint.x(); - data[i * 3 + 1]= currentPoint.y(); - data[i * 3 + 2]= currentPoint.z(); - } - return GLC_Geometry::m_WireData.addVerticeGroup(data); -} - -GLC_Polylines& GLC_Polylines::operator=(const GLC_Polylines& polyline) -{ - if (this != &polyline) - { - GLC_Geometry::operator=(polyline); - } - return *this; -} - -////////////////////////////////////////////////////////////////////// -// OpenGL Functions -////////////////////////////////////////////////////////////////////// -void GLC_Polylines::glDraw(const GLC_RenderProperties& renderProperties) -{ - if (!GLC_Geometry::m_WireData.isEmpty()) - { - GLC_Geometry::m_WireData.glDraw(renderProperties, GL_LINE_STRIP); - } -} - diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_polylines.h b/ground/gcs/src/libs/glc_lib/geometry/glc_polylines.h deleted file mode 100644 index 545d5382a..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_polylines.h +++ /dev/null @@ -1,111 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_polyline.h interface for the GLC_Polylines class. - -#ifndef GLC_POLYLINES_H_ -#define GLC_POLYLINES_H_ - -#include "glc_geometry.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Polylines -/*! \brief GLC_Polylines : OpenGL 3D Polylines*/ - -/*! An GLC_Polylines is a group of wire polyline - * All polylines of this class have the same color*/ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_Polylines : public GLC_Geometry -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Construct an empty polylines - GLC_Polylines(); - - //! Copy constructor - GLC_Polylines(const GLC_Polylines& polyline); - - //! Destructor - virtual ~GLC_Polylines(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the polylines bounding box - const GLC_BoundingBox& boundingBox(); - - //! Return a copy of the geometry - virtual GLC_Geometry* clone() const; - - //! Return true if this polylines is empty - inline bool isEmpty() const - {return GLC_Geometry::m_WireData.isEmpty();} - - -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Add a Polyline to this polylines and returns its id if id are managed - inline GLC_uint addPolyline(const GLfloatVector& data) - {return GLC_Geometry::m_WireData.addVerticeGroup(data);} - - //! Add polyline with the given list of points to this polylines and returns its id if id are managed - GLC_uint addPolyline(const QList& pointsList); - - //! Add polyline with the given list of points to this polylines and returns its id if id are managed - GLC_uint addPolyline(const QList& pointsList); - - //! Set this polylines from the given polylines and return a reference of this polylines - GLC_Polylines& operator=(const GLC_Polylines& polyline); - - //! Clear the content of this polylines Data and makes it empty - inline void clear() - {GLC_Geometry::m_WireData.clear();} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -protected: - - //! Virtual interface for OpenGL Geometry set up. - /*! This Virtual function is implemented here.\n - * Throw GLC_OpenGlException*/ - virtual void glDraw(const GLC_RenderProperties&); - -//@} - -}; - -#endif /* GLC_POLYLINES_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_primitivegroup.cpp b/ground/gcs/src/libs/glc_lib/geometry/glc_primitivegroup.cpp deleted file mode 100644 index bae3546f6..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_primitivegroup.cpp +++ /dev/null @@ -1,395 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_primitivegroup.cpp implementation of the GLC_PrimitiveGroup class. - -#include "glc_primitivegroup.h" -#include "../glc_state.h" - -// Class chunk id -quint32 GLC_PrimitiveGroup::m_ChunkId= 0xA700; - -// Default constructor -GLC_PrimitiveGroup::GLC_PrimitiveGroup(GLC_uint materialId) -: m_Id(materialId) -, m_TrianglesIndex() -, m_TrianglesGroupsSizes() -, m_TrianglesGroupOffset() -, m_TrianglesGroupOffseti() -, m_TrianglesId() -, m_StripsIndex() -, m_StripIndexSizes() -, m_StripIndexOffset() -, m_StripIndexOffseti() -, m_StripsId() -, m_FansIndex() -, m_FansIndexSizes() -, m_FanIndexOffset() -, m_FanIndexOffseti() -, m_FansId() -, m_IsFinished(false) -, m_TrianglesIndexSize(0) -, m_TrianglesStripSize(0) -, m_TrianglesFanSize(0) -{ - - -} -//! Copy constructor -GLC_PrimitiveGroup::GLC_PrimitiveGroup(const GLC_PrimitiveGroup& group) -: m_Id(group.m_Id) -, m_TrianglesIndex(group.m_TrianglesIndex) -, m_TrianglesGroupsSizes(group.m_TrianglesGroupsSizes) -, m_TrianglesGroupOffset(group.m_TrianglesGroupOffset) -, m_TrianglesGroupOffseti(group.m_TrianglesGroupOffseti) -, m_TrianglesId(group.m_TrianglesId) -, m_StripsIndex(group.m_StripsIndex) -, m_StripIndexSizes(group.m_StripIndexSizes) -, m_StripIndexOffset(group.m_StripIndexOffset) -, m_StripIndexOffseti(group.m_StripIndexOffseti) -, m_StripsId(group.m_StripsId) -, m_FansIndex(group.m_FansIndex) -, m_FansIndexSizes(group.m_FansIndexSizes) -, m_FanIndexOffset(group.m_FanIndexOffset) -, m_FanIndexOffseti(group.m_FanIndexOffseti) -, m_FansId(group.m_FansId) -, m_IsFinished(group.m_IsFinished) -, m_TrianglesIndexSize(group.m_TrianglesIndexSize) -, m_TrianglesStripSize(group.m_TrianglesStripSize) -, m_TrianglesFanSize(group.m_TrianglesFanSize) -{ - - -} - -//! Copy constructor -GLC_PrimitiveGroup::GLC_PrimitiveGroup(const GLC_PrimitiveGroup& group, GLC_uint id) -: m_Id(id) -, m_TrianglesIndex(group.m_TrianglesIndex) -, m_TrianglesGroupsSizes(group.m_TrianglesGroupsSizes) -, m_TrianglesGroupOffset(group.m_TrianglesGroupOffset) -, m_TrianglesGroupOffseti(group.m_TrianglesGroupOffseti) -, m_TrianglesId(group.m_TrianglesId) -, m_StripsIndex(group.m_StripsIndex) -, m_StripIndexSizes(group.m_StripIndexSizes) -, m_StripIndexOffset(group.m_StripIndexOffset) -, m_StripIndexOffseti(group.m_StripIndexOffseti) -, m_StripsId(group.m_StripsId) -, m_FansIndex(group.m_FansIndex) -, m_FansIndexSizes(group.m_FansIndexSizes) -, m_FanIndexOffset(group.m_FanIndexOffset) -, m_FanIndexOffseti(group.m_FanIndexOffseti) -, m_FansId(group.m_FansId) -, m_IsFinished(group.m_IsFinished) -, m_TrianglesIndexSize(group.m_TrianglesIndexSize) -, m_TrianglesStripSize(group.m_TrianglesStripSize) -, m_TrianglesFanSize(group.m_TrianglesFanSize) -{ - - -} - -// = operator -GLC_PrimitiveGroup& GLC_PrimitiveGroup::operator=(const GLC_PrimitiveGroup& group) -{ - if (this != &group) - { - m_Id= group.m_Id; - m_TrianglesIndex= group.m_TrianglesIndex; - m_TrianglesGroupsSizes= group.m_TrianglesGroupsSizes; - m_TrianglesGroupOffset= group.m_TrianglesGroupOffset; - m_TrianglesGroupOffseti= group.m_TrianglesGroupOffseti; - m_TrianglesId= group.m_TrianglesId; - m_StripsIndex= group.m_StripsIndex; - m_StripIndexSizes= group.m_StripIndexSizes; - m_StripIndexOffset= group.m_StripIndexOffset; - m_StripIndexOffseti= group.m_StripIndexOffseti; - m_StripsId= group.m_StripsId; - m_FansIndex= group.m_FansIndex; - m_FansIndexSizes= group.m_FansIndexSizes; - m_FanIndexOffset= group.m_FanIndexOffset; - m_FanIndexOffseti= group.m_FanIndexOffseti; - m_FansId= group.m_FansId; - m_IsFinished= group.m_IsFinished; - m_TrianglesIndexSize= group.m_TrianglesIndexSize; - m_TrianglesStripSize= group.m_TrianglesStripSize; - m_TrianglesFanSize= group.m_TrianglesFanSize; - } - return *this; -} - -GLC_PrimitiveGroup::~GLC_PrimitiveGroup() -{ - -} -// Return the class Chunk ID -quint32 GLC_PrimitiveGroup::chunckID() -{ - return m_ChunkId; -} - -// Add triangles to the group -void GLC_PrimitiveGroup::addTriangles(const IndexList& input, GLC_uint id) -{ - m_TrianglesIndex+= input; - m_TrianglesIndexSize= m_TrianglesIndex.size(); - - m_TrianglesGroupsSizes.append(static_cast(input.size())); - - if (m_TrianglesGroupOffseti.isEmpty()) - { - m_TrianglesGroupOffseti.append(0); - } - int offset= m_TrianglesGroupOffseti.last() + m_TrianglesGroupsSizes.last(); - m_TrianglesGroupOffseti.append(offset); - - // The Triangles group id - if (0 != id) m_TrianglesId.append(id); - else Q_ASSERT(m_TrianglesId.isEmpty()); -} - -// Add triangle strip to the group -void GLC_PrimitiveGroup::addTrianglesStrip(const IndexList& input, GLC_uint id) -{ - m_StripsIndex+= input; - m_TrianglesStripSize= m_StripsIndex.size(); - - m_StripIndexSizes.append(static_cast(input.size())); - - if (m_StripIndexOffseti.isEmpty()) - { - m_StripIndexOffseti.append(0); - } - int offset= m_StripIndexOffseti.last() + m_StripIndexSizes.last(); - m_StripIndexOffseti.append(offset); - - // The strip id - if (0 != id) m_StripsId.append(id); - else Q_ASSERT(m_StripsId.isEmpty()); -} -// Set the triangle index offset -void GLC_PrimitiveGroup::setTrianglesOffset(GLvoid* pOffset) -{ - //m_TrianglesGroupOffseti.pop_back(); - const int size= m_TrianglesGroupOffseti.size(); - for (int i= 0; i < size; ++i) - { - m_TrianglesGroupOffset.append(BUFFER_OFFSET(static_cast(m_TrianglesGroupOffseti[i]) * sizeof(GLuint) + reinterpret_cast(pOffset))); - } -} - -// Set the triangle index offset -void GLC_PrimitiveGroup::setTrianglesOffseti(int offset) -{ - m_TrianglesGroupOffseti.pop_back(); - const int size= m_TrianglesGroupOffseti.size(); - for (int i= 0; i < size; ++i) - { - m_TrianglesGroupOffseti[i]= m_TrianglesGroupOffseti[i] + offset; - } -} - -// Set base triangle strip offset -void GLC_PrimitiveGroup::setBaseTrianglesStripOffset(GLvoid* pOffset) -{ - //m_StripIndexOffseti.pop_back(); - const int size= m_StripIndexOffseti.size(); - for (int i= 0; i < size; ++i) - { - m_StripIndexOffset.append(BUFFER_OFFSET(static_cast(m_StripIndexOffseti[i]) * sizeof(GLuint) + reinterpret_cast(pOffset))); - } -} - -// Set base triangle strip offset -void GLC_PrimitiveGroup::setBaseTrianglesStripOffseti(int offset) -{ - m_StripIndexOffseti.pop_back(); - const int size= m_StripIndexOffseti.size(); - for (int i= 0; i < size; ++i) - { - m_StripIndexOffseti[i]= m_StripIndexOffseti[i] + offset; - } -} - -//! Add triangle fan to the group -void GLC_PrimitiveGroup::addTrianglesFan(const IndexList& input, GLC_uint id) -{ - m_FansIndex+= input; - m_TrianglesFanSize= m_FansIndex.size(); - - m_FansIndexSizes.append(static_cast(input.size())); - - if (m_FanIndexOffseti.isEmpty()) - { - m_FanIndexOffseti.append(0); - } - int offset= m_FanIndexOffseti.last() + m_FansIndexSizes.last(); - m_FanIndexOffseti.append(offset); - - // The fan id - if (0 != id) m_FansId.append(id); - else Q_ASSERT(m_FansId.isEmpty()); - - -} - -// Set base triangle fan offset -void GLC_PrimitiveGroup::setBaseTrianglesFanOffset(GLvoid* pOffset) -{ - //m_FanIndexOffseti.pop_back(); - const int size= m_FanIndexOffseti.size(); - for (int i= 0; i < size; ++i) - { - m_FanIndexOffset.append(BUFFER_OFFSET(static_cast(m_FanIndexOffseti[i]) * sizeof(GLuint) + reinterpret_cast(pOffset))); - } -} - -// Set base triangle fan offset -void GLC_PrimitiveGroup::setBaseTrianglesFanOffseti(int offset) -{ - m_FanIndexOffseti.pop_back(); - const int size= m_FanIndexOffseti.size(); - for (int i= 0; i < size; ++i) - { - m_FanIndexOffseti[i]= m_FanIndexOffseti[i] + offset; - } -} - -// Change index to VBO mode -void GLC_PrimitiveGroup::computeVboOffset() -{ - m_TrianglesGroupOffset.clear(); - const int triangleOffsetSize= m_TrianglesGroupOffseti.size(); - for (int i= 0; i < triangleOffsetSize; ++i) - { - m_TrianglesGroupOffset.append(BUFFER_OFFSET(static_cast(m_TrianglesGroupOffseti.at(i)) * sizeof(GLuint))); - } - - m_StripIndexOffset.clear(); - const int stripOffsetSize= m_StripIndexOffseti.size(); - for (int i= 0; i < stripOffsetSize; ++i) - { - m_StripIndexOffset.append(BUFFER_OFFSET(static_cast(m_StripIndexOffseti.at(i)) * sizeof(GLuint))); - } - - m_FanIndexOffset.clear(); - const int fanOffsetSize= m_FanIndexOffseti.size(); - for (int i= 0; i < fanOffsetSize; ++i) - { - m_FanIndexOffset.append(BUFFER_OFFSET(static_cast(m_FanIndexOffseti.at(i)) * sizeof(GLuint))); - } -} - -// Clear the group -void GLC_PrimitiveGroup::clear() -{ - m_TrianglesIndex.clear(); - m_TrianglesGroupsSizes.clear(); - m_TrianglesGroupOffset.clear(); - m_TrianglesGroupOffseti.clear(); - m_StripsIndex.clear(); - m_StripIndexSizes.clear(); - m_StripIndexOffset.clear(); - m_StripIndexOffseti.clear(); - m_FansIndex.clear(); - m_FansIndexSizes.clear(); - m_FanIndexOffset.clear(); - m_FanIndexOffseti.clear(); - m_IsFinished= false; - m_TrianglesIndexSize= 0; - m_TrianglesStripSize= 0; - m_TrianglesFanSize= 0; -} - - -// Non Member methods -// Non-member stream operator -QDataStream &operator<<(QDataStream &stream, const GLC_PrimitiveGroup &primitiveGroup) -{ - Q_ASSERT(primitiveGroup.isFinished()); - quint32 chunckId= GLC_PrimitiveGroup::m_ChunkId; - stream << chunckId; - - // Primitive group id - stream << primitiveGroup.m_Id; - - // Triangles, strips and fan offset index - OffsetVectori trianglesGroupOffseti; - OffsetVectori stripIndexOffseti; - OffsetVectori fanIndexOffseti; - - // Get triangles, strips and fans offset - trianglesGroupOffseti= primitiveGroup.m_TrianglesGroupOffseti; - stripIndexOffseti= primitiveGroup.m_StripIndexOffseti; - fanIndexOffseti= primitiveGroup.m_FanIndexOffseti; - - // Triangles index - stream << primitiveGroup.m_TrianglesIndexSize; - stream << trianglesGroupOffseti; - stream << primitiveGroup.m_TrianglesGroupsSizes; - stream << primitiveGroup.m_TrianglesId; - - // Triangles strips index - stream << primitiveGroup.m_TrianglesStripSize; - stream << stripIndexOffseti; - stream << primitiveGroup.m_StripIndexSizes; - stream << primitiveGroup.m_StripsId; - - // Triangles fans index - stream << primitiveGroup.m_TrianglesFanSize; - stream << fanIndexOffseti; - stream << primitiveGroup.m_FansIndexSizes; - stream << primitiveGroup.m_FansId; - - return stream; -} -QDataStream &operator>>(QDataStream &stream, GLC_PrimitiveGroup &primitiveGroup) -{ - quint32 chunckId; - stream >> chunckId; - Q_ASSERT(chunckId == GLC_PrimitiveGroup::m_ChunkId); - stream >> primitiveGroup.m_Id; - - // Triangles index - stream >> primitiveGroup.m_TrianglesIndexSize; - stream >> primitiveGroup.m_TrianglesGroupOffseti; - stream >> primitiveGroup.m_TrianglesGroupsSizes; - stream >> primitiveGroup.m_TrianglesId; - - // Triangles strips index - stream >> primitiveGroup.m_TrianglesStripSize; - stream >> primitiveGroup.m_StripIndexOffseti; - stream >> primitiveGroup.m_StripIndexSizes; - stream >> primitiveGroup.m_StripsId; - - // Triangles fans index - stream >> primitiveGroup.m_TrianglesFanSize; - stream >> primitiveGroup.m_FanIndexOffseti; - stream >> primitiveGroup.m_FansIndexSizes; - stream >> primitiveGroup.m_FansId; - - - primitiveGroup.finish(); - - return stream; -} - diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_primitivegroup.h b/ground/gcs/src/libs/glc_lib/geometry/glc_primitivegroup.h deleted file mode 100644 index b14f3e06c..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_primitivegroup.h +++ /dev/null @@ -1,330 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_primitivegroup.h interface for the GLC_PrimitiveGroup class. - -#ifndef GLC_PRIMITIVEGROUP_H_ -#define GLC_PRIMITIVEGROUP_H_ - -#include "../glc_ext.h" -#include "../glc_global.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_PrimitiveGroup -/*! \brief GLC_PrimitiveGroup : Triangles, Strip and fan index*/ - -/*! An GLC_PrimitiveGroup is used to stored Triangles, strips and fans index - * Grouped by material*/ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_PrimitiveGroup -{ - friend GLC_LIB_EXPORT QDataStream &operator<<(QDataStream &, const GLC_PrimitiveGroup &); - friend GLC_LIB_EXPORT QDataStream &operator>>(QDataStream &, GLC_PrimitiveGroup &); - -public: -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// - - //! Default constructor - GLC_PrimitiveGroup(GLC_uint id= 0); - - //! Copy constructor - GLC_PrimitiveGroup(const GLC_PrimitiveGroup&); - - //! Copy constructor - GLC_PrimitiveGroup(const GLC_PrimitiveGroup&, GLC_uint); - - //! = operator - GLC_PrimitiveGroup& operator=(const GLC_PrimitiveGroup&); - - ~GLC_PrimitiveGroup(); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the class Chunk ID - static quint32 chunckID(); - - //! Return true if the group is finished - inline bool isFinished() const - {return m_IsFinished;} - - //! Return the group id - inline GLC_uint id() const - {return m_Id;} - - //! Return true if the group contains triangles - inline bool containsTriangles() const - {return m_TrianglesIndexSize > 0;} - - //! Return true if the group contains triangles group id - inline bool containsTrianglesGroupId() const - {return !m_TrianglesId.isEmpty();} - - //! Return the triangle group ID - inline QList triangleGroupId() const - {return m_TrianglesId;} - - //! Return the Triangle group ID at the given index - inline GLC_uint triangleGroupId(int index) const - {return m_TrianglesId.at(index);} - - //! Return the size of list of triangles index of the group - inline int trianglesIndexSize() const - {return m_TrianglesIndexSize;} - - //! Return the size of list of triangles index of the group - inline const IndexSizes& trianglesIndexSizes() const - {return m_TrianglesGroupsSizes;} - - //! Return the list of triangles index of the group - inline const IndexList& trianglesIndex() const - { - Q_ASSERT(!m_IsFinished); - return m_TrianglesIndex; - } - - //! Return the offset of triangles index - inline const GLvoid* trianglesIndexOffset() const - {return m_TrianglesGroupOffset.first();} - - //! Return the offset of triangles index - inline int trianglesIndexOffseti() const - {return m_TrianglesGroupOffseti.first();} - - //! Return the offset of triangles index - inline const OffsetVector& trianglesGroupOffset() const - {return m_TrianglesGroupOffset;} - - //! Return the offset of triangles index - inline const OffsetVectori& trianglesGroupOffseti() const - {return m_TrianglesGroupOffseti;} - - //! Return true if the group contains strips - inline bool containsStrip() const - {return m_TrianglesStripSize > 0;} - - //! Return true if the group contains strips group id - inline bool containsStripGroupId() const - {return !m_StripsId.isEmpty();} - - //! Return the strip ID - inline QList stripGroupId() const - {return m_StripsId;} - - //! Return the strip ID at the given index - inline GLC_uint stripGroupId(int index) const - {return m_StripsId.at(index);} - - //! Return the size of index of strips - inline int stripsIndexSize() const - {return m_TrianglesStripSize;} - - //! Return the list of index of strips - inline const IndexList& stripsIndex() const - { - Q_ASSERT(!m_IsFinished); - return m_StripsIndex; - } - - //! Return the vector of strips sizes - inline const IndexSizes& stripsSizes() const - {return m_StripIndexSizes;} - - //! Return the vector of strip offset - inline const OffsetVector& stripsOffset() const - {return m_StripIndexOffset;} - - //! Return the vector of strip offset - inline const OffsetVectori& stripsOffseti() const - {return m_StripIndexOffseti;} - - //! Return true if the group contains fans - inline bool containsFan() const - {return m_TrianglesFanSize > 0;} - - //! Return true if the group contains fans group id - inline bool containsFanGroupId() const - {return !m_FansId.isEmpty();} - - //! Return the fan ID - inline QList fanGroupId() const - {return m_FansId;} - - //! Return the fan ID at the given index - inline GLC_uint fanGroupId(int index) const - {return m_FansId.at(index);} - - //! Return the size of index of fans - inline int fansIndexSize() const - {return m_TrianglesFanSize;} - - //! Return the list of index of fans - inline const IndexList& fansIndex() const - { - Q_ASSERT(!m_IsFinished); - return m_FansIndex; - } - - //! Return the vector of fans sizes - inline const IndexSizes& fansSizes() const - {return m_FansIndexSizes;} - - //! Return the vector of strip offset - inline const OffsetVector& fansOffset() const - {return m_FanIndexOffset;} - - //! Return the vector of strip offset - inline const OffsetVectori& fansOffseti() const - {return m_FanIndexOffseti;} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Set the group id - inline void setId(GLC_uint id) - {m_Id= id;} - - //! Add triangles to the group - void addTriangles(const IndexList& input, GLC_uint id= 0); - - //! Set the triangle index offset - void setTrianglesOffset(GLvoid* pOffset); - - //! Set the triangle index offset - void setTrianglesOffseti(int offset); - - //! Add triangle strip to the group - void addTrianglesStrip(const IndexList&, GLC_uint id= 0); - - //! Set base triangle strip offset - void setBaseTrianglesStripOffset(GLvoid*); - - //! Set base triangle strip offset - void setBaseTrianglesStripOffseti(int); - - //! Add triangle fan to the group - void addTrianglesFan(const IndexList&, GLC_uint id= 0); - - //! Set base triangle fan offset - void setBaseTrianglesFanOffset(GLvoid*); - - //! Set base triangle fan offset - void setBaseTrianglesFanOffseti(int); - - //! Compute VBO offset - void computeVboOffset(); - - //! The mesh wich use this group is finished - inline void finish() - { - m_TrianglesIndex.clear(); - m_StripsIndex.clear(); - m_FansIndex.clear(); - m_IsFinished= true; - } - - //! Clear the group - void clear(); - -//@} - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - //! Grouped material id - GLC_uint m_Id; - - //! Triangles index list - IndexList m_TrianglesIndex; - - //! Triangles groups index size - IndexSizes m_TrianglesGroupsSizes; - - //! Vector of triangles group offset - OffsetVector m_TrianglesGroupOffset; - OffsetVectori m_TrianglesGroupOffseti; - - //! Triangles groups id - QList m_TrianglesId; - - //! Strips index list - IndexList m_StripsIndex; - - //! Strips index size - IndexSizes m_StripIndexSizes; - - //! Vector of strips offset - OffsetVector m_StripIndexOffset; - OffsetVectori m_StripIndexOffseti; - - //! Strips id - QList m_StripsId; - - //! Fans index list - IndexList m_FansIndex; - - //! Fans index size - IndexSizes m_FansIndexSizes; - - //! Vector of fan Offset - OffsetVector m_FanIndexOffset; - OffsetVectori m_FanIndexOffseti; - - //! Fans id - QList m_FansId; - - //! Flag to know if the group is finish - int m_IsFinished; - - //! Flag to know if there is triangles - int m_TrianglesIndexSize; - - //! Flag to know if there is triangles strip - int m_TrianglesStripSize; - - //! Flag to know if there is triangles fan - int m_TrianglesFanSize; - - //! Class chunk id - static quint32 m_ChunkId; - -}; - -//! Non-member stream operator -GLC_LIB_EXPORT QDataStream &operator<<(QDataStream &, const GLC_PrimitiveGroup &); -GLC_LIB_EXPORT QDataStream &operator>>(QDataStream &, GLC_PrimitiveGroup &); - -#endif /* GLC_PRIMITIVEGROUP_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_rectangle.cpp b/ground/gcs/src/libs/glc_lib/geometry/glc_rectangle.cpp deleted file mode 100644 index 631d7c278..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_rectangle.cpp +++ /dev/null @@ -1,178 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -//! \file glc_rectangle.cpp Implementation for the GLC_Rectangle class. - -#include "glc_rectangle.h" -#include "../glc_state.h" - -GLC_Rectangle::GLC_Rectangle() -:GLC_Mesh() -, m_L1(1.0) -, m_L2(1.0) -{ - -} - -GLC_Rectangle::GLC_Rectangle(double l1, double l2) -:GLC_Mesh() -, m_L1(l1) -, m_L2(l2) -{ - -} - -GLC_Rectangle::GLC_Rectangle(const GLC_Rectangle& rect) -:GLC_Mesh(rect) -, m_L1(rect.m_L1) -, m_L2(rect.m_L2) -{ - -} - - -GLC_Rectangle::~GLC_Rectangle() -{ - -} -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -GLC_Geometry* GLC_Rectangle::clone() const -{ - return new GLC_Rectangle(*this); -} - -// return the rectangle bounding box -const GLC_BoundingBox& GLC_Rectangle::boundingBox() -{ - if (GLC_Mesh::isEmpty()) - { - createMeshAndWire(); - } - return GLC_Mesh::boundingBox(); -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -GLC_Rectangle& GLC_Rectangle::setRectangle(double l1, double l2) -{ - m_L1= l1; - m_L2= l2; - - GLC_Mesh::clearMeshWireAndBoundingBox(); - - return *this; -} - -void GLC_Rectangle::setLength1(double value) -{ - m_L1= value; - - GLC_Mesh::clearMeshWireAndBoundingBox(); -} - -void GLC_Rectangle::setLength2(double value) -{ - m_L2= value; - - GLC_Mesh::clearMeshWireAndBoundingBox(); -} - -////////////////////////////////////////////////////////////////////// -// Private OpenGL Functions -////////////////////////////////////////////////////////////////////// - -void GLC_Rectangle::glDraw(const GLC_RenderProperties& renderProperties) -{ - if (GLC_Mesh::isEmpty()) - { - createMeshAndWire(); - } - - GLC_Mesh::glDraw(renderProperties); -} - -////////////////////////////////////////////////////////////////////// -// Private services Functions -////////////////////////////////////////////////////////////////////// - -void GLC_Rectangle::createMeshAndWire() -{ - Q_ASSERT(GLC_Mesh::isEmpty()); - - const GLfloat lgX= static_cast(m_L1 / 2.0); - const GLfloat lgY= static_cast(m_L2 / 2.0); - - GLfloatVector verticeVector; - GLfloatVector normalsVector; - GLfloatVector texelVector; - - // the unique face of this rectangle - verticeVector << -lgX; verticeVector << -lgY; verticeVector << 0.0f; - normalsVector << 0.0f; normalsVector << 0.0f; normalsVector << 1.0f; - texelVector << 0.0f; texelVector << 0.0f; - - verticeVector << lgX; verticeVector << -lgY; verticeVector << 0.0f; - normalsVector << 0.0f; normalsVector << 0.0f; normalsVector << 1.0f; - texelVector << 1.0f; texelVector << 0.0f; - - verticeVector << lgX; verticeVector << lgY; verticeVector << 0.0f; - normalsVector << 0.0f; normalsVector << 0.0f; normalsVector << 1.0f; - texelVector << 1.0f; texelVector << 1.0f; - - verticeVector << -lgX; verticeVector << lgY; verticeVector << 0.0f; - normalsVector << 0.0f; normalsVector << 0.0f; normalsVector << 1.0f; - texelVector << 0.0f; texelVector << 1.0f; - - // Add bulk data in to the mesh - GLC_Mesh::addVertice(verticeVector); - GLC_Mesh::addNormals(normalsVector); - GLC_Mesh::addTexels(texelVector); - - // Add the first point of the rectangle for wire - verticeVector << -lgX; verticeVector << -lgY; verticeVector << 0.0f; - GLC_Geometry::addVerticeGroup(verticeVector); - - // Set the material to use - GLC_Material* pMaterial; - if (hasMaterial()) - { - pMaterial= this->firstMaterial(); - } - else - { - pMaterial= new GLC_Material(); - } - - IndexList index; - // Face 1 - index << 0 << 1 << 3 << 2; - GLC_Mesh::addTrianglesStrip(pMaterial, index); - - GLC_Mesh::finish(); -} - - diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_rectangle.h b/ground/gcs/src/libs/glc_lib/geometry/glc_rectangle.h deleted file mode 100644 index 17c18a99a..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_rectangle.h +++ /dev/null @@ -1,129 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -//! \file glc_rectangle.h interface for the GLC_Rectangle class. - -#ifndef GLC_RECTANGLE_H_ -#define GLC_RECTANGLE_H_ - -#include "glc_mesh.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Rectangle -/*! \brief GLC_Rectangle : OpenGL flat 3D Rectangle*/ - -/*! An GLC_Rectangle is just a simple 3D Rectangle*/ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_Rectangle : public GLC_Mesh -{ - -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Default constructor - GLC_Rectangle(); - - //! Construct a rectangle with the given lenght - GLC_Rectangle(double l1, double l2); - - //! Construct a restangle with the given rectangle - GLC_Rectangle(const GLC_Rectangle&); - - //! Destructor - virtual ~GLC_Rectangle(); -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return length 1 of this rectangle - inline double length1() const - { return m_L1;} - - //! Return length 2 of this rectangle - inline double length2() const - { return m_L2;} - - //! Clone this rectangle - virtual GLC_Geometry* clone() const; - - //! Return this rectangle bounding box - virtual const GLC_BoundingBox& boundingBox(void); - -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Set this rectangle with the given lenght - GLC_Rectangle& setRectangle(double l1, double l2); - - //! Set this rectangle length 1 - void setLength1(double l1); - - //! Set this rectangle length 2 - void setLength2(double l2); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -private: - - //! Virtual interface for OpenGL Geometry set up. - /*! This Virtual function is implemented here.\n - * Throw GLC_OpenGlException*/ - virtual void glDraw(const GLC_RenderProperties&); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Private services Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -private: - //! Create this rectangle mesh and wire - void createMeshAndWire(); -//@} - - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - //! The Rectangle length 1 - double m_L1; - - //! The Rectangle length 2 - double m_L2; - -}; - -#endif /* GLC_RECTANGLE_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_rep.cpp b/ground/gcs/src/libs/glc_lib/geometry/glc_rep.cpp deleted file mode 100644 index 224c0ba6e..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_rep.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -#include "glc_rep.h" -#include "QtDebug" - -// Default constructor -GLC_Rep::GLC_Rep() -: m_pIsLoaded(new bool(false)) -, m_pNumberOfRepresentation(new int(1)) -, m_pFileName(new QString()) -, m_pName(new QString()) -, m_pDateTime(new QDateTime) -{ - -} - -// Copy Constructor -GLC_Rep::GLC_Rep(const GLC_Rep& rep) -: m_pIsLoaded(rep.m_pIsLoaded) -, m_pNumberOfRepresentation(rep.m_pNumberOfRepresentation) -, m_pFileName(rep.m_pFileName) -, m_pName(rep.m_pName) -, m_pDateTime(rep.m_pDateTime) -{ - ++(*m_pNumberOfRepresentation); -} - -// Assignement operator -GLC_Rep& GLC_Rep::operator=(const GLC_Rep& rep) -{ - if (this != &rep) - { - // Clear this representation - clear(); - m_pIsLoaded= rep.m_pIsLoaded; - m_pNumberOfRepresentation= rep.m_pNumberOfRepresentation; - ++(*m_pNumberOfRepresentation); - m_pFileName= rep.m_pFileName; - m_pName= rep.m_pName; - m_pDateTime= rep.m_pDateTime; - } - - return *this; -} - -// Destructor -GLC_Rep::~GLC_Rep() -{ - // Clear this representation - clear(); -} - - -////////////////////////////////////////////////////////////////////// -// private services functions -////////////////////////////////////////////////////////////////////// -// Clear current representation -void GLC_Rep::clear() -{ - Q_ASSERT(NULL != m_pNumberOfRepresentation); - if ((--(*m_pNumberOfRepresentation)) == 0) - { - delete m_pIsLoaded; - m_pIsLoaded= NULL; - delete m_pNumberOfRepresentation; - m_pNumberOfRepresentation= NULL; - delete m_pFileName; - m_pFileName= NULL; - delete m_pName; - m_pName= NULL; - delete m_pDateTime; - m_pDateTime= NULL; - } -} diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_rep.h b/ground/gcs/src/libs/glc_lib/geometry/glc_rep.h deleted file mode 100644 index 7e313d106..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_rep.h +++ /dev/null @@ -1,165 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -#include -#include - -#include "../glc_config.h" - -#ifndef GLC_REP_H_ -#define GLC_REP_H_ -////////////////////////////////////////////////////////////////////// -//! \class GLC_Rep -/*! \brief GLC_Rep : Abstract class for a reference represention*/ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_Rep -{ -public: - enum Type - { - GLC_VBOGEOM= 1 - }; -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Default constructor - GLC_Rep(); - - //! Copy constructor - GLC_Rep(const GLC_Rep&); - - //! Assignement operator - virtual GLC_Rep &operator=(const GLC_Rep&); - - //! Clone the representation - virtual GLC_Rep* clone() const = 0; - - //! Return a deep copy of the representation - virtual GLC_Rep* deepCopy() const = 0; - - //! Destructor - virtual ~GLC_Rep(); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return true if the representation is the last - inline bool isTheLast() const - {return 1 == (*m_pNumberOfRepresentation);} - - //! Return true if representations are equals - inline bool operator==(const GLC_Rep& rep) - { - return (rep.m_pNumberOfRepresentation == m_pNumberOfRepresentation); - } - - //! Return the representation file name - inline QString fileName() const - {return (*m_pFileName);} - - //! Return the type of representation - virtual int type() const =0; - - //! Return the name of the rep - inline QString name() const - {return (*m_pName);} - - //! Return true if the representation is empty - virtual bool isEmpty() const= 0; - - //! Return true if the representation as been loaded - inline bool isLoaded() const - {return *m_pIsLoaded;} - - //! Return the rep file las modified date and time - inline QDateTime lastModified() const - {return *m_pDateTime;} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Set the representation FileName - inline void setFileName(const QString& fileName) - {(*m_pFileName)= fileName;} - - //! Set the representation Name - inline void setName(const QString& name) - {(*m_pName)= name;} - - //! Load the representation - virtual bool load()= 0; - - //! UnLoad the representation - virtual bool unload()= 0; - - //! Replace the representation - virtual void replace(GLC_Rep*)= 0; - - //! Set the last modified date and time - inline void setLastModified(const QDateTime& dateTime) - {*m_pDateTime= dateTime;} - -//@} -////////////////////////////////////////////////////////////////////// -// private services functions -////////////////////////////////////////////////////////////////////// -private: - //! Clear current representation - void clear(); -////////////////////////////////////////////////////////////////////// -// protected members -////////////////////////////////////////////////////////////////////// -protected: - - //! Flag to know if the representation has been loaded - bool* m_pIsLoaded; - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - - //! Number of this representation - int* m_pNumberOfRepresentation; - - //! The File Name of this representation - QString* m_pFileName; - - //! The Name of the rep - QString* m_pName; - - //! The Date and time of the rep - QDateTime* m_pDateTime; - -}; - -#endif /* GLC_REP_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_sphere.cpp b/ground/gcs/src/libs/glc_lib/geometry/glc_sphere.cpp deleted file mode 100644 index 22d1f56e2..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_sphere.cpp +++ /dev/null @@ -1,220 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2010 Laurent Bauer - Copyright (C) 2010 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_sphere.cpp implementation of the GLC_Sphere class. - -#include "glc_sphere.h" - -// Class chunk id -quint32 GLC_Sphere::m_ChunkId= 0xA710; - -GLC_Sphere::GLC_Sphere(double radius, int discretization) -: GLC_Mesh() -, m_Radius (radius) -, m_Discret(discretization) -, m_ThetaMin (0.0) -, m_ThetaMax(2 * glc::PI) -, m_PhiMin(-glc::PI / 2.0) -, m_PhiMax(glc::PI / 2.0) -, m_Center() -{ - createMesh(); -} - -GLC_Sphere::GLC_Sphere(double radius, const GLC_Point3d& center, int discretization) -: GLC_Mesh() -, m_Radius (radius) -, m_Discret(discretization) -, m_ThetaMin (0.0) -, m_ThetaMax(2 * glc::PI) -, m_PhiMin(-glc::PI / 2.0) -, m_PhiMax(glc::PI / 2.0) -, m_Center(center) -{ - createMesh(); -} - - -GLC_Sphere::GLC_Sphere(const GLC_Sphere & sphere) -:GLC_Mesh(sphere) -, m_Radius (sphere.m_Radius) -, m_Discret(sphere.m_Discret) -, m_ThetaMin (sphere.m_ThetaMin) -, m_ThetaMax(sphere.m_ThetaMax) -, m_PhiMin(sphere.m_PhiMin) -, m_PhiMax(sphere.m_PhiMax) -, m_Center(sphere.m_Center) -{ - if (isEmpty()) createMesh(); -} - -GLC_Sphere::~GLC_Sphere() -{ - -} - -GLC_Geometry* GLC_Sphere::clone() const -{ - return new GLC_Sphere (*this); -} - -const GLC_BoundingBox& GLC_Sphere::boundingBox() -{ - if ( GLC_Mesh::isEmpty() ) - { - createMesh(); - } - return GLC_Mesh::boundingBox(); -} - -void GLC_Sphere::setRadius(double Radius) -{ - Q_ASSERT(Radius > 0.0); - m_Radius= Radius; - - GLC_Mesh::clearMeshWireAndBoundingBox(); -} - - -void GLC_Sphere::setDiscretion(int TargetDiscret) -{ - Q_ASSERT(TargetDiscret > 0); - if (TargetDiscret != m_Discret) - { - m_Discret= TargetDiscret; - if (m_Discret < 6) m_Discret= 6; - - GLC_Mesh::clearMeshWireAndBoundingBox(); - } -} - -void GLC_Sphere::setCenter(const GLC_Point3d& pos) -{ - if (pos != m_Center) - { - m_Center= pos; - - GLC_Mesh::clearMeshWireAndBoundingBox(); - } -} - -void GLC_Sphere::glDraw(const GLC_RenderProperties& renderProperties) -{ - if (GLC_Mesh::isEmpty()) - { - createMesh(); - } - - GLC_Mesh::glDraw(renderProperties); -} - -void GLC_Sphere::createMesh() -{ - - Q_ASSERT(GLC_Mesh::isEmpty()); - - GLfloatVector verticeFloat; - GLfloatVector normalsFloat; - GLfloatVector texelVector; - - int currentIndex=0; - - float wishedThetaStep= glc::PI / m_Discret; - float thetaRange= m_ThetaMax-m_ThetaMin; - int nbThetaSteps= (int) (thetaRange / wishedThetaStep) + 1 ; - float thetaStep= thetaRange / nbThetaSteps; - - float wishedPhiStep= wishedThetaStep; - float phiRange= m_PhiMax-m_PhiMin; - int nbPhiSteps= (int) (phiRange / wishedPhiStep) + 1 ; - float phiStep= phiRange / nbPhiSteps; - - float cost, sint, cosp, sinp, cospp, sinpp; - float xi, yi, zi, xf, yf, zf; - float theta= m_ThetaMin; - float phi= m_PhiMin; - - GLfloatVector thetaMinWire; - GLfloatVector thetaMaxWire; - GLfloatVector phiMinWire; - GLfloatVector phiMaxWire; - - GLC_Material* pMaterial; - if (hasMaterial()) - pMaterial= this->firstMaterial(); - else - pMaterial= new GLC_Material(); - - const double dx= m_Center.x(); - const double dy= m_Center.y(); - const double dz= m_Center.z(); - - // shaded face - for (int p= 0; p < nbPhiSteps; ++p) - { - cosp= cos (phi); - sinp= sin (phi); - cospp= cos (phi + phiStep); - sinpp= sin (phi + phiStep); - - zi = m_Radius * sinp; - zf = m_Radius * sinpp; - - IndexList indexFace; - - theta = m_ThetaMin; - int t; - for (t= 0; t <= nbThetaSteps; ++t) - { - cost= cos( theta ); - sint= sin( theta ); - - xi= m_Radius * cost * cosp; - yi= m_Radius * sint * cosp; - xf= m_Radius * cost * cospp; - yf= m_Radius * sint * cospp; - - verticeFloat << (xf + dx) << (yf + dy) << (zf + dz) << (xi + dx) << (yi + dy) << (zi + dz); - normalsFloat << cost * cospp << sint * cospp << sinpp << cost * cosp << sint * cosp << sinp; - texelVector << static_cast(t) * 1.0 / static_cast(nbThetaSteps) - << static_cast(p) * 1.0 / static_cast(nbPhiSteps) - << static_cast(t) * 1.0 / static_cast(nbThetaSteps) - << static_cast(p+1) * 1.0 / static_cast(nbPhiSteps); - - indexFace << currentIndex + 2 * t << currentIndex + 2 * t + 1 ; - theta+= thetaStep; - - } - - currentIndex+= 2 * t; - addTrianglesStrip(pMaterial, indexFace); - phi+= phiStep; - } - - addVertice(verticeFloat); - addNormals(normalsFloat); - addTexels(texelVector); - - finish(); -} - - diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_sphere.h b/ground/gcs/src/libs/glc_lib/geometry/glc_sphere.h deleted file mode 100644 index 9741e734d..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_sphere.h +++ /dev/null @@ -1,146 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2010 Laurent Bauer - Copyright (C) 2010 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_sphere.h interface for the GLC_Sphere class. - -#ifndef GLC_SPHERE_H_ -#define GLC_SPHERE_H_ - -#include "glc_mesh.h" -#include "../maths/glc_vector3d.h" -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Sphere -/*! \brief GLC_Sphere : OpenGL 3D Sphere*/ - -/*! An GLC_Sphere is a polygonnal geometry */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_Sphere : public GLC_Mesh -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Construct a sphere with the given radius - GLC_Sphere(double radius, int discretization= glc::GLC_POLYDISCRET); - - //! Construct a sphere with the given radius and center - GLC_Sphere(double radius, const GLC_Point3d& center, int discretization= glc::GLC_POLYDISCRET); - - //! Copy constructor - GLC_Sphere(const GLC_Sphere & sphere); - - //! Destructor - virtual ~GLC_Sphere(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the class Chunk ID - static quint32 chunckID(); - - //! Return the Radius of this sphere - inline double radius(void) const - {return m_Radius;} - - //! Get Sphere discretion - inline int discretion(void) const - {return m_Discret;} - - //! Return a copy of the Sphere - virtual GLC_Geometry* clone() const; - - //! Return the sphere bounding box - virtual const GLC_BoundingBox& boundingBox(void); - - //! Return the sphere center - inline GLC_Point3d center() const - {return m_Center;} -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Set Sphere radius - /*! Radius must be > 0*/ - void setRadius(double Radius); - - //! Set Discretion - /*! Discretion must be > 0*/ - void setDiscretion(int TargetDiscret); - - //! Set Sphere center - void setCenter(const GLC_Point3d& pos); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -private: - //! Virtual interface for OpenGL Geometry set up. - /*! This Virtual function is implemented here.\n - * Throw GLC_OpenGlException*/ - virtual void glDraw(const GLC_RenderProperties&); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Private services Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -private: - //! Create the sphere mesh - void createMesh(); - -//@} - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - //! Sphere radius - double m_Radius; - - //! Sphere polygon discretisation - int m_Discret; - - double m_ThetaMin; - double m_ThetaMax; - double m_PhiMin; - double m_PhiMax; - - GLC_Point3d m_Center; - - //! Class chunk id - static quint32 m_ChunkId; - -}; - -#endif /* GLC_SPHERE_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_wiredata.cpp b/ground/gcs/src/libs/glc_lib/geometry/glc_wiredata.cpp deleted file mode 100644 index 69b61121e..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_wiredata.cpp +++ /dev/null @@ -1,576 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -//! \file glc_wiredata.cpp Implementation for the GLC_WireData class. - -#include "glc_wiredata.h" -#include "glc_bsrep.h" -#include "../glc_ext.h" -#include "../glc_state.h" -#include "../glc_exception.h" - -// Class chunk id -// Old chunkId = 0xA706 -quint32 GLC_WireData::m_ChunkId= 0xA711; - - -GLC_WireData::GLC_WireData() -: m_VerticeBuffer() -, m_NextPrimitiveLocalId(1) -, m_Positions() -, m_ColorBuffer() -, m_Colors() -, m_IndexBuffer(QGLBuffer::IndexBuffer) -, m_IndexVector() -, m_PositionSize(0) -, m_ColorSize(0) -, m_pBoundingBox(NULL) -, m_VerticeGrouprSizes() -, m_VerticeGroupOffseti() -, m_VerticeGroupOffset() -, m_VerticeGroupId() -, m_VerticeGroupCount(0) -, m_UseVbo(false) -{ - -} - - -GLC_WireData::GLC_WireData(const GLC_WireData& data) -: m_VerticeBuffer() -, m_NextPrimitiveLocalId(data.m_NextPrimitiveLocalId) -, m_Positions(data.positionVector()) -, m_ColorBuffer() -, m_Colors(data.colorVector()) -, m_IndexBuffer(QGLBuffer::IndexBuffer) -, m_IndexVector(data.indexVector()) -, m_PositionSize(data.m_PositionSize) -, m_ColorSize(data.m_ColorSize) -, m_pBoundingBox(NULL) -, m_VerticeGrouprSizes(data.m_VerticeGrouprSizes) -, m_VerticeGroupOffseti(data.m_VerticeGroupOffseti) -, m_VerticeGroupOffset(data.m_VerticeGroupOffset) -, m_VerticeGroupId(data.m_VerticeGroupId) -, m_VerticeGroupCount(data.m_VerticeGroupCount) -, m_UseVbo(data.m_UseVbo) -{ - if (NULL != data.m_pBoundingBox) - { - m_pBoundingBox= new GLC_BoundingBox(*(data.m_pBoundingBox)); - } -} - - -GLC_WireData& GLC_WireData::operator=(const GLC_WireData& data) -{ - if (this != &data) - { - clear(); - m_NextPrimitiveLocalId= data.m_NextPrimitiveLocalId; - m_Positions= data.positionVector(); - m_Colors= data.colorVector(); - m_IndexVector= data.indexVector(); - m_PositionSize= data.m_PositionSize; - m_ColorSize= data.m_ColorSize; - if (NULL != data.m_pBoundingBox) - { - m_pBoundingBox= new GLC_BoundingBox(*(data.m_pBoundingBox)); - } - m_VerticeGrouprSizes= data.m_VerticeGrouprSizes; - m_VerticeGroupOffseti= data.m_VerticeGroupOffseti; - m_VerticeGroupOffset= data.m_VerticeGroupOffset; - m_VerticeGroupId= data.m_VerticeGroupId; - m_VerticeGroupCount= data.m_VerticeGroupCount; - m_UseVbo= data.m_UseVbo; - } - return *this; -} - -GLC_WireData::~GLC_WireData() -{ - clear(); -} -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - - -quint32 GLC_WireData::chunckID() -{ - return m_ChunkId; -} - - -GLfloatVector GLC_WireData::positionVector() const -{ - if (m_VerticeBuffer.isCreated()) - { - Q_ASSERT((NULL != QGLContext::currentContext()) && QGLContext::currentContext()->isValid()); - // VBO created get data from VBO - const int sizeOfVbo= m_PositionSize; - const GLsizeiptr dataSize= sizeOfVbo * sizeof(float); - GLfloatVector positionVector(sizeOfVbo); - - const_cast(m_VerticeBuffer).bind(); - GLvoid* pVbo = const_cast(m_VerticeBuffer).map(QGLBuffer::ReadOnly); - memcpy(positionVector.data(), pVbo, dataSize); - const_cast(m_VerticeBuffer).unmap(); - const_cast(m_VerticeBuffer).release(); - return positionVector; - } - else - { - return m_Positions; - } -} - -// Return the color Vector -GLfloatVector GLC_WireData::colorVector() const -{ - if (m_ColorBuffer.isCreated()) - { - // VBO created get data from VBO - const int sizeOfVbo= m_ColorSize; - const GLsizeiptr dataSize= sizeOfVbo * sizeof(GLfloat); - GLfloatVector normalVector(sizeOfVbo); - - const_cast(m_ColorBuffer).bind(); - GLvoid* pVbo = const_cast(m_ColorBuffer).map(QGLBuffer::ReadOnly); - memcpy(normalVector.data(), pVbo, dataSize); - const_cast(m_ColorBuffer).unmap(); - const_cast(m_ColorBuffer).release(); - return normalVector; - } - else - { - return m_Colors; - } -} - -QVector GLC_WireData::indexVector() const -{ - if (m_IndexBuffer.isCreated()) - { - // VBO created get data from VBO - const int sizeOfIbo= m_PositionSize / 3; - const GLsizeiptr dataSize= sizeOfIbo * sizeof(GLuint); - QVector indexVector(sizeOfIbo); - - const_cast(m_IndexBuffer).bind(); - GLvoid* pIbo = const_cast(m_IndexBuffer).map(QGLBuffer::ReadOnly); - memcpy(indexVector.data(), pIbo, dataSize); - const_cast(m_IndexBuffer).unmap(); - const_cast(m_IndexBuffer).release(); - return indexVector; - } - else - { - return m_IndexVector; - } -} - - -GLC_BoundingBox& GLC_WireData::boundingBox() -{ - if (NULL == m_pBoundingBox) - { - m_pBoundingBox= new GLC_BoundingBox(); - - if (m_Positions.isEmpty()) - { - //qDebug() << "GLC_WireData::getBoundingBox empty m_Positions"; - } - else - { - const int max= m_Positions.size(); - if (max == 3) // Only One point - { - const double delta= 1e-2; - GLC_Point3d lower(m_Positions[0] - delta, - m_Positions[1] - delta, - m_Positions[2] - delta); - GLC_Point3d upper(m_Positions[0] + delta, - m_Positions[1] + delta, - m_Positions[2] + delta); - m_pBoundingBox->combine(lower); - m_pBoundingBox->combine(upper); - - } - else - { - for (int i= 0; i < max; i= i + 3) - { - GLC_Point3d point(m_Positions[i], m_Positions[i + 1], m_Positions[i + 2]); - m_pBoundingBox->combine(point); - } - } - } - - } - return *m_pBoundingBox; -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - - -GLC_uint GLC_WireData::addVerticeGroup(const GLfloatVector& floatVector) -{ - Q_ASSERT((floatVector.size() % 3) == 0); - - ++m_VerticeGroupCount; - m_Positions+= floatVector; - - m_VerticeGrouprSizes.append(static_cast(floatVector.size() / 3)); - - if (m_VerticeGroupOffseti.isEmpty()) - { - m_VerticeGroupOffseti.append(0); - } - int offset= m_VerticeGroupOffseti.last() + m_VerticeGrouprSizes.last(); - m_VerticeGroupOffseti.append(offset); - - // The Polyline id - m_VerticeGroupId.append(m_NextPrimitiveLocalId); - return m_NextPrimitiveLocalId++; -} - -void GLC_WireData::clear() -{ - m_VerticeBuffer.destroy(); - m_NextPrimitiveLocalId= 1; - m_Positions.clear(); - m_PositionSize= 0; - delete m_pBoundingBox; - m_pBoundingBox= NULL; - - m_VerticeGrouprSizes.clear(); - m_VerticeGroupOffseti.clear(); - m_VerticeGroupId.clear(); - m_VerticeGroupCount= 0; -} - -void GLC_WireData::copyVboToClientSide() -{ - if (m_VerticeBuffer.isCreated() && m_Positions.isEmpty()) - { - m_Positions= positionVector(); - - if (m_ColorBuffer.isCreated() && m_Colors.isEmpty()) - { - m_Colors= colorVector(); - } - m_IndexVector= indexVector(); - } - -} - -void GLC_WireData::releaseVboClientSide(bool update) -{ - if (m_VerticeBuffer.isCreated() && !m_Positions.isEmpty()) - { - if (update) finishVbo(); - } -} - -void GLC_WireData::setVboUsage(bool usage) -{ - m_UseVbo= usage; - if (!isEmpty()) - { - if (m_UseVbo && (m_PositionSize != 0) && (!m_Positions.isEmpty())&& (!m_VerticeBuffer.isCreated())) - { - finishVbo(); - } - else if (!m_UseVbo && m_VerticeBuffer.isCreated()) - { - m_Positions= positionVector(); - m_VerticeBuffer.destroy(); - m_Colors= colorVector(); - m_ColorBuffer.destroy(); - m_IndexVector= indexVector(); - m_IndexBuffer.destroy(); - } - } -} - -////////////////////////////////////////////////////////////////////// -// OpenGL Functions -////////////////////////////////////////////////////////////////////// - -void GLC_WireData::finishVbo() -{ - Q_ASSERT((NULL != QGLContext::currentContext()) && QGLContext::currentContext()->isValid()); - if (!m_VerticeBuffer.isCreated()) - { - m_VerticeBuffer.create(); - } - if ((m_Colors.size() > 0) && !m_ColorBuffer.isCreated()) - { - m_ColorBuffer.create(); - } - if (!m_IndexBuffer.isCreated()) - { - m_IndexBuffer.create(); - } - fillVBOs(); - - m_PositionSize= m_Positions.size(); - m_Positions.clear(); - - m_IndexVector.clear(); - - if (m_ColorBuffer.isCreated()) - { - m_ColorSize= m_Colors.size(); - m_Colors.clear(); - } -} - -void GLC_WireData::useVBO(GLC_WireData::VboType type, bool use) -{ - if (use) - { - - // Chose the right VBO - if (type == GLC_WireData::GLC_Vertex) - { - if (!m_VerticeBuffer.bind()) - { - GLC_Exception exception("GLC_WireData::useVBO Failed to bind vertex buffer"); - throw(exception); - } - } - else if (type == GLC_WireData::GLC_Color) - { - Q_ASSERT(m_ColorSize > 0); - if (!m_ColorBuffer.bind()) - { - GLC_Exception exception("GLC_WireData::useVBO Failed to bind color buffer"); - throw(exception); - } - } - else if ((type == GLC_WireData::GLC_Index) && m_IndexBuffer.isCreated()) - { - if (!m_IndexBuffer.bind()) - { - GLC_Exception exception("GLC_WireData::useVBO Failed to bind index buffer"); - throw(exception); - } - } - } - else - { - QGLBuffer::release(QGLBuffer::VertexBuffer); - QGLBuffer::release(QGLBuffer::IndexBuffer); - } -} - -void GLC_WireData::glDraw(const GLC_RenderProperties&, GLenum mode) -{ - Q_ASSERT((NULL != QGLContext::currentContext()) && QGLContext::currentContext()->isValid()); - Q_ASSERT(!isEmpty()); - - const bool vboIsUsed= m_UseVbo && GLC_State::vboSupported(); - - if (vboIsUsed && ((m_PositionSize == 0) || !m_VerticeBuffer.isCreated())) - { - finishOffset(); - buidIndex(); - finishVbo(); - } - else if (!vboIsUsed && (m_PositionSize == 0)) - { - finishOffset(); - buidIndex(); - m_PositionSize= m_Positions.size(); - m_ColorSize= m_Colors.size(); - } - - // Activate VBO or Vertex Array - if (vboIsUsed) - { - activateVboAndIbo(); - glVertexPointer(3, GL_FLOAT, 0, 0); - glEnableClientState(GL_VERTEX_ARRAY); - if (m_ColorSize > 0) - { - glColorPointer(4, GL_FLOAT, 0, 0); - glEnableClientState(GL_COLOR_ARRAY); - } - - // Render polylines - for (int i= 0; i < m_VerticeGroupCount; ++i) - { - glDrawElements(mode, m_VerticeGrouprSizes.at(i), GL_UNSIGNED_INT, m_VerticeGroupOffset.at(i)); - } - - useVBO(GLC_WireData::GLC_Index, false); - } - else - { - glVertexPointer(3, GL_FLOAT, 0, m_Positions.data()); - glEnableClientState(GL_VERTEX_ARRAY); - if (m_ColorSize > 0) - { - glColorPointer(4, GL_FLOAT, 0, m_Colors.data()); - glEnableClientState(GL_COLOR_ARRAY); - } - // Render polylines - for (int i= 0; i < m_VerticeGroupCount; ++i) - { - glDrawElements(mode, m_VerticeGrouprSizes.at(i), GL_UNSIGNED_INT, &(m_IndexVector.data()[m_VerticeGroupOffseti.at(i)])); - } - - } - - if (m_ColorSize > 0) - { - glDisableClientState(GL_COLOR_ARRAY); - } - - glDisableClientState(GL_VERTEX_ARRAY); - - if (vboIsUsed) - { - QGLBuffer::release(QGLBuffer::IndexBuffer); - QGLBuffer::release(QGLBuffer::VertexBuffer); - } -} - - -void GLC_WireData::fillVBOs() -{ - { - Q_ASSERT(m_VerticeBuffer.isCreated()); - useVBO(GLC_WireData::GLC_Vertex, true); - const GLsizei dataNbr= static_cast(m_Positions.size()); - const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat); - m_VerticeBuffer.allocate(m_Positions.data(), dataSize); - } - - { - Q_ASSERT(m_IndexBuffer.isCreated()); - useVBO(GLC_WireData::GLC_Index, true); - const GLsizei dataNbr= static_cast(m_IndexVector.size()); - const GLsizeiptr dataSize= dataNbr * sizeof(GLuint); - m_IndexBuffer.allocate(m_IndexVector.data(), dataSize); - } - - if (m_ColorBuffer.isCreated()) - { - useVBO(GLC_WireData::GLC_Color, true); - const GLsizei dataNbr= static_cast(m_Colors.size()); - const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat); - m_ColorBuffer.allocate(m_Colors.data(), dataSize); - } -} - -void GLC_WireData::buidIndex() -{ - const int size= m_Positions.size(); - m_IndexVector.resize(size); - for (int i= 0; i < size; ++i) - { - m_IndexVector[i]= i; - } -} - -void GLC_WireData::activateVboAndIbo() -{ - // Activate Vertices VBO - useVBO(GLC_WireData::GLC_Vertex, true); - glVertexPointer(3, GL_FLOAT, 0, 0); - glEnableClientState(GL_VERTEX_ARRAY); - - // Activate Color VBO if needed - if (m_ColorSize > 0) - { - useVBO(GLC_WireData::GLC_Color, true); - glEnable(GL_COLOR_MATERIAL); - glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); - glColorPointer(4, GL_FLOAT, 0, 0); - glEnableClientState(GL_COLOR_ARRAY); - } - - // Activate index Buffer object - useVBO(GLC_WireData::GLC_Index, true); -} - -void GLC_WireData::finishOffset() -{ - m_VerticeGroupOffseti.remove(m_VerticeGroupOffseti.size() - 1); - m_VerticeGroupOffset.clear(); - const int offsetSize= m_VerticeGroupOffseti.size(); - for (int i= 0; i < offsetSize; ++i) - { - m_VerticeGroupOffset.append(BUFFER_OFFSET(static_cast(m_VerticeGroupOffseti.at(i)) * sizeof(GLuint))); - } -} - -QDataStream &operator<<(QDataStream &stream, const GLC_WireData &wireData) -{ - quint32 chunckId= GLC_WireData::m_ChunkId; - stream << chunckId; - - stream << wireData.m_NextPrimitiveLocalId; - stream << wireData.positionVector(); - stream << wireData.m_PositionSize; - - stream << wireData.m_VerticeGrouprSizes; - stream << wireData.m_VerticeGroupOffseti; - stream << wireData.m_VerticeGroupId; - stream << wireData.m_VerticeGroupCount; - - // New version Data - stream << wireData.colorVector(); - stream << wireData.m_ColorSize; - - return stream; -} - -QDataStream &operator>>(QDataStream &stream, GLC_WireData &wireData) -{ - quint32 chunckId; - stream >> chunckId; - Q_ASSERT((chunckId == GLC_WireData::m_ChunkId) || chunckId == 0xA706); - - wireData.clear(); - stream >> wireData.m_NextPrimitiveLocalId; - stream >> wireData.m_Positions; - stream >> wireData.m_PositionSize; - - stream >> wireData.m_VerticeGrouprSizes; - stream >> wireData.m_VerticeGroupOffseti; - stream >> wireData.m_VerticeGroupId; - stream >> wireData.m_VerticeGroupCount; - - if (chunckId == GLC_WireData::m_ChunkId) - { - // New version Data - stream >> wireData.m_Colors; - stream >> wireData.m_ColorSize; - } - - return stream; -} diff --git a/ground/gcs/src/libs/glc_lib/geometry/glc_wiredata.h b/ground/gcs/src/libs/glc_lib/geometry/glc_wiredata.h deleted file mode 100644 index b4b384c72..000000000 --- a/ground/gcs/src/libs/glc_lib/geometry/glc_wiredata.h +++ /dev/null @@ -1,228 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_wiredata.h Interface for the GLC_WireData class. - -#ifndef GLC_WIREDATA_H_ -#define GLC_WIREDATA_H_ - -#include -#include - -#include "../glc_global.h" -#include "../glc_boundingbox.h" -#include "../shading/glc_renderproperties.h" - -#include "../glc_config.h" -////////////////////////////////////////////////////////////////////// -//! \class GLC_WireData -/*! \brief GLC_WireData : Contains geometries's wire data - */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_WireData -{ - friend GLC_LIB_EXPORT QDataStream &operator<<(QDataStream &, const GLC_WireData &); - friend GLC_LIB_EXPORT QDataStream &operator>>(QDataStream &, GLC_WireData &); - - //! Enum of VBO TYPE - enum VboType - { - GLC_Vertex= 30, - GLC_Color, - GLC_Index - }; - -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Construct a empty wire data - GLC_WireData(); - - //! Construct wire data from the given wire data - GLC_WireData(const GLC_WireData&); - - //! Copy the given wire data in this wire data - GLC_WireData& operator=(const GLC_WireData&); - - //! Destructor - virtual ~GLC_WireData(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return this wire data class Chunk ID - static quint32 chunckID(); - - //! Return this wire data Position Vector - GLfloatVector positionVector() const; - - //! Return the color Vector - GLfloatVector colorVector() const; - - //! Return the unique index vector - QVector indexVector() const; - - //! Return true if this wire data is empty - inline bool isEmpty() const - {return ((m_PositionSize == 0) && m_Positions.isEmpty());} - - //! Return this wire data bounding box - GLC_BoundingBox& boundingBox(); - - //! Return the number of vertice group - inline int verticeGroupCount() const - {return m_VerticeGroupCount;} - - //! Return the vertice group offset from the given index - inline GLuint verticeGroupOffset(int index) const - {return m_VerticeGroupOffseti.at(index);} - - //! Return the vertice group size from the given index - inline GLsizei verticeGroupSize(int index) const - {return m_VerticeGrouprSizes.at(index);} - - //! Return true if this wire data use indexed colors - inline bool useIndexdColors() const - {return (m_ColorSize > 0) || (m_Colors.size() > 0);} -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Add a Polyline to this wire and returns its id if id are managed - GLC_uint addVerticeGroup(const GLfloatVector&); - - //! Add Colors - inline void addColors(const GLfloatVector& colors) - {m_Colors+= colors;} - - //! Clear the content of this wire Data and makes it empty - void clear(); - - //! Copy VBO to the Client Side - void copyVboToClientSide(); - - //! Release client VBO - void releaseVboClientSide(bool update= false); - - //! Set VBO usage - void setVboUsage(bool usage); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Make this wire data a VBO - void finishVbo(); - - //! Set vbo usage of this wire data - void useVBO(GLC_WireData::VboType type, bool usage); - - //! Render this wire data using Opengl - /*! The mode can be : GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP GL_LINES*/ - void glDraw(const GLC_RenderProperties&, GLenum mode); - -private: - - //! Fill this wire data VBO from memmory - void fillVBOs(); - - //! Built index - void buidIndex(); - - //! Activate VBO and IBO - void activateVboAndIbo(); - - //! Finish offset - void finishOffset(); -//@} - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - //! VBO ID - QGLBuffer m_VerticeBuffer; - - //! The next primitive local id - GLC_uint m_NextPrimitiveLocalId; - - //! Vertex Position Vector - GLfloatVector m_Positions; - - //! Color Buffer - QGLBuffer m_ColorBuffer; - - //! Color index - GLfloatVector m_Colors; - - //! The Index Buffer - QGLBuffer m_IndexBuffer; - - //! The Index Vector - QVector m_IndexVector; - - //! The size of the VBO - int m_PositionSize; - - //! The size of Color VBO - int m_ColorSize; - - //! Wire data bounding box - GLC_BoundingBox* m_pBoundingBox; - - //! Vector of Vertice group size - IndexSizes m_VerticeGrouprSizes; - - //! Vector of vertice group offset - OffsetVectori m_VerticeGroupOffseti; - - //! VBO Vector of vertice group offset - OffsetVector m_VerticeGroupOffset; - - //! Vertice groups id - QList m_VerticeGroupId; - - //! The number of vertice group - int m_VerticeGroupCount; - - //! VBO usage - bool m_UseVbo; - - //! Class chunk id - static quint32 m_ChunkId; -}; - -//! Non-member stream operator -GLC_LIB_EXPORT QDataStream &operator<<(QDataStream &, const GLC_WireData &); -GLC_LIB_EXPORT QDataStream &operator>>(QDataStream &, GLC_WireData &); - -#endif /* GLC_WIREDATA_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/glc_boundingbox.cpp b/ground/gcs/src/libs/glc_lib/glc_boundingbox.cpp deleted file mode 100644 index 83f9e0b78..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_boundingbox.cpp +++ /dev/null @@ -1,234 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_boundingbox.cpp implementation of the GLC_BoundingBox class. - -#include "glc_boundingbox.h" -#include "maths/glc_matrix4x4.h" - -quint32 GLC_BoundingBox::m_ChunkId= 0xA707; - -////////////////////////////////////////////////////////////////////// -// Constructor Destructor -////////////////////////////////////////////////////////////////////// - -GLC_BoundingBox::GLC_BoundingBox() -: m_Lower(0, 0, 0) -, m_Upper(0, 0, 0) -, m_IsEmpty(true) -{ - -} - -GLC_BoundingBox::GLC_BoundingBox(const GLC_BoundingBox& boundingBox) -: m_Lower(boundingBox.m_Lower) -, m_Upper(boundingBox.m_Upper) -, m_IsEmpty(boundingBox.m_IsEmpty) -{ -} - -GLC_BoundingBox::GLC_BoundingBox(const GLC_Point3d& lower, const GLC_Point3d& upper) -: m_Lower(lower) -, m_Upper(upper) -, m_IsEmpty(false) -{ - -} - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -quint32 GLC_BoundingBox::chunckID() -{ - return m_ChunkId; -} - -bool GLC_BoundingBox::intersect(const GLC_Point3d& point) const -{ - if (!m_IsEmpty) - { - bool result= (point.x() < m_Upper.x()) && (point.y() < m_Upper.y()) - && (point.z() < m_Upper.z()) && (point.x() > m_Lower.x()) - && (point.y() > m_Lower.y()) && (point.z() > m_Lower.z()); - - return result; - } - else - { - return false; - } -} - -bool GLC_BoundingBox::intersectBoundingSphere(const GLC_Point3d& point) const -{ - const double distance= (center() - point).length(); - return distance < boundingSphereRadius(); -} - -bool GLC_BoundingBox::intersectBoundingSphere(const GLC_BoundingBox& boundingSphere) const -{ - const double distance= (center() - boundingSphere.center()).length(); - return distance < (boundingSphereRadius() + boundingSphere.boundingSphereRadius()); -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -GLC_BoundingBox& GLC_BoundingBox::combine(const GLC_Point3d& point) -{ - if (m_IsEmpty) - { - m_Lower= point; - m_Upper= point; - m_IsEmpty= false; - } - else - { - double lowerX= qMin(point.x(), m_Lower.x()); - double lowerY= qMin(point.y(), m_Lower.y()); - double lowerZ= qMin(point.z(), m_Lower.z()); - m_Lower.setVect(lowerX, lowerY, lowerZ); - - double upperX= qMax(point.x(), m_Upper.x()); - double upperY= qMax(point.y(), m_Upper.y()); - double upperZ= qMax(point.z(), m_Upper.z()); - m_Upper.setVect(upperX, upperY, upperZ); - } - return *this; -} - -GLC_BoundingBox& GLC_BoundingBox::combine(const GLC_Point3df& pointf) -{ - GLC_Point3d point(pointf); - if (m_IsEmpty) - { - m_Lower= point; - m_Upper= point; - m_IsEmpty= false; - } - else - { - double lowerX= qMin(point.x(), m_Lower.x()); - double lowerY= qMin(point.y(), m_Lower.y()); - double lowerZ= qMin(point.z(), m_Lower.z()); - m_Lower.setVect(lowerX, lowerY, lowerZ); - - double upperX= qMax(point.x(), m_Upper.x()); - double upperY= qMax(point.y(), m_Upper.y()); - double upperZ= qMax(point.z(), m_Upper.z()); - m_Upper.setVect(upperX, upperY, upperZ); - } - return *this; -} - -GLC_BoundingBox& GLC_BoundingBox::combine(const GLC_BoundingBox& box) -{ - if (m_IsEmpty && !box.m_IsEmpty) - { - m_Lower= box.m_Lower; - m_Upper= box.m_Upper; - m_IsEmpty= box.m_IsEmpty; - } - else if (! box.m_IsEmpty) - { - double lowerX= qMin(box.m_Lower.x(), m_Lower.x()); - double lowerY= qMin(box.m_Lower.y(), m_Lower.y()); - double lowerZ= qMin(box.m_Lower.z(), m_Lower.z()); - m_Lower.setVect(lowerX, lowerY, lowerZ); - - double upperX= qMax(box.m_Upper.x(), m_Upper.x()); - double upperY= qMax(box.m_Upper.y(), m_Upper.y()); - double upperZ= qMax(box.m_Upper.z(), m_Upper.z()); - m_Upper.setVect(upperX, upperY, upperZ); - } - - return *this; -} - -GLC_BoundingBox& GLC_BoundingBox::transform(const GLC_Matrix4x4& matrix) -{ - if (!m_IsEmpty) - { - // Compute Transformed BoundingBox Corner - GLC_Point3d corner1(m_Lower); - GLC_Point3d corner7(m_Upper); - GLC_Point3d corner2(corner7.x(), corner1.y(), corner1.z()); - GLC_Point3d corner3(corner7.x(), corner7.y(), corner1.z()); - GLC_Point3d corner4(corner1.x(), corner7.y(), corner1.z()); - GLC_Point3d corner5(corner1.x(), corner1.y(), corner7.z()); - GLC_Point3d corner6(corner7.x(), corner1.y(), corner7.z()); - GLC_Point3d corner8(corner1.x(), corner7.y(), corner7.z()); - - corner1 = (matrix * corner1); - corner2 = (matrix * corner2); - corner3 = (matrix * corner3); - corner4 = (matrix * corner4); - corner5 = (matrix * corner5); - corner6 = (matrix * corner6); - corner7 = (matrix * corner7); - corner8 = (matrix * corner8); - - // Compute the new BoundingBox - GLC_BoundingBox boundingBox; - boundingBox.combine(corner1); - boundingBox.combine(corner2); - boundingBox.combine(corner3); - boundingBox.combine(corner4); - boundingBox.combine(corner5); - boundingBox.combine(corner6); - boundingBox.combine(corner7); - boundingBox.combine(corner8); - - m_Lower= boundingBox.m_Lower; - m_Upper= boundingBox.m_Upper; - } - - return *this; -} - -QDataStream &operator<<(QDataStream &stream, const GLC_BoundingBox &bBox) -{ - quint32 chunckId= GLC_BoundingBox::m_ChunkId; - stream << chunckId; - - stream << bBox.m_IsEmpty; - stream << bBox.m_Lower; - stream << bBox.m_Upper; - - return stream; -} - -QDataStream &operator>>(QDataStream &stream, GLC_BoundingBox &bBox) -{ - quint32 chunckId; - stream >> chunckId; - Q_ASSERT(chunckId == GLC_BoundingBox::m_ChunkId); - - stream >> bBox.m_IsEmpty; - stream >> bBox.m_Lower; - stream >> bBox.m_Upper; - - return stream; -} - diff --git a/ground/gcs/src/libs/glc_lib/glc_boundingbox.h b/ground/gcs/src/libs/glc_lib/glc_boundingbox.h deleted file mode 100644 index 9a3c7fb79..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_boundingbox.h +++ /dev/null @@ -1,193 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_boundingbox.h interface for the GLC_BoundingBox class. - -#ifndef GLC_BOUNDINGBOX_ -#define GLC_BOUNDINGBOX_ - -#include "maths/glc_vector3d.h" -#include "maths/glc_utils_maths.h" -#include "maths/glc_matrix4x4.h" -#include -#include "glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_BoundingBox -/*! \brief GLC_BoundingBox : Geometry bounding box*/ - -/*! An GLC_BoundingBox is a non oriented bounding box -*/ - -////////////////////////////////////////////////////////////////////// - -class GLC_LIB_EXPORT GLC_BoundingBox -{ - friend GLC_LIB_EXPORT QDataStream &operator<<(QDataStream &, const GLC_BoundingBox &); - friend GLC_LIB_EXPORT QDataStream &operator>>(QDataStream &, GLC_BoundingBox &); - -////////////////////////////////////////////////////////////////////// -/*! @name Constructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Construct an empty bounding box - GLC_BoundingBox(); - - //! Construct a bounding box from the given bounding box - GLC_BoundingBox(const GLC_BoundingBox& boundingBox); - - //! Construct a bounding box from the given 3d point - GLC_BoundingBox(const GLC_Point3d& lower, const GLC_Point3d& upper); - -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return this class Chunk ID - static quint32 chunckID(); - - //! Return true if this bounding box is empty - bool isEmpty(void) const - { - return m_IsEmpty; - } - - //! Return true if the given 3d point intersect this bounding box - bool intersect(const GLC_Point3d& point) const; - - //! Return true if the given bounding box intersect this bounding box - inline bool intersect(const GLC_BoundingBox& boundingBox) const; - - //! Return true if the given 3d point intersect this bounding sphere of bounding box - bool intersectBoundingSphere(const GLC_Point3d&) const; - - //! Return true if the given bounding sphere of bounding box intersect the bounding sphere of box bounding box - bool intersectBoundingSphere(const GLC_BoundingBox&) const; - - //! Return the lower corner of this bounding box - inline const GLC_Point3d& lowerCorner() const - {return m_Lower;} - - //! Return the upper corner of this bounding box - inline const GLC_Point3d& upperCorner() const - {return m_Upper;} - - //! Return the center of this bounding box - inline GLC_Point3d center() const; - - //! Return the radius of this bounding sphere of bounding box - inline double boundingSphereRadius() const - {return GLC_Vector3d(m_Lower - m_Upper).length() / 2.0;} - - //! Return true if this bounding box is equal of the given bounding box - inline bool operator == (const GLC_BoundingBox& boundingBox); - - //! Return true if this bounding box is not equal of the given bounding box - inline bool operator != (const GLC_BoundingBox& boundingBox) - {return !(*this == boundingBox);} - - //! Return the length off this bounding box on x axis - inline double xLength() const - {return fabs(m_Upper.x() - m_Lower.x());} - - //! Return the length off this bounding box on y axis - inline double yLength() const - {return fabs(m_Upper.y() - m_Lower.y());} - - //! Return the length off this bounding box on z axis - inline double zLength() const - {return fabs(m_Upper.z() - m_Lower.z());} - - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Combine this bounding Box with the given 3d point and return a reference of this bounding box - GLC_BoundingBox& combine(const GLC_Point3d& point); - - //! Combine this bounding Box with the given 3d point and return a reference of this bounding box - GLC_BoundingBox& combine(const GLC_Point3df& point); - - //! Combine this bounding Box with the given bounding box and return a reference of this bounding box - GLC_BoundingBox& combine(const GLC_BoundingBox& box); - - //! Transform this bounding Box with the given matrix and return a reference of this bounding box - GLC_BoundingBox& transform(const GLC_Matrix4x4& matrix); - -//@} - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - //! Lower corner 3d point - GLC_Point3d m_Lower; - - //! Upper corner 3d point - GLC_Point3d m_Upper; - - //! Flag to know if this bounding box is empty - bool m_IsEmpty; - - //! This class chunk id - static quint32 m_ChunkId; -}; - -//! Non-member stream operator -GLC_LIB_EXPORT QDataStream &operator<<(QDataStream &, const GLC_BoundingBox &); -GLC_LIB_EXPORT QDataStream &operator>>(QDataStream &, GLC_BoundingBox &); - -// Return true if the given bounding box intersect this bounding box -bool GLC_BoundingBox::intersect(const GLC_BoundingBox& boundingBox) const -{ - // Distance between bounding box center - GLC_Vector3d thisCenter= center(); - GLC_Vector3d otherCenter= boundingBox.center(); - const double distanceX= fabs(thisCenter.x() - otherCenter.x()); - const double distanceY= fabs(thisCenter.y() - otherCenter.y()); - const double distanceZ= fabs(thisCenter.z() - otherCenter.z()); - - bool intersect= distanceX < ((xLength() + boundingBox.xLength()) * 0.5); - intersect= intersect && (distanceY < ((yLength() + boundingBox.yLength()) * 0.5)); - intersect= intersect && (distanceZ < ((zLength() + boundingBox.zLength()) * 0.5)); - return intersect; -} - -bool GLC_BoundingBox::operator == (const GLC_BoundingBox& box) -{ - return (m_Lower == box.m_Lower) && (m_Upper == box.m_Upper); -} - -GLC_Point3d GLC_BoundingBox::center(void) const -{ - GLC_Vector3d vectResult = (m_Lower + m_Upper) * 0.5; - return vectResult; -} - -#endif /*GLC_BOUNDINGBOX_*/ diff --git a/ground/gcs/src/libs/glc_lib/glc_cachemanager.cpp b/ground/gcs/src/libs/glc_lib/glc_cachemanager.cpp deleted file mode 100644 index a644c9be6..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_cachemanager.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_cachemanager.cpp implementation of the GLC_CacheManager class. - -#include "glc_cachemanager.h" -#include - - -GLC_CacheManager::GLC_CacheManager(const QString& path) -: m_Dir() -, m_UseCompression(true) -, m_CompressionLevel(-1) -{ - if (! path.isEmpty()) - { - QFileInfo pathInfo(path); - if (pathInfo.isDir() && pathInfo.isReadable()) - { - m_Dir.setPath(path); - } - } -} - -// Copy constructor -GLC_CacheManager::GLC_CacheManager(const GLC_CacheManager& cacheManager) -:m_Dir(cacheManager.m_Dir) -, m_UseCompression(cacheManager.m_UseCompression) -, m_CompressionLevel(cacheManager.m_CompressionLevel) -{ - -} - -// Assignement operator -GLC_CacheManager& GLC_CacheManager::operator=(const GLC_CacheManager& cacheManager) -{ - m_Dir= cacheManager.m_Dir; - m_UseCompression= cacheManager.m_UseCompression; - m_CompressionLevel= cacheManager.m_CompressionLevel; - - return *this; -} - -GLC_CacheManager::~GLC_CacheManager() -{ - -} - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -// Return true if the cache is is readable -bool GLC_CacheManager::isReadable() const -{ - bool isReadable= true; - isReadable= isReadable && m_Dir.exists(); - QFileInfo dirInfo(m_Dir.absolutePath()); - isReadable= isReadable && dirInfo.isReadable(); - - return isReadable; - -} - -// Return true if the cache is writable -bool GLC_CacheManager::isWritable() const -{ - bool isWritable= true; - isWritable= isWritable && m_Dir.exists(); - QFileInfo dirInfo(m_Dir.absolutePath()); - isWritable= isWritable && dirInfo.isWritable(); - - return isWritable; -} - -// Return True if the specified file is cashed in the specified context -bool GLC_CacheManager::isCashed(const QString& context, const QString& fileName) const -{ - if (! isReadable()) return false; - - QFileInfo fileInfo(m_Dir.absolutePath() + QDir::separator() + context + QDir::separator() + fileName + '.' + GLC_BSRep::suffix()); - return fileInfo.exists(); -} - -// Return True if the cached file is usable -bool GLC_CacheManager::isUsable(const QDateTime& timeStamp, const QString& context, const QString& fileName) const -{ - bool result= isCashed(context, fileName); - - if (result) - { - QFileInfo cacheFileInfo(m_Dir.absolutePath() + QDir::separator() + context + QDir::separator() + fileName+ '.' + GLC_BSRep::suffix()); - //result= result && (timeStamp == cacheFileInfo.lastModified()); - result= result && cacheFileInfo.isReadable(); - if (result) - { - GLC_BSRep binaryRep; - binaryRep.setAbsoluteFileName(cacheFileInfo.absoluteFilePath()); - result= result && binaryRep.isUsable(timeStamp); - } - } - - return result; -} - -// Return the binary serialized representation of the specified file -GLC_BSRep GLC_CacheManager::binary3DRep(const QString& context, const QString& fileName) const -{ - const QString absoluteFileName(m_Dir.absolutePath() + QDir::separator() + context + QDir::separator() + fileName + '.' + GLC_BSRep::suffix()); - GLC_BSRep binaryRep(absoluteFileName); - - return binaryRep; -} - -// Add the specified file in the cache -bool GLC_CacheManager::addToCache(const QString& context, const GLC_3DRep& rep) -{ - Q_ASSERT(!rep.fileName().isEmpty()); - bool addedToCache= isWritable(); - if (addedToCache) - { - QFileInfo contextCacheInfo(m_Dir.absolutePath() + QDir::separator() + context); - if (! contextCacheInfo.exists()) - { - addedToCache= m_Dir.mkdir(context); - } - if (addedToCache) - { - QString repFileName= rep.fileName(); - if (glc::isArchiveString(repFileName)) - { - repFileName= glc::archiveEntryFileName(repFileName); - } - else - { - repFileName= QFileInfo(repFileName).fileName(); - } - const QString binaryFileName= contextCacheInfo.filePath() + QDir::separator() + repFileName; - GLC_BSRep binariRep(binaryFileName, m_UseCompression); - binariRep.setCompressionLevel(m_CompressionLevel); - addedToCache= binariRep.save(rep); - } - } - - return addedToCache; -} - -////////////////////////////////////////////////////////////////////// -//Set Functions -////////////////////////////////////////////////////////////////////// - -// Set the cache file path -bool GLC_CacheManager::setCachePath(const QString& path) -{ - QFileInfo pathInfo(path); - bool result= pathInfo.isDir(); - result= result && pathInfo.isReadable(); - - if (result) - { - m_Dir.setPath(path); - } - return result; -} - diff --git a/ground/gcs/src/libs/glc_lib/glc_cachemanager.h b/ground/gcs/src/libs/glc_lib/glc_cachemanager.h deleted file mode 100644 index 6d91ad2d4..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_cachemanager.h +++ /dev/null @@ -1,136 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_cachemanager.h interface for the GLC_CacheManager class. - -#ifndef GLC_CACHEMANAGER_H_ -#define GLC_CACHEMANAGER_H_ - -#include -#include -#include -#include "geometry/glc_bsrep.h" - -#include "glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_CacheManager -/*! \brief GLC_CacheManager : The 3D Rep Binary cache manager*/ - -/*! By default the binary rep are compressed with a default - * compression level - */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_CacheManager -{ -public: -////////////////////////////////////////////////////////////////////// -/*! @name Constructor */ -//@{ -////////////////////////////////////////////////////////////////////// - //! Default constructor - GLC_CacheManager(const QString& path= QString()); - - //! Copy constructor - GLC_CacheManager(const GLC_CacheManager&); - - //! Assignement operator - GLC_CacheManager& operator=(const GLC_CacheManager&); - - //! Destructor - virtual ~GLC_CacheManager(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the cache absolute path - inline QString absolutePath() const - {return m_Dir.absolutePath();} - - //! Return true if the cache dir exists - inline bool exists() const - {return m_Dir.exists();} - - //! Return true if the cache is is readable - bool isReadable() const; - - //! Return true if the cache is is writable - bool isWritable() const; - - //! Return True if the specified file is cashed in the specified context - bool isCashed(const QString&, const QString&) const; - - //! Return True if the cached file is usable - bool isUsable(const QDateTime&, const QString&, const QString&) const; - - //! Return the binary serialized representation of the specified file - GLC_BSRep binary3DRep(const QString&, const QString&) const; - - //! Add the specified file in the cache - bool addToCache(const QString&, const GLC_3DRep&); - - //! Return true if the compression is used - inline bool compressionIsUsed() const - {return m_UseCompression;} - - //! Return the cache compression level - inline int compressionLevel() const - {return m_CompressionLevel;} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Set the cache file path - bool setCachePath(const QString&); - - //! Set the cache compression usage - inline void setCompressionUsage(bool use) - {m_UseCompression= use;} - - //! Set the cache compression level - inline void setCompressionLevel(int level) - {m_CompressionLevel= level;} -//@} - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - - //! The cache directory - QDir m_Dir; - - //! Compress Data - bool m_UseCompression; - - //! The compression level - int m_CompressionLevel; -}; - -#endif /* GLC_CACHEMANAGER_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/glc_config.h b/ground/gcs/src/libs/glc_lib/glc_config.h deleted file mode 100644 index 45646d152..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_config.h +++ /dev/null @@ -1,44 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_config.h the GLC_lib configuration file - -#ifndef GLC_CONFIG_H -#define GLC_CONFIG_H - -#include - -// Dynamic library export macros -#ifndef GLC_LIB_STATIC -# ifdef CREATE_GLC_LIB_DLL -# define GLC_LIB_EXPORT Q_DECL_EXPORT -# else -# define GLC_LIB_EXPORT Q_DECL_IMPORT -# endif -#endif - -// For static library, this macro is empty -#ifndef GLC_LIB_EXPORT -# define GLC_LIB_EXPORT -#endif - -#endif // GLC_CONFIG_H diff --git a/ground/gcs/src/libs/glc_lib/glc_context.cpp b/ground/gcs/src/libs/glc_lib/glc_context.cpp deleted file mode 100644 index 48c43b9fc..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_context.cpp +++ /dev/null @@ -1,289 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_context.cpp implementation of the GLC_Context class. - -#include "glc_context.h" -#include "glc_contextmanager.h" -#include "shading/glc_shader.h" - -#include "glc_state.h" - -GLC_Context* GLC_Context::m_pCurrentContext= NULL; - -GLC_Context::GLC_Context(const QGLFormat& format) -: QGLContext(format) -, m_CurrentMatrixMode() -, m_MatrixStackHash() -, m_ContextSharedData() -, m_UniformShaderData() -, m_LightingIsEnable() -{ - qDebug() << "GLC_Context::GLC_Context"; - GLC_ContextManager::instance()->addContext(this); - init(); -} - -GLC_Context::~GLC_Context() -{ - qDebug() << "GLC_Context::~GLC_Context()"; - GLC_ContextManager::instance()->remove(this); - QHash* >::iterator iStack= m_MatrixStackHash.begin(); - while (iStack != m_MatrixStackHash.end()) - { - delete iStack.value(); - ++iStack; - } -} - - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -GLC_Context* GLC_Context::current() -{ - return m_pCurrentContext; -} - -////////////////////////////////////////////////////////////////////// -// OpenGL Functions -////////////////////////////////////////////////////////////////////// -void GLC_Context::glcMatrixMode(GLenum mode) -{ - Q_ASSERT(QGLContext::isValid()); - Q_ASSERT((mode == GL_MODELVIEW) || (mode == GL_PROJECTION)); - - m_CurrentMatrixMode= mode; -#ifdef GLC_OPENGL_ES_2 - -#else - glMatrixMode(m_CurrentMatrixMode); -#endif - -} - -void GLC_Context::glcLoadIdentity() -{ - Q_ASSERT(QGLContext::isValid()); - m_MatrixStackHash.value(m_CurrentMatrixMode)->top().setToIdentity(); - -#ifdef GLC_OPENGL_ES_2 - m_UniformShaderData.setModelViewProjectionMatrix(m_MatrixStackHash.value(GL_MODELVIEW)->top(), m_MatrixStackHash.value(GL_PROJECTION)->top()); -#else - if (GLC_Shader::hasActiveShader()) - { - m_UniformShaderData.setModelViewProjectionMatrix(m_MatrixStackHash.value(GL_MODELVIEW)->top(), m_MatrixStackHash.value(GL_PROJECTION)->top()); - } - glLoadIdentity(); -#endif - -} - -void GLC_Context::glcPushMatrix() -{ - Q_ASSERT(QGLContext::isValid()); - m_MatrixStackHash.value(m_CurrentMatrixMode)->push(m_MatrixStackHash.value(m_CurrentMatrixMode)->top()); - -#ifndef GLC_OPENGL_ES_2 - glPushMatrix(); -#endif - -} - -void GLC_Context::glcPopMatrix() -{ - Q_ASSERT(QGLContext::isValid()); - m_MatrixStackHash.value(m_CurrentMatrixMode)->pop(); - -#ifdef GLC_OPENGL_ES_2 - this->glcLoadMatrix(m_MatrixStackHash.value(m_CurrentMatrixMode)->top()); -#else - if (GLC_Shader::hasActiveShader()) - { - this->glcLoadMatrix(m_MatrixStackHash.value(m_CurrentMatrixMode)->top()); - } - glPopMatrix(); -#endif - -} - - -void GLC_Context::glcLoadMatrix(const GLC_Matrix4x4& matrix) -{ - m_MatrixStackHash.value(m_CurrentMatrixMode)->top()= matrix; - -#ifdef GLC_OPENGL_ES_2 - m_UniformShaderData.setModelViewProjectionMatrix(m_MatrixStackHash.value(GL_MODELVIEW)->top(), m_MatrixStackHash.value(GL_PROJECTION)->top()); -#else - if (GLC_Shader::hasActiveShader()) - { - m_UniformShaderData.setModelViewProjectionMatrix(m_MatrixStackHash.value(GL_MODELVIEW)->top(), m_MatrixStackHash.value(GL_PROJECTION)->top()); - } - ::glLoadMatrixd(matrix.getData()); -#endif - -} - -void GLC_Context::glcMultMatrix(const GLC_Matrix4x4& matrix) -{ - const GLC_Matrix4x4 current= m_MatrixStackHash.value(m_CurrentMatrixMode)->top(); - m_MatrixStackHash.value(m_CurrentMatrixMode)->top()= m_MatrixStackHash.value(m_CurrentMatrixMode)->top() * matrix; -#ifdef GLC_OPENGL_ES_2 - m_UniformShaderData.setModelViewProjectionMatrix(m_MatrixStackHash.value(GL_MODELVIEW)->top(), m_MatrixStackHash.value(GL_PROJECTION)->top()); -#else - if (GLC_Shader::hasActiveShader()) - { - m_UniformShaderData.setModelViewProjectionMatrix(m_MatrixStackHash.value(GL_MODELVIEW)->top(), m_MatrixStackHash.value(GL_PROJECTION)->top()); - } - ::glMultMatrixd(matrix.getData()); -#endif - -} - -void GLC_Context::glcScaled(double x, double y, double z) -{ - GLC_Matrix4x4 scale; - scale.setMatScaling(x, y, z); - glcMultMatrix(scale); -} - -void GLC_Context::glcOrtho(double left, double right, double bottom, double top, double nearVal, double farVal) -{ - GLC_Matrix4x4 orthoMatrix; - double* m= orthoMatrix.setData(); - - const double tx= - (right + left) / (right - left); - const double ty= - (top + bottom) / (top - bottom); - const double tz= - (farVal + nearVal) / (farVal - nearVal); - m[0]= 2.0 / (right - left); - m[5]= 2.0 / (top - bottom); - m[10]= -2.0 / (farVal - nearVal); - m[12]= tx; - m[13]= ty; - m[14]= tz; - - glcMultMatrix(orthoMatrix); -} - -void GLC_Context::glcFrustum(double left, double right, double bottom, double top, double nearVal, double farVal) -{ - GLC_Matrix4x4 perspMatrix; - double* m= perspMatrix.setData(); - - const double a= (right + left) / (right - left); - const double b= (top + bottom) / (top - bottom); - const double c= - (farVal + nearVal) / (farVal - nearVal); - const double d= - (2.0 * farVal * nearVal) / (farVal - nearVal); - - m[0]= (2.0 * nearVal) / (right - left); - m[5]= (2.0 * nearVal) / (top - bottom); - m[8]= a; - m[9]= b; - m[10]= c; - m[11]= -1.0; - m[14]= d; - m[15]= 0.0; - - glcMultMatrix(perspMatrix); -} - -void GLC_Context::glcEnableLighting(bool enable) -{ - if (enable != m_LightingIsEnable.top()) - { - m_LightingIsEnable.top()= enable; - -#ifdef GLC_OPENGL_ES_2 - - m_UniformShaderData.setLightingState(m_LightingIsEnable); -#else - if (GLC_Shader::hasActiveShader()) - { - m_UniformShaderData.setLightingState(m_LightingIsEnable.top()); - } - if (m_LightingIsEnable.top()) ::glEnable(GL_LIGHTING); - else ::glDisable(GL_LIGHTING); -#endif - - } -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -void GLC_Context::makeCurrent() -{ - QGLContext::makeCurrent(); - if (!GLC_State::isValid()) - { - GLC_State::init(); - } - GLC_ContextManager::instance()->setCurrent(this); - m_pCurrentContext= this; -} - -void GLC_Context::doneCurrent() -{ - QGLContext::doneCurrent(); - GLC_ContextManager::instance()->setCurrent(NULL); - m_pCurrentContext= NULL; -} - -bool GLC_Context::chooseContext(const QGLContext* shareContext) -{ - qDebug() << "GLC_Context::chooseContext"; - const bool success= QGLContext::chooseContext(shareContext); - if (!success) - { - qDebug() << "enable to create context " << this; - } - else if (NULL != shareContext) - { - GLC_Context* pContext= const_cast(dynamic_cast(shareContext)); - Q_ASSERT(NULL != pContext); - m_ContextSharedData= pContext->m_ContextSharedData; - } - else - { - m_ContextSharedData= QSharedPointer(new GLC_ContextSharedData()); - } - - return success; -} - -////////////////////////////////////////////////////////////////////// -// Private services Functions -////////////////////////////////////////////////////////////////////// -void GLC_Context::init() -{ - QStack* pStack1= new QStack(); - pStack1->push(GLC_Matrix4x4()); - m_MatrixStackHash.insert(GL_MODELVIEW, pStack1); - - QStack* pStack2= new QStack(); - pStack2->push(GLC_Matrix4x4()); - m_MatrixStackHash.insert(GL_PROJECTION, pStack2); - - m_LightingIsEnable.push(false); -} - diff --git a/ground/gcs/src/libs/glc_lib/glc_context.h b/ground/gcs/src/libs/glc_lib/glc_context.h deleted file mode 100644 index da3378db8..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_context.h +++ /dev/null @@ -1,196 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_context.h interface for the GLC_Context class. - -#ifndef GLC_CONTEXT_H_ -#define GLC_CONTEXT_H_ - -#include -#include -#include -#include -#include - -#include "glc_config.h" -#include "maths/glc_matrix4x4.h" -#include "glc_contextshareddata.h" -#include "glc_uniformshaderdata.h" - -class GLC_ContextSharedData; - -// OpenGL ES define -#if defined(QT_OPENGL_ES_2) -#define GLC_OPENGL_ES_2 1 - -#define GL_MODELVIEW 0x1700 -#define GL_PROJECTION 0x1701 -#endif - - -//#define GLC_OPENGL_ES_2 1 - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Context -/*! \brief GLC_Context : Encapsulates OpenGL rendering context*/ - -/*! The GLC_Context class store all GLC state associated to an OpenGL rendering context. - * This class is also used to simplified OpenGL and OpenGL-ES interoperability - */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_Context : public QGLContext -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// - -public: - GLC_Context(const QGLFormat& format); - virtual ~GLC_Context(); - -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the current context - static GLC_Context* current(); - - //! Return the model view matrix - inline GLC_Matrix4x4 modelViewMatrix() const - {Q_ASSERT(m_MatrixStackHash.contains(GL_MODELVIEW)); return m_MatrixStackHash.value(GL_MODELVIEW)->top();} - - //! Return the projection matrix - inline GLC_Matrix4x4 projectionMatrix() const - {Q_ASSERT(m_MatrixStackHash.contains(GL_PROJECTION)); return m_MatrixStackHash.value(GL_PROJECTION)->top();} - - //! Return lighting enable state - inline bool lightingIsEnable() const - {return m_LightingIsEnable.top();} -//@} -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Set the matrix mode - void glcMatrixMode(GLenum mode); - - //! Replace the current matrix with the identity - void glcLoadIdentity(); - - //! push and pop the current matrix stack - void glcPushMatrix(); - void glcPopMatrix(); - - //! Replace the current matrix with the specified matrix - void glcLoadMatrix(const GLC_Matrix4x4& matrix); - - //! Multiply the current matrix with the specified matrix - void glcMultMatrix(const GLC_Matrix4x4& matrix); - - //! Multiply the current matrix by a translation matrix - inline void glcTranslated(double x, double y, double z) - {glcMultMatrix(GLC_Matrix4x4(x, y, z));} - - //! Multiply the current matrix by a general scaling matrix - void glcScaled(double x, double y, double z); - - //! Multiply the current matrix with an orthographic matrix - void glcOrtho(double left, double right, double bottom, double top, double nearVal, double farVal); - - //! Multiply the current matrix by a perspective matrix - void glcFrustum(double left, double right, double bottom, double top, double nearVal, double farVal); - - //! Enable lighting - void glcEnableLighting(bool enable); - -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Make this context the current one - virtual void makeCurrent(); - - //! Make no context to be the current one - virtual void doneCurrent(); - - //! Update uniform variable - inline void updateUniformVariables() - {m_UniformShaderData.updateAll(this);} - -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Private services Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -protected: -//@{ - - virtual bool chooseContext(const QGLContext* shareContext= 0); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Private services Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -private: -//@{ - - //! Init this context state - void init(); -//@} - - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - - //! The current matrix mode - GLenum m_CurrentMatrixMode; - - //! Mapping between matrixMode and matrix stack - QHash* > m_MatrixStackHash; - - //! The context shared data - QSharedPointer m_ContextSharedData; - - //! The uniform data of the current shader - GLC_UniformShaderData m_UniformShaderData; - - //! The current context - static GLC_Context* m_pCurrentContext; - - //! Enable lighting state - QStack m_LightingIsEnable; - - //! Lights enable state - QHash m_LightsEnableState; - -}; - -#endif /* GLC_CONTEXT_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/glc_contextmanager.cpp b/ground/gcs/src/libs/glc_lib/glc_contextmanager.cpp deleted file mode 100644 index d0fbcb7e6..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_contextmanager.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_contextmanager.cpp implementation of the GLC_ContextManager class. - -#include - -#include "glc_contextmanager.h" -#include "glc_state.h" - -GLC_ContextManager* GLC_ContextManager::m_pContextManager= NULL; - -GLC_ContextManager::GLC_ContextManager() -: m_pCurrentContext(NULL) -, m_SetOfContext() -{ - - -} - -GLC_ContextManager::~GLC_ContextManager() -{ - -} - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// -GLC_ContextManager* GLC_ContextManager::instance() -{ - if (NULL == m_pContextManager) - { - m_pContextManager= new GLC_ContextManager(); - } - - return m_pContextManager; -} - -GLC_Context* GLC_ContextManager::currentContext() const -{ - return m_pCurrentContext; -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// -void GLC_ContextManager::addContext(GLC_Context* pContext) -{ - Q_ASSERT(!m_SetOfContext.contains(pContext)); - m_SetOfContext.insert(pContext); -} - -void GLC_ContextManager::remove(GLC_Context* pContext) -{ - Q_ASSERT(m_SetOfContext.contains(pContext)); - m_SetOfContext.remove(pContext); - if (m_pCurrentContext == pContext) - { - m_pCurrentContext= NULL; - } -} - -void GLC_ContextManager::setCurrent(GLC_Context* pContext) -{ - - Q_ASSERT((NULL == pContext) || m_SetOfContext.contains(pContext)); - m_pCurrentContext= pContext; -} - - diff --git a/ground/gcs/src/libs/glc_lib/glc_contextmanager.h b/ground/gcs/src/libs/glc_lib/glc_contextmanager.h deleted file mode 100644 index 7165dd13f..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_contextmanager.h +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_contextmanager.h interface for the GLC_ContextManager class. - -#ifndef GLC_CONTEXTMANAGER_H_ -#define GLC_CONTEXTMANAGER_H_ - -#include - -#include "glc_config.h" - - -class GLC_Context; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_ContextManager -/*! \brief GLC_ContextManager : Manager a set of GLC_Context*/ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_ContextManager -{ -private: - GLC_ContextManager(); -public: - virtual ~GLC_ContextManager(); - -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the unique instance of context manager - static GLC_ContextManager* instance(); - - //! Return the current context - GLC_Context* currentContext() const; - - //! Return true if there is a current context - inline bool currentContextExists() const - {return (NULL != m_pCurrentContext);} - - //! Return true if this manager has context - inline bool hasContext() const - {return !m_SetOfContext.isEmpty();} - -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Add the given context - void addContext(GLC_Context* pContext); - - //! Remove the given context - void remove(GLC_Context* pContext); - - //! Set the current the given context - void setCurrent(GLC_Context* pContext); - -////////////////////////////////////////////////////////////////////// -/*! \name Private services Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -private: -//@{ - -//@} - - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - //! The unique instance of the context manager - static GLC_ContextManager* m_pContextManager; - - //! The current context - GLC_Context* m_pCurrentContext; - - //! The Set of context to manage - QSet m_SetOfContext; -}; - -#endif /* GLC_CONTEXTMANAGER_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/glc_contextshareddata.cpp b/ground/gcs/src/libs/glc_lib/glc_contextshareddata.cpp deleted file mode 100644 index 0c108036e..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_contextshareddata.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_contextshareddata.cpp implementation of the GLC_ContextSharedData class. - -#include - -#include "glc_contextshareddata.h" - -GLC_ContextSharedData::GLC_ContextSharedData() -{ - qDebug() << "GLC_ContextSharedData::GLC_ContextSharedData()"; - -} - -GLC_ContextSharedData::~GLC_ContextSharedData() -{ - qDebug() << "GLC_ContextSharedData::~GLC_ContextSharedData()"; -} diff --git a/ground/gcs/src/libs/glc_lib/glc_contextshareddata.h b/ground/gcs/src/libs/glc_lib/glc_contextshareddata.h deleted file mode 100644 index 8c6640384..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_contextshareddata.h +++ /dev/null @@ -1,36 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_contextshareddata.h interface for the GLC_ContextSharedData class. - -#ifndef GLC_CONTEXTSHAREDDATA_H_ -#define GLC_CONTEXTSHAREDDATA_H_ - -#include "glc_config.h" - -class GLC_LIB_EXPORT GLC_ContextSharedData -{ -public: - GLC_ContextSharedData(); - virtual ~GLC_ContextSharedData(); -}; - -#endif /* GLC_CONTEXTSHAREDDATA_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/glc_errorlog.cpp b/ground/gcs/src/libs/glc_lib/glc_errorlog.cpp deleted file mode 100644 index 230fbf46f..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_errorlog.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -//! \file glc_errorlog.h implementation of the GLC_ErrorLog class. - -#include "glc_errorlog.h" -#include -#include "glc_global.h" -#include - -GLC_ErrorLog* GLC_ErrorLog::m_pErrorLog= NULL; -QMutex GLC_ErrorLog::m_Mutex; - -GLC_ErrorLog::GLC_ErrorLog(const QString& fullLogFileName) -: GLC_Log(fullLogFileName) -{ - -} - -GLC_ErrorLog::~GLC_ErrorLog() -{ - -} - -GLC_ErrorLog* GLC_ErrorLog::instance() -{ - if (NULL == m_pErrorLog) - { - QString fileName(QApplication::applicationName()); - if (fileName.isEmpty()) - { - fileName= "GLC_lib_ErrLog"; - } - else - { - fileName= fileName + "_ErrLog"; - } - QString logFileName(QDir::tempPath() + QDir::separator() + fileName); - m_pErrorLog= new GLC_ErrorLog(logFileName); - m_pErrorLog->writeHeader(); - } - return m_pErrorLog; -} - -bool GLC_ErrorLog::isEmpty() -{ - return (NULL == m_pErrorLog); -} - -void GLC_ErrorLog::addError(const QStringList& errorDescription) -{ - QMutexLocker locker(&m_Mutex); - GLC_ErrorLog::instance()->addSeparator(); - GLC_ErrorLog::instance()->addCurrentTime(); - const int size= errorDescription.size(); - for (int i= 0; i < size; ++i) - { - GLC_ErrorLog::instance()->add(errorDescription.at(i)); - } -} -void GLC_ErrorLog::close() -{ - QMutexLocker locker(&m_Mutex); - delete m_pErrorLog; - m_pErrorLog= NULL; -} - -void GLC_ErrorLog::writeHeader() -{ - QString currentLine; - currentLine= "Error Log file"; - GLC_Log::m_TextStream << currentLine << '\n'; - currentLine= "Application " + QCoreApplication::applicationName(); - GLC_Log::m_TextStream << currentLine << '\n'; - currentLine= QDate::currentDate().toString(Qt::ISODate); - GLC_Log::m_TextStream << currentLine << '\n'; - GLC_Log::m_TextStream.flush(); -} diff --git a/ground/gcs/src/libs/glc_lib/glc_errorlog.h b/ground/gcs/src/libs/glc_lib/glc_errorlog.h deleted file mode 100644 index f28879597..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_errorlog.h +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_errorlog.h interface for the GLC_ErrorLog class. - -#ifndef GLC_ERRORLOG_H_ -#define GLC_ERRORLOG_H_ - -#include "glc_log.h" -#include "glc_config.h" -#include -#include - -////////////////////////////////////////////////////////////////////// -//! \class GLC_ErrorLog -/*! \brief GLC_ErrorLog : handl GLC_lib error log*/ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_ErrorLog : public GLC_Log -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor */ -//@{ -////////////////////////////////////////////////////////////////////// -private: - //! Private constructor - GLC_ErrorLog(const QString& fullLogFileName); -public: - //! Destructor - virtual ~GLC_ErrorLog(); -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the unique instance of error log file - static GLC_ErrorLog* instance(); - - //! Return true if the log is empty - static bool isEmpty(); - -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Add error into the log - static void addError(const QStringList& errorDescription); - - //! Close the log file - static void close(); - -//@} - - -////////////////////////////////////////////////////////////////////// -/*! \name Private services Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Write error Log header - void writeHeader(); - -//@} - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - //! The unique error log instance - static GLC_ErrorLog* m_pErrorLog; - - //! The mutex of this unique log - static QMutex m_Mutex; - -}; - -#endif /* GLC_ERRORLOG_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/glc_exception.cpp b/ground/gcs/src/libs/glc_lib/glc_exception.cpp deleted file mode 100644 index 53a82213f..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_exception.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_exception.cpp implementation of the GLC_Exception class. - -#include "glc_exception.h" - -////////////////////////////////////////////////////////////////////// -// Constructor destructor -////////////////////////////////////////////////////////////////////// - -GLC_Exception::GLC_Exception(const QString &message) -: m_ErrorDescription(message) -{ - GLC_ErrorLog::addError(QStringList(m_ErrorDescription)); -} -GLC_Exception::~GLC_Exception() throw() -{ - -} - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// -//! Return exception description -const char* GLC_Exception::what() const throw() -{ - QString exceptionmsg("GLC_Exception : "); - exceptionmsg.append(m_ErrorDescription); - return exceptionmsg.toLatin1().data(); -} diff --git a/ground/gcs/src/libs/glc_lib/glc_exception.h b/ground/gcs/src/libs/glc_lib/glc_exception.h deleted file mode 100644 index 32447d314..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_exception.h +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_exception.h Interface for the GLC_Exception class. - -#ifndef GLC_EXCEPTION_H_ -#define GLC_EXCEPTION_H_ - -#include -#include -#include "glc_errorlog.h" - -#include "glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Exception -/*! \brief GLC_Exception : Base Class for all GLC_Exception Class - */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_Exception : public std::exception -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Default constructor - GLC_Exception(const QString &message); - - //! Destructor - virtual ~GLC_Exception() throw(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return exception description - virtual const char* what() const throw(); - -//@} - -////////////////////////////////////////////////////////////////////// -// protected members -////////////////////////////////////////////////////////////////////// -protected: - - //! Error description - QString m_ErrorDescription; -}; - -#endif /*GLC_EXCEPTION_H_*/ diff --git a/ground/gcs/src/libs/glc_lib/glc_ext.cpp b/ground/gcs/src/libs/glc_lib/glc_ext.cpp deleted file mode 100644 index ef4a32248..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_ext.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ -//! \file glc_ext.cpp implementation of the GLC Opengl extension functions. - -#include "glc_ext.h" -#include -#include -#include -#include -#include - -#if !defined(Q_OS_MAC) - -// GL_point_parameters Point Sprite -PFNGLPOINTPARAMETERFARBPROC glPointParameterf = NULL; -PFNGLPOINTPARAMETERFVARBPROC glPointParameterfv = NULL; - -#endif - - -// Return true if the extension is supported -bool glc::extensionIsSupported(const QString& extension) -{ - QString glExtension(reinterpret_cast(glGetString(GL_EXTENSIONS))); - return glExtension.contains(extension); -} - -// Return true if VBO extension is succesfully loaded -bool glc::loadVboExtension() -{ - QGLBuffer buffer; - bool result= buffer.create(); - buffer.destroy(); - return result; -} - -// Load GLSL extensions -bool glc::loadGlSlExtension() -{ - return QGLShaderProgram::hasOpenGLShaderPrograms(); -} - -// Load Point Sprite extension -bool glc::loadPointSpriteExtension() -{ - bool result= true; -#if !defined(Q_OS_MAC) && !defined(Q_OS_LINUX) - const QGLContext* pContext= QGLContext::currentContext(); - glPointParameterf = (PFNGLPOINTPARAMETERFARBPROC)pContext->getProcAddress(QLatin1String("glPointParameterf")); - if (!glPointParameterf) qDebug() << "not glPointParameterf"; - glPointParameterfv = (PFNGLPOINTPARAMETERFVARBPROC)pContext->getProcAddress(QLatin1String("glPointParameterfv")); - if (!glPointParameterfv) qDebug() << "not glPointParameterfv"; - - result= glPointParameterf && glPointParameterfv; - -#endif - return result; -} - diff --git a/ground/gcs/src/libs/glc_lib/glc_ext.h b/ground/gcs/src/libs/glc_lib/glc_ext.h deleted file mode 100644 index c8ffc3308..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_ext.h +++ /dev/null @@ -1,56 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ -//! \file glc_ext.h Header of the GLC Opengl extension functions. - -#ifndef GLC_EXT_H_ -#define GLC_EXT_H_ - -#include - -#if !defined(Q_OS_MAC) - -// GL_point_parameters Point Sprite -#include "3rdparty/glext/glext.h" -extern PFNGLPOINTPARAMETERFARBPROC glPointParameterf; -extern PFNGLPOINTPARAMETERFVARBPROC glPointParameterfv; - -#endif - -// Buffer offset used by VBO -#define BUFFER_OFFSET(i) ((char*)NULL + (i)) - - -namespace glc -{ - //! Return true if the extension is supported - bool extensionIsSupported(const QString&); - - //! Load VBO extension - bool loadVboExtension(); - - //! Load GLSL extensions - bool loadGlSlExtension(); - - //! Load Point Sprite extension - bool loadPointSpriteExtension(); -}; -#endif /*GLC_EXT_H_*/ diff --git a/ground/gcs/src/libs/glc_lib/glc_factory.cpp b/ground/gcs/src/libs/glc_lib/glc_factory.cpp deleted file mode 100644 index 8ff879d91..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_factory.cpp +++ /dev/null @@ -1,458 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - Copyright (C) 2011 Jrme Forrissier - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_factory.cpp implementation of the GLC_Factory class. - -#include "glc_factory.h" -#include "io/glc_fileloader.h" -#include "io/glc_3dxmltoworld.h" -#include "io/glc_worldreaderplugin.h" - -#include "viewport/glc_panmover.h" -#include "viewport/glc_zoommover.h" -#include "viewport/glc_settargetmover.h" -#include "viewport/glc_trackballmover.h" -#include "viewport/glc_turntablemover.h" -#include "viewport/glc_repcrossmover.h" -#include "viewport/glc_reptrackballmover.h" -#include "viewport/glc_flymover.h" -#include "viewport/glc_repflymover.h" -#include "viewport/glc_tsrmover.h" -#include "maths/glc_line3d.h" -#include "maths/glc_geomtools.h" - -#include "glc_fileformatexception.h" - -// init static member -GLC_Factory* GLC_Factory::m_pFactory= NULL; -QList GLC_Factory::m_WorldReaderPluginList; -QSet GLC_Factory::m_SupportedExtensionSet; - -////////////////////////////////////////////////////////////////////// -// static method -////////////////////////////////////////////////////////////////////// -// Return the unique instance of the factory -GLC_Factory* GLC_Factory::instance() -{ - if(m_pFactory == NULL) - { - m_pFactory= new GLC_Factory(); - } - return m_pFactory; -} - -////////////////////////////////////////////////////////////////////// -// Constructor destructor -////////////////////////////////////////////////////////////////////// - -// Protected constructor -GLC_Factory::GLC_Factory() -{ - loadPlugins(); -} - -// Destructor -GLC_Factory::~GLC_Factory() -{ - -} - -////////////////////////////////////////////////////////////////////// -// Create functions -////////////////////////////////////////////////////////////////////// - -GLC_3DRep GLC_Factory::createPoint(const GLC_Point3d &coord) const -{ - GLC_3DRep newPoint(new GLC_Point(coord)); - return newPoint; -} - -GLC_3DRep GLC_Factory::createPoint(double x, double y, double z) const -{ - GLC_3DRep newPoint(new GLC_Point(x, y, z)); - return newPoint; -} - -GLC_3DRep GLC_Factory::createPointCloud(const GLfloatVector& data, const QColor& color) -{ - GLC_PointCloud* pPointCloud= new GLC_PointCloud(); - pPointCloud->addPoint(data); - pPointCloud->setWireColor(color); - return GLC_3DRep(pPointCloud); -} - -GLC_3DRep GLC_Factory::createPointCloud(const QList& pointList, const QColor& color) -{ - GLC_PointCloud* pPointCloud= new GLC_PointCloud(); - pPointCloud->addPoint(pointList); - pPointCloud->setWireColor(color); - return GLC_3DRep(pPointCloud); -} - -GLC_3DRep GLC_Factory::createPointCloud(const QList& pointList, const QColor& color) -{ - GLC_PointCloud* pPointCloud= new GLC_PointCloud(); - pPointCloud->addPoint(pointList); - pPointCloud->setWireColor(color); - return GLC_3DRep(pPointCloud); -} - - -GLC_3DRep GLC_Factory::createPointSprite(float size, GLC_Material* pMaterial) const -{ - GLC_3DRep newPoint(new GLC_PointSprite(size, pMaterial)); - return newPoint; -} - -GLC_3DRep GLC_Factory::createLine(const GLC_Point3d& point1, const GLC_Point3d& point2) const -{ - GLC_3DRep newPoint(new GLC_Line(point1, point2)); - return newPoint; -} - -GLC_3DRep GLC_Factory::createCircle(double radius, double angle) const -{ - GLC_3DRep newCircle(new GLC_Circle(radius, angle)); - return newCircle; -} - -GLC_3DRep GLC_Factory::createBox(double lx, double ly, double lz) const -{ - - GLC_3DRep newBox(new GLC_Box(lx, ly, lz)); - return newBox; -} - -GLC_3DViewInstance GLC_Factory::createBox(const GLC_BoundingBox& boundingBox) const -{ - const double lx= boundingBox.upperCorner().x() - boundingBox.lowerCorner().x(); - const double ly= boundingBox.upperCorner().y() - boundingBox.lowerCorner().y(); - const double lz= boundingBox.upperCorner().z() - boundingBox.lowerCorner().z(); - GLC_Box* pBox= new GLC_Box(lx, ly, lz); - GLC_3DViewInstance newBox(pBox); - newBox.translate(boundingBox.center().x(), boundingBox.center().y() - , boundingBox.center().z()); - return newBox; -} - -GLC_3DRep GLC_Factory::createCylinder(double radius, double length) const -{ - - GLC_3DRep newCylinder(new GLC_Cylinder(radius, length)); - return newCylinder; -} - -GLC_3DRep GLC_Factory::createCone(double radius, double length) const -{ - GLC_3DRep newCone(new GLC_Cone(radius, length)); - return newCone; -} - -GLC_3DRep GLC_Factory::createSphere(double radius) const -{ - GLC_3DRep newSphere(new GLC_Sphere(radius)); - return newSphere; -} - -GLC_3DRep GLC_Factory::createRectangle(double l1, double l2) -{ - GLC_3DRep newRectangle(new GLC_Rectangle(l1, l2)); - return newRectangle; -} - -GLC_3DViewInstance GLC_Factory::createRectangle(const GLC_Point3d& point, const GLC_Vector3d& normal, double l1, double l2) -{ - // Create the rectangle to (0,0) and z normal - GLC_3DViewInstance rectangleInstance(createRectangle(l1, l2)); - - // Create the plane rotation matrix - const GLC_Matrix4x4 rotationMatrix(glc::Z_AXIS, normal); - // Vector from origin to the plane - rectangleInstance.setMatrix(GLC_Matrix4x4(point) * rotationMatrix); - - return rectangleInstance; -} - -GLC_3DViewInstance GLC_Factory::createCuttingPlane(const GLC_Point3d& point, const GLC_Vector3d& normal, double l1, double l2, GLC_Material* pMat) -{ - // Create the rectangle to (0,0) and z normal - GLC_Rectangle* pRectangle= new GLC_Rectangle(l1, l2); - pRectangle->replaceMasterMaterial(pMat); - - GLC_3DViewInstance rectangleInstance(pRectangle); - - // Create the plane rotation matrix - const GLC_Matrix4x4 rotationMatrix(glc::Z_AXIS, normal); - // Vector from origin to the plane - rectangleInstance.setMatrix(GLC_Matrix4x4(point) * rotationMatrix); - - return rectangleInstance; - -} - -GLC_World GLC_Factory::createWorldFromFile(QFile &file, QStringList* pAttachedFileName) const -{ - GLC_FileLoader* pLoader = createFileLoader(); - connect(pLoader, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int))); - GLC_World world = pLoader->createWorldFromFile(file, pAttachedFileName); - delete pLoader; - - return world; -} - -GLC_World GLC_Factory::createWorldStructureFrom3dxml(QFile &file, bool GetExtRefName) const -{ - GLC_World* pWorld= NULL; - - if (QFileInfo(file).suffix().toLower() == "3dxml") - { - GLC_3dxmlToWorld d3dxmlToWorld; - connect(&d3dxmlToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int))); - pWorld= d3dxmlToWorld.createWorldFrom3dxml(file, true, GetExtRefName); - } - - if (NULL == pWorld) - { - // File extension not recognize or file not loaded - QString message(QString("GLC_Factory::createWorldStructureFrom3dxml File ") + file.fileName() + QString(" not loaded")); - GLC_FileFormatException fileFormatException(message, file.fileName(), GLC_FileFormatException::FileNotSupported); - throw(fileFormatException); - } - GLC_World resulWorld(*pWorld); - delete pWorld; - - return resulWorld; -} - -GLC_3DRep GLC_Factory::create3DRepFromFile(const QString& fileName) const -{ - GLC_3DRep rep; - - if ((QFileInfo(fileName).suffix().toLower() == "3dxml") || (QFileInfo(fileName).suffix().toLower() == "3drep") || (QFileInfo(fileName).suffix().toLower() == "xml")) - { - GLC_3dxmlToWorld d3dxmlToWorld; - connect(&d3dxmlToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int))); - rep= d3dxmlToWorld.create3DrepFrom3dxmlRep(fileName); - } - - return rep; - -} - -GLC_FileLoader* GLC_Factory::createFileLoader() const -{ - return new GLC_FileLoader; -} - -GLC_Material* GLC_Factory::createMaterial() const -{ - return new GLC_Material(); -} - -GLC_Material* GLC_Factory::createMaterial(const GLfloat *pAmbiantColor) const -{ - return new GLC_Material("Material", pAmbiantColor); -} - -GLC_Material* GLC_Factory::createMaterial(const QColor &color) const -{ - return new GLC_Material(color); -} - -GLC_Material* GLC_Factory::createMaterial(GLC_Texture* pTexture) const -{ - return new GLC_Material(pTexture, "TextureMaterial"); -} - -GLC_Material* GLC_Factory::createMaterial(const QString &textureFullFileName) const -{ - GLC_Texture* pTexture= createTexture(textureFullFileName); - return createMaterial(pTexture); -} - -GLC_Material* GLC_Factory::createMaterial(const QImage &image) const -{ - GLC_Texture* pTexture= createTexture(image); - return createMaterial(pTexture); -} - -GLC_Texture* GLC_Factory::createTexture(const QString &textureFullFileName) const -{ - return new GLC_Texture(textureFullFileName); -} - -GLC_Texture* GLC_Factory::createTexture(const QImage & image, const QString& imageFileName) const -{ - return new GLC_Texture(image, imageFileName); -} - -GLC_MoverController GLC_Factory::createDefaultMoverController(const QColor& color, GLC_Viewport* pViewport) -{ - GLC_MoverController defaultController; - - ////////////////////////////////////////////////////////////////////// - // Pan Mover - ////////////////////////////////////////////////////////////////////// - // Create Pan Mover representation - GLC_RepMover* pRepMover= new GLC_RepCrossMover(pViewport); - pRepMover->setMainColor(color); - QList listOfRep; - listOfRep.append(pRepMover); - // Create the Pan Mover - GLC_Mover* pMover= new GLC_PanMover(pViewport, listOfRep); - // Add the Pan Mover to the controller - defaultController.addMover(pMover, GLC_MoverController::Pan); - - ////////////////////////////////////////////////////////////////////// - // Zoom Mover - ////////////////////////////////////////////////////////////////////// - // Copy the pan Mover representation - pRepMover= pRepMover->clone(); - listOfRep.clear(); - listOfRep.append(pRepMover); - // Create the Zoom Mover - pMover= new GLC_ZoomMover(pViewport, listOfRep); - // Add the Zoom Mover to the controller - defaultController.addMover(pMover, GLC_MoverController::Zoom); - - ////////////////////////////////////////////////////////////////////// - // Set Target Mover - ////////////////////////////////////////////////////////////////////// - // Create the Zoom Mover - pMover= new GLC_SetTargetMover(pViewport); - // Add the Zoom Mover to the controller - defaultController.addMover(pMover, GLC_MoverController::Target); - - ////////////////////////////////////////////////////////////////////// - // Track Ball Mover - ////////////////////////////////////////////////////////////////////// - // Copy the pan Mover representation - pRepMover= pRepMover->clone(); - listOfRep.clear(); - listOfRep.append(pRepMover); - // Create the track ball representation - pRepMover= new GLC_RepTrackBallMover(pViewport); - pRepMover->setMainColor(color); - listOfRep.append(pRepMover); - // Create the Track Ball Mover - pMover= new GLC_TrackBallMover(pViewport, listOfRep); - // Add the Track ball Mover to the controller - defaultController.addMover(pMover, GLC_MoverController::TrackBall); - - ////////////////////////////////////////////////////////////////////// - // Turn Table Mover - ////////////////////////////////////////////////////////////////////// - // Create the Turn Table Mover - pMover= new GLC_TurnTableMover(pViewport); - // Add the Turn Table Mover to the controller - defaultController.addMover(pMover, GLC_MoverController::TurnTable); - - ////////////////////////////////////////////////////////////////////// - // Fly Mover - ////////////////////////////////////////////////////////////////////// - listOfRep.clear(); - pRepMover= new GLC_RepFlyMover(pViewport); - pRepMover->setMainColor(color); - listOfRep.append(pRepMover); - // Create the fly mover - pMover= new GLC_FlyMover(pViewport, listOfRep); - // Add the fly mover to the controller - defaultController.addMover(pMover, GLC_MoverController::Fly); - - ////////////////////////////////////////////////////////////////////// - // Translation, rotation and scaling Mover - ////////////////////////////////////////////////////////////////////// - // Create the Turn Table Mover - pMover= new GLC_TsrMover(pViewport); - // Add the Turn Table Mover to the controller - defaultController.addMover(pMover, GLC_MoverController::TSR); - - return defaultController; -} - - -void GLC_Factory::loadPlugins() -{ - Q_ASSERT(NULL != QCoreApplication::instance()); - const QStringList libraryPath= QCoreApplication::libraryPaths(); - foreach(QString path, libraryPath) - { - const QDir pluginsDir= QDir(path); - const QStringList pluginNames= pluginsDir.entryList(QDir::Files); - foreach (QString fileName, pluginNames) - { - QPluginLoader loader(pluginsDir.absoluteFilePath(fileName)); - QObject* pPlugin= loader.instance(); - GLC_WorldReaderPlugin* pWorldReader = qobject_cast(pPlugin); - if (pWorldReader) - { - m_WorldReaderPluginList.append(pWorldReader); - m_SupportedExtensionSet.unite(QSet::fromList(pWorldReader->keys())); - } - } - } - - //qDebug() << m_WorldReaderPluginList.size() << " Loaded plugins."; -} - -QList GLC_Factory::worldReaderPlugins() -{ - if (NULL == m_pFactory) - { - instance(); - } - return m_WorldReaderPluginList; -} - -bool GLC_Factory::canBeLoaded(const QString& extension) -{ - if (NULL == m_pFactory) - { - instance(); - } - - return m_SupportedExtensionSet.contains(extension.toLower()); -} - -GLC_WorldReaderHandler* GLC_Factory::loadingHandler(const QString& fileName) -{ - if (NULL == m_pFactory) - { - instance(); - } - - const QString extension= QFileInfo(fileName).suffix(); - if (canBeLoaded(extension)) - { - foreach(GLC_WorldReaderPlugin* pPlugin, m_WorldReaderPluginList) - { - if (pPlugin->keys().contains(extension.toLower())) - { - return pPlugin->readerHandler(); - } - } - } - return NULL; -} - - diff --git a/ground/gcs/src/libs/glc_lib/glc_factory.h b/ground/gcs/src/libs/glc_lib/glc_factory.h deleted file mode 100644 index 89ebd39eb..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_factory.h +++ /dev/null @@ -1,209 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - Copyright (C) 2011 Jrme Forrissier - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_factory.h Interface for the GLC_Factory class. - -#ifndef GLC_FACTORY_ -#define GLC_FACTORY_ - -#include -#include -#include -#include - -//class to built -#include "geometry/glc_point.h" -#include "geometry/glc_pointsprite.h" -#include "geometry/glc_line.h" -#include "geometry/glc_circle.h" -#include "geometry/glc_box.h" -#include "geometry/glc_cylinder.h" -#include "geometry/glc_cone.h" -#include "geometry/glc_sphere.h" -#include "geometry/glc_rectangle.h" -#include "geometry/glc_3drep.h" -#include "geometry/glc_pointcloud.h" -#include "shading/glc_material.h" -#include "shading/glc_texture.h" -#include "sceneGraph/glc_world.h" -#include "sceneGraph/glc_3dviewinstance.h" -#include "glc_boundingbox.h" -#include "viewport/glc_movercontroller.h" -#include "viewport/glc_viewport.h" -#include "io/glc_fileloader.h" - -// end of class to built - -class GLC_WorldReaderHandler; -class GLC_WorldReaderPlugin; - -#include "glc_config.h" -////////////////////////////////////////////////////////////////////// -//! \class GLC_Factory -/*! \brief GLC_Factory : Factory for all geometrical objects - * this class is a singleton - */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_Factory : public QObject -{ - Q_OBJECT - -public: - //! Get unique instance of the factory - static GLC_Factory* instance(); - -protected: - //! Constructor - GLC_Factory(); -public: - //! Destructor - ~GLC_Factory(); - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Create a GLC_Point - GLC_3DRep createPoint(const GLC_Point3d &coord) const; - - GLC_3DRep createPoint(double x, double y, double z) const; - - //! Create a cloud of points - GLC_3DRep createPointCloud(const GLfloatVector& data, const QColor& color); - - GLC_3DRep createPointCloud(const QList& pointList, const QColor& color); - - GLC_3DRep createPointCloud(const QList& pointList, const QColor& color); - - //! Create a GLC_PointSprite - GLC_3DRep createPointSprite(float, GLC_Material*) const; - - //! Create a GLC_Line - GLC_3DRep createLine(const GLC_Point3d&, const GLC_Point3d&) const; - - //! Create a GLC_Circle - GLC_3DRep createCircle(double radius, double angle= 2 * glc::PI) const; - - //! Create a GLC_Box - GLC_3DRep createBox(double lx, double ly, double lz) const; - - GLC_3DViewInstance createBox(const GLC_BoundingBox& boundingBox) const; - - //! Create a GLC_Cylinder - GLC_3DRep createCylinder(double radius, double length) const; - - //! Create a GLC_Cone - GLC_3DRep createCone(double radius, double length) const; - - //! Create a GLC_Sphere - GLC_3DRep createSphere(double radius) const; - - //!Create a GLC_Rectangle - GLC_3DRep createRectangle(double, double); - - //! Create a GLC_Rectangle from the given 3d point, normal and the given lenght - GLC_3DViewInstance createRectangle(const GLC_Point3d& point, const GLC_Vector3d& normal, double l1, double l2); - - //! Create the representation of a cutting from the given 3d point, normal, lenght and material - GLC_3DViewInstance createCuttingPlane(const GLC_Point3d& point, const GLC_Vector3d& normal, double l1, double l2, GLC_Material* pMat); - - //! Create a GLC_World from a QFile - GLC_World createWorldFromFile(QFile &file, QStringList* pAttachedFileName= NULL) const; - - //! Create a GLC_World containing only the 3dxml structure - GLC_World createWorldStructureFrom3dxml(QFile &file, bool GetExtRefName= false) const; - - //! Create 3DRep from 3dxml or 3DRep file - GLC_3DRep create3DRepFromFile(const QString&) const; - - //! Create a GLC_FileLoader - GLC_FileLoader* createFileLoader() const; - - //! Create default material - GLC_Material* createMaterial() const; - - //! create a material with an ambient color - GLC_Material* createMaterial(const GLfloat *pAmbiantColor) const; - - //! create a material with an ambient color - GLC_Material* createMaterial(const QColor &color) const; - - //! create a material textured with a texture - GLC_Material* createMaterial(GLC_Texture* pTexture) const; - - //! create a material textured with a image file name - GLC_Material* createMaterial(const QString &textureFullFileName) const; - - //! create a material textured with a QImage - GLC_Material* createMaterial(const QImage &) const; - - //! Create a GLC_Texture - GLC_Texture* createTexture(const QString &textureFullFileName) const; - - //! Create a GLC_Texture with a QImage - GLC_Texture* createTexture(const QImage &, const QString& imageFileName= QString()) const; - - //! Create the default mover controller - GLC_MoverController createDefaultMoverController(const QColor&, GLC_Viewport*); - - //! Return the list of world reader plugin - static QList worldReaderPlugins(); - - //! Return true if the given file extension can be loaded - static bool canBeLoaded(const QString& extension); - - //! Return an handle to the plugin tu use for the given file - static GLC_WorldReaderHandler* loadingHandler(const QString& fileName); - -//@} - -signals: - //! For progress bar management - void currentQuantum(int) const; - -////////////////////////////////////////////////////////////////////// -// Private services functions -////////////////////////////////////////////////////////////////////// -private: - //! Load GLC_lib plugins - void loadPlugins(); - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// - -private: - //! The unique instance of the factory - static GLC_Factory* m_pFactory; - - //! The list off worldReader plugins - static QList m_WorldReaderPluginList; - - //! The supported extension set - static QSet m_SupportedExtensionSet; - -}; - -#endif /*GLC_FACTORY_*/ diff --git a/ground/gcs/src/libs/glc_lib/glc_fileformatexception.cpp b/ground/gcs/src/libs/glc_lib/glc_fileformatexception.cpp deleted file mode 100644 index ffb8df56f..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_fileformatexception.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_fileformatexception.cpp implementation of the GLC_FileFormatException class. - -#include "glc_fileformatexception.h" - -GLC_FileFormatException::GLC_FileFormatException(const QString &message, const QString &fileName, ExceptionType exceptionType) -: GLC_Exception(message) -, m_FileName(fileName) -, m_ExceptionType(exceptionType) -{ - -} - -GLC_FileFormatException::~GLC_FileFormatException() throw() -{ -} - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -// Return exception description -const char* GLC_FileFormatException::what() const throw() -{ - QString exceptionmsg("GLC_FileFormatException : "); - exceptionmsg.append(m_ErrorDescription); - exceptionmsg.append(" in file : "); - exceptionmsg.append(m_FileName); - return exceptionmsg.toLatin1().data(); -} diff --git a/ground/gcs/src/libs/glc_lib/glc_fileformatexception.h b/ground/gcs/src/libs/glc_lib/glc_fileformatexception.h deleted file mode 100644 index 944b1b886..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_fileformatexception.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_fileformatexception.h Interface for the GLC_FileFormatException class. - -#ifndef GLC_FILEFORMATEXCEPTION_H_ -#define GLC_FILEFORMATEXCEPTION_H_ -#include "glc_exception.h" - -#include "glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_FileFormatException -/*! \brief GLC_FileFormatException : Class for all File Format ERROR - */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_FileFormatException : public GLC_Exception -{ -public: - //! Enum of exception Type - enum ExceptionType - { - FileNotFound= 1, - FileNotSupported, - WrongFileFormat, - NoMeshFound - }; - - GLC_FileFormatException(const QString&, const QString&, ExceptionType); - virtual ~GLC_FileFormatException() throw(); - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return exception description - virtual const char* what() const throw(); - - //! Return exception type - inline ExceptionType exceptionType() const - {return m_ExceptionType;} - -//@} -////////////////////////////////////////////////////////////////////// -// private members -////////////////////////////////////////////////////////////////////// -private: - - //! The name of the file - QString m_FileName; - - //! The Exception type - ExceptionType m_ExceptionType; - -}; - -#endif /*GLC_FILEFORMATEXCEPTION_H_*/ diff --git a/ground/gcs/src/libs/glc_lib/glc_global.cpp b/ground/gcs/src/libs/glc_lib/glc_global.cpp deleted file mode 100644 index 86a84a1a9..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_global.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_global.cpp implementation of usefull utilities - -#include "glc_global.h" - -QMutex glc::iDMutex; -QMutex glc::geomIdMutex; -QMutex glc::userIdMutex; -QMutex glc::widget3dIdMutex; -QMutex glc::shadingGroupIdMutex; - -GLC_uint glc::GLC_GenID(void) -{ - static GLC_uint Id= 0; - glc::iDMutex.lock(); - Id++; - glc::iDMutex.unlock(); - return Id; -} - -GLC_uint glc::GLC_GenGeomID(void) -{ - static GLC_uint Id= 0; - glc::geomIdMutex.lock(); - Id++; - glc::geomIdMutex.unlock(); - return Id; -} - -GLC_uint glc::GLC_GenUserID(void) -{ - static GLC_uint Id= 0; - glc::userIdMutex.lock(); - Id++; - glc::userIdMutex.unlock(); - return Id; -} - -GLC_uint glc::GLC_Gen3DWidgetID(void) -{ - static GLC_uint Id= 0; - glc::widget3dIdMutex.lock(); - Id++; - glc::widget3dIdMutex.unlock(); - return Id; -} - -GLC_uint glc::GLC_GenShaderGroupID() -{ - static GLC_uint Id= 1; - glc::shadingGroupIdMutex.lock(); - Id++; - glc::shadingGroupIdMutex.unlock(); - return Id; -} - -const QString glc::archivePrefix() -{ - return "glc_Zip::"; -} - -const QString glc::archiveInfix() -{ - return "::glc_Zip::"; -} - -const QString glc::filePrefix() -{ - return "File::"; -} - -const QString glc::fileInfix() -{ - return "::File::"; -} - -bool glc::isArchiveString(const QString& fileName) -{ - bool inArchive= fileName.startsWith(archivePrefix()); - inArchive= inArchive && fileName.contains(archiveInfix()); - return inArchive; -} - -bool glc::isFileString(const QString& fileName) -{ - bool inFile= fileName.startsWith(filePrefix()); - inFile= inFile && fileName.contains(fileInfix()); - return inFile; -} - -QString glc::builtArchiveString(const QString& Archive, const QString& entry) -{ - return QString(archivePrefix() + Archive + archiveInfix() + entry); -} - -QString glc::builtFileString(const QString& File, const QString& entry) -{ - const QString repFileName= QFileInfo(File).absolutePath() + QDir::separator() + entry; - return QString(filePrefix() + File + fileInfix() + repFileName); -} - -QString glc::archiveFileName(const QString& archiveString) -{ - const bool isArchiveEncoded= isArchiveString(archiveString); - const bool isFileEncoded= isFileString(archiveString); - - Q_ASSERT(isArchiveEncoded || isFileEncoded); - QString infix; - QString prefix; - if (isArchiveEncoded) - { - infix= archiveInfix(); - prefix= archivePrefix(); - } - else if (isFileEncoded) - { - infix= fileInfix(); - prefix= filePrefix(); - } - const int indexOfInfix= archiveString.indexOf(infix); - const int prefixLength= prefix.length(); - const int length= indexOfInfix - prefixLength; - return archiveString.mid(prefixLength, length); -} - -QString glc::archiveEntryFileName(const QString& archiveString) -{ - const bool isArchiveEncoded= isArchiveString(archiveString); - const bool isFileEncoded= isFileString(archiveString); - - Q_ASSERT(isArchiveEncoded || isFileEncoded); - QString infix; - if (isArchiveEncoded) - { - infix= archiveInfix(); - } - else if (isFileEncoded) - { - infix= fileInfix(); - } - const int indexOfInfix= archiveString.indexOf(infix); - const int infixLength= infix.length(); - const int length= archiveString.length() - (indexOfInfix + infixLength); - return archiveString.right(length); -} - diff --git a/ground/gcs/src/libs/glc_lib/glc_global.h b/ground/gcs/src/libs/glc_lib/glc_global.h deleted file mode 100644 index 01b7f15bd..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_global.h +++ /dev/null @@ -1,153 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_global.h provide usefull utilities - -#ifndef GLC_GLOBAL_H_ -#define GLC_GLOBAL_H_ - -#include -#include -#include -#include -#include - -#include "glc_config.h" - -// GLC_lib typedef -//! Type used for all GLC_lib ID -typedef unsigned int GLC_uint; - -//! Types used for Bulk Opengl Data : QVector of GLfloat -typedef QVector GLfloatVector; - -//! Types used for index Opengl Data : QVector of GLuint -typedef QVector GLuintVector; - -typedef QList IndexList; -typedef QVector IndexSizes; -typedef QVector OffsetVector; -typedef QVector OffsetVectori; - - -namespace glc -{ - //! Simple ID generation - GLC_LIB_EXPORT GLC_uint GLC_GenID(); - - //! Simple Geom ID generation - GLC_LIB_EXPORT GLC_uint GLC_GenGeomID(); - - //! Simple User ID generation - GLC_LIB_EXPORT GLC_uint GLC_GenUserID(); - - //! Simple 3D widget ID generation - GLC_LIB_EXPORT GLC_uint GLC_Gen3DWidgetID(); - - //! Simple shading group generation - GLC_LIB_EXPORT GLC_uint GLC_GenShaderGroupID(); - - //! Return the GLC_uint decoded ID from RGB encoded ID - inline GLC_uint decodeRgbId(const GLubyte*); - - //! Return the encoded color of the id - inline void encodeRgbId(GLC_uint, GLubyte*); - - const int GLC_DISCRET= 70; - const int GLC_POLYDISCRET= 60; - - extern QMutex iDMutex; - extern QMutex geomIdMutex; - extern QMutex userIdMutex; - extern QMutex widget3dIdMutex; - extern QMutex shadingGroupIdMutex; - - //! 3D widget event flag - enum WidgetEventFlag - { - AcceptEvent, - IgnoreEvent, - BlockedEvent - }; - - //! Return GLC_lib Archive prefix string - GLC_LIB_EXPORT const QString archivePrefix(); - - //! Return GLC_lib Archive infix string - GLC_LIB_EXPORT const QString archiveInfix(); - - //! Return GLC_lib File prefix string - GLC_LIB_EXPORT const QString filePrefix(); - - //! Return GLC_lib File infix string - GLC_LIB_EXPORT const QString fileInfix(); - - //! Return true if the given file name is in a archive string - GLC_LIB_EXPORT bool isArchiveString(const QString& fileName); - - //! Return true if the given file name is in a File string - GLC_LIB_EXPORT bool isFileString(const QString& fileName); - - //! Return archive string form the given archive fileName and fileName entry - GLC_LIB_EXPORT QString builtArchiveString(const QString& Archive, const QString& entry); - - //! Return archive string form the given archive fileName and fileName entry - GLC_LIB_EXPORT QString builtFileString(const QString& File, const QString& entry); - - //! Return Archive filename from the given archive string - GLC_LIB_EXPORT QString archiveFileName(const QString& archiveString); - - //! Return Archive entry filname from the given archive string - GLC_LIB_EXPORT QString archiveEntryFileName(const QString& archiveString); - - // GLC_Lib version - const QString version("2.5.0"); - const QString description("GLC_lib is a Open Source C++ class library that enables the quick creation of an OpenGL application based on QT4."); - -}; - -// Return the GLC_uint decoded ID from RGBA encoded ID -GLC_uint glc::decodeRgbId(const GLubyte* pcolorId) -{ - GLC_uint returnId= 0; - returnId|= (GLC_uint)pcolorId[0] << (0 * 8); - returnId|= (GLC_uint)pcolorId[1] << (1 * 8); - returnId|= (GLC_uint)pcolorId[2] << (2 * 8); - // Only get first 24 bits - //returnId|= (GLC_uint)pcolorId[3] << (3 * 8); - - return returnId; -} - -// Encode Id to RGBA color -void glc::encodeRgbId(GLC_uint id, GLubyte* colorId) -{ - colorId[0]= static_cast((id >> (0 * 8)) & 0xFF); - colorId[1]= static_cast((id >> (1 * 8)) & 0xFF); - colorId[2]= static_cast((id >> (2 * 8)) & 0xFF); - colorId[3]= static_cast((id >> (3 * 8)) & 0xFF); -} - - -#endif //GLC_GLOBAL_H_ - - diff --git a/ground/gcs/src/libs/glc_lib/glc_lib.pri b/ground/gcs/src/libs/glc_lib/glc_lib.pri deleted file mode 100644 index d3199ba3a..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_lib.pri +++ /dev/null @@ -1,2 +0,0 @@ -QT += opengl -LIBS *= -l$$qtLibraryName(GLC_lib) diff --git a/ground/gcs/src/libs/glc_lib/glc_lib.pro b/ground/gcs/src/libs/glc_lib/glc_lib.pro deleted file mode 100644 index 578346fcd..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_lib.pro +++ /dev/null @@ -1,516 +0,0 @@ -TEMPLATE = lib -TARGET = GLC_lib -#VERSION = 2.2.0 - -DEFINES += GLC_LIB_LIBRARY -include(../../library.pri) - -QT += core opengl - -# disable all warnings (no need for warnings as glc sources are imported) -CONFIG += exceptions warn_off - -DEFINES += CREATE_GLC_LIB_DLL -DEFINES += LIB3DS_EXPORTS - -DEFINES += _CRT_SECURE_NO_WARNINGS - -unix:OBJECTS_DIR = ./Build -unix:MOC_DIR = ./Build -unix:UI_DIR = ./Build - -DEPENDPATH += . -INCLUDEPATH += . -INCLUDEPATH += ./3rdparty/zlib - -RESOURCES += glc_lib.qrc - -# Input -HEADERS_QUAZIP += 3rdparty/quazip/crypt.h \ - 3rdparty/quazip/ioapi.h \ - 3rdparty/quazip/quazip.h \ - 3rdparty/quazip/quazipfile.h \ - 3rdparty/quazip/quazipfileinfo.h \ - 3rdparty/quazip/quazipnewinfo.h \ - 3rdparty/quazip/unzip.h \ - 3rdparty/quazip/zip.h - -HEADERS_LIB3DS += 3rdparty/lib3ds/atmosphere.h \ - 3rdparty/lib3ds/background.h \ - 3rdparty/lib3ds/camera.h \ - 3rdparty/lib3ds/chunk.h \ - 3rdparty/lib3ds/chunktable.h \ - 3rdparty/lib3ds/ease.h \ - 3rdparty/lib3ds/file.h \ - 3rdparty/lib3ds/io.h \ - 3rdparty/lib3ds/light.h \ - 3rdparty/lib3ds/material.h \ - 3rdparty/lib3ds/matrix.h \ - 3rdparty/lib3ds/mesh.h \ - 3rdparty/lib3ds/node.h \ - 3rdparty/lib3ds/quat.h \ - 3rdparty/lib3ds/shadow.h \ - 3rdparty/lib3ds/tcb.h \ - 3rdparty/lib3ds/tracks.h \ - 3rdparty/lib3ds/types.h \ - 3rdparty/lib3ds/vector.h \ - 3rdparty/lib3ds/viewport.h - -HEADERS_GLEXT += 3rdparty/glext/glext.h - -HEADERS_GLC_MATHS += maths/glc_utils_maths.h \ - maths/glc_vector2d.h \ - maths/glc_vector2df.h \ - maths/glc_vector3d.h \ - maths/glc_vector4d.h \ - maths/glc_vector3df.h \ - maths/glc_matrix4x4.h \ - maths/glc_interpolator.h \ - maths/glc_plane.h \ - maths/glc_geomtools.h \ - maths/glc_line3d.h - -HEADERS_GLC_IO += io/glc_objmtlloader.h \ - io/glc_objtoworld.h \ - io/glc_stltoworld.h \ - io/glc_offtoworld.h \ - io/glc_3dstoworld.h \ - io/glc_3dxmltoworld.h \ - io/glc_colladatoworld.h \ - io/glc_worldto3dxml.h \ - io/glc_worldto3ds.h \ - io/glc_bsreptoworld.h \ - io/glc_xmlutil.h \ - io/glc_fileloader.h \ - io/glc_worldreaderplugin.h \ - io/glc_worldreaderhandler.h - -HEADERS_GLC_SCENEGRAPH += sceneGraph/glc_3dviewcollection.h \ - sceneGraph/glc_3dviewinstance.h \ - sceneGraph/glc_structreference.h \ - sceneGraph/glc_structinstance.h \ - sceneGraph/glc_structoccurence.h \ - sceneGraph/glc_world.h \ - sceneGraph/glc_attributes.h \ - sceneGraph/glc_worldhandle.h \ - sceneGraph/glc_spacepartitioning.h \ - sceneGraph/glc_octree.h \ - sceneGraph/glc_octreenode.h \ - sceneGraph/glc_selectionset.h - -HEADERS_GLC_GEOMETRY += geometry/glc_geometry.h \ - geometry/glc_circle.h \ - geometry/glc_cylinder.h \ - geometry/glc_point.h \ - geometry/glc_box.h \ - geometry/glc_meshdata.h \ - geometry/glc_primitivegroup.h \ - geometry/glc_mesh.h \ - geometry/glc_lod.h \ - geometry/glc_rectangle.h \ - geometry/glc_line.h \ - geometry/glc_rep.h \ - geometry/glc_3drep.h \ - geometry/glc_pointsprite.h \ - geometry/glc_bsrep.h \ - geometry/glc_wiredata.h \ - geometry/glc_arrow.h \ - geometry/glc_polylines.h \ - geometry/glc_disc.h \ - geometry/glc_cone.h \ - geometry/glc_sphere.h \ - geometry/glc_pointcloud.h \ - geometry/glc_extrudedmesh.h - -HEADERS_GLC_SHADING += shading/glc_material.h \ - shading/glc_texture.h \ - shading/glc_shader.h \ - shading/glc_selectionmaterial.h \ - shading/glc_light.h \ - shading/glc_renderproperties.h \ - shading/glc_renderer.h - -HEADERS_GLC_VIEWPORT += viewport/glc_camera.h \ - viewport/glc_imageplane.h \ - viewport/glc_viewport.h \ - viewport/glc_movercontroller.h\ - viewport/glc_mover.h \ - viewport/glc_panmover.h \ - viewport/glc_repmover.h \ - viewport/glc_repcrossmover.h \ - viewport/glc_zoommover.h \ - viewport/glc_trackballmover.h \ - viewport/glc_reptrackballmover.h \ - viewport/glc_settargetmover.h \ - viewport/glc_turntablemover.h \ - viewport/glc_frustum.h \ - viewport/glc_flymover.h \ - viewport/glc_repflymover.h \ - viewport/glc_userinput.h \ - viewport/glc_tsrmover.h - -HEADERS_GLC += glc_global.h \ - glc_object.h \ - glc_factory.h \ - glc_boundingbox.h \ - glc_exception.h \ - glc_openglexception.h \ - glc_fileformatexception.h \ - glc_ext.h \ - glc_state.h \ - glc_config.h \ - glc_cachemanager.h \ - glc_renderstatistics.h \ - glc_log.h \ - glc_errorlog.h \ - glc_tracelog.h \ - glc_context.h \ - glc_contextmanager.h \ - glc_contextshareddata.h \ - glc_uniformshaderdata.h - -HEADERS_GLC_3DWIDGET += 3DWidget/glc_3dwidget.h \ - 3DWidget/glc_cuttingplane.h \ - 3DWidget/glc_3dwidgetmanager.h \ - 3DWidget/glc_3dwidgetmanagerhandle.h \ - 3DWidget/glc_abstractmanipulator.h \ - 3DWidget/glc_pullmanipulator.h \ - 3DWidget/glc_rotationmanipulator.h \ - 3DWidget/glc_axis.h - -HEADERS_GLC_GLU += glu/glc_glu.h - -HEADERS += $${HEADERS_QUAZIP} $${HEADERS_LIB3DS} $${HEADERS_GLC_MATHS} $${HEADERS_GLC_IO} -HEADERS += $${HEADERS_GLC} $${HEADERS_GLEXT} $${HEADERS_GLC_SCENEGRAPH} $${HEADERS_GLC_GEOMETRY} -HEADERS += $${HEADERS_GLC_SHADING} $${HEADERS_GLC_VIEWPORT} $${HEADERS_GLC_3DWIDGET} $${HEADERS_GLC_GLU} - -SOURCES += 3rdparty/zlib/adler32.c \ - 3rdparty/zlib/compress.c \ - 3rdparty/zlib/crc32.c \ - 3rdparty/zlib/deflate.c \ - 3rdparty/zlib/gzio.c \ - 3rdparty/zlib/inffast.c \ - 3rdparty/zlib/inflate.c \ - 3rdparty/zlib/inftrees.c \ - 3rdparty/zlib/trees.c \ - 3rdparty/zlib/uncompr.c \ - 3rdparty/zlib/zutil.c - -SOURCES += 3rdparty/quazip/ioapi.c \ - 3rdparty/quazip/quazip.cpp \ - 3rdparty/quazip/quazipfile.cpp \ - 3rdparty/quazip/quazipnewinfo.cpp \ - 3rdparty/quazip/unzip.c \ - 3rdparty/quazip/zip.c - -SOURCES += 3rdparty/lib3ds/atmosphere.c \ - 3rdparty/lib3ds/background.c \ - 3rdparty/lib3ds/camera.c \ - 3rdparty/lib3ds/chunk.c \ - 3rdparty/lib3ds/ease.c \ - 3rdparty/lib3ds/file.c \ - 3rdparty/lib3ds/io.c \ - 3rdparty/lib3ds/light.c \ - 3rdparty/lib3ds/material.c \ - 3rdparty/lib3ds/matrix.c \ - 3rdparty/lib3ds/mesh.c \ - 3rdparty/lib3ds/node.c \ - 3rdparty/lib3ds/quat.c \ - 3rdparty/lib3ds/shadow.c \ - 3rdparty/lib3ds/tcb.c \ - 3rdparty/lib3ds/tracks.c \ - 3rdparty/lib3ds/vector.c \ - 3rdparty/lib3ds/viewport.c - -SOURCES += maths/glc_matrix4x4.cpp \ - maths/glc_vector4d.cpp \ - maths/glc_interpolator.cpp \ - maths/glc_plane.cpp \ - maths/glc_geomtools.cpp \ - maths/glc_line3d.cpp - -SOURCES += io/glc_objmtlloader.cpp \ - io/glc_objtoworld.cpp \ - io/glc_stltoworld.cpp \ - io/glc_offtoworld.cpp \ - io/glc_3dstoworld.cpp \ - io/glc_3dxmltoworld.cpp \ - io/glc_colladatoworld.cpp \ - io/glc_worldto3dxml.cpp \ - io/glc_worldto3ds.cpp \ - io/glc_bsreptoworld.cpp \ - io/glc_fileloader.cpp - -SOURCES += sceneGraph/glc_3dviewcollection.cpp \ - sceneGraph/glc_3dviewinstance.cpp \ - sceneGraph/glc_structreference.cpp \ - sceneGraph/glc_structinstance.cpp \ - sceneGraph/glc_structoccurence.cpp \ - sceneGraph/glc_world.cpp \ - sceneGraph/glc_attributes.cpp \ - sceneGraph/glc_worldhandle.cpp \ - sceneGraph/glc_spacepartitioning.cpp \ - sceneGraph/glc_octree.cpp \ - sceneGraph/glc_octreenode.cpp \ - sceneGraph/glc_selectionset.cpp - -SOURCES += geometry/glc_geometry.cpp \ - geometry/glc_circle.cpp \ - geometry/glc_cylinder.cpp \ - geometry/glc_point.cpp \ - geometry/glc_box.cpp \ - geometry/glc_meshdata.cpp \ - geometry/glc_primitivegroup.cpp \ - geometry/glc_mesh.cpp \ - geometry/glc_lod.cpp \ - geometry/glc_rectangle.cpp \ - geometry/glc_line.cpp \ - geometry/glc_rep.cpp \ - geometry/glc_3drep.cpp \ - geometry/glc_pointsprite.cpp \ - geometry/glc_bsrep.cpp \ - geometry/glc_wiredata.cpp \ - geometry/glc_arrow.cpp \ - geometry/glc_polylines.cpp \ - geometry/glc_disc.cpp \ - geometry/glc_cone.cpp \ - geometry/glc_sphere.cpp \ - geometry/glc_pointcloud.cpp \ - geometry/glc_extrudedmesh.cpp - - -SOURCES += shading/glc_material.cpp \ - shading/glc_texture.cpp \ - shading/glc_light.cpp \ - shading/glc_selectionmaterial.cpp \ - shading/glc_shader.cpp \ - shading/glc_renderproperties.cpp \ - shading/glc_renderer.cpp - -SOURCES += viewport/glc_camera.cpp \ - viewport/glc_imageplane.cpp \ - viewport/glc_viewport.cpp \ - viewport/glc_movercontroller.cpp\ - viewport/glc_mover.cpp \ - viewport/glc_panmover.cpp \ - viewport/glc_repmover.cpp \ - viewport/glc_repcrossmover.cpp \ - viewport/glc_zoommover.cpp \ - viewport/glc_trackballmover.cpp \ - viewport/glc_reptrackballmover.cpp \ - viewport/glc_settargetmover.cpp \ - viewport/glc_turntablemover.cpp \ - viewport/glc_frustum.cpp \ - viewport/glc_flymover.cpp \ - viewport/glc_repflymover.cpp \ - viewport/glc_userinput.cpp \ - viewport/glc_tsrmover.cpp - -SOURCES += glc_global.cpp \ - glc_object.cpp \ - glc_factory.cpp \ - glc_boundingbox.cpp \ - glc_exception.cpp \ - glc_openglexception.cpp \ - glc_fileformatexception.cpp \ - glc_ext.cpp \ - glc_state.cpp \ - glc_cachemanager.cpp \ - glc_renderstatistics.cpp \ - glc_log.cpp \ - glc_errorlog.cpp \ - glc_tracelog.cpp \ - glc_context.cpp \ - glc_contextmanager.cpp \ - glc_contextshareddata.cpp \ - glc_uniformshaderdata.cpp - -SOURCES += 3DWidget/glc_3dwidget.cpp \ - 3DWidget/glc_cuttingplane.cpp \ - 3DWidget/glc_3dwidgetmanager.cpp \ - 3DWidget/glc_3dwidgetmanagerhandle.cpp \ - 3DWidget/glc_abstractmanipulator.cpp \ - 3DWidget/glc_pullmanipulator.cpp \ - 3DWidget/glc_rotationmanipulator.cpp \ - 3DWidget/glc_axis.cpp - -SOURCES += glu/glc_project.cpp - -# Windows compilation configuration -win32:CONFIG *= dll - -# install header -HEADERS_INST = include/GLC_BoundingBox \ - include/GLC_Box \ - include/GLC_Camera \ - include/GLC_Circle \ - include/GLC_3DViewCollection \ - include/GLC_Cylinder \ - include/GLC_Exception \ - include/GLC_Factory \ - include/GLC_FileFormatException \ - include/GLC_Geometry \ - include/GLC_ImagePlane \ - include/GLC_3DViewInstance \ - include/GLC_Interpolator \ - include/GLC_Light \ - include/GLC_Material \ - include/GLC_Matrix4x4 \ - include/GLC_Node \ - include/GLC_Object \ - include/GLC_OpenGlException \ - include/GLC_Point \ - include/GLC_Point2d \ - include/GLC_Point2df \ - include/GLC_Point3d \ - include/GLC_Point3df \ - include/GLC_Texture \ - include/GLC_Vector2d \ - include/GLC_Vector2df \ - include/GLC_Vector3d \ - include/GLC_Vector3df \ - include/GLC_Vector4d \ - include/GLC_Viewport \ - include/GLC_World \ - include/GLC_Shader \ - include/GLC_SelectionMaterial \ - include/GLC_State \ - include/GLC_Mover \ - include/GLC_MoverController \ - include/GLC_PanMover \ - include/GLC_ZoomMover \ - include/GLC_TrackBallMover \ - include/GLC_RepMover \ - include/GLC_RepCrossMover \ - include/GLC_RepTrackBallMover \ - include/GLC_TurnTableMover \ - include/GLC_Attributes \ - include/GLC_Rectangle \ - include/GLC_Mesh \ - include/GLC_StructOccurence \ - include/GLC_StructInstance \ - include/GLC_StructReference \ - include/GLC_Line \ - include/GLC_Rep \ - include/GLC_3DRep \ - include/GLC_PointSprite \ - include/GLC_CacheManager \ - include/GLC_BSRep \ - include/GLC_RenderProperties \ - include/GLC_Global \ - include/GLC_SpacePartitioning \ - include/GLC_Octree \ - include/GLC_OctreeNode \ - include/GLC_Plane \ - include/GLC_Frustum \ - include/GLC_GeomTools \ - include/GLC_Line3d \ - include/GLC_3DWidget \ - include/GLC_CuttingPlane \ - include/GLC_3DWidgetManager \ - include/GLC_3DWidgetManagerHandle \ - include/GLC_Arrow \ - include/GLC_Polylines \ - include/GLC_Disc \ - include/GLC_AbstractManipulator \ - include/GLC_PullManipulator \ - include/GLC_RotationManipulator \ - include/GLC_FlyMover \ - include/GLC_RepFlyMover \ - include/GLC_WorldTo3dxml \ - include/GLC_WorldTo3ds \ - include/GLC_RenderStatistics \ - include/GLC_Ext \ - include/GLC_Cone \ - include/GLC_Sphere \ - include/GLC_Axis \ - include/GLC_Log \ - include/GLC_ErrorLog \ - include/GLC_TraceLog \ - include/glcXmlUtil \ - include/GLC_RenderState \ - include/GLC_FileLoader \ - include/GLC_WorldReaderPlugin \ - include/GLC_WorldReaderHandler \ - include/GLC_PointCloud \ - include/GLC_SelectionSet \ - include/GLC_UserInput \ - include/GLC_TsrMover \ - include/GLC_Glu \ - include/GLC_Context \ - include/GLC_ContextManager \ - include/GLC_Renderer \ - include/GLC_ExtrudedMesh - - -# Linux and macx install configuration -unix { - # Location of HEADERS and library - LIB_DIR = /usr/local/lib - INCLUDE_DIR = /usr/local/include - # Adds a -P to preserve link - QMAKE_COPY_FILE = $${QMAKE_COPY_FILE} -P - include.path = $${INCLUDE_DIR}/GLC_lib - include_lib3ds.path = $${INCLUDE_DIR}/GLC_lib/3rdparty/lib3ds - include_glext.path = $${INCLUDE_DIR}/GLC_lib/3rdparty/glext - include_quazip.path = $${INCLUDE_DIR}/GLC_lib/3rdparty/quazip - include_glc_maths.path = $${INCLUDE_DIR}/GLC_lib/maths - include_glc_io.path = $${INCLUDE_DIR}/GLC_lib/io - include_glc_scengraph.path = $${INCLUDE_DIR}/GLC_lib/sceneGraph - include_glc_geometry.path = $${INCLUDE_DIR}/GLC_lib/geometry - include_glc_shading.path = $${INCLUDE_DIR}/GLC_lib/shading - include_glc_viewport.path = $${INCLUDE_DIR}/GLC_lib/viewport - include_glc_3dwidget.path = $${INCLUDE_DIR}/GLC_lib/3DWidget - include_glc_glu.path = $${INCLUDE_DIR}/GLC_lib/glu -} - -# Windows Install configuration -win32 { - # Location of HEADERS and library - LIB_DIR = C:/GLC_lib/lib - INCLUDE_DIR = C:/GLC_lib/include - include.path = $${INCLUDE_DIR} - include_lib3ds.path = $${INCLUDE_DIR}/3rdparty/lib3ds - include_glext.path = $${INCLUDE_DIR}/3rdparty/glext - include_quazip.path = $${INCLUDE_DIR}/3rdparty/quazip - include_glc_maths.path = $${INCLUDE_DIR}/maths - include_glc_io.path = $${INCLUDE_DIR}/io - include_glc_scengraph.path = $${INCLUDE_DIR}/sceneGraph - include_glc_geometry.path = $${INCLUDE_DIR}/geometry - include_glc_shading.path = $${INCLUDE_DIR}/shading - include_glc_viewport.path = $${INCLUDE_DIR}/viewport - include_glc_3dwidget.path = $${INCLUDE_DIR}/3DWidget - include_glc_glu.path = $${INCLUDE_DIR}/glu -} - -include.files = $${HEADERS_GLC} $${HEADERS_INST} -include_lib3ds.files = $${HEADERS_LIB3DS} -include_glext.files =$${HEADERS_GLEXT} -include_quazip.files = $${HEADERS_QUAZIP} -include_glc_maths.files= $${HEADERS_GLC_MATHS} -include_glc_io.files= $${HEADERS_GLC_IO} -include_glc_scengraph.files= $${HEADERS_GLC_SCENEGRAPH} -include_glc_geometry.files= $${HEADERS_GLC_GEOMETRY} -include_glc_shading.files = $${HEADERS_GLC_SHADING} -include_glc_viewport.files = $${HEADERS_GLC_VIEWPORT} -include_glc_3dwidget.files = $${HEADERS_GLC_3DWIDGET} -include_glc_glu.files = $${HEADERS_GLC_GLU} - -# install library -target.path = $${LIB_DIR} - -# "make install" configuration options -INSTALLS += include_lib3ds include_glext include_quazip include_glc_maths include_glc_io -INSTALLS += include_glc_scengraph include_glc_geometry include_glc_shading include_glc_viewport -INSTALLS += include_glc_3dwidget include_glc_glu - -INSTALLS += target -INSTALLS +=include - -OTHER_FILES += \ - qtc_packaging/debian_harmattan/rules \ - qtc_packaging/debian_harmattan/README \ - qtc_packaging/debian_harmattan/copyright \ - qtc_packaging/debian_harmattan/control \ - qtc_packaging/debian_harmattan/compat \ - qtc_packaging/debian_harmattan/changelog diff --git a/ground/gcs/src/libs/glc_lib/glc_lib.qrc b/ground/gcs/src/libs/glc_lib/glc_lib.qrc deleted file mode 100644 index d74f34bc9..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_lib.qrc +++ /dev/null @@ -1,6 +0,0 @@ - - - shading/shaders/default.frag - shading/shaders/default.vert - - diff --git a/ground/gcs/src/libs/glc_lib/glc_log.cpp b/ground/gcs/src/libs/glc_lib/glc_log.cpp deleted file mode 100644 index 8fe0908dd..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_log.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -//! \file glc_log.h implementation of the GLC_Log class. - -#include "glc_log.h" -#include -#include - -GLC_Log::GLC_Log(const QString& baseLogFileName) -: m_pFile(new QTemporaryFile(baseLogFileName)) -, m_TextStream() -{ - Q_CHECK_PTR(m_pFile); - m_pFile->open(); - m_pFile->setAutoRemove(false); - m_TextStream.setDevice(m_pFile); -} - -GLC_Log::~GLC_Log() -{ - m_TextStream.flush(); - delete m_pFile; -} - -QString GLC_Log::fullFileName() const -{ - Q_ASSERT(NULL != m_pFile); - return m_pFile->fileName(); -} - -void GLC_Log::add(const QString& line) -{ - Q_ASSERT(NULL != m_pFile); - qWarning() << line; - m_TextStream << line << '\n'; - m_TextStream.flush(); -} - -void GLC_Log::addSeparator() -{ - Q_ASSERT(NULL != m_pFile); - const QString separator("---------------------------------------------------------------------"); - qWarning() << separator; - m_TextStream << separator << '\n'; - m_TextStream.flush(); -} - -void GLC_Log::addCurrentTime() -{ - Q_ASSERT(NULL != m_pFile); - m_TextStream << QTime::currentTime().toString() << '\n'; - m_TextStream.flush(); -} diff --git a/ground/gcs/src/libs/glc_lib/glc_log.h b/ground/gcs/src/libs/glc_lib/glc_log.h deleted file mode 100644 index 08fc42304..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_log.h +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -//! \file glc_log.h interface for the GLC_Log class. - -#ifndef GLC_LOG_H_ -#define GLC_LOG_H_ - -#include -#include -#include -#include "glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Log -/*! \brief GLC_Log : Base class for GLC_lib log*/ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_Log -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor */ -//@{ -////////////////////////////////////////////////////////////////////// -protected: - //! Construct a log of the given base fileName - GLC_Log(const QString& baseLogFileName); -public: - //! Destructor - virtual ~GLC_Log(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return this log full file name - QString fullFileName() const; - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -protected: - //! Add the given string to this log - void add(const QString& line); - - //! Add blank line to this log - inline void addBlankLine() - {add(QString());} - - //! Add a separator in the log - void addSeparator(); - - //! Add current time in log - void addCurrentTime(); - - -//@} - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -protected: - - //! This log file - QTemporaryFile* m_pFile; - - //! This log textStream - QTextStream m_TextStream; - -}; - -#endif /* GLC_LOG_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/glc_object.cpp b/ground/gcs/src/libs/glc_lib/glc_object.cpp deleted file mode 100644 index 5ce211ca9..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_object.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file GLC_Object.cpp Implementation of the GLC_Object class. - -#include "glc_object.h" - -////////////////////////////////////////////////////////////////////// -// Constructor/Destructor -////////////////////////////////////////////////////////////////////// - -GLC_Object::GLC_Object(const QString& name) -: m_Uid(glc::GLC_GenID()) // Object ID -, m_Name(name) // Object Name -, m_Mutex() -{ - -} - -GLC_Object::GLC_Object(GLC_uint id, const QString& name) -: m_Uid(id) -, m_Name(name) -, m_Mutex() -{ - -} - -GLC_Object::GLC_Object(const GLC_Object& sourceObject) -: m_Uid(sourceObject.m_Uid) -, m_Name(sourceObject.m_Name) -, m_Mutex() -{ -} - -GLC_Object::~GLC_Object() -{ - -} - - -////////////////////////////////////////////////////////////////////// -// Set function -////////////////////////////////////////////////////////////////////// - -void GLC_Object::setId(const GLC_uint id) -{ - QMutexLocker mutexLocker(&m_Mutex); - m_Uid= id; -} - -void GLC_Object::setName(const QString& name) -{ - QMutexLocker mutexLocker(&m_Mutex); - m_Name= name; -} - - -GLC_Object& GLC_Object::operator=(const GLC_Object& object) -{ - QMutexLocker mutexLocker(&m_Mutex); - m_Uid= object.m_Uid; - m_Name= object.m_Name; - return *this; -} - - diff --git a/ground/gcs/src/libs/glc_lib/glc_object.h b/ground/gcs/src/libs/glc_lib/glc_object.h deleted file mode 100644 index 9885b35b8..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_object.h +++ /dev/null @@ -1,124 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file GLC_object.h Interface for the GLC_Object class. - -#ifndef GLC_OBJECT_H_ -#define GLC_OBJECT_H_ - -#include -#include -#include -#include -#include "glc_global.h" - -#include "glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Object -/*! \brief GLC_Object is base class for some GLC class*/ - -/*! GLC_Object is a abstract class. \n \n - * Every GLC_Object have : - * - unique ID #m_Uid generated by #GLC_GenID - * - virtual OpenGL method GLC_Object::glExecute - */ -////////////////////////////////////////////////////////////////////// - -class GLC_LIB_EXPORT GLC_Object -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Default constructor - /*! Construct a GLC_Object , Generate is UID GLC_Object::m_Uid - * and set GLC_Object::m_Name to specified name*/ - GLC_Object(const QString& name= QString()); - - //! Construct a GLC_Object with the given UID - GLC_Object(GLC_uint id, const QString& name= QString()); - - //! Construct a GLC_Object from the given GLC_Object - GLC_Object(const GLC_Object& sourceObject); - - //! Virtual destructor - virtual ~GLC_Object(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return this object id - inline GLC_uint id() const - {return m_Uid;} - - //! Return this object name - inline const QString name() const - {return m_Name;} - - //! Return true if this object is equal to the given object - inline bool operator == (const GLC_Object& obj) - {return (m_Uid == obj.m_Uid) && (m_Name == obj.m_Name);} -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Set this object Id - /*! This method is thread safe*/ - void setId(const GLC_uint id); - - //! Set this object Name - /*! This method is thread safe*/ - void setName(const QString& name); - - //! Set this object from the given object - /*! This method is thread safe*/ - GLC_Object &operator=(const GLC_Object&); - -//@} - - -////////////////////////////////////////////////////////////////////// -// Protected member -////////////////////////////////////////////////////////////////////// - -protected: - //! The Unique ID of an GLC_Object - /*! Generated on GLC_Object creation*/ - GLC_uint m_Uid; - - //! Name of an GLC_Object - QString m_Name; - - //! GLC_Object Mutex - QMutex m_Mutex; -}; -#endif //GLC_OBJECT_H_ diff --git a/ground/gcs/src/libs/glc_lib/glc_openglexception.cpp b/ground/gcs/src/libs/glc_lib/glc_openglexception.cpp deleted file mode 100644 index 4f8921691..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_openglexception.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_openglexception.cpp implementation of the GLC_OpenGlException class. - -#include "glc_openglexception.h" - -////////////////////////////////////////////////////////////////////// -// Constructor destructor -////////////////////////////////////////////////////////////////////// - -GLC_OpenGlException::GLC_OpenGlException(const QString& message, GLenum glError) -:GLC_Exception(message) -{ - switch (glError) - { - case GL_INVALID_ENUM : - m_GlErrorDescription= "GLenum argument out of range"; - break; - case GL_INVALID_VALUE : - m_GlErrorDescription= "Numeric argument out of range"; - break; - case GL_INVALID_OPERATION : - m_GlErrorDescription= "Operation illegal in current state"; - break; - case GL_STACK_OVERFLOW : - m_GlErrorDescription= "Command would cause a stack overflow"; - break; - case GL_STACK_UNDERFLOW : - m_GlErrorDescription= "Command would cause a stack underflow"; - break; - case GL_OUT_OF_MEMORY : - m_GlErrorDescription= "Not enough memmory left to execute command"; - break; - default : - m_GlErrorDescription= "VERY BAD : UNKNOWN ERROR"; - break; - - } -} - -GLC_OpenGlException::~GLC_OpenGlException() throw() -{ - -} - - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -// Return exception description -const char* GLC_OpenGlException::what() const throw() -{ - QString exceptionmsg("GLC_OpenGlException : "); - exceptionmsg.append(m_ErrorDescription); - exceptionmsg.append(m_GlErrorDescription); - return exceptionmsg.toLatin1().data(); -} diff --git a/ground/gcs/src/libs/glc_lib/glc_openglexception.h b/ground/gcs/src/libs/glc_lib/glc_openglexception.h deleted file mode 100644 index 02132e952..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_openglexception.h +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_openglexception.h Interface for the GLC_OpenGlException class. - -#ifndef GLC_OPENGLEXCEPTION_H_ -#define GLC_OPENGLEXCEPTION_H_ - - -#include "glc_exception.h" - -#include - -#include "glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_OpenGlException -/*! \brief GLC_OpenGlException : Class for all OpenGL error - */ -////////////////////////////////////////////////////////////////////// - -class GLC_LIB_EXPORT GLC_OpenGlException : public GLC_Exception -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Default constructor - GLC_OpenGlException(const QString& message, GLenum glError); - - //! Destructor - virtual ~GLC_OpenGlException() throw(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return exception description - virtual const char* what() const throw(); -//@} - -////////////////////////////////////////////////////////////////////// -// protected members -////////////////////////////////////////////////////////////////////// -protected: - - //! Opengl Error description - QString m_GlErrorDescription; - -}; - -#endif /*GLC_OPENGLEXCEPTION_H_*/ diff --git a/ground/gcs/src/libs/glc_lib/glc_renderstatistics.cpp b/ground/gcs/src/libs/glc_lib/glc_renderstatistics.cpp deleted file mode 100644 index 877f83014..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_renderstatistics.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_renderstatistics.cpp implementation of the GLC_RenderStatistics class. - -#include "glc_renderstatistics.h" - -// Static variables initialisation -bool GLC_RenderStatistics::m_IsActivated= false; -unsigned int GLC_RenderStatistics::m_LastRenderGeometryCount= 0; -unsigned long GLC_RenderStatistics::m_LastRenderPolygonCount= 0; - -GLC_RenderStatistics::GLC_RenderStatistics() -{ - - -} - -GLC_RenderStatistics::~GLC_RenderStatistics() -{ - -} - -////////////////////////////////////////////////////////////////////// -// Get methods -////////////////////////////////////////////////////////////////////// -bool GLC_RenderStatistics::activated() -{ - return m_IsActivated; -} - -unsigned int GLC_RenderStatistics::bodyCount() -{ - return m_LastRenderGeometryCount; -} - -unsigned long GLC_RenderStatistics::triangleCount() -{ - return m_LastRenderPolygonCount; -} - -////////////////////////////////////////////////////////////////////// -// Set methods -////////////////////////////////////////////////////////////////////// -void GLC_RenderStatistics::setActivationFlag(bool flag) -{ - m_IsActivated= flag; -} - -void GLC_RenderStatistics::reset() -{ - m_LastRenderGeometryCount= 0; - m_LastRenderPolygonCount= 0; -} - -void GLC_RenderStatistics::addBodies(unsigned int bodies) -{ - if (m_IsActivated) - { - m_LastRenderGeometryCount+= bodies; - } -} - -void GLC_RenderStatistics::addTriangles(unsigned int triangles) -{ - if (m_IsActivated) - { - m_LastRenderPolygonCount+= triangles; - } -} diff --git a/ground/gcs/src/libs/glc_lib/glc_renderstatistics.h b/ground/gcs/src/libs/glc_lib/glc_renderstatistics.h deleted file mode 100644 index 88e8fec47..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_renderstatistics.h +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_renderstatistics.h interface for the GLC_RenderStatistics class. - -#ifndef GLC_RENDERSTATISTICS_H_ -#define GLC_RENDERSTATISTICS_H_ - -#include "glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_RenderStatistics -/*! \brief GLC_RenderStatistics is use to collect render statistics*/ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_RenderStatistics -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -private: - //! Private constructor. This class is static only - GLC_RenderStatistics(); - virtual ~GLC_RenderStatistics(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return true statistics are activated - static bool activated(); - - //! Return current body count - static unsigned int bodyCount(); - - //! Return current triangles count - static unsigned long triangleCount(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Set activation flag to the given flag - static void setActivationFlag(bool flag); - - //! Reset all count - static void reset(); - - //! Add bodies to the current body count - static void addBodies(unsigned int bodies); - - //! Add Triangles to the current tringle count - static void addTriangles(unsigned int triangles); - -//@} - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - - //! Flag to know if statistics are activated - static bool m_IsActivated; - - //! Last render geometry count - static unsigned int m_LastRenderGeometryCount; - - //! Last render polygon count - static unsigned long m_LastRenderPolygonCount; -}; - -#endif /* GLC_RENDERSTATISTICS_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/glc_state.cpp b/ground/gcs/src/libs/glc_lib/glc_state.cpp deleted file mode 100644 index 6f03b3609..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_state.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_state.cpp implementation of the GLC_State class. - -#include "glc_state.h" -#include "glc_ext.h" -#include "sceneGraph/glc_octree.h" - -#include - -bool GLC_State::m_VboSupported= false; -bool GLC_State::m_UseVbo= true; -bool GLC_State::m_GlslSupported= false; -bool GLC_State::m_PointSpriteSupported= false; -bool GLC_State::m_UseShader= true; -bool GLC_State::m_UseSelectionShader= false; -bool GLC_State::m_IsInSelectionMode= false; -bool GLC_State::m_IsPixelCullingActivated= true; -bool GLC_State::m_IsFrameBufferSupported= false; - -QString GLC_State::m_Version; -QString GLC_State::m_Vendor; -QString GLC_State::m_Renderer; - -bool GLC_State::m_UseCache= false; - -GLC_CacheManager GLC_State::m_CacheManager; - -bool GLC_State::m_IsSpacePartitionningActivated= false; -bool GLC_State::m_IsFrustumCullingActivated= false; -bool GLC_State::m_IsValid= false; - -GLC_State::~GLC_State() -{ -} - -bool GLC_State::vboSupported() -{ - return m_VboSupported; -} - -bool GLC_State::vboUsed() -{ - return m_UseVbo; -} - -bool GLC_State::glslSupported() -{ - return m_GlslSupported; -} - -bool GLC_State::frameBufferSupported() -{ - return m_IsFrameBufferSupported; -} - -bool GLC_State::glslUsed() -{ - return m_UseShader && m_GlslSupported; -} - -bool GLC_State::pointSpriteSupported() -{ - return m_PointSpriteSupported; -} - -bool GLC_State::selectionShaderUsed() -{ - return m_UseSelectionShader; -} - -bool GLC_State::isInSelectionMode() -{ - return m_IsInSelectionMode; -} - -QString GLC_State::version() -{ - return m_Version; -} - -QString GLC_State::vendor() -{ - return m_Vendor; -} - -QString GLC_State::renderer() -{ - return m_Renderer; -} - -bool GLC_State::vendorIsNvidia() -{ - return m_Vendor.contains("NVIDIA"); -} - -bool GLC_State::isPixelCullingActivated() -{ - return m_IsPixelCullingActivated; -} - -bool GLC_State::cacheIsUsed() -{ - return m_UseCache; -} - -GLC_CacheManager& GLC_State::currentCacheManager() -{ - return m_CacheManager; -} - -bool GLC_State::isSpacePartitionningActivated() -{ - return m_IsSpacePartitionningActivated; -} - -int GLC_State::defaultOctreeDepth() -{ - return GLC_Octree::defaultDepth(); -} - -bool GLC_State::isFrustumCullingActivated() -{ - return m_IsFrustumCullingActivated; -} - -void GLC_State::init() -{ - if (!m_IsValid) - { - Q_ASSERT((NULL != QGLContext::currentContext()) && QGLContext::currentContext()->isValid()); - setVboSupport(); - setGlslSupport(); - setPointSpriteSupport(); - setFrameBufferSupport(); - m_Version= (char *) glGetString(GL_VERSION); - m_Vendor= (char *) glGetString(GL_VENDOR); - m_Renderer= (char *) glGetString(GL_RENDERER); - - m_IsValid= true; - } -} - -bool GLC_State::isValid() -{ - return m_IsValid; -} - -void GLC_State::setVboSupport() -{ - m_VboSupported= glc::extensionIsSupported("ARB_vertex_buffer_object") && glc::loadVboExtension(); - setVboUsage(m_UseVbo); -} - -void GLC_State::setVboUsage(const bool vboUsed) -{ - m_UseVbo= m_VboSupported && vboUsed; -} - -void GLC_State::setGlslSupport() -{ - m_GlslSupported= glc::extensionIsSupported("GL_ARB_shading_language_100") && glc::loadGlSlExtension(); - setGlslUsage(m_UseShader); -} - -void GLC_State::setPointSpriteSupport() -{ - m_PointSpriteSupported= glc::extensionIsSupported("GL_ARB_point_parameters") && glc::loadPointSpriteExtension(); -} - -void GLC_State::setFrameBufferSupport() -{ - m_IsFrameBufferSupported= QGLFramebufferObject::hasOpenGLFramebufferObjects(); -} - -void GLC_State::setGlslUsage(const bool glslUsage) -{ - m_UseShader= m_GlslSupported && glslUsage; -} - -void GLC_State::setSelectionShaderUsage(const bool shaderUsed) -{ - m_UseSelectionShader= shaderUsed && m_GlslSupported; -} - -void GLC_State::setSelectionMode(const bool mode) -{ - m_IsInSelectionMode= mode; -} - -void GLC_State::setPixelCullingUsage(const bool activation) -{ - m_IsPixelCullingActivated= activation; -} - -void GLC_State::setCacheUsage(const bool cacheUsage) -{ - m_UseCache= cacheUsage; -} - -void GLC_State::setCurrentCacheManager(const GLC_CacheManager& cacheManager) -{ - m_CacheManager= cacheManager; -} - -void GLC_State::setSpacePartionningUsage(const bool usage) -{ - m_IsSpacePartitionningActivated= usage; -} - -void GLC_State::setDefaultOctreeDepth(int depth) -{ - GLC_Octree::setDefaultDepth(depth); -} - -void GLC_State::setFrustumCullingUsage(bool usage) -{ - m_IsFrustumCullingActivated= usage; -} diff --git a/ground/gcs/src/libs/glc_lib/glc_state.h b/ground/gcs/src/libs/glc_lib/glc_state.h deleted file mode 100644 index c6b52d7e7..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_state.h +++ /dev/null @@ -1,220 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_state.h interface for the GLC_State class. - -#ifndef GLC_STATE_H_ -#define GLC_STATE_H_ - -#include - -#include "glc_cachemanager.h" - -#include "glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_State -/*! \brief GLC_State store GLC_lib state*/ - -/*! GLC_State is used to set and get glabal GLC_lib state - * */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_State -{ -private: - GLC_State(); -public: - ~GLC_State(); - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return true if VBO is supported - static bool vboSupported(); - - //! Return true if VBO is used - static bool vboUsed(); - - //! Return true if GLSL is supported - static bool glslSupported(); - - //! Return true if frameBuffer is supported - static bool frameBufferSupported(); - - //! Return true if GLSL is used - static bool glslUsed(); - - //! Return true if Point Sprite is supported - static bool pointSpriteSupported(); - - //! Return true if selection shader is used - static bool selectionShaderUsed(); - - //! Return true if is in selection mode - static bool isInSelectionMode(); - - //! Return the Opengl version - static QString version(); - - //! Return the Opengl vendor - static QString vendor(); - - //! Return the Opengl renderer - static QString renderer(); - - //! Return true if OpenGL Vendor is NVIDIA - static bool vendorIsNvidia(); - - //! Return true if pixel culling is activate - static bool isPixelCullingActivated(); - - //! Return true if the cache is used - static bool cacheIsUsed(); - - //! Return the current cache manager - static GLC_CacheManager& currentCacheManager(); - - //! Return true if space partitionning is used - static bool isSpacePartitionningActivated(); - - //! Return the default octree depth - static int defaultOctreeDepth(); - - //! Return true if frustum culling is activated - static bool isFrustumCullingActivated(); - - //! Return true valid - static bool isValid(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Intialize the state - static void init(); - - //! Set VBO support - static void setVboSupport(); - - //! Set VBO usage - static void setVboUsage(const bool); - - //! Set GLSL support - static void setGlslSupport(); - - //! Set Point Sprite support - static void setPointSpriteSupport(); - - //! Set the frame buffer support - static void setFrameBufferSupport(); - - //! Set GLSL usage - static void setGlslUsage(const bool); - - //! Set selection shader usage - static void setSelectionShaderUsage(const bool); - - //! Set selection mode - static void setSelectionMode(const bool); - - //! Set pixel culling state - static void setPixelCullingUsage(const bool); - - //! Set the cache usage - static void setCacheUsage(const bool); - - //! Set the current cache manager - static void setCurrentCacheManager(const GLC_CacheManager&); - - //! Set space partionning usage - static void setSpacePartionningUsage(const bool); - - //! Set the default octree depth - static void setDefaultOctreeDepth(int); - - //! Set the frustum culling usage - static void setFrustumCullingUsage(bool); - -//@} - -////////////////////////////////////////////////////////////////////// -//Private attributes -////////////////////////////////////////////////////////////////////// -private: - //! VBO supported flag - static bool m_VboSupported; - - //! VBO used - static bool m_UseVbo; - - //! GLSL supported flag - static bool m_GlslSupported; - - //! Point Sprite supported flag - static bool m_PointSpriteSupported; - - //! Use shader - static bool m_UseShader; - - //! Use selectionShader flag - static bool m_UseSelectionShader; - - //! In selection mode - static bool m_IsInSelectionMode; - - //! Pixel culling activation - static bool m_IsPixelCullingActivated; - - //! The Opengl card version - static QString m_Version; - - //! The Opengl card vendor - static QString m_Vendor; - - //! The Opengl card renderer - static QString m_Renderer; - - //! Cache usage - static bool m_UseCache; - - //! The current cache manager - static GLC_CacheManager m_CacheManager; - - //! Space partitionning activation - static bool m_IsSpacePartitionningActivated; - - //! Frustum culling activated - static bool m_IsFrustumCullingActivated; - - //! Frame buffer supported - static bool m_IsFrameBufferSupported; - - //! State valid flag - static bool m_IsValid; - -}; - -#endif /*GLC_STATE_H_*/ diff --git a/ground/gcs/src/libs/glc_lib/glc_tracelog.cpp b/ground/gcs/src/libs/glc_lib/glc_tracelog.cpp deleted file mode 100644 index 4537513dc..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_tracelog.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -#include "glc_tracelog.h" - -#include -#include "glc_global.h" -#include - -GLC_TraceLog* GLC_TraceLog::m_pTraceLog= NULL; -QMutex GLC_TraceLog::m_Mutex; -bool GLC_TraceLog::m_IsEnable= false; - -GLC_TraceLog::GLC_TraceLog(const QString& fullLogFileName) -: GLC_Log(fullLogFileName) -{ - -} - -GLC_TraceLog::~GLC_TraceLog() -{ - -} - -GLC_TraceLog* GLC_TraceLog::instance(QString baseName) -{ - if (NULL == m_pTraceLog) - { - if (baseName.isEmpty()) - { - QString fileName(QApplication::applicationName()); - if (fileName.isEmpty()) - { - baseName= "GLC_lib_TraceLog"; - } - else - { - baseName= fileName + "_TraceLog"; - } - } - QString logFileName(QDir::tempPath() + QDir::separator() + baseName); - m_pTraceLog= new GLC_TraceLog(logFileName); - m_pTraceLog->writeHeader(); - } - return m_pTraceLog; -} - -bool GLC_TraceLog::isEmpty() -{ - return (NULL == m_pTraceLog); -} - -bool GLC_TraceLog::isEnable() -{ - return m_IsEnable; -} - -void GLC_TraceLog::addTrace(const QStringList& traceDescription) -{ - if (m_IsEnable) - { - QMutexLocker locker(&m_Mutex); - GLC_TraceLog::instance()->addSeparator(); - GLC_TraceLog::instance()->addCurrentTime(); - const int size= traceDescription.size(); - for (int i= 0; i < size; ++i) - { - GLC_TraceLog::instance()->add(traceDescription.at(i)); - } - } -} -void GLC_TraceLog::close() -{ - QMutexLocker locker(&m_Mutex); - delete m_pTraceLog; - m_pTraceLog= NULL; -} - -void GLC_TraceLog::setEnabled(bool enable) -{ - m_IsEnable= enable; -} - -void GLC_TraceLog::writeHeader() -{ - QString currentLine; - currentLine= "Trace Log file"; - GLC_Log::m_TextStream << currentLine << '\n'; - currentLine= "Application " + QCoreApplication::applicationName(); - GLC_Log::m_TextStream << currentLine << '\n'; - currentLine= QDate::currentDate().toString(Qt::ISODate); - GLC_Log::m_TextStream << currentLine << '\n'; - GLC_Log::m_TextStream.flush(); -} diff --git a/ground/gcs/src/libs/glc_lib/glc_tracelog.h b/ground/gcs/src/libs/glc_lib/glc_tracelog.h deleted file mode 100644 index 4bd2ef9c0..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_tracelog.h +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -#ifndef GLC_TRACELOG_H_ -#define GLC_TRACELOG_H_ - -#include "glc_log.h" -#include "glc_config.h" -#include -#include - -////////////////////////////////////////////////////////////////////// -//! \class GLC_TraceLog -/*! \brief GLC_TraceLog : handle GLC_lib trace log*/ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_TraceLog : public GLC_Log -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor */ -//@{ -////////////////////////////////////////////////////////////////////// -private: - //! Private constructor - GLC_TraceLog(const QString& fullLogFileName); -public: - //! Destructor - virtual ~GLC_TraceLog(); -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the unique instance of trace log file - static GLC_TraceLog* instance(QString baseName= QString()); - - //! Return true if the log is empty - static bool isEmpty(); - - //! Return true if the trace log is enable - static bool isEnable(); - -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Add error into the log - static void addTrace(const QStringList& traceDescription); - - //! Close the log file - static void close(); - - //! Set enable - static void setEnabled(bool enable); - -//@} - - -////////////////////////////////////////////////////////////////////// -/*! \name Private services Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Write trace Log header - void writeHeader(); - -//@} - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - //! The unique trace log instance - static GLC_TraceLog* m_pTraceLog; - - //! The mutex of this unique log - static QMutex m_Mutex; - - //! the trace log enable status - static bool m_IsEnable; - -}; - -#endif /* GLC_TRACELOG_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/glc_uniformshaderdata.cpp b/ground/gcs/src/libs/glc_lib/glc_uniformshaderdata.cpp deleted file mode 100644 index f994998de..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_uniformshaderdata.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_uniformshaderdata.cpp implementation of the GLC_UniformShaderData class. - -#include - -#include "shading/glc_shader.h" -#include "glc_context.h" -#include "glc_uniformshaderdata.h" - - -GLC_UniformShaderData::GLC_UniformShaderData() -{ - - -} - -GLC_UniformShaderData::~GLC_UniformShaderData() -{ - -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// -void GLC_UniformShaderData::setLightValues(const GLC_Light& light) -{ - -} - -void GLC_UniformShaderData::setLightingState(bool enable) -{ - GLC_Shader* pCurrentShader= GLC_Shader::currentShaderHandle(); - pCurrentShader->programShaderHandle()->setUniformValue(pCurrentShader->enableLightingId(), enable); -} - -void GLC_UniformShaderData::setModelViewProjectionMatrix(const GLC_Matrix4x4& modelView, const GLC_Matrix4x4& projection) -{ - // Set model view matrix - const double* pMvmatrixData= modelView.getData(); - GLfloat mvFloatMatrix[4][4]; - GLfloat* pData= &(mvFloatMatrix[0][0]); - for (int i= 0; i < 16; ++i) - { - pData[i]= static_cast(pMvmatrixData[i]); - } - - // Set model view projection matrix - GLC_Matrix4x4 modelViewProjectionMatrix= projection * modelView; - const double* pMvpmatrixData= modelViewProjectionMatrix.getData(); - GLfloat mvpFloatMatrix[4][4]; - pData= &(mvpFloatMatrix[0][0]); - for (int i= 0; i < 16; ++i) - { - pData[i]= static_cast(pMvpmatrixData[i]); - } - - // Set the transpose of inv model view matrix (For normal computation) - GLC_Matrix4x4 invTransposeModelView= modelView.inverted(); - invTransposeModelView.transpose(); - GLfloat invTmdv[3][3]; - { - const double* data= invTransposeModelView.getData(); - - invTmdv[0][0]= static_cast(data[0]); invTmdv[1][0]= static_cast(data[4]); invTmdv[2][0]= static_cast(data[8]); - invTmdv[0][1]= static_cast(data[1]); invTmdv[1][1]= static_cast(data[5]); invTmdv[2][1]= static_cast(data[9]); - invTmdv[0][2]= static_cast(data[2]); invTmdv[1][2]= static_cast(data[6]); invTmdv[2][2]= static_cast(data[10]); - } - - Q_ASSERT(GLC_Shader::hasActiveShader()); - - GLC_Shader* pCurrentShader= GLC_Shader::currentShaderHandle(); - pCurrentShader->programShaderHandle()->setUniformValue(pCurrentShader->modelViewLocationId(), mvFloatMatrix); - pCurrentShader->programShaderHandle()->setUniformValue(pCurrentShader->mvpLocationId(), mvpFloatMatrix); - pCurrentShader->programShaderHandle()->setUniformValue(pCurrentShader->invModelViewLocationId(), invTmdv); -} - -void GLC_UniformShaderData::updateAll(const GLC_Context* pContext) -{ - setModelViewProjectionMatrix(pContext->modelViewMatrix(), pContext->projectionMatrix()); - setLightingState(pContext->lightingIsEnable()); -} diff --git a/ground/gcs/src/libs/glc_lib/glc_uniformshaderdata.h b/ground/gcs/src/libs/glc_lib/glc_uniformshaderdata.h deleted file mode 100644 index c30e205b6..000000000 --- a/ground/gcs/src/libs/glc_lib/glc_uniformshaderdata.h +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_uniformshaderdata.h interface for the GLC_UniformShaderData class. - -#ifndef GLC_UNIFORMSHADERDATA_H_ -#define GLC_UNIFORMSHADERDATA_H_ - -#include - -#include "maths/glc_matrix4x4.h" -#include "shading/glc_light.h" - -#include "glc_config.h" - -class GLC_Context; - -class GLC_LIB_EXPORT GLC_UniformShaderData -{ -public: - GLC_UniformShaderData(); - virtual ~GLC_UniformShaderData(); - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Set Light values from the given light - void setLightValues(const GLC_Light& light); - - //! Set lighting enbale state - void setLightingState(bool enable); - - //! Set the model view matrix - void setModelViewProjectionMatrix(const GLC_Matrix4x4& modelView, const GLC_Matrix4x4& projection); - - //! Update all uniform variables - void updateAll(const GLC_Context* pContext); - -//@} - -////////////////////////////////////////////////////////////////////// -// private members -////////////////////////////////////////////////////////////////////// -private: - -}; - -#endif /* GLC_UNIFORMSHADERDATA_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/glu/glc_glu.h b/ground/gcs/src/libs/glc_lib/glu/glc_glu.h deleted file mode 100644 index 218f0742b..000000000 --- a/ground/gcs/src/libs/glc_lib/glu/glc_glu.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_glu.h declaration of glu functions - - - -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ - - -#ifndef GLC_GLU_H_ -#define GLC_GLU_H_ - -#include - -#include "../glc_config.h" - -namespace glc -{ - GLC_LIB_EXPORT void gluLookAt (GLdouble eyeX, GLdouble eyeY, GLdouble eyeZ, GLdouble centerX, GLdouble centerY, GLdouble centerZ, GLdouble upX, GLdouble upY, GLdouble upZ); - GLC_LIB_EXPORT void gluOrtho2D (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top); - GLC_LIB_EXPORT void gluPerspective (GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar); - GLC_LIB_EXPORT void gluPickMatrix (GLdouble x, GLdouble y, GLdouble delX, GLdouble delY, GLint *viewport); - GLC_LIB_EXPORT GLint gluProject (GLdouble objX, GLdouble objY, GLdouble objZ, const GLdouble *model, const GLdouble *proj, const GLint *view, GLdouble* winX, GLdouble* winY, GLdouble* winZ); - GLC_LIB_EXPORT GLint gluUnProject (GLdouble winX, GLdouble winY, GLdouble winZ, const GLdouble *model, const GLdouble *proj, const GLint *view, GLdouble* objX, GLdouble* objY, GLdouble* objZ); - GLC_LIB_EXPORT GLint gluUnProject4 (GLdouble winX, GLdouble winY, GLdouble winZ, GLdouble clipW, const GLdouble *model, const GLdouble *proj, const GLint *view, GLdouble nearVal, GLdouble farVal, GLdouble* objX, GLdouble* objY, GLdouble* objZ, GLdouble* objW); -}; - - -#endif /*GLC_GLU_H_*/ diff --git a/ground/gcs/src/libs/glc_lib/glu/glc_project.cpp b/ground/gcs/src/libs/glc_lib/glu/glc_project.cpp deleted file mode 100644 index cf76ea12b..000000000 --- a/ground/gcs/src/libs/glc_lib/glu/glc_project.cpp +++ /dev/null @@ -1,379 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_project implementation of glu project function - - -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ - -#include "../glc_context.h" -#include "glc_glu.h" - -/* -** Make m an identity matrix -*/ -static void __gluMakeIdentityd(GLdouble m[16]) -{ - m[0+4*0] = 1; m[0+4*1] = 0; m[0+4*2] = 0; m[0+4*3] = 0; - m[1+4*0] = 0; m[1+4*1] = 1; m[1+4*2] = 0; m[1+4*3] = 0; - m[2+4*0] = 0; m[2+4*1] = 0; m[2+4*2] = 1; m[2+4*3] = 0; - m[3+4*0] = 0; m[3+4*1] = 0; m[3+4*2] = 0; m[3+4*3] = 1; -} - -static void __gluMakeIdentityf(GLfloat m[16]) -{ - m[0+4*0] = 1; m[0+4*1] = 0; m[0+4*2] = 0; m[0+4*3] = 0; - m[1+4*0] = 0; m[1+4*1] = 1; m[1+4*2] = 0; m[1+4*3] = 0; - m[2+4*0] = 0; m[2+4*1] = 0; m[2+4*2] = 1; m[2+4*3] = 0; - m[3+4*0] = 0; m[3+4*1] = 0; m[3+4*2] = 0; m[3+4*3] = 1; -} - -void glc::gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top) -{ - GLC_Context::current()->glcOrtho(left, right, bottom, top, -1, 1); -} - -#define __glPi 3.14159265358979323846 - -void glc::gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar) -{ - GLdouble m[4][4]; - double sine, cotangent, deltaZ; - double radians = fovy / 2 * __glPi / 180; - - deltaZ = zFar - zNear; - sine = sin(radians); - if ((deltaZ == 0) || (sine == 0) || (aspect == 0)) { - return; - } - cotangent = cos(radians) / sine; - - __gluMakeIdentityd(&m[0][0]); - m[0][0] = cotangent / aspect; - m[1][1] = cotangent; - m[2][2] = -(zFar + zNear) / deltaZ; - m[2][3] = -1; - m[3][2] = -2 * zNear * zFar / deltaZ; - m[3][3] = 0; - GLC_Context::current()->glcMultMatrix(GLC_Matrix4x4(&m[0][0])); -} - -static void normalize(float v[3]) -{ - float r; - - r = sqrt( v[0]*v[0] + v[1]*v[1] + v[2]*v[2] ); - if (r == 0.0) return; - - v[0] /= r; - v[1] /= r; - v[2] /= r; -} - -static void cross(float v1[3], float v2[3], float result[3]) -{ - result[0] = v1[1]*v2[2] - v1[2]*v2[1]; - result[1] = v1[2]*v2[0] - v1[0]*v2[2]; - result[2] = v1[0]*v2[1] - v1[1]*v2[0]; -} - -void glc::gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx, - GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy, - GLdouble upz) -{ - float forward[3], side[3], up[3]; - GLfloat m[4][4]; - - forward[0] = centerx - eyex; - forward[1] = centery - eyey; - forward[2] = centerz - eyez; - - up[0] = upx; - up[1] = upy; - up[2] = upz; - - normalize(forward); - - /* Side = forward x up */ - cross(forward, up, side); - normalize(side); - - /* Recompute up as: up = side x forward */ - cross(side, forward, up); - - __gluMakeIdentityf(&m[0][0]); - m[0][0] = side[0]; - m[1][0] = side[1]; - m[2][0] = side[2]; - - m[0][1] = up[0]; - m[1][1] = up[1]; - m[2][1] = up[2]; - - m[0][2] = -forward[0]; - m[1][2] = -forward[1]; - m[2][2] = -forward[2]; - - GLC_Matrix4x4 translate; - translate.setMatTranslate(-eyex, -eyey, -eyez); - GLC_Matrix4x4 result= GLC_Matrix4x4(&m[0][0]) * translate; - GLC_Context::current()->glcMultMatrix(result); -} - -static void __gluMultMatrixVecd(const GLdouble matrix[16], const GLdouble in[4], - GLdouble out[4]) -{ - int i; - - for (i=0; i<4; i++) { - out[i] = - in[0] * matrix[0*4+i] + - in[1] * matrix[1*4+i] + - in[2] * matrix[2*4+i] + - in[3] * matrix[3*4+i]; - } -} - -/* -** Invert 4x4 matrix. -** Contributed by David Moore (See Mesa bug #6748) -*/ -static int __gluInvertMatrixd(const GLdouble m[16], GLdouble invOut[16]) -{ - double inv[16], det; - int i; - - inv[0] = m[5]*m[10]*m[15] - m[5]*m[11]*m[14] - m[9]*m[6]*m[15] - + m[9]*m[7]*m[14] + m[13]*m[6]*m[11] - m[13]*m[7]*m[10]; - inv[4] = -m[4]*m[10]*m[15] + m[4]*m[11]*m[14] + m[8]*m[6]*m[15] - - m[8]*m[7]*m[14] - m[12]*m[6]*m[11] + m[12]*m[7]*m[10]; - inv[8] = m[4]*m[9]*m[15] - m[4]*m[11]*m[13] - m[8]*m[5]*m[15] - + m[8]*m[7]*m[13] + m[12]*m[5]*m[11] - m[12]*m[7]*m[9]; - inv[12] = -m[4]*m[9]*m[14] + m[4]*m[10]*m[13] + m[8]*m[5]*m[14] - - m[8]*m[6]*m[13] - m[12]*m[5]*m[10] + m[12]*m[6]*m[9]; - inv[1] = -m[1]*m[10]*m[15] + m[1]*m[11]*m[14] + m[9]*m[2]*m[15] - - m[9]*m[3]*m[14] - m[13]*m[2]*m[11] + m[13]*m[3]*m[10]; - inv[5] = m[0]*m[10]*m[15] - m[0]*m[11]*m[14] - m[8]*m[2]*m[15] - + m[8]*m[3]*m[14] + m[12]*m[2]*m[11] - m[12]*m[3]*m[10]; - inv[9] = -m[0]*m[9]*m[15] + m[0]*m[11]*m[13] + m[8]*m[1]*m[15] - - m[8]*m[3]*m[13] - m[12]*m[1]*m[11] + m[12]*m[3]*m[9]; - inv[13] = m[0]*m[9]*m[14] - m[0]*m[10]*m[13] - m[8]*m[1]*m[14] - + m[8]*m[2]*m[13] + m[12]*m[1]*m[10] - m[12]*m[2]*m[9]; - inv[2] = m[1]*m[6]*m[15] - m[1]*m[7]*m[14] - m[5]*m[2]*m[15] - + m[5]*m[3]*m[14] + m[13]*m[2]*m[7] - m[13]*m[3]*m[6]; - inv[6] = -m[0]*m[6]*m[15] + m[0]*m[7]*m[14] + m[4]*m[2]*m[15] - - m[4]*m[3]*m[14] - m[12]*m[2]*m[7] + m[12]*m[3]*m[6]; - inv[10] = m[0]*m[5]*m[15] - m[0]*m[7]*m[13] - m[4]*m[1]*m[15] - + m[4]*m[3]*m[13] + m[12]*m[1]*m[7] - m[12]*m[3]*m[5]; - inv[14] = -m[0]*m[5]*m[14] + m[0]*m[6]*m[13] + m[4]*m[1]*m[14] - - m[4]*m[2]*m[13] - m[12]*m[1]*m[6] + m[12]*m[2]*m[5]; - inv[3] = -m[1]*m[6]*m[11] + m[1]*m[7]*m[10] + m[5]*m[2]*m[11] - - m[5]*m[3]*m[10] - m[9]*m[2]*m[7] + m[9]*m[3]*m[6]; - inv[7] = m[0]*m[6]*m[11] - m[0]*m[7]*m[10] - m[4]*m[2]*m[11] - + m[4]*m[3]*m[10] + m[8]*m[2]*m[7] - m[8]*m[3]*m[6]; - inv[11] = -m[0]*m[5]*m[11] + m[0]*m[7]*m[9] + m[4]*m[1]*m[11] - - m[4]*m[3]*m[9] - m[8]*m[1]*m[7] + m[8]*m[3]*m[5]; - inv[15] = m[0]*m[5]*m[10] - m[0]*m[6]*m[9] - m[4]*m[1]*m[10] - + m[4]*m[2]*m[9] + m[8]*m[1]*m[6] - m[8]*m[2]*m[5]; - - det = m[0]*inv[0] + m[1]*inv[4] + m[2]*inv[8] + m[3]*inv[12]; - if (det == 0) - return GL_FALSE; - - det = 1.0 / det; - - for (i = 0; i < 16; i++) - invOut[i] = inv[i] * det; - - return GL_TRUE; -} - -static void __gluMultMatricesd(const GLdouble a[16], const GLdouble b[16], - GLdouble r[16]) -{ - int i, j; - - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - r[i*4+j] = - a[i*4+0]*b[0*4+j] + - a[i*4+1]*b[1*4+j] + - a[i*4+2]*b[2*4+j] + - a[i*4+3]*b[3*4+j]; - } - } -} - -GLint glc::gluProject(GLdouble objx, GLdouble objy, GLdouble objz, - const GLdouble modelMatrix[16], - const GLdouble projMatrix[16], - const GLint viewport[4], - GLdouble *winx, GLdouble *winy, GLdouble *winz) -{ - double in[4]; - double out[4]; - - in[0]=objx; - in[1]=objy; - in[2]=objz; - in[3]=1.0; - __gluMultMatrixVecd(modelMatrix, in, out); - __gluMultMatrixVecd(projMatrix, out, in); - if (in[3] == 0.0) return(GL_FALSE); - in[0] /= in[3]; - in[1] /= in[3]; - in[2] /= in[3]; - /* Map x, y and z to range 0-1 */ - in[0] = in[0] * 0.5 + 0.5; - in[1] = in[1] * 0.5 + 0.5; - in[2] = in[2] * 0.5 + 0.5; - - /* Map x,y to viewport */ - in[0] = in[0] * viewport[2] + viewport[0]; - in[1] = in[1] * viewport[3] + viewport[1]; - - *winx=in[0]; - *winy=in[1]; - *winz=in[2]; - return(GL_TRUE); -} - -GLint glc::gluUnProject(GLdouble winx, GLdouble winy, GLdouble winz, - const GLdouble modelMatrix[16], - const GLdouble projMatrix[16], - const GLint viewport[4], - GLdouble *objx, GLdouble *objy, GLdouble *objz) -{ - double finalMatrix[16]; - double in[4]; - double out[4]; - - __gluMultMatricesd(modelMatrix, projMatrix, finalMatrix); - if (!__gluInvertMatrixd(finalMatrix, finalMatrix)) return(GL_FALSE); - - in[0]=winx; - in[1]=winy; - in[2]=winz; - in[3]=1.0; - - /* Map x and y from window coordinates */ - in[0] = (in[0] - viewport[0]) / viewport[2]; - in[1] = (in[1] - viewport[1]) / viewport[3]; - - /* Map to range -1 to 1 */ - in[0] = in[0] * 2 - 1; - in[1] = in[1] * 2 - 1; - in[2] = in[2] * 2 - 1; - - __gluMultMatrixVecd(finalMatrix, in, out); - if (out[3] == 0.0) return(GL_FALSE); - out[0] /= out[3]; - out[1] /= out[3]; - out[2] /= out[3]; - *objx = out[0]; - *objy = out[1]; - *objz = out[2]; - return(GL_TRUE); -} - -GLint glc::gluUnProject4(GLdouble winx, GLdouble winy, GLdouble winz, GLdouble clipw, - const GLdouble modelMatrix[16], - const GLdouble projMatrix[16], - const GLint viewport[4], - GLclampd nearVal, GLclampd farVal, - GLdouble *objx, GLdouble *objy, GLdouble *objz, - GLdouble *objw) -{ - double finalMatrix[16]; - double in[4]; - double out[4]; - - __gluMultMatricesd(modelMatrix, projMatrix, finalMatrix); - if (!__gluInvertMatrixd(finalMatrix, finalMatrix)) return(GL_FALSE); - - in[0]=winx; - in[1]=winy; - in[2]=winz; - in[3]=clipw; - - /* Map x and y from window coordinates */ - in[0] = (in[0] - viewport[0]) / viewport[2]; - in[1] = (in[1] - viewport[1]) / viewport[3]; - in[2] = (in[2] - nearVal) / (farVal - nearVal); - - /* Map to range -1 to 1 */ - in[0] = in[0] * 2 - 1; - in[1] = in[1] * 2 - 1; - in[2] = in[2] * 2 - 1; - - __gluMultMatrixVecd(finalMatrix, in, out); - if (out[3] == 0.0) return(GL_FALSE); - *objx = out[0]; - *objy = out[1]; - *objz = out[2]; - *objw = out[3]; - return(GL_TRUE); -} - -void glc::gluPickMatrix(GLdouble x, GLdouble y, GLdouble deltax, GLdouble deltay, - GLint viewport[4]) -{ - if (deltax <= 0 || deltay <= 0) { - return; - } - - /* Translate and scale the picked region to the entire window */ - GLC_Matrix4x4 translate; - translate.setMatTranslate((viewport[2] - 2 * (x - viewport[0])) / deltax, (viewport[3] - 2 * (y - viewport[1])) / deltay, 0.0); - - GLC_Matrix4x4 scaling; - scaling.setMatScaling(viewport[2] / deltax, viewport[3] / deltay, 0.0); - GLC_Context::current()->glcMultMatrix(translate * scaling); -} diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_3DRep b/ground/gcs/src/libs/glc_lib/include/GLC_3DRep deleted file mode 100644 index f9d6643f7..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_3DRep +++ /dev/null @@ -1 +0,0 @@ -#include "geometry/glc_3drep.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_3DViewCollection b/ground/gcs/src/libs/glc_lib/include/GLC_3DViewCollection deleted file mode 100644 index 88dea1166..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_3DViewCollection +++ /dev/null @@ -1 +0,0 @@ -#include "sceneGraph/glc_3dviewcollection.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_3DViewInstance b/ground/gcs/src/libs/glc_lib/include/GLC_3DViewInstance deleted file mode 100644 index 93c72b1c1..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_3DViewInstance +++ /dev/null @@ -1 +0,0 @@ -#include "sceneGraph/glc_3dviewinstance.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_3DWidget b/ground/gcs/src/libs/glc_lib/include/GLC_3DWidget deleted file mode 100644 index e73fa2731..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_3DWidget +++ /dev/null @@ -1 +0,0 @@ -#include "3DWidget/glc_3dwidget.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_3DWidgetManager b/ground/gcs/src/libs/glc_lib/include/GLC_3DWidgetManager deleted file mode 100644 index b4b055698..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_3DWidgetManager +++ /dev/null @@ -1 +0,0 @@ -#include "3DWidget/glc_3dwidgetmanager.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_3DWidgetManagerHandle b/ground/gcs/src/libs/glc_lib/include/GLC_3DWidgetManagerHandle deleted file mode 100644 index 6dfcf9197..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_3DWidgetManagerHandle +++ /dev/null @@ -1 +0,0 @@ -#include "3DWidget/glc_3dwidgetmanagerhandle.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_AbstractManipulator b/ground/gcs/src/libs/glc_lib/include/GLC_AbstractManipulator deleted file mode 100644 index 55c3a2d07..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_AbstractManipulator +++ /dev/null @@ -1 +0,0 @@ -#include "3DWidget/glc_abstractmanipulator.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Arrow b/ground/gcs/src/libs/glc_lib/include/GLC_Arrow deleted file mode 100644 index f951fa027..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Arrow +++ /dev/null @@ -1 +0,0 @@ -#include "geometry/glc_arrow.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Attributes b/ground/gcs/src/libs/glc_lib/include/GLC_Attributes deleted file mode 100644 index 6b7d9ee2a..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Attributes +++ /dev/null @@ -1 +0,0 @@ -#include "sceneGraph/glc_attributes.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Axis b/ground/gcs/src/libs/glc_lib/include/GLC_Axis deleted file mode 100644 index 671eb7ece..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Axis +++ /dev/null @@ -1 +0,0 @@ -#include "3DWidget/glc_axis.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_BSRep b/ground/gcs/src/libs/glc_lib/include/GLC_BSRep deleted file mode 100644 index b6e3b5cca..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_BSRep +++ /dev/null @@ -1 +0,0 @@ -#include "geometry/glc_bsrep.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_BoundingBox b/ground/gcs/src/libs/glc_lib/include/GLC_BoundingBox deleted file mode 100644 index 676d13bdb..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_BoundingBox +++ /dev/null @@ -1 +0,0 @@ -#include "glc_boundingbox.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Box b/ground/gcs/src/libs/glc_lib/include/GLC_Box deleted file mode 100644 index 53fc7c827..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Box +++ /dev/null @@ -1 +0,0 @@ -#include "geometry/glc_box.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_CacheManager b/ground/gcs/src/libs/glc_lib/include/GLC_CacheManager deleted file mode 100644 index 390653efa..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_CacheManager +++ /dev/null @@ -1 +0,0 @@ -#include "glc_cachemanager.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Camera b/ground/gcs/src/libs/glc_lib/include/GLC_Camera deleted file mode 100644 index ed2fa35db..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Camera +++ /dev/null @@ -1 +0,0 @@ -#include "viewport/glc_camera.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Circle b/ground/gcs/src/libs/glc_lib/include/GLC_Circle deleted file mode 100644 index 5e6a7f81e..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Circle +++ /dev/null @@ -1 +0,0 @@ -#include "geometry/glc_circle.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Cone b/ground/gcs/src/libs/glc_lib/include/GLC_Cone deleted file mode 100644 index 00e32cfbc..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Cone +++ /dev/null @@ -1 +0,0 @@ -#include "geometry/glc_cone.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Context b/ground/gcs/src/libs/glc_lib/include/GLC_Context deleted file mode 100644 index d204f90bb..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Context +++ /dev/null @@ -1 +0,0 @@ -#include "glc_context.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_ContextManager b/ground/gcs/src/libs/glc_lib/include/GLC_ContextManager deleted file mode 100644 index 8e7985eb4..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_ContextManager +++ /dev/null @@ -1 +0,0 @@ -#include "glc_contextmanager.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_CuttingPlane b/ground/gcs/src/libs/glc_lib/include/GLC_CuttingPlane deleted file mode 100644 index 3b46742b4..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_CuttingPlane +++ /dev/null @@ -1 +0,0 @@ -#include "3DWidget/glc_cuttingplane.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Cylinder b/ground/gcs/src/libs/glc_lib/include/GLC_Cylinder deleted file mode 100644 index ab0d0ff1f..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Cylinder +++ /dev/null @@ -1 +0,0 @@ -#include "geometry/glc_cylinder.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Disc b/ground/gcs/src/libs/glc_lib/include/GLC_Disc deleted file mode 100644 index a9962c239..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Disc +++ /dev/null @@ -1 +0,0 @@ -#include "geometry/glc_disc.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_ErrorLog b/ground/gcs/src/libs/glc_lib/include/GLC_ErrorLog deleted file mode 100644 index 2d4f53bc9..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_ErrorLog +++ /dev/null @@ -1 +0,0 @@ -#include "glc_errorlog.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Exception b/ground/gcs/src/libs/glc_lib/include/GLC_Exception deleted file mode 100644 index 122455f0e..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Exception +++ /dev/null @@ -1 +0,0 @@ -#include "glc_exception.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Ext b/ground/gcs/src/libs/glc_lib/include/GLC_Ext deleted file mode 100644 index 98a7a701a..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Ext +++ /dev/null @@ -1 +0,0 @@ -#include "glc_ext.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_ExtrudedMesh b/ground/gcs/src/libs/glc_lib/include/GLC_ExtrudedMesh deleted file mode 100644 index 3df40586d..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_ExtrudedMesh +++ /dev/null @@ -1 +0,0 @@ -#include "geometry/glc_extrudedmesh.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Factory b/ground/gcs/src/libs/glc_lib/include/GLC_Factory deleted file mode 100644 index 5d86240d8..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Factory +++ /dev/null @@ -1 +0,0 @@ -#include "glc_factory.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_FileFormatException b/ground/gcs/src/libs/glc_lib/include/GLC_FileFormatException deleted file mode 100644 index 35bd2c612..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_FileFormatException +++ /dev/null @@ -1 +0,0 @@ -#include "glc_fileformatexception.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_FileLoader b/ground/gcs/src/libs/glc_lib/include/GLC_FileLoader deleted file mode 100644 index e64087293..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_FileLoader +++ /dev/null @@ -1 +0,0 @@ -#include "io/glc_fileloader.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_FlyMover b/ground/gcs/src/libs/glc_lib/include/GLC_FlyMover deleted file mode 100644 index 43068977a..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_FlyMover +++ /dev/null @@ -1 +0,0 @@ -#include "viewport/glc_flymover.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Frustum b/ground/gcs/src/libs/glc_lib/include/GLC_Frustum deleted file mode 100644 index d19cb6005..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Frustum +++ /dev/null @@ -1 +0,0 @@ -#include "viewport/glc_frustum.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_GeomTools b/ground/gcs/src/libs/glc_lib/include/GLC_GeomTools deleted file mode 100644 index 5b52e7833..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_GeomTools +++ /dev/null @@ -1 +0,0 @@ -#include "maths/glc_geomtools.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Geometry b/ground/gcs/src/libs/glc_lib/include/GLC_Geometry deleted file mode 100644 index 57d8d7494..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Geometry +++ /dev/null @@ -1 +0,0 @@ -#include "geometry/glc_geometry.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Global b/ground/gcs/src/libs/glc_lib/include/GLC_Global deleted file mode 100644 index 51b8bbabd..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Global +++ /dev/null @@ -1 +0,0 @@ -#include "glc_global.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Glu b/ground/gcs/src/libs/glc_lib/include/GLC_Glu deleted file mode 100644 index 38ada69e1..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Glu +++ /dev/null @@ -1 +0,0 @@ -#include "glu/glc_glu.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_ImagePlane b/ground/gcs/src/libs/glc_lib/include/GLC_ImagePlane deleted file mode 100644 index 4ad46e629..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_ImagePlane +++ /dev/null @@ -1 +0,0 @@ -#include "viewport/glc_imageplane.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Interpolator b/ground/gcs/src/libs/glc_lib/include/GLC_Interpolator deleted file mode 100644 index 3cc316011..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Interpolator +++ /dev/null @@ -1 +0,0 @@ -#include "maths/glc_interpolator.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Light b/ground/gcs/src/libs/glc_lib/include/GLC_Light deleted file mode 100644 index 3d90d8407..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Light +++ /dev/null @@ -1 +0,0 @@ -#include "shading/glc_light.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Line b/ground/gcs/src/libs/glc_lib/include/GLC_Line deleted file mode 100644 index e4b0dafab..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Line +++ /dev/null @@ -1 +0,0 @@ -#include "geometry/glc_line.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Line3d b/ground/gcs/src/libs/glc_lib/include/GLC_Line3d deleted file mode 100644 index e6b482090..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Line3d +++ /dev/null @@ -1 +0,0 @@ -#include "maths/glc_line3d.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Log b/ground/gcs/src/libs/glc_lib/include/GLC_Log deleted file mode 100644 index 62da7a5a9..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Log +++ /dev/null @@ -1 +0,0 @@ -#include "glc_log.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Material b/ground/gcs/src/libs/glc_lib/include/GLC_Material deleted file mode 100644 index e1357616e..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Material +++ /dev/null @@ -1 +0,0 @@ -#include "shading/glc_material.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Matrix4x4 b/ground/gcs/src/libs/glc_lib/include/GLC_Matrix4x4 deleted file mode 100644 index 4426a087e..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Matrix4x4 +++ /dev/null @@ -1 +0,0 @@ -#include "maths/glc_matrix4x4.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Mesh b/ground/gcs/src/libs/glc_lib/include/GLC_Mesh deleted file mode 100644 index bf8c0657f..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Mesh +++ /dev/null @@ -1 +0,0 @@ -#include "geometry/glc_mesh.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Mover b/ground/gcs/src/libs/glc_lib/include/GLC_Mover deleted file mode 100644 index 5b98ad0ed..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Mover +++ /dev/null @@ -1 +0,0 @@ -#include "viewport/glc_mover.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_MoverController b/ground/gcs/src/libs/glc_lib/include/GLC_MoverController deleted file mode 100644 index da22c73eb..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_MoverController +++ /dev/null @@ -1 +0,0 @@ -#include "viewport/glc_movercontroller.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Object b/ground/gcs/src/libs/glc_lib/include/GLC_Object deleted file mode 100644 index 86e9b2f8d..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Object +++ /dev/null @@ -1 +0,0 @@ -#include "glc_object.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Octree b/ground/gcs/src/libs/glc_lib/include/GLC_Octree deleted file mode 100644 index 28c84762c..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Octree +++ /dev/null @@ -1 +0,0 @@ -#include "sceneGraph/glc_octree.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_OctreeNode b/ground/gcs/src/libs/glc_lib/include/GLC_OctreeNode deleted file mode 100644 index abfdb83e9..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_OctreeNode +++ /dev/null @@ -1 +0,0 @@ -#include "sceneGraph/glc_octreenode.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_OpenGlException b/ground/gcs/src/libs/glc_lib/include/GLC_OpenGlException deleted file mode 100644 index 8e1d352d6..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_OpenGlException +++ /dev/null @@ -1 +0,0 @@ -#include "glc_openglexception.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_PanMover b/ground/gcs/src/libs/glc_lib/include/GLC_PanMover deleted file mode 100644 index 69916d0c1..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_PanMover +++ /dev/null @@ -1 +0,0 @@ -#include "viewport/glc_panmover.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Plane b/ground/gcs/src/libs/glc_lib/include/GLC_Plane deleted file mode 100644 index 87952f25f..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Plane +++ /dev/null @@ -1 +0,0 @@ -#include "maths/glc_plane.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Point b/ground/gcs/src/libs/glc_lib/include/GLC_Point deleted file mode 100644 index 1bd38f6a6..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Point +++ /dev/null @@ -1 +0,0 @@ -#include "geometry/glc_point.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Point2d b/ground/gcs/src/libs/glc_lib/include/GLC_Point2d deleted file mode 100644 index 79fcf82b8..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Point2d +++ /dev/null @@ -1 +0,0 @@ -#include "maths/glc_vector2d.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Point2df b/ground/gcs/src/libs/glc_lib/include/GLC_Point2df deleted file mode 100644 index 17f84c7f0..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Point2df +++ /dev/null @@ -1 +0,0 @@ -#include "maths/glc_vector2df.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Point3d b/ground/gcs/src/libs/glc_lib/include/GLC_Point3d deleted file mode 100644 index 16e48ca73..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Point3d +++ /dev/null @@ -1 +0,0 @@ -#include "maths/glc_vector3d.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Point3df b/ground/gcs/src/libs/glc_lib/include/GLC_Point3df deleted file mode 100644 index 70748f2f7..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Point3df +++ /dev/null @@ -1 +0,0 @@ -#include "maths/glc_vector3df.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Point4d b/ground/gcs/src/libs/glc_lib/include/GLC_Point4d deleted file mode 100644 index 2053b8083..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Point4d +++ /dev/null @@ -1 +0,0 @@ -#include "maths/glc_vector4d.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_PointCloud b/ground/gcs/src/libs/glc_lib/include/GLC_PointCloud deleted file mode 100644 index e55f5fb08..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_PointCloud +++ /dev/null @@ -1 +0,0 @@ -#include "geometry/glc_pointcloud.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_PointSprite b/ground/gcs/src/libs/glc_lib/include/GLC_PointSprite deleted file mode 100644 index 06dccfe6a..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_PointSprite +++ /dev/null @@ -1 +0,0 @@ -#include "geometry/glc_pointsprite.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Polylines b/ground/gcs/src/libs/glc_lib/include/GLC_Polylines deleted file mode 100644 index f8d0fad1f..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Polylines +++ /dev/null @@ -1 +0,0 @@ -#include "geometry/glc_polylines.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_PullManipulator b/ground/gcs/src/libs/glc_lib/include/GLC_PullManipulator deleted file mode 100644 index 00a2fe680..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_PullManipulator +++ /dev/null @@ -1 +0,0 @@ -#include "3DWidget/glc_pullmanipulator.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Rectangle b/ground/gcs/src/libs/glc_lib/include/GLC_Rectangle deleted file mode 100644 index e3e28df67..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Rectangle +++ /dev/null @@ -1 +0,0 @@ -#include "geometry/glc_rectangle.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_RenderProperties b/ground/gcs/src/libs/glc_lib/include/GLC_RenderProperties deleted file mode 100644 index a271ed40a..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_RenderProperties +++ /dev/null @@ -1 +0,0 @@ -#include "shading/glc_renderproperties.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_RenderState b/ground/gcs/src/libs/glc_lib/include/GLC_RenderState deleted file mode 100644 index aa799f8fe..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_RenderState +++ /dev/null @@ -1 +0,0 @@ -#include "glc_renderstate.h diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_RenderStatistics b/ground/gcs/src/libs/glc_lib/include/GLC_RenderStatistics deleted file mode 100644 index 6b89f2c50..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_RenderStatistics +++ /dev/null @@ -1 +0,0 @@ -#include "glc_renderstatistics.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Renderer b/ground/gcs/src/libs/glc_lib/include/GLC_Renderer deleted file mode 100644 index a9ee640a5..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Renderer +++ /dev/null @@ -1,2 +0,0 @@ -#include "shading/glc_renderer.h" - diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Rep b/ground/gcs/src/libs/glc_lib/include/GLC_Rep deleted file mode 100644 index b798dcde1..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Rep +++ /dev/null @@ -1 +0,0 @@ -#include "geometry/glc_rep.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_RepCrossMover b/ground/gcs/src/libs/glc_lib/include/GLC_RepCrossMover deleted file mode 100644 index f3b70385f..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_RepCrossMover +++ /dev/null @@ -1 +0,0 @@ -#include "viewport/glc_repcrossmover.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_RepFlyMover b/ground/gcs/src/libs/glc_lib/include/GLC_RepFlyMover deleted file mode 100644 index 561a8810b..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_RepFlyMover +++ /dev/null @@ -1 +0,0 @@ -#include "viewport/glc_repflymover.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_RepMover b/ground/gcs/src/libs/glc_lib/include/GLC_RepMover deleted file mode 100644 index e57e359ea..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_RepMover +++ /dev/null @@ -1 +0,0 @@ -#include "viewport/glc_repmover.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_RepTrackBallMover b/ground/gcs/src/libs/glc_lib/include/GLC_RepTrackBallMover deleted file mode 100644 index 163668c62..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_RepTrackBallMover +++ /dev/null @@ -1 +0,0 @@ -#include "viewport/glc_reptrackballmover.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_RotationManipulator b/ground/gcs/src/libs/glc_lib/include/GLC_RotationManipulator deleted file mode 100644 index d2e8f29c7..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_RotationManipulator +++ /dev/null @@ -1 +0,0 @@ -#include "3DWidget/glc_rotationmanipulator.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_SelectionMaterial b/ground/gcs/src/libs/glc_lib/include/GLC_SelectionMaterial deleted file mode 100644 index 1c0690d75..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_SelectionMaterial +++ /dev/null @@ -1 +0,0 @@ -#include "shading/glc_selectionmaterial.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_SelectionSet b/ground/gcs/src/libs/glc_lib/include/GLC_SelectionSet deleted file mode 100644 index d96a282f9..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_SelectionSet +++ /dev/null @@ -1 +0,0 @@ -#include "sceneGraph/glc_selectionset.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Shader b/ground/gcs/src/libs/glc_lib/include/GLC_Shader deleted file mode 100644 index f058f2f45..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Shader +++ /dev/null @@ -1 +0,0 @@ -#include "shading/glc_shader.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_SpacePartitioning b/ground/gcs/src/libs/glc_lib/include/GLC_SpacePartitioning deleted file mode 100644 index 6ddabbadd..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_SpacePartitioning +++ /dev/null @@ -1 +0,0 @@ -#include "sceneGraph/glc_spacepertitionning.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Sphere b/ground/gcs/src/libs/glc_lib/include/GLC_Sphere deleted file mode 100644 index 17d43946e..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Sphere +++ /dev/null @@ -1 +0,0 @@ -#include "geometry/glc_sphere.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_State b/ground/gcs/src/libs/glc_lib/include/GLC_State deleted file mode 100644 index eeffae68e..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_State +++ /dev/null @@ -1 +0,0 @@ -#include "glc_state.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_StructInstance b/ground/gcs/src/libs/glc_lib/include/GLC_StructInstance deleted file mode 100644 index 7287ef0a0..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_StructInstance +++ /dev/null @@ -1 +0,0 @@ -#include "sceneGraph/glc_structinstance.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_StructOccurence b/ground/gcs/src/libs/glc_lib/include/GLC_StructOccurence deleted file mode 100644 index 295022968..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_StructOccurence +++ /dev/null @@ -1 +0,0 @@ -#include "sceneGraph/glc_structoccurence.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_StructReference b/ground/gcs/src/libs/glc_lib/include/GLC_StructReference deleted file mode 100644 index cc1d1983e..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_StructReference +++ /dev/null @@ -1 +0,0 @@ -#include "sceneGraph/glc_structreference.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Texture b/ground/gcs/src/libs/glc_lib/include/GLC_Texture deleted file mode 100644 index d3f388b94..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Texture +++ /dev/null @@ -1 +0,0 @@ -#include "shading/glc_texture.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_TraceLog b/ground/gcs/src/libs/glc_lib/include/GLC_TraceLog deleted file mode 100644 index a01ca19d1..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_TraceLog +++ /dev/null @@ -1 +0,0 @@ -#include "glc_tracelog.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_TrackBallMover b/ground/gcs/src/libs/glc_lib/include/GLC_TrackBallMover deleted file mode 100644 index ccfa82792..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_TrackBallMover +++ /dev/null @@ -1 +0,0 @@ -#include "viewport/glc_trackballmover.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_TsrMover b/ground/gcs/src/libs/glc_lib/include/GLC_TsrMover deleted file mode 100644 index d55ac1b43..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_TsrMover +++ /dev/null @@ -1 +0,0 @@ -#include "viewport/tsrmover.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_TurnTableMover b/ground/gcs/src/libs/glc_lib/include/GLC_TurnTableMover deleted file mode 100644 index 9665a18ac..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_TurnTableMover +++ /dev/null @@ -1 +0,0 @@ -#include "viewport/glc_turntablemover.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_UserInput b/ground/gcs/src/libs/glc_lib/include/GLC_UserInput deleted file mode 100644 index 49e7b16f0..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_UserInput +++ /dev/null @@ -1 +0,0 @@ -#include "viewport/glc_userinput.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Vector2d b/ground/gcs/src/libs/glc_lib/include/GLC_Vector2d deleted file mode 100644 index 79fcf82b8..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Vector2d +++ /dev/null @@ -1 +0,0 @@ -#include "maths/glc_vector2d.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Vector2df b/ground/gcs/src/libs/glc_lib/include/GLC_Vector2df deleted file mode 100644 index 17f84c7f0..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Vector2df +++ /dev/null @@ -1 +0,0 @@ -#include "maths/glc_vector2df.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Vector3d b/ground/gcs/src/libs/glc_lib/include/GLC_Vector3d deleted file mode 100644 index 16e48ca73..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Vector3d +++ /dev/null @@ -1 +0,0 @@ -#include "maths/glc_vector3d.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Vector3df b/ground/gcs/src/libs/glc_lib/include/GLC_Vector3df deleted file mode 100644 index 70748f2f7..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Vector3df +++ /dev/null @@ -1 +0,0 @@ -#include "maths/glc_vector3df.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Vector4d b/ground/gcs/src/libs/glc_lib/include/GLC_Vector4d deleted file mode 100644 index 2053b8083..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Vector4d +++ /dev/null @@ -1 +0,0 @@ -#include "maths/glc_vector4d.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_Viewport b/ground/gcs/src/libs/glc_lib/include/GLC_Viewport deleted file mode 100644 index b7201a3f0..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_Viewport +++ /dev/null @@ -1 +0,0 @@ -#include "viewport/glc_viewport.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_World b/ground/gcs/src/libs/glc_lib/include/GLC_World deleted file mode 100644 index 9b29e8602..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_World +++ /dev/null @@ -1 +0,0 @@ -#include "sceneGraph/glc_world.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_WorldReaderHandler b/ground/gcs/src/libs/glc_lib/include/GLC_WorldReaderHandler deleted file mode 100644 index b322e1d31..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_WorldReaderHandler +++ /dev/null @@ -1 +0,0 @@ -#include "io/glc_worldreaderhandler.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_WorldReaderPlugin b/ground/gcs/src/libs/glc_lib/include/GLC_WorldReaderPlugin deleted file mode 100644 index 72cbf206a..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_WorldReaderPlugin +++ /dev/null @@ -1 +0,0 @@ -#include "io/glc_worldreaderplugin.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_WorldTo3ds b/ground/gcs/src/libs/glc_lib/include/GLC_WorldTo3ds deleted file mode 100644 index 1ed1ade60..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_WorldTo3ds +++ /dev/null @@ -1 +0,0 @@ -#include "io/glc_worldto3ds.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_WorldTo3dxml b/ground/gcs/src/libs/glc_lib/include/GLC_WorldTo3dxml deleted file mode 100644 index 2544b75dc..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_WorldTo3dxml +++ /dev/null @@ -1 +0,0 @@ -#include "io/glc_worldto3dxml.h" diff --git a/ground/gcs/src/libs/glc_lib/include/GLC_ZoomMover b/ground/gcs/src/libs/glc_lib/include/GLC_ZoomMover deleted file mode 100644 index af2a29be0..000000000 --- a/ground/gcs/src/libs/glc_lib/include/GLC_ZoomMover +++ /dev/null @@ -1 +0,0 @@ -#include "viewport/glc_zoommover.h" diff --git a/ground/gcs/src/libs/glc_lib/include/glcXmlUtil b/ground/gcs/src/libs/glc_lib/include/glcXmlUtil deleted file mode 100644 index 09ba23c12..000000000 --- a/ground/gcs/src/libs/glc_lib/include/glcXmlUtil +++ /dev/null @@ -1 +0,0 @@ -#include "io/glc_xmlutil.h" diff --git a/ground/gcs/src/libs/glc_lib/io/glc_3dstoworld.cpp b/ground/gcs/src/libs/glc_lib/io/glc_3dstoworld.cpp deleted file mode 100644 index 4b7ac0542..000000000 --- a/ground/gcs/src/libs/glc_lib/io/glc_3dstoworld.cpp +++ /dev/null @@ -1,441 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_3dstoworld.cpp implementation of the GLC_3dsToWorld class. - -#include "glc_3dstoworld.h" - -#include "../geometry/glc_mesh.h" -#include "../sceneGraph/glc_world.h" -#include "../glc_fileformatexception.h" -#include "../geometry/glc_circle.h" -#include "../shading/glc_material.h" -#include "../maths/glc_vector2df.h" -#include "../maths/glc_vector3df.h" -#include "../sceneGraph/glc_structreference.h" -#include "../sceneGraph/glc_structinstance.h" -#include "../sceneGraph/glc_structoccurence.h" - -// Lib3ds Header -#include "3rdparty/lib3ds/file.h" -#include "3rdparty/lib3ds/mesh.h" -#include "3rdparty/lib3ds/node.h" -#include "3rdparty/lib3ds/matrix.h" -#include "3rdparty/lib3ds/material.h" - -#include -#include - -GLC_3dsToWorld::GLC_3dsToWorld() -: m_pWorld(NULL) -, m_FileName() -, m_pCurrentMesh(NULL) -, m_pLib3dsFile(NULL) -, m_Materials() -, m_NextMaterialIndex(0) -, m_LoadedMeshes() -, m_InitQuantumValue(50) -, m_CurrentQuantumValue(0) -, m_PreviousQuantumValue(0) -, m_NumberOfMeshes(0) -, m_CurrentMeshNumber(0) -, m_ListOfAttachedFileName() -{ -} - -GLC_3dsToWorld::~GLC_3dsToWorld() -{ - clear(); -} - -// Create an GLC_World from an input 3DS File -GLC_World* GLC_3dsToWorld::CreateWorldFrom3ds(QFile &file) -{ - clear(); - m_FileName= file.fileName(); - - ////////////////////////////////////////////////////////////////// - // Test if the file exist and can be opened - ////////////////////////////////////////////////////////////////// - if (!file.open(QIODevice::ReadOnly)) - { - QString message(QString("GLC_3dsToWorld::CreateWorldFrom3ds File ") + m_FileName + QString(" doesn't exist")); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotFound); - throw(fileFormatException); - } - // Close the file before open it with lib3ds - file.close(); - - ////////////////////////////////////////////////////////////////// - // Init member - ////////////////////////////////////////////////////////////////// - m_pWorld= new GLC_World; - - //Load 3ds File - m_pLib3dsFile=lib3ds_file_load(m_FileName.toLocal8Bit().data()); - if (!m_pLib3dsFile) - { - QString message= "GLC_3dsToWorld::CreateWorldFrom3ds : Loading Failed"; - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported); - clear(); - throw(fileFormatException); - } - // Evaluate Nodes Matrix for the first frame (Needed by instances) - lib3ds_file_eval(m_pLib3dsFile, 0.0); - m_CurrentQuantumValue= m_InitQuantumValue; - m_PreviousQuantumValue= m_CurrentQuantumValue; - - emit currentQuantum(m_CurrentQuantumValue); - // Count the number of meshes - for(Lib3dsMesh *pMesh= m_pLib3dsFile->meshes; pMesh != NULL; pMesh = pMesh->next) - { - ++m_NumberOfMeshes; - } - // Check if there is some meshes in the 3ds file - if (0 == m_NumberOfMeshes) - { - QString message= "GLC_3dsToWorld::CreateWorldFrom3ds : No mesh found !"; - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::NoMeshFound); - clear(); - throw(fileFormatException); - } - - // Create GLC_3DViewInstance with Node - for (Lib3dsNode *pNode=m_pLib3dsFile->nodes; pNode!=0; pNode=pNode->next) - { - createMeshes(m_pWorld->rootOccurence(), pNode); - } - - // Load unloaded mesh name - for(Lib3dsMesh *pMesh= m_pLib3dsFile->meshes; pMesh != NULL; pMesh = pMesh->next) - { - if (!m_LoadedMeshes.contains(QString(pMesh->name))) - { - //qDebug() << "Mesh without parent found" << QString(pMesh->name); - Lib3dsNode *pNode= lib3ds_node_new_object(); - strcpy(pNode->name, pMesh->name); - pNode->parent_id= LIB3DS_NO_PARENT; - lib3ds_file_insert_node(m_pLib3dsFile, pNode); - createMeshes(m_pWorld->rootOccurence(), pNode); - } - } - - // Free Lib3dsFile and all its ressources - lib3ds_file_free(m_pLib3dsFile); - m_pLib3dsFile= NULL; - emit currentQuantum(100); - // Create the world bounding box - m_pWorld->collection()->boundingBox(); - return m_pWorld; -} - -///////////////////////////////////////////////////////////////////// -// Private services Functions -////////////////////////////////////////////////////////////////////// - -// clear 3dsToWorld allocate memory and reset member -void GLC_3dsToWorld::clear() -{ - if (NULL != m_pCurrentMesh) - { - delete m_pCurrentMesh; - m_pCurrentMesh= NULL; - } - m_pWorld= NULL; - m_FileName.clear(); - if (NULL != m_pLib3dsFile) - { - lib3ds_file_free(m_pLib3dsFile); - m_pLib3dsFile= NULL; - } - - // Remove unused material - QHash::iterator i; - for (i= m_Materials.begin(); i != m_Materials.end(); ++i) - { - if (i.value()->isUnused()) delete i.value(); - } - m_Materials.clear(); - m_NextMaterialIndex= 0; - // Clear the loaded meshes Set - m_LoadedMeshes.clear(); - // Progress indicator - m_CurrentQuantumValue= 0; - m_PreviousQuantumValue= 0; - m_NumberOfMeshes= 0; - m_CurrentMeshNumber= 0; - m_ListOfAttachedFileName.clear(); -} - -// Create meshes from the 3ds File -void GLC_3dsToWorld::createMeshes(GLC_StructOccurence* pProduct, Lib3dsNode* pFatherNode) -{ - GLC_StructOccurence* pChildProduct= NULL; - Lib3dsMesh *pMesh= NULL; - - if (pFatherNode->type == LIB3DS_OBJECT_NODE) - { - //qDebug() << "Node type LIB3DS_OBJECT_NODE is named : " << QString(pFatherNode->name); - //qDebug() << "Node Matrix :"; - //qDebug() << GLC_Matrix4x4(&(pFatherNode->matrix[0][0])).toString(); - - // Check if the node is a mesh or dummy - if (!(strcmp(pFatherNode->name,"$$$DUMMY")==0)) - { - pMesh = lib3ds_file_mesh_by_name(m_pLib3dsFile, pFatherNode->name); - if( pMesh != NULL ) - { - GLC_3DRep representation(create3DRep(pMesh)); - // Test if there is vertex in the mesh - if (0 != representation.vertexCount()) - { - m_LoadedMeshes.insert(representation.name()); - // Load node matrix - GLC_Matrix4x4 nodeMat(&(pFatherNode->matrix[0][0])); - // The mesh matrix to inverse - GLC_Matrix4x4 matInv(&(pMesh->matrix[0][0])); - matInv.invert(); - // Get the node pivot - Lib3dsObjectData *pObjectData; - pObjectData= &pFatherNode->data.object; - GLC_Matrix4x4 trans(-pObjectData->pivot[0], -pObjectData->pivot[1], -pObjectData->pivot[2]); - // Compute the part matrix - nodeMat= nodeMat * trans * matInv; // I don't know why... - nodeMat.optimise(); - // move the part by the matrix - pProduct->addChild((new GLC_StructInstance(new GLC_3DRep(representation)))->move(nodeMat)); - } - else - { - // the instance will be deleted, check material usage - QSet meshMaterials= representation.materialSet(); - QSet::const_iterator iMat= meshMaterials.constBegin(); - while (iMat != meshMaterials.constEnd()) - { - if ((*iMat)->numberOfUsage() == 1) - { - m_Materials.remove((*iMat)->name()); - } - ++iMat; - } - } - } - } // End If DUMMY - } - else return; - // If there is a child, create a child product - if (NULL != pFatherNode->childs) - { - pChildProduct= new GLC_StructOccurence(); - pProduct->addChild(pChildProduct); - - pChildProduct->setName(QString("Product") + QString::number(pFatherNode->node_id)); - - //pChildProduct->move(GLC_Matrix4x4(&(pFatherNode->matrix[0][0]))); - - // Create Childs meshes if exists - for (Lib3dsNode* pNode= pFatherNode->childs; pNode!=0; pNode= pNode->next) - { - createMeshes(pChildProduct, pNode); - } - } - - -} -//! Create 3DRep from a Lib3dsNode -GLC_3DRep GLC_3dsToWorld::create3DRep(Lib3dsMesh* p3dsMesh) -{ - QString meshName(p3dsMesh->name); - if (m_LoadedMeshes.contains(meshName)) - { - // This mesh as been already loaded - QList instancesList(m_pWorld->collection()->instancesHandle()); - GLC_3DViewInstance* pCurrentInstance= NULL; - int currentIndex= -1; - do - { - pCurrentInstance= instancesList[++currentIndex]; - } while (pCurrentInstance->name() != meshName); - // return an instance. - //qDebug() << "instance"; - return pCurrentInstance->representation(); - } - GLC_Mesh * pMesh= new GLC_Mesh(); - pMesh->setName(p3dsMesh->name); - // The mesh normals - const int normalsNumber= p3dsMesh->faces * 3; - - Lib3dsVector *normalL= static_cast(malloc(normalsNumber * sizeof(Lib3dsVector))); - lib3ds_mesh_calculate_normals(p3dsMesh, normalL); - - // Position vector - QVector position(normalsNumber * 3); - - // Normal Vector - QVector normal(normalsNumber * 3); - memcpy((void*)normal.data(), normalL, normalsNumber * 3 * sizeof(float)); - - // Texel Vector - QVector texel; - if (p3dsMesh->texels > 0) - { - texel.resize(normalsNumber * 2); - } - - int normalIndex= 0; - for (unsigned int i= 0; i < p3dsMesh->faces; ++i) - { - IndexList triangleIndex; - Lib3dsFace *p3dsFace=&p3dsMesh->faceL[i]; - for (int i=0; i < 3; ++i) - { - triangleIndex.append(normalIndex); - // Add vertex coordinate - memcpy((void*)&(position.data()[normalIndex * 3]), &p3dsMesh->pointL[p3dsFace->points[i]], 3 * sizeof(float)); - - // Add texel - if (p3dsMesh->texels > 0) - { - memcpy((void*)&(texel.data()[normalIndex * 2]), &p3dsMesh->texelL[p3dsFace->points[i]], 2 * sizeof(float)); - } - ++normalIndex; - } - - // Load the material - // The material current face index - GLC_Material* pCurMaterial= NULL; - if (p3dsFace->material[0]) - { - Lib3dsMaterial* p3dsMat=lib3ds_file_material_by_name(m_pLib3dsFile, p3dsFace->material); - if (NULL != p3dsMat) - { - // Check it this material as already been loaded - const QString materialName(p3dsFace->material); - - if (!m_Materials.contains(materialName)) - { // Material not already loaded, load it - loadMaterial(p3dsMat); - } - pCurMaterial= m_Materials.value(materialName); - } - } - pMesh->addTriangles(pCurMaterial, triangleIndex); - } - pMesh->addVertice(position); - pMesh->addNormals(normal); - if (p3dsMesh->texels > 0) - { - pMesh->addTexels(texel); - } - - // free normal memmory - delete[] normalL; - // Compute loading progress - ++m_CurrentMeshNumber; - m_CurrentQuantumValue = static_cast((static_cast(m_CurrentMeshNumber) / m_NumberOfMeshes) * (100 - m_InitQuantumValue)) + m_InitQuantumValue; - if (m_CurrentQuantumValue > m_PreviousQuantumValue) - { - emit currentQuantum(m_CurrentQuantumValue); - } - m_PreviousQuantumValue= m_CurrentQuantumValue; - - pMesh->finish(); - return GLC_3DRep(pMesh); -} - -// Load Material -void GLC_3dsToWorld::loadMaterial(Lib3dsMaterial* p3dsMaterial) -{ - GLC_Material* pMaterial= new GLC_Material; - // Set the material name - const QString materialName(p3dsMaterial->name); - pMaterial->setName(materialName); - // Check if there is a texture - if (p3dsMaterial->texture1_map.name[0]) - { - const QString textureName(p3dsMaterial->texture1_map.name); - // Retrieve the .3ds file path - QFileInfo fileInfo(m_FileName); - QString textureFileName(fileInfo.absolutePath() + QDir::separator()); - textureFileName.append(textureName); - - // TGA file type are not supported - if (!textureName.right(3).contains("TGA", Qt::CaseInsensitive)) - { - QFile textureFile(textureFileName); - - if (textureFile.open(QIODevice::ReadOnly)) - { - // Create the texture and assign it to the material - GLC_Texture *pTexture = new GLC_Texture(textureFile); - pMaterial->setTexture(pTexture); - m_ListOfAttachedFileName << textureFileName; - textureFile.close(); - } - else - { - QStringList stringList(m_FileName); - stringList.append("Open File : " + textureFileName + " failed"); - GLC_ErrorLog::addError(stringList); - } - - } - else - { - QStringList stringList(m_FileName); - stringList.append("Image : " + textureFileName + " not suported"); - GLC_ErrorLog::addError(stringList); - } - } - - // Ambient Color - QColor ambient; - ambient.setRgbF(p3dsMaterial->ambient[0], p3dsMaterial->ambient[1], p3dsMaterial->ambient[2]); - ambient.setAlphaF(p3dsMaterial->ambient[3]); - pMaterial->setAmbientColor(ambient); - // Diffuse Color - QColor diffuse; - diffuse.setRgbF(p3dsMaterial->diffuse[0], p3dsMaterial->diffuse[1], p3dsMaterial->diffuse[2]); - diffuse.setAlphaF(p3dsMaterial->diffuse[3]); - pMaterial->setDiffuseColor(diffuse); - // Specular Color - QColor specular; - specular.setRgbF(p3dsMaterial->specular[0], p3dsMaterial->specular[1], p3dsMaterial->specular[2]); - specular.setAlphaF(p3dsMaterial->specular[3]); - pMaterial->setSpecularColor(specular); - // Shininess - - if (0 != p3dsMaterial->shininess) - { - float matShininess= p3dsMaterial->shininess * 128.0f; - if (matShininess > 128.0f) matShininess= 128.0f; - if (matShininess < 5.0f) matShininess= 20.0f; - pMaterial->setShininess(matShininess); - } - // Transparency - - pMaterial->setOpacity(1.0 - p3dsMaterial->transparency); - - // Add the material to the hash table - m_Materials.insert(materialName, pMaterial); -} - diff --git a/ground/gcs/src/libs/glc_lib/io/glc_3dstoworld.h b/ground/gcs/src/libs/glc_lib/io/glc_3dstoworld.h deleted file mode 100644 index 9aa7330c3..000000000 --- a/ground/gcs/src/libs/glc_lib/io/glc_3dstoworld.h +++ /dev/null @@ -1,167 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_3dstoworld.h interface for the GLC_3dsToWorld class. - -#ifndef GLC_3DSTOWORLD_H_ -#define GLC_3DSTOWORLD_H_ - -#include -#include -#include -#include -#include -#include -#include - -#include "../sceneGraph/glc_3dviewinstance.h" - -#include "../glc_config.h" - -class GLC_World; -class QGLContext; -class GLC_Mesh; -class GLC_StructOccurence; -class GLC_Material; - -struct Lib3dsFile; -struct Lib3dsNode; -struct Lib3dsMesh; -struct Lib3dsMaterial; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_3dsToWorld -/*! \brief GLC_3dsToWorld : Create an GLC_World from 3ds file */ - -/*! An GLC_3dsToWorld extract meshs from an .3ds file \n - * List of elements extracted from the 3ds - * - Vertex - * - Face - * - Normal coordinate - * - Material - * - Meshes - */ -////////////////////////////////////////////////////////////////////// - -class GLC_LIB_EXPORT GLC_3dsToWorld : public QObject -{ - Q_OBJECT - -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// - -public: - GLC_3dsToWorld(); - virtual ~GLC_3dsToWorld(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! @name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Create an GLC_World from an input 3DS File - GLC_World* CreateWorldFrom3ds(QFile &file); - - //! Get the list of attached files - inline QStringList listOfAttachedFileName() const - {return m_ListOfAttachedFileName.toList();} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! @name Private services functions */ -//@{ -////////////////////////////////////////////////////////////////////// -private: - //! clear 3dsToWorld allocate memmory - void clear(); - - //! Create meshes from the 3ds File - void createMeshes(GLC_StructOccurence*, Lib3dsNode*); - - //! Create 3DRep from a Lib3dsMesh - GLC_3DRep create3DRep(Lib3dsMesh*); - - //! Load Material - void loadMaterial(Lib3dsMaterial*); - -//@} - -////////////////////////////////////////////////////////////////////// -// Qt Signals -////////////////////////////////////////////////////////////////////// - signals: - void currentQuantum(int); - -////////////////////////////////////////////////////////////////////// - /* Private members */ -////////////////////////////////////////////////////////////////////// -private: - //! pointer to a GLC_World - GLC_World* m_pWorld; - - //! The 3DS File name - QString m_FileName; - - //! The current mesh - GLC_Mesh* m_pCurrentMesh; - - //! The Lib3dsFile Structure - Lib3dsFile* m_pLib3dsFile; - - //! The GLC_Material Hash Table - QHash m_Materials; - - //! The next material index - int m_NextMaterialIndex; - - // The Hash of loaded meshes - QSet m_LoadedMeshes; - - // Initial quantum value - const int m_InitQuantumValue; - - // The current quantum value - int m_CurrentQuantumValue; - - // The previous quantum value - int m_PreviousQuantumValue; - - // The number of meshes - int m_NumberOfMeshes; - - // The Current mesh index - int m_CurrentMeshNumber; - - //! The list of attached file name - QSet m_ListOfAttachedFileName; - - - - - -}; - -#endif /*GLC_3DSTOWORLD_H_*/ diff --git a/ground/gcs/src/libs/glc_lib/io/glc_3dxmltoworld.cpp b/ground/gcs/src/libs/glc_lib/io/glc_3dxmltoworld.cpp deleted file mode 100644 index fcea092de..000000000 --- a/ground/gcs/src/libs/glc_lib/io/glc_3dxmltoworld.cpp +++ /dev/null @@ -1,2417 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_3dxmltoworld.cpp implementation of the GLC_3dxmlToWorld class. - -#include "glc_3dxmltoworld.h" -#include "../sceneGraph/glc_world.h" -#include "../glc_fileformatexception.h" -#include "../geometry/glc_mesh.h" -#include "../geometry/glc_3drep.h" -#include "glc_xmlutil.h" - -// Quazip library -#include "../3rdparty/quazip/quazip.h" -#include "../3rdparty/quazip/quazipfile.h" - -#include -#include -#include -#include -#include - -//using namespace glcXmlUtil; - -QMutex GLC_3dxmlToWorld::m_ZipMutex; - -static qint64 chunckSize= 10000000; - -GLC_3dxmlToWorld::GLC_3dxmlToWorld() -: QObject() -, m_pStreamReader(NULL) -, m_FileName() -, m_p3dxmlArchive(NULL) -, m_pCurrentFile(NULL) -, m_RootName() -, m_pWorld(NULL) -, m_ReferenceHash() -, m_AssyLinkList() -, m_InstanceOf() -, m_SetOfExtRef() -, m_InstanceOfExtRefHash() -, m_ExternalReferenceHash() -, m_MaterialHash() -, m_IsInArchive(false) -, m_ReferenceRepHash() -, m_LocalRepLinkList() -, m_ExternRepLinkList() -, m_SetOfExtRep() -, m_pCurrentMaterial(NULL) -, m_TextureImagesHash() -, m_LoadStructureOnly(false) -, m_SetOfAttachedFileName() -, m_CurrentFileName() -, m_CurrentDateTime() -, m_V3OccurenceAttribHash() -, m_V4OccurenceAttribList() -, m_GetExternalRef3DName(false) -, m_ByteArrayList() -, m_IsVersion3(false) -{ - -} - -GLC_3dxmlToWorld::~GLC_3dxmlToWorld() -{ - delete m_pStreamReader; - m_pStreamReader= NULL; - - delete m_pCurrentFile; - delete m_p3dxmlArchive; - - clearMaterialHash(); - - // Clear specific attributes hash table - QHash::iterator iAttrib= m_V3OccurenceAttribHash.begin(); - while (m_V3OccurenceAttribHash.constEnd() != iAttrib) - { - delete iAttrib.value(); - ++iAttrib; - } - - const int v4OccurenceAttribCount= m_V4OccurenceAttribList.count(); - for (int i= 0; i < v4OccurenceAttribCount; ++i) - { - delete m_V4OccurenceAttribList.at(i); - } -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -// Create an GLC_World from an input 3DXML File -GLC_World* GLC_3dxmlToWorld::createWorldFrom3dxml(QFile &file, bool structureOnly, bool getExternalRef) -{ - clear(); - m_pWorld= new GLC_World(); - m_GetExternalRef3DName= getExternalRef; - m_LoadStructureOnly= structureOnly; - m_FileName= file.fileName(); - - // Create the 3dxml Zip archive - m_p3dxmlArchive= new QuaZip(m_FileName); - // Trying to load archive - if(!m_p3dxmlArchive->open(QuaZip::mdUnzip)) - { - // In this case, the 3dxml is not compressed or is not valid - m_RootName= m_FileName; - delete m_p3dxmlArchive; - m_p3dxmlArchive= NULL; - } - else - { - // Get the 3DXML time stamp - m_CurrentDateTime= QFileInfo(m_FileName).lastModified(); - - m_IsInArchive= true; - // Set the file Name Codec - //m_p3dxmlArchive->setFileNameCodec("IBM866"); - - // Load the manifest - loadManifest(); - } - - if (!m_LoadStructureOnly) - { - // Trying to Load CATRepImage file - loadCatRepImage(); - - // Trying to Load CATRefMaterial File - loadCatMaterialRef(); - } - - // Read the header - readHeader(); - - // Load the product structure - loadProductStructure(); - - - emit currentQuantum(100); - return m_pWorld; -} - -// Create 3DRep from an 3DXML rep -GLC_3DRep GLC_3dxmlToWorld::create3DrepFrom3dxmlRep(const QString& fileName) -{ - GLC_3DRep resultRep; - if (glc::isArchiveString(fileName)) - { - m_FileName= glc::archiveFileName(fileName); - - // Create the 3dxml Zip archive - m_ZipMutex.lock(); - m_p3dxmlArchive= new QuaZip(m_FileName); - // Trying to load archive - if(!m_p3dxmlArchive->open(QuaZip::mdUnzip)) - { - delete m_p3dxmlArchive; - return GLC_3DRep(); - } - else - { - m_IsInArchive= true; - // Set the file Name Codec - //m_p3dxmlArchive->setFileNameCodec("IBM866"); - } - m_ZipMutex.unlock(); - m_CurrentFileName= glc::archiveEntryFileName(fileName); - - // Get the 3DXML time stamp - m_CurrentDateTime= QFileInfo(QFileInfo(m_FileName)).lastModified(); - } - else if (glc::isFileString(fileName)) - { - m_FileName= glc::archiveFileName(fileName); - m_CurrentFileName= glc::archiveEntryFileName(fileName); - - // Get the rep time stamp - m_CurrentDateTime= QFileInfo(m_CurrentFileName).lastModified(); - - // Keep only the file name - QDir structureDir(QFileInfo(m_FileName).absolutePath() + QDir::separator()); - m_CurrentFileName= structureDir.relativeFilePath(m_CurrentFileName); - - } - else - { - return resultRep; - } - - - setRepresentationFileName(&resultRep); - - if (QFileInfo(m_CurrentFileName).suffix().toLower() == "3dxml") - { - if (GLC_State::cacheIsUsed() && GLC_State::currentCacheManager().isUsable(m_CurrentDateTime, QFileInfo(m_FileName).baseName(), QFileInfo(m_CurrentFileName).fileName())) - { - GLC_CacheManager cacheManager = GLC_State::currentCacheManager(); - - GLC_BSRep binaryRep = cacheManager.binary3DRep(QFileInfo(m_FileName).baseName(), QFileInfo(m_CurrentFileName).fileName()); - resultRep = binaryRep.loadRep(); - } - else - { - if (setStreamReaderToFile(m_CurrentFileName, true)) - { - GLC_StructReference* pStructRef = createReferenceRep(QString(), NULL); - GLC_3DRep* pRep = NULL; - if ((NULL != pStructRef) && pStructRef->hasRepresentation()) - { - pRep= dynamic_cast (pStructRef->representationHandle()); - - if (NULL != pRep) - { - resultRep = GLC_3DRep(*pRep); - resultRep.setName(pStructRef->name()); - } - } - delete pStructRef; - } - } - } - else if ((QFileInfo(m_CurrentFileName).suffix().toLower() == "3drep") || (QFileInfo(m_CurrentFileName).suffix().toLower() == "xml")) - { - if (GLC_State::cacheIsUsed() && GLC_State::currentCacheManager().isUsable(m_CurrentDateTime, QFileInfo(m_FileName).baseName(), QFileInfo(m_CurrentFileName).fileName())) - { - GLC_CacheManager cacheManager = GLC_State::currentCacheManager(); - GLC_BSRep binaryRep = cacheManager.binary3DRep(QFileInfo(m_FileName).baseName(), QFileInfo(m_CurrentFileName).fileName()); - resultRep = binaryRep.loadRep(); - } - else - { - if (setStreamReaderToFile(m_CurrentFileName, true)) - { - resultRep = loadCurrentExtRep(); - } - } - } - resultRep.clean(); - - return resultRep; -} - -////////////////////////////////////////////////////////////////////// -// Private services functions -////////////////////////////////////////////////////////////////////// -// Load the 3dxml's manifest -void GLC_3dxmlToWorld::loadManifest() -{ - setStreamReaderToFile("Manifest.xml"); - m_RootName= getContent(m_pStreamReader, "Root"); - - if (m_pStreamReader->atEnd() || m_pStreamReader->hasError()) - { - QString message(QString("GLC_3dxmlToWorld::loadManifest Manifest file ") + m_FileName + " doesn't contains Root Element"); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - - delete m_pStreamReader; - m_pStreamReader= NULL; -} - -//! Close all files and clear memmory -void GLC_3dxmlToWorld::clear() -{ - delete m_pWorld; - m_pWorld= NULL; - - delete m_pStreamReader; - m_pStreamReader= NULL; - - m_ByteArrayList.clear(); - // Clear current file - if (NULL != m_pCurrentFile) - { - m_pCurrentFile->close(); - delete m_pCurrentFile; - m_pCurrentFile= NULL; - } - - // Clear the 3dxml archive - if (NULL != m_p3dxmlArchive) - { - m_p3dxmlArchive->close(); - delete m_p3dxmlArchive; - m_p3dxmlArchive= NULL; - } - - m_SetOfAttachedFileName.clear(); - - clearMaterialHash(); -} - -// Go to a Rep of a xml -void GLC_3dxmlToWorld::goToRepId(const QString& id) -{ - while(!m_pStreamReader->atEnd() && !((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "Representation") - && (m_pStreamReader->attributes().value("id").toString() == id))) - { - readNext(); - } - -} - -// Go to Polygonal Rep Type -void GLC_3dxmlToWorld::gotToPolygonalRepType() -{ - while(endElementNotReached(m_pStreamReader, "Representation") && !m_pStreamReader->atEnd() && !((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - && ((m_pStreamReader->name() == "Rep") || (m_pStreamReader->name() == "Root")) - && (m_pStreamReader->attributes().value("xsi:type").toString() == "PolygonalRepType"))) - { - //qDebug() << m_pStreamReader->name(); - //qDebug() << m_pStreamReader->attributes().value("xsi:type").toString(); - readNext(); - } - -} - -// Read the specified attribute -QString GLC_3dxmlToWorld::readAttribute(const QString& name, bool required) -{ - QString attributeValue; - if (required && !m_pStreamReader->attributes().hasAttribute(name)) - { - QString message(QString("required attribute ") + name + QString(" Not found")); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - else - { - attributeValue= m_pStreamReader->attributes().value(name).toString(); - } - return attributeValue; -} - -void GLC_3dxmlToWorld::readHeader() -{ - setStreamReaderToFile(m_RootName); - - goToElement(m_pStreamReader, "Header"); - if (m_pStreamReader->atEnd() || m_pStreamReader->hasError()) - { - QString message(QString("GLC_3dxmlToWorld::readHeader Element Header Not found in ") + m_FileName); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - - while(endElementNotReached(m_pStreamReader, "Header")) - { - if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "SchemaVersion")) - { - QString version= getContent(m_pStreamReader, "SchemaVersion"); - m_IsVersion3= version.startsWith('3'); - } - readNext(); - } -} - -// Load the product structure -void GLC_3dxmlToWorld::loadProductStructure() -{ - - goToElement(m_pStreamReader, "ProductStructure"); - if (m_pStreamReader->atEnd() || m_pStreamReader->hasError()) - { - QString message(QString("GLC_3dxmlToWorld::loadProductStructure Element ProctStructure Not found in ") + m_FileName); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - - // Load the structure - while(endElementNotReached(m_pStreamReader, "ProductStructure")) - { - if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - && ((m_pStreamReader->name() == "Reference3D") || (m_pStreamReader->name() == "Instance3D") - || (m_pStreamReader->name() == "ReferenceRep") || (m_pStreamReader->name() == "InstanceRep"))) - { - if (m_pStreamReader->name() == "Reference3D") loadReference3D(); - else if (m_pStreamReader->name() == "Instance3D") loadInstance3D(); - else if (m_pStreamReader->name() == "ReferenceRep") loadReferenceRep(); - else loadInstanceRep(); - } - - readNext(); - } - - // Load Default view properties - while(endElementNotReached(m_pStreamReader, "Model_3dxml")) - { - if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - && ((m_pStreamReader->name() == "DefaultView") || (m_pStreamReader->name() == "GeometricRepresentationSet"))) - { - if (m_pStreamReader->name() == "DefaultView") loadDefaultView(); - else if (m_pStreamReader->name() == "GeometricRepresentationSet") loadLocalRepresentations(); - - } - readNext(); - } - - // Check if an error Occur - if (m_pStreamReader->hasError()) - { - QString message(QString("GLC_3dxmlToWorld::loadProductStructure An error occur in ") + m_FileName); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - - // Load external ref (3DXML V3) - loadExternalRef3D(); - - // Load extern representations (3DXML V4) - loadExternRepresentations(); - - { // Link locals instance with reference - InstanceOfHash::iterator iInstance= m_InstanceOf.begin(); - while (iInstance != m_InstanceOf.constEnd()) - { - GLC_StructInstance* pInstance= iInstance.key(); - GLC_StructReference* pRef= m_ReferenceHash.value(iInstance.value()); - if (NULL == pRef) - { - QString message(QString("GLC_3dxmlToWorld::loadProductStructure a instance reference a non existing reference")); - message.append(" Instance name " + pInstance->name()); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - pInstance->setReference(pRef); - - ++iInstance; - } - m_InstanceOf.clear(); - - } - //qDebug() << "Local instance linked with reference"; - - { // Link external instance with reference - - InstanceOfExtRefHash::iterator iInstance= m_InstanceOfExtRefHash.begin(); - while (iInstance != m_InstanceOfExtRefHash.constEnd()) - { - GLC_StructInstance* pInstance= iInstance.key(); - GLC_StructReference* pRef; - if (m_ExternalReferenceHash.contains(iInstance.value())) - { - pRef= m_ExternalReferenceHash.value(iInstance.value()); - } - else - { - QString referenceName= pInstance->name(); - referenceName= referenceName.left(pInstance->name().lastIndexOf('.')); - QStringList stringList(m_FileName); - stringList.append("Reference not found : " + referenceName); - GLC_ErrorLog::addError(stringList); - pRef= new GLC_StructReference(referenceName); - } - - pInstance->setReference(pRef); - - ++iInstance; - } - - // Check usage of reference in the external reference hash - ExternalReferenceHash::const_iterator iRef= m_ExternalReferenceHash.constBegin(); - while (m_ExternalReferenceHash.constEnd() != iRef) - { - GLC_StructReference* pRef= iRef.value(); - if (! pRef->hasStructInstance()) - { - QStringList stringList(m_FileName); - stringList.append("Orphan reference : " + pRef->name()); - GLC_ErrorLog::addError(stringList); - delete pRef; - } - ++iRef; - } - m_ExternalReferenceHash.clear(); - - } - //qDebug() << "external instance linked with reference"; - - // Create the unfolded tree - createUnfoldedTree(); - - // Update occurence number - m_pWorld->rootOccurence()->updateOccurenceNumber(1); - - // Change occurence attributes for 3DXML V3 - if (! m_V3OccurenceAttribHash.isEmpty()) - { - //qDebug() << "Not visible occurence= " << m_V3OccurenceAttribHash.size(); - QList occurenceList= m_pWorld->listOfOccurence(); - const int size= occurenceList.size(); - for (int i= 0; i < size; ++i) - { - if (m_V3OccurenceAttribHash.contains(occurenceList.at(i)->occurenceNumber())) - { - V3OccurenceAttrib* pOccurenceAttrib= m_V3OccurenceAttribHash.value(occurenceList.at(i)->occurenceNumber()); - occurenceList.at(i)->setVisibility(pOccurenceAttrib->m_IsVisible); - if (NULL != pOccurenceAttrib->m_pRenderProperties) - { - occurenceList.at(i)->setRenderProperties(*(pOccurenceAttrib->m_pRenderProperties)); - } - } - } - } - - // Change occurence attributes for 3DXML V4 - if (!m_V4OccurenceAttribList.isEmpty()) - { - QHash instanceToIdHash; - const int assyCount= m_AssyLinkList.count(); - for (int i= 0; i < assyCount; ++i) - { - AssyLink assyLink= m_AssyLinkList.at(i); - instanceToIdHash.insert(assyLink.m_pChildInstance, assyLink.m_InstanceId); - } - - const int attribCount= m_V4OccurenceAttribList.count(); - for (int i= 0; i < attribCount; ++i) - { - V4OccurenceAttrib* pCurrentV4OccurenceAttrib= m_V4OccurenceAttribList.at(i); - //qDebug() << pCurrentV4OccurenceAttrib->m_Path; - applyV4Attribute(m_pWorld->rootOccurence(), pCurrentV4OccurenceAttrib, instanceToIdHash); - } - } - - // Check usage of Instance - InstanceOfExtRefHash::const_iterator iInstance= m_InstanceOfExtRefHash.constBegin(); - while (m_InstanceOfExtRefHash.constEnd() != iInstance) - { - GLC_StructInstance* pInstance= iInstance.key(); - if (!pInstance->hasStructOccurence()) - { - QStringList stringList(m_FileName); - stringList.append("Orphan Instance : " + pInstance->name()); - GLC_ErrorLog::addError(stringList); - delete pInstance; - } - else - { - QList occurences= pInstance->listOfStructOccurences(); - const int size= occurences.size(); - for (int i= 0; i < size; ++i) - { - const GLC_StructOccurence* pOccurence= occurences.at(i); - if (pOccurence->isOrphan()) - { - QStringList stringList(m_FileName); - stringList.append("Orphan occurence : " + pOccurence->name()); - GLC_ErrorLog::addError(stringList); - delete pOccurence; - } - } - } - ++iInstance; - } - - m_InstanceOfExtRefHash.clear(); - - - //qDebug() << "Unfolded tree created"; - -} - -// Load a Reference3D -void GLC_3dxmlToWorld::loadReference3D() -{ - const unsigned int id= readAttribute("id", true).toUInt(); - const QString refName(readAttribute("name", true)); - GLC_StructReference* pStructReference; - - if (id == 1) // This is the root reference. - { - m_pWorld->setRootName(refName); - pStructReference= m_pWorld->rootOccurence()->structInstance()->structReference(); - pStructReference->setName(refName); - } - else - { - pStructReference= new GLC_StructReference(refName); - } - // Try to find extension - GLC_Attributes userAttributes; - while (endElementNotReached(m_pStreamReader, "Reference3D")) - { - if (m_pStreamReader->isStartElement() && (m_pStreamReader->name() == "Reference3DExtensionType")) - { - while (endElementNotReached(m_pStreamReader, "Reference3DExtensionType")) - { - if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "Attribute")) - { - QString name= readAttribute("name", true); - QString value= readAttribute("value", true); - if (name == "FILEPATH" && QDir(value).isRelative()) - { - value= QFileInfo(m_FileName).absolutePath() + QDir::separator() + value; - } - userAttributes.insert(name, value); - } - readNext(); - } - } - readNext(); - } - if (!userAttributes.isEmpty()) - { - pStructReference->setAttributes(userAttributes); - } - - m_ReferenceHash.insert(id, pStructReference); -} - -// Load a Instance3D -void GLC_3dxmlToWorld::loadInstance3D() -{ - const QString local= "urn:3DXML:Reference:loc:"; - const QString externRef= "urn:3DXML:Reference:ext:"; - - const unsigned int instanceId= readAttribute("id", true).toUInt(); - const QString instName(readAttribute("name", false)); - goToElement(m_pStreamReader, "IsAggregatedBy"); - const unsigned int aggregatedById= getContent(m_pStreamReader, "IsAggregatedBy").toUInt(); - QString instanceOf= getContent(m_pStreamReader, "IsInstanceOf"); - const QString matrixString= getContent(m_pStreamReader, "RelativeMatrix"); - GLC_Matrix4x4 instanceMatrix= loadMatrix(matrixString); - - - GLC_StructInstance* pStructInstance= new GLC_StructInstance(instName); - pStructInstance->move(instanceMatrix); - - // Try to find extension - GLC_Attributes userAttributes; - while (endElementNotReached(m_pStreamReader, "Instance3D")) - { - if (m_pStreamReader->isStartElement() && (m_pStreamReader->name() == "Instance3DExtensionType")) - { - while (endElementNotReached(m_pStreamReader, "Instance3DExtensionType")) - { - if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "Attribute")) - { - QString name= readAttribute("name", true); - QString value= readAttribute("value", true); - userAttributes.insert(name, value); - } - readNext(); - } - } - readNext(); - } - if (!userAttributes.isEmpty()) - { - pStructInstance->setAttributes(userAttributes); - } - if (instanceOf.contains(externRef)) - { - - const QString extRefId= instanceOf.remove(externRef).remove("#1"); - m_SetOfExtRef << extRefId; - m_InstanceOfExtRefHash.insert(pStructInstance, extRefId); - } - else if (instanceOf.contains(local)) - { - const unsigned int refId= instanceOf.remove(local).toUInt(); - m_InstanceOf.insert(pStructInstance, refId); - } - else - { - // 3dvia 3dxml - const unsigned int refId= instanceOf.toUInt(); - m_InstanceOf.insert(pStructInstance, refId); - } - - AssyLink assyLink; - assyLink.m_ParentRefId= aggregatedById; - assyLink.m_pChildInstance= pStructInstance; - assyLink.m_InstanceId= instanceId; - m_AssyLinkList.append(assyLink); -} - -// Load a Reference representation -void GLC_3dxmlToWorld::loadReferenceRep() -{ - const QString local= "urn:3DXML:Representation:loc:"; - const QString externName= "urn:3DXML:"; - - const unsigned int id= readAttribute("id", true).toUInt(); - //const QString refName(readAttribute("name", true)); - const QString format= readAttribute("format", false); - QString associatedFile(readAttribute("associatedFile", true)); - if (format == "TESSELLATED") - { - if (associatedFile.contains(local)) - { - const QString repId= associatedFile.remove(local); - m_ReferenceRepHash.insert(id, repId); - } - else if (associatedFile.contains(externName)) - { - const QString repId= associatedFile.remove(externName); - m_ReferenceRepHash.insert(id, repId); - } - } - else if (format == "UVR") - { - QString message(QString("GLC_3dxmlToWorld::loadReferenceRep in file ") + m_CurrentFileName + " format " + format + " not supported"); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported); - clear(); - throw(fileFormatException); - - } -} - -// Load a Instance representation -void GLC_3dxmlToWorld::loadInstanceRep() -{ - const QString local= "urn:3DXML:Reference:loc:"; - - goToElement(m_pStreamReader, "IsAggregatedBy"); - const unsigned int aggregatedById= getContent(m_pStreamReader, "IsAggregatedBy").toUInt(); - QString instanceOf= getContent(m_pStreamReader, "IsInstanceOf"); - - if (instanceOf.contains(local)) - { - // The 3dxml is a 3dxml rep from CATIA V5 - const unsigned int refId= instanceOf.remove(local).toUInt(); - - RepLink repLink; - repLink.m_ReferenceId= aggregatedById; - repLink.m_RepId= refId; - - m_LocalRepLinkList.append(repLink); - } - else - { - // The 3dxml is a 3dvia 3dxml - const unsigned int refId= instanceOf.toUInt(); - RepLink repLink; - repLink.m_ReferenceId= aggregatedById; - repLink.m_RepId= refId; - - m_ExternRepLinkList.append(repLink); - } -} - -// Load External Ref -void GLC_3dxmlToWorld::loadExternalRef3D() -{ - if (m_SetOfExtRef.isEmpty()) return; - - const int size= m_SetOfExtRef.size(); - int previousQuantumValue= 0; - int currentQuantumValue= 0; - int currentFileIndex= 0; - emit currentQuantum(currentQuantumValue); - - SetOfExtRef::iterator iExtRef= m_SetOfExtRef.begin(); - while (iExtRef != m_SetOfExtRef.constEnd()) - { - - m_CurrentFileName= (*iExtRef); - - if (! m_IsInArchive) - { - // Get the representation time stamp - m_CurrentDateTime= QFileInfo(QFileInfo(m_FileName).absolutePath() + QDir::separator() + QFileInfo(m_CurrentFileName).fileName()).lastModified(); - } - - if (!m_LoadStructureOnly && GLC_State::cacheIsUsed() && GLC_State::currentCacheManager().isUsable(m_CurrentDateTime, QFileInfo(m_FileName).baseName(), m_CurrentFileName)) - { - GLC_CacheManager cacheManager= GLC_State::currentCacheManager(); - - GLC_BSRep binaryRep= cacheManager.binary3DRep(QFileInfo(m_FileName).baseName(), m_CurrentFileName); - GLC_3DRep* pRep= new GLC_3DRep(binaryRep.loadRep()); - - setRepresentationFileName(pRep); - - GLC_StructReference* pCurrentRef= new GLC_StructReference(pRep); - pCurrentRef->setName(QFileInfo(m_CurrentFileName).baseName()); - m_ExternalReferenceHash.insert(m_CurrentFileName, pCurrentRef); - - } - else if (!m_LoadStructureOnly && setStreamReaderToFile(m_CurrentFileName)) - { - - // Avoid recursive call off createReferenceRep - const QString localFileName= m_CurrentFileName; - - GLC_StructReference* pCurrentRef= createReferenceRep(QString(), NULL); - if (NULL != pCurrentRef) - { - m_ExternalReferenceHash.insert(localFileName, pCurrentRef); - } - else - { - QStringList stringList(m_FileName); - stringList.append("GLC_3dxmlToWorld::loadExternalRef3D"); - stringList.append("Failed to load " + m_CurrentFileName); - GLC_ErrorLog::addError(stringList); - } - } - else if(m_LoadStructureOnly) - { - GLC_3DRep* pRep= new GLC_3DRep(); - if (m_IsInArchive) - { - pRep->setFileName(glc::builtArchiveString(m_FileName, m_CurrentFileName)); - } - else - { - const QString repFileName= glc::builtFileString(m_FileName, m_CurrentFileName); - pRep->setFileName(repFileName); - m_SetOfAttachedFileName << glc::archiveEntryFileName(repFileName); - } - - if (m_GetExternalRef3DName && setStreamReaderToFile(m_CurrentFileName)) - { - const QString localFileName= m_CurrentFileName; - GLC_StructReference* pCurrentRef= createReferenceRep(QString(), pRep); - m_ExternalReferenceHash.insert(localFileName, pCurrentRef); - } - else - { - GLC_StructReference* pCurrentRef= new GLC_StructReference(pRep); - pCurrentRef->setName(QFileInfo(m_CurrentFileName).baseName()); - m_ExternalReferenceHash.insert(m_CurrentFileName, pCurrentRef); - } - } - else - { - qDebug() << "GLC_3dxmlToWorld::loadExternalRef3D No File Found"; - } - - ++currentFileIndex; - // Progrees bar indicator - currentQuantumValue = static_cast((static_cast(currentFileIndex) / size) * 100); - if (currentQuantumValue > previousQuantumValue) - { - emit currentQuantum(currentQuantumValue); - } - previousQuantumValue= currentQuantumValue; - - ++iExtRef; - } - m_SetOfExtRef.clear(); - -} - -// Create Instance from 3DXML Rep -GLC_StructReference* GLC_3dxmlToWorld::createReferenceRep(QString repId, GLC_3DRep* pRep) -{ - //qDebug() << "GLC_3dxmlToWorld::createReferenceRep :" << repId; - - QString refName; - - if (repId.isEmpty()) - { - goToElement(m_pStreamReader, "ProductStructure"); - checkForXmlError("Element ProductStructure not found"); - - goToElement(m_pStreamReader, "Reference3D"); - checkForXmlError("Element Reference3D not found"); - refName= readAttribute("name", true); - - if (pRep != NULL) - { - pRep->setName(refName); - return new GLC_StructReference(pRep); - } - - goToElement(m_pStreamReader, "ReferenceRep"); - if (m_pStreamReader->atEnd()) - { - QStringList stringList(m_FileName); - stringList.append("Element ReferenceRep not found in file " + m_CurrentFileName); - GLC_ErrorLog::addError(stringList); - return NULL; - } - checkForXmlError("Element ReferenceRep contains error"); - - const QString format(readAttribute("format", true)); - if (format != "TESSELLATED") - { - QString message(QString("GLC_3dxmlToWorld::addExtenalRef 3D rep format ") + format + " Not Supported"); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported); - clear(); - throw(fileFormatException); - } - - repId= readAttribute("associatedFile"); - - const QString local= "urn:3DXML:Representation:loc:"; - const QString ext= "urn:3DXML:Representation:ext:"; - if (repId.contains(ext)) - { - repId.remove(ext); - repId.resize(repId.size() - 2); - if (setStreamReaderToFile(repId)) - { - return createReferenceRep(QString(), NULL); - } - else - { - return NULL; - } - } - else - { - repId.remove(local); - } - - checkForXmlError("attribute associatedFile not found"); - goToRepId(repId); - checkForXmlError("repId not found"); - } - - GLC_Mesh* pMesh= new GLC_Mesh(); - pMesh->setName(refName); - GLC_3DRep currentMesh3DRep(pMesh); - // Add time Stamp and file name to the 3D rep - - if (repId.contains("3DXML_Local_")) - { - QString saveCurrentFileName= m_CurrentFileName; - m_CurrentFileName= repId; - setRepresentationFileName(¤tMesh3DRep); - m_CurrentFileName= saveCurrentFileName; - } - else - { - setRepresentationFileName(¤tMesh3DRep); - } - - currentMesh3DRep.setLastModified(m_CurrentDateTime); - - int numberOfMesh= 1; - while (endElementNotReached(m_pStreamReader, "Representation")) - { - gotToPolygonalRepType(); - if (!endElementNotReached(m_pStreamReader, "Representation") || m_pStreamReader->atEnd() || m_pStreamReader->hasError()) - { - if (m_pStreamReader->hasError() || m_pStreamReader->atEnd()) - { - QString message(QString("An element have not been found in file ") + m_FileName); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - else - { - pMesh->finish(); - currentMesh3DRep.clean(); - if (!currentMesh3DRep.isEmpty()) - { - if (GLC_State::cacheIsUsed()) - { - GLC_CacheManager currentManager= GLC_State::currentCacheManager(); - if (!currentManager.addToCache(QFileInfo(m_FileName).baseName(), currentMesh3DRep)) - { - QStringList stringList("GLC_3dxmlToWorld::createReferenceRep"); - stringList.append(m_FileName); - stringList.append("File " + currentMesh3DRep.fileName() + " Not Added to cache"); - GLC_ErrorLog::addError(stringList); - } - } - - return new GLC_StructReference(new GLC_3DRep(currentMesh3DRep)); - } - else - { - return new GLC_StructReference("Empty Rep"); - } - } - } - if (numberOfMesh > 1) - { - pMesh->finish(); - pMesh = new GLC_Mesh(); - pMesh->setName(refName); - currentMesh3DRep.addGeom(pMesh); - } - - loadRep(pMesh); - - ++numberOfMesh; - } - - pMesh->finish(); - - currentMesh3DRep.clean(); - if (!currentMesh3DRep.isEmpty()) - { - if (GLC_State::cacheIsUsed()) - { - GLC_CacheManager currentManager= GLC_State::currentCacheManager(); - currentManager.addToCache(QFileInfo(m_FileName).baseName(), currentMesh3DRep); - } - - return new GLC_StructReference(new GLC_3DRep(currentMesh3DRep)); - } - else - { - return new GLC_StructReference("Empty Rep"); - } -} - -// Load Matrix -GLC_Matrix4x4 GLC_3dxmlToWorld::loadMatrix(const QString& stringMatrix) -{ - - QStringList stringValues(stringMatrix.split(" ")); - - if (stringValues.size() != 12) return GLC_Matrix4x4(); - - QVector values(16); - // Rotation - values[0]= stringValues[0].toDouble(); - values[1]= stringValues[1].toDouble(); - values[2]= stringValues[2].toDouble(); - values[3]= 0.0; - values[4]= stringValues[3].toDouble(); - values[5]= stringValues[4].toDouble(); - values[6]= stringValues[5].toDouble(); - values[7]= 0.0; - values[8]= stringValues[6].toDouble(); - values[9]= stringValues[7].toDouble(); - values[10]= stringValues[8].toDouble(); - values[11]= 0.0; - // Translation - values[12]= stringValues[9].toDouble(); - values[13]= stringValues[10].toDouble(); - values[14]= stringValues[11].toDouble(); - values[15]= 1.0; - - GLC_Matrix4x4 resultMatrix(values.data()); - resultMatrix.optimise(); - - return resultMatrix; -} - -// Create the unfolded tree -void GLC_3dxmlToWorld::createUnfoldedTree() -{ - //qDebug() << "createUnfoldedTree"; - // Run throw all link in the list of link - - qSort(m_AssyLinkList.begin(), m_AssyLinkList.end()); - AssyLinkList::iterator iLink= m_AssyLinkList.begin(); - while(iLink != m_AssyLinkList.constEnd()) - { - GLC_StructInstance* pChildInstance= (*iLink).m_pChildInstance; - if (pChildInstance->structReference() == NULL) - { - QStringList stringList(m_FileName); - stringList.append("Instance without reference"); - GLC_ErrorLog::addError(stringList); - pChildInstance->setReference(new GLC_StructReference("Part")); - } - Q_ASSERT(m_ReferenceHash.contains((*iLink).m_ParentRefId)); - GLC_StructReference* pRef= m_ReferenceHash.value((*iLink).m_ParentRefId); - // Attach pInstance at all Occurence of pRef - QList instanceList= pRef->listOfStructInstances(); - const int instanceNumber= instanceList.size(); - for (int i= 0; i < instanceNumber; ++i) - { - if (instanceList.at(i)->hasStructOccurence()) - { - QList occurenceList= instanceList.at(i)->listOfStructOccurences(); - const int occurenceNumber= occurenceList.size(); - for (int j= 0; j < occurenceNumber; ++j) - { - if (pChildInstance->hasStructOccurence() && pChildInstance->firstOccurenceHandle()->isOrphan()) - { - Q_ASSERT(pChildInstance->listOfStructOccurences().size() == 1); - occurenceList.at(j)->addChild(pChildInstance->firstOccurenceHandle()); - } - else - { - occurenceList.at(j)->addChild(pChildInstance); - } - } - } - else - { - GLC_StructOccurence* pOccurence= new GLC_StructOccurence(instanceList.at(i), m_pWorld->worldHandle()); - if (pChildInstance->hasStructOccurence() && pChildInstance->firstOccurenceHandle()->isOrphan()) - { - Q_ASSERT(pChildInstance->listOfStructOccurences().size() == 1); - pOccurence->addChild(pChildInstance->firstOccurenceHandle()); - } - else - { - pOccurence->addChild(pChildInstance); - } - } - } - - ++iLink; - } - - // Check the assembly structure occurence - ReferenceHash::const_iterator iRef= m_ReferenceHash.constBegin(); - while (m_ReferenceHash.constEnd() != iRef) - { - if (iRef.key() != 1) - { - GLC_StructReference* pReference= iRef.value(); - if (!pReference->hasStructInstance()) - { - QStringList stringList(m_FileName); - stringList.append("GLC_3dxmlToWorld::createUnfoldedTree() : Orphan reference: " + pReference->name()); - GLC_ErrorLog::addError(stringList); - delete pReference; - } - else - { - QList instances= pReference->listOfStructInstances(); - const int size= instances.size(); - for (int i= 0; i < size; ++i) - { - GLC_StructInstance* pInstance= instances.at(i); - if (!pInstance->hasStructOccurence()) - { - QStringList stringList(m_FileName); - stringList.append("GLC_3dxmlToWorld::createUnfoldedTree() : Orphan Instance: " + pInstance->name()); - GLC_ErrorLog::addError(stringList); - delete pInstance; - } - else - { - QList occurences= pInstance->listOfStructOccurences(); - const int occurencesSize= occurences.size(); - for (int j= 0; j < occurencesSize; ++j) - { - GLC_StructOccurence* pOcc= occurences.at(j); - if (pOcc->isOrphan()) - { - QStringList stringList(m_FileName); - stringList.append("GLC_3dxmlToWorld::createUnfoldedTree(): Orphan occurence: " + pOcc->name()); - GLC_ErrorLog::addError(stringList); - delete pOcc; - } - } - } - } - } - } - ++iRef; - } - m_ReferenceHash.clear(); - - // Update position - m_pWorld->rootOccurence()->updateChildrenAbsoluteMatrix(); - -} -// Check for XML error -void GLC_3dxmlToWorld::checkForXmlError(const QString& info) -{ - if (m_pStreamReader->atEnd() || m_pStreamReader->hasError()) - { - QString message(QString("An element have not been found in file ") + m_CurrentFileName); - - QStringList stringList(info + " " + m_pStreamReader->errorString()); - stringList.append(message); - GLC_ErrorLog::addError(stringList); - - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } -} - -// Load a face -void GLC_3dxmlToWorld::loadFace(GLC_Mesh* pMesh, const int lod, double accuracy) -{ - //qDebug() << "GLC_3dxmlToWorld::loadFace" << m_pStreamReader->name(); - // List of index declaration - QString triangles= readAttribute("triangles", false).trimmed(); - QString strips= readAttribute("strips", false).trimmed(); - QString fans= readAttribute("fans", false).trimmed(); - - if (triangles.isEmpty() && strips.isEmpty() && fans.isEmpty()) - { - QStringList stringList(m_CurrentFileName); - stringList.append("GLC_3dxmlToWorld::loadFace : Empty face found"); - GLC_ErrorLog::addError(stringList); - return; - } - - GLC_Material* pCurrentMaterial= NULL; - - while(endElementNotReached(m_pStreamReader, "Face")) - { - if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "SurfaceAttributes")) - { - pCurrentMaterial= loadSurfaceAttributes(); - } - readNext(); - } - if (NULL == pCurrentMaterial) - { - pCurrentMaterial= m_pCurrentMaterial; - } - - // Trying to find triangles - if (!triangles.isEmpty()) - { - // For 3dvia mesh - if (triangles.contains(',')) - { - triangles.remove(','); - } - QTextStream trianglesStream(&triangles); - IndexList trianglesIndex; - QString buff; - while ((!trianglesStream.atEnd())) - { - trianglesStream >> buff; - trianglesIndex.append(buff.toUInt()); - } - pMesh->addTriangles(pCurrentMaterial, trianglesIndex, lod, accuracy); - } - // Trying to find trips - if (!strips.isEmpty()) - { - - QStringList stripsList(strips.split(",")); - const int size= stripsList.size(); - for (int i= 0; i < size; ++i) - { - //qDebug() << "Strip " << stripsList.at(i); - QTextStream stripsStream(&stripsList[i]); - IndexList stripsIndex; - QString buff; - while ((!stripsStream.atEnd())) - { - stripsStream >> buff; - stripsIndex.append(buff.toUInt()); - } - pMesh->addTrianglesStrip(pCurrentMaterial, stripsIndex, lod, accuracy); - } - } - // Trying to find fans - if (!fans.isEmpty()) - { - QStringList fansList(fans.split(",")); - const int size= fansList.size(); - for (int i= 0; i < size; ++i) - { - QTextStream fansStream(&fansList[i]); - IndexList fansIndex; - QString buff; - while ((!fansStream.atEnd())) - { - fansStream >> buff; - fansIndex.append(buff.toUInt()); - } - pMesh->addTrianglesFan(pCurrentMaterial, fansIndex, lod, accuracy); - } - } - -} - -// Load polyline -void GLC_3dxmlToWorld::loadPolyline(GLC_Mesh* pMesh) -{ - QString data= readAttribute("vertices", true); - - data.replace(',', ' '); - QTextStream dataStream(&data); - QList values; - QString buff; - while ((!dataStream.atEnd())) - { - dataStream >> buff; - values.append(buff.toFloat()); - } - if ((values.size() % 3) == 0) - { - pMesh->addVerticeGroup(values.toVector()); - } - else - { - QString message(QString("polyline buffer is not a multiple of 3 ") + m_CurrentFileName); - - QStringList stringList(message); - GLC_ErrorLog::addError(stringList); - - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - - -} - -// Clear material hash -void GLC_3dxmlToWorld::clearMaterialHash() -{ - MaterialHash::iterator iMaterial= m_MaterialHash.begin(); - while (m_MaterialHash.constEnd() != iMaterial) - { - if (iMaterial.value()->isUnused()) - { - delete iMaterial.value(); - } - ++iMaterial; - } - - m_MaterialHash.clear(); -} - -GLC_Material* GLC_3dxmlToWorld::loadSurfaceAttributes() -{ - GLC_Material* pMaterial= NULL; - while(endElementNotReached(m_pStreamReader, "SurfaceAttributes")) - { - if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "Color")) - { - pMaterial= getMaterial(); - } - else if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "MaterialApplication")) - { - while (endElementNotReached(m_pStreamReader, "MaterialApplication")) - { - readNext(); - if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "MaterialId")) - { - checkForXmlError("Material ID not found"); - QString materialId= readAttribute("id", true).remove("urn:3DXML:CATMaterialRef.3dxml#"); - pMaterial= m_MaterialHash.value(materialId); - } - } - - } - readNext(); - } - - return pMaterial; -} - -GLC_Material* GLC_3dxmlToWorld::getMaterial() -{ - GLC_Material* pMaterial= NULL; - const QString red(readAttribute("red", true)); - const QString green(readAttribute("green", true)); - const QString blue(readAttribute("blue", true)); - const QString alpha(readAttribute("alpha", true)); - - qreal redReal= red.toDouble(); - qreal greenReal= green.toDouble(); - qreal blueReal= blue.toDouble(); - qreal alphaReal= alpha.toDouble(); - QColor diffuse; - diffuse.setRgbF(redReal, greenReal, blueReal); - pMaterial= new GLC_Material(diffuse); - pMaterial->setName("Material_" + QString::number(m_MaterialHash.size())); - pMaterial->setAmbientColor(QColor(50, 50, 50)); - pMaterial->setSpecularColor(QColor(70, 70, 70)); - pMaterial->setShininess(35.0); - pMaterial->setOpacity(alphaReal); - - const QString matKey= QString::number(pMaterial->hashCode()); - if (m_MaterialHash.contains(matKey)) - { - delete pMaterial; - pMaterial= m_MaterialHash.value(matKey); - } - else - { - m_MaterialHash.insert(matKey, pMaterial); - } - - return pMaterial; -} - -// Set the stream reader to the specified file -bool GLC_3dxmlToWorld::setStreamReaderToFile(QString fileName, bool test) -{ - m_CurrentFileName= fileName; - if (m_IsInArchive) - { - QMutexLocker locker(&m_ZipMutex); - m_ByteArrayList.clear(); - // Create QuaZip File - QuaZipFile* p3dxmlFile= new QuaZipFile(m_p3dxmlArchive); - - // Get the file of the 3dxml - if (!m_p3dxmlArchive->setCurrentFile(fileName, QuaZip::csInsensitive)) - { - if (!test) - { - QString message(QString("GLC_3dxmlToWorld::setStreamReaderToFile File ") + m_FileName + " doesn't contains " + fileName); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - else return false; - } - - // Open the file of the 3dxml - if(!p3dxmlFile->open(QIODevice::ReadOnly)) - { - QString message(QString("GLC_3dxmlToWorld::setStreamReaderToFile Unable to Open ") + fileName); - GLC_FileFormatException fileFormatException(message, fileName, GLC_FileFormatException::FileNotSupported); - clear(); - throw(fileFormatException); - } - - // Test if the file is a binary - checkFileValidity(p3dxmlFile); - { - delete p3dxmlFile; - p3dxmlFile= new QuaZipFile(m_p3dxmlArchive); - m_p3dxmlArchive->setCurrentFile(fileName, QuaZip::csInsensitive); - p3dxmlFile->open(QIODevice::ReadOnly); - } - - // Set the stream reader - delete m_pStreamReader; - - QByteArray currentByteArray; - while (!currentByteArray.isEmpty() || m_ByteArrayList.isEmpty()) - { - currentByteArray= p3dxmlFile->read(chunckSize); - m_ByteArrayList.append(currentByteArray); - } - m_pStreamReader= new QXmlStreamReader(m_ByteArrayList.takeFirst()); - delete p3dxmlFile; - } - else - { - delete m_pCurrentFile; - // Create the file to load - if (fileName != m_FileName && !m_FileName.isEmpty()) - { - fileName= QFileInfo(m_FileName).absolutePath() + QDir::separator() + fileName; - } - // Get the 3DXML time stamp - m_CurrentDateTime= QFileInfo(fileName).lastModified(); - - m_pCurrentFile= new QFile(fileName); - if (!m_pCurrentFile->open(QIODevice::ReadOnly)) - { - QString message(QString("GLC_3dxmlToWorld::setStreamReaderToFile File ") + fileName + QString(" not found")); - QStringList stringList(message); - GLC_ErrorLog::addError(stringList); - return false; - } - else if (m_FileName != fileName) - { - m_SetOfAttachedFileName << fileName; - } - - // Test if the file is a binary - checkFileValidity(m_pCurrentFile); - - // Set the stream reader - delete m_pStreamReader; - m_pStreamReader= new QXmlStreamReader(m_pCurrentFile); - } - return true; -} - -// Load the local representation -void GLC_3dxmlToWorld::loadLocalRepresentations() -{ - qDebug() << "GLC_3dxmlToWorld::loadLocalRepresentations()"; - - if (m_LocalRepLinkList.isEmpty()) return; - QHash repHash; - - // Load all local ref - goToElement(m_pStreamReader, "GeometricRepresentationSet"); - while (endElementNotReached(m_pStreamReader, "GeometricRepresentationSet")) - { - if (m_pStreamReader->name() == "Representation") - { - QString id= readAttribute("id", true); - GLC_StructReference* pRef= createReferenceRep("3DXML_Local_" + id, NULL); - if (pRef->hasRepresentation()) - { - GLC_3DRep representation(*(dynamic_cast(pRef->representationHandle()))); - repHash.insert(id, representation); - } - delete pRef; - } - readNext(); - } - //qDebug() << "Local rep loaded"; - - // Attach the ref to the structure reference - RepLinkList::iterator iLocalRep= m_LocalRepLinkList.begin(); - while (iLocalRep != m_LocalRepLinkList.constEnd()) - { - unsigned int referenceId= (*iLocalRep).m_ReferenceId; - unsigned int refId= (*iLocalRep).m_RepId; - - GLC_StructReference* pReference= m_ReferenceHash.value(referenceId); - const QString representationID= m_ReferenceRepHash.value(refId); - pReference->setRepresentation(repHash.value(representationID)); - pReference->setRepresentationName(pReference->name()); - - ++iLocalRep; - } -} - -void GLC_3dxmlToWorld::loadDefaultView() -{ - if (m_pStreamReader->atEnd() || m_pStreamReader->hasError()) - { - QString message(QString("GLC_3dxmlToWorld::loadGraphicsProperties Element DefaultView Not found in ") + m_FileName); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - - // Load the graphics properties - while(endElementNotReached(m_pStreamReader, "DefaultView")) - { - if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "DefaultViewProperty")) - { - if (m_IsVersion3) loadV3DefaultViewProperty(); - else loadV4DefaultViewProperty(); - } - - readNext(); - } - - // Check if an error Occur - if (m_pStreamReader->hasError()) - { - QString message(QString("GLC_3dxmlToWorld::loadGraphicsProperties An error occur in ") + m_FileName); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - -} - -void GLC_3dxmlToWorld::loadV3DefaultViewProperty() -{ - goToElement(m_pStreamReader, "OccurenceId"); - unsigned int occurenceId= getContent(m_pStreamReader, "OccurenceId").toUInt(); - - // Load the graphics properties - while(endElementNotReached(m_pStreamReader, "DefaultViewProperty")) - { - if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "GraphicProperties")) - { - while(endElementNotReached(m_pStreamReader, "GraphicProperties")) - { - if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "GeneralAttributes")) - { - QString visibleString= readAttribute("visible", true); - if (visibleString != "true") - { - if (!m_V3OccurenceAttribHash.contains(occurenceId)) - { - V3OccurenceAttrib* pOccurenceAttrib= new V3OccurenceAttrib(); - pOccurenceAttrib->m_IsVisible= false; - m_V3OccurenceAttribHash.insert(occurenceId, pOccurenceAttrib); - } - else m_V3OccurenceAttribHash.value(occurenceId)->m_IsVisible= false; - } - } - else if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "SurfaceAttributes")) - { - goToElement(m_pStreamReader, "Color"); - const double red= readAttribute("red", true).toDouble(); - const double green= readAttribute("green", true).toDouble(); - const double blue= readAttribute("blue", true).toDouble(); - double alpha= 1.0; - QString alphaString= readAttribute("alpha", false); - if (!alphaString.isEmpty()) alpha= alphaString.toDouble(); - - GLC_RenderProperties* pRenderProperties= new GLC_RenderProperties(); - if (red != -1.0f) - { - QColor diffuseColor; - diffuseColor.setRgbF(red, green, blue, alpha); - GLC_Material* pMaterial= new GLC_Material(); - pMaterial->setDiffuseColor(diffuseColor); - pRenderProperties->setOverwriteMaterial(pMaterial); - pRenderProperties->setRenderingMode(glc::OverwriteMaterial); - } - else if (alpha < 1.0f) - { - pRenderProperties->setOverwriteTransparency(static_cast(alpha)); - pRenderProperties->setRenderingMode(glc::OverwriteTransparency); - } - if (!m_V3OccurenceAttribHash.contains(occurenceId)) - { - V3OccurenceAttrib* pOccurenceAttrib= new V3OccurenceAttrib(); - pOccurenceAttrib->m_pRenderProperties= pRenderProperties; - m_V3OccurenceAttribHash.insert(occurenceId, pOccurenceAttrib); - } - else m_V3OccurenceAttribHash.value(occurenceId)->m_pRenderProperties= pRenderProperties; - } - - readNext(); - } - - } - - readNext(); - } - - // Check if an error Occur - if (m_pStreamReader->hasError()) - { - QString message(QString("GLC_3dxmlToWorld::loadDefaultViewProperty An error occur in ") + m_FileName); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - -} - -void GLC_3dxmlToWorld::loadV4DefaultViewProperty() -{ - V4OccurenceAttrib* pV4OccurenceAttrib= new V4OccurenceAttrib(); - - while(endElementNotReached(m_pStreamReader, "DefaultViewProperty")) - { - if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "OccurenceId")) - { - pV4OccurenceAttrib->m_Path= loadOccurencePath(); - } - else if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "RelativePosition")) - { - const QString matrix= getContent(m_pStreamReader, "RelativePosition"); - pV4OccurenceAttrib->m_pMatrix= new GLC_Matrix4x4(loadMatrix(matrix)); - } - else if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "GraphicProperties")) - { - loadGraphicProperties(pV4OccurenceAttrib); - } - readNext(); - } - - if(!pV4OccurenceAttrib->m_Path.isEmpty()) - { - m_V4OccurenceAttribList.append(pV4OccurenceAttrib); - } - else - { - delete pV4OccurenceAttrib; - } - - // Check if an error Occur - if (m_pStreamReader->hasError()) - { - QString message(QString("GLC_3dxmlToWorld::loadV4DefaultViewProperty An error occur in ") + m_FileName); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - -} - -QList GLC_3dxmlToWorld::loadOccurencePath() -{ - QList path; - while(endElementNotReached(m_pStreamReader, "OccurenceId")) - { - if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "id")) - { - QString instanceId= getContent(m_pStreamReader, "id"); - instanceId= instanceId.right(instanceId.length() - 1 - instanceId.indexOf('#')); - path.append(instanceId.toUInt()); - } - readNext(); - } - - // Check if an error Occur - if (m_pStreamReader->hasError() || path.contains(0)) - { - QString message(QString("GLC_3dxmlToWorld::loadOccurencePath An error occur in ") + m_FileName); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - - return path; -} - -void GLC_3dxmlToWorld::loadGraphicProperties(V4OccurenceAttrib* pAttrib) -{ - while(endElementNotReached(m_pStreamReader, "GraphicProperties")) - { - if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "GeneralAttributes")) - { - QString visibleString= readAttribute("visible", true); - if (visibleString != "true") - { - pAttrib->m_IsVisible= false; - } - } - else if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "SurfaceAttributes")) - { - goToElement(m_pStreamReader, "Color"); - const double red= readAttribute("red", true).toDouble(); - const double green= readAttribute("green", true).toDouble(); - const double blue= readAttribute("blue", true).toDouble(); - double alpha= 1.0; - QString alphaString= readAttribute("alpha", false); - if (!alphaString.isEmpty()) alpha= alphaString.toDouble(); - - GLC_RenderProperties* pRenderProperties= new GLC_RenderProperties(); - if (red != -1.0f) - { - QColor diffuseColor; - diffuseColor.setRgbF(red, green, blue, alpha); - GLC_Material* pMaterial= new GLC_Material(); - pMaterial->setDiffuseColor(diffuseColor); - pRenderProperties->setOverwriteMaterial(pMaterial); - pRenderProperties->setRenderingMode(glc::OverwriteMaterial); - } - else if (alpha < 1.0f) - { - pRenderProperties->setOverwriteTransparency(static_cast(alpha)); - pRenderProperties->setRenderingMode(glc::OverwriteTransparency); - } - - pAttrib->m_pRenderProperties= pRenderProperties; - } - - readNext(); - } -} - -// Load the extern representation -void GLC_3dxmlToWorld::loadExternRepresentations() -{ - - if (m_ExternRepLinkList.isEmpty()) return; - - QHash repHash; - - // Progress bar variables - const int size= m_ReferenceRepHash.size(); - int previousQuantumValue= 0; - int currentQuantumValue= 0; - int currentFileIndex= 0; - emit currentQuantum(currentQuantumValue); - - // Load all external rep - ReferenceRepHash::iterator iRefRep= m_ReferenceRepHash.begin(); - while (iRefRep != m_ReferenceRepHash.constEnd()) - { - m_CurrentFileName= iRefRep.value(); - const unsigned int id= iRefRep.key(); - - if (!m_IsInArchive) - { - // Get the 3DXML time stamp - m_CurrentDateTime= QFileInfo(QFileInfo(m_FileName).absolutePath() + QDir::separator() + QFileInfo(m_CurrentFileName).fileName()).lastModified(); - } - - - if (!m_LoadStructureOnly && setStreamReaderToFile(m_CurrentFileName)) - { - GLC_3DRep representation; - if (GLC_State::cacheIsUsed() && GLC_State::currentCacheManager().isUsable(m_CurrentDateTime, QFileInfo(m_FileName).baseName(), m_CurrentFileName)) - { - GLC_CacheManager cacheManager= GLC_State::currentCacheManager(); - GLC_BSRep binaryRep= cacheManager.binary3DRep(QFileInfo(m_FileName).baseName(), m_CurrentFileName); - representation= binaryRep.loadRep(); - setRepresentationFileName(&representation); - } - else - { - representation= loadCurrentExtRep(); - representation.clean(); - } - if (!representation.isEmpty()) - { - repHash.insert(id, representation); - } - } - else if (m_LoadStructureOnly) - { - GLC_3DRep representation; - if (m_IsInArchive) - { - representation.setFileName(glc::builtArchiveString(m_FileName, m_CurrentFileName)); - } - else - { - const QString repFileName= glc::builtFileString(m_FileName, m_CurrentFileName); - representation.setFileName(repFileName); - m_SetOfAttachedFileName << glc::archiveEntryFileName(repFileName); - } - - repHash.insert(id, representation); - } - - // Progrees bar indicator - ++currentFileIndex; - currentQuantumValue = static_cast((static_cast(currentFileIndex) / size) * 100); - if (currentQuantumValue > previousQuantumValue) - { - emit currentQuantum(currentQuantumValue); - } - previousQuantumValue= currentQuantumValue; - - ++iRefRep; - } - - // Attach the ref to the structure reference - RepLinkList::iterator iExtRep= m_ExternRepLinkList.begin(); - while (iExtRep != m_ExternRepLinkList.constEnd()) - { - unsigned int referenceId= (*iExtRep).m_ReferenceId; - unsigned int refId= (*iExtRep).m_RepId; - - GLC_StructReference* pReference= m_ReferenceHash.value(referenceId); - if (pReference->hasRepresentation()) - { - GLC_3DRep* pRep= dynamic_cast(pReference->representationHandle()); - if (NULL != pRep) - { - GLC_3DRep newRep(repHash.value(refId)); - pRep->take(&newRep); - } - } - else - { - pReference->setRepresentation(repHash.value(refId)); - } - // If representation hasn't a name. Set his name to reference name - if (pReference->representationName().isEmpty()) - { - pReference->setRepresentationName(pReference->name()); - } - - ++iExtRep; - } - -} - -// Return the instance of the current extern representation -GLC_3DRep GLC_3dxmlToWorld::loadCurrentExtRep() -{ - GLC_Mesh* pMesh= new GLC_Mesh(); - GLC_3DRep currentMeshRep(pMesh); - currentMeshRep.setName(QString()); - // Set rep file name and time stamp - setRepresentationFileName(¤tMeshRep); - - currentMeshRep.setLastModified(m_CurrentDateTime); - - int numberOfMesh= 1; - while (!m_pStreamReader->atEnd()) - { - m_pCurrentMaterial= NULL; - gotToPolygonalRepType(); - if (m_pStreamReader->atEnd() || m_pStreamReader->hasError()) - { - if (m_pStreamReader->hasError()) - { - QString message(QString("An element have not been found in file ") + m_FileName); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - else - { - pMesh->finish(); - currentMeshRep.clean(); - - if (GLC_State::cacheIsUsed()) - { - GLC_CacheManager currentManager= GLC_State::currentCacheManager(); - currentManager.addToCache(QFileInfo(m_FileName).baseName(), currentMeshRep); - } - - return currentMeshRep; - } - } - if (numberOfMesh > 1) - { - pMesh->finish(); - pMesh = new GLC_Mesh(); - currentMeshRep.addGeom(pMesh); - } - - loadRep(pMesh); - - ++numberOfMesh; - } - - pMesh->finish(); - currentMeshRep.clean(); - - if (GLC_State::cacheIsUsed()) - { - GLC_CacheManager currentManager= GLC_State::currentCacheManager(); - currentManager.addToCache(QFileInfo(m_FileName).baseName(), currentMeshRep); - } - - return currentMeshRep; -} -// Load CatMaterial Ref if present -void GLC_3dxmlToWorld::loadCatMaterialRef() -{ - - QList materialRefList; - - // Load material Name, Id and associated File - if (setStreamReaderToFile("CATMaterialRef.3dxml", true)) - { - // Load the material file - //qDebug() << "CATMaterialRef.3dxml found and current"; - goToElement(m_pStreamReader, "CATMaterialRef"); - checkForXmlError("Element CATMaterialRef not found in CATMaterialRef.3dxml"); - while (endElementNotReached(m_pStreamReader, "CATMaterialRef")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if (currentElementName == "CATMatReference") - { - MaterialRef currentMaterial; - currentMaterial.m_Id= readAttribute("id", true); - currentMaterial.m_Name= readAttribute("name", true); - goToElement(m_pStreamReader, "MaterialDomain"); - checkForXmlError("Element MaterialDomain not found after CATMatReference Element"); - currentMaterial.m_AssociatedFile= readAttribute("associatedFile", true).remove("urn:3DXML:"); - materialRefList.append(currentMaterial); - //qDebug() << "Material " << currentMaterial.m_Name << " Added"; - } - } - readNext(); - } - } - // Load material files - const int size= materialRefList.size(); - for (int i= 0; i < size; ++i) - { - if (setStreamReaderToFile(materialRefList.at(i).m_AssociatedFile, true)) - { - //qDebug() << "Load MaterialDef : " << materialRefList.at(i).m_AssociatedFile; - loadMaterialDef(materialRefList.at(i)); - } - } -} - -// Create material from material def file -void GLC_3dxmlToWorld::loadMaterialDef(const MaterialRef& materialRef) -{ - GLC_Material* pMaterial= new GLC_Material(); - goToElement(m_pStreamReader, "Osm"); - checkForXmlError(QString("Element Osm not found in file : ") + materialRef.m_AssociatedFile); - while (endElementNotReached(m_pStreamReader, "Osm")) - { - readNext(); - if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && m_pStreamReader->name() == "Attr") - { - const QString currentName= readAttribute("Name", true); - if (currentName == "DiffuseColor") - { - QString color= m_pStreamReader->attributes().value("Value").toString(); - color.remove('['); - color.remove(']'); - QStringList colors(color.split(",")); - QColor diffuseColor; - diffuseColor.setRedF(colors.at(0).toDouble()); - diffuseColor.setGreenF(colors.at(1).toDouble()); - diffuseColor.setBlueF(colors.at(2).toDouble()); - pMaterial->setDiffuseColor(diffuseColor); - } - else if (currentName == "Transparency") - { - double opacity= readAttribute("Value", true).toDouble(); - opacity= 1.0 - opacity; - pMaterial->setOpacity(opacity); - } - else if (currentName == "SpecularExponent") - { - double SpecularExponent= readAttribute("Value", true).toDouble() * 128.0; - pMaterial->setShininess(SpecularExponent); - } - else if (currentName == "TextureImage") - { - //qDebug() << "TextureImage"; - QString imageId= readAttribute("Value", true).remove("urn:3DXML:CATRepImage.3dxml#"); - if (m_TextureImagesHash.contains(imageId)) - { - QString imageName= m_TextureImagesHash.value(imageId); - GLC_Texture* pTexture= loadTexture(imageName); - if (NULL != pTexture) - { - pMaterial->setTexture(pTexture); - } - } - } - else if (currentName == "EmissiveCoef") - { - - } - else if (currentName == "SpecularColor") - { - QString color= readAttribute("Value", true); - color.remove('['); - color.remove(']'); - QStringList colors(color.split(",")); - QColor specularColor; - specularColor.setRedF(colors.at(0).toDouble()); - specularColor.setGreenF(colors.at(1).toDouble()); - specularColor.setBlueF(colors.at(2).toDouble()); - pMaterial->setSpecularColor(specularColor); - } - else if (currentName == "AmbientColor") - { - QString color= readAttribute("Value", true); - color.remove('['); - color.remove(']'); - QStringList colors(color.split(",")); - QColor ambientColor; - ambientColor.setRedF(colors.at(0).toDouble()); - ambientColor.setGreenF(colors.at(1).toDouble()); - ambientColor.setBlueF(colors.at(2).toDouble()); - pMaterial->setAmbientColor(ambientColor); - } - - } - } - pMaterial->setName(materialRef.m_Name); - m_MaterialHash.insert(materialRef.m_Id, pMaterial); -} - -// Load CATRepIage if present -void GLC_3dxmlToWorld::loadCatRepImage() -{ - // Load texture image name - if (setStreamReaderToFile("CATRepImage.3dxml", true)) - { - //qDebug() << "CATRepImage.3dxml Found"; - goToElement(m_pStreamReader, "CATRepImage"); - checkForXmlError("Element CATRepImage not found in CATRepImage.3dxml"); - while (endElementNotReached(m_pStreamReader, "CATRepImage")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if (currentElementName == "CATRepresentationImage") - { - QString id= readAttribute("id", true); - QString associatedFile= readAttribute("associatedFile", true).remove("urn:3DXML:"); - m_TextureImagesHash.insert(id,associatedFile); - } - } - readNext(); - } - //qDebug() << "CATRepImage.3dxml Load"; - } -} - -// try to load the specified image -GLC_Texture* GLC_3dxmlToWorld::loadTexture(QString fileName) -{ - QString format= QFileInfo(fileName).suffix().toUpper(); - QImage resultImage; - QString resultImageFileName; - if (m_IsInArchive) - { - // Create QuaZip File - QuaZipFile* p3dxmlFile= new QuaZipFile(m_p3dxmlArchive); - - // Get the file of the 3dxml - if (!m_p3dxmlArchive->setCurrentFile(fileName, QuaZip::csInsensitive)) - { - return NULL; - } - - // Open the file of the 3dxml - if(!p3dxmlFile->open(QIODevice::ReadOnly)) - { - delete p3dxmlFile; - QString message(QString("GLC_3dxmlToWorld::loadImage Unable to Open ") + fileName); - GLC_FileFormatException fileFormatException(message, fileName, GLC_FileFormatException::FileNotSupported); - clear(); - throw(fileFormatException); - } - resultImage.load(p3dxmlFile, format.toLocal8Bit()); - p3dxmlFile->close(); - delete p3dxmlFile; - resultImageFileName= glc::builtArchiveString(m_FileName, fileName); - } - else - { - // Create the file to load - if (fileName != m_FileName) - { - resultImageFileName= QFileInfo(m_FileName).absolutePath() + QDir::separator() + fileName; - } - QFile* pCurrentFile= new QFile(resultImageFileName); - if (!pCurrentFile->open(QIODevice::ReadOnly)) - { - delete pCurrentFile; - QString message(QString("GLC_3dxmlToWorld::loadImage File ") + resultImageFileName + QString(" not found")); - QStringList stringList(m_CurrentFileName); - stringList.append(message); - GLC_ErrorLog::addError(stringList); - return NULL; - } - else - { - m_SetOfAttachedFileName << resultImageFileName; - } - resultImage.load(pCurrentFile, format.toLocal8Bit()); - pCurrentFile->close(); - delete pCurrentFile; - } - - GLC_Texture* pTexture= NULL; - if (!resultImage.isNull()) - { - pTexture= new GLC_Texture(resultImage, resultImageFileName); - } - else - { - QStringList stringList(m_CurrentFileName); - stringList.append("Unable to load " + resultImageFileName); - GLC_ErrorLog::addError(stringList); - } - - return pTexture; -} - -void GLC_3dxmlToWorld::setRepresentationFileName(GLC_3DRep* pRep) -{ - if (m_IsInArchive) - { - pRep->setFileName(glc::builtArchiveString(m_FileName, m_CurrentFileName)); - } - else - { - pRep->setFileName(QFileInfo(m_FileName).absolutePath() + QDir::separator() + m_CurrentFileName); - } -} - -void GLC_3dxmlToWorld::checkFileValidity(QIODevice* pIODevice) -{ - QByteArray begining= pIODevice->read(2); - if (begining == "V5") - { - QString message(QString("GLC_3dxmlToWorld::setStreamReaderToFile : File ") + m_CurrentFileName + " is binary"); - GLC_FileFormatException fileFormatException(message, m_CurrentFileName, GLC_FileFormatException::FileNotSupported); - clear(); - throw(fileFormatException); - } - else - { - pIODevice->seek(0); - } -} - -void GLC_3dxmlToWorld::applyV4Attribute(GLC_StructOccurence* pOccurence, V4OccurenceAttrib* pV4OccurenceAttrib, QHash& instanceToIdHash) -{ - Q_ASSERT(pOccurence->hasChild() && !pV4OccurenceAttrib->m_Path.isEmpty()); - unsigned int id= pV4OccurenceAttrib->m_Path.takeFirst(); - - const int childCount= pOccurence->childCount(); - bool occurenceFound= false; - int i= 0; - while (!occurenceFound && (i < childCount)) - { - GLC_StructOccurence* pChildOccurence= pOccurence->child(i); - if (instanceToIdHash.contains(pChildOccurence->structInstance()) && (instanceToIdHash.value(pChildOccurence->structInstance()) == id)) - { - Q_ASSERT(id == instanceToIdHash.value(pChildOccurence->structInstance())); - occurenceFound= true; - - if (pV4OccurenceAttrib->m_Path.isEmpty()) - { - pChildOccurence->setVisibility(pV4OccurenceAttrib->m_IsVisible); - if (NULL != pV4OccurenceAttrib->m_pRenderProperties) - { - pChildOccurence->setRenderProperties(*(pV4OccurenceAttrib->m_pRenderProperties)); - } - if (pV4OccurenceAttrib->m_pMatrix != NULL) - { - pChildOccurence->makeFlexible(*(pV4OccurenceAttrib->m_pMatrix)); - } - } - else - { - applyV4Attribute(pChildOccurence, pV4OccurenceAttrib, instanceToIdHash); - } - } - else - { - ++i; - } - } - if (!occurenceFound) - { - qDebug() << "GLC_3dxmlToWorld::applyV4Attribute Occurrence not found" << id; - } - -} - -void GLC_3dxmlToWorld::loadRep(GLC_Mesh* pMesh) -{ - double masteLodAccuracy= readAttribute("accuracy", false).toDouble(); - int lodIndex= 1; - - bool masterLodFound= false; - bool vertexBufferFound= false; - - while (endElementNotReached(m_pStreamReader, "Rep") && endElementNotReached(m_pStreamReader, "Root")) - { - if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType())) - { - if (m_pStreamReader->name() == "SurfaceAttributes") - { - m_pCurrentMaterial= loadSurfaceAttributes(); - } - else if (m_pStreamReader->name() == "PolygonalLOD") - { - double accuracy= readAttribute("accuracy", true).toDouble(); - while (endElementNotReached(m_pStreamReader, "Faces")) - { - readNext(); - if ( m_pStreamReader->name() == "Face") - { - loadFace(pMesh, lodIndex, accuracy); - } - } - checkForXmlError("End of Faces not found"); - ++lodIndex; - } - else if (m_pStreamReader->name() == "Faces") - { - masterLodFound= true; - while (endElementNotReached(m_pStreamReader, "Faces")) - { - readNext(); - if ( m_pStreamReader->name() == "Face") - { - loadFace(pMesh, 0, masteLodAccuracy); - } - } - checkForXmlError("End of Faces not found"); - } - else if (m_pStreamReader->name() == "Edges") - { - while (endElementNotReached(m_pStreamReader, "Edges")) - { - readNext(); - if ( m_pStreamReader->name() == "Polyline") - { - loadPolyline(pMesh); - readNext(); - } - } - } - else if (m_pStreamReader->name() == "VertexBuffer") - { - vertexBufferFound= true; - loadVertexBuffer(pMesh); - } - else readNext(); - } - else - { - readNext(); - } - } - checkForXmlError("End of Rep or Root not found"); - - if (!masterLodFound || !vertexBufferFound) - { - QString message; - if (!masterLodFound) - { - message= QString("Master LOD not found in file ") + m_FileName; - } - else - { - message= QString("Vertex Buffer not found in file ") + m_FileName; - } - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - - -} - -void GLC_3dxmlToWorld::loadVertexBuffer(GLC_Mesh* pMesh) -{ - { - QString verticePosition= getContent(m_pStreamReader, "Positions").replace(',', ' '); - //qDebug() << "Position " << verticePosition; - checkForXmlError("Error while retrieving Position ContentVertexBuffer"); - // Load Vertice position - QTextStream verticeStream(&verticePosition); - QList verticeValues; - QString buff; - while ((!verticeStream.atEnd())) - { - verticeStream >> buff; - verticeValues.append(buff.toFloat()); - } - if ((verticeValues.size() % 3) == 0) - { - pMesh->addVertice(verticeValues.toVector()); - } - else - { - QString message(QString("Vertice buffer is not a multiple of 3 ") + m_CurrentFileName); - - QStringList stringList(message); - GLC_ErrorLog::addError(stringList); - - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - } - - { - QString normals= getContent(m_pStreamReader, "Normals").replace(',', ' '); - //qDebug() << "Normals " << normals; - checkForXmlError("Error while retrieving Normals values"); - // Load Vertice Normals - QTextStream normalsStream(&normals); - QList normalValues; - QString buff; - while ((!normalsStream.atEnd())) - { - normalsStream >> buff; - normalValues.append(buff.toFloat()); - } - if ((normalValues.size() % 3) == 0) - { - pMesh->addNormals(normalValues.toVector()); - } - else - { - QString message(QString("Normal buffer is not a multiple of 3 ") + m_CurrentFileName); - - QStringList stringList(message); - GLC_ErrorLog::addError(stringList); - - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - - } - // Try to find texture coordinate - while (endElementNotReached(m_pStreamReader, "VertexBuffer")) - { - if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "TextureCoordinates")) - { - QString texels= getContent(m_pStreamReader, "TextureCoordinates").replace(',', ' '); - checkForXmlError("Error while retrieving Texture coordinates"); - QTextStream texelStream(&texels); - QList texelValues; - QString buff; - while ((!texelStream.atEnd())) - { - texelStream >> buff; - texelValues.append(buff.toFloat()); - } - - if ((texelValues.size() % 2) == 0) - { - pMesh->addTexels(texelValues.toVector()); - } - else - { - QString message(QString("Texel buffer is not a multiple of 2 ") + m_CurrentFileName); - - QStringList stringList(message); - GLC_ErrorLog::addError(stringList); - - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - } - readNext(); - } - checkForXmlError("VertexBuffer not found"); -} diff --git a/ground/gcs/src/libs/glc_lib/io/glc_3dxmltoworld.h b/ground/gcs/src/libs/glc_lib/io/glc_3dxmltoworld.h deleted file mode 100644 index 1b2c094dd..000000000 --- a/ground/gcs/src/libs/glc_lib/io/glc_3dxmltoworld.h +++ /dev/null @@ -1,472 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_3dxmltoworld.h interface for the GLC_3dxmlToWorld class. - -#ifndef GLC_3DXMLTOWORLD_H_ -#define GLC_3DXMLTOWORLD_H_ - -#include -#include -#include -#include -#include -#include -#include "../maths/glc_matrix4x4.h" -#include "../sceneGraph/glc_3dviewinstance.h" - -#include "../glc_config.h" - -class GLC_World; -class QGLContext; -class QuaZip; -class QuaZipFile; -class GLC_StructReference; -class GLC_StructInstance; -class GLC_StructOccurence; -class GLC_Mesh; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_3dxmlToWorld -/*! \brief GLC_3dxmlToWorld : Create an GLC_World from 3dxml file */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_3dxmlToWorld : public QObject -{ - Q_OBJECT - - //! \struct AssyLink - /*! \brief AssyLink : Assemblage link between parent id and GLC_StructInstance* */ - struct AssyLink - { - unsigned int m_ParentRefId; - GLC_StructInstance* m_pChildInstance; - unsigned int m_InstanceId; - inline bool operator < (const AssyLink& l) const - {return m_InstanceId < l.m_InstanceId;} - }; - //! \class RepLink - /*! \brief RepLink : Representation link between reference id and representation id */ - struct RepLink - { - unsigned int m_ReferenceId; - unsigned int m_RepId; - }; - //! \class MaterialRef - /*! \brief MaterialRef : Material reference containing id, name and associated file */ - struct MaterialRef - { - QString m_Id; - QString m_Name; - QString m_AssociatedFile; - }; - - //! \class V3OccurenceAttrib - /*! \brief V3OccurenceAttrib : Specifique occurence attribute */ - struct V3OccurenceAttrib - { - inline V3OccurenceAttrib() - : m_IsVisible(true) - , m_pRenderProperties(NULL) - {} - inline ~V3OccurenceAttrib() - {delete m_pRenderProperties;} - - //! Visibility attribute - bool m_IsVisible; - //! Render properties attribute - GLC_RenderProperties* m_pRenderProperties; - }; - - //! \class V3OccurenceAttrib - /*! \brief V3OccurenceAttrib : Specifique occurence attribute */ - struct V4OccurenceAttrib - { - inline V4OccurenceAttrib() - : m_IsVisible(true) - , m_pRenderProperties(NULL) - , m_pMatrix(NULL) - , m_Path() - {} - inline ~V4OccurenceAttrib() - { - delete m_pRenderProperties; - delete m_pMatrix; - } - - //! Visibility attribute - bool m_IsVisible; - //! Render properties attribute - GLC_RenderProperties* m_pRenderProperties; - //! Relative matrix - GLC_Matrix4x4* m_pMatrix; - //! The path of this attrib - QList m_Path; - }; - - typedef QHash ReferenceHash; - typedef QHash InstanceOfHash; - typedef QHash InstanceOfExtRefHash; - typedef QSet SetOfExtRef; - typedef QList AssyLinkList; - typedef QList RepLinkList; - typedef QHash ExternalReferenceHash; - typedef QHash MaterialHash; - typedef QHash ReferenceRepHash; - -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Default constructor - GLC_3dxmlToWorld(); - - virtual ~GLC_3dxmlToWorld(); -//@} -////////////////////////////////////////////////////////////////////// -/*! @name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Create an GLC_World from an input 3DXML File - GLC_World* createWorldFrom3dxml(QFile &, bool StructureOnly, bool getExternalRef= false); - - //! Create 3DRep from an 3DXML rep - GLC_3DRep create3DrepFrom3dxmlRep(const QString&); - - //! Get the list of attached files - inline QStringList listOfAttachedFileName() const - {return m_SetOfAttachedFileName.toList();} - - -//@} - -////////////////////////////////////////////////////////////////////// -// Qt Signals -////////////////////////////////////////////////////////////////////// - signals: - void currentQuantum(int); - -////////////////////////////////////////////////////////////////////// -/*! @name Private services functions */ -//@{ -////////////////////////////////////////////////////////////////////// -private: - //! Load the 3dxml's manifest - void loadManifest(); - - //! Close all files and clear memmory - void clear(); - - //! Go to a Rep of a xml - void goToRepId(const QString&); - - //! Go to Polygonal Rep Type - void gotToPolygonalRepType(); - - //! Read the specified attribute - QString readAttribute(const QString&, bool required= false); - - //! Read the Header - void readHeader(); - - //! Load the product structure - void loadProductStructure(); - - //! Load a Reference3D - void loadReference3D(); - - //! Load a Instance3D - void loadInstance3D(); - - //! Load a Reference representation - void loadReferenceRep(); - - //! Load a Instance representation - void loadInstanceRep(); - - //! Load External Ref - void loadExternalRef3D(); - - //! Add a reference from 3dxml to m_ExternalReferenceHash - GLC_StructReference* createReferenceRep(QString id, GLC_3DRep* pRep); - - //! Load Matrix - GLC_Matrix4x4 loadMatrix(const QString&); - - //! Create the unfolded tree - void createUnfoldedTree(); - - //! Check for XML error - //! Throw ecxeption if error occur - void checkForXmlError(const QString&); - - //! Load a face - void loadFace(GLC_Mesh*, const int lod, double accuracy); - - //! Load polyline - void loadPolyline(GLC_Mesh*); - - //! Clear material hash - void clearMaterialHash(); - - //! Load surface attributes - GLC_Material* loadSurfaceAttributes(); - - //! get material - GLC_Material* getMaterial(); - - //! Set the stream reader to the specified file - bool setStreamReaderToFile(QString, bool test= false); - - //! Load default view element - void loadDefaultView(); - - //! Load 3DXML V3 default view property - void loadV3DefaultViewProperty(); - - //! Load 3DXML V4 default view property - void loadV4DefaultViewProperty(); - - //! Return the occurence path of the current DefaultViewProperty - QList loadOccurencePath(); - - //! Load Graphics properties element - void loadGraphicProperties(V4OccurenceAttrib* pAttrib); - - //! Load the local representation - void loadLocalRepresentations(); - - //! Load the extern representation - void loadExternRepresentations(); - - //! Return the instance of the current extern representation - GLC_3DRep loadCurrentExtRep(); - - //! Load CatMaterial Ref if present - void loadCatMaterialRef(); - - //! Create material from material def file - void loadMaterialDef(const MaterialRef&); - - //! Load CATRepIage if present - void loadCatRepImage(); - - //! Try to construct a texture with the specified fileName - GLC_Texture* loadTexture(QString); - - //! Set fileName of the given 3DRep - void setRepresentationFileName(GLC_3DRep* pRep); - - //! Read next element from the stream - inline QXmlStreamReader::TokenType readNext(); - - //! Go to the given xml Element, return true on succes - inline bool goToElement(QXmlStreamReader* pReader, const QString& element); - - // Return the content of an element - inline QString getContent(QXmlStreamReader* pReader, const QString& element); - - //! Read the specified attribute - inline QString readAttribute(QXmlStreamReader* pReader, const QString& attribute); - - //! Return true if the end of specified element is not reached - inline bool endElementNotReached(QXmlStreamReader* pReader, const QString& element); - - //! Return true if the start of specified element is not reached - inline bool startElementNotReached(QXmlStreamReader* pReader, const QString& element); - - //! Go to the end Element of a xml - inline void goToEndElement(QXmlStreamReader* pReader, const QString& element); - - //! Check if the given file is binary - void checkFileValidity(QIODevice* pIODevice); - - //! Apply the given attribute to the right occurence from the given occurence - void applyV4Attribute(GLC_StructOccurence* pOccurence, V4OccurenceAttrib* pV4OccurenceAttrib, QHash& InstanceToIdHash); - - //! Load representation from 3DRep file - void loadRep(GLC_Mesh* pMesh); - - //! Load The 3DXML vertex buffer - void loadVertexBuffer(GLC_Mesh* pMesh); - -//@} - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - //! Xml Reader - QXmlStreamReader* m_pStreamReader; - - //! The 3dxml fileName - QString m_FileName; - - //! The Quazip archive - QuaZip* m_p3dxmlArchive; - - //! The current file (if there is no archive) - QFile* m_pCurrentFile; - - //! The root Name of the 3dxml file - QString m_RootName; - - //! The World to return - GLC_World* m_pWorld; - - //! Reference Hash Table - ReferenceHash m_ReferenceHash; - - //! The Structure Link Hash Table - AssyLinkList m_AssyLinkList; - - //! Instance of Hash table - InstanceOfHash m_InstanceOf; - - //! The set of ext ref to load - SetOfExtRef m_SetOfExtRef; - - //! Instance of ext ref hash table - InstanceOfExtRefHash m_InstanceOfExtRefHash; - - //! Externam reference hash table - ExternalReferenceHash m_ExternalReferenceHash; - - //! Hash table of material - MaterialHash m_MaterialHash; - - //! Flag to know if the 3dxml is in an archive - bool m_IsInArchive; - - //! The Reference representation hash table - ReferenceRepHash m_ReferenceRepHash; - - //! The list of local representation link - RepLinkList m_LocalRepLinkList; - - //! The list of extern representation link - RepLinkList m_ExternRepLinkList; - - //! The set of ext rep to load - SetOfExtRef m_SetOfExtRep; - - //! The 3DREP current material - GLC_Material* m_pCurrentMaterial; - - //! The image file hash table - QHash m_TextureImagesHash; - - //! Flag indicate the loading method - bool m_LoadStructureOnly; - - //! The Set of attached file name - QSet m_SetOfAttachedFileName; - - //! The current file name - QString m_CurrentFileName; - - //! The current file time and date - QDateTime m_CurrentDateTime; - - //! Hash table of occurence specific attributes for 3DXML V3 - QHash m_V3OccurenceAttribHash; - - //! List of occurence specific attributes for 3DXML V4 - QList m_V4OccurenceAttribList; - - //! bool get external ref 3D name - bool m_GetExternalRef3DName; - - static QMutex m_ZipMutex; - - QList m_ByteArrayList; - - //! Flag to know if the 3DXML is in version 3.x - bool m_IsVersion3; - -}; - -QXmlStreamReader::TokenType GLC_3dxmlToWorld::readNext() -{ - QXmlStreamReader::TokenType token= m_pStreamReader->readNext(); - if (QXmlStreamReader::PrematureEndOfDocumentError == m_pStreamReader->error()) - { - //qDebug() << "QXmlStreamReader::PrematureEndOfDocumentError == m_pStreamReader->error()"; - if (!m_ByteArrayList.isEmpty()) - { - m_pStreamReader->addData(m_ByteArrayList.takeFirst()); - return readNext(); - } - } - return token; -} - -bool GLC_3dxmlToWorld::goToElement(QXmlStreamReader* pReader, const QString& element) -{ - while(!pReader->atEnd() && !pReader->hasError() && !(pReader->isStartElement() && (pReader->name() == element))) - { - readNext(); - } - return !pReader->atEnd() && !pReader->hasError(); -} - -QString GLC_3dxmlToWorld::getContent(QXmlStreamReader* pReader, const QString& element) -{ - QString content; - while(endElementNotReached(pReader, element)) - { - readNext(); - if (pReader->isCharacters() && !pReader->text().isEmpty()) - { - content+= pReader->text().toString(); - } - } - - return content.trimmed(); -} - -QString GLC_3dxmlToWorld::readAttribute(QXmlStreamReader* pReader, const QString& attribute) -{ - return pReader->attributes().value(attribute).toString(); -} - -bool GLC_3dxmlToWorld::endElementNotReached(QXmlStreamReader* pReader, const QString& element) -{ - return !pReader->atEnd() && !pReader->hasError() && !(pReader->isEndElement() && (pReader->name() == element)); -} - -bool GLC_3dxmlToWorld::startElementNotReached(QXmlStreamReader* pReader, const QString& element) -{ - return !pReader->atEnd() && !pReader->hasError() && !(pReader->isStartElement() && (pReader->name() == element)); -} - -void GLC_3dxmlToWorld::goToEndElement(QXmlStreamReader* pReader, const QString& element) -{ - while(endElementNotReached(pReader, element)) - { - readNext(); - } -} - - -#endif /* GLC_3DXMLTOWORLD_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/io/glc_bsreptoworld.cpp b/ground/gcs/src/libs/glc_lib/io/glc_bsreptoworld.cpp deleted file mode 100644 index 417b4b2b3..000000000 --- a/ground/gcs/src/libs/glc_lib/io/glc_bsreptoworld.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_bsreptoworld.cpp implementation of the GLC_BSRepToWorld class. - -#include "glc_bsreptoworld.h" -#include "../sceneGraph/glc_world.h" -#include "../glc_fileformatexception.h" - -GLC_BSRepToWorld::GLC_BSRepToWorld() -{ - -} - -GLC_BSRepToWorld::~GLC_BSRepToWorld() -{ - -} - -GLC_World* GLC_BSRepToWorld::CreateWorldFromBSRep(QFile &file) -{ - ////////////////////////////////////////////////////////////////// - // Test if the file exist and can be opened - ////////////////////////////////////////////////////////////////// - if (!file.open(QIODevice::ReadOnly)) - { - QString fileName(file.fileName()); - QString message(QString("GLC_BSRepToWorld::CreateWorldFromBSRep File ") + fileName + QString(" doesn't exist")); - GLC_FileFormatException fileFormatException(message, fileName, GLC_FileFormatException::FileNotFound); - throw(fileFormatException); - } - file.close(); - GLC_BSRep bsRep(file.fileName()); - GLC_3DRep rep(bsRep.loadRep()); - GLC_World* pWorld= new GLC_World(); - pWorld->rootOccurence()->addChild(new GLC_StructOccurence(new GLC_3DRep(rep))); - return pWorld; -} diff --git a/ground/gcs/src/libs/glc_lib/io/glc_bsreptoworld.h b/ground/gcs/src/libs/glc_lib/io/glc_bsreptoworld.h deleted file mode 100644 index c1f8ab158..000000000 --- a/ground/gcs/src/libs/glc_lib/io/glc_bsreptoworld.h +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_bsreptoworld.h interface for the GLC_BSRepToWorld class. - -#ifndef GLC_BSREPTOWORLD_H_ -#define GLC_BSREPTOWORLD_H_ - -#include -#include "../glc_config.h" - -class GLC_World; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_BSRepToWorld -/*! \brief GLC_BSRepToWorld : Create an GLC_World from BSRep file */ - -/*! An GLC_BSRepToWorld extract the only mesh from an .BSRep file*/ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_BSRepToWorld -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - GLC_BSRepToWorld(); - virtual ~GLC_BSRepToWorld(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! @name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Create and return an GLC_World* from an input BSRep File - GLC_World* CreateWorldFromBSRep(QFile &file); -//@} - -}; - -#endif /* GLC_BSREPTOWORLD_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/io/glc_colladatoworld.cpp b/ground/gcs/src/libs/glc_lib/io/glc_colladatoworld.cpp deleted file mode 100644 index c863be11b..000000000 --- a/ground/gcs/src/libs/glc_lib/io/glc_colladatoworld.cpp +++ /dev/null @@ -1,2100 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -#include "glc_colladatoworld.h" -#include "../sceneGraph/glc_world.h" -#include "../glc_fileformatexception.h" -#include "../maths/glc_geomtools.h" -#include "../glc_factory.h" -#include "glc_xmlutil.h" - -static QString prefixNodeId= "GLC_LIB_COLLADA_ID_"; -static int currentNodeId= 0; - -using namespace glcXmlUtil; - -// Default constructor -GLC_ColladaToWorld::GLC_ColladaToWorld() -: QObject() -, m_pWorld(NULL) -, m_pStreamReader(NULL) -, m_FileName() -, m_pFile(NULL) -, m_ImageFileHash() -, m_MaterialLibHash() -, m_SurfaceImageHash() -, m_MaterialEffectHash() -, m_pCurrentMaterial(NULL) -, m_TextureToMaterialHash() -, m_BulkDataHash() -, m_DataAccessorHash() -, m_VerticesSourceHash() -, m_pMeshInfo(NULL) -, m_GeometryHash() -, m_ColladaNodeHash() -, m_TopLevelColladaNode() -, m_MaterialInstanceMap() -, m_3DRepHash() -, m_StructInstanceHash() -, m_CurrentId() -, m_FileSize(0) -, m_CurrentOffset(0) -, m_ListOfAttachedFileName() -, m_TransparentIsRgbZero(false) -{ - currentNodeId= 0; -} - -// Destructor -GLC_ColladaToWorld::~GLC_ColladaToWorld() -{ - // Normal ends, world has not to be deleted - m_pWorld= NULL; - clear(); -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// -// Create an GLC_World from an input Collada File -GLC_World* GLC_ColladaToWorld::CreateWorldFromCollada(QFile &file) -{ - m_pWorld= new GLC_World(); - m_FileName= file.fileName(); - m_pFile= &file; - - ////////////////////////////////////////////////////////////////// - // Test if the file exist and can be opened - ////////////////////////////////////////////////////////////////// - if (!m_pFile->open(QIODevice::ReadOnly)) - { - QString message(QString("GLC_ColladaToWorld::CreateWorldFromCollada File ") + m_FileName + QString(" doesn't exist")); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotFound); - throw(fileFormatException); - } - // Get the file size - m_FileSize= QFileInfo(m_FileName).size(); - - m_pStreamReader= new QXmlStreamReader(m_pFile); - - // Go to the collada root Element - goToElement("COLLADA"); - - // Read the collada version - QString version= readAttribute("version", true); - - // Go to the asset Element to get the Up vector - goToElement("asset"); - while (endElementNotReached(m_pStreamReader, "asset")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if (currentElementName == "up_axis") - { - const QString upAxis= getContent("up_axis"); - if (upAxis == "X_UP") m_pWorld->setUpVector(glc::X_AXIS); - else if (upAxis == "Y_UP") m_pWorld->setUpVector(glc::Y_AXIS); - else if (upAxis == "Z_UP") m_pWorld->setUpVector(glc::Z_AXIS); - } - } - m_pStreamReader->readNext(); - } - - while (endElementNotReached(m_pStreamReader, "COLLADA")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if (currentElementName == "library_images") loadLibraryImage(); - else if (currentElementName == "library_materials") loadLibraryMaterials(); - else if (currentElementName == "library_effects") loadLibraryEffects(); - else if (currentElementName == "library_geometries") loadLibraryGeometries(); - else if (currentElementName == "library_nodes") loadLibraryNodes(); - else if (currentElementName == "library_controllers") loadLibraryContollers(); - else if (currentElementName == "library_visual_scenes") loadVisualScenes(); - else if (currentElementName == "scene") loadScene(); - } - - m_pStreamReader->readNext(); - } - - m_pFile->close(); - m_pFile= NULL; - - // Link the textures to materials - linkTexturesToMaterials(); - - // Create the mesh and link them to material - createMesh(); - - // Create the scene graph struct - createSceneGraph(); - - emit currentQuantum(100); - - return m_pWorld; -} - -////////////////////////////////////////////////////////////////////// -// Private services Functions -////////////////////////////////////////////////////////////////////// -// Go to Element -void GLC_ColladaToWorld::goToElement(const QString& elementName) -{ - while(startElementNotReached(m_pStreamReader, elementName)) - { - m_pStreamReader->readNext(); - } - checkForXmlError(QString("Element ") + elementName + QString(" Not Found")); -} - -// Go to the end Element of a xml -void GLC_ColladaToWorld::goToEndElement(const QString& elementName) -{ - while(endElementNotReached(m_pStreamReader, elementName)) - { - m_pStreamReader->readNext(); - } - checkForXmlError(QString("End Element ") + elementName + QString(" Not Found")); -} - -// Return the content of an element -QString GLC_ColladaToWorld::getContent(const QString& element) -{ - QString Content; - while(endElementNotReached(m_pStreamReader, element)) - { - m_pStreamReader->readNext(); - if (m_pStreamReader->isCharacters() && !m_pStreamReader->text().isEmpty()) - { - Content+= m_pStreamReader->text().toString(); - } - } - - return Content.simplified(); -} - -// Read the specified attribute -QString GLC_ColladaToWorld::readAttribute(const QString& name, bool required) -{ - QString attributeValue; - if (required && !m_pStreamReader->attributes().hasAttribute(name)) - { - QString message(QString("required attribute ") + name + QString(" Not found")); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - else - { - attributeValue= m_pStreamReader->attributes().value(name).toString(); - } - return attributeValue; -} - -// Check for XML error -void GLC_ColladaToWorld::checkForXmlError(const QString& info) -{ - if (m_pStreamReader->atEnd() || m_pStreamReader->hasError()) - { - GLC_FileFormatException fileFormatException(info, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } -} -// Throw an exception with the specified text -void GLC_ColladaToWorld::throwException(const QString& message) -{ - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); -} - -// Clear memmory -void GLC_ColladaToWorld::clear() -{ - delete m_pWorld; - m_pWorld= NULL; - - - delete m_pStreamReader; - m_pStreamReader= NULL; - - if (m_pFile != NULL) m_pFile->close(); - m_pFile= NULL; - - m_ImageFileHash.clear(); - m_MaterialLibHash.clear(); - m_SurfaceImageHash.clear(); - - // Clear the material effect hash table - MaterialHash::iterator iMat= m_MaterialEffectHash.begin(); - while (iMat != m_MaterialEffectHash.constEnd()) - { - if (iMat.value()->isUnused()) delete iMat.value(); - ++iMat; - } - m_MaterialEffectHash.clear(); - - delete m_pCurrentMaterial; - m_pCurrentMaterial= NULL; - - m_TextureToMaterialHash.clear(); - - m_BulkDataHash.clear(); - m_DataAccessorHash.clear(); - - m_VerticesSourceHash.clear(); - - delete m_pMeshInfo; - m_pMeshInfo= NULL; - - // Delete all geometry from the geometry hash - QHash::iterator iGeomHash= m_GeometryHash.begin(); - while (m_GeometryHash.constEnd() != iGeomHash) - { - delete iGeomHash.value(); - ++iGeomHash; - } - m_GeometryHash.clear(); - - // Delete all collada node from the colalda node hash - QHash::iterator iColladaNode= m_ColladaNodeHash.begin(); - while (m_ColladaNodeHash.constEnd() != iColladaNode) - { - delete iColladaNode.value(); - ++iColladaNode; - } - m_ColladaNodeHash.clear(); - - // Clear the list of top level node (Not must not to be deleted) - m_TopLevelColladaNode.clear(); - - // Clear the material instance map - m_MaterialInstanceMap.clear(); - - //! Delete all 3DRep - QHash::iterator i3DRep= m_3DRepHash.begin(); - while (m_3DRepHash.constEnd() != i3DRep) - { - delete i3DRep.value(); - ++i3DRep; - } - m_3DRepHash.clear(); - - // Clear instance Hash table - m_StructInstanceHash.clear(); - - m_CurrentId.clear(); - - m_ListOfAttachedFileName.clear(); -} - -// Load library_images element -void GLC_ColladaToWorld::loadLibraryImage() -{ - while (endElementNotReached(m_pStreamReader, "library_images")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if (currentElementName == "image") loadImage(); - } - m_pStreamReader->readNext(); - - updateProgressBar(); - } - checkForXmlError("Error occur while loading element : library_images"); -} - -// Load image element -void GLC_ColladaToWorld::loadImage() -{ - //qDebug() << "GLC_ColladaToWorld::loadImage()"; - // load image id - m_CurrentId= readAttribute("id", true); - QString fileName; - // Trying to find external image fileName - while (endElementNotReached(m_pStreamReader, "image")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if (currentElementName == "init_from") - { - fileName= getContent("init_from"); - } - } - m_pStreamReader->readNext(); - } - - checkForXmlError("Error occur while loading element : image"); - - // Add the image in the image fileName Hash table - if (!fileName.isEmpty()) - { - m_ImageFileHash.insert(m_CurrentId, fileName); - } -} - -// Load library_materials element -void GLC_ColladaToWorld::loadLibraryMaterials() -{ - while (endElementNotReached(m_pStreamReader, "library_materials")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if (currentElementName == "material") loadMaterial(); - } - m_pStreamReader->readNext(); - - updateProgressBar(); - } - checkForXmlError("Error occur while loading element : library_materials"); - -} - -// Load a material -void GLC_ColladaToWorld::loadMaterial() -{ - // load material id - m_CurrentId= readAttribute("id", true); - - goToElement("instance_effect"); - - // Load instance effect url - const QString url= readAttribute("url", true).remove('#'); - //qDebug() << "instance effect URL : " << url; - - // Read instance effect parameters - while (endElementNotReached(m_pStreamReader, "instance_effect")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if (currentElementName == "setparam") - { - qDebug() << "GLC_ColladaToWorld::loadMaterial : setparam found"; - } - } - m_pStreamReader->readNext(); - } - - checkForXmlError("Error occur while loading element : material"); - - // Add the image in the image fileName Hash table - if (!url.isEmpty()) - { - //qDebug() << "insert material : " << m_CurrentId << " url: " << url; - m_MaterialLibHash.insert(m_CurrentId, url); - } - -} - -// Load library_effects element -void GLC_ColladaToWorld::loadLibraryEffects() -{ - while (endElementNotReached(m_pStreamReader, "library_effects")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if (currentElementName == "effect") loadEffect(); - } - m_pStreamReader->readNext(); - - updateProgressBar(); - } - checkForXmlError("Error occur while loading element : library_effects"); - -} - -// Load an effect -void GLC_ColladaToWorld::loadEffect() -{ - // load effect id - const QString id= readAttribute("id", true); - m_CurrentId= id; - m_pCurrentMaterial= new GLC_Material(); - m_pCurrentMaterial->setName(id); - - while (endElementNotReached(m_pStreamReader, "effect")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if (currentElementName == "profile_COMMON") loadProfileCommon(); - } - m_pStreamReader->readNext(); - } - - checkForXmlError("Error occur while loading element : effect"); - - m_MaterialEffectHash.insert(id, m_pCurrentMaterial); - m_pCurrentMaterial= NULL; - -} - -// Load profile_COMMON -void GLC_ColladaToWorld::loadProfileCommon() -{ - //qDebug() << "GLC_ColladaToWorld::loadProfileCommon"; - while (endElementNotReached(m_pStreamReader, "profile_COMMON")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if (currentElementName == "image") loadImage(); - else if (currentElementName == "newparam") loadNewParam(); - else if (currentElementName == "technique") loadTechnique(); - } - m_pStreamReader->readNext(); - } - checkForXmlError("Error occur while loading element : profile_COMMON"); -} - -// Load a new param of the common profile -void GLC_ColladaToWorld::loadNewParam() -{ - //qDebug() << "GLC_ColladaToWorld::loadNewParam"; - // load param sid - const QString sid= m_CurrentId + "::" + readAttribute("sid", true); - while (endElementNotReached(m_pStreamReader, "newparam")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if (currentElementName == "surface") loadSurface(sid); - else if (currentElementName == "sampler2D") loadSampler2D(sid); - } - m_pStreamReader->readNext(); - } - checkForXmlError("Error occur while loading element : profile_COMMON"); -} - -// Load a surface -void GLC_ColladaToWorld::loadSurface(const QString& sid) -{ - //qDebug() << "GLC_ColladaToWorld::loadSurface sid=" << sid ; - while (endElementNotReached(m_pStreamReader, "surface")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if (currentElementName == "init_from") - { - const QString imageId= getContent("init_from"); - m_SurfaceImageHash.insert(sid, imageId); - } - } - m_pStreamReader->readNext(); - } - checkForXmlError("Error occur while loading element : surface"); -} - -// Load Sampler 2D -void GLC_ColladaToWorld::loadSampler2D(const QString& sid) -{ - //qDebug() << "GLC_ColladaToWorld::loadSampler2D sid= " << sid; - while (endElementNotReached(m_pStreamReader, "sampler2D")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if (currentElementName == "source") - { - const QString source= m_CurrentId + "::" + getContent("source"); - m_Sampler2DSurfaceHash.insert(sid, source); - } - } - m_pStreamReader->readNext(); - } - checkForXmlError("Error occur while loading element : sampler2D"); -} - -// Load technique -void GLC_ColladaToWorld::loadTechnique() -{ - //qDebug() << "GLC_ColladaToWorld::loadTechnique"; - while (endElementNotReached(m_pStreamReader, "technique")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if (currentElementName == "phong") loadMaterialTechnique(currentElementName.toString()); - if (currentElementName == "lambert") loadMaterialTechnique(currentElementName.toString()); - if (currentElementName == "blinn") loadMaterialTechnique(currentElementName.toString()); - } - m_pStreamReader->readNext(); - } - checkForXmlError("Error occur while loading element : technique"); -} - -// load phong material -void GLC_ColladaToWorld::loadMaterialTechnique(const QString& elementName) -{ - //qDebug() << "GLC_ColladaToWorld::loadMaterialTechnique"; - while (endElementNotReached(m_pStreamReader, elementName)) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if ((currentElementName == "emission") - || (currentElementName == "ambient") - || (currentElementName == "diffuse") - ||(currentElementName == "specular")) - loadCommonColorOrTexture(currentElementName.toString()); - else if (currentElementName == "transparent") loadTransparent(); - else if (currentElementName == "transparency") loadTransparency(currentElementName.toString()); - else if (currentElementName == "shininess") loadShininess(currentElementName.toString()); - } - m_pStreamReader->readNext(); - } - checkForXmlError("Error occur while loading element : " + elementName); -} - -// load common color or texture -void GLC_ColladaToWorld::loadCommonColorOrTexture(const QString& name) -{ - //qDebug() << "GLC_ColladaToWorld::loadCommonColorOrTexture " << name; - Q_ASSERT(NULL != m_pCurrentMaterial); - - while (endElementNotReached(m_pStreamReader, name)) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if (currentElementName == "color") - { - if (name == "emission") m_pCurrentMaterial->setEmissiveColor(readXmlColor()); - else if (name == "ambient") m_pCurrentMaterial->setAmbientColor(readXmlColor()); - else if (name == "diffuse") m_pCurrentMaterial->setDiffuseColor(readXmlColor()); - else if (name == "specular") m_pCurrentMaterial->setSpecularColor(readXmlColor()); - } - else if (currentElementName == "texture") - { - //qDebug() << "Load texture " << name; - const QString sid = m_CurrentId + "::" + readAttribute("texture", true); - m_TextureToMaterialHash.insert(sid, m_pCurrentMaterial); - } - } - m_pStreamReader->readNext(); - } - checkForXmlError("Error occur while loading element : " + name); -} - -// Load transparent -void GLC_ColladaToWorld::loadTransparent() -{ - const QString opaque= readAttribute("opaque", false); - if (opaque == "RGB_ZERO") m_TransparentIsRgbZero= true; - else m_TransparentIsRgbZero= false; -} - -// Load transparency -void GLC_ColladaToWorld::loadTransparency(const QString& name) -{ - //qDebug() << "GLC_ColladaToWorld::loadTransparency"; - Q_ASSERT(NULL != m_pCurrentMaterial); - while (endElementNotReached(m_pStreamReader, name)) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if (currentElementName == "float") - { - bool stringToFloatOk= false; - const QString alphaString= getContent("float"); - float alpha; - if (m_TransparentIsRgbZero) - { - alpha= alphaString.toFloat(&stringToFloatOk); - } - else - { - alpha= 1.0f - alphaString.toFloat(&stringToFloatOk); - } - // A material mustn't be invisible (no sense) - if (qFuzzyCompare(alpha, 0.0f)) alpha= 1.0f; - - m_pCurrentMaterial->setOpacity(alpha); - if (!stringToFloatOk) throwException("Error while trying to convert :" + alphaString + " to float"); - } - } - m_pStreamReader->readNext(); - } - checkForXmlError("Error occur while loading element : " + name); -} - -// Load shininess -void GLC_ColladaToWorld::loadShininess(const QString& name) -{ - //qDebug() << "GLC_ColladaToWorld::loadShininess"; - Q_ASSERT(NULL != m_pCurrentMaterial); - while (endElementNotReached(m_pStreamReader, name)) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if (currentElementName == "float") - { - bool stringToFloatOk= false; - const QString shininessString= getContent("float"); - const float shininess= shininessString.toFloat(&stringToFloatOk); - if (!stringToFloatOk) - { - QStringList stringList(m_FileName); - stringList.append("Error while trying to convert :" + shininessString + " to float"); - GLC_ErrorLog::addError(stringList); - } - else m_pCurrentMaterial->setShininess(shininess); - } - } - m_pStreamReader->readNext(); - } - checkForXmlError("Error occur while loading element : " + name); -} - -// Read a xml Color -QColor GLC_ColladaToWorld::readXmlColor() -{ - //qDebug() << "GLC_ColladaToWorld::readXmlColor()"; - QColor resultColor; - - QString colorString= getContent("color"); - QStringList colors= colorString.split(' '); - if(colors.size() == 4) - { - bool okRed, okGreen, okBlue, okAlpha; - const float red= colors.at(0).toFloat(&okRed); - const float green= colors.at(1).toFloat(&okGreen); - const float blue= colors.at(2).toFloat(&okBlue); - const float alpha= colors.at(3).toFloat(&okAlpha); - if (okRed && okGreen && okBlue && okAlpha) - { - resultColor.setRedF(red); - resultColor.setGreenF(green); - resultColor.setBlueF(blue); - resultColor.setAlphaF(alpha); - } - else - { - QString info= "Error occur while reading xml color : " + colorString; - qDebug() << info << " " << m_FileName; - GLC_FileFormatException fileFormatException(info, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - } - else - { - QString info= "Error occur while reading xml color : " + colorString; - qDebug() << info << " " << m_FileName; - GLC_FileFormatException fileFormatException(info, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - - return resultColor; -} - -// Load library_geometries element -void GLC_ColladaToWorld::loadLibraryGeometries() -{ - while (endElementNotReached(m_pStreamReader, "library_geometries")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if (currentElementName == "geometry") loadGeometry(); - } - - m_pStreamReader->readNext(); - - updateProgressBar(); - } - checkForXmlError("Error occur while loading element : library_geometries"); -} - -// Load an geometry element -void GLC_ColladaToWorld::loadGeometry() -{ - delete m_pMeshInfo; - m_pMeshInfo= new MeshInfo(); - m_pMeshInfo->m_pMesh= new GLC_Mesh; - - const QString id= readAttribute("id", false); - m_CurrentId= id; - if (!id.isEmpty()) - { - m_pMeshInfo->m_pMesh->setName(id); - //qDebug() << "Loading geometry : " << id; - } - else - { - qDebug() << "Geometry without id found !!"; - } - - while (endElementNotReached(m_pStreamReader, "geometry")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if (currentElementName == "mesh") loadMesh(); - } - - m_pStreamReader->readNext(); - } - checkForXmlError("Error occur while loading element : geometry"); - - // Add the current mesh info to the geometry hash - if (!id.isEmpty()) - { - m_GeometryHash.insert(id, m_pMeshInfo); - m_pMeshInfo= NULL; - } -} - -// Load a mesh -void GLC_ColladaToWorld::loadMesh() -{ - while (endElementNotReached(m_pStreamReader, "mesh")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if (currentElementName == "source") loadVertexBulkData(); - else if (currentElementName == "vertices") loadVertices(); - else if (currentElementName == "polylist") loadPolylist(); - else if (currentElementName == "polygons") loadPolygons(); - else if (currentElementName == "triangles") loadTriangles(); - //else if (currentElementName == "trifans") loadTriFans(); - //else if (currentElementName == "tristrips") loadTriStrip(); - } - - m_pStreamReader->readNext(); - } - checkForXmlError("Error occur while loading element : mesh"); -} - -// Load Vertex bulk data -void GLC_ColladaToWorld::loadVertexBulkData() -{ - //qDebug() << "GLC_ColladaToWorld::loadVertexBulkData()"; - // load Vertex Bulk data id - m_CurrentId= readAttribute("id", true); - //qDebug() << "id=" << m_CurrentId; - QList vertices; - - while (endElementNotReached(m_pStreamReader, "source")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if ((currentElementName == "float_array")) - { - int count= readAttribute("count", true).toInt(); - QString array= getContent("float_array"); - QStringList list= array.split(' '); - // Check the array size - if (count != list.size()) throwException("float_array size not match"); - - for (int i= 0; i < count; ++i) - { - vertices.append(list.at(i).toFloat()); - } - } - else if (currentElementName == "technique_common") loadTechniqueCommon(); - } - - m_pStreamReader->readNext(); - } - checkForXmlError("Error occur while loading element : source"); - m_BulkDataHash.insert(m_CurrentId, vertices); - - updateProgressBar(); -} - -void GLC_ColladaToWorld::loadTechniqueCommon() -{ - //qDebug() << "GLC_ColladaToWorld::loadTechniqueCommon()"; - - while (endElementNotReached(m_pStreamReader, "technique_common")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if ((currentElementName == "accessor")) loadAccessor(); - } - - m_pStreamReader->readNext(); - } - checkForXmlError("Error occur while loading element : technique_common"); - -} - -void GLC_ColladaToWorld::loadAccessor() -{ - //qDebug() << "GLC_ColladaToWorld::loadAccessor()"; - Accessor accessor; - const QString count= readAttribute("count", true); - const QString offset= readAttribute("offset", false); - const QString stride= readAttribute("stride", false); - bool conversionOk; - accessor.m_Count= count.toUInt(&conversionOk); - if (conversionOk) - { - if (!offset.isEmpty()) - { - accessor.m_Offset= offset.toUInt(&conversionOk); - } - if (!stride.isEmpty()) - { - accessor.m_Stride= stride.toUInt(&conversionOk); - } - } - - while (endElementNotReached(m_pStreamReader, "accessor")) - { - m_pStreamReader->readNext(); - } - checkForXmlError("Error occur while loading element : technique_common"); - - m_DataAccessorHash.insert(m_CurrentId, accessor); -} - -// Load attributes and identity of mesh vertices -void GLC_ColladaToWorld::loadVertices() -{ - //qDebug() << "GLC_ColladaToWorld::loadVertices()"; - // load Vertices id - m_CurrentId= readAttribute("id", true); - - goToElement("input"); - const QString source= readAttribute("source", true).remove('#'); - m_VerticesSourceHash.insert(m_CurrentId, source); - checkForXmlError("Error occur while loading element : vertices"); -} - -// Load polygons or polylist -void GLC_ColladaToWorld::loadPolylist() -{ - //qDebug() << "GLC_ColladaToWorld::loadPolylist()"; - // The number of polygon - const int polygonCount= readAttribute("count", true).toInt(); - - // The material id - const QString materialId= readAttribute("material", false); - - // Offsets and data source list - QList inputDataList; - - // Polygon number of vertice list - QList vcountList; - - // Polygon index list - QList polyIndexList; - - while (endElementNotReached(m_pStreamReader, "polylist")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if ((currentElementName == "input") && vcountList.isEmpty()) - { - InputData currentInput; - // Get input data offset - currentInput.m_Offset= readAttribute("offset", true).toInt(); - // Get input data semantic - const QString semantic= readAttribute("semantic", true); - if (semantic == "VERTEX") currentInput.m_Semantic= VERTEX; - else if (semantic == "NORMAL") currentInput.m_Semantic= NORMAL; - else if (semantic == "TEXCOORD") currentInput.m_Semantic= TEXCOORD; - else throwException("Source semantic :" + semantic + "Not supported"); - // Get input data source id - currentInput.m_Source= readAttribute("source", true).remove('#'); - - // Bypasss vertices indirection - if (m_VerticesSourceHash.contains(currentInput.m_Source)) - { - currentInput.m_Source= m_VerticesSourceHash.value(currentInput.m_Source); - } - inputDataList.append(currentInput); - } - else if ((currentElementName == "vcount") && (inputDataList.size() > 0)) - { - QString vcountString= getContent("vcount"); - QStringList vcountStringList= vcountString.split(' '); - if (vcountStringList.size() != polygonCount) throwException("vcount size not match"); - bool toIntOK; - for (int i= 0; i < polygonCount; ++i) - { - vcountList.append(vcountStringList.at(i).toInt(&toIntOK)); - if (!toIntOK) throwException("Unable to convert string :" + vcountStringList.at(i) + " To int"); - } - } - else if ((currentElementName == "p") && !vcountList.isEmpty() && polyIndexList.isEmpty()) - { - { // Fill index List - QString pString= getContent("p"); - QStringList pStringList= pString.split(' '); - bool toIntOK; - const int size= pStringList.size(); - for (int i= 0; i < size; ++i) - { - polyIndexList.append(pStringList.at(i).toInt(&toIntOK)); - if (!toIntOK) throwException("Unable to convert string :" + pStringList.at(i) + " To int"); - } - } - - } - } - m_pStreamReader->readNext(); - } - // Add the polylist to the current mesh - addPolylistToCurrentMesh(inputDataList, vcountList, polyIndexList, materialId); - - updateProgressBar(); -} - -// Load Polygons -void GLC_ColladaToWorld::loadPolygons() -{ - // The material id - const QString materialId= readAttribute("material", false); - - // Offsets and data source list - QList inputDataList; - - // Polygon number of vertice list - QList vcountList; - - // The input number - int inputCount= 0; - // Polygon index list - QList polyIndexList; - while (endElementNotReached(m_pStreamReader, "polygons")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if ((currentElementName == "input") && vcountList.isEmpty()) - { - ++inputCount; - InputData currentInput; - // Get input data offset - currentInput.m_Offset= readAttribute("offset", true).toInt(); - // Get input data semantic - const QString semantic= readAttribute("semantic", true); - if (semantic == "VERTEX") currentInput.m_Semantic= VERTEX; - else if (semantic == "NORMAL") currentInput.m_Semantic= NORMAL; - else if (semantic == "TEXCOORD") currentInput.m_Semantic= TEXCOORD; - else throwException("Source semantic :" + semantic + "Not supported"); - // Get input data source id - currentInput.m_Source= readAttribute("source", true).remove('#'); - - // Bypasss vertices indirection - if (m_VerticesSourceHash.contains(currentInput.m_Source)) - { - currentInput.m_Source= m_VerticesSourceHash.value(currentInput.m_Source); - } - inputDataList.append(currentInput); - } - else if (currentElementName == "p") - { - { // Fill index List - QString pString= getContent("p"); - QStringList pStringList= pString.split(' '); - bool toIntOK; - const int size= pStringList.size(); - for (int i= 0; i < size; ++i) - { - polyIndexList.append(pStringList.at(i).toInt(&toIntOK)); - if (!toIntOK) throwException("Unable to convert string :" + pStringList.at(i) + " To int"); - } - // Add the polygon size in vcountList - vcountList.append(size / inputCount); - } - } - } - m_pStreamReader->readNext(); - } - // Add the polylist to the current mesh - addPolylistToCurrentMesh(inputDataList, vcountList, polyIndexList, materialId); - - updateProgressBar(); -} - -// Add the polylist to the current mesh -void GLC_ColladaToWorld::addPolylistToCurrentMesh(const QList& inputDataList, const QList& vcountList, const QList& polyIndexList, const QString& materialId) -{ - //qDebug() << "GLC_ColladaToWorld::addPolylistToCurrentMesh"; - - const int polygonCount= vcountList.size(); - const int inputDataCount= inputDataList.size(); - const int polyIndexCount= polyIndexList.size(); - - // Flag to know if the polylist has normal - bool hasNormals= false; - bool hasTexture= false; - // Check the existance of data source - for (int dataIndex= 0; dataIndex < inputDataCount; ++dataIndex) - { - const QString source= inputDataList.at(dataIndex).m_Source; - if ( !m_BulkDataHash.contains(source)) - { - throwException(" Source : " + source + " Not found"); - } - if (inputDataList.at(dataIndex).m_Semantic == NORMAL) hasNormals= true; - if (inputDataList.at(dataIndex).m_Semantic == TEXCOORD) hasTexture= true; - } - - int maxOffset= 0; - for (int i= 0; i < inputDataCount; ++i) - { - if (inputDataList.at(i).m_Offset > maxOffset) - { - maxOffset= inputDataList.at(i).m_Offset; - } - } - //qDebug() << " Max Offset :" << maxOffset; - - // the polygonIndex of the polylist - QList polygonIndex; - - // Fill the mapping, bulk data and index list of the current mesh info - for (int i= 0; i < polyIndexCount; i+= maxOffset + 1) - { - // Create and set the current vertice index - ColladaVertice currentVertice; - for (int dataIndex= 0; dataIndex < inputDataCount; ++dataIndex) - { - currentVertice.m_Values[inputDataList.at(dataIndex).m_Semantic]= polyIndexList.at(i + inputDataList.at(dataIndex).m_Offset); - } - - if (m_pMeshInfo->m_Mapping.contains(currentVertice)) - { - // Add the the index to the polygon index - polygonIndex.append(m_pMeshInfo->m_Mapping.value(currentVertice)); - } - else - { - // Add the current vertice to the current mesh info mapping hash table and increment the freeIndex - m_pMeshInfo->m_Mapping.insert(currentVertice, (m_pMeshInfo->m_FreeIndex)++); - // Add the the index to the polygon index - polygonIndex.append(m_pMeshInfo->m_Mapping.value(currentVertice)); - - // Add the bulk data associated to the current vertice to the current mesh info - for (int dataIndex= 0; dataIndex < inputDataCount; ++dataIndex) - { - // The current input data - InputData currentInputData= inputDataList.at(dataIndex); - // QHash iterator on the right QList - BulkDataHash::const_iterator iBulkHash= m_BulkDataHash.find(currentInputData.m_Source); - int stride; - if (m_DataAccessorHash.contains(currentInputData.m_Source)) - { - stride= m_DataAccessorHash.value(currentInputData.m_Source).m_Stride; - } - else if (currentInputData.m_Semantic != TEXCOORD) stride= 3; else stride= 2; - // Firts value - m_pMeshInfo->m_Datas[currentInputData.m_Semantic].append(iBulkHash.value().at(polyIndexList.at(i + currentInputData.m_Offset) * stride)); - // Second value - m_pMeshInfo->m_Datas[currentInputData.m_Semantic].append(iBulkHash.value().at(polyIndexList.at(i + currentInputData.m_Offset) * stride + 1)); - // Fird value - if (currentInputData.m_Semantic != TEXCOORD) - { - m_pMeshInfo->m_Datas[currentInputData.m_Semantic].append(iBulkHash.value().at(polyIndexList.at(i + currentInputData.m_Offset) * stride + 2)); - } - } - // Avoid problem wich occur with mesh containing materials with and without texture - if (!hasTexture) - { - m_pMeshInfo->m_Datas[TEXCOORD].append(0.0); - } - - } - } - - // Save mesh info index offset - const int indexOffset= m_pMeshInfo->m_Index.size(); - // Triangulate the polygons of the polylist - // Input polygon index must start from 0 and succesive : (0 1 2 3 4) - QList onePolygonIndex; - for (int i= 0; i < polygonCount; ++i) - { - const int polygonSize= vcountList.at(i); - Q_ASSERT(polygonSize > 2); - for (int i= 0; i < polygonSize; ++i) - { - onePolygonIndex.append(polygonIndex.takeFirst()); - } - // Triangulate the current polygon if the polygon as more than 3 vertice - if (polygonSize > 3) - { - glc::triangulatePolygon(&onePolygonIndex, m_pMeshInfo->m_Datas.at(VERTEX)); - } - // Add index to the mesh info - //Q_ASSERT(not onePolygonIndex.isEmpty()); - if (!onePolygonIndex.isEmpty()) - { - m_pMeshInfo->m_Index.append(onePolygonIndex); - } - else - { - QStringList stringList(m_FileName); - stringList.append("Unable to triangulate a polygon of " + m_pMeshInfo->m_pMesh->name()); - GLC_ErrorLog::addError(stringList); - } - onePolygonIndex.clear(); - } - - // Check if normal computation is needed - if (!hasNormals) - { - qDebug() << "Compute Normals with offset " << indexOffset; - computeNormalOfCurrentPrimitiveOfCurrentMesh(indexOffset); - } - - // Add material the current mesh info - MatOffsetSize matInfo; - matInfo.m_Offset= indexOffset; - matInfo.m_size= m_pMeshInfo->m_Index.size() - indexOffset; - m_pMeshInfo->m_Materials.insert(materialId, matInfo); - -} -// Compute Normals for the current primitive element of the current mesh -void GLC_ColladaToWorld::computeNormalOfCurrentPrimitiveOfCurrentMesh(int indexOffset) -{ - const QList* pData= &(m_pMeshInfo->m_Datas.at(VERTEX)); - // Fill the list of normal - QList* pNormal= &(m_pMeshInfo->m_Datas[NORMAL]); - const int normalOffset= pNormal->size(); - const int normalCount= pData->size() - normalOffset; - for (int i= 0; i < normalCount; ++i) - { - pNormal->append(0.0f); - } - // Compute the normals and add them to the current mesh info - const int size= m_pMeshInfo->m_Index.size() - indexOffset; - double xn, yn, zn; - - - for (int i= indexOffset; i < size; i+=3) - { - // Vertex 1 - xn= pData->at(m_pMeshInfo->m_Index.at(i) * 3); - yn= pData->at(m_pMeshInfo->m_Index.at(i) * 3 + 1); - zn= pData->at(m_pMeshInfo->m_Index.at(i) * 3 + 2); - const GLC_Vector3d vect1(xn, yn, zn); - - // Vertex 2 - xn= pData->at(m_pMeshInfo->m_Index.at(i + 1) * 3); - yn= pData->at(m_pMeshInfo->m_Index.at(i + 1) * 3 + 1); - zn= pData->at(m_pMeshInfo->m_Index.at(i + 1) * 3 + 2); - const GLC_Vector3d vect2(xn, yn, zn); - - // Vertex 3 - xn= pData->at(m_pMeshInfo->m_Index.at(i + 2) * 3); - yn= pData->at(m_pMeshInfo->m_Index.at(i + 2) * 3 + 1); - zn= pData->at(m_pMeshInfo->m_Index.at(i + 2) * 3 + 2); - const GLC_Vector3d vect3(xn, yn, zn); - - const GLC_Vector3d edge1(vect3 - vect2); - const GLC_Vector3d edge2(vect1 - vect2); - - GLC_Vector3d normal(edge1 ^ edge2); - normal.normalize(); - - GLC_Vector3df curNormal= normal.toVector3df(); - for (int curVertex= 0; curVertex < 3; ++curVertex) - { - (*pNormal)[m_pMeshInfo->m_Index.at(i + curVertex) * 3]= curNormal.x(); - (*pNormal)[m_pMeshInfo->m_Index.at(i + curVertex) * 3 + 1]= curNormal.y(); - (*pNormal)[m_pMeshInfo->m_Index.at(i + curVertex) * 3 + 2]= curNormal.z(); - } - } -} - -// Load triangles -void GLC_ColladaToWorld::loadTriangles() -{ - //qDebug() << "GLC_ColladaToWorld::loadTriangles()"; - // The material id - const QString materialId= readAttribute("material", false); - - // Offsets and data source list - QList inputDataList; - - // triangle index list - QList trianglesIndexList; - - while (endElementNotReached(m_pStreamReader, "triangles")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if ((currentElementName == "input") && trianglesIndexList.isEmpty()) - { - InputData currentInput; - // Get input data offset - currentInput.m_Offset= readAttribute("offset", true).toInt(); - // Get input data semantic - const QString semantic= readAttribute("semantic", true); - if (semantic == "VERTEX") currentInput.m_Semantic= VERTEX; - else if (semantic == "NORMAL") currentInput.m_Semantic= NORMAL; - else if (semantic == "TEXCOORD") currentInput.m_Semantic= TEXCOORD; - else throwException("Source semantic :" + semantic + "Not supported"); - // Get input data source id - currentInput.m_Source= readAttribute("source", true).remove('#'); - - // Bypasss vertices indirection - if (m_VerticesSourceHash.contains(currentInput.m_Source)) - { - currentInput.m_Source= m_VerticesSourceHash.value(currentInput.m_Source); - } - inputDataList.append(currentInput); - } - else if ((currentElementName == "p") && trianglesIndexList.isEmpty()) - { - { // Fill index List - QString pString= getContent("p"); - QStringList pStringList= pString.split(' '); - bool toIntOK; - const int size= pStringList.size(); - for (int i= 0; i < size; ++i) - { - trianglesIndexList.append(pStringList.at(i).toInt(&toIntOK)); - if (!toIntOK) throwException("Unable to convert string :" + pStringList.at(i) + " To int"); - } - } - - } - } - m_pStreamReader->readNext(); - } - - // Add the polylist to the current mesh - addTrianglesToCurrentMesh(inputDataList, trianglesIndexList, materialId); - - updateProgressBar(); - -} - -// Add the triangles to current mesh -void GLC_ColladaToWorld::addTrianglesToCurrentMesh(const QList& inputDataList, const QList& trianglesIndexList, const QString& materialId) -{ - //qDebug() << "GLC_ColladaToWorld::addTrianglesToCurrentMesh"; - - const int inputDataCount= inputDataList.size(); - const int trianglesIndexCount= trianglesIndexList.size(); - - // Flag to know if the polylist has normal - bool hasNormals= false; - bool hasTexture= false; - - // Check the existance of data source - for (int dataIndex= 0; dataIndex < inputDataCount; ++dataIndex) - { - const QString source= inputDataList.at(dataIndex).m_Source; - if ( !m_BulkDataHash.contains(source)) - { - throwException(" Source : " + source + " Not found"); - } - if (inputDataList.at(dataIndex).m_Semantic == NORMAL) hasNormals= true; - if (inputDataList.at(dataIndex).m_Semantic == TEXCOORD) hasTexture= true; - } - - int maxOffset= 0; - for (int i= 0; i < inputDataCount; ++i) - { - if (inputDataList.at(i).m_Offset > maxOffset) - { - maxOffset= inputDataList.at(i).m_Offset; - } - } - //qDebug() << " Triangles Max Offset :" << maxOffset; - - // the polygonIndex of the polylist - QList trianglesIndex; - - // Fill the mapping, bulk data and index list of the current mesh info - for (int i= 0; i < trianglesIndexCount; i+= maxOffset + 1) - { - // Create and set the current vertice index - ColladaVertice currentVertice; - for (int dataIndex= 0; dataIndex < inputDataCount; ++dataIndex) - { - currentVertice.m_Values[inputDataList.at(dataIndex).m_Semantic]= trianglesIndexList.at(i + inputDataList.at(dataIndex).m_Offset); - } - - if (m_pMeshInfo->m_Mapping.contains(currentVertice)) - { - // Add the the index to the triangles index - trianglesIndex.append(m_pMeshInfo->m_Mapping.value(currentVertice)); - } - else - { - // Add the current vertice to the current mesh info mapping hash table and increment the freeIndex - m_pMeshInfo->m_Mapping.insert(currentVertice, (m_pMeshInfo->m_FreeIndex)++); - // Add the the index to the triangles index - trianglesIndex.append(m_pMeshInfo->m_Mapping.value(currentVertice)); - - // Add the bulk data associated to the current vertice to the current mesh info - for (int dataIndex= 0; dataIndex < inputDataCount; ++dataIndex) - { - // The current input data - InputData currentInputData= inputDataList.at(dataIndex); - // QHash iterator on the right QList - BulkDataHash::const_iterator iBulkHash= m_BulkDataHash.find(currentInputData.m_Source); - int stride; - if (m_DataAccessorHash.contains(currentInputData.m_Source)) - { - stride= m_DataAccessorHash.value(currentInputData.m_Source).m_Stride; - } - else if (currentInputData.m_Semantic != TEXCOORD) stride= 3; else stride= 2; - // Firts value - m_pMeshInfo->m_Datas[currentInputData.m_Semantic].append(iBulkHash.value().at(trianglesIndexList.at(i + currentInputData.m_Offset) * stride)); - // Second value - m_pMeshInfo->m_Datas[currentInputData.m_Semantic].append(iBulkHash.value().at(trianglesIndexList.at(i + currentInputData.m_Offset) * stride + 1)); - // Fird value - if (currentInputData.m_Semantic != TEXCOORD) - { - m_pMeshInfo->m_Datas[currentInputData.m_Semantic].append(iBulkHash.value().at(trianglesIndexList.at(i + currentInputData.m_Offset) * stride + 2)); - } - // Avoid problem wich occur with mesh containing materials with and without texture - if (!hasTexture) - { - m_pMeshInfo->m_Datas[TEXCOORD].append(0.0); - } - } - } - } - - // Save mesh info index offset - const int indexOffset= m_pMeshInfo->m_Index.size(); - - // Add index to the mesh info - m_pMeshInfo->m_Index.append(trianglesIndex); - - // Check if normal computation is needed - if (!hasNormals) - { - computeNormalOfCurrentPrimitiveOfCurrentMesh(indexOffset); - } - - // Add material the current mesh info - MatOffsetSize matInfo; - matInfo.m_Offset= indexOffset; - matInfo.m_size= m_pMeshInfo->m_Index.size() - indexOffset; - m_pMeshInfo->m_Materials.insertMulti(materialId, matInfo); - -} - -// Load the library nodes -void GLC_ColladaToWorld::loadLibraryNodes() -{ - //qDebug() << "GLC_ColladaToWorld::loadLibraryNodes"; - - while (endElementNotReached(m_pStreamReader, "library_nodes")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if ((currentElementName == "node")) - { - GLC_ColladaToWorld::ColladaNode* pNode= loadNode(NULL); - if (NULL != pNode) - { - - } - } - } - - updateProgressBar(); - - m_pStreamReader->readNext(); - } - checkForXmlError("Error occur while loading element : library_nodes"); -} - -// Load the library controllers -void GLC_ColladaToWorld::loadLibraryContollers() -{ - //qDebug() << "GLC_ColladaToWorld::loadLibraryContollers"; - - while (endElementNotReached(m_pStreamReader, "library_controllers")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if ((currentElementName == "controller")) loadController(); - } - - updateProgressBar(); - - m_pStreamReader->readNext(); - } - checkForXmlError("Error occur while loading element : library_controllers"); -} - -// Load library_visual_scenes element -void GLC_ColladaToWorld::loadVisualScenes() -{ - //qDebug() << "GLC_ColladaToWorld::loadVisualScenes"; - // The element library visual scene must contains a visual scene element - goToElement("visual_scene"); - - while (endElementNotReached(m_pStreamReader, "visual_scene")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if (currentElementName == "node") - { - GLC_ColladaToWorld::ColladaNode* pNode= loadNode(NULL); - if (NULL != pNode) - { - m_TopLevelColladaNode.append(pNode); - } - } - } - - updateProgressBar(); - - m_pStreamReader->readNext(); - } - checkForXmlError("Error occur while loading element : visual_scene"); -} - -// Load an instance geometry -void GLC_ColladaToWorld::loadInstanceGeometry(ColladaNode* pNode) -{ - //qDebug() << "GLC_ColladaToWorld::loadInstanceGeometry"; - - const QString url= readAttribute("url", true).remove('#'); - pNode->m_InstanceGeometryIDs.append(url); - - while (endElementNotReached(m_pStreamReader, "instance_geometry")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if ((currentElementName == "instance_material")) - { - const QString target= readAttribute("target", true).remove('#'); - const QString symbol= readAttribute("symbol", true); - m_MaterialInstanceMap.insert(symbol, target); - } - - } - m_pStreamReader->readNext(); - } - checkForXmlError("Error occur while loading element : instance_geometry"); -} - -// Load an instance of node -void GLC_ColladaToWorld::loadInstanceNode(ColladaNode* pNode) -{ - //qDebug() << "GLC_ColladaToWorld::loadInstanceNode"; - const QString url= readAttribute("url", true).remove('#'); - pNode->m_InstanceOffNodeIds.append(url); -} - -// Load an instance Controller -void GLC_ColladaToWorld::loadInstanceController(ColladaNode* pNode) -{ - const QString url= readAttribute("url", true).remove('#'); - pNode->m_InstanceOffNodeIds.append(url); - - while (endElementNotReached(m_pStreamReader, "instance_controller")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if ((currentElementName == "instance_material")) - { - const QString target= readAttribute("target", true).remove('#'); - const QString symbol= readAttribute("symbol", true); - m_MaterialInstanceMap.insert(symbol, target); - } - } - m_pStreamReader->readNext(); - } - checkForXmlError("Error occur while loading element : instance_controller"); -} - -// Load a collada controller node -void GLC_ColladaToWorld::loadController() -{ - - m_CurrentId= readAttribute("id", true); - while (endElementNotReached(m_pStreamReader, "controller")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - if ((currentElementName == "skin")) - { - const QString source= readAttribute("source", true).remove('#'); - ColladaNode* pNode= new ColladaNode(m_CurrentId, NULL); - pNode->m_InstanceGeometryIDs.append(source); - m_ColladaNodeHash.insert(m_CurrentId, pNode); - } - } - m_pStreamReader->readNext(); - } - checkForXmlError("Error occur while loading element : controller"); - -} - -// Load a Collada Node element -GLC_ColladaToWorld::ColladaNode* GLC_ColladaToWorld::loadNode(ColladaNode* pParent) -{ - //qDebug() << "GLC_ColladaToWorld::loadNode"; - - - QString id= readAttribute("id", false); - if (id.isEmpty()) - { - id= readAttribute("name", false); - } - if (id.isEmpty()) - { - id= prefixNodeId + QString::number(++currentNodeId); - } - - qint64 currentOffset= m_pStreamReader->characterOffset(); - //qDebug() << "Load Node " << id; - m_CurrentId= id; - // The node - ColladaNode* pNode= new ColladaNode(id, pParent); - // To avoid infinite call - //m_pStreamReader->readNext(); - - while (endElementNotReached(m_pStreamReader, "node")) - { - if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) - { - const QStringRef currentElementName= m_pStreamReader->name(); - - if ((currentElementName == "translate")) translateNode(pNode); - else if ((currentElementName == "scale")) scaleNode(pNode); - else if ((currentElementName == "rotate")) rotateNode(pNode); - else if ((currentElementName == "matrix")) composeMatrixNode(pNode); - else if ((currentElementName == "instance_geometry")) loadInstanceGeometry(pNode); - else if ((currentElementName == "instance_node")) loadInstanceNode(pNode); - else if ((currentElementName == "instance_controller")) loadInstanceController(pNode); - else if ((currentElementName == "node")) - { - if (currentOffset != m_pStreamReader->characterOffset()) - { - QString newId= readAttribute("id", false); - if (newId.isEmpty()) - { - //qDebug() << "Child ReadAttribute name"; - newId= readAttribute("name", false); - } - //qDebug() << "New ID = " << newId; - GLC_ColladaToWorld::ColladaNode* pChildNode= loadNode(pNode); - if (NULL != pNode) - { - //qDebug() << "Add child"; - pNode->m_ChildNodes.append(pChildNode); - } - } - } - else if ((currentElementName == "instance_camera") - || (currentElementName == "instance_light")) - { - // Node type not supported - delete pNode; - pNode= NULL; - } - } - m_pStreamReader->readNext(); - - } - - if (NULL != pNode) - { - // Add the collada node to the collada node hash table - m_ColladaNodeHash.insert(id, pNode); - } - return pNode; -} - - -// Translate the node -void GLC_ColladaToWorld::translateNode(ColladaNode* pNode) -{ - //qDebug() << "Translate Node"; - Q_ASSERT(NULL != pNode); - // Load translation values - QStringList translateStringList= getContent("translate").simplified().split(' '); - // A translation must contains 3 string - const int size= translateStringList.size(); - if (translateStringList.size() != 3) throwException("Translate element must contains 3 floats and it's contains :" + QString::number(translateStringList.size())); - // Convert the string to double - double translate[3]; - bool toFloatOk= false; - for (int i= 0; i < size; ++i) - { - translate[i]= static_cast(translateStringList.at(i).toFloat(&toFloatOk)); - if (!toFloatOk) throwException("The number :" + translateStringList.at(i) + "Is not a float"); - } - // Built the translation matrix - GLC_Matrix4x4 translationMatrix(translate[0], translate[1], translate[2]); - // Update the node matrix - pNode->m_Matrix= pNode->m_Matrix * translationMatrix; -} - -// Scale the node -void GLC_ColladaToWorld::scaleNode(ColladaNode* pNode) -{ - //qDebug() << "Scale Node"; - Q_ASSERT(NULL != pNode); - // Load scale values - QStringList scaleStringList= getContent("scale").simplified().split(' '); - // A scale must contains 3 string - const int size= scaleStringList.size(); - if (scaleStringList.size() != 3) throwException("Scale element must contains 3 floats and it's contains :" + QString::number(scaleStringList.size())); - // Convert the string to double - double scale[3]; - bool toFloatOk= false; - for (int i= 0; i < size; ++i) - { - scale[i]= static_cast(scaleStringList.at(i).toFloat(&toFloatOk)); - if (!toFloatOk) throwException("The number :" + scaleStringList.at(i) + "Is not a float"); - } - // Built the translation matrix - GLC_Matrix4x4 scaleMatrix; - scaleMatrix.setMatScaling(scale[0], scale[1], scale[2]); - scaleMatrix.optimise(); - // Update the node matrix - pNode->m_Matrix= pNode->m_Matrix * scaleMatrix; -} - -// Rotate the node -void GLC_ColladaToWorld::rotateNode(ColladaNode* pNode) -{ - //qDebug() << "Rotate Node"; - Q_ASSERT(NULL != pNode); - // Load rotate values - QStringList rotateStringList= getContent("rotate").simplified().split(' '); - // A rotate must contains 4 string (Axis Vector 3 + Angle) - const int size= rotateStringList.size(); - if (rotateStringList.size() != 4) throwException("Rotate element must contains 4 floats and it's contains :" + QString::number(rotateStringList.size())); - // Convert the string to double - double rotate[4]; - bool toFloatOk= false; - for (int i= 0; i < size; ++i) - { - rotate[i]= static_cast(rotateStringList.at(i).toFloat(&toFloatOk)); - if (!toFloatOk) throwException("The number :" + rotateStringList.at(i) + "Is not a float"); - } - // Rotation vector - GLC_Vector3d rotationAxis(rotate[0], rotate[1], rotate[2]); - // Built the rotation matrix - GLC_Matrix4x4 rotationMatrix(rotationAxis, rotate[3]); - // Update the node matrix - pNode->m_Matrix= pNode->m_Matrix * rotationMatrix; -} - -// Compose Node matrix -void GLC_ColladaToWorld::composeMatrixNode(ColladaNode* pNode) -{ - Q_ASSERT(NULL != pNode); - - // Load matrix values - QStringList matrixStringList= getContent("matrix").simplified().split(' '); - // A rotate must contains 16 string 4 x 4 Matrix - const int size= matrixStringList.size(); - if (size != 16) throwException("Matrix element must contains 16 floats and it's contains :" + QString::number(size)); - // Convert the string to double - double matrix[16]; - bool toFloatOk= false; - for (int i= 0; i < 4; ++i) - { - matrix[i]= static_cast(matrixStringList.at(i * 4).toFloat(&toFloatOk)); - if (!toFloatOk) throwException("The number :" + matrixStringList.at(i) + "Is not a float"); - - matrix[i + 4]= static_cast(matrixStringList.at(i * 4 + 1).toFloat(&toFloatOk)); - if (!toFloatOk) throwException("The number :" + matrixStringList.at(i * 4 + 1) + "Is not a float"); - - matrix[i + 8]= static_cast(matrixStringList.at(i * 4 + 2).toFloat(&toFloatOk)); - if (!toFloatOk) throwException("The number :" + matrixStringList.at(i * 4 + 2) + "Is not a float"); - - matrix[i + 12]= static_cast(matrixStringList.at(i * 4 + 3).toFloat(&toFloatOk)); - if (!toFloatOk) throwException("The number :" + matrixStringList.at(i * 4 + 3) + "Is not a float"); - - } - // Built the matrix - GLC_Matrix4x4 currentMatrix(matrix); - currentMatrix.optimise(); - - // Update the node matrix - pNode->m_Matrix= pNode->m_Matrix * currentMatrix; -} - -// Load scene element -void GLC_ColladaToWorld::loadScene() -{ - //qDebug() << "GLC_ColladaToWorld::loadScene"; - while (endElementNotReached(m_pStreamReader, "scene")) - { - // Nothing to do - m_pStreamReader->readNext(); - } -} - -// Link texture to material -void GLC_ColladaToWorld::linkTexturesToMaterials() -{ - // Iterate throuth the the texture id to material hash - MaterialHash::iterator iMat= m_TextureToMaterialHash.begin(); - while (iMat != m_TextureToMaterialHash.constEnd()) - { - GLC_Material* pCurrentMaterial= iMat.value(); - const QString textureId= iMat.key(); - - // Check that the texture is present - if (m_Sampler2DSurfaceHash.contains(textureId)) - { - const QString surfaceId= m_Sampler2DSurfaceHash.value(textureId); - if (m_SurfaceImageHash.contains(surfaceId)) - { - const QString imageFileId= m_SurfaceImageHash.value(surfaceId); - } - } - if (m_Sampler2DSurfaceHash.contains(textureId) && m_SurfaceImageHash.contains(m_Sampler2DSurfaceHash.value(textureId)) - && m_ImageFileHash.contains(m_SurfaceImageHash.value(m_Sampler2DSurfaceHash.value(textureId)))) - { - const QString imageFileName= m_ImageFileHash.value(m_SurfaceImageHash.value(m_Sampler2DSurfaceHash.value(textureId))); - QString fullImageFileName= QFileInfo(m_FileName).absolutePath() + QDir::separator() + imageFileName; - if (QFileInfo(fullImageFileName).exists()) - { - m_ListOfAttachedFileName << fullImageFileName; - GLC_Texture* pTexture= new GLC_Texture(fullImageFileName); - pCurrentMaterial->setTexture(pTexture); - } - else if (QFileInfo(m_FileName).absolutePath() != QFileInfo(fullImageFileName).absolutePath()) - { - // Trying to find image in collada file path - QString fullImageFileName= QFileInfo(m_FileName).absolutePath() + QDir::separator() + QFileInfo(imageFileName).fileName(); - if (QFileInfo(fullImageFileName).exists()) - { - m_ListOfAttachedFileName << fullImageFileName; - GLC_Texture* pTexture= new GLC_Texture(fullImageFileName); - pCurrentMaterial->setTexture(pTexture); - } - else - { - QStringList stringList(m_FileName); - stringList.append(imageFileName + " Not found"); - GLC_ErrorLog::addError(stringList); - } - } - else - { - QStringList stringList(m_FileName); - stringList.append(imageFileName + " Not found"); - GLC_ErrorLog::addError(stringList); - } - - } - else - { - QStringList stringList(m_FileName); - stringList.append("Texture : " + textureId + " Not found"); - GLC_ErrorLog::addError(stringList); - } - ++iMat; - } -} -// Create mesh and link them to material -void GLC_ColladaToWorld::createMesh() -{ - //qDebug() << "GLC_ColladaToWorld::createMesh()"; - QHash::iterator iMeshInfo= m_GeometryHash.begin(); - while (m_GeometryHash.constEnd() != iMeshInfo) - { - MeshInfo* pCurrentMeshInfo= iMeshInfo.value(); - // Add Bulk Data to the mesh - // Add vertice - pCurrentMeshInfo->m_pMesh->addVertice(pCurrentMeshInfo->m_Datas.at(VERTEX).toVector()); - //qDebug() << "Add " << pCurrentMeshInfo->m_Datas[VERTEX].size() << " Vertice"; - pCurrentMeshInfo->m_Datas[VERTEX].clear(); - - // Add Normal - pCurrentMeshInfo->m_pMesh->addNormals(pCurrentMeshInfo->m_Datas.at(NORMAL).toVector()); - //qDebug() << "Add " << pCurrentMeshInfo->m_Datas[NORMAL].size() << " Normal"; - pCurrentMeshInfo->m_Datas[NORMAL].clear(); - - // Add texel if necessary - //qDebug() << "Add " << pCurrentMeshInfo->m_Datas[TEXCOORD].size() << " texel"; - if (!pCurrentMeshInfo->m_Datas.at(TEXCOORD).isEmpty()) - { - pCurrentMeshInfo->m_pMesh->addTexels(pCurrentMeshInfo->m_Datas.at(TEXCOORD).toVector()); - pCurrentMeshInfo->m_Datas[TEXCOORD].clear(); - } - - // Add face index and material to the mesh - QHash::iterator iMatInfo= pCurrentMeshInfo->m_Materials.begin(); - while (pCurrentMeshInfo->m_Materials.constEnd() != iMatInfo) - { - // Trying to find the material - QString materialId= iMatInfo.key(); - GLC_Material* pCurrentMaterial= NULL; - if (m_MaterialInstanceMap.contains(materialId)) - { - //qDebug() << "Map " << materialId << " to " << m_MaterialInstanceMap.value(materialId); - materialId= m_MaterialInstanceMap.value(materialId); - } - //qDebug() << "MaterialLibHash size : " << m_MaterialLibHash.size(); - if (m_MaterialLibHash.contains(materialId)) - { - materialId= m_MaterialLibHash.value(materialId); - //qDebug() << "Material id " << materialId; - } - if (m_MaterialEffectHash.contains(materialId)) - { - //qDebug() << "Material " << materialId << " find"; - pCurrentMaterial= m_MaterialEffectHash.value(materialId); - Q_ASSERT(NULL != pCurrentMaterial); - } - else - { - QStringList stringList(m_FileName); - stringList.append("Material " + materialId + " Not found"); - GLC_ErrorLog::addError(stringList); - } - - // Create the list of triangles to add to the mesh - const int offset= iMatInfo.value().m_Offset; - const int size= iMatInfo.value().m_size; - //qDebug() << "Offset : " << offset << " size : " << size; - QList triangles; - for (int i= offset; i < (offset + size); ++i) - { - triangles.append(pCurrentMeshInfo->m_Index.at(i)); - } - //qDebug() << "Add " << triangles.size() << " elment to the triangle index"; - // Add the list of triangle to the mesh - if (!triangles.isEmpty()) - { - pCurrentMeshInfo->m_pMesh->addTriangles(pCurrentMaterial, triangles); - } - - ++iMatInfo; - } - pCurrentMeshInfo->m_pMesh->finish(); - GLC_3DRep* pRep= new GLC_3DRep(pCurrentMeshInfo->m_pMesh); - pCurrentMeshInfo->m_pMesh= NULL; - pRep->clean(); - //qDebug() << "Insert Rep : " << iMeshInfo.key(); - m_3DRepHash.insert(iMeshInfo.key(), pRep); - ++iMeshInfo; - } -} - -// Create the scene graph struct -void GLC_ColladaToWorld::createSceneGraph() -{ - const int topLevelNodeCount= m_TopLevelColladaNode.size(); - for (int i= 0; i < topLevelNodeCount; ++i) - { - ColladaNode* pCurrentColladaNode= m_TopLevelColladaNode.at(i); - //qDebug() << "Top level node is : " << pCurrentColladaNode->m_Id; - if (NULL != pCurrentColladaNode) - { - GLC_StructOccurence* pOccurence= createOccurenceFromNode(pCurrentColladaNode); - m_pWorld->rootOccurence()->addChild(pOccurence); - } - } - - // Update position - m_pWorld->rootOccurence()->removeEmptyChildren(); - m_pWorld->rootOccurence()->updateChildrenAbsoluteMatrix(); - -} - -// Create Occurence tree from node tree -GLC_StructOccurence* GLC_ColladaToWorld::createOccurenceFromNode(ColladaNode* pNode) -{ - //qDebug() << "GLC_ColladaToWorld::createOccurenceFromNode"; - Q_ASSERT(NULL != pNode); - GLC_StructInstance* pInstance= NULL; - GLC_StructOccurence* pOccurence= NULL; - if (!pNode->m_InstanceGeometryIDs.isEmpty()) - { - if (m_StructInstanceHash.contains(pNode->m_Id)) - { - pInstance= new GLC_StructInstance(m_StructInstanceHash.value(pNode->m_Id)); - pInstance->move(pNode->m_Matrix); - //qDebug() << "Instance move with this matrix :" << pNode->m_Matrix.toString(); - pOccurence= new GLC_StructOccurence(pInstance); - } - else - { - const int size= pNode->m_InstanceGeometryIDs.size(); - GLC_3DRep* pRep= NULL; - for (int i= 0; i < size; ++i) - { - const QString geometryId= pNode->m_InstanceGeometryIDs.at(i); - if (NULL == pRep) - { - pRep= new GLC_3DRep(*(m_3DRepHash.value(geometryId))); - } - else - { - pRep->merge(m_3DRepHash.value(geometryId)); - } - } - if (NULL != pRep) - { - GLC_StructReference* pStructRef= NULL; - if (pRep->isEmpty()) - { - QStringList stringList(m_FileName); - stringList.append("Empty rep : " + pRep->name()); - GLC_ErrorLog::addError(stringList); - delete pRep; - pRep= NULL; - } - else - { - pStructRef= new GLC_StructReference(pRep); - pInstance= new GLC_StructInstance(pStructRef); - - // Save instance in instance hash Table - m_StructInstanceHash.insert(pNode->m_Id, pInstance); - - pInstance->move(pNode->m_Matrix); - //qDebug() << "Instance move with this matrix :" << pNode->m_Matrix.toString(); - pOccurence= new GLC_StructOccurence(pInstance); - } - - } - else - { - QStringList stringList(m_FileName); - stringList.append("Geometry Id Not found"); - GLC_ErrorLog::addError(stringList); - } - } - } - if (!pNode->m_ChildNodes.isEmpty()) - { - if (NULL == pOccurence) // The node hasn't geometry -> Create an occurence - { - if (m_StructInstanceHash.contains(pNode->m_Id)) - { - pInstance= new GLC_StructInstance(m_StructInstanceHash.value(pNode->m_Id)); - } - else - { - GLC_StructReference* pStructRef= new GLC_StructReference(pNode->m_Id); - pInstance= new GLC_StructInstance(pStructRef); - } - - pInstance->move(pNode->m_Matrix); - pOccurence= new GLC_StructOccurence(pInstance); - } - - const int size= pNode->m_ChildNodes.size(); - for (int i= 0; i < size; ++i) - { - if (NULL != pNode->m_ChildNodes.at(i)) - { - pOccurence->addChild(createOccurenceFromNode(pNode->m_ChildNodes.at(i))); - } - } - } - if (!pNode->m_InstanceOffNodeIds.isEmpty()) - { - if (NULL == pOccurence) // The node hasn't geometry and childs -> Create an occurence - { - if (m_StructInstanceHash.contains(pNode->m_Id)) - { - pInstance= new GLC_StructInstance(m_StructInstanceHash.value(pNode->m_Id)); - } - else - { - GLC_StructReference* pStructRef= new GLC_StructReference(pNode->m_Id); - pInstance= new GLC_StructInstance(pStructRef); - } - - pInstance->move(pNode->m_Matrix); - pOccurence= new GLC_StructOccurence(pInstance); - } - - const int size= pNode->m_InstanceOffNodeIds.size(); - for (int i= 0; i < size; ++i) - { - if (m_ColladaNodeHash.contains(pNode->m_InstanceOffNodeIds.at(i))) - { - pOccurence->addChild(createOccurenceFromNode(m_ColladaNodeHash.value(pNode->m_InstanceOffNodeIds.at(i)))); - } - else - { - const QString errorMsg= "Instance Node : " + pNode->m_InstanceOffNodeIds.at(i) + "Not Found"; - throwException(errorMsg); - } - } - } - if (NULL == pOccurence) - { - if (m_StructInstanceHash.contains(pNode->m_Id)) - { - pInstance= new GLC_StructInstance(m_StructInstanceHash.value(pNode->m_Id)); - } - else - { - GLC_StructReference* pStructRef= new GLC_StructReference(pNode->m_Id); - pInstance= new GLC_StructInstance(pStructRef); - } - - pInstance->move(pNode->m_Matrix); - pOccurence= new GLC_StructOccurence(pInstance); - } - - return pOccurence; -} - -// Update progress bar -void GLC_ColladaToWorld::updateProgressBar() -{ - qint64 currentOffset= m_pStreamReader->characterOffset(); - - int currentQuantumValue; - // Progrees bar indicator - currentQuantumValue = static_cast((static_cast(currentOffset) / m_FileSize) * 100); - if (currentQuantumValue > m_CurrentOffset) - { - emit currentQuantum(currentQuantumValue); - m_CurrentOffset= currentQuantumValue; - } - -} diff --git a/ground/gcs/src/libs/glc_lib/io/glc_colladatoworld.h b/ground/gcs/src/libs/glc_lib/io/glc_colladatoworld.h deleted file mode 100644 index 9139305e2..000000000 --- a/ground/gcs/src/libs/glc_lib/io/glc_colladatoworld.h +++ /dev/null @@ -1,455 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_colladatoworld.h interface for the GLC_ColladaToWorld class. - -#ifndef GLC_COLLADATOWORLD_H_ -#define GLC_COLLADATOWORLD_H_ - -#include -#include -#include -#include -#include -#include - -#include "../shading/glc_material.h" -#include "../geometry/glc_mesh.h" -#include "../sceneGraph/glc_structoccurence.h" - -#include "../glc_config.h" - -class GLC_World; -class QGLContext; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_ColladaToWorld -/*! \brief GLC_ColladaToWorld : Create an GLC_World from dae file */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_ColladaToWorld : public QObject -{ -private: - Q_OBJECT - - // The 3 supported semantic - enum Semantic - { // Values are very important ! - VERTEX= 0, - NORMAL= 1, - TEXCOORD= 2 - }; - - // input data info - struct InputData - { - int m_Offset; - QString m_Source; - Semantic m_Semantic; - }; -public: - // Collada Vertice (Position index, Normal index and TexCoord index) - struct ColladaVertice - { - ColladaVertice() - : m_Values(3) - { - m_Values[0]= 0; - m_Values[1]= 0; - m_Values[2]= 0; - } - - QVector m_Values; - }; -private: - - // Material assignement - struct MatOffsetSize - { - int m_Offset; - int m_size; - }; - - // Accessor a source data (bulk) - struct Accessor - { - Accessor() - : m_Count(0) - , m_Offset(0) - , m_Stride(1) - {} - unsigned int m_Count; - unsigned int m_Offset; - unsigned int m_Stride; - }; - - // The loading mesh info - struct MeshInfo - { - MeshInfo() - : m_pMesh(NULL) - , m_Datas(3) - , m_Mapping() - , m_Index() - , m_FreeIndex(0) - {} - - ~MeshInfo() {delete m_pMesh;} - // Mesh of the mesh info - GLC_Mesh* m_pMesh; - // Bulk data vector (Position, normal, texel) - QVector > m_Datas; - // Mapping between collada vertice and index - QHash m_Mapping; - // Triangle index - IndexList m_Index; - // Next index Position - GLuint m_FreeIndex; - // QHash containing material id and associated offset and size - QHash m_Materials; - }; - - // The collada Node - struct ColladaNode - { - ColladaNode(const QString id, ColladaNode* pParent) - : m_Id(id) - , m_Matrix() - , m_InstanceGeometryIDs() - , m_InstanceOffNodeIds() - , m_ChildNodes() - , m_pParent(pParent) - {} - // Destrucot not needed - // The node id - QString m_Id; - // Position matrix - GLC_Matrix4x4 m_Matrix; - // Instance geometry id - QList m_InstanceGeometryIDs; - // Instance off another node - QList m_InstanceOffNodeIds; - // Child Node - QList m_ChildNodes; - // Parent Node - ColladaNode* m_pParent; - }; - - typedef QHash MaterialHash; - typedef QHash > BulkDataHash; - typedef QHash DataAccessorHash; -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Default constructor - GLC_ColladaToWorld(); - - //! Destructor - virtual ~GLC_ColladaToWorld(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! @name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Create an GLC_World from an input Collada File - GLC_World* CreateWorldFromCollada(QFile &); - - //! Get the list of attached files - inline QStringList listOfAttachedFileName() const - {return m_ListOfAttachedFileName.toList();} - -//@} - -////////////////////////////////////////////////////////////////////// -// Qt Signals -////////////////////////////////////////////////////////////////////// - signals: - void currentQuantum(int); - -////////////////////////////////////////////////////////////////////// -/*! @name Private services functions */ -//@{ -////////////////////////////////////////////////////////////////////// -private: - //! Go to an Element of a xml - void goToElement(const QString&); - - //! Go to the end Element of a xml - void goToEndElement(const QString&); - - // Return the content of an element - QString getContent(const QString&); - - //! Read the specified attribute - QString readAttribute(const QString&, bool required= false); - - //! Check for XML error - //! Throw ecxeption if error occur - void checkForXmlError(const QString&); - - //! Throw an exception with the specified text - void throwException(const QString&); - - //! Clear memmory - void clear(); - - //! Load library_images element - void loadLibraryImage(); - - //! Load image element - void loadImage(); - - //! Load library_materials element - void loadLibraryMaterials(); - - //! Load a material - void loadMaterial(); - - //! Load library_effects element - void loadLibraryEffects(); - - //! Load an effect - void loadEffect(); - - //! Load profile_COMMON - void loadProfileCommon(); - - //! Load a new param - void loadNewParam(); - - //! Load a surface - void loadSurface(const QString&); - - //! Load Sampler 2D - void loadSampler2D(const QString&); - - //! Load technique - void loadTechnique(); - - //! load material technique - void loadMaterialTechnique(const QString&); - - //! load common color or texture - void loadCommonColorOrTexture(const QString&); - - //! Load transparent - void loadTransparent(); - - //! Load transparency - void loadTransparency(const QString&); - - //! Load shininess - void loadShininess(const QString&); - - //! Read a xml Color - QColor readXmlColor(); - - //! Load library_geometries element - void loadLibraryGeometries(); - - //! Load an geometry element - void loadGeometry(); - - //! Load a mesh - void loadMesh(); - - //! Load Vertex bulk data - void loadVertexBulkData(); - - //! Load Technique Common - void loadTechniqueCommon(); - - //! Load Accessor - void loadAccessor(); - - //! Load attributes and identity of mesh vertices - void loadVertices(); - - //! Load polylist - void loadPolylist(); - - //! Load Polygons - void loadPolygons(); - - //! Add the polylist to the current mesh - void addPolylistToCurrentMesh(const QList&, const QList&, const QList&, const QString&); - - //! Compute Normals for the current primitive element of the current mesh from the specified offset - void computeNormalOfCurrentPrimitiveOfCurrentMesh(int offset); - - //! Load triangles - void loadTriangles(); - - //! Add the triangles to current mesh - void addTrianglesToCurrentMesh(const QList&, const QList&, const QString&); - - //! Load the library nodes - void loadLibraryNodes(); - - //! Load the library controllers - void loadLibraryContollers(); - - //! Load library_visual_scenes element - void loadVisualScenes(); - - //! Load an instance geometry - void loadInstanceGeometry(ColladaNode*); - - //! Load an instance geometry - void loadInstanceNode(ColladaNode*); - - //! Load an instance Controller - void loadInstanceController(ColladaNode*); - - //! Load a collada controller node - void loadController(); - - //! Load a Collada Node element and return it - ColladaNode* loadNode(ColladaNode*); - - //! Translate the node - void translateNode(ColladaNode*); - - //! Scale the node - void scaleNode(ColladaNode*); - - //! Rotate the node - void rotateNode(ColladaNode*); - - //! Compose Node matrix - void composeMatrixNode(ColladaNode*); - - //! Load scene element - void loadScene(); - - //! Link texture to material - void linkTexturesToMaterials(); - - //! Create mesh and link them to material - void createMesh(); - - //! Create the scene graph struct - void createSceneGraph(); - - //! Create Occurence tree from node tree - GLC_StructOccurence* createOccurenceFromNode(ColladaNode*); - - //! Update progress bar - void updateProgressBar(); - - - -//@} -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - //! The world to built - GLC_World* m_pWorld; - - //! Xml Reader - QXmlStreamReader* m_pStreamReader; - - //! The collada fileName - QString m_FileName; - - //! The collada file - QFile* m_pFile; - - //! Map image id to image file name - QHash m_ImageFileHash; - - //! Map materialInstance to material - QHash m_MaterialLibHash; - - //! Map surface sid to image id - QHash m_SurfaceImageHash; - - //! Map sampler2D sid to surface sid - QHash m_Sampler2DSurfaceHash; - - //! Material Effect hash table - MaterialHash m_MaterialEffectHash; - - //! The current material - GLC_Material* m_pCurrentMaterial; - - //! Texture to material link - MaterialHash m_TextureToMaterialHash; - - //! Bulk data hash table - BulkDataHash m_BulkDataHash; - - //! Data accessor hash - DataAccessorHash m_DataAccessorHash; - - //! Map vertices id to source data id - QHash m_VerticesSourceHash; - - //! The current loadeed mesh - MeshInfo* m_pMeshInfo; - - //! Hash table off geometry (MeshInfo*) - QHash m_GeometryHash; - - //! Hash table off collada node - QHash m_ColladaNodeHash; - - //! The list of top level node - QList m_TopLevelColladaNode; - - //! Mapping between material instance and material - QHash m_MaterialInstanceMap; - - //! 3DRep hash table - QHash m_3DRepHash; - - //! GLC instance Hash table - QHash m_StructInstanceHash; - - //! The current Collada Element id - QString m_CurrentId; - - //! The Collada file size - qint64 m_FileSize; - - //! The current offset in the collada file - int m_CurrentOffset; - - //! The list of attached file name - QSet m_ListOfAttachedFileName; - - //! The transparent mode is RGB_ZERO - bool m_TransparentIsRgbZero; - -}; - -// To use ColladaVertice as a QHash key -inline bool operator==(const GLC_ColladaToWorld::ColladaVertice& vertice1, const GLC_ColladaToWorld::ColladaVertice& vertice2) -{ return (vertice1.m_Values == vertice2.m_Values);} - -inline uint qHash(const GLC_ColladaToWorld::ColladaVertice& vertice) -{ return qHash(QString::number(vertice.m_Values.at(0)) + QString::number(vertice.m_Values.at(1)) + QString::number(vertice.m_Values.at(2)));} - -#endif /* GLC_COLLADATOWORLD_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/io/glc_fileloader.cpp b/ground/gcs/src/libs/glc_lib/io/glc_fileloader.cpp deleted file mode 100644 index 49e364a53..000000000 --- a/ground/gcs/src/libs/glc_lib/io/glc_fileloader.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2011 Jrme Forrissier - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_filetoworld.cpp implementation of the GLC_FileToWorld class. - - -#include "glc_fileloader.h" - -#include "glc_objtoworld.h" -#include "glc_stltoworld.h" -#include "glc_offtoworld.h" -#include "glc_3dstoworld.h" -#include "glc_3dxmltoworld.h" -#include "glc_colladatoworld.h" -#include "glc_bsreptoworld.h" - -#include "../sceneGraph/glc_world.h" -#include "../glc_fileformatexception.h" -#include "../glc_factory.h" -#include "glc_worldreaderplugin.h" - -////////////////////////////////////////////////////////////////////// -// Constructor -////////////////////////////////////////////////////////////////////// -GLC_FileLoader::GLC_FileLoader() -{ -} - -GLC_FileLoader::~GLC_FileLoader() -{ -} - -///////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -// Create an GLC_World from an input File -GLC_World GLC_FileLoader::createWorldFromFile(QFile &file, QStringList* pAttachedFileName) -{ -#if defined(Q_OS_WIN) - // We need to force the connection type on Windows, not sure why: - // Qt::DirectConnection should be selected automatically since - // source and destination are in the same thread... -#define connect(snd, sig, rcv, memb) \ - connect(snd, sig, rcv, memb, Qt::DirectConnection) -#endif - - const QString suffix= QFileInfo(file).suffix(); - if (GLC_Factory::canBeLoaded(suffix)) - { - GLC_WorldReaderHandler* pReaderHandler= GLC_Factory::loadingHandler(file.fileName()); - if (NULL != pReaderHandler) - { - qDebug() << "Use STL plugin"; - QObject* pObject= dynamic_cast(pReaderHandler); - Q_ASSERT(NULL != pObject); - connect(pObject, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int))); - GLC_World resultWorld= pReaderHandler->read(&file); - if (NULL != pAttachedFileName) - { - (*pAttachedFileName)= pReaderHandler->listOfAttachedFileName(); - } - - delete pReaderHandler; - return resultWorld; - } - } - GLC_World* pWorld= NULL; - if (QFileInfo(file).suffix().toLower() == "obj") - { - GLC_ObjToWorld objToWorld; - connect(&objToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int))); - pWorld= objToWorld.CreateWorldFromObj(file); - if (NULL != pAttachedFileName) - { - (*pAttachedFileName)= objToWorld.listOfAttachedFileName(); - } - } - else if (QFileInfo(file).suffix().toLower() == "stl") - { - GLC_StlToWorld stlToWorld; - connect(&stlToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int))); - pWorld= stlToWorld.CreateWorldFromStl(file); - } - else if (QFileInfo(file).suffix().toLower() == "off") - { - GLC_OffToWorld offToWorld; - connect(&offToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int))); - pWorld= offToWorld.CreateWorldFromOff(file); - } - else if (QFileInfo(file).suffix().toLower() == "3ds") - { - GLC_3dsToWorld studioToWorld; - connect(&studioToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int))); - pWorld= studioToWorld.CreateWorldFrom3ds(file); - if (NULL != pAttachedFileName) - { - (*pAttachedFileName)= studioToWorld.listOfAttachedFileName(); - } - } - else if (QFileInfo(file).suffix().toLower() == "3dxml") - { - GLC_3dxmlToWorld d3dxmlToWorld; - connect(&d3dxmlToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int))); - pWorld= d3dxmlToWorld.createWorldFrom3dxml(file, false); - if (NULL != pAttachedFileName) - { - (*pAttachedFileName)= d3dxmlToWorld.listOfAttachedFileName(); - } - } - else if (QFileInfo(file).suffix().toLower() == "dae") - { - GLC_ColladaToWorld colladaToWorld; - connect(&colladaToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int))); - pWorld= colladaToWorld.CreateWorldFromCollada(file); - if (NULL != pAttachedFileName) - { - (*pAttachedFileName)= colladaToWorld.listOfAttachedFileName(); - } - } - else if (QFileInfo(file).suffix().toLower() == "bsrep") - { - GLC_BSRepToWorld bsRepToWorld; - pWorld= bsRepToWorld.CreateWorldFromBSRep(file); - emit currentQuantum(100); - } - - if (NULL == pWorld) - { - // File extension not recognize or file not loaded - QString message(QString("GLC_Factory::createWorldFromFile File ") + file.fileName() + QString(" not loaded")); - GLC_FileFormatException fileFormatException(message, file.fileName(), GLC_FileFormatException::FileNotSupported); - throw(fileFormatException); - } - GLC_World resulWorld(*pWorld); - delete pWorld; - - return resulWorld; -} diff --git a/ground/gcs/src/libs/glc_lib/io/glc_fileloader.h b/ground/gcs/src/libs/glc_lib/io/glc_fileloader.h deleted file mode 100644 index 199316b87..000000000 --- a/ground/gcs/src/libs/glc_lib/io/glc_fileloader.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2011 Jrme Forrissier - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_fileloader.h common interface to 3D file parsers. - -#ifndef GLC_FILELOADER_H_ -#define GLC_FILELOADER_H_ - -#include -#include -#include -#include -#include -#include - -#include "../glc_config.h" - -class GLC_World; -class QGLContext; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_FileLoader -/*! \brief GLC_FileLoader : Create a GLC_World from file */ - -/*! GLC_FileLoader loads a 3D model from a file. - * A suitable parser is selected based on the file name extension. - */ -////////////////////////////////////////////////////////////////////// - -class GLC_LIB_EXPORT GLC_FileLoader : public QObject -{ - Q_OBJECT -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// - -public: - GLC_FileLoader(); - virtual ~GLC_FileLoader(); -//@} -////////////////////////////////////////////////////////////////////// -/*! @name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Create a GLC_World from a file - GLC_World createWorldFromFile(QFile &file, QStringList* pAttachedFileName= NULL); -//@} - - -////////////////////////////////////////////////////////////////////// -// Qt Signals -////////////////////////////////////////////////////////////////////// - signals: - void currentQuantum(int); - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: -}; - -#endif /*GLC_FILELOADER_H_*/ diff --git a/ground/gcs/src/libs/glc_lib/io/glc_objmtlloader.cpp b/ground/gcs/src/libs/glc_lib/io/glc_objmtlloader.cpp deleted file mode 100644 index 51c3c92be..000000000 --- a/ground/gcs/src/libs/glc_lib/io/glc_objmtlloader.cpp +++ /dev/null @@ -1,395 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - Version 2.0.0, packaged on July 2010. - - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_objmtlloader.cpp implementation of the GLC_ObjMtlLoader class. - -#include "glc_objmtlloader.h" -#include "../glc_fileformatexception.h" -#include -#include -#include -#include -#include - -GLC_ObjMtlLoader::GLC_ObjMtlLoader(const QString& fileName) -: m_FileName(fileName) -, m_pCurrentMaterial(NULL) -, m_Materials() -, m_LoadStatus() -, m_ListOfAttachedFileName() -{ -} - -GLC_ObjMtlLoader::~GLC_ObjMtlLoader() -{ - // Remove unused material - QHash::iterator i; - for (i= m_Materials.begin(); i != m_Materials.end(); ++i) - { - if (i.value()->isUnused()) delete i.value(); - } - m_Materials.clear(); - m_ListOfAttachedFileName.clear(); -} -///////////////////////////////////////////////////////////////////// -// Get functions -////////////////////////////////////////////////////////////////////// -// Get a material from is name -GLC_Material* GLC_ObjMtlLoader::material(const QString& materialName) -{ - if (m_Materials.contains(materialName)) - { - return m_Materials[materialName]; - } - else - { - return NULL; - } -} - -///////////////////////////////////////////////////////////////////// -// Set functions -////////////////////////////////////////////////////////////////////// -// Load the materials -bool GLC_ObjMtlLoader::loadMaterials() -{ - - // Create the input file stream - QFile mtlFile(m_FileName); - - if (!mtlFile.open(QIODevice::ReadOnly)) - { - qDebug() << "GLC_ObjMtlLoader::LoadMaterial File " << m_FileName << " doesn't exist"; - return false; - } - else - { - //qDebug() << "GLC_ObjMtlLoader::LoadMaterial OK File " << m_FileName << " exist"; - } - - QTextStream mtlStream(&mtlFile); - - QString lineBuff; - QString header; - - while (!mtlStream.atEnd()) - { - lineBuff= mtlStream.readLine(); - //qDebug() << lineBuff; - QTextStream streamLine(lineBuff.toLatin1()); - - if ((streamLine >> header).status() ==QTextStream::Ok) - { - - // Search New material - if (header =="newmtl") - { - //qDebug() << "New material find"; - - if (NULL != m_pCurrentMaterial) - { // It's not the first material - //qDebug() << "Add material : " << m_pCurrentMaterial->name(); - processMayaSpecific(); - m_Materials.insert(m_pCurrentMaterial->name(), m_pCurrentMaterial); - m_pCurrentMaterial= NULL; - } - - m_pCurrentMaterial= new GLC_Material; - if (!extractMaterialName(lineBuff)) return false; - //qDebug() << "New Material " << m_pCurrentMaterial->name(); - - } - else if ((header == "Ka") || (header == "Kd") || (header == "Ks")) // ambiant, diffuse and specular color - { - if (!extractRGBValue(lineBuff)) return false; - } - - else if ((header == "Ns") || (header == "d")) // shiness Or transparency - { - if (!extractOneValue(lineBuff)) return false; - } - else if ((header == "map_Kd") || (header == "map_Ka")) // Texture - { - //qDebug() << "Texture detected"; - extractTextureFileName(lineBuff); - } - - } - } - - if (NULL != m_pCurrentMaterial) - { - //qDebug() << "Add material : " << m_pCurrentMaterial->name(); - m_Materials.insert(m_pCurrentMaterial->name(), m_pCurrentMaterial); - m_pCurrentMaterial= NULL; - } - - mtlFile.close(); - return true; - -} -///////////////////////////////////////////////////////////////////// -// Private services functions -////////////////////////////////////////////////////////////////////// - -// Extract the material name -bool GLC_ObjMtlLoader::extractMaterialName(QString &ligne) -{ - bool result= false; - QTextStream stream(&ligne); - QString valueString; - QString header; - if ((stream >> header >> valueString).status() == QTextStream::Ok) - { - // If There is an space in the string to extracts - QString valueString2; - while ((stream >> valueString2).status() == QTextStream::Ok) - { - valueString.append(" "); - valueString.append(valueString2); - } - m_pCurrentMaterial->setName(valueString); - //qDebug() << "Material name is : " << valueString; - result= true; - } - else - { - m_LoadStatus= "GLC_ObjMtlLoader::extractMaterialName : something is wrong!!"; - result= false; - } - return result; -} -// Extract the texture file name -void GLC_ObjMtlLoader::extractTextureFileName(QString &ligne) -{ - QTextStream stream(&ligne); - QString valueString; - QString header; - if ((stream >> header >> valueString).status() == QTextStream::Ok) - { - // Retrieve the .obj file path - QFileInfo fileInfo(m_FileName); - - QString textureFileName(fileInfo.absolutePath() + QDir::separator()); - // concatenate File Path with texture filename - textureFileName.append(getTextureName(stream, valueString)); - - QFile textureFile(textureFileName); - - if (!textureFile.open(QIODevice::ReadOnly)) - { - QStringList stringList(m_FileName); - stringList.append("Open File : " + textureFileName + " failed"); - GLC_ErrorLog::addError(stringList); - } - else if ((textureFileName.right(3).contains("TGA", Qt::CaseInsensitive))) - { - QStringList stringList(m_FileName); - stringList.append("Image : " + textureFileName + " not suported"); - GLC_ErrorLog::addError(stringList); - } - else - { - m_ListOfAttachedFileName << textureFileName; - // Create the texture and assign it to current material - GLC_Texture *pTexture = new GLC_Texture(textureFile); - m_pCurrentMaterial->setTexture(pTexture); - //qDebug() << "Texture File is : " << valueString; - } - textureFile.close(); - } -} - -// Extract RGB value -bool GLC_ObjMtlLoader::extractRGBValue(QString &ligne) -{ - bool result= false; - QTextStream stream(&ligne); - QString header; - QString rColor, gColor, bColor; - QColor color(Qt::white); - - if ((stream >> header >> rColor >> gColor >> bColor).status() == QTextStream::Ok) - { - bool okr, okg, okb; - color.setRedF(rColor.toDouble(&okr)); - color.setGreenF(gColor.toDouble(&okg)); - color.setBlueF(bColor.toDouble(&okb)); - if (!(okr && okg && okb)) - { - m_LoadStatus= "GLC_ObjMtlLoader::ExtractRGBValue : Wrong format of rgb color value!!"; - qDebug() << m_LoadStatus; - result= false; - } - else - { - color.setAlphaF(1.0); - if (header == "Ka") // Ambiant Color - { - m_pCurrentMaterial->setAmbientColor(color); - //qDebug() << "Ambiant Color : " << color.redF() << " " << color.greenF() << " " << color.blueF(); - result= true; - } - - else if (header == "Kd") // Diffuse Color - { - m_pCurrentMaterial->setDiffuseColor(color); - //qDebug() << "Diffuse Color : " << color.redF() << " " << color.greenF() << " " << color.blueF(); - result= true; - } - - else if (header == "Ks") // Specular Color - { - m_pCurrentMaterial->setSpecularColor(color); - //qDebug() << "Specular Color : " << color.redF() << " " << color.greenF() << " " << color.blueF(); - result= true; - } - - else - { - m_LoadStatus= "GLC_ObjMtlLoader::ExtractRGBValue : something is wrong!!"; - result= false; - } - } - - }else - { - m_LoadStatus= "GLC_ObjMtlLoader::ExtractRGBValue : something is wrong!!"; - qDebug() << m_LoadStatus; - result= false; - } - - return result; - -} - -// Extract One value -bool GLC_ObjMtlLoader::extractOneValue(QString &ligne) -{ - QTextStream stream(&ligne); - QString valueString; - QString header; - GLfloat value; - - if ((stream >> header >> valueString).status() == QTextStream::Ok) - { - if (header == "Ns") // Ambient color - { - bool ok; - value= valueString.toFloat(&ok); - if (!ok) - { - m_LoadStatus= "GLC_ObjMtlLoader::ExtractOneValue : Wrong format of Shiness !"; - qDebug() << m_LoadStatus; - return false; - } - m_pCurrentMaterial->setShininess(value); - return true; - } - else if (header == "d") // Transparancy - { - bool ok; - value= valueString.toFloat(&ok); - if (!ok) - { - m_LoadStatus= "GLC_ObjMtlLoader::ExtractOneValue : Wrong format Transparency!"; - qDebug() << m_LoadStatus; - return false; - } - m_pCurrentMaterial->setOpacity(static_cast(value)); - return true; - } - - else - { - m_LoadStatus= "GLC_ObjMtlLoader::ExtractOneValue : Ambient Color not found!!"; - qDebug() << m_LoadStatus; - return false; - } - } - else - { - m_LoadStatus= "GLC_ObjMtlLoader::ExtractOneValue : something is wrong!!"; - qDebug() << m_LoadStatus; - GLC_FileFormatException fileFormatException(m_LoadStatus, m_FileName, GLC_FileFormatException::WrongFileFormat); - return false; - } - -} - -// Get texture file name without parameters -QString GLC_ObjMtlLoader::getTextureName(QTextStream &inputStream, const QString &input) -{ - QString textureName(input); - int numberOfStringToSkip= 0; - // Check if there is a map parameter and count - if ((input == "-o") || (input == "-s") || (input == "-t")) - { - numberOfStringToSkip= 3; - } - else if (input == "-mm") - { - numberOfStringToSkip= 2; - } - else if ((input == "-blendu") || (input == "-blendv") || (input == "-cc") - || (input == "-clamp") || (input == "-texres")) - { - numberOfStringToSkip= 1; - } - - if (numberOfStringToSkip != 0) - { - // Skip unread map parameters - for (int i= 0; i < numberOfStringToSkip; ++i) - { - inputStream >> textureName; - } - - if ((inputStream >> textureName).status() == QTextStream::Ok) - { - textureName= getTextureName(inputStream, textureName); - } - else - { - m_LoadStatus== "GLC_ObjToMesh2::extractString : Error occur when trying to decode map option"; - GLC_FileFormatException fileFormatException(m_LoadStatus, m_FileName, GLC_FileFormatException::WrongFileFormat); - throw(fileFormatException); - } - } - return textureName; -} -// Process Maya specific obj -void GLC_ObjMtlLoader::processMayaSpecific() -{ - // Test if the current material have a texture - if (m_pCurrentMaterial->hasTexture()) - { - // Test if the diffuse color of material is black - if (m_pCurrentMaterial->diffuseColor() == Qt::black) - { - // Change the material's diffuse color in order to see the texture - m_pCurrentMaterial->setDiffuseColor(Qt::lightGray); - } - } -} diff --git a/ground/gcs/src/libs/glc_lib/io/glc_objmtlloader.h b/ground/gcs/src/libs/glc_lib/io/glc_objmtlloader.h deleted file mode 100644 index 4700d2f1e..000000000 --- a/ground/gcs/src/libs/glc_lib/io/glc_objmtlloader.h +++ /dev/null @@ -1,132 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - Version 2.0.0, packaged on July 2010. - - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_objmtlloader.h interface for the GLC_ObjMtlLoader class. - -#ifndef GLC_OBJMTLLOADER_H_ -#define GLC_OBJMTLLOADER_H_ - -#include -#include -#include -#include "../shading/glc_material.h" - -#include "../glc_config.h" - -class QGLContext; -////////////////////////////////////////////////////////////////////// -//! \class GLC_ObjMtlLoader -/*! \brief GLC_ObjMtlLoader : Load the mtl file associated to a OBJ File */ - -/*! An GLC_ObjMtlLoader create GLC_Material from the .mtl file \n - */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_ObjMtlLoader -{ - -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - GLC_ObjMtlLoader(const QString&); - - virtual ~GLC_ObjMtlLoader(); -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return true if the material name is found - inline bool contains(const QString &name) const - {return m_Materials.contains(name);} - - //! Get a material from is name - GLC_Material* material(const QString&); - - //! Get the list of attached files - inline QStringList listOfAttachedFileName() const - {return m_ListOfAttachedFileName.toList();} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Load the materials - bool loadMaterials(); - -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Private services functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -private: - //! Extract the material name - bool extractMaterialName(QString &); - - //! Extract the texture file name - void extractTextureFileName(QString &); - - //! Extract RGB value - bool extractRGBValue(QString &); - - //! Extract One value - bool extractOneValue(QString &); - - //! Get texture file name without parameters - QString getTextureName(QTextStream &, const QString &); - - //! Process Maya specific obj - void processMayaSpecific(); - - -//@} - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - //! The mtl file name - QString m_FileName; - - //! Current material - GLC_Material* m_pCurrentMaterial; - - //! The GLC_Material Hash Table - QHash m_Materials; - - //! the Load status - QString m_LoadStatus; - - //! The list of attached file name - QSet m_ListOfAttachedFileName; - - -}; - -#endif /*GLC_OBJMTLLOADER_H_*/ diff --git a/ground/gcs/src/libs/glc_lib/io/glc_objtoworld.cpp b/ground/gcs/src/libs/glc_lib/io/glc_objtoworld.cpp deleted file mode 100644 index a7ba2f8d4..000000000 --- a/ground/gcs/src/libs/glc_lib/io/glc_objtoworld.cpp +++ /dev/null @@ -1,898 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - Version 2.0.0, packaged on July 2010. - - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_objToworld.cpp implementation of the GLC_ObjToWorld class. - - -#include "glc_objtoworld.h" -#include "../sceneGraph/glc_world.h" -#include "glc_objmtlloader.h" -#include "../glc_fileformatexception.h" -#include "../maths/glc_geomtools.h" -#include "../sceneGraph/glc_structreference.h" -#include "../sceneGraph/glc_structinstance.h" -#include "../sceneGraph/glc_structoccurence.h" -#include -#include -#include - -////////////////////////////////////////////////////////////////////// -// Constructor -////////////////////////////////////////////////////////////////////// -GLC_ObjToWorld::GLC_ObjToWorld() -: m_pWorld(NULL) -, m_FileName() -, m_pMtlLoader(NULL) -, m_CurrentLineNumber(0) -, m_pCurrentObjMesh(NULL) -, m_FaceType(notSet) -, m_CurrentMeshMaterials() -, m_CurrentMaterialName("GLC_Default") -, m_ListOfAttachedFileName() -, m_Positions() -, m_Normals() -, m_Texels() -{ -} - -GLC_ObjToWorld::~GLC_ObjToWorld() -{ - clear(); -} - -///////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -// Create an GLC_World from an input OBJ File -GLC_World* GLC_ObjToWorld::CreateWorldFromObj(QFile &file) -{ - m_ListOfAttachedFileName.clear(); - m_FileName= file.fileName(); - ////////////////////////////////////////////////////////////////// - // Test if the file exist and can be opened - ////////////////////////////////////////////////////////////////// - if (!file.open(QIODevice::ReadOnly)) - { - QString message(QString("GLC_ObjToWorld::CreateWorldFromObj File ") + m_FileName + QString(" doesn't exist")); - //qDebug() << message; - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotFound); - throw(fileFormatException); - } - - ////////////////////////////////////////////////////////////////// - // Init member - ////////////////////////////////////////////////////////////////// - m_pWorld= new GLC_World; - - // Create Working variables - int currentQuantumValue= 0; - int previousQuantumValue= 0; - int numberOfLine= 0; - - // Create the input file stream - QTextStream objStream(&file); - - // QString buffer - QString lineBuff; - - QString mtlLibLine; - - ////////////////////////////////////////////////////////////////// - // Searching mtllib attribute - ////////////////////////////////////////////////////////////////// - while (!objStream.atEnd() && !lineBuff.contains("mtllib")) - { - ++numberOfLine; - lineBuff= objStream.readLine(); - if (lineBuff.contains("mtllib")) mtlLibLine= lineBuff; - } - - ////////////////////////////////////////////////////////////////// - // Count the number of lines of the OBJ file - ////////////////////////////////////////////////////////////////// - while (!objStream.atEnd()) - { - ++numberOfLine; - objStream.readLine(); - } - - ////////////////////////////////////////////////////////////////// - // Reset the stream - ////////////////////////////////////////////////////////////////// - objStream.resetStatus(); - objStream.seek(0); - - ////////////////////////////////////////////////////////////////// - // if mtl file found, load it - ////////////////////////////////////////////////////////////////// - QString mtlLibFileName(getMtlLibFileName(mtlLibLine)); - if (!mtlLibFileName.isEmpty()) - { - m_pMtlLoader= new GLC_ObjMtlLoader(mtlLibFileName); - if (!m_pMtlLoader->loadMaterials()) - { - delete m_pMtlLoader; - m_pMtlLoader= NULL; - if (!mtlLibLine.isEmpty()) - { - QStringList stringList(m_FileName); - stringList.append("Open Material File : " + mtlLibFileName + " failed"); - GLC_ErrorLog::addError(stringList); - } - } - else - { - // Update Attached file name list - m_ListOfAttachedFileName << mtlLibFileName; - m_ListOfAttachedFileName << m_pMtlLoader->listOfAttachedFileName(); - } - } - else - { - //qDebug() << "GLC_ObjToWorld::CreateWorldFromObj: mtl file not found"; - } - - ////////////////////////////////////////////////////////////////// - // Read Buffer and create the world - ////////////////////////////////////////////////////////////////// - emit currentQuantum(currentQuantumValue); - m_CurrentLineNumber= 0; - while (!objStream.atEnd()) - { - ++m_CurrentLineNumber; - lineBuff= objStream.readLine(); - - mergeLines(&lineBuff, &objStream); - - scanLigne(lineBuff); - currentQuantumValue = static_cast((static_cast(m_CurrentLineNumber) / numberOfLine) * 100); - if (currentQuantumValue > previousQuantumValue) - { - emit currentQuantum(currentQuantumValue); - } - previousQuantumValue= currentQuantumValue; - - } - file.close(); - - addCurrentObjMeshToWorld(); - - //! Test if there is meshes in the world - if (m_pWorld->rootOccurence()->childCount() == 0) - { - QString message= "GLC_ObjToWorld::CreateWorldFromObj " + m_FileName + " No mesh found!"; - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::NoMeshFound); - clear(); - throw(fileFormatException); - } - return m_pWorld; - -} - -////////////////////////////////////////////////////////////////////// -// Private services functions -////////////////////////////////////////////////////////////////////// - -// Return the name of the mtl file -QString GLC_ObjToWorld::getMtlLibFileName(QString line) -{ - // Search mtl file with the same name than the OBJ file Name - QString mtlFileName(m_FileName); - mtlFileName.replace(m_FileName.size() - 3, 3, "mtl"); - QFile mtlFile(mtlFileName); - if (!mtlFile.exists())// mtl file with same name not found - { - QTextStream stream(&line); - QString header; - if ((stream >> header >> mtlFileName).status() == QTextStream::Ok) - { - // If There is spaces in the string to extracts - QString valueString2; - while ((stream >> valueString2).status() == QTextStream::Ok) - { - mtlFileName.append(" "); - mtlFileName.append(valueString2); - } - QFileInfo fileInfo(m_FileName); - mtlFileName= fileInfo.absolutePath() + QDir::separator() + mtlFileName; - } - else - { - // There is no mtl file to load - mtlFileName.clear(); - } - } - return mtlFileName; -} - -// Scan a line previously extracted from OBJ file -void GLC_ObjToWorld::scanLigne(QString &line) -{ - line= line.trimmed(); - // Search Vertexs vectors - if (line.startsWith("v ")|| line.startsWith(QString("v") + QString(QChar(9)))) - { - line.remove(0,2); // Remove first 2 char - m_Positions.append(extract3dVect(line)); - m_FaceType = notSet; - } - - // Search texture coordinate vectors - else if (line.startsWith("vt ")|| line.startsWith(QString("vt") + QString(QChar(9)))) - { - line.remove(0,3); // Remove first 3 char - m_Texels.append(extract2dVect(line)); - m_FaceType = notSet; - } - - // Search normals vectors - else if (line.startsWith("vn ") || line.startsWith(QString("vn") + QString(QChar(9)))) - { - line.remove(0,3); // Remove first 3 char - m_Normals.append(extract3dVect(line)); - m_FaceType = notSet; - } - - // Search faces to update index - else if (line.startsWith("f ") || line.startsWith(QString("f") + QString(QChar(9)))) - { - // If there is no group or object in the OBJ file - if (NULL == m_pCurrentObjMesh) - { - changeGroup("GLC_Default"); - //qDebug() << "Default group " << line; - } - line.remove(0,2); // Remove first 2 char - extractFaceIndex(line); - } - - // Search Material - else if (line.startsWith("usemtl ") || line.startsWith(QString("usemtl") + QString(QChar(9)))) - { - line.remove(0,7); // Remove first 7 char - setCurrentMaterial(line); - m_FaceType = notSet; - } - - // Search Group - else if (line.startsWith("g ") || line.startsWith("o ") || line.startsWith(QString("g") + QString(QChar(9))) - || line.startsWith(QString("o") + QString(QChar(9)))) - { - m_FaceType = notSet; - line.remove(0,2); // Remove first 2 char - changeGroup(line); - } - -} -// Change current group -void GLC_ObjToWorld::changeGroup(QString line) -{ - //qDebug() << "GLC_ObjToWorld::changeGroup at Line :" << line; - ////////////////////////////////////////////////////////////////// - // Parse the line containing the group name - ////////////////////////////////////////////////////////////////// - QTextStream stream(&line); - QString groupName; - if ((stream >> groupName).status() == QTextStream::Ok) - { - // If There is an space in the string to extracts - QString valueString2; - while ((stream >> valueString2).status() == QTextStream::Ok) - { - groupName.append(" "); - groupName.append(valueString2); - } - ////////////////////////////////////////////////////////////// - // If the groupName == "default" nothing to do - ////////////////////////////////////////////////////////////// - if("default" != groupName) - { - addCurrentObjMeshToWorld(); - m_pCurrentObjMesh= new CurrentObjMesh(m_CurrentMaterialName); - m_pCurrentObjMesh->m_pMesh->setName(groupName); - - } - } - else - { - QString message= "GLC_ObjToWorld::changeGroup " + m_FileName + " something is wrong!!"; - message.append("\nAt line : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported); - clear(); - throw(fileFormatException); - } - -} - -// Extract a Vector from a string -QList GLC_ObjToWorld::extract3dVect(QString &line) -{ - float x=0.0f; - float y=0.0f; - float z=0.0f; - - QList vectResult; - QTextStream stringVecteur(&line); - - QString xString, yString, zString; - - if (((stringVecteur >> xString >> yString >> zString).status() == QTextStream::Ok)) - { - bool xOk, yOk, zOk; - x= xString.toFloat(&xOk); - y= yString.toFloat(&yOk); - z= zString.toFloat(&zOk); - if (!(xOk && yOk && zOk)) - { - QString message= "GLC_ObjToWorld::extract3dVect " + m_FileName + " failed to convert vector component to float"; - message.append("\nAt ligne : "); - message.append(QString::number(m_CurrentLineNumber)); - QStringList stringList(m_FileName); - stringList.append(message); - GLC_ErrorLog::addError(stringList); - - //GLC_FileFormatException fileFormatException(message, m_FileName); - //clear(); - //throw(fileFormatException); - } - else - { - vectResult << x << y << z; - } - } - - return vectResult; - -} - -// Extract a Vector from a string -QList GLC_ObjToWorld::extract2dVect(QString &line) -{ - float x=0.0f; - float y=0.0f; - QList vectResult; - QTextStream stringVecteur(&line); - - QString xString, yString; - - if (((stringVecteur >> xString >> yString).status() == QTextStream::Ok)) - { - bool xOk, yOk; - x= xString.toFloat(&xOk); - y= yString.toFloat(&yOk); - if (!(xOk && yOk)) - { - QString message= "GLC_ObjToWorld::extract2dVect " + m_FileName + " failed to convert vector component to double"; - message.append("\nAt ligne : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - vectResult << x << y; - } - - return vectResult; -} - -// Extract a face from a string -void GLC_ObjToWorld::extractFaceIndex(QString &line) -{ - QString buff; - - int coordinateIndex; - int normalIndex; - int textureCoordinateIndex; - - QList currentFaceIndex; - ////////////////////////////////////////////////////////////////// - // Parse the line containing face index - ////////////////////////////////////////////////////////////////// - QTextStream streamFace(&line); - while ((!streamFace.atEnd())) - { - streamFace >> buff; - extractVertexIndex(buff, coordinateIndex, normalIndex, textureCoordinateIndex); - - ObjVertice currentVertice(coordinateIndex, normalIndex, textureCoordinateIndex); - if (m_pCurrentObjMesh->m_ObjVerticeIndexMap.contains(currentVertice)) - { - currentFaceIndex.append(m_pCurrentObjMesh->m_ObjVerticeIndexMap.value(currentVertice)); - } - else - { - // Add Vertex to the mesh bulk data - m_pCurrentObjMesh->m_Positions.append(m_Positions.value(coordinateIndex * 3)); - m_pCurrentObjMesh->m_Positions.append(m_Positions.value(coordinateIndex * 3 + 1)); - m_pCurrentObjMesh->m_Positions.append(m_Positions.value(coordinateIndex * 3 + 2)); - if (-1 != normalIndex) - { - // Add Normal to the mesh bulk data - m_pCurrentObjMesh->m_Normals.append(m_Normals.value(normalIndex * 3)); - m_pCurrentObjMesh->m_Normals.append(m_Normals.value(normalIndex * 3 + 1)); - m_pCurrentObjMesh->m_Normals.append(m_Normals.value(normalIndex * 3 + 2)); - } - else - { - // Add Null Normal to the mesh bulk data - m_pCurrentObjMesh->m_Normals.append(0.0f); - m_pCurrentObjMesh->m_Normals.append(0.0f); - m_pCurrentObjMesh->m_Normals.append(0.0f); - } - if (-1 != textureCoordinateIndex) - { - // Add texture coordinate to the mesh bulk data - m_pCurrentObjMesh->m_Texels.append(m_Texels.value(textureCoordinateIndex * 2)); - m_pCurrentObjMesh->m_Texels.append(m_Texels.value(textureCoordinateIndex * 2 + 1)); - } - else if (!m_pCurrentObjMesh->m_Texels.isEmpty()) - { - // Add epmty texture coordinate - m_pCurrentObjMesh->m_Texels.append(0.0f); - m_pCurrentObjMesh->m_Texels.append(0.0f); - } - // Add the index to current face index - currentFaceIndex.append(m_pCurrentObjMesh->m_NextFreeIndex); - // Add ObjVertice to ObjVertice Map - m_pCurrentObjMesh->m_ObjVerticeIndexMap.insert(currentVertice, m_pCurrentObjMesh->m_NextFreeIndex); - // Increment next free index - ++(m_pCurrentObjMesh->m_NextFreeIndex); - } - - } - ////////////////////////////////////////////////////////////////// - // Check the number of face's vertex - ////////////////////////////////////////////////////////////////// - const int size= currentFaceIndex.size(); - if (size < 3) - { - QStringList stringList(m_FileName); - stringList.append("GLC_ObjToWorld::extractFaceIndex Face with less than 3 vertex found"); - GLC_ErrorLog::addError(stringList); - return; - } - ////////////////////////////////////////////////////////////////// - // Add the face to the current mesh - ////////////////////////////////////////////////////////////////// - if ((m_FaceType == coordinateAndNormal) || (m_FaceType == coordinateAndTextureAndNormal)) - { - if (size > 3) - { - glc::triangulatePolygon(¤tFaceIndex, m_pCurrentObjMesh->m_Positions); - } - m_pCurrentObjMesh->m_Index.append(currentFaceIndex); - } - else if (m_FaceType != notSet) - { - if (size > 3) - { - glc::triangulatePolygon(¤tFaceIndex, m_pCurrentObjMesh->m_Positions); - } - // Comput the face normal - if (currentFaceIndex.size() < 3) return; - GLC_Vector3df normal= computeNormal(currentFaceIndex.at(0), currentFaceIndex.at(1), currentFaceIndex.at(2)); - - // Add Face normal to bulk data - QSet indexSet= currentFaceIndex.toSet(); - QSet::iterator iIndexSet= indexSet.begin(); - while (indexSet.constEnd() != iIndexSet) - { - m_pCurrentObjMesh->m_Normals[*iIndexSet * 3]= normal.x(); - m_pCurrentObjMesh->m_Normals[*iIndexSet * 3 + 1]= normal.y(); - m_pCurrentObjMesh->m_Normals[*iIndexSet * 3 + 2]= normal.z(); - - ++iIndexSet; - } - - m_pCurrentObjMesh->m_Index.append(currentFaceIndex); - - } - else - { - QString message= "GLC_ObjToWorld::extractFaceIndex " + m_FileName + " unknow face type"; - message.append("\nAt line : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported); - clear(); - throw(fileFormatException); - } -} -//! Set Current material index -void GLC_ObjToWorld::setCurrentMaterial(QString &line) -{ - QTextStream streamString(&line); - QString materialName; - - if (!((streamString >> materialName).status() == QTextStream::Ok)) - { - QString message= "GLC_ObjToWorld::SetCurrentMaterial " + m_FileName + " : failed to extract materialName"; - message.append("\nAt line : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - ////////////////////////////////////////////////////////////////// - // Check if the material is already loaded from the current mesh - ////////////////////////////////////////////////////////////////// - if ((NULL != m_pMtlLoader) && m_pMtlLoader->contains(materialName)) - { - if (NULL == m_pCurrentObjMesh) - { - changeGroup("GLC_Default"); - } - Q_ASSERT(NULL != m_pCurrentObjMesh->m_pLastOffsetSize); - - if (m_pCurrentObjMesh->m_Index.size() != m_pCurrentObjMesh->m_pLastOffsetSize->m_Offset) - { - // Update last material offsetSize - m_pCurrentObjMesh->m_pLastOffsetSize->m_size= m_pCurrentObjMesh->m_Index.size() - m_pCurrentObjMesh->m_pLastOffsetSize->m_Offset; - } - else - { - QHash::iterator iMat= m_pCurrentObjMesh->m_Materials.begin(); - while (m_pCurrentObjMesh->m_Materials.constEnd() != iMat) - { - if (iMat.value() == m_pCurrentObjMesh->m_pLastOffsetSize) - { - iMat= m_pCurrentObjMesh->m_Materials.erase(iMat); - } - else - { - ++iMat; - } - } - } - // Create this material offsetSize - MatOffsetSize* pMatOffsetSize= new MatOffsetSize(); - pMatOffsetSize->m_Offset= m_pCurrentObjMesh->m_Index.size(); - // Update current Obj mesh - m_pCurrentObjMesh->m_pLastOffsetSize= pMatOffsetSize; - m_pCurrentObjMesh->m_Materials.insertMulti(materialName, pMatOffsetSize); - // Update current material name - m_CurrentMaterialName= materialName; - } - -} -// Extract a vertex from a string -void GLC_ObjToWorld::extractVertexIndex(QString line, int &Coordinate, int &Normal, int &TextureCoordinate) -{ - if (m_FaceType == notSet) - { - setObjType(line); - } - - if (m_FaceType == coordinateAndTextureAndNormal) - { - // Replace "/" with " " - line.replace('/', ' '); - QTextStream streamVertex(&line); - QString coordinateString, textureCoordinateString, normalString; - if ((streamVertex >> coordinateString >> textureCoordinateString >> normalString).status() == QTextStream::Ok) - { - bool coordinateOk, textureCoordinateOk, normalOk; - Coordinate= coordinateString.toInt(&coordinateOk); - --Coordinate; - TextureCoordinate= textureCoordinateString.toInt(&textureCoordinateOk); - --TextureCoordinate; - Normal= normalString.toInt(&normalOk); - --Normal; - if (!(coordinateOk && textureCoordinateOk && normalOk)) - { - QString message= "GLC_ObjToWorld::extractVertexIndex " + m_FileName + " failed to convert String to int"; - message.append("\nAt line : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - } - else - { - QString message= "GLC_ObjToWorld::extractVertexIndex Obj file " + m_FileName + " type is not supported"; - message.append("\nAt line : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported); - clear(); - throw(fileFormatException); - } - - } - else if (m_FaceType == coordinateAndTexture) - { - // Replace "/" with " " - line.replace('/', ' '); - QTextStream streamVertex(&line); - QString coordinateString, textureCoordinateString; - if ((streamVertex >> coordinateString >> textureCoordinateString).status() == QTextStream::Ok) - { - bool coordinateOk, textureCoordinateOk; - Coordinate= coordinateString.toInt(&coordinateOk); - --Coordinate; - TextureCoordinate= textureCoordinateString.toInt(&textureCoordinateOk); - --TextureCoordinate; - Normal= -1; - if (!(coordinateOk && textureCoordinateOk)) - { - QString message= "GLC_ObjToWorld::extractVertexIndex " + m_FileName + "failed to convert String to int"; - message.append("\nAt line : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - } - else - { - QString message= "GLC_ObjToWorld::extractVertexIndex " + m_FileName + " this Obj file type is not supported"; - message.append("\nAt line : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported); - clear(); - throw(fileFormatException); - } - } - else if (m_FaceType == coordinateAndNormal) - { - // Replace "/" with " " - line.replace('/', ' '); - QTextStream streamVertex(&line); - QString coordinateString, normalString; - if ((streamVertex >> coordinateString >> normalString).status() == QTextStream::Ok) - { - bool coordinateOk, normalOk; - Coordinate= coordinateString.toInt(&coordinateOk); - --Coordinate; - TextureCoordinate= -1; - Normal= normalString.toInt(&normalOk); - --Normal; - if (!(coordinateOk && normalOk)) - { - QString message= "GLC_ObjToWorld::extractVertexIndex " + m_FileName + " failed to convert String to int"; - message.append("\nAt line : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - } - else - { - QString message= "GLC_ObjToWorld::extractVertexIndex " + m_FileName + " this Obj file type is not supported"; - message.append("\nAt line : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported); - clear(); - throw(fileFormatException); - } - } - else if (m_FaceType == coordinate) - { - QTextStream streamVertex(&line); - QString coordinateString; - if ((streamVertex >> coordinateString).status() == QTextStream::Ok) - { - bool coordinateOk; - Coordinate= coordinateString.toInt(&coordinateOk); - --Coordinate; - TextureCoordinate= -1; - Normal= -1; - if (!coordinateOk) - { - QString message= "GLC_ObjToWorld::extractVertexIndex " + m_FileName + " failed to convert String to int"; - message.append("\nAt line : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - } - else - { - QString message= "GLC_ObjToWorld::extractVertexIndex Obj " + m_FileName + " file type is not supported"; - message.append("\nAt line : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported); - clear(); - throw(fileFormatException); - } - } - else - { - QString message= "GLC_ObjToWorld::extractVertexIndex OBJ file " + m_FileName + " not reconize"; - message.append("\nAt line : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported); - clear(); - throw(fileFormatException); - } -} - -// set the OBJ File type -void GLC_ObjToWorld::setObjType(QString& ligne) -{ - const QRegExp coordinateOnlyRegExp("^\\d{1,}$"); // ex. 10 - const QRegExp coordinateTextureNormalRegExp("^\\d{1,}/\\d{1,}/\\d{1,}$"); // ex. 10/30/54 - const QRegExp coordinateNormalRegExp("^\\d{1,}//\\d{1,}$"); // ex. 10//54 - const QRegExp coordinateTextureRegExp("^\\d{1,}/\\d{1,}$"); // ex. 10/56 - - if (coordinateTextureNormalRegExp.exactMatch(ligne)) - { - m_FaceType= coordinateAndTextureAndNormal; - } - else if (coordinateTextureRegExp.exactMatch(ligne)) - { - m_FaceType= coordinateAndTexture; - } - else if (coordinateNormalRegExp.exactMatch(ligne)) - { - m_FaceType= coordinateAndNormal; - } - else if (coordinateOnlyRegExp.exactMatch(ligne)) - { - m_FaceType= coordinate; - } - else - { - QString message= "GLC_ObjToWorld::setObjType OBJ file " + m_FileName + " not reconize"; - message.append("\nAt line : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported); - clear(); - throw(fileFormatException); - } -} - -// compute face normal -GLC_Vector3df GLC_ObjToWorld::computeNormal(GLuint index1, GLuint index2, GLuint index3) -{ - double xn, yn, zn; - - // Vertex 1 - xn= m_pCurrentObjMesh->m_Positions.at(index1 * 3); - yn= m_pCurrentObjMesh->m_Positions.at(index1 * 3 + 1); - zn= m_pCurrentObjMesh->m_Positions.at(index1 * 3 + 2); - const GLC_Vector3d vect1(xn, yn, zn); - - // Vertex 2 - xn= m_pCurrentObjMesh->m_Positions.at(index2 * 3); - yn= m_pCurrentObjMesh->m_Positions.at(index2 * 3 + 1); - zn= m_pCurrentObjMesh->m_Positions.at(index2 * 3 + 2); - const GLC_Vector3d vect2(xn, yn, zn); - - // Vertex 3 - xn= m_pCurrentObjMesh->m_Positions.at(index3 * 3); - yn= m_pCurrentObjMesh->m_Positions.at(index3 * 3 + 1); - zn= m_pCurrentObjMesh->m_Positions.at(index3 * 3 + 2); - const GLC_Vector3d vect3(xn, yn, zn); - - const GLC_Vector3d edge1(vect3 - vect2); - const GLC_Vector3d edge2(vect1 - vect2); - - GLC_Vector3d normal(edge1 ^ edge2); - normal.normalize(); - - return normal.toVector3df(); -} - -// clear objToWorld allocate memmory -void GLC_ObjToWorld::clear() -{ - m_CurrentMeshMaterials.clear(); - m_ListOfAttachedFileName.clear(); - - if (NULL != m_pMtlLoader) - { - delete m_pMtlLoader; - m_pMtlLoader= NULL; - } - if (NULL != m_pCurrentObjMesh) - { - delete m_pCurrentObjMesh; - m_pCurrentObjMesh= NULL; - } - -} -// Merge Mutli line in one -void GLC_ObjToWorld::mergeLines(QString* pLineBuff, QTextStream* p0bjStream) -{ - if (pLineBuff->endsWith(QChar('\\'))) - { - pLineBuff->replace(QChar('\\'), QChar(' ')); - pLineBuff->append(p0bjStream->readLine()); - ++m_CurrentLineNumber; - mergeLines(pLineBuff, p0bjStream); - } -} - -// Add the current Obj mesh to the world -void GLC_ObjToWorld::addCurrentObjMeshToWorld() -{ - if (NULL != m_pCurrentObjMesh) - { - if (!m_pCurrentObjMesh->m_Positions.isEmpty()) - { - m_pCurrentObjMesh->m_pMesh->addVertice(m_pCurrentObjMesh->m_Positions.toVector()); - m_pCurrentObjMesh->m_Positions.clear(); - m_pCurrentObjMesh->m_pMesh->addNormals(m_pCurrentObjMesh->m_Normals.toVector()); - m_pCurrentObjMesh->m_Normals.clear(); - if (!m_pCurrentObjMesh->m_Texels.isEmpty()) - { - m_pCurrentObjMesh->m_pMesh->addTexels(m_pCurrentObjMesh->m_Texels.toVector()); - m_pCurrentObjMesh->m_Texels.clear(); - } - QHash::iterator iMat= m_pCurrentObjMesh->m_Materials.begin(); - while (m_pCurrentObjMesh->m_Materials.constEnd() != iMat) - { - GLC_Material* pCurrentMaterial= NULL; - if ((NULL != m_pMtlLoader) && (m_pMtlLoader->contains(iMat.key()))) - { - pCurrentMaterial= m_pMtlLoader->material(iMat.key()); - } - // Create the list of triangles to add to the mesh - const int offset= iMat.value()->m_Offset; - int size= iMat.value()->m_size; - if (0 == size) - { - size= m_pCurrentObjMesh->m_Index.size() - offset; - } - //qDebug() << "Offset : " << offset << " size : " << size; - QList triangles; - for (int i= offset; i < (offset + size); ++i) - { - triangles.append(m_pCurrentObjMesh->m_Index.at(i)); - } - // Add the list of triangle to the mesh - if (!triangles.isEmpty()) - { - m_pCurrentObjMesh->m_pMesh->addTriangles(pCurrentMaterial, triangles); - } - - ++iMat; - } - if (m_pCurrentObjMesh->m_pMesh->faceCount(0) > 0) - { - m_pCurrentObjMesh->m_pMesh->finish(); - GLC_3DRep* pRep= new GLC_3DRep(m_pCurrentObjMesh->m_pMesh); - m_pWorld->rootOccurence()->addChild((new GLC_StructInstance(pRep))); - } - else - { - delete m_pCurrentObjMesh->m_pMesh; - } - - } - else - { - delete m_pCurrentObjMesh->m_pMesh; - } - - delete m_pCurrentObjMesh; - m_pCurrentObjMesh= NULL; - } -} - - diff --git a/ground/gcs/src/libs/glc_lib/io/glc_objtoworld.h b/ground/gcs/src/libs/glc_lib/io/glc_objtoworld.h deleted file mode 100644 index 092a625e2..000000000 --- a/ground/gcs/src/libs/glc_lib/io/glc_objtoworld.h +++ /dev/null @@ -1,269 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - Version 2.0.0, packaged on July 2010. - - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_objToworld.h interface for the GLC_ObjToWorld class. - -#ifndef GLC_OBJTOWORLD_H_ -#define GLC_OBJTOWORLD_H_ - -#include -#include -#include -#include -#include -#include - -#include "../maths/glc_vector3d.h" -#include "../maths/glc_vector2df.h" -#include "../maths/glc_vector3df.h" -#include "../geometry/glc_mesh.h" - -#include "../glc_config.h" - -enum FaceType -{ - notSet, - coordinate, - coordinateAndTexture, - coordinateAndNormal, - coordinateAndTextureAndNormal -}; - -class GLC_World; -class GLC_ObjMtlLoader; -class QGLContext; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_ObjToWorld -/*! \brief GLC_ObjToWorld : Create an GLC_World from obj file */ - -/*! An GLC_ObjToWorld extract the meshs from an .obj file \n - * List of elements extracted from the OBJ - * - Vertex - * - Face - * - Texture coordinate - * - Normal coordinate - */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_ObjToWorld : public QObject -{ - Q_OBJECT - -public: - // OBJ Vertice (Position index, Normal index and TexCoord index) - struct ObjVertice - { - ObjVertice() - : m_Values(3) - { - m_Values[0]= 0; - m_Values[1]= 0; - m_Values[2]= 0; - } - ObjVertice(int v1, int v2, int v3) - : m_Values(3) - { - m_Values[0]= v1; - m_Values[1]= v2; - m_Values[2]= v3; - } - - QVector m_Values; - }; - - // Material assignement - struct MatOffsetSize - { - MatOffsetSize() - : m_Offset(0) - , m_size(0) - {} - int m_Offset; - int m_size; - }; - - // Current OBJ Mesh - struct CurrentObjMesh - { - CurrentObjMesh(const QString materialName) - : m_pMesh(new GLC_Mesh()) - , m_Positions() - , m_Normals() - , m_Texels() - , m_Index() - , m_pLastOffsetSize(new MatOffsetSize()) - , m_Materials() - , m_NextFreeIndex(0) - , m_ObjVerticeIndexMap() - { - m_Materials.insert(materialName, m_pLastOffsetSize); - } - ~CurrentObjMesh() - { - QHash::iterator i= m_Materials.begin(); - while (m_Materials.constEnd() != i) - { - delete i.value(); - ++i; - } - } - GLC_Mesh* m_pMesh; - QList m_Positions; - QList m_Normals; - QList m_Texels; - //! The index of the current Mesh - IndexList m_Index; - // Pointer to the last matOffsetSize - MatOffsetSize* m_pLastOffsetSize; - // QHash containing material id and associated offset and size - QHash m_Materials; - //! The next free index - int m_NextFreeIndex; - //! The Hash table of obj vertice mapping to index - QHash m_ObjVerticeIndexMap; - }; - -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// - -public: - GLC_ObjToWorld(); - virtual ~GLC_ObjToWorld(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Create an GLC_World from an input OBJ File - GLC_World* CreateWorldFromObj(QFile &file); - - //! Get the list of attached files - inline QStringList listOfAttachedFileName() const{return m_ListOfAttachedFileName;} -//@} - -////////////////////////////////////////////////////////////////////// -// Private services functions -////////////////////////////////////////////////////////////////////// -private: - //! Return the name of the mtl file - QString getMtlLibFileName(QString); - - //! Scan a line previously extracted from OBJ file - void scanLigne(QString &); - - //! Change current group - void changeGroup(QString); - - //! Extract a 3D Vector from a string - QList extract3dVect(QString &); - - //! Extract a 2D Vector from a string - QList extract2dVect(QString &); - - //! Extract a face from a string - void extractFaceIndex(QString &); - - //! Set Current material index - void setCurrentMaterial(QString &line); - - //! Extract a vertex from a string - void extractVertexIndex(QString ligne, int &Coordinate, int &Normal, int &TextureCoordinate); - - //! set the OBJ File type - void setObjType(QString &); - - //! compute face normal - GLC_Vector3df computeNormal(GLuint, GLuint, GLuint); - - //! clear objToWorld allocate memmory - void clear(); - - //! Merge Mutli line in one - void mergeLines(QString*, QTextStream*); - - //! Add the current Obj mesh to the world - void addCurrentObjMeshToWorld(); - - - -////////////////////////////////////////////////////////////////////// -// Qt Signals -////////////////////////////////////////////////////////////////////// - signals: - void currentQuantum(int); - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - //! pointer to a GLC_World - GLC_World* m_pWorld; - - //! The Obj File name - QString m_FileName; - - //! the Obj Mtl loader - GLC_ObjMtlLoader* m_pMtlLoader; - - //! The current line number - int m_CurrentLineNumber; - - //! The current mesh - CurrentObjMesh* m_pCurrentObjMesh; - - //! Face type - FaceType m_FaceType; - - //! List of material already used by the current mesh - QHash m_CurrentMeshMaterials; - - //! Current material name - QString m_CurrentMaterialName; - - //! The list of attached file name - QStringList m_ListOfAttachedFileName; - - //! The position bulk data - QList m_Positions; - - //! The normal bulk data - QList m_Normals; - - //! The texture coordinate bulk data - QList m_Texels; -}; - -// To use ObjVertice as a QHash key -inline bool operator==(const GLC_ObjToWorld::ObjVertice& vertice1, const GLC_ObjToWorld::ObjVertice& vertice2) -{ return (vertice1.m_Values == vertice2.m_Values);} - -inline uint qHash(const GLC_ObjToWorld::ObjVertice& vertice) -{ return qHash(QString::number(vertice.m_Values.at(0)) + QString::number(vertice.m_Values.at(1)) + QString::number(vertice.m_Values.at(2)));} - - -#endif /*GLC_OBJTOWORLD_H_*/ diff --git a/ground/gcs/src/libs/glc_lib/io/glc_offtoworld.cpp b/ground/gcs/src/libs/glc_lib/io/glc_offtoworld.cpp deleted file mode 100644 index 25b786867..000000000 --- a/ground/gcs/src/libs/glc_lib/io/glc_offtoworld.cpp +++ /dev/null @@ -1,551 +0,0 @@ - -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_offtoworld.cpp implementation of the GLC_OffToWorld class. - -#include "glc_offtoworld.h" -#include "../sceneGraph/glc_world.h" -#include "../glc_fileformatexception.h" -#include "../sceneGraph/glc_structreference.h" -#include "../sceneGraph/glc_structinstance.h" -#include "../sceneGraph/glc_structoccurence.h" - -#include -#include -#include - -GLC_OffToWorld::GLC_OffToWorld() -: m_pWorld(NULL) -, m_FileName() -, m_CurrentLineNumber(0) -, m_pCurrentMesh(NULL) -, m_CurVertexIndex(0) -, m_NbrOfVertexs(0) -, m_NbrOfFaces(0) -, m_IsCoff(false) -, m_Is4off(false) -, m_PositionBulk() -, m_NormalBulk() -, m_ColorBulk() -, m_IndexList() -{ - -} - -GLC_OffToWorld::~GLC_OffToWorld() -{ - clear(); -} - -///////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -// Create an GLC_World from an input OFF File -GLC_World* GLC_OffToWorld::CreateWorldFromOff(QFile &file) -{ - clear(); - m_FileName= file.fileName(); - ////////////////////////////////////////////////////////////////// - // Test if the file exist and can be opened - ////////////////////////////////////////////////////////////////// - if (!file.open(QIODevice::ReadOnly)) - { - QString message(QString("GLC_OffToWorld::CreateWorldFromOff File ") + m_FileName + QString(" doesn't exist")); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotFound); - throw(fileFormatException); - } - - ////////////////////////////////////////////////////////////////// - // Init member - ////////////////////////////////////////////////////////////////// - m_pWorld= new GLC_World; - - // Create Working variables - int currentQuantumValue= 0; - int previousQuantumValue= 0; - - // Create the input file stream - QTextStream offStream(&file); - - // QString buffer - QString lineBuff; - - ////////////////////////////////////////////////////////////////// - // Check the OFF Header - ////////////////////////////////////////////////////////////////// - // Check if the file begin with "OFF" or "COFF" - ++m_CurrentLineNumber; - lineBuff= offStream.readLine(); - lineBuff= lineBuff.trimmed(); - if(offStream.atEnd() || (!lineBuff.startsWith("OFF") && !lineBuff.startsWith("COFF") && !lineBuff.startsWith("4OFF"))) - { - QString message= "GLC_OffToWorld::CreateWorldFromOff : OFF or COFF header not found"; - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported); - clear(); - throw(fileFormatException); - } - - // Set the COFF flag - m_IsCoff= lineBuff.startsWith("COFF"); - - // Set the 4OFF flag - m_Is4off= lineBuff.startsWith("4OFF"); - - // Create the mesh - m_pCurrentMesh= new GLC_Mesh(); - - // Set mesh color per vertex if needed - if (m_IsCoff) - { - m_pCurrentMesh->setColorPearVertex(true); - } - // Get the number of vertex and faces and skip comments - ++m_CurrentLineNumber; - lineBuff= offStream.readLine(); - lineBuff= lineBuff.trimmed(); - while(!offStream.atEnd() && lineBuff.startsWith(QChar('#'))) - { - ++m_CurrentLineNumber; - lineBuff= offStream.readLine(); - lineBuff= lineBuff.trimmed(); - } - extractNbrVertexsAndNbrFaces(lineBuff); - - ////////////////////////////////////////////////////////////////// - // Read Buffer and load vertexs - ////////////////////////////////////////////////////////////////// - emit currentQuantum(currentQuantumValue); - - for (int currentVertex= 0; currentVertex < m_NbrOfVertexs; ++currentVertex) - { - // Check it the end of file has been reached - if(offStream.atEnd()) - { - QString message= "GLC_OffToWorld::CreateWorldFromOff : This file seems to be incomplete"; - message.append("\nAt ligne : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported); - clear(); - throw(fileFormatException); - } - - ++m_CurrentLineNumber; - lineBuff= offStream.readLine(); - // Skip empty line - while (lineBuff.isEmpty()) - { - ++m_CurrentLineNumber; - lineBuff= offStream.readLine(); - } - // Add current vertex and color if needed to the mesh - extractVertex(lineBuff); - - // Update Current Quantum for progress bar usage. - currentQuantumValue = static_cast((static_cast(currentVertex) / (m_NbrOfVertexs + m_NbrOfFaces)) * 100); - if (currentQuantumValue > previousQuantumValue) - { - emit currentQuantum(currentQuantumValue); - } - previousQuantumValue= currentQuantumValue; - } - - ////////////////////////////////////////////////////////////////// - // Read Buffer and load faces - ////////////////////////////////////////////////////////////////// - for (int currentFace= 0; currentFace < m_NbrOfFaces; ++currentFace) - { - // Check it the end of file has been reached - if(offStream.atEnd()) - { - QString message= "GLC_OffToWorld::CreateWorldFromOff : This file seems to be incomplete"; - message.append("\nAt ligne : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported); - clear(); - throw(fileFormatException); - } - - ++m_CurrentLineNumber; - lineBuff= offStream.readLine(); - while (lineBuff.isEmpty()) - { - ++m_CurrentLineNumber; - lineBuff= offStream.readLine(); - } - - // Add current Face to the mesh - extractFaceIndex(lineBuff); - - // Update Current Quantum for progress bar usage. - currentQuantumValue = static_cast((static_cast(currentFace + m_NbrOfVertexs + 1) / (m_NbrOfVertexs + m_NbrOfFaces)) * 100); - if (currentQuantumValue > previousQuantumValue) - { - emit currentQuantum(currentQuantumValue); - } - previousQuantumValue= currentQuantumValue; - - } - - file.close(); - // Compute mesh normals - computeNormal(); - - m_pCurrentMesh->addVertice(m_PositionBulk.toVector()); - m_pCurrentMesh->addNormals(m_NormalBulk.toVector()); - if (!m_ColorBulk.isEmpty()) - { - m_pCurrentMesh->addColors(m_ColorBulk.toVector()); - } - m_pCurrentMesh->addTriangles(NULL, m_IndexList); - - m_pCurrentMesh->finish(); - GLC_3DRep* pRep= new GLC_3DRep(m_pCurrentMesh); - m_pCurrentMesh= NULL; - m_pWorld->rootOccurence()->addChild(new GLC_StructOccurence(pRep)); - - return m_pWorld; -} - -///////////////////////////////////////////////////////////////////// -// Private services Functions -////////////////////////////////////////////////////////////////////// - -// clear offToWorld allocate memmory and reset member -void GLC_OffToWorld::clear() -{ - if (NULL != m_pCurrentMesh) - { - delete m_pCurrentMesh; - m_pCurrentMesh= NULL; - } - m_pWorld= NULL; - m_FileName.clear(); - m_CurrentLineNumber= 0; - m_pCurrentMesh= NULL; - m_CurVertexIndex= 0; - m_NbrOfVertexs= 0; - m_NbrOfFaces= 0; - m_IsCoff= false; - m_Is4off= false; - m_PositionBulk.clear(); - m_NormalBulk.clear(); - m_ColorBulk.clear(); -} - -// Extract a Vertex from a string and add color component if needed -void GLC_OffToWorld::extractVertex(QString &line) -{ - - QTextStream stringVecteur(&line); - - QString xString, yString, zString; - - if (((stringVecteur >> xString >> yString >> zString).status() == QTextStream::Ok)) - { - bool xOk, yOk, zOk; - m_PositionBulk.append(xString.toFloat(&xOk)); - m_PositionBulk.append(yString.toFloat(&yOk)); - m_PositionBulk.append(zString.toFloat(&zOk)); - if (!(xOk && yOk && zOk)) - { - QString message= "GLC_OffToWorld::extractVertex : failed to convert vertex component to float"; - message.append("\nAt ligne : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - if (m_Is4off) - { - QString wString; - if (((stringVecteur >> wString).status() == QTextStream::Ok)) - { - float w; - bool wOk; - w= wString.toFloat(&wOk); - if (!wOk) - { - QString message= "GLC_OffToWorld::extractVertex : failed to convert vertex fourth component to float"; - message.append("\nAt ligne : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - const int lastValue= m_PositionBulk.size() - 1; - m_PositionBulk[lastValue - 2]= m_PositionBulk.at(lastValue - 2) / w; - m_PositionBulk[lastValue - 1]= m_PositionBulk.at(lastValue - 1) / w; - m_PositionBulk[lastValue]= m_PositionBulk.at(lastValue) / w; - } - else - { - QString message= "GLC_OffToWorld::extractVertex : failed to read vector fourth component"; - message.append("\nAt ligne : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - } - - // Test if the file is a COFF - if (m_IsCoff) - { - QString rString, gString, bString, aString; - - if (((stringVecteur >> rString >> gString >> bString >> aString).status() == QTextStream::Ok)) - { - bool rOk, gOk, bOk, aOk; - m_ColorBulk.append(rString.toFloat(&rOk)); - m_ColorBulk.append(gString.toFloat(&gOk)); - m_ColorBulk.append(bString.toFloat(&bOk)); - m_ColorBulk.append(aString.toFloat(&aOk)); - if (!(rOk && gOk && bOk && aOk)) - { - QString message= "GLC_OffToWorld::extractVertex : failed to convert color component to float"; - message.append("\nAt ligne : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - } - else - { - QString message= "GLC_OffToWorld::extractVertex : failed to read vertex color"; - message.append("\nAt ligne : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - } - - } - else - { - QString message= "GLC_OffToWorld::extractVertex : failed to read vector component"; - message.append("\nAt ligne : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - -} - -// Extract Number off Vertex and faces -void GLC_OffToWorld::extractNbrVertexsAndNbrFaces(QString &line) -{ - QTextStream stringVecteur(&line); - - QString xString, yString; - - if (((stringVecteur >> xString >> yString).status() == QTextStream::Ok)) - { - bool xOk, yOk; - m_NbrOfVertexs= xString.toInt(&xOk); - m_NbrOfFaces= yString.toInt(&yOk); - if (!(xOk && yOk)) - { - QString message= "GLC_OffToWorld::extractNbrVertexsAndNbrFaces : failed to convert text to int"; - message.append("\nAt ligne : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - } - else - { - QString message= "GLC_OffToWorld::extractNbrVertexsAndNbrFaces : failed to extract nbr of vertexs/faces"; - message.append("\nAt ligne : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - - } -} - -// Extract a face from a string -void GLC_OffToWorld::extractFaceIndex(QString &line) -{ - QString buff; - - QList indexList; - - ////////////////////////////////////////////////////////////////// - // Parse the line containing face index - ////////////////////////////////////////////////////////////////// - QTextStream streamFace(&line); - // Get the number of vertex - if((streamFace >> buff).status() != QTextStream::Ok) - { - QString message= "GLC_OffToWorld::extractFaceIndex failed to extract number of vertex index"; - message.append("\nAt line : "); - message.append(QString::number(m_CurrentLineNumber)); - message.append(QString("\n") + line); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - bool conversionOk; - // Convert the QString Number of vertex to int - int numberOfVertex= buff.toInt(&conversionOk); - if (!conversionOk) - { - QString message= "GLC_OffToWorld::extractFaceIndex failed to convert String to int"; - message.append("\nAt line : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - // Extract the face's vertexs index - for (int i= 0; i < numberOfVertex; ++i) - { - // Get a vertex index - if((streamFace >> buff).status() != QTextStream::Ok) - { - QString message= "GLC_OffToWorld::extractFaceIndex failed to extract vertex index"; - message.append("\nAt line : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - // Convert the QString vertex index into int - int index= buff.toInt(&conversionOk); - if (conversionOk) - { - indexList.append(index); - } - else - { - QString message= "GLC_ObjToWorld::extractFaceIndex failed to convert String to int"; - message.append("\nAt line : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - } - - // Trying to read face color - QString rString, gString, bString; - if((streamFace >> rString >> gString >> bString).status() == QTextStream::Ok) - { - // Fill color bulk data if needed - if (m_ColorBulk.isEmpty()) - { - const int size= m_PositionBulk.size() / 3 * 4; - for (int i= 0; i < size; ++i) - { - m_PositionBulk.append(0.0); - } - } - float r, g, b; - bool rOk, gOk, bOk; - r= rString.toFloat(&rOk); - g= gString.toFloat(&gOk); - b= bString.toFloat(&bOk); - if (!rOk || !gOk || !bOk) - { - QString message= "GLC_ObjToWorld::extractFaceIndex failed to convert String to float"; - message.append("\nAt line : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - for (int i= 0; i < numberOfVertex; ++i) - { - m_ColorBulk[indexList[i] * 4]= r; - m_ColorBulk[indexList[i] * 4 + 1]= g; - m_ColorBulk[indexList[i] * 4 + 2]= b; - m_ColorBulk[indexList[i] * 4 + 3]= 1.0f; - } - } - - // Add the face to index List - m_IndexList.append(indexList); -} - -// compute face normal -void GLC_OffToWorld::computeNormal() -{ - //qDebug() << "GLC_OffToWorld::computeNormal"; - //qDebug() << "Position size= " << m_PositionBulk.size(); - //qDebug() << "Normal size= " << m_NormalBulk.size(); - const QList* pData= &m_PositionBulk; - // Fill the list of normal - QList* pNormal= &m_NormalBulk; - const int normalCount= pData->size(); - for (int i= 0; i < normalCount; ++i) - { - pNormal->append(0.0f); - } - // Compute the normals and add them to the current mesh info - const int size= m_IndexList.size(); - double xn, yn, zn; - - - for (int i= 0; i < size; i+=3) - { - // Vertex 1 - xn= pData->at(m_IndexList.at(i) * 3); - yn= pData->at(m_IndexList.at(i) * 3 + 1); - zn= pData->at(m_IndexList.at(i) * 3 + 2); - const GLC_Vector3d vect1(xn, yn, zn); - - // Vertex 2 - xn= pData->at(m_IndexList.at(i + 1) * 3); - yn= pData->at(m_IndexList.at(i + 1) * 3 + 1); - zn= pData->at(m_IndexList.at(i + 1) * 3 + 2); - const GLC_Vector3d vect2(xn, yn, zn); - - // Vertex 3 - xn= pData->at(m_IndexList.at(i + 2) * 3); - yn= pData->at(m_IndexList.at(i + 2) * 3 + 1); - zn= pData->at(m_IndexList.at(i + 2) * 3 + 2); - const GLC_Vector3d vect3(xn, yn, zn); - - const GLC_Vector3d edge1(vect3 - vect2); - const GLC_Vector3d edge2(vect1 - vect2); - - GLC_Vector3d normal(edge1 ^ edge2); - normal.normalize(); - - GLC_Vector3df curNormal= normal.toVector3df(); - for (int curVertex= 0; curVertex < 3; ++curVertex) - { - (*pNormal)[m_IndexList.at(i + curVertex) * 3]= curNormal.x(); - (*pNormal)[m_IndexList.at(i + curVertex) * 3 + 1]= curNormal.y(); - (*pNormal)[m_IndexList.at(i + curVertex) * 3 + 2]= curNormal.z(); - } - } - -} - diff --git a/ground/gcs/src/libs/glc_lib/io/glc_offtoworld.h b/ground/gcs/src/libs/glc_lib/io/glc_offtoworld.h deleted file mode 100644 index c87d64ea7..000000000 --- a/ground/gcs/src/libs/glc_lib/io/glc_offtoworld.h +++ /dev/null @@ -1,157 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_offtoworld.h interface for the GLC_OffToWorld class. - -#ifndef GLC_OFFTOWORLD_H_ -#define GLC_OFFTOWORLD_H_ - -#include -#include -#include -#include -#include -#include - -#include "../maths/glc_vector3d.h" -#include "../maths/glc_vector2df.h" -#include "../maths/glc_vector3df.h" -#include "../geometry/glc_mesh.h" - -#include "../glc_config.h" - -class GLC_World; -class QGLContext; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_OffToWorld -/*! \brief GLC_OffToWorld : Create an GLC_World from off file */ - -/*! An GLC_OffToWorld extract the only mesh from an .off file \n - * List of elements extracted from the off - * - Vertex - * - Face - * - Normal coordinate - * - Face Color - * - Vertex Color - */ -////////////////////////////////////////////////////////////////////// - -class GLC_LIB_EXPORT GLC_OffToWorld : public QObject -{ - Q_OBJECT -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// - -public: - GLC_OffToWorld(); - virtual ~GLC_OffToWorld(); -//@} -////////////////////////////////////////////////////////////////////// -/*! @name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Create an GLC_World from an input OFF File - GLC_World* CreateWorldFromOff(QFile &file); -//@} - -////////////////////////////////////////////////////////////////////// -/*! @name Private services functions */ -//@{ -////////////////////////////////////////////////////////////////////// -private: - //! clear stlToWorld allocate memmory - void clear(); - - //! Extract a vertex from a string and add color component if needed - void extractVertex(QString &); - - //! Extract Number off Vertex and faces - void extractNbrVertexsAndNbrFaces(QString &); - - //! Extract a face from a string - void extractFaceIndex(QString &); - - //! compute faces normal - void computeNormal(); - - -//@} - -////////////////////////////////////////////////////////////////////// -// Qt Signals -////////////////////////////////////////////////////////////////////// - signals: - void currentQuantum(int); - -////////////////////////////////////////////////////////////////////// - /* Private members */ -////////////////////////////////////////////////////////////////////// -private: - //! pointer to a GLC_World - GLC_World* m_pWorld; - - //! The Stl File name - QString m_FileName; - - //! The current line number - int m_CurrentLineNumber; - - //! The current mesh - GLC_Mesh* m_pCurrentMesh; - - //! Index of the current vertex - int m_CurVertexIndex; - - //! The number of vertexs - int m_NbrOfVertexs; - - //! The number of faces - int m_NbrOfFaces; - - //! The OFF is a COFF - bool m_IsCoff; - - //! The OFF is 4OFF - bool m_Is4off; - - // The position bulk data - QList m_PositionBulk; - - //! The Normal Bulk data - QList m_NormalBulk; - - //! The color Bulk data - QList m_ColorBulk; - - //! The indexList - IndexList m_IndexList; - - - - -}; - -#endif /*GLC_OFFTOWORLD_H_*/ diff --git a/ground/gcs/src/libs/glc_lib/io/glc_stltoworld.cpp b/ground/gcs/src/libs/glc_lib/io/glc_stltoworld.cpp deleted file mode 100644 index 72138e88d..000000000 --- a/ground/gcs/src/libs/glc_lib/io/glc_stltoworld.cpp +++ /dev/null @@ -1,428 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_stltoworld.cpp implementation of the GLC_StlToWorld class. - -#include "glc_stltoworld.h" -#include "../sceneGraph/glc_world.h" -#include "../glc_fileformatexception.h" -#include "../sceneGraph/glc_structreference.h" -#include "../sceneGraph/glc_structinstance.h" -#include "../sceneGraph/glc_structoccurence.h" - -#include -#include -#include -#include - -GLC_StlToWorld::GLC_StlToWorld() -: QObject() -, m_pWorld(NULL) -, m_FileName() -, m_CurrentLineNumber(0) -, m_StlStream() -, m_pCurrentMesh(NULL) -, m_CurrentFace() -, m_VertexBulk() -, m_NormalBulk() -, m_CurrentIndex(0) -{ - -} - -GLC_StlToWorld::~GLC_StlToWorld() -{ - clear(); -} - -///////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -// Create an GLC_World from an input STL File -GLC_World* GLC_StlToWorld::CreateWorldFromStl(QFile &file) -{ - clear(); - m_FileName= file.fileName(); - ////////////////////////////////////////////////////////////////// - // Test if the file exist and can be opened - ////////////////////////////////////////////////////////////////// - if (!file.open(QIODevice::ReadOnly)) - { - QString message(QString("GLC_StlToWorld::CreateWorldFromStl File ") + m_FileName + QString(" doesn't exist")); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotFound); - throw(fileFormatException); - } - ////////////////////////////////////////////////////////////////// - // Init member - ////////////////////////////////////////////////////////////////// - m_pWorld= new GLC_World; - - // Create Working variables - int currentQuantumValue= 0; - int previousQuantumValue= 0; - int numberOfLine= 0; - - // Attach the stream to the file - m_StlStream.setDevice(&file); - - // QString buffer - QString lineBuff; - - ////////////////////////////////////////////////////////////////// - // Count the number of lines of the STL file - ////////////////////////////////////////////////////////////////// - while (!m_StlStream.atEnd()) - { - ++numberOfLine; - m_StlStream.readLine(); - } - - ////////////////////////////////////////////////////////////////// - // Reset the stream - ////////////////////////////////////////////////////////////////// - m_StlStream.resetStatus(); - m_StlStream.seek(0); - ////////////////////////////////////////////////////////////////// - // Read Buffer and create the world - ////////////////////////////////////////////////////////////////// - - emit currentQuantum(currentQuantumValue); - m_CurrentLineNumber= 0; - // Search Object section in the STL - - // Test if the STL File is ASCII or Binary - ++m_CurrentLineNumber; - lineBuff= m_StlStream.readLine(); - lineBuff= lineBuff.trimmed().toLower(); - if (!lineBuff.startsWith("solid")) - { - // The STL File is not ASCII trying to load Binary STL File - m_pCurrentMesh= new GLC_Mesh(); - file.reset(); - LoadBinariStl(file); - m_pCurrentMesh->addTriangles(NULL, m_CurrentFace); - m_CurrentFace.clear(); - m_pCurrentMesh->addVertice(m_VertexBulk.toVector()); - m_VertexBulk.clear(); - m_pCurrentMesh->addNormals(m_NormalBulk.toVector()); - m_NormalBulk.clear(); - m_pCurrentMesh->finish(); - GLC_3DRep* pRep= new GLC_3DRep(m_pCurrentMesh); - m_pCurrentMesh= NULL; - m_pWorld->rootOccurence()->addChild(new GLC_StructOccurence(pRep)); - } - else - { - // The STL File is ASCII - lineBuff.remove(0, 5); - lineBuff= lineBuff.trimmed(); - m_pCurrentMesh= new GLC_Mesh(); - m_pCurrentMesh->setName(lineBuff); - // Read the mesh facet - while (!m_StlStream.atEnd()) - { - scanFacet(); - - currentQuantumValue = static_cast((static_cast(m_CurrentLineNumber) / numberOfLine) * 100); - if (currentQuantumValue > previousQuantumValue) - { - emit currentQuantum(currentQuantumValue); - } - previousQuantumValue= currentQuantumValue; - } - } - file.close(); - - return m_pWorld; -} - -///////////////////////////////////////////////////////////////////// -// Private services Functions -////////////////////////////////////////////////////////////////////// - -// clear stlToWorld allocate memmory and reset member -void GLC_StlToWorld::clear() -{ - if (NULL != m_pCurrentMesh) - { - delete m_pCurrentMesh; - m_pCurrentMesh= NULL; - } - m_pWorld= NULL; - m_FileName.clear(); - m_CurrentLineNumber= 0; - m_pCurrentMesh= NULL; - m_CurrentFace.clear(); -} - -// Scan a line previously extracted from STL file -void GLC_StlToWorld::scanFacet() -{ -////////////////////////////////////////////// Test end of solid section//////////////////// - ++m_CurrentLineNumber; - QString lineBuff(m_StlStream.readLine()); - lineBuff= lineBuff.trimmed().toLower(); - // Test if this is the end of current solid - if (lineBuff.startsWith("endsolid") || lineBuff.startsWith("end solid")) - { - m_pCurrentMesh->addTriangles(NULL, m_CurrentFace); - m_CurrentFace.clear(); - m_pCurrentMesh->addVertice(m_VertexBulk.toVector()); - m_VertexBulk.clear(); - m_pCurrentMesh->addNormals(m_NormalBulk.toVector()); - m_NormalBulk.clear(); - - m_pCurrentMesh->finish(); - GLC_3DRep* pRep= new GLC_3DRep(m_pCurrentMesh); - m_pCurrentMesh= NULL; - m_pWorld->rootOccurence()->addChild(new GLC_StructOccurence(pRep)); - return; - } - // Test if this is the start of new solid - if (lineBuff.startsWith("solid")) - { - // The STL File is ASCII - lineBuff.remove(0, 5); - lineBuff= lineBuff.trimmed(); - m_pCurrentMesh= new GLC_Mesh(); - m_pCurrentMesh->setName(lineBuff); - return; - } - -////////////////////////////////////////////// Facet Normal//////////////////////////////// - // lineBuff Must begin with "facet normal" - if (!lineBuff.startsWith("facet normal")) - { - QString message= "GLC_StlToWorld::scanFacet : \"facet normal\" not found!"; - message.append("\nAt line : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - lineBuff.remove(0,12); // Remove first 12 chars - lineBuff= lineBuff.trimmed().toLower(); - GLC_Vector3df cur3dVect= extract3dVect(lineBuff); - for (int i= 0; i < 3; ++i) - { - m_NormalBulk.append(cur3dVect.x()); - m_NormalBulk.append(cur3dVect.y()); - m_NormalBulk.append(cur3dVect.z()); - } - -////////////////////////////////////////////// Outer Loop//////////////////////////////// - ++m_CurrentLineNumber; - lineBuff= m_StlStream.readLine(); - lineBuff= lineBuff.trimmed().toLower(); - // lineBuff Must begin with "outer loop" - if (!lineBuff.startsWith("outer loop")) - { - QString message= "GLC_StlToWorld::scanFacet : \"outer loop\" not found!"; - message.append("\nAt line : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - -////////////////////////////////////////////// Vertex //////////////////////////////// - - for (int i= 0; i < 3; ++i) - { - ++m_CurrentLineNumber; - lineBuff= m_StlStream.readLine(); - lineBuff= lineBuff.trimmed().toLower(); - // lineBuff Must begin with "vertex" - if (!lineBuff.startsWith("vertex")) - { - QString message= "GLC_StlToWorld::scanFacet : \"vertex\" not found!"; - message.append("\nAt line : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - lineBuff.remove(0,6); // Remove first 6 chars - lineBuff= lineBuff.trimmed(); - - cur3dVect= extract3dVect(lineBuff); - m_VertexBulk.append(cur3dVect.x()); - m_VertexBulk.append(cur3dVect.y()); - m_VertexBulk.append(cur3dVect.z()); - - m_CurrentFace.append(m_CurrentIndex); - ++m_CurrentIndex; - } - -////////////////////////////////////////////// End Loop//////////////////////////////// - ++m_CurrentLineNumber; - lineBuff= m_StlStream.readLine(); - lineBuff= lineBuff.trimmed().toLower(); - // lineBuff Must begin with "endloop" - if (!lineBuff.startsWith("endloop")) - { - QString message= "GLC_StlToWorld::scanFacet : \"endloop\" not found!"; - message.append("\nAt line : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - -////////////////////////////////////////////// End Facet//////////////////////////////// - ++m_CurrentLineNumber; - lineBuff= m_StlStream.readLine(); - lineBuff= lineBuff.trimmed().toLower(); - // lineBuff Must begin with "endfacet" - if (!lineBuff.startsWith("endfacet")) - { - QString message= "GLC_StlToWorld::scanFacet : \"endfacet\" not found!"; - message.append("\nAt line : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - -} - -// Extract a Vector from a string -GLC_Vector3df GLC_StlToWorld::extract3dVect(QString &line) -{ - float x=0.0f; - float y=0.0f; - float z=0.0f; - - GLC_Vector3df vectResult; - QTextStream stringVecteur(&line); - - QString xString, yString, zString; - - if (((stringVecteur >> xString >> yString >> zString).status() == QTextStream::Ok)) - { - bool xOk, yOk, zOk; - x= xString.toFloat(&xOk); - y= yString.toFloat(&yOk); - z= zString.toFloat(&zOk); - if (!(xOk && yOk && zOk)) - { - QString message= "GLC_StlToWorld::extract3dVect : failed to convert vector component to float"; - message.append("\nAt ligne : "); - message.append(QString::number(m_CurrentLineNumber)); - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - else - { - vectResult.setVect(x, y, z); - } - } - - return vectResult; - -} -// Load Binarie STL File -void GLC_StlToWorld::LoadBinariStl(QFile &file) -{ - // Create Working variables - int currentQuantumValue= 0; - int previousQuantumValue= 0; - - QDataStream stlBinFile(&file); - stlBinFile.setVersion(QDataStream::Qt_4_6); - stlBinFile.setFloatingPointPrecision(QDataStream::SinglePrecision); - stlBinFile.setByteOrder(QDataStream::LittleEndian); - - // Skip 80 Bytes STL header - int SkipedData= stlBinFile.skipRawData(80); - // Check if an error occur - if (-1 == SkipedData) - { - QString message= "GLC_StlToWorld::LoadBinariStl : Failed to skip Header of binary STL"; - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - // Read the number of facet - quint32 numberOfFacet= 0; - stlBinFile >> numberOfFacet; - // Check if an error occur - if (QDataStream::Ok != stlBinFile.status()) - { - QString message= "GLC_StlToWorld::LoadBinariStl : Failed to read the number of facets of binary STL"; - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - for (quint32 i= 0; i < numberOfFacet; ++i) - { - // Extract the facet normal - float nx, ny, nz; - stlBinFile >> nx >> ny >> nz; - // Check if an error occur - if (QDataStream::Ok != stlBinFile.status()) - { - QString message= "GLC_StlToWorld::LoadBinariStl : Failed to read the Normal of binary STL"; - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - - // Extract the 3 Vertexs - for (int j= 0; j < 3; ++j) - { - float x, y, z; - stlBinFile >> x >> y >> z; - // Check if an error occur - if (QDataStream::Ok != stlBinFile.status()) - { - QString message= "GLC_StlToWorld::LoadBinariStl : Failed to read the Vertex of binary STL"; - GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat); - clear(); - throw(fileFormatException); - } - m_VertexBulk.append(x); - m_VertexBulk.append(y); - m_VertexBulk.append(z); - - m_NormalBulk.append(nx); - m_NormalBulk.append(ny); - m_NormalBulk.append(nz); - - m_CurrentFace.append(m_CurrentIndex); - ++m_CurrentIndex; - } - currentQuantumValue = static_cast((static_cast(i + 1) / numberOfFacet) * 100); - if (currentQuantumValue > previousQuantumValue) - { - emit currentQuantum(currentQuantumValue); - } - previousQuantumValue= currentQuantumValue; - - // Skip 2 fill-bytes not needed !!!! - stlBinFile.skipRawData(2); - - } -} - diff --git a/ground/gcs/src/libs/glc_lib/io/glc_stltoworld.h b/ground/gcs/src/libs/glc_lib/io/glc_stltoworld.h deleted file mode 100644 index 7590c4e93..000000000 --- a/ground/gcs/src/libs/glc_lib/io/glc_stltoworld.h +++ /dev/null @@ -1,129 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_stltoworld.h interface for the GLC_StlToWorld class. - -#ifndef GLC_STLTOWORLD_H_ -#define GLC_STLTOWORLD_H_ - -#include -#include -#include -#include - -#include "../geometry/glc_mesh.h" -#include "../maths/glc_vector3df.h" - -#include "../glc_config.h" - -class GLC_World; -class QGLContext; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_StlToWorld -/*! \brief GLC_StlToWorld : Create an GLC_World from stl file */ - -/*! An GLC_StlToWorld extract the only mesh from an .stl file \n - * List of elements extracted from the STL - * - Vertex - * - Face - * - Normal coordinate - */ -////////////////////////////////////////////////////////////////////// - -class GLC_LIB_EXPORT GLC_StlToWorld : public QObject -{ - Q_OBJECT -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - GLC_StlToWorld(); - virtual ~GLC_StlToWorld(); -//@} -////////////////////////////////////////////////////////////////////// -/*! @name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Create and return an GLC_World* from an input STL File - GLC_World* CreateWorldFromStl(QFile &file); -//@} - -////////////////////////////////////////////////////////////////////// -/*! @name Private services functions */ -//@{ -////////////////////////////////////////////////////////////////////// -private: - //! clear stlToWorld allocate memmory - void clear(); - //! Scan a line previously extracted from STL file - void scanFacet(); - //! Extract a 3D Vector from a string - GLC_Vector3df extract3dVect(QString &); - //! Load Binarie STL File - void LoadBinariStl(QFile &); - - - -//@} - -////////////////////////////////////////////////////////////////////// -// Qt Signals -////////////////////////////////////////////////////////////////////// - signals: - void currentQuantum(int); - -////////////////////////////////////////////////////////////////////// - /* Private members */ -////////////////////////////////////////////////////////////////////// -private: - //! pointer to a GLC_World - GLC_World* m_pWorld; - - //! The Stl File name - QString m_FileName; - - //! The current line number - int m_CurrentLineNumber; - - //! The Text Stream - QTextStream m_StlStream; - - //! The current mesh - GLC_Mesh* m_pCurrentMesh; - - //! Current face index - IndexList m_CurrentFace; - - //! Vertex Bulk data - QList m_VertexBulk; - - //! Normal Bulk data - QList m_NormalBulk; - - //! The current index - GLuint m_CurrentIndex; -}; - -#endif /*GLC_STLTOWORLD_H_*/ diff --git a/ground/gcs/src/libs/glc_lib/io/glc_worldreaderhandler.h b/ground/gcs/src/libs/glc_lib/io/glc_worldreaderhandler.h deleted file mode 100644 index 20a3a62ef..000000000 --- a/ground/gcs/src/libs/glc_lib/io/glc_worldreaderhandler.h +++ /dev/null @@ -1,46 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_worldreaderplugin.h interface for reading world from 3D model - -#ifndef GLC_WORLDREADERHANDLER_H_ -#define GLC_WORLDREADERHANDLER_H_ - -class QFile; -#include - -#include "../sceneGraph/glc_world.h" - -class GLC_WorldReaderHandler -{ -public: - virtual ~GLC_WorldReaderHandler(){} - - //! Read a world from the given file - virtual GLC_World read(QFile* pFile)= 0; - - //! Get the list of attached files - virtual QStringList listOfAttachedFileName() const{return QStringList();} - -}; - -#endif /* GLC_WORLDREADERHANDLER_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/io/glc_worldreaderplugin.h b/ground/gcs/src/libs/glc_lib/io/glc_worldreaderplugin.h deleted file mode 100644 index 629eb5272..000000000 --- a/ground/gcs/src/libs/glc_lib/io/glc_worldreaderplugin.h +++ /dev/null @@ -1,47 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_worldreaderplugin.h interface for reading world from 3D model - -#ifndef GLC_WORLDREADERPLUGIN_H_ -#define GLC_WORLDREADERPLUGIN_H_ - -#include -#include - -#include "glc_worldreaderhandler.h" - -class GLC_WorldReaderPlugin -{ -public: - virtual ~GLC_WorldReaderPlugin() {} - - //! Return the list of 3D model keys this plugin support - virtual QStringList keys() const =0; - - //! Return a reader handler - virtual GLC_WorldReaderHandler* readerHandler()= 0; -}; - -Q_DECLARE_INTERFACE(GLC_WorldReaderPlugin, "com.GLC_lib.GLC_WorldReaderPlugin") - -#endif /* GLC_WORLDREADERPLUGIN_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/io/glc_worldto3ds.cpp b/ground/gcs/src/libs/glc_lib/io/glc_worldto3ds.cpp deleted file mode 100644 index 32dd986e4..000000000 --- a/ground/gcs/src/libs/glc_lib/io/glc_worldto3ds.cpp +++ /dev/null @@ -1,497 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_worldto3ds.cpp implementation of the GLC_WorldTo3ds class. - -#include -#include - -#include "../geometry/glc_3drep.h" -#include "../geometry/glc_geometry.h" -#include "../geometry/glc_mesh.h" - -#include "../shading/glc_material.h" - -// Lib3ds Header -#include "3rdparty/lib3ds/file.h" -#include "3rdparty/lib3ds/mesh.h" -#include "3rdparty/lib3ds/node.h" -#include "3rdparty/lib3ds/matrix.h" -#include "3rdparty/lib3ds/material.h" - -#include "glc_worldto3ds.h" - -GLC_WorldTo3ds::GLC_WorldTo3ds(const GLC_World& world) -: QObject() -, m_World(world) -, m_pLib3dsFile(NULL) -, m_FileName() -, m_ReferenceToMesh() -, m_NameToMaterial() -, m_pRootLib3dsNode(NULL) -, m_CurrentNodeId(0) -, m_OccIdToNodeId() -, m_CurrentMeshIndex(0) -, m_UseAbsolutePosition(false) -, m_TextureToFileName() -{ - - -} - -GLC_WorldTo3ds::~GLC_WorldTo3ds() -{ - -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// -bool GLC_WorldTo3ds::exportToFile(const QString& fileName, bool useAbsolutePosition) -{ - m_ReferenceToMesh.clear(); - m_NameToMaterial.clear(); - m_pRootLib3dsNode= NULL; - m_CurrentNodeId= 0; - m_OccIdToNodeId.clear(); - m_CurrentMeshIndex= 0; - m_UseAbsolutePosition= useAbsolutePosition; - m_TextureToFileName.clear(); - - m_FileName= fileName; - bool subject= false; - { - QFile exportFile(m_FileName); - subject= exportFile.open(QIODevice::WriteOnly); - exportFile.close(); - } - if (subject) - { - m_pLib3dsFile= lib3ds_file_new(); - saveWorld(); - subject= lib3ds_file_save(m_pLib3dsFile, fileName.toLatin1().data()); - } - - return subject; -} - - -////////////////////////////////////////////////////////////////////// -// Private services functions -////////////////////////////////////////////////////////////////////// - -void GLC_WorldTo3ds::saveWorld() -{ - if (!m_UseAbsolutePosition) - { - saveMeshes(); - } - - // Save node structure - GLC_StructOccurence* pRoot= m_World.rootOccurence(); - const int childCount= pRoot->childCount(); - for (int i= 0; i < childCount; ++i) - { - saveBranch(pRoot->child(i)); - } -} - -void GLC_WorldTo3ds::saveMeshes() -{ - // Retrieve the list of mesh and save them into the 3ds - QList refList= m_World.references(); - const int refCount= refList.count(); - for (int i= 0; i < refCount; ++i) - { - GLC_StructReference* pRef= refList.at(i); - if (pRef->hasRepresentation()) - { - GLC_3DRep* pRep= dynamic_cast(pRef->representationHandle()); - if (NULL != pRep) - { - // This reference has a mesh - const QString meshName= pRef->name() + '_' + QString::number(++m_CurrentMeshIndex); - QList meshes= createMeshsFrom3DRep(pRep, meshName); - { - const int count= meshes.count(); - for (int i= 0; i < count; ++i) - { - lib3ds_file_insert_mesh(m_pLib3dsFile, meshes.at(i)); - m_ReferenceToMesh.insertMulti(pRef, meshes.at(i)); - } - } - } - } - } -} - -void GLC_WorldTo3ds::saveBranch(GLC_StructOccurence* pOcc) -{ - createNodeFromOccurrence(pOcc); - - const int childCount= pOcc->childCount(); - for (int i= 0; i < childCount; ++i) - { - saveBranch(pOcc->child(i)); - } -} - -void GLC_WorldTo3ds::createNodeFromOccurrence(GLC_StructOccurence* pOcc) -{ - Lib3dsNode* p3dsNode = lib3ds_node_new_object(); - p3dsNode->node_id= m_CurrentNodeId; - m_OccIdToNodeId.insert(pOcc->id(), m_CurrentNodeId++); - - if (pOcc->parent() == m_World.rootOccurence()) - { - p3dsNode->parent_id= LIB3DS_NO_PARENT; - } - else - { - Q_ASSERT(m_OccIdToNodeId.contains(pOcc->parent()->id())); - p3dsNode->parent_id= m_OccIdToNodeId.value(pOcc->parent()->id()); - } - - lib3ds_file_insert_node(m_pLib3dsFile, p3dsNode); - - GLC_StructReference* pRef= pOcc->structReference(); - if (m_UseAbsolutePosition) - { - if (pOcc->structReference()->hasRepresentation()) - { - GLC_3DRep* pRep= dynamic_cast(pOcc->structReference()->representationHandle()); - if (NULL != pRep) - { - // This reference has a mesh - const GLC_Matrix4x4 matrix= pOcc->absoluteMatrix(); - const QString meshName= pRef->name() + '_' + QString::number(++m_CurrentMeshIndex); - QList meshes= createMeshsFrom3DRep(pRep, meshName, matrix); - - const int meshCount= meshes.count(); - for (int i= 0; i < meshCount; ++i) - { - lib3ds_file_insert_mesh(m_pLib3dsFile, meshes.at(i)); - } - - if (meshCount > 1) - { - for (int i= 0; i < meshCount; ++i) - { - - Lib3dsNode* pCurrent3dsNode = lib3ds_node_new_object(); - pCurrent3dsNode->node_id= m_CurrentNodeId++; - pCurrent3dsNode->parent_id= p3dsNode->node_id; - - strcpy(pCurrent3dsNode->name, meshes.at(i)->name); - lib3ds_file_insert_node(m_pLib3dsFile, pCurrent3dsNode); - } - } - else if (!meshes.isEmpty()) - { - strcpy(p3dsNode->name, meshes.first()->name); - } - } - } - } - else - { - // Node matrix - const GLC_Matrix4x4 matrix= pOcc->structInstance()->relativeMatrix(); - setNodePosition(p3dsNode, matrix); - - // Set mesh name if necessary - if (m_ReferenceToMesh.contains(pRef)) - { - - QList meshes= m_ReferenceToMesh.values(pRef); - const int meshCount= meshes.count(); - if (meshCount > 1) - { - for (int i= 0; i < meshCount; ++i) - { - - Lib3dsNode* pCurrent3dsNode = lib3ds_node_new_object(); - pCurrent3dsNode->node_id= m_CurrentNodeId++; - pCurrent3dsNode->parent_id= p3dsNode->node_id; - - strcpy(pCurrent3dsNode->name, meshes.at(i)->name); - lib3ds_file_insert_node(m_pLib3dsFile, pCurrent3dsNode); - } - } - else - { - strcpy(p3dsNode->name, m_ReferenceToMesh.value(pRef)->name); - } - - } - } -} - -QList GLC_WorldTo3ds::createMeshsFrom3DRep(GLC_3DRep* pRep, const QString& name, const GLC_Matrix4x4& matrix) -{ - QList subject; - int bodyIndex= 0; - - const int bodyCount= pRep->numberOfBody(); - for (int i= 0; i < bodyCount; ++i) - { - GLC_Mesh* pCurrentMesh= dynamic_cast(pRep->geomAt(i)); - if ((NULL != pCurrentMesh) && !pCurrentMesh->isEmpty()) - { - bool deleteCurrentMesh= false; - if (pCurrentMesh->lodCount() > 1) - { - // Keep only the first level of detail - pCurrentMesh= pCurrentMesh->createMeshOfGivenLod(0); - deleteCurrentMesh= true; - } - const QString bodyMeshName= name + '_' + QString::number(bodyIndex++); - if (matrix.type() != GLC_Matrix4x4::Identity) - { - if (!deleteCurrentMesh) - { - pCurrentMesh= new GLC_Mesh(*pCurrentMesh); - deleteCurrentMesh= true; - } - pCurrentMesh->transformVertice(matrix); - Q_ASSERT(!pCurrentMesh->isEmpty()); - } - Lib3dsMesh* p3dsMesh= create3dsMeshFromGLC_Mesh(pCurrentMesh, bodyMeshName); - - if (deleteCurrentMesh) delete pCurrentMesh; - subject.append(p3dsMesh); - } - } - - return subject; -} - -Lib3dsMesh* GLC_WorldTo3ds::create3dsMeshFromGLC_Mesh(GLC_Mesh* pMesh, const QString& meshName) -{ - // Create empty 3ds mesh with the given name - Lib3dsMesh* p3dsMesh= lib3ds_mesh_new(meshName.toLatin1().data()); - - const int stride= 3; - - GLfloatVector vertice= pMesh->positionVector(); - const uint pointsCount= vertice.count() / stride; - - // Add points to the 3DS mesh - lib3ds_mesh_new_point_list(p3dsMesh, pointsCount); - - for (uint i= 0; i < pointsCount; ++i) - { - Lib3dsPoint point; - point.pos[0]= vertice[i * 3]; - point.pos[1]= vertice[i * 3 + 1]; - point.pos[2]= vertice[i * 3 + 2]; - - p3dsMesh->pointL[i]= point; - } - - // Add texel to the 3DS mesh - GLfloatVector texelVector= pMesh->texelVector(); - if(!texelVector.isEmpty()) - { - lib3ds_mesh_new_texel_list(p3dsMesh, pointsCount); - for (uint i= 0; i < pointsCount; ++i) - { - p3dsMesh->texelL[i][0]= texelVector[i * 2]; - p3dsMesh->texelL[i][1]= texelVector[i * 2 + 1]; - } - } - - // Add faces to the 3ds mesh - const uint totalFaceCount= pMesh->faceCount(0); - lib3ds_mesh_new_face_list(p3dsMesh, totalFaceCount); - - QSet materialSet= pMesh->materialSet(); - QSet::iterator iMat= materialSet.begin(); - uint currentFaceIndex= 0; - while(iMat != materialSet.end()) - { - GLC_Material* pCurrentGLCMat= *iMat; - Lib3dsMaterial* pMaterial= get3dsMaterialFromGLC_Material(pCurrentGLCMat); - IndexList currentTriangleIndex= pMesh->getEquivalentTrianglesStripsFansIndex(0, pCurrentGLCMat->id()); - const int faceCount= currentTriangleIndex.count() / 3; - for (int i= 0; i < faceCount; ++i) - { - Lib3dsFace face; - strcpy(face.material, pMaterial->name); - - face.points[0]= currentTriangleIndex.at(i * 3); - face.points[1]= currentTriangleIndex.at(i * 3 + 1); - face.points[2]= currentTriangleIndex.at(i * 3 + 2); - - p3dsMesh->faceL[currentFaceIndex++]= face; - Q_ASSERT(currentFaceIndex <= totalFaceCount); - } - ++iMat; - } - - return p3dsMesh; -} - -Lib3dsMaterial* GLC_WorldTo3ds::get3dsMaterialFromGLC_Material(GLC_Material* pMat) -{ - Lib3dsMaterial* pSubject= NULL; - const QString matName= materialName(pMat); - if (m_NameToMaterial.contains(matName)) - { - pSubject= m_NameToMaterial.value(matName); - } - else - { - pSubject= create3dsMaterialFromGLC_Material(pMat, matName); - } - - return pSubject; -} - -Lib3dsMaterial* GLC_WorldTo3ds::create3dsMaterialFromGLC_Material(GLC_Material* pMat, const QString& matName) -{ - Lib3dsMaterial* pSubject= lib3ds_material_new(); - strcpy(pSubject->name, matName.toLatin1().data()); - - - // Ambient Color - QColor ambient= pMat->ambientColor(); - pSubject->ambient[0]= static_cast(ambient.redF()); - pSubject->ambient[1]= static_cast(ambient.greenF()); - pSubject->ambient[2]= static_cast(ambient.blueF()); - pSubject->ambient[3]= static_cast(ambient.alphaF()); - - // Diffuse Color - QColor diffuse= pMat->diffuseColor(); - pSubject->diffuse[0]= static_cast(diffuse.redF()); - pSubject->diffuse[1]= static_cast(diffuse.greenF()); - pSubject->diffuse[2]= static_cast(diffuse.blueF()); - pSubject->diffuse[3]= static_cast(diffuse.alphaF()); - - // Specular Color - QColor specular= pMat->specularColor(); - pSubject->specular[0]= static_cast(specular.redF()); - pSubject->specular[1]= static_cast(specular.greenF()); - pSubject->specular[2]= static_cast(specular.blueF()); - pSubject->specular[3]= static_cast(specular.alphaF()); - - - // Shininess - pSubject->shininess= pMat->shininess(); - - // Transparency - - pSubject->transparency= 1.0f - static_cast(pMat->opacity()); - - // Texture - if (pMat->hasTexture()) - { - if (!m_TextureToFileName.contains(pMat->textureHandle())) - { - QString filePath= QFileInfo(m_FileName).absolutePath(); - QString textureName= matName; - QImage textureImage= pMat->textureHandle()->imageOfTexture(); - if (!pMat->textureFileName().isEmpty()) - { - textureName= QFileInfo(pMat->textureFileName()).fileName(); - if (QFileInfo(pMat->textureFileName()).exists()) - { - textureImage.load(pMat->textureFileName()); - } - } - else - { - textureName= textureName + ".jpg"; - } - textureName= textureName.right(63); - - if (!textureImage.isNull()) - { - const QString type(QFileInfo(textureName).suffix()); - QString newTextureFile= filePath + '/' + textureName; - textureImage.save(newTextureFile, type.toUpper().toLatin1().data()); - strcpy(pSubject->texture1_map.name, textureName.toLatin1().data()); - m_TextureToFileName.insert(pMat->textureHandle(), textureName); - } - } - else - { - QString textureName= m_TextureToFileName.value(pMat->textureHandle()); - strcpy(pSubject->texture1_map.name, textureName.toLatin1().data()); - } - - } - - lib3ds_file_insert_material(m_pLib3dsFile, pSubject); - m_NameToMaterial.insert(matName, pSubject); - - return pSubject; -} - -QString GLC_WorldTo3ds::materialName(GLC_Material* pMat) const -{ - QString subject= pMat->name() + '_' + QString::number(pMat->id()); - subject= subject.right(63); - - return subject; -} - -void GLC_WorldTo3ds::setNodePosition(Lib3dsNode* pNode, const GLC_Matrix4x4& matrix) -{ - Lib3dsObjectData *pObjectData= &pNode->data.object; - - GLC_Matrix4x4 isoMatrix(matrix.isometricMatrix()); - // Translation - Lib3dsLin3Key* pLin3Key= lib3ds_lin3_key_new(); - pLin3Key->value[0]= isoMatrix.getData()[12]; - pLin3Key->value[1]= isoMatrix.getData()[13]; - pLin3Key->value[2]= isoMatrix.getData()[14]; - - pLin3Key->tcb.frame= 1; - pObjectData->pos_track.keyL= pLin3Key; - - - // Scaling - Lib3dsLin3Key* pScale3Key= lib3ds_lin3_key_new(); - pScale3Key->value[0]= static_cast(matrix.scalingX()); - pScale3Key->value[1]= static_cast(matrix.scalingY()); - pScale3Key->value[2]= static_cast(matrix.scalingZ()); - - pScale3Key->tcb.frame= 1; - pObjectData->scl_track.keyL= pScale3Key; - - // Rotation - - Lib3dsQuatKey* pQuatKey= lib3ds_quat_key_new(); - - QQuaternion quaternion= matrix.quaternion(); - QPair pair= matrix.rotationVectorAndAngle(); - - pQuatKey->angle= static_cast(pair.second); - pQuatKey->axis[0]= static_cast(pair.first.x()); - pQuatKey->axis[1]= static_cast(pair.first.y()); - pQuatKey->axis[2]= static_cast(pair.first.z()); - - pQuatKey->tcb.frame= 1; - - pObjectData->rot_track.keyL= pQuatKey; - -} diff --git a/ground/gcs/src/libs/glc_lib/io/glc_worldto3ds.h b/ground/gcs/src/libs/glc_lib/io/glc_worldto3ds.h deleted file mode 100644 index 833d912e5..000000000 --- a/ground/gcs/src/libs/glc_lib/io/glc_worldto3ds.h +++ /dev/null @@ -1,152 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_worldto3ds.h interface for the GLC_WorldTo3ds class. - -#ifndef GLC_WORLDTO3DS_H_ -#define GLC_WORLDTO3DS_H_ - -#include -#include - -#include "../sceneGraph/glc_world.h" - -#include "../glc_config.h" - -struct Lib3dsFile; -struct Lib3dsMesh; -struct Lib3dsMaterial; -struct Lib3dsNode; - -class GLC_StructReference; -class GLC_3DRep; -class GLC_Mesh; -class GLC_StructOccurence; -class GLC_Matrix4x4; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_WorldTo3ds -/*! \brief GLC_WorldTo3ds : Export a GLC_World to a 3ds file */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_WorldTo3ds : public QObject -{ - Q_OBJECT -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - GLC_WorldTo3ds(const GLC_World& world); - virtual ~GLC_WorldTo3ds(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! @name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Save the world to the specified file name - bool exportToFile(const QString& fileName, bool useAbsolutePosition= false); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! @name Private services functions */ -//@{ -////////////////////////////////////////////////////////////////////// -private: - //! Save the world into the lib3ds file structure - void saveWorld(); - - //! Save all meshes into the lib3ds file structure - void saveMeshes(); - - //! Save the branch from the given GLC_StructOccurence - void saveBranch(GLC_StructOccurence* pOcc); - - //! Create 3ds node from the given GLC_StructOccurence - void createNodeFromOccurrence(GLC_StructOccurence* pOcc); - - //! Return the list of 3ds mesh from the given GLC_3DRep - QList createMeshsFrom3DRep(GLC_3DRep* pRep, const QString& name, const GLC_Matrix4x4& matrix= GLC_Matrix4x4()); - - //! Return the 3ds mesh from the given GLC_Mesh - Lib3dsMesh* create3dsMeshFromGLC_Mesh(GLC_Mesh* pMesh, const QString& meshName); - - //! Return the 3ds material from the given GLC_Material - Lib3dsMaterial* get3dsMaterialFromGLC_Material(GLC_Material* pMat); - - //! Create and return the 3ds material from the given GLC_Material and name - Lib3dsMaterial* create3dsMaterialFromGLC_Material(GLC_Material* pMat, const QString& materialName); - - //! Return the material name of the given material - QString materialName(GLC_Material* pMat) const; - - //! Set the object data position from the given matrix - void setNodePosition(Lib3dsNode* pNode, const GLC_Matrix4x4& matrix); - -//@} - -////////////////////////////////////////////////////////////////////// -// Qt Signals -////////////////////////////////////////////////////////////////////// -signals: - void currentQuantum(int); - -////////////////////////////////////////////////////////////////////// - /* Private members */ -////////////////////////////////////////////////////////////////////// -private: - //! The world to export - GLC_World m_World; - - //! The Lib3dsFile Structure - Lib3dsFile* m_pLib3dsFile; - - //! The file absolute path - QString m_FileName; - - //! Reference to 3ds mesh hash table - QHash m_ReferenceToMesh; - - //! Name to 3ds material hash table - QHash m_NameToMaterial; - - //! The root lib3ds node - Lib3dsNode* m_pRootLib3dsNode; - - //! The current node id - int m_CurrentNodeId; - - //! Occurence id to node id hash - QHash m_OccIdToNodeId; - - //! The current mesh inde - int m_CurrentMeshIndex; - - //! Use absolute position (meshes are duplicated) - bool m_UseAbsolutePosition; - - //! GLC_Texture to fileName hash table - QHash m_TextureToFileName; -}; - -#endif /* GLC_WORLDTO3DS_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/io/glc_worldto3dxml.cpp b/ground/gcs/src/libs/glc_lib/io/glc_worldto3dxml.cpp deleted file mode 100644 index b6fe3a293..000000000 --- a/ground/gcs/src/libs/glc_lib/io/glc_worldto3dxml.cpp +++ /dev/null @@ -1,1304 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_worldto3dxml.cpp implementation of the GLC_WorldTo3dxml class. - -#include "glc_worldto3dxml.h" -// Quazip library -#include "../3rdparty/quazip/quazip.h" -#include "../3rdparty/quazip/quazipfile.h" -#include "../glc_exception.h" -#include "../geometry/glc_mesh.h" - -#include - -GLC_WorldTo3dxml::GLC_WorldTo3dxml(const GLC_World& world, bool threaded) -: QObject() -, m_World(world) -, m_ExportType(Compressed3dxml) -, m_FileName() -, m_pOutStream(NULL) -, m_Generator("GLC_LIB") -, m_CurrentId(0) -, m_p3dxmlArchive(NULL) -, m_pCurrentZipFile(NULL) -, m_pCurrentFile(NULL) -, m_AbsolutePath() -, m_ReferenceToIdHash() -, m_InstanceToIdHash() -, m_ReferenceRepToIdHash() -, m_ReferenceRepTo3dxmlFileName() -, m_InstanceRep() -, m_MaterialIdToMaterialName() -, m_MaterialIdToMaterialId() -, m_MaterialIdToTexture3dxmlName() -, m_MaterialIdTo3dxmlImageId() -, m_ExportMaterial(true) -, m_3dxmlFileSet() -, m_FileNameIncrement(0) -, m_ListOfOverLoadedOccurence() -, m_pReadWriteLock(NULL) -, m_pIsInterupted(NULL) -, m_IsThreaded(threaded) -{ - m_World.rootOccurence()->updateOccurenceNumber(1); -} - -GLC_WorldTo3dxml::~GLC_WorldTo3dxml() -{ - delete m_p3dxmlArchive; - delete m_pCurrentZipFile; - delete m_pCurrentFile; -} - -bool GLC_WorldTo3dxml::exportTo3dxml(const QString& filename, GLC_WorldTo3dxml::ExportType exportType, bool exportMaterial) -{ - m_3dxmlFileSet.clear(); - m_ListOfOverLoadedOccurence.clear(); - m_FileNameIncrement= 0; - m_ExportMaterial= exportMaterial; - m_FileName= filename; - m_ExportType= exportType; - bool isExported= false; - if (m_ExportType == Compressed3dxml) - { - m_p3dxmlArchive= new QuaZip(m_FileName); - isExported= m_p3dxmlArchive->open(QuaZip::mdCreate); - // Add the manifest - addManifest(); - - } - else - { - m_AbsolutePath= QFileInfo(m_FileName).absolutePath() + QDir::separator(); - QFile exportFile(m_FileName); - isExported= exportFile.open(QIODevice::WriteOnly); - exportFile.close(); - } - if (isExported) - { - if (m_ExportMaterial && (m_ExportType != StructureOnly)) - { - writeAllMaterialRelatedFilesIn3dxml(); - } - - // Export the assembly structure from the list of structure reference - exportAssemblyStructure(); - - if (m_ExportType != StructureOnly) - { - int previousQuantumValue= 0; - int currentQuantumValue= 0; - emit currentQuantum(currentQuantumValue); - - int currentRepIndex= 0; - const int size= m_ReferenceRepTo3dxmlFileName.size(); - // Export the representation - QHash::const_iterator iRep= m_ReferenceRepTo3dxmlFileName.constBegin(); - while ((m_ReferenceRepTo3dxmlFileName.constEnd() != iRep) && continu()) - { - write3DRep(iRep.key(), iRep.value()); - ++iRep; - - // Progrees bar indicator - ++currentRepIndex; - currentQuantumValue = static_cast((static_cast(currentRepIndex) / size) * 100); - if (currentQuantumValue > previousQuantumValue) - { - emit currentQuantum(currentQuantumValue); - } - previousQuantumValue= currentQuantumValue; - if (!m_IsThreaded) - { - QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents); - } - } - } - } - - emit currentQuantum(100); - return isExported; -} - -bool GLC_WorldTo3dxml::exportReferenceTo3DRep(const GLC_3DRep* p3DRep, const QString& fullFileName) -{ - m_3dxmlFileSet.clear(); - m_ListOfOverLoadedOccurence.clear(); - m_FileNameIncrement= 0; - m_ExportMaterial= false; - - m_AbsolutePath= QFileInfo(fullFileName).absolutePath() + QDir::separator(); - - write3DRep(p3DRep, QFileInfo(fullFileName).fileName()); - - return true; -} - -void GLC_WorldTo3dxml::setInterupt(QReadWriteLock* pReadWriteLock, bool* pInterupt) -{ - m_pReadWriteLock= pReadWriteLock; - m_pIsInterupted= pInterupt; -} - -void GLC_WorldTo3dxml::writeHeader() -{ - const QString title(QFileInfo(m_FileName).fileName()); - - m_pOutStream->writeStartElement("Header"); - m_pOutStream->writeTextElement("SchemaVersion", "4.0"); - m_pOutStream->writeTextElement("Title", title); - m_pOutStream->writeTextElement("Generator", m_Generator); - m_pOutStream->writeTextElement("Created", QDate::currentDate().toString(Qt::ISODate)); - m_pOutStream->writeEndElement(); -} - -void GLC_WorldTo3dxml::writeReference3D(const GLC_StructReference* pRef) -{ - m_pOutStream->writeStartElement("Reference3D"); - m_pOutStream->writeAttribute("xsi:type", "Reference3DType"); - m_pOutStream->writeAttribute("id", QString::number(++m_CurrentId)); - m_pOutStream->writeAttribute("name", pRef->name()); - if (pRef->containsAttributes()) - { - m_pOutStream->writeStartElement("Reference3DExtensionType"); - writeExtensionAttributes(pRef->attributesHandle()); - m_pOutStream->writeEndElement(); // Reference3DExtensionType - } - m_pOutStream->writeEndElement(); // Reference3D - - m_ReferenceToIdHash.insert(pRef, m_CurrentId); -} - -void GLC_WorldTo3dxml::writeReferenceRep(const GLC_3DRep* p3DRep) -{ - const QString id(QString::number(++m_CurrentId)); - m_ReferenceRepToIdHash.insert(p3DRep, m_CurrentId); - const QString associateFile(representationFileName(p3DRep)); - m_ReferenceRepTo3dxmlFileName.insert(p3DRep, QString(associateFile).remove("urn:3DXML:")); - - m_pOutStream->writeStartElement("ReferenceRep"); - m_pOutStream->writeAttribute("xsi:type", "ReferenceRepType"); - m_pOutStream->writeAttribute("id", id); - m_pOutStream->writeAttribute("name", p3DRep->name()); - m_pOutStream->writeAttribute("format", "TESSELLATED"); - m_pOutStream->writeAttribute("version", "1.2"); - m_pOutStream->writeAttribute("associatedFile", associateFile); - m_pOutStream->writeTextElement("PLM_ExternalID", p3DRep->name()); - m_pOutStream->writeTextElement("V_discipline", "Design"); - m_pOutStream->writeTextElement("V_usage", "3DShape"); - m_pOutStream->writeTextElement("V_nature", "1"); - m_pOutStream->writeEndElement(); - - -} -void GLC_WorldTo3dxml::writeInstance3D(const GLC_StructInstance* pInstance, unsigned int parentId) -{ - const GLC_StructReference* pRef= pInstance->structReference(); - const unsigned int referenceId= m_ReferenceToIdHash.value(pRef); - const QString instanceMatrix(matrixString(pInstance->relativeMatrix())); - - m_pOutStream->writeStartElement("Instance3D"); - m_pOutStream->writeAttribute("xsi:type", "Instance3DType"); - m_pOutStream->writeAttribute("id", QString::number(++m_CurrentId)); - m_pOutStream->writeAttribute("name", pInstance->name()); - m_pOutStream->writeTextElement("IsAggregatedBy", QString::number(parentId)); - m_pOutStream->writeTextElement("IsInstanceOf", QString::number(referenceId)); - m_pOutStream->writeTextElement("RelativeMatrix", instanceMatrix); - if (pInstance->containsAttributes()) - { - m_pOutStream->writeStartElement("Instance3DExtensionType"); - writeExtensionAttributes(pInstance->attributesHandle()); - m_pOutStream->writeEndElement(); // Instance3DExtensionType - } - - m_pOutStream->writeEndElement(); // Instance3D - - m_InstanceToIdHash.insert(pInstance, m_CurrentId); -} - -void GLC_WorldTo3dxml::writeInstanceRep(const GLC_3DRep* p3DRep, unsigned int parentId) -{ - const unsigned int referenceId= m_ReferenceRepToIdHash.value(p3DRep); - m_pOutStream->writeStartElement("InstanceRep"); - m_pOutStream->writeAttribute("xsi:type", "InstanceRepType"); - m_pOutStream->writeAttribute("id", QString::number(++m_CurrentId)); - m_pOutStream->writeAttribute("name", p3DRep->name()); - m_pOutStream->writeTextElement("IsAggregatedBy", QString::number(parentId)); - m_pOutStream->writeTextElement("IsInstanceOf", QString::number(referenceId)); - m_pOutStream->writeEndElement(); - - m_InstanceRep.insert(parentId); - -} -void GLC_WorldTo3dxml::setStreamWriterToFile(const QString& fileName) -{ - delete m_pOutStream; - m_pOutStream= NULL; - - bool success= false; - if (NULL != m_p3dxmlArchive) - { - if (NULL != m_pCurrentZipFile) - { - m_pCurrentZipFile->close(); - delete m_pOutStream; - delete m_pCurrentZipFile; - } - QuaZipNewInfo quazipNewInfo(fileName); - m_pCurrentZipFile= new QuaZipFile(m_p3dxmlArchive); - success= m_pCurrentZipFile->open(QIODevice::WriteOnly, quazipNewInfo); - if (success) - { - m_pOutStream= new QXmlStreamWriter(m_pCurrentZipFile); - } - } - else - { - delete m_pCurrentFile; - m_pCurrentFile= new QFile(m_AbsolutePath + fileName); - success= m_pCurrentFile->open(QIODevice::WriteOnly); - if (success) - { - m_pOutStream= new QXmlStreamWriter(m_pCurrentFile); - } - } - - if (NULL == m_pOutStream) - { - QString message(QString("GLC_WorldTo3dxml::setStreamWriterToFile Unable to create ") + fileName); - GLC_Exception fileException(message); - throw(fileException); - } - else - { - m_pOutStream->setAutoFormatting(true); - } -} - -void GLC_WorldTo3dxml::addManifest() -{ - setStreamWriterToFile("Manifest.xml"); - m_pOutStream->writeStartDocument(); - - m_pOutStream->writeStartElement("Manifest"); - m_pOutStream->writeAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); - m_pOutStream->writeAttribute("xsi:noNamespaceSchemaLocation", "Manifest.xsd"); - m_pOutStream->writeTextElement("Root", QFileInfo(m_FileName).fileName()); - m_pOutStream->writeEndElement(); - m_pOutStream->writeEndElement(); - - m_pOutStream->writeEndDocument(); -} - -void GLC_WorldTo3dxml::exportAssemblyStructure() -{ - m_ReferenceToIdHash.clear(); - m_InstanceToIdHash.clear(); - m_ReferenceRepToIdHash.clear(); - m_ReferenceRepTo3dxmlFileName.clear(); - m_InstanceRep.clear(); - - // Create the assembly file - setStreamWriterToFile(QFileInfo(m_FileName).fileName()); - m_pOutStream->writeStartDocument(); - m_pOutStream->writeStartElement("Model_3dxml"); - m_pOutStream->writeAttribute("xmlns", "http://www.3ds.com/xsd/3DXML"); - m_pOutStream->writeAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); - m_pOutStream->writeAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink"); - - writeHeader(); - - // Product Structure - m_pOutStream->writeStartElement("ProductStructure"); - m_pOutStream->writeAttribute("root", "1"); - exportAssemblyFromOccurence(m_World.rootOccurence()); - m_pOutStream->writeEndElement(); // ProductStructure - - if (!m_ListOfOverLoadedOccurence.isEmpty()) - { - m_pOutStream->writeStartElement("DefaultView"); - const int size= m_ListOfOverLoadedOccurence.size(); - for (int i= 0; i < size; ++i) - { - writeOccurenceDefaultViewProperty(m_ListOfOverLoadedOccurence.at(i)); - } - m_pOutStream->writeEndElement(); // DefaultView - } - - m_pOutStream->writeEndElement(); // Model_3dxml - - m_pOutStream->writeEndDocument(); -} - -void GLC_WorldTo3dxml::exportAssemblyFromOccurence(const GLC_StructOccurence* pOccurence) -{ - if (pOccurence->isOrphan()) - { - writeReference3D(pOccurence->structReference()); - } - else - { - // Reference 3D - GLC_StructReference* pCurrentRef= pOccurence->structReference(); - if (!m_ReferenceToIdHash.contains(pCurrentRef)) - { - writeReference3D(pCurrentRef); - // Reference Rep - if (pCurrentRef->hasRepresentation()) - { - GLC_3DRep* pCurrentRep= dynamic_cast(pCurrentRef->representationHandle()); - if (NULL != pCurrentRep && !m_ReferenceRepToIdHash.contains(pCurrentRep)) - { - writeReferenceRep(pCurrentRep); - } - } - } - // Instance 3D and instance rep - GLC_StructInstance* pCurrentInstance= pOccurence->structInstance(); - if (!m_InstanceToIdHash.contains(pCurrentInstance)) - { - // Instance 3D - const unsigned int parentId= m_ReferenceToIdHash.value(pOccurence->parent()->structReference()); - writeInstance3D(pCurrentInstance, parentId); - - // Instance Rep - if (pCurrentRef->hasRepresentation()) - { - GLC_3DRep* pCurrentRep= dynamic_cast(pCurrentRef->representationHandle()); - const unsigned int parentId= m_ReferenceToIdHash.value(pCurrentRef); - if (NULL != pCurrentRep && !m_InstanceRep.contains(parentId)) - { - writeInstanceRep(pCurrentRep, parentId); - } - } - } - } - - // Process children - const int childCount= pOccurence->childCount(); - for (int i= 0; i < childCount; ++i) - { - exportAssemblyFromOccurence(pOccurence->child(i)); - } - - // Add occurence with Overload properties to a list - if (m_World.collection()->contains(pOccurence->id())) - { - GLC_3DViewInstance* pInstance= m_World.collection()->instanceHandle(pOccurence->id()); - Q_ASSERT(NULL != pInstance); - const bool isVisible= pInstance->isVisible(); - - // Test if render properties are overloaded - GLC_RenderProperties* pRenderProperties= pInstance->renderPropertiesHandle(); - bool RenderOverloaded= !pRenderProperties->isDefault(); - if (RenderOverloaded) - { - RenderOverloaded= false; - RenderOverloaded= (pRenderProperties->renderingMode() == glc::OverwriteMaterial); - RenderOverloaded= RenderOverloaded || (pRenderProperties->renderingMode() == glc::OverwriteTransparency); - RenderOverloaded= RenderOverloaded || (pRenderProperties->renderingMode() == glc::OverwriteTransparencyAndMaterial); - } - - const bool isOverload= !isVisible || RenderOverloaded || pOccurence->isFlexible(); - if (isOverload) - { - m_ListOfOverLoadedOccurence.append(pOccurence); - } - } - -} - -QString GLC_WorldTo3dxml::matrixString(const GLC_Matrix4x4& matrix) -{ - QString resultMatrix; - const QChar spaceChar(' '); - // Rotation - resultMatrix+= QString::number(matrix.getData()[0], 'g', 16) + spaceChar; - resultMatrix+= QString::number(matrix.getData()[1], 'g', 16) + spaceChar; - resultMatrix+= QString::number(matrix.getData()[2], 'g', 16) + spaceChar; - - resultMatrix+= QString::number(matrix.getData()[4], 'g', 16) + spaceChar; - resultMatrix+= QString::number(matrix.getData()[5], 'g', 16) + spaceChar; - resultMatrix+= QString::number(matrix.getData()[6], 'g', 16) + spaceChar; - - resultMatrix+= QString::number(matrix.getData()[8], 'g', 16) + spaceChar; - resultMatrix+= QString::number(matrix.getData()[9], 'g', 16) + spaceChar; - resultMatrix+= QString::number(matrix.getData()[10], 'g', 16) + spaceChar; - - // Translation - resultMatrix+= QString::number(matrix.getData()[12], 'g', 16) + spaceChar; - resultMatrix+= QString::number(matrix.getData()[13], 'g', 16) + spaceChar; - resultMatrix+= QString::number(matrix.getData()[14], 'g', 16); - - return resultMatrix; -} - -void GLC_WorldTo3dxml::write3DRep(const GLC_3DRep* pRep, const QString& fileName) -{ - setStreamWriterToFile(fileName); - - m_pOutStream->writeStartDocument(); - m_pOutStream->writeStartElement("XMLRepresentation"); - m_pOutStream->writeAttribute("version", "1.2"); - m_pOutStream->writeAttribute("xmlns", "http://www.3ds.com/xsd/3DXML"); - m_pOutStream->writeAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); - m_pOutStream->writeAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink"); - m_pOutStream->writeAttribute("xsi:schemaLocation", "http://www.3ds.com/xsd/3DXML ./3DXMLMesh.xsd"); - - m_pOutStream->writeStartElement("Root"); // Root - m_pOutStream->writeAttribute("xsi:type", "BagRepType"); - m_pOutStream->writeAttribute("id", QString::number(++m_CurrentId)); - const int bodyCount= pRep->numberOfBody(); - for (int i= 0; i < bodyCount; ++i) - { - GLC_Mesh* pMesh= dynamic_cast(pRep->geomAt(i)); - if (NULL != pMesh) - { - writeGeometry(pMesh); - } - } - m_pOutStream->writeEndElement(); // Root - - m_pOutStream->writeEndElement(); // XMLRepresentation - - m_pOutStream->writeEndDocument(); -} - -QString GLC_WorldTo3dxml::representationFileName(const GLC_3DRep* pRep) -{ - Q_ASSERT(m_ReferenceRepToIdHash.contains(pRep)); - QString repName= pRep->name(); - QString fileName; - if (m_ExportType == StructureOnly) - { - QString newFileName= pRep->fileName(); - // Test if the file name is encoded by GLC_Lib (Structure only loaded) - if (glc::isFileString(newFileName)) - { - newFileName= glc::archiveEntryFileName(newFileName); - } - if (newFileName.isEmpty() || (glc::isArchiveString(newFileName))) - { - fileName= "urn:3DXML:NoFile_0.3DRep"; - } - else - { - // Compute the relative fileName from the structure - QDir structureDir(m_AbsolutePath); - QString relativeFilePath= structureDir.relativeFilePath(newFileName); - fileName= "urn:3DXML:" + relativeFilePath; - } - } - else if (repName.isEmpty()) - { - fileName= "urn:3DXML:Representation_0.3DRep"; - } - else - { - fileName= "urn:3DXML:" + repName + ".3DRep"; - } - return xmlFileName(fileName); -} - -void GLC_WorldTo3dxml::writeGeometry(const GLC_Mesh* pMesh) -{ - // Get the list of material id - QList materialList= pMesh->materialIds(); - const int materialCount= materialList.size(); - - m_pOutStream->writeStartElement("Rep"); - m_pOutStream->writeAttribute("xsi:type", "PolygonalRepType"); - m_pOutStream->writeAttribute("id", QString::number(++m_CurrentId)); - const double masterAccuracy= pMesh->getLodAccuracy(0); - m_pOutStream->writeAttribute("accuracy", QString::number(masterAccuracy)); - m_pOutStream->writeAttribute("solid", "1"); - const int lodCount= pMesh->lodCount(); - if (lodCount > 1) - { - // The mesh contains LOD - for (int i= 1; i < lodCount; ++i) - { - const double lodAccuracy= pMesh->getLodAccuracy(i); - m_pOutStream->writeStartElement("PolygonalLOD"); - m_pOutStream->writeAttribute("accuracy", QString::number(lodAccuracy)); - m_pOutStream->writeStartElement("Faces"); - for (int matIndex= 0; matIndex < materialCount; ++matIndex) - { - const GLC_uint materialId= materialList.at(matIndex); - if (pMesh->lodContainsMaterial(i, materialId)) - { - writeGeometryFace(pMesh, i, materialId); - } - } - m_pOutStream->writeEndElement(); // Faces - m_pOutStream->writeEndElement(); // PolygonalLOD - } - } - - // Master LOD - m_pOutStream->writeStartElement("Faces"); - for (int matIndex= 0; matIndex < materialCount; ++matIndex) - { - const GLC_uint materialId= materialList.at(matIndex); - if (pMesh->lodContainsMaterial(0, materialId)) - { - writeGeometryFace(pMesh, 0, materialId); - } - } - m_pOutStream->writeEndElement(); // Faces - if (!pMesh->wireDataIsEmpty()) - { - writeEdges(pMesh); - } - - // Save Bulk data - m_pOutStream->writeStartElement("VertexBuffer"); - { - // Get positions - GLfloatVector positionVector= pMesh->positionVector(); - QString positions; - const int size= positionVector.size(); - for (int i= 0; i < size; i+=3) - { - positions.append(QString::number(positionVector.at(i))); - positions.append(' '); - positions.append(QString::number(positionVector.at(i + 1))); - positions.append(' '); - positions.append(QString::number(positionVector.at(i + 2))); - positions.append(", "); - } - positions.remove(positions.size() - 2, 2); - m_pOutStream->writeTextElement("Positions", positions); - } - { - // Get normals - GLfloatVector normalVector= pMesh->normalVector(); - QString normals; - const int size= normalVector.size(); - for (int i= 0; i < size; i+=3) - { - normals.append(QString::number(normalVector.at(i))); - normals.append(' '); - normals.append(QString::number(normalVector.at(i + 1))); - normals.append(' '); - normals.append(QString::number(normalVector.at(i + 2))); - normals.append(", "); - } - normals.remove(normals.size() - 2, 2); - m_pOutStream->writeTextElement("Normals", normals); - } - { - // Get texture coordinates - GLfloatVector texelVector= pMesh->texelVector(); - if (!texelVector.isEmpty()) - { - QString texels; - const int size= texelVector.size(); - for (int i= 0; i < size; i+=2) - { - texels.append(QString::number(texelVector.at(i))); - texels.append(' '); - texels.append(QString::number(texelVector.at(i + 1))); - texels.append(", "); - } - texels.remove(texels.size() - 2, 2); - - m_pOutStream->writeStartElement("TextureCoordinates"); - m_pOutStream->writeAttribute("dimension", "2D"); - m_pOutStream->writeAttribute("channel", "0"); - m_pOutStream->writeCharacters(texels); - m_pOutStream->writeEndElement(); // TexturesCoordinates - } - } - - - m_pOutStream->writeEndElement(); // VertexBuffer - m_pOutStream->writeEndElement(); // Rep - -} -void GLC_WorldTo3dxml::writeGeometryFace(const GLC_Mesh* pMesh, int lod, GLC_uint materialId) -{ - m_pOutStream->writeStartElement("Face"); - if (pMesh->containsTriangles(lod, materialId)) - { - QVector triangleIndex= pMesh->getTrianglesIndex(lod, materialId); - QString indexString; - const int indexSize= triangleIndex.size(); - for (int index= 0; index < indexSize; ++index) - { - indexString.append(QString::number(triangleIndex.at(index))); - indexString.append(' '); - } - indexString.remove(indexString.size() - 1, 1); - m_pOutStream->writeAttribute("triangles", indexString); - } - if (pMesh->containsStrips(lod, materialId)) - { - QList > stripsIndex= pMesh->getStripsIndex(lod, materialId); - QString indexStrips; - const int stripCount= stripsIndex.size(); - for (int stripIndex= 0; stripIndex < stripCount; ++stripIndex) - { - QVector currentStripIndex= stripsIndex.at(stripIndex); - QString currentIndex; - const int indexSize= currentStripIndex.size(); - for (int index= 0; index < indexSize; ++index) - { - currentIndex.append(QString::number(currentStripIndex.at(index))); - currentIndex.append(' '); - } - currentIndex.remove(currentIndex.size() - 1, 1); - indexStrips.append(currentIndex); - indexStrips.append(','); - } - indexStrips.remove(indexStrips.size() - 1, 1); - m_pOutStream->writeAttribute("strips", indexStrips); - } - if (pMesh->containsFans(lod, materialId)) - { - QList > fansIndex= pMesh->getFansIndex(lod, materialId); - QString indexFans; - const int fanCount= fansIndex.size(); - for (int fanIndex= 0; fanIndex < fanCount; ++fanIndex) - { - QVector currentFanIndex= fansIndex.at(fanIndex); - QString currentIndex; - const int indexSize= currentFanIndex.size(); - for (int index= 0; index < indexSize; ++index) - { - currentIndex.append(QString::number(currentFanIndex.at(index))); - currentIndex.append(' '); - } - currentIndex.remove(currentIndex.size() - 1, 1); - indexFans.append(currentIndex); - indexFans.append(','); - } - indexFans.remove(indexFans.size() - 1, 1); - m_pOutStream->writeAttribute("fans", indexFans); - } - - writeSurfaceAttributes(pMesh->material(materialId)); - - m_pOutStream->writeEndElement(); // Face - -} - -void GLC_WorldTo3dxml::writeSurfaceAttributes(const GLC_Material* pMaterial) -{ - QColor diffuseColor= pMaterial->diffuseColor(); - m_pOutStream->writeStartElement("SurfaceAttributes"); - if (m_ExportMaterial) - { - const QString material3dxmlId=(QString::number(m_MaterialIdToMaterialId.value(pMaterial->id()))); - m_pOutStream->writeStartElement("MaterialApplication"); - m_pOutStream->writeAttribute("xsi:type", "MaterialApplicationType"); - m_pOutStream->writeAttribute("mappingChannel", "0"); - m_pOutStream->writeStartElement("MaterialId"); - m_pOutStream->writeAttribute("id", "urn:3DXML:CATMaterialRef.3dxml#" + material3dxmlId); - m_pOutStream->writeEndElement(); // MaterialId - m_pOutStream->writeEndElement(); // MaterialApplication - } - else - { - m_pOutStream->writeStartElement("Color"); - m_pOutStream->writeAttribute("xsi:type", "RGBAColorType"); - m_pOutStream->writeAttribute("red", QString::number(diffuseColor.redF())); - m_pOutStream->writeAttribute("green", QString::number(diffuseColor.greenF())); - m_pOutStream->writeAttribute("blue", QString::number(diffuseColor.blueF())); - m_pOutStream->writeAttribute("alpha", QString::number(diffuseColor.alphaF())); - m_pOutStream->writeEndElement(); // Color - } - m_pOutStream->writeEndElement(); // SurfaceAttributes -} - -void GLC_WorldTo3dxml::writeEdges(const GLC_Mesh* pMesh) -{ - m_pOutStream->writeStartElement("Edges"); - writeLineAttributes(pMesh->wireColor()); - - GLfloatVector positionVector= pMesh->wirePositionVector(); - const int polylineCount= pMesh->wirePolylineCount(); - for (int i= 0; i < polylineCount; ++i) - { - m_pOutStream->writeStartElement("Polyline"); - QString polylinePosition; - const GLuint offset= pMesh->wirePolylineOffset(i); - const GLsizei size= pMesh->wirePolylineSize(i); - for (GLsizei index= 0; index < size; ++index) - { - const int startIndex= 3 * (offset + index); - polylinePosition.append(QString::number(positionVector.at(startIndex))); - polylinePosition.append(' '); - polylinePosition.append(QString::number(positionVector.at(startIndex + 1))); - polylinePosition.append(' '); - polylinePosition.append(QString::number(positionVector.at(startIndex + 2))); - polylinePosition.append(','); - } - polylinePosition.remove(polylinePosition.size() - 1, 1); - m_pOutStream->writeAttribute("vertices", polylinePosition); - m_pOutStream->writeEndElement(); // Polyline - } - m_pOutStream->writeEndElement(); // Edges -} - -void GLC_WorldTo3dxml::writeLineAttributes(const QColor& color) -{ - m_pOutStream->writeStartElement("LineAttributes"); - m_pOutStream->writeAttribute("lineType", "SOLID"); - m_pOutStream->writeAttribute("thickness", "1"); - m_pOutStream->writeStartElement("Color"); - m_pOutStream->writeAttribute("xsi:type", "RGBAColorType"); - m_pOutStream->writeAttribute("red", QString::number(color.redF())); - m_pOutStream->writeAttribute("green", QString::number(color.greenF())); - m_pOutStream->writeAttribute("blue", QString::number(color.blueF())); - m_pOutStream->writeAttribute("alpha", QString::number(color.alphaF())); - m_pOutStream->writeEndElement(); // Color - m_pOutStream->writeEndElement(); // LineAttributes -} - -void GLC_WorldTo3dxml::writeMaterial(const GLC_Material* pMaterial) -{ - const GLC_uint materialId= pMaterial->id(); - QString materialName; - if (pMaterial->name().isEmpty()) - { - materialName= "Material_0" + QString::number(materialId); - } - else - { - materialName= symplifyName(pMaterial->name()); - - // If the materialName is already uses append material id to the name - QSet materialsName= QSet::fromList(m_MaterialIdToMaterialName.values()); - while (materialsName.contains(materialName)) - { - materialName= materialName + '_' + QString::number(materialId); - } - } - - m_MaterialIdToMaterialName.insert(materialId, materialName); - - const QString fileName= xmlFileName(materialName + "_Rendering.3DRep"); - setStreamWriterToFile(fileName); - - // Begin to write the material file - m_pOutStream->writeStartDocument(); - m_pOutStream->writeStartElement("Osm"); - m_pOutStream->writeAttribute("xmlns", "http://www.3ds.com/xsd/osm.xsd"); - m_pOutStream->writeAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); - m_pOutStream->writeAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink"); - m_pOutStream->writeAttribute("xsi:schemaLocation", "http://www.3ds.com/xsd/3DXML ./osm.xsd"); - m_pOutStream->writeStartElement("Feature"); - m_pOutStream->writeAttribute("Alias", "RenderingRootFeature"); - m_pOutStream->writeAttribute("Id", "1"); - m_pOutStream->writeAttribute("StartUp", "RenderingRootFeature"); - m_pOutStream->writeEndElement(); // Feature - m_pOutStream->writeStartElement("Feature"); - m_pOutStream->writeAttribute("Alias", "RenderingFeature"); - m_pOutStream->writeAttribute("Id", "2"); - m_pOutStream->writeAttribute("StartUp", "RenderingFeature"); - m_pOutStream->writeAttribute("Aggregating", "1"); - - writeMaterialAttributtes("Filtering", "int", "1"); - writeMaterialAttributtes("Rotation", "double", "0"); - writeMaterialAttributtes("PreviewType", "int", "1"); - writeMaterialAttributtes("AmbientCoef", "double", "1"); - writeMaterialAttributtes("DiffuseCoef", "double", "1"); - writeMaterialAttributtes("SpecularCoef", "double", "1"); - writeMaterialAttributtes("EmissiveCoef", "double", "0"); - writeMaterialAttributtes("AlphaTest", "boolean", "false"); - writeMaterialAttributtes("TextureFunction", "int", "0"); - writeMaterialAttributtes("MappingType", "int", "2"); - writeMaterialAttributtes("Refraction", "double", "1"); - writeMaterialAttributtes("TextureDimension", "int", "2"); - writeMaterialAttributtes("TranslationU", "double", "0"); - writeMaterialAttributtes("TranslationV", "double", "0"); - writeMaterialAttributtes("FlipU", "boolean", "false"); - writeMaterialAttributtes("FlipV", "boolean", "false"); - writeMaterialAttributtes("WrappingModeU", "int", "1"); - writeMaterialAttributtes("WrappingModeV", "int", "1"); - writeMaterialAttributtes("ScaleU", "double", "1"); - writeMaterialAttributtes("ScaleV", "double", "1"); - writeMaterialAttributtes("Reflectivity", "double", "0.1"); - writeMaterialAttributtes("BlendColor", "double", "[1,1,1]"); - - writeMaterialAttributtes("Transparency", "double", QString::number(1.0 - pMaterial->opacity())); - double specularExponent= pMaterial->shininess() / 128.0; - writeMaterialAttributtes("SpecularExponent", "double", QString::number(specularExponent)); - writeMaterialAttributtes("DiffuseColor", "double", colorToString(pMaterial->diffuseColor())); - writeMaterialAttributtes("SpecularColor", "double", colorToString(pMaterial->specularColor())); - writeMaterialAttributtes("AmbientColor", "double", colorToString(pMaterial->ambientColor())); - writeMaterialAttributtes("EmissiveColor", "double", colorToString(pMaterial->emissiveColor())); - if (pMaterial->hasTexture()) - { - Q_ASSERT(m_MaterialIdTo3dxmlImageId.contains(pMaterial->id())); - const QString imageId(QString::number(m_MaterialIdTo3dxmlImageId.value(pMaterial->id()))); - - writeMaterialAttributtes("TextureImage", "external", "urn:3DXML:CATRepImage.3dxml#" + imageId); - } - m_pOutStream->writeEndElement(); // Feature - m_pOutStream->writeEndElement(); // Osm - m_pOutStream->writeEndDocument(); -} - -void GLC_WorldTo3dxml::writeMaterialAttributtes(const QString& name, const QString& type, const QString& value) -{ - m_pOutStream->writeStartElement("Attr"); - m_pOutStream->writeAttribute("Name", name); - m_pOutStream->writeAttribute("Type", type); - m_pOutStream->writeAttribute("Value", value); - m_pOutStream->writeEndElement(); // Attr -} - -QString GLC_WorldTo3dxml::colorToString(const QColor& color) -{ - return QString('[' + QString::number(color.redF()) + ',' + QString::number(color.greenF()) + ',' + QString::number(color.blueF()) + ']'); -} - -void GLC_WorldTo3dxml::writeCatRepImageFile(const QList& materialList) -{ - unsigned int currentId= 0; - const QString fileName("CATRepImage.3dxml"); - setStreamWriterToFile(fileName); - - // Begin to write the rep image file - m_pOutStream->writeStartDocument(); - m_pOutStream->writeStartElement("Model_3dxml"); - m_pOutStream->writeAttribute("xmlns", "http://www.3ds.com/xsd/3DXML"); - m_pOutStream->writeAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); - m_pOutStream->writeAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink"); - m_pOutStream->writeAttribute("xsi:schemaLocation", "http://www.3ds.com/xsd/3DXML ./3DXML.xsd"); - writeHeader(); - m_pOutStream->writeStartElement("CATRepImage"); - m_pOutStream->writeAttribute("root", QString::number(currentId)); - const int size= materialList.size(); - for (int i= 0; i < size; ++i) - { - writeCATRepresentationImage(materialList.at(i), ++currentId); - } - m_pOutStream->writeEndElement(); // CATRepImage - m_pOutStream->writeEndElement(); // Model_3dxml - m_pOutStream->writeEndDocument(); -} - -void GLC_WorldTo3dxml::writeCATRepresentationImage(const GLC_Material* pMat, unsigned int id) -{ - Q_ASSERT(pMat->hasTexture()); - m_MaterialIdTo3dxmlImageId.insert(pMat->id(), id); - - const QString imageName= pMat->name(); - QString imageFileName; - QString imageFormat; - const QString textureFileName= pMat->textureHandle()->fileName(); - if (textureFileName.isEmpty()) - { - imageFormat= "jpg"; - if (imageName.isEmpty()) - { - imageFileName= xmlFileName("textureImage." + imageFormat); - } - else - { - imageFileName= xmlFileName(imageName + '.' + imageFormat); - } - } - else - { - imageFormat= QFileInfo(textureFileName).suffix(); - imageFileName= xmlFileName(QFileInfo(textureFileName).fileName()); - } - m_MaterialIdToTexture3dxmlName.insert(pMat->id(), imageFileName); - - m_pOutStream->writeStartElement("CATRepresentationImage"); - m_pOutStream->writeAttribute("xsi:type", "CATRepresentationImageType"); - m_pOutStream->writeAttribute("id", QString::number(id)); - m_pOutStream->writeAttribute("name", imageName); - m_pOutStream->writeAttribute("format", imageFormat); - m_pOutStream->writeAttribute("associatedFile", QString("urn:3DXML:" + imageFileName)); - - m_pOutStream->writeTextElement("PLM_ExternalID", imageName); - m_pOutStream->writeTextElement("V_PrimaryMimeType", imageFormat); - m_pOutStream->writeTextElement("V_PrimaryFileName", imageFileName); - m_pOutStream->writeEndElement(); // CATRepresentationImage -} - -void GLC_WorldTo3dxml::writeAllMaterialRelatedFilesIn3dxml() -{ - m_MaterialIdToMaterialName.clear(); - m_MaterialIdToMaterialId.clear(); - m_MaterialIdToTexture3dxmlName.clear(); - m_MaterialIdTo3dxmlImageId.clear(); - - // Get the list of material - QList materialList= m_World.listOfMaterials(); - - // Create the list of textured material and modified material list - QList texturedMaterial; - const int size= materialList.size(); - for (int i= 0; i < size; ++i) - { - if (materialList.at(i)->hasTexture()) - { - texturedMaterial.append(materialList.at(i)); - } - } - - if (!texturedMaterial.isEmpty()) - { - writeCatRepImageFile(texturedMaterial); - writeImageFileIn3dxml(texturedMaterial); - } - - - // Write material 3DRep in the 3DXML - for (int i= 0; i < size; ++i) - { - writeMaterial(materialList.at(i)); - } - - writeCatMaterialRef(materialList); - - - -} -void GLC_WorldTo3dxml::writeImageFileIn3dxml(const QList& materialList) -{ - const int size= materialList.size(); - Q_ASSERT(size == m_MaterialIdToTexture3dxmlName.size()); - for (int i= 0; i < size; ++i) - { - const GLC_Material* pCurrentMaterial= materialList.at(i); - const GLC_Texture* pTexture= pCurrentMaterial->textureHandle(); - const QString imageName(m_MaterialIdToTexture3dxmlName.value(pCurrentMaterial->id())); - // Get the texture image - if (!pTexture->fileName().isEmpty()) - { - // Try to load the texture - QImage textureImage(pTexture->fileName()); - if (! textureImage.isNull()) - { - addImageTextureTo3dxml(textureImage, imageName); - } - else - { - addImageTextureTo3dxml(pTexture->imageOfTexture(), imageName); - } - } - else - { - addImageTextureTo3dxml(pTexture->imageOfTexture(), imageName); - } - } - -} - -void GLC_WorldTo3dxml::writeCatMaterialRef(const QList& materialList) -{ - const QString fileName("CATMaterialRef.3dxml"); - - setStreamWriterToFile(fileName); - - unsigned int currentId= 0; - - // Begin to write the rep image file - m_pOutStream->writeStartDocument(); - m_pOutStream->writeStartElement("Model_3dxml"); - m_pOutStream->writeAttribute("xmlns", "http://www.3ds.com/xsd/3DXML"); - m_pOutStream->writeAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); - m_pOutStream->writeAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink"); - m_pOutStream->writeAttribute("xsi:schemaLocation", "http://www.3ds.com/xsd/3DXML ./3DXML.xsd"); - writeHeader(); - m_pOutStream->writeStartElement("CATMaterialRef"); - m_pOutStream->writeAttribute("root", QString::number(currentId)); - const int size= materialList.size(); - for (int i= 0; i < size; ++i) - { - writeMaterialToCatMaterialRef(materialList.at(i), &(++currentId)); - } - m_pOutStream->writeEndElement(); // CATMaterialRef - m_pOutStream->writeEndElement(); // Model_3dxml - m_pOutStream->writeEndDocument(); -} - -void GLC_WorldTo3dxml::writeMaterialToCatMaterialRef(const GLC_Material* pMat, unsigned int* id) -{ - const QString materialName= m_MaterialIdToMaterialName.value(pMat->id()); - m_MaterialIdToMaterialId.insert(pMat->id(), *id); - - m_pOutStream->writeStartElement("CATMatReference"); - m_pOutStream->writeAttribute("xsi:type", "CATMatReferenceType"); - m_pOutStream->writeAttribute("id", QString::number(*id)); - m_pOutStream->writeAttribute("name", materialName); - m_pOutStream->writeTextElement("PLM_ExternalID", materialName); - m_pOutStream->writeEndElement(); // CATMatReference - - const QString domainName= materialName + "_Rendering"; - m_pOutStream->writeStartElement("MaterialDomain"); - m_pOutStream->writeAttribute("xsi:type", "MaterialDomainType"); - m_pOutStream->writeAttribute("id", QString::number(++(*id))); - m_pOutStream->writeAttribute("name", domainName); - m_pOutStream->writeAttribute("format", "TECHREP"); - const QString associatedFileName("urn:3DXML:" + domainName + ".3DRep"); - m_pOutStream->writeAttribute("associatedFile", associatedFileName); - m_pOutStream->writeAttribute("version", "1.0"); - m_pOutStream->writeTextElement("PLM_ExternalID", domainName); - if (pMat->hasTexture()) - { - m_pOutStream->writeStartElement("PLMRelation"); - m_pOutStream->writeTextElement("C_Semantics", "Reference"); - m_pOutStream->writeTextElement("C_Role", "CATMaterialReferenceToTextureLink"); - m_pOutStream->writeStartElement("Ids"); - const QString imageId(QString::number(m_MaterialIdTo3dxmlImageId.value(pMat->id()))); - m_pOutStream->writeTextElement("id", "urn:3DXML:CATRepImage.3dxml#" + imageId); - m_pOutStream->writeEndElement(); // Ids - m_pOutStream->writeEndElement(); // PLMRelation - } - m_pOutStream->writeTextElement("V_MatDomain", "Rendering"); - m_pOutStream->writeEndElement(); // MaterialDomain - - m_pOutStream->writeStartElement("MaterialDomainInstance"); - m_pOutStream->writeAttribute("xsi:type", "MaterialDomainInstanceType"); - m_pOutStream->writeAttribute("id", QString::number(++(*id))); - m_pOutStream->writeAttribute("name", materialName + ".1"); - m_pOutStream->writeTextElement("PLM_ExternalID", materialName + ".1"); - m_pOutStream->writeTextElement("IsAggregatedBy", QString::number((*id) - 2)); - m_pOutStream->writeTextElement("IsInstanceOf", QString::number((*id) - 1)); - m_pOutStream->writeEndElement(); // MaterialDomainInstance -} - -void GLC_WorldTo3dxml::addImageTextureTo3dxml(const QImage& image, const QString& fileName) -{ - delete m_pOutStream; - m_pOutStream= NULL; - - bool success= false; - if (NULL != m_p3dxmlArchive) - { - if (NULL != m_pCurrentZipFile) - { - m_pCurrentZipFile->close(); - delete m_pOutStream; - delete m_pCurrentZipFile; - } - QuaZipNewInfo quazipNewInfo(fileName); - m_pCurrentZipFile= new QuaZipFile(m_p3dxmlArchive); - success= m_pCurrentZipFile->open(QIODevice::WriteOnly, quazipNewInfo); - if (success) - { - image.save(m_pCurrentZipFile, QFileInfo(fileName).suffix().toLatin1().constData()); - m_pCurrentZipFile->close(); - delete m_pCurrentZipFile; - m_pCurrentZipFile= NULL; - } - } - else - { - delete m_pCurrentFile; - m_pCurrentFile= new QFile(m_AbsolutePath + fileName); - success= m_pCurrentFile->open(QIODevice::WriteOnly); - if (success) - { - image.save(m_pCurrentFile, QFileInfo(fileName).suffix().toLatin1().constData()); - delete m_pCurrentFile; - m_pCurrentFile= NULL; - } - } -} - -QString GLC_WorldTo3dxml::xmlFileName(QString fileName) -{ - QString prefix; - if (fileName.contains("urn:3DXML:")) - { - prefix= "urn:3DXML:"; - fileName.remove(prefix); - } - - if (m_ExportType != StructureOnly) - { - fileName= symplifyName(fileName); - } - - QString newName; - if (!m_3dxmlFileSet.contains(prefix + fileName)) - { - fileName.prepend(prefix); - m_3dxmlFileSet << fileName; - newName= fileName; - } - else - { - newName= QFileInfo(fileName).completeBaseName() + QString::number(++m_FileNameIncrement) + '.' + QFileInfo(fileName).suffix(); - newName.prepend(prefix); - } - return newName; -} - -void GLC_WorldTo3dxml::writeExtensionAttributes(GLC_Attributes* pAttributes) -{ - QList attributesNames= pAttributes->names(); - const int size= attributesNames.size(); - for (int i= 0; i < size; ++i) - { - const QString name= attributesNames.at(i); - QString value= pAttributes->value(name); - m_pOutStream->writeStartElement("Attribute"); - m_pOutStream->writeAttribute("name", name); - if (name == "FILEPATH") - { - QDir thisPath(m_AbsolutePath); - value= thisPath.relativeFilePath(value); - } - m_pOutStream->writeAttribute("value", value); - m_pOutStream->writeEndElement(); // Attribute - } -} - -void GLC_WorldTo3dxml::writeOccurenceDefaultViewProperty(const GLC_StructOccurence* pOccurence) -{ - QList path= instancePath(pOccurence); - - GLC_3DViewInstance* pInstance= m_World.collection()->instanceHandle(pOccurence->id()); - Q_ASSERT(NULL != pInstance); - const bool isVisible= pOccurence->isVisible(); - m_pOutStream->writeStartElement("DefaultViewProperty"); - m_pOutStream->writeStartElement("OccurenceId"); - const QString prefix= "urn:3DXML:" + QFileInfo(m_FileName).fileName() + "#"; - const int pathSize= path.size(); - for (int i= 0; i < pathSize; ++i) - { - m_pOutStream->writeTextElement("id", prefix + QString::number(path.at(i))); - } - m_pOutStream->writeEndElement(); // OccurenceId - - if (pOccurence->isFlexible()) - { - m_pOutStream->writeTextElement("RelativePosition", matrixString(pOccurence->occurrenceRelativeMatrix())); - } - - if (!isVisible || !pInstance->renderPropertiesHandle()->isDefault()) - { - qDebug() << "(!isVisible || !pInstance->renderPropertiesHandle()->isDefault())"; - m_pOutStream->writeStartElement("GraphicProperties"); - m_pOutStream->writeAttribute("xsi:type", "GraphicPropertiesType"); - if (! isVisible) - { - m_pOutStream->writeStartElement("GeneralAttributes"); - m_pOutStream->writeAttribute("xsi:type", "GeneralAttributesType"); - m_pOutStream->writeAttribute("visible", "false"); - m_pOutStream->writeAttribute("selectable", "true"); - m_pOutStream->writeEndElement(); // GeneralAttributes - } - if (!pInstance->renderPropertiesHandle()->isDefault()) - { - const GLC_RenderProperties* pProperties= pInstance->renderPropertiesHandle(); - if ((pProperties->renderingMode() == glc::OverwriteTransparency)) - { - m_pOutStream->writeStartElement("SurfaceAttributes"); - m_pOutStream->writeAttribute("xsi:type", "SurfaceAttributesType"); - m_pOutStream->writeStartElement("Color"); - m_pOutStream->writeAttribute("xsi:type", "RGBAColorType"); - m_pOutStream->writeAttribute("red", "-1"); - m_pOutStream->writeAttribute("green", "-1"); - m_pOutStream->writeAttribute("blue", "-1"); - m_pOutStream->writeAttribute("alpha", QString::number(pProperties->overwriteTransparency())); - m_pOutStream->writeEndElement(); // Color - m_pOutStream->writeEndElement(); // SurfaceAttributes - } - else if ((pProperties->renderingMode() == glc::OverwriteTransparencyAndMaterial)) - { - GLC_Material* pMaterial= pProperties->overwriteMaterial(); - m_pOutStream->writeStartElement("SurfaceAttributes"); - m_pOutStream->writeAttribute("xsi:type", "SurfaceAttributesType"); - m_pOutStream->writeStartElement("Color"); - m_pOutStream->writeAttribute("xsi:type", "RGBAColorType"); - m_pOutStream->writeAttribute("red", QString::number(pMaterial->diffuseColor().redF())); - m_pOutStream->writeAttribute("green", QString::number(pMaterial->diffuseColor().greenF())); - m_pOutStream->writeAttribute("blue", QString::number(pMaterial->diffuseColor().blueF())); - m_pOutStream->writeAttribute("alpha", QString::number(pProperties->overwriteTransparency())); - m_pOutStream->writeEndElement(); // Color - m_pOutStream->writeEndElement(); // SurfaceAttributes - } - else if ((pProperties->renderingMode() == glc::OverwriteMaterial)) - { - GLC_Material* pMaterial= pProperties->overwriteMaterial(); - m_pOutStream->writeStartElement("SurfaceAttributes"); - m_pOutStream->writeAttribute("xsi:type", "SurfaceAttributesType"); - m_pOutStream->writeStartElement("Color"); - m_pOutStream->writeAttribute("xsi:type", "RGBAColorType"); - m_pOutStream->writeAttribute("red", QString::number(pMaterial->diffuseColor().redF())); - m_pOutStream->writeAttribute("green", QString::number(pMaterial->diffuseColor().greenF())); - m_pOutStream->writeAttribute("blue", QString::number(pMaterial->diffuseColor().blueF())); - m_pOutStream->writeAttribute("alpha", QString::number(pMaterial->opacity())); - m_pOutStream->writeEndElement(); // Color - m_pOutStream->writeEndElement(); // SurfaceAttributes - } - - } - m_pOutStream->writeEndElement(); // GraphicProperties - } - m_pOutStream->writeEndElement(); // DefaultViewProperty -} - -bool GLC_WorldTo3dxml::continu() -{ - bool continuValue= true; - if (NULL != m_pReadWriteLock) - { - Q_ASSERT(NULL != m_pIsInterupted); - m_pReadWriteLock->lockForRead(); - continuValue= !(*m_pIsInterupted); - m_pReadWriteLock->unlock(); - } - return continuValue; -} - -QString GLC_WorldTo3dxml::symplifyName(QString name) -{ - const int nameSize= name.size(); - for (int i= 0; i < nameSize; ++i) - { - const QChar curChar= name.at(i); - bool simplifyCharacter= !curChar.isLetterOrNumber() && (curChar != '.'); - simplifyCharacter= simplifyCharacter && (curChar != '/') && (curChar != '\\'); - if (simplifyCharacter) - { - name.replace(i, 1, '_'); - } - } - - return name; -} - -QList GLC_WorldTo3dxml::instancePath(const GLC_StructOccurence* pOccurence) -{ - QList path; - if (!pOccurence->isOrphan()) - { - GLC_StructInstance* pInstance= pOccurence->structInstance(); - Q_ASSERT(m_InstanceToIdHash.contains(pInstance)); - path.prepend(m_InstanceToIdHash.value(pInstance)); - QList subPath(instancePath(pOccurence->parent())); - subPath.append(path); - path= subPath; - } - return path; -} diff --git a/ground/gcs/src/libs/glc_lib/io/glc_worldto3dxml.h b/ground/gcs/src/libs/glc_lib/io/glc_worldto3dxml.h deleted file mode 100644 index c9344e2a9..000000000 --- a/ground/gcs/src/libs/glc_lib/io/glc_worldto3dxml.h +++ /dev/null @@ -1,278 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_worldto3dxml.h interface for the GLC_WorldTo3dxml class. - -#ifndef GLC_WORLDTO3DXML_H_ -#define GLC_WORLDTO3DXML_H_ -#include -#include - -#include "../sceneGraph/glc_world.h" -#include "../glc_config.h" -#include - -class QuaZip; -class QuaZipFile; -class QFile; -class GLC_Mesh; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_WorldTo3dxml -/*! \brief GLC_WorldTo3dxml : Export a GLC_World to a 3dxml file */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_WorldTo3dxml : public QObject -{ - Q_OBJECT - -public: - enum ExportType - { - Compressed3dxml, - Exploded3dxml, - StructureOnly - }; -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - GLC_WorldTo3dxml(const GLC_World& world, bool threaded= true); - virtual ~GLC_WorldTo3dxml(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! @name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Save the world to the specified file name - bool exportTo3dxml(const QString& filename, GLC_WorldTo3dxml::ExportType exportType, bool exportMaterial= true); - - //! Save the given 3DRep into the given path name - bool exportReferenceTo3DRep(const GLC_3DRep* p3DRep, const QString& fullFileName); - - //! Set the name of the 3dxml generator default is GLC_LIB - inline void setGeneratorName(const QString& generator) - {m_Generator= generator;} - - //! set interrupt flag adress - void setInterupt(QReadWriteLock* pReadWriteLock, bool* pInterupt); -//@} - -////////////////////////////////////////////////////////////////////// -/*! @name Private services functions */ -//@{ -////////////////////////////////////////////////////////////////////// -private: - - //! Write 3DXML Header - void writeHeader(); - - //! Write 3DXML reference 3D element - void writeReference3D(const GLC_StructReference* pRef); - - //! Write 3DXML reference representation - void writeReferenceRep(const GLC_3DRep* p3DRep); - - //! Write 3DXML instance 3D element - void writeInstance3D(const GLC_StructInstance* pInstance, unsigned int parentId); - - //! Write 3DXML instance 3D element - void writeInstanceRep(const GLC_3DRep* p3DRep, unsigned int parentId); - - //! Set the streamwriter to the specified file and return true if success - void setStreamWriterToFile(const QString& fileName); - - //! Add the manifest to 3DXML compressed file - void addManifest(); - - //! Export the assembly structure from the list of reference - void exportAssemblyStructure(); - - //! Export assembly from the given occurence - void exportAssemblyFromOccurence(const GLC_StructOccurence* pOccurence); - - //! Return the 3DXML string of the given matrix - QString matrixString(const GLC_Matrix4x4& matrix); - - //! Write the given 3DRep to 3DXML 3DRep - void write3DRep(const GLC_3DRep* pRep, const QString& fileName); - - //! Return the file name of the given 3DRep - QString representationFileName(const GLC_3DRep* pRep); - - //! Write the given mesh to 3DXML 3DRep - void writeGeometry(const GLC_Mesh* pMesh); - - //! Write the geometry face from the given lod and material - void writeGeometryFace(const GLC_Mesh* pMesh, int lod, GLC_uint materialId); - - //! Write surface attributes - void writeSurfaceAttributes(const GLC_Material* pMaterial); - - //! Write edges - void writeEdges(const GLC_Mesh* pMesh); - - //! Write lines attributes - void writeLineAttributes(const QColor& color); - - //! Write Material - void writeMaterial(const GLC_Material* pMaterial); - - //! Write material attributes - void writeMaterialAttributtes(const QString& name, const QString& type, const QString& value); - - //! Return a QString of a color - QString colorToString(const QColor& color); - - //! Write the CATRepImage.3dxml file - void writeCatRepImageFile(const QList& materialList); - - //! Write CATRepresentationImage of the given material and id - void writeCATRepresentationImage(const GLC_Material* pMat, unsigned int id); - - //! Write all material related files in the 3dxml - void writeAllMaterialRelatedFilesIn3dxml(); - - //! Write image file in 3DXML archive or folder - void writeImageFileIn3dxml(const QList& materialList); - - //! Write de CATMaterialRef - void writeCatMaterialRef(const QList& materialList); - - //! Write a material in the CATMaterialRef - void writeMaterialToCatMaterialRef(const GLC_Material* pMat, unsigned int* id); - - //! Add the given texture to 3DXML with the given name - void addImageTextureTo3dxml(const QImage& image, const QString& fileName); - - //! Transform the given name to the 3DXML name (no double) - QString xmlFileName(QString fileName); - - //! Write extension attributes to 3DXML - void writeExtensionAttributes(GLC_Attributes* pAttributes); - - //! Write the default view property of the given occurence - void writeOccurenceDefaultViewProperty(const GLC_StructOccurence* pOccurence); - - //! return true if export must continu - bool continu(); - - //! Return the simplified name of the given name - QString symplifyName(QString name); - - //! Return the path of the given occurence - QList instancePath(const GLC_StructOccurence* pOccurence); - -//@} - -////////////////////////////////////////////////////////////////////// -// Qt Signals -////////////////////////////////////////////////////////////////////// - signals: - void currentQuantum(int); - -////////////////////////////////////////////////////////////////////// - /* Private members */ -////////////////////////////////////////////////////////////////////// -private: - //! The world to export - GLC_World m_World; - - //! The export type - ExportType m_ExportType; - - //! The file name in which the world is exported - QString m_FileName; - - //! The Stream writer - QXmlStreamWriter* m_pOutStream; - - //! QString the 3DXML Generator - QString m_Generator; - - //! The current 3DXML id - unsigned int m_CurrentId; - - //! The 3DXML Archive - QuaZip* m_p3dxmlArchive; - - //! The current quazp file - QuaZipFile* m_pCurrentZipFile; - - //! The current file - QFile* m_pCurrentFile; - - //! the 3dxml absolute path - QString m_AbsolutePath; - - //! Map reference to 3dxml id - QHash m_ReferenceToIdHash; - - //! Map instance to 3dxml id - QHash m_InstanceToIdHash; - - //! Map reference rep to 3dxml id - QHash m_ReferenceRepToIdHash; - - //! Map Reference rep to 3dxml fileName - QHash m_ReferenceRepTo3dxmlFileName; - - //! InstanceRep SET - QSet m_InstanceRep; - - //! Map between material id and 3DRep name - QHash m_MaterialIdToMaterialName; - - //! Map between material id and 3dxml image id - QHash m_MaterialIdToMaterialId; - - //! Map between material id and 3DXML texture name - QHash m_MaterialIdToTexture3dxmlName; - - //! Map between material id and 3dxml image id - QHash m_MaterialIdTo3dxmlImageId; - - //! Flag to know if material must be exported - bool m_ExportMaterial; - - //! Set of files in the 3dxml - QSet m_3dxmlFileSet; - - //! file name increment - unsigned int m_FileNameIncrement; - - //! List of structOccurence with overload properties - QList m_ListOfOverLoadedOccurence; - - //! Mutex - QReadWriteLock* m_pReadWriteLock; - - //! Flag to know if export must be interupted - bool* m_pIsInterupted; - - //! Flag to know if export is threaded (the default) - bool m_IsThreaded; - -}; - -#endif /* GLC_WORLDTO3DXML_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/io/glc_xmlutil.h b/ground/gcs/src/libs/glc_lib/io/glc_xmlutil.h deleted file mode 100644 index 1f85bad76..000000000 --- a/ground/gcs/src/libs/glc_lib/io/glc_xmlutil.h +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_xmlutil.h interface for some QStream XML utilities. - -#ifndef XMLUTIL_H_ -#define XMLUTIL_H_ -#include -#include -#include -#include - -namespace glcXmlUtil -{ -//! Go to the given xml Element, return true on succes -inline bool goToElement(QXmlStreamReader* pReader, const QString& element); - -// Return the content of an element -inline QString getContent(QXmlStreamReader* pReader, const QString& element); - -//! Read the specified attribute -inline QString readAttribute(QXmlStreamReader* pReader, const QString& attribute); - -//! Return true if the end of specified element is not reached -inline bool endElementNotReached(QXmlStreamReader* pReader, const QString& element); - -//! Return true if the start of specified element is not reached -inline bool startElementNotReached(QXmlStreamReader* pReader, const QString& element); - -//! Go to the end Element of a xml -inline void goToEndElement(QXmlStreamReader* pReader, const QString& element); - -}; - - -bool glcXmlUtil::goToElement(QXmlStreamReader* pReader, const QString& element) -{ - while(!pReader->atEnd() && !(pReader->isStartElement() && (pReader->name() == element))) - { - pReader->readNext(); - } - return !pReader->atEnd(); -} - -QString glcXmlUtil::getContent(QXmlStreamReader* pReader, const QString& element) -{ - QString content; - while(endElementNotReached(pReader, element)) - { - pReader->readNext(); - if (pReader->isCharacters() && !pReader->text().isEmpty()) - { - content+= pReader->text().toString(); - } - } - - return content.trimmed(); -} - -QString glcXmlUtil::readAttribute(QXmlStreamReader* pReader, const QString& attribute) -{ - return pReader->attributes().value(attribute).toString(); -} - -bool glcXmlUtil::endElementNotReached(QXmlStreamReader* pReader, const QString& element) -{ - return !pReader->atEnd() && !(pReader->isEndElement() && (pReader->name() == element)); -} - -bool glcXmlUtil::startElementNotReached(QXmlStreamReader* pReader, const QString& element) -{ - return !pReader->atEnd() && !(pReader->isStartElement() && (pReader->name() == element)); -} - -void glcXmlUtil::goToEndElement(QXmlStreamReader* pReader, const QString& element) -{ - while(endElementNotReached(pReader, element)) - { - pReader->readNext(); - } -} - -#endif /* XMLUTIL_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/maths/glc_geomtools.cpp b/ground/gcs/src/libs/glc_lib/maths/glc_geomtools.cpp deleted file mode 100644 index fa8af18bc..000000000 --- a/ground/gcs/src/libs/glc_lib/maths/glc_geomtools.cpp +++ /dev/null @@ -1,787 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_geomtools.cpp implementation of geometry function. - -#include "glc_geomtools.h" -#include "glc_matrix4x4.h" - -#include - - -double glc::comparedPrecision= glc::defaultPrecision; - -////////////////////////////////////////////////////////////////////// -//Tools Functions -////////////////////////////////////////////////////////////////////// - -// Test if a polygon is convex -bool glc::polygon2DIsConvex(const QList& vertices) -{ - bool isConvex= true; - const int size= vertices.size(); - if (vertices.size() > 3) - { - GLC_Point2d s0(vertices.at(0)); - GLC_Point2d s1(vertices.at(1)); - GLC_Point2d s2(vertices.at(2)); - const bool openAngle= ((s1.x() - s0.x()) * (s2.y() - s0.y()) - (s2.x() - s0.x()) * (s1.y() - s0.y())) < 0.0; - - int i= 3; - while ((i < size) && isConvex) - { - s0= s1; - s1= s2; - s2= vertices.at(i); - isConvex= openAngle == (((s1.x() - s0.x()) * (s2.y() - s0.y()) - (s2.x() - s0.x()) * (s1.y() - s0.y())) < 0.0); - ++i; - } - } - - return isConvex; -} - -bool glc::polygonIsConvex(QList* pIndexList, const QList& bulkList) -{ - bool isConvex= true; - const int size= pIndexList->size(); - GLuint currentIndex; - GLC_Vector3d v0; - GLC_Vector3d v1; - int i= 0; - while ((i < size) && isConvex) - { - currentIndex= pIndexList->at(i); - v0.setVect(bulkList.at(currentIndex * 3), bulkList.at(currentIndex * 3 + 1), bulkList.at(currentIndex * 3 + 2)); - currentIndex= pIndexList->at((i + 1) % size); - v1.setVect(bulkList.at(currentIndex * 3), bulkList.at(currentIndex * 3 + 1), bulkList.at(currentIndex * 3 + 2)); - isConvex= (v0.angleWithVect(v1) < glc::PI); - ++i; - } - return isConvex; -} -// find intersection between two 2D segments -QVector glc::findIntersection(const GLC_Point2d& s1p1, const GLC_Point2d& s1p2, const GLC_Point2d& s2p1, const GLC_Point2d& s2p2) -{ - const GLC_Vector2d D0= s1p2 - s1p1; - const GLC_Vector2d D1= s2p2 - s2p1; - // The QVector of result points - QVector result; - - const GLC_Vector2d E(s2p1 - s1p1); - double kross= D0 ^ D1; - double sqrKross= kross * kross; - const double sqrLen0= D0.x() * D0.x() + D0.y() * D0.y(); - const double sqrLen1= D1.x() * D1.x() + D1.y() * D1.y(); - // Test if the line are nor parallel - if (sqrKross > (EPSILON * sqrLen0 * sqrLen1)) - { - const double s= (E ^ D1) / kross; - if ((s < 0.0) || (s > 1.0)) - { - // Intersection of lines is not a point on segment s1p1 + s * DO - return result; // Return empty QVector - } - const double t= (E ^ D0) / kross; - - if ((t < 0.0) || (t > 1.0)) - { - // Intersection of lines is not a point on segment s2p1 + t * D1 - return result; // Return empty QVector - } - - // Intersection of lines is a point on each segment - result << (s1p1 + (D0 * s)); - return result; // Return a QVector of One Point - } - - // Lines of the segments are parallel - const double sqrLenE= E.x() * E.x() + E.y() * E.y(); - kross= E ^ D0; - sqrKross= kross * kross; - if (sqrKross > (EPSILON * sqrLen0 * sqrLenE)) - { - // Lines of the segments are different - return result; // Return empty QVector - } - - // Lines of the segments are the same. Need to test for overlap of segments. - const double s0= (D0 * E) / sqrLen0; - const double s1= (D0 * D1) / sqrLen0; - const double sMin= qMin(s0, s1); - const double sMax= qMax(s0, s1); - QVector overlaps= findIntersection(0.0, 1.0, sMin, sMax); - const int iMax= overlaps.size(); - for (int i= 0; i < iMax; ++i) - { - result.append(s1p1 + (D0 * overlaps[i])); - } - return result; -} - -// return true if there is an intersection between 2 segments -bool glc::isIntersected(const GLC_Point2d& s1p1, const GLC_Point2d& s1p2, const GLC_Point2d& s2p1, const GLC_Point2d& s2p2) -{ - const GLC_Vector2d D0= s1p2 - s1p1; - const GLC_Vector2d D1= s2p2 - s2p1; - - const GLC_Vector2d E(s2p1 - s1p1); - double kross= D0 ^ D1; - double sqrKross= kross * kross; - const double sqrLen0= D0.x() * D0.x() + D0.y() * D0.y(); - const double sqrLen1= D1.x() * D1.x() + D1.y() * D1.y(); - // Test if the line are nor parallel - if (sqrKross > (EPSILON * sqrLen0 * sqrLen1)) - { - const double s= (E ^ D1) / kross; - if ((s < 0.0) || (s > 1.0)) - { - // Intersection of lines is not a point on segment s1p1 + s * DO - return false; - } - const double t= (E ^ D0) / kross; - - if ((t < 0.0) || (t > 1.0)) - { - // Intersection of lines is not a point on segment s2p1 + t * D1 - return false; - } - - // Intersection of lines is a point on each segment - return true; - } - - // Lines of the segments are parallel - const double sqrLenE= E.x() * E.x() + E.y() * E.y(); - kross= E ^ D0; - sqrKross= kross * kross; - if (sqrKross > (EPSILON * sqrLen0 * sqrLenE)) - { - // Lines of the segments are different - return false; - } - - // Lines of the segments are the same. Need to test for overlap of segments. - const double s0= (D0 * E) / sqrLen0; - const double s1= s0 + (D0 * D1) / sqrLen0; - const double sMin= qMin(s0, s1); - const double sMax= qMax(s0, s1); - if (findIntersection(0.0, 1.0, sMin, sMax).size() == 0) return false; else return true; - -} - -// return true if there is an intersection between a ray and a segment -bool glc::isIntersectedRaySegment(const GLC_Point2d& s1p1, const GLC_Vector2d& s1p2, const GLC_Point2d& s2p1, const GLC_Point2d& s2p2) -{ - const GLC_Vector2d D0= s1p2 - s1p1; - const GLC_Vector2d D1= s2p2 - s2p1; - - const GLC_Vector2d E(s2p1 - s1p1); - double kross= D0 ^ D1; - double sqrKross= kross * kross; - const double sqrLen0= D0.x() * D0.x() + D0.y() * D0.y(); - const double sqrLen1= D1.x() * D1.x() + D1.y() * D1.y(); - // Test if the line are nor parallel - if (sqrKross > (EPSILON * sqrLen0 * sqrLen1)) - { - const double s= (E ^ D1) / kross; - if ((s < 0.0)) - { - // Intersection of lines is not a point on segment s1p1 + s * DO - return false; - } - const double t= (E ^ D0) / kross; - - if ((t < 0.0) || (t > 1.0)) - { - // Intersection of lines is not a point on segment s2p1 + t * D1 - return false; - } - - // Intersection of lines is a point on each segment - return true; - } - - // Lines of the segments are parallel - const double sqrLenE= E.x() * E.x() + E.y() * E.y(); - kross= E ^ D0; - sqrKross= kross * kross; - if (sqrKross > (EPSILON * sqrLen0 * sqrLenE)) - { - // Lines of are different - return false; - } - else return true; - -} - -// find intersection of two intervals [u0, u1] and [v0, v1] -QVector glc::findIntersection(const double& u0, const double& u1, const double& v0, const double& v1) -{ - //Q_ASSERT((u0 < u1) and (v0 < v1)); - QVector result; - if (u1 < v0 || u0 > v1) return result; // Return empty QVector - - if (u1 > v0) - { - if (u0 < v1) - { - if (u0 < v0) result.append(v0); else result.append(u0); - if (u1 > v1) result.append(v1); else result.append(u1); - return result; - } - else // u0 == v1 - { - result.append(u0); - return result; - } - } - else // u1 == v0 - { - result.append(u1); - return result; - } -} - -// return true if the segment is in polygon cone -bool glc::segmentInCone(const GLC_Point2d& V0, const GLC_Point2d& V1, const GLC_Point2d& VM, const GLC_Point2d& VP) -{ - // assert: VM, V0, VP are not collinear - const GLC_Vector2d diff(V1 - V0); - const GLC_Vector2d edgeL(VM - V0); - const GLC_Vector2d edgeR(VP - V0); - if ((edgeR ^ edgeL) > 0) - { - // Vertex is convex - return (((diff ^ edgeR) < 0.0) && ((diff ^ edgeL) > 0.0)); - } - else - { - // Vertex is reflex - return (((diff ^ edgeR) < 0.0) || ((diff ^ edgeL) > 0.0)); - } -} - -// Return true if the segment is a polygon diagonal -bool glc::isDiagonal(const QList& polygon, const int i0, const int i1) -{ - const int size= polygon.size(); - int iM= (i0 - 1) % size; - if (iM < 0) iM= size - 1; - int iP= (i0 + 1) % size; - - if (!segmentInCone(polygon[i0], polygon[i1], polygon[iM], polygon[iP])) - { - return false; - } - - int j0= 0; - int j1= size - 1; - // test segment to see if it is a diagonal - while (j0 < size) - { - if (j0 != i0 && j0 != i1 && j1 != i0 && j1 != i1) - { - if (isIntersected(polygon[i0], polygon[i1], polygon[j0], polygon[j1])) - return false; - } - - j1= j0; - ++j0; - } - - return true; -} - -// Triangulate a polygon -void glc::triangulate(QList& polygon, QList& index, QList& tList) -{ - const int size= polygon.size(); - if (size == 3) - { - tList << index[0] << index[1] << index[2]; - return; - } - int i0= 0; - int i1= 1; - int i2= 2; - while(i0 < size) - { - if (isDiagonal(polygon, i0, i2)) - { - // Add the triangle before removing the ear. - tList << index[i0] << index[i1] << index[i2]; - // Remove the ear from polygon and index lists - polygon.removeAt(i1); - index.removeAt(i1); - // recurse to the new polygon - triangulate(polygon, index, tList); - return; - } - ++i0; - i1= (i1 + 1) % size; - i2= (i2 + 1) % size; - } -} - -// return true if the polygon is couterclockwise ordered -bool glc::isCounterclockwiseOrdered(const QList& polygon) -{ - const int size= polygon.size(); - int j0= 0; - int j1= size - 1; - // test segment to see if it is a diagonal - while (j0 < size) - { - GLC_Vector2d perp((polygon[j0] - polygon[j1]).perp()); - int j2= 0; - int j3= size - 1; - bool isIntersect= false; - // Application of perp vector - GLC_Point2d moy((polygon[j0] + polygon[j1]) * 0.5); - while (j2 < size && !isIntersect) - { - if(j2 != j0 && j3 != j1) - { - if (isIntersectedRaySegment(moy, (perp + moy), polygon[j2], polygon[j3])) - isIntersect= true; - } - j3= j2; - ++j2; - } - if(!isIntersect) return false; - j1= j0; - ++j0; - } - - return true; - -} - -// Triangulate a no convex polygon -void glc::triangulatePolygon(QList* pIndexList, const QList& bulkList) -{ - int size= pIndexList->size(); - if (polygonIsConvex(pIndexList, bulkList)) - { - QList indexList(*pIndexList); - pIndexList->clear(); - for (int i= 0; i < size - 2; ++i) - { - pIndexList->append(indexList.at(0)); - pIndexList->append(indexList.at(i + 1)); - pIndexList->append(indexList.at(i + 2)); - } - } - else - { - // Get the polygon vertice - QList originPoints; - QHash indexMap; - - QList face; - GLC_Point3d currentPoint; - int delta= 0; - for (int i= 0; i < size; ++i) - { - const int currentIndex= pIndexList->at(i); - currentPoint= GLC_Point3d(bulkList.at(currentIndex * 3), bulkList.at(currentIndex * 3 + 1), bulkList.at(currentIndex * 3 + 2)); - if (!originPoints.contains(currentPoint)) - { - originPoints.append(GLC_Point3d(bulkList.at(currentIndex * 3), bulkList.at(currentIndex * 3 + 1), bulkList.at(currentIndex * 3 + 2))); - indexMap.insert(i - delta, currentIndex); - face.append(i - delta); - } - else - { - qDebug() << "Multi points"; - ++delta; - } - } - // Values of PindexList must be reset - pIndexList->clear(); - - // Update size - size= size - delta; - - // Check new size - if (size < 3) return; - - //-------------- Change frame to mach polygon plane - // Compute face normal - const GLC_Point3d point1(originPoints[0]); - const GLC_Point3d point2(originPoints[1]); - const GLC_Point3d point3(originPoints[2]); - - const GLC_Vector3d edge1(point2 - point1); - const GLC_Vector3d edge2(point3 - point2); - - GLC_Vector3d polygonPlaneNormal(edge1 ^ edge2); - polygonPlaneNormal.normalize(); - - // Create the transformation matrix - GLC_Matrix4x4 transformation; - - GLC_Vector3d rotationAxis(polygonPlaneNormal ^ Z_AXIS); - if (!rotationAxis.isNull()) - { - const double angle= acos(polygonPlaneNormal * Z_AXIS); - transformation.setMatRot(rotationAxis, angle); - } - - QList polygon; - // Transform polygon vertexs - for (int i=0; i < size; ++i) - { - originPoints[i]= transformation * originPoints[i]; - // Create 2d vector - polygon << originPoints[i].toVector2d(Z_AXIS); - } - // Create the index - QList index= face; - - const bool faceIsCounterclockwise= isCounterclockwiseOrdered(polygon); - - if(!faceIsCounterclockwise) - { - //qDebug() << "face Is Not Counterclockwise"; - const int max= size / 2; - for (int i= 0; i < max; ++i) - { - polygon.swap(i, size - 1 -i); - int temp= face[i]; - face[i]= face[size - 1 - i]; - face[size - 1 - i]= temp; - } - } - - QList tList; - triangulate(polygon, index, tList); - size= tList.size(); - for (int i= 0; i < size; i+= 3) - { - // Avoid normal problem - if (faceIsCounterclockwise) - { - pIndexList->append(indexMap.value(face[tList[i]])); - pIndexList->append(indexMap.value(face[tList[i + 1]])); - pIndexList->append(indexMap.value(face[tList[i + 2]])); - } - else - { - pIndexList->append(indexMap.value(face[tList[i + 2]])); - pIndexList->append(indexMap.value(face[tList[i + 1]])); - pIndexList->append(indexMap.value(face[tList[i]])); - } - } - Q_ASSERT(size == pIndexList->size()); - } - -} - -bool glc::lineIntersectPlane(const GLC_Line3d& line, const GLC_Plane& plane, GLC_Point3d* pPoint) -{ - const GLC_Vector3d n= plane.normal(); - const GLC_Point3d p= line.startingPoint(); - const GLC_Vector3d d= line.direction(); - - const double denominator= d * n; - if (qFuzzyCompare(fabs(denominator), 0.0)) - { - qDebug() << " glc::lineIntersectPlane : Line parallel to the plane"; - // The line is parallel to the plane - return false; - } - else - { - // The line intersect the plane by one point - const double t= -((n * p) + plane.coefD()) / denominator; - (*pPoint)= p + (t * d); - - return true; - } -} - -GLC_Point3d glc::project(const GLC_Point3d& point, const GLC_Line3d& line) -{ - const GLC_Vector3d lineDirection(line.direction().normalize()); - double t= lineDirection * (point - line.startingPoint()); - GLC_Point3d projectedPoint= line.startingPoint() + (t * lineDirection); - return projectedPoint; -} - -double glc::pointLineDistance(const GLC_Point3d& point, const GLC_Line3d& line) -{ - const GLC_Vector3d lineDirection(line.direction().normalize()); - double t= lineDirection * (point - line.startingPoint()); - GLC_Point3d projectedPoint= line.startingPoint() + (t * lineDirection); - return (point - projectedPoint).length(); -} - -bool glc::pointsAreCollinear(const GLC_Point3d& p1, const GLC_Point3d& p2, const GLC_Point3d& p3) -{ - bool subject= false; - if (compare(p1, p2) || compare(p1, p3) || compare(p2, p3)) - { - subject= true; - } - else - { - GLC_Vector3d p1p2= (p2 - p1).setLength(1.0); - GLC_Vector3d p2p3= (p3 - p2).setLength(1.0); - subject= (compare(p1p2, p2p3) || compare(p1p2, p2p3.inverted())); - } - return subject; -} - -bool glc::compare(double p1, double p2) -{ - return qAbs(p1 - p2) <= comparedPrecision; -} - -bool glc::compare(double p1, double p2, double accuracy) -{ - return qAbs(p1 - p2) <= accuracy; -} - -bool glc::compareAngle(double p1, double p2) -{ - const double anglePrecision= toRadian(comparedPrecision); - return qAbs(p1 - p2) <= anglePrecision; -} - -bool glc::compare(const GLC_Vector3d& v1, const GLC_Vector3d& v2) -{ - bool compareResult= (qAbs(v1.x() - v2.x()) <= comparedPrecision); - compareResult= compareResult && (qAbs(v1.y() - v2.y()) <= comparedPrecision); - compareResult= compareResult && (qAbs(v1.z() - v2.z()) <= comparedPrecision); - - return compareResult; -} - -bool glc::compare(const GLC_Vector3d& v1, const GLC_Vector3d& v2, double accuracy) -{ - bool compareResult= (qAbs(v1.x() - v2.x()) <= accuracy); - compareResult= compareResult && (qAbs(v1.y() - v2.y()) <= accuracy); - compareResult= compareResult && (qAbs(v1.z() - v2.z()) <= accuracy); - - return compareResult; -} - -bool glc::compare(const GLC_Vector2d& v1, const GLC_Vector2d& v2) -{ - bool compareResult= (qAbs(v1.x() - v2.x()) <= comparedPrecision); - return compareResult && (qAbs(v1.y() - v2.y()) <= comparedPrecision); -} - -bool glc::compare(const GLC_Vector2d& v1, const GLC_Vector2d& v2, double accuracy) -{ - bool compareResult= (qAbs(v1.x() - v2.x()) <= accuracy); - return compareResult && (qAbs(v1.y() - v2.y()) <= accuracy); -} - -bool glc::compare(const QPointF& v1, const QPointF& v2) -{ - bool compareResult= (qAbs(v1.x() - v2.x()) <= comparedPrecision); - return compareResult && (qAbs(v1.y() - v2.y()) <= comparedPrecision); -} - -bool glc::compare(const QPointF& v1, const QPointF& v2, double accuracy) -{ - bool compareResult= (qAbs(v1.x() - v2.x()) <= accuracy); - return compareResult && (qAbs(v1.y() - v2.y()) <= accuracy); -} - -double glc::round(double value) -{ - value= value / comparedPrecision; - value= (value >= 0.0 ? floor(value + 0.5) : ceil(value - 0.5)); - value= value * comparedPrecision; - return value; -} - -double glc::round(double value, double accuracy) -{ - value= value / accuracy; - value= (value >= 0.0 ? floor(value + 0.5) : ceil(value - 0.5)); - value= value * accuracy; - return value; -} - -QPointF glc::round(const QPointF& point) -{ - QPointF subject(glc::round(static_cast(point.x())), glc::round(static_cast(point.y()))); - return subject; -} - -QPointF glc::round(const QPointF& point, double accuracy) -{ - QPointF subject(glc::round(static_cast(point.x()), accuracy), glc::round(static_cast(point.y()), accuracy)); - return subject; -} - -GLC_Vector2d round(const GLC_Vector2d& vector) -{ - GLC_Vector2d subject(glc::round(vector.x()), glc::round(vector.y())); - - return subject; -} - -GLC_Vector2d round(const GLC_Vector2d& vector, double accuracy) -{ - GLC_Vector2d subject(glc::round(vector.x(), accuracy), glc::round(vector.y(), accuracy)); - - return subject; -} - -GLC_Vector3d round(const GLC_Vector3d& vector) -{ - GLC_Vector3d subject(glc::round(vector.x()), glc::round(vector.y()), glc::round(vector.z())); - - return subject; -} - -GLC_Vector3d round(const GLC_Vector3d& vector, double accuracy) -{ - GLC_Vector3d subject(glc::round(vector.x(), accuracy), glc::round(vector.y(), accuracy), glc::round(vector.z(), accuracy)); - - return subject; -} - -bool glc::pointInPolygon(const GLC_Point2d& point, const QList& polygon) -{ - const int polygonSize= polygon.size(); - bool inside= false; - int i= 0; - int j= polygonSize - 1; - - while (i < polygonSize) - { - const GLC_Point2d point0= polygon.at(i); - const GLC_Point2d point1= polygon.at(j); - if (point.y() < point1.y()) - { - //point1 above ray - if (point0.y() <= point.y()) - { - //point2 on or below ray - const double val1= (point.y() - point0.y()) * (point1.x() - point0.x()); - const double val2= (point.x() - point0.x()) * (point1.y() - point0.y()); - if (val1 > val2) inside= !inside; - } - } - else if (point.y() < point0.y()) - { - // point 1 on or below ray, point0 above ray - const double val1= (point.y() - point0.y()) * (point1.x() - point0.x()); - const double val2= (point.x() - point0.x()) * (point1.y() - point0.y()); - if (val1 < val2) inside= !inside; - } - j= i; - ++i; - } - return inside; -} - -double glc::zeroTo2PIAngle(double angle) -{ - if (qFuzzyCompare(fabs(angle), glc::PI)) - { - angle= glc::PI; - } - else if (angle < 0) - { - angle= (2.0 * glc::PI) + angle; - } - return angle; -} - -QList glc::polygonIn2d(QList polygon3d) -{ - const int count= polygon3d.count(); - Q_ASSERT(count > 2); - - // Compute face normal - const GLC_Point3d point1(polygon3d[0]); - const GLC_Point3d point2(polygon3d[1]); - const GLC_Point3d point3(polygon3d[2]); - - const GLC_Vector3d edge1(point2 - point1); - const GLC_Vector3d edge2(point3 - point2); - - GLC_Vector3d polygonPlaneNormal(edge1 ^ edge2); - polygonPlaneNormal.normalize(); - - // Create the transformation matrix - GLC_Matrix4x4 transformation; - - GLC_Vector3d rotationAxis(polygonPlaneNormal ^ Z_AXIS); - if (!rotationAxis.isNull()) - { - const double angle= acos(polygonPlaneNormal * Z_AXIS); - transformation.setMatRot(rotationAxis, angle); - } - - QList subject; - // Transform polygon vertexs - for (int i=0; i < count; ++i) - { - polygon3d[i]= transformation * polygon3d[i]; - // Create 2d vector - subject << polygon3d[i].toVector2d(Z_AXIS); - } - - return subject; -} - -QList glc::normalyzePolygon(const QList& polygon) -{ - QList subject; - const int count= polygon.count(); - Q_ASSERT(count > 2); - - GLC_Point2d minPoint= polygon.first(); - GLC_Point2d maxPoint= minPoint; - for (int i= 1; i < count; ++i) - { - GLC_Point2d point= polygon.at(i); - minPoint.setX(qMin(point.x(), minPoint.x())); - minPoint.setY(qMin(point.y(), minPoint.y())); - - maxPoint.setX(qMax(point.x(), maxPoint.x())); - maxPoint.setY(qMax(point.y(), maxPoint.y())); - } - const GLC_Vector2d range= maxPoint - minPoint; - Q_ASSERT(range.x() != 0.0); - Q_ASSERT(range.y() != 0.0); - - for (int i= 0; i < count; ++i) - { - const GLC_Point2d point= polygon.at(i); - const GLC_Point2d temp= (point - minPoint); - - const GLC_Point2d result(temp.x() / range.x(), temp.y() / range.y()); - subject.append(result); - } - - return subject; -} diff --git a/ground/gcs/src/libs/glc_lib/maths/glc_geomtools.h b/ground/gcs/src/libs/glc_lib/maths/glc_geomtools.h deleted file mode 100644 index a1ee2ef09..000000000 --- a/ground/gcs/src/libs/glc_lib/maths/glc_geomtools.h +++ /dev/null @@ -1,162 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_geomtools.h declaration of geometry tools functions - -#ifndef GLC_GEOMTOOLS_H_ -#define GLC_GEOMTOOLS_H_ - -#include -#include -#include - -#include "glc_vector3d.h" -#include "glc_line3d.h" -#include "glc_plane.h" - -#include "../geometry/glc_mesh.h" - -#include "../glc_config.h" - -namespace glc -{ - const double defaultPrecision= 0.01; - GLC_LIB_EXPORT extern double comparedPrecision; -////////////////////////////////////////////////////////////////////// -/*! \name Tools Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// - //! test if the given 2D polygon is convex - GLC_LIB_EXPORT bool polygon2DIsConvex(const QList& vertices); - - //! Test if the given 3d polygon is convex - GLC_LIB_EXPORT bool polygonIsConvex(QList* pIndexList, const QList& bulkList); - - //! find intersection between two 2D segments - /*! Return the intersection as QVector of GLC_Point2d - * - Empty QVector if there is no intersection - * - Qvector size 1 if there is a unique intersection - * - Qvector size 2 if the segement overlap*/ - GLC_LIB_EXPORT QVector findIntersection(const GLC_Point2d&, const GLC_Point2d&, const GLC_Point2d&, const GLC_Point2d&); - - //! Return true if there is an intersection between 2 segments - GLC_LIB_EXPORT bool isIntersected(const GLC_Point2d&, const GLC_Point2d&, const GLC_Point2d&, const GLC_Point2d&); - - //! return true if there is an intersection between a ray and a segment - GLC_LIB_EXPORT bool isIntersectedRaySegment(const GLC_Point2d&, const GLC_Vector2d&, const GLC_Point2d&, const GLC_Point2d&); - - //! Find intersection of two intervals [u0, u1] and [v0, v1] - /*! Return the intersection as QVector of GLC_Vector2d - * - Empty QVector if there is no intersection - * - Qvector size 1 if there is a unique intersection - * - Qvector size 2 if the segement overlap*/ - GLC_LIB_EXPORT QVector findIntersection(const double&, const double&, const double&, const double&); - - //! Return true if the segment is in polygon cone - GLC_LIB_EXPORT bool segmentInCone(const GLC_Point2d&, const GLC_Point2d&, const GLC_Point2d&, const GLC_Point2d&); - - //! Return true if the segment is a polygon diagonal - GLC_LIB_EXPORT bool isDiagonal(const QList&, const int, const int); - - //! Triangulate a polygon - GLC_LIB_EXPORT void triangulate(QList&, QList&, QList&); - - //! Return true if the polygon is couterclockwise ordered - GLC_LIB_EXPORT bool isCounterclockwiseOrdered(const QList&); - - //! Triangulate a polygon return true if the polygon is convex - /*! If the polygon is convex the returned index is a fan*/ - GLC_LIB_EXPORT void triangulatePolygon(QList*, const QList&); - - //! Return true if the given 3d line is intersected with the given plane - /*! If there is an intersection point is set to the given 3d point - * If the line lie on the plane this method return false*/ - GLC_LIB_EXPORT bool lineIntersectPlane(const GLC_Line3d& line, const GLC_Plane& plane, GLC_Point3d* pPoint); - - //! Return the projected point on the given line form the given point - GLC_LIB_EXPORT GLC_Point3d project(const GLC_Point3d& point, const GLC_Line3d& line); - - //! Return the midpoint of the two given points - inline GLC_Point3d midPoint(const GLC_Point3d& point1, const GLC_Point3d point2) - {return point1 + (point2 - point1) * 0.5;} - - //! Return the perpendicular 2D vector of the given 2D vector - inline GLC_Vector2d perpVector(const GLC_Vector2d& vect) - {return GLC_Vector2d(-vect.y(), vect.x());} - - //! Return the distance between the given point and line - GLC_LIB_EXPORT double pointLineDistance(const GLC_Point3d& point, const GLC_Line3d& line); - - //! Return true if the given 3 points are collinear - GLC_LIB_EXPORT bool pointsAreCollinear(const GLC_Point3d& p1, const GLC_Point3d& p2, const GLC_Point3d& p3); - - GLC_LIB_EXPORT bool compare(double p1, double p2); - - GLC_LIB_EXPORT bool compare(double p1, double p2, double accuracy); - - GLC_LIB_EXPORT bool compareAngle(double p1, double p2); - - GLC_LIB_EXPORT bool compare(const GLC_Vector3d& v1, const GLC_Vector3d& v2); - - GLC_LIB_EXPORT bool compare(const GLC_Vector3d& v1, const GLC_Vector3d& v2, double accuracy); - - GLC_LIB_EXPORT bool compare(const GLC_Vector2d& v1, const GLC_Vector2d& v2); - - GLC_LIB_EXPORT bool compare(const GLC_Vector2d& v1, const GLC_Vector2d& v2, double accuracy); - - GLC_LIB_EXPORT bool compare(const QPointF& v1, const QPointF& v2); - - GLC_LIB_EXPORT bool compare(const QPointF& v1, const QPointF& v2, double accuracy); - - GLC_LIB_EXPORT double round(double value); - - GLC_LIB_EXPORT double round(double value, double accuracy); - - GLC_LIB_EXPORT QPointF round(const QPointF& point); - - GLC_LIB_EXPORT QPointF round(const QPointF& point, double accuracy); - - GLC_LIB_EXPORT GLC_Vector2d round(const GLC_Vector2d& vector); - - GLC_LIB_EXPORT GLC_Vector2d round(const GLC_Vector2d& vector, double accuracy); - - GLC_LIB_EXPORT GLC_Vector3d round(const GLC_Vector3d& vector); - - GLC_LIB_EXPORT GLC_Vector3d round(const GLC_Vector3d& vector, double accuracy); - - //! Return true if the given 2d point is inside the given polygon - GLC_LIB_EXPORT bool pointInPolygon(const GLC_Point2d& point, const QList& polygon); - - //! Return the angle from 0 to 2PI from an given angle from -PI to PI - GLC_LIB_EXPORT double zeroTo2PIAngle(double angle); - - //! Return the 2D polygon from the given plane 3D polygon - GLC_LIB_EXPORT QList polygonIn2d(QList polygon3d); - - //! Return 2D polygon with normalyze coordinate - GLC_LIB_EXPORT QList normalyzePolygon(const QList& polygon); - -//@} - -} - -#endif /*GLC_GEOMTOOLS_H_*/ diff --git a/ground/gcs/src/libs/glc_lib/maths/glc_interpolator.cpp b/ground/gcs/src/libs/glc_lib/maths/glc_interpolator.cpp deleted file mode 100644 index e42d170a8..000000000 --- a/ground/gcs/src/libs/glc_lib/maths/glc_interpolator.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_interpolator.cpp implementation of the GLC_Interpolator class. - -#include "glc_interpolator.h" - -using namespace glc; - -GLC_Interpolator::GLC_Interpolator() -: m_InterpolType(INTERPOL_LINEAIRE) -, m_StepCount(1) -{ - -} - -////////////////////////////////////////////////////////////////////// -// Set Function -////////////////////////////////////////////////////////////////////// -void GLC_Interpolator::SetInterpolMat(int NbrPas, const GLC_Vector3d &VectDepart, const GLC_Vector3d &VectArrive - , INTERPOL_TYPE Interpolation) -{ - m_InterpolType= Interpolation; - if (NbrPas != 0) - m_StepCount= NbrPas; - - m_StartPoint= VectDepart; - m_EndPoint= VectArrive; - - CalcInterpolMat(); -} - -void GLC_Interpolator::SetType(INTERPOL_TYPE Interpolation) -{ - if (m_InterpolType != Interpolation) - { - m_InterpolType= Interpolation; - - CalcInterpolMat(); - } -} - -void GLC_Interpolator::SetNbrPas(int NbrPas) -{ - - if ((NbrPas != 0) && (m_StepCount != NbrPas)) - { - m_StepCount= NbrPas; - - CalcInterpolMat(); - } -} - -void GLC_Interpolator::SetVecteurs(const GLC_Vector3d &VectDepart, const GLC_Vector3d &VectArrive) -{ - m_StartPoint= VectDepart; - m_EndPoint= VectArrive; - - - CalcInterpolMat(); - -} - -////////////////////////////////////////////////////////////////////// -// Private sevices functions -////////////////////////////////////////////////////////////////////// - -bool GLC_Interpolator::CalcInterpolMat(void) -{ - - if (m_StartPoint != m_EndPoint) - { - switch (m_InterpolType) - { - case INTERPOL_LINEAIRE: - return CalcInterpolLineaireMat(); - break; - - case INTERPOL_ANGULAIRE: - return CalcInterpolAngulaireMat(); - break; - - case INTERPOL_HOMOTETIE: - return false; - break; - - default: - return false; - } - } - else return false; - -} - - -bool GLC_Interpolator::CalcInterpolLineaireMat(void) -{ - - const GLC_Vector3d VectTrans= (m_EndPoint - m_StartPoint) * (1.0 / m_StepCount); - if(VectTrans.isNull()) - { - m_InterpolMat.setToIdentity(); - return false; - } - else - { - m_InterpolMat.setMatTranslate(VectTrans); - return true; - } -} - -bool GLC_Interpolator::CalcInterpolAngulaireMat(void) -{ - - const GLC_Vector3d AxeRot(m_StartPoint ^ m_EndPoint); - - const double Angle= m_EndPoint.angleWithVect(m_StartPoint) / m_StepCount; - - if (qFuzzyCompare(Angle, 0.0)) - { - m_InterpolMat.setToIdentity(); - return false; - } - else - { - m_InterpolMat.setMatRot( AxeRot, Angle); - return true; - } -} - - - diff --git a/ground/gcs/src/libs/glc_lib/maths/glc_interpolator.h b/ground/gcs/src/libs/glc_lib/maths/glc_interpolator.h deleted file mode 100644 index 83db355cf..000000000 --- a/ground/gcs/src/libs/glc_lib/maths/glc_interpolator.h +++ /dev/null @@ -1,112 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_interpolator.h interface for the GLC_Interpolator class. - -#ifndef GLC_INTERPOLATOR_H_ -#define GLC_INTERPOLATOR_H_ - -#include "glc_vector3d.h" -#include "glc_matrix4x4.h" - -#include "../glc_config.h" - -// Types d'interpolation -enum INTERPOL_TYPE -{ - INTERPOL_LINEAIRE, - INTERPOL_ANGULAIRE, - INTERPOL_HOMOTETIE -}; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Interpolator -/*! \brief GLC_Interpolator : Matrix interpolation class*/ - -/*! An GLC_Interpolator is a class used to interpolate 2 4D matrix*/ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_Interpolator -{ - -public: - //! Default linear interpolation constructor - GLC_Interpolator(); - -////////////////////////////////////////////////////////////////////// -// Set Function -////////////////////////////////////////////////////////////////////// -public: - //! Set interpolation matrix - void SetInterpolMat(int NbrPas, const GLC_Vector3d &VectDepart, const GLC_Vector3d &VectArrive - , INTERPOL_TYPE Interpolation = INTERPOL_LINEAIRE); - - //! Set interpolation type - void SetType(INTERPOL_TYPE Interpolation); - - // Number of step - void SetNbrPas(int NbrPas); - - //! Set start and end vector - void SetVecteurs(const GLC_Vector3d &VectDepart, const GLC_Vector3d &VectArrive); - -////////////////////////////////////////////////////////////////////// -// Get Function -////////////////////////////////////////////////////////////////////// -public: - //! Return th interpolation matrix - inline GLC_Matrix4x4 GetInterpolMat(void) const - {return m_InterpolMat;} - -////////////////////////////////////////////////////////////////////// -// Private services functions -////////////////////////////////////////////////////////////////////// -private: - //! Compute interpolation matrix - bool CalcInterpolMat(void); - - //! Compute linear interolation matrix - bool CalcInterpolLineaireMat(void); - - //! Compute angular interpolation matrix - bool CalcInterpolAngulaireMat(void); - -////////////////////////////////////////////////////////////////////// -// Membres privs -////////////////////////////////////////////////////////////////////// -private: - //! Start Point - GLC_Point3d m_StartPoint; - - //! End Point - GLC_Point3d m_EndPoint; - - //! Interpolation type - INTERPOL_TYPE m_InterpolType; - - //! Interpolation step count - int m_StepCount; - - //! Interpolation matrix - GLC_Matrix4x4 m_InterpolMat; -}; - -#endif /*GLC_INTERPOLATOR_H_*/ diff --git a/ground/gcs/src/libs/glc_lib/maths/glc_line3d.cpp b/ground/gcs/src/libs/glc_lib/maths/glc_line3d.cpp deleted file mode 100644 index 27f7e36a5..000000000 --- a/ground/gcs/src/libs/glc_lib/maths/glc_line3d.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_line3d.cpp Implementation of the GLC_Line3d class. - -#include "glc_line3d.h" - -GLC_Line3d::GLC_Line3d() -: m_Point() -, m_Vector() -{ - -} - -GLC_Line3d::GLC_Line3d(const GLC_Point3d& point, const GLC_Vector3d& vector) -: m_Point(point) -, m_Vector(vector) -{ - -} - - -GLC_Line3d::GLC_Line3d(const GLC_Line3d& line) -: m_Point(line.m_Point) -, m_Vector(line.m_Vector) -{ - -} - - -GLC_Line3d::~GLC_Line3d() -{ - -} diff --git a/ground/gcs/src/libs/glc_lib/maths/glc_line3d.h b/ground/gcs/src/libs/glc_lib/maths/glc_line3d.h deleted file mode 100644 index 85a0e123a..000000000 --- a/ground/gcs/src/libs/glc_lib/maths/glc_line3d.h +++ /dev/null @@ -1,98 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_line3d.h Interface for the GLC_Line3d class. - -#ifndef GLC_LINE3D_H_ -#define GLC_LINE3D_H_ - -#include "glc_vector3d.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Line3d -/*! \brief GLC_Line3d : Math 3d line representation */ - -/*! GLC_Line3d is definined by a 3d point and a vector*/ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_Line3d -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Default constructor - GLC_Line3d(); - - //! Construct a 3d line with the given 3d point and vector - GLC_Line3d(const GLC_Point3d& point, const GLC_Vector3d& vector); - - //! Construct a 3d line with the given 3d line - GLC_Line3d(const GLC_Line3d& line); - - //! Destructor - ~GLC_Line3d(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the starting 3d point of this line - inline GLC_Point3d startingPoint() const - {return m_Point;} - - //! Return the direction vector of this line - inline GLC_Vector3d direction() const - {return m_Vector;} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Set the starting point of this 3d line - inline void setStartingPoint(const GLC_Point3d& point) - {m_Point= point;} - - //! Set the direction vector of this line - inline void setDirection(const GLC_Vector3d& direction) - {m_Vector= direction;} -//@} - -////////////////////////////////////////////////////////////////////// -// Private Member -////////////////////////////////////////////////////////////////////// -private: - //! Starting point of the 3d line - GLC_Point3d m_Point; - - //! Vector of the line - GLC_Vector3d m_Vector; - -}; - -#endif /* GLC_LINE3D_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/maths/glc_matrix4x4.cpp b/ground/gcs/src/libs/glc_lib/maths/glc_matrix4x4.cpp deleted file mode 100644 index ba224734d..000000000 --- a/ground/gcs/src/libs/glc_lib/maths/glc_matrix4x4.cpp +++ /dev/null @@ -1,201 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ -//! \file glc_matrix4x4.cpp implementation of the GLC_Matrix4x4 class. - -#include "glc_matrix4x4.h" - -#include - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -GLC_Matrix4x4& GLC_Matrix4x4::fromEuler(const double angle_x, const double angle_y, const double angle_z) -{ - const double A= cos(angle_x); - const double B= sin(angle_x); - const double C= cos(angle_y); - const double D= sin(angle_y); - const double E= cos(angle_z); - const double F= sin(angle_z); - - const double AD= A * D; - const double BD= B * D; - - m_Matrix[0] = C * E; - m_Matrix[4] = -C * F; - m_Matrix[8] = -D; - m_Matrix[1] = -BD * E + A * F; - m_Matrix[5] = BD * F + A * E; - m_Matrix[9] = -B * C; - m_Matrix[2] = AD * E + B * F; - m_Matrix[6] = -AD * F + B * E; - m_Matrix[10] = A * C; - - m_Matrix[12]= 0.0; m_Matrix[13]= 0.0; m_Matrix[14]= 0.0; m_Matrix[3]= 0.0; m_Matrix[7]= 0.0; m_Matrix[11] = 0.0; - m_Matrix[15] = 1.0; - - return *this; -} - -GLC_Matrix4x4& GLC_Matrix4x4::setColumn(int index, const GLC_Vector3d& vector) -{ - Q_ASSERT(index < 4); - index= index * 4; - m_Matrix[index]= vector.x(); - m_Matrix[index + 1]= vector.y(); - m_Matrix[index + 2]= vector.z(); - - m_Type= General; - - return *this; -} -////////////////////////////////////////////////////////////////////// -// Private services function -////////////////////////////////////////////////////////////////////// - -QVector GLC_Matrix4x4::toEuler(void) const -{ - double angle_x; - double angle_y; - double angle_z; - double tracex, tracey; - angle_y= -asin(m_Matrix[8]); - double C= cos(angle_y); - - if (!(qAbs(C - 0.0) <= glc::EPSILON)) // Gimball lock? - { - tracex= m_Matrix[10] / C; - tracey= - m_Matrix[9] / C; - angle_x= atan2( tracey, tracex); - - tracex= m_Matrix[0] / C; - tracey= - m_Matrix[4] / C; - angle_z= atan2( tracey, tracex); - } - else // Gimball lock? - { - angle_x= 0.0; - tracex= m_Matrix[5] / C; - tracey= m_Matrix[1] / C; - angle_z= atan2( tracey, tracex); - } - QVector result; - result.append(fmod(angle_x, 2.0 * glc::PI)); - result.append(fmod(angle_y, 2.0 * glc::PI)); - result.append(fmod(angle_z, 2.0 * glc::PI)); - - return result; -} - -QString GLC_Matrix4x4::toString() const -{ - QString result; - for (int i= 0; i < DIMMAT4X4; ++i) - { - result+= (QString::number(m_Matrix[0 + i])) + QString(" "); - result+= (QString::number(m_Matrix[4 + i])) + QString(" "); - result+= (QString::number(m_Matrix[8 + i])) + QString(" "); - result+= (QString::number(m_Matrix[12 + i])) + QString("\n"); - } - result.remove(result.size() - 1, 1); - return result; -} - -QQuaternion GLC_Matrix4x4::quaternion() const -{ - QQuaternion subject; - GLC_Matrix4x4 rotMat= rotationMatrix(); - if ((this->type() != GLC_Matrix4x4::Identity) && (rotMat != GLC_Matrix4x4())) - { - const double matrixTrace= rotMat.trace(); - double s, w, x, y, z; - - if (matrixTrace > 0.0) - { - s= 0.5 / sqrt(matrixTrace); - w= 0.25 / s; - x= (rotMat.m_Matrix[9] - rotMat.m_Matrix[6]) * s; - y= (rotMat.m_Matrix[2] - rotMat.m_Matrix[8]) * s; - z= (rotMat.m_Matrix[4] - rotMat.m_Matrix[1]) * s; - } - else - { - if ((abs(rotMat.m_Matrix[0]) > abs(rotMat.m_Matrix[5])) && (abs(rotMat.m_Matrix[0]) > abs(rotMat.m_Matrix[15]))) - { // column 0 greater - s= sqrt(1.0 + rotMat.m_Matrix[0] - rotMat.m_Matrix[5] - rotMat.m_Matrix[10]) * 2.0; - - w= (rotMat.m_Matrix[6] + rotMat.m_Matrix[9] ) / s; - x= 0.5 / s; - y= (rotMat.m_Matrix[1] + rotMat.m_Matrix[4] ) / s; - z= (rotMat.m_Matrix[2] + rotMat.m_Matrix[8] ) / s; - } - else if ((abs(rotMat.m_Matrix[5]) > abs(rotMat.m_Matrix[0])) && (abs(rotMat.m_Matrix[5]) > abs(rotMat.m_Matrix[15]))) - { // column 1 greater - s= sqrt(1.0 + rotMat.m_Matrix[5] - rotMat.m_Matrix[0] - rotMat.m_Matrix[10]) * 2.0; - - w= (rotMat.m_Matrix[2] + rotMat.m_Matrix[8]) / s; - x= (rotMat.m_Matrix[1] + rotMat.m_Matrix[4]) / s; - y= 0.5 / s; - z= (rotMat.m_Matrix[6] + rotMat.m_Matrix[9]) / s; - } - else - { // column 3 greater - s= sqrt(1.0 + rotMat.m_Matrix[10] - rotMat.m_Matrix[0] - rotMat.m_Matrix[5]) * 2.0; - - w = (rotMat.m_Matrix[1] + rotMat.m_Matrix[4]) / s; - x = (rotMat.m_Matrix[2] + rotMat.m_Matrix[8]) / s; - y = (rotMat.m_Matrix[6] + rotMat.m_Matrix[9]) / s; - z = 0.5 / s; - } - } - subject= QQuaternion(w, x, y, z); - } - - return subject; -} - -QPair GLC_Matrix4x4::rotationVectorAndAngle() const -{ - QPair subject(GLC_Vector3d(), 0.0); - if (GLC_Matrix4x4(*this).optimise().type() != GLC_Matrix4x4::Identity) - { - QQuaternion quaternion= this->quaternion(); - quaternion.normalize(); - - const double cos_angle= quaternion.scalar(); - const double angle= acos(cos_angle); - double sin_angle= sqrt(1.0 - cos_angle * cos_angle); - - - if (fabs(sin_angle) < 0.0005) sin_angle= 1.0; - - subject.first.setX(quaternion.x() / sin_angle); - subject.first.setY(quaternion.y() / sin_angle); - subject.first.setZ(quaternion.z() / sin_angle); - - subject.second= angle * 2.0; - } - - return subject; -} - diff --git a/ground/gcs/src/libs/glc_lib/maths/glc_matrix4x4.h b/ground/gcs/src/libs/glc_lib/maths/glc_matrix4x4.h deleted file mode 100644 index 366a21261..000000000 --- a/ground/gcs/src/libs/glc_lib/maths/glc_matrix4x4.h +++ /dev/null @@ -1,775 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_matrix4x4.h interface for the GLC_Matrix4x4 class. - -#ifndef GLC_MATRIX4X4_H_ -#define GLC_MATRIX4X4_H_ - -#include -#include -#include - -#include "glc_vector3d.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Matrix4x4 -/*! \brief GLC_Matrix4x4 is a 4 dimensions Matrix*/ - -/*! GLC_Matrix4x4 is used to represent 3d homogeneous transformation in 3d space \n - * GLC_Matrix4x4 is a row first matrix compatible with OpenGL Matrix - * */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_Matrix4x4 -{ - friend class GLC_Vector3d; -public: - //! matrix possible type - enum - { - General= 0x0000, - Direct= 0x0001, - Indirect= 0x0002, - Identity= 0x0003 - }; - -////////////////////////////////////////////////////////////////////// -// Constructor -////////////////////////////////////////////////////////////////////// -public: -//! @name Constructor -//@{ - //! Construct an identity matrix - inline GLC_Matrix4x4(); - - //! Construct a matrix from another matrix - inline GLC_Matrix4x4(const GLC_Matrix4x4 &matrix) - :m_Type(matrix.m_Type) - { - memcpy(m_Matrix, matrix.m_Matrix, sizeof(double) * 16); - } - - //! Construct a matrix from an array of 16 double elements. - inline GLC_Matrix4x4(const double *pArray) - : m_Type(General) - { - memcpy(m_Matrix, pArray, sizeof(double) * 16); - } - - //! Construct a Matrix from an array of 16 float elements. - inline GLC_Matrix4x4(const float *); - - //! Construct rotation matrix from a 3d vector and an angle in radians - inline GLC_Matrix4x4(const GLC_Vector3d &Vect, const double &dAngleRad); - - //! Construct rotation matrix from 2 3d vectors - inline GLC_Matrix4x4(const GLC_Vector3d &Vect1, const GLC_Vector3d &Vect2); - - //! Construct translation matrix from a 3d vector - inline GLC_Matrix4x4(const GLC_Vector3d &Vect) - {setMatTranslate(Vect);} - - //! Construct translation matrix from coordinates in double - inline GLC_Matrix4x4(const double Tx, const double Ty, const double Tz) - {setMatTranslate(Tx, Ty, Tz);} -//@} - -////////////////////////////////////////////////////////////////////// -/*! @name Operator Overload */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Copy the content of the given matrix in this matrix - inline GLC_Matrix4x4& operator = (const GLC_Matrix4x4 &matrix); - - //! Return the product of this matrix to the given matrix - inline GLC_Matrix4x4 operator * (const GLC_Matrix4x4 &Mat) const; - - //! Return the result of transforming the given vector by this matrix - inline GLC_Vector3d operator * (const GLC_Vector3d &Vect) const; - - //! Return true if this matrix is equal to the given matrix - inline bool operator==(const GLC_Matrix4x4& mat) const; - - //! Return true if this matrix is not equal to the given matrix - inline bool operator!=(const GLC_Matrix4x4& mat) const - {return !operator==(mat);} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Function*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the determinant of this matrix - inline double determinant(void) const; - - //! Return a pointer to the row first array of 16 elements of this matrix - /*! Don't modify data with this method*/ - inline const double* getData(void) - {return m_Matrix;} - - //! Return a const pointer to the row first array of 16 elements of this matrix - inline const double* getData(void) const - {return m_Matrix;} - - //! Return a pointer to the row first array of 16 elements of this matrix - inline double* setData(void) - { - m_Type= General; - return m_Matrix; - } - - //! Return a QVector which contains radians Euler angle of this matrix - QVector toEuler(void) const; - - //! Return the string representation of this matrix - QString toString() const; - - //! Return the rotation matrix of this matrix - inline GLC_Matrix4x4 rotationMatrix() const; - - //! Return the isometric matrix of this matrix - inline GLC_Matrix4x4 isometricMatrix() const; - - //! Return the x Scaling of this matrix - inline double scalingX() const - {return GLC_Vector3d(m_Matrix[0], m_Matrix[1], m_Matrix[2]).length();} - - //! Return the y Scaling of this matrix - inline double scalingY() const - {return GLC_Vector3d(m_Matrix[4], m_Matrix[5], m_Matrix[6]).length();} - - //! Return the z Scaling of this matrix - inline double scalingZ() const - {return GLC_Vector3d(m_Matrix[8], m_Matrix[9], m_Matrix[10]).length();} - - //! Return the inverse of this matrix - inline GLC_Matrix4x4 inverted() const - {return GLC_Matrix4x4(*this).invert();} - - //! Return The type af this matrix - inline int type() const - { - return m_Type; - } - - //! Return true if this matrix is direct - inline bool isDirect() const - {return (m_Type & Direct);} - - //! Return this matrix trace - inline double trace() const - {return (m_Matrix[0] + m_Matrix[5] + m_Matrix[10] + m_Matrix[15]);} - - //! Return the quaternion of this matrix - QQuaternion quaternion() const; - - //! Return the rotation vector and angle of this matrix - QPair rotationVectorAndAngle() const; - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Function*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Set this matrix to a rotation matrix given by a 3d vector and an angle in radian - inline GLC_Matrix4x4& setMatRot(const GLC_Vector3d &, const double &); - - //! Set this matrix to a rotation matrix given by 2 3d vectors - inline GLC_Matrix4x4& setMatRot(const GLC_Vector3d &, const GLC_Vector3d &); - - //! Set this matrix to a translation matrix given by a 3d vector - inline GLC_Matrix4x4& setMatTranslate(const GLC_Vector3d &); - - //! Set this matrix to a translation matrix given by 3 double coordinates - inline GLC_Matrix4x4& setMatTranslate(const double, const double, const double); - - //! Set this matrix to a scaling matrix define by 3 double - inline GLC_Matrix4x4& setMatScaling(const double, const double, const double); - - //! Inverse this Matrix and return a reference to this matrix - inline GLC_Matrix4x4& invert(void); - - //! Set this matrix to the identify matrix and return a reference to this matrix - inline GLC_Matrix4x4& setToIdentity(); - - //! Transpose this matrix and return a reference to this matrix - inline GLC_Matrix4x4& transpose(void); - - //! Set this matrix with Euler angle and return a reference to this matrix - GLC_Matrix4x4& fromEuler(const double, const double, const double); - - //! Set this matrix column from the given 3d vector - GLC_Matrix4x4& setColumn(int index, const GLC_Vector3d& vector); - - //! Optimise the usage of this matrix (Genral, Direct, Identity) - inline GLC_Matrix4x4& optimise(bool force= false); - -//@} - -////////////////////////////////////////////////////////////////////// -//! Private services Functions -////////////////////////////////////////////////////////////////////// -private: - - //! Return true if the index (argument) is in the diagonal of this matrix - inline bool isInDiagonal(const int index) const - { - if ((index == 0) || (index == 5) || (index == 10) || (index == 15)) - return true; - else - return false; - } - - //! Return the determinant of this matrix cell given from 2 int - inline double getDeterminantLC(const int, const int) const; - - //! Compute Sub 3X3 matrix given by 2 int and set the given double pointeur - inline void getSubMat(const int, const int, double *) const; - - //! Return the transpose matrix of this matrix - inline GLC_Matrix4x4 getTranspose(void) const; - - //! Return the co-matrix of this matrix - inline GLC_Matrix4x4 getCoMat4x4(void) const; - - - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - - //! Number of elements of this matrix - enum {TAILLEMAT4X4 = 16}; - - //! Matrix size - enum {DIMMAT4X4 = 4}; - - //! Matrix row first array - double m_Matrix[TAILLEMAT4X4]; - - //! the type of this matrix - int m_Type; - -/* -the matrix : - a[00] a[04] a[08] a[12] - - a[01] a[05] a[09] a[13] - - a[02] a[06] a[10] a[14] - - a[03] a[07] a[11] a[15] - */ -// Tx = 12, Ty = 13, Tz = 14 - -}; - - -////////////////////////////////////////////////////////////////////// -// Constructor/Destructor -////////////////////////////////////////////////////////////////////// - -GLC_Matrix4x4::GLC_Matrix4x4() -: m_Type(Identity) -{ - setToIdentity(); -} - -GLC_Matrix4x4::GLC_Matrix4x4(const float *Tableau) -: m_Type(General) -{ - - for (int i=0; i < TAILLEMAT4X4; i++) - { - m_Matrix[i]= static_cast(Tableau[i]); - } -} -GLC_Matrix4x4::GLC_Matrix4x4(const GLC_Vector3d &Vect, const double &dAngleRad) -: m_Type(Direct) -{ - setToIdentity(); - setMatRot(Vect, dAngleRad); -} - -GLC_Matrix4x4::GLC_Matrix4x4(const GLC_Vector3d &Vect1, const GLC_Vector3d &Vect2) -: m_Type(Direct) -{ - setToIdentity(); - setMatRot(Vect1, Vect2); -} - -GLC_Matrix4x4 GLC_Matrix4x4::operator * (const GLC_Matrix4x4 &Mat) const -{ - if (m_Type == Identity) - { - return Mat; - } - else if (Mat.m_Type == Identity) - { - return *this; - } - - int Colonne; - int Ligne; - int i; - double ValInt; - - int IndexInt; - - GLC_Matrix4x4 MatResult; - for (Ligne= 0; Ligne < DIMMAT4X4; Ligne++) - { - for (Colonne=0; Colonne < DIMMAT4X4; Colonne++) - { - ValInt= 0.0; - IndexInt= Colonne * DIMMAT4X4; - - for (i= 0; i < DIMMAT4X4; i++) - { - ValInt+= m_Matrix[ (i * DIMMAT4X4) + Ligne] * Mat.m_Matrix[ IndexInt + i]; - } - MatResult.m_Matrix[ IndexInt + Ligne]= ValInt; - } - } - if ((m_Type == Indirect) || (Mat.m_Type == Indirect)) - { - MatResult.m_Type= Indirect; - } - else - { - MatResult.m_Type= m_Type & Mat.m_Type; - } - - return MatResult; -} - -GLC_Matrix4x4& GLC_Matrix4x4::operator = (const GLC_Matrix4x4 &matrix) -{ - m_Type= matrix.m_Type; - memcpy(m_Matrix, matrix.m_Matrix, sizeof(double) * 16); - - return *this; -} - -GLC_Vector3d GLC_Matrix4x4::operator * (const GLC_Vector3d &Vect) const -{ - double ValInt; - int i; - GLC_Vector3d VectResult; - double mat[4]; - - for (int Index= 0; Index < DIMMAT4X4; Index++) - { - ValInt= 0.0; - for (i= 0; i < DIMMAT4X4 - 1; i++) - { - ValInt+= m_Matrix[(i * DIMMAT4X4) + Index] * Vect.m_Vector[i]; - } - ValInt+= m_Matrix[(3 * DIMMAT4X4) + Index]; - mat[Index]= ValInt; - } - - double invW= 1.0; - if (fabs(mat[3]) > 0.00001) - { - invW/= mat[3]; - } - VectResult.m_Vector[0]= mat[0] * invW; - VectResult.m_Vector[1]= mat[1] * invW; - VectResult.m_Vector[2]= mat[2] * invW; - - - return VectResult; -} - -bool GLC_Matrix4x4::operator==(const GLC_Matrix4x4& mat) const -{ - bool result= true; - int i= 0; - while (result && (i < TAILLEMAT4X4)) - { - result= (qAbs(m_Matrix[i] - mat.m_Matrix[i]) <= glc::EPSILON); - ++i; - } - return result; -} - -GLC_Matrix4x4 GLC_Matrix4x4::rotationMatrix() const -{ - GLC_Matrix4x4 result(*this); - const double invScaleX= 1.0 / scalingX(); - const double invScaleY= 1.0 / scalingY(); - const double invScaleZ= 1.0 / scalingZ(); - result.m_Matrix[0]= result.m_Matrix[0] * invScaleX; - result.m_Matrix[1]= result.m_Matrix[1] * invScaleX; - result.m_Matrix[2]= result.m_Matrix[2] * invScaleX; - - result.m_Matrix[4]= result.m_Matrix[4] * invScaleY; - result.m_Matrix[5]= result.m_Matrix[5] * invScaleY; - result.m_Matrix[6]= result.m_Matrix[6] * invScaleY; - - result.m_Matrix[8]= result.m_Matrix[8] * invScaleZ; - result.m_Matrix[9]= result.m_Matrix[9] * invScaleZ; - result.m_Matrix[10]= result.m_Matrix[10] * invScaleZ; - - result.m_Matrix[12]= 0.0; result.m_Matrix[13]= 0.0; result.m_Matrix[14]= 0.0; - result.m_Matrix[3]= 0.0; result.m_Matrix[7]= 0.0; result.m_Matrix[11]= 0.0; - result.m_Matrix[15]= 1.0; - - result.m_Type= General; - - return result; -} - -GLC_Matrix4x4 GLC_Matrix4x4::isometricMatrix() const -{ - GLC_Matrix4x4 result(*this); - const double invScaleX= 1.0 / scalingX(); - const double invScaleY= 1.0 / scalingY(); - const double invScaleZ= 1.0 / scalingZ(); - result.m_Matrix[0]= result.m_Matrix[0] * invScaleX; - result.m_Matrix[1]= result.m_Matrix[1] * invScaleX; - result.m_Matrix[2]= result.m_Matrix[2] * invScaleX; - - result.m_Matrix[4]= result.m_Matrix[4] * invScaleY; - result.m_Matrix[5]= result.m_Matrix[5] * invScaleY; - result.m_Matrix[6]= result.m_Matrix[6] * invScaleY; - - result.m_Matrix[8]= result.m_Matrix[8] * invScaleZ; - result.m_Matrix[9]= result.m_Matrix[9] * invScaleZ; - result.m_Matrix[10]= result.m_Matrix[10] * invScaleZ; - - result.m_Type= General; - - return result; -} - -GLC_Matrix4x4& GLC_Matrix4x4::setMatRot(const GLC_Vector3d &Vect, const double &dAngleRad) -{ - // Normalize the vector - GLC_Vector3d VectRot(Vect); - VectRot.normalize(); - - // Code optimisation - const double SinAngleSur2= sin(dAngleRad / 2.0); - - // Quaternion computation - const double q0= cos(dAngleRad / 2); - const double q1= VectRot.m_Vector[0] * SinAngleSur2; - const double q2= VectRot.m_Vector[1] * SinAngleSur2; - const double q3= VectRot.m_Vector[2] * SinAngleSur2; - - // Code optimisation - const double q0Carre= (q0 * q0); - const double q1Carre= (q1 * q1); - const double q2Carre= (q2 * q2); - const double q3Carre= (q3 * q3); - - m_Matrix[0]= q0Carre + q1Carre - q2Carre - q3Carre; - m_Matrix[1]= 2.0 * (q1 *q2 + q0 * q3); - m_Matrix[2]= 2.0 * (q1 * q3 - q0 * q2); - m_Matrix[3]= 0.0; - m_Matrix[4]= 2.0 * (q1 * q2 - q0 * q3); - m_Matrix[5]= q0Carre + q2Carre - q3Carre - q1Carre; - m_Matrix[6]= 2.0 * (q2 * q3 + q0 * q1); - m_Matrix[7]= 0.0; - m_Matrix[8]= 2.0 * (q1 * q3 + q0 * q2); - m_Matrix[9]= 2.0 * (q2 * q3 - q0 * q1); - m_Matrix[10]= q0Carre + q3Carre - q1Carre - q2Carre; - m_Matrix[11]= 0.0; - - m_Matrix[12]= 0.0; //TX - m_Matrix[13]= 0.0; //TY - m_Matrix[14]= 0.0; //TZ - m_Matrix[15]= 1.0; - - m_Type= Direct; - - return *this; -} - -GLC_Matrix4x4& GLC_Matrix4x4::setMatRot(const GLC_Vector3d &v1, const GLC_Vector3d &v2) -{ - - if ((v1 != v2) && !v1.isNull() && !v2.isNull()) - { - if (v1 != -v2) - { - const GLC_Vector3d rotationAxis(v1 ^ v2); - if (!rotationAxis.isNull()) - { - const double Angle= acos(v1 * v2); - setMatRot(rotationAxis, Angle); - } - } - else - { - // v1 == -v2 - GLC_Vector3d otherVector(glc::Z_AXIS); - if ((otherVector == v1) || (otherVector == -v2)) - { - otherVector= glc::Y_AXIS; - } - const GLC_Vector3d rotationVector((v1 ^ otherVector).normalize()); - setMatRot(rotationVector, glc::PI); - } - } - - return *this; -} - -GLC_Matrix4x4& GLC_Matrix4x4::setMatTranslate(const GLC_Vector3d &Vect) -{ - m_Matrix[0]= 1.0; m_Matrix[4]= 0.0; m_Matrix[8]= 0.0; m_Matrix[12]= Vect.m_Vector[0]; - m_Matrix[1]= 0.0; m_Matrix[5]= 1.0; m_Matrix[9]= 0.0; m_Matrix[13]= Vect.m_Vector[1]; - m_Matrix[2]= 0.0; m_Matrix[6]= 0.0; m_Matrix[10]= 1.0; m_Matrix[14]= Vect.m_Vector[2]; - m_Matrix[3]= 0.0; m_Matrix[7]= 0.0; m_Matrix[11]= 0.0; m_Matrix[15]= 1.0; - - m_Type= Direct; - - return *this; -} - -GLC_Matrix4x4& GLC_Matrix4x4::setMatTranslate(const double Tx, const double Ty, const double Tz) -{ - m_Matrix[0]= 1.0; m_Matrix[4]= 0.0; m_Matrix[8]= 0.0; m_Matrix[12]= Tx; - m_Matrix[1]= 0.0; m_Matrix[5]= 1.0; m_Matrix[9]= 0.0; m_Matrix[13]= Ty; - m_Matrix[2]= 0.0; m_Matrix[6]= 0.0; m_Matrix[10]= 1.0; m_Matrix[14]= Tz; - m_Matrix[3]= 0.0; m_Matrix[7]= 0.0; m_Matrix[11]= 0.0; m_Matrix[15]= 1.0; - - m_Type= Direct; - - return *this; -} - -GLC_Matrix4x4& GLC_Matrix4x4::setMatScaling(const double sX, const double sY, const double sZ) -{ - m_Matrix[0]= sX; m_Matrix[4]= 0.0; m_Matrix[8]= 0.0; m_Matrix[12]= 0.0; - m_Matrix[1]= 0.0; m_Matrix[5]= sY; m_Matrix[9]= 0.0; m_Matrix[13]= 0.0; - m_Matrix[2]= 0.0; m_Matrix[6]= 0.0; m_Matrix[10]= sZ; m_Matrix[14]= 0.0; - m_Matrix[3]= 0.0; m_Matrix[7]= 0.0; m_Matrix[11]= 0.0; m_Matrix[15]= 1.0; - - m_Type= General; - - return *this; -} - - -GLC_Matrix4x4& GLC_Matrix4x4::invert(void) -{ - const double det= determinant(); - - // Test if the inverion is possible - if (det == 0.0f) return *this; - - const double invDet = 1.0 / det; - GLC_Matrix4x4 TCoMat= getCoMat4x4().getTranspose(); - - for (int i= 0; i < TAILLEMAT4X4; i++) - { - m_Matrix[i]= TCoMat.m_Matrix[i] * invDet; - } - - return *this; -} - -GLC_Matrix4x4& GLC_Matrix4x4::setToIdentity() -{ - m_Matrix[0]= 1.0; m_Matrix[4]= 0.0; m_Matrix[8]= 0.0; m_Matrix[12]= 0.0; - m_Matrix[1]= 0.0; m_Matrix[5]= 1.0; m_Matrix[9]= 0.0; m_Matrix[13]= 0.0; - m_Matrix[2]= 0.0; m_Matrix[6]= 0.0; m_Matrix[10]= 1.0; m_Matrix[14]= 0.0; - m_Matrix[3]= 0.0; m_Matrix[7]= 0.0; m_Matrix[11]= 0.0; m_Matrix[15]= 1.0; - - m_Type= Identity; - - return *this; -} - -GLC_Matrix4x4& GLC_Matrix4x4::transpose(void) -{ - GLC_Matrix4x4 MatT(m_Matrix); - int IndexOrigine; - int IndexTrans; - for (int Colonne= 0; Colonne < DIMMAT4X4; Colonne++) - { - for (int Ligne=0 ; Ligne < DIMMAT4X4; Ligne++) - { - IndexOrigine= (Colonne * DIMMAT4X4) + Ligne; - IndexTrans= (Ligne * DIMMAT4X4) + Colonne; - - MatT.m_Matrix[IndexTrans]= m_Matrix[IndexOrigine]; - } - } - - // Load the transposed matrix in this matrix - memcpy(m_Matrix, MatT.m_Matrix, sizeof(double) * 16); - - return *this; -} - -GLC_Matrix4x4& GLC_Matrix4x4::optimise(bool force) -{ - if (force || (m_Type == General)) - { - bool identityVal= (m_Matrix[0] == 1.0f) && (m_Matrix[4] == 0.0f) && (m_Matrix[8] == 0.0f) && (m_Matrix[12] == 0.0f); - identityVal= identityVal && (m_Matrix[1] == 0.0f) && (m_Matrix[5] == 1.0f) && (m_Matrix[9] == 0.0f) && (m_Matrix[13] == 0.0); - identityVal= identityVal && (m_Matrix[2] == 0.0f) && (m_Matrix[6] == 0.0f) && (m_Matrix[10] == 1.0f) && (m_Matrix[14] == 0.0); - identityVal= identityVal && (m_Matrix[3] == 0.0f) && (m_Matrix[7] == 0.0f) && (m_Matrix[11] == 0.0f) && (m_Matrix[15] == 1.0f); - if (identityVal) - { - m_Type= Identity; - } - else - { - if (determinant() > 0) - { - m_Type= Direct; - } - else - { - m_Type= Indirect; - } - } - } - return *this; -} - -double GLC_Matrix4x4::determinant(void) const -{ - double Determinant= 0.0; - double SubMat3x3[9]; - int Signe= 1; - - for (int Colonne= 0; Colonne < DIMMAT4X4; Colonne++, Signe*= -1) - { - getSubMat(0, Colonne, SubMat3x3); - Determinant+= Signe * m_Matrix[Colonne * DIMMAT4X4] * getDeterminant3x3(SubMat3x3); - } - - return Determinant; - -} - -double GLC_Matrix4x4::getDeterminantLC(const int Ligne, const int Colonne) const -{ - double Mat3x3[9]; - double Determinant; - - getSubMat(Ligne, Colonne, Mat3x3); - - if ( 0 == ((Ligne + Colonne) % 2)) // Even number - Determinant= m_Matrix[(Colonne + DIMMAT4X4) + Ligne] * getDeterminant3x3(Mat3x3); - else - Determinant= - m_Matrix[(Colonne + DIMMAT4X4) + Ligne] * getDeterminant3x3(Mat3x3); - - return Determinant; -} - -void GLC_Matrix4x4::getSubMat(const int Ligne, const int Colonne, double *ResultMat) const -{ - - int LigneResult; - int ColonneResult; - int IndexOrigine; - int IndexResult; - - for (int ColonneOrigine= 0; ColonneOrigine < DIMMAT4X4; ColonneOrigine++) - { - if (ColonneOrigine != Colonne) - { - if (ColonneOrigine < Colonne) - ColonneResult= ColonneOrigine; - else - ColonneResult= ColonneOrigine - 1; - - for (int LigneOrigine= 0; LigneOrigine < DIMMAT4X4; LigneOrigine++) - { - if (LigneOrigine != Ligne) - { - if (LigneOrigine < Ligne) - LigneResult= LigneOrigine; - else - LigneResult= LigneOrigine - 1; - IndexOrigine= (ColonneOrigine * DIMMAT4X4) + LigneOrigine; - IndexResult= (ColonneResult * (DIMMAT4X4 - 1)) + LigneResult; - - ResultMat[IndexResult]= m_Matrix[IndexOrigine]; - } - } - } - } -} - -GLC_Matrix4x4 GLC_Matrix4x4::getTranspose(void) const -{ - GLC_Matrix4x4 MatT(m_Matrix); - int IndexOrigine; - int IndexTrans; - for (int Colonne= 0; Colonne < DIMMAT4X4; Colonne++) - { - for (int Ligne=0 ; Ligne < DIMMAT4X4; Ligne++) - { - IndexOrigine= (Colonne * DIMMAT4X4) + Ligne; - IndexTrans= (Ligne * DIMMAT4X4) + Colonne; - - MatT.m_Matrix[IndexTrans]= m_Matrix[IndexOrigine]; - } - } - - MatT.m_Type= m_Type; - return MatT; -} - -GLC_Matrix4x4 GLC_Matrix4x4::getCoMat4x4(void) const -{ - GLC_Matrix4x4 CoMat(m_Matrix); - double SubMat3x3[9]; - int Index; - - for (int Colonne= 0; Colonne < DIMMAT4X4; Colonne++) - { - for (int Ligne=0 ; Ligne < DIMMAT4X4; Ligne++) - { - getSubMat(Ligne, Colonne, SubMat3x3); - Index= (Colonne * DIMMAT4X4) + Ligne; - if (((Colonne + Ligne + 2) % 2) == 0) // Even Number - CoMat.m_Matrix[Index]= getDeterminant3x3(SubMat3x3); - else - CoMat.m_Matrix[Index]= -getDeterminant3x3(SubMat3x3); - } - } - - - CoMat.m_Type= General; - return CoMat; -} - - -#endif /*GLC_MATRIX4X4_H_*/ diff --git a/ground/gcs/src/libs/glc_lib/maths/glc_plane.cpp b/ground/gcs/src/libs/glc_lib/maths/glc_plane.cpp deleted file mode 100644 index 9fbd6a0c0..000000000 --- a/ground/gcs/src/libs/glc_lib/maths/glc_plane.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_plane.cpp Implementation of the GLC_Plane class. - -#include -#include "glc_plane.h" -#include "glc_geomtools.h" - -GLC_Plane::GLC_Plane() -{ - m_Eq[0]= 0.0; - m_Eq[1]= 0.0; - m_Eq[2]= 0.0; - m_Eq[3]= 0.0; -} - -GLC_Plane::GLC_Plane(double a, double b, double c, double d) -{ - m_Eq[0]= a; - m_Eq[1]= b; - m_Eq[2]= c; - m_Eq[3]= d; - -} - -GLC_Plane::GLC_Plane(const GLC_Vector3d& normal, double d) -{ - m_Eq[0]= normal.x(); - m_Eq[1]= normal.y(); - m_Eq[2]= normal.z(); - m_Eq[3]= d; -} - -GLC_Plane::GLC_Plane(const GLC_Vector3d& normal, const GLC_Point3d& point) -{ - m_Eq[0]= normal.x(); - m_Eq[1]= normal.y(); - m_Eq[2]= normal.z(); - m_Eq[3]= -normal * point; -} - - -GLC_Plane::GLC_Plane(const GLC_Point3d& p1, const GLC_Point3d& p2, const GLC_Point3d& p3) -{ - const GLC_Vector3d v1(p2 - p1); - const GLC_Vector3d v2(p3 - p1); - const GLC_Vector3d normal((v1 ^ v2).normalize()); - m_Eq[0]= normal.x(); - m_Eq[1]= normal.y(); - m_Eq[2]= normal.z(); - m_Eq[3]= -normal * p1; -} - - -GLC_Plane::GLC_Plane(const GLC_Plane& plane) -{ - memcpy(m_Eq, plane.m_Eq, sizeof(double) * 4); -} - - -GLC_Plane& GLC_Plane::operator=(const GLC_Plane& p) -{ - if ((this != &p) && (*this != p)) - { - memcpy(m_Eq, p.m_Eq, sizeof(double) * 4); - } - return *this; -} - - -GLC_Plane::~GLC_Plane() -{ - -} - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - - -bool GLC_Plane::operator==(GLC_Plane p2) const -{ - GLC_Plane p1(*this); - p1.normalize(); - p2.normalize(); - - bool areEqual= glc::compare(p1.m_Eq[0], p2.m_Eq[0], glc::EPSILON); - areEqual= areEqual && glc::compare(p1.m_Eq[1], p2.m_Eq[1], glc::EPSILON); - areEqual= areEqual && glc::compare(p1.m_Eq[2], p2.m_Eq[2], glc::EPSILON); - areEqual= areEqual && glc::compare(p1.m_Eq[3], p2.m_Eq[3], glc::EPSILON); - - return areEqual; -} - -bool GLC_Plane::lieOnThisPlane(const GLC_Point3d &p) -{ - const double value= (m_Eq[0] * p.x() + m_Eq[1] * p.y() + m_Eq[2] * p.z() + m_Eq[3]); - bool subject = glc::compare(value, 0.0, glc::EPSILON); - - return subject; -} - -QString GLC_Plane::toString() const -{ - return QString::number(m_Eq[0]) + "x + " + QString::number(m_Eq[1]) + "y + " + QString::number(m_Eq[2]) + "z + " + QString::number(m_Eq[3]); -} -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -// Normalize the plane -void GLC_Plane::normalize() -{ - const double invMag= 1.0 / sqrt(m_Eq[0] * m_Eq[0] + m_Eq[1] * m_Eq[1] + m_Eq[2] * m_Eq[2]); - - m_Eq[0]= m_Eq[0] * invMag; - m_Eq[1]= m_Eq[1] * invMag; - m_Eq[2]= m_Eq[2] * invMag; - m_Eq[3]= m_Eq[3] * invMag; -} - -GLC_Plane& GLC_Plane::setPlane(const GLC_Vector3d& normal, const GLC_Point3d& point) -{ - m_Eq[0]= normal.x(); - m_Eq[1]= normal.y(); - m_Eq[2]= normal.z(); - m_Eq[3]= -normal * point; - - return *this; -} - -GLC_Plane& GLC_Plane::setNormal(const GLC_Vector3d& normal) -{ - m_Eq[0]= normal.x(); - m_Eq[1]= normal.y(); - m_Eq[2]= normal.z(); - - return *this; -} diff --git a/ground/gcs/src/libs/glc_lib/maths/glc_plane.h b/ground/gcs/src/libs/glc_lib/maths/glc_plane.h deleted file mode 100644 index 24f0ba8bc..000000000 --- a/ground/gcs/src/libs/glc_lib/maths/glc_plane.h +++ /dev/null @@ -1,160 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_plane.h Interface for the GLC_Plane class. - -#ifndef GLC_PLANE_H_ -#define GLC_PLANE_H_ - -#include "glc_vector3d.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Plane -/*! \brief GLC_Plane : Math plane representation */ - -/*! GLC_Plane is definined by its equation : Ax + By + CZ + D= 0 */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_Plane -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Default constructor - GLC_Plane(); - - //! Contruct a plan with specified parameter - /*! Plane equation : Ax + By + CZ + D= 0*/ - GLC_Plane(double A, double B, double C, double D); - - //! Construct a plane with normal vector and the minimum distance from this plane to the origin - GLC_Plane(const GLC_Vector3d& normal, double minimumDistance); - - //! Construct a plane with normal vector and a 3d point - GLC_Plane(const GLC_Vector3d& normal, const GLC_Point3d& point); - - //! Contruct a plane with 3 given 3d points - /*! first : origine, second x, third y*/ - GLC_Plane(const GLC_Point3d&, const GLC_Point3d&, const GLC_Point3d&); - - //! Copy constructor - GLC_Plane(const GLC_Plane&); - - //! Assignement operator - GLC_Plane &operator=(const GLC_Plane&); - - //! Destructor - ~GLC_Plane(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Return A coef - inline double coefA() const - {return m_Eq[0];} - - //! Return B coef - inline double coefB() const - {return m_Eq[1];} - - //! Return C coef - inline double coefC() const - {return m_Eq[2];} - - //! Return D coef - inline double coefD() const - {return m_Eq[3];} - - //! Return the signed distance to a point - inline double distanceToPoint(const GLC_Point3d& p) const - {return m_Eq[0] * p.x() + m_Eq[1] * p.y() + m_Eq[2] * p.z() + m_Eq[3];} - - //! Equality operator - bool operator==(GLC_Plane) const; - - //! diff operator - inline bool operator!=(const GLC_Plane& p) const - {return !operator==(p);} - - //! Return this plane normal - inline GLC_Vector3d normal() const - {return GLC_Vector3d(m_Eq[0], m_Eq[1], m_Eq[2]);} - - //! Return true if the given point is on this plane - bool lieOnThisPlane(const GLC_Point3d& p); - - //! Return a pointer to this plane equation data - const double* data() const - {return m_Eq;} - - //! Return the plane data to string - QString toString() const; -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Set A coef - inline void setA(double a) - {m_Eq[0]= a;} - - //! Set B coef - inline void setB(double b) - {m_Eq[1]= b;} - - //! Set C coef - inline void setC(double c) - {m_Eq[2]= c;} - - //! Set D coef - inline void setD(double d) - {m_Eq[3]= d;} - - //! Normalize the plane - void normalize(); - - //! Set the plane from the given normal and point and return a reference to this plane - GLC_Plane& setPlane(const GLC_Vector3d& normal, const GLC_Point3d& point); - - //! Set this plane normal to the given normal and return a reference to this plane - GLC_Plane& setNormal(const GLC_Vector3d& normal); - - -//@} - -////////////////////////////////////////////////////////////////////// -// Private Member -////////////////////////////////////////////////////////////////////// -private: - //! Plane is define by equation : Ax + By + Cz + D= 0 - double m_Eq[4]; -}; - -#endif /* GLC_PLANE_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/maths/glc_utils_maths.h b/ground/gcs/src/libs/glc_lib/maths/glc_utils_maths.h deleted file mode 100644 index bd867074e..000000000 --- a/ground/gcs/src/libs/glc_lib/maths/glc_utils_maths.h +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ -//! \file glc_utils_maths.h Mathematic constants. -/*! \brief Definition of usefull constants*/ - -#ifndef GLC_UTILS_MATHS_H_ -#define GLC_UTILS_MATHS_H_ - -// Standard C math library -#include -namespace glc -{ - /*! \def EPSILON - * \brief Define precison of comparaison*/ - - const double EPSILON= 1e-10; - - /*! \def PI - * \brief Define the magic number PI */ - const double PI= acos(-1.0); - - //! Convert the given degrees angle in radian - inline double toRadian(double angleInDegrees) - {return PI * angleInDegrees / 180.0;} - - //! Convert the given radian angle in degre - inline double toDegrees(double angleInRadians) - {return 180.0 * angleInRadians / PI;} -} - -#endif /*GLC_UTILS_MATHS_H_*/ diff --git a/ground/gcs/src/libs/glc_lib/maths/glc_vector2d.h b/ground/gcs/src/libs/glc_lib/maths/glc_vector2d.h deleted file mode 100644 index 08cbbacbd..000000000 --- a/ground/gcs/src/libs/glc_lib/maths/glc_vector2d.h +++ /dev/null @@ -1,305 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_vector2d.h interface for the GLC_Vector2d class. - -#ifndef GLC_VECTOR2D_H_ -#define GLC_VECTOR2D_H_ - -#include -#include - -#include "glc_utils_maths.h" -#include "glc_vector2df.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -// definition global -////////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Vector2d -/*! \brief GLC_Vector2d is a 2 dimensions Vector*/ - -/*! GLC_Vector2d is used to represent 2D position and vectors.*/ -////////////////////////////////////////////////////////////////////// - -class GLC_LIB_EXPORT GLC_Vector2d -{ - friend class GLC_Vector4d; - friend class GLC_Vector3d; - - /*! Overload unary "-" operator*/ - inline friend GLC_Vector2d operator - (const GLC_Vector2d &Vect) - { - return GLC_Vector2d(-Vect.m_Vector[0], -Vect.m_Vector[1]); - } - - -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - /*! Default constructor - * Value is set to - * \n X = 0.0 - * \n Y = 0.0 - */ - inline GLC_Vector2d() - { - m_Vector[0]= 0.0; - m_Vector[1]= 0.0; - } - - /*! Standard constructor With x, y = 0.0*/ - inline GLC_Vector2d(const double &dX, const double &dY) - { - m_Vector[0]= dX; - m_Vector[1]= dY; - } - - //! Copy constructor - inline GLC_Vector2d(const GLC_Vector2d &Vect) - { - m_Vector[0]= Vect.m_Vector[0]; - m_Vector[1]= Vect.m_Vector[1]; - } - - //! Return the QPointF of this GLC_Vector - inline QPointF toQPointF() const - {return QPointF(m_Vector[0], m_Vector[1]);} - -//@} -////////////////////////////////////////////////////////////////////// -/*! @name Operator Overload */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - /*! Overload binary "+" operator*/ - inline GLC_Vector2d operator + (const GLC_Vector2d &Vect) const - { - GLC_Vector2d VectResult(m_Vector[0] + Vect.m_Vector[0], m_Vector[1] + Vect.m_Vector[1]); - - return VectResult; - } - - /*! Overload "=" operator*/ - inline GLC_Vector2d& operator = (const GLC_Vector2d &Vect) - { - m_Vector[0]= Vect.m_Vector[0]; - m_Vector[1]= Vect.m_Vector[1]; - - return *this; - } - - /*! Overload "=" operator*/ - inline GLC_Vector2d& operator = (const GLC_Vector2df &Vect) - { - m_Vector[0]= static_cast(Vect.vector[0]); - m_Vector[1]= static_cast(Vect.vector[1]); - - return *this; - } - - - /*! Overload "+=" operator*/ - inline GLC_Vector2d* operator += (const GLC_Vector2d &Vect) - { - *this= *this + Vect; - return this; - } - - - /*! Overload binary "-" operator*/ - inline GLC_Vector2d operator - (const GLC_Vector2d &Vect) const - { - GLC_Vector2d VectResult(m_Vector[0] - Vect.m_Vector[0], m_Vector[1] - Vect.m_Vector[1]); - - return VectResult; - } - - /*! Overload binary "-=" operator*/ - inline GLC_Vector2d* operator -= (const GLC_Vector2d &Vect) - { - *this= *this - Vect; - return this; - } - - /*! Overload dot product "^" operator*/ - inline double operator ^ (const GLC_Vector2d &Vect) const - { - return m_Vector[0] * Vect.m_Vector[1] - m_Vector[1] * Vect.m_Vector[0]; - } - - /*! Overload scalar product "*" operator between 2 vector*/ - inline double operator * (const GLC_Vector2d &Vect) const - { - return m_Vector[0] * Vect.m_Vector[0] + m_Vector[1] * Vect.m_Vector[1]; - } - - /*! Overload scalar division "/" operator between 2 vector*/ - inline double operator / (const GLC_Vector2d &Vect) const - { - return m_Vector[0] / Vect.m_Vector[0] + m_Vector[1] / Vect.m_Vector[1]; - } - - /*! Overload scalar product "*" operator between 1 vector and one scalar*/ - inline GLC_Vector2d operator * (double Scalaire) const - { - return GLC_Vector2d(m_Vector[0] * Scalaire, m_Vector[1] * Scalaire);; - } - - /*! Overload scalar division "/" operator between 1 vector and one scalar*/ - inline GLC_Vector2d operator / (double Scalaire) const - { - return GLC_Vector2d(m_Vector[0] / Scalaire, m_Vector[1] / Scalaire);; - } - - /*! Overload equality "==" operator*/ - inline bool operator == (const GLC_Vector2d &Vect) const - { - bool bResult= (qAbs(m_Vector[0]) - qAbs(Vect.m_Vector[0])) < glc::EPSILON; - bResult= bResult && ((qAbs(m_Vector[1]) - qAbs(Vect.m_Vector[1])) < glc::EPSILON); - - return bResult; - } - - /*! Overload "!=" operator*/ - inline bool operator != (const GLC_Vector2d &Vect) const - { - return !(*this == Vect); - } - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - /*! X Composante*/ - inline GLC_Vector2d& setX(const double &dX) - { - m_Vector[0]= dX; - return *this; - } - - /*! Y Composante*/ - inline GLC_Vector2d& setY(const double &dY) - { - m_Vector[1]= dY; - return *this; - } - - /*! All Composante*/ - inline GLC_Vector2d& setVect(const double &dX, const double &dY) - { - m_Vector[0]= dX; - m_Vector[1]= dY; - return *this; - } - - /*! From another Vector*/ - inline GLC_Vector2d& setVect(const GLC_Vector2d &Vect) - { - m_Vector[0]= Vect.m_Vector[0]; - m_Vector[1]= Vect.m_Vector[1]; - return *this; - } - - //! Set vector lenght from the given scalar and return a reference of this vector - inline GLC_Vector2d& setLength(double); - - //! Normalize this vector and return a reference to it - inline GLC_Vector2d& normalize() - {return setLength(1.0);} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - /*! X Component*/ - inline double x(void) const - {return m_Vector[0];} - - /*! Y Component*/ - inline double y(void) const - {return m_Vector[1];} - - /*! retourne un pointeur constant vers le tableau du vecteur.*/ - inline const double *return_dVect(void) const - {return m_Vector;} - - /*! Return true if the vector is null*/ - inline bool isNull(void) const - {return (qAbs(m_Vector[0]) < glc::EPSILON) && (qAbs(m_Vector[1]) < glc::EPSILON);} - - //! return the string representation of vector - inline QString toString() const - {return QString("[") + QString::number(m_Vector[0]) + QString(" , ") + QString::number(m_Vector[1]) + QString("]");} - - //! Return a vector perpendicular to this - inline GLC_Vector2d perp() const - {return GLC_Vector2d(-m_Vector[1], m_Vector[0]);} - - //! Return the length of this vector - inline double length() const - {return sqrt(m_Vector[0] * m_Vector[0] + m_Vector[1] * m_Vector[1]);} - -//@} - -////////////////////////////////////////////////////////////////////// -//name Private attributes -////////////////////////////////////////////////////////////////////// -private: - /*! Vector array definition \n - * vector[0] X \n - * vector[1] Y \n - */ - double m_Vector[2]; - -}; //class GLC_Vector2d - -//! Define GLC_Point2D -typedef GLC_Vector2d GLC_Point2d; - -inline GLC_Vector2d& GLC_Vector2d::setLength(double lenght) -{ - const double currentLenght= sqrt( m_Vector[0] * m_Vector[0] + m_Vector[1] * m_Vector[1]); - - if (currentLenght != 0.0f) - { - const double Coef = lenght / currentLenght; - - m_Vector[0] = m_Vector[0] * Coef; - m_Vector[1] = m_Vector[1] * Coef; - } - return *this; -} - -#endif /*GLC_VECTOR2D_H_*/ diff --git a/ground/gcs/src/libs/glc_lib/maths/glc_vector2df.h b/ground/gcs/src/libs/glc_lib/maths/glc_vector2df.h deleted file mode 100644 index 15d014d2e..000000000 --- a/ground/gcs/src/libs/glc_lib/maths/glc_vector2df.h +++ /dev/null @@ -1,163 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_vector2df.h interface for the GLC_Vector2df class. - -#ifndef GLC_VECTOR2DF_H_ -#define GLC_VECTOR2DF_H_ - -#include "glc_utils_maths.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -// definition global -////////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Vector2df -/*! \brief GLC_Vector2df is a 2 dimensions Vector*/ - -/*! GLC_Vector2df is used to represent 2D position and vectors. - * */ -////////////////////////////////////////////////////////////////////// - -class GLC_LIB_EXPORT GLC_Vector2df -{ - friend class GLC_Vector2d; -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - /*! Default constructor - * Value is set to - * \n X = 0.0 - * \n Y = 0.0 - */ - inline GLC_Vector2df() - { - vector[0]= 0.0f; - vector[1]= 0.0f; - } - - //! Standard constructor With x, y = 0.0 - inline GLC_Vector2df(const float &dX, const float &dY) - { - vector[0]= dX; - vector[1]= dY; - } - - /*! Copy constructor - * Sample use - * \code - * NewVect = new GLC_Vector2d(OldVect); - * \endcode - */ - inline GLC_Vector2df(const GLC_Vector2df &Vect) - { - vector[0]= Vect.vector[0]; - vector[1]= Vect.vector[1]; - } -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! X Compound - inline GLC_Vector2df& setX(const float &dX) - { - vector[0]= dX; - return *this; - } - - //! Y Compound - inline GLC_Vector2df& setY(const float &dY) - { - vector[1]= dY; - return *this; - } - - //! All Compound - inline GLC_Vector2df& setVect(const float &dX, const float &dY) - { - vector[0]= dX; - vector[1]= dY; - return *this; - } - - //! From another Vector - inline GLC_Vector2df& setVect(const GLC_Vector2df &Vect) - { - vector[0]= Vect.vector[0]; - vector[1]= Vect.vector[1]; - return *this; - } - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return X Compound - inline float X(void) const - { - return vector[0]; - } - //! Return Y Compound - inline float Y(void) const - { - return vector[1]; - } - //! Return a pointer to vector data - inline const float *return_dVect(void) const - { - return vector; - } - //! Return true if the vector is null - inline bool isNull(void) const - { - return (qFuzzyCompare(vector[0], 0.0f) && qFuzzyCompare(vector[1], 0.0f)); - } - -//@} - -////////////////////////////////////////////////////////////////////// -//name Private attributes -////////////////////////////////////////////////////////////////////// -private: - /*! Vector array definition \n - * vector[0] X \n - * vector[1] Y \n - */ - float vector[2]; - -}; //class GLC_Vector2df - -//! Define GLC_Point2D -typedef GLC_Vector2df GLC_Point2df; - -#endif /*GLC_VECTOR2DF_H_*/ diff --git a/ground/gcs/src/libs/glc_lib/maths/glc_vector3d.h b/ground/gcs/src/libs/glc_lib/maths/glc_vector3d.h deleted file mode 100644 index 3ca4f3d12..000000000 --- a/ground/gcs/src/libs/glc_lib/maths/glc_vector3d.h +++ /dev/null @@ -1,500 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_vector3d.h interface for the GLC_Vector3d class. - -#ifndef GLC_VECTOR3D_H_ -#define GLC_VECTOR3D_H_ - -#include - -#include "glc_utils_maths.h" -#include "glc_vector3df.h" -#include "glc_vector2d.h" -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Vector3d -/*! \brief GLC_Vector3d is a 3 dimensions Vector*/ - -/*! GLC_Vector3d is used to represent 3D vectors in 3D space coordinate. - * */ -////////////////////////////////////////////////////////////////////// - -class GLC_LIB_EXPORT GLC_Vector3d -{ - friend class GLC_Vector4d; - friend class GLC_Matrix4x4; - - //! Overload unary "-" operator - inline friend GLC_Vector3d operator - (const GLC_Vector3d &Vect) - {return GLC_Vector3d(-Vect.m_Vector[0], -Vect.m_Vector[1], -Vect.m_Vector[2]);} - - //! Overload scalar operator - inline friend GLC_Vector3d operator*(double s, const GLC_Vector3d &v) - {return GLC_Vector3d(s * v.m_Vector[0], s * v.m_Vector[1], s * v.m_Vector[2]);} - -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Default constructor - /*! Value is set to - * \n X = 0.0 - * \n Y = 0.0 - * \n Z = 0.0 - */ - inline GLC_Vector3d(); - - //! Standard constructor with coordinate: (x, y, z) - inline GLC_Vector3d(double x, double y, double z); - - //! Construct a 3d vector from another 3d vector - inline GLC_Vector3d(const GLC_Vector3d &vector) - {memcpy(m_Vector, vector.m_Vector, sizeof(double) * 3);} - - //! Construct a 3d vector from another 3d float vector - inline GLC_Vector3d(const GLC_Vector3df &vector); - - //! Construct a 3d vector from a 2d float vector - inline GLC_Vector3d(const GLC_Vector2d &vector); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the x coordinate of this vector - inline double x() const - {return m_Vector[0];} - - //! Return the y coordinate of this vector - inline double y() const - {return m_Vector[1];} - - //! Return the z coordinate of this vector - inline double z() const - {return m_Vector[2];} - - //! Return a const pointer to this vector data - inline const double *data() const - {return m_Vector;} - - //! Return true if this vector is null - inline bool isNull() const - {return (qAbs(m_Vector[0]) < glc::EPSILON) && (qAbs(m_Vector[1]) < glc::EPSILON) && (qAbs(m_Vector[2]) < glc::EPSILON);} - - //! Return the length of this vector - inline double length() const - {return sqrt(m_Vector[0] * m_Vector[0] + m_Vector[1] * m_Vector[1] + m_Vector[2] * m_Vector[2]);} - - //! Return the 2D vector specified by the given mask vector - /*! retrieve component corresponding to mask vector NULL component*/ - inline GLC_Vector2d toVector2d(const GLC_Vector3d& mask) const; - - //! Return the Angle from this vector to the given vector (from 0 to PI) - inline double angleWithVect(GLC_Vector3d Vect) const; - - //! Return the signed angle from this vector to th given vector with the given direction (from 0 to -PI and 0 to PI) - inline double signedAngleWithVect(GLC_Vector3d Vect, const GLC_Vector3d& dir) const; - - //! Return the float 3D vector from this vector - inline GLC_Vector3df toVector3df() const - {return GLC_Vector3df(static_cast(m_Vector[0]), static_cast(m_Vector[1]), static_cast(m_Vector[2]));} - - //! Return the string of this vector - inline QString toString() const; - - //! Return the inverted vector of this vector - inline GLC_Vector3d inverted() const - {return GLC_Vector3d(*this).invert();} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! @name Operator Overload */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the Addition of this vector to the given vector - inline GLC_Vector3d operator + (const GLC_Vector3d &vector) const - {return GLC_Vector3d(m_Vector[0] + vector.m_Vector[0], m_Vector[1] + vector.m_Vector[1], m_Vector[2] + vector.m_Vector[2]);} - - //! Copy the given vector to this vector and return a reference to this vector - inline GLC_Vector3d& operator = (const GLC_Vector3d &vector) - { - if (this != &vector) memcpy(m_Vector, vector.m_Vector, sizeof(double) * 3); - return *this; - } - - //! Copy the given float vector to this vector and return a reference to this vector - inline GLC_Vector3d& operator = (const GLC_Vector3df &); - - //! Add this vector to the given vector and return a reference to this vector - inline GLC_Vector3d& operator += (const GLC_Vector3d &vector) - { - *this= *this + vector; - return *this; - } - - //! Return the substracts of the given vector to this vector - inline GLC_Vector3d operator - (const GLC_Vector3d &Vect) const - {return GLC_Vector3d(m_Vector[0] - Vect.m_Vector[0], m_Vector[1] - Vect.m_Vector[1], m_Vector[2] - Vect.m_Vector[2]);} - - //! Substracts the given vector to this vector and return a reference to this vector - GLC_Vector3d& operator -= (const GLC_Vector3d &Vect) - { - *this= *this - Vect; - return *this; - } - - //! Return the cross product of this vector to the given vector - inline GLC_Vector3d operator ^ (const GLC_Vector3d &vector) const; - - //! Return the scalar product of this vector to the given vector - inline double operator * (const GLC_Vector3d &Vect) const - {return m_Vector[0] * Vect.m_Vector[0] + m_Vector[1] * Vect.m_Vector[1] + m_Vector[2] * Vect.m_Vector[2];} - - //! Return the scalar product of this vector to the given scalar - inline GLC_Vector3d operator * (double Scalaire) const - {return GLC_Vector3d(m_Vector[0] * Scalaire, m_Vector[1] * Scalaire, m_Vector[2] * Scalaire);} - - - //! Return true if this vector is fuzzyequal to the given vector - inline bool operator == (const GLC_Vector3d &vector) const; - - //! Return true if this vector is > to the given vector - inline bool operator > (const GLC_Vector3d &vector) const; - - //! Return true if this vector is < to the given vector - inline bool operator < (const GLC_Vector3d &vector) const; - - //! Return false if this vector is fuzzyequal to the given vector - inline bool operator != (const GLC_Vector3d &Vect) const - {return !(*this == Vect);} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Set x coordinate of this vector from the given x coordinate - inline GLC_Vector3d& setX(const double &dX) - { - m_Vector[0]= dX; - return *this; - } - - //! Set y coordinate of this vector from the given y coordinate - inline GLC_Vector3d& setY(const double &dY) - { - m_Vector[1]= dY; - return *this; - } - - //! Set z coordinate of this vector from the given z coordinate - inline GLC_Vector3d& setZ(const double &dZ) - { - m_Vector[2]= dZ; - return *this; - } - - //! Set (x, y, z) coordinate of this vector from the given (x, y, z) coordinates - inline GLC_Vector3d& setVect(double, double, double); - - //! Set (x, y, z) coordinate of this vector from the given vector coordinates - GLC_Vector3d& setVect(const GLC_Vector3d &vector) - { - memcpy(m_Vector, vector.m_Vector, sizeof(double) * 3); - return *this; - } - - //! Set vector lenght from the given scalar and return a reference of this vector - inline GLC_Vector3d& setLength(double lenght); - - //! Normalize this vector and return a reference to it - inline GLC_Vector3d& normalize() - {return setLength(1.0);} - - //! Invert this vector and return a reference to it - inline GLC_Vector3d& invert(); - -//@} - - -////////////////////////////////////////////////////////////////////// -//Private attributes -////////////////////////////////////////////////////////////////////// -private: - /*! Vector array definition \n - * vector[0] X \n - * vector[1] Y \n - * vector[2] Z \n - */ - double m_Vector[3]; - -}; //class GLC_Vector3d - -// Vector constant in glc namespace -namespace glc -{ - // Axis definition - /*! \var X_AXIS - * \brief X axis Vector*/ - const GLC_Vector3d X_AXIS(1.0, 0.0, 0.0); - - /*! \var Y_AXIS - * \brief Y axis Vector*/ - const GLC_Vector3d Y_AXIS(0.0, 1.0, 0.0); - - /*! \var Z_AXIS - * \brief Z axis Vector*/ - const GLC_Vector3d Z_AXIS(0.0, 0.0, 1.0); -}; - -//! Define GLC_Point3D -typedef GLC_Vector3d GLC_Point3d; - -//! Write the vector to stream -inline QDataStream &operator<<(QDataStream & stream, const GLC_Vector3d & vector) -{ - stream << vector.x() << vector.y() << vector.z(); - return stream; -} - -//! Read the vector from stream -inline QDataStream &operator>>(QDataStream &stream, GLC_Vector3d &vector) -{ - double x, y, z; - stream >> x >> y >> z; - vector.setVect(x, y, z); - return stream; -} - -//! Return the determinant of the given Matrix 3X3 -inline double getDeterminant3x3(const double *Mat3x3) -{ - double Determinant; - - Determinant= Mat3x3[0] * ( Mat3x3[4] * Mat3x3[8] - Mat3x3[7] * Mat3x3[5]); - Determinant+= - Mat3x3[3] * ( Mat3x3[1] * Mat3x3[8] - Mat3x3[7] * Mat3x3[2]); - Determinant+= Mat3x3[6] * ( Mat3x3[1] * Mat3x3[5] - Mat3x3[4] * Mat3x3[2]); - - return Determinant; -} - -////////////////////////////////////////////////////////////////////// -// inline method implementation -////////////////////////////////////////////////////////////////////// - -GLC_Vector3d::GLC_Vector3d() -{ - m_Vector[0]= 0.0; - m_Vector[1]= 0.0; - m_Vector[2]= 0.0; -} - -GLC_Vector3d::GLC_Vector3d(double x, double y, double z) -{ - m_Vector[0]= x; - m_Vector[1]= y; - m_Vector[2]= z; -} - -GLC_Vector3d::GLC_Vector3d(const GLC_Vector3df &vector) -{ - m_Vector[0]= static_cast(vector.m_Vector[0]); - m_Vector[1]= static_cast(vector.m_Vector[1]); - m_Vector[2]= static_cast(vector.m_Vector[2]); -} - -GLC_Vector3d::GLC_Vector3d(const GLC_Vector2d &vector) -{ - m_Vector[0]= vector.x(); - m_Vector[1]= vector.y(); - m_Vector[2]= 0.0; -} - -GLC_Vector3d& GLC_Vector3d::operator = (const GLC_Vector3df &Vect) -{ - m_Vector[0]= static_cast(Vect.m_Vector[0]); - m_Vector[1]= static_cast(Vect.m_Vector[1]); - m_Vector[2]= static_cast(Vect.m_Vector[2]); - - return *this; -} - -GLC_Vector3d GLC_Vector3d::operator ^ (const GLC_Vector3d &vector) const -{ - GLC_Vector3d vectResult; - vectResult.m_Vector[0]= m_Vector[1] * vector.m_Vector[2] - m_Vector[2] * vector.m_Vector[1]; - vectResult.m_Vector[1]= m_Vector[2] * vector.m_Vector[0] - m_Vector[0] * vector.m_Vector[2]; - vectResult.m_Vector[2]= m_Vector[0] * vector.m_Vector[1] - m_Vector[1] * vector.m_Vector[0]; - - return vectResult; -} - -bool GLC_Vector3d::operator == (const GLC_Vector3d &vector) const -{ - bool bResult= qFuzzyCompare(m_Vector[0], vector.m_Vector[0]); - bResult= bResult && qFuzzyCompare(m_Vector[1], vector.m_Vector[1]); - bResult= bResult && qFuzzyCompare(m_Vector[2], vector.m_Vector[2]); - - return bResult; -} - -bool GLC_Vector3d::operator > (const GLC_Vector3d &vector) const -{ - bool result= m_Vector[0] > vector.m_Vector[0]; - result= result && (m_Vector[1] > vector.m_Vector[1]); - result= result && (m_Vector[2] > vector.m_Vector[2]); - return result; -} - -bool GLC_Vector3d::operator < (const GLC_Vector3d &vector) const -{ - bool result= m_Vector[0] < vector.m_Vector[0]; - result= result && (m_Vector[1] < vector.m_Vector[1]); - result= result && (m_Vector[2] < vector.m_Vector[2]); - return result; -} - -GLC_Vector3d& GLC_Vector3d::setVect(double x, double y, double z) -{ - m_Vector[0]= x; - m_Vector[1]= y; - m_Vector[2]= z; - - return *this; -} - -inline GLC_Vector3d& GLC_Vector3d::setLength(double lenght) -{ - const double currentLenght= sqrt( m_Vector[0] * m_Vector[0] + m_Vector[1] * m_Vector[1] + m_Vector[2] * m_Vector[2]); - - if (qAbs(currentLenght) > glc::EPSILON) - { - const double Coef = lenght / currentLenght; - - m_Vector[0] = m_Vector[0] * Coef; - m_Vector[1] = m_Vector[1] * Coef; - m_Vector[2] = m_Vector[2] * Coef; - } - return *this; -} - -GLC_Vector3d& GLC_Vector3d::invert() -{ - m_Vector[0]= - m_Vector[0]; - m_Vector[1]= - m_Vector[1]; - m_Vector[2]= - m_Vector[2]; - return *this; -} - -GLC_Vector2d GLC_Vector3d::toVector2d(const GLC_Vector3d& mask) const -{ - GLC_Vector2d resultVect; - if (mask.m_Vector[0] == 0.0) - { - resultVect.setX(m_Vector[0]); - if (mask.m_Vector[1] == 0.0) resultVect.setY(m_Vector[1]); - else resultVect.setY(m_Vector[2]); - } - else resultVect.setVect(m_Vector[1], m_Vector[2]); - - return resultVect; -} - -double GLC_Vector3d::angleWithVect(GLC_Vector3d Vect) const -{ - GLC_Vector3d ThisVect(*this); - ThisVect.normalize(); - Vect.normalize(); - // Rotation axis - const GLC_Vector3d VectAxeRot(ThisVect ^ Vect); - // Check if the rotation axis vector is null - if (!VectAxeRot.isNull()) - { - return acos(ThisVect * Vect); - } - else return 0.0; -} - -double GLC_Vector3d::signedAngleWithVect(GLC_Vector3d Vect, const GLC_Vector3d& dir) const -{ - double angle= 0.0; - - GLC_Vector3d ThisVect(*this); - ThisVect.normalize(); - Vect.normalize(); - if (Vect == ThisVect.inverted()) - { - angle= glc::PI; - } - else if (Vect != ThisVect) - { - // Rotation axis - const GLC_Vector3d VectAxeRot(ThisVect ^ Vect); - // Check if the rotation axis vector is null - if (!VectAxeRot.isNull()) - { - double mat3x3[9]; - mat3x3[0]= ThisVect.m_Vector[0]; - mat3x3[1]= ThisVect.m_Vector[1]; - mat3x3[2]= ThisVect.m_Vector[2]; - - mat3x3[3]= Vect.m_Vector[0]; - mat3x3[4]= Vect.m_Vector[1]; - mat3x3[5]= Vect.m_Vector[2]; - - mat3x3[6]= dir.m_Vector[0]; - mat3x3[7]= dir.m_Vector[1]; - mat3x3[8]= dir.m_Vector[2]; - - double det= getDeterminant3x3(mat3x3); - - double sign= 1.0; - if (det != 0) sign= fabs(det) / det; - angle= acos(ThisVect * Vect) * sign; - } - } - - return angle; -} - -QString GLC_Vector3d::toString() const -{ - QString result("["); - - result+= QString::number(m_Vector[0]) + QString(" , "); - result+= QString::number(m_Vector[1]) + QString(" , "); - result+= QString::number(m_Vector[2]) + QString("]"); - - return result; -} - -#endif /*GLC_VECTOR3D_H_*/ diff --git a/ground/gcs/src/libs/glc_lib/maths/glc_vector3df.h b/ground/gcs/src/libs/glc_lib/maths/glc_vector3df.h deleted file mode 100644 index 0448ea899..000000000 --- a/ground/gcs/src/libs/glc_lib/maths/glc_vector3df.h +++ /dev/null @@ -1,188 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_vector3df.h interface for the GLC_Vector3df class. - -#ifndef GLC_VECTOR3DF_H_ -#define GLC_VECTOR3DF_H_ -#include "glc_utils_maths.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Vector3df -/*! \brief GLC_Vector3df is a 3 dimensions Vector*/ - -/*! GLC_Vector3df is used to represent 3D position and vectors. - * */ -////////////////////////////////////////////////////////////////////// - -class GLC_LIB_EXPORT GLC_Vector3df -{ - friend class GLC_Vector4d; - friend class GLC_Vector3d; -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - /*! Default constructor - * Value is set to - * \n X = 0.0 - * \n Y = 0.0 - * \n Z = 0.0 - */ - inline GLC_Vector3df() - { - m_Vector[0]= 0.0f; - m_Vector[1]= 0.0f; - m_Vector[2]= 0.0f; - } - - //! Standard constructor With x, y, z - inline GLC_Vector3df(const float &dX, const float &dY, const float &dZ) - { - setVect(dX, dY, dZ); - } - - /*! Copy constructor - * Sample use - * \code - * NewVect = new GLC_Vector3d(OldVect); - * \endcode - */ - inline GLC_Vector3df(const GLC_Vector3df &Vect) - { - m_Vector[0]= Vect.m_Vector[0]; - m_Vector[1]= Vect.m_Vector[1]; - m_Vector[2]= Vect.m_Vector[2]; - } -//@} - - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! X Compound - inline GLC_Vector3df& setX(const float &dX) - { - m_Vector[0]= dX; - return *this; - } - - //! Y Compound - inline GLC_Vector3df& setY(const float &dY) - { - m_Vector[1]= dY; - return *this; - } - - //! Z Compound - inline GLC_Vector3df& setZ(const float &dZ) - { - m_Vector[2]= dZ; - return *this; - } - - //! All Compound - inline GLC_Vector3df& setVect(const float &dX, const float &dY, const float &dZ) - { - m_Vector[0]= dX; - m_Vector[1]= dY; - m_Vector[2]= dZ; - - return *this; - } - - //! From another Vector - GLC_Vector3df& setVect(const GLC_Vector3df &Vect) - { - m_Vector[0]= Vect.m_Vector[0]; - m_Vector[1]= Vect.m_Vector[1]; - m_Vector[2]= Vect.m_Vector[2]; - return *this; - } - - //! Invert Vector - inline GLC_Vector3df& setInv(void) - { - m_Vector[0]= - m_Vector[0]; - m_Vector[1]= - m_Vector[1]; - m_Vector[2]= - m_Vector[2]; - return *this; - } - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return X Compound - inline float x(void) const - { - return m_Vector[0]; - } - //! Return Y Compound - inline float y(void) const - { - return m_Vector[1]; - } - //! Return Z Compound - inline float z(void) const - { - return m_Vector[2]; - } - //! Return a pointer to vector data - inline const float *data(void) const - { - return m_Vector; - } - //! Return true if the vector is null - inline bool isNull(void) const - { - return qFuzzyCompare(m_Vector[0], 0.0f) && qFuzzyCompare(m_Vector[1], 0.0f) - && qFuzzyCompare(m_Vector[2], 0.0f); - } - -//@} - -////////////////////////////////////////////////////////////////////// -//name Private attributes -////////////////////////////////////////////////////////////////////// -private: - /*! Vector array definition \n - * data[0] X \n - * data[1] Y \n - * data[2] Z \n - */ - float m_Vector[3]; - -}; //class GLC_Vector3d - -//! Define GLC_Point3D -typedef GLC_Vector3df GLC_Point3df; - -#endif /*GLC_VECTOR3DF_H_*/ diff --git a/ground/gcs/src/libs/glc_lib/maths/glc_vector4d.cpp b/ground/gcs/src/libs/glc_lib/maths/glc_vector4d.cpp deleted file mode 100644 index 60fee38ad..000000000 --- a/ground/gcs/src/libs/glc_lib/maths/glc_vector4d.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - - -//! \file glc_vector4d.cpp implementation of the GLC_Vector4d class. -#include "glc_vector4d.h" -#include - -using namespace glc; -////////////////////////////////////////////////////////////////////// -// Operators overload -////////////////////////////////////////////////////////////////////// - - -// Overload dot product "^" operator -GLC_Vector4d GLC_Vector4d::operator^ (const GLC_Vector4d &Vect) const -{ - GLC_Vector4d VectResult; - VectResult.vector[0]= vector[1] * Vect.vector[2] - vector[2] * Vect.vector[1]; - VectResult.vector[1]= vector[2] * Vect.vector[0] - vector[0] * Vect.vector[2]; - VectResult.vector[2]= vector[0] * Vect.vector[1] - vector[1] * Vect.vector[0]; - - return VectResult; -} - -// Overload equality "==" operator -bool GLC_Vector4d::operator == (const GLC_Vector4d &Vect) const -{ - bool bResult= qFuzzyCompare(vector[0], Vect.vector[0]); - bResult= bResult && qFuzzyCompare(vector[1], Vect.vector[1]); - bResult= bResult && qFuzzyCompare(vector[2], Vect.vector[2]); - bResult= bResult && qFuzzyCompare(vector[3], Vect.vector[3]); - - return bResult; -} -////////////////////////////////////////////////////////////////////// -// Set Function -////////////////////////////////////////////////////////////////////// - -GLC_Vector4d& GLC_Vector4d::setW(const double &dW) -{ - if (dW != 0) - { - const double invDW= 1.0 / dW; - vector[0]*= invDW; - vector[1]*= invDW; - vector[2]*= invDW; - vector[3]= 1.0; // For calculation, W = 1. - } - return *this; -} - -GLC_Vector4d& GLC_Vector4d::setVect(const double &dX, const double &dY, - const double &dZ, const double &dW) -{ - if ((dW == 1.0) || (dW <= 0.0)) - { - vector[0]= dX; - vector[1]= dY; - vector[2]= dZ; - } - else - { - const double invDW= 1.0 / dW; - vector[0]= dX * invDW; - vector[1]= dY * invDW; - vector[2]= dZ * invDW; - } - - vector[3]= 1.0; // For calculation, W = 1. - - return *this; -} - -GLC_Vector4d& GLC_Vector4d::setNormal(const double &Norme) -{ - const double dNormeCur= sqrt( vector[0] * vector[0] + vector[1] * vector[1] + vector[2] * vector[2]); - - if (dNormeCur != 0) - { - const double Coef = Norme / dNormeCur; - - vector[0] = vector[0] * Coef; - vector[1] = vector[1] * Coef; - vector[2] = vector[2] * Coef; - } - return *this; -} - -////////////////////////////////////////////////////////////////////// -// Get Function -////////////////////////////////////////////////////////////////////// - -// Return the Angle with another vector -double GLC_Vector4d::getAngleWithVect(GLC_Vector4d Vect) const -{ - GLC_Vector4d ThisVect(*this); - ThisVect.setNormal(1); - Vect.setNormal(1); - // Rotation axis - const GLC_Vector4d VectAxeRot(ThisVect ^ Vect); - // Check if the rotation axis vector is null - if (!VectAxeRot.isNull()) - { - return acos(ThisVect * Vect); - } - else return 0.0; -} - -// return the vector string -QString GLC_Vector4d::toString() const -{ - QString result("["); - - result+= QString::number(vector[0]) + QString(" , "); - result+= QString::number(vector[1]) + QString(" , "); - result+= QString::number(vector[2]) + QString(" , "); - result+= QString::number(vector[3]) + QString("]"); - - return result; -} - -// return the 2D vector -GLC_Vector2d GLC_Vector4d::toVector2d(const GLC_Vector4d& mask) const -{ - double x; - double y; - if (mask.vector[0] == 0.0) - { - x= vector[0]; - if (mask.vector[1] == 0.0) - y= vector[1]; - else - y= vector[2]; - - } - else - { - x= vector[1]; - y= vector[2]; - - } - return GLC_Vector2d(x, y); -} - -////////////////////////////////////////////////////////////////////// -// Services private function -////////////////////////////////////////////////////////////////////// - -// Normalize Vector w <- 1 -void GLC_Vector4d::normalizeW(void) -{ - if (fabs(vector[3]) > 0.00001) - { - const double invW= 1.0 / vector[3]; - vector[0]*= invW; - vector[1]*= invW; - vector[2]*= invW; - } - vector[3]= 1.0; -} - -// Non-member stream operator -QDataStream &operator<<(QDataStream &stream, const GLC_Vector4d &vector) -{ - stream << vector.X() << vector.Y() << vector.Z() << vector.W(); - return stream; -} -QDataStream &operator>>(QDataStream &stream, GLC_Vector4d &vector) -{ - double x, y, z, w; - stream >> x >> y >> z >> w; - vector.setVect(x, y, z, w); - return stream; -} - - diff --git a/ground/gcs/src/libs/glc_lib/maths/glc_vector4d.h b/ground/gcs/src/libs/glc_lib/maths/glc_vector4d.h deleted file mode 100644 index fee674224..000000000 --- a/ground/gcs/src/libs/glc_lib/maths/glc_vector4d.h +++ /dev/null @@ -1,393 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_vector4d.h interface for the GLC_Vector4d class. - -#ifndef GLC_VECTOR4D_H_ -#define GLC_VECTOR4D_H_ - -#include -#include - -#include "glc_utils_maths.h" -#include "glc_vector2d.h" -#include "glc_vector3d.h" -#include "glc_vector3df.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Vector4d -/*! \brief GLC_Vector4d is a 4 dimensions Vector*/ - -/*! GLC_Vector4d is used to represent 3D position and vectors. \n - * it had 4 Dimensions for compatibility purpose with GLC_Matrix4x4 - * */ -////////////////////////////////////////////////////////////////////// - -class GLC_LIB_EXPORT GLC_Vector4d -{ - //! GLC_Matrix4x4 class - friend class GLC_Matrix4x4; - - //! Overload unary "-" operator - inline friend GLC_Vector4d operator - (const GLC_Vector4d &Vect) - { - return GLC_Vector4d(-Vect.vector[0], -Vect.vector[1], -Vect.vector[2]); - } - - -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - /*! Default constructor - * Value is set to - * \n X = 0.0 - * \n Y = 0.0 - * \n Z = 0.0 - * \n W = 1.0*/ - inline GLC_Vector4d() - { - vector[0]= 0.0; - vector[1]= 0.0; - vector[2]= 0.0; - - vector[3]= 1.0; - } - //! Standard constructor With x, y, z and w with default value of 1.0 - inline GLC_Vector4d(const double &dX, const double &dY, const double &dZ, const double &dW= 1.0) - { - setVect(dX, dY, dZ, dW); - } - //! Copy constructor - inline GLC_Vector4d(const GLC_Vector4d &Vect) - { - vector[0]= Vect.vector[0]; - vector[1]= Vect.vector[1]; - vector[2]= Vect.vector[2]; - vector[3]= Vect.vector[3]; - } - - //! Copy from an GLC_Vector3d - inline GLC_Vector4d(const GLC_Vector3d &Vect) - { - vector[0]= Vect.m_Vector[0]; - vector[1]= Vect.m_Vector[1]; - vector[2]= Vect.m_Vector[2]; - vector[3]= 1.0; - } - - //! Copy from an GLC_Vector3d - inline GLC_Vector4d(const GLC_Vector3df &Vect) - { - vector[0]= static_cast(Vect.m_Vector[0]); - vector[1]= static_cast(Vect.m_Vector[1]); - vector[2]= static_cast(Vect.m_Vector[2]); - vector[3]= 1.0; - } - - //! Copy from an GLC_Vector3d - inline GLC_Vector4d(const GLC_Vector2d &Vect) - { - vector[0]= Vect.m_Vector[0]; - vector[1]= Vect.m_Vector[1]; - vector[2]= 0.0; - vector[3]= 1.0; - } - -//@} - -////////////////////////////////////////////////////////////////////// -/*! @name Operator Overload */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Overload binary "+" operator - inline GLC_Vector4d operator + (const GLC_Vector4d &Vect) const - { - GLC_Vector4d VectResult(vector[0] + Vect.vector[0], vector[1] + Vect.vector[1], - vector[2] + Vect.vector[2]); - - return VectResult; - } - - //! Overload "=" operator - inline GLC_Vector4d& operator = (const GLC_Vector4d &Vect) - { - vector[0]= Vect.vector[0]; - vector[1]= Vect.vector[1]; - vector[2]= Vect.vector[2]; - vector[3]= Vect.vector[3]; - - return *this; - } - - //! Overload "=" operator - inline GLC_Vector4d& operator = (const GLC_Vector3d &Vect) - { - vector[0]= Vect.m_Vector[0]; - vector[1]= Vect.m_Vector[1]; - vector[2]= Vect.m_Vector[2]; - vector[3]= 1.0; - - return *this; - } - - //! Overload "=" operator - inline GLC_Vector4d& operator = (const GLC_Vector3df &Vect) - { - vector[0]= static_cast(Vect.m_Vector[0]); - vector[1]= static_cast(Vect.m_Vector[1]); - vector[2]= static_cast(Vect.m_Vector[2]); - vector[3]= 1.0; - - return *this; - } - - //! Overload "=" operator - inline GLC_Vector4d& operator = (const GLC_Vector2d &Vect) - { - vector[0]= Vect.m_Vector[0]; - vector[1]= Vect.m_Vector[1]; - vector[2]= 0.0; - vector[3]= 1.0; - - return *this; - } - - //! Overload "+=" operator - inline GLC_Vector4d* operator += (const GLC_Vector4d &Vect) - { - *this= *this + Vect; - return this; - } - - - //! Overload binary "-" operator - inline GLC_Vector4d operator - (const GLC_Vector4d &Vect) const - { - GLC_Vector4d VectResult(vector[0] - Vect.vector[0], vector[1] - Vect.vector[1], - vector[2] - Vect.vector[2]); - - return VectResult; - } - - //! Overload binary "-=" operator - GLC_Vector4d* operator -= (const GLC_Vector4d &Vect) - { - *this= *this - Vect; - return this; - } - - //! Overload dot product "^" operator - GLC_Vector4d operator ^ (const GLC_Vector4d &Vect) const; - - //! Overload scalar product "*" operator between 2 vector - inline double operator * (const GLC_Vector4d &Vect) const - { - // W Component is ignored - return vector[0] * Vect.vector[0] + vector[1] * Vect.vector[1] + - vector[2] * Vect.vector[2]; - } - - //! Overload scalar product "*" operator between 1 vector and one scalar - inline GLC_Vector4d operator * (double Scalaire) const - { - return GLC_Vector4d(vector[0] * Scalaire, vector[1] * Scalaire, vector[2] * Scalaire); - } - - - //! Overload equality "==" operator - bool operator == (const GLC_Vector4d &Vect) const; - - //! Overload dot product "!=" operator - inline bool operator != (const GLC_Vector4d &Vect) const - { - return !(*this == Vect); - } - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! X Compound - inline GLC_Vector4d& setX(const double &dX) - { - vector[0]= dX; - return *this; - } - - //! Y Compound - inline GLC_Vector4d& setY(const double &dY) - { - vector[1]= dY; - return *this; - } - - //! Z Compound - inline GLC_Vector4d& setZ(const double &dZ) - { - vector[2]= dZ; - return *this; - } - - //! W Compound - GLC_Vector4d& setW(const double &dW); - - //! All Compound - GLC_Vector4d& setVect(const double &dX, const double &dY, const double &dZ, const double &dW= 1); - - //! From another Vector - inline GLC_Vector4d& setVect(const GLC_Vector4d &Vect) - { - vector[0]= Vect.vector[0]; - vector[1]= Vect.vector[1]; - vector[2]= Vect.vector[2]; - vector[3]= Vect.vector[3]; - return *this; - } - - //! Vector Normal - GLC_Vector4d& setNormal(const double &Norme); - - /*! Invert Vector*/ - inline GLC_Vector4d& invert(void) - { - vector[0]= - vector[0]; - vector[1]= - vector[1]; - vector[2]= - vector[2]; - return *this; - } - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return X Compound - inline double X(void) const - { - return vector[0]; - } - //! Return Y Compound - inline double Y(void) const - { - return vector[1]; - } - //! Return Z Compound - inline double Z(void) const - { - return vector[2]; - } - //! Return W Compound - inline double W(void) const - { - return vector[3]; - } - inline GLC_Vector3d toVector3d() const - { - return GLC_Vector3d(vector[0], vector[1], vector[2]); - } - inline GLC_Vector3df toVector3df() const - { - return GLC_Vector3df(static_cast(vector[0]), static_cast(vector[1]), static_cast(vector[2])); - } - //! Return a pointer to vector data - inline const double *data(void) const - { - return vector; - } - //! Return Vector Norm - inline double norm(void) const - { - return sqrt(vector[0] * vector[0] + vector[1] * vector[1] - + vector[2] * vector[2]); - } - /*! Vector is null*/ - inline bool isNull(void) const - { - bool result; - - result= qFuzzyCompare(vector[0], 0.0) && qFuzzyCompare(vector[1], 0.0) - && qFuzzyCompare(vector[2], 0.0); - - return result; - } - - //! Return the Angle with another vector - double getAngleWithVect(GLC_Vector4d Vect) const; - - //! Return the vector string - QString toString() const; - - //! Return the 2D vector specified by a mask vector - /*! retrieve component corresponding to - * mask NULL component*/ - GLC_Vector2d toVector2d(const GLC_Vector4d&) const; - - //! Return a QVector of 3 values - inline QVector toFloat3dQVector() const - { - QVector result; - result << static_cast(vector[0]) << static_cast(vector[1]) << static_cast(vector[2]); - return result; - } -//@} - -////////////////////////////////////////////////////////////////////// -// Private services functions -////////////////////////////////////////////////////////////////////// -private: - - //! Normalize Vector w <- 1 - void normalizeW(void); - -////////////////////////////////////////////////////////////////////// -//name Private attributes -////////////////////////////////////////////////////////////////////// -private: - /*! Vector array definition \n - * vector[0] X \n - * vector[1] Y \n - * vector[2] Z \n - * vector[3] 1 - */ - enum {VECT4DIMENSION = 4}; - double vector[VECT4DIMENSION]; - -}; //class GLC_Vector4d - -//! Define GLC_Point4D -//typedef GLC_Vector4d GLC_Point4d; - -//! Non-member stream operator -QDataStream &operator<<(QDataStream &, const GLC_Vector4d &); -QDataStream &operator>>(QDataStream &, GLC_Vector4d &); - -#endif /*GLC_VECTOR4D_H_*/ diff --git a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_3dviewcollection.cpp b/ground/gcs/src/libs/glc_lib/sceneGraph/glc_3dviewcollection.cpp deleted file mode 100644 index dbf0702aa..000000000 --- a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_3dviewcollection.cpp +++ /dev/null @@ -1,713 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_3dviewcollection.cpp implementation of the GLC_3DViewCollection class. - - -#include "glc_3dviewcollection.h" -#include "../shading/glc_material.h" -#include "../glc_openglexception.h" -#include "../shading/glc_selectionmaterial.h" -#include "../glc_state.h" -#include "../shading/glc_shader.h" -#include "../viewport/glc_viewport.h" -#include "glc_spacepartitioning.h" - -#include - -////////////////////////////////////////////////////////////////////// -// Constructor/Destructor -////////////////////////////////////////////////////////////////////// - -GLC_3DViewCollection::GLC_3DViewCollection() -: m_3DViewInstanceHash() -, m_SelectedInstances() -, m_ShadedPointerViewInstanceHash() -, m_ShaderGroup() -, m_MainInstances() -, m_IsInShowSate(true) -, m_UseLod(false) -, m_pViewport(NULL) -, m_pSpacePartitioning(NULL) -, m_UseSpacePartitioning(false) -, m_IsViewable(true) -{ -} - -GLC_3DViewCollection::~GLC_3DViewCollection() -{ - // Delete all collection's elements and the collection bounding box - clear(); -} -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -bool GLC_3DViewCollection::bindShader(GLC_uint shaderId) -{ - if (m_ShadedPointerViewInstanceHash.contains(shaderId)) - { - return false; - } - else - { - PointerViewInstanceHash* pNodeHash= new PointerViewInstanceHash; - m_ShadedPointerViewInstanceHash.insert(shaderId, pNodeHash); - return true; - } -} - -bool GLC_3DViewCollection::unBindShader(GLC_uint shaderId) -{ - bool result= false; - if (m_ShadedPointerViewInstanceHash.contains(shaderId)) - { - // Find node which use the shader - QList nodeId(m_ShaderGroup.keys(shaderId)); - - // Move these node in the standard hash and remove them from shader group - PointerViewInstanceHash* pShaderNodeHash= m_ShadedPointerViewInstanceHash.take(shaderId); - for (int i= 0; i < nodeId.size(); ++i) - { - const GLC_uint id= nodeId[i]; - GLC_3DViewInstance* pInstance= pShaderNodeHash->value(id); - - if (!pInstance->isSelected()) - { - m_MainInstances.insert(id, pInstance); - } - else - { - m_SelectedInstances.insert(id, pInstance); - } - m_ShaderGroup.remove(id); - } - pShaderNodeHash->clear(); - delete pShaderNodeHash; - result= true; - } - Q_ASSERT(!m_ShadedPointerViewInstanceHash.contains(shaderId)); - return result; -} - -bool GLC_3DViewCollection::unBindAllShader() -{ - bool result= true; - HashList::iterator iEntry= m_ShadedPointerViewInstanceHash.begin(); - QList shaderList; - while (iEntry != m_ShadedPointerViewInstanceHash.constEnd()) - { - shaderList.append(iEntry.key()); - ++iEntry; - } - const int size= shaderList.size(); - for (int i=0; i < size; ++i) - { - result= result && unBindShader(shaderList[i]); - } - return result; -} - -bool GLC_3DViewCollection::add(const GLC_3DViewInstance& node, GLC_uint shaderID) -{ - bool result= false; - const GLC_uint key= node.id(); - if (m_3DViewInstanceHash.contains(key)) - { - return false; - } - - m_3DViewInstanceHash.insert(key, node); - // Create an GLC_3DViewInstance pointer of the inserted instance - ViewInstancesHash::iterator iNode= m_3DViewInstanceHash.find(key); - GLC_3DViewInstance* pInstance= &(iNode.value()); - // Chose the hash where instance is - if(0 != shaderID) - { - // Test if shaderId group exist - if (m_ShadedPointerViewInstanceHash.contains(shaderID)) - { - m_ShaderGroup.insert(key, shaderID); - - if(pInstance->isSelected()) - { - m_SelectedInstances.insert(key, pInstance); - } - else - { - m_ShadedPointerViewInstanceHash.value(shaderID)->insert(key, pInstance); - } - result=true; - } - } - else if (!pInstance->isSelected()) - { - m_MainInstances.insert(key, pInstance); - result=true; - } - else - { - m_SelectedInstances.insert(key, pInstance); - result=true; - } - - return result; -} - -void GLC_3DViewCollection::changeShadingGroup(GLC_uint instanceId, GLC_uint shaderId) -{ - // Test if the specified instance exist - Q_ASSERT(m_3DViewInstanceHash.contains(instanceId)); - // Get the instance shading group - const GLuint instanceShadingGroup= shadingGroup(instanceId); - // Get a pointer to the instance - GLC_3DViewInstance* pInstance= NULL; - if (0 == instanceShadingGroup) - { - // The instance is not in a shading group - if (m_MainInstances.contains(instanceId)) - { - pInstance= m_MainInstances.take(instanceId); - } - else if (m_SelectedInstances.contains(instanceId)) - { - // The instance is selected don't take it - pInstance= m_SelectedInstances.value(instanceId); - } - else - { - Q_ASSERT(false); - } - } - else - { - m_ShaderGroup.remove(instanceId); - // The instance is in a shading group - if (m_SelectedInstances.contains(instanceId)) - { - // The instance is selected don't take it - pInstance= m_SelectedInstances.value(instanceId); - } - else - { - pInstance= m_ShadedPointerViewInstanceHash.value(instanceShadingGroup)->take(instanceId); - } - - } - // Put the instance in specified shading group - if (0 != shaderId) - { - m_ShaderGroup.insert(instanceId, shaderId); - if (!pInstance->isSelected()) - { - m_ShadedPointerViewInstanceHash.value(shaderId)->insert(instanceId, pInstance); - } - } - else if (!pInstance->isSelected()) - { - m_MainInstances.insert(instanceId, pInstance); - } -} - -bool GLC_3DViewCollection::remove(GLC_uint Key) -{ - ViewInstancesHash::iterator iNode= m_3DViewInstanceHash.find(Key); - - if (iNode != m_3DViewInstanceHash.end()) - { // Ok, the key exist - - if (selectionSize() > 0) - { - // if the geometry is selected, unselect it - unselect(Key); - } - - m_MainInstances.remove(Key); - - m_3DViewInstanceHash.remove(Key); // Delete the conteneur - - //qDebug("GLC_3DViewCollection::removeNode : Element succesfuly deleted"); - return true; - - } - else - { // KO, key doesn't exist - return false; - } - -} - -void GLC_3DViewCollection::clear(void) -{ - // Clear Selected node Hash Table - m_SelectedInstances.clear(); - // Clear the not transparent Hash Table - m_MainInstances.clear(); - // Clear Other Node Hash List - HashList::iterator iEntry= m_ShadedPointerViewInstanceHash.begin(); - while (iEntry != m_ShadedPointerViewInstanceHash.constEnd()) - { - iEntry.value()->clear(); - delete iEntry.value(); - iEntry= m_ShadedPointerViewInstanceHash.erase(iEntry); - } - - m_ShadedPointerViewInstanceHash.clear(); - m_ShaderGroup.clear(); - - // Clear main Hash table - m_3DViewInstanceHash.clear(); - - // delete the space partitioning - delete m_pSpacePartitioning; -} - -bool GLC_3DViewCollection::select(GLC_uint key, bool primitive) -{ - if (!m_3DViewInstanceHash.contains(key)) return false; - //qDebug() << "GLC_Collection::select " << key; - - GLC_3DViewInstance* pSelectedInstance; - ViewInstancesHash::iterator iNode= m_3DViewInstanceHash.find(key); - PointerViewInstanceHash::iterator iSelectedNode= m_SelectedInstances.find(key); - - if ((iNode != m_3DViewInstanceHash.end()) && (iSelectedNode == m_SelectedInstances.end())) - { // Ok, the key exist and the node is not selected - pSelectedInstance= &(iNode.value()); - m_SelectedInstances.insert(pSelectedInstance->id(), pSelectedInstance); - - // Remove Selected Node from is previous collection - if (isInAShadingGroup(key)) - { - m_ShadedPointerViewInstanceHash.value(shadingGroup(key))->remove(key); - //qDebug() << "remove from shader list"; - } - else - { - m_MainInstances.remove(key); - } - pSelectedInstance->select(primitive); - - //qDebug("GLC_3DViewCollection::selectNode : Element succesfuly selected"); - return true; - } - else - { // KO, instance allready selected - return false; - } -} - -void GLC_3DViewCollection::selectAll(bool allShowState) -{ - unselectAll(); - ViewInstancesHash::iterator iNode= m_3DViewInstanceHash.begin(); - while (iNode != m_3DViewInstanceHash.end()) - { - GLC_3DViewInstance *pCurrentInstance= &(iNode.value()); - const GLC_uint instanceId= pCurrentInstance->id(); - - if (allShowState || (pCurrentInstance->isVisible() == m_IsInShowSate)) - { - pCurrentInstance->select(false); - m_SelectedInstances.insert(instanceId, pCurrentInstance); - m_MainInstances.remove(instanceId); - if(isInAShadingGroup(instanceId)) - { - m_ShadedPointerViewInstanceHash.value(shadingGroup(instanceId))->remove(instanceId); - } - } - iNode++; - } -} - -bool GLC_3DViewCollection::unselect(GLC_uint key) -{ - GLC_3DViewInstance* pSelectedNode; - - PointerViewInstanceHash::iterator iSelectedNode= m_SelectedInstances.find(key); - - if (iSelectedNode != m_SelectedInstances.end()) - { // Ok, the key exist and the node is selected - iSelectedNode.value()->unselect(); - - pSelectedNode= iSelectedNode.value(); - m_SelectedInstances.remove(key); - - // Insert Selected Node to the right collection - if (isInAShadingGroup(key)) - { - m_ShadedPointerViewInstanceHash.value(shadingGroup(key))->insert(key, pSelectedNode); - } - else - { - m_MainInstances.insert(key, pSelectedNode); - } - - //qDebug("GLC_3DViewCollection::unselectNode : Node succesfuly unselected"); - return true; - - } - else - { // KO, key doesn't exist or node allready selected - //qDebug("GLC_3DViewCollection::unselectNode : Node not unselected"); - return false; - } -} - -void GLC_3DViewCollection::unselectAll() -{ - PointerViewInstanceHash::iterator iSelectedNode= m_SelectedInstances.begin(); - - while (iSelectedNode != m_SelectedInstances.end()) - { - GLC_3DViewInstance* pInstance= iSelectedNode.value(); - pInstance->unselect(); - if (isInAShadingGroup(pInstance->id())) - { - m_ShadedPointerViewInstanceHash.value(shadingGroup(pInstance->id()))->insert(pInstance->id(), pInstance); - } - else - { - m_MainInstances.insert(pInstance->id(), pInstance); - } - - ++iSelectedNode; - } - // Clear selected node hash table - m_SelectedInstances.clear(); -} - -void GLC_3DViewCollection::setPolygonModeForAll(GLenum face, GLenum mode) -{ - ViewInstancesHash::iterator iEntry= m_3DViewInstanceHash.begin(); - - while (iEntry != m_3DViewInstanceHash.constEnd()) - { - iEntry.value().setPolygonMode(face, mode); - iEntry++; - } - -} - -void GLC_3DViewCollection::setVisibility(const GLC_uint key, const bool visibility) -{ - ViewInstancesHash::iterator iNode= m_3DViewInstanceHash.find(key); - if (iNode != m_3DViewInstanceHash.end()) - { // Ok, the key exist - iNode.value().setVisibility(visibility); - } -} - -void GLC_3DViewCollection::showAll() -{ - ViewInstancesHash::iterator iEntry= m_3DViewInstanceHash.begin(); - - while (iEntry != m_3DViewInstanceHash.constEnd()) - { - iEntry.value().setVisibility(true); - iEntry++; - } -} - -void GLC_3DViewCollection::hideAll() -{ - ViewInstancesHash::iterator iEntry= m_3DViewInstanceHash.begin(); - - while (iEntry != m_3DViewInstanceHash.constEnd()) - { - iEntry.value().setVisibility(false); - iEntry++; - } - -} - -void GLC_3DViewCollection::bindSpacePartitioning(GLC_SpacePartitioning* pSpacePartitioning) -{ - Q_ASSERT(NULL != pSpacePartitioning); - Q_ASSERT(pSpacePartitioning->collectionHandle() == this); - - delete m_pSpacePartitioning; - m_pSpacePartitioning= pSpacePartitioning; -} - -void GLC_3DViewCollection::unbindSpacePartitioning() -{ - delete m_pSpacePartitioning; - m_pSpacePartitioning= NULL; - m_UseSpacePartitioning= false; - - ViewInstancesHash::iterator iEntry= m_3DViewInstanceHash.begin(); - while (iEntry != m_3DViewInstanceHash.constEnd()) - { - // Update Instance viewable flag - iEntry.value().setViewable(GLC_3DViewInstance::FullViewable); - iEntry++; - } - -} - -void GLC_3DViewCollection::updateInstanceViewableState(GLC_Matrix4x4* pMatrix) -{ - if ((NULL != m_pViewport) && m_UseSpacePartitioning && (NULL != m_pSpacePartitioning)) - { - if (m_pViewport->updateFrustum(pMatrix)) - m_pSpacePartitioning->updateViewableInstances(m_pViewport->frustum()); - } -} - -void GLC_3DViewCollection::updateInstanceViewableState(const GLC_Frustum& frustum) -{ - m_pSpacePartitioning->updateViewableInstances(frustum); -} - -void GLC_3DViewCollection::setVboUsage(bool usage) -{ - ViewInstancesHash::iterator iEntry= m_3DViewInstanceHash.begin(); - - while (iEntry != m_3DViewInstanceHash.constEnd()) - { - iEntry.value().setVboUsage(usage); - iEntry++; - } -} - -QList GLC_3DViewCollection::instancesHandle() -{ - QList instancesList; - - ViewInstancesHash::iterator iEntry= m_3DViewInstanceHash.begin(); - - while (iEntry != m_3DViewInstanceHash.constEnd()) - { - instancesList.append(&(iEntry.value())); - iEntry++; - } - return instancesList; -} - -QList GLC_3DViewCollection::visibleInstancesHandle() -{ - QList instancesList; - - ViewInstancesHash::iterator iEntry= m_3DViewInstanceHash.begin(); - - while (iEntry != m_3DViewInstanceHash.constEnd()) - { - if (iEntry.value().isVisible()) - { - instancesList.append(&(iEntry.value())); - } - iEntry++; - } - return instancesList; - -} - -QList GLC_3DViewCollection::viewableInstancesHandle() -{ - QList instancesList; - - ViewInstancesHash::iterator iEntry= m_3DViewInstanceHash.begin(); - - while (iEntry != m_3DViewInstanceHash.constEnd()) - { - if (iEntry.value().isVisible() == m_IsInShowSate) - { - instancesList.append(&(iEntry.value())); - } - iEntry++; - } - return instancesList; -} - -GLC_3DViewInstance* GLC_3DViewCollection::instanceHandle(GLC_uint Key) -{ - Q_ASSERT(m_3DViewInstanceHash.contains(Key)); - return &(m_3DViewInstanceHash[Key]); -} - -GLC_BoundingBox GLC_3DViewCollection::boundingBox(bool allObject) -{ - GLC_BoundingBox boundingBox; - // Check if the bounding box have to be updated - if (!m_3DViewInstanceHash.isEmpty()) - { - ViewInstancesHash::iterator iEntry= m_3DViewInstanceHash.begin(); - while (iEntry != m_3DViewInstanceHash.constEnd()) - { - if(allObject || iEntry.value().isVisible() == m_IsInShowSate) - { - // Combine Collection BoundingBox with element Bounding Box - boundingBox.combine(iEntry.value().boundingBox()); - } - ++iEntry; - } - } - return boundingBox; -} - -int GLC_3DViewCollection::drawableObjectsSize() const -{ - // The number of object to drw - int numberOffDrawnHit= 0; - - // Count the number off instance to draw - ViewInstancesHash::const_iterator i= m_3DViewInstanceHash.begin(); - while (i != m_3DViewInstanceHash.constEnd()) - { - //qDebug() << "transparent"; - if (i.value().isVisible() == m_IsInShowSate) - { - ++numberOffDrawnHit; - } - ++i; - } - return numberOffDrawnHit; -} - -QList GLC_3DViewCollection::instanceNamesFromShadingGroup(GLuint shaderId) const -{ - QList listOfInstanceName; - QList listOfInstanceNameId= m_ShaderGroup.keys(shaderId); - if (!listOfInstanceNameId.isEmpty()) - { - const int size= listOfInstanceNameId.size(); - for (int i= 0; i < size; ++i) - { - listOfInstanceName << m_3DViewInstanceHash.value(listOfInstanceNameId[i]).name(); - } - } - return listOfInstanceName; -} - -int GLC_3DViewCollection::numberOfUsedShadingGroup() const -{ - return m_ShaderGroup.values().toSet().size(); -} - -////////////////////////////////////////////////////////////////////// -// OpenGL Functions -////////////////////////////////////////////////////////////////////// - -void GLC_3DViewCollection::render(GLuint groupId, glc::RenderFlag renderFlag) -{ - if (!isEmpty() && m_IsViewable) - { - if (renderFlag == glc::WireRenderFlag) - { - glEnable(GL_POLYGON_OFFSET_FILL); - glPolygonOffset (1.0, 1.0); - } - if (GLC_State::isInSelectionMode()) - { - glDisable(GL_BLEND); - GLC_Context::current()->glcEnableLighting(false); - glDisable(GL_TEXTURE_2D); - } - else - { - GLC_Context::current()->glcEnableLighting(true); - } - glDraw(groupId, renderFlag); - - if (renderFlag == glc::WireRenderFlag) - { - glDisable(GL_POLYGON_OFFSET_FILL); - } - } -} -void GLC_3DViewCollection::renderShaderGroup(glc::RenderFlag renderFlag) -{ - if (!isEmpty() && m_IsViewable) - { - if (GLC_State::isInSelectionMode()) - { - glDisable(GL_BLEND); - GLC_Context::current()->glcEnableLighting(false); - glDisable(GL_TEXTURE_2D); - } - - HashList::iterator iEntry= m_ShadedPointerViewInstanceHash.begin(); - while (iEntry != m_ShadedPointerViewInstanceHash.constEnd()) - { - glDraw(iEntry.key(), renderFlag); - ++iEntry; - } - } -} - -void GLC_3DViewCollection::glDraw(GLC_uint groupId, glc::RenderFlag renderFlag) -{ - // Set render Mode and OpenGL state - if (!GLC_State::isInSelectionMode() && (groupId == 0)) - { - if (renderFlag == glc::TransparentRenderFlag) - { - glEnable(GL_BLEND); - glDepthMask(GL_FALSE); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - } - else - { - glDisable(GL_BLEND); - glDepthMask(GL_TRUE); - glEnable(GL_DEPTH_TEST); - } - } - - // Normal GLC_3DViewInstance - if ((groupId == 0) && !m_MainInstances.isEmpty()) - { - glDrawInstancesOf(&m_MainInstances, renderFlag); - - } - // Selected GLC_3DVIewInstance - else if ((groupId == 1) && !m_SelectedInstances.isEmpty()) - { - if (GLC_State::selectionShaderUsed()) GLC_SelectionMaterial::useShader(); - - glDrawInstancesOf(&m_SelectedInstances, renderFlag); - - if (GLC_State::selectionShaderUsed()) GLC_SelectionMaterial::unUseShader(); - } - // GLC_3DViewInstance with shader - else if (!m_ShadedPointerViewInstanceHash.isEmpty()) - { - if(m_ShadedPointerViewInstanceHash.contains(groupId) && !m_ShadedPointerViewInstanceHash.value(groupId)->isEmpty()) - { - PointerViewInstanceHash* pNodeHash= m_ShadedPointerViewInstanceHash.value(groupId); - - GLC_Shader::use(groupId); - glDrawInstancesOf(pNodeHash, renderFlag); - GLC_Shader::unuse(); - } - } - - // Restore OpenGL state - if (renderFlag && !GLC_State::isInSelectionMode() && (groupId == 0)) - { - glDisable(GL_BLEND); - glDepthMask(GL_TRUE); - glEnable(GL_DEPTH_TEST); - } -} diff --git a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_3dviewcollection.h b/ground/gcs/src/libs/glc_lib/sceneGraph/glc_3dviewcollection.h deleted file mode 100644 index 9fc6d4384..000000000 --- a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_3dviewcollection.h +++ /dev/null @@ -1,403 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_3dviewcollection.h interface for the GLC_3DViewCollection class. - -#ifndef GLC_3DVIEWCOLLECTION_H_ -#define GLC_3DVIEWCOLLECTION_H_ - - -#include -#include "glc_3dviewinstance.h" -#include "../glc_global.h" -#include "../viewport/glc_frustum.h" - -#include "../glc_config.h" - -class GLC_SpacePartitioning; -class GLC_Material; -class GLC_Shader; -class GLC_Viewport; - -//! GLC_3DViewInstance Hash table -typedef QHash< GLC_uint, GLC_3DViewInstance> ViewInstancesHash; - -//! GLC_3DViewInstance pointer Hash table -typedef QHash PointerViewInstanceHash; - -//! Hash table of GLC_3DViewInstance Hash table which use a shader -typedef QHash HashList; - -//! Map Shader id to instances id (instances which use the shader) -typedef QHash ShaderIdToInstancesId; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_3DViewCollection -/*! \brief GLC_3DViewCollection : GLC_3DViewInstance flat collection */ - -/*! An GLC_3DViewCollection contains : - * - A hash table containing GLC_3DViewInstance Class - * - A hash table use to associate shader with GLC_3DViewInstance - */ -////////////////////////////////////////////////////////////////////// - -class GLC_LIB_EXPORT GLC_3DViewCollection -{ - -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Default constructor - GLC_3DViewCollection(); - - //! Destructor - /*! Delete all Node in the Hash Table and clear the Hash Table*/ - virtual ~GLC_3DViewCollection(); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Return true if the collection is empty - inline bool isEmpty() const - {return m_3DViewInstanceHash.size() == 0;} - - //! Return the number of Node in the collection - inline int size(void) const - {return m_3DViewInstanceHash.size();} - - //! Return all GLC_3DViewInstance from collection - QList instancesHandle(); - - //! Return all visible GLC_3DViewInstance from the collection - QList visibleInstancesHandle(); - - //! Return all viewable GLC_3DViewInstance from the collection - QList viewableInstancesHandle(); - - //! Return a GLC_3DViewInstance from collection - /*! If the element is not found in collection a empty node is return*/ - GLC_3DViewInstance* instanceHandle(GLC_uint Key); - - //! Return the entire collection Bounding Box - /*! If all object is set to true, visible and non visible object are used*/ - GLC_BoundingBox boundingBox(bool allObject= false); - - //! Return the number of Node in the selection Hash - inline int selectionSize(void) const - {return m_SelectedInstances.size();} - - //! Get the Hash table of Selected Nodes - inline PointerViewInstanceHash* selection() - {return &m_SelectedInstances;} - - //! Return true if the Instance Id is in the collection - inline bool contains(GLC_uint key) const - {return m_3DViewInstanceHash.contains(key);} - - //! Return true if the element is selected - inline bool isSelected(GLC_uint key) const - {return m_SelectedInstances.contains(key);} - - //! Return the showing state - inline bool showState() const - {return m_IsInShowSate;} - - //! Return the number of drawable objects - int drawableObjectsSize() const; - - //! Return the element shading group - inline GLC_uint shadingGroup(GLC_uint key) const - { return m_ShaderGroup.value(key);} - - //! Return true if the element is in a shading group - inline bool isInAShadingGroup(GLC_uint key) const - { return m_ShaderGroup.contains(key);} - - //! Return instances name from the specified shading group - QList instanceNamesFromShadingGroup(GLuint) const; - - //! Return the number of used shading group - int numberOfUsedShadingGroup() const; - - //! Return true if the space partitioning is used - inline bool spacePartitioningIsUsed() const - {return m_UseSpacePartitioning;} - - //! Return an handle to the space partitioning - inline GLC_SpacePartitioning* spacePartitioningHandle() - {return m_pSpacePartitioning;} - - //! Return true if the collection is viewable - inline bool isViewable() const - {return m_IsViewable;} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Bind the specified shader to the collection - /* return true if success false if shader is already bind*/ - bool bindShader(GLC_uint shaderId); - - //! Unbind the specified shader from the collection - /* return true if success false otherwise*/ - bool unBindShader(GLC_uint shaderId); - - //! Unbind All shader - bool unBindAllShader(); - - //! Add a GLC_3DViewInstance in the collection - /*! return true if success false otherwise - * If shading group is specified, add instance in desire shading group*/ - bool add(const GLC_3DViewInstance& ,GLC_uint shaderID=0); - - //! Change instance shading group - /* Move the specified instances into - * the specified shading group - * Return true if success false otherwise*/ - void changeShadingGroup(GLC_uint instanceId, GLC_uint shaderId); - - //! Remove a GLC_Geometry from the collection and delete it - /*! - Find the GLC_Geometry in the collection - * - Delete the GLC_Geometry - * - Remove the Geometry container from collection - * - Delete the associated OpenGL Display list - * - Remove the Display list container from collection - * - Invalidate the collection - * return true if success false otherwise*/ - bool remove(GLC_uint instanceId); - - //! Remove and delete all GLC_Geometry from the collection - void clear(void); - - //! Select a Instance - bool select(GLC_uint instanceId, bool primitive= false); - - //! Select all instances in current show state or in all show state - void selectAll(bool allShowState= false); - - //! unselect a Instance - bool unselect(GLC_uint instanceId); - - //! unselect all Instance - void unselectAll(); - - //! Set the polygon mode for all Instance - void setPolygonModeForAll(GLenum face, GLenum mode); - - //! Set Instance visibility - void setVisibility(const GLC_uint instanceId, const bool visible); - - //! Show all instances of the collection - void showAll(); - - //! Hide all instances of collection - void hideAll(); - - //! Set the Show or noShow state - inline void swapShowState() - {m_IsInShowSate= !m_IsInShowSate;} - - //! Set the LOD usage - inline void setLodUsage(const bool usage, GLC_Viewport* pView) - { - m_UseLod= usage; - m_pViewport= pView; - } - - //! Bind the space partitioning - void bindSpacePartitioning(GLC_SpacePartitioning*); - - //! Unbind the space partitioning - void unbindSpacePartitioning(); - - //! Use the space partitioning - inline void setSpacePartitionningUsage(bool use) - {m_UseSpacePartitioning= use;} - - //! Update the instance viewable state - /*! Update the frustrum culling from the viewport - * If the specified matrix pointer is not null*/ - void updateInstanceViewableState(GLC_Matrix4x4* pMatrix= NULL); - - //! Update the instance viewable state with the specified frustum - void updateInstanceViewableState(const GLC_Frustum&); - - //! Set the attached viewport of this collection - inline void setAttachedViewport(GLC_Viewport* pViewport) - {m_pViewport= pViewport;} - - //! Set the collection viewable state - inline void setViewable(bool viewable) - {m_IsViewable= viewable;} - - //! Set VBO usage - void setVboUsage(bool usage); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Display the specified collection group - /*! The main group is 0 - * The selection group is 1 - * User group are identified by user id - */ - void render(GLuint, glc::RenderFlag); - - //! Display all shader group - void renderShaderGroup(glc::RenderFlag); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// - -private: - //! Display collection's member - void glDraw(GLC_uint groupID, glc::RenderFlag renderFlag); - - //! Draw instances of a PointerViewInstanceHash - inline void glDrawInstancesOf(PointerViewInstanceHash*, glc::RenderFlag); - -//@} - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - //! GLC_3DViewInstance Hash Table - ViewInstancesHash m_3DViewInstanceHash; - - //! Selected Node Hash Table - PointerViewInstanceHash m_SelectedInstances; - - //! List of other Node Hash Table - HashList m_ShadedPointerViewInstanceHash; - - //! Shader groups hash - ShaderIdToInstancesId m_ShaderGroup; - - //! Normal Node Hash Table - PointerViewInstanceHash m_MainInstances; - - //! Show State - bool m_IsInShowSate; - - //! Level of detail usage - bool m_UseLod; - - //! The viewport associted to the collection for LOD Usage - GLC_Viewport* m_pViewport; - - //! The space partitioning - GLC_SpacePartitioning* m_pSpacePartitioning; - - //! The space partition usage - bool m_UseSpacePartitioning; - - //! Viewable state - bool m_IsViewable; - - -}; - -// Draw instances of a PointerViewInstanceHash -void GLC_3DViewCollection::glDrawInstancesOf(PointerViewInstanceHash* pHash, glc::RenderFlag renderFlag) -{ - bool forceDisplay= false; - if (GLC_State::isInSelectionMode()) - { - forceDisplay= true; - } - - PointerViewInstanceHash::iterator iEntry= pHash->begin(); - // The current instance - GLC_3DViewInstance* pCurInstance; - if (forceDisplay) - { - while (iEntry != pHash->constEnd()) - { - pCurInstance= iEntry.value(); - if ((pCurInstance->viewableFlag() != GLC_3DViewInstance::NoViewable) && (pCurInstance->isVisible() == m_IsInShowSate)) - { - pCurInstance->render(renderFlag, m_UseLod, m_pViewport); - } - ++iEntry; - } - } - else - { - if (!(renderFlag == glc::TransparentRenderFlag)) - { - while (iEntry != pHash->constEnd()) - { - pCurInstance= iEntry.value(); - if ((pCurInstance->viewableFlag() != GLC_3DViewInstance::NoViewable) && (pCurInstance->isVisible() == m_IsInShowSate)) - { - if (!pCurInstance->isTransparent() || pCurInstance->renderPropertiesHandle()->isSelected() || (renderFlag == glc::WireRenderFlag)) - { - pCurInstance->render(renderFlag, m_UseLod, m_pViewport); - } - } - - ++iEntry; - } - - } - else - { - while (iEntry != pHash->constEnd()) - { - pCurInstance= iEntry.value(); - if ((pCurInstance->viewableFlag() != GLC_3DViewInstance::NoViewable) && (pCurInstance->isVisible() == m_IsInShowSate)) - { - if (pCurInstance->hasTransparentMaterials()) - { - pCurInstance->render(renderFlag, m_UseLod, m_pViewport); - } - } - - ++iEntry; - } - } - - } -} - -#endif //GLC_3DVIEWCOLLECTION_H_ diff --git a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_3dviewinstance.cpp b/ground/gcs/src/libs/glc_lib/sceneGraph/glc_3dviewinstance.cpp deleted file mode 100644 index 2f5a1e90a..000000000 --- a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_3dviewinstance.cpp +++ /dev/null @@ -1,538 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_instance.cpp implementation of the GLC_3DViewInstance class. - -#include "glc_3dviewinstance.h" -#include "../shading/glc_selectionmaterial.h" -#include "../viewport/glc_viewport.h" -#include -#include "../glc_state.h" - -//! A Mutex -QMutex GLC_3DViewInstance::m_Mutex; - -//! The global default LOD -int GLC_3DViewInstance::m_GlobalDefaultLOD= 10; - - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -GLC_3DViewInstance::GLC_3DViewInstance() -: GLC_Object() -, m_3DRep() -, m_pBoundingBox(NULL) -, m_AbsoluteMatrix() -, m_IsBoundingBoxValid(false) -, m_RenderProperties() -, m_IsVisible(true) -, m_DefaultLOD(m_GlobalDefaultLOD) -, m_ViewableFlag(GLC_3DViewInstance::FullViewable) -, m_ViewableGeomFlag() -{ - // Encode Color Id - glc::encodeRgbId(m_Uid, m_colorId); - -} - -GLC_3DViewInstance::GLC_3DViewInstance(GLC_Geometry* pGeom) -: GLC_Object() -, m_3DRep(pGeom) -, m_pBoundingBox(NULL) -, m_AbsoluteMatrix() -, m_IsBoundingBoxValid(false) -, m_RenderProperties() -, m_IsVisible(true) -, m_DefaultLOD(m_GlobalDefaultLOD) -, m_ViewableFlag(GLC_3DViewInstance::FullViewable) -, m_ViewableGeomFlag() -{ - // Encode Color Id - glc::encodeRgbId(m_Uid, m_colorId); - - setName(m_3DRep.name()); -} - -GLC_3DViewInstance::GLC_3DViewInstance(GLC_Geometry* pGeom, GLC_uint id) -: GLC_Object(id) -, m_3DRep(pGeom) -, m_pBoundingBox(NULL) -, m_AbsoluteMatrix() -, m_IsBoundingBoxValid(false) -, m_RenderProperties() -, m_IsVisible(true) -, m_DefaultLOD(m_GlobalDefaultLOD) -, m_ViewableFlag(GLC_3DViewInstance::FullViewable) -, m_ViewableGeomFlag() -{ - // Encode Color Id - glc::encodeRgbId(m_Uid, m_colorId); - - setName(m_3DRep.name()); -} - -GLC_3DViewInstance::GLC_3DViewInstance(const GLC_3DRep& rep) -: GLC_Object(rep.name()) -, m_3DRep(rep) -, m_pBoundingBox(NULL) -, m_AbsoluteMatrix() -, m_IsBoundingBoxValid(false) -, m_RenderProperties() -, m_IsVisible(true) -, m_DefaultLOD(m_GlobalDefaultLOD) -, m_ViewableFlag(GLC_3DViewInstance::FullViewable) -, m_ViewableGeomFlag() -{ - // Encode Color Id - glc::encodeRgbId(m_Uid, m_colorId); - -} - -GLC_3DViewInstance::GLC_3DViewInstance(const GLC_3DRep& rep, GLC_uint id) -: GLC_Object(id, rep.name()) -, m_3DRep(rep) -, m_pBoundingBox(NULL) -, m_AbsoluteMatrix() -, m_IsBoundingBoxValid(false) -, m_RenderProperties() -, m_IsVisible(true) -, m_DefaultLOD(m_GlobalDefaultLOD) -, m_ViewableFlag(GLC_3DViewInstance::FullViewable) -, m_ViewableGeomFlag() -{ - // Encode Color Id - glc::encodeRgbId(m_Uid, m_colorId); - -} - -// Copy constructor -GLC_3DViewInstance::GLC_3DViewInstance(const GLC_3DViewInstance& inputNode) -: GLC_Object(inputNode) -, m_3DRep(inputNode.m_3DRep) -, m_pBoundingBox(NULL) -, m_AbsoluteMatrix(inputNode.m_AbsoluteMatrix) -, m_IsBoundingBoxValid(inputNode.m_IsBoundingBoxValid) -, m_RenderProperties(inputNode.m_RenderProperties) -, m_IsVisible(inputNode.m_IsVisible) -, m_DefaultLOD(inputNode.m_DefaultLOD) -, m_ViewableFlag(inputNode.m_ViewableFlag) -, m_ViewableGeomFlag(inputNode.m_ViewableGeomFlag) -{ - // Encode Color Id - glc::encodeRgbId(m_Uid, m_colorId); - - if (NULL != inputNode.m_pBoundingBox) - { - m_pBoundingBox= new GLC_BoundingBox(*inputNode.m_pBoundingBox); - } -} - - -// Assignement operator -GLC_3DViewInstance& GLC_3DViewInstance::operator=(const GLC_3DViewInstance& inputNode) -{ - if (this != &inputNode) - { - // Clear this instance - clear(); - GLC_Object::operator=(inputNode); - // Encode Color Id - glc::encodeRgbId(m_Uid, m_colorId); - - m_3DRep= inputNode.m_3DRep; - if (NULL != inputNode.m_pBoundingBox) - { - m_pBoundingBox= new GLC_BoundingBox(*inputNode.m_pBoundingBox); - } - m_AbsoluteMatrix= inputNode.m_AbsoluteMatrix; - m_IsBoundingBoxValid= inputNode.m_IsBoundingBoxValid; - m_RenderProperties= inputNode.m_RenderProperties; - m_IsVisible= inputNode.m_IsVisible; - m_DefaultLOD= inputNode.m_DefaultLOD; - m_ViewableFlag= inputNode.m_ViewableFlag; - m_ViewableGeomFlag= inputNode.m_ViewableGeomFlag; - - //qDebug() << "GLC_3DViewInstance::operator= :ID = " << m_Uid; - //qDebug() << "Number of instance" << (*m_pNumberOfInstance); - } - - return *this; -} - -// Destructor -GLC_3DViewInstance::~GLC_3DViewInstance() -{ - clear(); -} - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -// Get the bounding box -GLC_BoundingBox GLC_3DViewInstance::boundingBox(void) -{ - GLC_BoundingBox resultBox; - if (boundingBoxValidity()) - { - resultBox= *m_pBoundingBox; - } - else if (!m_3DRep.isEmpty()) - { - computeBoundingBox(); - m_IsBoundingBoxValid= true; - resultBox= *m_pBoundingBox; - } - - return resultBox; -} - -//! Set the global default LOD value -void GLC_3DViewInstance::setGlobalDefaultLod(int lod) -{ - QMutexLocker locker(&m_Mutex); - m_GlobalDefaultLOD= lod; -} - -void GLC_3DViewInstance::setVboUsage(bool usage) -{ - m_3DRep.setVboUsage(usage); -} - -// Clone the instance -GLC_3DViewInstance GLC_3DViewInstance::deepCopy() const -{ - - GLC_3DRep* pRep= dynamic_cast(m_3DRep.deepCopy()); - Q_ASSERT(NULL != pRep); - GLC_3DRep newRep(*pRep); - delete pRep; - GLC_3DViewInstance cloneInstance(newRep); - - if (NULL != m_pBoundingBox) - { - cloneInstance.m_pBoundingBox= new GLC_BoundingBox(*m_pBoundingBox); - } - - cloneInstance.m_AbsoluteMatrix= m_AbsoluteMatrix; - cloneInstance.m_IsBoundingBoxValid= m_IsBoundingBoxValid; - cloneInstance.m_RenderProperties= m_RenderProperties; - cloneInstance.m_IsVisible= m_IsVisible; - cloneInstance.m_ViewableFlag= m_ViewableFlag; - return cloneInstance; -} - -// Instanciate the instance -GLC_3DViewInstance GLC_3DViewInstance::instanciate() -{ - GLC_3DViewInstance instance(*this); - instance.m_Uid= glc::GLC_GenID(); - // Encode Color Id - glc::encodeRgbId(m_Uid, m_colorId); - - return instance; -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - - -// Set the instance Geometry -bool GLC_3DViewInstance::addGeometry(GLC_Geometry* pGeom) -{ - if (m_3DRep.contains(pGeom)) - { - return false; - } - else - { - m_3DRep.addGeom(pGeom); - return true; - } -} - -// Instance translation -GLC_3DViewInstance& GLC_3DViewInstance::translate(double Tx, double Ty, double Tz) -{ - multMatrix(GLC_Matrix4x4(Tx, Ty, Tz)); - - return *this; -} - - -// Move instance with a 4x4Matrix -GLC_3DViewInstance& GLC_3DViewInstance::multMatrix(const GLC_Matrix4x4 &MultMat) -{ - m_AbsoluteMatrix= MultMat * m_AbsoluteMatrix; - m_IsBoundingBoxValid= false; - - return *this; -} - -// Replace the instance Matrix -GLC_3DViewInstance& GLC_3DViewInstance::setMatrix(const GLC_Matrix4x4 &SetMat) -{ - m_AbsoluteMatrix= SetMat; - m_IsBoundingBoxValid= false; - - return *this; -} - -// Reset the instance Matrix -GLC_3DViewInstance& GLC_3DViewInstance::resetMatrix(void) -{ - m_AbsoluteMatrix.setToIdentity(); - m_IsBoundingBoxValid= false; - - return *this; -} - -////////////////////////////////////////////////////////////////////// -// OpenGL Functions -////////////////////////////////////////////////////////////////////// - -// Display the instance -void GLC_3DViewInstance::render(glc::RenderFlag renderFlag, bool useLod, GLC_Viewport* pView) -{ - //qDebug() << "GLC_3DViewInstance::render render properties= " << m_RenderProperties.renderingMode(); - if (m_3DRep.isEmpty()) return; - const int bodyCount= m_3DRep.numberOfBody(); - - if (bodyCount != m_ViewableGeomFlag.size()) - { - m_ViewableGeomFlag.fill(true, bodyCount); - } - - m_RenderProperties.setRenderingFlag(renderFlag); - - // Save current OpenGL Matrix - GLC_Context::current()->glcPushMatrix(); - OpenglVisProperties(); - - // Change front face orientation if this instance absolute matrix is indirect - if (m_AbsoluteMatrix.type() == GLC_Matrix4x4::Indirect) - { - glFrontFace(GL_CW); - } - if(GLC_State::isInSelectionMode()) - { - glColor3ubv(m_colorId); // D'ont use Alpha component - } - - if (useLod && (NULL != pView)) - { - for (int i= 0; i < bodyCount; ++i) - { - if (m_ViewableGeomFlag.at(i)) - { - const int lodValue= choseLod(m_3DRep.geomAt(i)->boundingBox(), pView, useLod); - if (lodValue <= 100) - { - m_3DRep.geomAt(i)->setCurrentLod(lodValue); - m_RenderProperties.setCurrentBodyIndex(i); - m_3DRep.geomAt(i)->render(m_RenderProperties); - } - } - } - } - else - { - for (int i= 0; i < bodyCount; ++i) - { - if (m_ViewableGeomFlag.at(i)) - { - int lodValue= 0; - if (GLC_State::isPixelCullingActivated() && (NULL != pView)) - { - lodValue= choseLod(m_3DRep.geomAt(i)->boundingBox(), pView, useLod); - } - - if (lodValue <= 100) - { - m_3DRep.geomAt(i)->setCurrentLod(m_DefaultLOD); - m_RenderProperties.setCurrentBodyIndex(i); - m_3DRep.geomAt(i)->render(m_RenderProperties); - } - } - } - } - // Restore OpenGL Matrix - GLC_Context::current()->glcPopMatrix(); - - // Restore front face orientation if this instance absolute matrix is indirect - if (m_AbsoluteMatrix.type() == GLC_Matrix4x4::Indirect) - { - glFrontFace(GL_CCW); - } - -} - -// Display the instance in Body selection mode -void GLC_3DViewInstance::renderForBodySelection() -{ - Q_ASSERT(GLC_State::isInSelectionMode()); - if (m_3DRep.isEmpty()) return; - - // Save previous rendering mode and set the rendering mode to BodySelection - glc::RenderMode previousRenderMode= m_RenderProperties.renderingMode(); - m_RenderProperties.setRenderingMode(glc::BodySelection); - - // Save current OpenGL Matrix - GLC_Context::current()->glcPushMatrix(); - OpenglVisProperties(); - - GLubyte colorId[4]; - const int size= m_3DRep.numberOfBody(); - for (int i= 0; i < size; ++i) - { - GLC_Geometry* pGeom= m_3DRep.geomAt(i); - glc::encodeRgbId(pGeom->id(), colorId); - glColor3ubv(colorId); - pGeom->setCurrentLod(m_DefaultLOD); - m_RenderProperties.setCurrentBodyIndex(i); - pGeom->render(m_RenderProperties); - } - - // Restore rendering mode - m_RenderProperties.setRenderingMode(previousRenderMode); - // Restore OpenGL Matrix - GLC_Context::current()->glcPopMatrix(); -} - -// Display the instance in Primitive selection mode and return the body index -int GLC_3DViewInstance::renderForPrimitiveSelection(GLC_uint bodyId) -{ - Q_ASSERT(GLC_State::isInSelectionMode()); - if (m_3DRep.isEmpty()) return -1; - // Save previous rendering mode and set the rendering mode to BodySelection - glc::RenderMode previousRenderMode= m_RenderProperties.renderingMode(); - m_RenderProperties.setRenderingMode(glc::PrimitiveSelection); - - // Save current OpenGL Matrix - GLC_Context::current()->glcPushMatrix(); - OpenglVisProperties(); - - const int size= m_3DRep.numberOfBody(); - int i= 0; - bool continu= true; - while ((i < size) && continu) - { - GLC_Geometry* pGeom= m_3DRep.geomAt(i); - if (pGeom->id() == bodyId) - { - pGeom->setCurrentLod(0); - pGeom->render(m_RenderProperties); - continu= false; - } - else ++i; - } - - m_RenderProperties.setRenderingMode(previousRenderMode); - - // Restore OpenGL Matrix - GLC_Context::current()->glcPopMatrix(); - - return i; -} - - - -////////////////////////////////////////////////////////////////////// -// private services functions -////////////////////////////////////////////////////////////////////// - - -// compute the instance bounding box -// m_pGeomList should be not null -void GLC_3DViewInstance::computeBoundingBox(void) -{ - if (m_3DRep.isEmpty()) return; - - if (m_pBoundingBox != NULL) - { - delete m_pBoundingBox; - m_pBoundingBox= NULL; - } - m_pBoundingBox= new GLC_BoundingBox(); - const int size= m_3DRep.numberOfBody(); - for (int i= 0; i < size; ++i) - { - m_pBoundingBox->combine(m_3DRep.geomAt(i)->boundingBox()); - } - - m_pBoundingBox->transform(m_AbsoluteMatrix); -} - -// Clear current instance -void GLC_3DViewInstance::clear() -{ - - delete m_pBoundingBox; - m_pBoundingBox= NULL; - - // invalidate the bounding box - m_IsBoundingBoxValid= false; - -} - -// Compute LOD -int GLC_3DViewInstance::choseLod(const GLC_BoundingBox& boundingBox, GLC_Viewport* pView, bool useLod) -{ - if (NULL == pView) return 0; - double pixelCullingRatio= 0.0; - if (useLod) - { - pixelCullingRatio= pView->minimumDynamicPixelCullingRatio(); - } - else - { - pixelCullingRatio= pView->minimumStaticPixelCullingRatio(); - } - - const double diameter= boundingBox.boundingSphereRadius() * 2.0 * m_AbsoluteMatrix.scalingX(); - GLC_Vector3d center(m_AbsoluteMatrix * boundingBox.center()); - - const double dist= (center - pView->cameraHandle()->eye()).length(); - const double cameraCover= dist * pView->viewTangent(); - - double ratio= diameter / cameraCover * 100.0; - if (ratio > 100.0) ratio= 100.0; - ratio= 100.0 - ratio; - - if ((ratio > (100.0 - pixelCullingRatio)) && GLC_State::isPixelCullingActivated()) ratio= 110.0; - else if(useLod && (ratio > 50.0)) - { - ratio= (ratio - 50.0) / 50.0 * 100.0; - if (ratio < static_cast(m_DefaultLOD)) ratio= static_cast(m_DefaultLOD); - } - else - { - ratio= static_cast(m_DefaultLOD); - } - - return static_cast(ratio); -} - - diff --git a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_3dviewinstance.h b/ground/gcs/src/libs/glc_lib/sceneGraph/glc_3dviewinstance.h deleted file mode 100644 index 35582d837..000000000 --- a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_3dviewinstance.h +++ /dev/null @@ -1,432 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_instance.h interface for the GLC_3DViewInstance class. - -#ifndef GLC_3DVIEWINSTANCE_H_ -#define GLC_3DVIEWINSTANCE_H_ - -#include "../glc_global.h" -#include "../glc_boundingbox.h" -#include "../glc_object.h" -#include "../maths/glc_matrix4x4.h" -#include "../glc_state.h" -#include "../geometry/glc_3drep.h" -#include "../shading/glc_renderproperties.h" -#include "../glc_context.h" - -#include - -#include "../glc_config.h" - -class GLC_Viewport; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_3DViewInstance -/*! \brief GLC_3DViewInstance : GLC_3DRep + bounding box*/ - -/*! An GLC_3DViewInstance contain : - * - GLC_3DRep - * - Geometry Bounding box in position - * - Positionning 4 x 4 matrix - */ -////////////////////////////////////////////////////////////////////// - -class GLC_LIB_EXPORT GLC_3DViewInstance : public GLC_Object -{ -public: - //! Viewable instance property - enum Viewable - { - FullViewable= 120, - PartialViewable= 121, - NoViewable= 122 - }; -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Default constructor - GLC_3DViewInstance(); - - //! Contruct instance from a geometry - GLC_3DViewInstance(GLC_Geometry* pGeom); - - //! Contruct instance from a geometry and the given UID - GLC_3DViewInstance(GLC_Geometry* pGeom, GLC_uint id); - - //! Contruct instance from a 3DRep - GLC_3DViewInstance(const GLC_3DRep&); - - //! Contruct instance from a 3DRep and the given UID - GLC_3DViewInstance(const GLC_3DRep& rep, GLC_uint id); - - //! Copy constructor - GLC_3DViewInstance(const GLC_3DViewInstance& ); - - //! Assignement operator - GLC_3DViewInstance &operator=(const GLC_3DViewInstance&); - - //! Destructor - ~GLC_3DViewInstance(); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return true if the all instance's mesh are transparent - inline bool isTransparent() const; - - //! Return true if the instance contains mesh which contains transparent material - inline bool hasTransparentMaterials() const; - - //! Return true if the instance as no geometry - inline bool isEmpty() const - {return m_3DRep.isEmpty();} - - //! Return true if the instance is selected - inline bool isSelected(void) const - {return m_RenderProperties.isSelected();} - - //! Return the number of geometry - inline int numberOfGeometry() const - {return m_3DRep.numberOfBody();} - - - //! Return the geometry at the specified position - inline GLC_Geometry* geomAt(int index) const - { - if (!m_3DRep.isEmpty()) return m_3DRep.geomAt(index); - else return NULL; - } - - //! Get the bounding box - GLC_BoundingBox boundingBox(); - - //! Get the validity of the Bounding Box - inline bool boundingBoxValidity() const - {return (m_pBoundingBox != NULL) && m_IsBoundingBoxValid && m_3DRep.boundingBoxIsValid();} - - //! Return transfomation 4x4Matrix - inline const GLC_Matrix4x4& matrix() const - {return m_AbsoluteMatrix;} - - //! Make a deep copy of the instance - GLC_3DViewInstance deepCopy() const; - - //! Instanciate the instance - GLC_3DViewInstance instanciate(); - - //! Get the Polygon mode off the instance - /*! Polygon Mode can Be : GL_POINT, GL_LINE, or GL_FILL*/ - inline GLenum polygonMode() const - {return m_RenderProperties.polygonMode();} - - //! Return an handle to the renderProperties - inline GLC_RenderProperties* renderPropertiesHandle() - {return &m_RenderProperties;} - - //! Get the visibility state of instance - inline bool isVisible() const - {return m_IsVisible;} - - //! Return true if the instance is viewable - inline GLC_3DViewInstance::Viewable viewableFlag() const - {return m_ViewableFlag;} - - //! Return true if the geom at the index is viewable - inline bool isGeomViewable(int index) const - {return m_ViewableGeomFlag.at(index);} - - //! Get number of faces - inline unsigned int numberOfFaces() const - {return m_3DRep.faceCount();} - - //! Get number of vertex - inline unsigned int numberOfVertex() const - {return m_3DRep.vertexCount();} - - //! Get number of materials - inline unsigned int numberOfMaterials() const - {return m_3DRep.materialCount();} - - //! Get materials List - inline QSet materialSet() const - {return m_3DRep.materialSet();} - - //! Return the default LOD Value - inline int defaultLodValue() const - {return m_DefaultLOD;} - - //! Return the instance representation - inline GLC_3DRep representation() const - {return m_3DRep;} - - //! Return the number of body contains in the 3DRep - inline int numberOfBody() const - {return m_3DRep.numberOfBody();} - - //! Return the global default LOD value - inline static int globalDefaultLod() - { - return m_GlobalDefaultLOD; - } - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Set the instance Geometry - bool addGeometry(GLC_Geometry* pGeom); - - //! Remove empty geometries - inline void removeEmptyGeometry() - {m_3DRep.clean();} - - //! Reverse geometry normals - inline void reverseGeometriesNormals() - {m_3DRep.reverseNormals();} - - //! Translate Instance - GLC_3DViewInstance& translate(double Tx, double Ty, double Tz); - - //! Translate Instance - inline GLC_3DViewInstance& translate(const GLC_Vector3d& v) - { - return translate(v.x(), v.y(), v.z()); - } - - //! Move instance with a 4x4Matrix - GLC_3DViewInstance& multMatrix(const GLC_Matrix4x4 &MultMat); - - //! Replace the instance Matrix - GLC_3DViewInstance& setMatrix(const GLC_Matrix4x4 &SetMat); - - //! Reset the instance Matrix - GLC_3DViewInstance& resetMatrix(void); - - //! Polygon's display style - /*! Face Polygon Mode can be : GL_FRONT_AND_BACK, GL_FRONT, or GL_BACK - * mode can be : GL_POINT, GL_LINE, or GL_FILL */ - inline void setPolygonMode(GLenum Face, GLenum Mode) - {m_RenderProperties.setPolygonMode(Face, Mode);} - - //! Select the instance - inline void select(bool primitive) - {m_RenderProperties.select(primitive);} - - //! Unselect the instance - inline void unselect(void) - {m_RenderProperties.unselect();} - - //! Set instance visibility - inline void setVisibility(bool visibility) - {m_IsVisible= visibility;} - - //! Set Instance Id - inline void setId(const GLC_uint id) - { - GLC_Object::setId(id); - glc::encodeRgbId(m_Uid, m_colorId); - } - - //! Set the default LOD value - inline void setDefaultLodValue(int lod) - { - m_DefaultLOD= lod; - } - - //! Set the viewable flag - inline bool setViewable(GLC_3DViewInstance::Viewable flag); - - //! Set the viewable flag of a geometry - inline void setGeomViewable(int index, bool flag) - {m_ViewableGeomFlag[index]= flag;} - - - //! Set the global default LOD value - static void setGlobalDefaultLod(int); - - //! Set the renderProperties of this 3DView instance - inline void setRenderProperties(const GLC_RenderProperties& renderProperties) - {m_RenderProperties= renderProperties;} - - //! Set VBO usage - void setVboUsage(bool usage); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Display the instance - void render(glc::RenderFlag renderFlag= glc::ShadingFlag, bool useLoad= false, GLC_Viewport* pView= NULL); - - //! Display the instance in Body selection mode - void renderForBodySelection(); - - //! Display the instance in Primitive selection mode of the specified body id and return the body index - int renderForPrimitiveSelection(GLC_uint); - - -private: - //! Set instance visualisation properties - inline void OpenglVisProperties() - { - // Polygons display mode - glPolygonMode(m_RenderProperties.polyFaceMode(), m_RenderProperties.polygonMode()); - // Change the current matrix - GLC_Context::current()->glcMultMatrix(m_AbsoluteMatrix); - } - - -//@} - -////////////////////////////////////////////////////////////////////// -// private services functions -////////////////////////////////////////////////////////////////////// -private: - //! compute the instance bounding box - void computeBoundingBox(void); - - //! Clear current instance - void clear(); - - //! Compute LOD - int choseLod(const GLC_BoundingBox&, GLC_Viewport*, bool); - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - - //! The 3D rep of the instance - GLC_3DRep m_3DRep; - - //! BoundingBox of the instance - GLC_BoundingBox* m_pBoundingBox; - - //! Geometry matrix - GLC_Matrix4x4 m_AbsoluteMatrix; - - //! Bounding box validity - bool m_IsBoundingBoxValid; - - //! The 3DViewInstance rendering properties - GLC_RenderProperties m_RenderProperties; - - //! Visibility - bool m_IsVisible; - - //! The instance color ID - GLubyte m_colorId[4]; - - //! The Default LOD - int m_DefaultLOD; - - //! Flag to know if the instance is viewable - Viewable m_ViewableFlag; - - //! vector of Flag to know if geometies of this instance are viewable - QVector m_ViewableGeomFlag; - - //! A Mutex - static QMutex m_Mutex; - - //! The global default LOD - static int m_GlobalDefaultLOD; - - -}; - -// Return true if the all instance's mesh are transparent -bool GLC_3DViewInstance::isTransparent() const -{ - if (m_3DRep.isEmpty()) return false; - if (m_RenderProperties.renderingMode() == glc::OverwriteTransparency) return true; - if (m_RenderProperties.renderingMode() == glc::OverwriteMaterial) - { - return m_RenderProperties.overwriteMaterial()->isTransparent(); - } - const int size= m_3DRep.numberOfBody(); - bool result= true; - int i= 0; - while((i < size) && result) - { - result= result && m_3DRep.geomAt(i)->isTransparent(); - ++i; - } - return result && m_RenderProperties.needToRenderWithTransparency(); -} - -// Return true if the instance contains mesh which contains transparent material -bool GLC_3DViewInstance::hasTransparentMaterials() const -{ - if (m_3DRep.isEmpty()) return false; - if (m_RenderProperties.needToRenderWithTransparency()) return true; - const int size= m_3DRep.numberOfBody(); - bool result= false; - int i= 0; - while ((i < size) && !result) - { - result= result || m_3DRep.geomAt(i)->hasTransparentMaterials(); - ++i; - } - return result; -} -//! Set the viewable flag -bool GLC_3DViewInstance::setViewable(GLC_3DViewInstance::Viewable flag) -{ - const int bodyCount= m_3DRep.numberOfBody(); - if (bodyCount != m_ViewableGeomFlag.size()) - { - m_ViewableGeomFlag.fill(true, bodyCount); - } - bool asChange= m_ViewableFlag != flag; - if (asChange) - { - m_ViewableFlag= flag; - if (flag != GLC_3DViewInstance::PartialViewable) - { - bool viewable= (flag == GLC_3DViewInstance::FullViewable); - - for (int i= 0; i < bodyCount; ++i) - { - m_ViewableGeomFlag[i]= viewable; - } - } - } - return asChange; -} - - -#endif /*GLC_3DVIEWINSTANCE_H_*/ diff --git a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_attributes.cpp b/ground/gcs/src/libs/glc_lib/sceneGraph/glc_attributes.cpp deleted file mode 100644 index 9ff4280cc..000000000 --- a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_attributes.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_attributes.cpp implementation of the GLC_Attributes class. - -#include "glc_attributes.h" - -// Default constructor -GLC_Attributes::GLC_Attributes() -: m_AttributesHash() -, m_AttributesList() -{ - -} - -// Copy Constructor -GLC_Attributes::GLC_Attributes(const GLC_Attributes& attr) -: m_AttributesHash(attr.m_AttributesHash) -, m_AttributesList(attr.m_AttributesList) -{ - -} - -// Overload "=" operator -GLC_Attributes& GLC_Attributes::operator=(const GLC_Attributes& attr) -{ - if (this != &attr) - { - m_AttributesHash= attr.m_AttributesHash; - m_AttributesList= attr.m_AttributesList; - } - return *this; -} - -// Destructor -GLC_Attributes::~GLC_Attributes() -{ - -} diff --git a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_attributes.h b/ground/gcs/src/libs/glc_lib/sceneGraph/glc_attributes.h deleted file mode 100644 index 29f3ce56d..000000000 --- a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_attributes.h +++ /dev/null @@ -1,144 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_attributes.h interface for the GLC_Attributes class. - -#ifndef GLC_ATTRIBUTES_H_ -#define GLC_ATTRIBUTES_H_ - -#include -#include -#include - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Attributes -/*! \brief GLC_Attributes : User attributes of instance and reference */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_Attributes -{ - -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Default Constructor - GLC_Attributes(); - - //! Copy Constructor - GLC_Attributes(const GLC_Attributes&); - - //! Overload "=" operator - GLC_Attributes& operator=(const GLC_Attributes&); - - //! Destructor - virtual ~GLC_Attributes(); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return true if attributes is empty - inline bool isEmpty() const - {return m_AttributesHash.isEmpty();} - - //! Return the size of attributes - inline int size() const - {return m_AttributesHash.size();} - - //! Return true if the specified attribute exist - bool contains(const QString& name) const - {return m_AttributesHash.contains(name);} - - //! Return the list of attribute name - inline QList names() const - {return m_AttributesList;} - - //! Return the value of the specified attributes - /*! Return NULL String if attribute doesn't exist*/ - inline QString value(const QString& name) const - {return m_AttributesHash.value(name);} - - //! Return the name of the specified attributes index - /*! Return empty String if attribute doesn't exist*/ - inline QString name(int at) const - {return m_AttributesList.value(at);} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Insert an attribute (if the attribute exists, it's updated) - inline void insert(const QString& name, const QString& value) - { - if ((!m_AttributesHash.contains(name))) m_AttributesList.append(name); - m_AttributesHash.insert(name, value); - } - - //! Remove an attribute - inline void remove(const QString& name) - { - Q_ASSERT(m_AttributesHash.contains(name)); - m_AttributesHash.remove(name); - m_AttributesList.removeOne(name); - } - - //! Clear the content of this attribute - inline void clear() - { - m_AttributesHash.clear(); - m_AttributesList.clear(); - } - -//@} - -////////////////////////////////////////////////////////////////////// -/*! @name Operator Overload */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Equal operator overload - inline bool operator==(const GLC_Attributes& attr) const - {return m_AttributesHash == attr.m_AttributesHash;} - -//@} -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - //! Attributes Hash table - QHash m_AttributesHash; - - //! the list of attribute name - QList m_AttributesList; - -}; - -#endif /* GLC_ATTRIBUTES_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_octree.cpp b/ground/gcs/src/libs/glc_lib/sceneGraph/glc_octree.cpp deleted file mode 100644 index 9e38cea12..000000000 --- a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_octree.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_octree.cpp implementation for the GLC_Octree class. - -#include "glc_octree.h" -#include "glc_octreenode.h" -#include "glc_3dviewcollection.h" -#include "../glc_factory.h" - -int GLC_Octree::m_DefaultOctreeDepth= 3; - -GLC_Octree::GLC_Octree(GLC_3DViewCollection* pCollection) -: GLC_SpacePartitioning(pCollection) -, m_pRootNode(NULL) -, m_OctreeDepth(m_DefaultOctreeDepth) -{ - - -} - -GLC_Octree::GLC_Octree(const GLC_Octree& octree) -: GLC_SpacePartitioning(octree) -, m_pRootNode(NULL) -, m_OctreeDepth(octree.m_OctreeDepth) -{ - if (NULL != octree.m_pRootNode) - { - m_pRootNode= new GLC_OctreeNode(*(octree.m_pRootNode)); - } -} - -GLC_Octree::~GLC_Octree() -{ - delete m_pRootNode; -} - -int GLC_Octree::defaultDepth() -{ - return m_DefaultOctreeDepth; -} - -QList GLC_Octree::listOfIntersectedInstances(const GLC_BoundingBox& bBox) -{ - if (NULL == m_pRootNode) - { - updateSpacePartitioning(); - } - return m_pRootNode->setOfIntersectedInstances(bBox).toList(); -} - -void GLC_Octree::updateViewableInstances(const GLC_Frustum& frustum) -{ - if (NULL == m_pRootNode) - { - updateSpacePartitioning(); - } - m_pRootNode->updateViewableInstances(frustum); -} - -void GLC_Octree::updateSpacePartitioning() -{ - delete m_pRootNode; - m_pRootNode= new GLC_OctreeNode(m_pCollection->boundingBox(true)); - // fill the octree - QList instanceList(m_pCollection->instancesHandle()); - const int size= instanceList.size(); - for (int i= 0; i < size; ++i) - { - m_pRootNode->addInstance(instanceList.at(i), m_OctreeDepth); - } - m_pRootNode->removeEmptyChildren(); -} - -void GLC_Octree::clear() -{ - delete m_pRootNode; - m_pRootNode= NULL; -} - -void GLC_Octree::setDepth(int depth) -{ - m_OctreeDepth= depth; - if (NULL != m_pRootNode) - { - updateSpacePartitioning(); - } -} - -void GLC_Octree::createBox(GLC_Material* pMat, GLC_3DViewCollection* pCol) -{ - if (NULL == m_pRootNode) - { - updateSpacePartitioning(); - } - - if (NULL == pCol) pCol= m_pCollection; - if (!m_pRootNode->isEmpty()) - { - createBoxWithMaterial(pCol, m_pRootNode, pMat); - } -} - -void GLC_Octree::setDefaultDepth(int depth) -{ - m_DefaultOctreeDepth= depth; -} - -void GLC_Octree::createBoxWithMaterial(GLC_3DViewCollection* pCol, GLC_OctreeNode* pNode, GLC_Material* pMat) -{ - if (!pNode->isEmpty()) - { - if (pNode->hasGeometry()) - { - GLC_3DViewInstance box= GLC_Factory::instance()->createBox(pNode->boundingBox()); - box.geomAt(0)->replaceMasterMaterial(pMat); - pCol->add(box); - } - - if (pNode->hasChild()) - { - const int size= pNode->childCount(); - for (int i= 0; i < size; ++i) - { - createBoxWithMaterial(pCol, pNode->childAt(i), pMat); - } - } - - } - -} - diff --git a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_octree.h b/ground/gcs/src/libs/glc_lib/sceneGraph/glc_octree.h deleted file mode 100644 index d44de1190..000000000 --- a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_octree.h +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_octree.h interface for the GLC_Octree class. - -#ifndef GLC_OCTREE_H_ -#define GLC_OCTREE_H_ - -#include "glc_spacepartitioning.h" -#include "../glc_config.h" - -class GLC_OctreeNode; -class GLC_Material; -class GLC_3DViewInstance; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Octree -/*! \brief GLC_Octree : represent space partioning implementation with octree */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_Octree : public GLC_SpacePartitioning -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Create an empty octree of the given 3D view collection - GLC_Octree(GLC_3DViewCollection*); - - //! Create the octree from the given octree - GLC_Octree(const GLC_Octree&); - - //! Destructor - virtual ~GLC_Octree(); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the default octree Depth - static int defaultDepth(); - - //! Return the list off instances inside or intersect the given bounding box - virtual QList listOfIntersectedInstances(const GLC_BoundingBox& bBox); - -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Update the viewable 3d view instance of this octree from the given frustum - virtual void updateViewableInstances(const GLC_Frustum&); - - //! Update this octree space partionning - virtual void updateSpacePartitioning(); - - //! Clear the space partionning - virtual void clear(); - - //! Set this octree depth - /*! If space partitionning is already done, update it*/ - void setDepth(int); - - //! Create octree box representation in the given collection with the specified material - void createBox(GLC_Material*, GLC_3DViewCollection* pCol= NULL); - - //! Set the default octree depth - static void setDefaultDepth(int depth); - -//@} - -////////////////////////////////////////////////////////////////////// -// Private services function -////////////////////////////////////////////////////////////////////// -private: - - //! Create octree box representation in the given 3d view collection - /*! Create box of the given Octree node with the given material*/ - void createBoxWithMaterial(GLC_3DViewCollection*, GLC_OctreeNode*, GLC_Material*); - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - //! Octree root node - GLC_OctreeNode* m_pRootNode; - - //! Octree depth - int m_OctreeDepth; - - //! The default octree Depth - static int m_DefaultOctreeDepth; -}; - -#endif /* GLC_OCTREE_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_octreenode.cpp b/ground/gcs/src/libs/glc_lib/sceneGraph/glc_octreenode.cpp deleted file mode 100644 index ec76e1262..000000000 --- a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_octreenode.cpp +++ /dev/null @@ -1,375 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_octreenode.cpp implementation for the GLC_OctreeNode class. - -#include "glc_octreenode.h" - -bool GLC_OctreeNode::m_useBoundingSphere= true; - -GLC_OctreeNode::GLC_OctreeNode(const GLC_BoundingBox& boundingBox, GLC_OctreeNode* pParent) -: m_BoundingBox(boundingBox) -, m_pParent(pParent) -, m_Children() -, m_3DViewInstanceSet() -, m_Empty(true) -{ - - -} - -GLC_OctreeNode::GLC_OctreeNode(const GLC_OctreeNode& octreeNode, GLC_OctreeNode* pParent) -: m_BoundingBox(octreeNode.m_BoundingBox) -, m_pParent(pParent) -, m_Children() -, m_3DViewInstanceSet(octreeNode.m_3DViewInstanceSet) -, m_Empty(octreeNode.m_Empty) -{ - if (!octreeNode.m_Children.isEmpty()) - { - const int size= octreeNode.m_Children.size(); - for (int i= 0; i < size; ++i) - { - m_Children.append(new GLC_OctreeNode(*(octreeNode.m_Children.at(i)), this)); - } - } -} - -GLC_OctreeNode::~GLC_OctreeNode() -{ - const int size= m_Children.size(); - for (int i= 0; i < size; ++i) - { - delete m_Children.at(i); - } -} - -bool GLC_OctreeNode::intersectionWithBoundingSphereUsed() -{ - return m_useBoundingSphere; -} - -QSet GLC_OctreeNode::setOfIntersectedInstances(const GLC_BoundingBox& bBox) -{ - QSet instanceSet; - if (intersect(bBox)) - { - QSet::iterator iInstance= m_3DViewInstanceSet.begin(); - while (m_3DViewInstanceSet.constEnd() != iInstance) - { - if ((*iInstance)->boundingBox().intersect(bBox)) - { - instanceSet << *(iInstance); - } - ++iInstance; - } - const int childCount= m_Children.size(); - for (int i= 0; i < childCount; ++i) - { - instanceSet.unite(m_Children[i]->setOfIntersectedInstances(bBox)); - } - } - - return instanceSet; -} -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -void GLC_OctreeNode::addChildren() -{ - Q_ASSERT(m_Children.isEmpty()); - Q_ASSERT(!m_BoundingBox.isEmpty()); - - const double xLower= m_BoundingBox.lowerCorner().x(); - const double yLower= m_BoundingBox.lowerCorner().y(); - const double zLower= m_BoundingBox.lowerCorner().z(); - - const double xUpper= m_BoundingBox.upperCorner().x(); - const double dX= (xUpper - xLower) / 2.0; - const double yUpper= m_BoundingBox.upperCorner().y(); - const double dY= (yUpper - yLower) / 2.0; - const double zUpper= m_BoundingBox.upperCorner().z(); - const double dZ= (zUpper - zLower) / 2.0; - - - // Add 8 Children - GLC_Point3d lower; - GLC_Point3d upper; - GLC_OctreeNode* pOctreeNode= NULL; - - { // Child 1 - lower.setVect(xLower, yLower, zLower); - upper.setVect(xLower + dX, yLower + dY, zLower + dZ); - GLC_BoundingBox box(lower, upper); - pOctreeNode= new GLC_OctreeNode(box, this); - m_Children.append(pOctreeNode); - } - { // Child 2 - lower.setVect(xLower + dX, yLower, zLower); - upper.setVect(xUpper, yLower + dY, zLower + dZ); - GLC_BoundingBox box(lower, upper); - pOctreeNode= new GLC_OctreeNode(box, this); - m_Children.append(pOctreeNode); - } - { // Child 3 - lower.setVect(xLower + dX, yLower + dY, zLower); - upper.setVect(xUpper, yUpper, zLower + dZ); - GLC_BoundingBox box(lower, upper); - pOctreeNode= new GLC_OctreeNode(box, this); - m_Children.append(pOctreeNode); - } - { // Child 4 - lower.setVect(xLower, yLower + dY, zLower); - upper.setVect(xLower + dX, yUpper, zLower + dZ); - GLC_BoundingBox box(lower, upper); - pOctreeNode= new GLC_OctreeNode(box, this); - m_Children.append(pOctreeNode); - } - { // Child 5 - lower.setVect(xLower, yLower, zLower + dZ); - upper.setVect(xLower + dX, yLower + dY, zUpper); - GLC_BoundingBox box(lower, upper); - pOctreeNode= new GLC_OctreeNode(box, this); - m_Children.append(pOctreeNode); - } - { // Child 6 - lower.setVect(xLower + dX, yLower, zLower + dZ); - upper.setVect(xUpper, yLower + dY, zUpper); - GLC_BoundingBox box(lower, upper); - pOctreeNode= new GLC_OctreeNode(box, this); - m_Children.append(pOctreeNode); - } - { // Child 7 - lower.setVect(xLower + dX, yLower + dY, zLower + dZ); - upper.setVect(xUpper, yUpper, zUpper); - GLC_BoundingBox box(lower, upper); - pOctreeNode= new GLC_OctreeNode(box, this); - m_Children.append(pOctreeNode); - } - { // Child 8 - lower.setVect(xLower, yLower + dY, zLower + dZ); - upper.setVect(xLower + dX, yUpper, zUpper); - GLC_BoundingBox box(lower, upper); - pOctreeNode= new GLC_OctreeNode(box, this); - m_Children.append(pOctreeNode); - } -} - - -void GLC_OctreeNode::addInstance(GLC_3DViewInstance* pInstance, int depth) -{ - m_Empty= false; - const GLC_BoundingBox instanceBox= pInstance->boundingBox(); - // Check if the instance's bounding box intersect this node bounding box - if (!instanceBox.isEmpty() && intersect(instanceBox)) - { - if (0 == depth) - { - m_3DViewInstanceSet.insert(pInstance); - } - else - { - if (m_Children.isEmpty()) - { - // Create children - addChildren(); - } - QVector childIntersect(8); - bool allIntersect= true; - bool currentIntersect= false; - for (int i= 0; i < 8; ++i) - { - currentIntersect= m_Children.at(i)->intersect(instanceBox); - allIntersect= allIntersect && currentIntersect; - childIntersect[i]= currentIntersect; - } - if (allIntersect) - { - m_3DViewInstanceSet.insert(pInstance); - } - else - { - for (int i= 0; i < 8; ++i) - { - if (childIntersect[i]) - { - m_Children[i]->addInstance(pInstance, depth - 1); - } - } - } - } - - } -} - - -void GLC_OctreeNode::updateViewableInstances(const GLC_Frustum& frustum, QSet* pInstanceSet) -{ - - bool firstCall= false; - // Create the set of viewable instance if necessary - if (NULL == pInstanceSet) - { - pInstanceSet= new QSet(); - firstCall= true; - } - - // Test the localisation of current octree node - GLC_Frustum::Localisation nodeLocalisation= frustum.localizeBoundingBox(m_BoundingBox); - if (nodeLocalisation == GLC_Frustum::OutFrustum) - { - disableViewFlag(pInstanceSet); - } - else if (nodeLocalisation == GLC_Frustum::InFrustum) - { - unableViewFlag(pInstanceSet); - } - else // The current node intersect the frustum - { - QSet::iterator iInstance= m_3DViewInstanceSet.begin(); - while (m_3DViewInstanceSet.constEnd() != iInstance) - { - // Test if the instances is in the viewable set - if (!pInstanceSet->contains(*iInstance)) - { - GLC_3DViewInstance* pCurrentInstance= (*iInstance); - // Test the localisation of the current instance - GLC_Frustum::Localisation instanceLocalisation= frustum.localizeBoundingBox(pCurrentInstance->boundingBox()); - - if (instanceLocalisation == GLC_Frustum::OutFrustum) - { - pCurrentInstance->setViewable(GLC_3DViewInstance::NoViewable); - } - else if (instanceLocalisation == GLC_Frustum::InFrustum) - { - pInstanceSet->insert(pCurrentInstance); - pCurrentInstance->setViewable(GLC_3DViewInstance::FullViewable); - } - else - { - pInstanceSet->insert(pCurrentInstance); - pCurrentInstance->setViewable(GLC_3DViewInstance::PartialViewable); - //Update the geometries viewable property of the instance - GLC_Matrix4x4 instanceMat= pCurrentInstance->matrix(); - const int size= pCurrentInstance->numberOfBody(); - for (int i= 0; i < size; ++i) - { - // Get the geometry bounding box - GLC_BoundingBox geomBox= pCurrentInstance->geomAt(i)->boundingBox(); - GLC_Point3d center(instanceMat * geomBox.center()); - double radius= geomBox.boundingSphereRadius() * instanceMat.scalingX(); - GLC_Frustum::Localisation geomLocalisation= frustum.localizeSphere(center, radius); - - pCurrentInstance->setGeomViewable(i, geomLocalisation != GLC_Frustum::OutFrustum); - } - } - } - - ++iInstance; - } - const int size= m_Children.size(); - for (int i= 0; i < size; ++i) - { - m_Children.at(i)->updateViewableInstances(frustum, pInstanceSet); - } - } - if (firstCall) delete pInstanceSet; -} - - -void GLC_OctreeNode::removeEmptyChildren() -{ - NodeList::iterator iList= m_Children.begin(); - while(m_Children.constEnd() != iList) - { - GLC_OctreeNode* pCurrentChild= *iList; - if (pCurrentChild->isEmpty()) - { - delete pCurrentChild; - iList= m_Children.erase(iList); - } - else - { - pCurrentChild->removeEmptyChildren(); - if (pCurrentChild->isEmpty()) - { - delete pCurrentChild; - iList= m_Children.erase(iList); - } - else ++iList; - } - } - // Update empty flag - if (m_Children.isEmpty() && (NULL != m_pParent)) - { - if (1 == m_3DViewInstanceSet.size()) - { - m_pParent->m_3DViewInstanceSet.insert(*(m_3DViewInstanceSet.begin())); - m_3DViewInstanceSet.clear(); - } - m_Empty= m_3DViewInstanceSet.isEmpty(); - } -} - -void GLC_OctreeNode::useBoundingSphereIntersection(bool use) -{ - m_useBoundingSphere= use; -} - -void GLC_OctreeNode::unableViewFlag(QSet* pInstanceSet) -{ - QSet::iterator iInstance= m_3DViewInstanceSet.begin(); - while (m_3DViewInstanceSet.constEnd() != iInstance) - { - if (!pInstanceSet->contains(*iInstance)) - { - (*iInstance)->setViewable(GLC_3DViewInstance::FullViewable); - pInstanceSet->insert(*iInstance); - } - - ++iInstance; - } - const int size= m_Children.size(); - for (int i= 0; i < size; ++i) - { - m_Children.at(i)->unableViewFlag(pInstanceSet); - } -} - - -void GLC_OctreeNode::disableViewFlag(QSet* pInstanceSet) -{ - QSet::iterator iInstance= m_3DViewInstanceSet.begin(); - while (m_3DViewInstanceSet.constEnd() != iInstance) - { - if (!pInstanceSet->contains(*iInstance)) - (*iInstance)->setViewable(GLC_3DViewInstance::NoViewable); - - ++iInstance; - } - const int size= m_Children.size(); - for (int i= 0; i < size; ++i) - { - m_Children.at(i)->disableViewFlag(pInstanceSet); - } -} - diff --git a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_octreenode.h b/ground/gcs/src/libs/glc_lib/sceneGraph/glc_octreenode.h deleted file mode 100644 index ac9627d59..000000000 --- a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_octreenode.h +++ /dev/null @@ -1,170 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_octreenode.h interface for the GLC_OctreeNode class. - - -#ifndef GLC_OCTREENODE_H_ -#define GLC_OCTREENODE_H_ - -#include "glc_3dviewinstance.h" -#include "../glc_boundingbox.h" -#include "../glc_config.h" -#include "../viewport/glc_frustum.h" -#include -#include - -class GLC_LIB_EXPORT GLC_OctreeNode; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_OctreeNode -/*! \brief GLC_OctreeNode : A node of Space partioning implemented with octree */ -////////////////////////////////////////////////////////////////////// -class GLC_OctreeNode -{ - typedef QList NodeList; -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Construct a octree node from the given bounding box within the given octree node - GLC_OctreeNode(const GLC_BoundingBox&, GLC_OctreeNode* pParent= NULL); - - //! Construct a octree node from the first given octree node within the second given octree node - GLC_OctreeNode(const GLC_OctreeNode&, GLC_OctreeNode* pParent= NULL); - - //! Destructor - virtual ~GLC_OctreeNode(); -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - // Return this octree node bounding box - inline GLC_BoundingBox& boundingBox() - {return m_BoundingBox;} - - //! Return True if this octree node intersect the bounding box - inline bool intersect(const GLC_BoundingBox& boundingBox); - - //! Return true if this octree has child octree node - inline bool hasChild() const - {return !m_Children.isEmpty();} - - //! Return the child octree node at the given index - /*! The child must exist*/ - inline GLC_OctreeNode* childAt(int i) const - { - Q_ASSERT(i < m_Children.size()); - return m_Children.at(i); - } - - //! Return this octree node child octree node count - inline int childCount() const - {return m_Children.size();} - - //! Return true if this node contains 3D view instances - inline bool hasGeometry() const - {return !m_3DViewInstanceSet.isEmpty();} - - //! Return true if this octree node is empty - /*! An empty node doesn't contains child and 3d view instance*/ - inline bool isEmpty() const - {return m_Empty;} - - //! Return true if intersection are calculated with bounded sphere - static bool intersectionWithBoundingSphereUsed(); - - //! Return the list off instances inside or intersect the given bounding box - QSet setOfIntersectedInstances(const GLC_BoundingBox& bBox); - - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Add 8 octree node children to this octree node - void addChildren(); - - //! Add 3d view instance in this octree node branch - void addInstance(GLC_3DViewInstance*, int); - - //! Update 3d view instances visibility of this octree node branch from the given frustum - /*! Viewable 3d view instance are inserted the the given set if exist also the set is created*/ - void updateViewableInstances(const GLC_Frustum&, QSet* pInstanceSet= NULL); - - //! Remove empty child octree node from this octree node - void removeEmptyChildren(); - - //! Set intersection to bounding sphere - static void useBoundingSphereIntersection(bool); -//@} - -////////////////////////////////////////////////////////////////////// -// Private services function -////////////////////////////////////////////////////////////////////// -private: - //! Unable the node and sub node view flag - void unableViewFlag(QSet*); - - //! Disable the node and sub node view flag - void disableViewFlag(QSet*); - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - //! Octree node bounding box - GLC_BoundingBox m_BoundingBox; - - //! Parent Octree node - GLC_OctreeNode* m_pParent; - - //! Children list of octree node - NodeList m_Children; - - //! This node set of 3DViewInstance - QSet m_3DViewInstanceSet; - - //! Flag to know if the node is empty - bool m_Empty; - - //! Flag to know if intersection is calculated with bounding sphere - static bool m_useBoundingSphere; - -}; - -bool GLC_OctreeNode::intersect(const GLC_BoundingBox& boundingBox) -{ - if (m_useBoundingSphere) - return m_BoundingBox.intersectBoundingSphere(boundingBox); - else - return m_BoundingBox.intersect(boundingBox); -} - -#endif /* GLC_OCTREENODE_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_selectionset.cpp b/ground/gcs/src/libs/glc_lib/sceneGraph/glc_selectionset.cpp deleted file mode 100644 index 3531e5209..000000000 --- a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_selectionset.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_selectionset.cpp implementation for the GLC_SelectionSet class. - -#include "glc_selectionset.h" -#include "glc_worldhandle.h" - -GLC_SelectionSet::GLC_SelectionSet(GLC_WorldHandle* pWorldHandle) -: m_pWorldHandle(pWorldHandle) -, m_OccurenceHash() -{ - Q_ASSERT(0 == m_pWorldHandle->collection()->selectionSize()); - -} - -GLC_SelectionSet::~GLC_SelectionSet() -{ - -} - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -bool GLC_SelectionSet::isEmpty() const -{ - return m_OccurenceHash.isEmpty(); -} - - -int GLC_SelectionSet::count() const -{ - return m_OccurenceHash.size(); -} - -QList GLC_SelectionSet::occurencesList() const -{ - return m_OccurenceHash.values(); -} - - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// -bool GLC_SelectionSet::insert(GLC_StructOccurence* pOccurence) -{ - return insert(pOccurence->id()); -} - -bool GLC_SelectionSet::insert(GLC_uint occurenceId) -{ - Q_ASSERT(m_pWorldHandle->containsOccurence(occurenceId)); - if (!m_OccurenceHash.contains(occurenceId)) - { - GLC_StructOccurence* pOccurence= m_pWorldHandle->getOccurence(occurenceId); - m_OccurenceHash.insert(occurenceId, pOccurence); - return true; - } - else return false; -} - -bool GLC_SelectionSet::remove(GLC_StructOccurence* pOccurence) -{ - return remove(pOccurence->id()); -} - -bool GLC_SelectionSet::remove(GLC_uint occurenceId) -{ - Q_ASSERT(m_pWorldHandle->containsOccurence(occurenceId)); - if (m_OccurenceHash.contains(occurenceId)) - { - m_OccurenceHash.remove(occurenceId); - return true; - } - else return false; -} - -void GLC_SelectionSet::clear() -{ - m_OccurenceHash.clear(); -} diff --git a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_selectionset.h b/ground/gcs/src/libs/glc_lib/sceneGraph/glc_selectionset.h deleted file mode 100644 index e839b430f..000000000 --- a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_selectionset.h +++ /dev/null @@ -1,122 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_selectionset.h interface for the GLC_SelectionSet class. - -#ifndef GLC_SELECTIONSET_H_ -#define GLC_SELECTIONSET_H_ - -#include -#include -#include - -#include "glc_structoccurence.h" -#include "../glc_global.h" - -#include "../glc_config.h" - -class GLC_WorldHandle; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_SelectionSet -/*! \brief GLC_SelectionSet : GLC_StructOccurence and primitive selection set */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_SelectionSet -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// - -public: - //! Construct the selection set associated to the given GLC_WorldHandle - GLC_SelectionSet(GLC_WorldHandle* pWorld); - virtual ~GLC_SelectionSet(); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Return true if this selection set is empty - bool isEmpty() const; - - //! Return the number of occurence in this selection set - inline int size() const - {return count();} - - //! Return the number of occurence in this selection set - int count() const; - - //! Return the list of selected occurences - QList occurencesList() const; - - //! Return true if this selection set contains the given occurence - bool contains(const GLC_StructOccurence* pOccurence) const - {return contains(pOccurence->id());} - - //! Return true if this selection set contains the given occurence id - bool contains(GLC_uint occurenceId) const - {return m_OccurenceHash.contains(occurenceId);} - -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Insert the given Occurence into the selection set and return true on success - /*! The given occurence must belongs to this selection set's world*/ - bool insert(GLC_StructOccurence* pOccurence); - - //! Insert the given Occurence id into the selection set and return true on success - /*! The given occurence id must belongs to this selection set's world*/ - bool insert(GLC_uint occurenceId); - - //! Remove the given occurence from the selection set and return true on success - /*! The given occurence must belongs to this selection set's world*/ - bool remove(GLC_StructOccurence* pOccurence); - - //! Remove the given occurence from the selection set and return true on success - /*! The given occurence id must belongs to this selection set's world*/ - bool remove(GLC_uint occurenceId); - - //! Clear this selection set - void clear(); - -//@} - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - //! The worldHandle attached to this selection set - GLC_WorldHandle* m_pWorldHandle; - - //! Hash table of selected occurence - QHash m_OccurenceHash; - -}; - -#endif /* GLC_SELECTIONSET_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_spacepartitioning.cpp b/ground/gcs/src/libs/glc_lib/sceneGraph/glc_spacepartitioning.cpp deleted file mode 100644 index 82228f3d9..000000000 --- a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_spacepartitioning.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_spacepartitioning.cpp implementation for the GLC_SpacePartitioning class. - -#include "glc_spacepartitioning.h" -#include "glc_3dviewcollection.h" - -#include - -// Default constructor -GLC_SpacePartitioning::GLC_SpacePartitioning(GLC_3DViewCollection* pCollection) -: m_pCollection(pCollection) -{ - Q_ASSERT(m_pCollection != NULL); -} - -// Copy constructor -GLC_SpacePartitioning::GLC_SpacePartitioning(const GLC_SpacePartitioning& spacePartitionning) -: m_pCollection(spacePartitionning.m_pCollection) -{ - -} - -GLC_SpacePartitioning::~GLC_SpacePartitioning() -{ - -} diff --git a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_spacepartitioning.h b/ground/gcs/src/libs/glc_lib/sceneGraph/glc_spacepartitioning.h deleted file mode 100644 index 772ab0125..000000000 --- a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_spacepartitioning.h +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_spacepartitioning.h interface for the GLC_SpacePartitioning class. - -#ifndef GLC_SPACEPARTITIONING_H_ -#define GLC_SPACEPARTITIONING_H_ - -#include "../glc_config.h" -#include "../glc_boundingbox.h" -#include "../viewport/glc_frustum.h" - -class GLC_3DViewCollection; -class GLC_3DViewInstance; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_SpacePartitioning -/*! \brief GLC_SpacePartitioning : Abstract class for space partitionning */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_SpacePartitioning -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Default constructor - GLC_SpacePartitioning(GLC_3DViewCollection*); - - //! Copy constructor - GLC_SpacePartitioning(const GLC_SpacePartitioning&); - - //! Destructor - virtual ~GLC_SpacePartitioning(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the 3DViewCollection of the space partitioning - inline GLC_3DViewCollection* collectionHandle() - {return m_pCollection;} - - //! Return the list off instances inside or intersect the given bounding box - virtual QList listOfIntersectedInstances(const GLC_BoundingBox&)= 0; - - -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Update visible GLC_3DViewInstance - virtual void updateViewableInstances(const GLC_Frustum&)= 0; - - //! Update the space partionning - virtual void updateSpacePartitioning()= 0; - - //! Clear the space partionning - virtual void clear()= 0; - -//@} - -////////////////////////////////////////////////////////////////////// -// Protected members -////////////////////////////////////////////////////////////////////// -protected: - //! The Collection containing 3dview Instances - GLC_3DViewCollection* m_pCollection; - -}; - -#endif /* GLC_SPACEPARTITIONING_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_structinstance.cpp b/ground/gcs/src/libs/glc_lib/sceneGraph/glc_structinstance.cpp deleted file mode 100644 index 0137c5def..000000000 --- a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_structinstance.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_structinstance.cpp implementation of the GLC_StructInstance class. - -#include "glc_structinstance.h" -#include "glc_structreference.h" -#include "glc_structoccurence.h" - -// Default constructor -GLC_StructInstance::GLC_StructInstance(GLC_StructReference* pStructReference) -: m_pNumberOfInstance(NULL) -, m_pStructReference(pStructReference) -, m_ListOfOccurences() -, m_RelativeMatrix() -, m_Name() -, m_pAttributes(NULL) -{ - if (NULL == m_pStructReference) - { - m_pStructReference= new GLC_StructReference(); - } - m_Name= m_pStructReference->name(); - - if (m_pStructReference->hasStructInstance()) - { - m_pNumberOfInstance= m_pStructReference->firstInstanceHandle()->m_pNumberOfInstance; - ++(*m_pNumberOfInstance); - } - else - { - m_pNumberOfInstance= new int(1); - } - // Inform reference that an instance has been created - m_pStructReference->structInstanceCreated(this); - //qDebug() << "GLC_StructInstance::GLC_StructInstance : " << (*m_pNumberOfInstance) << " " << m_pNumberOfInstance; -} - -// Create instance with a rep -GLC_StructInstance::GLC_StructInstance(GLC_Rep* pRep) -: m_pNumberOfInstance(NULL) -, m_pStructReference(new GLC_StructReference(pRep)) -, m_ListOfOccurences() -, m_RelativeMatrix() -, m_Name(m_pStructReference->name()) -, m_pAttributes(NULL) -{ - if (m_pStructReference->hasStructInstance()) - { - m_pNumberOfInstance= m_pStructReference->firstInstanceHandle()->m_pNumberOfInstance; - ++(*m_pNumberOfInstance); - } - else - { - m_pNumberOfInstance= new int(1); - } - // Inform reference that an instance has been created - m_pStructReference->structInstanceCreated(this); -} - -// Copy constructor -GLC_StructInstance::GLC_StructInstance(const GLC_StructInstance& structInstance) -: m_pNumberOfInstance(structInstance.m_pNumberOfInstance) -, m_pStructReference(structInstance.m_pStructReference) -, m_ListOfOccurences() -, m_RelativeMatrix(structInstance.m_RelativeMatrix) -, m_Name(structInstance.name()) -, m_pAttributes(NULL) -{ - //qDebug() << "Instance Copy constructor"; - Q_ASSERT(NULL != m_pStructReference); - // Copy attributes if necessary - if (NULL != structInstance.m_pAttributes) - { - m_pAttributes= new GLC_Attributes(*(structInstance.m_pAttributes)); - } - - ++(*m_pNumberOfInstance); - - // Inform reference that an instance has been created - m_pStructReference->structInstanceCreated(this); -} - -// Copy constructor -GLC_StructInstance::GLC_StructInstance(GLC_StructInstance* pStructInstance) -: m_pNumberOfInstance(pStructInstance->m_pNumberOfInstance) -, m_pStructReference(pStructInstance->m_pStructReference) -, m_ListOfOccurences() -, m_RelativeMatrix(pStructInstance->m_RelativeMatrix) -, m_Name(pStructInstance->name()) -, m_pAttributes(NULL) -{ - //qDebug() << "Instance Copy constructor"; - Q_ASSERT(NULL != m_pStructReference); - // Copy attributes if necessary - if (NULL != pStructInstance->m_pAttributes) - { - m_pAttributes= new GLC_Attributes(*(pStructInstance->m_pAttributes)); - } - - ++(*m_pNumberOfInstance); - - // Inform reference that an instance has been created - m_pStructReference->structInstanceCreated(this); -} - -// Create empty instance -GLC_StructInstance::GLC_StructInstance(const QString& name) -: m_pNumberOfInstance(NULL) -, m_pStructReference(NULL) -, m_ListOfOccurences() -, m_RelativeMatrix() -, m_Name(name) -, m_pAttributes(NULL) -{ -} - -// Set the reference of an empty instance -void GLC_StructInstance::setReference(GLC_StructReference* pStructReference) -{ - Q_ASSERT(NULL == m_pStructReference); - Q_ASSERT(NULL == m_pNumberOfInstance); - m_pStructReference= pStructReference; - if (m_pStructReference->hasStructInstance()) - { - m_pNumberOfInstance= m_pStructReference->firstInstanceHandle()->m_pNumberOfInstance; - ++(*m_pNumberOfInstance); - } - else - { - m_pNumberOfInstance= new int(1); - } - // Inform reference that an instance has been created - m_pStructReference->structInstanceCreated(this); - - if (m_Name.isEmpty()) - { - m_Name= pStructReference->name(); - } -} - -// Destructor -GLC_StructInstance::~GLC_StructInstance() -{ - if(m_pNumberOfInstance != NULL) - { - // Update number of instance - if ((--(*m_pNumberOfInstance)) == 0) - { - delete m_pStructReference; - delete m_pNumberOfInstance; - } - else - { - // Inform reference that an instance has been deleted - m_pStructReference->structInstanceDeleted(this); - Q_ASSERT(m_pStructReference->hasStructInstance()); - } - delete m_pAttributes; - } - else qDebug() << "GLC_StructInstance::~GLC_StructInstance() of empty instance"; - -} - -void GLC_StructInstance::updateOccurencesAbsoluteMatrix() -{ - const int occurenceCount= m_ListOfOccurences.count(); - for (int i= 0; i < occurenceCount; ++i) - { - m_ListOfOccurences.at(i)->updateChildrenAbsoluteMatrix(); - } -} diff --git a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_structinstance.h b/ground/gcs/src/libs/glc_lib/sceneGraph/glc_structinstance.h deleted file mode 100644 index 3ae653965..000000000 --- a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_structinstance.h +++ /dev/null @@ -1,204 +0,0 @@ - -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_structinstance.h interface for the GLC_StructInstance class. - -#ifndef GLC_STRUCTINSTANCE_H_ -#define GLC_STRUCTINSTANCE_H_ - -#include -#include -#include "../maths/glc_matrix4x4.h" -#include "glc_3dviewinstance.h" -#include "glc_attributes.h" - -#include "../glc_config.h" - -class GLC_StructReference; -class GLC_StructOccurence; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_StructInstance -/*! \brief GLC_StructInstance : A scene graph instance node */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_StructInstance -{ -public: - //! Default constructor - GLC_StructInstance(GLC_StructReference* pRef= NULL); - - //! Create instance with a rep - GLC_StructInstance(GLC_Rep*); - - //! Copy constructor - GLC_StructInstance(const GLC_StructInstance&); - - //! Copy constructor - GLC_StructInstance(GLC_StructInstance*); - - //! Create empty instance - GLC_StructInstance(const QString&); - - //! Set the reference of an empty instance - void setReference(GLC_StructReference*); - - // Destructor - virtual ~GLC_StructInstance(); -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return true if this instance have occurence - inline bool hasStructOccurence() const - { return !m_ListOfOccurences.isEmpty();} - - //! Return the number of occurence - inline int numberOfOccurence() const - {return m_ListOfOccurences.size();} - - //! Return first occurence handle - inline GLC_StructOccurence* firstOccurenceHandle() const - { return m_ListOfOccurences.first();} - - //! Return the relative matrix of this instance - inline GLC_Matrix4x4 relativeMatrix() const - { return m_RelativeMatrix;} - - //! Return the reference of this instance - inline GLC_StructReference* structReference() const - { return m_pStructReference;} - - //! Return the list off occurence of this instance - inline QList listOfStructOccurences() const - { return m_ListOfOccurences;} - - //! Return the instance name - inline QString name() const - {return m_Name;} - - //! Return true if the reference contains User attributes - inline bool containsAttributes() const - { return ((NULL != m_pAttributes) && !m_pAttributes->isEmpty());} - - //! Return handle to the reference attributes - inline GLC_Attributes* attributesHandle() const - {return m_pAttributes;} - - //! Return the number of usage of this instance - inline int usageCount() const - {return *m_pNumberOfInstance;} - -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! An occurence of this instance have been created - inline void structOccurenceCreated(GLC_StructOccurence* pOccurence) - { - Q_ASSERT(!m_ListOfOccurences.contains(pOccurence)); - m_ListOfOccurences.append(pOccurence); - } - - inline void structOccurenceDeleted(GLC_StructOccurence *pOccurence) - { - m_ListOfOccurences.removeOne(pOccurence); - } - - //! Move the instance by specified matrix - inline GLC_StructInstance* move(const GLC_Matrix4x4& matrix) - { - m_RelativeMatrix= matrix * m_RelativeMatrix; - return this; - } - - //! Translate Instance - inline GLC_StructInstance* translate(double Tx, double Ty, double Tz) - { - m_RelativeMatrix= GLC_Matrix4x4(Tx, Ty, Tz) * m_RelativeMatrix; - return this; - } - - //! Translate Instance - inline GLC_StructInstance* translate(const GLC_Vector3d& v) - { - return translate(v.x(), v.y(), v.z()); - } - - //! Replace the instance Matrix - inline GLC_StructInstance* setMatrix(const GLC_Matrix4x4 &SetMat) - { - m_RelativeMatrix= SetMat; - return this; - } - - //! Reset the instance Matrix - inline GLC_StructInstance* resetMatrix() - { - m_RelativeMatrix = GLC_Matrix4x4(); - return this; - } - - //! Set the instance name - inline void setName(const QString& name) - {m_Name= name;} - - //! Set the instance attributes - inline void setAttributes(const GLC_Attributes& attr) - { - delete m_pAttributes; - m_pAttributes= new GLC_Attributes(attr); - } - - //! Update absolute matrix off children and all occurences of this instance - void updateOccurencesAbsoluteMatrix(); - - -//@} - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - //! Number of this Instance - int* m_pNumberOfInstance; - - //! The Struct reference of this instance - GLC_StructReference* m_pStructReference; - - //! The list of instance's occurences - QList m_ListOfOccurences; - - //! The relative matrix - GLC_Matrix4x4 m_RelativeMatrix; - - //! The instance Name - QString m_Name; - - //! The Reference attributes - GLC_Attributes* m_pAttributes; -}; - -#endif /* GLC_STRUCTINSTANCE_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_structoccurence.cpp b/ground/gcs/src/libs/glc_lib/sceneGraph/glc_structoccurence.cpp deleted file mode 100644 index 97d7a7258..000000000 --- a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_structoccurence.cpp +++ /dev/null @@ -1,969 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_structoccurence.cpp implementation of the GLC_StructOccurence class. - -#include "glc_structoccurence.h" -#include "glc_3dviewcollection.h" -#include "glc_structreference.h" -#include "glc_worldhandle.h" -#include "../glc_errorlog.h" - -GLC_StructOccurence::GLC_StructOccurence() -: m_Uid(glc::GLC_GenID()) -, m_pWorldHandle(NULL) -, m_pNumberOfOccurence(new int(1)) -, m_pStructInstance(new GLC_StructInstance()) -, m_pParent(NULL) -, m_Childs() -, m_AbsoluteMatrix() -, m_OccurenceNumber(0) -, m_IsVisible(true) -, m_pRenderProperties(NULL) -, m_AutomaticCreationOf3DViewInstance(true) -, m_pRelativeMatrix(NULL) -{ - // Update instance - m_pStructInstance->structOccurenceCreated(this); -} - -GLC_StructOccurence::GLC_StructOccurence(GLC_StructInstance* pStructInstance, GLC_WorldHandle* pWorldHandle, GLuint shaderId) -: m_Uid(glc::GLC_GenID()) -, m_pWorldHandle(pWorldHandle) -, m_pNumberOfOccurence(NULL) -, m_pStructInstance(pStructInstance) -, m_pParent(NULL) -, m_Childs() -, m_AbsoluteMatrix() -, m_OccurenceNumber(0) -, m_IsVisible(true) -, m_pRenderProperties(NULL) -, m_AutomaticCreationOf3DViewInstance(true) -, m_pRelativeMatrix(NULL) -{ - doCreateOccurrenceFromInstance(shaderId); -} - -GLC_StructOccurence::GLC_StructOccurence(GLC_StructInstance* pStructInstance, GLC_uint id, GLC_WorldHandle* pWorldHandle, GLuint shaderId) -: m_Uid(id) -, m_pWorldHandle(pWorldHandle) -, m_pNumberOfOccurence(NULL) -, m_pStructInstance(pStructInstance) -, m_pParent(NULL) -, m_Childs() -, m_AbsoluteMatrix() -, m_OccurenceNumber(0) -, m_IsVisible(true) -, m_pRenderProperties(NULL) -, m_AutomaticCreationOf3DViewInstance(true) -, m_pRelativeMatrix(NULL) -{ - doCreateOccurrenceFromInstance(shaderId); -} - -GLC_StructOccurence::GLC_StructOccurence(GLC_3DRep* pRep) -: m_Uid(glc::GLC_GenID()) -, m_pWorldHandle(NULL) -, m_pNumberOfOccurence(new int(1)) -, m_pStructInstance(NULL) -, m_pParent(NULL) -, m_Childs() -, m_AbsoluteMatrix() -, m_OccurenceNumber(0) -, m_IsVisible(true) -, m_pRenderProperties(NULL) -, m_AutomaticCreationOf3DViewInstance(true) -, m_pRelativeMatrix(NULL) -{ - m_pStructInstance= new GLC_StructInstance(pRep); - - // Update instance - m_pStructInstance->structOccurenceCreated(this); -} - -GLC_StructOccurence::GLC_StructOccurence(GLC_3DRep* pRep, GLC_uint id) -: m_Uid(id) -, m_pWorldHandle(NULL) -, m_pNumberOfOccurence(new int(1)) -, m_pStructInstance(NULL) -, m_pParent(NULL) -, m_Childs() -, m_AbsoluteMatrix() -, m_OccurenceNumber(0) -, m_IsVisible(true) -, m_pRenderProperties(NULL) -, m_AutomaticCreationOf3DViewInstance(true) -, m_pRelativeMatrix(NULL) -{ - m_pStructInstance= new GLC_StructInstance(pRep); - - // Update instance - m_pStructInstance->structOccurenceCreated(this); -} - -GLC_StructOccurence::GLC_StructOccurence(GLC_WorldHandle* pWorldHandle, const GLC_StructOccurence& structOccurence, bool shareInstance) -: m_Uid(glc::GLC_GenID()) -, m_pWorldHandle(pWorldHandle) -, m_pNumberOfOccurence(NULL) -, m_pStructInstance(NULL) -, m_pParent(NULL) -, m_Childs() -, m_AbsoluteMatrix(structOccurence.m_AbsoluteMatrix) -, m_OccurenceNumber(0) -, m_IsVisible(structOccurence.m_IsVisible) -, m_pRenderProperties(NULL) -, m_AutomaticCreationOf3DViewInstance(structOccurence.m_AutomaticCreationOf3DViewInstance) -, m_pRelativeMatrix(NULL) -{ - if (shareInstance) - { - m_pStructInstance= structOccurence.m_pStructInstance; - m_pNumberOfOccurence= structOccurence.m_pNumberOfOccurence; - ++(*m_pNumberOfOccurence); - } - else - { - m_pNumberOfOccurence= new int(1); - m_pStructInstance= new GLC_StructInstance(structOccurence.m_pStructInstance); - } - - - // Test if structOccurence has representation and has a shader - GLuint shaderId= 0; - bool instanceIsSelected= false; - if ((NULL != m_pWorldHandle) && (NULL != structOccurence.m_pWorldHandle) && structOccurence.m_pWorldHandle->collection()->contains(structOccurence.id())) - { - GLC_3DViewInstance* p3DViewInstance= structOccurence.m_pWorldHandle->collection()->instanceHandle(structOccurence.id()); - - if(structOccurence.m_pWorldHandle->collection()->isInAShadingGroup(structOccurence.id())) - { - shaderId= structOccurence.m_pWorldHandle->collection()->shadingGroup(structOccurence.id()); - } - - instanceIsSelected= p3DViewInstance->isSelected(); - // Test the rendering properties - if (! p3DViewInstance->renderPropertiesHandle()->isDefault()) - { - m_pRenderProperties= new GLC_RenderProperties(*(p3DViewInstance->renderPropertiesHandle())); - } - } - else if (NULL != structOccurence.m_pRenderProperties) - { - m_pRenderProperties= new GLC_RenderProperties(*(structOccurence.m_pRenderProperties)); - } - - // Inform the world Handle - if (NULL != m_pWorldHandle) - { - m_pWorldHandle->addOccurence(this, instanceIsSelected, shaderId); - if (NULL != m_pRenderProperties && this->has3DViewInstance()) - { - m_pWorldHandle->collection()->instanceHandle(id())->setRenderProperties(*m_pRenderProperties); - delete m_pRenderProperties; - m_pRenderProperties= NULL; - } - } - - // Check flexibility - if (NULL != structOccurence.m_pRelativeMatrix) - { - m_pRelativeMatrix= new GLC_Matrix4x4(*(structOccurence.m_pRelativeMatrix)); - } - - // Update Absolute matrix - updateAbsoluteMatrix(); - - - // Create childs - const int size= structOccurence.childCount(); - for (int i= 0; i < size; ++i) - { - GLC_StructOccurence* pChild= structOccurence.child(i)->clone(m_pWorldHandle, true); - addChild(pChild); - } - updateChildrenAbsoluteMatrix(); - // Update instance - m_pStructInstance->structOccurenceCreated(this); -} - -GLC_StructOccurence::~GLC_StructOccurence() -{ - //qDebug() << "Delete " << id(); - Q_ASSERT(m_pNumberOfOccurence != NULL); - // Remove from the GLC_WorldHandle - if (NULL != m_pWorldHandle) - { - m_pWorldHandle->removeOccurence(this); - } - - // Remove Childs - const int size= m_Childs.size(); - for (int i= 0; i < size; ++i) - { - GLC_StructOccurence* pChild= m_Childs.first(); - removeChild(pChild); - delete pChild; - } - // Update number of occurence and instance - if ((--(*m_pNumberOfOccurence)) == 0) - { - delete m_pStructInstance; - delete m_pNumberOfOccurence; - } - else - { - m_pStructInstance->structOccurenceDeleted(this); - if (!m_pStructInstance->hasStructOccurence()) - { - - QStringList errorList; - errorList << "StructOccurence count error"; - errorList << ("ref name = " + m_pStructInstance->structReference()->name()); - GLC_ErrorLog::addError(errorList); - - delete m_pStructInstance; - //delete m_pNumberOfOccurence; - } - } - - delete m_pRenderProperties; - delete m_pRelativeMatrix; -} - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -GLC_Matrix4x4 GLC_StructOccurence::occurrenceRelativeMatrix() const -{ - GLC_Matrix4x4 matrix; - if (NULL != m_pRelativeMatrix) - { - matrix= *m_pRelativeMatrix; - } - return matrix; -} - -bool GLC_StructOccurence::hasRepresentation() const -{ - if ((NULL != m_pStructInstance) && (m_pStructInstance->structReference() != NULL)) - { - return this->structReference()->hasRepresentation(); - } - else return false; -} - -bool GLC_StructOccurence::has3DViewInstance() const -{ - if ( NULL != m_pWorldHandle) - { - return m_pWorldHandle->collection()->contains(m_Uid); - } - else return false; -} - -bool GLC_StructOccurence::canBeAddedToChildren(GLC_StructOccurence* pOccurence) const -{ - bool canBeAdded= false; - if ((NULL != m_pStructInstance) && (m_pStructInstance->hasStructOccurence()) && (NULL != pOccurence->m_pStructInstance) && (NULL != pOccurence->structReference())) - { - if (this->structReference() != pOccurence->structReference()) - { - QSet thisRefSet= GLC_StructOccurence::parentsReferences(this); - thisRefSet << this->structReference(); - QSet childRefSet= pOccurence->childrenReferences(); - - canBeAdded= thisRefSet == (thisRefSet - childRefSet); - } - } - else - { - canBeAdded= true; - } - return canBeAdded; -} - -QList GLC_StructOccurence::subOccurenceList() const -{ - QList subOccurence; - const int childCount= m_Childs.size(); - for (int i= 0; i < childCount; ++i) - { - GLC_StructOccurence* pCurrentChild= m_Childs.at(i); - subOccurence.append(pCurrentChild); - if (pCurrentChild->hasChild()) - { - subOccurence.append(pCurrentChild->subOccurenceList()); - } - } - - return subOccurence; -} - -unsigned int GLC_StructOccurence::numberOfFaces() const -{ - unsigned int result= 0; - if (hasRepresentation()) - { - result= structInstance()->structReference()->numberOfFaces(); - } - - const int size= m_Childs.size(); - for (int i= 0; i < size; ++i) - { - result+= m_Childs.at(i)->numberOfFaces(); - } - - return result; -} - -unsigned int GLC_StructOccurence::numberOfVertex() const -{ - unsigned int result= 0; - if (hasRepresentation()) - { - result= structInstance()->structReference()->numberOfVertex(); - } - const int size= m_Childs.size(); - for (int i= 0; i < size; ++i) - { - result+= m_Childs.at(i)->numberOfVertex(); - } - - return result; -} - -unsigned int GLC_StructOccurence::numberOfMaterials() const -{ - unsigned int result= 0; - QSet materialSet; - if (hasRepresentation()) - { - result= structInstance()->structReference()->numberOfMaterials(); - } - - const int size= m_Childs.size(); - for (int i= 0; i < size; ++i) - { - materialSet.unite(m_Childs.at(i)->materialSet()); - } - result= static_cast(materialSet.size()); - - return result; -} - -QSet GLC_StructOccurence::materialSet() const -{ - QSet materialSet; - if (hasRepresentation()) - { - materialSet= structInstance()->structReference()->materialSet(); - } - - const int size= m_Childs.size(); - for (int i= 0; i < size; ++i) - { - materialSet.unite(m_Childs.at(i)->materialSet()); - } - - return materialSet; -} - -GLC_StructOccurence* GLC_StructOccurence::clone(GLC_WorldHandle* pWorldHandle, bool shareInstance) const -{ - return new GLC_StructOccurence(pWorldHandle, *this, shareInstance); -} - -bool GLC_StructOccurence::isVisible() const -{ - bool isHidden= true; - - if ((NULL != m_pWorldHandle) && m_pWorldHandle->collection()->contains(m_Uid)) - { - isHidden= !m_pWorldHandle->collection()->instanceHandle(m_Uid)->isVisible(); - } - else if (childCount() > 0) - { - const int size= childCount(); - int i= 0; - while ((i < size) && isHidden) - { - isHidden= isHidden && !child(i)->isVisible(); - ++i; - } - } - else - { - isHidden= !m_IsVisible; - } - return !isHidden; -} - -GLC_BoundingBox GLC_StructOccurence::boundingBox() const -{ - GLC_BoundingBox boundingBox; - - if (NULL != m_pWorldHandle) - { - if (has3DViewInstance()) - { - Q_ASSERT(m_pWorldHandle->collection()->contains(id())); - boundingBox= m_pWorldHandle->collection()->instanceHandle(id())->boundingBox(); - } - else - { - if (hasChild()) - { - QList childrenList= children(); - const int size= childrenList.size(); - - for (int i= 0; i < size; ++i) - { - boundingBox.combine(childrenList.at(i)->boundingBox()); - } - } - } - } - - return boundingBox; -} - -unsigned int GLC_StructOccurence::nodeCount() const -{ - unsigned int result= 1; - const int size= m_Childs.size(); - for (int i= 0; i < size; ++i) - { - result+= m_Childs.at(i)->nodeCount(); - } - return result; -} - -QSet GLC_StructOccurence::childrenReferences() const -{ - QSet refChildrenSet; - const int childCount= m_Childs.size(); - for (int i= 0; i < childCount; ++i) - { - GLC_StructOccurence* pCurrentChild= m_Childs.at(i); - if ((NULL != pCurrentChild->structInstance()) && (NULL != pCurrentChild->structReference())) - { - refChildrenSet << pCurrentChild->structReference(); - } - } - - return refChildrenSet; -} - -QSet GLC_StructOccurence::parentsReferences(const GLC_StructOccurence* pOccurence) -{ - QSet parentSet; - GLC_StructOccurence* pParent= pOccurence->parent(); - if (NULL != pParent) - { - if ((NULL != pParent->structInstance()) && (NULL != pParent->structReference())) - { - parentSet << pParent->structReference(); - parentSet.unite(GLC_StructOccurence::parentsReferences(pParent)); - } - } - - return parentSet; -} - -int GLC_StructOccurence::indexOf(const GLC_StructOccurence* pOcc) const -{ - int subject= -1; - const int childCount= m_Childs.count(); - bool containsOcc= false; - int i= 0; - while (!containsOcc && (i < childCount)) - { - if (m_Childs.at(i) == pOcc) - { - containsOcc= true; - subject= i; - } - ++i; - } - return subject; -} - -bool GLC_StructOccurence::containsChild(const GLC_StructOccurence* pOcc) const -{ - return pOcc->parent() == this; -} -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -GLC_StructOccurence* GLC_StructOccurence::updateAbsoluteMatrix() -{ - GLC_Matrix4x4 relativeMatrix; - if (NULL == m_pRelativeMatrix) - { - relativeMatrix= m_pStructInstance->relativeMatrix(); - } - else - { - relativeMatrix= *m_pRelativeMatrix; - } - - if (NULL != m_pParent) - { - m_AbsoluteMatrix= m_pParent->absoluteMatrix() * relativeMatrix; - } - else - { - m_AbsoluteMatrix= relativeMatrix; - } - // If the occurence have a representation, update it. - - if ((NULL != m_pWorldHandle) && m_pWorldHandle->collection()->contains(m_Uid)) - { - m_pWorldHandle->collection()->instanceHandle(m_Uid)->setMatrix(m_AbsoluteMatrix); - } - return this; -} - -GLC_StructOccurence* GLC_StructOccurence::updateChildrenAbsoluteMatrix() -{ - updateAbsoluteMatrix(); - const int size= m_Childs.size(); - for (int i= 0; i < size; ++i) - { - m_Childs[i]->updateChildrenAbsoluteMatrix(); - } - return this; -} - -void GLC_StructOccurence::addChild(GLC_StructOccurence* pChild) -{ - Q_ASSERT(pChild->isOrphan()); - Q_ASSERT((NULL == pChild->m_pWorldHandle) || (m_pWorldHandle == pChild->m_pWorldHandle)); - - //qDebug() << "Add Child " << pChild->name() << "id=" << pChild->id() << " to " << name() << " id=" << id(); - // Add the child to the list of child - // Get occurence reference - m_Childs.append(pChild); - pChild->m_pParent= this; - if (NULL == pChild->m_pWorldHandle) - { - pChild->setWorldHandle(m_pWorldHandle); - } - pChild->updateChildrenAbsoluteMatrix(); -} - -void GLC_StructOccurence::insertChild(int index, GLC_StructOccurence* pChild) -{ - Q_ASSERT(pChild->isOrphan()); - Q_ASSERT((NULL == pChild->m_pWorldHandle) || (m_pWorldHandle == pChild->m_pWorldHandle)); - Q_ASSERT(m_Childs.count() >= index); - - //qDebug() << "Add Child " << pChild->name() << "id=" << pChild->id() << " to " << name() << " id=" << id(); - // Add the child to the list of child - // Get occurence reference - m_Childs.insert(index, pChild); - pChild->m_pParent= this; - if (NULL == pChild->m_pWorldHandle) - { - pChild->setWorldHandle(m_pWorldHandle); - } - pChild->updateChildrenAbsoluteMatrix(); -} - -GLC_StructOccurence* GLC_StructOccurence::addChild(GLC_StructInstance* pInstance) -{ - GLC_StructOccurence* pOccurence; - pOccurence= new GLC_StructOccurence(pInstance, m_pWorldHandle); - - addChild(pOccurence); - - return pOccurence; -} - -GLC_StructOccurence* GLC_StructOccurence::insertChild(int index, GLC_StructInstance* pInstance) -{ - GLC_StructOccurence* pOccurence; - pOccurence= new GLC_StructOccurence(pInstance, m_pWorldHandle); - - insertChild(index, pOccurence); - - return pOccurence; -} - -void GLC_StructOccurence::makeOrphan() -{ - if(!isOrphan()) - { - m_pParent->removeChild(this); - } - else - { - detach(); - } -} - -bool GLC_StructOccurence::removeChild(GLC_StructOccurence* pChild) -{ - Q_ASSERT(pChild->m_pParent == this); - Q_ASSERT(m_Childs.contains(pChild)); - pChild->m_pParent= NULL; - pChild->detach(); - - return m_Childs.removeOne(pChild); -} - - -void GLC_StructOccurence::reverseNormals() -{ - if (has3DViewInstance()) - { - m_pWorldHandle->collection()->instanceHandle(id())->reverseGeometriesNormals(); - } -} - -bool GLC_StructOccurence::create3DViewInstance(GLuint shaderId) -{ - bool subject= false; - if (!has3DViewInstance() && (NULL != m_pWorldHandle) && hasRepresentation()) - { - GLC_3DRep* p3DRep= dynamic_cast(structReference()->representationHandle()); - if (NULL != p3DRep) - { - GLC_3DViewInstance instance(*p3DRep, m_Uid); - instance.setName(name()); - - if (NULL != m_pRenderProperties) - { - instance.setRenderProperties(*m_pRenderProperties); - delete m_pRenderProperties; - m_pRenderProperties= NULL; - } - - if (0 != shaderId) m_pWorldHandle->collection()->bindShader(shaderId); - subject= m_pWorldHandle->collection()->add(instance, shaderId); - m_pWorldHandle->collection()->setVisibility(m_Uid, m_IsVisible); - if (m_pWorldHandle->selectionSetHandle()->contains(m_Uid)) - { - m_pWorldHandle->collection()->select(m_Uid); - } - } - } - return subject; -} - -bool GLC_StructOccurence::remove3DViewInstance() -{ - if (NULL != m_pWorldHandle) - { - return m_pWorldHandle->collection()->remove(m_Uid); - } - else return false; -} - -// Set the occurence world Handle -void GLC_StructOccurence::setWorldHandle(GLC_WorldHandle* pWorldHandle) -{ - // Check if world handles are equal - if (m_pWorldHandle == pWorldHandle) return; - - if (NULL != m_pWorldHandle) - { - m_pWorldHandle->removeOccurence(this); - } - - m_pWorldHandle= pWorldHandle; - - if (NULL != m_pWorldHandle) - { - m_pWorldHandle->addOccurence(this); - m_pWorldHandle->collection()->setVisibility(m_Uid, m_IsVisible); - - const int size= m_Childs.size(); - for (int i= 0; i < size; ++i) - { - m_Childs[i]->setWorldHandle(m_pWorldHandle); - } - } -} - -// Load the representation and return true if success -bool GLC_StructOccurence::loadRepresentation() -{ - Q_ASSERT(!this->has3DViewInstance()); - - bool loadSuccess= false; - if (hasRepresentation()) - { - GLC_StructReference* pReference= this->structReference(); - if (pReference->representationIsLoaded()) - { - loadSuccess= create3DViewInstance(); - } - else - { - loadSuccess= m_pStructInstance->structReference()->loadRepresentation(); - if (loadSuccess && !m_AutomaticCreationOf3DViewInstance) - { - loadSuccess= create3DViewInstance(); - } - } - } - - return loadSuccess; -} - -// UnLoad the representation and return true if success -bool GLC_StructOccurence::unloadRepresentation() -{ - bool unloadResult= false; - if (hasRepresentation()) - { - GLC_StructReference* pRef= this->structReference(); - if (pRef->representationIsLoaded()) - { - if (this->has3DViewInstance()) - { - unloadResult= m_pWorldHandle->collection()->remove(m_Uid); - QSet occurenceSet= pRef->setOfStructOccurence(); - QSet::const_iterator iOcc= occurenceSet.constBegin(); - bool unloadReferenceRep= true; - while (occurenceSet.constEnd() != iOcc) - { - unloadReferenceRep= unloadReferenceRep && !(*iOcc)->has3DViewInstance(); - ++iOcc; - } - if (unloadReferenceRep) - { - pRef->unloadRepresentation(); - } - } - } - } - return unloadResult; -} - -unsigned int GLC_StructOccurence::updateOccurenceNumber(unsigned int n) -{ - m_OccurenceNumber= n++; - const int childCount= m_Childs.size(); - for (int i= 0; i < childCount; ++i) - { - n= m_Childs[i]->updateOccurenceNumber(n); - } - return n; -} - -void GLC_StructOccurence::setVisibility(bool visibility) -{ - m_IsVisible= visibility; - if (has3DViewInstance()) - { - m_pWorldHandle->collection()->setVisibility(m_Uid, m_IsVisible); - } - const int childCount= m_Childs.size(); - for (int i= 0; i < childCount; ++i) - { - m_Childs[i]->setVisibility(m_IsVisible); - } -} - -void GLC_StructOccurence::setRenderProperties(const GLC_RenderProperties& renderProperties) -{ - qDebug() << "GLC_StructOccurence::setRenderProperties"; - delete m_pRenderProperties; - m_pRenderProperties= NULL; - if (has3DViewInstance()) - { - m_pWorldHandle->collection()->instanceHandle(m_Uid)->setRenderProperties(renderProperties); - } - - if (hasChild()) - { - const int childCount= m_Childs.size(); - for (int i= 0; i < childCount; ++i) - { - m_Childs[i]->setRenderProperties(renderProperties); - } - } - else if (!has3DViewInstance()) - { - m_pRenderProperties= new GLC_RenderProperties(renderProperties); - } -} - -void GLC_StructOccurence::removeEmptyChildren() -{ - QList::iterator iChild= m_Childs.begin(); - while (m_Childs.constEnd() != iChild) - { - if (!((*iChild)->hasChild()) && !((*iChild)->hasRepresentation())) - { - delete *iChild; - iChild= m_Childs.erase(iChild); - } - else - { - (*iChild)->removeEmptyChildren(); - ++iChild; - } - } -} - -void GLC_StructOccurence::setReference(GLC_StructReference* pRef) -{ - Q_ASSERT(m_pStructInstance->structReference() == NULL); - Q_ASSERT((*m_pNumberOfOccurence) == 1); - - if (pRef->hasStructInstance()) - { - GLC_StructInstance* pExistingInstance= pRef->firstInstanceHandle(); - if (pExistingInstance->hasStructOccurence()) - { - GLC_StructOccurence* pFirstOccurence= pExistingInstance->firstOccurenceHandle(); - QList childs= pFirstOccurence->m_Childs; - const int size= childs.size(); - for (int i= 0; i < size; ++i) - { - GLC_StructOccurence* pChild= childs.at(i)->clone(m_pWorldHandle, true); - addChild(pChild); - } - - QList instances= pRef->listOfStructInstances(); - const int instanceCount= instances.size(); - int i= 0; - bool continu= true; - while (continu && (i < instanceCount)) - { - if (m_pStructInstance == instances.at(i)) - { - continu= false; - delete m_pNumberOfOccurence; - m_pNumberOfOccurence= instances.at(i)->firstOccurenceHandle()->m_pNumberOfOccurence; - ++(*m_pNumberOfOccurence); - } - ++i; - } - } - } - - m_pStructInstance->setReference(pRef); -} - -void GLC_StructOccurence::makeFlexible(const GLC_Matrix4x4& relativeMatrix) -{ - delete m_pRelativeMatrix; - m_pRelativeMatrix= new GLC_Matrix4x4(relativeMatrix); - - updateChildrenAbsoluteMatrix(); -} - -void GLC_StructOccurence::makeRigid() -{ - delete m_pRelativeMatrix; - m_pRelativeMatrix= NULL; - - updateChildrenAbsoluteMatrix(); -} - -void GLC_StructOccurence::swap(int i, int j) -{ - Q_ASSERT(i != j); - - GLC_StructReference* pRef= this->structReference(); - QList occurences= pRef->listOfStructOccurence(); - const int count= occurences.count(); - for (int i= 0; i < count; ++i) - { - GLC_StructOccurence* pOcc= occurences.at(i); - Q_ASSERT(i <= pOcc->m_Childs.count()); - Q_ASSERT(j <= pOcc->m_Childs.count()); - pOcc->m_Childs.swap(i, j); - } - -} - -////////////////////////////////////////////////////////////////////// -// Private services function -////////////////////////////////////////////////////////////////////// - -void GLC_StructOccurence::detach() -{ - if (NULL != m_pWorldHandle) - { - // retrieve renderProperties if needed - if (m_pWorldHandle->collection()->contains(m_Uid)) - { - GLC_3DViewInstance* pInstance= m_pWorldHandle->collection()->instanceHandle(m_Uid); - if (!pInstance->renderPropertiesHandle()->isDefault()) - { - Q_ASSERT(NULL == m_pRenderProperties); - m_pRenderProperties= new GLC_RenderProperties(*(pInstance->renderPropertiesHandle())); - } - } - m_pWorldHandle->removeOccurence(this); - m_pWorldHandle= NULL; - if (!m_Childs.isEmpty()) - { - const int size= m_Childs.size(); - for (int i= 0; i < size; ++i) - { - m_Childs[i]->detach(); - } - } - } -} - -void GLC_StructOccurence::doCreateOccurrenceFromInstance(GLuint shaderId) -{ - // Update the number of occurences - if (m_pStructInstance->hasStructOccurence()) - { - GLC_StructOccurence* pFirstOccurence= m_pStructInstance->firstOccurenceHandle(); - m_pNumberOfOccurence= pFirstOccurence->m_pNumberOfOccurence; - ++(*m_pNumberOfOccurence); - QList childs= pFirstOccurence->m_Childs; - const int size= childs.size(); - for (int i= 0; i < size; ++i) - { - GLC_StructOccurence* pChild= childs.at(i)->clone(m_pWorldHandle, true); - addChild(pChild); - } - } - else - { - m_pNumberOfOccurence= new int(1); - } - - // Inform the world Handle - if (NULL != m_pWorldHandle) - { - m_pWorldHandle->addOccurence(this, shaderId); - } - - // Update Absolute matrix - updateAbsoluteMatrix(); - - // Update instance - m_pStructInstance->structOccurenceCreated(this); -} diff --git a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_structoccurence.h b/ground/gcs/src/libs/glc_lib/sceneGraph/glc_structoccurence.h deleted file mode 100644 index 07e06e803..000000000 --- a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_structoccurence.h +++ /dev/null @@ -1,341 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_structoccurence.h interface for the GLC_StructOccurence class. - -#ifndef GLC_STRUCTOCCURENCE_H_ -#define GLC_STRUCTOCCURENCE_H_ - -#include "../maths/glc_matrix4x4.h" -#include "../glc_boundingbox.h" -#include "glc_structinstance.h" -#include - -#include "../glc_config.h" - -class GLC_WorldHandle; -class GLC_Material; -class GLC_RenderProperties; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_StructOccurence -/*! \brief GLC_StructOccurence : A scene graph occurence node */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_StructOccurence -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// - -public: - //! Default constructor - GLC_StructOccurence(); - - //! Create Occurence of the specified instance - GLC_StructOccurence(GLC_StructInstance* pStructInstance, GLC_WorldHandle* pWorldHandle= NULL, GLuint shaderId=0); - - //! Create Occurence of the specified instance and Uid - GLC_StructOccurence(GLC_StructInstance* pStructInstance, GLC_uint id, GLC_WorldHandle* pWorldHandle= NULL, GLuint shaderId=0); - - //! Construct Occurence with the specified GLC_3DRep - GLC_StructOccurence(GLC_3DRep* pRep); - - //! Construct Occurence from the given GLC_3DRep and Uid - GLC_StructOccurence(GLC_3DRep* pRep, GLC_uint id); - - //! Copy constructor - GLC_StructOccurence(GLC_WorldHandle*, const GLC_StructOccurence&, bool shareInstance); - - //! Destructor - virtual ~GLC_StructOccurence(); -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return this Occurence id - inline GLC_uint id() const - {return m_Uid;} - - //! Return the instance name of this occurence - inline const QString name() const - {return m_pStructInstance->name();} - - //! Return the absolute matrix of this occurence - inline GLC_Matrix4x4 absoluteMatrix() const - { return m_AbsoluteMatrix;} - - //! Return the surcharged relative matrix - GLC_Matrix4x4 occurrenceRelativeMatrix() const; - - //! Return true if this occurence is orphan - inline bool isOrphan() const - { return NULL == m_pParent;} - - //! Return true if this occurence has parent - inline bool hasParent() const - { return NULL != m_pParent;} - - //! Return true if this occurence has a representation - bool hasRepresentation() const; - - //! Return true if this occurence has 3DViewInstance - bool has3DViewInstance() const; - - //! Return the instance of this occurence - inline GLC_StructInstance* structInstance() const - { return m_pStructInstance;} - - //! Return the reference of this occurence - inline GLC_StructReference* structReference() const - { - Q_ASSERT(NULL != m_pStructInstance); - return m_pStructInstance->structReference(); - } - - //! Return the number of childs - inline int childCount() const - { return m_Childs.size();} - - //! Return true if the occurence has child - inline bool hasChild() const - {return childCount() > 0;} - - //! Return true if the given occurence can be added to this occurence children - bool canBeAddedToChildren(GLC_StructOccurence* pOccurence) const; - - //! Return The parent of this occurence - inline GLC_StructOccurence* parent() const - {return m_pParent;} - - //! Return a child of this occurence - /*! The index must exist*/ - inline GLC_StructOccurence* child(const int index) const - {return m_Childs.at(index);} - - //! Return the list of children of this occurence - inline QList children() const - {return m_Childs;} - - //! Return the list of all accurence under this occurence - QList subOccurenceList() const; - - //! Return the number of faces of the representation of this occurence - unsigned int numberOfFaces() const; - - //! Return the number of vertex of the representation of this occurence - unsigned int numberOfVertex() const; - - //! Return the number of materials of the representation of this occurence - unsigned int numberOfMaterials() const; - - //! Return the materials List of the representation of this occurence - QSet materialSet() const; - - //! Return a clone this occurence - GLC_StructOccurence* clone(GLC_WorldHandle*, bool shareInstance) const; - - //! Return true if this occurence is visible - bool isVisible() const; - - //! Return the occurence Bounding Box - GLC_BoundingBox boundingBox() const; - - //! Return the occurence number of this occurence - inline unsigned int occurenceNumber() const - {return m_OccurenceNumber;} - - //! Return an handle of the renderProperties of this occurence - GLC_RenderProperties* renderPropertiesHandle() const - {return m_pRenderProperties;} - - //! Return the number of node of this branch - unsigned int nodeCount() const; - - //! Return the world handle of this occurence - inline GLC_WorldHandle* worldHandle() const - {return m_pWorldHandle;} - - //! Return the Set of children references of this occurence - QSet childrenReferences() const; - - //! Return the set of parents references of the given occurence - static QSet parentsReferences(const GLC_StructOccurence* pOccurence); - - //! Return true if the automatic creation of 3DViewInstance is used - inline bool useAutomatic3DViewInstanceCreation() const - {return m_AutomaticCreationOf3DViewInstance;} - - //! Return true if this occurence is flexible - inline bool isFlexible() const - {return (m_pRelativeMatrix != NULL);} - - //! Return the index position of the given occurrence - /*! Return -1 if the given occurence is not a child of this occurence*/ - int indexOf(const GLC_StructOccurence* pOcc) const; - - //! Return true if this occurence contains the given occurence has child - bool containsChild(const GLC_StructOccurence* pOcc) const; -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Set Occurence instance Name - inline void setName(const QString name) {m_pStructInstance->setName(name);} - - //! Update the absolute matrix - GLC_StructOccurence* updateAbsoluteMatrix(); - - //! Update children obsolute Matrix - GLC_StructOccurence* updateChildrenAbsoluteMatrix(); - - //! Add Child - /*! The new child must be orphan*/ - void addChild(GLC_StructOccurence*); - - //! insert Child at the given position - /*! The new child must be orphan and index >= childcount*/ - void insertChild(int index, GLC_StructOccurence* pChild); - - //! Add Child instance and returns the newly created occurence - GLC_StructOccurence* addChild(GLC_StructInstance*); - - //! Insert Child instance and returns the newly created occurence - GLC_StructOccurence* insertChild(int index, GLC_StructInstance* pInstance); - - //! make the occurence orphan - void makeOrphan(); - - //! Remove the specified child - /*! The removed child will not be deleted*/ - bool removeChild(GLC_StructOccurence* pChild); - - //! Reverse Normals of this Occurence and childs - void reverseNormals(); - - //! Create the 3DViewInstance of this occurence if there is a valid 3DRep - bool create3DViewInstance(GLuint shaderId= 0); - - //! Remove the 3DViewInstance of this occurence - bool remove3DViewInstance(); - - //! Set this occurence world Handle - void setWorldHandle(GLC_WorldHandle*); - - //! Load the representation and return true if success - bool loadRepresentation(); - - //! UnLoad the representation and return true if success - bool unloadRepresentation(); - - //! Set the occurence number of this occurence - inline void setOccurenceNumber(unsigned int n) - {m_OccurenceNumber= n;} - - //! Update the occurence number of this occurence branch - unsigned int updateOccurenceNumber(unsigned int n); - - //! Set this occurence and children visibility - void setVisibility(bool visibility); - - //! set the renderProperties of this occurence - void setRenderProperties(const GLC_RenderProperties& renderProperties); - - //! Remove empty children - void removeEmptyChildren(); - - //! Set the given reference to this occurence - void setReference(GLC_StructReference* pRef); - - //! Set the automatic creation of 3DViewInstance usage - inline void setAutomatic3DViewInstanceCreationUsage(bool usage) - {m_AutomaticCreationOf3DViewInstance= usage;} - - //! Make this occurence a flexible occurence - void makeFlexible(const GLC_Matrix4x4& relativeMatrix); - - //! Make this occurence rigid - void makeRigid(); - - //! Exchange the occurrence at index position i with the occurrence at index position j - /*!This function assumes that both i and j are at least 0 but less than childCount().*/ - void swap(int i, int j); -//@} - -////////////////////////////////////////////////////////////////////// -// Private services function -////////////////////////////////////////////////////////////////////// -private: - //! Detach the occurence from the GLC_World - void detach(); - - //! Create occurrence from instance and given shader id - void doCreateOccurrenceFromInstance(GLuint shaderId); - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - //! Occurence Unique ID - GLC_uint m_Uid; - - //! the occurence's World Handle - GLC_WorldHandle* m_pWorldHandle; - - //! Number of this Occurence - int* m_pNumberOfOccurence; - - //! The struct instance of this occurence - GLC_StructInstance* m_pStructInstance; - - //! The parent of this occurence - GLC_StructOccurence* m_pParent; - - //! The Child of this occurence - QList m_Childs; - - //! The absolute matrix of the occurence - GLC_Matrix4x4 m_AbsoluteMatrix; - - //! The occurence number - unsigned int m_OccurenceNumber; - - //! Flag to know if a occurence without instance is visible - bool m_IsVisible; - - //! The occurence rendering properties - GLC_RenderProperties* m_pRenderProperties; - - //! Automatique cration of 3DViewInstance - bool m_AutomaticCreationOf3DViewInstance; - - //! The relative matrix of this occurence if this occurence is flexible - GLC_Matrix4x4* m_pRelativeMatrix; - -}; - -#endif /* GLC_STRUCTOCCURENCE_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_structreference.cpp b/ground/gcs/src/libs/glc_lib/sceneGraph/glc_structreference.cpp deleted file mode 100644 index 85ea82574..000000000 --- a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_structreference.cpp +++ /dev/null @@ -1,272 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_structreference.cpp implementation of the GLC_StructReference class. - -#include "glc_structreference.h" -#include "glc_structoccurence.h" - -// Default constructor -GLC_StructReference::GLC_StructReference(const QString& name) -: m_SetOfInstance() -, m_pRepresentation(NULL) -, m_Name(name) -, m_pAttributes(NULL) -{ - - -} - -// Create reference with representation -GLC_StructReference::GLC_StructReference(GLC_Rep* pRep) -: m_SetOfInstance() -, m_pRepresentation(pRep) -, m_Name(m_pRepresentation->name()) -, m_pAttributes(NULL) -{ - -} - -// Copy constructor -GLC_StructReference::GLC_StructReference(const GLC_StructReference& ref) -: m_SetOfInstance() -, m_pRepresentation(NULL) -, m_Name(ref.m_Name) -, m_pAttributes(new GLC_Attributes(*(ref.m_pAttributes))) -{ - if (NULL != ref.m_pRepresentation) - { - m_pRepresentation= ref.m_pRepresentation->clone(); - } -} - -//! Overload "=" operator -GLC_StructReference& GLC_StructReference::operator=(const GLC_StructReference& ref) -{ - if (this != &ref) - { - m_SetOfInstance.clear(); - delete m_pAttributes; - m_pAttributes= NULL; - - m_Name= ref.m_Name; - m_pAttributes= new GLC_Attributes(*(ref.m_pAttributes)); - - if (NULL != ref.m_pRepresentation) - { - m_pRepresentation= ref.m_pRepresentation->clone(); - } - } - return *this; -} - -GLC_StructReference::~GLC_StructReference() -{ - delete m_pRepresentation; - delete m_pAttributes; -} - - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -QSet GLC_StructReference::setOfStructOccurence() const -{ - QList instanceList= listOfStructInstances(); - QSet occurenceSet; - const int size= instanceList.size(); - for (int i= 0; i < size; ++i) - { - QList occurenceList= instanceList.at(i)->listOfStructOccurences(); - const int occurenceSize= occurenceList.size(); - for (int occIndex= 0; occIndex < occurenceSize; ++occIndex) - { - occurenceSet.insert(occurenceList.at(occIndex)); - } - } - return occurenceSet; -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// -// Set the reference representation -void GLC_StructReference::setRepresentation(const GLC_3DRep& rep) -{ - // Unload occurence representation - { - QSet structOccurenceSet= this->setOfStructOccurence(); - QSet::iterator iOcc= structOccurenceSet.begin(); - while (structOccurenceSet.constEnd() != iOcc) - { - (*iOcc)->remove3DViewInstance(); - ++iOcc; - } - } - - if(NULL == m_pRepresentation) - { - m_pRepresentation= new GLC_3DRep(rep); - } - else - { - *(m_pRepresentation)= rep; - } - - if (m_pRepresentation->isLoaded()) - { - QSet structOccurenceSet= this->setOfStructOccurence(); - QSet::iterator iOcc= structOccurenceSet.begin(); - while (structOccurenceSet.constEnd() != iOcc) - { - GLC_StructOccurence* pOccurence= *iOcc; - Q_ASSERT(!pOccurence->has3DViewInstance()); - if (pOccurence->useAutomatic3DViewInstanceCreation()) - { - pOccurence->create3DViewInstance(); - } - ++iOcc; - } - } -} - -GLC_Rep* GLC_StructReference::representationHandle() const -{ - Q_ASSERT(NULL != m_pRepresentation); - return m_pRepresentation; -} - -QString GLC_StructReference::representationName() const -{ - if (NULL != m_pRepresentation) - { - return m_pRepresentation->name(); - } - else return QString(); -} - -bool GLC_StructReference::representationIsLoaded() const -{ - if (NULL != m_pRepresentation) - { - return m_pRepresentation->isLoaded(); - } - else return false; - -} - -QString GLC_StructReference::representationFileName() const -{ - if (NULL != m_pRepresentation) - { - return m_pRepresentation->fileName(); - } - else return QString(); -} - -bool GLC_StructReference::representationIsEmpty() const -{ - if (NULL != m_pRepresentation) - { - return m_pRepresentation->isEmpty(); - } - else return true; - -} - -void GLC_StructReference::setRepresentationName(const QString& representationName) -{ - if (NULL != m_pRepresentation) - { - m_pRepresentation->setName(representationName); - } -} - -bool GLC_StructReference::loadRepresentation() -{ - Q_ASSERT(NULL != m_pRepresentation); - if (m_pRepresentation->load()) - { - QSet structOccurenceSet= this->setOfStructOccurence(); - QSet::iterator iOcc= structOccurenceSet.begin(); - while (structOccurenceSet.constEnd() != iOcc) - { - GLC_StructOccurence* pOccurence= *iOcc; - Q_ASSERT(!pOccurence->has3DViewInstance()); - if (pOccurence->useAutomatic3DViewInstanceCreation()) - { - pOccurence->create3DViewInstance(); - } - ++iOcc; - } - return true; - } - else return false; -} - -bool GLC_StructReference::unloadRepresentation() -{ - Q_ASSERT(NULL != m_pRepresentation); - if (m_pRepresentation->unload()) - { - QSet structOccurenceSet= this->setOfStructOccurence(); - QSet::iterator iOcc= structOccurenceSet.begin(); - while (structOccurenceSet.constEnd() != iOcc) - { - (*iOcc)->remove3DViewInstance(); - ++iOcc; - } - return true; - } - else return false; -} - -QList GLC_StructReference::addChild(GLC_StructOccurence* pOccurence) -{ - QList subject; - if (hasStructInstance() && firstInstanceHandle()->hasStructOccurence()) - { - QList parentOccurences= listOfStructOccurence(); - const int parentCount= parentOccurences.count(); - GLC_StructInstance* pNewInstance= NULL; - for (int i= 0; i < parentCount; ++i) - { - GLC_StructOccurence* pCurrentParent= parentOccurences.at(i); - GLC_StructOccurence* pNewChild= NULL; - if (NULL == pNewInstance) - { - pNewChild= pOccurence; - pNewInstance= pNewChild->structInstance(); - pCurrentParent->addChild(pNewChild); - } - else - { - pNewChild= pCurrentParent->addChild(pNewInstance); - } - subject.append(pNewChild); - } - } - - return subject; -} - diff --git a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_structreference.h b/ground/gcs/src/libs/glc_lib/sceneGraph/glc_structreference.h deleted file mode 100644 index 32ed53c69..000000000 --- a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_structreference.h +++ /dev/null @@ -1,238 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_structreference.h interface for the GLC_StructReference class. - -#ifndef GLC_STRUCTREFERENCE_H_ -#define GLC_STRUCTREFERENCE_H_ - -#include -#include - -#include "../geometry/glc_3drep.h" -#include "glc_3dviewinstance.h" -#include "glc_attributes.h" -#include "glc_structinstance.h" - -#include "../glc_config.h" - -class GLC_StructOccurence; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_StructReference -/*! \brief GLC_StructReference : A scene graph reference node */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_StructReference -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Default Constructor - GLC_StructReference(const QString& name= QString()); - - //! Create reference with representation - GLC_StructReference(GLC_Rep*); - - //! Copy constructor - GLC_StructReference(const GLC_StructReference&); - - //! Overload "=" operator - GLC_StructReference& operator=(const GLC_StructReference&); - - //! Destructor - virtual ~GLC_StructReference(); -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return true if this reference has instance - inline bool hasStructInstance() const - { return !m_SetOfInstance.isEmpty();} - - //! Return first instance handle - inline GLC_StructInstance* firstInstanceHandle() const - { return *(m_SetOfInstance.begin());} - - //! Return the list of instance of this reference - inline QList listOfStructInstances() const - { return m_SetOfInstance.toList();} - - //! Return the Set of occurence of this reference - QSet setOfStructOccurence() const; - - //! Return the list of occurence of this reference - inline QList listOfStructOccurence() const - {return setOfStructOccurence().toList();} - - //! Return true if this reference has a representation - inline bool hasRepresentation() const - {return NULL != m_pRepresentation;} - - //! Return the representation of this reference - /*! The representation must exists*/ - GLC_Rep* representationHandle() const; - - //! Return the name - inline QString name() const - {return m_Name;} - - //! Get number of faces - inline unsigned int numberOfFaces() const - { - Q_ASSERT(NULL != m_pRepresentation); - GLC_3DRep* pRep= dynamic_cast(m_pRepresentation); - if (NULL != pRep) return pRep->faceCount(); - else return 0; - } - - //! Get number of vertex - inline unsigned int numberOfVertex() const - { - Q_ASSERT(NULL != m_pRepresentation); - GLC_3DRep* pRep= dynamic_cast(m_pRepresentation); - if (NULL != pRep) return pRep->vertexCount(); - else return 0; - } - - //! Get number of materials - inline unsigned int numberOfMaterials() const - { - Q_ASSERT(NULL != m_pRepresentation); - GLC_3DRep* pRep= dynamic_cast(m_pRepresentation); - if (NULL != pRep) return pRep->materialCount(); - else return 0; - } - - //! Return the number of body - inline unsigned int numberOfBody() const - { - if(NULL != m_pRepresentation) - { - GLC_3DRep* pRep= dynamic_cast(m_pRepresentation); - if (NULL != pRep) return pRep->numberOfBody(); - else return 0; - } - else return 0; - } - - //! Get materials List - inline QSet materialSet() const - { - Q_ASSERT(NULL != m_pRepresentation); - GLC_3DRep* pRep= dynamic_cast(m_pRepresentation); - if (NULL != pRep) return pRep->materialSet(); - else return QSet(); - } - - //! Return true if the reference contains User attributes - inline bool containsAttributes() const - { return ((NULL != m_pAttributes) && !m_pAttributes->isEmpty());} - - //! Return handle to the reference attributes - inline GLC_Attributes* attributesHandle() const - {return m_pAttributes;} - - //! Return the name of the representation - QString representationName() const; - - //! Return true if the representation is loaded - bool representationIsLoaded() const; - - //! Return the representation file name - QString representationFileName() const; - - //! Return true if the representation is empty or if there is no representation - bool representationIsEmpty() const; - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! An Instance of this reference have been created - inline void structInstanceCreated(GLC_StructInstance* pInstance) - { - Q_ASSERT(!m_SetOfInstance.contains(pInstance)); - m_SetOfInstance << pInstance; - } - - //! An Instance of this reference have been deleted - inline void structInstanceDeleted(GLC_StructInstance* pInstance) - {m_SetOfInstance.remove(pInstance);} - - //! Set the reference name - inline void setName(const QString& name) - {m_Name= name;} - - //! Set the reference representation - void setRepresentation(const GLC_3DRep& rep); - - //! Set the reference attributes - inline void setAttributes(const GLC_Attributes& attr) - { - delete m_pAttributes; - m_pAttributes= new GLC_Attributes(attr); - } - - //! Set the representation name - void setRepresentationName(const QString& representationName); - - //! Load the representation - /*! The representation must exists*/ - bool loadRepresentation(); - - //! Unload the representation - /*! The representation must exists*/ - bool unloadRepresentation(); - - //! Add the given occurence as a child of all occurrences of this reference - /*! Return the list of added occurence*/ - QList addChild(GLC_StructOccurence* pOccurence); - - -//@} - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// -private: - //! The Set of reference's instances - QSet m_SetOfInstance; - - //! The representation of reference - GLC_Rep* m_pRepresentation; - - //! The Reference Name - QString m_Name; - - //! The Reference attributes - GLC_Attributes* m_pAttributes; - -}; - -#endif /* GLC_STRUCTREFERENCE_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_world.cpp b/ground/gcs/src/libs/glc_lib/sceneGraph/glc_world.cpp deleted file mode 100644 index 484ba43f7..000000000 --- a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_world.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_world.cpp implementation of the GLC_World class. - -#include "glc_world.h" -#include "glc_structinstance.h" -#include "glc_structreference.h" - -GLC_World::GLC_World() -: m_pWorldHandle(new GLC_WorldHandle()) -, m_pRoot(new GLC_StructOccurence()) -{ - m_pRoot->setWorldHandle(m_pWorldHandle); -} - -GLC_World::GLC_World(GLC_StructOccurence* pOcc) -: m_pWorldHandle(new GLC_WorldHandle()) -, m_pRoot(pOcc) -{ - m_pRoot->setWorldHandle(m_pWorldHandle); -} - -GLC_World::GLC_World(const GLC_World& world) -: m_pWorldHandle(world.m_pWorldHandle) -, m_pRoot(world.m_pRoot) -{ - //qDebug() << "GLC_World::GLC_World() : " << (*m_pNumberOfWorld) << " " << this; - // Increment the number of world - m_pWorldHandle->increment(); - -} - -GLC_World::~GLC_World() -{ - // Decrement the number of world - m_pWorldHandle->decrement(); - if (m_pWorldHandle->isOrphan()) - { - // this is the last World, delete the root product and collection - //m_pWorldHandle->collection()->clear(); // Clear collection first (performance) - delete m_pRoot; - delete m_pWorldHandle; - } -} - -GLC_StructOccurence* GLC_World::takeRootOccurrence() -{ - GLC_StructOccurence* pSubject= m_pRoot; - pSubject->makeOrphan(); - - m_pRoot= new GLC_StructOccurence(); - m_pRoot->setWorldHandle(m_pWorldHandle); - - return pSubject; -} - -void GLC_World::replaceRootOccurrence(GLC_StructOccurence* pOcc) -{ - Q_ASSERT(pOcc->isOrphan()); - delete m_pRoot; - m_pRoot= pOcc; - m_pRoot->setWorldHandle(m_pWorldHandle); -} - -void GLC_World::mergeWithAnotherWorld(GLC_World& anotherWorld) -{ - GLC_StructOccurence* pAnotherRoot= anotherWorld.rootOccurence(); - if (pAnotherRoot->childCount() > 0) - { - QList childs= pAnotherRoot->children(); - const int size= childs.size(); - for (int i= 0; i < size; ++i) - { - m_pRoot->addChild(childs.at(i)->clone(m_pWorldHandle, false)); - } - m_pRoot->updateChildrenAbsoluteMatrix(); - } - else - { - m_pRoot->addChild(anotherWorld.rootOccurence()->clone(m_pWorldHandle, false)); - } -} - -GLC_World& GLC_World::operator=(const GLC_World& world) -{ - if (this != &world) - { - // Decrement the number of world - m_pWorldHandle->decrement(); - if (m_pWorldHandle->isOrphan()) - { - // this is the last World, delete the root product and collection - //m_pWorldHandle->collection()->clear(); // Clear collection first (performance) - delete m_pRoot; - delete m_pWorldHandle; - } - m_pRoot= world.m_pRoot; - m_pWorldHandle= world.m_pWorldHandle; - m_pWorldHandle->increment(); - } - return *this; -} diff --git a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_world.h b/ground/gcs/src/libs/glc_lib/sceneGraph/glc_world.h deleted file mode 100644 index f4a49f720..000000000 --- a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_world.h +++ /dev/null @@ -1,288 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_world.h interface for the GLC_World class. - -#ifndef GLC_WORLD_H_ -#define GLC_WORLD_H_ - -#include "glc_3dviewcollection.h" -#include "glc_structoccurence.h" -#include "glc_structreference.h" -#include "glc_structinstance.h" -#include "glc_worldhandle.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_World -/*! \brief GLC_World : The Root of GLC_Lib Scene Graph*/ -/*! - * GLC_World contain : - * - The Scene root GLC_Product. - * - a GLC_3DViewCollection which manage all scene shapes (GLC_3DViewInstance) - * - */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_World -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Default constructor - GLC_World(); - - //! Create a world and set the root occurrence to the given occurrence - explicit GLC_World(GLC_StructOccurence* pOcc); - - //! Copy constructor - GLC_World(const GLC_World&); - - //! Destructor - virtual ~GLC_World(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the entire world Bounding Box - inline GLC_BoundingBox boundingBox() - { return m_pWorldHandle->collection()->boundingBox();} - - //! Return the root of the world - inline GLC_StructOccurence* rootOccurence() const - {return m_pRoot;} - - //! Return the world collection - inline GLC_3DViewCollection* collection() - {return m_pWorldHandle->collection();} - - //! Return the size of the world - inline int size() const - {return m_pWorldHandle->collection()->size();} - - //! Return true if the world is empty - inline bool isEmpty() const - {return m_pWorldHandle->collection()->isEmpty() && !m_pRoot->hasChild();} - - //! Return number of faces - inline int numberOfFaces() const - {return m_pRoot->numberOfFaces();} - - //! Return number of vertex - inline int numberOfVertex() const - {return m_pRoot->numberOfVertex();} - - //! Return the number of materials - inline int numberOfMaterials() const - {return m_pRoot->numberOfMaterials();} - - //! Return the list of material - inline QList listOfMaterials() const - {return m_pRoot->materialSet().toList();} - - //! Return list of world's instances - inline QList instancesHandle() const - {return m_pWorldHandle->collection()->instancesHandle();} - - //! Return all visible GLC_3DViewInstance from the world - inline QList visibleInstancesHandle() const - {return m_pWorldHandle->collection()->visibleInstancesHandle();} - - //! Return instances name from the specified shading group - inline QList instanceNamesFromShadingGroup(GLuint id) const - {return m_pWorldHandle->collection()->instanceNamesFromShadingGroup(id);} - - //! Return the number of used shading group - inline int numberOfUsedShadingGroup() const - {return m_pWorldHandle->collection()->numberOfUsedShadingGroup();} - - //! Return the worldHandle of this world - inline GLC_WorldHandle* worldHandle() - {return m_pWorldHandle;} - - //! Return the occurence specified by an id - /*! Id must be a valid identifier*/ - inline GLC_StructOccurence* occurence(GLC_uint id) const - {return m_pWorldHandle->getOccurence(id);} - - //! Return the list off occurences - inline QList listOfOccurence() const - {return m_pWorldHandle->occurences();} - - //! Return the number of occurence - inline int numberOfOccurence() const - {return m_pWorldHandle->numberOfOccurence();} - - //! Return true if the world contians specified id - inline int containsOccurence(GLC_uint id) const - {return m_pWorldHandle->containsOccurence(id);} - - //! Return the list of instance - inline QList instances() const - {return m_pWorldHandle->instances();} - - //! Return the list of Reference - inline QList references() const - {return m_pWorldHandle->references();} - - //! Return the number of body - inline int numberOfBody() const - {return m_pWorldHandle->numberOfBody();} - - //! Return the number of representation - inline int representationCount() const - {return m_pWorldHandle->representationCount();} - - //! Return the world Up vector - inline GLC_Vector3d upVector() const - {return m_pWorldHandle->upVector();} - - //! Return the number of selected occurence - int selectionSize() const - {return m_pWorldHandle->selectionSetHandle()->size();} - - //! Return true if the given occurence is selected - inline bool isSelected(const GLC_StructOccurence* pOccurence) const - {return m_pWorldHandle->selectionSetHandle()->contains(pOccurence);} - - //! Return true if the given occurence id is selected - inline bool isSelected(GLC_uint selectionId) const - {return m_pWorldHandle->selectionSetHandle()->contains(selectionId);} - - //! Return the list of selected occurences - inline QList selectedOccurenceList() const - {return m_pWorldHandle->selectionSetHandle()->occurencesList();} - - //! Take the root occurence of this world - GLC_StructOccurence* takeRootOccurrence(); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Replace the root occurrence of this world by the given occurrence - void replaceRootOccurrence(GLC_StructOccurence* pOcc); - - //! Merge this world with another world - void mergeWithAnotherWorld(GLC_World &); - - //! Reverse worlds part normal - inline void reversePartNormal() {m_pRoot->reverseNormals();} - - //! Clear this world - GLC_World& clear() {return *this= GLC_World();} - - //! Set the World root Name - inline void setRootName(const QString& name) - {m_pRoot->setName(name);} - - //! Set the world Up Vector - inline void setUpVector(const GLC_Vector3d& vect) - {m_pWorldHandle->setUpVector(vect);} - - //! Set the attached viewport of this world - inline void setAttachedViewport(GLC_Viewport* pViewport) - {m_pWorldHandle->setAttachedViewport(pViewport);} - - //! Select the given occurence - /*! The given occurence must belong to the world handle of this world*/ - inline void select(const GLC_StructOccurence* pOccurence) - {m_pWorldHandle->select(pOccurence->id());} - - //! Select the given occurence id - /*! The given occurence id must belong to the world handle of this world*/ - inline void select(GLC_uint occurenceId) - {m_pWorldHandle->select(occurenceId);} - - //! Unselect the given occurence id - /*! The given occurence id must belong to the world handle of this world*/ - inline void unselect(GLC_uint occurenceId) - {m_pWorldHandle->unselect(occurenceId);} - - //! Select all occurence of this world with a 3DViewInstance - inline void selectAllWith3DViewInstance() - {m_pWorldHandle->selectAllWith3DViewInstance(true);} - - //! Select all occurence of this world with a 3DViewInstance in the current show state - inline void selectAllWith3DViewInstanceInCurrentShowState() - {m_pWorldHandle->selectAllWith3DViewInstance(false);} - - //! Unselect all occurence of this world - inline void unselectAll() - {m_pWorldHandle->unselectAll();} - - //! Show / Hide selected 3DViewInstance - inline void showHideSelected3DViewInstance() - {m_pWorldHandle->showHideSelected3DViewInstance();} - - //! Show selected 3DViewInstance - inline void showSelected3DViewInstance() - {m_pWorldHandle->setSelected3DViewInstanceVisibility(true);} - - //! Hide selected 3DViewInstance - inline void hideSelected3DViewInstance() - {m_pWorldHandle->setSelected3DViewInstanceVisibility(false);} -//@} - -////////////////////////////////////////////////////////////////////// -/*! @name Operator Overload */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Assignement operator - GLC_World& operator=(const GLC_World&); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Display the world - inline void render(GLuint groupId, glc::RenderFlag renderFlag= glc::ShadingFlag) - {m_pWorldHandle->collection()->render(groupId, renderFlag);} - - //! Display the world's shader group - inline void renderShaderGroup(glc::RenderFlag renderFlag= glc::ShadingFlag) - {m_pWorldHandle->collection()->renderShaderGroup(renderFlag);} - -//@} -////////////////////////////////////////////////////////////////////// -// private members -////////////////////////////////////////////////////////////////////// -private: - //! The World Handle - GLC_WorldHandle* m_pWorldHandle; - - //! The root of the structure - GLC_StructOccurence* m_pRoot; -}; - -#endif /*GLC_WORLD_H_*/ diff --git a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_worldhandle.cpp b/ground/gcs/src/libs/glc_lib/sceneGraph/glc_worldhandle.cpp deleted file mode 100644 index 2c2106d13..000000000 --- a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_worldhandle.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -#include "glc_worldhandle.h" -#include "glc_structreference.h" -#include - -GLC_WorldHandle::GLC_WorldHandle() -: m_Collection() -, m_NumberOfWorld(1) -, m_OccurenceHash() -, m_UpVector(glc::Z_AXIS) -, m_SelectionSet(this) -{ - -} - -GLC_WorldHandle::~GLC_WorldHandle() -{ - -} - -// Return the list of instance -QList GLC_WorldHandle::instances() const -{ - QSet instancesSet; - QHash::const_iterator iOccurence= m_OccurenceHash.constBegin(); - while (iOccurence != m_OccurenceHash.constEnd()) - { - instancesSet.insert(iOccurence.value()->structInstance()); - ++iOccurence; - } - return instancesSet.toList(); -} - -// Return the list of Reference -QList GLC_WorldHandle::references() const -{ - QSet referencesSet; - QHash::const_iterator iOccurence= m_OccurenceHash.constBegin(); - while (iOccurence != m_OccurenceHash.constEnd()) - { - referencesSet.insert(iOccurence.value()->structReference()); - ++iOccurence; - } - return referencesSet.toList(); -} - -// Return the number of body -int GLC_WorldHandle::numberOfBody() const -{ - QList referenceList(references()); - const int size= referenceList.size(); - int numberOfBody= 0; - for (int i= 0; i < size; ++i) - { - numberOfBody+= referenceList.at(i)->numberOfBody(); - } - return numberOfBody; -} - -int GLC_WorldHandle::representationCount() const -{ - QList referenceList(references()); - const int size= referenceList.size(); - int count= 0; - for (int i= 0; i < size; ++i) - { - if (referenceList.at(i)->hasRepresentation()) ++count; - } - return count; - -} - -// An Occurence has been added -void GLC_WorldHandle::addOccurence(GLC_StructOccurence* pOccurence, bool isSelected, GLuint shaderId) -{ - Q_ASSERT(!m_OccurenceHash.contains(pOccurence->id())); - m_OccurenceHash.insert(pOccurence->id(), pOccurence); - GLC_StructReference* pRef= pOccurence->structReference(); - Q_ASSERT(NULL != pRef); - - // Add instance representation in the collection - if (pOccurence->useAutomatic3DViewInstanceCreation() && pRef->representationIsLoaded()) - { - pOccurence->create3DViewInstance(shaderId); - if (isSelected) select(pOccurence->id()); - } -} - -// An Occurence has been removed -void GLC_WorldHandle::removeOccurence(GLC_StructOccurence* pOccurence) -{ - Q_ASSERT(m_OccurenceHash.contains(pOccurence->id())); - // Remove the occurence from the selection set - m_SelectionSet.remove(pOccurence); - // Remove the occurence from the main occurence hash table - m_OccurenceHash.remove(pOccurence->id()); - // Remove instance representation from the collection - m_Collection.remove(pOccurence->id()); -} - -void GLC_WorldHandle::select(GLC_uint occurenceId) -{ - Q_ASSERT(m_OccurenceHash.contains(occurenceId)); - m_SelectionSet.insert(occurenceId); - m_Collection.select(occurenceId); - - const GLC_StructOccurence* pSelectedOccurence= m_OccurenceHash.value(occurenceId); - if (pSelectedOccurence->hasChild()) - { - QList subOccurenceList= pSelectedOccurence->subOccurenceList(); - const int subOccurenceCount= subOccurenceList.size(); - for (int i= 0; i < subOccurenceCount; ++i) - { - const GLC_uint currentOccurenceId= subOccurenceList.at(i)->id(); - if (m_Collection.contains(currentOccurenceId)) - { - m_Collection.select(currentOccurenceId); - } - } - } -} - -void GLC_WorldHandle::unselect(GLC_uint occurenceId, bool propagate) -{ - Q_ASSERT(m_OccurenceHash.contains(occurenceId)); - m_SelectionSet.remove(occurenceId); - m_Collection.unselect(occurenceId); - - const GLC_StructOccurence* pSelectedOccurence= m_OccurenceHash.value(occurenceId); - if (propagate && pSelectedOccurence->hasChild()) - { - QList subOccurenceList= pSelectedOccurence->subOccurenceList(); - const int subOccurenceCount= subOccurenceList.size(); - for (int i= 0; i < subOccurenceCount; ++i) - { - const GLC_uint currentOccurenceId= subOccurenceList.at(i)->id(); - m_Collection.unselect(currentOccurenceId); - } - } -} - -void GLC_WorldHandle::selectAllWith3DViewInstance(bool allShowState) -{ - m_Collection.selectAll(allShowState); - QList selectedId= m_Collection.selection()->keys(); - m_SelectionSet.clear(); - const int selectionCount= selectedId.count(); - for (int i= 0; i < selectionCount; ++i) - { - m_SelectionSet.insert(selectedId.at(i)); - } -} - -void GLC_WorldHandle::unselectAll() -{ - m_SelectionSet.clear(); - m_Collection.unselectAll(); -} - -void GLC_WorldHandle::showHideSelected3DViewInstance() -{ - QList selected3dviewInstance= m_Collection.selection()->values(); - const int instanceCount= selected3dviewInstance.count(); - for(int i= 0; i < instanceCount; ++i) - { - GLC_3DViewInstance* pCurrentInstance= selected3dviewInstance.at(i); - pCurrentInstance->setVisibility(!pCurrentInstance->isVisible()); - } -} - -void GLC_WorldHandle::setSelected3DViewInstanceVisibility(bool isVisible) -{ - QList selected3dviewInstance= m_Collection.selection()->values(); - const int instanceCount= selected3dviewInstance.count(); - for(int i= 0; i < instanceCount; ++i) - { - GLC_3DViewInstance* pCurrentInstance= selected3dviewInstance.at(i); - pCurrentInstance->setVisibility(isVisible); - } -} - diff --git a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_worldhandle.h b/ground/gcs/src/libs/glc_lib/sceneGraph/glc_worldhandle.h deleted file mode 100644 index b16e850ef..000000000 --- a/ground/gcs/src/libs/glc_lib/sceneGraph/glc_worldhandle.h +++ /dev/null @@ -1,186 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -#ifndef GLC_WORLDHANDLE_H_ -#define GLC_WORLDHANDLE_H_ - -#include "glc_3dviewcollection.h" -#include "glc_structoccurence.h" -#include "glc_selectionset.h" - -#include - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_WorldHandle -/*! \brief GLC_WorldHandle : Handle of shared GLC_World*/ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_WorldHandle -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! The default constructor - GLC_WorldHandle(); - - //! The default destructor - ~GLC_WorldHandle(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the collection - inline GLC_3DViewCollection* collection() - {return &m_Collection;} - - //! Return the number of world associated with this handle - inline int numberOfWorld() const - {return m_NumberOfWorld;} - - //! Return true if there is only one world associated with this handle - inline bool isOrphan() const - {return m_NumberOfWorld == 0;} - - //! Return true if the specified occurence id is in this world - inline bool containsOccurence(GLC_uint id) const - {return m_OccurenceHash.contains(id);} - - //! Return the occurence specified by an id - /*! Id must be a valid identifier*/ - inline GLC_StructOccurence* getOccurence(GLC_uint id) const - { - Q_ASSERT(m_OccurenceHash.contains(id)); - return m_OccurenceHash.value(id); - } - - //! Return the list off occurences - inline QList occurences() const - {return m_OccurenceHash.values();} - - //! Return the number of occurence - inline int numberOfOccurence() const - {return m_OccurenceHash.size();} - - //! Return the list of instance - QList instances() const; - - //! Return the list of Reference - QList references() const; - - //! Return the number of body - int numberOfBody() const; - - //! Return the number of representation - int representationCount() const; - - //! Return the world Up vector - inline GLC_Vector3d upVector() const - {return m_UpVector;} - - //! Return an handle to the selection set - inline GLC_SelectionSet* selectionSetHandle() - {return &m_SelectionSet;} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Increment the number of world - inline void increment() - {++m_NumberOfWorld;} - - //! Decrement the number of world - inline void decrement() - {--m_NumberOfWorld;} - - //! An Occurence has been added - void addOccurence(GLC_StructOccurence* pOccurence, bool isSelected= false, GLuint shaderId= 0); - - //! An Occurence has been removed - void removeOccurence(GLC_StructOccurence* pOccurence); - - //! All Occurence has been removed - inline void removeAllOccurences() - { - m_OccurenceHash.clear(); - } - - //! Set the world Up Vector - inline void setUpVector(const GLC_Vector3d& vect) - {m_UpVector= vect;} - - //! Set the attached viewport of this world handle - inline void setAttachedViewport(GLC_Viewport* pViewport) - {m_Collection.setAttachedViewport(pViewport);} - - //! Select the given occurence id - /*! The given occurence id must belong to this worldhandle*/ - void select(GLC_uint occurenceId); - - //! Unselect the given occurence id - /*! The given occurence id must belong to this worldhandle*/ - void unselect(GLC_uint occurenceId, bool propagate= true); - - //! Select all occurence of this world handle - void selectAllWith3DViewInstance(bool allShowState); - - //! Unselect all occurence of this world handle - void unselectAll(); - - //! Show / Hide selected 3DViewInstance - void showHideSelected3DViewInstance(); - - //! Set selected 3DViewInstance visibility - void setSelected3DViewInstanceVisibility(bool isVisible); - -//@} - -////////////////////////////////////////////////////////////////////// -// private members -////////////////////////////////////////////////////////////////////// -private: - //! The Collection - GLC_3DViewCollection m_Collection; - - //! Number of this world - int m_NumberOfWorld; - - //! The hash table containing struct occurence - QHash m_OccurenceHash; - - //! This world Up Vector - GLC_Vector3d m_UpVector; - - //! This world selectionSet - GLC_SelectionSet m_SelectionSet; -}; - -#endif /* GLC_WORLDHANDLE_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/shading/glc_light.cpp b/ground/gcs/src/libs/glc_lib/shading/glc_light.cpp deleted file mode 100644 index c08708c59..000000000 --- a/ground/gcs/src/libs/glc_lib/shading/glc_light.cpp +++ /dev/null @@ -1,364 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_light.cpp implementation of the GLC_Light class. - -#include -#include - -#include "glc_light.h" -#include "../glc_openglexception.h" -#include "../glc_context.h" - -GLint GLC_Light::m_MaxLight= 8; -QHash > GLC_Light::m_ContextToFreeLightSet; - -////////////////////////////////////////////////////////////////////// -// Constructor Destructor -////////////////////////////////////////////////////////////////////// -GLC_Light::GLC_Light(const QGLContext* pContext, const QColor& color) -:GLC_Object("Light") -, m_LightID(-1) -, m_LightType(LightPosition) -, m_AmbientColor(Qt::black) -, m_DiffuseColor(color) -, m_SpecularColor(Qt::white) -, m_Position() -, m_SpotDirection(0.0, 0.0, -1.0) -, m_SpotExponent(0.0f) -, m_SpotCutoffAngle(180.0f) -, m_ConstantAttenuation(1.0f) -, m_LinearAttenuation(0.0f) -, m_QuadraticAttenuation(0.0f) -, m_TwoSided(false) -, m_pContext(const_cast(pContext)) -, m_IsValid(false) -{ - addNewLight(); -} - -GLC_Light::GLC_Light(LightType lightType, const QGLContext* pContext, const QColor& color) -:GLC_Object("Light") -, m_LightID(-1) -, m_LightType(lightType) -, m_AmbientColor(Qt::black) -, m_DiffuseColor(color) -, m_SpecularColor(Qt::white) -, m_Position() -, m_SpotDirection(0.0, 0.0, -1.0) -, m_SpotExponent(0.0f) -, m_SpotCutoffAngle(180.0f) -, m_ConstantAttenuation(1.0f) -, m_LinearAttenuation(0.0f) -, m_QuadraticAttenuation(0.0f) -, m_TwoSided(false) -, m_pContext(const_cast(pContext)) -, m_IsValid(false) -{ - addNewLight(); -} - -GLC_Light::GLC_Light(const GLC_Light& light) -:GLC_Object(light) -, m_LightID(-1) -, m_LightType(light.m_LightType) -, m_AmbientColor(light.m_AmbientColor) -, m_DiffuseColor(light.m_DiffuseColor) -, m_SpecularColor(light.m_SpecularColor) -, m_Position(light.m_Position) -, m_SpotDirection(light.m_SpotDirection) -, m_SpotExponent(light.m_SpotExponent) -, m_SpotCutoffAngle(light.m_SpotCutoffAngle) -, m_ConstantAttenuation(light.m_ConstantAttenuation) -, m_LinearAttenuation(light.m_LinearAttenuation) -, m_QuadraticAttenuation(light.m_QuadraticAttenuation) -, m_TwoSided(light.m_TwoSided) -, m_pContext(light.m_pContext) -, m_IsValid(false) -{ - addNewLight(); -} - -GLC_Light::~GLC_Light(void) -{ - removeThisLight(); -} - -///////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -int GLC_Light::maxLightCount() -{ - return m_MaxLight; -} - -int GLC_Light::builtAbleLightCount(QGLContext* pContext) -{ - if (m_ContextToFreeLightSet.contains(pContext)) - { - return m_ContextToFreeLightSet.value(pContext).size(); - } - else return m_MaxLight; -} - -///////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// -void GLC_Light::initForThisContext() -{ - for (int i= 0; i < m_MaxLight; ++i) - { - m_ContextToFreeLightSet[m_pContext].insert(GL_LIGHT0 + i); - } -} - -void GLC_Light::setPosition(const GLC_Point3d &pos) -{ - m_Position= pos; -} - -void GLC_Light::setPosition(GLfloat x, GLfloat y, GLfloat z) -{ - m_Position.setVect(static_cast(x), static_cast(y), static_cast(z)); -} - -void GLC_Light::setAmbientColor(const QColor& color) -{ - m_AmbientColor= color; - m_IsValid= false; -} - -void GLC_Light::setDiffuseColor(const QColor& color) -{ - m_DiffuseColor= color; - m_IsValid= false; -} - -void GLC_Light::setSpecularColor(const QColor& color) -{ - m_SpecularColor= color; - m_IsValid= false; -} - -void GLC_Light::setTwoSided(const bool mode) -{ - m_TwoSided= mode; - m_IsValid= false; -} - -void GLC_Light::setConstantAttenuation(GLfloat constantAttenuation) -{ - m_ConstantAttenuation= constantAttenuation; - m_IsValid= false; -} - -void GLC_Light::setLinearAttenuation(GLfloat linearAttenuation) -{ - m_LinearAttenuation= linearAttenuation; - m_IsValid= false; -} - -void GLC_Light::setQuadraticAttenuation(GLfloat quadraticAttenuation) -{ - m_QuadraticAttenuation= quadraticAttenuation; - m_IsValid= false; -} - -void GLC_Light::setSpotDirection(const GLC_Vector3d& direction) -{ - m_SpotDirection= direction; - m_IsValid= false; -} - -void GLC_Light::setSpotCutoffAngle(GLfloat cutoffAngle) -{ - m_SpotCutoffAngle= cutoffAngle; - m_IsValid= false; -} - -void GLC_Light::setSpotEponent(GLfloat exponent) -{ - m_SpotExponent= exponent; - m_IsValid= false; -} - -////////////////////////////////////////////////////////////////////// -// OpenGL Functions -////////////////////////////////////////////////////////////////////// - - -void GLC_Light::disable() -{ - if (NULL != m_pContext) - { - glDisable(m_LightID); - } -} - - -void GLC_Light::glExecute() -{ - if (NULL == m_pContext) - { - m_pContext= const_cast(QGLContext::currentContext()); - Q_ASSERT(NULL != m_pContext); - addNewLight(); - } - - GLC_Context::current()->glcEnableLighting(true); - glEnable(m_LightID); - - if (m_pContext != QGLContext::currentContext()) - { - Q_ASSERT(QGLContext::areSharing(m_pContext, QGLContext::currentContext())); - m_IsValid= false; - } - Q_ASSERT(m_pContext->isValid()); - - GLfloat setArray[4]; - - // Position - setArray[0]= static_cast(m_Position.x()); - setArray[1]= static_cast(m_Position.y()); - setArray[2]= static_cast(m_Position.z()); - - if (LightDirection == m_LightType) - { - setArray[3]= 0.0f; - glLightfv(m_LightID, GL_POSITION, setArray); // Direction of the Light - } - else - { - setArray[3]= 1.0f; - glLightfv(m_LightID, GL_POSITION, setArray); // Position of the Light - } - - - if (!m_IsValid) - { - // Set the lighting model - if (m_TwoSided) - { - glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1); - } - else - { - glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0); - } - - // Color - setArray[0]= static_cast(m_AmbientColor.redF()); - setArray[1]= static_cast(m_AmbientColor.greenF()); - setArray[2]= static_cast(m_AmbientColor.blueF()); - setArray[3]= static_cast(m_AmbientColor.alphaF()); - glLightfv(m_LightID, GL_AMBIENT, setArray); // Setup The Ambient Light - - setArray[0]= static_cast(m_DiffuseColor.redF()); - setArray[1]= static_cast(m_DiffuseColor.greenF()); - setArray[2]= static_cast(m_DiffuseColor.blueF()); - setArray[3]= static_cast(m_DiffuseColor.alphaF()); - glLightfv(m_LightID, GL_DIFFUSE, setArray); // Setup The Diffuse Light - - - setArray[0]= static_cast(m_SpecularColor.redF()); - setArray[1]= static_cast(m_SpecularColor.greenF()); - setArray[2]= static_cast(m_SpecularColor.blueF()); - setArray[3]= static_cast(m_SpecularColor.alphaF()); - glLightfv(m_LightID, GL_SPECULAR, setArray); // Setup The specular Light - - if (LightDirection != m_LightType) - glLightf(m_LightID, GL_CONSTANT_ATTENUATION, m_ConstantAttenuation); - glLightf(m_LightID, GL_LINEAR_ATTENUATION, m_LinearAttenuation); - glLightf(m_LightID, GL_QUADRATIC_ATTENUATION, m_QuadraticAttenuation); - - // Spot light parameters - if (LightSpot == m_LightType) - { - // Spot Direction - setArray[0]= static_cast(m_SpotDirection.x()); - setArray[1]= static_cast(m_SpotDirection.y()); - setArray[2]= static_cast(m_SpotDirection.z()); - glLightfv(m_LightID, GL_SPOT_DIRECTION, setArray); - glLightf(m_LightID, GL_SPOT_EXPONENT, m_SpotExponent); - glLightf(m_LightID, GL_SPOT_CUTOFF, m_SpotCutoffAngle); - } - - m_IsValid= true; - } - - // OpenGL error handler - GLenum error= glGetError(); - if (error != GL_NO_ERROR) - { - qDebug() << "GLC_Light::glExecute Exception, id= " << m_LightID; - GLC_OpenGlException OpenGlException("GLC_Light::glExecute ", error); - throw(OpenGlException); - } - -} - -////////////////////////////////////////////////////////////////////// -// Private services Functions -////////////////////////////////////////////////////////////////////// - - -////////////////////////////////////////////////////////////////////// -// Private services fonction -////////////////////////////////////////////////////////////////////// -void GLC_Light::addNewLight() -{ - if (NULL != m_pContext) - { - if (!m_ContextToFreeLightSet.contains(m_pContext)) - { - m_ContextToFreeLightSet.insert(m_pContext, QSet()); - initForThisContext(); - } - - // Some OpenGL driver support only Light0 ??? - if (m_ContextToFreeLightSet.value(m_pContext).size() == m_MaxLight) - { - m_LightID= GL_LIGHT0; - } - else - { - m_LightID= *(m_ContextToFreeLightSet[m_pContext].constBegin()); - } - - m_ContextToFreeLightSet[m_pContext].remove(m_LightID); - } -} - -void GLC_Light::removeThisLight() -{ - if (NULL != m_pContext) - { - Q_ASSERT(m_ContextToFreeLightSet.contains(m_pContext)); - Q_ASSERT(!m_ContextToFreeLightSet[m_pContext].contains(m_LightID)); - m_ContextToFreeLightSet[m_pContext].insert(m_LightID); - if (m_ContextToFreeLightSet[m_pContext].size() == m_MaxLight) - { - m_ContextToFreeLightSet.remove(m_pContext); - } - } -} diff --git a/ground/gcs/src/libs/glc_lib/shading/glc_light.h b/ground/gcs/src/libs/glc_lib/shading/glc_light.h deleted file mode 100644 index 761e76d2f..000000000 --- a/ground/gcs/src/libs/glc_lib/shading/glc_light.h +++ /dev/null @@ -1,274 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_light.h interface for the GLC_Light class. - -#ifndef GLC_LIGHT_H_ -#define GLC_LIGHT_H_ - -#include -#include -#include - -#include "../glc_object.h" -#include "../maths/glc_vector3d.h" - -#include "../glc_config.h" - -class QGLContext; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Light -/*! \brief GLC_Light : OpenGL Point Light*/ - -/*! An GLC_Light is an OpenGL point Light source at a 3D location\n - * Point light is omnidirectional and have color*/ -////////////////////////////////////////////////////////////////////// - -class GLC_LIB_EXPORT GLC_Light : public GLC_Object -{ -public: - //! Light Type enum - enum LightType - { - LightPosition= 0, - LightDirection= 1, - LightSpot= 2 - }; -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Construct a default GLC_Light - /*! By default, ambient color is black, diffuse Color is white and specular color is white*/ - GLC_Light(const QGLContext* pContext= NULL, const QColor& color= Qt::white); - - //! Construct a default GLC_Light - /*! By default, ambient color is black, diffuse Color is white and specular color is white*/ - GLC_Light(LightType lightType, const QGLContext* pContext= NULL, const QColor& color= Qt::white); - - //! Copy constructor - GLC_Light(const GLC_Light& light); - - //! Delete OpenGL list - virtual ~GLC_Light(void); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the maximum number light - static int maxLightCount(); - - //! Return the number of builtable light - static int builtAbleLightCount(QGLContext* pContext); - - //! Return a GLC_Point3d representing light position - inline GLC_Point3d position(void) const - {return m_Position;} - - //! Return the QColor of the light's ambient color - inline QColor ambientColor() const - {return m_AmbientColor;} - - //! Return the QColor of the light's Diffuse color - inline QColor diffuseColor() const - { return m_DiffuseColor;} - - //! Return the QColor of the light's Specular color - inline QColor specularColor() const - {return m_SpecularColor;} - - //! Return true if the light used two sided ilumination - inline bool isTwoSided() const - {return m_TwoSided;} - - //! Return the type of this light - inline LightType type() const - {return m_LightType;} - - //! Return the OpenGL ID of this light - inline GLenum openglID() const - {return m_LightID;} - - //! Return this light const attenuation - inline GLfloat constantAttenuation() const - {return m_ConstantAttenuation;} - - //! Return this light linear attenuation - inline GLfloat linearAttenuation() const - {return m_LinearAttenuation;} - - //! Return this light quadratic attenuation - inline GLfloat quadraticAttenuation() const - {return m_QuadraticAttenuation;} - - //! Return this light spot direction - inline GLC_Vector3d spotDirection() const - {return m_SpotDirection;} - - //! Return this light spot cutoff angle - inline GLfloat spotCutoffAngle() const - {return m_SpotCutoffAngle;} - - //! Return this light spot exponent - inline GLfloat spotEponent() const - {return m_SpotExponent;} -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Init Max number of light for this light context - void initForThisContext(); - - //! Set lihgt's position by a point - void setPosition(const GLC_Point3d &pos); - - //! Set lihgt's position by a 3 GLfloat - void setPosition(GLfloat x, GLfloat y, GLfloat z); - - //! Set light's ambiant color by a QColor - void setAmbientColor(const QColor &color); - - //! Set light's diffuse color by a QColor - void setDiffuseColor(const QColor &color); - - //! Set light's specular color by a QColor - void setSpecularColor(const QColor &color); - - //! Set Mode - void setTwoSided(const bool mode); - - //! Set this light constant attenuation - void setConstantAttenuation(GLfloat constantAttenuation); - - //! Set this light linear attenuation - void setLinearAttenuation(GLfloat linearAttenuation); - - //! Set this light quadratic attenuation - void setQuadraticAttenuation(GLfloat quadraticAttenuation); - - //! Set this light spot direction - void setSpotDirection(const GLC_Vector3d& direction); - - //! Set this light spot cutoff angle - void setSpotCutoffAngle(GLfloat cutoffAngle); - - //! Set this light spot exponent - void setSpotEponent(GLfloat exponent); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - // Disable the light - void disable(); - - //! Execute OpenGL light - virtual void glExecute(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// - -private: - - -//@} - -////////////////////////////////////////////////////////////////////// -// Private services fonction -////////////////////////////////////////////////////////////////////// -private: - //! Add context new light - void addNewLight(); - - //! Remove contetx light - void removeThisLight(); - -////////////////////////////////////////////////////////////////////// -// Private Members -////////////////////////////////////////////////////////////////////// -private: - //! OpenGL light ID - GLenum m_LightID; - - //! The Light type - LightType m_LightType; - - //! Light ambiant color - QColor m_AmbientColor; - //! Light diffuse color - QColor m_DiffuseColor; - //! Light specular color - QColor m_SpecularColor; - - //! Light position - GLC_Point3d m_Position; - - //! The spot light direction - GLC_Vector3d m_SpotDirection; - - //! The spot exponent - GLfloat m_SpotExponent; - - //! The spot cutoff angle - GLfloat m_SpotCutoffAngle; - - //! Constant attenation - GLfloat m_ConstantAttenuation; - - //! Linear attenuation - GLfloat m_LinearAttenuation; - - //! Quadratic attenuation - GLfloat m_QuadraticAttenuation; - - //! Lighting mode - bool m_TwoSided; - - // Static member - //! Maximum number of light - static GLint m_MaxLight; - - //! The context of this light - QGLContext* m_pContext; - - //! Flag to know if this light is valid - bool m_IsValid; - - //! Mapping between context and light set - static QHash > m_ContextToFreeLightSet; -}; -#endif //GLC_LIGHT_H_ diff --git a/ground/gcs/src/libs/glc_lib/shading/glc_material.cpp b/ground/gcs/src/libs/glc_lib/shading/glc_material.cpp deleted file mode 100644 index a60e1b94c..000000000 --- a/ground/gcs/src/libs/glc_lib/shading/glc_material.cpp +++ /dev/null @@ -1,703 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_material.cpp implementation of the GLC_Material class. - -#include "glc_material.h" -#include "../geometry/glc_geometry.h" -#include "../glc_factory.h" -#include "../glc_openglexception.h" - -#include - -// Class chunk id -quint32 GLC_Material::m_ChunkId= 0xA703; - -////////////////////////////////////////////////////////////////////// -// Constructor Destructor -////////////////////////////////////////////////////////////////////// -// Default constructor -GLC_Material::GLC_Material() -:GLC_Object("Material") -, m_AmbientColor() -, m_DiffuseColor() -, m_SpecularColor() -, m_EmissiveColor() -, m_Shininess(50.0) // By default shininess 50 -, m_WhereUsed() -, m_OtherUsage() -, m_pTexture(NULL) // no texture -, m_Opacity(1.0) -{ - //qDebug() << "GLC_Material::GLC_Material" << id(); - // Diffuse Color - initDiffuseColor(); - - // Others - initOtherColor(); -} - -GLC_Material::GLC_Material(const QColor &diffuseColor) -:GLC_Object("Material") -, m_AmbientColor() -, m_DiffuseColor(diffuseColor) -, m_SpecularColor() -, m_EmissiveColor() -, m_Shininess(50.0) // By default shininess 50 -, m_WhereUsed() -, m_OtherUsage() -, m_pTexture(NULL) // no texture -, m_Opacity(1.0) -{ - // Others - initOtherColor(); -} - - -GLC_Material::GLC_Material(const QString& name ,const GLfloat *pDiffuseColor) -:GLC_Object(name) -, m_AmbientColor() -, m_DiffuseColor() -, m_SpecularColor() -, m_EmissiveColor() -, m_Shininess(50.0) // By default shininess 50 -, m_WhereUsed() -, m_OtherUsage() -, m_pTexture(NULL) // no texture -, m_Opacity(1.0) -{ - //qDebug() << "GLC_Material::GLC_Material" << id(); - // Init Diffuse Color - if (pDiffuseColor != 0) - { - m_DiffuseColor.setRgbF(static_cast(pDiffuseColor[0]), - static_cast(pDiffuseColor[1]), - static_cast(pDiffuseColor[2]), - static_cast(pDiffuseColor[3])); - } - else - { - initDiffuseColor(); - } - // Others - initOtherColor(); -} -GLC_Material::GLC_Material(GLC_Texture* pTexture, const QString& name) -:GLC_Object(name) -, m_AmbientColor() -, m_DiffuseColor() -, m_SpecularColor() -, m_EmissiveColor() -, m_Shininess(50.0) // By default shininess 50 -, m_WhereUsed() -, m_OtherUsage() -, m_pTexture(pTexture) // init texture -, m_Opacity(1.0) -{ - Q_ASSERT(NULL != m_pTexture); - //qDebug() << "GLC_Material::GLC_Material" << id(); - - // Diffuse Color - initDiffuseColor(); - - // Others - initOtherColor(); - - //if (m_pTexture->hasAlphaChannel()) m_Transparency= 0.99; -} - -// Copy constructor -GLC_Material::GLC_Material(const GLC_Material &InitMaterial) -:GLC_Object(InitMaterial) -, m_AmbientColor(InitMaterial.m_AmbientColor) -, m_DiffuseColor(InitMaterial.m_DiffuseColor) -, m_SpecularColor(InitMaterial.m_SpecularColor) -, m_EmissiveColor(InitMaterial.m_EmissiveColor) -, m_Shininess(InitMaterial.m_Shininess) -, m_WhereUsed() -, m_OtherUsage() -, m_pTexture(NULL) -, m_Opacity(InitMaterial.m_Opacity) -{ - //qDebug() << "GLC_Material::GLC_Material copy constructor" << id(); - if (NULL != InitMaterial.m_pTexture) - { - m_pTexture= new GLC_Texture(*(InitMaterial.m_pTexture)); - Q_ASSERT(m_pTexture != NULL); - } - -} - -// Destructor -GLC_Material::~GLC_Material(void) -{ - delete m_pTexture; -} - - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// -// Return the class Chunk ID -quint32 GLC_Material::chunckID() -{ - return m_ChunkId; -} - -// Get Ambiant color -QColor GLC_Material::ambientColor() const -{ - return m_AmbientColor; -} - -// Get diffuse color -QColor GLC_Material::diffuseColor() const -{ - return m_DiffuseColor; -} - -// Get specular color -QColor GLC_Material::specularColor() const -{ - return m_SpecularColor; -} - -// Get the emissive color -QColor GLC_Material::emissiveColor() const -{ - return m_EmissiveColor; -} -// Get the texture File Name -QString GLC_Material::textureFileName() const -{ - if (m_pTexture != NULL) - { - return m_pTexture->fileName(); - } - else - { - return ""; - } -} - -// Get Texture Id -GLuint GLC_Material::textureID() const -{ - if (m_pTexture != NULL) - { - return m_pTexture->GL_ID(); - } - else - { - return 0; - } - -} - -// return true if the texture is loaded -bool GLC_Material::textureIsLoaded() const -{ - if (m_pTexture != NULL) - { - return m_pTexture->isLoaded(); - } - else - { - return false; - } -} - -// Return true if materials are equivalent -bool GLC_Material::operator==(const GLC_Material& mat) const -{ - bool result; - if (this == &mat) - { - result= true; - } - else - { - result= m_AmbientColor == mat.m_AmbientColor; - result= result && (m_DiffuseColor == mat.m_DiffuseColor); - result= result && (m_SpecularColor == mat.m_SpecularColor); - result= result && (m_EmissiveColor == mat.m_EmissiveColor); - result= result && (m_Shininess == mat.m_Shininess); - if ((NULL != m_pTexture) && (NULL != mat.m_pTexture)) - { - result= result && ((*m_pTexture) == (*mat.m_pTexture)); - } - else - { - result= result && (m_pTexture == mat.m_pTexture); - } - result= result && (m_Opacity == mat.m_Opacity); - } - return result; -} - -// Return the material hash code -uint GLC_Material::hashCode() const -{ - QString stringKey= QString::number(m_AmbientColor.rgba()); - stringKey+= QString::number(m_DiffuseColor.rgba()); - stringKey+= QString::number(m_SpecularColor.rgba()); - stringKey+= QString::number(m_EmissiveColor.rgba()); - stringKey+= QString::number(m_Shininess); - stringKey+= QString::number(m_Opacity); - if (NULL != m_pTexture) - { - stringKey+= m_pTexture->fileName(); - } - - return qHash(stringKey); -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// -// Set Material properties - void GLC_Material::setMaterial(const GLC_Material* pMat) - { - if (NULL != pMat->m_pTexture) - { - GLC_Texture* pTexture= new GLC_Texture(*(pMat->m_pTexture)); - setTexture(pTexture); - } - else if (NULL != m_pTexture) - { - qDebug() << "Delete texture"; - delete m_pTexture; - m_pTexture= NULL; - } - // Ambient Color - m_AmbientColor= pMat->m_AmbientColor; - // Diffuse Color - m_DiffuseColor= pMat->m_DiffuseColor; - // Specular Color - m_SpecularColor= pMat->m_SpecularColor; - // Lighting emit - m_EmissiveColor= pMat->m_EmissiveColor; - // Shininess - m_Shininess= pMat->m_Shininess; - // Transparency - m_Opacity= pMat->m_Opacity; - // Update geometry which use this material - WhereUsed::const_iterator iGeom= m_WhereUsed.constBegin(); - while (iGeom != m_WhereUsed.constEnd()) - { - iGeom.value()->updateTransparentMaterialNumber(); - ++iGeom; - } - - } - -// Set Ambiant Color -void GLC_Material::setAmbientColor(const QColor& ambientColor) -{ - m_AmbientColor= ambientColor; - m_AmbientColor.setAlphaF(m_Opacity); -} - -// Set Diffuse color -void GLC_Material::setDiffuseColor(const QColor& diffuseColor) -{ - m_DiffuseColor= diffuseColor; - m_DiffuseColor.setAlphaF(m_Opacity); -} - -// Set Specular color -void GLC_Material::setSpecularColor(const QColor& specularColor) -{ - m_SpecularColor= specularColor; - m_SpecularColor.setAlphaF(m_Opacity); -} - -// Set Emissive -void GLC_Material::setEmissiveColor(const QColor& lightEmission) -{ - m_EmissiveColor= lightEmission; - m_EmissiveColor.setAlphaF(m_Opacity); -} - -// Set Texture -void GLC_Material::setTexture(GLC_Texture* pTexture) -{ - Q_ASSERT(NULL != pTexture); - //qDebug() << "GLC_Material::SetTexture"; - if (m_pTexture != NULL) - { - delete m_pTexture; - m_pTexture= pTexture; - glLoadTexture(); - } - else - { - // It is not sure that there is OpenGL context - m_pTexture= pTexture; - } - - //if (m_pTexture->hasAlphaChannel()) m_Transparency= 0.99; -} - -// remove Material Texture -void GLC_Material::removeTexture() -{ - if (m_pTexture != NULL) - { - delete m_pTexture; - m_pTexture= NULL; - } -} - -// Add Geometry to where used hash table -bool GLC_Material::addGLC_Geom(GLC_Geometry* pGeom) -{ - QMutexLocker mutexLocker(&m_Mutex); - //qDebug() << "GLC_Material::addGLC_Geom" << pGeom->id(); - WhereUsed::iterator iGeom= m_WhereUsed.find(pGeom->id()); - - if (iGeom == m_WhereUsed.end()) - { // Ok, ID doesn't exist - // Add Geometry to where used hash table - m_WhereUsed.insert(pGeom->id(), pGeom); - return true; - } - else - { // KO, ID exist - qDebug("GLC_Material::addGLC_Geom : Geometry not added"); - return false; - } -} - -// Remove a geometry from the collection -bool GLC_Material::delGLC_Geom(GLC_uint Key) -{ - QMutexLocker mutexLocker(&m_Mutex); - - if (m_WhereUsed.contains(Key)) - { // Ok, ID exist - m_WhereUsed.remove(Key); // Remove container - - return true; - } - else - { // KO doesn't exist - qDebug("GLC_Material::delGLC_Geom : Geometry not remove"); - return false; - } - -} -// Add the id to the other used Set -bool GLC_Material::addUsage(GLC_uint id) -{ - QMutexLocker mutexLocker(&m_Mutex); - if (!m_OtherUsage.contains(id)) - { - m_OtherUsage << id; - return true; - } - else - { - qDebug("GLC_Material::addUsage : id not added"); - return false; - } -} - -// Remove the id to the other used Set -bool GLC_Material::delUsage(GLC_uint id) -{ - QMutexLocker mutexLocker(&m_Mutex); - if (m_OtherUsage.contains(id)) - { - m_OtherUsage.remove(id); - return true; - } - else - { - qDebug() << "GLC_Material::delUsage : id not removed " << m_Uid; - return false; - } -} - - -// Set the material opacity -void GLC_Material::setOpacity(const qreal alpha) -{ - m_Opacity= alpha; - m_AmbientColor.setAlphaF(m_Opacity); - m_DiffuseColor.setAlphaF(m_Opacity); - m_SpecularColor.setAlphaF(m_Opacity); - m_EmissiveColor.setAlphaF(m_Opacity); - // Update geometry which use this material - WhereUsed::const_iterator iGeom= m_WhereUsed.constBegin(); - while (iGeom != m_WhereUsed.constEnd()) - { - iGeom.value()->updateTransparentMaterialNumber(); - ++iGeom; - } -} - -////////////////////////////////////////////////////////////////////// -// OpenGL Functions -////////////////////////////////////////////////////////////////////// - -// Load the texture -void GLC_Material::glLoadTexture(QGLContext* pContext) -{ - if (m_pTexture != NULL) - { - m_pTexture->glLoadTexture(pContext); - } - else - { - qDebug() << "GLC_Material::glLoadTexture : Material without texture !"; - } -} - -// Execute OpenGL Material -void GLC_Material::glExecute() -{ - - GLfloat pAmbientColor[4]= {ambientColor().redF(), - ambientColor().greenF(), - ambientColor().blueF(), - ambientColor().alphaF()}; - - GLfloat pDiffuseColor[4]= {diffuseColor().redF(), - diffuseColor().greenF(), - diffuseColor().blueF(), - diffuseColor().alphaF()}; - - GLfloat pSpecularColor[4]= {specularColor().redF(), - specularColor().greenF(), - specularColor().blueF(), - specularColor().alphaF()}; - - GLfloat pLightEmission[4]= {emissiveColor().redF(), - emissiveColor().greenF(), - emissiveColor().blueF(), - emissiveColor().alphaF()}; - - const bool textureIsEnable= glIsEnabled(GL_TEXTURE_2D); - if (m_pTexture != NULL) - { - if (!textureIsEnable) glEnable(GL_TEXTURE_2D); - m_pTexture->glcBindTexture(); - if (GLC_State::glslUsed()) - { - if (GLC_Shader::hasActiveShader()) - { - GLC_Shader::currentShaderHandle()->programShaderHandle()->setUniformValue("tex", GLint(0)); - GLC_Shader::currentShaderHandle()->programShaderHandle()->setUniformValue("useTexture", true); - } - } - - } - else - { - - if (GLC_State::glslUsed() && GLC_Shader::hasActiveShader()) - { - if (!textureIsEnable) glEnable(GL_TEXTURE_2D); - GLC_Shader::currentShaderHandle()->programShaderHandle()->setUniformValue("tex", GLint(0)); - GLC_Shader::currentShaderHandle()->programShaderHandle()->setUniformValue("useTexture", false); - } - else - { - if (textureIsEnable) glDisable(GL_TEXTURE_2D); - } - - } - - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, pAmbientColor); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, pDiffuseColor); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, pSpecularColor); - glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, pLightEmission); - glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &m_Shininess); - - glColor4fv(pDiffuseColor); - - - // OpenGL Error handler - GLenum error= glGetError(); - if (error != GL_NO_ERROR) - { - GLC_OpenGlException OpenGlException("GLC_Material::glExecute() ", error); - throw(OpenGlException); - } - -} - -// Execute OpenGL Material -void GLC_Material::glExecute(float overwriteTransparency) -{ - GLfloat pAmbientColor[4]= {ambientColor().redF(), - ambientColor().greenF(), - ambientColor().blueF(), - overwriteTransparency}; - - GLfloat pDiffuseColor[4]= {diffuseColor().redF(), - diffuseColor().greenF(), - diffuseColor().blueF(), - overwriteTransparency}; - - GLfloat pSpecularColor[4]= {specularColor().redF(), - specularColor().greenF(), - specularColor().blueF(), - overwriteTransparency}; - - GLfloat pLightEmission[4]= {emissiveColor().redF(), - emissiveColor().greenF(), - emissiveColor().blueF(), - overwriteTransparency}; - - const bool textureIsEnable= glIsEnabled(GL_TEXTURE_2D); - - if (m_pTexture != NULL) - { - if (!textureIsEnable) glEnable(GL_TEXTURE_2D); - m_pTexture->glcBindTexture(); - if (GLC_State::glslUsed()) - { - if (GLC_Shader::hasActiveShader()) - { - GLC_Shader::currentShaderHandle()->programShaderHandle()->setUniformValue("tex", GLint(0)); - GLC_Shader::currentShaderHandle()->programShaderHandle()->setUniformValue("useTexture", true); - } - } - } - else - { - if (textureIsEnable) glDisable(GL_TEXTURE_2D); - if (GLC_State::glslUsed()) - { - if (GLC_Shader::hasActiveShader()) - { - GLC_Shader::currentShaderHandle()->programShaderHandle()->setUniformValue("tex", GLint(0)); - GLC_Shader::currentShaderHandle()->programShaderHandle()->setUniformValue("useTexture", false); - } - } - } - - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, pAmbientColor); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, pDiffuseColor); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, pSpecularColor); - glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, pLightEmission); - glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &m_Shininess); - - glColor4fv(pDiffuseColor); - - // OpenGL Error handler - GLenum error= glGetError(); - if (error != GL_NO_ERROR) - { - GLC_OpenGlException OpenGlException("GLC_Material::glExecute(float overwriteTransparency) ", error); - throw(OpenGlException); - } -} - -////////////////////////////////////////////////////////////////////// -// Private servicies Functions -////////////////////////////////////////////////////////////////////// - -// Init Ambiant Color -void GLC_Material::initDiffuseColor(void) -{ - m_DiffuseColor.setRgbF(1.0, 1.0, 1.0, 1.0); -} - -// Init default color -void GLC_Material::initOtherColor(void) -{ - //Ambiant Color - m_AmbientColor.setRgbF(0.8, 0.8, 0.8, 1.0); - - // Specular Color - m_SpecularColor.setRgbF(0.5, 0.5, 0.5, 1.0); - - // Lighting emit - m_EmissiveColor.setRgbF(0.0, 0.0, 0.0, 1.0); -} - -// Non Member methods -// Non-member stream operator -QDataStream &operator<<(QDataStream &stream, const GLC_Material &material) -{ - quint32 chunckId= GLC_Material::m_ChunkId; - stream << chunckId; - - // Store GLC_Object class members - stream << material.id() << material.name(); - - // Store GLC_Material class members - stream << material.ambientColor() << material.diffuseColor() << material.specularColor(); - stream << material.emissiveColor() << material.shininess() << material.opacity(); - - // Test if the material has texture - bool hasTexture= material.hasTexture(); - stream << hasTexture; - if (hasTexture) - { - GLC_Texture texture(*(material.textureHandle())); - stream << texture; - } - - return stream; -} -QDataStream &operator>>(QDataStream &stream, GLC_Material &material) -{ - quint32 chunckId; - stream >> chunckId; - - Q_ASSERT(chunckId == GLC_Material::m_ChunkId); - - // Retrieve GLC_Object members - GLC_uint id; - QString name; - stream >> id >> name; - material.setId(id); - material.setName(name); - - // Retrieve GLC_Material members - QColor ambient, diffuse, specular, lightEmission; - float shininess; - double alpha; - stream >> ambient >> diffuse >> specular >> lightEmission; - stream >> shininess >> alpha; - material.setAmbientColor(ambient); - material.setDiffuseColor(diffuse); - material.setSpecularColor(specular); - material.setEmissiveColor(lightEmission); - material.setShininess(shininess); - material.setOpacity(alpha); - - // Test if material has texture - bool hasTexture; - stream >> hasTexture; - if (hasTexture) - { - GLC_Texture texture; - stream >> texture; - material.setTexture(new GLC_Texture(texture)); - } - return stream; -} diff --git a/ground/gcs/src/libs/glc_lib/shading/glc_material.h b/ground/gcs/src/libs/glc_lib/shading/glc_material.h deleted file mode 100644 index 668b47aae..000000000 --- a/ground/gcs/src/libs/glc_lib/shading/glc_material.h +++ /dev/null @@ -1,279 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_material.h interface for the GLC_Material class. - -#ifndef GLC_MATERIAL_H_ -#define GLC_MATERIAL_H_ - - -#include "../glc_object.h" -#include "glc_texture.h" -#include -#include -#include - -#include "../glc_config.h" - -class GLC_Geometry; - -typedef QHash< GLC_uint, GLC_Geometry*> WhereUsed; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Material -/*! \brief GLC_Material : OpenGL surface material properties */ - -/*! An GLC_Material specifies surface material properties */ -////////////////////////////////////////////////////////////////////// - - -class GLC_LIB_EXPORT GLC_Material : public GLC_Object -{ - friend QDataStream &operator<<(QDataStream &, const GLC_Material &); - friend QDataStream &operator>>(QDataStream &, GLC_Material &); - -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Construct Colored GLC_Material - //! Default constructor - GLC_Material(); - - /*! By default, Ambiant Color is dark grey*/ - GLC_Material(const QColor &); - - /*! By default, Ambiant Color is dark grey*/ - GLC_Material(const QString& name, const GLfloat *); - - //! Construct textured GLC_Material - GLC_Material(GLC_Texture* pTexture, const QString& name= QString()); - - //! Copy constructor - /*! Hast usage table are not copying - */ - GLC_Material(const GLC_Material &InitMaterial); - - //! Remove material where used geometry - virtual ~GLC_Material(void); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the class Chunk ID - static quint32 chunckID(); - - //! Return true if the material is used - inline bool isUnused() const - {return m_WhereUsed.isEmpty() && m_OtherUsage.isEmpty();} - - //! Return true is material has attached texture - inline bool hasTexture() const - {return m_pTexture != NULL;} - - //! Get Ambiant color - QColor ambientColor() const; - - //! Get diffuse color - QColor diffuseColor() const; - - //! Get specular color - QColor specularColor() const; - - //! Get the emissive color - QColor emissiveColor() const; - - //! Get Shininess - inline GLfloat shininess() const - {return m_Shininess;} - - //! Get the texture File Name - QString textureFileName() const; - - //! Get Texture Id - GLuint textureID() const; - - //! return true if the texture is loaded - bool textureIsLoaded() const; - - //! Return true if the material is transparent - inline bool isTransparent() const - {return m_Opacity < 1.0;} - - //! Return true if materials are equivalent - bool operator==(const GLC_Material&) const; - - //! Return the material opacity - inline double opacity() const - {return m_DiffuseColor.alphaF();} - - //! Return the number of this material usage - inline int numberOfUsage() const - {return m_WhereUsed.size() + m_OtherUsage.size();} - - //! Return the texture handle - inline GLC_Texture* textureHandle() const - {return m_pTexture;} - - //! Return the material hash code - uint hashCode() const; - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Assignement operator - /*! The Hash Table WhereUse - * is not modified - */ - inline GLC_Material &operator=(const GLC_Material& mat) - { - setMaterial(&mat); - return *this; - } - - //! Set Material properties - /*! The Hash Table WhereUse - * is not modified - */ - void setMaterial(const GLC_Material*); - - //! Set Ambiant Color - void setAmbientColor(const QColor& ambientColor); - - //! Set Diffuse color - void setDiffuseColor(const QColor& diffuseColor); - - //! Set Specular color - void setSpecularColor(const QColor& specularColor); - - //! Set Emissive - void setEmissiveColor(const QColor& lightEmission); - - //! Set Shininess - inline void setShininess(GLfloat Shininess) - { m_Shininess= Shininess;} - - //! Set Texture - void setTexture(GLC_Texture* pTexture); - - //! remove Material Texture - void removeTexture(); - - //! Add Geometry to the "where used" hash table - /*! This method is thread safe*/ - bool addGLC_Geom(GLC_Geometry* pGeom); - - //! Remove Geometry to the "where used" hash table - /*! This method is thread safe*/ - bool delGLC_Geom(GLC_uint Key); - - //! Add the id to the other used Set - /*! This method is thread safe*/ - bool addUsage(GLC_uint); - - //! Remove the id to the other used Set - /*! This method is thread safe*/ - bool delUsage(GLC_uint); - - //! Set the material opacity - void setOpacity(const qreal); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Load the texture - void glLoadTexture(QGLContext* pContext= NULL); - - //! Execute OpenGL Material - virtual void glExecute(); - - //! Execute OpenGL Material with overWrite transparency - virtual void glExecute(float); - -//@} - -////////////////////////////////////////////////////////////////////// -// Private services Functions -////////////////////////////////////////////////////////////////////// -private: - //! Init Ambiant Color - void initDiffuseColor(void); - - //! Init other color - void initOtherColor(void); - - -////////////////////////////////////////////////////////////////////// -// Private Member -////////////////////////////////////////////////////////////////////// - -private: - - //! Ambiant Color - QColor m_AmbientColor; - //! Diffuse Color - QColor m_DiffuseColor; - //! Specular Color - QColor m_SpecularColor; - - //! emmisive lighting - QColor m_EmissiveColor; - - //! Shiness - GLfloat m_Shininess; - - //! Hash table of geomtries which used this material - WhereUsed m_WhereUsed; - - //! Set of id of other objects that uses this material - QSet m_OtherUsage; - - //! Material's texture - GLC_Texture* m_pTexture; - - //! Material opacity - qreal m_Opacity; - - //! Class chunk id - static quint32 m_ChunkId; - -}; - -//! Non-member stream operator -QDataStream &operator<<(QDataStream &, const GLC_Material &); -QDataStream &operator>>(QDataStream &, GLC_Material &); - -#endif //GLC_MATERIAL_H_ diff --git a/ground/gcs/src/libs/glc_lib/shading/glc_renderer.cpp b/ground/gcs/src/libs/glc_lib/shading/glc_renderer.cpp deleted file mode 100644 index e9a4aa954..000000000 --- a/ground/gcs/src/libs/glc_lib/shading/glc_renderer.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_renderer.cpp implementation of the GLC_Renderer class. - -#include - -#include "../sceneGraph/glc_3dviewcollection.h" - -#include "glc_renderer.h" - -GLC_Renderer::GLC_Renderer() -: m_pCollection(NULL) -, m_IdToRenderProperties() -, m_IsCurrent(false) -{ - -} - -GLC_Renderer::GLC_Renderer(GLC_3DViewCollection* pCollection) -: m_pCollection(pCollection) -, m_IdToRenderProperties() -, m_IsCurrent(false) -{ - -} - -GLC_Renderer::GLC_Renderer(const GLC_Renderer& other) -: m_pCollection(other.m_pCollection) -, m_IdToRenderProperties(other.m_IdToRenderProperties) -, m_IsCurrent(false) -{ - -} - -GLC_Renderer::~GLC_Renderer() -{ - clear(); -} - -bool GLC_Renderer::instanceRenderPropertiesIsAvailable(GLC_uint id) const -{ - return m_IdToRenderProperties.contains(id); -} - -const GLC_RenderProperties& GLC_Renderer::renderPropertiesOfInstance(GLC_uint id) const -{ - Q_ASSERT(m_IdToRenderProperties.contains(id)); - return m_IdToRenderProperties.find(id).value(); -} - -void GLC_Renderer::clear() -{ - m_pCollection= NULL; - m_IdToRenderProperties.clear(); -} - -GLC_Renderer& GLC_Renderer::operator=(const GLC_Renderer& other) -{ - if (this != &other) - { - m_pCollection= other.m_pCollection; - m_IdToRenderProperties= other.m_IdToRenderProperties; - // m_IsCurrent doesn't change - } - - return *this; -} - -void GLC_Renderer::setCollection(GLC_3DViewCollection* pCollection) -{ - if (pCollection != m_pCollection) - { - clear(); - m_pCollection= pCollection; - } -} - -void GLC_Renderer::setCurrent() -{ - if (NULL != m_pCollection) - { - Q_ASSERT(!m_IsCurrent); - m_IsCurrent= true; - QHash::const_iterator iRender= m_IdToRenderProperties.constBegin(); - while (iRender != m_IdToRenderProperties.constEnd()) - { - if (m_pCollection->contains(iRender.key())) - { - m_pCollection->instanceHandle(iRender.key())->renderPropertiesHandle()->operator =(iRender.value()); - } - ++iRender; - } - m_IdToRenderProperties.clear(); - } -} - -void GLC_Renderer::unSetCurrent() -{ - if (NULL != m_pCollection) - { - Q_ASSERT(m_IdToRenderProperties.isEmpty()); - Q_ASSERT(m_IsCurrent); - m_IsCurrent= false; - QList instances= m_pCollection->instancesHandle(); - const int count= instances.count(); - for (int i= 0; i < count; ++i) - { - GLC_3DViewInstance* pInstance= instances.at(i); - m_IdToRenderProperties.insert(pInstance->id(), *(pInstance->renderPropertiesHandle())); - } - } -} - -void GLC_Renderer::addRenderPropertiesOfInstanceId(GLC_uint id) -{ - Q_ASSERT(NULL != m_pCollection); - Q_ASSERT(m_pCollection->contains(id)); - m_IdToRenderProperties.insert(id, *(m_pCollection->instanceHandle(id)->renderPropertiesHandle())); -} diff --git a/ground/gcs/src/libs/glc_lib/shading/glc_renderer.h b/ground/gcs/src/libs/glc_lib/shading/glc_renderer.h deleted file mode 100644 index a105bfe28..000000000 --- a/ground/gcs/src/libs/glc_lib/shading/glc_renderer.h +++ /dev/null @@ -1,126 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_renderer.h interface for the GLC_Renderer class. - -#ifndef GLC_RENDERER_H_ -#define GLC_RENDERER_H_ - -#include - -#include "glc_renderproperties.h" - -#include "../glc_config.h" - -class GLC_3DViewCollection; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Renderer -/*! \brief GLC_Renderer : Is used to store and retrieve overload rendering properties*/ - -/*! An GLC_Renderer is attached to a GLC_3DViewCollection \n - * The renderer is used to render a scene in a specific way.*/ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_Renderer -{ -public: -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// - - GLC_Renderer(); - GLC_Renderer(GLC_3DViewCollection* pCollection); - GLC_Renderer(const GLC_Renderer& other); - virtual ~GLC_Renderer(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return true if this renderer has an attached collection - inline bool hasCollection() const - {return m_pCollection != NULL;} - - //! Return the 3DView collection attached to this renderer - inline GLC_3DViewCollection* collection() const - {return m_pCollection;} - - //! Return true if the renderProperties of the given instance id is available - bool instanceRenderPropertiesIsAvailable(GLC_uint id) const; - - //! Return the renderProperties of the given instance id - const GLC_RenderProperties& renderPropertiesOfInstance(GLC_uint id) const; - - //! Return true if this renderer is current - inline bool isCurrent() const - {return m_IsCurrent;} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Clear the content of this render - void clear(); - - //! Assignement operator - GLC_Renderer& operator=(const GLC_Renderer& other); - - //! Set the collection to use - void setCollection(GLC_3DViewCollection* pCollection); - - //! Set this renderer the current renderer - /*! Apply stored renderProperties to the attached collection*/ - void setCurrent(); - - //! Unset this rendere the current rendere - /*! Save the render properties of all instance of the scene*/ - void unSetCurrent(); - - //! Add the renderProperties of the given instance id - void addRenderPropertiesOfInstanceId(GLC_uint id); -//@} - -////////////////////////////////////////////////////////////////////// -// Private services fonction -////////////////////////////////////////////////////////////////////// -private: - -////////////////////////////////////////////////////////////////////// -// Private Members -////////////////////////////////////////////////////////////////////// -private: - //! The 3DView collection attached to this renderer - GLC_3DViewCollection* m_pCollection; - - QHash m_IdToRenderProperties; - - bool m_IsCurrent; - -}; - -#endif /* GLC_RENDERER_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/shading/glc_renderproperties.cpp b/ground/gcs/src/libs/glc_lib/shading/glc_renderproperties.cpp deleted file mode 100644 index 66f3940bd..000000000 --- a/ground/gcs/src/libs/glc_lib/shading/glc_renderproperties.cpp +++ /dev/null @@ -1,391 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_renderproperties.cpp implementation for the GLC_RenderProperties class. - -#include "glc_renderproperties.h" - -// Default constructor -GLC_RenderProperties::GLC_RenderProperties() -: m_Uid(glc::GLC_GenUserID()) -, m_IsSelected(false) -, m_PolyFace(GL_FRONT_AND_BACK) -, m_PolyMode(GL_FILL) -, m_RenderMode(glc::NormalRenderMode) -, m_SavedRenderMode(m_RenderMode) -, m_pOverwriteMaterial(NULL) -, m_OverwriteOpacity(-1.0f) -, m_pBodySelectedPrimitvesId(NULL) -, m_pOverwritePrimitiveMaterialMaps(NULL) -, m_RenderingFlag(glc::ShadingFlag) -, m_CurrentBody(0) -, m_MaterialsUsage() -{ - -} - -// Copy constructor -GLC_RenderProperties::GLC_RenderProperties(const GLC_RenderProperties& renderProperties) -: m_Uid(glc::GLC_GenUserID()) -, m_IsSelected(renderProperties.m_IsSelected) -, m_PolyFace(renderProperties.m_PolyFace) -, m_PolyMode(renderProperties.m_PolyMode) -, m_RenderMode(renderProperties.m_RenderMode) -, m_SavedRenderMode(renderProperties.m_SavedRenderMode) -, m_pOverwriteMaterial(renderProperties.m_pOverwriteMaterial) -, m_OverwriteOpacity(renderProperties.m_OverwriteOpacity) -, m_pBodySelectedPrimitvesId(NULL) -, m_pOverwritePrimitiveMaterialMaps(NULL) -, m_RenderingFlag(renderProperties.m_RenderingFlag) -, m_CurrentBody(renderProperties.m_CurrentBody) -, m_MaterialsUsage(renderProperties.m_MaterialsUsage) -{ - // Update overwrite material usage - if (NULL != m_pOverwriteMaterial) - { - m_pOverwriteMaterial->addUsage(m_Uid); - } - - // Copy the Hash of set of id of selected primitives - if (NULL != renderProperties.m_pBodySelectedPrimitvesId) - { - m_pBodySelectedPrimitvesId= new QHash* >(); - QHash* >::const_iterator iSet= renderProperties.m_pBodySelectedPrimitvesId->constBegin(); - while (renderProperties.m_pBodySelectedPrimitvesId->constEnd() != iSet) - { - // Copy the current body set of id of selected primitive - m_pBodySelectedPrimitvesId->insert(iSet.key(), new QSet(*(iSet.value()))); - ++iSet; - } - } - - // Copy of the overwrite primitive materials maps - if (NULL != renderProperties.m_pOverwritePrimitiveMaterialMaps) - { - // Copy the hash table of overwrite materials - m_pOverwritePrimitiveMaterialMaps= new QHash* >; - QHash* >::const_iterator iMatMaps= renderProperties.m_pOverwritePrimitiveMaterialMaps->constBegin(); - while (renderProperties.m_pOverwritePrimitiveMaterialMaps->constEnd() != iMatMaps) - { - QHash* pBodyMatMap= new QHash(*(iMatMaps.value())); - m_pOverwritePrimitiveMaterialMaps->insert(iMatMaps.key(), pBodyMatMap); - ++iMatMaps; - } - } - - // Update material usage - QHash::iterator iMatUsage= m_MaterialsUsage.begin(); - while (m_MaterialsUsage.constEnd() != iMatUsage) - { - iMatUsage.key()->addUsage(m_Uid); - ++iMatUsage; - } -} - -// Assignement operator -GLC_RenderProperties& GLC_RenderProperties::operator=(const GLC_RenderProperties& renderProperties) -{ - if (this != &renderProperties) - { - clear(); - m_IsSelected= renderProperties.m_IsSelected; - m_PolyFace= renderProperties.m_PolyFace; - m_PolyMode= renderProperties.m_PolyMode; - m_RenderMode= renderProperties.m_RenderMode; - m_SavedRenderMode= renderProperties.m_SavedRenderMode; - m_pOverwriteMaterial= renderProperties.m_pOverwriteMaterial; - m_OverwriteOpacity= renderProperties.m_OverwriteOpacity; - m_pBodySelectedPrimitvesId= NULL; - m_pOverwritePrimitiveMaterialMaps= NULL; - m_RenderingFlag= renderProperties.m_RenderingFlag; - m_CurrentBody= renderProperties.m_CurrentBody; - - // Update overwrite material usage - if (NULL != m_pOverwriteMaterial) - { - m_pOverwriteMaterial->addUsage(m_Uid); - } - - // Copy the Hash of set of id of selected primitives - if (NULL != renderProperties.m_pBodySelectedPrimitvesId) - { - m_pBodySelectedPrimitvesId= new QHash* >(); - QHash* >::const_iterator iSet= renderProperties.m_pBodySelectedPrimitvesId->constBegin(); - while (renderProperties.m_pBodySelectedPrimitvesId->constEnd() != iSet) - { - // Copy the current body set of id of selected primitive - m_pBodySelectedPrimitvesId->insert(iSet.key(), new QSet(*(iSet.value()))); - ++iSet; - } - } - - // Update primitive overwrite material usage - if (NULL != renderProperties.m_pOverwritePrimitiveMaterialMaps) - { - // Copy the hash table of overwrite materials - m_pOverwritePrimitiveMaterialMaps= new QHash* >; - QHash* >::const_iterator iMatMaps= renderProperties.m_pOverwritePrimitiveMaterialMaps->constBegin(); - while (renderProperties.m_pOverwritePrimitiveMaterialMaps->constEnd() != iMatMaps) - { - QHash* pBodyMatMap= new QHash(*(iMatMaps.value())); - m_pOverwritePrimitiveMaterialMaps->insert(iMatMaps.key(), pBodyMatMap); - - QHash::iterator iMatMap= pBodyMatMap->begin(); - while (pBodyMatMap->constEnd() != iMatMap) - { - iMatMap.value()->addUsage(m_Uid); - ++iMatMap; - } - - ++iMatMaps; - } - } - } - - return *this; -} - -// Destructor -GLC_RenderProperties::~GLC_RenderProperties() -{ - clear(); -} - -// Return true if rendering properties needs to render with transparency -bool GLC_RenderProperties::needToRenderWithTransparency() const -{ - bool renderWithTransparency= false; - if (m_RenderMode == glc::OverwriteMaterial) - { - Q_ASSERT(NULL != m_pOverwriteMaterial); - renderWithTransparency= m_pOverwriteMaterial->isTransparent(); - } - else if ((m_RenderMode == glc::OverwriteTransparency) || (m_RenderMode == glc::OverwriteTransparencyAndMaterial)) - { - Q_ASSERT(-1.0f != m_OverwriteOpacity); - renderWithTransparency= (m_OverwriteOpacity < 1.0f); - } - else if ((m_RenderMode == glc::OverwritePrimitiveMaterial) - || ((m_RenderMode == glc::PrimitiveSelected) && (NULL != m_pOverwritePrimitiveMaterialMaps) && (!m_pOverwritePrimitiveMaterialMaps->isEmpty()))) - { - Q_ASSERT(NULL != m_pOverwritePrimitiveMaterialMaps); - Q_ASSERT(!m_pOverwritePrimitiveMaterialMaps->isEmpty()); - - QList* > hashList= m_pOverwritePrimitiveMaterialMaps->values(); - QSet materialSet; - const int size= hashList.size(); - for (int i= 0; i < size; ++i) - { - materialSet.unite(QSet::fromList(hashList.at(i)->values())); - } - - QSet::const_iterator iMat= materialSet.constBegin(); - while ((materialSet.constEnd() != iMat) && !renderWithTransparency) - { - renderWithTransparency= (*iMat)->isTransparent(); - ++iMat; - } - } - - return renderWithTransparency; -} - -bool GLC_RenderProperties::isDefault() const -{ - bool isDefault= (NULL == m_pOverwriteMaterial); - isDefault= isDefault && (m_OverwriteOpacity == -1.0f); - return isDefault; -} - -// Clear the content of the render properties and update materials usage -void GLC_RenderProperties::clear() -{ - if (NULL != m_pOverwriteMaterial) - { - // Delete the material if it is unused - m_pOverwriteMaterial->delUsage(m_Uid); - if (m_pOverwriteMaterial->isUnused()) delete m_pOverwriteMaterial; - m_pOverwriteMaterial= NULL; - } - - clearSelectedPrimitives(); - - clearOverwritePrimitiveMaterials(); -} - -// Set the overwrite material -void GLC_RenderProperties::setOverwriteMaterial(GLC_Material* pMaterial) -{ - Q_ASSERT(NULL != pMaterial); - if (NULL != m_pOverwriteMaterial) - { - m_pOverwriteMaterial->delUsage(m_Uid); - if (m_pOverwriteMaterial->isUnused()) delete m_pOverwriteMaterial; - } - m_pOverwriteMaterial= pMaterial; - - m_pOverwriteMaterial->addUsage(m_Uid); -} - -// Return true if the specified primitive id of the specified body index is selected -bool GLC_RenderProperties::primitiveIsSelected(int index, GLC_uint id) const -{ - bool result= false; - if ((NULL != m_pBodySelectedPrimitvesId) && m_pBodySelectedPrimitvesId->contains(m_CurrentBody)) - { - result= m_pBodySelectedPrimitvesId->value(index)->contains(id); - } - return result; -} - -// Set the list of selected primitives id -void GLC_RenderProperties::addSetOfSelectedPrimitivesId(const QSet& set, int body) -{ - if (NULL == m_pBodySelectedPrimitvesId) - { - m_pBodySelectedPrimitvesId= new QHash* >(); - m_pBodySelectedPrimitvesId->insert(body, new QSet(set)); - } - else if (!m_pBodySelectedPrimitvesId->contains(body)) - { - m_pBodySelectedPrimitvesId->insert(body, new QSet(set)); - } - else - { - m_pBodySelectedPrimitvesId->value(body)->unite(set); - } -} - -// Add a selected primitive -void GLC_RenderProperties::addSelectedPrimitive(GLC_uint id, int body) -{ - if (NULL == m_pBodySelectedPrimitvesId) - { - m_pBodySelectedPrimitvesId= new QHash* >(); - m_pBodySelectedPrimitvesId->insert(body, new QSet()); - - } - else if (!m_pBodySelectedPrimitvesId->contains(body)) - { - m_pBodySelectedPrimitvesId->insert(body, new QSet()); - } - m_pBodySelectedPrimitvesId->value(body)->insert(id); -} - -// Clear selectedPrimitive Set -void GLC_RenderProperties::clearSelectedPrimitives() -{ - if (NULL != m_pBodySelectedPrimitvesId) - { - QHash* >::const_iterator iSet= m_pBodySelectedPrimitvesId->constBegin(); - while (m_pBodySelectedPrimitvesId->constEnd() != iSet) - { - delete iSet.value(); - ++iSet; - } - } - delete m_pBodySelectedPrimitvesId; - m_pBodySelectedPrimitvesId= NULL; -} - -// Add an overwrite primitive material -void GLC_RenderProperties::addOverwritePrimitiveMaterial(GLC_uint id, GLC_Material* pMaterial, int bodyIndex) -{ - Q_ASSERT(NULL != pMaterial); - if (NULL != m_pOverwritePrimitiveMaterialMaps) - { - if (m_pOverwritePrimitiveMaterialMaps->contains(bodyIndex)) - { - QHash* pHash= m_pOverwritePrimitiveMaterialMaps->value(bodyIndex); - if (pHash->contains(id)) - { - if (pHash->value(id) != pMaterial) - { - GLC_Material* pOldMaterial= pHash->value(id); - unUseMaterial(pOldMaterial); - pHash->remove(id); - - pHash->insert(id, pMaterial); - useMaterial(pMaterial); - } - // Else, noting to do - } - else - { - pHash->insert(id, pMaterial); - useMaterial(pMaterial); - } - } - else - { - QHash* pHash= new QHash(); - pHash->insert(id, pMaterial); - useMaterial(pMaterial); - m_pOverwritePrimitiveMaterialMaps->insert(bodyIndex, pHash); - } - } - else - { - m_pOverwritePrimitiveMaterialMaps= new QHash* >(); - QHash* pHash= new QHash(); - pHash->insert(id, pMaterial); - m_pOverwritePrimitiveMaterialMaps->insert(bodyIndex, pHash); - useMaterial(pMaterial); - } -} - -// Clear overwrite primitive materials -void GLC_RenderProperties::clearOverwritePrimitiveMaterials() -{ - if (NULL != m_pOverwritePrimitiveMaterialMaps) - { - Q_ASSERT(!m_MaterialsUsage.isEmpty()); - QHash* >::iterator iHash= m_pOverwritePrimitiveMaterialMaps->begin(); - while (m_pOverwritePrimitiveMaterialMaps->constEnd() != iHash) - { - delete iHash.value(); - ++iHash; - } - - QHash::iterator iMat= m_MaterialsUsage.begin(); - while (m_MaterialsUsage.constEnd() != iMat) - { - GLC_Material* pMat= iMat.key(); - pMat->delUsage(m_Uid); - if (pMat->isUnused()) delete pMat; - ++iMat; - } - m_MaterialsUsage.clear(); - } - else - { - Q_ASSERT(m_MaterialsUsage.isEmpty()); - } - - delete m_pOverwritePrimitiveMaterialMaps; - m_pOverwritePrimitiveMaterialMaps= NULL; - - if ((m_SavedRenderMode == glc::OverwritePrimitiveMaterial)) - { - m_SavedRenderMode= glc::NormalRenderMode; - } -} - diff --git a/ground/gcs/src/libs/glc_lib/shading/glc_renderproperties.h b/ground/gcs/src/libs/glc_lib/shading/glc_renderproperties.h deleted file mode 100644 index a936a09bb..000000000 --- a/ground/gcs/src/libs/glc_lib/shading/glc_renderproperties.h +++ /dev/null @@ -1,331 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -//! \file glc_renderproperties.h interface for the GLC_RenderProperties class. - -#ifndef GLC_RENDERPROPERTIES_H_ -#define GLC_RENDERPROPERTIES_H_ - -#include "glc_material.h" -#include "../glc_global.h" - -#include -#include -#include - -#include "../glc_config.h" - -//! Define render mode enum in glc namespace -namespace glc -{ - //! Geometry rendering mode enumeration - enum RenderMode - { - NormalRenderMode= 0, - OverwriteMaterial= 1, - OverwriteTransparency= 2, - OverwriteTransparencyAndMaterial= 3, - PrimitiveSelected= 4, - OverwritePrimitiveMaterial= 5, - BodySelection= 6, - PrimitiveSelection= 7 - }; - - //! Geometry rendring flag enumaration - enum RenderFlag - { - ShadingFlag= 800, - WireRenderFlag, - TransparentRenderFlag - }; -}; -////////////////////////////////////////////////////////////////////// -//! \class GLC_RenderProperties -/*! \brief GLC_RenderProperties encapsulate the render properties - * off all GLC_3DViewInstance class*/ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_RenderProperties -{ - -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Default constructor - GLC_RenderProperties(); - - //! Copy constructor - GLC_RenderProperties(const GLC_RenderProperties&); - - //! Assignement operator - GLC_RenderProperties &operator=(const GLC_RenderProperties&); - - //! Destructor - virtual ~GLC_RenderProperties(); -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return true if it is selected - inline bool isSelected() const - {return m_IsSelected;} - - //! Return the rendering mode - inline glc::RenderMode renderingMode() const - {return m_RenderMode;} - - //! Return the saved rendering mode - inline glc::RenderMode savedRenderingMode() const - {return m_SavedRenderMode;} - - //! Return an handle to the overwrite material - inline GLC_Material* overwriteMaterial() const - {return m_pOverwriteMaterial;} - - //! Return the overwrite transparency - inline float overwriteTransparency() const - {return m_OverwriteOpacity;} - - //! Return an handle to the set of selected primitives id of the current body - inline QSet* setOfSelectedPrimitivesId() const - { - Q_ASSERT(NULL != m_pBodySelectedPrimitvesId); - if (m_pBodySelectedPrimitvesId->contains(m_CurrentBody)) - return m_pBodySelectedPrimitvesId->value(m_CurrentBody); - else return NULL; - } - - //! Return true if the set of selected primitive id is empty - inline bool setOfSelectedPrimitiveIdIsEmpty() const - {return (!((NULL != m_pBodySelectedPrimitvesId) && m_pBodySelectedPrimitvesId->contains(m_CurrentBody)));} - - //! Return true if the specified primitive id of the specified body index is selected - bool primitiveIsSelected(int index, GLC_uint id) const; - - //! Return an handle to the overwrite primitive material Hash - inline QHash* hashOfOverwritePrimitiveMaterials() const - { - Q_ASSERT(NULL != m_pOverwritePrimitiveMaterialMaps); - if (m_pOverwritePrimitiveMaterialMaps->contains(m_CurrentBody)) - return m_pOverwritePrimitiveMaterialMaps->value(m_CurrentBody); - else return NULL; - } - - //! Return true if the hash of overwrite primitive material is empty - inline bool hashOfOverwritePrimitiveMaterialsIsEmpty() const - {return (!((NULL != m_pOverwritePrimitiveMaterialMaps) && m_pOverwritePrimitiveMaterialMaps->contains(m_CurrentBody)));} - - //! Get the PolyFace mode - /*! PolyFace Mode can Be : GL_FRONT_AND_BACK, GL_FRONT, or GL_BACK*/ - inline GLenum polyFaceMode() const - {return m_PolyFace;} - - //! Get the Polygon mode - /*! Polygon Mode can Be : GL_POINT, GL_LINE, or GL_FILL*/ - inline GLenum polygonMode() const - {return m_PolyMode;} - - //! Return rendering flag render flag - inline glc::RenderFlag renderingFlag() const - {return m_RenderingFlag;} - - //! Return true if rendering properties needs to render with transparency - bool needToRenderWithTransparency() const; - - //! Return the current body index - inline int currentBodyIndex() const - {return m_CurrentBody;} - - //! Return true if this rendering properties has defaut value - bool isDefault() const; - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Clear the content of the render properties and update materials usage - void clear(); -//@} -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Select the instance - inline void select(bool primitive); - - //! Unselect the instance - inline void unselect(void); - - //! Set the rendering mode - inline void setRenderingMode(glc::RenderMode mode) - {m_RenderMode= mode;} - - //! Set the overwrite material - void setOverwriteMaterial(GLC_Material*); - - //! Set the overwrite transparency - inline void setOverwriteTransparency(float alpha) - {m_OverwriteOpacity= alpha;} - - //! Add the set of selected primitives id of the specified body - void addSetOfSelectedPrimitivesId(const QSet&, int body= 0); - - //! Add a selected primitive of the specified body - void addSelectedPrimitive(GLC_uint, int body= 0); - - //! Clear selectedPrimitive Set - void clearSelectedPrimitives(); - - //! Add an overwrite primitive material - void addOverwritePrimitiveMaterial(GLC_uint, GLC_Material*, int bodyIndex= 0); - - //! Clear overwrite primitive materials - void clearOverwritePrimitiveMaterials(); - - //! Polygon's display style - /*! Face Polygon Mode can be : GL_FRONT_AND_BACK, GL_FRONT, or GL_BACK - * mode can be : GL_POINT, GL_LINE, or GL_FILL */ - inline void setPolygonMode(GLenum Face, GLenum Mode) - { - m_PolyFace= Face; - m_PolyMode= Mode; - } - - //! Set the rendering flag - inline void setRenderingFlag(glc::RenderFlag flag) - {m_RenderingFlag= flag;} - - //! Set the current body index - inline void setCurrentBodyIndex(int index) - {m_CurrentBody= index;} - - //! Used the specified material - inline void useMaterial(GLC_Material*); - - //! Unused the specified material - inline void unUseMaterial(GLC_Material*); - - -//@} - -////////////////////////////////////////////////////////////////////// -//Private attributes -////////////////////////////////////////////////////////////////////// -private: - //! The render properties uid : GLC_GenUserID (For GLC_Material usage) - GLC_uint m_Uid; - - //! Flag to know if it is selected - bool m_IsSelected; - - //! OpenGL polygon rendering mode - GLenum m_PolyFace; - GLenum m_PolyMode; - - //! Geometry rendering mode - glc::RenderMode m_RenderMode; - - //! Geometry saved rendering mode - glc::RenderMode m_SavedRenderMode; - - //! The overwrite material - GLC_Material* m_pOverwriteMaterial; - - //! The overwrite opacity - float m_OverwriteOpacity; - - //! The selected primitive id regrouped by body - QHash* >* m_pBodySelectedPrimitvesId; - - //! The overwrite primitive material mapping - QHash* >* m_pOverwritePrimitiveMaterialMaps; - - //! Transparent material render flag - glc::RenderFlag m_RenderingFlag; - - //! The current rendere body - int m_CurrentBody; - - //! The Hash table of overwrite primitive maped to the number of usages in this render properties - QHash m_MaterialsUsage; - -}; - -// Select the instance -void GLC_RenderProperties::select(bool primitive) -{ - m_IsSelected= true; - if (primitive && (m_RenderMode != glc::PrimitiveSelected)) - { - m_SavedRenderMode= m_RenderMode; - m_RenderMode= glc::PrimitiveSelected; - } -} - -// Unselect the instance -void GLC_RenderProperties::unselect(void) -{ - m_IsSelected= false; - if (m_RenderMode == glc::PrimitiveSelected) - { - m_RenderMode= m_SavedRenderMode; - } -} -// Used the specified material -void GLC_RenderProperties::useMaterial(GLC_Material* pMaterial) -{ - if (m_MaterialsUsage.contains(pMaterial)) - { - QHash::iterator iMat= m_MaterialsUsage.find(pMaterial); - iMat.value()= iMat.value() + 1; - } - else - { - m_MaterialsUsage.insert(pMaterial, 1); - pMaterial->addUsage(m_Uid); - } - -} - -// Unused the specified material -void GLC_RenderProperties::unUseMaterial(GLC_Material* pMaterial) -{ - Q_ASSERT(m_MaterialsUsage.contains(pMaterial)); - QHash::iterator iMat= m_MaterialsUsage.find(pMaterial); - iMat.value()= iMat.value() - 1; - if (iMat.value() == 0) - { - pMaterial->delUsage(m_Uid); - if (pMaterial->isUnused()) delete pMaterial; - m_MaterialsUsage.remove(pMaterial); - } -} - -#endif /* GLC_RENDERPROPERTIES_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/shading/glc_selectionmaterial.cpp b/ground/gcs/src/libs/glc_lib/shading/glc_selectionmaterial.cpp deleted file mode 100644 index 22ccc77b4..000000000 --- a/ground/gcs/src/libs/glc_lib/shading/glc_selectionmaterial.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ -//! \file glc_selectionmaterial.cpp implementation of the GLC_SelectionMaterial class. - -#include - -#include "glc_selectionmaterial.h" -#include "glc_material.h" - - -QHash GLC_SelectionMaterial::m_SelectionShaderHash; -GLC_uint GLC_SelectionMaterial::m_SelectionMaterialId= 0; -GLC_Material* GLC_SelectionMaterial::m_pMaterial= NULL; - -GLC_SelectionMaterial::GLC_SelectionMaterial() -{ - -} - -void GLC_SelectionMaterial::useMaterial(GLC_Material* pMaterial) -{ - if (0 == m_SelectionMaterialId) - { - m_SelectionMaterialId= glc::GLC_GenUserID(); - } - Q_ASSERT(NULL != pMaterial); - if (NULL != m_pMaterial) - { - m_pMaterial->delUsage(m_SelectionMaterialId); - if (m_pMaterial->isUnused()) - { - delete m_pMaterial; - } - } - m_pMaterial= pMaterial; - m_pMaterial->addUsage(m_SelectionMaterialId); -} - -void GLC_SelectionMaterial::useDefautSelectionColor() -{ - if (NULL != m_pMaterial) - { - m_pMaterial->delUsage(m_SelectionMaterialId); - if (m_pMaterial->isUnused()) - { - delete m_pMaterial; - } - m_pMaterial= NULL; - } -} - - -// Execute OpenGL Material -void GLC_SelectionMaterial::glExecute() -{ - if (NULL != m_pMaterial) - { - m_pMaterial->glExecute(); - } - else - { - // Use default selection color - static GLfloat pAmbientColor[4]= {1.0f, 0.376f, 0.223f, 1.0f}; - - static GLfloat pDiffuseColor[4]= {1.0f, 0.376f, 0.223f, 1.0f}; - - static GLfloat pSpecularColor[4]= {1.0f, 1.0f, 1.0f, 1.0f}; - - static GLfloat pLightEmission[4]= {0.0f, 0.0f, 0.0f, 1.0f}; - - static float shininess= 50.0f; - - glColor4fv(pAmbientColor); - - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, pAmbientColor); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, pDiffuseColor); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, pSpecularColor); - glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, pLightEmission); - glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &shininess); - } -} - -void GLC_SelectionMaterial::initShader(const QGLContext* pContext) -{ - Q_ASSERT(m_SelectionShaderHash.contains(pContext)); - m_SelectionShaderHash.value(pContext)->createAndCompileProgrammShader(); -} - -void GLC_SelectionMaterial::setShaders(QFile& vertex, QFile& fragment, const QGLContext* pContext) -{ - if (m_SelectionShaderHash.contains(pContext)) - { - deleteShader(pContext); - } - GLC_Shader* pShader= new GLC_Shader; - - pShader->setVertexAndFragmentShader(vertex, fragment); - m_SelectionShaderHash.insert(pContext, pShader); -} - - -void GLC_SelectionMaterial::useShader() -{ - QGLContext* pContext= const_cast(QGLContext::currentContext()); - Q_ASSERT(NULL != pContext); - Q_ASSERT(pContext->isValid()); - if(!m_SelectionShaderHash.contains(pContext)) - { - Q_ASSERT(pContext->isSharing()); - pContext= sharingContext(pContext); - Q_ASSERT(NULL != pContext); - } - - m_SelectionShaderHash.value(pContext)->use(); -} - -void GLC_SelectionMaterial::unUseShader() -{ - QGLContext* pContext= const_cast(QGLContext::currentContext()); - Q_ASSERT(NULL != pContext); - Q_ASSERT(pContext->isValid()); - if(!m_SelectionShaderHash.contains(pContext)) - { - Q_ASSERT(pContext->isSharing()); - pContext= sharingContext(pContext); - Q_ASSERT(NULL != pContext); - } - - m_SelectionShaderHash.value(pContext)->unuse(); -} - -////////////////////////////////////////////////////////////////////// -// Private services fonction -////////////////////////////////////////////////////////////////////// -QGLContext* GLC_SelectionMaterial::sharingContext(const QGLContext* pContext) -{ - QGLContext* pSharingContext= NULL; - QHash::const_iterator iContext= m_SelectionShaderHash.constBegin(); - - while ((NULL == pSharingContext) && (iContext != m_SelectionShaderHash.constEnd())) - { - const QGLContext* pCurrentContext= iContext.key(); - if (QGLContext::areSharing(pContext, pCurrentContext)) - { - pSharingContext= const_cast(pCurrentContext); - } - ++iContext; - } - - return pSharingContext; -} - -//! delete shader -void GLC_SelectionMaterial::deleteShader(const QGLContext* pContext) -{ - Q_ASSERT(m_SelectionShaderHash.contains(pContext)); - GLC_Shader* pShader= m_SelectionShaderHash.value(pContext); - pShader->deleteShader(); - delete pShader; - m_SelectionShaderHash.remove(pContext); -} diff --git a/ground/gcs/src/libs/glc_lib/shading/glc_selectionmaterial.h b/ground/gcs/src/libs/glc_lib/shading/glc_selectionmaterial.h deleted file mode 100644 index ca3345742..000000000 --- a/ground/gcs/src/libs/glc_lib/shading/glc_selectionmaterial.h +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ -//! \file glc_selectionmaterial.h interface for the GLC_SelectionMaterial class. - -#ifndef GLC_SELECTIONMATERIAL_H_ -#define GLC_SELECTIONMATERIAL_H_ - -#include -#include -#include - -#include "../glc_ext.h" -#include "glc_shader.h" - -#include "../glc_config.h" - -class QGLContext; -class GLC_Material; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_SelectionMaterial -/*! \brief GLC_SelectionMaterial : Material used for selection feedback*/ - -////////////////////////////////////////////////////////////////////// - -class GLC_LIB_EXPORT GLC_SelectionMaterial -{ -private: - GLC_SelectionMaterial(); - - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Use the given material as selection material - static void useMaterial(GLC_Material* pMaterial); - - //! Use the default selection color - /*! if a selection material is used, unused it*/ - static void useDefautSelectionColor(); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Execute OpenGL Material - static void glExecute(); - //! Init shader - static void initShader(const QGLContext* pContext); - //! delete shader - static void deleteShader(const QGLContext* pContext); - //! Set shader - static void setShaders(QFile& vertex, QFile& fragment, const QGLContext* pContext); - //! Use shader - static void useShader(); - //! Unused shader - static void unUseShader(); - -//@} - -////////////////////////////////////////////////////////////////////// -// Private services fonction -////////////////////////////////////////////////////////////////////// -private: - //! Return the sharing context of the given context - static QGLContext* sharingContext(const QGLContext* pContext); - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// - -private: - //! Selection Shader - static QHash m_SelectionShaderHash; - - //! Selection material id - static GLC_uint m_SelectionMaterialId; - - //! Material of this selection material - static GLC_Material* m_pMaterial; - -}; - -#endif /*GLC_SELECTIONMATERIAL_H_*/ diff --git a/ground/gcs/src/libs/glc_lib/shading/glc_shader.cpp b/ground/gcs/src/libs/glc_lib/shading/glc_shader.cpp deleted file mode 100644 index 437a18886..000000000 --- a/ground/gcs/src/libs/glc_lib/shading/glc_shader.cpp +++ /dev/null @@ -1,392 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_shader.cpp implementation of the GLC_Shader class. - -#include "glc_shader.h" -#include -#include -#include "../glc_exception.h" -#include "../glc_state.h" -#include "../glc_context.h" -#include "glc_light.h" - -// Static member initialization -QStack GLC_Shader::m_ShadingGroupStack; -GLuint GLC_Shader::m_CurrentShadingGroupId= 0; -QHash GLC_Shader::m_ShaderProgramHash; - -GLC_Shader::GLC_Shader() -: m_VertexShader(QGLShader::Vertex) -, m_FragmentShader(QGLShader::Fragment) -, m_ProgramShader() -, m_ProgramShaderId(glc::GLC_GenShaderGroupID()) -, m_Name("Empty Shader") -, m_PositionAttributeId(-1) -, m_TextcoordAttributeId(-1) -, m_ColorAttributeId(-1) -, m_NormalAttributeId(-1) -, m_ModelViewLocationId(-1) -, m_MvpLocationId(-1) -, m_InvModelViewLocationId(-1) -, m_EnableLightingId(-1) -, m_LightsEnableStateId(-1) -, m_LightsPositionId() -, m_LightsAmbientColorId() -, m_LightsDiffuseColorId() -, m_LightsSpecularColorId() -, m_LightsSpotDirectionId() -, m_LightsAttenuationFactorsId() -, m_LightsSpotExponentId() -, m_LightsSpotCutoffAngleId() -, m_LightsComputeDistanceAttenuationId() -{ - initLightsUniformId(); - m_ShaderProgramHash.insert(m_ProgramShaderId, this); -} - -GLC_Shader::GLC_Shader(QFile& vertex, QFile& fragment) -: m_VertexShader(QGLShader::Vertex) -, m_FragmentShader(QGLShader::Fragment) -, m_ProgramShader() -, m_ProgramShaderId(glc::GLC_GenShaderGroupID()) -, m_Name("Empty Shader") -, m_PositionAttributeId(-1) -, m_TextcoordAttributeId(-1) -, m_ColorAttributeId(-1) -, m_NormalAttributeId(-1) -, m_ModelViewLocationId(-1) -, m_MvpLocationId(-1) -, m_InvModelViewLocationId(-1) -, m_EnableLightingId(-1) -, m_LightsEnableStateId(-1) -, m_LightsPositionId() -, m_LightsAmbientColorId() -, m_LightsDiffuseColorId() -, m_LightsSpecularColorId() -, m_LightsSpotDirectionId() -, m_LightsAttenuationFactorsId() -, m_LightsSpotExponentId() -, m_LightsSpotCutoffAngleId() -, m_LightsComputeDistanceAttenuationId() -{ - initLightsUniformId(); - m_ShaderProgramHash.insert(m_ProgramShaderId, this); - setVertexAndFragmentShader(vertex, fragment); -} - -GLC_Shader::GLC_Shader(const GLC_Shader& shader) -: m_VertexShader(QGLShader::Vertex) -, m_FragmentShader(QGLShader::Fragment) -, m_ProgramShader() -, m_ProgramShaderId(glc::GLC_GenShaderGroupID()) -, m_Name(shader.m_Name) -, m_PositionAttributeId(-1) -, m_TextcoordAttributeId(-1) -, m_ColorAttributeId(-1) -, m_NormalAttributeId(-1) -, m_ModelViewLocationId(-1) -, m_MvpLocationId(-1) -, m_InvModelViewLocationId(-1) -, m_EnableLightingId(-1) -, m_LightsEnableStateId(-1) -, m_LightsPositionId() -, m_LightsAmbientColorId() -, m_LightsDiffuseColorId() -, m_LightsSpecularColorId() -, m_LightsSpotDirectionId() -, m_LightsAttenuationFactorsId() -, m_LightsSpotExponentId() -, m_LightsSpotCutoffAngleId() -, m_LightsComputeDistanceAttenuationId() -{ - initLightsUniformId(); - m_ShaderProgramHash.insert(m_ProgramShaderId, this); - - if (shader.m_VertexShader.isCompiled()) - { - m_VertexShader.compileSourceCode(shader.m_VertexShader.sourceCode()); - } - if (shader.m_FragmentShader.isCompiled()) - { - m_FragmentShader.compileSourceCode(shader.m_FragmentShader.sourceCode()); - } - - createAndCompileProgrammShader(); -} - -GLC_Shader::~GLC_Shader() -{ - deleteShader(); -} - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -bool GLC_Shader::canBeDeleted() const -{ - return m_CurrentShadingGroupId != m_ProgramShaderId; -} - -int GLC_Shader::shaderCount() -{ - return m_ShaderProgramHash.size(); -} - -bool GLC_Shader::asShader(GLC_uint shadingGroupId) -{ - return m_ShaderProgramHash.contains(shadingGroupId); -} - -GLC_Shader* GLC_Shader::shaderHandle(GLC_uint shadingGroupId) -{ - return m_ShaderProgramHash.value(shadingGroupId); -} - -bool GLC_Shader::hasActiveShader() -{ - return 0 != m_CurrentShadingGroupId; -} - -GLC_Shader* GLC_Shader::currentShaderHandle() -{ - return m_ShaderProgramHash.value(m_CurrentShadingGroupId); -} - -////////////////////////////////////////////////////////////////////// -// OpenGL Functions -////////////////////////////////////////////////////////////////////// - -void GLC_Shader::use() -{ - if (GLC_State::isInSelectionMode()) return; - // Program shader must be valid - Q_ASSERT(m_ProgramShader.isLinked()); - - m_ShadingGroupStack.push(m_ProgramShaderId); - // Test if the program shader is not already the current one - if (m_CurrentShadingGroupId != m_ProgramShaderId) - { - m_CurrentShadingGroupId= m_ProgramShaderId; - m_ShaderProgramHash.value(m_CurrentShadingGroupId)->m_ProgramShader.bind(); - GLC_Context::current()->updateUniformVariables(); - } - -} - -bool GLC_Shader::use(GLC_uint shaderId) -{ - Q_ASSERT(0 != shaderId); - if (GLC_State::isInSelectionMode()) return false; - - if (m_ShaderProgramHash.contains(shaderId)) - { - m_ShadingGroupStack.push(shaderId); - // Test if the program shader is not already the current one - if (m_CurrentShadingGroupId != shaderId) - { - m_CurrentShadingGroupId= shaderId; - m_ShaderProgramHash.value(m_CurrentShadingGroupId)->m_ProgramShader.bind(); - GLC_Context::current()->updateUniformVariables(); - } - - return true; - } - else - { - return false; - } -} - -void GLC_Shader::unuse() -{ - - if (GLC_State::isInSelectionMode()) return; - - Q_ASSERT(!m_ShadingGroupStack.isEmpty()); - - const GLC_uint stackShadingGroupId= m_ShadingGroupStack.pop(); - if (m_ShadingGroupStack.isEmpty()) - { - m_CurrentShadingGroupId= 0; - m_ShaderProgramHash.value(stackShadingGroupId)->m_ProgramShader.release(); - } - else - { - m_CurrentShadingGroupId= m_ShadingGroupStack.top(); - m_ShaderProgramHash.value(m_CurrentShadingGroupId)->m_ProgramShader.bind(); - } -} - -void GLC_Shader::createAndCompileProgrammShader() -{ - qDebug() << "GLC_Shader::createAndCompileProgrammShader()"; - m_ProgramShader.addShader(&m_VertexShader); - m_ProgramShader.addShader(&m_FragmentShader); - - if (!m_ProgramShader.link()) - { - QString message("GLC_Shader::setVertexAndFragmentShader Failed to link program "); - GLC_Exception exception(message); - throw(exception); - } - else - { - m_PositionAttributeId= m_ProgramShader.attributeLocation("a_position"); - //qDebug() << "m_PositionAttributeId " << m_PositionAttributeId; - m_TextcoordAttributeId= m_ProgramShader.attributeLocation("a_textcoord0"); - //qDebug() << "m_TextcoordAttributeId " << m_TextcoordAttributeId; - m_ColorAttributeId= m_ProgramShader.attributeLocation("a_color"); - //qDebug() << "m_ColorAttributeId " << m_ColorAttributeId; - m_NormalAttributeId= m_ProgramShader.attributeLocation("a_normal"); - //qDebug() << "m_NormalAttributeId " << m_NormalAttributeId; - - m_ModelViewLocationId= m_ProgramShader.uniformLocation("modelview_matrix"); - //qDebug() << "m_ModelViewLocationId " << m_ModelViewLocationId; - m_MvpLocationId= m_ProgramShader.uniformLocation("mvp_matrix"); - //qDebug() << "m_MvpLocationId " << m_MvpLocationId; - m_InvModelViewLocationId= m_ProgramShader.uniformLocation("inv_modelview_matrix"); - //qDebug() << "m_InvModelViewLocationId " << m_InvModelViewLocationId; - m_EnableLightingId= m_ProgramShader.uniformLocation("enable_lighting"); - //qDebug() << "m_EnableLightingId " << m_EnableLightingId; - m_LightsEnableStateId= m_ProgramShader.uniformLocation("light_enable_state"); - //qDebug() << "m_LightsEnableStateId " << m_LightsEnableStateId; - const int size= GLC_Light::maxLightCount(); - for (int i= (GL_LIGHT0); i < (size + GL_LIGHT0); ++i) - { - m_LightsPositionId[i]= m_ProgramShader.uniformLocation("light_state[" + QString::number(i) + "].position"); - //qDebug() << "Position id " << m_LightsPositionId.value(i); - m_LightsAmbientColorId[i]= m_ProgramShader.uniformLocation("light_state[" + QString::number(i) + "].ambient_color"); - //qDebug() << "m_LightsAmbientColorId " << m_LightsAmbientColorId.value(i); - m_LightsDiffuseColorId[i]= m_ProgramShader.uniformLocation("light_state[" + QString::number(i) + "].diffuse_color"); - //qDebug() << "m_LightsDiffuseColorId " << m_LightsDiffuseColorId.value(i); - m_LightsSpecularColorId[i]= m_ProgramShader.uniformLocation("light_state[" + QString::number(i) + "].specular_color"); - //qDebug() << "m_LightsSpecularColorId " << m_LightsSpecularColorId.value(i); - m_LightsSpotDirectionId[i]= m_ProgramShader.uniformLocation("light_state[" + QString::number(i) + "].spot_direction"); - //qDebug() << "m_LightsSpotDirectionId " << m_LightsSpotDirectionId.value(i); - m_LightsAttenuationFactorsId[i]= m_ProgramShader.uniformLocation("light_state[" + QString::number(i) + "].attenuation_factors"); - //qDebug() << "m_LightsAttenuationFactorsId " << m_LightsAttenuationFactorsId.value(i); - m_LightsSpotExponentId[i]= m_ProgramShader.uniformLocation("light_state[" + QString::number(i) + "].spot_exponent"); - //qDebug() << "m_LightsSpotExponentId " << m_LightsSpotExponentId.value(i); - m_LightsSpotCutoffAngleId[i]= m_ProgramShader.uniformLocation("light_state[" + QString::number(i) + "].spot_cutoff_angle"); - //qDebug() << "m_LightsSpotCutoffAngleId " << m_LightsSpotCutoffAngleId.value(i); - m_LightsComputeDistanceAttenuationId[i]= m_ProgramShader.uniformLocation("light_state[" + QString::number(i) + "].compute_distance_attenuation"); - //qDebug() << "m_LightsComputeDistanceAttenuationId " << m_LightsComputeDistanceAttenuationId.value(i); - - - } - } -} - -void GLC_Shader::deleteShader() -{ - if (m_ProgramShaderId != 0) - { - // Test if the shader is the current one - if (m_CurrentShadingGroupId == m_ProgramShaderId) - { - qDebug() << "Warning deleting current shader"; - } - //removing shader id from the stack - if (m_ShadingGroupStack.contains(m_ProgramShaderId)) - { - int indexToDelete= m_ShadingGroupStack.indexOf(m_ProgramShaderId); - while (indexToDelete != -1) - { - m_ShadingGroupStack.remove(indexToDelete); - indexToDelete= m_ShadingGroupStack.indexOf(m_ProgramShaderId); - } - } - m_ShaderProgramHash.remove(m_ProgramShaderId); - } - -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - - -void GLC_Shader::setVertexAndFragmentShader(QFile& vertexFile, QFile& fragmentFile) -{ - m_Name= QFileInfo(vertexFile).baseName(); - vertexFile.open(QIODevice::ReadOnly); - m_VertexShader.compileSourceCode(vertexFile.readAll()); - vertexFile.close(); - - fragmentFile.open(QIODevice::ReadOnly); - m_FragmentShader.compileSourceCode(fragmentFile.readAll()); - fragmentFile.close(); -} - - -void GLC_Shader::replaceShader(const GLC_Shader& sourceShader) -{ - Q_ASSERT(isUsable() == sourceShader.isUsable()); - - // Test if the source shader is the same than this shader - if (this == &sourceShader) - { - return; - } - m_ProgramShader.removeAllShaders(); - - if (sourceShader.m_VertexShader.isCompiled()) - { - m_VertexShader.compileSourceCode(sourceShader.m_VertexShader.sourceCode()); - } - if (sourceShader.m_FragmentShader.isCompiled()) - { - m_FragmentShader.compileSourceCode(sourceShader.m_FragmentShader.sourceCode()); - } - - m_ProgramShader.link(); - -} - -void GLC_Shader::initLightsUniformId() -{ - m_LightsPositionId.clear(); - m_LightsAmbientColorId.clear(); - m_LightsDiffuseColorId.clear(); - m_LightsSpecularColorId.clear(); - m_LightsSpotDirectionId.clear(); - m_LightsAttenuationFactorsId.clear(); - m_LightsSpotExponentId.clear(); - m_LightsSpotCutoffAngleId.clear(); - m_LightsComputeDistanceAttenuationId.clear(); - - for (int i= 0; i < GLC_Light::maxLightCount(); ++i) - { - m_LightsPositionId.insert(GL_LIGHT0 + i, -1); - m_LightsAmbientColorId.insert(GL_LIGHT0 + i, -1); - m_LightsDiffuseColorId.insert(GL_LIGHT0 + i, -1); - m_LightsSpecularColorId.insert(GL_LIGHT0 + i, -1); - m_LightsSpotDirectionId.insert(GL_LIGHT0 + i, -1); - m_LightsAttenuationFactorsId.insert(GL_LIGHT0 + i, -1); - m_LightsSpotExponentId.insert(GL_LIGHT0 + i, -1); - m_LightsSpotCutoffAngleId.insert(GL_LIGHT0 + i, -1); - m_LightsComputeDistanceAttenuationId.insert(GL_LIGHT0 + i, -1); - } -} - diff --git a/ground/gcs/src/libs/glc_lib/shading/glc_shader.h b/ground/gcs/src/libs/glc_lib/shading/glc_shader.h deleted file mode 100644 index a08cc550c..000000000 --- a/ground/gcs/src/libs/glc_lib/shading/glc_shader.h +++ /dev/null @@ -1,322 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_shader.h interface for the GLC_Shader class. - -#ifndef GLC_SHADER_H_ -#define GLC_SHADER_H_ - -#include "../glc_global.h" -#include -#include -#include -#include -#include -#include -#include - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Shader -/*! \brief GLC_Shader : OpenGL shader abstraction*/ - -/*! An GLC_Shader encapsulate vertex, fragment shader and programm\n - * GLC_Shader provide functionnality to load, compile and execute - * GLSL vertex and fragment shader. - */ - -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_Shader -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Default constructor - GLC_Shader(); - - //! Construct shader with specifie vertex and fragment - GLC_Shader(QFile&, QFile&); - - //! Copy constructor - GLC_Shader(const GLC_Shader&); - - //! Shader destructor - ~GLC_Shader(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the program shader id - inline GLuint id() const - {return m_ProgramShaderId;} - - //! Return true if the shader is usable - inline bool isUsable() const - {return m_ProgramShader.isLinked();} - - //! Return true if the shader can be deleted - bool canBeDeleted() const; - - //! Return the shader's name - inline QString name() const - {return m_Name;} - - //! Return an handle to the QGLProgramShader of this shader - inline QGLShaderProgram* programShaderHandle() - {return &m_ProgramShader;} - - //! Return the position attribute id - inline int positionAttributeId() const - {return m_PositionAttributeId;} - - //! Return the texture coordinate attribute id - inline int textureAttributeId() const - {return m_TextcoordAttributeId;} - - //! Return the color attribute id - inline int colorAttributeId() const - {return m_ColorAttributeId;} - - //! Return the normal attribute id - inline int normalAttributeId() const - {return m_NormalAttributeId;} - - //! Return the number of shader - static int shaderCount(); - - //! Return true if the given shading group id as a shader - static bool asShader(GLC_uint shadingGroupId); - - //! Return handle to the shader associated to the given group id - /*! Return NULL if the given shading group as no associated shader*/ - static GLC_Shader* shaderHandle(GLC_uint shadingGroupId); - - //! Return true if there is an active shader - static bool hasActiveShader(); - - //! Return handle to the current active shader - /*! Return NULL if there is no current active shader*/ - static GLC_Shader* currentShaderHandle(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Set Vertex and fragment shaders - void setVertexAndFragmentShader(QFile&, QFile&); - - //! Replace this shader by a copy of another shader - /* If this shader is usable replacing shader must be usable*/ - void replaceShader(const GLC_Shader&); - - //! Assignement operator which use replace shader method - inline GLC_Shader& operator=(const GLC_Shader& shader) - { - replaceShader(shader); - return *this; - } - - //! Set the Shader Name - inline void setName(const QString& name) - {m_Name= name;} - - //! Return the modelView location id - inline int modelViewLocationId() const - {return m_ModelViewLocationId;} - - //! Return the modelView Projection matrix id - inline int mvpLocationId() const - {return m_MvpLocationId;} - - //! Return the inverse modelView location id - inline int invModelViewLocationId() const - {return m_InvModelViewLocationId;} - - //! Return the enable lighting location id - inline int enableLightingId() const - {return m_EnableLightingId;} - - //! Return the lights enable state id - inline int lightsEnableStateId() const - {return m_LightsEnableStateId;} - - //! Return the light position id of the given light id - inline int lightPositionId(GLenum lightId) const - {return m_LightsPositionId.value(lightId);} - - //! Return the light ambient color id of the given light id - inline int lightAmbientColorId(GLenum lightId) const - {return m_LightsAmbientColorId.value(lightId);} - - //! Return the light diffuse color id of the given light id - inline int lightDiffuseColorId(GLenum lightId) const - {return m_LightsDiffuseColorId.value(lightId);} - - //! Return the light specular color id of the given light id - inline int lightSpecularColorId(GLenum lightId) const - {return m_LightsSpecularColorId.value(lightId);} - - //! Return the light spot direction id of the given light id - inline int lightSpotDirectionId(GLenum lightId) const - {return m_LightsSpotDirectionId.value(lightId);} - - //! Return the light attenuation factors id of the given light id - inline int lightAttebuationFactorsId(GLenum lightId) const - {return m_LightsAttenuationFactorsId.value(lightId);} - - //! Return the light spot exponent id of the given light id - inline int lightSpotExponentId(GLenum lightId) const - {return m_LightsSpotExponentId.value(lightId);} - - //! Return the light spot cutoff id of the given light id - inline int lightSpotCutoffId(GLenum lightId) const - {return m_LightsSpotCutoffAngleId.value(lightId);} - - //! Return the light compute distance attenuation id of the given light id - inline int lightComputeDistanceAttenuationId(GLenum lightId) const - {return m_LightsComputeDistanceAttenuationId.value(lightId);} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Use this shader program - /*! Throw GLC_Exception if the program is not usable*/ - void use(); - - //! Use specified program shader - /*! Return true if the given shading group id is usable*/ - static bool use(GLC_uint ShadingGroupId); - - //! unuse programm shader - static void unuse(); - - //! Compile and attach shaders to a program shader - /*! Throw GLC_Exception if vertex and fragment shader are not been set*/ - void createAndCompileProgrammShader(); - - //!Delete the shader - void deleteShader(); -//@} - -////////////////////////////////////////////////////////////////////// -// private services function -////////////////////////////////////////////////////////////////////// -private: - //! Init light uniform id - void initLightsUniformId(); -////////////////////////////////////////////////////////////////////// -// private members -////////////////////////////////////////////////////////////////////// -private: - //! The shading group Stack - static QStack m_ShadingGroupStack; - - //! The current shading goup ID - static GLC_uint m_CurrentShadingGroupId; - - //! Map between shading group id and program shader - static QHash m_ShaderProgramHash; - - //! Vertex shader - QGLShader m_VertexShader; - - //! Fragment shader - QGLShader m_FragmentShader; - - //! The programShader - QGLShaderProgram m_ProgramShader; - - //! Programm shader ID - GLC_uint m_ProgramShaderId; - - //! The Shader's name - QString m_Name; - - //! The position attribute id - int m_PositionAttributeId; - - //! The Texture coordinate attribute id - int m_TextcoordAttributeId; - - //! The color attribute id - int m_ColorAttributeId; - - //! The Normal attribute id - int m_NormalAttributeId; - - //! The modelView location matrix id - int m_ModelViewLocationId; - - //! The modelView Projection matrix id - int m_MvpLocationId; - - //! The inverse modelView location id - int m_InvModelViewLocationId; - - //! The enable lighting id - int m_EnableLightingId; - - //! Lights enable states id - int m_LightsEnableStateId; - - //! Lights positions id - QMap m_LightsPositionId; - - //! Lights ambient color id - QMap m_LightsAmbientColorId; - - //! Lights diffuse color id - QMap m_LightsDiffuseColorId; - - //! Lights specular color id - QMap m_LightsSpecularColorId; - - //! Lights spot direction id - QMap m_LightsSpotDirectionId; - - //! Lights attenuation factors id - QMap m_LightsAttenuationFactorsId; - - //! Lights spot exponent id - QMap m_LightsSpotExponentId; - - //! Lights spot cutoff angle id - QMap m_LightsSpotCutoffAngleId; - - //! Lights compute distance attenuation - QMap m_LightsComputeDistanceAttenuationId; - -}; - -#endif /*GLC_SHADER_H_*/ diff --git a/ground/gcs/src/libs/glc_lib/shading/glc_texture.cpp b/ground/gcs/src/libs/glc_lib/shading/glc_texture.cpp deleted file mode 100644 index be525d55e..000000000 --- a/ground/gcs/src/libs/glc_lib/shading/glc_texture.cpp +++ /dev/null @@ -1,341 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_texture.cpp implementation of the GLC_Texture class. - - -#include "glc_texture.h" -#include "../glc_exception.h" -#include "../glc_global.h" - -// Quazip library -#include "../quazip/quazip.h" -#include "../quazip/quazipfile.h" - -#include - -// The default maximum texture size -QSize GLC_Texture::m_MaxTextureSize(676, 676); - -// The Minimum texture size -const QSize GLC_Texture::m_MinTextureSize(10, 10); - -QHash GLC_Texture::m_TextureIdUsage; - -////////////////////////////////////////////////////////////////////// -// Constructor Destructor -////////////////////////////////////////////////////////////////////// - -//! Default constructor -GLC_Texture::GLC_Texture() -: m_pQGLContext(NULL) -, m_FileName() -, m_GlTextureID(0) -, m_textureImage() -, m_TextureSize() -, m_HasAlphaChannel(false) -{ - -} - -// Constructor with fileName -GLC_Texture::GLC_Texture(const QString &Filename) -: m_pQGLContext(NULL) -, m_FileName(Filename) -, m_GlTextureID(0) -, m_textureImage(loadFromFile(m_FileName)) -, m_TextureSize() -, m_HasAlphaChannel(m_textureImage.hasAlphaChannel()) -{ - if (m_textureImage.isNull()) - { - QString ErrorMess("GLC_Texture::GLC_Texture open image : "); - ErrorMess.append(m_FileName).append(" Failed"); - qDebug() << ErrorMess; - GLC_Exception e(ErrorMess); - throw(e); - } -} -// Constructor with QFile -GLC_Texture::GLC_Texture(const QFile &file) -: m_pQGLContext(NULL) -, m_FileName(file.fileName()) -, m_GlTextureID(0) -, m_textureImage() -, m_TextureSize() -, m_HasAlphaChannel(m_textureImage.hasAlphaChannel()) -{ - m_textureImage.load(const_cast(&file), QFileInfo(m_FileName).suffix().toLocal8Bit()); - if (m_textureImage.isNull()) - { - QString ErrorMess("GLC_Texture::GLC_Texture open image : "); - ErrorMess.append(m_FileName).append(" Failed"); - qDebug() << ErrorMess; - GLC_Exception e(ErrorMess); - throw(e); - } -} - -// Constructor with QImage -GLC_Texture::GLC_Texture(const QImage& image, const QString& fileName) -: m_pQGLContext(NULL) -, m_FileName(fileName) -, m_GlTextureID(0) -, m_textureImage(image) -, m_TextureSize() -, m_HasAlphaChannel(m_textureImage.hasAlphaChannel()) -{ - Q_ASSERT(!m_textureImage.isNull()); -} - -GLC_Texture::GLC_Texture(const GLC_Texture &TextureToCopy) -: m_pQGLContext(TextureToCopy.m_pQGLContext) -, m_FileName(TextureToCopy.m_FileName) -, m_GlTextureID(TextureToCopy.m_GlTextureID) -, m_textureImage(TextureToCopy.m_textureImage) -, m_TextureSize(TextureToCopy.m_TextureSize) -, m_HasAlphaChannel(m_textureImage.hasAlphaChannel()) -{ - if (m_textureImage.isNull()) - { - QString ErrorMess("GLC_Texture::GLC_Texture open image : "); - ErrorMess.append(m_FileName).append(" Failed"); - qDebug() << ErrorMess; - GLC_Exception e(ErrorMess); - throw(e); - } - addThisOpenGLTextureId(); - -} - -// Overload "=" operator -GLC_Texture& GLC_Texture::operator=(const GLC_Texture& texture) -{ - if (!(*this == texture)) - { - removeThisOpenGLTextureId(); - m_pQGLContext= texture.m_pQGLContext; - m_FileName= texture.m_FileName; - m_GlTextureID= texture.m_GlTextureID; - addThisOpenGLTextureId(); - m_textureImage= texture.m_textureImage; - m_TextureSize= texture.m_TextureSize; - m_HasAlphaChannel= m_textureImage.hasAlphaChannel(); - } - - return *this; -} - -GLC_Texture::~GLC_Texture() -{ - //qDebug() << "GLC_Texture::~GLC_Texture Texture ID : " << m_GlTextureID; - removeThisOpenGLTextureId(); -} -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -// Return true if texture are the same -bool GLC_Texture::operator==(const GLC_Texture& texture) const -{ - bool result; - if (this == &texture) - { - result= true; - } - else - { - result= (m_FileName == texture.m_FileName) && (m_textureImage == texture.m_textureImage); - } - return result; -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -// Set the maximum texture size -void GLC_Texture::setMaxTextureSize(const QSize& size) -{ - if ((size.height() > m_MinTextureSize.height()) && (size.width() > m_MinTextureSize.width())) - { - m_MaxTextureSize= size; - } - else - { - qDebug() << "GLC_Texture::setMaxTextureSize m_MaxTextureSize set to m_MinTextureSize"; - m_MaxTextureSize= m_MinTextureSize; - } -} - -////////////////////////////////////////////////////////////////////// -// Private OpenGL functions -////////////////////////////////////////////////////////////////////// -// Load the texture -void GLC_Texture::glLoadTexture(QGLContext* pContext) -{ - if (m_GlTextureID == 0) - { - if (NULL == pContext) - { - m_pQGLContext= const_cast(QGLContext::currentContext()); - } - else - { - m_pQGLContext= pContext; - } - - // Test image size - if ((m_textureImage.height() > m_MaxTextureSize.height()) - || (m_textureImage.width() > m_MaxTextureSize.width())) - { - QImage rescaledImage; - if(m_textureImage.height() > m_textureImage.width()) - { - rescaledImage= m_textureImage.scaledToHeight(m_MaxTextureSize.height(), Qt::SmoothTransformation); - } - else - { - rescaledImage= m_textureImage.scaledToWidth(m_MaxTextureSize.width(), Qt::SmoothTransformation); - } - m_textureImage= rescaledImage; - m_TextureSize= m_textureImage.size(); - } - else - { - m_TextureSize= m_textureImage.size(); - } - m_GlTextureID= m_pQGLContext->bindTexture(m_textureImage); - addThisOpenGLTextureId(); - - //qDebug() << "GLC_Texture::glcBindTexture Texture ID = " << m_GlTextureID; - } -} - -// Bind texture in 2D mode -void GLC_Texture::glcBindTexture(void) -{ - if (m_GlTextureID == 0) - { - glLoadTexture(); - } - glBindTexture(GL_TEXTURE_2D, m_GlTextureID); -} - -QImage GLC_Texture::loadFromFile(const QString& fileName) -{ - QImage resultImage; - if (glc::isArchiveString(fileName)) - { - - // Load the image from a zip archive - QuaZip* p3dxmlArchive= new QuaZip(glc::archiveFileName(fileName)); - // Trying to load archive - if(!p3dxmlArchive->open(QuaZip::mdUnzip)) - { - delete p3dxmlArchive; - return QImage(); - } - else - { - // Set the file Name Codec - p3dxmlArchive->setFileNameCodec("IBM866"); - } - QString imageFileName= glc::archiveEntryFileName(fileName); - - // Create QuaZip File - QuaZipFile* p3dxmlFile= new QuaZipFile(p3dxmlArchive); - - // Get the file of the 3dxml - if (!p3dxmlArchive->setCurrentFile(imageFileName, QuaZip::csInsensitive)) - { - delete p3dxmlFile; - delete p3dxmlArchive; - return QImage(); - } - - // Open the file of the 3dxml - if(!p3dxmlFile->open(QIODevice::ReadOnly)) - { - delete p3dxmlFile; - delete p3dxmlArchive; - return QImage(); - } - resultImage.load(p3dxmlFile, QFileInfo(imageFileName).suffix().toLocal8Bit()); - p3dxmlFile->close(); - delete p3dxmlFile; - delete p3dxmlArchive; - } - else - { - resultImage.load(fileName); - } - - return resultImage; -} - -void GLC_Texture::removeThisOpenGLTextureId() -{ - if ( 0 != m_GlTextureID) - { - Q_ASSERT(m_TextureIdUsage.contains(m_GlTextureID)); - --m_TextureIdUsage[m_GlTextureID]; - if (m_TextureIdUsage.value(m_GlTextureID) == 0) - { - m_pQGLContext->deleteTexture(m_GlTextureID); - m_TextureIdUsage.remove(m_GlTextureID); - m_GlTextureID= 0; - } - } -} - -void GLC_Texture::addThisOpenGLTextureId() -{ - if (0 != m_GlTextureID) - { - if (m_TextureIdUsage.contains(m_GlTextureID)) - { - ++m_TextureIdUsage[m_GlTextureID]; - } - else - { - m_TextureIdUsage.insert(m_GlTextureID, 1); - } - } -} - -// Non-member stream operator -QDataStream &operator<<(QDataStream &stream, const GLC_Texture &texture) -{ - stream << texture.fileName(); - - return stream; -} -QDataStream &operator>>(QDataStream &stream, GLC_Texture &texture) -{ - QString fileName; - stream >> fileName; - texture= GLC_Texture(fileName); - - return stream; -} - diff --git a/ground/gcs/src/libs/glc_lib/shading/glc_texture.h b/ground/gcs/src/libs/glc_lib/shading/glc_texture.h deleted file mode 100644 index 86d1c52de..000000000 --- a/ground/gcs/src/libs/glc_lib/shading/glc_texture.h +++ /dev/null @@ -1,186 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_texture.h interface for the GLC_Texture class. - -#ifndef GLC_TEXTURE_H_ -#define GLC_TEXTURE_H_ - -#include -#include - -#include "../glc_config.h" - -///////////////////////////////////////////////////////////////////// -//! \class GLC_Texture -/*! \brief GLC_Texture : Image texture */ - -/*! Image texture define a texture map in 2 D coordinate system*/ -////////////////////////////////////////////////////////////////////// - - -class GLC_LIB_EXPORT GLC_Texture -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// - -public: - //! Default constructor - GLC_Texture(); - - //! Constructor with fileName - GLC_Texture(const QString&); - - //! Constructor with QFile - GLC_Texture(const QFile&); - - //! Constructor with QImage - GLC_Texture(const QImage&, const QString& fileName= QString()); - - //! Copy constructor - GLC_Texture(const GLC_Texture& TextureToCopy); - - //! Overload "=" operator - GLC_Texture& operator=(const GLC_Texture&); - - //! Default Destructor - virtual ~GLC_Texture(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the QGLContext of the texture - inline QGLContext* context() const - {return m_pQGLContext;} - - //! Return the texture File Name - inline QString fileName() const - {return m_FileName;} - - //! Return OpenGL Texture Id - inline GLuint GL_ID() const - {return m_GlTextureID;} - - //! Return true if the texture is loaded - inline bool isLoaded() const - {return (m_GlTextureID != 0);} - - //! Return the texture size - inline QSize size() const - {return m_TextureSize;} - - //! Return the maximum texture size - static QSize maxSize() - {return m_MaxTextureSize;} - - //! Return true if texture are the same - bool operator==(const GLC_Texture&) const; - - //! Return true if the texture has alpha channel - inline bool hasAlphaChannel() const - { return m_HasAlphaChannel;} - - //! Return the an image of the texture - inline QImage imageOfTexture() const - { return m_textureImage;} - - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - // Set the maximum texture size - static void setMaxTextureSize(const QSize&); - -//@} -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Load the texture - void glLoadTexture(QGLContext* pContext= NULL); - //! Bind texture in 2D mode - void glcBindTexture(void); - - -////////////////////////////////////////////////////////////////////// -/*! @name Private services functions */ -//@{ -////////////////////////////////////////////////////////////////////// -private: - //! Load the image of this texture from the given fileName and return resutling image - QImage loadFromFile(const QString& fileName); - - //! Remove this Opengl texture id - void removeThisOpenGLTextureId(); - - //! Add this Opengl texture id - void addThisOpenGLTextureId(); - -//@} - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// - -private: - //! OpenGL Context - QGLContext *m_pQGLContext; - - //! Texture Name - QString m_FileName; - - //! OpenGL Texture ID - GLuint m_GlTextureID; - - //! QImage off the texture - QImage m_textureImage; - - //! Size of the texture - QSize m_TextureSize; - - //! Flag to know if the texture has alpha channel - bool m_HasAlphaChannel; - - //! Static member used to check texture size - static QSize m_MaxTextureSize; - static const QSize m_MinTextureSize; - - //! Static hash table to manage OpenGL testure ID - static QHash m_TextureIdUsage; -}; - -//! Non-member stream operator -QDataStream &operator<<(QDataStream &, const GLC_Texture &); -QDataStream &operator>>(QDataStream &, GLC_Texture &); - - -#endif //GLC_TEXTURE_H_ diff --git a/ground/gcs/src/libs/glc_lib/shading/shaders/default.frag b/ground/gcs/src/libs/glc_lib/shading/shaders/default.frag deleted file mode 100644 index e69de29bb..000000000 diff --git a/ground/gcs/src/libs/glc_lib/shading/shaders/default.vert b/ground/gcs/src/libs/glc_lib/shading/shaders/default.vert deleted file mode 100644 index 30044d866..000000000 --- a/ground/gcs/src/libs/glc_lib/shading/shaders/default.vert +++ /dev/null @@ -1,12 +0,0 @@ -uniform mat4 modelview_matrix; -uniform mat4 mvp_matrix; - -attribute vec4 a_position; -attribute vec4 a_textcoord0; -attribute vec4 a_color; -attribute vec3 a_normal; - -void main() -{ - gl_Position= mvp_matrix * a_position; -} \ No newline at end of file diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_camera.cpp b/ground/gcs/src/libs/glc_lib/viewport/glc_camera.cpp deleted file mode 100644 index c830a83c6..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_camera.cpp +++ /dev/null @@ -1,470 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - Copyright (C) 2009 Laurent Bauer - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_camera.cpp Implementation of the GLC_Camera class. - -#include "glc_camera.h" -#include "../glc_context.h" - -#include - -using namespace glc; -////////////////////////////////////////////////////////////////////// -// Constructor Destructor -////////////////////////////////////////////////////////////////////// -GLC_Camera::GLC_Camera() -: GLC_Object("Camera") -, m_Eye(0,0,1) -, m_Target() -, m_VectUp(Y_AXIS) -, m_ModelViewMatrix() -, m_DefaultVectUp(Y_AXIS) -{ - -} - -GLC_Camera::GLC_Camera(const GLC_Point3d &Eye, const GLC_Point3d &Target, const GLC_Vector3d &Up) -: GLC_Object("Camera") -, m_Eye() -, m_Target() -, m_VectUp() -, m_ModelViewMatrix() -, m_DefaultVectUp(Y_AXIS) -{ - setCam(Eye, Target, Up); - createMatComp(); -} - -// Copy constructor -GLC_Camera::GLC_Camera(const GLC_Camera& cam) -: GLC_Object(cam) -, m_Eye(cam.m_Eye) -, m_Target(cam.m_Target) -, m_VectUp(cam.m_VectUp) -, m_ModelViewMatrix(cam.m_ModelViewMatrix) -, m_DefaultVectUp(cam.m_DefaultVectUp) -{ - -} - -///////////////////////////////////////////////////////////////////// -// Get Functions -///////////////////////////////////////////////////////////////////// - -// equality operator -bool GLC_Camera::operator==(const GLC_Camera& cam) const -{ - return (m_Eye == cam.m_Eye) && (m_Target == cam.m_Target) - && (m_VectUp == cam.m_VectUp) && (m_DefaultVectUp == cam.m_DefaultVectUp); -} - - -///////////////////////////////////////////////////////////////////// -// Set Functions -///////////////////////////////////////////////////////////////////// -GLC_Camera& GLC_Camera::orbit(GLC_Vector3d VectOldPoss, GLC_Vector3d VectCurPoss) -{ - // Map Vectors - GLC_Matrix4x4 invMat(m_ModelViewMatrix); - invMat.invert(); - VectOldPoss= invMat * VectOldPoss; - VectCurPoss= invMat * VectCurPoss; - - // Compute rotation matrix - const GLC_Vector3d VectAxeRot(VectCurPoss ^ VectOldPoss); - // Check if rotation vector is not null - if (!VectAxeRot.isNull()) - { // Ok, is not null - const double Angle= acos(VectCurPoss * VectOldPoss); - const GLC_Matrix4x4 MatOrbit(VectAxeRot, Angle); - - // Camera transformation - m_Eye= (MatOrbit * (m_Eye - m_Target)) + m_Target; - m_VectUp= MatOrbit * m_VectUp; - createMatComp(); - } - - return *this; -} - -GLC_Camera& GLC_Camera::pan(GLC_Vector3d VectDep) -{ - // Vector mapping - GLC_Matrix4x4 invMat(m_ModelViewMatrix); - invMat.invert(); - VectDep= invMat * VectDep; - - // Camera transformation - m_Eye= m_Eye + VectDep; - m_Target= m_Target + VectDep; - - return *this; -} - -GLC_Camera& GLC_Camera::zoom(double factor) -{ - Q_ASSERT(factor > 0); - // Eye->target vector - GLC_Vector3d VectCam(m_Eye - m_Target); - - // Compute new vector length - const double Norme= VectCam.length() * 1 / factor; - VectCam.setLength(Norme); - - m_Eye= VectCam + m_Target; - - return *this; -} - -// Move camera -GLC_Camera& GLC_Camera::move(const GLC_Matrix4x4 &MatMove) -{ - m_Eye= MatMove * m_Eye; - m_Target= MatMove * m_Target; - m_VectUp= MatMove.rotationMatrix() * m_VectUp; - createMatComp(); - - return *this; -} - -// Rotate around an axis -GLC_Camera& GLC_Camera::rotateAround(const GLC_Vector3d& axis, const double& angle, const GLC_Point3d& point) -{ - const GLC_Matrix4x4 rotationMatrix(axis, angle); - translate(-point); - move(rotationMatrix); - translate(point); - - return *this; -} - -// Rotate around camera target -GLC_Camera& GLC_Camera::rotateAroundTarget(const GLC_Vector3d& axis, const double& angle) -{ - GLC_Point3d target(m_Target); - rotateAround(axis, angle, target); - - return *this; -} - -GLC_Camera& GLC_Camera::translate(const GLC_Vector3d &VectTrans) -{ - m_Eye= m_Eye + VectTrans; - m_Target= m_Target + VectTrans; - - return *this; -} - -GLC_Camera& GLC_Camera::setEyeCam(const GLC_Point3d &Eye) -{ - // Old camera's vector - GLC_Vector3d VectOldCam(m_Eye - m_Target); - // New camera's vector - GLC_Vector3d VectCam(Eye - m_Target); - if ( !(VectOldCam - VectCam).isNull() ) - { - VectOldCam.setLength(1); - VectCam.setLength(1); - const double Angle= acos(VectOldCam * VectCam); - if ( !qFuzzyCompare(Angle, 0.0) && !qFuzzyCompare(PI - Angle, 0.0)) - { - const GLC_Vector3d VectAxeRot(VectOldCam ^ VectCam); - const GLC_Matrix4x4 MatRot(VectAxeRot, Angle); - m_VectUp= MatRot * m_VectUp; - } - else - { - if ( qFuzzyCompare(PI - Angle, 0.0)) - { // Angle de 180% - m_VectUp.invert(); - } - } - - setCam(Eye, m_Target, m_VectUp); - } - - return *this; -} - -GLC_Camera& GLC_Camera::setTargetCam(const GLC_Point3d &Target) -{ - // Old camera's vector - GLC_Vector3d VectOldCam(m_Eye - m_Target); - // New camera's vector - GLC_Vector3d VectCam(m_Eye - Target); - if ( !(VectOldCam - VectCam).isNull() ) - { - VectOldCam.setLength(1); - VectCam.setLength(1); - const double Angle= acos(VectOldCam * VectCam); - if ( !qFuzzyCompare(Angle, 0.0) && !qFuzzyCompare(PI - Angle, 0.0)) - { - const GLC_Vector3d VectAxeRot(VectOldCam ^ VectCam); - const GLC_Matrix4x4 MatRot(VectAxeRot, Angle); - m_VectUp= MatRot * m_VectUp; - } - else - { - if ( qFuzzyCompare(PI - Angle, 0.0)) - { // Angle of 180% - m_VectUp.invert(); - } - } - - setCam(m_Eye, Target, m_VectUp); - } - - return *this; -} - -GLC_Camera& GLC_Camera::setUpCam(const GLC_Vector3d &Up) -{ - if ( !(m_VectUp - Up).isNull() ) - { - if (!qFuzzyCompare(forward().angleWithVect(Up), 0.0)) - { - setCam(m_Eye, m_Target, Up); - } - } - - return *this; -} - -GLC_Camera& GLC_Camera::setCam(GLC_Point3d Eye, GLC_Point3d Target, GLC_Vector3d Up) -{ - Up.setLength(1); - - const GLC_Vector3d VectCam((Eye - Target).setLength(1)); - const double Angle= acos(VectCam * Up); - - /* m_VectUp and VectCam could not be parallel - * m_VectUp could not be NULL - * VectCam could not be NULL */ - //Q_ASSERT((Angle > EPSILON) && ((PI - Angle) > EPSILON)); - - if ( !qFuzzyCompare(Angle - (PI / 2), 0.0)) - { // Angle not equal to 90 - const GLC_Vector3d AxeRot(VectCam ^ Up); - GLC_Matrix4x4 MatRot(AxeRot, PI / 2); - Up= MatRot * VectCam; - } - - m_Eye= Eye; - m_Target= Target; - m_VectUp= Up; - createMatComp(); - - return *this; -} - -//! Set the camera by copying another camera -GLC_Camera& GLC_Camera::setCam(const GLC_Camera& cam) -{ - m_Eye= cam.m_Eye; - m_Target= cam.m_Target; - m_VectUp= cam.m_VectUp; - m_ModelViewMatrix= cam.m_ModelViewMatrix; - - return *this; -} - - -GLC_Camera& GLC_Camera::setDistEyeTarget(double Longueur) -{ - GLC_Vector3d VectCam(forward()); - VectCam.setLength(Longueur); - m_Eye= m_Target - VectCam; - - return *this; -} -GLC_Camera& GLC_Camera::setDistTargetEye(double Longueur) -{ - GLC_Vector3d VectCam(forward()); - VectCam.setLength(Longueur); - m_Target= m_Eye + VectCam; - - return *this; -} - -// Assignment operator -GLC_Camera &GLC_Camera::operator=(const GLC_Camera& cam) -{ - GLC_Object::operator=(cam); - m_Eye= cam.m_Eye; - m_Target= cam.m_Target; - m_VectUp= cam.m_VectUp; - m_ModelViewMatrix= cam.m_ModelViewMatrix; - m_DefaultVectUp= cam.m_DefaultVectUp; - - return *this; -} -// almost equality (Bauer Laurent) -bool GLC_Camera::isAlmostEqualTo(const GLC_Camera& cam, const double distanceAccuracy) const -{ - GLC_Vector3d incident1 = m_Target - m_Eye; - GLC_Vector3d incident2 = cam.m_Target - cam.m_Eye; - - double allowedGap = incident1.length() * distanceAccuracy; - GLC_Point3d left1 = incident1 ^ m_VectUp; - GLC_Point3d left2 = incident2 ^ cam.m_VectUp; - - return ((m_Eye - cam.m_Eye).length() < allowedGap ) && ( (m_Target - cam.m_Target).length() < allowedGap) - && ((left1 - left2).length() < allowedGap) ; -} - -// Return the standard front view form this camera -GLC_Camera GLC_Camera::frontView() const -{ - GLC_Vector3d eye; - - if (m_DefaultVectUp == glc::Z_AXIS) - { - eye.setVect(0.0, -1.0, 0.0); - } - else // Y_AXIS or X_AXIS - { - eye.setVect(0.0, 0.0, 1.0); - } - eye= eye + m_Target; - - GLC_Camera newCam(eye, m_Target, m_DefaultVectUp); - newCam.setDistEyeTarget(distEyeTarget()); - newCam.setDefaultUpVector(m_DefaultVectUp); - return newCam; -} - -// Return the standard rear view form this camera -GLC_Camera GLC_Camera::rearView() const -{ - return frontView().rotateAroundTarget(m_DefaultVectUp, glc::PI); -} - -// Return the standard right view form this camera -GLC_Camera GLC_Camera::rightView() const -{ - return frontView().rotateAroundTarget(m_DefaultVectUp, glc::PI / 2.0);} - -// Return the standard left view form this camera -GLC_Camera GLC_Camera::leftView() const -{ - return frontView().rotateAroundTarget(m_DefaultVectUp, - glc::PI / 2.0); -} - -// Return the standard top view form this camera -GLC_Camera GLC_Camera::topView() const -{ - GLC_Vector3d eye= m_DefaultVectUp; - eye= eye + m_Target; - GLC_Vector3d up; - - if (m_DefaultVectUp == glc::Y_AXIS) - { - up.setVect(0.0, 0.0, -1.0); - } - else // Z_AXIS or X_AXIS - { - up.setVect(0.0, 1.0, 0.0); - } - - GLC_Camera newCam(eye, m_Target, up); - newCam.setDistEyeTarget(distEyeTarget()); - newCam.setDefaultUpVector(m_DefaultVectUp); - - return newCam; -} - -// Return the standard bottom view form this camera -GLC_Camera GLC_Camera::bottomView() const -{ - GLC_Camera newCam(topView()); - newCam.rotateAroundTarget(newCam.upVector(), glc::PI); - - return newCam; -} - -// Return the standard isoview from his camera -GLC_Camera GLC_Camera::isoView() const -{ - GLC_Vector3d eye; - if (m_DefaultVectUp == glc::Z_AXIS) - { - eye.setVect(-1.0, -1.0, 1.0); - } - else if (m_DefaultVectUp == glc::Y_AXIS) - { - eye.setVect(-1.0, 1.0, 1.0); - } - else - { - eye.setVect(1.0, 1.0, 1.0); - } - - eye= eye + m_Target; - - GLC_Camera newCam(eye, m_Target, m_DefaultVectUp); - newCam.setDistEyeTarget(distEyeTarget()); - newCam.setDefaultUpVector(m_DefaultVectUp); - return newCam; -} - -////////////////////////////////////////////////////////////////////// -// OpenGL Functions -////////////////////////////////////////////////////////////////////// -void GLC_Camera::glExecute() -{ - GLC_Context::current()->glcMultMatrix(modelViewMatrix()); -} - -////////////////////////////////////////////////////////////////////// -// Private services Functions -////////////////////////////////////////////////////////////////////// - -void GLC_Camera::createMatComp(void) -{ - const GLC_Vector3d forward((m_Target - m_Eye).normalize()); - const GLC_Vector3d side((forward ^ m_VectUp).normalize()); - - // Update camera matrix - m_ModelViewMatrix.setData()[0]= side.x(); - m_ModelViewMatrix.setData()[4]= side.y(); - m_ModelViewMatrix.setData()[8]= side.z(); - m_ModelViewMatrix.setData()[12]= 0.0; - - // Vector Up is Y Axis - m_ModelViewMatrix.setData()[1]= m_VectUp.x(); - m_ModelViewMatrix.setData()[5]= m_VectUp.y(); - m_ModelViewMatrix.setData()[9]= m_VectUp.z(); - m_ModelViewMatrix.setData()[13]= 0.0; - - // Vector Cam is Z axis - m_ModelViewMatrix.setData()[2]= - forward.x(); - m_ModelViewMatrix.setData()[6]= - forward.y(); - m_ModelViewMatrix.setData()[10]= - forward.z(); - m_ModelViewMatrix.setData()[14]= 0.0; - - m_ModelViewMatrix.setData()[3]= 0.0; - m_ModelViewMatrix.setData()[7]= 0.0; - m_ModelViewMatrix.setData()[11]= 0.0; - m_ModelViewMatrix.setData()[15]= 1.0; - -} diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_camera.h b/ground/gcs/src/libs/glc_lib/viewport/glc_camera.h deleted file mode 100644 index 016f1e0a4..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_camera.h +++ /dev/null @@ -1,271 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - Copyright (C) 2009 Laurent Bauer - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_camera.h Interface for the GLC_Camera class. - -#ifndef GLC_CAMERA_H_ -#define GLC_CAMERA_H_ - -#include "../glc_object.h" -#include "../maths/glc_vector3d.h" -#include "../maths/glc_matrix4x4.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Camera -/*! \brief GLC_Camera : OpenGL perpective viewpoint */ - -/*! An GLC_Camera define Viewpoint and orientation - * of an OpenGL perpective camera*/ -////////////////////////////////////////////////////////////////////// - -class GLC_LIB_EXPORT GLC_Camera : - public GLC_Object -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Default constructor - /*! Point of view (0, 0, 1) Up Vector (0, 1, 0)*/ - GLC_Camera(); - - //! Explicit constructor - /* VectUp and VectCam could not be parallel - * VectUp could not be NULL - * VectCam could not be NULL */ - GLC_Camera(const GLC_Point3d &, const GLC_Point3d &, const GLC_Vector3d &); - - //! Copy constructor - GLC_Camera(const GLC_Camera&); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Get the distance between the eye and the target of camera - inline double distEyeTarget(void) const - {return (m_Eye - m_Target).length();} - - //! Get camera's eye coordinate point - inline GLC_Point3d eye(void) const - {return m_Eye;} - - //! Get camera's target coordinate point - inline GLC_Point3d target(void) const - {return m_Target;} - - //! Get camera's Up vector - inline GLC_Vector3d upVector(void) const - {return m_VectUp;} - - //! Get camera's forward vector (from eye to target) - inline GLC_Vector3d forward(void) const - {return m_Target - m_Eye;} - - //! Side camera vector - inline GLC_Vector3d sideVector() const - {return ((m_Target - m_Eye).normalize() ^ m_VectUp).normalize();} - - //! Get camera's orbit composition matrix - inline GLC_Matrix4x4 viewMatrix(void) const - {return m_ModelViewMatrix;} - - //! equality operator - bool operator==(const GLC_Camera&) const; - - //! almost equality (Bauer Laurent) - bool isAlmostEqualTo(const GLC_Camera&, const double distanceAccuracy=0.05) const; - - //! Return the default up vector - inline GLC_Vector3d defaultUpVector() const - {return m_DefaultVectUp;} - - //! Return the standard front view form this camera - GLC_Camera frontView() const; - - //! Return the standard rear view form this camera - GLC_Camera rearView() const; - - //! Return the standard right view form this camera - GLC_Camera rightView() const; - - //! Return the standard left view form this camera - GLC_Camera leftView() const; - - //! Return the standard top view form this camera - GLC_Camera topView() const; - - //! Return the standard bottom view form this camera - GLC_Camera bottomView() const; - - //! Return the standard isoview from his camera - /*! Iso View is at the front top left*/ - GLC_Camera isoView() const; - - //! Return the model view matrix of the camera - inline GLC_Matrix4x4 modelViewMatrix() const - { - GLC_Matrix4x4 translate(-m_Eye); - GLC_Matrix4x4 modelView= GLC_Matrix4x4(m_ModelViewMatrix * translate); - return modelView; - } - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Camera orbiting - GLC_Camera& orbit(GLC_Vector3d VectOldPoss, GLC_Vector3d VectCurPoss); - - //! panoramic movement - GLC_Camera& pan(GLC_Vector3d VectDep); - - //! move camera's eye along camera vector (eye -> target) - /*! Factor must be > 0*/ - GLC_Camera& zoom(double factor); - - //! Move camera - GLC_Camera& move(const GLC_Matrix4x4 &MatMove); - - //! Rotate around an axis - GLC_Camera& rotateAround(const GLC_Vector3d&, const double&, const GLC_Point3d&); - - //! Rotate around camera target - GLC_Camera& rotateAroundTarget(const GLC_Vector3d&, const double&); - - //! Camera translation - GLC_Camera& translate(const GLC_Vector3d &VectTrans); - - //! Set the camera - /* VectUp and VectCam could not be parallel - * VectUp could not be NULL - * VectCam could not be NULL */ - GLC_Camera& setCam(GLC_Point3d Eye, GLC_Point3d Target, GLC_Vector3d Up); - - //! Set the camera by copying another camera - GLC_Camera& setCam(const GLC_Camera&); - - //! Set camera's eye coordinate vector - GLC_Camera& setEyeCam(const GLC_Point3d &Eye); - - //! Set camera's target coordinate vector - GLC_Camera& setTargetCam(const GLC_Point3d &Target); - - //! Set camera's Up vector - GLC_Camera& setUpCam(const GLC_Vector3d &Up); - - //! Set the distance between eye and target (move eye) - GLC_Camera& setDistEyeTarget(double Longueur); - - //! Set the distance between target and eye (move target) - GLC_Camera& setDistTargetEye(double Longueur); - - //! Assignement operator - GLC_Camera& operator=(const GLC_Camera&); - - //! Set the default Up vector - /*! Must Be X, Y or Z Axis*/ - inline GLC_Camera& setDefaultUpVector(const GLC_Vector3d& up) - { - Q_ASSERT((up == glc::X_AXIS) || (up == glc::Y_AXIS) || (up == glc::Z_AXIS)); - m_DefaultVectUp= up; - return *this; - } - - //! Set the standard front view form this camera - inline void setFrontView() - {setCam(frontView());} - - //! Set the standard rear view form this camera - inline void setRearView() - {setCam(rearView());} - - //! Set the standard right view form this camera - inline void setRightView() - {setCam(rightView());} - - //! Set the standard left view form this camera - inline void setLeftView() - {setCam(leftView());} - - //! Set the standard top view form this camera - inline void setTopView() - {setCam(topView());} - - //! Set the standard bottom view form this camera - inline void setBottomView() - {setCam(bottomView());} - - //! Set the standard isoview from his camera - /*! Iso View is at the front top left*/ - inline void setIsoView() - {setCam(isoView());} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Execute OpenGL Camera - void glExecute(); - -//@} - -////////////////////////////////////////////////////////////////////// -// Private services Functions -////////////////////////////////////////////////////////////////////// -private: - //! compute composition matrix - void createMatComp(void); - - -////////////////////////////////////////////////////////////////////// -// Private Member -////////////////////////////////////////////////////////////////////// -private: - //! Camera's eye point - GLC_Point3d m_Eye; - - //! Camera's target point - GLC_Point3d m_Target; - - //! Camera's Up vector - GLC_Vector3d m_VectUp; - - //! Camera model view matrix - GLC_Matrix4x4 m_ModelViewMatrix; - - //! The default Up axis - GLC_Vector3d m_DefaultVectUp; -}; -#endif //GLC_CAMERA_H_ diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_flymover.cpp b/ground/gcs/src/libs/glc_lib/viewport/glc_flymover.cpp deleted file mode 100644 index abda923bc..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_flymover.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_flymover.cpp Implementation of the GLC_FlyMover class. - -#include "glc_flymover.h" -#include "glc_viewport.h" -#include "../maths/glc_utils_maths.h" - -GLC_FlyMover::GLC_FlyMover(GLC_Viewport* pViewport, const QList& repsList) -: GLC_Mover(pViewport, repsList) -, m_TurnRate(glc::toRadian(6)) -, m_TimerId(0) -, m_TimerInterval(66) -, m_Velocity(1.0) -{ - GLC_Mover::m_MoverInfo.m_VectorInfo.append(GLC_Vector3d()); - GLC_Mover::m_MoverInfo.m_DoubleInfo.append(m_Velocity); -} - -GLC_FlyMover::GLC_FlyMover(const GLC_FlyMover& flyMover) -: GLC_Mover(flyMover) -, m_TurnRate(flyMover.m_TurnRate) -, m_TimerId(0) -, m_TimerInterval(flyMover.m_TimerInterval) -, m_Velocity(flyMover.m_Velocity) -{ - -} - -GLC_FlyMover::~GLC_FlyMover() -{ - if (0 != m_TimerId) - { - QObject::killTimer(m_TimerId); - } -} - -////////////////////////////////////////////////////////////////////// -//Get Functions -////////////////////////////////////////////////////////////////////// - -GLC_Mover* GLC_FlyMover::clone() const -{ - return new GLC_FlyMover(*this); -} - - -////////////////////////////////////////////////////////////////////// -//Set Functions -////////////////////////////////////////////////////////////////////// - -void GLC_FlyMover::init(const GLC_UserInput& userInput) -{ - m_PreviousVector= mapForFlying(static_cast(userInput.x()), static_cast(userInput.y())); - GLC_Point3d point= m_pViewport->unProject(userInput.x(), userInput.y()); - const double distance= (point - m_pViewport->cameraHandle()->eye()).length(); - m_pViewport->cameraHandle()->setDistTargetEye(distance); - // 5 secondes to travel - m_Velocity= distance / 5000; - - GLC_Mover::m_MoverInfo.m_DoubleInfo.first()= m_Velocity; - - // Start the timer - m_TimerId= QObject::startTimer(m_TimerInterval); -} - -bool GLC_FlyMover::move(const GLC_UserInput& userInput) -{ - m_PreviousVector= mapForFlying(static_cast(userInput.x()), static_cast(userInput.y())); - GLC_Point3d point= m_pViewport->unProject(userInput.x(), userInput.y()); - const double distance= (point - m_pViewport->cameraHandle()->eye()).length(); - m_pViewport->cameraHandle()->setDistTargetEye(distance); - - return false; -} -void GLC_FlyMover::ends() -{ - QObject::killTimer(m_TimerId); - m_TimerId= 0; -} - -void GLC_FlyMover::setFlyingVelocity(double velocity) -{ - m_Velocity= velocity; - GLC_Mover::m_MoverInfo.m_DoubleInfo.first()= m_Velocity; -} - -void GLC_FlyMover::increaseVelocity(double factor) -{ - m_Velocity*= factor; - GLC_Mover::m_MoverInfo.m_DoubleInfo.first()= m_Velocity; -} - -void GLC_FlyMover::timerEvent(QTimerEvent*) -{ - fly(); - GLC_Vector3d direction(m_pViewport->cameraHandle()->forward()); - direction.normalize(); - direction= direction * m_Velocity * m_TimerInterval; - const GLC_Matrix4x4 translation(direction); - m_pViewport->cameraHandle()->move(translation); - - emit updated(); -} - -GLC_Vector3d GLC_FlyMover::mapForFlying(double x, double y) -{ - double AspectRatio; - const double winHSize= static_cast(GLC_Mover::m_pViewport->viewHSize()); - const double winVSize= static_cast(GLC_Mover::m_pViewport->viewVSize()); - - - // Change origin and cover - if (winHSize < winVSize) - { - AspectRatio= winVSize / winHSize; - x= ( (x - winHSize / 2.0 ) / ( winHSize / 2.0) ) / AspectRatio; - y= ( ( winVSize / 2.0 - y) / ( winVSize / 2.0 ) ); - } - else - { - AspectRatio= winHSize / winVSize; - x= ( (x - winHSize / 2.0 ) / ( winHSize / 2.0) ); - y= ( (winVSize / 2.0 - y) / (winVSize / 2.0 ) ) / AspectRatio; - } - - GLC_Vector3d pos(x, y, 0.0); - - if (pos.length() > 1.0) - { - pos.normalize(); - } - GLC_Mover::m_MoverInfo.m_VectorInfo.first()= pos; - GLC_Mover::updateRepresentation(); - - double z= -cos(m_TurnRate) / sin(m_TurnRate); - pos.setZ(z); - pos.normalize(); - return pos; -} -void GLC_FlyMover::fly() -{ - const GLC_Matrix4x4 viewMatrix(m_pViewport->cameraHandle()->viewMatrix()); - const GLC_Vector3d newPos= viewMatrix.inverted() * m_PreviousVector; - const GLC_Vector3d forward(GLC_Vector3d(m_pViewport->cameraHandle()->forward()).normalize()); - - // Compute rotation matrix - const GLC_Vector3d axe(forward ^ newPos); - if (!axe.isNull()) - { - const double angle= acos(forward * newPos); - const GLC_Matrix4x4 rotation(axe, angle); - const GLC_Matrix4x4 trans1(-m_pViewport->cameraHandle()->eye()); - const GLC_Matrix4x4 trans2(m_pViewport->cameraHandle()->eye()); - const GLC_Matrix4x4 composition(trans2 * rotation * trans1); - m_pViewport->cameraHandle()->move(composition); - } -} diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_flymover.h b/ground/gcs/src/libs/glc_lib/viewport/glc_flymover.h deleted file mode 100644 index cd8f569d5..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_flymover.h +++ /dev/null @@ -1,125 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_flymover.h Interface for the GLC_FlyMover class. - -#ifndef GLC_FLYMOVER_H_ -#define GLC_FLYMOVER_H_ -#include "glc_mover.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_FlyMover -/*! \brief GLC_FlyMover : Fly Mode interactive manipulation */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_FlyMover : public GLC_Mover -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Default constructor - GLC_FlyMover(GLC_Viewport*, const QList& repsList= QList()); - - //! Copy constructor - GLC_FlyMover(const GLC_FlyMover& flyMover); - - //! Destructor - virtual ~GLC_FlyMover(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return a clone of the mover - virtual GLC_Mover* clone() const; - - //! Return the turning rate in degres - inline double turningRate() const - {return m_TurnRate / glc::PI * 180.0;} - - //! Return the flying velocity - inline double flyingVelocity() const - {return m_Velocity;} -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Initialized the mover - virtual void init(const GLC_UserInput& userInput); - - //! Move the camera - virtual bool move(const GLC_UserInput& userInput); - - //! Ends this mover - virtual void ends(); - - //! Set the maximum turning rate in degre - inline void setMaximumTurnRate(double turnRate) - {m_TurnRate= turnRate;} - - //! Set the flying velocity - void setFlyingVelocity(double velocity); - - //! increase the flying velocity - void increaseVelocity(double factor); - -//@} - -protected: - void timerEvent(QTimerEvent*); - -///////////////////////////////////////////////////////////////////// -// Private services Functions -////////////////////////////////////////////////////////////////////// -private: - //! Map the position of mouse for the fly mode - GLC_Vector3d mapForFlying(double x, double y); - - //! Fly - void fly(); - -////////////////////////////////////////////////////////////////////// -// Private Members -////////////////////////////////////////////////////////////////////// -private: - //! THe turning rate - double m_TurnRate; - - //! The timer id - int m_TimerId; - - //! the timer interval - int m_TimerInterval; - - //! fly velocity - double m_Velocity; - -}; - -#endif /* GLC_FLYMOVER_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_frustum.cpp b/ground/gcs/src/libs/glc_lib/viewport/glc_frustum.cpp deleted file mode 100644 index eb1330699..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_frustum.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_frustum.cpp Implementation of the GLC_Frustum class. - -#include "glc_frustum.h" -#include "glc_viewport.h" - -GLC_Frustum::GLC_Frustum() -: m_PlaneList() -, m_PreviousMatrix() -{ - for (int i= 0; i < 6; ++i) - { - m_PlaneList.append(GLC_Plane()); - } -} - -GLC_Frustum::GLC_Frustum(const GLC_Frustum& frustum) -: m_PlaneList(frustum.m_PlaneList) -, m_PreviousMatrix(frustum.m_PreviousMatrix) -{ - -} - -GLC_Frustum::~GLC_Frustum() -{ - -} - -GLC_Frustum::Localisation GLC_Frustum::localizeBoundingBox(const GLC_BoundingBox& box) const -{ - const GLC_Point3d center= box.center(); - const double radius= box.boundingSphereRadius(); - - return localizeSphere(center, radius); -} - -GLC_Frustum::Localisation GLC_Frustum::localizeSphere(const GLC_Point3d& center, double radius) const -{ - GLC_Frustum::Localisation localisationResult= InFrustum; - - int i= 0; - bool continu= true; - while (continu && (i < 6)) - { - //qDebug() << "Localisation of plane " << i; - localisationResult= static_cast(localisationResult | localizeSphereToPlane(center, radius, m_PlaneList.at(i))); - continu= (localisationResult != GLC_Frustum::OutFrustum); - ++i; - } - - return localisationResult; -} - -GLC_Frustum::Localisation GLC_Frustum::localizeSphereToPlane(const GLC_Point3d& center, double radius, const GLC_Plane& plane) const -{ - GLC_Frustum::Localisation localisationResult; - const double signedDistance= plane.distanceToPoint(center); - const double distance= fabs(signedDistance); - if (distance > radius) - { - if (signedDistance > 0) localisationResult= GLC_Frustum::InFrustum; - else localisationResult= GLC_Frustum::OutFrustum; - } - else - { - localisationResult= GLC_Frustum::IntersectFrustum; - } - - return localisationResult; -} - -bool GLC_Frustum::update(const GLC_Matrix4x4& compMatrix) -{ - - // Test if the frustum change - if (compMatrix == m_PreviousMatrix) - { - //qDebug() << "No change in frustum"; - return false; - } - else - { - m_PreviousMatrix= compMatrix; - // Left plane - m_PlaneList[LeftPlane].setA(compMatrix.getData()[3] + compMatrix.getData()[0]); - m_PlaneList[LeftPlane].setB(compMatrix.getData()[7] + compMatrix.getData()[4]); - m_PlaneList[LeftPlane].setC(compMatrix.getData()[11] + compMatrix.getData()[8]); - m_PlaneList[LeftPlane].setD(compMatrix.getData()[15] + compMatrix.getData()[12]); - m_PlaneList[LeftPlane].normalize(); - - // Right plane - m_PlaneList[RightPlane].setA(compMatrix.getData()[3] - compMatrix.getData()[0]); - m_PlaneList[RightPlane].setB(compMatrix.getData()[7] - compMatrix.getData()[4]); - m_PlaneList[RightPlane].setC(compMatrix.getData()[11] - compMatrix.getData()[8]); - m_PlaneList[RightPlane].setD(compMatrix.getData()[15] - compMatrix.getData()[12]); - m_PlaneList[RightPlane].normalize(); - - //Top plane - m_PlaneList[TopPlane].setA(compMatrix.getData()[3] + compMatrix.getData()[1]); - m_PlaneList[TopPlane].setB(compMatrix.getData()[7] + compMatrix.getData()[5]); - m_PlaneList[TopPlane].setC(compMatrix.getData()[11] + compMatrix.getData()[9]); - m_PlaneList[TopPlane].setD(compMatrix.getData()[15] + compMatrix.getData()[13]); - m_PlaneList[TopPlane].normalize(); - - //Bottom plane - m_PlaneList[BottomPlane].setA(compMatrix.getData()[3] - compMatrix.getData()[1]); - m_PlaneList[BottomPlane].setB(compMatrix.getData()[7] - compMatrix.getData()[5]); - m_PlaneList[BottomPlane].setC(compMatrix.getData()[11] - compMatrix.getData()[9]); - m_PlaneList[BottomPlane].setD(compMatrix.getData()[15] - compMatrix.getData()[13]); - m_PlaneList[BottomPlane].normalize(); - - //Near plane - m_PlaneList[NearPlane].setA(compMatrix.getData()[3] + compMatrix.getData()[2]); - m_PlaneList[NearPlane].setB(compMatrix.getData()[7] + compMatrix.getData()[6]); - m_PlaneList[NearPlane].setC(compMatrix.getData()[11] + compMatrix.getData()[10]); - m_PlaneList[NearPlane].setD(compMatrix.getData()[15] + compMatrix.getData()[14]); - m_PlaneList[NearPlane].normalize(); - - //Far plane - m_PlaneList[FarPlane].setA(compMatrix.getData()[3] - compMatrix.getData()[2]); - m_PlaneList[FarPlane].setB(compMatrix.getData()[7] - compMatrix.getData()[6]); - m_PlaneList[FarPlane].setC(compMatrix.getData()[11] - compMatrix.getData()[10]); - m_PlaneList[FarPlane].setD(compMatrix.getData()[15] - compMatrix.getData()[14]); - m_PlaneList[FarPlane].normalize(); - return true; - } -} diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_frustum.h b/ground/gcs/src/libs/glc_lib/viewport/glc_frustum.h deleted file mode 100644 index 1080ce9d3..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_frustum.h +++ /dev/null @@ -1,165 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_frustum.h Interface for the GLC_Frustum class. - -#ifndef GLC_FRUSTUM_H_ -#define GLC_FRUSTUM_H_ - -#include "../maths/glc_plane.h" -#include "../glc_boundingbox.h" -#include "../glc_config.h" - -class GLC_LIB_EXPORT GLC_Viewport; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Frustum -/*! \brief GLC_Frustum : OpenGL Frustum */ - -/*! GLC_Frustum by 6 planes */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_Frustum -{ -private: - enum planeId - { - LeftPlane= 0, - RightPlane= 1, - TopPlane= 2, - BottomPlane= 3, - NearPlane= 4, - FarPlane= 5 - }; -public: - enum Localisation - { - InFrustum = 0, - IntersectFrustum = 1, - OutFrustum= 3 - }; -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Default constructor - GLC_Frustum(); - - //! Copy constructor - GLC_Frustum(const GLC_Frustum&); - - //! Destructor - ~GLC_Frustum(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Return the left clipping plane - inline GLC_Plane leftClippingPlane() const - {return m_PlaneList.at(LeftPlane);} - - //! Return the Right clipping plane - inline GLC_Plane rightClippingPlane() const - {return m_PlaneList.at(RightPlane);} - - //! Return the top clipping plane - inline GLC_Plane topClippingPlane() const - {return m_PlaneList.at(TopPlane);} - - //! Return the bottom clipping plane - inline GLC_Plane bottomClippingPlane() const - {return m_PlaneList.at(BottomPlane);} - - //! Return the near clipping plane - inline GLC_Plane nearClippingPlane() const - {return m_PlaneList.at(NearPlane);} - - //! Return the far clipping plane - inline GLC_Plane farClippingPlane() const - {return m_PlaneList.at(FarPlane);} - - //! Localize bounding box - Localisation localizeBoundingBox(const GLC_BoundingBox&) const; - - //! Localize sphere - Localisation localizeSphere(const GLC_Point3d&, double) const; - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Set the left clipping plane - inline void setLeftClippingPlane(const GLC_Plane& plane) - {m_PlaneList[LeftPlane]= plane;} - - //! Set the right clipping plane - inline void setRightClippingPlane(const GLC_Plane& plane) - {m_PlaneList[RightPlane]= plane;} - - //! Set the top clipping plane - inline void setTopClippingPlane(const GLC_Plane& plane) - {m_PlaneList[TopPlane]= plane;} - - //! Set the bottom clipping plane - inline void setBottomClippingPlane(const GLC_Plane& plane) - {m_PlaneList[BottomPlane]= plane;} - - //! Set the near clipping plane - inline void setNearClippingPlane(const GLC_Plane& plane) - {m_PlaneList[NearPlane]= plane;} - - //! Set the far clipping plane - inline void setFarClippingPlane(const GLC_Plane& plane) - {m_PlaneList[FarPlane]= plane;} - - //! Update the frustum - /*! Return true if the frustum as change*/ - bool update(const GLC_Matrix4x4&); - -//@} -////////////////////////////////////////////////////////////////////// -// Private services function -////////////////////////////////////////////////////////////////////// -private: - //! localize a sphere to a plane - Localisation localizeSphereToPlane(const GLC_Point3d&, double, const GLC_Plane&) const; - -////////////////////////////////////////////////////////////////////// -// Private Member -////////////////////////////////////////////////////////////////////// -private: - - //! The list of frustum plane - QList m_PlaneList; - - //! The previous frustum matrix - GLC_Matrix4x4 m_PreviousMatrix; -}; - -#endif /* GLC_FRUSTUM_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_imageplane.cpp b/ground/gcs/src/libs/glc_lib/viewport/glc_imageplane.cpp deleted file mode 100644 index 0f0e6eeca..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_imageplane.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_imagePlane.cpp implementation of the GLC_ImagePlane class. -#include "glc_imageplane.h" -#include "glc_viewport.h" -#include "../glc_openglexception.h" -#include "../glc_factory.h" -#include "../glc_context.h" -#include - -////////////////////////////////////////////////////////////////////// -// Constructor Destructor -////////////////////////////////////////////////////////////////////// - -GLC_ImagePlane::GLC_ImagePlane(const QString& ImageName) -: m_Representation(GLC_Factory::instance()->createRectangle(2.0, 2.0)) -{ - GLC_Texture* pImgTexture= GLC_Factory::instance()->createTexture(ImageName); - pImgTexture->setMaxTextureSize(pImgTexture->imageOfTexture().size()); - m_Representation.geomAt(0)->addMaterial(new GLC_Material(pImgTexture)); -} - -GLC_ImagePlane::GLC_ImagePlane(const QImage& image) -: m_Representation(GLC_Factory::instance()->createRectangle(2.0, 2.0)) -{ - GLC_Texture* pImgTexture= GLC_Factory::instance()->createTexture(image); - pImgTexture->setMaxTextureSize(image.size()); - m_Representation.geomAt(0)->addMaterial(new GLC_Material(pImgTexture)); -} - -GLC_ImagePlane::~GLC_ImagePlane() -{ - -} - -////////////////////////////////////////////////////////////////////// -// OpenGL Functions -////////////////////////////////////////////////////////////////////// - -void GLC_ImagePlane::render() -{ - GLC_Context::current()->glcMatrixMode(GL_PROJECTION); - GLC_Context::current()->glcPushMatrix(); - GLC_Context::current()->glcLoadIdentity(); - GLC_Context::current()->glcOrtho(-1,1,-1,1,-1,1); - GLC_Context::current()->glcMatrixMode(GL_MODELVIEW); - - glDisable(GL_BLEND); - glDisable(GL_DEPTH_TEST); - glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); - - m_Representation.render(); - - glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glEnable(GL_DEPTH_TEST); - - GLC_Context::current()->glcMatrixMode(GL_PROJECTION); - GLC_Context::current()->glcPopMatrix(); - GLC_Context::current()->glcMatrixMode(GL_MODELVIEW); -} diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_imageplane.h b/ground/gcs/src/libs/glc_lib/viewport/glc_imageplane.h deleted file mode 100644 index 51ce957a2..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_imageplane.h +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_imagePlane.h interface for the GLC_ImagePlane class. - -#ifndef GLC_IMAGEPLANE_H_ -#define GLC_IMAGEPLANE_H_ - -#include "../shading/glc_material.h" -#include "../sceneGraph/glc_3dviewinstance.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_ImagePlane -/*! \brief GLC_ImagePlane : Viewport background image*/ - -/*! An GLC_ImagePlane is just a plane with a image texture.*/ -////////////////////////////////////////////////////////////////////// - -class GLC_LIB_EXPORT GLC_ImagePlane -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Construct image plane from the given image file name and QGLContext - GLC_ImagePlane(const QString& ImageName); - - //! Construct image plane from the given image and QGLContext - GLC_ImagePlane(const QImage& image); - - ~GLC_ImagePlane(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Render this image plane - void render(); -//@} - -////////////////////////////////////////////////////////////////////// -// Private members -////////////////////////////////////////////////////////////////////// - -private: - - //! The image representation - GLC_3DViewInstance m_Representation; - -}; - -#endif //GLC_IMAGEPLANE_H_ diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_mover.cpp b/ground/gcs/src/libs/glc_lib/viewport/glc_mover.cpp deleted file mode 100644 index 573682339..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_mover.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -//! \file glc_mover.cpp Implementation of the GLC_Mover class. - -#include "glc_mover.h" -#include "glc_viewport.h" - -GLC_Mover::GLC_Mover(GLC_Viewport* pViewport, const QList& repsList) -: QObject() -, m_RepMoverList(repsList) -, m_PreviousVector() -, m_pViewport(pViewport) -, m_MoverInfo() -{ - const int size= m_RepMoverList.size(); - for (int i= 0; i < size; ++i) - { - m_RepMoverList[i]->setRepMoverInfo(&m_MoverInfo); - } -} - -// Copy constructor -GLC_Mover::GLC_Mover(const GLC_Mover& mover) -: QObject() -, m_RepMoverList() -, m_PreviousVector(mover.m_PreviousVector) -, m_pViewport(mover.m_pViewport) -, m_MoverInfo(mover.m_MoverInfo) -{ - const int size= mover.m_RepMoverList.size(); - for (int i= 0; i < size; ++i) - { - m_RepMoverList.append(mover.m_RepMoverList.at(i)->clone()); - m_RepMoverList.last()->setRepMoverInfo(&m_MoverInfo); - } -} - -GLC_Mover::~GLC_Mover() -{ - clearMoverRepresentation(); -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -// Set the mover representation list -void GLC_Mover::setRepresentationsList(const QList& listOfRep) -{ - qDebug() << "GLC_Mover::setRepresentationsList"; - clearMoverRepresentation(); - m_RepMoverList= listOfRep; - const int size= m_RepMoverList.size(); - for (int i= 0; i < size; ++i) - { - m_RepMoverList[i]->setRepMoverInfo(&m_MoverInfo); - } -} - -// Update representation -void GLC_Mover::initRepresentation() -{ - const int size= m_RepMoverList.size(); - for (int i= 0; i < size; ++i) - { - m_RepMoverList[i]->init(); - } -} - -// Update representation -void GLC_Mover::updateRepresentation() -{ - const int size= m_RepMoverList.size(); - for (int i= 0; i < size; ++i) - { - m_RepMoverList[i]->update(); - } - -} - -////////////////////////////////////////////////////////////////////// -// OpenGL Functions -////////////////////////////////////////////////////////////////////// - -// Mover representations list display -void GLC_Mover::renderRepresentation() -{ - const int size= m_RepMoverList.size(); - for (int i= 0; i < size; ++i) - { - m_RepMoverList[i]->render(); - } -} - -////////////////////////////////////////////////////////////////////// -// Private services Functions -////////////////////////////////////////////////////////////////////// - -// Clear mover representation -void GLC_Mover::clearMoverRepresentation() -{ - // Delete mover representations - const int size= m_RepMoverList.size(); - for (int i= 0; i < size; ++i) - { - delete m_RepMoverList.at(i); - } -} - - diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_mover.h b/ground/gcs/src/libs/glc_lib/viewport/glc_mover.h deleted file mode 100644 index 047b2d8a2..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_mover.h +++ /dev/null @@ -1,131 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -//! \file glc_mover.h Interface for the GLC_Mover class. - -#ifndef GLC_MOVER_H_ -#define GLC_MOVER_H_ - -#include "glc_repmover.h" -#include "../maths/glc_vector3d.h" -#include "glc_userinput.h" - -#include -#include - -#include "../glc_config.h" - -class GLC_Viewport; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Mover -/*! \brief GLC_Mover : Base class for all interactive manipulation */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_Mover : public QObject -{ - Q_OBJECT - -public: - //! Default constructor - GLC_Mover(GLC_Viewport*, const QList&); - - //! Copy constructor - GLC_Mover(const GLC_Mover&); - - //! Destructor - virtual ~GLC_Mover(); - - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return a clone of the mover - virtual GLC_Mover* clone() const= 0; -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Initialized the mover - virtual void init(const GLC_UserInput& userInput)= 0; - - //! Move the camera - virtual bool move(const GLC_UserInput& userInput)= 0; - - //! Ends this mover - virtual void ends(){} - - //! Set the mover representation list - void setRepresentationsList(const QList&); - - //! Init representation - void initRepresentation(); - - //! Update representation - void updateRepresentation(); - - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Mover representations list display - void renderRepresentation(); - -//@} - -signals: - //! Signal sent if the view as been updated - void updated(); - -////////////////////////////////////////////////////////////////////// -// Private services Functions -////////////////////////////////////////////////////////////////////// -private: - //! Clear mover representation - void clearMoverRepresentation(); - -////////////////////////////////////////////////////////////////////// -// Protected Members -////////////////////////////////////////////////////////////////////// -protected: - //! The mover representations list - QList m_RepMoverList; - - //! The previous mover value - GLC_Vector3d m_PreviousVector; - - //! The Viewport - GLC_Viewport* m_pViewport; - - //! The mover info (passed to the rep) - GLC_RepMover::RepMoverInfo m_MoverInfo; -}; - -#endif /* GLC_MOVER_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_movercontroller.cpp b/ground/gcs/src/libs/glc_lib/viewport/glc_movercontroller.cpp deleted file mode 100644 index e1b684cd4..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_movercontroller.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -//! \file glc_movercontroller.cpp Implementation of the GLC_MoverController class. - -#include "glc_movercontroller.h" - -// Default constructor -GLC_MoverController::GLC_MoverController() -: QObject() -, m_ActiveMoverId(0) -, m_MoverHash() -{ - - -} - -// Copy constructor -GLC_MoverController::GLC_MoverController(const GLC_MoverController& controller) -: QObject() -, m_ActiveMoverId(controller.m_ActiveMoverId) -, m_MoverHash() -{ - MoverHash::const_iterator iMover= controller.m_MoverHash.constBegin(); - while (iMover != controller.m_MoverHash.constEnd()) - { - m_MoverHash.insert(iMover.key(), iMover.value()->clone()); - ++iMover; - } -} - -// Destructor -GLC_MoverController::~GLC_MoverController() -{ - MoverHash::iterator iMover= m_MoverHash.begin(); - while (iMover != m_MoverHash.constEnd()) - { - delete iMover.value(); - - ++iMover; - } -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -//! Assign another mover controller -GLC_MoverController& GLC_MoverController::operator = (const GLC_MoverController& controller) -{ - if (&controller != this) - { - m_ActiveMoverId= controller.m_ActiveMoverId; - - // Clear the inner movers - { - MoverHash::iterator iMover= m_MoverHash.begin(); - while (iMover != m_MoverHash.constEnd()) - { - delete iMover.value(); - - ++iMover; - } - m_MoverHash.clear(); - } - // Copy movers - MoverHash::const_iterator iMover= controller.m_MoverHash.constBegin(); - while (iMover != controller.m_MoverHash.constEnd()) - { - m_MoverHash.insert(iMover.key(), iMover.value()->clone()); - ++iMover; - } - } - return *this; -} - -// Add a mover to the controller -void GLC_MoverController::addMover(GLC_Mover* pMover, const int id) -{ - Q_ASSERT(!m_MoverHash.contains(id)); - m_MoverHash.insert(id, pMover); -} - -// Remove mover from the controller -void GLC_MoverController::removeMover(const int id) -{ - Q_ASSERT(m_MoverHash.contains(id)); - m_MoverHash.remove(id); - if (id == m_ActiveMoverId) - { - m_ActiveMoverId= 0; - } -} - -void GLC_MoverController::setActiveMover(const int id, const GLC_UserInput& userInput) -{ - Q_ASSERT(m_MoverHash.contains(id)); - m_ActiveMoverId= id; - connect(m_MoverHash.value(m_ActiveMoverId), SIGNAL(updated()), this, SIGNAL(repaintNeeded())); - m_MoverHash.value(m_ActiveMoverId)->init(userInput); -} - -void GLC_MoverController::setNoMover() -{ - if (0 != m_ActiveMoverId) - { - m_MoverHash.value(m_ActiveMoverId)->ends(); - disconnect(m_MoverHash.value(m_ActiveMoverId), SIGNAL(updated()), this, SIGNAL(repaintNeeded())); - m_ActiveMoverId= 0; - } -} - diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_movercontroller.h b/ground/gcs/src/libs/glc_lib/viewport/glc_movercontroller.h deleted file mode 100644 index 08f8d4a28..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_movercontroller.h +++ /dev/null @@ -1,154 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -//! \file glc_movercontroller.h Interface for the GLC_MoverController class. - -#ifndef GLC_MOVERCONTROLLER_H_ -#define GLC_MOVERCONTROLLER_H_ - -#include "glc_mover.h" -#include -#include -#include - -#include "../glc_config.h" -#include "glc_userinput.h" - -class QGLWidget; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_MoverController -/*! \brief GLC_MoverController : Control activation of interactive manipulation mover */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_MoverController : public QObject -{ - Q_OBJECT -public: - //! The mover hash table - typedef QHash MoverHash; - - //! Standard mover Id - enum MoverType - { - Pan= 1, - Zoom= 2, - TrackBall= 3, - Target= 4, - TurnTable= 5, - Fly= 6, - TSR= 7 - }; - -public: - //! Default Constructor - GLC_MoverController(); - - //! Copy Constructor - GLC_MoverController(const GLC_MoverController&); - - //! Destructor - virtual ~GLC_MoverController(); - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Return true if there is an active mover - inline bool hasActiveMover() const - { return (m_ActiveMoverId != 0);} - - //! Return the active mover id - inline int activeMoverId() const - {return m_ActiveMoverId;} - - //! Return a handle on the current mover - inline GLC_Mover* activeMover() const - {return m_MoverHash.value(m_ActiveMoverId);} - - //! Return the mover of the given id - inline GLC_Mover* getMover(const int id) const - {return m_MoverHash.value(id);} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Assign another mover controller - GLC_MoverController& operator = (const GLC_MoverController&); - - //! Add a mover to the controller - void addMover(GLC_Mover*, const int); - - //! Remove mover from the controller - void removeMover(const int); - - //! Set the specified mover as active - void setActiveMover(const int id, const GLC_UserInput& userInput); - - //! Set no mover as active - void setNoMover(); - - //! Move with the active mover - inline bool move(const GLC_UserInput& userInput) - { - Q_ASSERT(0 != m_ActiveMoverId); - return m_MoverHash.value(m_ActiveMoverId)->move(userInput); - } - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Mover representations list display - inline void drawActiveMoverRep() - { - if(0 != m_ActiveMoverId) - { - m_MoverHash.value(m_ActiveMoverId)->renderRepresentation(); - } - } - -//@} -signals: - //! Signal emitted if the view as to be repaint - void repaintNeeded(); - -////////////////////////////////////////////////////////////////////// -// Private Members -////////////////////////////////////////////////////////////////////// -private: - //! The active mover id - int m_ActiveMoverId; - - //! Hash table of mover - MoverHash m_MoverHash; -}; - -#endif /* GLC_MOVERCONTROLLER_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_panmover.cpp b/ground/gcs/src/libs/glc_lib/viewport/glc_panmover.cpp deleted file mode 100644 index 40c0e6d26..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_panmover.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -//! \file glc_panmover.cpp Implementation of the GLC_PanMover class. - -#include "glc_panmover.h" -#include "glc_viewport.h" -#include "QMouseEvent" - -// Default constructor -GLC_PanMover::GLC_PanMover(GLC_Viewport* pViewport, const QList& repsList) -: GLC_Mover(pViewport, repsList) -{ - -} - -// Copy constructor -GLC_PanMover::GLC_PanMover(const GLC_PanMover& panMover) -: GLC_Mover(panMover) -{ - -} - - -GLC_PanMover::~GLC_PanMover() -{ - -} - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -// Return a clone of the mover -GLC_Mover* GLC_PanMover::clone() const -{ - return new GLC_PanMover(*this); -} - - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -// Initialized the mover -void GLC_PanMover::init(const GLC_UserInput& userInput) -{ - m_PreviousVector= m_pViewport->mapPosMouse(static_cast(userInput.x()), static_cast(userInput.y())); -} - -// Move the camera -bool GLC_PanMover::move(const GLC_UserInput& userInput) -{ - const GLC_Vector3d VectCur(m_pViewport->mapPosMouse(static_cast(userInput.x()), static_cast(userInput.y()))); - const GLC_Vector3d VectPan= VectCur - m_PreviousVector; // moving Vector - - // Pan the camera - m_pViewport->cameraHandle()->pan(-VectPan); - m_PreviousVector= VectCur; - return true; -} - diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_panmover.h b/ground/gcs/src/libs/glc_lib/viewport/glc_panmover.h deleted file mode 100644 index c7204f00b..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_panmover.h +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -//! \file glc_panmover.h Interface for the GLC_PanMover class. - -#ifndef GLC_PANMOVER_H_ -#define GLC_PANMOVER_H_ - -#include "glc_mover.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_PanMover -/*! \brief GLC_PanMover : Panoramic interactive manipulation */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_PanMover : public GLC_Mover -{ -public: - //! Default constructor - GLC_PanMover(GLC_Viewport*, const QList& repsList= QList()); - - //! Copy constructor - GLC_PanMover(const GLC_PanMover&); - - //! Destructor - virtual ~GLC_PanMover(); - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return a clone of the mover - virtual GLC_Mover* clone() const; -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Initialized the mover - virtual void init(const GLC_UserInput& userInput); - - //! Move the camera - virtual bool move(const GLC_UserInput& userInput); -//@} - -}; - -#endif /* GLC_PANMOVER_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_repcrossmover.cpp b/ground/gcs/src/libs/glc_lib/viewport/glc_repcrossmover.cpp deleted file mode 100644 index c10d88f68..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_repcrossmover.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -#include "glc_repcrossmover.h" -#include "glc_viewport.h" -#include "../geometry/glc_polylines.h" - -// Default constructor -GLC_RepCrossMover::GLC_RepCrossMover(GLC_Viewport* pViewport) -: GLC_RepMover(pViewport) -{ - -} - -// Copy constructor -GLC_RepCrossMover::GLC_RepCrossMover(const GLC_RepCrossMover& repMover) -: GLC_RepMover(repMover) -{ - -} - -GLC_RepCrossMover::~GLC_RepCrossMover() -{ - -} - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -// Return a clone of the repmover -GLC_RepMover* GLC_RepCrossMover::clone() const -{ - return new GLC_RepCrossMover(*this); -} - -////////////////////////////////////////////////////////////////////// -// OpenGL Functions -////////////////////////////////////////////////////////////////////// - -// Virtual interface for OpenGL Geometry set up. -void GLC_RepCrossMover::glDraw() -{ - GLC_3DViewInstance crossInstance(createCrossInstance()); - - glDisable(GL_BLEND); - m_RenderProperties.setRenderingFlag(glc::WireRenderFlag); - crossInstance.render(glc::WireRenderFlag); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - m_RenderProperties.setRenderingFlag(glc::TransparentRenderFlag); - // Display arcs - crossInstance.render(glc::TransparentRenderFlag); -} - -////////////////////////////////////////////////////////////////////// -// Private services Functions -////////////////////////////////////////////////////////////////////// -GLC_3DViewInstance GLC_RepCrossMover::createCrossInstance() -{ - GLC_Polylines* pCross= new GLC_Polylines(); - - int nLgAxe; - const int winHSize= m_pViewport->viewHSize(); - const int winVSize= m_pViewport->viewVSize(); - if (winHSize > winVSize) - { - nLgAxe = static_cast(static_cast(winVSize) / 2.0); - } - else - { - nLgAxe = static_cast(static_cast(winHSize) / 2.0); - } - - // Compute the length of camera's field of view - const double ChampsVision = 2 * (m_pViewport->cameraHandle()->distEyeTarget()) * tan((m_pViewport->viewAngle() * glc::PI / 180.0) / 2.0); - - // the side of camera's square is mapped on Vertical length of window - // Axis length in OpenGL unit = length(Pixel) * (dimend GL / dimens Pixel) - const double dLgAxe= ((double)nLgAxe * ChampsVision / (double)winVSize) / 7; - const double dDecAxe= dLgAxe / 3; - - //X axis - { - GLC_Point3d p1(-dLgAxe, 0, 0); - GLC_Point3d p2(-dDecAxe, 0, 0); - GLC_Point3d p3(dDecAxe, 0, 0); - GLC_Point3d p4(dLgAxe, 0, 0); - QList points; - points << p1 << p2 << p3 << p4; - pCross->addPolyline(points); - } - - //Y axis - { - GLC_Point3d p1(0, -dLgAxe, 0); - GLC_Point3d p2(0, -dDecAxe, 0); - GLC_Point3d p3(0, dDecAxe, 0); - GLC_Point3d p4(0, dLgAxe, 0); - QList points; - points << p1 << p2 << p3 << p4; - pCross->addPolyline(points); - } - - //Z axis - { - GLC_Point3d p1(0, 0, -dLgAxe); - GLC_Point3d p2(0, 0, -dDecAxe); - GLC_Point3d p3(0, 0, dDecAxe); - GLC_Point3d p4(0, 0, dLgAxe); - QList points; - points << p1 << p2 << p3 << p4; - pCross->addPolyline(points); - } - - pCross->setWireColor(m_MainColor); - GLC_3DViewInstance crossInstance(pCross); - - GLC_Matrix4x4 translation; - translation.setMatTranslate(m_pViewport->cameraHandle()->target()); - - crossInstance.setMatrix(translation); - - return crossInstance; -} - diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_repcrossmover.h b/ground/gcs/src/libs/glc_lib/viewport/glc_repcrossmover.h deleted file mode 100644 index 8f570919f..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_repcrossmover.h +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -#ifndef GLC_REPCROSSMOVER_H_ -#define GLC_REPCROSSMOVER_H_ - -#include "glc_repmover.h" - -#include "../sceneGraph/glc_3dviewinstance.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_RepCrossMover -/*! \brief GLC_RepCrossMover : Cross representation*/ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_RepCrossMover : public GLC_RepMover -{ -public: - //! Default constructor - GLC_RepCrossMover(GLC_Viewport*); - - //! Copy constructor - GLC_RepCrossMover(const GLC_RepCrossMover&); - - //! Destructor - virtual ~GLC_RepCrossMover(); - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// - //! Return a clone of the repmover - virtual GLC_RepMover* clone() const; -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Virtual interface for OpenGL Geometry set up. - virtual void glDraw(); - -//@} - -////////////////////////////////////////////////////////////////////// -// Private services Functions -////////////////////////////////////////////////////////////////////// -private: - //! Create and return the cross instance - GLC_3DViewInstance createCrossInstance(); - -}; - -#endif /* GLC_REPCROSSMOVER_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_repflymover.cpp b/ground/gcs/src/libs/glc_lib/viewport/glc_repflymover.cpp deleted file mode 100644 index 766c3f3d3..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_repflymover.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -//! \file glc_repflymover.cpp Implementation of the GLC_RepFlyMover class. - -#include "glc_repflymover.h" -#include "glc_viewport.h" -#include "../geometry/glc_polylines.h" -#include "../glc_context.h" - -#include - -GLC_RepFlyMover::GLC_RepFlyMover(GLC_Viewport* pViewport) -: GLC_RepMover(pViewport) -, m_Radius(0.06) -, m_CenterCircle() -, m_Plane() -, m_Hud() -, m_HudOffset(m_Radius * 5.0, m_Radius * 5.3) -{ - - createRepresentation(); -} - -GLC_RepFlyMover::GLC_RepFlyMover(const GLC_RepFlyMover& repFlyMover) -: GLC_RepMover(repFlyMover) -, m_Radius(repFlyMover.m_Radius) -, m_CenterCircle(repFlyMover.m_CenterCircle) -, m_Plane(repFlyMover.m_Plane) -, m_Hud(repFlyMover.m_Hud) -, m_HudOffset(repFlyMover.m_HudOffset) -{ - -} - -GLC_RepFlyMover::~GLC_RepFlyMover() -{ - -} - -GLC_RepMover* GLC_RepFlyMover::clone() const -{ - return new GLC_RepFlyMover(*this); -} - -void GLC_RepFlyMover::update() -{ - Q_ASSERT(NULL != m_pRepMoverInfo); - Q_ASSERT(!m_pRepMoverInfo->m_VectorInfo.isEmpty()); - Q_ASSERT(!m_pRepMoverInfo->m_DoubleInfo.isEmpty()); - - GLC_Vector3d vector(m_pRepMoverInfo->m_VectorInfo.first()); - - // Rotation - double deltaX= vector.x(); - double angle= - deltaX; - GLC_Matrix4x4 rotation(glc::Z_AXIS, angle); - - // Translation - vector.setX(vector.x() * m_Radius * 4.0); - vector.setY(vector.y() * m_Radius * 4.0); - GLC_Matrix4x4 translation(vector); - - m_Plane.setMatrix(translation * rotation); -} -void GLC_RepFlyMover::setMainColor(const QColor& color) -{ - GLC_RepMover::setMainColor(color); - m_CenterCircle.geomAt(0)->setWireColor(color); - m_Plane.geomAt(0)->setWireColor(color); - m_Hud.geomAt(0)->setWireColor(color); -} - -void GLC_RepFlyMover::setThickness(double thickness) -{ - GLC_RepMover::setThickness(thickness); - m_CenterCircle.geomAt(0)->setLineWidth(thickness); - m_Plane.geomAt(0)->setLineWidth(thickness); - m_Hud.geomAt(0)->setLineWidth(thickness); -} - -void GLC_RepFlyMover::glDraw() -{ - Q_ASSERT(NULL != m_pRepMoverInfo); - Q_ASSERT(!m_pRepMoverInfo->m_DoubleInfo.isEmpty()); - - // Get viewport informations - const double calibre= 800.0; - const double hRatio= static_cast(m_pViewport->viewHSize()) / calibre; - const double vRatio= static_cast(m_pViewport->viewVSize()) / calibre; - - glDisable(GL_TEXTURE_2D); - GLC_Context::current()->glcEnableLighting(false); - glDisable(GL_DEPTH_TEST); - - GLC_Context::current()->glcMatrixMode(GL_PROJECTION); - GLC_Context::current()->glcPushMatrix(); - GLC_Context::current()->glcLoadIdentity(); - GLC_Context::current()->glcOrtho(hRatio * -1.0 ,hRatio * 1.0 ,vRatio * -1.0 ,vRatio * 1.0 ,-1.0 ,1.0); - GLC_Context::current()->glcMatrixMode(GL_MODELVIEW); - GLC_Context::current()->glcPushMatrix(); - GLC_Context::current()->glcLoadIdentity(); - - m_CenterCircle.render(glc::WireRenderFlag); - m_Hud.render(glc::WireRenderFlag); - m_Plane.render(glc::WireRenderFlag); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - m_CenterCircle.render(glc::TransparentRenderFlag); - m_Hud.render(glc::TransparentRenderFlag); - m_Plane.render(glc::TransparentRenderFlag); - - /* - // Render velocity value + text - QString velocity(QChar(' ') + QString::number(static_cast(100.0 * m_pRepMoverInfo->m_DoubleInfo.first()))); - QFont myFont; - myFont.setBold(true); - QFontMetrics fontmetrics(myFont); - int txtHeight= fontmetrics.boundingRect(velocity).height(); - double posy= 2.0 * static_cast(txtHeight) / calibre; - m_pViewport->qGLWidgetHandle()->renderText(- m_HudOffset.getX(), m_HudOffset.getY() - posy, 0.0, velocity, myFont); - */ - - GLC_Context::current()->glcPopMatrix(); - GLC_Context::current()->glcMatrixMode(GL_PROJECTION); - GLC_Context::current()->glcPopMatrix(); - GLC_Context::current()->glcMatrixMode(GL_MODELVIEW); - - glEnable(GL_DEPTH_TEST); -} - -void GLC_RepFlyMover::createRepresentation() -{ - // HUD creation - GLC_Circle* pCircle= new GLC_Circle(m_Radius); - pCircle->setWireColor(GLC_RepMover::m_MainColor); - pCircle->setLineWidth(GLC_RepMover::m_Thickness); - m_CenterCircle.addGeometry(pCircle); - - GLC_Polylines* pPolylines= new GLC_Polylines(); - GLfloatVector points; - const double hudx= m_HudOffset.x(); - const double hudy= m_HudOffset.y(); - points << -hudx << -hudy << 0.0; - points << -hudx << hudy << 0.0; - pPolylines->addPolyline(points); - points.clear(); - points << hudx << -hudy << 0.0; - points << hudx << hudy << 0.0; - pPolylines->addPolyline(points); - pPolylines->setWireColor(GLC_RepMover::m_MainColor); - pPolylines->setLineWidth(GLC_RepMover::m_Thickness); - m_Hud.addGeometry(pPolylines); - - // Plane creation - pPolylines= new GLC_Polylines(); - points.clear(); - const double l1= m_Radius * 1.5; - points << (-m_Radius - l1) << -m_Radius << 0.0; - points << -m_Radius << -m_Radius << 0.0; - points << 0.0 << 0.0 << 0.0; - points << m_Radius << -m_Radius << 0.0; - points << (m_Radius + l1) << -m_Radius << 0.0; - pPolylines->addPolyline(points); - pPolylines->setWireColor(GLC_RepMover::m_MainColor); - pPolylines->setLineWidth(GLC_RepMover::m_Thickness); - m_Plane.addGeometry(pPolylines); -} diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_repflymover.h b/ground/gcs/src/libs/glc_lib/viewport/glc_repflymover.h deleted file mode 100644 index 50940451d..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_repflymover.h +++ /dev/null @@ -1,117 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_repflymover.h Interface for the GLC_RepFlyMover class. - -#ifndef GLC_REPFLYMOVER_H_ -#define GLC_REPFLYMOVER_H_ - -#include "glc_repmover.h" -#include "../geometry/glc_circle.h" -#include "../sceneGraph/glc_3dviewinstance.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_RepFlyMover -/*! \brief GLC_RepFlyMover : Fly representation*/ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_RepFlyMover : public GLC_RepMover -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Default constructor - GLC_RepFlyMover(GLC_Viewport* pViewport); - - //! Copy constructor - GLC_RepFlyMover(const GLC_RepFlyMover& repFlyMover); - - //! Destructor - virtual ~GLC_RepFlyMover(); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// - //! Return a clone of the flymover - virtual GLC_RepMover* clone() const; - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// - //! Update the representation - virtual void update(); - - //! Set representation main color - virtual void setMainColor(const QColor& color); - - //! Set representation wire thickness - virtual void setThickness(double thickness); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Virtual interface for OpenGL Geometry set up. - virtual void glDraw(); - -//@} - - -///////////////////////////////////////////////////////////////////// -// Private services Functions -////////////////////////////////////////////////////////////////////// -private: - //! Create the plane representation - void createRepresentation(); - -////////////////////////////////////////////////////////////////////// -// Private Members -////////////////////////////////////////////////////////////////////// -private: - //! Center Circle radius - double m_Radius; - - //! Center Circle - GLC_3DViewInstance m_CenterCircle; - - //! Plane - GLC_3DViewInstance m_Plane; - - //! HUD - GLC_3DViewInstance m_Hud; - - //! HUD offset - GLC_Vector2d m_HudOffset; -}; - -#endif /* GLC_REPFLYMOVER_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_repmover.cpp b/ground/gcs/src/libs/glc_lib/viewport/glc_repmover.cpp deleted file mode 100644 index 738304a61..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_repmover.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -//! \file glc_repmover.cpp Implementation of the GLC_RepMover class. - -#include "glc_repmover.h" -#include "glc_viewport.h" - - -GLC_RepMover::GLC_RepMover(GLC_Viewport* pViewport) -: m_pViewport(pViewport) -, m_MainColor(Qt::black) -, m_Thickness(1.0) -, m_RenderProperties() -, m_pRepMoverInfo(NULL) -{ - -} -// Copy constructor -GLC_RepMover::GLC_RepMover(const GLC_RepMover& repMover) -: m_pViewport(repMover.m_pViewport) -, m_MainColor(repMover.m_MainColor) -, m_Thickness(repMover.m_Thickness) -, m_RenderProperties(repMover.m_RenderProperties) -, m_pRepMoverInfo(repMover.m_pRepMoverInfo) -{ - -} - - -GLC_RepMover::~GLC_RepMover() -{ - -} - -void GLC_RepMover::setRepMoverInfo(RepMoverInfo* pRepMoverInfo) -{ - m_pRepMoverInfo= pRepMoverInfo; -} - -void GLC_RepMover::setMainColor(const QColor& color) -{ - m_MainColor= color; -} - -void GLC_RepMover::setThickness(double thickness) -{ - m_Thickness= thickness; -} - -////////////////////////////////////////////////////////////////////// -// OpenGL Functions -////////////////////////////////////////////////////////////////////// - -// Representation OpenGL Execution -void GLC_RepMover::render() -{ - // Call virtual draw function - glDraw(); -} diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_repmover.h b/ground/gcs/src/libs/glc_lib/viewport/glc_repmover.h deleted file mode 100644 index dee957cfb..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_repmover.h +++ /dev/null @@ -1,131 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -//! \file glc_repmover.h Interface for the GLC_RepMover class. - -#ifndef GLC_REPMOVER_H_ -#define GLC_REPMOVER_H_ - -#include -#include "../maths/glc_vector3d.h" -#include "../maths/glc_matrix4x4.h" -#include "../shading/glc_renderproperties.h" -#include "../glc_config.h" - -class GLC_Viewport; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_RepMover -/*! \brief GLC_RepMover : Base class for all interactive manipulation representation*/ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_RepMover -{ -public: - struct RepMoverInfo - { - QVector m_MatrixInfo; - QVector m_VectorInfo; - QVector m_DoubleInfo; - QVector m_IntInfo; - QVector m_StringInfo; - }; - -public: - //! Default constructor - GLC_RepMover(GLC_Viewport*); - - //! Copy constructor - GLC_RepMover(const GLC_RepMover&); - - //! Destructor - virtual ~GLC_RepMover(); - - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the main Color - inline QColor mainColor() - {return m_MainColor;} - - //! Return a clone of the repmover - virtual GLC_RepMover* clone() const= 0; -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// - //! Set representation main color - virtual void setMainColor(const QColor& color); - - //! Set representation wire thickness - virtual void setThickness(double thickness); - - //! Init the representation - virtual void init(){} - - //! Update the representation - virtual void update(){} - - //! Set the repMoverInfo of this rep - void setRepMoverInfo(RepMoverInfo* pRepMoverInfo); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Representation OpenGL Execution - void render(); - -protected: - //! Virtual interface for OpenGL Geometry set up. - virtual void glDraw()= 0; - -//@} - -////////////////////////////////////////////////////////////////////// -// Protected Members -////////////////////////////////////////////////////////////////////// -protected: - //! The viewport - GLC_Viewport* m_pViewport; - - //! The rep main color - QColor m_MainColor; - - //! The rep wire thickness - double m_Thickness; - - //! The rep rendering properties - GLC_RenderProperties m_RenderProperties; - - //! The repmover info of this rep - RepMoverInfo* m_pRepMoverInfo; -}; - -#endif /* GLC_REPMOVER_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_reptrackballmover.cpp b/ground/gcs/src/libs/glc_lib/viewport/glc_reptrackballmover.cpp deleted file mode 100644 index aac0d9ece..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_reptrackballmover.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -//! \file glc_reptrackballmover.cpp Implementation of the GLC_RepTrackBallMover class. - -#include "glc_reptrackballmover.h" -#include "glc_viewport.h" -#include "../glc_factory.h" -#include "../glc_context.h" -#include - -using namespace glc; -//! The angle of arcs -#define ARCANGLE (30 * PI / 180) - -GLC_RepTrackBallMover::GLC_RepTrackBallMover(GLC_Viewport* pViewport) -: GLC_RepMover(pViewport) -, m_Radius(1.0) -, m_MainCircle(m_Radius) -, m_Arc1(GLC_Factory::instance()->createCircle(m_Radius, ARCANGLE)) -, m_MatArc1() -, m_Arc2(GLC_Factory::instance()->createCircle(m_Radius, ARCANGLE)) -, m_MatArc2() -, m_Ratio(0.95) -{ - m_MainCircle.setWireColor(GLC_RepMover::m_MainColor); - m_Arc1.geomAt(0)->setWireColor(GLC_RepMover::m_MainColor); - m_Arc2.geomAt(0)->setWireColor(GLC_RepMover::m_MainColor); - - // 2 circle arcs position - GLC_Matrix4x4 MatRot(Z_AXIS, -ARCANGLE / 2); - GLC_Matrix4x4 MatInt(Y_AXIS, -PI / 2); - MatRot= MatInt * MatRot; - - m_MatArc1= MatRot; - - MatInt.setMatRot(Z_AXIS, PI/2); - MatRot= MatInt * MatRot; - - m_MatArc2= MatRot; - -} - -// Copy constructor -GLC_RepTrackBallMover::GLC_RepTrackBallMover(const GLC_RepTrackBallMover& repMover) -: GLC_RepMover(repMover) -, m_Radius(repMover.m_Radius) -, m_MainCircle(repMover.m_MainCircle) -, m_Arc1(repMover.m_Arc1.deepCopy()) -, m_MatArc1(repMover.m_MatArc1) -, m_Arc2(repMover.m_Arc2.deepCopy()) -, m_MatArc2(repMover.m_MatArc2) -, m_Ratio(repMover.m_Ratio) -{ - -} - -GLC_RepTrackBallMover::~GLC_RepTrackBallMover() -{ - -} - - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -// Return a clone of the repmover -GLC_RepMover* GLC_RepTrackBallMover::clone() const -{ - return new GLC_RepTrackBallMover(*this); -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -// Set Arcs orientation and position in concordance with mouse position -void GLC_RepTrackBallMover::init() -{ - Q_ASSERT(NULL != m_pRepMoverInfo); - Q_ASSERT(!m_pRepMoverInfo->m_VectorInfo.isEmpty()); - Q_ASSERT(!m_pRepMoverInfo->m_MatrixInfo.isEmpty()); - - GLC_Vector3d VectAngle(m_pRepMoverInfo->m_VectorInfo.first()); - VectAngle.setZ(0); - VectAngle.setLength(1); - - GLC_Matrix4x4 MatRot; - double Angle; - - // Compute the 2 arcs orientation - if (VectAngle.y() > 0) - { // Angle entre 0 et PI - Angle= acos(VectAngle.x()); - MatRot.setMatRot(Z_AXIS, Angle); - } - else - { // Angle between 0 et -PI - Angle= -acos(VectAngle.x()); - MatRot.setMatRot(Z_AXIS, Angle); - } - - // Composition of orientation matrix and mapping matrix - MatRot= m_pRepMoverInfo->m_MatrixInfo.first() * MatRot; - - m_Arc1.setMatrix(MatRot * m_MatArc1); - m_Arc2.setMatrix(MatRot * m_MatArc2); -} - -// Set Arcs position in concordance with mouse position -void GLC_RepTrackBallMover::update() -{ - Q_ASSERT(NULL != m_pRepMoverInfo); - Q_ASSERT(!m_pRepMoverInfo->m_MatrixInfo.isEmpty()); - const GLC_Matrix4x4 matrix(m_pRepMoverInfo->m_MatrixInfo.first()); - m_Arc1.multMatrix(matrix); - m_Arc2.multMatrix(matrix); -} - -// overload function setColor(color); -void GLC_RepTrackBallMover::setMainColor(const QColor& color) -{ - GLC_RepMover::setMainColor(color); - m_MainCircle.setWireColor(GLC_RepMover::m_MainColor); - m_Arc1.geomAt(0)->setWireColor(GLC_RepMover::m_MainColor); - m_Arc2.geomAt(0)->setWireColor(GLC_RepMover::m_MainColor); -} - -////////////////////////////////////////////////////////////////////// -// OpenGL Functions -////////////////////////////////////////////////////////////////////// - -// Virtual interface for OpenGL Geometry set up. -void GLC_RepTrackBallMover::glDraw() -{ - computeRadius(); - const double aspectRatio= static_cast(m_pViewport->viewHSize())/static_cast(m_pViewport->viewVSize()); - - // orbit circle must be shown - glDisable(GL_DEPTH_TEST); - - GLC_Context::current()->glcMatrixMode(GL_PROJECTION); - GLC_Context::current()->glcPushMatrix(); - GLC_Context::current()->glcLoadIdentity(); - GLC_Context::current()->glcOrtho(aspectRatio * -1.0 ,aspectRatio * 1.0 ,-1.0 ,1.0 ,-1.0 ,1.0); - GLC_Context::current()->glcMatrixMode(GL_MODELVIEW); - GLC_Context::current()->glcPushMatrix(); - GLC_Context::current()->glcLoadIdentity(); - - glDisable(GL_BLEND); - m_RenderProperties.setRenderingFlag(glc::WireRenderFlag); - // Display arcs - m_Arc1.render(glc::WireRenderFlag); - m_Arc2.render(glc::WireRenderFlag); - // Display base class (Main circle) - m_MainCircle.render(m_RenderProperties); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - m_RenderProperties.setRenderingFlag(glc::TransparentRenderFlag); - // Display arcs - m_Arc1.render(glc::TransparentRenderFlag); - m_Arc2.render(glc::TransparentRenderFlag); - // Display base class (Main circle) - m_MainCircle.render(m_RenderProperties); - - GLC_Context::current()->glcPopMatrix(); - GLC_Context::current()->glcMatrixMode(GL_PROJECTION); - GLC_Context::current()->glcPopMatrix(); - GLC_Context::current()->glcMatrixMode(GL_MODELVIEW); - -} - -////////////////////////////////////////////////////////////////////// -// Private services Functions -////////////////////////////////////////////////////////////////////// - -// Compute trackball radius -void GLC_RepTrackBallMover::computeRadius() -{ - int nRayonSph; - const double winHSize= static_cast(m_pViewport->viewHSize()); - const double winVSize= static_cast(m_pViewport->viewVSize()); - - if (winHSize > winVSize) - { - nRayonSph = static_cast(m_Ratio * winVSize / 2.0); - } - else - { - nRayonSph = static_cast(m_Ratio * winHSize / 2.0); - } - - // Compute the length of camera's field of view - const double ChampsVision = 2.0; - - // the side of camera's square is mapped on Vertical length of window - // Circle radius in OpenGL unit = Radius(Pixel) * (dimend GL / dimens Pixel) - const double RayonSph= fabs((static_cast(nRayonSph) * ChampsVision / winVSize)); - - if ((!qFuzzyCompare(RayonSph, 0.0) && !qFuzzyCompare(RayonSph - m_Radius, 0.0)) || (RayonSph < 2.0)) - { - // Main circle radius - m_MainCircle.setRadius(RayonSph); - - GLC_Circle* pCircle; - // Arc 1 radius - pCircle= static_cast(m_Arc1.geomAt(0)); - pCircle->setRadius(RayonSph); - // Arc 2 radius - pCircle= static_cast(m_Arc2.geomAt(0)); - pCircle->setRadius(RayonSph); - } - -} diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_reptrackballmover.h b/ground/gcs/src/libs/glc_lib/viewport/glc_reptrackballmover.h deleted file mode 100644 index 72271e55e..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_reptrackballmover.h +++ /dev/null @@ -1,117 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_reptrackballmover.h Interface for the GLC_RepTrackBallMover class. - -#ifndef GLC_REPTRACKBALLMOVER_H_ -#define GLC_REPTRACKBALLMOVER_H_ - -#include "glc_repmover.h" -#include "../geometry/glc_circle.h" -#include "../sceneGraph/glc_3dviewinstance.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_RepTrackBallMover -/*! \brief GLC_RepTrackBallMover : Track Ball representation*/ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_RepTrackBallMover : public GLC_RepMover -{ -public: - //! Default constructor - GLC_RepTrackBallMover(GLC_Viewport*); - - //! Copy constructor - GLC_RepTrackBallMover(const GLC_RepTrackBallMover&); - - // Destructor - virtual ~GLC_RepTrackBallMover(); - - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// - //! Return a clone of the repmover - virtual GLC_RepMover* clone() const; -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Set Arcs orientation and position in concordance with mouse position - virtual void init(); - - //! Set Arcs position in concordance with mouse position - virtual void update(); - - //! Set representation main color - virtual void setMainColor(const QColor& color); - - //! Set representation screen ration - inline void setRatio(double ratio) - {m_Ratio= ratio;} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Virtual interface for OpenGL Geometry set up. - virtual void glDraw(); - -//@} - -////////////////////////////////////////////////////////////////////// -// Private services Functions -////////////////////////////////////////////////////////////////////// -private: - //! Compute trackball radius - void computeRadius(); - -////////////////////////////////////////////////////////////////////// -// Private Members -////////////////////////////////////////////////////////////////////// -private: - //! trackball radius - double m_Radius; - //! Main Circle - GLC_Circle m_MainCircle; - //! Arc 1 showing orbit sphere orientation - GLC_3DViewInstance m_Arc1; - //! Arc 1 positionning Matrix - GLC_Matrix4x4 m_MatArc1; - //! Arc 2 showing orbit sphere orientation - GLC_3DViewInstance m_Arc2; - //! Arc 2 positionning Matrix - GLC_Matrix4x4 m_MatArc2; - //! The ratio of the trackball size - double m_Ratio; - -}; - -#endif /* GLC_REPTRACKBALLMOVER_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_settargetmover.cpp b/ground/gcs/src/libs/glc_lib/viewport/glc_settargetmover.cpp deleted file mode 100644 index fce588103..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_settargetmover.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -#include "glc_settargetmover.h" -#include "glc_viewport.h" -#include "glc_openglexception.h" - -// Default constructor -GLC_SetTargetMover::GLC_SetTargetMover(GLC_Viewport* pViewport, const QList& repsList) -: GLC_Mover(pViewport, repsList) -{ - - -} - -// Copy constructor -GLC_SetTargetMover::GLC_SetTargetMover(const GLC_SetTargetMover& mover) -: GLC_Mover(mover) -{ - - -} - -GLC_SetTargetMover::~GLC_SetTargetMover() -{ - -} - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -// Return a clone of the mover -GLC_Mover* GLC_SetTargetMover::clone() const -{ - return new GLC_SetTargetMover(*this); -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -// Initialized the mover -void GLC_SetTargetMover::init(const GLC_UserInput& userInput) -{ - // Z Buffer component of selected point between 0 and 1 - GLfloat Depth; - // read selected point - glReadPixels(userInput.x(), m_pViewport->viewVSize() - userInput.y() , 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &Depth); - - // Test if there is geometry under picking point - if (!qFuzzyCompare(Depth, 1.0f)) - { // Geometry find -> Update camera's target position - const GLC_Point3d target(m_pViewport->unProject(userInput.x(), userInput.y())); - m_pViewport->cameraHandle()->setTargetCam(target); - } - else - { // Geometry not find -> panning - - const GLC_Point3d curPos(m_pViewport->mapPosMouse(userInput.x(), userInput.y())); - const GLC_Point3d prevPos(m_pViewport->mapPosMouse(m_pViewport->viewHSize() / 2, m_pViewport->viewVSize() / 2)); - const GLC_Vector3d VectPan(curPos - prevPos); // panning vector - // pan camera - m_pViewport->cameraHandle()->pan(VectPan); - } -} diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_settargetmover.h b/ground/gcs/src/libs/glc_lib/viewport/glc_settargetmover.h deleted file mode 100644 index 5d0ae637a..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_settargetmover.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -#ifndef GLC_SETTARGETMOVER_H_ -#define GLC_SETTARGETMOVER_H_ - -#include "glc_mover.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_SetTargetMover -/*! \brief GLC_SetTargetMover : Define the view target */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_SetTargetMover : public GLC_Mover -{ -public: - //! Default constructor - GLC_SetTargetMover(GLC_Viewport*, const QList& repsList= QList()); - - //! Copy constructor - GLC_SetTargetMover(const GLC_SetTargetMover&); - - //! Destructor - virtual ~GLC_SetTargetMover(); - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return a clone of the mover - virtual GLC_Mover* clone() const; -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Initialized the mover - virtual void init(const GLC_UserInput& userInput); - - //! Move the camera - virtual bool move(const GLC_UserInput&){return true;} -//@} - -}; - -#endif /* GLC_SETTARGETMOVER_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_trackballmover.cpp b/ground/gcs/src/libs/glc_lib/viewport/glc_trackballmover.cpp deleted file mode 100644 index 766e32385..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_trackballmover.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_trackballmover.cpp Implementation of the GLC_TrackBallMover class. - -#include "glc_trackballmover.h" -#include "glc_viewport.h" -#include "glc_reptrackballmover.h" - -// Default constructor -GLC_TrackBallMover::GLC_TrackBallMover(GLC_Viewport* pViewport, const QList& repsList) -: GLC_Mover(pViewport, repsList) -, m_Ratio(0.95) -{ - GLC_Mover::m_MoverInfo.m_MatrixInfo.append(GLC_Matrix4x4()); - GLC_Mover::m_MoverInfo.m_VectorInfo.append(GLC_Vector3d()); -} - -// Copy constructor -GLC_TrackBallMover::GLC_TrackBallMover(const GLC_TrackBallMover& mover) -: GLC_Mover(mover) -, m_Ratio(mover.m_Ratio) -{ - -} - -GLC_TrackBallMover::~GLC_TrackBallMover() -{ - -} - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -// Return a clone of the mover -GLC_Mover* GLC_TrackBallMover::clone() const -{ - return new GLC_TrackBallMover(*this); -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -// Initialized the mover -void GLC_TrackBallMover::init(const GLC_UserInput& userInput) -{ - GLC_Mover::m_PreviousVector.setVect(mapForTracking(static_cast(userInput.x()), static_cast(userInput.y()))); - - const double Angle= acos(glc::Z_AXIS * GLC_Mover::m_PreviousVector); - const GLC_Vector3d AxeRot(glc::Z_AXIS ^ GLC_Mover::m_PreviousVector); - - GLC_Matrix4x4 Matrice(AxeRot, Angle); - - GLC_Mover::m_MoverInfo.m_MatrixInfo.first()= Matrice; - GLC_Mover::m_MoverInfo.m_VectorInfo.first()= GLC_Mover::m_PreviousVector; - // Update trackball representations - initRepresentation(); -} - -// Move the camera -bool GLC_TrackBallMover::move(const GLC_UserInput& userInput) -{ - const GLC_Vector3d VectCurOrbit(mapForTracking(static_cast(userInput.x()), static_cast(userInput.y()))); - - // Update camera position (orbit) - GLC_Mover::m_pViewport->cameraHandle()->orbit(GLC_Mover::m_PreviousVector, VectCurOrbit); - - // Update arcs of circle's positionning matrix - const GLC_Matrix4x4 MatRot(GLC_Mover::m_PreviousVector, VectCurOrbit); - - GLC_Mover::m_MoverInfo.m_MatrixInfo.first()= MatRot; - updateRepresentation(); - - // Previous vector become current vector - GLC_Mover::m_PreviousVector = VectCurOrbit; - - return true; -} - -void GLC_TrackBallMover::setRatio(double ratio) -{ - m_Ratio= ratio; - const int repCount= m_RepMoverList.count(); - for (int i= 0; i < repCount; ++i) - { - GLC_RepTrackBallMover* pRep= dynamic_cast(m_RepMoverList.at(i)); - if (NULL != pRep) - { - pRep->setRatio(ratio); - } - } -} -///////////////////////////////////////////////////////////////////// -// Private services Functions -////////////////////////////////////////////////////////////////////// - -// Convert mouse View coordinate to tracking coordinate (Centred and betwen (-1,-1) and (1,1)) -GLC_Vector3d GLC_TrackBallMover::mapForTracking( double x, double y) const -{ - double AspectRatio; - const double winHSize= static_cast(GLC_Mover::m_pViewport->viewHSize()); - const double winVSize= static_cast(GLC_Mover::m_pViewport->viewVSize()); - - // Change origine and cover - if (winHSize < winVSize) - { - AspectRatio= winVSize / winHSize; - x= ( (x - winHSize / 2.0 ) / ( winHSize / 2.0) ) / m_Ratio; - y= AspectRatio * ( ( winVSize / 2.0 - y) / ( winVSize / 2.0 ) ) / m_Ratio; - } - else - { - AspectRatio= winHSize / winVSize; - x= AspectRatio * ( (x - winHSize / 2.0 ) / ( winHSize / 2.0) ) / m_Ratio; - y= ( (winVSize / 2.0 - y) / (winVSize / 2.0 ) ) / m_Ratio; - } - - // Distance between pick point and origine can't be over then 1 (1 is radius of orbit circle) - GLC_Vector3d mousePos(x, y, 0.0); - if (mousePos.length() > 1.0) - { - mousePos.setLength(1.0); - } - else - { - mousePos.setZ(sqrt(1.0 - mousePos.x() * mousePos.x() - mousePos.y() * mousePos.y())); - } - - return mousePos; - -} diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_trackballmover.h b/ground/gcs/src/libs/glc_lib/viewport/glc_trackballmover.h deleted file mode 100644 index 7a11b4ba0..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_trackballmover.h +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ -//! \file glc_trackballmover.h Interface for the GLC_TrackBallMover class. - -#ifndef GLC_TRACKBALLMOVER_H_ -#define GLC_TRACKBALLMOVER_H_ - -#include "glc_mover.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_TrackBallMover -/*! \brief GLC_TrackBallMover : Track ball interactive manipulation */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_TrackBallMover : public GLC_Mover -{ -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Default constructor - GLC_TrackBallMover(GLC_Viewport*, const QList& repsList= QList()); - - //! Copy constructor - GLC_TrackBallMover(const GLC_TrackBallMover&); - - //! Destructor - virtual ~GLC_TrackBallMover(); -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return a clone of the mover - virtual GLC_Mover* clone() const; -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Initialized the mover - virtual void init(const GLC_UserInput& userInput); - - //! Move the camera - virtual bool move(const GLC_UserInput& userInput); - - //! Set this mover screen ratio - void setRatio(double ratio); - -//@} - -///////////////////////////////////////////////////////////////////// -// Private services Functions -////////////////////////////////////////////////////////////////////// -private: - //! Convert mouse View coordinate to tracking coordinate (Centred and betwen (-1,-1) and (1,1)) - GLC_Vector3d mapForTracking( double , double) const; - -////////////////////////////////////////////////////////////////////// -// Private Members -////////////////////////////////////////////////////////////////////// -private: - //! The ratio of the trackball size - double m_Ratio; - - -}; - -#endif /* GLC_TRACKBALLMOVER_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_tsrmover.cpp b/ground/gcs/src/libs/glc_lib/viewport/glc_tsrmover.cpp deleted file mode 100644 index 7b71b1073..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_tsrmover.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -//! \file glc_tsrmover.cpp Implementation of the GLC_TsrMover class. - -#include "glc_tsrmover.h" -#include "glc_viewport.h" - -#include "../geometry/glc_point.h" - -// Default constructor -GLC_TsrMover::GLC_TsrMover(GLC_Viewport* pViewport, const QList& repsList) -: GLC_Mover(pViewport, repsList) -{ - -} - -// Copy constructor -GLC_TsrMover::GLC_TsrMover(const GLC_TsrMover& tsrMover) -: GLC_Mover(tsrMover) -{ - -} - - -GLC_TsrMover::~GLC_TsrMover() -{ - -} - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -// Return a clone of the mover -GLC_Mover* GLC_TsrMover::clone() const -{ - return new GLC_TsrMover(*this); -} - - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -// Initialized the mover -void GLC_TsrMover::init(const GLC_UserInput& userInput) -{ - m_PreviousVector= GLC_Point3d(userInput.normalyzeXTouchCenter(), userInput.normalyzeYTouchCenter(), 0.0); -} - -// Move the camera -bool GLC_TsrMover::move(const GLC_UserInput& userInput) -{ - if (!(userInput.normalyzeXTouchCenter() < 0.0) && !(userInput.normalyzeYTouchCenter() < 0.0)) - { - m_PreviousVector= GLC_Point3d(userInput.normalyzeXTouchCenter(), userInput.normalyzeYTouchCenter(), 0.0); - } - else - { - qDebug() << "Pas cool"; - if (!userInput.translation().isNull()) - { - m_PreviousVector= GLC_Vector3d(userInput.translation().x(), userInput.translation().y(), 0.0) + m_PreviousVector; - } - } - - const double x= m_PreviousVector.x(); - const double y= m_PreviousVector.y(); - //GLC_Point3d center2= m_pViewport->unProject(x * m_pViewport->viewHSize(), y * m_pViewport->viewVSize()); - - //qDebug() << "touch center= " << x << " , " << y; - - - if (!qFuzzyCompare(userInput.scaleFactor(), 0)) - { - GLC_Point dummy(m_pViewport->cameraHandle()->target()); - m_pViewport->setDistMinAndMax(dummy.boundingBox()); - - GLC_Point2d nPos= m_pViewport->mapNormalyzeToOpenGLScreen(x, y); - GLC_Point3d nPos3D(nPos.x(), nPos.y(), 1.0); - GLC_Point3d projected= m_pViewport->compositionMatrix().inverted() * nPos3D; - - m_pViewport->cameraHandle()->zoom(userInput.scaleFactor()); - - m_pViewport->setDistMinAndMax(dummy.boundingBox()); - GLC_Point3d projected2= m_pViewport->compositionMatrix().inverted() * nPos3D; - GLC_Vector3d delta= projected - projected2; - m_pViewport->cameraHandle()->translate(delta); - } - - if (!qFuzzyCompare(userInput.rotationAngle(), 0)) - { - GLC_Point dummy(m_pViewport->cameraHandle()->target()); - m_pViewport->setDistMinAndMax(dummy.boundingBox()); - - GLC_Point2d nPos= m_pViewport->mapNormalyzeToOpenGLScreen(x, y); - GLC_Point3d nPos3D(nPos.x(), nPos.y(), 1.0); - GLC_Point3d center= m_pViewport->compositionMatrix().inverted() * nPos3D; - - GLC_Vector3d axis= m_pViewport->cameraHandle()->forward(); - - m_pViewport->cameraHandle()->rotateAround(axis, userInput.rotationAngle(), center); - } - - if (!userInput.translation().isNull()) - { - double transX= userInput.translation().x() * m_pViewport->viewHSize(); - double transY= userInput.translation().y() * m_pViewport->viewVSize(); - - GLC_Vector3d mappedTranslation(-transX, -transY, 0.0); - // Compute the length of camera's field of view - const double ChampsVision = m_pViewport->cameraHandle()->distEyeTarget() * m_pViewport->viewTangent(); - - // the side of camera's square is mapped on Vertical length of window - // Ratio OpenGL/Pixel = dimend GL / dimens Pixel - const double Ratio= ChampsVision / static_cast(m_pViewport->viewVSize()); - - mappedTranslation= mappedTranslation * Ratio; - m_pViewport->cameraHandle()->pan(mappedTranslation); - } - - return true; -} - diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_tsrmover.h b/ground/gcs/src/libs/glc_lib/viewport/glc_tsrmover.h deleted file mode 100644 index f18604b97..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_tsrmover.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -//! \file glc_tsrmover Interface for the GLC_TsrMover class. - -#ifndef GLC_TSRMOVER_H_ -#define GLC_TSRMOVER_H_ - -#include "glc_mover.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_TsrMover -/*! \brief GLC_TsrMover : Translationn scaling and rotation interactive manipulation */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_TsrMover : public GLC_Mover -{ -public: - //! Default constructor - GLC_TsrMover(GLC_Viewport*, const QList& repsList= QList()); - - //! Copy constructor - GLC_TsrMover(const GLC_TsrMover&); - - //! Destructor - virtual ~GLC_TsrMover(); - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return a clone of the mover - virtual GLC_Mover* clone() const; -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Initialized the mover - virtual void init(const GLC_UserInput& userInput); - - //! Move the camera - virtual bool move(const GLC_UserInput& userInput); -//@} -}; -#endif /* GLC_TSRMOVER_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_turntablemover.cpp b/ground/gcs/src/libs/glc_lib/viewport/glc_turntablemover.cpp deleted file mode 100644 index 4d56ade13..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_turntablemover.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - Copyright (C) 2009 Laurent Bauer - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -#include "glc_turntablemover.h" -#include "glc_viewport.h" - -// Default constructor -GLC_TurnTableMover::GLC_TurnTableMover(GLC_Viewport* pViewport, const QList& repsList) -: GLC_Mover(pViewport, repsList) -, m_Sign(1.0) -{ - -} - - -// Copy constructor -GLC_TurnTableMover::GLC_TurnTableMover(const GLC_TurnTableMover& mover) -: GLC_Mover(mover) -, m_Sign(mover.m_Sign) -{ -} - - -GLC_TurnTableMover::~GLC_TurnTableMover() -{ -} - - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -// Return a clone of the mover -GLC_Mover* GLC_TurnTableMover::clone() const -{ - return new GLC_TurnTableMover(*this); -} - - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -// Initialized the mover -void GLC_TurnTableMover::init(const GLC_UserInput& userInput) -{ - GLC_Mover::m_PreviousVector.setVect(static_cast(userInput.x()), static_cast(userInput.y()),0.0); - GLC_Camera* pCamera= GLC_Mover::m_pViewport->cameraHandle(); - // Calculate angle sign - m_Sign= pCamera->defaultUpVector() * pCamera->upVector(); - if (m_Sign == 0) - { - m_Sign= 1; - } - else - { - m_Sign= m_Sign / fabs(m_Sign); - } - - pCamera->setUpCam(pCamera->defaultUpVector() * m_Sign); -} - - -bool GLC_TurnTableMover::move(const GLC_UserInput& userInput) -{ - GLC_Camera* pCamera= GLC_Mover::m_pViewport->cameraHandle(); - // Turn table rotation - const double rotSpeed= 2.3; - const double width= static_cast ( GLC_Mover::m_pViewport->viewVSize() ); - const double height= static_cast ( GLC_Mover::m_pViewport->viewHSize() ); - - const double alpha = -((static_cast(userInput.x()) - GLC_Mover::m_PreviousVector.x()) / width) * rotSpeed; - const double beta = ((static_cast(userInput.y()) - GLC_Mover::m_PreviousVector.y()) / height) * rotSpeed; - - // Rotation around the screen vertical axis - pCamera->rotateAroundTarget(pCamera->defaultUpVector(), alpha * m_Sign); - - // Rotation around the screen horizontal axis - GLC_Vector3d incidentVector= -pCamera->forward(); - GLC_Vector3d rightVector= incidentVector ^ pCamera->upVector(); - if (!rightVector.isNull()) - { - pCamera->rotateAroundTarget(rightVector, beta); - } - - m_PreviousVector.setVect(static_cast(userInput.x()), static_cast(userInput.y()), 0.0); - - return true; -} diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_turntablemover.h b/ground/gcs/src/libs/glc_lib/viewport/glc_turntablemover.h deleted file mode 100644 index 7eb44621a..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_turntablemover.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - Copyright (C) 2009 Laurent Bauer - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -#ifndef GLC_TURNTABLEMOVER_H_ -#define GLC_TURNTABLEMOVER_H_ - -#include "glc_mover.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_TurnTableMover -/*! \brief GLC_TurnTableMover : Turn table interactive manipulation */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_TurnTableMover : public GLC_Mover -{ -public: - //! Default constructor - GLC_TurnTableMover(GLC_Viewport*, const QList& repsList= QList()); - - //! Copy constructor - GLC_TurnTableMover(const GLC_TurnTableMover&); - - //! Destructor - virtual ~GLC_TurnTableMover(); - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return a clone of the mover - virtual GLC_Mover* clone() const; -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Initialized the mover - virtual void init(const GLC_UserInput& userInput); - - //! Move the camera - virtual bool move(const GLC_UserInput& userInput); - -//@} - -///////////////////////////////////////////////////////////////////// -// Private services Functions -////////////////////////////////////////////////////////////////////// -private: - -////////////////////////////////////////////////////////////////////// -// Private Members -////////////////////////////////////////////////////////////////////// - //! The rotation sign - double m_Sign; -}; - -#endif /* GLC_TURNTABLEMOVER_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_userinput.cpp b/ground/gcs/src/libs/glc_lib/viewport/glc_userinput.cpp deleted file mode 100644 index 1788efbd4..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_userinput.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -//! \file glc_mover.cpp Implementation of the GLC_Mover class. - -#include "glc_userinput.h" - -GLC_UserInput::GLC_UserInput(int x, int y) -: m_X(x) -, m_Y(y) -, m_NormalyzeX(0.0) -, m_NormalyzeY(0.0) -, m_Translation() -, m_Rotation(0.0) -, m_ScaleFactor(1.0) -, m_TransformationIsSet(false) -{ - -} - -GLC_UserInput::~GLC_UserInput() -{ - -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// -void GLC_UserInput::setPosition(int x, int y) -{ - m_X= x; - m_Y= y; -} - -void GLC_UserInput::setNormalyzeTouchCenterPosition(double x, double y) -{ - m_NormalyzeX= x; - m_NormalyzeY= y; -} - -void GLC_UserInput::setTransformation(const GLC_Vector2d& translation, double rotation, double scaleFactor) -{ - m_Translation= translation; - m_Rotation= rotation; - m_ScaleFactor= scaleFactor; - - m_TransformationIsSet= true; -} diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_userinput.h b/ground/gcs/src/libs/glc_lib/viewport/glc_userinput.h deleted file mode 100644 index 63fa8526a..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_userinput.h +++ /dev/null @@ -1,133 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -//! \file glc_userinput.h Interface for the GLC_UserInput class. - -#ifndef GLC_USERINPUT_H_ -#define GLC_USERINPUT_H_ - -#include "../maths/glc_vector2d.h" - -#include "../glc_config.h" - -class GLC_LIB_EXPORT GLC_UserInput -{ -public: - GLC_UserInput(int x= 0, int y= 0); - virtual ~GLC_UserInput(); - - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! return the x position - inline int x() const - {return m_X;} - - //! Return the y position - inline int y() const - {return m_Y;} - - //! Return normalyze x touch center - inline double normalyzeXTouchCenter() const - {return m_NormalyzeX;} - - //! Return normalyze x touch center - inline double normalyzeYTouchCenter() const - {return m_NormalyzeX;} - - //! Return the translation - inline GLC_Vector2d translation() const - {return m_Translation;} - - //! Return the rotation angle - inline double rotationAngle() const - {return m_Rotation;} - - //! Return the scale factor - inline double scaleFactor() const - {return m_ScaleFactor;} - - //! Return true if the transformation has been set - inline bool transformationIsSet() const - {return m_TransformationIsSet;} -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Set the position - void setPosition(int x, int y); - - //! Set the normalyze position of the center of touch - void setNormalyzeTouchCenterPosition(double x, double y); - - //! Set the transformation - void setTransformation(const GLC_Vector2d& translation, double rotation= 0.0, double scaleFactor= 1.0); - - //! Set translation - inline void setTranslation(const GLC_Vector2d& translation) - {m_Translation= translation;} - - //! Set rotation - inline void setRotation(double rotation) - {m_Rotation= rotation;} - - //! Set scaling - inline void setScaleFactor(double scaleFactor) - {m_ScaleFactor= scaleFactor;} -//@} - -////////////////////////////////////////////////////////////////////// -// Private Members -////////////////////////////////////////////////////////////////////// -private: - //! the x position of the user input - int m_X; - - //! The y position of the user input - int m_Y; - - //Normalize position of center of touchs - double m_NormalyzeX; - double m_NormalyzeY; - - // Transformation data - //! Translation vector - GLC_Vector2d m_Translation; - - //! Rotation angle - double m_Rotation; - - //! Scale factor - double m_ScaleFactor; - - //! Flag to know if a transformation has been set - bool m_TransformationIsSet; - -}; - -#endif /* GLC_USERINPUT_H_ */ diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_viewport.cpp b/ground/gcs/src/libs/glc_lib/viewport/glc_viewport.cpp deleted file mode 100644 index b9fa5eb6f..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_viewport.cpp +++ /dev/null @@ -1,756 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_viewport.cpp implementation of the GLC_Viewport class. - -#include - -#include "../glu/glc_glu.h" -#include "glc_viewport.h" -#include "../glc_openglexception.h" -#include "../glc_ext.h" -#include "../shading/glc_selectionmaterial.h" -#include "../glc_state.h" -#include "../sceneGraph/glc_3dviewinstance.h" - -#include - -using namespace glc; -////////////////////////////////////////////////////////////////////// -// Constructor Destructor -////////////////////////////////////////////////////////////////////// - -GLC_Viewport::GLC_Viewport() -// Camera definition -: m_pViewCam(new GLC_Camera()) // Camera -, m_DistanceMax(500.0) // Camera Maximum distance -, m_dDistanceMini(0.01) // Camera Minimum distance -, m_ViewAngle(35) // Camera angle of view -, m_ViewTangent(tan(glc::toRadian(m_ViewAngle))) -, m_pImagePlane(NULL) // Background image -// OpenGL Window size -, m_WindowHSize(0) // Horizontal OpenGL viewport size -, m_WindowVSize(0) // Vertical OpenGL viewport size -, m_AspectRatio(1.0) -// the default backgroundColor -, m_BackgroundColor(Qt::black) -, m_SelectionSquareSize(4) -, m_ProjectionMatrix() -, m_Frustum() -, m_ClipPlanesHash() -, m_UseClipPlane(false) -, m_3DWidgetCollection() -, m_UseParallelProjection(false) -, m_MinimumStaticPixelSize(10) -, m_MinimumStaticRatioSize(0.0) -, m_MinimumDynamicRatioSize(0.0) -{ - updateMinimumRatioSize(); -} - -GLC_Viewport::~GLC_Viewport() -{ - delete m_pViewCam; - - // delete background image - deleteBackGroundImage(); - - // Delete clip planes - QHash::iterator iClip= m_ClipPlanesHash.begin(); - while (m_ClipPlanesHash.constEnd() != iClip) - { - delete iClip.value(); - ++iClip; - } -} - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// -GLC_Point2d GLC_Viewport::normalyseMousePosition(int x, int y) -{ - double nX= 0.0; - double nY= 0.0; - if (m_WindowHSize != 0) - { - nX= static_cast(x) / static_cast(m_WindowHSize); - } - - if (m_WindowVSize != 0) - { - nY= static_cast(y) / static_cast(m_WindowVSize); - } - - return GLC_Point2d(nX, nY); -} - -GLC_Point2d GLC_Viewport::mapToOpenGLScreen(int x, int y) -{ - GLC_Point2d nPos= normalyseMousePosition(x, y); - - return mapNormalyzeToOpenGLScreen(nPos.x(), nPos.y()); -} - -GLC_Point2d GLC_Viewport::mapNormalyzeToOpenGLScreen(double x, double y) -{ - GLC_Point2d pos(x, y); - pos= pos * 2.0; - pos.setY(pos.y() * -1.0); - pos= pos + GLC_Point2d(-1.0, 1.0); - return pos; -} - -GLC_Vector3d GLC_Viewport::mapPosMouse( GLdouble Posx, GLdouble Posy) const -{ - // Change the window origin (Up Left -> centred) - Posx= Posx - static_cast(m_WindowHSize) / 2.0; - Posy= static_cast(m_WindowVSize) / 2.0 - Posy; - - GLC_Vector3d VectMouse(Posx, Posy,0); - - // Compute the length of camera's field of view - const double ChampsVision = m_pViewCam->distEyeTarget() * m_ViewTangent; - - // the side of camera's square is mapped on Vertical length of window - // Ratio OpenGL/Pixel = dimend GL / dimens Pixel - const double Ratio= ChampsVision / static_cast(m_WindowVSize); - - VectMouse= VectMouse * Ratio; - - return VectMouse; -} - -GLC_Vector3d GLC_Viewport::mapNormalyzePosMouse(double Posx, double Posy) const -{ - double screenX= Posx * static_cast(m_WindowHSize); - double screenY= Posy * static_cast(m_WindowVSize); - return mapPosMouse(screenX, screenY); -} - -////////////////////////////////////////////////////////////////////// -// Public OpenGL Functions -////////////////////////////////////////////////////////////////////// - -void GLC_Viewport::initGl() -{ - glClearColor(m_BackgroundColor.redF(), m_BackgroundColor.greenF(), m_BackgroundColor.blueF(), 1.0f); - glClearDepth(1.0f); // Depth Buffer Setup - glShadeModel(GL_SMOOTH); // Enable Smooth Shading - glEnable(GL_DEPTH_TEST); // Enables Depth Testing - glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculation - glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glPolygonOffset (1.0f, 1.0f); -} - -void GLC_Viewport::glExecuteCam(void) -{ - renderImagePlane(); - m_pViewCam->glExecute(); -} - -void GLC_Viewport::updateProjectionMat(void) -{ - GLC_Context::current()->glcMatrixMode(GL_PROJECTION); // select The Projection Matrix - GLC_Context::current()->glcLoadIdentity(); // Reset The Projection Matrix - - if (m_UseParallelProjection) - { - const double ChampsVision = m_pViewCam->distEyeTarget() * m_ViewTangent; - const double height= ChampsVision; - const double with= ChampsVision * m_AspectRatio; - const double left= -with * 0.5; - const double right= -left; - const double bottom= - height * 0.5; - const double top= -bottom; - GLC_Context::current()->glcOrtho(left, right, bottom, top, m_dDistanceMini, m_DistanceMax); - } - else - { - const double yMax= m_dDistanceMini * tan(m_ViewAngle * glc::PI / 360.0); - const double yMin= -yMax; - const double xMax= yMax * m_AspectRatio; - const double xMin= -xMax; - GLC_Context::current()->glcFrustum(xMin, xMax, yMin, yMax, m_dDistanceMini, m_DistanceMax); - } - - // Save the projection matrix - m_ProjectionMatrix= GLC_Context::current()->projectionMatrix(); - - GLC_Context::current()->glcMatrixMode(GL_MODELVIEW); // select The Modelview Matrix -} - -void GLC_Viewport::forceAspectRatio(double ratio) -{ - m_AspectRatio= ratio; - updateProjectionMat(); -} - -void GLC_Viewport::updateAspectRatio() -{ - // Update The Aspect Ratio Of The Window - m_AspectRatio= static_cast(m_WindowHSize)/static_cast(m_WindowVSize); -} -GLC_Frustum GLC_Viewport::selectionFrustum(int x, int y) const -{ - const int halfSize= m_SelectionSquareSize / 2; - // Calculate the 4 points of the selection - //p1->p2 - // - //p0 p3 - QList coordinates; - // Point 0 - coordinates << (x - halfSize) << (y + halfSize); - // Point 1 - coordinates << (x - halfSize) << (y - halfSize); - // Point 2 - coordinates << (x + halfSize) << (y - halfSize); - // Point 3 - coordinates << (x + halfSize) << (y + halfSize); - - // Unproject the 4 point - QList listOfPoint= unproject(coordinates); - - Q_ASSERT(4 == listOfPoint.size()); - // Create the four frustum planes - GLC_Point3d eye= m_pViewCam->eye(); - const GLC_Plane leftPlane(listOfPoint.at(0), listOfPoint.at(1), eye); - const GLC_Plane rightPlane(listOfPoint.at(3), eye , listOfPoint.at(2)); - const GLC_Plane upPlane(listOfPoint.at(2), eye, listOfPoint.at(1)); - const GLC_Plane bottomPlane(listOfPoint.at(0), eye, listOfPoint.at(3)); - - GLC_Frustum selectionFrustum(m_Frustum); - selectionFrustum.setLeftClippingPlane(leftPlane); - selectionFrustum.setRightClippingPlane(rightPlane); - selectionFrustum.setTopClippingPlane(upPlane); - selectionFrustum.setBottomClippingPlane(bottomPlane); - - return selectionFrustum; -} - -GLC_Point3d GLC_Viewport::unProject(int x, int y) const -{ - // Z Buffer component of the given coordinate is between 0 and 1 - GLfloat Depth; - // read selected point - glReadPixels(x, m_WindowVSize - y , 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &Depth); - - // The current viewport opengl definition - GLint Viewport[4]; - glGetIntegerv(GL_VIEWPORT, Viewport); - - // OpenGL ccordinate of selected point - GLdouble pX, pY, pZ; - glc::gluUnProject((GLdouble) x, (GLdouble) (m_WindowVSize - y) , Depth - , m_pViewCam->modelViewMatrix().getData(), m_ProjectionMatrix.getData(), Viewport, &pX, &pY, &pZ); - - return GLC_Point3d(pX, pY, pZ); -} - -QList GLC_Viewport::unproject(const QList& list)const -{ - const int size= list.size(); - Q_ASSERT((size % 2) == 0); - - // The current viewport opengl definition - GLint Viewport[4]; - glGetIntegerv(GL_VIEWPORT, Viewport); - - // Z Buffer component of the given coordinate is between 0 and 1 - GLfloat Depth; - - // Coordinate of readed points - GLdouble pX, pY, pZ; - QList unprojectedPoints; - for (int i= 0; i < size; i+= 2) - { - const int x= list.at(i); - const int y= m_WindowVSize - list.at(i + 1); - glReadPixels(x, y , 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &Depth); - - glc::gluUnProject(static_cast(x), static_cast(y) , Depth , m_pViewCam->modelViewMatrix().getData() - , m_ProjectionMatrix.getData(), Viewport, &pX, &pY, &pZ); - unprojectedPoints.append(GLC_Point3d(pX, pY, pZ)); - } - - return unprojectedPoints; -} - -////////////////////////////////////////////////////////////////////// -// Private OpenGL Functions -////////////////////////////////////////////////////////////////////// - -void GLC_Viewport::renderImagePlane() -{ - - if(!GLC_State::isInSelectionMode()) - { - if (m_pImagePlane != NULL) - { - m_pImagePlane->render(); - } - } -} - -void GLC_Viewport::render3DWidget() -{ - m_3DWidgetCollection.render(0, glc::WireRenderFlag); - m_3DWidgetCollection.render(0, glc::TransparentRenderFlag); -} -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -void GLC_Viewport::setWinGLSize(int HSize, int VSize) -{ - if ((m_WindowHSize != HSize) || (m_WindowVSize != VSize)) - { - m_WindowHSize= HSize; - m_WindowVSize= VSize; - - // from NeHe's Tutorial 3 - if (m_WindowVSize == 0) // Prevent A Divide By Zero By - { - m_WindowVSize= 1; // Making Height Equal One - } - - glViewport(0,0,m_WindowHSize,m_WindowVSize); // Reset The Current Viewport - - updateAspectRatio(); - - updateProjectionMat(); - - updateMinimumRatioSize(); - } -} - -GLC_uint GLC_Viewport::renderAndSelect(int x, int y) -{ - const QColor clearColor(Qt::black); - glClearColor(clearColor.redF(), clearColor.greenF(), clearColor.blueF(), 1.0f); - GLC_State::setSelectionMode(true); - // Draw the scene - emit updateOpenGL(); - GLC_State::setSelectionMode(false); - - return selectOnPreviousRender(x, y); -} - -GLC_uint GLC_Viewport::selectOnPreviousRender(int x, int y) -{ - GLsizei width= m_SelectionSquareSize; - GLsizei height= width; - GLint newX= x - width / 2; - GLint newY= (m_WindowVSize - y) - height / 2; - if (newX < 0) newX= 0; - if (newY < 0) newY= 0; - - return meaningfulIdInsideSquare(newX, newY, width, height); -} -GLC_uint GLC_Viewport::selectBody(GLC_3DViewInstance* pInstance, int x, int y) -{ - const QColor clearColor(Qt::black); - glClearColor(clearColor.redF(), clearColor.greenF(), clearColor.blueF(), 1.0f); - GLC_State::setSelectionMode(true); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - GLC_Context::current()->glcLoadIdentity(); - - glExecuteCam(); - - // Draw the scene - glDisable(GL_BLEND); - GLC_Context::current()->glcEnableLighting(false); - glDisable(GL_TEXTURE_2D); - - pInstance->renderForBodySelection(); - GLC_State::setSelectionMode(false); - - GLsizei width= 6; - GLsizei height= width; - GLint newX= x - width / 2; - GLint newY= (m_WindowVSize - y) - height / 2; - if (newX < 0) newX= 0; - if (newY < 0) newY= 0; - - return meaningfulIdInsideSquare(newX, newY, width, height); -} - -QPair GLC_Viewport::selectPrimitive(GLC_3DViewInstance* pInstance, int x, int y) -{ - QPair result; - - const QColor clearColor(Qt::black); - glClearColor(clearColor.redF(), clearColor.greenF(), clearColor.blueF(), 1.0f); - GLC_State::setSelectionMode(true); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - GLC_Context::current()->glcLoadIdentity(); - - glExecuteCam(); - - // Draw the scene - glDisable(GL_BLEND); - GLC_Context::current()->glcEnableLighting(false); - glDisable(GL_TEXTURE_2D); - - pInstance->renderForBodySelection(); - - - GLsizei width= 6; - GLsizei height= width; - GLint newX= x - width / 2; - GLint newY= (m_WindowVSize - y) - height / 2; - if (newX < 0) newX= 0; - if (newY < 0) newY= 0; - - GLC_uint bodyId= meaningfulIdInsideSquare(newX, newY, width, height); - if (bodyId == 0) - { - result.first= -1; - result.second= 0; - } - else - { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - result.first= pInstance->renderForPrimitiveSelection(bodyId); - result.second= meaningfulIdInsideSquare(newX, newY, width, height); - } - GLC_State::setSelectionMode(false); - return result; -} - -QSet GLC_Viewport::selectInsideSquare(int x1, int y1, int x2, int y2) -{ - if (x1 > x2) - { - int xTemp= x1; - x1= x2; - x2= xTemp; - } - if (y2 > y1) - { - int yTemp= y1; - y1= y2; - y2= yTemp; - } - const QColor clearColor(Qt::black); - glClearColor(clearColor.redF(), clearColor.greenF(), clearColor.blueF(), 1.0f); - GLC_State::setSelectionMode(true); - // Draw the scene - updateOpenGL(); - GLC_State::setSelectionMode(false); - - GLsizei width= x2 - x1; - GLsizei height= y1 - y2; - GLint newX= x1; - GLint newY= (m_WindowVSize - y1); - if (newX < 0) newX= 0; - if (newY < 0) newY= 0; - - return listOfIdInsideSquare(newX, newY, width, height); -} - -GLC_uint GLC_Viewport::meaningfulIdInsideSquare(GLint x, GLint y, GLsizei width, GLsizei height) -{ - const int squareSize= width * height; - const GLsizei arraySize= squareSize * 4; // 4 -> R G B A - QVector colorId(arraySize); - - // Get the array of pixels - glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, colorId.data()); - - // Restore Background color - glClearColor(m_BackgroundColor.redF(), m_BackgroundColor.greenF(), m_BackgroundColor.blueF(), 1.0f); - - QHash idHash; - QList idWeight; - - // Find the most meaningful color - GLC_uint returnId= 0; - // There is nothing at the center - int maxWeight= 0; - int currentIndex= 0; - for (int i= 0; i < squareSize; ++i) - { - GLC_uint id= glc::decodeRgbId(&colorId[i * 4]); - if (idHash.contains(id)) - { - const int currentWeight= ++(idWeight[idHash.value(id)]); - if (maxWeight < currentWeight) - { - returnId= id; - maxWeight= currentWeight; - } - } - else if (id != 0) - { - idHash.insert(id, currentIndex++); - idWeight.append(1); - if (maxWeight < 1) - { - returnId= id; - maxWeight= 1; - } - } - } - - return returnId; -} - -QSet GLC_Viewport::listOfIdInsideSquare(GLint x, GLint y, GLsizei width, GLsizei height) -{ - const int squareSize= width * height; - const GLsizei arraySize= squareSize * 4; // 4 -> R G B A - QVector colorId(arraySize); - - // Get the array of pixels - glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, colorId.data()); - - // Restore Background color - glClearColor(m_BackgroundColor.redF(), m_BackgroundColor.greenF(), m_BackgroundColor.blueF(), 1.0f); - - QSet idSet; - - // get the color inside square - for (int i= 0; i < squareSize; ++i) - { - GLC_uint id= glc::decodeRgbId(&colorId[i * 4]); - idSet << id; - } - - return idSet; -} - -void GLC_Viewport::updateMinimumRatioSize() -{ - int size= qMax(m_WindowHSize, m_WindowVSize); - m_MinimumStaticRatioSize= static_cast(m_MinimumStaticPixelSize) / static_cast(size) * 100.0; - m_MinimumDynamicRatioSize= m_MinimumStaticRatioSize * 2.0; - //qDebug() << "GLC_Viewport::updateMinimumRatioSize() m_MinimumRatioSize " << m_MinimumStaticRatioSize; -} - -void GLC_Viewport::loadBackGroundImage(const QString& ImageFile) -{ - delete m_pImagePlane; - m_pImagePlane= new GLC_ImagePlane(ImageFile); -} - -void GLC_Viewport::loadBackGroundImage(const QImage& image) -{ - delete m_pImagePlane; - m_pImagePlane= new GLC_ImagePlane(image); -} - -void GLC_Viewport::deleteBackGroundImage() -{ - delete m_pImagePlane; - m_pImagePlane= NULL; -} - -void GLC_Viewport::clearBackground(const QColor& color) const -{ - glClearColor(color.redF(), color.greenF(), color.blueF(), 1.0f); -} - -void GLC_Viewport::setToOrtho(bool useOrtho) -{ - if (m_UseParallelProjection != useOrtho) - { - m_UseParallelProjection= useOrtho; - updateProjectionMat(); - } - -} - -void GLC_Viewport::reframe(const GLC_BoundingBox& box) -{ - Q_ASSERT(!box.isEmpty()); - - // Center view on the BoundingBox - const GLC_Vector3d deltaVector(box.center() - m_pViewCam->target()); - m_pViewCam->translate(deltaVector); - - double cameraCover= box.boundingSphereRadius() * 2.2; - - // Compute Camera distance - const double distance = cameraCover / m_ViewTangent; - - // Update Camera position - m_pViewCam->setDistEyeTarget(distance); -} - -bool GLC_Viewport::setDistMin(double DistMin) -{ - DistMin= fabs(DistMin); - if (DistMin < m_DistanceMax) - { - m_dDistanceMini= DistMin; - - updateProjectionMat(); // Update OpenGL projection matrix - - return true; - } - else - { - qDebug("GLC_Viewport::SetDistMin : KO"); - return false; - } - -} - -bool GLC_Viewport::setDistMax(double DistMax) -{ - DistMax= fabs(DistMax); - if (DistMax > m_dDistanceMini) - { - m_DistanceMax= DistMax; - - // Update OpenGL projection matrix - updateProjectionMat(); - - return true; - } - else - { - qDebug("GLC_Viewport::SetDistMax : KO"); - return false; - } -} - -void GLC_Viewport::setDistMinAndMax(const GLC_BoundingBox& bBox) -{ - if(!bBox.isEmpty()) - { - // The scene is not empty - GLC_Matrix4x4 matComp(m_pViewCam->modelViewMatrix()); - - // The bounding Box in Camera coordinate - GLC_BoundingBox boundingBox(bBox); - boundingBox.transform(matComp); - - // Increase size of the bounding box - const double increaseFactor= 1.1; - // Convert box distance in sphere distance - const double center= fabs(boundingBox.center().z()); - const double radius= boundingBox.boundingSphereRadius(); - const double min= center - radius * increaseFactor; - const double max= center + radius * increaseFactor; - - GLC_Point3d camEye(m_pViewCam->eye()); - camEye= matComp * camEye; - - if (min > 0.0) - { - // Outside bounding Sphere - m_dDistanceMini= min; - m_DistanceMax= max; - //qDebug() << "distmin" << m_dCamDistMin; - //qDebug() << "distmax" << m_dCamDistMax; - } - else - { - // Inside bounding Sphere - m_dDistanceMini= qMin(0.01 * radius, m_pViewCam->distEyeTarget() / 4.0); - m_DistanceMax= max; - //qDebug() << "inside distmin" << m_dCamDistMin; - //qDebug() << "inside distmax" << m_dCamDistMax; - } - } - else - { - // The scene is empty - m_dDistanceMini= m_pViewCam->distEyeTarget() / 2.0; - m_DistanceMax= m_pViewCam->distEyeTarget(); - } - - // Update OpenGL projection matrix - updateProjectionMat(); -} - -void GLC_Viewport::setBackgroundColor(QColor setColor) -{ - m_BackgroundColor= setColor; - glClearColor(m_BackgroundColor.redF(), m_BackgroundColor.greenF(), m_BackgroundColor.blueF(), 1.0f); -} - -void GLC_Viewport::addClipPlane(GLenum planeGlEnum,GLC_Plane* pPlane) -{ - if (m_ClipPlanesHash.contains(planeGlEnum)) - { - delete m_ClipPlanesHash.value(planeGlEnum); - m_ClipPlanesHash.remove(planeGlEnum); - } - m_ClipPlanesHash.insert(planeGlEnum, pPlane); -} - -void GLC_Viewport::removeClipPlane(GLenum planeGlEnum) -{ - if (m_ClipPlanesHash.contains(planeGlEnum)) - { - delete m_ClipPlanesHash.value(planeGlEnum); - m_ClipPlanesHash.remove(planeGlEnum); - } - else - { - qDebug() << "GLC_Viewport::removeClipPlane Clipp plane " << planeGlEnum << " Not found"; - } -} - -void GLC_Viewport::removeAllClipPlane() -{ - // Delete clip planes - QHash::iterator iClip= m_ClipPlanesHash.begin(); - while (m_ClipPlanesHash.constEnd() != iClip) - { - delete iClip.value(); - ++iClip; - } -} - -void GLC_Viewport::useClipPlane(bool flag) -{ - m_UseClipPlane= flag; - if (m_UseClipPlane) - { - QHash::iterator iClip= m_ClipPlanesHash.begin(); - while (m_ClipPlanesHash.constEnd() != iClip) - { - GLenum planeKey= iClip.key(); - GLC_Plane* pPlane= iClip.value(); - - glClipPlane (planeKey, pPlane->data()); - glEnable (planeKey); - ++iClip; - } - } - else - { - QHash::iterator iClip= m_ClipPlanesHash.begin(); - while (m_ClipPlanesHash.constEnd() != iClip) - { - glDisable(iClip.key()); - ++iClip; - } - } - -} diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_viewport.h b/ground/gcs/src/libs/glc_lib/viewport/glc_viewport.h deleted file mode 100644 index 6e91bf9d4..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_viewport.h +++ /dev/null @@ -1,434 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -//! \file glc_viewport.h interface for the GLC_Viewport class. - -#ifndef GLC_VIEWPORT_H_ -#define GLC_VIEWPORT_H_ -#include -#include -#include -#include - -#include "glc_camera.h" -#include "glc_imageplane.h" -#include "../glc_boundingbox.h" -#include "glc_frustum.h" -#include "../maths/glc_plane.h" -#include "../sceneGraph/glc_3dviewcollection.h" - -#include "../glc_config.h" - -class GLC_3DViewInstance; - -////////////////////////////////////////////////////////////////////// -//! \class GLC_Viewport -/*! \brief GLC_Viewport : OpenGL Viewport */ - -/*! An GLC_Viewport define Viewport with these specification - * - Default GLC_Camera - * - Max distance of view - * - Min distance of view - * - Angle of view - * - Maximum zoom factor - */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_Viewport : public QObject -{ - Q_OBJECT - -////////////////////////////////////////////////////////////////////// -/*! @name Constructor / Destructor */ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Default constructor - /*! Construct Viewport with these specifications : - * - Default GLC_Camera - * - Max distance of view : 500 - * - Min distance of view : 0.01 - * - Angle of view : 35 - * - Maximum zoom factor : 3.0 - * */ - GLC_Viewport(); - - //! Delete Camera, Image Plane and orbit circle - virtual ~GLC_Viewport(); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the camera associate to this viewport - inline GLC_Camera* cameraHandle() const - {return m_pViewCam;} - - //! Get this viewport Horizontal size - inline int viewHSize() const - { return m_WindowHSize;} - - //! Get this viewport Vertical size - inline int viewVSize() const - { return m_WindowVSize;} - - //! Get this viewport ratio - inline double aspectRatio() const - { return static_cast(m_WindowHSize) / static_cast(m_WindowVSize);} - - //! Return the normalyse mouse position from screen coordinate - GLC_Point2d normalyseMousePosition(int x, int y); - - //! Map screen position to OpenGL screen position - GLC_Point2d mapToOpenGLScreen(int x, int y); - - //! Map normalyze screen position to OpenGL screen position - GLC_Point2d mapNormalyzeToOpenGLScreen(double x, double y); - - //! Map Screen position to OpenGL position (On image Plane) according to this viewport - GLC_Vector3d mapPosMouse( GLdouble Posx, GLdouble Posy) const; - - //! Map normalyse Screen position to OpenGL position (On image Plane) according to this viewport - GLC_Vector3d mapNormalyzePosMouse(double Posx, double Posy) const; - - //! Get this viewport's camera's angle of view - inline double viewAngle() const - { return m_ViewAngle;} - - //! Get this viewport's camera's tangent value of view - inline double viewTangent() const - { return m_ViewTangent;} - - - //! Get this viewport near clipping plane distance - inline double nearClippingPlaneDist(void) const - { return m_dDistanceMini;} - - //! Get this viewport far clipping plane distance - inline double farClippingPlaneDist(void) const - { return m_DistanceMax;} - - //! Get this viewportbackground Color - inline QColor backgroundColor(void) const - { return m_BackgroundColor;} - - //! Return the selection square size of this viewport - inline GLsizei selectionSquareSize() const - {return m_SelectionSquareSize;} - - //! Return this viewport's the projection matrix - inline GLC_Matrix4x4 projectionMatrix() const - {return m_ProjectionMatrix;} - - //! Return the composition matrix between projection matrix and view matrix - inline GLC_Matrix4x4 compositionMatrix() const; - - //! Return an handle to the widget 3D collection - inline GLC_3DViewCollection* widget3dCollectionHandle() - {return &m_3DWidgetCollection;} - - //! Return true if this viewport use orthographic projection - inline bool useOrtho()const - {return m_UseParallelProjection;} - - //! Return the minimum pixel culling size - inline int minimumPixelCullingSize() const - {return m_MinimumStaticPixelSize;} - - //! Return the minimum pixel culling ratio - inline double minimumStaticPixelCullingRatio() const - {return m_MinimumStaticRatioSize;} - - //! Return the minimum dynamic pixel culling ratio - inline double minimumDynamicPixelCullingRatio() const - {return m_MinimumDynamicRatioSize;} - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Initialize OpenGL with default values - /*! Glew initialisation is made here */ - void initGl(); - - //! Load camera's transformation Matrix and display image if necessary - void glExecuteCam(void); - - //! Update this viewport OpenGL projection matrix - void updateProjectionMat(void); - - //! Force the aspect ratio of this viewport - void forceAspectRatio(double); - - //! Update the aspect ratio of this viewport - void updateAspectRatio(); - - //! Return the frustum associated to this viewport - const GLC_Frustum& frustum() const - {return m_Frustum;} - - //! Return the frustum associated to a selection coordinate - GLC_Frustum selectionFrustum(int, int) const; - - //! Return the world 3d point from the given screen coordinate - GLC_Point3d unProject(int, int) const; - - //! Return the list af world 3d point form the givne list af screen coordinates - /*! The size of the given list must be a multiple of 2*/ - QList unproject(const QList&)const; - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name OpenGL Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -private: - - //! Render this viewport's image plane - void renderImagePlane(); - -public: - - //! Render viewport 3D widget - void render3DWidget(); - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - - //! Inform the viewport that the OpenGL window size has been modified - void setWinGLSize(int HSize, int VSize); - - //! Call the attached QGLWidgetSelect updateGL function and return the picking id - /*! Return UID of the nearest picked object */ - GLC_uint renderAndSelect(int x, int y); - - //! Return the picking id from the already render window - GLC_uint selectOnPreviousRender(int x, int y); - - //! Select a body inside a 3DViewInstance and return its UID - /*! Return UID of the nearest picked body */ - GLC_uint selectBody(GLC_3DViewInstance*, int x, int y); - - //! Select a primitive inside a 3DViewInstance and return its UID and its body index - /*! Return UID of the nearest picked primitive */ - QPair selectPrimitive(GLC_3DViewInstance*, int x, int y); - - //! Select objects inside specified square and return its UID in a set - QSet selectInsideSquare(int x1, int y1, int x2, int y2); - - //! load background image from file in this viewport - void loadBackGroundImage(const QString& imageFile); - - //! load background image in this viewport - void loadBackGroundImage(const QImage& image); - - //! delete background image of this viewport - void deleteBackGroundImage(); - - //! Set Camera's angle of view of this viewport - inline void setViewAngle(double TargetFov) - { - m_ViewAngle= TargetFov; - m_ViewTangent= tan(glc::toRadian(m_ViewAngle)); - updateProjectionMat(); - } - - //! Set near clipping distance of this viewport - bool setDistMin(double DistMin); - - //! Set far clipping distance of this viewport - bool setDistMax(double DistMax); - - //! Set Near and Far clipping distance of this viewport - /*! box shouldn't be empty*/ - void setDistMinAndMax(const GLC_BoundingBox& bBox); - - //! Set the Background color of this viewport - void setBackgroundColor(QColor setColor); - - //! Set the selection square size of this viewport - inline void setSelectionSquareSize(GLsizei size) - {m_SelectionSquareSize= size;} - - //! Update this viewport frustum (frustum cullin purpose) - /*! Return true if the frustum has changed*/ - inline bool updateFrustum(GLC_Matrix4x4* pMat= NULL); - - //! Add a clipping plane to this viewport - void addClipPlane(GLenum planeGlEnum, GLC_Plane* pPlane); - - //! Remove the clip plane coresponding to the given id - void removeClipPlane(GLenum planeGlEnum); - - //! Remove all clip plane - void removeAllClipPlane(); - - //! Set the clipping plane usage - void useClipPlane(bool flag); - - //! Add 3DWidget to this viewport - inline void add3DWidget(GLC_3DViewInstance& widget) - {m_3DWidgetCollection.add(widget);} - - //! Clear the background color with the specified color - void clearBackground(const QColor& color) const; - - //! Set othographic usage to the given flag - void setToOrtho(bool useOrtho); - - //! Set minimum pixel culling size - inline void setMinimumPixelCullingSize(int size) - { - m_MinimumStaticPixelSize= size; - updateMinimumRatioSize(); - } -//@} - - -///////////////////////////////////////////////////////////////////// -//! @name zoom Functions -//{@ - //! Set the viewport's camera in order to reframe on the current scene - /*! box shouldn't be empty*/ - void reframe(const GLC_BoundingBox& box); - -//@} End Zooming functions -///////////////////////////////////////////////////////////////////// - -///////////////////////////////////////////////////////////////////// -//! @name Signals -//{@ -signals: - //! Set the viewport's camera in order to reframe on the current scene - void updateOpenGL(); - -//@} End Signals -///////////////////////////////////////////////////////////////////// - - -////////////////////////////////////////////////////////////////////// -// private services functions -////////////////////////////////////////////////////////////////////// -private: - //! Return the meaningful color ID inside a square in screen coordinates - GLC_uint meaningfulIdInsideSquare(GLint x, GLint y, GLsizei width, GLsizei height); - - //! Return the Set of ID inside a square in screen coordinate - QSet listOfIdInsideSquare(GLint x, GLint y, GLsizei width, GLsizei height); - - //! Update minimum ratio size for pixel culling - void updateMinimumRatioSize(); - - -////////////////////////////////////////////////////////////////////// -// Private Members -////////////////////////////////////////////////////////////////////// -private: - - //! Viewport's camera - GLC_Camera *m_pViewCam; - - double m_DistanceMax; //!< Camera Maximum distance (far clipping plane) - double m_dDistanceMini; //!< Camera Minimum distance (near clipping plane) - double m_ViewAngle; //!< Camera angle of view - double m_ViewTangent; //!< Camera angle tangent - - - //! Image plane (Background image) - GLC_ImagePlane* m_pImagePlane; - - // OpenGL View Definition - int m_WindowHSize; //!< Horizontal OpenGL viewport size - int m_WindowVSize; //!< Vertical OpenGL viewport size - - //! View AspectRatio - double m_AspectRatio; - - //! Viewport Background color - QColor m_BackgroundColor; - - //! The selection square size - GLsizei m_SelectionSquareSize; - - //! The projection matrix - GLC_Matrix4x4 m_ProjectionMatrix; - - //! The frustum associated to the viewport - GLC_Frustum m_Frustum; - - //! The list of additionnal clipping plane - QHash m_ClipPlanesHash; - - //! Flag to know if clipping plane must be used - bool m_UseClipPlane; - - //! The collection wich contains 3D widget - GLC_3DViewCollection m_3DWidgetCollection; - - //! Flag to know if the viewport use orthographic projection - bool m_UseParallelProjection; - - //! The minimum static pixel culling size - int m_MinimumStaticPixelSize; - - //! The minimum static size ratio - double m_MinimumStaticRatioSize; - - //! The minimum dynamic size ratio - double m_MinimumDynamicRatioSize; -}; - -GLC_Matrix4x4 GLC_Viewport::compositionMatrix() const -{ - // Get the viewport projection matrix - GLC_Matrix4x4 projectionMatrix= m_ProjectionMatrix; - // Get the camera modelView matrix - GLC_Matrix4x4 modelViewMatrix= m_pViewCam->modelViewMatrix(); - // Composition matrix - GLC_Matrix4x4 compMatrix= projectionMatrix * modelViewMatrix; - - return compMatrix; -} - -bool GLC_Viewport::updateFrustum(GLC_Matrix4x4* pMat) -{ - if (NULL == pMat) - { - return m_Frustum.update(compositionMatrix()); - } - else - { - return m_Frustum.update(*pMat); - } -} -#endif //GLC_VIEWPORT_H_ diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_zoommover.cpp b/ground/gcs/src/libs/glc_lib/viewport/glc_zoommover.cpp deleted file mode 100644 index 0c288687a..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_zoommover.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -#include "glc_zoommover.h" -#include "glc_viewport.h" - -// Default constructor -GLC_ZoomMover::GLC_ZoomMover(GLC_Viewport* pViewport, const QList& repsList) -: GLC_Mover(pViewport, repsList) -, m_MaxZoomFactor(3.0) -{ - -} - -// Copy constructor -GLC_ZoomMover::GLC_ZoomMover(const GLC_ZoomMover& mover) -: GLC_Mover(mover) -, m_MaxZoomFactor(mover.m_MaxZoomFactor) -{ - -} - -GLC_ZoomMover::~GLC_ZoomMover() -{ - -} - - -////////////////////////////////////////////////////////////////////// -// Get Functions -////////////////////////////////////////////////////////////////////// - -// Return a clone of the mover -GLC_Mover* GLC_ZoomMover::clone() const -{ - return new GLC_ZoomMover(*this); -} - -////////////////////////////////////////////////////////////////////// -// Set Functions -////////////////////////////////////////////////////////////////////// - -// Initialized the mover -void GLC_ZoomMover::init(const GLC_UserInput& userInput) -{ - // Change origine (view center) and cover between -1 and 1 - const double vSize= static_cast(m_pViewport->viewVSize()); - m_PreviousVector.setY((vSize / 2.0 - userInput.y()) / ( vSize / 2.0)); -} - -// Move the camera -bool GLC_ZoomMover::move(const GLC_UserInput& userInput) -{ - // Change origine (View Center) and cover (from -1 to 1) - const double vSize= static_cast(m_pViewport->viewVSize()); - const double Posy= (vSize / 2.0 - userInput.y()) / ( vSize / 2.0); - - // Compute zoom factor between (1 / MAXZOOMFACTOR) and (MAXZOOMFACTOR) - double ZoomFactor= Posy - m_PreviousVector.y(); - - if (ZoomFactor > 0) - { - ZoomFactor= (m_MaxZoomFactor - 1.0) * ZoomFactor + 1.0; - } - else - { - ZoomFactor= 1.0 / ( (m_MaxZoomFactor - 1.0) * fabs(ZoomFactor) + 1.0 ); - } - - m_pViewport->cameraHandle()->zoom(ZoomFactor); - - m_PreviousVector.setY(Posy); - - return true; -} diff --git a/ground/gcs/src/libs/glc_lib/viewport/glc_zoommover.h b/ground/gcs/src/libs/glc_lib/viewport/glc_zoommover.h deleted file mode 100644 index 862e33267..000000000 --- a/ground/gcs/src/libs/glc_lib/viewport/glc_zoommover.h +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** - - This file is part of the GLC-lib library. - Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) - http://glc-lib.sourceforge.net - - GLC-lib is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - GLC-lib is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with GLC-lib; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - *****************************************************************************/ - -#ifndef GLC_ZOOMMOVER_H_ -#define GLC_ZOOMMOVER_H_ - -#include "glc_mover.h" - -#include "../glc_config.h" - -////////////////////////////////////////////////////////////////////// -//! \class GLC_ZoomMover -/*! \brief GLC_ZoomMover : Zoom interactive manipulation */ -////////////////////////////////////////////////////////////////////// -class GLC_LIB_EXPORT GLC_ZoomMover : public GLC_Mover -{ -public: - //! Default constructor - GLC_ZoomMover(GLC_Viewport*, const QList& repsList= QList()); - - //! Copy constructor - GLC_ZoomMover(const GLC_ZoomMover&); - - //! Destructor - virtual ~GLC_ZoomMover(); - - -////////////////////////////////////////////////////////////////////// -/*! \name Get Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Return the maximum zoom factor - inline double maxZoomFactor() const - {return m_MaxZoomFactor;} - - //! Return a clone of the mover - virtual GLC_Mover* clone() const; - -//@} - -////////////////////////////////////////////////////////////////////// -/*! \name Set Functions*/ -//@{ -////////////////////////////////////////////////////////////////////// -public: - //! Initialized the mover - virtual void init(const GLC_UserInput& userInput); - - //! Move the camera - virtual bool move(const GLC_UserInput& userInput); - - //! Set the maximum zoom factor - inline void setMaxZoomFactor(const double factor) - {m_MaxZoomFactor= factor;} - -//@} -////////////////////////////////////////////////////////////////////// -// private Members -////////////////////////////////////////////////////////////////////// -private: - //! The maximum zoom factor - double m_MaxZoomFactor; - -}; - -#endif /* GLC_ZOOMMOVER_H_ */ diff --git a/ground/gcs/src/libs/libs.pro b/ground/gcs/src/libs/libs.pro index ae82bc9db..e1b355cf2 100644 --- a/ground/gcs/src/libs/libs.pro +++ b/ground/gcs/src/libs/libs.pro @@ -7,12 +7,11 @@ SUBDIRS = \ qtconcurrent \ aggregation \ extensionsystem \ - glc_lib \ utils \ opmapcontrol \ qwt \ sdlgamepad -exists( $(OSG_SDK_DIR) ) { +osg { SUBDIRS += osgearth } diff --git a/ground/gcs/src/libs/opmapcontrol/src/core/opmaps.cpp b/ground/gcs/src/libs/opmapcontrol/src/core/opmaps.cpp index eeb4f5203..91a7843b9 100644 --- a/ground/gcs/src/libs/opmapcontrol/src/core/opmaps.cpp +++ b/ground/gcs/src/libs/opmapcontrol/src/core/opmaps.cpp @@ -37,16 +37,14 @@ OPMaps *OPMaps::Instance() } return m_pInstance; } + OPMaps::OPMaps() : RetryLoadTile(2), useMemoryCache(true) { accessmode = AccessMode::ServerAndCache; - // Need to figure out why this is *fixed* to Portugese. This casues pt-PT to be sent with every Google request - Language = LanguageType::PortuguesePortugal; - LanguageStr = LanguageType().toShortString(Language); + LanguageStr = QLocale().bcp47Name(); Cache::Instance(); } - OPMaps::~OPMaps() { TileDBcacheQueue.wait(); @@ -183,20 +181,26 @@ QByteArray OPMaps::GetImageFrom(const MapType::Types &type, const Point &pos, co default: break; } +#ifdef DEBUG_GMAPS qDebug() << "Timeout is " << Timeout; + qDebug() << "Get " << qheader.url(); +#endif // DEBUG_GMAPS reply = network.get(qheader); +#ifdef DEBUG_GMAPS qDebug() << "reply " << reply; +#endif // DEBUG_GMAPS QTime time; while ((!(reply->isFinished()) || (time.elapsed() > (6 * Timeout)))) { QCoreApplication::processEvents(QEventLoop::AllEvents); } +#ifdef DEBUG_GMAPS qDebug() << "Finished?" << reply->error() << " abort?" << (time.elapsed() > Timeout * 6); +#endif // DEBUG_GMAPS // If you are seeing Error 6 here you are dealing with a QT SSL Bug!!! - if ((reply->error() != QNetworkReply::NoError) | (time.elapsed() > Timeout * 6)) { - qDebug() << "reply error: " << reply->error() << " see table at - http://doc.qt.io/qt-5/qnetworkreply.html"; + qWarning() << "Reply error: " << reply->errorString() << qheader.url(); return ret; } ret = reply->readAll(); diff --git a/ground/gcs/src/libs/opmapcontrol/src/core/providerstrings.cpp b/ground/gcs/src/libs/opmapcontrol/src/core/providerstrings.cpp index c9c244292..73a357560 100644 --- a/ground/gcs/src/libs/opmapcontrol/src/core/providerstrings.cpp +++ b/ground/gcs/src/libs/opmapcontrol/src/core/providerstrings.cpp @@ -41,7 +41,8 @@ ProviderStrings::ProviderStrings() { // Google version strings VersionGoogleMap = "m@301"; - VersionGoogleSatellite = "184"; + QString version = qgetenv("GCS_GOOGLE_SAT_VERSION").constData(); + VersionGoogleSatellite = version.isEmpty() ? "694" : version; VersionGoogleLabels = "h@301"; VersionGoogleTerrain = "t@132,r@301"; SecGoogleWord = "Galileo"; diff --git a/ground/gcs/src/libs/opmapcontrol/src/core/tilecachequeue.cpp b/ground/gcs/src/libs/opmapcontrol/src/core/tilecachequeue.cpp index a47716517..465b59134 100644 --- a/ground/gcs/src/libs/opmapcontrol/src/core/tilecachequeue.cpp +++ b/ground/gcs/src/libs/opmapcontrol/src/core/tilecachequeue.cpp @@ -86,7 +86,9 @@ void TileCacheQueue::run() usleep(44); delete task; } else { +#ifdef DEBUG_TILECACHEQUEUE qDebug() << "Cache engine BEGIN WAIT"; +#endif // DEBUG_TILECACHEQUEUE waitmutex.lock(); int tout = 4000; if (!waitc.wait(&waitmutex, tout)) { @@ -101,7 +103,9 @@ void TileCacheQueue::run() } mutex.unlock(); } +#ifdef DEBUG_TILECACHEQUEUE qDebug() << "Cache Engine DID NOT TimeOut"; +#endif // DEBUG_TILECACHEQUEUE waitmutex.unlock(); } } diff --git a/ground/gcs/src/libs/opmapcontrol/src/core/urlfactory.cpp b/ground/gcs/src/libs/opmapcontrol/src/core/urlfactory.cpp index 4ae1a4889..aa6fa3487 100644 --- a/ground/gcs/src/libs/opmapcontrol/src/core/urlfactory.cpp +++ b/ground/gcs/src/libs/opmapcontrol/src/core/urlfactory.cpp @@ -372,19 +372,21 @@ QString UrlFactory::MakeImageUrl(const MapType::Types &type, const Point &pos, c { // http://wiki.openstreetmap.org/wiki/MapSurfer.NET -> Mapsurfernet.com -> dead // http://wiki.openstreetmap.org/wiki/OpenMapSurfer mentions: http://korona.geog.uni-heidelberg.de + // http://korona.geog.uni-heidelberg.de/contact.html - // Searched Google for tms_r.ashx and found korona.geog.uni-heidelberg.de has a service on port 8001 - // http://129.206.74.245:8001/tms_r.ashx?x=37378&y=20826&z=16 + // OSM Roads layer: http://korona.geog.uni-heidelberg.de/tiles/roads/x={x}&y={y}&z={z} + // or http://129.206.66.245:8001/tms_r.ashx?x={x}&y={y}&z={z} #ifdef DEBUG_URLFACTORY - qDebug() << QString("http://129.206.74.245:8001/tms_r.ashx?x=%1&y=%2&z=%3").arg(pos.X()).arg(pos.Y()).arg(zoom); + qDebug() << QString("http://korona.geog.uni-heidelberg.de/tiles/roads/x=%1&y=%2&z=%3").arg(pos.X()).arg(pos.Y()).arg(zoom); #endif - return QString("http://129.206.74.245:8001/tms_r.ashx?x=%1&y=%2&z=%3").arg(pos.X()).arg(pos.Y()).arg(zoom); + return QString("http://korona.geog.uni-heidelberg.de/tiles/roads/x=%1&y=%2&z=%3").arg(pos.X()).arg(pos.Y()).arg(zoom); } break; case MapType::OpenStreetMapSurferTerrain: { - // http://korona.geog.uni-heidelberg.de/tiles/asterh/x=501&y=388&z=10 + // ASTER GDEM & SRTM Hillshade layer: http://korona.geog.uni-heidelberg.de/tiles/asterh/ + // or http://129.206.66.245:8004/tms_hs.ashx?x={x}&y={y}&z={z} #ifdef DEBUG_URLFACTORY qDebug() << QString("http://korona.geog.uni-heidelberg.de/tiles/asterh/x=%1&y=%2&z=%3").arg(pos.X()).arg(pos.Y()).arg(zoom); diff --git a/ground/gcs/src/libs/opmapcontrol/src/internals/tile.cpp b/ground/gcs/src/libs/opmapcontrol/src/internals/tile.cpp index c07ca63b3..43da1d416 100644 --- a/ground/gcs/src/libs/opmapcontrol/src/internals/tile.cpp +++ b/ground/gcs/src/libs/opmapcontrol/src/internals/tile.cpp @@ -39,9 +39,6 @@ void Tile::Clear() qDebug() << "Tile:Clear Overlays"; #endif // DEBUG_TILE mutex.lock(); - foreach(QByteArray img, Overlays) { - img.~QByteArray(); - } Overlays.clear(); mutex.unlock(); } diff --git a/ground/gcs/src/libs/opmapcontrol/src/mapwidget/mapgraphicitem.h b/ground/gcs/src/libs/opmapcontrol/src/mapwidget/mapgraphicitem.h index 463800fb1..f14c43fbc 100644 --- a/ground/gcs/src/libs/opmapcontrol/src/mapwidget/mapgraphicitem.h +++ b/ground/gcs/src/libs/opmapcontrol/src/mapwidget/mapgraphicitem.h @@ -27,19 +27,18 @@ #ifndef MAPGRAPHICITEM_H #define MAPGRAPHICITEM_H -#include #include "../internals/core.h" -// #include "../internals/point.h" #include "../core/diagnostics.h" #include "configuration.h" +#include "waypointitem.h" + +#include #include #include #include #include #include #include -#include "waypointitem.h" -// #include "uavitem.h" namespace mapcontrol { class WayPointItem; diff --git a/ground/gcs/src/libs/opmapcontrol/src/mapwidget/opmapwidget.cpp b/ground/gcs/src/libs/opmapcontrol/src/mapwidget/opmapwidget.cpp index ee28e2501..f38632da4 100644 --- a/ground/gcs/src/libs/opmapcontrol/src/mapwidget/opmapwidget.cpp +++ b/ground/gcs/src/libs/opmapcontrol/src/mapwidget/opmapwidget.cpp @@ -26,9 +26,11 @@ */ #include "opmapwidget.h" +#include "waypointitem.h" + #include #include -#include "waypointitem.h" +#include namespace mapcontrol { OPMapWidget::OPMapWidget(QWidget *parent, Configuration *config) : QGraphicsView(parent), configuration(config), UAV(0), GPS(0), Home(0) @@ -210,7 +212,7 @@ void OPMapWidget::SetUseOpenGL(const bool &value) { useOpenGL = value; if (useOpenGL) { - setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); + setViewport(new QOpenGLWidget()); // QGLFormat(QGL::SampleBuffers))); } else { setupViewport(new QWidget()); } diff --git a/ground/gcs/src/libs/opmapcontrol/src/mapwidget/opmapwidget.h b/ground/gcs/src/libs/opmapcontrol/src/mapwidget/opmapwidget.h index 895baf452..4f7d9d7fc 100644 --- a/ground/gcs/src/libs/opmapcontrol/src/mapwidget/opmapwidget.h +++ b/ground/gcs/src/libs/opmapcontrol/src/mapwidget/opmapwidget.h @@ -33,11 +33,7 @@ #include "../core/languagetype.h" #include "../core/diagnostics.h" #include "configuration.h" -#include -#include #include "waypointitem.h" -#include "QtSvg/QGraphicsSvgItem" -#include "QGraphicsView" #include "uavitem.h" #include "gpsitem.h" #include "homeitem.h" @@ -45,6 +41,11 @@ #include "waypointline.h" #include "waypointcircle.h" #include "waypointitem.h" + +#include +#include "QtSvg/QGraphicsSvgItem" +#include "QGraphicsView" + namespace mapcontrol { class UAVItem; class GPSItem; diff --git a/ground/gcs/src/libs/osgearth/copydata.pro b/ground/gcs/src/libs/osgearth/copydata.pro index 85e77482c..2c7b10c8b 100644 --- a/ground/gcs/src/libs/osgearth/copydata.pro +++ b/ground/gcs/src/libs/osgearth/copydata.pro @@ -1,200 +1,255 @@ # # copy osg and osgearth libraries and data to build dir # -equals(copyosg, 1) { - OSG_VERSION = 3.4.0 - - linux { - # copy osg libraries - - data_copy.commands += $(MKDIR) $${GCS_LIBRARY_PATH}/osg $$addNewline() - exists( $${OSG_SDK_DIR}/lib64 ) { - data_copy.commands += $(COPY_DIR) $$shell_quote($$OSG_SDK_DIR/lib64/)* $$shell_quote($$GCS_LIBRARY_PATH/osg/) - } - else { - data_copy.commands += $(COPY_DIR) $$shell_quote($$OSG_SDK_DIR/lib/)* $$shell_quote($$GCS_LIBRARY_PATH/osg/) - } - - # add make target - POST_TARGETDEPS += copydata - - data_copy.target = copydata - QMAKE_EXTRA_TARGETS += data_copy - } - - macx { - - data_copy.commands += $(COPY_DIR) $$shell_quote($$OSG_SDK_DIR/lib/)* $$shell_quote($$GCS_LIBRARY_PATH/) - - # add make target - POST_TARGETDEPS += copydata - - data_copy.target = copydata - QMAKE_EXTRA_TARGETS += data_copy - } - - win32 { - # set debug suffix if needed - CONFIG(debug, debug|release):DS = "d" - - # copy osg libraries - OSG_LIBS = \ - libcurl-4.dll \ - libfreetype-6.dll \ - libgdal.dll \ - libgeos-3-3-8.dll \ - libgeos_c-1.dll \ - libjpeg-9.dll \ - libpng16-16.dll \ - libproj-0.dll \ - libtiff-5.dll \ - libtiffxx-5.dll \ - zlib1.dll \ - libOpenThreads$${DS}.dll \ - libosg$${DS}.dll \ - libosgAnimation$${DS}.dll \ - libosgDB$${DS}.dll \ - libosgEarth$${DS}.dll \ - libosgEarthAnnotation$${DS}.dll \ - libosgEarthFeatures$${DS}.dll \ - libosgEarthQt$${DS}.dll \ - libosgEarthSymbology$${DS}.dll \ - libosgEarthUtil$${DS}.dll \ - libosgFX$${DS}.dll \ - libosgGA$${DS}.dll \ - libosgManipulator$${DS}.dll \ - libosgParticle$${DS}.dll \ - libosgPresentation$${DS}.dll \ - libosgQt$${DS}.dll \ - libosgShadow$${DS}.dll \ - libosgSim$${DS}.dll \ - libosgTerrain$${DS}.dll \ - libosgText$${DS}.dll \ - libosgUtil$${DS}.dll \ - libosgViewer$${DS}.dll \ - libosgVolume$${DS}.dll \ - libosgWidget$${DS}.dll - for(lib, OSG_LIBS) { - addCopyFileTarget($${lib},$${OSG_SDK_DIR}/bin,$${GCS_APP_PATH}) - } - - OSG_PLUGINS = \ - mingw_osgdb_3dc$${DS}.dll \ - mingw_osgdb_3ds$${DS}.dll \ - mingw_osgdb_ac$${DS}.dll \ - mingw_osgdb_bmp$${DS}.dll \ - mingw_osgdb_bsp$${DS}.dll \ - mingw_osgdb_bvh$${DS}.dll \ - mingw_osgdb_cfg$${DS}.dll \ - mingw_osgdb_curl$${DS}.dll \ - mingw_osgdb_dds$${DS}.dll \ - mingw_osgdb_dot$${DS}.dll \ - mingw_osgdb_dw$${DS}.dll \ - mingw_osgdb_dxf$${DS}.dll \ - mingw_osgdb_earth$${DS}.dll \ - mingw_osgdb_gdal$${DS}.dll \ - mingw_osgdb_glsl$${DS}.dll \ - mingw_osgdb_gz$${DS}.dll \ - mingw_osgdb_hdr$${DS}.dll \ - mingw_osgdb_ive$${DS}.dll \ - mingw_osgdb_jpeg$${DS}.dll \ - mingw_osgdb_kml$${DS}.dll \ - mingw_osgdb_ktx$${DS}.dll \ - mingw_osgdb_logo$${DS}.dll \ - mingw_osgdb_lwo$${DS}.dll \ - mingw_osgdb_lws$${DS}.dll \ - mingw_osgdb_md2$${DS}.dll \ - mingw_osgdb_mdl$${DS}.dll \ - mingw_osgdb_normals$${DS}.dll \ - mingw_osgdb_obj$${DS}.dll \ - mingw_osgdb_ogr$${DS}.dll \ - mingw_osgdb_openflight$${DS}.dll \ - mingw_osgdb_osc$${DS}.dll \ - mingw_osgdb_osg$${DS}.dll \ - mingw_osgdb_osga$${DS}.dll \ - mingw_osgdb_osgearth_agglite$${DS}.dll \ - mingw_osgdb_osgearth_arcgis$${DS}.dll \ - mingw_osgdb_osgearth_arcgis_map_cache$${DS}.dll \ - mingw_osgdb_osgearth_bing$${DS}.dll \ - mingw_osgdb_osgearth_cache_filesystem$${DS}.dll \ - mingw_osgdb_osgearth_colorramp$${DS}.dll \ - mingw_osgdb_osgearth_debug$${DS}.dll \ - mingw_osgdb_osgearth_engine_byo$${DS}.dll \ - mingw_osgdb_osgearth_engine_mp$${DS}.dll \ - mingw_osgdb_osgearth_feature_ogr$${DS}.dll \ - mingw_osgdb_osgearth_feature_tfs$${DS}.dll \ - mingw_osgdb_osgearth_feature_wfs$${DS}.dll \ - mingw_osgdb_osgearth_gdal$${DS}.dll \ - mingw_osgdb_osgearth_label_annotation$${DS}.dll \ - mingw_osgdb_osgearth_mask_feature$${DS}.dll \ - mingw_osgdb_osgearth_model_feature_geom$${DS}.dll \ - mingw_osgdb_osgearth_model_feature_stencil$${DS}.dll \ - mingw_osgdb_osgearth_model_simple$${DS}.dll \ - mingw_osgdb_osgearth_noise$${DS}.dll \ - mingw_osgdb_osgearth_ocean_simple$${DS}.dll \ - mingw_osgdb_osgearth_osg$${DS}.dll \ - mingw_osgdb_osgearth_refresh$${DS}.dll \ - mingw_osgdb_osgearth_scriptengine_javascript$${DS}.dll \ - mingw_osgdb_osgearth_sky_gl$${DS}.dll \ - mingw_osgdb_osgearth_sky_simple$${DS}.dll \ - mingw_osgdb_osgearth_splat_mask$${DS}.dll \ - mingw_osgdb_osgearth_template_matclass$${DS}.dll \ - mingw_osgdb_osgearth_tilecache$${DS}.dll \ - mingw_osgdb_osgearth_tileindex$${DS}.dll \ - mingw_osgdb_osgearth_tileservice$${DS}.dll \ - mingw_osgdb_osgearth_tms$${DS}.dll \ - mingw_osgdb_osgearth_vdatum_egm2008$${DS}.dll \ - mingw_osgdb_osgearth_vdatum_egm84$${DS}.dll \ - mingw_osgdb_osgearth_vdatum_egm96$${DS}.dll \ - mingw_osgdb_osgearth_vpb$${DS}.dll \ - mingw_osgdb_osgearth_wcs$${DS}.dll \ - mingw_osgdb_osgearth_wms$${DS}.dll \ - mingw_osgdb_osgearth_xyz$${DS}.dll \ - mingw_osgdb_osgearth_yahoo$${DS}.dll \ - mingw_osgdb_osgshadow$${DS}.dll \ - mingw_osgdb_osgterrain$${DS}.dll \ - mingw_osgdb_osgtgz$${DS}.dll \ - mingw_osgdb_osgviewer$${DS}.dll \ - mingw_osgdb_p3d$${DS}.dll \ - mingw_osgdb_pic$${DS}.dll \ - mingw_osgdb_ply$${DS}.dll \ - mingw_osgdb_png$${DS}.dll \ - mingw_osgdb_pnm$${DS}.dll \ - mingw_osgdb_pov$${DS}.dll \ - mingw_osgdb_pvr$${DS}.dll \ - mingw_osgdb_revisions$${DS}.dll \ - mingw_osgdb_rgb$${DS}.dll \ - mingw_osgdb_rot$${DS}.dll \ - mingw_osgdb_scale$${DS}.dll \ - mingw_osgdb_serializers_osg$${DS}.dll \ - mingw_osgdb_serializers_osganimation$${DS}.dll \ - mingw_osgdb_serializers_osgfx$${DS}.dll \ - mingw_osgdb_serializers_osgga$${DS}.dll \ - mingw_osgdb_serializers_osgmanipulator$${DS}.dll \ - mingw_osgdb_serializers_osgparticle$${DS}.dll \ - mingw_osgdb_serializers_osgshadow$${DS}.dll \ - mingw_osgdb_serializers_osgsim$${DS}.dll \ - mingw_osgdb_serializers_osgterrain$${DS}.dll \ - mingw_osgdb_serializers_osgtext$${DS}.dll \ - mingw_osgdb_serializers_osgviewer$${DS}.dll \ - mingw_osgdb_serializers_osgvolume$${DS}.dll \ - mingw_osgdb_shp$${DS}.dll \ - mingw_osgdb_stl$${DS}.dll \ - mingw_osgdb_tga$${DS}.dll \ - mingw_osgdb_tgz$${DS}.dll \ - mingw_osgdb_tiff$${DS}.dll \ - mingw_osgdb_trans$${DS}.dll \ - mingw_osgdb_trk$${DS}.dll \ - mingw_osgdb_txf$${DS}.dll \ - mingw_osgdb_txp$${DS}.dll \ - mingw_osgdb_vtf$${DS}.dll \ - mingw_osgdb_x$${DS}.dll \ - mingw_osgdb_zip$${DS}.dll - # copy osg plugins - for(lib, OSG_PLUGINS) { - addCopyFileTarget($${lib},$${OSG_SDK_DIR}/bin/osgPlugins-$${OSG_VERSION},$${GCS_LIBRARY_PATH}/osg/osgPlugins-$${OSG_VERSION}) - } - } +OSG_VERSION = $$system(osgversion --version-number) +contains(QT_ARCH, x86_64) { + LIB_DIR_NAME = lib64 +} else { + LIB_DIR_NAME = lib +} + +# set debug suffix if needed +win32:CONFIG(debug, debug|release):DS = "d" + +osg:linux { + # copy osg libraries + data_copy.commands += $(MKDIR) $$GCS_LIBRARY_PATH/osg $$addNewline() + data_copy.commands += $(COPY_DIR) $$shell_quote($$OSG_SDK_DIR/$$LIB_DIR_NAME/)* $$shell_quote($$GCS_LIBRARY_PATH/osg/) $$addNewline() +} + +osgearth:linux { + # copy osgearth libraries + data_copy.commands += $(MKDIR) $$GCS_LIBRARY_PATH/osg $$addNewline() + data_copy.commands += $(COPY_DIR) $$shell_quote($$OSGEARTH_SDK_DIR/$$LIB_DIR_NAME/)* $$shell_quote($$GCS_LIBRARY_PATH/osg/) $$addNewline() +} + +osg:macx { + # copy osg libraries + data_copy.commands += $(COPY_DIR) $$shell_quote($$OSG_SDK_DIR/lib/)* $$shell_quote($$GCS_LIBRARY_PATH/) $$addNewline() +} + +osgearth:macx { + # copy osgearth libraries + data_copy.commands += $(COPY_DIR) $$shell_quote($$OSGEARTH_SDK_DIR/lib/)* $$shell_quote($$GCS_LIBRARY_PATH/) $$addNewline() +} + +linux|macx { + # add make target + POST_TARGETDEPS += copydata + + data_copy.target = copydata + QMAKE_EXTRA_TARGETS += data_copy +} + +osg:win32 { + # osg & osgearth dependencies + + # curl + OSG_LIBS = \ + libcurl-4.dll \ + libidn-11.dll \ + librtmp-1.dll \ + libgmp-10.dll \ + libgnutls-30.dll \ + libp11-kit-0.dll \ + libffi-6.dll \ + libtasn1-6.dll \ + libhogweed-4-2.dll \ + libnettle-6-2.dll \ + libssh2-1.dll \ + libnghttp2-14.dll + + # other + OSG_LIBS += \ + libjpeg-8.dll \ + libfreetype-6.dll \ + libpng16-16.dll \ + libiconv-2.dll \ + zlib1.dll + + # osg libraries + OSG_LIBS += \ + libOpenThreads$${DS}.dll \ + libosg$${DS}.dll \ + libosgAnimation$${DS}.dll \ + libosgDB$${DS}.dll \ + libosgFX$${DS}.dll \ + libosgGA$${DS}.dll \ + libosgManipulator$${DS}.dll \ + libosgParticle$${DS}.dll \ + libosgPresentation$${DS}.dll \ + libosgShadow$${DS}.dll \ + libosgSim$${DS}.dll \ + libosgTerrain$${DS}.dll \ + libosgText$${DS}.dll \ + libosgUtil$${DS}.dll \ + libosgViewer$${DS}.dll \ + libosgVolume$${DS}.dll \ + libosgWidget$${DS}.dll + + osgQt:OSG_LIBS += \ + libosgQt$${DS}.dll + + for(lib, OSG_LIBS) { + addCopyFileTarget($${lib},$${OSG_SDK_DIR}/bin,$${GCS_APP_PATH}) + } + + # osg plugins + OSG_PLUGINS = \ + mingw_osgdb_3ds$${DS}.dll \ + mingw_osgdb_freetype$${DS}.dll \ + mingw_osgdb_jpeg$${DS}.dll \ + mingw_osgdb_osg$${DS}.dll \ + mingw_osgdb_png$${DS}.dll \ + mingw_osgdb_tiff$${DS}.dll \ + mingw_osgdb_zip$${DS}.dll \ + mingw_osgdb_serializers_osg$${DS}.dll + + osg_extra:OSG_PLUGINS = \ + mingw_osgdb_3dc$${DS}.dll \ + mingw_osgdb_ac$${DS}.dll \ + mingw_osgdb_bmp$${DS}.dll \ + mingw_osgdb_bsp$${DS}.dll \ + mingw_osgdb_bvh$${DS}.dll \ + mingw_osgdb_cfg$${DS}.dll \ + mingw_osgdb_curl$${DS}.dll \ + mingw_osgdb_dds$${DS}.dll \ + mingw_osgdb_dot$${DS}.dll \ + mingw_osgdb_dw$${DS}.dll \ + mingw_osgdb_dxf$${DS}.dll \ + mingw_osgdb_gdal$${DS}.dll \ + mingw_osgdb_glsl$${DS}.dll \ + mingw_osgdb_gz$${DS}.dll \ + mingw_osgdb_hdr$${DS}.dll \ + mingw_osgdb_ive$${DS}.dll \ + mingw_osgdb_ktx$${DS}.dll \ + mingw_osgdb_logo$${DS}.dll \ + mingw_osgdb_lwo$${DS}.dll \ + mingw_osgdb_lws$${DS}.dll \ + mingw_osgdb_md2$${DS}.dll \ + mingw_osgdb_mdl$${DS}.dll \ + mingw_osgdb_normals$${DS}.dll \ + mingw_osgdb_obj$${DS}.dll \ + mingw_osgdb_ogr$${DS}.dll \ + mingw_osgdb_openflight$${DS}.dll \ + mingw_osgdb_osc$${DS}.dll \ + mingw_osgdb_osga$${DS}.dll \ + mingw_osgdb_osgshadow$${DS}.dll \ + mingw_osgdb_osgterrain$${DS}.dll \ + mingw_osgdb_osgtgz$${DS}.dll \ + mingw_osgdb_osgviewer$${DS}.dll \ + mingw_osgdb_p3d$${DS}.dll \ + mingw_osgdb_pic$${DS}.dll \ + mingw_osgdb_ply$${DS}.dll \ + mingw_osgdb_pnm$${DS}.dll \ + mingw_osgdb_pov$${DS}.dll \ + mingw_osgdb_pvr$${DS}.dll \ + mingw_osgdb_revisions$${DS}.dll \ + mingw_osgdb_rgb$${DS}.dll \ + mingw_osgdb_rot$${DS}.dll \ + mingw_osgdb_scale$${DS}.dll \ + mingw_osgdb_shp$${DS}.dll \ + mingw_osgdb_stl$${DS}.dll \ + mingw_osgdb_tga$${DS}.dll \ + mingw_osgdb_tgz$${DS}.dll \ + mingw_osgdb_trans$${DS}.dll \ + mingw_osgdb_trk$${DS}.dll \ + mingw_osgdb_txf$${DS}.dll \ + mingw_osgdb_txp$${DS}.dll \ + mingw_osgdb_vtf$${DS}.dll \ + mingw_osgdb_x$${DS}.dll \ + mingw_osgdb_serializers_osganimation$${DS}.dll \ + mingw_osgdb_serializers_osgfx$${DS}.dll \ + mingw_osgdb_serializers_osgga$${DS}.dll \ + mingw_osgdb_serializers_osgmanipulator$${DS}.dll \ + mingw_osgdb_serializers_osgparticle$${DS}.dll \ + mingw_osgdb_serializers_osgshadow$${DS}.dll \ + mingw_osgdb_serializers_osgsim$${DS}.dll \ + mingw_osgdb_serializers_osgterrain$${DS}.dll \ + mingw_osgdb_serializers_osgtext$${DS}.dll \ + mingw_osgdb_serializers_osgviewer$${DS}.dll \ + mingw_osgdb_serializers_osgvolume$${DS}.dll + + for(lib, OSG_PLUGINS) { + addCopyFileTarget($${lib},$${OSG_SDK_DIR}/bin/osgPlugins-$${OSG_VERSION},$${GCS_LIBRARY_PATH}/osg/osgPlugins-$${OSG_VERSION}) + } +} + +osgearth:win32 { + # osgearth libraries + OSGEARTH_LIBS = \ + libosgEarth$${DS}.dll \ + libosgEarthAnnotation$${DS}.dll \ + libosgEarthFeatures$${DS}.dll \ + libosgEarthSymbology$${DS}.dll \ + libosgEarthUtil$${DS}.dll + + # gdal + OSGEARTH_LIBS += \ + libgdal-20.dll \ + libgeos_c.dll \ + libgeos.dll \ + libopenjp2-7.dll \ + libtiff-5.dll \ + liblzma-5.dll + + osgearthQt:OSGEARTH_LIBS += \ + libosgEarthQt$${DS}.dll + + for(lib, OSGEARTH_LIBS) { + addCopyFileTarget($${lib},$${OSGEARTH_SDK_DIR}/bin,$${GCS_APP_PATH}) + } + + # osgearth plugins + OSGEARTH_PLUGINS += \ + mingw_osgdb_earth$${DS}.dll \ + mingw_osgdb_osgearth_arcgis$${DS}.dll \ + mingw_osgdb_osgearth_engine_mp$${DS}.dll \ + mingw_osgdb_osgearth_sky_simple$${DS}.dll \ + mingw_osgdb_osgearth_tms$${DS}.dll \ + mingw_osgdb_osgearth_xyz$${DS}.dll \ + mingw_osgdb_osgearth_cache_filesystem$${DS}.dll + + osgearth_extra:OSGEARTH_PLUGINS += \ + mingw_osgdb_kml$${DS}.dll \ + mingw_osgdb_osgearth_agglite$${DS}.dll \ + mingw_osgdb_osgearth_arcgis_map_cache$${DS}.dll \ + mingw_osgdb_osgearth_bing$${DS}.dll \ + mingw_osgdb_osgearth_colorramp$${DS}.dll \ + mingw_osgdb_osgearth_debug$${DS}.dll \ + mingw_osgdb_osgearth_engine_byo$${DS}.dll \ + mingw_osgdb_osgearth_feature_ogr$${DS}.dll \ + mingw_osgdb_osgearth_feature_tfs$${DS}.dll \ + mingw_osgdb_osgearth_feature_wfs$${DS}.dll \ + mingw_osgdb_osgearth_gdal$${DS}.dll \ + mingw_osgdb_osgearth_label_annotation$${DS}.dll \ + mingw_osgdb_osgearth_mask_feature$${DS}.dll \ + mingw_osgdb_osgearth_model_feature_geom$${DS}.dll \ + mingw_osgdb_osgearth_model_feature_stencil$${DS}.dll \ + mingw_osgdb_osgearth_model_simple$${DS}.dll \ + mingw_osgdb_osgearth_noise$${DS}.dll \ + mingw_osgdb_osgearth_ocean_simple$${DS}.dll \ + mingw_osgdb_osgearth_osg$${DS}.dll \ + mingw_osgdb_osgearth_refresh$${DS}.dll \ + mingw_osgdb_osgearth_scriptengine_javascript$${DS}.dll \ + mingw_osgdb_osgearth_sky_gl$${DS}.dll \ + mingw_osgdb_osgearth_splat_mask$${DS}.dll \ + mingw_osgdb_osgearth_template_matclass$${DS}.dll \ + mingw_osgdb_osgearth_tilecache$${DS}.dll \ + mingw_osgdb_osgearth_tileindex$${DS}.dll \ + mingw_osgdb_osgearth_tileservice$${DS}.dll \ + mingw_osgdb_osgearth_vdatum_egm2008$${DS}.dll \ + mingw_osgdb_osgearth_vdatum_egm84$${DS}.dll \ + mingw_osgdb_osgearth_vdatum_egm96$${DS}.dll \ + mingw_osgdb_osgearth_vpb$${DS}.dll \ + mingw_osgdb_osgearth_wcs$${DS}.dll \ + mingw_osgdb_osgearth_wms$${DS}.dll \ + mingw_osgdb_osgearth_xyz$${DS}.dll \ + mingw_osgdb_osgearth_yahoo$${DS}.dll + + for(lib, OSGEARTH_PLUGINS) { + addCopyFileTarget($${lib},$${OSGEARTH_SDK_DIR}/bin/osgPlugins-$${OSG_VERSION},$${GCS_LIBRARY_PATH}/osg/osgPlugins-$${OSG_VERSION}) + } } diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/DirtySupport.cpp b/ground/gcs/src/libs/osgearth/osgQtQuick/DirtySupport.cpp new file mode 100644 index 000000000..c5d488159 --- /dev/null +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/DirtySupport.cpp @@ -0,0 +1,148 @@ +/** + ****************************************************************************** + * + * @file DirtySupport.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "DirtySupport.hpp" + +#include +#include + +#include + +namespace osgQtQuick { +class Hidden; + +struct DirtySupport::NodeUpdateCallback : public osg::NodeCallback { +public: + NodeUpdateCallback(DirtySupport::Hidden *h) : h(h) + {} + + void operator()(osg::Node *node, osg::NodeVisitor *nv); + +private: + DirtySupport::Hidden *const h; +}; + +struct DirtySupport::Hidden { +private: + DirtySupport *const self; + + osg::ref_ptr nodeUpdateCallback; + + int dirtyFlags; + +public: + Hidden(DirtySupport *self) : self(self), dirtyFlags(0) + {} + + bool isDirty(int mask) const + { + return (dirtyFlags & mask) != 0; + } + + int dirty() const + { + return dirtyFlags; + } + + void setDirty(int mask) + { + // qDebug() << "DirtySupport::setDirty" << mask; + if (!dirtyFlags) { + osg::Node *node = self->nodeToUpdate(); + if (node) { + if (!nodeUpdateCallback.valid()) { + // lazy creation + nodeUpdateCallback = new NodeUpdateCallback(this); + } + node->addUpdateCallback(nodeUpdateCallback.get()); + } else { + // qWarning() << "DirtySupport::setDirty - node to update is null"; + } + } + dirtyFlags |= mask; + } + + void clearDirty() + { + osg::Node *node = self->nodeToUpdate(); + + if (node && nodeUpdateCallback.valid()) { + node->removeUpdateCallback(nodeUpdateCallback.get()); + } + dirtyFlags = 0; + } + + void update() + { + // qDebug() << "DirtySupport::update"; + if (dirtyFlags) { + // qDebug() << "DirtySupport::update - updating..."; + self->update(); + } + clearDirty(); + } +}; + +/* struct DirtySupport::NodeUpdateCallback */ + +void DirtySupport::NodeUpdateCallback::operator()(osg::Node *node, osg::NodeVisitor *nv) +{ + // qDebug() << "DirtySupport::NodeUpdateCallback"; + nv->traverse(*node); + h->update(); +} + +/* class DirtySupport */ + +DirtySupport::DirtySupport() : h(new Hidden(this)) +{} + +DirtySupport::~DirtySupport() +{ + delete h; +} + +int DirtySupport::dirty() const +{ + return h->dirty(); +} + +bool DirtySupport::isDirty(int mask) const +{ + return h->isDirty(mask); +} + +void DirtySupport::setDirty(int mask) +{ + h->setDirty(mask); +} + +void DirtySupport::clearDirty() +{ + h->clearDirty(); +} +} // namespace osgQtQuick diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/DirtySupport.hpp b/ground/gcs/src/libs/osgearth/osgQtQuick/DirtySupport.hpp new file mode 100644 index 000000000..f802fc8c6 --- /dev/null +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/DirtySupport.hpp @@ -0,0 +1,63 @@ +/** + ****************************************************************************** + * + * @file DirtySupport.hpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _H_OSGQTQUICK_DIRTYSUPPORT_H_ +#define _H_OSGQTQUICK_DIRTYSUPPORT_H_ + +namespace osg { +class Node; +} // namespace osg + +namespace osgQtQuick { +/** + * Provides support to: + * - manage dirty state flags + * - add/remove node callback to trigger refresh (compatible with viewer on demand mode) + */ +class DirtySupport { +public: + explicit DirtySupport(); + virtual ~DirtySupport(); + +protected: + int dirty() const; + bool isDirty(int mask = 0xFFFF) const; + void setDirty(int mask = 0xFFFF); + void clearDirty(); + +private: + struct Hidden; + struct NodeUpdateCallback; + Hidden *const h; + + virtual osg::Node *nodeToUpdate() const = 0; + + virtual void update() = 0; +}; +} // namespace osgQtQuick + +#endif // _H_OSGQTQUICK_DIRTYSUPPORT_H_ diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/Export.hpp b/ground/gcs/src/libs/osgearth/osgQtQuick/Export.hpp index e7499efc0..779eea607 100644 --- a/ground/gcs/src/libs/osgearth/osgQtQuick/Export.hpp +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/Export.hpp @@ -2,7 +2,7 @@ ****************************************************************************** * * @file Export.hpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * @addtogroup * @{ * @addtogroup diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGBackgroundNode.cpp b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGBackgroundNode.cpp deleted file mode 100644 index 0d624b9d6..000000000 --- a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGBackgroundNode.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/** - ****************************************************************************** - * - * @file OSGBackgroundNode.cpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. - * @addtogroup - * @{ - * @addtogroup - * @{ - * @brief - *****************************************************************************/ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "OSGBackgroundNode.hpp" - -#include -#include -#include - -#include -#include - -namespace osgQtQuick { -struct OSGBackgroundNode::Hidden : public QObject { - Q_OBJECT - -public: - Hidden(OSGBackgroundNode *parent) : QObject(parent), self(parent), url() {} - - bool acceptImageFile(QUrl url) - { - // qDebug() << "OSGBackgroundNode::acceptImageFile" << url; - if (this->url == url) { - return false; - } - - this->url = url; - - realize(); - - return true; - } - - void realize() - { - qDebug() << "OSGBackgroundNode::realize"; - - // qDebug() << "OSGBackgroundNode::realize - reading image file" << h->url.path(); - osg::ref_ptr texture = new osg::Texture2D; - osg::ref_ptr image = osgDB::readImageFile(url.path().toStdString()); - texture->setImage(image.get()); - - osg::ref_ptr quad = osg::createTexturedQuadGeometry( - osg::Vec3(), osg::Vec3(1.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 1.0f, 0.0f)); - quad->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture.get()); - - osg::ref_ptr geode = new osg::Geode; - geode->addDrawable(quad.get()); - - osg::Camera *camera = new osg::Camera; - camera->setClearMask(0); - camera->setCullingActive(false); - camera->setAllowEventFocus(false); - camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); - camera->setRenderOrder(osg::Camera::POST_RENDER); - camera->setProjectionMatrix(osg::Matrix::ortho2D(0.0, 1.0, 0.0, 1.0)); - camera->addChild(geode.get()); - - osg::StateSet *ss = camera->getOrCreateStateSet(); - ss->setMode(GL_LIGHTING, osg::StateAttribute::OFF); - ss->setAttributeAndModes(new osg::Depth(osg::Depth::LEQUAL, 1.0, 1.0)); - - self->setNode(camera); - } - - OSGBackgroundNode *const self; - - QUrl url; -}; - -OSGBackgroundNode::OSGBackgroundNode(QObject *parent) : OSGNode(parent), h(new Hidden(this)) -{ - // qDebug() << "OSGBackgroundNode::OSGBackgroundNode"; -} - -OSGBackgroundNode::~OSGBackgroundNode() -{ - // qDebug() << "OSGBackgroundNode::~OSGBackgroundNode"; -} - -const QUrl OSGBackgroundNode::imageFile() const -{ - return h->url; -} - -void OSGBackgroundNode::setImageFile(const QUrl &url) -{ - // qDebug() << "OSGBackgroundNode::setImageFile" << url; - if (h->acceptImageFile(url)) { - emit imageFileChanged(imageFile()); - } -} -} // namespace osgQtQuick - -#include "OSGBackgroundNode.moc" diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGBillboardNode.cpp b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGBillboardNode.cpp new file mode 100644 index 000000000..f5a27efba --- /dev/null +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGBillboardNode.cpp @@ -0,0 +1,94 @@ +/** + ****************************************************************************** + * + * @file OSGBillboardNode.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "OSGBillboardNode.hpp" + +#include +#include +#include + +#include + +#include + +namespace osgQtQuick { +// NOTE : these flags should not overlap with OSGGroup flags!!! +// TODO : find a better way... +enum DirtyFlag {}; + +struct OSGBillboardNode::Hidden : public QObject { + Q_OBJECT + +private: + OSGBillboardNode * const self; + + osg::ref_ptr camera; + +public: + Hidden(OSGBillboardNode *self) : QObject(self), self(self) + {} + + osg::Node *createNode() + { + camera = new osg::Camera; + camera->setClearMask(0); + camera->setCullingActive(false); + camera->setAllowEventFocus(false); + camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); + camera->setRenderOrder(osg::Camera::POST_RENDER); + camera->setProjectionMatrix(osg::Matrix::ortho2D(0.0, 1.0, 0.0, 1.0)); + + osg::StateSet *ss = camera->getOrCreateStateSet(); + ss->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + ss->setAttributeAndModes(new osg::Depth(osg::Depth::LEQUAL, 1.0, 1.0)); + + return camera; + } +}; + +/* class OSGBillboardNode */ + +OSGBillboardNode::OSGBillboardNode(QObject *parent) : Inherited(parent), h(new Hidden(this)) +{} + +OSGBillboardNode::~OSGBillboardNode() +{ + delete h; +} + +osg::Node *OSGBillboardNode::createNode() +{ + return h->createNode(); +} + +void OSGBillboardNode::updateNode() +{ + Inherited::updateNode(); +} +} // namespace osgQtQuick + +#include "OSGBillboardNode.moc" diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGCubeNode.hpp b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGBillboardNode.hpp similarity index 70% rename from ground/gcs/src/libs/osgearth/osgQtQuick/OSGCubeNode.hpp rename to ground/gcs/src/libs/osgearth/osgQtQuick/OSGBillboardNode.hpp index 0ea0aab66..b2edda15c 100644 --- a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGCubeNode.hpp +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGBillboardNode.hpp @@ -1,8 +1,8 @@ /** ****************************************************************************** * - * @file OSGCubeNode.hpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @file OSGBillboardNode.hpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * @addtogroup * @{ * @addtogroup @@ -25,24 +25,30 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _H_OSGQTQUICK_CUBENODE_H_ -#define _H_OSGQTQUICK_CUBENODE_H_ +#ifndef _H_OSGQTQUICK_BILLBOARDNODE_H_ +#define _H_OSGQTQUICK_BILLBOARDNODE_H_ #include "Export.hpp" -#include "OSGNode.hpp" +#include "OSGGroup.hpp" namespace osgQtQuick { -class OSGQTQUICK_EXPORT OSGCubeNode : public OSGNode { +class OSGQTQUICK_EXPORT OSGBillboardNode : public OSGGroup { Q_OBJECT + typedef OSGGroup Inherited; + public: - OSGCubeNode(QObject *parent = 0); - virtual ~OSGCubeNode(); + OSGBillboardNode(QObject *parent = 0); + virtual ~OSGBillboardNode(); + +protected: + virtual osg::Node *createNode(); + virtual void updateNode(); private: struct Hidden; - Hidden *h; + Hidden *const h; }; } // namespace osgQtQuick -#endif // _H_OSGQTQUICK_CUBENODE_H_ +#endif // _H_OSGQTQUICK_BILLBOARDNODE_H_ diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGCamera.cpp b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGCamera.cpp index b0d566aae..0db64ce40 100644 --- a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGCamera.cpp +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGCamera.cpp @@ -2,7 +2,7 @@ ****************************************************************************** * * @file OSGCamera.cpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * @addtogroup * @{ * @addtogroup @@ -27,450 +27,189 @@ #include "OSGCamera.hpp" -#include "OSGNode.hpp" - -#include "../utility.h" - #include -#include #include -#include -#include -#include - -#include - -#include -#include -#include +#ifdef USE_OSGEARTH #include +#endif #include -#include -#include namespace osgQtQuick { +enum DirtyFlag { FieldOfView = 1 << 0, ClearColor = 1 << 1, LogDepthBuffer = 1 << 4 }; + struct OSGCamera::Hidden : public QObject { Q_OBJECT - struct CameraUpdateCallback : public osg::NodeCallback { -public: - CameraUpdateCallback(Hidden *h) : h(h) {} +private: + OSGCamera * const self; - void operator()(osg::Node *node, osg::NodeVisitor *nv); - - mutable Hidden *h; - }; - friend class CameraUpdateCallback; + osg::ref_ptr camera; public: + // Camera vertical field of view in degrees + // fov depends on the scenery space (probably distance) + // here are some value: 75°, 60°, 45° many gamers use + // x-plane uses 45° for 4:3 and 60° for 16:9/16:10 + // flightgear uses 55° / 70° + qreal fieldOfView; - Hidden(OSGCamera *parent) : - QObject(parent), sceneData(NULL), manipulatorMode(Default), node(NULL), - trackerMode(NodeCenterAndAzim), trackNode(NULL), - logDepthBufferEnabled(false), logDepthBuffer(NULL), clampToTerrain(false) + QColor clearColor; + + bool logDepthBufferEnabled; + +#ifdef USE_OSGEARTH + osgEarth::Util::LogarithmicDepthBuffer *logDepthBuffer; +#endif + +public: + Hidden(OSGCamera *self) : QObject(self), self(self), fieldOfView(90), clearColor(0, 0, 0, 255), logDepthBufferEnabled(false) { - fieldOfView = 90.0; - - first = true; - - dirty = false; - - sizeDirty = false; - x = 0; - y = 0; - width = 0; - height = 0; +#ifdef USE_OSGEARTH + logDepthBuffer = NULL; +#endif } ~Hidden() { - if (logDepthBuffer) { - delete logDepthBuffer; - logDepthBuffer = NULL; - } - } - - bool acceptSceneData(OSGNode *node) - { - qDebug() << "OSGCamera::acceptSceneData" << node; - if (sceneData == node) { - return true; - } - - if (sceneData) { - disconnect(sceneData); - } - - sceneData = node; - - if (sceneData) { - // connect(sceneData, &OSGNode::nodeChanged, this, &Hidden::onSceneDataChanged); - } - - return true; - } - - bool acceptManipulatorMode(ManipulatorMode mode) - { - // qDebug() << "OSGCamera::acceptManipulatorMode" << mode; - if (manipulatorMode == mode) { - return false; - } - - manipulatorMode = mode; - - return true; - } - - bool acceptNode(OSGNode *node) - { - qDebug() << "OSGCamera::acceptNode" << node; - if (this->node == node) { - return false; - } - - if (this->node) { - disconnect(this->node); - } - - this->node = node; - - if (this->node) { - connect(this->node, SIGNAL(nodeChanged(osg::Node *)), this, SLOT(onNodeChanged(osg::Node *))); - } - - return true; - } - - bool acceptTrackNode(OSGNode *node) - { - qDebug() << "OSGCamera::acceptTrackNode" << node; - if (trackNode == node) { - return false; - } - - if (trackNode) { - disconnect(trackNode); - } - - trackNode = node; - - if (trackNode) { - connect(trackNode, SIGNAL(nodeChanged(osg::Node *)), this, SLOT(onTrackNodeChanged(osg::Node *))); - } - - return true; - } - - bool attach(osgViewer::View *view) - { - attachCamera(view->getCamera()); - attachManipulator(view); - return true; - } - - bool detach(osgViewer::View *view) - { - detachManipulator(view); - detachCamera(view->getCamera()); - return true; - } - - void attachCamera(osg::Camera *camera) - { - qDebug() << "OSGCamera::attach" << camera; - - this->camera = camera; - - cameraUpdateCallback = new CameraUpdateCallback(this); - camera->addUpdateCallback(cameraUpdateCallback); - - // install log depth buffer if requested - if (logDepthBufferEnabled) { - qDebug() << "OSGCamera::attach - install logarithmic depth buffer"; - logDepthBuffer = new osgEarth::Util::LogarithmicDepthBuffer(); - // logDepthBuffer->setUseFragDepth(true); - logDepthBuffer->install(camera); - } - - dirty = true; - sizeDirty = true; - updateCamera(); - } - - void detachCamera(osg::Camera *camera) - { - qDebug() << "OSGCamera::detach" << camera; - - if (camera != this->camera) { - qWarning() << "OSGCamera::detach - camera not attached" << camera; - return; - } - this->camera = NULL; - - if (cameraUpdateCallback.valid()) { - camera->removeUpdateCallback(cameraUpdateCallback); - cameraUpdateCallback = NULL; - } - +#ifdef USE_OSGEARTH if (logDepthBuffer) { logDepthBuffer->uninstall(camera); delete logDepthBuffer; logDepthBuffer = NULL; } - - // reset viewport - x = y = width = height = 0; +#endif } - void attachManipulator(osgViewer::View *view) + osg::Node *createNode() { - qDebug() << "OSGCamera::attachManipulator" << view; + camera = new osg::Camera(); - osgGA::CameraManipulator *cm = NULL; + camera->setClearColor(osg::Vec4(clearColor.redF(), clearColor.greenF(), clearColor.blueF(), clearColor.alphaF())); - switch (manipulatorMode) { - case OSGCamera::Default: - { - qDebug() << "OSGCamera::attachManipulator - use TrackballManipulator"; - osgGA::TrackballManipulator *tm = new osgGA::TrackballManipulator(); - // Set the minimum distance of the eye point from the center before the center is pushed forward. - // tm->setMinimumDistance(1, true); - cm = tm; - break; - } - case OSGCamera::User: - qDebug() << "OSGCamera::attachManipulator - no camera manipulator"; - // disable any installed camera manipulator - cm = NULL; - break; - case OSGCamera::Earth: - { - qDebug() << "OSGCamera::attachManipulator - use EarthManipulator"; - osgEarth::Util::EarthManipulator *em = new osgEarth::Util::EarthManipulator(); - em->getSettings()->setThrowingEnabled(true); - cm = em; - break; - } - case OSGCamera::Track: - qDebug() << "OSGCamera::attachManipulator - use NodeTrackerManipulator"; - if (trackNode && trackNode->node()) { - // setup tracking camera - // TODO when camera is thrown, then changing attitude has jitter (could be due to different frequency between refresh and animation) - // TODO who takes ownership? - osgGA::NodeTrackerManipulator *ntm = new osgGA::NodeTrackerManipulator( - /*osgGA::StandardManipulator::COMPUTE_HOME_USING_BBOX | osgGA::StandardManipulator::DEFAULT_SETTINGS*/); - switch (trackerMode) { - case NodeCenter: - ntm->setTrackerMode(osgGA::NodeTrackerManipulator::NODE_CENTER); - break; - case NodeCenterAndAzim: - ntm->setTrackerMode(osgGA::NodeTrackerManipulator::NODE_CENTER_AND_AZIM); - break; - case NodeCenterAndRotation: - ntm->setTrackerMode(osgGA::NodeTrackerManipulator::NODE_CENTER_AND_ROTATION); - break; - } - ntm->setTrackNode(trackNode->node()); - // ntm->setRotationMode(trackRotationMode) - // ntm->setMinimumDistance(2, false); - ntm->setVerticalAxisFixed(false); - // ntm->setAutoComputeHomePosition(true); - // ntm->setDistance(100); - cm = ntm; - } else { - qWarning() << "OSGCamera::attachManipulator - no track node provided."; - cm = NULL; - } - break; - default: - qWarning() << "OSGCamera::attachManipulator - should not reach here!"; - break; - } + osg::StateSet *stateset = camera->getOrCreateStateSet(); + stateset->setGlobalDefaults(); - view->setCameraManipulator(cm, false); - if (cm && node && node->node()) { - qDebug() << "OSGCamera::attachManipulator - camera node" << node; - // set node used to auto compute home position - // needs to be done after setting the manipulator on the view as the view will set its scene as the node - cm->setNode(node->node()); - } - if (cm) { - view->home(); - } + return camera; } - void detachManipulator(osgViewer::View *view) + void updateClearColor() { - qDebug() << "OSGCamera::detachManipulator" << view; - - view->setCameraManipulator(NULL, false); - } - - void updateCamera() - { - if (first) { - first = false; - updateCameraFOV(); - } - updateCameraSize(); - if (manipulatorMode == User) { - updateCameraPosition(); - } - } - - void updateCameraSize() - { - if (!sizeDirty || !camera.valid()) { + if (!camera.valid()) { + qWarning() << "OSGCamera::updateClearColor - invalid camera"; return; } - sizeDirty = false; - - // qDebug() << "OSGCamera::updateCamera size" << x << y << width << height << fieldOfView; - camera->getGraphicsContext()->resized(x, y, width, height); - camera->setViewport(x, y, width, height); - updateAspectRatio(); + // qDebug() << "OSGCamera::updateClearColor" << clearColor; + camera->setClearColor(osg::Vec4(clearColor.redF(), clearColor.greenF(), clearColor.blueF(), clearColor.alphaF())); } - void updateCameraFOV() + void updateFieldOfView() { - // qDebug() << "OSGCamera::updateCameraFOV"; + if (!camera.valid()) { + qWarning() << "OSGCamera::updateFieldOfView - invalid camera"; + return; + } + + // qDebug() << "OSGCamera::updateFieldOfView" << fieldOfView; + double fovy, ar, zn, zf; - camera->getProjectionMatrixAsPerspective(fovy, ar, zn, zf); - fovy = fieldOfView; camera->setProjectionMatrixAsPerspective(fovy, ar, zn, zf); } void updateAspectRatio() { + if (!camera.valid()) { + qWarning() << "OSGCamera::updateAspectRatio - invalid camera"; + return; + } + osg::Viewport *viewport = camera->getViewport(); + if (!viewport) { + qWarning() << "OSGCamera::updateAspectRatio - no viewport" << viewport; + return; + } + + double aspectRatio = static_cast(viewport->width()) / static_cast(viewport->height()); + + // qDebug() << "OSGCamera::updateAspectRatio" << aspectRatio; + double fovy, ar, zn, zf; - camera->getProjectionMatrixAsPerspective(fovy, ar, zn, zf); - - ar = static_cast(width) / static_cast(height); + ar = aspectRatio; camera->setProjectionMatrixAsPerspective(fovy, ar, zn, zf); } - void updateCameraPosition() + void updateLogDepthBuffer() { - if (!dirty || !camera.valid()) { + if (!camera.valid()) { + qWarning() << "OSGCamera::updateLogDepthBuffer - invalid camera"; return; } - dirty = false; + // qDebug() << "OSGCamera::updateLogDepthBuffer" << logDepthBufferEnabled; - // Altitude mode is absolute (absolute height above MSL/HAE) - // HAE : Height above ellipsoid. This is the default. - // MSL : Height above Mean Sea Level (MSL) if a geoid separation value is specified. - // TODO handle the case where the terrain SRS is not "wgs84" - // TODO check if position is not below terrain? - // TODO compensate antenna height when source of position is GPS (i.e. subtract antenna height from altitude) ;) +#ifdef USE_OSGEARTH + // install log depth buffer if requested + if (logDepthBufferEnabled && !logDepthBuffer) { + // qDebug() << "OSGCamera::updateLogDepthBuffer - installing logarithmic depth buffer"; + logDepthBuffer = new osgEarth::Util::LogarithmicDepthBuffer(); + logDepthBuffer->setUseFragDepth(true); + logDepthBuffer->install(camera); + } else if (!logDepthBufferEnabled && logDepthBuffer) { + // qDebug() << "OSGCamera::updateLogDepthBuffer - uninstalling logarithmic depth buffer"; + logDepthBuffer->uninstall(camera); + delete logDepthBuffer; + logDepthBuffer = NULL; + } +#endif + } - // Camera position - osgEarth::GeoPoint geoPoint = osgQtQuick::toGeoPoint(position); - if (clampToTerrain) { - if (sceneData) { - osgEarth::MapNode *mapNode = osgEarth::MapNode::findMapNode(sceneData->node()); - if (mapNode) { - intoTerrain = clampGeoPoint(geoPoint, 0.5f, mapNode); - } else { - qWarning() << "OSGCamera::updateNode - scene data does not contain a map node"; - } - } + void setGraphicsContext(osg::GraphicsContext *gc) + { + if (!camera.valid()) { + qWarning() << "OSGCamera::setGraphicsContext - invalid camera"; + return; } - osg::Matrix cameraPosition; - geoPoint.createLocalToWorld(cameraPosition); + // qDebug() << "OSGCamera::setGraphicsContext" << gc; - // Camera orientation - // By default the camera looks toward -Z, we must rotate it so it looks toward Y - osg::Matrix cameraRotation; - cameraRotation.makeRotate(osg::DegreesToRadians(90.0), osg::Vec3(1.0, 0.0, 0.0), - osg::DegreesToRadians(0.0), osg::Vec3(0.0, 1.0, 0.0), - osg::DegreesToRadians(0.0), osg::Vec3(0.0, 0.0, 1.0)); + camera->setGraphicsContext(gc); + camera->setViewport(0, 0, gc->getTraits()->width, gc->getTraits()->height); - // Final camera matrix - osg::Matrix cameraMatrix = cameraRotation - * osg::Matrix::rotate(osg::DegreesToRadians(attitude.x()), osg::Vec3(1.0, 0.0, 0.0)) - * osg::Matrix::rotate(osg::DegreesToRadians(attitude.y()), osg::Vec3(0.0, 1.0, 0.0)) - * osg::Matrix::rotate(osg::DegreesToRadians(attitude.z()), osg::Vec3(0.0, 0.0, 1.0)) * cameraPosition; + double aspectRatio = static_cast(gc->getTraits()->width) / static_cast(gc->getTraits()->height); - // Inverse the camera's position and orientation matrix to obtain the view matrix - cameraMatrix = osg::Matrix::inverse(cameraMatrix); - camera->setViewMatrix(cameraMatrix); - } + camera->setProjectionMatrixAsPerspective(fieldOfView, aspectRatio, 1.0f, 10000.0f); - qreal fieldOfView; + double fovy, ar, zn, zf; + camera->getProjectionMatrixAsPerspective(fovy, ar, zn, zf); - OSGNode *sceneData; - - ManipulatorMode manipulatorMode; - - // to compute home position - OSGNode *node; - - // for NodeTrackerManipulator - TrackerMode trackerMode; - OSGNode *trackNode; - - bool logDepthBufferEnabled; - osgEarth::Util::LogarithmicDepthBuffer *logDepthBuffer; - - bool first; - - // for User manipulator - bool dirty; - - bool clampToTerrain; - bool intoTerrain; - - QVector3D attitude; - QVector3D position; - - bool sizeDirty; - int x; - int y; - int width; - int height; - - osg::ref_ptr camera; - osg::ref_ptr cameraUpdateCallback; - -private slots: - void onNodeChanged(osg::Node *node) - { - qDebug() << "OSGCamera::onNodeChanged" << node; - qWarning() << "OSGCamera::onNodeChanged - needs to be implemented"; - } - - void onTrackNodeChanged(osg::Node *node) - { - qDebug() << "OSGCamera::onTrackNodeChanged" << node; - qWarning() << "OSGCamera::onTrackNodeChanged - needs to be implemented"; + // FIXME this is needed for PFD + Terrain (because of "user" mode) + // updatePosition(); } }; -/* struct Hidden::CameraUpdateCallback */ - -void OSGCamera::Hidden::CameraUpdateCallback::operator()(osg::Node *node, osg::NodeVisitor *nv) -{ - h->updateCamera(); - // traverse(node, nv); -} - /* class OSGCamera */ -OSGCamera::OSGCamera(QObject *parent) : QObject(parent), h(new Hidden(this)) -{ - qDebug() << "OSGCamera::OSGCamera"; -} +OSGCamera::OSGCamera(QObject *parent) : Inherited(parent), h(new Hidden(this)) +{} OSGCamera::~OSGCamera() { - qDebug() << "OSGCamera::~OSGCamera"; + delete h; +} + +QColor OSGCamera::clearColor() const +{ + return h->clearColor; +} + +void OSGCamera::setClearColor(const QColor &color) +{ + if (h->clearColor != color) { + h->clearColor = color; + emit clearColorChanged(color); + } } qreal OSGCamera::fieldOfView() const @@ -478,135 +217,16 @@ qreal OSGCamera::fieldOfView() const return h->fieldOfView; } -// ! Camera vertical field of view in degrees void OSGCamera::setFieldOfView(qreal arg) { if (h->fieldOfView != arg) { h->fieldOfView = arg; - h->sizeDirty = true; + setDirty(FieldOfView); emit fieldOfViewChanged(fieldOfView()); - - // it should be a queued call to OSGCameraRenderer instead - /*if (h->viewer.get()) { - h->viewer->getCamera()->setProjectionMatrixAsPerspective( - h->fieldOfView, - qreal(h->currentSize.width())/h->currentSize.height(), - 1.0f, 10000.0f); - }*/ - - // updateFrame(); } } -OSGNode *OSGCamera::sceneData() -{ - return h->sceneData; -} - -void OSGCamera::setSceneData(OSGNode *node) -{ - if (h->acceptSceneData(node)) { - emit sceneDataChanged(node); - } -} - -OSGCamera::ManipulatorMode OSGCamera::manipulatorMode() const -{ - return h->manipulatorMode; -} - -void OSGCamera::setManipulatorMode(ManipulatorMode mode) -{ - if (h->acceptManipulatorMode(mode)) { - emit manipulatorModeChanged(manipulatorMode()); - } -} - -OSGNode *OSGCamera::node() const -{ - return h->node; -} - -void OSGCamera::setNode(OSGNode *node) -{ - if (h->acceptNode(node)) { - emit nodeChanged(node); - } -} - -OSGNode *OSGCamera::trackNode() const -{ - return h->trackNode; -} - -void OSGCamera::setTrackNode(OSGNode *node) -{ - if (h->acceptTrackNode(node)) { - emit trackNodeChanged(node); - } -} - -OSGCamera::TrackerMode OSGCamera::trackerMode() const -{ - return h->trackerMode; -} - -void OSGCamera::setTrackerMode(TrackerMode mode) -{ - if (h->trackerMode != mode) { - h->trackerMode = mode; - emit trackerModeChanged(trackerMode()); - } -} - -bool OSGCamera::clampToTerrain() const -{ - return h->clampToTerrain; -} - -void OSGCamera::setClampToTerrain(bool arg) -{ - if (h->clampToTerrain != arg) { - h->clampToTerrain = arg; - h->dirty = true; - emit clampToTerrainChanged(clampToTerrain()); - } -} - -bool OSGCamera::intoTerrain() const -{ - return h->intoTerrain; -} - -QVector3D OSGCamera::attitude() const -{ - return h->attitude; -} - -void OSGCamera::setAttitude(QVector3D arg) -{ - if (h->attitude != arg) { - h->attitude = arg; - h->dirty = true; - emit attitudeChanged(attitude()); - } -} - -QVector3D OSGCamera::position() const -{ - return h->position; -} - -void OSGCamera::setPosition(QVector3D arg) -{ - if (h->position != arg) { - h->position = arg; - h->dirty = true; - emit positionChanged(position()); - } -} - -bool OSGCamera::logarithmicDepthBuffer() +bool OSGCamera::logarithmicDepthBuffer() const { return h->logDepthBufferEnabled; } @@ -615,35 +235,40 @@ void OSGCamera::setLogarithmicDepthBuffer(bool enabled) { if (h->logDepthBufferEnabled != enabled) { h->logDepthBufferEnabled = enabled; + setDirty(LogDepthBuffer); emit logarithmicDepthBufferChanged(logarithmicDepthBuffer()); } } -void OSGCamera::setViewport(int x, int y, int width, int height) +osg::Node *OSGCamera::createNode() { - // qDebug() << "OSGCamera::setViewport" << x << y << width << "x" << heigth; - if (width <= 0 || height <= 0) { - qWarning() << "OSGCamera::setViewport - invalid size" << width << "x" << height; - return; + return h->createNode(); +} + +void OSGCamera::updateNode() +{ + Inherited::updateNode(); + + if (isDirty(ClearColor)) { + h->updateClearColor(); } - if (h->x != x || h->y != y || h->width != width || h->height != height) { - qWarning() << "OSGCamera::setViewport" << width << "x" << height; - h->x = x; - h->y = y; - h->width = width; - h->height = height; - h->sizeDirty = true; + if (isDirty(FieldOfView)) { + h->updateFieldOfView(); + } + if (isDirty(LogDepthBuffer)) { + h->updateLogDepthBuffer(); } } -bool OSGCamera::attach(osgViewer::View *view) +osg::Camera *OSGCamera::asCamera() const { - return h->attach(view); + // BAD introduce templating + return (osg::Camera *)node(); } -bool OSGCamera::detach(osgViewer::View *view) +void OSGCamera::setGraphicsContext(osg::GraphicsContext *gc) { - return h->detach(view); + h->setGraphicsContext(gc); } } // namespace osgQtQuick diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGCamera.hpp b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGCamera.hpp index 6b40f153d..812c5b897 100644 --- a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGCamera.hpp +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGCamera.hpp @@ -2,7 +2,7 @@ ****************************************************************************** * * @file OSGCamera.hpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * @addtogroup * @{ * @addtogroup @@ -29,122 +29,54 @@ #define _H_OSGQTQUICK_OSGCAMERA_H_ #include "Export.hpp" +#include "OSGNode.hpp" #include -#include +#include -namespace osgViewer { -class View; +namespace osg { +class Camera; +class GraphicsContext; } namespace osgQtQuick { -class OSGNode; - -// This class does too much: -// - tracking a geo point and attitude -// - tracking another node -// camera should be simpler and provide only tracking -// - tracking of a modelnode (for ModelView) -// - tracking of a virtual node (for PFD with Terrain) -// -// TODO -// - expose track mode -// - provide good default distance and attitude for tracker camera -class OSGQTQUICK_EXPORT OSGCamera : public QObject { - Q_OBJECT Q_PROPERTY(qreal fieldOfView READ fieldOfView WRITE setFieldOfView NOTIFY fieldOfViewChanged) - - Q_PROPERTY(osgQtQuick::OSGNode * sceneData READ sceneData WRITE setSceneData NOTIFY sceneDataChanged) - - Q_PROPERTY(ManipulatorMode manipulatorMode READ manipulatorMode WRITE setManipulatorMode NOTIFY manipulatorModeChanged) - - Q_PROPERTY(osgQtQuick::OSGNode * node READ node WRITE setNode NOTIFY nodeChanged) - - Q_PROPERTY(osgQtQuick::OSGNode * trackNode READ trackNode WRITE setTrackNode NOTIFY trackNodeChanged) - Q_PROPERTY(TrackerMode trackerMode READ trackerMode WRITE setTrackerMode NOTIFY trackerModeChanged) - - Q_PROPERTY(bool clampToTerrain READ clampToTerrain WRITE setClampToTerrain NOTIFY clampToTerrainChanged) - Q_PROPERTY(bool intoTerrain READ intoTerrain NOTIFY intoTerrainChanged) - - Q_PROPERTY(QVector3D attitude READ attitude WRITE setAttitude NOTIFY attitudeChanged) - Q_PROPERTY(QVector3D position READ position WRITE setPosition NOTIFY positionChanged) - +class OSGQTQUICK_EXPORT OSGCamera : public OSGNode { + Q_OBJECT Q_PROPERTY(QColor clearColor READ clearColor WRITE setClearColor NOTIFY clearColorChanged) + Q_PROPERTY(qreal fieldOfView READ fieldOfView WRITE setFieldOfView NOTIFY fieldOfViewChanged) Q_PROPERTY(bool logarithmicDepthBuffer READ logarithmicDepthBuffer WRITE setLogarithmicDepthBuffer NOTIFY logarithmicDepthBufferChanged) - Q_ENUMS(ManipulatorMode) - Q_ENUMS(TrackerMode) + typedef OSGNode Inherited; + + friend class OSGViewport; public: - enum ManipulatorMode { Default, Earth, Track, User }; - - enum TrackerMode { NodeCenter, NodeCenterAndAzim, NodeCenterAndRotation }; - explicit OSGCamera(QObject *parent = 0); virtual ~OSGCamera(); - // fov depends on the scenery space (probaby distance) - // here are some value: 75°, 60°, 45° many gamers use - // x-plane uses 45° for 4:3 and 60° for 16:9/16:10 - // flightgear uses 55° / 70° + QColor clearColor() const; + void setClearColor(const QColor &color); + qreal fieldOfView() const; void setFieldOfView(qreal arg); - OSGNode *sceneData(); - void setSceneData(OSGNode *node); - - ManipulatorMode manipulatorMode() const; - void setManipulatorMode(ManipulatorMode); - - OSGNode *node() const; - void setNode(OSGNode *node); - - OSGNode *trackNode() const; - void setTrackNode(OSGNode *node); - - TrackerMode trackerMode() const; - void setTrackerMode(TrackerMode); - - bool clampToTerrain() const; - void setClampToTerrain(bool arg); - - bool intoTerrain() const; - - QVector3D attitude() const; - void setAttitude(QVector3D arg); - - QVector3D position() const; - void setPosition(QVector3D arg); - - bool logarithmicDepthBuffer(); + bool logarithmicDepthBuffer() const; void setLogarithmicDepthBuffer(bool enabled); - void setViewport(int x, int y, int width, int height); - - virtual bool attach(osgViewer::View *view); - virtual bool detach(osgViewer::View *view); - signals: + void clearColorChanged(const QColor &color); void fieldOfViewChanged(qreal arg); - - void sceneDataChanged(OSGNode *node); - - void manipulatorModeChanged(ManipulatorMode); - - void nodeChanged(OSGNode *node); - - void trackNodeChanged(OSGNode *node); - void trackerModeChanged(TrackerMode); - - void clampToTerrainChanged(bool arg); - void intoTerrainChanged(bool arg); - - void attitudeChanged(QVector3D arg); - void positionChanged(QVector3D arg); - void logarithmicDepthBufferChanged(bool enabled); +protected: + virtual osg::Node *createNode(); + virtual void updateNode(); + private: struct Hidden; - Hidden *h; + Hidden *const h; + + osg::Camera *asCamera() const; + void setGraphicsContext(osg::GraphicsContext *gc); }; } // namespace osgQtQuick diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGCubeNode.cpp b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGCubeNode.cpp deleted file mode 100644 index 99d1cb079..000000000 --- a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGCubeNode.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/** - ****************************************************************************** - * - * @file OSGCubeNode.cpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. - * @addtogroup - * @{ - * @addtogroup - * @{ - * @brief - *****************************************************************************/ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "OSGCubeNode.hpp" - -#include -#include -#include -#include - -#include - -namespace osgQtQuick { -struct OSGCubeNode::Hidden : public QObject { - Q_OBJECT - -public: - Hidden(OSGCubeNode *parent) : QObject(parent), self(parent) {} - - void realize() - { - qDebug() << "OSGCubeNode::realize"; - - // Declare a group to act as root node of a scene: - // osg::Group* root = new osg::Group(); - - // Declare a box class (derived from shape class) instance - // This constructor takes an osg::Vec3 to define the center - // and a float to define the height, width and depth. - // (an overloaded constructor allows you to specify unique - // height, width and height values.) - osg::Box *unitCube = new osg::Box(osg::Vec3(0, 0, 0), 1.0f); - - // Declare an instance of the shape drawable class and initialize - // it with the unitCube shape we created above. - // This class is derived from 'drawable' so instances of this - // class can be added to Geode instances. - osg::ShapeDrawable *unitCubeDrawable = new osg::ShapeDrawable(unitCube); - - // Declare a instance of the geode class: - osg::Geode *basicShapesGeode = new osg::Geode(); - - // Add the unit cube drawable to the geode: - basicShapesGeode->addDrawable(unitCubeDrawable); - - // Add the geode to the scene: - self->setNode(basicShapesGeode); - } - - OSGCubeNode *self; -}; - -// TODO turn into generic shape node... -// see http://trac.openscenegraph.org/projects/osg//wiki/Support/Tutorials/TransformsAndStates -OSGCubeNode::OSGCubeNode(QObject *parent) : OSGNode(parent), h(new Hidden(this)) -{ - qDebug() << "OSGCubeNode::OSGCubeNode"; - h->realize(); -} - -OSGCubeNode::~OSGCubeNode() -{ - qDebug() << "OSGCubeNode::~OSGCubeNode"; -} -} // namespace osgQtQuick - -#include "OSGCubeNode.moc" diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGFileNode.cpp b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGFileNode.cpp index 5e1d5ab5d..136954697 100644 --- a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGFileNode.cpp +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGFileNode.cpp @@ -2,7 +2,7 @@ ****************************************************************************** * * @file OSGFileNode.cpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * @addtogroup * @{ * @addtogroup @@ -37,28 +37,34 @@ #include namespace osgQtQuick { +enum DirtyFlag { Source = 1 << 0, Async = 1 << 1, OptimizeMode = 1 << 2 }; + class OSGFileLoader : public QThread { Q_OBJECT public: - OSGFileLoader(const QUrl &url) : url(url) {} + OSGFileLoader(const QUrl &url) : url(url) + {} void run() { - load(); + osg::Node *node = load(); + emit loaded(url, node); } - void load() + osg::Node *load() { QElapsedTimer t; t.start(); - qDebug() << "OSGFileLoader::load - reading node file" << url.path(); + // qDebug() << "OSGFileLoader::load - reading node file" << url.path(); // qDebug() << "OSGFileLoader - load - currentContext" << QOpenGLContext::currentContext(); osg::Node *node = osgDB::readNodeFile(url.path().toStdString()); + if (!node) { + qWarning() << "OSGFileLoader::load - failed to load" << url.path(); + } // qDebug() << "OSGFileLoader::load - reading node" << node << "took" << t.elapsed() << "ms"; - - emit loaded(url, node); + return node; } signals: @@ -75,33 +81,38 @@ private: OSGFileNode * const self; public: - Hidden(OSGFileNode *parent) : QObject(parent), self(parent), url(), async(false), optimizeMode(None) {} + QUrl source; + bool async; + OptimizeMode::Enum optimizeMode; - bool acceptSource(QUrl url) + Hidden(OSGFileNode *self) : QObject(self), self(self), source(), async(false), optimizeMode(OptimizeMode::None) + {} + + void updateSource() { - // qDebug() << "OSGFileNode::acceptSource" << url; - - if (this->url == url) { - return false; - } - - this->url = url; - - if (url.isValid()) { - realize(); - } else { - qWarning() << "OSGFileNode::acceptNode - invalid url" << url; + // qDebug() << "OSGFileNode::updateNode" << source; + if (!source.isValid()) { self->setNode(NULL); + if (!source.isEmpty()) { + qWarning() << "OSGFileNode::updateNode - invalid source" << source; + } + } + if (false /*async*/) { + // not supported yet + // it is not clear if thread safety is insured... + asyncLoad(source); + } else { + setNode(syncLoad(source)); } - - return true; } - QUrl url; - bool async; - OptimizeMode optimizeMode; - private: + osg::Node *syncLoad(const QUrl &url) + { + OSGFileLoader loader(url); + + return loader.load(); + } void asyncLoad(const QUrl &url) { @@ -112,63 +123,48 @@ private: loader->start(); } - void syncLoad(const QUrl &url) + void setNode(osg::Node *node) { - OSGFileLoader loader(url); - - connect(&loader, &OSGFileLoader::loaded, this, &Hidden::onLoaded); - loader.load(); - } - - void realize() - { - qDebug() << "OSGFileNode::realize"; - if (async) { - asyncLoad(url); - } else { - syncLoad(url); - } - } - - bool acceptNode(osg::Node *node) - { - qDebug() << "OSGFileNode::acceptNode" << node; - if (node && optimizeMode != OSGFileNode::None) { + // qDebug() << "OSGFileNode::setNode" << node; + if (node && optimizeMode != OptimizeMode::None) { // qDebug() << "OSGFileNode::acceptNode - optimize" << node << optimizeMode; osgUtil::Optimizer optimizer; optimizer.optimize(node, osgUtil::Optimizer::DEFAULT_OPTIMIZATIONS); } self->setNode(node); - return true; } private slots: void onLoaded(const QUrl &url, osg::Node *node) { - acceptNode(node); + // called in async mode + // question : is it thread safe to call setNode() ? + // could calling setDirty help? is setDirty() thread safe ? + setNode(node); } }; -OSGFileNode::OSGFileNode(QObject *parent) : OSGNode(parent), h(new Hidden(this)) -{ - qDebug() << "OSGFileNode::OSGFileNode"; -} +/* class OSGFileNode */ + +OSGFileNode::OSGFileNode(QObject *parent) : Inherited(parent), h(new Hidden(this)) +{} OSGFileNode::~OSGFileNode() { - qDebug() << "OSGFileNode::~OSGFileNode"; + delete h; } const QUrl OSGFileNode::source() const { - return h->url; + return h->source; } -void OSGFileNode::setSource(const QUrl &url) +void OSGFileNode::setSource(const QUrl &source) { - qDebug() << "OSGFileNode::setSource" << url; - if (h->acceptSource(url)) { - emit sourceChanged(source()); + if (h->source != source) { + h->source = source; + setDirty(Source); + emit sourceChanged(source); } } @@ -179,24 +175,45 @@ bool OSGFileNode::async() const void OSGFileNode::setAsync(const bool async) { - // qDebug() << "OSGFileNode::setAsync" << async; if (h->async != async) { h->async = async; + setDirty(Async); emit asyncChanged(async); } } -OSGFileNode::OptimizeMode OSGFileNode::optimizeMode() const +OptimizeMode::Enum OSGFileNode::optimizeMode() const { return h->optimizeMode; } -void OSGFileNode::setOptimizeMode(OptimizeMode mode) +void OSGFileNode::setOptimizeMode(OptimizeMode::Enum optimizeMode) { - // qDebug() << "OSGFileNode::setOptimizeMode" << mode; - if (h->optimizeMode != mode) { - h->optimizeMode = mode; - emit optimizeModeChanged(optimizeMode()); + if (h->optimizeMode != optimizeMode) { + h->optimizeMode = optimizeMode; + setDirty(OptimizeMode); + emit optimizeModeChanged(optimizeMode); + } +} + +osg::Node *OSGFileNode::createNode() +{ + // node is created later + return NULL; +} + +void OSGFileNode::updateNode() +{ + Inherited::updateNode(); + + if (isDirty(Async)) { + // do nothing... + } + if (isDirty(OptimizeMode)) { + // TODO: trigger a node update ? + } + if (isDirty(Source)) { + h->updateSource(); } } } // namespace osgQtQuick diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGFileNode.hpp b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGFileNode.hpp index fcac16093..4057c05ac 100644 --- a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGFileNode.hpp +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGFileNode.hpp @@ -2,7 +2,7 @@ ****************************************************************************** * * @file OSGFileNode.hpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * @addtogroup * @{ * @addtogroup @@ -37,16 +37,22 @@ class QUrl; QT_END_NAMESPACE namespace osgQtQuick { +class OSGQTQUICK_EXPORT OptimizeMode : public QObject { + Q_OBJECT + +public: + enum Enum { None, Optimize, OptimizeAndCheck }; + Q_ENUMS(Enum) // TODO switch to Q_ENUM once on Qt 5.5 +}; + class OSGQTQUICK_EXPORT OSGFileNode : public OSGNode { Q_OBJECT Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) Q_PROPERTY(bool async READ async WRITE setAsync NOTIFY asyncChanged) - Q_PROPERTY(OptimizeMode optimizeMode READ optimizeMode WRITE setOptimizeMode NOTIFY optimizeModeChanged) + Q_PROPERTY(osgQtQuick::OptimizeMode::Enum optimizeMode READ optimizeMode WRITE setOptimizeMode NOTIFY optimizeModeChanged) - Q_ENUMS(OptimizeMode) + typedef OSGNode Inherited; public: - enum OptimizeMode { None, Optimize, OptimizeAndCheck }; - OSGFileNode(QObject *parent = 0); virtual ~OSGFileNode(); @@ -56,17 +62,21 @@ public: bool async() const; void setAsync(const bool async); - OptimizeMode optimizeMode() const; - void setOptimizeMode(OptimizeMode); + OptimizeMode::Enum optimizeMode() const; + void setOptimizeMode(OptimizeMode::Enum); signals: void sourceChanged(const QUrl &url); void asyncChanged(const bool async); - void optimizeModeChanged(OptimizeMode); + void optimizeModeChanged(OptimizeMode::Enum); + +protected: + virtual osg::Node *createNode(); + virtual void updateNode(); private: struct Hidden; - Hidden *h; + Hidden *const h; }; } // namespace osgQtQuick diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGGeoTransformNode.cpp b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGGeoTransformNode.cpp new file mode 100644 index 000000000..2575fdfe3 --- /dev/null +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGGeoTransformNode.cpp @@ -0,0 +1,234 @@ +/** + ****************************************************************************** + * + * @file OSGGeoTransformNode.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "OSGGeoTransformNode.hpp" + +#include "utils/utility.h" + +#include + +#include +#include +#include + +#include + +namespace osgQtQuick { +// NOTE : these flags should not overlap with OSGGroup flags!!! +// TODO : find a better way... +enum DirtyFlag { Scene = 1 << 10, Position = 1 << 11, Clamp = 1 << 12 }; + +struct OSGGeoTransformNode::Hidden : public QObject { + Q_OBJECT + +private: + OSGGeoTransformNode * const self; + + osg::ref_ptr transform; + +public: + OSGNode *sceneNode; + + float offset; + + bool clampToTerrain; + bool intoTerrain; + + QVector3D position; + + Hidden(OSGGeoTransformNode *self) : QObject(self), self(self), sceneNode(NULL), offset(-1.0), clampToTerrain(false), intoTerrain(false) + {} + + osg::Node *createNode() + { + transform = new osgEarth::GeoTransform(); + transform->setAutoRecomputeHeights(true); + return transform; + } + + bool acceptSceneNode(OSGNode *node) + { + // qDebug() << "OSGGeoTransformNode::acceptSceneNode" << node; + if (sceneNode == node) { + return false; + } + + if (sceneNode) { + disconnect(sceneNode); + } + + sceneNode = node; + + if (sceneNode) { + connect(sceneNode, &OSGNode::nodeChanged, this, &OSGGeoTransformNode::Hidden::onSceneNodeChanged); + } + + return true; + } + + void updateSceneNode() + { + // qDebug() << "OSGGeoTransformNode::updateSceneNode" << sceneNode; + if (sceneNode && sceneNode->node()) { + osgEarth::MapNode *mapNode = osgEarth::MapNode::findMapNode(sceneNode->node()); + if (mapNode) { + transform->setTerrain(mapNode->getTerrain()); + } else { + qWarning() << "OSGGeoTransformNode::updateScene - scene data does not contain a map node"; + } + } + } + + void updatePosition() + { + // qDebug() << "OSGGeoTransformNode::updatePosition" << position; + + osgEarth::MapNode *mapNode = NULL; + + if (sceneNode && sceneNode->node()) { + mapNode = osgEarth::MapNode::findMapNode(sceneNode->node()); + if (!mapNode) { + qWarning() << "OSGGeoTransformNode::updatePosition - scene node does not contain a map node"; + } + } else { + qWarning() << "OSGGeoTransformNode::updatePosition - scene node is not valid"; + } + + // TODO factorize this logic to utility (same logic is found elsewhere) + osgEarth::GeoPoint geoPoint; + if (mapNode) { + geoPoint = osgQtQuick::toGeoPoint(mapNode->getTerrain()->getSRS(), position); + } else { + qWarning() << "OSGGeoTransformNode::onChildNodeChanged - no map node"; + geoPoint = osgQtQuick::toGeoPoint(position); + } + if (clampToTerrain && mapNode) { + // get "size" of model + // TODO this should be done once only... + osg::ComputeBoundsVisitor cbv; + transform->accept(cbv); + const osg::BoundingBox & bbox = cbv.getBoundingBox(); + offset = bbox.radius(); + + // qDebug() << "OSGGeoTransformNode::updateNode - offset" << offset; + + // clamp model to terrain if needed + intoTerrain = clampGeoPoint(geoPoint, offset, mapNode); + } else if (clampToTerrain) { + qWarning() << "OSGGeoTransformNode::onChildNodeChanged - cannot clamp without map node"; + } + + transform->setPosition(geoPoint); + } + +private slots: + void onSceneNodeChanged(osg::Node *node) + { + // qDebug() << "OSGGeoTransformNode::onSceneNodeChanged" << node; + updateSceneNode(); + updatePosition(); + } +}; + +/* class OSGGeoTransformNode */ + +OSGGeoTransformNode::OSGGeoTransformNode(QObject *parent) : Inherited(parent), h(new Hidden(this)) +{} + +OSGGeoTransformNode::~OSGGeoTransformNode() +{ + delete h; +} + +OSGNode *OSGGeoTransformNode::sceneNode() const +{ + return h->sceneNode; +} + +void OSGGeoTransformNode::setSceneNode(OSGNode *node) +{ + if (h->acceptSceneNode(node)) { + setDirty(Scene); + emit sceneNodeChanged(node); + } +} + +bool OSGGeoTransformNode::clampToTerrain() const +{ + return h->clampToTerrain; +} + +void OSGGeoTransformNode::setClampToTerrain(bool arg) +{ + if (h->clampToTerrain != arg) { + h->clampToTerrain = arg; + setDirty(Clamp); + emit clampToTerrainChanged(clampToTerrain()); + } +} + +bool OSGGeoTransformNode::intoTerrain() const +{ + return h->intoTerrain; +} + +QVector3D OSGGeoTransformNode::position() const +{ + return h->position; +} + +void OSGGeoTransformNode::setPosition(QVector3D arg) +{ + if (h->position != arg) { + h->position = arg; + setDirty(Position); + emit positionChanged(position()); + } +} + +osg::Node *OSGGeoTransformNode::createNode() +{ + return h->createNode(); +} + +void OSGGeoTransformNode::updateNode() +{ + Inherited::updateNode(); + + if (isDirty(Scene)) { + h->updateSceneNode(); + } + if (isDirty(Clamp)) { + // do nothing... + } + if (isDirty(Scene | Clamp | Position)) { + h->updatePosition(); + } +} +} // namespace osgQtQuick + +#include "OSGGeoTransformNode.moc" diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGGeoTransformNode.hpp b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGGeoTransformNode.hpp new file mode 100644 index 000000000..29f41eac8 --- /dev/null +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGGeoTransformNode.hpp @@ -0,0 +1,76 @@ +/** + ****************************************************************************** + * + * @file OSGGeoTransformNode.hpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _H_OSGQTQUICK_GEOTRANSFORMNODE_H_ +#define _H_OSGQTQUICK_GEOTRANSFORMNODE_H_ + +#include "Export.hpp" +#include "OSGGroup.hpp" + +#include + +namespace osgQtQuick { +class OSGQTQUICK_EXPORT OSGGeoTransformNode : public OSGGroup { + Q_OBJECT Q_PROPERTY(osgQtQuick::OSGNode *sceneNode READ sceneNode WRITE setSceneNode NOTIFY sceneNodeChanged) + Q_PROPERTY(bool clampToTerrain READ clampToTerrain WRITE setClampToTerrain NOTIFY clampToTerrainChanged) + Q_PROPERTY(bool intoTerrain READ intoTerrain NOTIFY intoTerrainChanged) + Q_PROPERTY(QVector3D position READ position WRITE setPosition NOTIFY positionChanged) + + typedef OSGGroup Inherited; + +public: + OSGGeoTransformNode(QObject *parent = 0); + virtual ~OSGGeoTransformNode(); + + OSGNode *sceneNode() const; + void setSceneNode(OSGNode *node); + + bool clampToTerrain() const; + void setClampToTerrain(bool arg); + + bool intoTerrain() const; + + QVector3D position() const; + void setPosition(QVector3D arg); + +signals: + void sceneNodeChanged(OSGNode *node); + void clampToTerrainChanged(bool arg); + void intoTerrainChanged(bool arg); + void positionChanged(QVector3D arg); + +protected: + virtual osg::Node *createNode(); + virtual void updateNode(); + +private: + struct Hidden; + Hidden *const h; +}; +} // namespace osgQtQuick + +#endif // _H_OSGQTQUICK_GEOTRANSFORMNODE_H_ diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGGroup.cpp b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGGroup.cpp index f6a814615..60f867a9f 100644 --- a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGGroup.cpp +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGGroup.cpp @@ -2,7 +2,7 @@ ****************************************************************************** * * @file OSGGroup.cpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * @addtogroup * @{ * @addtogroup @@ -33,118 +33,195 @@ #include namespace osgQtQuick { +enum DirtyFlag { Children = 1 << 0 }; + struct OSGGroup::Hidden : public QObject { Q_OBJECT -public: - Hidden(OSGGroup *parent) : QObject(parent), self(parent) - { - group = new osg::Group; - } - - OSGGroup *self; - - osg::ref_ptr group; - - QList children; +private: + OSGGroup * const self; QMap cache; - static void append_child(QQmlListProperty *list, OSGNode *child) - { - OSGGroup *group = qobject_cast(list->object); + QList children; - if (group && child) { - group->h->cache[child] = child->node(); - group->h->children.append(child); - if (child->node()) { - group->h->group->addChild(child->node()); - emit group->nodeChanged(group->h->group); - } - QObject::connect(child, SIGNAL(nodeChanged(osg::Node *)), group->h, SLOT(onNodeChanged(osg::Node *))); +public: + Hidden(OSGGroup *self) : QObject(self), self(self) + {} + + osg::Node *createNode() + { + return new osg::Group(); + } + + void appendChild(OSGNode *childNode) + { + // qDebug() << "OSGGroup::appendChild" << childNode; + children.append(childNode); + connect(childNode, &OSGNode::nodeChanged, this, &osgQtQuick::OSGGroup::Hidden::onChildNodeChanged, Qt::UniqueConnection); + self->setDirty(Children); + } + + int countChild() const + { + return children.size(); + } + + OSGNode *atChild(int index) const + { + if (index >= 0 && index < children.size()) { + return children[index]; } + return 0; + } + + void clearChild() + { + while (!children.isEmpty()) { + OSGNode *node = children.takeLast(); + disconnect(node); + } + children.clear(); + cache.clear(); + self->setDirty(Children); + } + + void updateChildren() + { + // qDebug() << "OSGGroup::updateChildren"; + + osg::Group *group = static_cast(self->node()); + + if (!group) { + qWarning() << "OSGGroup::updateChildren - null group"; + return; + } + + bool updated = false; + unsigned int index = 0; + + QListIterator i(children); + while (i.hasNext()) { + OSGNode *childNode = i.next(); + // qDebug() << "OSGGroup::updateChildren - child" << childNode; + if (childNode->node()) { + if (index < group->getNumChildren()) { + updated |= group->replaceChild(group->getChild(index), childNode->node()); + } else { + updated |= group->addChild(childNode->node()); + } + cache.insert(childNode, childNode->node()); + index++; + } + } + // removing eventual left overs + if (index < group->getNumChildren()) { + updated |= group->removeChild(index, group->getNumChildren() - index); + } + // if (updated) { + // self->emitNodeChanged(); + // } + } + + /* QQmlListProperty */ + + static void append_child(QQmlListProperty *list, OSGNode *childNode) + { + Hidden *h = qobject_cast(list->object); + + h->appendChild(childNode); } static int count_child(QQmlListProperty *list) { - OSGGroup *group = qobject_cast(list->object); + Hidden *h = qobject_cast(list->object); - if (group) { - return group->h->children.size(); - } - - return 0; + return h->countChild(); } static OSGNode *at_child(QQmlListProperty *list, int index) { - OSGGroup *group = qobject_cast(list->object); + Hidden *h = qobject_cast(list->object); - if (group && index >= 0 && index < group->h->children.size()) { - return group->h->children[index]; - } - - return 0; + return h->atChild(index); } static void clear_child(QQmlListProperty *list) { - OSGGroup *group = qobject_cast(list->object); + Hidden *h = qobject_cast(list->object); - if (group) { - while (!group->h->children.isEmpty()) { - OSGNode *node = group->h->children.takeLast(); - if (node->parent() == group) { - node->deleteLater(); - } - if (!node->parent()) { - node->deleteLater(); - } - } - group->h->group->removeChild(0, group->h->group->getNumChildren()); - group->h->cache.clear(); - } + h->clearChild(); } -public slots: - void onNodeChanged(osg::Node *node) +private slots: + void onChildNodeChanged(osg::Node *child) { - qDebug() << "OSGGroup::nodeChanged" << node; - OSGNode *obj = qobject_cast(sender()); - if (obj) { - osg::Node *cacheNode = cache.value(obj, NULL); - if (cacheNode) { - group->removeChild(cacheNode); - } - if (node) { - group->addChild(node); - } - cache[obj] = node; - emit self->nodeChanged(group.get()); + // qDebug() << "OSGGroup::onChildNodeChanged" << node; + + osg::Group *group = static_cast(self->node()); + + if (!group) { + qWarning() << "OSGGroup::onChildNodeChanged - null group"; + return; } + + OSGNode *childNode = qobject_cast(sender()); + // qDebug() << "OSGGroup::onChildNodeChanged - child node" << obj; + if (!childNode) { + qWarning() << "OSGGroup::onChildNodeChanged - sender is not an OSGNode" << sender(); + return; + } + if (childNode->node() != child) { + qWarning() << "OSGGroup::onChildNodeChanged - child node is not valid" << childNode; + return; + } + bool updated = false; + osg::Node *current = cache.value(childNode, NULL); + if (current) { + updated |= group->replaceChild(current, child); + } else { + // should not happen... + qWarning() << "OSGGroup::onChildNodeChanged - child node is not a child" << childNode; + } + cache[childNode] = childNode->node(); + // if (updated) { + // emit self->nodeChanged(group.get()); + // } } }; -OSGGroup::OSGGroup(QObject *parent) : - OSGNode(parent), h(new Hidden(this)) -{ - qDebug() << "OSGGroup::OSGGroup"; - setNode(h->group.get()); -} +/* class OSGGGroupNode */ + +OSGGroup::OSGGroup(QObject *parent) : Inherited(parent), h(new Hidden(this)) +{} OSGGroup::~OSGGroup() { - qDebug() << "OSGGroup::~OSGGroup"; + delete h; } -QQmlListProperty OSGGroup::children() +QQmlListProperty OSGGroup::children() const { - return QQmlListProperty(this, 0, + return QQmlListProperty(h, 0, &Hidden::append_child, &Hidden::count_child, &Hidden::at_child, &Hidden::clear_child); } + +osg::Node *OSGGroup::createNode() +{ + return h->createNode(); +} + +void OSGGroup::updateNode() +{ + Inherited::updateNode(); + + if (isDirty(Children)) { + h->updateChildren(); + } +} } // namespace osgQtQuick #include "OSGGroup.moc" diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGGroup.hpp b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGGroup.hpp index 9b4a082f7..00a8c7314 100644 --- a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGGroup.hpp +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGGroup.hpp @@ -2,7 +2,7 @@ ****************************************************************************** * * @file OSGGroup.hpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * @addtogroup * @{ * @addtogroup @@ -39,15 +39,21 @@ class OSGQTQUICK_EXPORT OSGGroup : public OSGNode { Q_CLASSINFO("DefaultProperty", "children") + typedef OSGNode Inherited; + public: explicit OSGGroup(QObject *parent = 0); virtual ~OSGGroup(); - QQmlListProperty children(); + QQmlListProperty children() const; + +protected: + virtual osg::Node *createNode(); + virtual void updateNode(); private: struct Hidden; - Hidden *h; + Hidden *const h; }; } // namespace osgQtQuick diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGImageNode.cpp b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGImageNode.cpp new file mode 100644 index 000000000..ab138d979 --- /dev/null +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGImageNode.cpp @@ -0,0 +1,128 @@ +/** + ****************************************************************************** + * + * @file OSGImageNode.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "OSGImageNode.hpp" + +#include + +#include + +#include +#include + +namespace osgQtQuick { +enum DirtyFlag { ImageFile = 1 << 0 }; + +struct OSGImageNode::Hidden : public QObject { + Q_OBJECT + +private: + OSGImageNode * const self; + + osg::ref_ptr texture; + +public: + QUrl url; + + Hidden(OSGImageNode *self) : QObject(self), self(self), url() + {} + + osg::Node *createNode() + { + osg::Drawable *quad = osg::createTexturedQuadGeometry(osg::Vec3(0, 0, 0), osg::Vec3(1, 0, 0), osg::Vec3(0, 1, 0)); + + osg::Geode *geode = new osg::Geode; + + geode->addDrawable(quad); + + geode->setStateSet(createState()); + + return geode; + } + + osg::StateSet *createState() + { + texture = new osg::Texture2D; + + // create the StateSet to store the texture data + osg::StateSet *stateset = new osg::StateSet; + + stateset->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON); + + return stateset; + } + + void updateImageFile() + { + qDebug() << "OSGImageNode::updateImageFile - reading image file" << url.path(); + osg::Image *image = osgDB::readImageFile(url.path().toStdString()); + if (texture.valid()) { + texture->setImage(image); + } + } +}; + +/* class OSGImageNode */ + +OSGImageNode::OSGImageNode(QObject *parent) : Inherited(parent), h(new Hidden(this)) +{} + +OSGImageNode::~OSGImageNode() +{ + delete h; +} + +const QUrl OSGImageNode::imageFile() const +{ + return h->url; +} + +void OSGImageNode::setImageFile(const QUrl &url) +{ + if (h->url != url) { + h->url = url; + setDirty(ImageFile); + emit imageFileChanged(url); + } +} + +osg::Node *OSGImageNode::createNode() +{ + return h->createNode(); +} + +void OSGImageNode::updateNode() +{ + Inherited::updateNode(); + + if (isDirty(ImageFile)) { + h->updateImageFile(); + } +} +} // namespace osgQtQuick + +#include "OSGImageNode.moc" diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGBackgroundNode.hpp b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGImageNode.hpp similarity index 76% rename from ground/gcs/src/libs/osgearth/osgQtQuick/OSGBackgroundNode.hpp rename to ground/gcs/src/libs/osgearth/osgQtQuick/OSGImageNode.hpp index 01a21fdd3..f543a0b54 100644 --- a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGBackgroundNode.hpp +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGImageNode.hpp @@ -1,8 +1,8 @@ /** ****************************************************************************** * - * @file OSGBackgroundNode.hpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @file OSGImageNode.hpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * @addtogroup * @{ * @addtogroup @@ -25,24 +25,23 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _H_OSGQTQUICK_BACKGROUNDNODE_H_ -#define _H_OSGQTQUICK_BACKGROUNDNODE_H_ +#ifndef _H_OSGQTQUICK_IMAGENODE_H_ +#define _H_OSGQTQUICK_IMAGENODE_H_ #include "Export.hpp" #include "OSGNode.hpp" #include -QT_BEGIN_NAMESPACE -class QUrl; -QT_END_NAMESPACE namespace osgQtQuick { -class OSGQTQUICK_EXPORT OSGBackgroundNode : public OSGNode { +class OSGQTQUICK_EXPORT OSGImageNode : public OSGNode { Q_OBJECT Q_PROPERTY(QUrl imageFile READ imageFile WRITE setImageFile NOTIFY imageFileChanged) + typedef OSGNode Inherited; + public: - OSGBackgroundNode(QObject *parent = 0); - virtual ~OSGBackgroundNode(); + OSGImageNode(QObject *parent = 0); + virtual ~OSGImageNode(); const QUrl imageFile() const; void setImageFile(const QUrl &url); @@ -50,10 +49,14 @@ public: signals: void imageFileChanged(const QUrl &url); +protected: + virtual osg::Node *createNode(); + virtual void updateNode(); + private: struct Hidden; - Hidden *h; + Hidden *const h; }; } // namespace osgQtQuick -#endif // _H_OSGQTQUICK_BACKGROUNDNODE_H_ +#endif // _H_OSGQTQUICK_IMAGENODE_H_ diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGModelNode.cpp b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGModelNode.cpp deleted file mode 100644 index 63907e37c..000000000 --- a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGModelNode.cpp +++ /dev/null @@ -1,367 +0,0 @@ -/** - ****************************************************************************** - * - * @file OSGModelNode.cpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. - * @addtogroup - * @{ - * @addtogroup - * @{ - * @brief - *****************************************************************************/ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "OSGModelNode.hpp" - -#include "../utility.h" - -#include -#include -#include - -#include -#include - -#include -#include - -#include - -#include - -namespace osgQtQuick { -struct OSGModelNode::Hidden : public QObject { - Q_OBJECT - - struct NodeUpdateCallback : public osg::NodeCallback { -public: - NodeUpdateCallback(Hidden *h) : h(h) {} - - void operator()(osg::Node *node, osg::NodeVisitor *nv); - - mutable Hidden *h; - }; - friend class NodeUpdateCallback; - -public: - - Hidden(OSGModelNode *parent) : QObject(parent), self(parent), modelData(NULL), sceneData(NULL), offset(-1.0), clampToTerrain(false), dirty(false) - {} - - ~Hidden() - {} - - bool acceptModelData(OSGNode *node) - { - qDebug() << "OSGModelNode::acceptModelData" << node; - if (modelData == node) { - return false; - } - - if (modelData) { - disconnect(modelData); - } - - modelData = node; - - if (modelData) { - acceptModelNode(modelData->node()); - connect(modelData, SIGNAL(nodeChanged(osg::Node *)), this, SLOT(onModelNodeChanged(osg::Node *))); - } - - return true; - } - - bool acceptModelNode(osg::Node *node) - { - qDebug() << "OSGModelNode::acceptModelNode" << node; - if (!node) { - qWarning() << "OSGModelNode::acceptModelNode - node is null"; - return false; - } - - if (!sceneData || !sceneData->node()) { - qWarning() << "OSGModelNode::acceptModelNode - no scene data"; - return false; - } - - osgEarth::MapNode *mapNode = osgEarth::MapNode::findMapNode(sceneData->node()); - if (!mapNode) { - qWarning() << "OSGModelNode::acceptModelNode - scene data does not contain a map node"; - return false; - } - - // establish the coordinate system we wish to use: - // const osgEarth::SpatialReference* latLong = osgEarth::SpatialReference::get("wgs84"); - - osgEarth::Symbology::Style style; - - // construct the symbology - osgEarth::Symbology::ModelSymbol *modelSymbol = style.getOrCreate(); - modelSymbol->setModel(node); - - // create ModelNode - modelNode = new osgEarth::Annotation::ModelNode(mapNode, style); - - // add update callback - if (!nodeUpdateCallback.valid()) { - nodeUpdateCallback = new NodeUpdateCallback(this); - } - modelNode->addUpdateCallback(nodeUpdateCallback.get()); - - // get "size" of model - osg::ComputeBoundsVisitor cbv; - modelNode->accept(cbv); - const osg::BoundingBox & bbox = cbv.getBoundingBox(); - offset = bbox.radius(); - - self->setNode(modelNode); - - dirty = true; - - return true; - } - - bool attach(osgViewer::View *view) - { - return true; - } - - bool detach(osgViewer::View *view) - { - qWarning() << "OSGModelNode::detach - not implemented"; - return true; - } - - bool acceptSceneData(OSGNode *node) - { - qDebug() << "OSGModelNode::acceptSceneData" << node; - if (sceneData == node) { - return false; - } - - if (sceneData) { - disconnect(sceneData); - } - - sceneData = node; - - if (sceneData) { - // TODO find a better way - if (modelData && modelData->node()) { - acceptModelNode(modelData->node()); - } - connect(sceneData, SIGNAL(nodeChanged(osg::Node *)), this, SLOT(onSceneNodeChanged(osg::Node *))); - } - - return true; - } - - // TODO model update gets jitter if camera is thrown (i.e animated) - void updateNode() - { - if (!dirty || !modelNode.valid()) { - return; - } - dirty = false; - - osgEarth::GeoPoint geoPoint = osgQtQuick::toGeoPoint(position); - if (clampToTerrain) { - osgEarth::MapNode *mapNode = osgEarth::MapNode::findMapNode(sceneData->node()); - if (mapNode) { - intoTerrain = clampGeoPoint(geoPoint, offset, mapNode); - } else { - qWarning() << "OSGModelNode::updateNode - scene data does not contain a map node"; - } - } - modelNode->setPosition(geoPoint); - modelNode->setLocalRotation(localRotation()); - } - - osg::Quat localRotation() - { - osg::Quat q = osg::Quat( - osg::DegreesToRadians(attitude.x()), osg::Vec3d(1, 0, 0), - osg::DegreesToRadians(attitude.y()), osg::Vec3d(0, 1, 0), - osg::DegreesToRadians(attitude.z()), osg::Vec3d(0, 0, 1)); - - return q; - } - - OSGModelNode *const self; - - OSGNode *modelData; - OSGNode *sceneData; - - osg::ref_ptr modelNode; - - float offset; - - bool clampToTerrain; - bool intoTerrain; - - QVector3D attitude; - QVector3D position; - - // handle attitude/position/etc independently - bool dirty; - - osg::observer_ptr nodeUpdateCallback; - -private slots: - - void onModelNodeChanged(osg::Node *node) - { - qDebug() << "OSGModelNode::onModelNodeChanged" << node; - if (modelData) { - if (modelNode.valid()) { - osgEarth::MapNode *mapNode = osgEarth::MapNode::findMapNode(sceneData->node()); - if (mapNode) { - mapNode->removeChild(modelNode); - } - if (nodeUpdateCallback.valid()) { - modelNode->removeUpdateCallback(nodeUpdateCallback.get()); - } - } - if (node) { - acceptModelNode(node); - } - } - } - - void onSceneNodeChanged(osg::Node *node) - { - qDebug() << "OSGModelNode::onSceneNodeChanged" << node; - // TODO needs to be improved... - if (modelData) { - if (modelNode.valid()) { - osgEarth::MapNode *mapNode = osgEarth::MapNode::findMapNode(sceneData->node()); - if (mapNode) { - mapNode->removeChild(modelNode); - } - if (nodeUpdateCallback.valid()) { - modelNode->removeUpdateCallback(nodeUpdateCallback.get()); - } - } - if (modelData->node()) { - acceptModelNode(modelData->node()); - } - } - } -}; - -/* struct Hidden::NodeUpdateCallback */ - -void OSGModelNode::Hidden::NodeUpdateCallback::operator()(osg::Node *node, osg::NodeVisitor *nv) -{ - h->updateNode(); - traverse(node, nv); -} - -OSGModelNode::OSGModelNode(QObject *parent) : OSGNode(parent), h(new Hidden(this)) -{ - qDebug() << "OSGModelNode::OSGModelNode"; -} - -OSGModelNode::~OSGModelNode() -{ - qDebug() << "OSGModelNode::~OSGModelNode"; -} - -OSGNode *OSGModelNode::modelData() -{ - return h->modelData; -} - -void OSGModelNode::setModelData(OSGNode *node) -{ - if (h->acceptModelData(node)) { - emit modelDataChanged(node); - } -} - -OSGNode *OSGModelNode::sceneData() -{ - return h->sceneData; -} - -void OSGModelNode::setSceneData(OSGNode *node) -{ - if (h->acceptSceneData(node)) { - emit sceneDataChanged(node); - } -} - -bool OSGModelNode::clampToTerrain() const -{ - return h->clampToTerrain; -} - -void OSGModelNode::setClampToTerrain(bool arg) -{ - if (h->clampToTerrain != arg) { - h->clampToTerrain = arg; - h->dirty = true; - emit clampToTerrainChanged(clampToTerrain()); - } -} - -bool OSGModelNode::intoTerrain() const -{ - return h->intoTerrain; -} - -QVector3D OSGModelNode::attitude() const -{ - return h->attitude; -} - -void OSGModelNode::setAttitude(QVector3D arg) -{ - if (h->attitude != arg) { - h->attitude = arg; - h->dirty = true; - emit attitudeChanged(attitude()); - } -} - -QVector3D OSGModelNode::position() const -{ - return h->position; -} - -void OSGModelNode::setPosition(QVector3D arg) -{ - if (h->position != arg) { - h->position = arg; - h->dirty = true; - emit positionChanged(position()); - } -} - -bool OSGModelNode::attach(osgViewer::View *view) -{ - return h->attach(view); -} - -bool OSGModelNode::detach(osgViewer::View *view) -{ - return h->detach(view); -} -} // namespace osgQtQuick - -#include "OSGModelNode.moc" diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGNode.cpp b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGNode.cpp index 70d557766..7e78bb0bb 100644 --- a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGNode.cpp +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGNode.cpp @@ -2,7 +2,7 @@ ****************************************************************************** * * @file OSGNode.cpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * @addtogroup * @{ * @addtogroup @@ -27,16 +27,64 @@ #include "OSGNode.hpp" +#include "DirtySupport.hpp" + #include -#include +#include namespace osgQtQuick { -struct OSGNode::Hidden { +class OSGNode; + +struct OSGNode::Hidden : public QObject, public DirtySupport { + Q_OBJECT + + friend class OSGNode; + +private: + OSGNode *const self; + osg::ref_ptr node; + + bool complete; + +public: + Hidden(OSGNode *self) : QObject(self), self(self), complete(false) /*, dirty(0)*/ + {} + + osg::Node *nodeToUpdate() const + { + return self->node(); + } + + void update() + { + return self->updateNode(); + } + + bool acceptNode(osg::Node *aNode) + { + if (node == aNode) { + return false; + } + + int flags = dirty(); + if (flags) { + clearDirty(); + } + node = aNode; + if (node) { + if (flags) { + setDirty(flags); + } + } + return true; + } }; -OSGNode::OSGNode(QObject *parent) : QObject(parent), h(new Hidden) +/* class OSGNode */ + +OSGNode::OSGNode(QObject *parent) : QObject(parent), QQmlParserStatus(), h(new Hidden(this)) {} OSGNode::~OSGNode() @@ -51,33 +99,59 @@ osg::Node *OSGNode::node() const void OSGNode::setNode(osg::Node *node) { - if (h->node.get() != node) { - h->node = node; - emit nodeChanged(node); + if (h->acceptNode(node)) { + emitNodeChanged(); } } -bool OSGNode::attach(osgViewer::View *view) +bool OSGNode::isDirty(int mask) const { - QListIterator i(children()); - while (i.hasNext()) { - OSGNode *node = qobject_cast(i.next()); - if (node) { - node->attach(view); - } - } - return true; + return h->isDirty(mask); } -bool OSGNode::detach(osgViewer::View *view) +void OSGNode::setDirty(int mask) { - QListIterator i(children()); - while (i.hasNext()) { - OSGNode *node = qobject_cast(i.next()); - if (node) { - node->detach(view); - } + h->setDirty(mask); +} + +void OSGNode::clearDirty() +{ + h->clearDirty(); +} + +osg::Node *OSGNode::createNode() +{ + return NULL; +} + +void OSGNode::updateNode() +{} + +void OSGNode::emitNodeChanged() +{ + if (h->complete) { + emit nodeChanged(node()); + } +} + +void OSGNode::classBegin() +{ + // qDebug() << "OSGNode::classBegin" << this; + + setNode(createNode()); +} + +void OSGNode::componentComplete() +{ + // qDebug() << "OSGNode::componentComplete" << this; + + updateNode(); + clearDirty(); + h->complete = true; + if (!h->node.valid()) { + qWarning() << "OSGNode::componentComplete - node is not valid!" << this; } - return true; } } // namespace osgQtQuick + +#include "OSGNode.moc" diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGNode.hpp b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGNode.hpp index 324132b8d..3b998aa6a 100644 --- a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGNode.hpp +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGNode.hpp @@ -2,7 +2,7 @@ ****************************************************************************** * * @file OSGNode.hpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * @addtogroup * @{ * @addtogroup @@ -31,18 +31,28 @@ #include "Export.hpp" #include +#include + +/** + * Only update() methods are allowed to update the OSG scenegraph. + * All other methods should call setDirty() which will later trigger an update. + * Exceptions: + * - node change events should be handled right away. + * + * Setting an OSGNode dirty will trigger the addition of a one time update callback. + * This approach leads to some potential issues: + * - if a child sets a parent dirty, the parent will be updated later on the next update traversal (i.e. before the next frame). + * + */ namespace osg { class Node; } // namespace osg -namespace osgViewer { -class View; -} // namespace osgViewer - namespace osgQtQuick { -class OSGQTQUICK_EXPORT OSGNode : public QObject { +class OSGQTQUICK_EXPORT OSGNode : public QObject, public QQmlParserStatus { Q_OBJECT + Q_INTERFACES(QQmlParserStatus) public: explicit OSGNode(QObject *parent = 0); @@ -51,15 +61,25 @@ public: osg::Node *node() const; void setNode(osg::Node *node); - virtual bool attach(osgViewer::View *view); - virtual bool detach(osgViewer::View *view); - signals: void nodeChanged(osg::Node *node) const; +protected: + bool isDirty(int mask = 0xFFFF) const; + void setDirty(int mask = 0xFFFF); + void clearDirty(); + + virtual osg::Node *createNode(); + virtual void updateNode(); + + void emitNodeChanged(); + + void classBegin(); + void componentComplete(); + private: struct Hidden; - Hidden *h; + Hidden *const h; }; } // namespace osgQtQuick diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGShapeNode.cpp b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGShapeNode.cpp new file mode 100644 index 000000000..6ca742f8c --- /dev/null +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGShapeNode.cpp @@ -0,0 +1,120 @@ +/** + ****************************************************************************** + * + * @file OSGShapeNode.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "OSGShapeNode.hpp" + +#include "utils/shapeutils.h" + +#include +#include +#include +#include + +#include + +namespace osgQtQuick { +enum DirtyFlag { ShapeType = 1 << 0 }; + +struct OSGShapeNode::Hidden : public QObject { + Q_OBJECT + +private: + OSGShapeNode * const self; + +public: + ShapeType::Enum shapeType; + + Hidden(OSGShapeNode *self) : QObject(self), self(self), shapeType(ShapeType::Sphere) + {} + + void updateShapeType() + { + osg::Node *node = NULL; + + switch (shapeType) { + case ShapeType::Cube: + node = ShapeUtils::createCube(); + break; + case ShapeType::Sphere: + node = ShapeUtils::createSphere(osg::Vec4(1, 0, 0, 1), 1.0); + break; + case ShapeType::Torus: + node = ShapeUtils::createOrientatedTorus(0.8, 1.0); + break; + case ShapeType::Axis: + node = ShapeUtils::create3DAxis(); + break; + case ShapeType::Rhombicuboctahedron: + node = ShapeUtils::createRhombicuboctahedron(); + break; + } + self->setNode(node); + } +}; + +/* class OSGShapeNode */ + +OSGShapeNode::OSGShapeNode(QObject *parent) : Inherited(parent), h(new Hidden(this)) +{ + setDirty(ShapeType); +} + +OSGShapeNode::~OSGShapeNode() +{ + delete h; +} + +ShapeType::Enum OSGShapeNode::shapeType() const +{ + return h->shapeType; +} + +void OSGShapeNode::setShapeType(ShapeType::Enum type) +{ + if (h->shapeType != type) { + h->shapeType = type; + setDirty(ShapeType); + emit shapeTypeChanged(type); + } +} + +osg::Node *OSGShapeNode::createNode() +{ + return NULL; +} + +void OSGShapeNode::updateNode() +{ + Inherited::updateNode(); + + if (isDirty(ShapeType)) { + h->updateShapeType(); + } +} +} // namespace osgQtQuick + +#include "OSGShapeNode.moc" diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGShapeNode.hpp b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGShapeNode.hpp new file mode 100644 index 000000000..88c264228 --- /dev/null +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGShapeNode.hpp @@ -0,0 +1,67 @@ +/** + ****************************************************************************** + * + * @file OSGShapeNode.hpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _H_OSGQTQUICK_SHAPENODE_H_ +#define _H_OSGQTQUICK_SHAPENODE_H_ + +#include "Export.hpp" +#include "OSGNode.hpp" + +namespace osgQtQuick { +class ShapeType : public QObject { + Q_OBJECT +public: + enum Enum { Cube, Sphere, Torus, Axis, Rhombicuboctahedron }; + Q_ENUMS(Enum) // TODO switch to Q_ENUM once on Qt 5.5 +}; + +class OSGQTQUICK_EXPORT OSGShapeNode : public OSGNode { + Q_OBJECT Q_PROPERTY(osgQtQuick::ShapeType::Enum shapeType READ shapeType WRITE setShapeType NOTIFY shapeTypeChanged) + + typedef OSGNode Inherited; + +public: + OSGShapeNode(QObject *parent = 0); + virtual ~OSGShapeNode(); + + ShapeType::Enum shapeType() const; + void setShapeType(ShapeType::Enum); + +signals: + void shapeTypeChanged(ShapeType::Enum); + +protected: + virtual osg::Node *createNode(); + virtual void updateNode(); + +private: + struct Hidden; + Hidden *const h; +}; +} // namespace osgQtQuick + +#endif // _H_OSGQTQUICK_SHAPENODE_H_ diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGSkyNode.cpp b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGSkyNode.cpp index 95b2bc76d..17e2f21cc 100644 --- a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGSkyNode.cpp +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGSkyNode.cpp @@ -2,7 +2,7 @@ ****************************************************************************** * * @file OSGSkyNode.cpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * @addtogroup * @{ * @addtogroup @@ -27,6 +27,8 @@ #include "OSGSkyNode.hpp" +#include "OSGViewport.hpp" + #include #include @@ -39,72 +41,91 @@ #include namespace osgQtQuick { +enum DirtyFlag { Scene = 1 << 0, Viewport = 1 << 1, DateTime = 1 << 2, Light = 1 << 3 }; + struct OSGSkyNode::Hidden : public QObject { Q_OBJECT +private: + OSGSkyNode * const self; + + osg::ref_ptr skyNode; + public: - Hidden(OSGSkyNode *parent) : QObject(parent), self(parent), sceneData(NULL), sunLightEnabled(true), dateTime(), minimumAmbientLight(0.03) - {} + OSGNode *sceneNode; + OSGViewport *viewport; + + bool sunLightEnabled; + QDateTime dateTime; + double minimumAmbientLight; + + Hidden(OSGSkyNode *self) : QObject(self), self(self), sceneNode(NULL), viewport(NULL), + sunLightEnabled(true), minimumAmbientLight(0.03) + { + dateTime = QDateTime::currentDateTime(); + } ~Hidden() {} bool acceptSceneNode(OSGNode *node) { - qDebug() << "OSGSkyNode::acceptSceneNode" << node; - if (sceneData == node) { + // qDebug() << "OSGSkyNode::acceptSceneNode" << node; + if (sceneNode == node) { return false; } - if (sceneData) { - disconnect(sceneData); + if (sceneNode) { + disconnect(sceneNode); } - sceneData = node; + sceneNode = node; - if (sceneData) { - acceptNode(sceneData->node()); - connect(sceneData, SIGNAL(nodeChanged(osg::Node *)), this, SLOT(onNodeChanged(osg::Node *))); + if (sceneNode) { + connect(sceneNode, &OSGNode::nodeChanged, this, &OSGSkyNode::Hidden::onSceneNodeChanged); } return true; } - bool acceptNode(osg::Node *node) + void updateScene() { - qDebug() << "OSGSkyNode::acceptNode" << node; - - osgEarth::MapNode *mapNode = osgEarth::MapNode::findMapNode(node); + if (!sceneNode || !sceneNode->node()) { + qWarning() << "OSGSkyNode::updateScene - scene node not valid"; + self->setNode(NULL); + return; + } + // qDebug() << "OSGSkyNode::updateScene - scene node" << sceneNode->node(); + osgEarth::MapNode *mapNode = osgEarth::MapNode::findMapNode(sceneNode->node()); if (!mapNode) { - qWarning() << "OSGSkyNode::acceptNode - scene data does not contain a map node"; - return false; + qWarning() << "OSGSkyNode::updateScene - scene node does not contain a map node"; + self->setNode(NULL); + return; } if (!mapNode->getMap()->isGeocentric()) { - qWarning() << "OSGSkyNode::acceptNode - map node is not geocentric"; - return false; + qWarning() << "OSGSkyNode::updateScene - map node is not geocentric"; + self->setNode(NULL); + return; } // create sky node - skyNode = createSimpleSky(mapNode); - // skyNode = createSilverLiningSky(mapNode); + if (!skyNode.valid()) { + skyNode = createSimpleSky(mapNode); + // skyNode = createSilverLiningSky(mapNode); - acceptSunLightEnabled(sunLightEnabled); - acceptDateTime(dateTime); - acceptMinimumAmbientLight(minimumAmbientLight); + // Ocean + // const osgEarth::Config & externals = mapNode->externalConfig(); + // if (externals.hasChild("ocean")) { + // s_ocean = osgEarth::Util::OceanNode::create(osgEarth::Util::OceanOptions(externals.child("ocean")), mapNode); + // if (s_ocean) root->addChild(s_ocean); - // skyNode->setStarsVisible(false); - - // Ocean - // const osgEarth::Config & externals = mapNode->externalConfig(); - // if (externals.hasChild("ocean")) { - // s_ocean = osgEarth::Util::OceanNode::create(osgEarth::Util::OceanOptions(externals.child("ocean")), mapNode); - // if (s_ocean) root->addChild(s_ocean); - - skyNode->addChild(node); - - self->setNode(skyNode); - - return true; + skyNode->addChild(sceneNode->node()); + self->setNode(skyNode); + } else { + skyNode->removeChild(0, 1); + skyNode->addChild(sceneNode->node()); + // self->emitNodeChanged(); + } } osgEarth::Util::SkyNode *createSimpleSky(osgEarth::MapNode *mapNode) @@ -128,158 +149,181 @@ public: } */ - bool acceptSunLightEnabled(bool enabled) + void updateViewport() { - // qDebug() << "OSGSkyNode::acceptSunLightEnabled" << enabled; - - this->sunLightEnabled = enabled; - - // TODO should be done in a node visitor... - if (skyNode) { - // skyNode->setLighting(sunLightEnabled ? osg::StateAttribute::ON : osg::StateAttribute::OFF); + // qDebug() << "OSGSkyNode::updateViewport" << skyNode; + if (!skyNode.valid()) { + qWarning() << "OSGSkyNode::updateViewport - invalid sky node" << skyNode; + return; } - - return true; + // qDebug() << "OSGSkyNode::updateViewport - attaching to" << viewport->asView(); + skyNode->attach(viewport->asView()); } - bool acceptDateTime(QDateTime dateTime) - { - qDebug() << "OSGSkyNode::acceptDateTime" << dateTime; - - if (!dateTime.isValid()) { - qWarning() << "OSGSkyNode::acceptDateTime - invalid date/time" << dateTime; - return false; - } - - this->dateTime = dateTime; - - // TODO should be done in a node visitor... - if (skyNode) { - QDate date = dateTime.date(); - QTime time = dateTime.time(); - double hours = time.hour() + (double)time.minute() / 60.0 + (double)time.second() / 3600.0; - skyNode->setDateTime(osgEarth::DateTime(date.year(), date.month(), date.day(), hours)); - } - - return true; - } - - bool acceptMinimumAmbientLight(double minimumAmbientLight) - { - // qDebug() << "OSGSkyNode::acceptMinimumAmbientLight" << minimumAmbientLight; - - this->minimumAmbientLight = minimumAmbientLight; - - // TODO should be done in a node visitor... - if (skyNode) { - double d = minimumAmbientLight; - // skyNode->getSunLight()->setAmbient(osg::Vec4(d, d, d, 1.0f)); - skyNode->setMinimumAmbient(osg::Vec4(d, d, d, 1.0f)); - } - - return true; - } - - bool attach(osgViewer::View *view) + void updateSunLightEnabled() { if (!skyNode.valid()) { - qWarning() << "OSGSkyNode::attach - invalid sky node" << skyNode; - return false; + qWarning() << "OSGSkyNode::updateSunLightEnabled - invalid sky node"; + return; } - skyNode->attach(view, 0); - return true; + if (!skyNode.valid()) { + return; + } + // skyNode->setLighting(sunLightEnabled ? osg::StateAttribute::ON : osg::StateAttribute::OFF); } - bool detach(osgViewer::View *view) + void updateDateTime() { - qWarning() << "OSGSkyNode::detach - not implemented"; - return true; + if (!skyNode.valid()) { + qWarning() << "OSGSkyNode::updateDateTime - invalid sky node"; + return; + } + if (!dateTime.isValid()) { + qWarning() << "OSGSkyNode::updateDateTime - invalid date/time" << dateTime; + } + + QDate date = dateTime.date(); + QTime time = dateTime.time(); + double hours = time.hour() + (double)time.minute() / 60.0 + (double)time.second() / 3600.0; + skyNode->setDateTime(osgEarth::DateTime(date.year(), date.month(), date.day(), hours)); } - OSGSkyNode *const self; + void updateMinimumAmbientLight() + { + if (!skyNode.valid()) { + qWarning() << "OSGSkyNode::updateMinimumAmbientLight - invalid sky node"; + return; + } + double d = minimumAmbientLight; + // skyNode->getSunLight()->setAmbient(osg::Vec4(d, d, d, 1.0f)); + skyNode->setMinimumAmbient(osg::Vec4(d, d, d, 1.0f)); + } - OSGNode *sceneData; - osg::ref_ptr skyNode; + void attachSkyNode(osgViewer::View *view) + { + if (!skyNode.valid()) { + qWarning() << "OSGSkyNode::attachSkyNode - invalid sky node" << skyNode; + return; + } + skyNode->attach(view); + } - bool sunLightEnabled; - QDateTime dateTime; - double minimumAmbientLight; + void detachSkyNode(osgViewer::View *view) + { + // TODO find a way to detach the skyNode (?) + } private slots: - - void onNodeChanged(osg::Node *node) + void onSceneNodeChanged(osg::Node *node) { - qDebug() << "OSGSkyNode::onNodeChanged" << node; - acceptNode(node); + // qDebug() << "OSGSkyNode::onSceneNodeChanged" << node; + updateScene(); } }; -OSGSkyNode::OSGSkyNode(QObject *parent) : OSGNode(parent), h(new Hidden(this)) +/* class OSGSkyNode */ + +OSGSkyNode::OSGSkyNode(QObject *parent) : Inherited(parent), h(new Hidden(this)) { - qDebug() << "OSGSkyNode::OSGSkyNode"; + setDirty(DateTime | Light); } OSGSkyNode::~OSGSkyNode() { - qDebug() << "OSGSkyNode::~OSGSkyNode"; + delete h; } -OSGNode *OSGSkyNode::sceneData() +OSGNode *OSGSkyNode::sceneNode() const { - return h->sceneData; + return h->sceneNode; } -void OSGSkyNode::setSceneData(OSGNode *node) +void OSGSkyNode::setSceneNode(OSGNode *node) { if (h->acceptSceneNode(node)) { - emit sceneDataChanged(node); + setDirty(Scene); + emit sceneNodeChanged(node); } } -bool OSGSkyNode::sunLightEnabled() +OSGViewport *OSGSkyNode::viewport() const +{ + return h->viewport; +} + +void OSGSkyNode::setViewport(OSGViewport *viewport) +{ + if (h->viewport != viewport) { + h->viewport = viewport; + setDirty(Viewport); + emit viewportChanged(viewport); + } +} + +bool OSGSkyNode::sunLightEnabled() const { return h->sunLightEnabled; } -void OSGSkyNode::setSunLightEnabled(bool arg) +void OSGSkyNode::setSunLightEnabled(bool enabled) { - if (h->acceptSunLightEnabled(arg)) { - emit sunLightEnabledChanged(sunLightEnabled()); + if (h->sunLightEnabled != enabled) { + h->sunLightEnabled = enabled; + setDirty(Light); + emit sunLightEnabledChanged(enabled); } } -QDateTime OSGSkyNode::dateTime() +QDateTime OSGSkyNode::dateTime() const { return h->dateTime; } -void OSGSkyNode::setDateTime(QDateTime arg) +void OSGSkyNode::setDateTime(QDateTime dateTime) { - if (h->acceptDateTime(arg)) { - emit dateTimeChanged(dateTime()); + if (h->dateTime != dateTime) { + h->dateTime = dateTime; + setDirty(DateTime); + emit dateTimeChanged(dateTime); } } -double OSGSkyNode::minimumAmbientLight() +double OSGSkyNode::minimumAmbientLight() const { return h->minimumAmbientLight; } -void OSGSkyNode::setMinimumAmbientLight(double arg) +void OSGSkyNode::setMinimumAmbientLight(double ambient) { - if (h->acceptMinimumAmbientLight(arg)) { - emit minimumAmbientLightChanged(minimumAmbientLight()); + if (h->minimumAmbientLight != ambient) { + h->minimumAmbientLight = ambient; + setDirty(Light); + emit minimumAmbientLightChanged(ambient); } } -bool OSGSkyNode::attach(osgViewer::View *view) +osg::Node *OSGSkyNode::createNode() { - return h->attach(view); + return NULL; } -bool OSGSkyNode::detach(osgViewer::View *view) +void OSGSkyNode::updateNode() { - return h->detach(view); + Inherited::updateNode(); + + if (isDirty(Scene)) { + h->updateScene(); + } + if (isDirty(Viewport)) { + h->updateViewport(); + } + if (isDirty(Light)) { + h->updateSunLightEnabled(); + h->updateMinimumAmbientLight(); + } + if (isDirty(DateTime)) { + h->updateDateTime(); + } } } // namespace osgQtQuick diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGSkyNode.hpp b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGSkyNode.hpp index 45117ab4f..3640610a3 100644 --- a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGSkyNode.hpp +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGSkyNode.hpp @@ -2,7 +2,7 @@ ****************************************************************************** * * @file OSGSkyNode.hpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * @addtogroup * @{ * @addtogroup @@ -43,42 +43,52 @@ class QUrl; QT_END_NAMESPACE namespace osgQtQuick { -class OSGQTQUICK_EXPORT OSGSkyNode : public OSGNode { - Q_OBJECT Q_PROPERTY(osgQtQuick::OSGNode *sceneData READ sceneData WRITE setSceneData NOTIFY sceneDataChanged) +class OSGViewport; +// TODO should derive from OSGGroup +class OSGQTQUICK_EXPORT OSGSkyNode : public OSGNode { + Q_OBJECT Q_PROPERTY(osgQtQuick::OSGNode *sceneNode READ sceneNode WRITE setSceneNode NOTIFY sceneNodeChanged) + Q_PROPERTY(osgQtQuick::OSGViewport * viewport READ viewport WRITE setViewport NOTIFY viewportChanged) Q_PROPERTY(bool sunLightEnabled READ sunLightEnabled WRITE setSunLightEnabled NOTIFY sunLightEnabledChanged) Q_PROPERTY(QDateTime dateTime READ dateTime WRITE setDateTime NOTIFY dateTimeChanged) Q_PROPERTY(double minimumAmbientLight READ minimumAmbientLight WRITE setMinimumAmbientLight NOTIFY minimumAmbientLightChanged) + typedef OSGNode Inherited; + public: OSGSkyNode(QObject *parent = 0); virtual ~OSGSkyNode(); - OSGNode *sceneData(); - void setSceneData(OSGNode *node); + OSGNode *sceneNode() const; + void setSceneNode(OSGNode *node); - bool sunLightEnabled(); + OSGViewport *viewport() const; + void setViewport(OSGViewport *viewport); + + bool sunLightEnabled() const; void setSunLightEnabled(bool arg); - QDateTime dateTime(); + QDateTime dateTime() const; void setDateTime(QDateTime arg); - double minimumAmbientLight(); + double minimumAmbientLight() const; void setMinimumAmbientLight(double arg); - virtual bool attach(osgViewer::View *view); - virtual bool detach(osgViewer::View *view); - signals: - void sceneDataChanged(OSGNode *node); + void sceneNodeChanged(OSGNode *node); + void viewportChanged(OSGViewport *viewport); void sunLightEnabledChanged(bool arg); void dateTimeChanged(QDateTime arg); void minimumAmbientLightChanged(double arg); +protected: + virtual osg::Node *createNode(); + virtual void updateNode(); + private: struct Hidden; - Hidden *h; + Hidden *const h; }; } // namespace osgQtQuick diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGTextNode.cpp b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGTextNode.cpp index ac0fc18b9..b6f1dce82 100644 --- a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGTextNode.cpp +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGTextNode.cpp @@ -2,7 +2,7 @@ ****************************************************************************** * * @file OSGTextNode.cpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * @addtogroup * @{ * @addtogroup @@ -27,7 +27,7 @@ #include "OSGTextNode.hpp" -#include "../utility.h" +#include "utils/utility.h" #include #include @@ -37,35 +37,62 @@ #include namespace osgQtQuick { -struct OSGTextNode::Hidden { -public: +enum DirtyFlag { Text = 1 << 0, Color = 1 << 1 }; + +struct OSGTextNode::Hidden : public QObject { + Q_OBJECT + +private: + OSGTextNode * const self; + osg::ref_ptr text; + +public: + QString textString; + QColor color; + + Hidden(OSGTextNode *self) : QObject(self), self(self) + {} + + osg::Node *createNode() + { + osg::ref_ptr textFont = createFont(QFont("Times")); + + text = createText(osg::Vec3(-100, 20, 0), "Hello World", 20.0f, textFont.get()); + osg::ref_ptr textGeode = new osg::Geode(); + textGeode->addDrawable(text.get()); + #if 0 + text->setAutoRotateToScreen(true); + #else + osg::Camera *camera = createHUDCamera(-100, 100, -100, 100); + camera->addChild(textGeode.get()); + camera->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + #endif + return textGeode; + } + + void updateText() + { + text->setText(textString.toStdString(), osgText::String::ENCODING_UTF8); + } + + void updateColor() + { + osg::Vec4 osgColor( + color.redF(), + color.greenF(), + color.blueF(), + color.alphaF()); + + text->setColor(osgColor); + } }; -OSGTextNode::OSGTextNode(QObject *parent) : - osgQtQuick::OSGNode(parent), - h(new Hidden) -{ - osg::ref_ptr textFont = createFont(QFont("Times")); +/* class OSGTextNode */ - h->text = createText(osg::Vec3(-100, 20, 0), - "The osgQtQuick :-)\n" - "И даже по русски!", - 20.0f, - textFont.get()); - osg::ref_ptr textGeode = new osg::Geode(); - h->text->setColor(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f)); - textGeode->addDrawable(h->text.get()); -#if 0 - h->text->setAutoRotateToScreen(true); - setNode(textGeode.get()); -#else - osg::Camera *camera = createHUDCamera(-100, 100, -100, 100); - camera->addChild(textGeode.get()); - camera->getOrCreateStateSet()->setMode( - GL_LIGHTING, osg::StateAttribute::OFF); - setNode(camera); -#endif +OSGTextNode::OSGTextNode(QObject *parent) : Inherited(parent), h(new Hidden(this)) +{ + setDirty(Text | Color); } OSGTextNode::~OSGTextNode() @@ -75,42 +102,48 @@ OSGTextNode::~OSGTextNode() QString OSGTextNode::text() const { - return QString::fromUtf8( - h->text->getText().createUTF8EncodedString().data()); + return h->textString; } void OSGTextNode::setText(const QString &text) { - std::string oldText = h->text->getText().createUTF8EncodedString(); - - if (text.toStdString() != oldText) { - h->text->setText(text.toStdString(), osgText::String::ENCODING_UTF8); + if (h->textString != text) { + h->textString != text; + setDirty(Text); emit textChanged(text); } } QColor OSGTextNode::color() const { - const osg::Vec4 osgColor = h->text->getColor(); - - return QColor::fromRgbF( - osgColor.r(), - osgColor.g(), - osgColor.b(), - osgColor.a()); + return h->color; } void OSGTextNode::setColor(const QColor &color) { - osg::Vec4 osgColor( - color.redF(), - color.greenF(), - color.blueF(), - color.alphaF()); - - if (h->text->getColor() != osgColor) { - h->text->setColor(osgColor); + if (h->color != color) { + h->color != color; + setDirty(Color); emit colorChanged(color); } } + +osg::Node *OSGTextNode::createNode() +{ + return h->createNode(); +} + +void OSGTextNode::updateNode() +{ + Inherited::updateNode(); + + if (isDirty(Text)) { + h->updateText(); + } + if (isDirty(Color)) { + h->updateColor(); + } +} } // namespace osgQtQuick + +#include "OSGTextNode.moc" diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGTextNode.hpp b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGTextNode.hpp index 5a0939478..0232b4335 100644 --- a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGTextNode.hpp +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGTextNode.hpp @@ -2,7 +2,7 @@ ****************************************************************************** * * @file OSGTextNode.hpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * @addtogroup * @{ * @addtogroup @@ -38,6 +38,8 @@ class OSGQTQUICK_EXPORT OSGTextNode : public OSGNode { Q_OBJECT Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged) Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) + typedef OSGNode Inherited; + public: explicit OSGTextNode(QObject *parent = 0); virtual ~OSGTextNode(); @@ -52,11 +54,13 @@ signals: void textChanged(const QString &text); void colorChanged(const QColor &color); -public slots: +protected: + virtual osg::Node *createNode(); + virtual void updateNode(); private: struct Hidden; - Hidden *h; + Hidden *const h; }; } // namespace osgQtQuick diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGTransformNode.cpp b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGTransformNode.cpp index 8b7f1b57b..0b28bb3d2 100644 --- a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGTransformNode.cpp +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGTransformNode.cpp @@ -2,7 +2,7 @@ ****************************************************************************** * * @file OSGTransformNode.cpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * @addtogroup * @{ * @addtogroup @@ -34,159 +34,69 @@ #include namespace osgQtQuick { +// NOTE : these flags should not overlap with OSGGroup flags!!! +// TODO : find a better way... +enum DirtyFlag { Scale = 1 << 10, Position = 1 << 11, Attitude = 1 << 12 }; + struct OSGTransformNode::Hidden : public QObject { Q_OBJECT - struct NodeUpdateCallback : public osg::NodeCallback { -public: - NodeUpdateCallback(Hidden *h) : h(h) {} +private: + OSGTransformNode * const self; - void operator()(osg::Node *node, osg::NodeVisitor *nv); - - mutable Hidden *h; - }; - friend class NodeUpdateCallback; + osg::ref_ptr transform; public: + QVector3D scale; + QVector3D attitude; + QVector3D position; - Hidden(OSGTransformNode *parent) : QObject(parent), self(parent), modelData(NULL), dirty(false) + Hidden(OSGTransformNode *self) : QObject(self), self(self) {} - ~Hidden() - {} - - bool acceptModelData(OSGNode *node) + osg::Node *createNode() { - qDebug() << "OSGTransformNode::acceptModelData" << node; - if (modelData == node) { - return false; - } - - if (modelData) { - disconnect(modelData); - } - - modelData = node; - - if (modelData) { - acceptNode(modelData->node()); - connect(modelData, SIGNAL(nodeChanged(osg::Node *)), this, SLOT(onNodeChanged(osg::Node *))); - } - - return true; - } - - bool acceptNode(osg::Node *node) - { - qDebug() << "OSGTransformNode::acceptNode" << node; - if (!node) { - qWarning() << "OSGTransformNode::acceptNode - node is null"; - return false; - } - - osg::Transform *transform = getOrCreateTransform(); - if (!transform) { - qWarning() << "OSGTransformNode::acceptNode - transform is null"; - return false; - } - - transform->addChild(node); - - self->setNode(transform); - - dirty = true; - updateNode(); - - return true; - } - - osg::Transform *getOrCreateTransform() - { - if (transform.valid()) { - return transform.get(); - } - transform = new osg::PositionAttitudeTransform(); - - transform->addUpdateCallback(new NodeUpdateCallback(this)); - - return transform.get(); + return transform; } - void updateNode() + void updateScale() { - if (!dirty || !transform.valid()) { - return; - } - dirty = false; - - // scale + // qDebug() << "OSGTransformNode::updateScale" << scale; if ((scale.x() != 0.0) || (scale.y() != 0.0) || (scale.z() != 0.0)) { transform->setScale(osg::Vec3d(scale.x(), scale.y(), scale.z())); // transform->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON); transform->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL, osg::StateAttribute::ON); } - - // rotate - osg::Quat q = osg::Quat( - osg::DegreesToRadians(rotate.x()), osg::Vec3d(1, 0, 0), - osg::DegreesToRadians(rotate.y()), osg::Vec3d(0, 1, 0), - osg::DegreesToRadians(rotate.z()), osg::Vec3d(0, 0, 1)); - transform->setAttitude(q); - - // translate - transform->setPosition(osg::Vec3d(translate.x(), translate.y(), translate.z())); } - OSGTransformNode *const self; - - OSGNode *modelData; - - osg::ref_ptr transform; - - bool dirty; - - QVector3D scale; - QVector3D rotate; - QVector3D translate; - -private slots: - - void onNodeChanged(osg::Node *node) + void updateAttitude() { - qDebug() << "OSGTransformNode::onNodeChanged" << node; - acceptNode(node); + double roll = osg::DegreesToRadians(attitude.x()); + double pitch = osg::DegreesToRadians(attitude.y()); + double yaw = osg::DegreesToRadians(attitude.z()); + osg::Quat q = osg::Quat( + roll, osg::Vec3d(0, 1, 0), + pitch, osg::Vec3d(1, 0, 0), + yaw, osg::Vec3d(0, 0, -1)); + + transform->setAttitude(q); + } + + void updatePosition() + { + transform->setPosition(osg::Vec3d(position.x(), position.y(), position.z())); } }; -/* struct Hidden::NodeUpdateCallback */ +/* class OSGTransformNode */ -void OSGTransformNode::Hidden::NodeUpdateCallback::operator()(osg::Node *node, osg::NodeVisitor *nv) -{ - h->updateNode(); - traverse(node, nv); -} - -OSGTransformNode::OSGTransformNode(QObject *parent) : OSGNode(parent), h(new Hidden(this)) -{ - qDebug() << "OSGTransformNode::OSGTransformNode"; -} +OSGTransformNode::OSGTransformNode(QObject *parent) : Inherited(parent), h(new Hidden(this)) +{} OSGTransformNode::~OSGTransformNode() { - qDebug() << "OSGTransformNode::~OSGTransformNode"; -} - -OSGNode *OSGTransformNode::modelData() -{ - return h->modelData; -} - -void OSGTransformNode::setModelData(OSGNode *node) -{ - if (h->acceptModelData(node)) { - emit modelDataChanged(node); - } + delete h; } QVector3D OSGTransformNode::scale() const @@ -198,36 +108,56 @@ void OSGTransformNode::setScale(QVector3D arg) { if (h->scale != arg) { h->scale = arg; - h->dirty = true; + setDirty(Scale); emit scaleChanged(scale()); } } -QVector3D OSGTransformNode::rotate() const +QVector3D OSGTransformNode::attitude() const { - return h->rotate; + return h->attitude; } -void OSGTransformNode::setRotate(QVector3D arg) +void OSGTransformNode::setAttitude(QVector3D arg) { - if (h->rotate != arg) { - h->rotate = arg; - h->dirty = true; - emit rotateChanged(rotate()); + if (h->attitude != arg) { + h->attitude = arg; + setDirty(Attitude); + emit attitudeChanged(attitude()); } } -QVector3D OSGTransformNode::translate() const +QVector3D OSGTransformNode::position() const { - return h->translate; + return h->position; } -void OSGTransformNode::setTranslate(QVector3D arg) +void OSGTransformNode::setPosition(QVector3D arg) { - if (h->translate != arg) { - h->translate = arg; - h->dirty = true; - emit translateChanged(translate()); + if (h->position != arg) { + h->position = arg; + setDirty(Position); + emit positionChanged(position()); + } +} + +osg::Node *OSGTransformNode::createNode() +{ + return h->createNode(); +} + +void OSGTransformNode::updateNode() +{ + Inherited::updateNode(); + + if (isDirty(Scale)) { + h->updateScale(); + } + if (isDirty(Attitude)) { + h->updateAttitude(); + } + if (isDirty(Position)) { + h->updatePosition(); } } } // namespace osgQtQuick diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGTransformNode.hpp b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGTransformNode.hpp index 510be9df0..2ca5cc0e7 100644 --- a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGTransformNode.hpp +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGTransformNode.hpp @@ -2,7 +2,7 @@ ****************************************************************************** * * @file OSGTransformNode.hpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * @addtogroup * @{ * @addtogroup @@ -29,47 +29,43 @@ #define _H_OSGQTQUICK_TRANSFORMNODE_H_ #include "Export.hpp" -#include "OSGNode.hpp" +#include "OSGGroup.hpp" #include -// TODO derive from OSGGroup... namespace osgQtQuick { -class OSGQTQUICK_EXPORT OSGTransformNode : public OSGNode { - Q_OBJECT - // TODO rename to parentNode and modelNode - Q_PROPERTY(osgQtQuick::OSGNode *modelData READ modelData WRITE setModelData NOTIFY modelDataChanged) +class OSGQTQUICK_EXPORT OSGTransformNode : public OSGGroup { + Q_OBJECT Q_PROPERTY(QVector3D scale READ scale WRITE setScale NOTIFY scaleChanged) + Q_PROPERTY(QVector3D attitude READ attitude WRITE setAttitude NOTIFY attitudeChanged) + Q_PROPERTY(QVector3D position READ position WRITE setPosition NOTIFY positionChanged) - Q_PROPERTY(QVector3D scale READ scale WRITE setScale NOTIFY scaleChanged) - Q_PROPERTY(QVector3D rotate READ rotate WRITE setRotate NOTIFY rotateChanged) - Q_PROPERTY(QVector3D translate READ translate WRITE setTranslate NOTIFY translateChanged) + typedef OSGGroup Inherited; public: OSGTransformNode(QObject *parent = 0); virtual ~OSGTransformNode(); - OSGNode *modelData(); - void setModelData(OSGNode *node); - QVector3D scale() const; void setScale(QVector3D arg); - QVector3D rotate() const; - void setRotate(QVector3D arg); + QVector3D attitude() const; + void setAttitude(QVector3D arg); - QVector3D translate() const; - void setTranslate(QVector3D arg); + QVector3D position() const; + void setPosition(QVector3D arg); signals: - void modelDataChanged(OSGNode *node); - void scaleChanged(QVector3D arg); - void rotateChanged(QVector3D arg); - void translateChanged(QVector3D arg); + void attitudeChanged(QVector3D arg); + void positionChanged(QVector3D arg); + +protected: + virtual osg::Node *createNode(); + virtual void updateNode(); private: struct Hidden; - Hidden *h; + Hidden *const h; }; } // namespace osgQtQuick diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGViewport.cpp b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGViewport.cpp index 7e47cff12..a01a47280 100644 --- a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGViewport.cpp +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGViewport.cpp @@ -2,7 +2,7 @@ ****************************************************************************** * * @file OSGViewport.cpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * @addtogroup * @{ * @addtogroup @@ -27,42 +27,38 @@ #include "OSGViewport.hpp" -#include "../osgearth.h" -#include "../utility.h" +#include "osgearth.h" +#include "utils/utility.h" #include "OSGNode.hpp" #include "OSGCamera.hpp" #include -#include -#include +#include #include +#include #include #include #include #include - -#include -#include -#include +#include +#include #include #include +#include #include #include #include #include -#include -#include +#include -namespace osgQtQuick { /* Debugging tips - export OSG_NOTIFY_LEVEL=DEBUG - Z-fighting can happen with coincident polygons, but it can also happen when the Z buffer has insufficient resolution to represent the data in the scene. In the case where you are close up to an object (the helicopter) and also viewing a far-off object (the earth) the Z buffer has to stretch to accommodate them both. @@ -71,254 +67,351 @@ namespace osgQtQuick { Assuming you are not messing around with the near/far computations, and assuming you don't have any other objects in the scene that are farther off than the earth, there are a couple things you can try. - One, adjust the near/far ratio of the camera. Look at osgearth_viewer.cpp to see how. + Adjust the near/far ratio of the camera. Look at osgearth_viewer.cpp to see how. + Use LogarythmicDepthBuffer. - Two, you can try to use the AutoClipPlaneHandler. You can install it automatically by running osgearth_viewer --autoclip. - - If none of that works, you can try parenting your helicopter with an osg::Camera in NESTED mode, + More complex : you can try parenting your helicopter with an osg::Camera in NESTED mode, which will separate the clip plane calculations of the helicopter from those of the earth. * TODO : add OSGView to handle multiple views for a given OSGViewport */ + +/* + that's a typical error when working with high-resolution (retina) + displays. The issue here is that on the high-resolution devices, the UI + operates with a virtual pixel size that is smaller than the real number + of pixels on the device. For example, you get coordinates from 0 to 2048 + while the real device resolution if 4096 pixels. This factor has to be + taken into account when mapping from window coordinates to OpenGL, e.g., + when calling glViewport. + + How you can get this factor depends on the GUI library you are using. In + Qt, you can query it with QWindow::devicePixelRatio(): + http://doc.qt.io/qt-5/qwindow.html#devicePixelRatio + + So, there should be something like + glViewport(0, 0, window->width() * window->devicePixelRatio(), + window->height() * window->devicePixelRatio()). + + Also keep in mind that you have to do the same e.g. for mouse coordinates. + + I think osgQt already handles this correctly, so you shouldn't have to + worry about this if you use the classes provided by osgQt ... + */ + +namespace osgQtQuick { +// enum DirtyFlag { Scene = 1 << 0, Camera = 1 << 1, Manipulator = 1 << 2, UpdateMode = 1 << 3, IncrementalCompile = 1 << 4 }; + +class ViewportRenderer; + +class MyViewer : public osgViewer::CompositeViewer { +public: + MyViewer() : osgViewer::CompositeViewer() + {} + + virtual bool checkNeedToDoFrame() + { + if (_requestRedraw) { + return true; + } + if (_requestContinousUpdate) { + return true; + } + + for (RefViews::iterator itr = _views.begin(); itr != _views.end(); ++itr) { + osgViewer::View *view = itr->get(); + if (view) { + // If the database pager is going to update the scene the render flag is + // set so that the updates show up + if (view->getDatabasePager()->getDataToCompileListSize() > 0) { + return true; + } + if (view->getDatabasePager()->getDataToMergeListSize() > 0) { + return true; + } + // if (view->getDatabasePager()->requiresUpdateSceneGraph()) return true; + // if (view->getDatabasePager()->getRequestsInProgress()) return true; + + // if there update callbacks then we need to do frame. + if (view->getCamera()->getUpdateCallback()) { + return true; + } + if (view->getSceneData() && view->getSceneData()->getUpdateCallback()) { + return true; + } + if (view->getSceneData() && view->getSceneData()->getNumChildrenRequiringUpdateTraversal() > 0) { + return true; + } + } + } + + // check if events are available and need processing + if (checkEvents()) { + return true; + } + + if (_requestRedraw) { + return true; + } + if (_requestContinousUpdate) { + return true; + } + + return false; + } +}; + struct OSGViewport::Hidden : public QObject { Q_OBJECT + friend ViewportRenderer; + +private: + OSGViewport *const self; + + QQuickWindow *window; + + int frameTimer; + + int frameCount; + + osg::ref_ptr gc; + public: + OSGNode *sceneNode; + OSGCamera *cameraNode; - Hidden(OSGViewport *quickItem) : QObject(quickItem), - self(quickItem), - window(NULL), - sceneData(NULL), - camera(NULL), - updateMode(Discrete), - frameTimer(-1) + osg::ref_ptr viewer; + osg::ref_ptr view; + + OSGCameraManipulator *manipulator; + + UpdateMode::Enum updateMode; + + bool incrementalCompile; + + bool busy; + + static osg::ref_ptr dummyGC; + + static QtKeyboardMap keyMap; + + Hidden(OSGViewport *self) : QObject(self), self(self), window(NULL), frameTimer(-1), frameCount(0), + sceneNode(NULL), cameraNode(NULL), manipulator(NULL), + updateMode(UpdateMode::OnDemand), incrementalCompile(false), busy(false) { - qDebug() << "OSGViewport::Hidden"; - OsgEarth::initialize(); // workaround to avoid using GraphicsContext #0 - if (!dummy.valid()) { - dummy = createGraphicsContext(); + // when switching tabs textures are not rebound (see https://librepilot.atlassian.net/secure/attachment/11500/lost_textures.png) + // so we create and retain GraphicsContext #0 so it won't be used elsewhere + if (!dummyGC.valid()) { + dummyGC = createGraphicsContext(); } createViewer(); - connect(quickItem, &OSGViewport::windowChanged, this, &Hidden::onWindowChanged); + connect(self, &OSGViewport::windowChanged, this, &Hidden::onWindowChanged); } ~Hidden() { - qDebug() << "OSGViewport::~Hidden"; - // osgQtQuick::openGLContextInfo(QOpenGLContext::currentContext(), "OSGViewport::~Hidden"); + stopTimer(); - stop(); - - destroyViewer(); + disconnect(self); } -public slots: +private slots: void onWindowChanged(QQuickWindow *window) { - qDebug() << "OSGViewport::onWindowChanged" << window; + // qDebug() << "OSGViewport::onWindowChanged" << window; // osgQtQuick::openGLContextInfo(QOpenGLContext::currentContext(), "onWindowChanged"); if (window) { - // window->setClearBeforeRendering(false); - connect(window, &QQuickWindow::sceneGraphInitialized, this, &Hidden::onSceneGraphInitialized, Qt::DirectConnection); - connect(window, &QQuickWindow::sceneGraphAboutToStop, this, &Hidden::onSceneGraphAboutToStop, Qt::DirectConnection); + // when hiding the QQuickWidget (happens when switching tab or re-parenting) the renderer is destroyed and sceneGraphInvalidated is signaled + // same happens when deleting the QQuickWidget + // problem is that there is no way to distinguish a hide and a delete so there is no good place to release gl objects, etc. + // it can't be done from other destructors as the gl context is not active at that time + // so we must delete the gl objects when hiding (and release it again when showing) + // deletion of the osg viewer will happen when the QQuickWidget is deleted. the gl context will not be active but it is ok because the + // viewer has no more gl objects to delete (we hope...) + // bad side effect is that when showing the scene after hiding it there is delay (on heavy scenes) to realise again the gl context. + // this is not happening on a separate thread (because of a limitation of QQuickWidget and Qt on windows related limitations) + // a workaround would be to not invalidate the scene when hiding/showing but that is not working atm... + // see https://bugreports.qt.io/browse/QTBUG-54133 for more details + // window->setPersistentSceneGraph(true); + + // connect(window, &QQuickWindow::sceneGraphInitialized, this, &Hidden::onSceneGraphInitialized, Qt::DirectConnection); connect(window, &QQuickWindow::sceneGraphInvalidated, this, &Hidden::onSceneGraphInvalidated, Qt::DirectConnection); - } else { - if (this->window) { - disconnect(this->window); - } + // connect(window, &QQuickWindow::afterSynchronizing, this, &Hidden::onAfterSynchronizing, Qt::DirectConnection); + connect(window, &QQuickWindow::afterSynchronizing, this, &Hidden::onAfterSynchronizing, Qt::DirectConnection); } this->window = window; } -public: - - bool acceptSceneData(OSGNode *node) - { - qDebug() << "OSGViewport::acceptSceneData" << node; - if (sceneData == node) { - return true; - } - - if (sceneData) { - disconnect(sceneData); - } - - sceneData = node; - - if (sceneData) { - acceptNode(sceneData->node()); - connect(sceneData, &OSGNode::nodeChanged, this, &Hidden::onNodeChanged); - } - - return true; - } - - bool acceptNode(osg::Node *node) - { - return true; - } - - bool attach(osgViewer::View *view) - { - if (!sceneData) { - qWarning() << "OSGViewport::attach - invalid scene!"; - return false; - } - if (!attach(view, sceneData->node())) { - qWarning() << "OSGViewport::attach - failed to attach node!"; - return false; - } - if (camera) { - camera->setViewport(0, 0, self->width(), self->height()); - camera->attach(view); - } else { - qWarning() << "OSGViewport::attach - no camera!"; - } - return true; - } - - bool attach(osgViewer::View *view, osg::Node *node) - { - qDebug() << "OSGViewport::attach" << node; - if (!view) { - qWarning() << "OSGViewport::attach - view is null"; - return false; - } - if (!node) { - qWarning() << "OSGViewport::attach - node is null"; - view->setSceneData(NULL); - return true; - } - - // TODO map handling should not be done here - osgEarth::MapNode *mapNode = osgEarth::MapNode::findMapNode(node); - if (false && mapNode) { - qDebug() << "OSGViewport::attach - found map node" << mapNode; - // install AutoClipPlaneCullCallback : computes near/far planes based on scene geometry - qDebug() << "OSGViewport::attach - set AutoClipPlaneCullCallback on camera"; - // TODO will the AutoClipPlaneCullCallback be destroyed ? - // TODO does it need to be added to the map node or to the view ? - cullCallback = new osgEarth::Util::AutoClipPlaneCullCallback(mapNode); - // view->getCamera()->addCullCallback(cullCallback); - mapNode->addCullCallback(cullCallback); - } - - // view->getCamera()->setSmallFeatureCullingPixelSize(-1.0f); - - view->setSceneData(node); - - return true; - } - - bool detach(osgViewer::View *view) - { - qDebug() << "OSGViewport::detach" << view; - - if (camera) { - camera->detach(view); - } - - osgEarth::MapNode *mapNode = osgEarth::MapNode::findMapNode(view->getSceneData()); - if (mapNode) { - view->getCamera()->removeCullCallback(cullCallback); - cullCallback = NULL; - } - - return true; - } + // emitted from the scene graph rendering thread (gl context bound) void onSceneGraphInitialized() { - qDebug() << "OSGViewport::onSceneGraphInitialized"; - // osgQtQuick::openGLContextInfo(QOpenGLContext::currentContext(), "onSceneGraphInitialized"); - } - - void onSceneGraphAboutToStop() - { - qDebug() << "OSGViewport::onSceneGraphAboutToStop"; - // osgQtQuick::openGLContextInfo(QOpenGLContext::currentContext(), "onSceneGraphAboutToStop"); + // qDebug() << "OSGViewport::onSceneGraphInitialized"; + initializeResources(); } + // emitted from the scene graph rendering thread (gl context bound) void onSceneGraphInvalidated() { - qDebug() << "OSGViewport::onSceneGraphInvalidated"; - // osgQtQuick::openGLContextInfo(QOpenGLContext::currentContext(), "onSceneGraphInvalidated"); + // qDebug() << "OSGViewport::onSceneGraphInvalidated"; + releaseResources(); } + // emitted from the scene graph rendering thread (gl context bound) + void onAfterSynchronizing() + { + // qDebug() << "OSGViewport::onAfterSynchronizing"; + } + +public: + bool acceptSceneNode(OSGNode *node) + { + // qDebug() << "OSGViewport::acceptSceneNode" << node; + if (sceneNode == node) { + return true; + } + + if (sceneNode) { + disconnect(sceneNode); + } + + sceneNode = node; + + if (sceneNode) { + connect(sceneNode, &OSGNode::nodeChanged, this, &Hidden::onSceneNodeChanged); + } + + return true; + } + + bool acceptCameraNode(OSGCamera *node) + { + // qDebug() << "OSGViewport::acceptCameraNode" << node; + if (cameraNode == node) { + return true; + } + + if (cameraNode) { + disconnect(cameraNode); + } + + cameraNode = node; + + if (cameraNode) { + connect(cameraNode, &OSGNode::nodeChanged, this, &Hidden::onCameraNodeChanged); + } + + return true; + } + + bool acceptManipulator(OSGCameraManipulator *m) + { + // qDebug() << "OSGViewport::acceptManipulator" << manipulator; + if (manipulator == m) { + return true; + } + + manipulator = m; + + return true; + } + +private: void initializeResources() { - qDebug() << "OSGViewport::initializeResources"; - if (!view.valid()) { - qDebug() << "OSGViewport::initializeResources - creating view"; - view = createView(); - self->attach(view.get()); - viewer->addView(view); - start(); - // osgDB::writeNodeFile(*(h->self->sceneData()->node()), "saved.osg"); - } - } - - void releaseResources() - { - qDebug() << "OSGViewport::releaseResources"; - if (!view.valid()) { - qWarning() << "OSGViewport::releaseResources - view is not valid!"; + // qDebug() << "OSGViewport::Hidden::initializeResources"; + // osgQtQuick::openGLContextInfo(QOpenGLContext::currentContext(), "OSGViewport::Hidden::initializeResources"); + if (gc.valid()) { + // qWarning() << "OSGViewport::initializeResources - gc already created!"; return; } - osg::deleteAllGLObjects(view->getCamera()->getGraphicsContext()->getState()->getContextID()); - // view->getSceneData()->releaseGLObjects(view->getCamera()->getGraphicsContext()->getState()); - // view->getCamera()->releaseGLObjects(view->getCamera()->getGraphicsContext()->getState()); - // view->getCamera()->getGraphicsContext()->close(); - // view->getCamera()->setGraphicsContext(NULL); - } - bool acceptUpdateMode(OSGViewport::UpdateMode mode) - { - // qDebug() << "OSGViewport::acceptUpdateMode" << mode; - if (updateMode == mode) { - return true; + // setup graphics context and camera + gc = createGraphicsContext(); + + // connect(QOpenGLContext::currentContext(), &QOpenGLContext::aboutToBeDestroyed, this, &Hidden::onAboutToBeDestroyed, Qt::DirectConnection); + + cameraNode->setGraphicsContext(gc); + + // qDebug() << "OSGViewport::initializeResources - camera" << cameraNode->asCamera(); + view->setCamera(cameraNode->asCamera()); + + // qDebug() << "OSGViewport::initializeResources - scene data" << sceneNode->node(); + view->setSceneData(sceneNode->node()); + + if (manipulator) { + osgGA::CameraManipulator *m = manipulator->asCameraManipulator(); + // qDebug() << "OSGViewport::initializeResources - manipulator" << m; + + // Setting the manipulator on the camera will change the manipulator node (used to compute the camera home position) + // to the view scene node. So we need to save and restore the manipulator node. + osg::Node *node = m->getNode(); + view->setCameraManipulator(m, false); + if (node) { + m->setNode(node); + } + view->home(); + } else { + view->setCameraManipulator(NULL, false); } - updateMode = mode; + installHanders(); - return true; + view->init(); + viewer->realize(); + + startTimer(); } - bool acceptCamera(OSGCamera *camera) + void onAboutToBeDestroyed() { - qDebug() << "OSGViewport::acceptCamera" << camera; - if (this->camera == camera) { - return true; - } - - this->camera = camera; - - return true; + // qDebug() << "OSGViewport::Hidden::onAboutToBeDestroyed"; + osgQtQuick::openGLContextInfo(QOpenGLContext::currentContext(), "OSGViewport::Hidden::onAboutToBeDestroyed"); + // context is not current and don't know how to make it current... } - OSGViewport *self; + // see https://github.com/openscenegraph/OpenSceneGraph/commit/161246d864ea0514543ed0493422e1bf0e99afb7#diff-91ee382a4d543072ea66aab422e5106f + // see https://github.com/openscenegraph/OpenSceneGraph/commit/3e0435febd677f14aae5f42ef1f43e81307fec41#diff-cadcd928403543a531cf42712a3d1126 + void releaseResources() + { + // qDebug() << "OSGViewport::Hidden::releaseResources"; + // osgQtQuick::openGLContextInfo(QOpenGLContext::currentContext(), "OSGViewport::Hidden::releaseResources"); + if (!gc.valid()) { + qWarning() << "OSGViewport::Hidden::releaseResources - gc is not valid!"; + return; + } + deleteAllGLObjects(); + } - QQuickWindow *window; + // there should be a simpler way to do that... + // for now, we mimic what is done in GraphicsContext::close() + // calling gc->close() and later gc->realize() does not work + void deleteAllGLObjects() + { + // TODO switch off the graphics thread (see GraphicsContext::close()) ? + // setGraphicsThread(0); - OSGNode *sceneData; - OSGCamera *camera; - - OSGViewport::UpdateMode updateMode; - - int frameTimer; - - osg::ref_ptr viewer; - osg::ref_ptr view; - - osg::ref_ptr cullCallback; - - static osg::ref_ptr dummy; - - static QtKeyboardMap keyMap; + for (osg::GraphicsContext::Cameras::iterator itr = gc->getCameras().begin(); + itr != gc->getCameras().end(); + ++itr) { + osg::Camera *camera = (*itr); + if (camera) { + OSG_INFO << "Releasing GL objects for Camera=" << camera << " _state=" << gc->getState() << std::endl; + camera->releaseGLObjects(gc->getState()); + } + } +#if OSG_VERSION_GREATER_OR_EQUAL(3, 5, 0) + gc->getState()->releaseGLObjects(); + osg::deleteAllGLObjects(gc->getState()->getContextID()); + osg::flushAllDeletedGLObjects(gc->getState()->getContextID()); + osg::discardAllGLObjects(gc->getState()->getContextID()); +#endif + } void createViewer() { @@ -326,38 +419,35 @@ public: qWarning() << "OSGViewport::createViewer - viewer is valid"; return; } + // qDebug() << "OSGViewport::createViewer"; - qDebug() << "OSGViewport::createViewer"; + viewer = new MyViewer(); + // viewer = new osgViewer::CompositeViewer(); - viewer = new osgViewer::CompositeViewer(); viewer->setThreadingModel(osgViewer::ViewerBase::SingleThreaded); - osg::ref_ptr ico = new osgUtil::IncrementalCompileOperation(); - ico->setTargetFrameRate(30.0f); - viewer->setIncrementalCompileOperation(ico); - // disable the default setting of viewer.done() by pressing Escape. viewer->setKeyEventSetsDone(0); // viewer->setQuitEventSetsDone(false); - } - void destroyViewer() - { - if (!viewer.valid()) { - qWarning() << "OSGViewport::destroyViewer - viewer is not valid"; - return; - } - - qDebug() << "OSGViewport::destroyViewer"; - - viewer = NULL; + view = createView(); + viewer->addView(view); } osgViewer::View *createView() { - qWarning() << "OSGViewport::createView"; + // qDebug() << "OSGViewport::createView"; osgViewer::View *view = new osgViewer::View(); + // TODO expose as Qml properties + view->setLightingMode(osgViewer::View::SKY_LIGHT); + view->getLight()->setAmbient(osg::Vec4(0.6f, 0.6f, 0.6f, 1.0f)); + + return view; + } + + void installHanders() + { // TODO will the handlers be destroyed??? // add the state manipulator view->addEventHandler(new osgGA::StateSetManipulator(view->getCamera()->getOrCreateStateSet())); @@ -383,17 +473,14 @@ public: // add the screen capture handler // view->addEventHandler(new osgViewer::ScreenCaptureHandler); - - view->getCamera()->setGraphicsContext(createGraphicsContext()); - - return view; } osg::GraphicsContext *createGraphicsContext() { - qWarning() << "OSGViewport::createGraphicsContext"; + // qDebug() << "OSGViewport::createGraphicsContext"; osg::GraphicsContext::Traits *traits = getTraits(); + // traitsInfo(*traits); traits->pbuffer = true; @@ -419,11 +506,17 @@ public: // traits->displayNum = 0; // } +#if OSG_VERSION_GREATER_OR_EQUAL(3, 5, 3) + // The MyQt windowing system is registered in osgearth.cpp + traits->windowingSystemPreference = "MyQt"; +#endif traits->windowDecoration = false; traits->x = 0; traits->y = 0; - traits->width = self->width(); - traits->height = self->height(); + + int dpr = self->window() ? self->window()->devicePixelRatio() : 1; + traits->width = self->width() * dpr; + traits->height = self->height() * dpr; traits->alpha = ds->getMinimumNumAlphaBits(); traits->stencil = ds->getMinimumNumStencilBits(); @@ -438,25 +531,24 @@ public: return traits; } - void start() + void startTimer() { - if (updateMode == OSGViewport::Discrete && (frameTimer < 0)) { - qDebug() << "OSGViewport::start - starting timer"; - frameTimer = startTimer(33, Qt::PreciseTimer); + if ((frameTimer < 0) && (updateMode != UpdateMode::Continuous)) { + // qDebug() << "OSGViewport::startTimer - starting timer"; + frameTimer = QObject::startTimer(33, Qt::PreciseTimer); } } - void stop() + void stopTimer() { if (frameTimer >= 0) { - qDebug() << "OSGViewport::stop - killing timer"; - killTimer(frameTimer); + // qDebug() << "OSGViewport::stopTimer - killing timer"; + QObject::killTimer(frameTimer); frameTimer = -1; } } protected: - void timerEvent(QTimerEvent *event) { if (event->timerId() == frameTimer) { @@ -469,37 +561,39 @@ protected: private slots: - - void onNodeChanged(osg::Node *node) + void onSceneNodeChanged(osg::Node *node) { - qDebug() << "OSGViewport::onNodeChanged" << node; - qWarning() << "OSGViewport::onNodeChanged - not implemented"; - // if (view.valid()) { - // acceptNode(node); - // } + qWarning() << "OSGViewport::onSceneNodeChanged - not implemented"; + } + + void onCameraNodeChanged(osg::Node *node) + { + qWarning() << "OSGViewport::onCameraNodeChanged - not implemented"; } }; /* class ViewportRenderer */ class ViewportRenderer : public QQuickFramebufferObject::Renderer { +private: + OSGViewport::Hidden *const h; + + bool initFrame; + bool needToDoFrame; + public: - ViewportRenderer(OSGViewport::Hidden *h) : h(h) + ViewportRenderer(OSGViewport::Hidden *h) : h(h), initFrame(true), needToDoFrame(false) { - qDebug() << "ViewportRenderer::ViewportRenderer"; - osgQtQuick::openGLContextInfo(QOpenGLContext::currentContext(), "ViewportRenderer::ViewportRenderer"); - + // qDebug() << "ViewportRenderer::ViewportRenderer"; + // osgQtQuick::openGLContextInfo(QOpenGLContext::currentContext(), "ViewportRenderer::ViewportRenderer"); h->initializeResources(); - - requestRedraw = false; } ~ViewportRenderer() { - qDebug() << "ViewportRenderer::~ViewportRenderer"; - osgQtQuick::openGLContextInfo(QOpenGLContext::currentContext(), "ViewportRenderer::~ViewportRenderer"); - - h->releaseResources(); + // qDebug() << "ViewportRenderer::~ViewportRenderer"; + // osgQtQuick::openGLContextInfo(QOpenGLContext::currentContext(), "ViewportRenderer::~ViewportRenderer"); + // h->releaseResources(); } // This function is the only place when it is safe for the renderer and the item to read and write each others members. @@ -508,12 +602,81 @@ public: // qDebug() << "ViewportRenderer::synchronize"; // osgQtQuick::openGLContextInfo(QOpenGLContext::currentContext(), "ViewportRenderer::synchronize"); + if (!h->viewer.valid()) { + qWarning() << "ViewportRenderer::synchronize - invalid viewer"; + return; + } + if (!h->view.valid()) { qWarning() << "ViewportRenderer::synchronize - invalid view"; return; } - // need to split frame() open and do the synchronization here (calling update callbacks, etc...) + if (initFrame) { + // workaround for https://bugreports.qt.io/browse/QTBUG-54073 + // busy indicator starting to spin indefinitly when switching tabs + h->self->setBusy(true); + h->self->setBusy(false); + } + + // NOTES: + // - needToDoFrame is always orred so "last" value is preserved. Make sure to set it to false if needed. + // - when switching tabs or re-parenting, the renderer is destroyed and recreated + // some special care is taken in case a renderer is (re)created; + // a new renderer will have initFrame set to true for the duration of the first frame + + // draw first frame of freshly initialized renderer + needToDoFrame |= initFrame; + + // if not on-demand then do frame + if (h->updateMode != UpdateMode::OnDemand) { + needToDoFrame = true; + } + + // check if viewport needs to be resized + // a redraw will be requested if necessary + // not really event driven... + int dpr = h->self->window()->devicePixelRatio(); + int width = item->width() * dpr; + int height = item->height() * dpr; + osg::Viewport *viewport = h->view->getCamera()->getViewport(); + if (initFrame || (viewport->width() != width) || (viewport->height() != height)) { + // qDebug() << "*** RESIZE" << h->frameCount << << initFrame << viewport->width() << "x" << viewport->height() << "->" << width << "x" << height; + needToDoFrame = true; + + h->gc->resized(0, 0, width, height); + h->view->getEventQueue()->windowResize(0, 0, width, height /*, resizeTime*/); + + // trick to force a "home" on first few frames to absorb initial spurious resizes + if (h->frameCount <= 2) { + h->view->home(); + } + } + + if (!needToDoFrame) { + // issue : UI events don't trigger a redraw + // this issue should be fixed here... + // event handling needs a lot of attention : + // - sometimes the scene is redrawing continuously (after a drag for example, and single click will stop continuous redraw) + // - some events (simple click for instance) trigger a redraw when not needed + // - in Earth View : continuous zoom (triggered by holding right button and moving mouse up/down) sometimes stops working when holding mouse still after initiating + needToDoFrame = !h->view->getEventQueue()->empty(); + } + + if (!needToDoFrame) { + needToDoFrame = h->viewer->checkNeedToDoFrame(); + } + if (needToDoFrame) { + // qDebug() << "ViewportRenderer::synchronize - update scene" << h->frameCount; + h->viewer->advance(); + h->viewer->eventTraversal(); + h->viewer->updateTraversal(); + } + + // refresh busy state + // TODO state becomes busy when scene is loading or downloading tiles (should do it only for download) + // TODO also expose request list size to Qml + h->self->setBusy(h->view->getDatabasePager()->getRequestsInProgress()); } // This function is called when the FBO should be rendered into. @@ -524,207 +687,181 @@ public: // osgQtQuick::openGLContextInfo(QOpenGLContext::currentContext(), "ViewportRenderer::render"); if (!h->viewer.valid()) { - qWarning() << "ViewportRenderer::render - invalid viewport"; + qWarning() << "ViewportRenderer::render - invalid viewer"; return; } - // needed to properly render models without terrain (Qt bug?) - QOpenGLContext::currentContext()->functions()->glUseProgram(0); + if (needToDoFrame) { + // qDebug() << "ViewportRenderer::render - render scene" << h->frameCount; - if (checkNeedToDoFrame()) { - // TODO scene update should NOT be done here - h->viewer->frame(); - requestRedraw = false; + // needed to properly render models without terrain (Qt bug?) + QOpenGLContext::currentContext()->functions()->glUseProgram(0); + + h->viewer->renderingTraversals(); + + needToDoFrame = false; } - // h->self->window()->resetOpenGLState(); - - if (h->updateMode == OSGViewport::Continuous) { + if (h->updateMode == UpdateMode::Continuous) { // trigger next update update(); } + + ++(h->frameCount); + initFrame = false; } QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) { - qDebug() << "ViewportRenderer::createFramebufferObject" << size; - if (h->camera) { - h->camera->setViewport(0, 0, size.width(), size.height()); - } - QOpenGLFramebufferObjectFormat format; + format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); // format.setSamples(4); - int dpr = h->self->window()->devicePixelRatio(); - QOpenGLFramebufferObject *fbo = new QOpenGLFramebufferObject(size.width() / dpr, size.height() / dpr, format); + + QOpenGLFramebufferObject *fbo = new QOpenGLFramebufferObject(size.width(), size.height(), format); return fbo; } - -private: - bool checkNeedToDoFrame() - { - // if (requestRedraw) { - // return true; - // } - // if (getDatabasePager()->requiresUpdateSceneGraph() || getDatabasePager()->getRequestsInProgress()) { - // return true; - // } - return true; - } - - OSGViewport::Hidden *h; - - bool requestRedraw; }; -osg::ref_ptr OSGViewport::Hidden::dummy; QtKeyboardMap OSGViewport::Hidden::keyMap = QtKeyboardMap(); +osg::ref_ptr OSGViewport::Hidden::dummyGC; + /* class OSGViewport */ - -OSGViewport::OSGViewport(QQuickItem *parent) : QQuickFramebufferObject(parent), h(new Hidden(this)) +OSGViewport::OSGViewport(QQuickItem *parent) : Inherited(parent), h(new Hidden(this)) { - qDebug() << "OSGViewport::OSGViewport"; // setClearBeforeRendering(false); +#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) + setMirrorVertically(true); +#endif setAcceptHoverEvents(true); setAcceptedMouseButtons(Qt::AllButtons); } -OSGViewport::~OSGViewport() -{ - qDebug() << "OSGViewport::~OSGViewport"; -} - -OSGViewport::UpdateMode OSGViewport::updateMode() const -{ - return h->updateMode; -} - -void OSGViewport::setUpdateMode(OSGViewport::UpdateMode mode) -{ - if (h->acceptUpdateMode(mode)) { - emit updateModeChanged(updateMode()); - } -} - -QColor OSGViewport::color() const -{ - const osg::Vec4 osgColor = h->view->getCamera()->getClearColor(); - - return QColor::fromRgbF(osgColor.r(), osgColor.g(), osgColor.b(), osgColor.a()); -} - -void OSGViewport::setColor(const QColor &color) -{ - osg::Vec4 osgColor(color.redF(), color.greenF(), color.blueF(), color.alphaF()); - - if (h->view->getCamera()->getClearColor() != osgColor) { - h->view->getCamera()->setClearColor(osgColor); - emit colorChanged(color); - } -} - -OSGNode *OSGViewport::sceneData() -{ - return h->sceneData; -} - -void OSGViewport::setSceneData(OSGNode *node) -{ - if (h->acceptSceneData(node)) { - emit sceneDataChanged(node); - } -} - -OSGCamera *OSGViewport::camera() -{ - return h->camera; -} - -void OSGViewport::setCamera(OSGCamera *camera) -{ - if (h->acceptCamera(camera)) { - emit cameraChanged(camera); - } -} - -QQuickFramebufferObject::Renderer *OSGViewport::createRenderer() const -{ - qDebug() << "OSGViewport::createRenderer"; - osgQtQuick::openGLContextInfo(QOpenGLContext::currentContext(), "createRenderer"); - return new ViewportRenderer(h); -} - -bool OSGViewport::attach(osgViewer::View *view) -{ - qDebug() << "OSGViewport::attach" << view; - - h->attach(view); - - QListIterator i(children()); - while (i.hasNext()) { - QObject *object = i.next(); - OSGNode *node = qobject_cast(object); - if (node) { - qDebug() << "OSGViewport::attach - child" << node; - node->attach(view); - } - } - - return true; -} - -bool OSGViewport::detach(osgViewer::View *view) -{ - qDebug() << "OSGViewport::detach" << view; - - QListIterator i(children()); - while (i.hasNext()) { - QObject *object = i.next(); - OSGNode *node = qobject_cast(object); - if (node) { - node->detach(view); - } - } - - h->detach(view); - - return true; -} - -void OSGViewport::releaseResources() -{ - QQuickFramebufferObject::releaseResources(); -} - -// see https://bugreports.qt-project.org/browse/QTBUG-41073 +#if QT_VERSION < QT_VERSION_CHECK(5, 6, 0) QSGNode *OSGViewport::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeData *nodeData) { - // qDebug() << "OSGViewport::updatePaintNode"; if (!node) { - qDebug() << "OSGViewport::updatePaintNode - set transform"; node = QQuickFramebufferObject::updatePaintNode(node, nodeData); QSGSimpleTextureNode *n = static_cast(node); if (n) { - // flip Y axis n->setTextureCoordinatesTransform(QSGSimpleTextureNode::MirrorVertically); } return node; } return QQuickFramebufferObject::updatePaintNode(node, nodeData); } +#endif - -QPointF OSGViewport::mousePoint(QMouseEvent *event) +OSGViewport::~OSGViewport() { - // qreal x = 0.01 * (event->x() - self->width() / 2); - // qreal y = 0.01 * (event->y() - self->height() / 2); - qreal x = 2.0 * (event->x() - width() / 2) / width(); - qreal y = 2.0 * (event->y() - height() / 2) / height(); + delete h; +} - return QPointF(x, y); +OSGNode *OSGViewport::sceneNode() const +{ + return h->sceneNode; +} + +void OSGViewport::setSceneNode(OSGNode *node) +{ + if (h->acceptSceneNode(node)) { + // setDirty(Scene); + emit sceneNodeChanged(node); + } +} + +OSGCamera *OSGViewport::cameraNode() const +{ + return h->cameraNode; +} + +void OSGViewport::setCameraNode(OSGCamera *node) +{ + if (h->acceptCameraNode(node)) { + // setDirty(Camera); + emit cameraNodeChanged(node); + } +} + +OSGCameraManipulator *OSGViewport::manipulator() const +{ + return h->manipulator; +} + +void OSGViewport::setManipulator(OSGCameraManipulator *manipulator) +{ + if (h->acceptManipulator(manipulator)) { + emit manipulatorChanged(manipulator); + } +} + +UpdateMode::Enum OSGViewport::updateMode() const +{ + return h->updateMode; +} + +void OSGViewport::setUpdateMode(UpdateMode::Enum mode) +{ + if (h->updateMode != mode) { + h->updateMode = mode; + emit updateModeChanged(mode); + } +} + +bool OSGViewport::incrementalCompile() const +{ + return h->incrementalCompile; +} + +void OSGViewport::setIncrementalCompile(bool incrementalCompile) +{ + if (h->incrementalCompile != incrementalCompile) { + h->incrementalCompile = incrementalCompile; + // setDirty(IncrementalCompile); + // TODO not thread safe... + h->viewer->setIncrementalCompileOperation(incrementalCompile ? new osgUtil::IncrementalCompileOperation() : NULL); + emit incrementalCompileChanged(incrementalCompile); + } +} + +bool OSGViewport::busy() const +{ + return h->busy; +} + +void OSGViewport::setBusy(bool busy) +{ + if (h->busy != busy) { + h->busy = busy; + emit busyChanged(busy); + } +} + +osgViewer::View *OSGViewport::asView() const +{ + return h->view; +} + +QQuickFramebufferObject::Renderer *OSGViewport::createRenderer() const +{ + // qDebug() << "OSGViewport::createRenderer"; + // osgQtQuick::openGLContextInfo(QOpenGLContext::currentContext(), "createRenderer"); + return new ViewportRenderer(h); +} + +void OSGViewport::classBegin() +{ + // qDebug() << "OSGViewport::classBegin" << this; + Inherited::classBegin(); +} + +void OSGViewport::componentComplete() +{ + // qDebug() << "OSGViewport::componentComplete" << this; + Inherited::componentComplete(); } void OSGViewport::mousePressEvent(QMouseEvent *event) @@ -741,26 +878,7 @@ void OSGViewport::mousePressEvent(QMouseEvent *event) setKeyboardModifiers(event); QPointF pos = mousePoint(event); if (h->view.valid()) { - h->view.get()->getEventQueue()->mouseButtonPress(pos.x(), pos.y(), button); - } -} - -void OSGViewport::setKeyboardModifiers(QInputEvent *event) -{ - int modkey = event->modifiers() & (Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier); - unsigned int mask = 0; - - if (modkey & Qt::ShiftModifier) { - mask |= osgGA::GUIEventAdapter::MODKEY_SHIFT; - } - if (modkey & Qt::ControlModifier) { - mask |= osgGA::GUIEventAdapter::MODKEY_CTRL; - } - if (modkey & Qt::AltModifier) { - mask |= osgGA::GUIEventAdapter::MODKEY_ALT; - } - if (h->view.valid()) { - h->view.get()->getEventQueue()->getCurrentEventState()->setModKeyMask(mask); + h->view->getEventQueue()->mouseButtonPress(pos.x(), pos.y(), button); } } @@ -769,7 +887,7 @@ void OSGViewport::mouseMoveEvent(QMouseEvent *event) setKeyboardModifiers(event); QPointF pos = mousePoint(event); if (h->view.valid()) { - h->view.get()->getEventQueue()->mouseMotion(pos.x(), pos.y()); + h->view->getEventQueue()->mouseMotion(pos.x(), pos.y()); } } @@ -787,7 +905,7 @@ void OSGViewport::mouseReleaseEvent(QMouseEvent *event) setKeyboardModifiers(event); QPointF pos = mousePoint(event); if (h->view.valid()) { - h->view.get()->getEventQueue()->mouseButtonRelease(pos.x(), pos.y(), button); + h->view->getEventQueue()->mouseButtonRelease(pos.x(), pos.y(), button); } } @@ -799,7 +917,7 @@ void OSGViewport::wheelEvent(QWheelEvent *event) (event->delta() > 0 ? osgGA::GUIEventAdapter::SCROLL_LEFT : osgGA::GUIEventAdapter::SCROLL_RIGHT); if (h->view.valid()) { - h->view.get()->getEventQueue()->mouseScroll(motion); + h->view->getEventQueue()->mouseScroll(motion); } } @@ -808,14 +926,14 @@ void OSGViewport::keyPressEvent(QKeyEvent *event) setKeyboardModifiers(event); int value = h->keyMap.remapKey(event); if (h->view.valid()) { - h->view.get()->getEventQueue()->keyPress(value); + h->view->getEventQueue()->keyPress(value); } // this passes the event to the regular Qt key event processing, // among others, it closes popup windows on ESC and forwards the event to the parent widgets // TODO implement // if( _forwardKeyEvents ) - // inherited::keyPressEvent( event ); + // Inherited::keyPressEvent(event); } void OSGViewport::keyReleaseEvent(QKeyEvent *event) @@ -826,7 +944,7 @@ void OSGViewport::keyReleaseEvent(QKeyEvent *event) setKeyboardModifiers(event); int value = h->keyMap.remapKey(event); if (h->view.valid()) { - h->view.get()->getEventQueue()->keyRelease(value); + h->view->getEventQueue()->keyRelease(value); } } @@ -834,7 +952,40 @@ void OSGViewport::keyReleaseEvent(QKeyEvent *event) // among others, it closes popup windows on ESC and forwards the event to the parent widgets // TODO implement // if( _forwardKeyEvents ) - // inherited::keyReleaseEvent( event ); + // Inherited::keyReleaseEvent(event); +} + +QPointF OSGViewport::mousePoint(QMouseEvent *event) +{ + qreal x, y; + + if (h->view.valid() && h->view->getEventQueue()->getUseFixedMouseInputRange()) { + x = 2.0 * (event->x() - width() / 2) / width(); + y = 2.0 * (event->y() - height() / 2) / height(); + } else { + x = event->x(); + y = event->y(); + } + return QPointF(x, y); +} + +void OSGViewport::setKeyboardModifiers(QInputEvent *event) +{ + int modkey = event->modifiers() & (Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier); + unsigned int mask = 0; + + if (modkey & Qt::ShiftModifier) { + mask |= osgGA::GUIEventAdapter::MODKEY_SHIFT; + } + if (modkey & Qt::ControlModifier) { + mask |= osgGA::GUIEventAdapter::MODKEY_CTRL; + } + if (modkey & Qt::AltModifier) { + mask |= osgGA::GUIEventAdapter::MODKEY_ALT; + } + if (h->view.valid()) { + h->view->getEventQueue()->getCurrentEventState()->setModKeyMask(mask); + } } } // namespace osgQtQuick diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGViewport.hpp b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGViewport.hpp index 14fc85953..fbe6725ba 100644 --- a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGViewport.hpp +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/OSGViewport.hpp @@ -2,7 +2,7 @@ ****************************************************************************** * * @file OSGViewport.hpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * @addtogroup * @{ * @addtogroup @@ -30,6 +30,8 @@ #include "Export.hpp" +#include "ga/OSGCameraManipulator.hpp" + #include namespace osgViewer { @@ -41,53 +43,65 @@ class Renderer; class OSGNode; class OSGCamera; -class OSGQTQUICK_EXPORT OSGViewport : public QQuickFramebufferObject { - Q_OBJECT Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) - Q_PROPERTY(UpdateMode updateMode READ updateMode WRITE setUpdateMode NOTIFY updateModeChanged) - Q_PROPERTY(osgQtQuick::OSGNode * sceneData READ sceneData WRITE setSceneData NOTIFY sceneDataChanged) - Q_PROPERTY(osgQtQuick::OSGCamera * camera READ camera WRITE setCamera NOTIFY cameraChanged) - - Q_ENUMS(UpdateMode) - +class UpdateMode : public QObject { + Q_OBJECT public: + enum Enum { Continuous, Discrete, OnDemand }; + Q_ENUMS(Enum) // TODO switch to Q_ENUM once on Qt 5.5 +}; + +class OSGQTQUICK_EXPORT OSGViewport : public QQuickFramebufferObject { + Q_OBJECT Q_PROPERTY(osgQtQuick::OSGNode *sceneNode READ sceneNode WRITE setSceneNode NOTIFY sceneNodeChanged) + Q_PROPERTY(osgQtQuick::OSGCamera * camera READ cameraNode WRITE setCameraNode NOTIFY cameraNodeChanged) + Q_PROPERTY(osgQtQuick::OSGCameraManipulator * manipulator READ manipulator WRITE setManipulator NOTIFY manipulatorChanged) + Q_PROPERTY(osgQtQuick::UpdateMode::Enum updateMode READ updateMode WRITE setUpdateMode NOTIFY updateModeChanged) + Q_PROPERTY(bool incrementalCompile READ incrementalCompile WRITE setIncrementalCompile NOTIFY incrementalCompileChanged) + Q_PROPERTY(bool busy READ busy NOTIFY busyChanged) + + typedef QQuickFramebufferObject Inherited; friend class ViewportRenderer; - // TODO rename to UpdateMode or something better - enum UpdateMode { - Continuous, - Discrete, - OnDemand - }; - +public: explicit OSGViewport(QQuickItem *parent = 0); virtual ~OSGViewport(); - UpdateMode updateMode() const; - void setUpdateMode(UpdateMode mode); + OSGNode *sceneNode() const; + void setSceneNode(OSGNode *node); - QColor color() const; - void setColor(const QColor &color); + OSGCamera *cameraNode() const; + void setCameraNode(OSGCamera *node); - OSGNode *sceneData(); - void setSceneData(OSGNode *node); + OSGCameraManipulator *manipulator() const; + void setManipulator(OSGCameraManipulator *manipulator); - OSGCamera *camera(); - void setCamera(OSGCamera *camera); + UpdateMode::Enum updateMode() const; + void setUpdateMode(UpdateMode::Enum mode); - virtual Renderer *createRenderer() const; - virtual void releaseResources(); + bool incrementalCompile() const; + void setIncrementalCompile(bool busy); - virtual bool attach(osgViewer::View *view); - virtual bool detach(osgViewer::View *view); + bool busy() const; + void setBusy(bool busy); + + osgViewer::View *asView() const; + + Renderer *createRenderer() const; signals: - void updateModeChanged(UpdateMode mode); - void colorChanged(const QColor &color); - void sceneDataChanged(OSGNode *node); - void cameraChanged(OSGCamera *camera); + void sceneNodeChanged(OSGNode *); + void cameraNodeChanged(OSGCamera *); + void manipulatorChanged(OSGCameraManipulator *); + void updateModeChanged(UpdateMode::Enum); + void incrementalCompileChanged(bool); + void busyChanged(bool busy); protected: + // QQmlParserStatus + void classBegin(); + void componentComplete(); + + // QQuickItem void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); @@ -95,14 +109,17 @@ protected: void keyPressEvent(QKeyEvent *event); void keyReleaseEvent(QKeyEvent *event); - void setKeyboardModifiers(QInputEvent *event); - QPointF mousePoint(QMouseEvent *event); - - QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData); +#if QT_VERSION < QT_VERSION_CHECK(5, 6, 0) + // QQuickFramebufferObject + QSGNode *updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeData *nodeData) override; +#endif private: struct Hidden; - Hidden *h; + Hidden *const h; + + void setKeyboardModifiers(QInputEvent *event); + QPointF mousePoint(QMouseEvent *event); }; } // namespace osgQtQuick diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGCameraManipulator.cpp b/ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGCameraManipulator.cpp new file mode 100644 index 000000000..f97098bb8 --- /dev/null +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGCameraManipulator.cpp @@ -0,0 +1,181 @@ +/** + ****************************************************************************** + * + * @file OSGCameraManipulator.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "OSGCameraManipulator.hpp" + +#include "../DirtySupport.hpp" +#include "../OSGNode.hpp" + +#include + +#include + +namespace osgQtQuick { +enum DirtyFlag { Scene = 1 << 0 }; + +struct OSGCameraManipulator::Hidden : public QObject, public DirtySupport { + Q_OBJECT + + friend class OSGCameraManipulator; + +private: + OSGCameraManipulator *const self; + +public: + osg::ref_ptr manipulator; + + OSGNode *sceneNode; + +public: + Hidden(OSGCameraManipulator *self) : QObject(self), self(self), sceneNode(NULL) + {} + + ~Hidden() + {} + + osg::Node *nodeToUpdate() const + { + return manipulator->getNode(); + } + + void update() + { + return self->update(); + } + + bool acceptSceneNode(OSGNode *node) + { + // qDebug() << "OSGCameraManipulator::acceptSceneNode" << node; + if (sceneNode == node) { + return true; + } + + if (sceneNode) { + disconnect(sceneNode); + } + + sceneNode = node; + + if (sceneNode) { + connect(sceneNode, &OSGNode::nodeChanged, this, &OSGCameraManipulator::Hidden::onSceneNodeChanged); + } + + return true; + } + + void updateSceneNode() + { + if (!sceneNode) { + qWarning() << "OSGCameraManipulator::updateSceneNode - no scene node"; + return; + } + // qDebug() << "OSGCameraManipulator::updateSceneNode" << sceneNode; + manipulator->setNode(sceneNode->node()); + } + +private slots: + void onSceneNodeChanged(osg::Node *node) + { + // qDebug() << "OSGCameraManipulator::onSceneNodeChanged" << node; + updateSceneNode(); + } +}; + +/* class OSGCameraManipulator */ + +OSGCameraManipulator::OSGCameraManipulator(QObject *parent) : QObject(parent), h(new Hidden(this)) +{} + +OSGCameraManipulator::~OSGCameraManipulator() +{ + delete h; +} + +OSGNode *OSGCameraManipulator::sceneNode() const +{ + return h->sceneNode; +} + +void OSGCameraManipulator::setSceneNode(OSGNode *node) +{ + if (h->acceptSceneNode(node)) { + setDirty(Scene); + emit sceneNodeChanged(node); + } +} + +bool OSGCameraManipulator::isDirty(int mask) const +{ + return h->isDirty(mask); +} + +void OSGCameraManipulator::setDirty(int mask) +{ + h->setDirty(mask); +} + +void OSGCameraManipulator::clearDirty() +{ + h->clearDirty(); +} + +void OSGCameraManipulator::classBegin() +{ + // qDebug() << "OSGCameraManipulator::classBegin" << this; +} + +void OSGCameraManipulator::componentComplete() +{ + // qDebug() << "OSGCameraManipulator::componentComplete" << this; + update(); + clearDirty(); +} + +osgGA::CameraManipulator *OSGCameraManipulator::manipulator() const +{ + return h->manipulator; +} + +void OSGCameraManipulator::setManipulator(osgGA::CameraManipulator *manipulator) +{ + h->manipulator = manipulator; +} + +osgGA::CameraManipulator *OSGCameraManipulator::asCameraManipulator() const +{ + return h->manipulator; +} + +void OSGCameraManipulator::update() +{ + if (isDirty(Scene)) { + h->updateSceneNode(); + } +} +} // namespace osgQtQuick + +#include "OSGCameraManipulator.moc" diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGCameraManipulator.hpp b/ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGCameraManipulator.hpp new file mode 100644 index 000000000..2546adbf1 --- /dev/null +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGCameraManipulator.hpp @@ -0,0 +1,81 @@ +/** + ****************************************************************************** + * + * @file OSGCameraManipulator.hpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _H_OSGQTQUICK_OSGCAMERAMANIPULATOR_H_ +#define _H_OSGQTQUICK_OSGCAMERAMANIPULATOR_H_ + +#include "../Export.hpp" + +#include +#include + +namespace osgGA { +class CameraManipulator; +} + +namespace osgQtQuick { +class OSGNode; + +class OSGQTQUICK_EXPORT OSGCameraManipulator : public QObject, public QQmlParserStatus { + Q_OBJECT + Q_INTERFACES(QQmlParserStatus) + + Q_PROPERTY(osgQtQuick::OSGNode * sceneNode READ sceneNode WRITE setSceneNode NOTIFY sceneNodeChanged) + +public: + explicit OSGCameraManipulator(QObject *parent = 0); + virtual ~OSGCameraManipulator(); + + osgGA::CameraManipulator *asCameraManipulator() const; + + OSGNode *sceneNode() const; + void setSceneNode(OSGNode *node); + +signals: + void sceneNodeChanged(OSGNode *node); + +protected: + bool isDirty(int mask = 0xFFFF) const; + void setDirty(int mask = 0xFFFF); + void clearDirty(); + + void classBegin(); + void componentComplete(); + + osgGA::CameraManipulator *manipulator() const; + void setManipulator(osgGA::CameraManipulator *manipulator); + +protected: + virtual void update(); + +private: + struct Hidden; + Hidden *const h; +}; +} // namespace osgQtQuick + +#endif // _H_OSGQTQUICK_OSGCAMERAMANIPULATOR_H_ diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGEarthManipulator.cpp b/ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGEarthManipulator.cpp new file mode 100644 index 000000000..4da67960d --- /dev/null +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGEarthManipulator.cpp @@ -0,0 +1,69 @@ +/** + ****************************************************************************** + * + * @file OSGEarthManipulator.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "OSGEarthManipulator.hpp" + +#include "../OSGNode.hpp" + +#include + +#include + +namespace osgQtQuick { +struct OSGEarthManipulator::Hidden : public QObject { + Q_OBJECT + +private: + OSGEarthManipulator * const self; + +public: + osg::ref_ptr manipulator; + + Hidden(OSGEarthManipulator *self) : QObject(self), self(self) + { + manipulator = new osgEarth::Util::EarthManipulator( + /*osgGA::StandardManipulator::COMPUTE_HOME_USING_BBOX | osgGA::StandardManipulator::DEFAULT_SETTINGS*/); + manipulator->getSettings()->setThrowingEnabled(true); + self->setManipulator(manipulator); + } + + ~Hidden() + {} +}; + +/* class OSGEarthManipulator */ + +OSGEarthManipulator::OSGEarthManipulator(QObject *parent) : Inherited(parent), h(new Hidden(this)) +{} + +OSGEarthManipulator::~OSGEarthManipulator() +{ + delete h; +} +} // namespace osgQtQuick + +#include "OSGEarthManipulator.moc" diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGEarthManipulator.hpp b/ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGEarthManipulator.hpp new file mode 100644 index 000000000..dbefa3411 --- /dev/null +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGEarthManipulator.hpp @@ -0,0 +1,52 @@ +/** + ****************************************************************************** + * + * @file OSGEarthManipulator.hpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _H_OSGQTQUICK_OSGEARTHMANIPULATOR_H_ +#define _H_OSGQTQUICK_OSGEARTHMANIPULATOR_H_ + +#include "../Export.hpp" +#include "OSGCameraManipulator.hpp" + +#include + +namespace osgQtQuick { +class OSGQTQUICK_EXPORT OSGEarthManipulator : public OSGCameraManipulator { + Q_OBJECT + + typedef OSGCameraManipulator Inherited; + +public: + explicit OSGEarthManipulator(QObject *parent = 0); + virtual ~OSGEarthManipulator(); + +private: + struct Hidden; + Hidden *const h; +}; +} // namespace osgQtQuick + +#endif // _H_OSGQTQUICK_OSGEARTHMANIPULATOR_H_ diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGGeoTransformManipulator.cpp b/ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGGeoTransformManipulator.cpp new file mode 100644 index 000000000..338754e82 --- /dev/null +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGGeoTransformManipulator.cpp @@ -0,0 +1,288 @@ +/** + ****************************************************************************** + * + * @file OSGGeoTransformManipulator.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "OSGGeoTransformManipulator.hpp" + +#include "../OSGNode.hpp" +#include "utils/utility.h" + +#include +#include +#include + +#include + +#include +#include +#include + +#include + +namespace osgQtQuick { +enum DirtyFlag { Position = 1 << 10, Attitude = 1 << 11, Clamp = 1 << 12 }; + +class MyManipulator : public osgGA::CameraManipulator { +public: + MyManipulator() + {} + + virtual void updateCamera(osg::Camera &camera); + + virtual const char *className() const + { + return "MyManipulator"; + } + + virtual void setByMatrix(const osg::Matrixd &matrix) + { + this->matrix = matrix; + } + + virtual void setByInverseMatrix(const osg::Matrixd &matrix) + { + this->invMatrix = matrix; + } + + virtual osg::Matrixd getMatrix() const + { + return matrix; + } + + virtual osg::Matrixd getInverseMatrix() const + { + return invMatrix; + } + + virtual void setNode(osg::Node *node) + { + this->node = node; + } + + virtual const osg::Node *getNode() const + { + return node.get(); + } + + virtual osg::Node *getNode() + { + return node.get(); + } + +private: + osg::Matrixd matrix; + osg::Matrixd invMatrix; + osg::ref_ptr node; +}; + +struct OSGGeoTransformManipulator::Hidden : public QObject { + Q_OBJECT + +private: + OSGGeoTransformManipulator * const self; + + osg::Matrix cameraPosition; + osg::Matrix cameraRotation; + +public: + osg::ref_ptr manipulator; + + QVector3D attitude; + QVector3D position; + + bool clampToTerrain; + bool intoTerrain; + + Hidden(OSGGeoTransformManipulator *self) : QObject(self), self(self), clampToTerrain(false), intoTerrain(false) + { + manipulator = new MyManipulator(); + self->setManipulator(manipulator); + } + + ~Hidden() + {} + + void updateManipulator() + { + // qDebug() << "OSGGeoTransformManipulator::updateManipulator"; + + osg::Matrix cameraMatrix = cameraRotation * cameraPosition; + + manipulator->setByMatrix(cameraMatrix); + + // Inverse the camera's position and orientation matrix to obtain the view matrix + cameraMatrix = osg::Matrix::inverse(cameraMatrix); + manipulator->setByInverseMatrix(cameraMatrix); + } + + void updatePosition() + { + // qDebug() << "OSGGeoTransformManipulator::updatePosition" << position; + + // Altitude mode is absolute (absolute height above MSL/HAE) + // HAE : Height above ellipsoid. This is the default. + // MSL : Height above Mean Sea Level (MSL) if a geoid separation value is specified. + // TODO handle the case where the terrain SRS is not "wgs84" + // TODO check if position is not below terrain? + // TODO compensate antenna height when source of position is GPS (i.e. subtract antenna height from altitude) ;) + + osgEarth::MapNode *mapNode = NULL; + + OSGNode *sceneNode = self->sceneNode(); + + if (sceneNode && sceneNode->node()) { + mapNode = osgEarth::MapNode::findMapNode(sceneNode->node()); + if (!mapNode) { + qWarning() << "OSGGeoTransformManipulator::updatePosition - manipulator node does not contain a map node"; + } + } else { + qWarning() << "OSGGeoTransformManipulator::updatePosition - scene node is null"; + } + + osgEarth::GeoPoint geoPoint; + if (mapNode) { + geoPoint = osgQtQuick::toGeoPoint(mapNode->getTerrain()->getSRS(), position); + } else { + geoPoint = osgQtQuick::toGeoPoint(position); + } + if (clampToTerrain && mapNode) { + // clamp model to terrain if needed + intoTerrain = osgQtQuick::clampGeoPoint(geoPoint, 0, mapNode); + } else if (clampToTerrain) { + qWarning() << "OSGGeoTransformManipulator::updatePosition - cannot clamp without map node"; + } + + geoPoint.createLocalToWorld(cameraPosition); + } + + void updateAttitude() + { + // qDebug() << "OSGGeoTransformManipulator::updateAttitude" << attitude; + + // By default the camera looks toward -Z, we must rotate it so it looks toward Y + cameraRotation.makeRotate(osg::DegreesToRadians(90.0), osg::Vec3(1.0, 0.0, 0.0), + osg::DegreesToRadians(0.0), osg::Vec3(0.0, 1.0, 0.0), + osg::DegreesToRadians(0.0), osg::Vec3(0.0, 0.0, 1.0)); + + // Final camera matrix + double roll = osg::DegreesToRadians(attitude.x()); + double pitch = osg::DegreesToRadians(attitude.y()); + double yaw = osg::DegreesToRadians(attitude.z()); + cameraRotation = cameraRotation + * osg::Matrix::rotate(roll, osg::Vec3(0, 1, 0)) + * osg::Matrix::rotate(pitch, osg::Vec3(1, 0, 0)) + * osg::Matrix::rotate(yaw, osg::Vec3(0, 0, -1)); + } +}; + +/* class OSGGeoTransformManipulator::MyManipulator */ + +void MyManipulator::updateCamera(osg::Camera & camera) +{ + // qDebug() << "MyManipulator::updateCamera"; + CameraManipulator::updateCamera(camera); +} + +/* class OSGGeoTransformManipulator */ + +OSGGeoTransformManipulator::OSGGeoTransformManipulator(QObject *parent) : Inherited(parent), h(new Hidden(this)) +{ + setDirty(Position | Attitude | Clamp); +} + +OSGGeoTransformManipulator::~OSGGeoTransformManipulator() +{ + delete h; +} + +bool OSGGeoTransformManipulator::clampToTerrain() const +{ + return h->clampToTerrain; +} + +void OSGGeoTransformManipulator::setClampToTerrain(bool arg) +{ + if (h->clampToTerrain != arg) { + h->clampToTerrain = arg; + setDirty(Clamp); + emit clampToTerrainChanged(clampToTerrain()); + } +} + +bool OSGGeoTransformManipulator::intoTerrain() const +{ + return h->intoTerrain; +} + +QVector3D OSGGeoTransformManipulator::attitude() const +{ + return h->attitude; +} + +void OSGGeoTransformManipulator::setAttitude(QVector3D arg) +{ + if (h->attitude != arg) { + h->attitude = arg; + setDirty(Attitude); + emit attitudeChanged(attitude()); + } +} + +QVector3D OSGGeoTransformManipulator::position() const +{ + return h->position; +} + +void OSGGeoTransformManipulator::setPosition(QVector3D arg) +{ + if (h->position != arg) { + h->position = arg; + setDirty(Position); + emit positionChanged(position()); + } +} + +void OSGGeoTransformManipulator::update() +{ + Inherited::update(); + + bool b = false; + + if (isDirty(Clamp | Position)) { + h->updatePosition(); + b = true; + } + if (isDirty(Attitude)) { + h->updateAttitude(); + b = true; + } + if (b) { + h->updateManipulator(); + } +} +} // namespace osgQtQuick + +#include "OSGGeoTransformManipulator.moc" diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGModelNode.hpp b/ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGGeoTransformManipulator.hpp similarity index 62% rename from ground/gcs/src/libs/osgearth/osgQtQuick/OSGModelNode.hpp rename to ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGGeoTransformManipulator.hpp index 4c45466dc..be5c6b1e7 100644 --- a/ground/gcs/src/libs/osgearth/osgQtQuick/OSGModelNode.hpp +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGGeoTransformManipulator.hpp @@ -1,8 +1,8 @@ /** ****************************************************************************** * - * @file OSGModelNode.hpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @file OSGGeoTransformManipulator.hpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * @addtogroup * @{ * @addtogroup @@ -25,46 +25,27 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _H_OSGQTQUICK_MODELNODE_H_ -#define _H_OSGQTQUICK_MODELNODE_H_ +#ifndef _H_OSGQTQUICK_OSGGEOTRANSFORMMANIPULATOR_H_ +#define _H_OSGQTQUICK_OSGGEOTRANSFORMMANIPULATOR_H_ -#include "Export.hpp" -#include "OSGNode.hpp" +#include "../Export.hpp" +#include "OSGCameraManipulator.hpp" +#include #include -#include - -namespace osgViewer { -class View; -} namespace osgQtQuick { -class OSGQTQUICK_EXPORT OSGModelNode : public OSGNode { - Q_OBJECT - // TODO rename to parentNode and modelNode - Q_PROPERTY(osgQtQuick::OSGNode *modelData READ modelData WRITE setModelData NOTIFY modelDataChanged) - Q_PROPERTY(osgQtQuick::OSGNode * sceneData READ sceneData WRITE setSceneData NOTIFY sceneDataChanged) - +class OSGQTQUICK_EXPORT OSGGeoTransformManipulator : public OSGCameraManipulator { + Q_OBJECT Q_PROPERTY(QVector3D attitude READ attitude WRITE setAttitude NOTIFY attitudeChanged) + Q_PROPERTY(QVector3D position READ position WRITE setPosition NOTIFY positionChanged) Q_PROPERTY(bool clampToTerrain READ clampToTerrain WRITE setClampToTerrain NOTIFY clampToTerrainChanged) Q_PROPERTY(bool intoTerrain READ intoTerrain NOTIFY intoTerrainChanged) - Q_PROPERTY(QVector3D attitude READ attitude WRITE setAttitude NOTIFY attitudeChanged) - Q_PROPERTY(QVector3D position READ position WRITE setPosition NOTIFY positionChanged) + typedef OSGCameraManipulator Inherited; public: - OSGModelNode(QObject *parent = 0); - virtual ~OSGModelNode(); - - OSGNode *modelData(); - void setModelData(OSGNode *node); - - OSGNode *sceneData(); - void setSceneData(OSGNode *node); - - bool clampToTerrain() const; - void setClampToTerrain(bool arg); - - bool intoTerrain() const; + explicit OSGGeoTransformManipulator(QObject *parent = 0); + virtual ~OSGGeoTransformManipulator(); QVector3D attitude() const; void setAttitude(QVector3D arg); @@ -72,23 +53,23 @@ public: QVector3D position() const; void setPosition(QVector3D arg); - virtual bool attach(osgViewer::View *view); - virtual bool detach(osgViewer::View *view); + bool clampToTerrain() const; + void setClampToTerrain(bool arg); + + bool intoTerrain() const; signals: - void modelDataChanged(OSGNode *node); - void sceneDataChanged(OSGNode *node); - + void attitudeChanged(QVector3D arg); + void positionChanged(QVector3D arg); void clampToTerrainChanged(bool arg); void intoTerrainChanged(bool arg); - void attitudeChanged(QVector3D arg); - void positionChanged(QVector3D arg); - private: struct Hidden; - Hidden *h; + Hidden *const h; + + virtual void update(); }; } // namespace osgQtQuick -#endif // _H_OSGQTQUICK_MODELNODE_H_ +#endif // _H_OSGQTQUICK_OSGGEOTRANSFORMMANIPULATOR_H_ diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGNodeTrackerManipulator.cpp b/ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGNodeTrackerManipulator.cpp new file mode 100644 index 000000000..b52c7a28f --- /dev/null +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGNodeTrackerManipulator.cpp @@ -0,0 +1,175 @@ +/** + ****************************************************************************** + * + * @file OSGNodeTrackerManipulator.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "OSGNodeTrackerManipulator.hpp" + +#include "../OSGNode.hpp" + +#include + +#include + +namespace osgQtQuick { +enum DirtyFlag { TrackNode = 1 << 10, TrackerMode = 1 << 11 }; + +struct OSGNodeTrackerManipulator::Hidden : public QObject { + Q_OBJECT + +private: + OSGNodeTrackerManipulator * const self; + +public: + osg::ref_ptr manipulator; + + OSGNode *trackNode; + TrackerMode::Enum trackerMode; + +public: + Hidden(OSGNodeTrackerManipulator *self) : QObject(self), self(self), + trackNode(NULL), trackerMode(TrackerMode::NodeCenterAndAzim) + { + manipulator = new osgGA::NodeTrackerManipulator( + /*osgGA::StandardManipulator::COMPUTE_HOME_USING_BBOX | osgGA::StandardManipulator::DEFAULT_SETTINGS*/); + manipulator->setTrackerMode(toOsg(trackerMode)); + manipulator->setVerticalAxisFixed(false); + + self->setManipulator(manipulator); + } + + ~Hidden() + {} + + bool acceptTrackNode(OSGNode *node) + { + // qDebug() << "OSGNodeTrackerManipulator::acceptTrackNode" << node; + if (trackNode == node) { + return false; + } + + if (trackNode) { + disconnect(trackNode); + } + + trackNode = node; + + if (trackNode) { + connect(trackNode, &OSGNode::nodeChanged, this, &OSGNodeTrackerManipulator::Hidden::onTrackNodeChanged); + } + + return true; + } + + void updateTrackNode() + { + if (!trackNode) { + qWarning() << "OSGNodeTrackerManipulator::updateTrackNode - no track node"; + return; + } + // qDebug() << "OSGNodeTrackerManipulator::updateTrackNode" << trackNode->node(); + manipulator->setTrackNode(trackNode->node()); + } + + void updateTrackerMode() + { + // qDebug() << "OSGNodeTrackerManipulator::updateTrackerMode" << mode; + manipulator->setTrackerMode(toOsg(trackerMode)); + } + + osgGA::NodeTrackerManipulator::TrackerMode toOsg(TrackerMode::Enum mode) + { + switch (mode) { + case TrackerMode::NodeCenter: + return osgGA::NodeTrackerManipulator::NODE_CENTER; + + case TrackerMode::NodeCenterAndAzim: + return osgGA::NodeTrackerManipulator::NODE_CENTER_AND_AZIM; + + case TrackerMode::NodeCenterAndRotation: + return osgGA::NodeTrackerManipulator::NODE_CENTER_AND_ROTATION; + } + return osgGA::NodeTrackerManipulator::NODE_CENTER_AND_ROTATION; + } + +private slots: + void onTrackNodeChanged(osg::Node *node) + { + // qDebug() << "OSGNodeTrackerManipulator::onTrackNodeChanged" << node; + qWarning() << "OSGNodeTrackerManipulator::onTrackNodeChanged - needs to be implemented"; + } +}; + +/* class OSGNodeTrackerManipulator */ + +OSGNodeTrackerManipulator::OSGNodeTrackerManipulator(QObject *parent) : Inherited(parent), h(new Hidden(this)) +{} + +OSGNodeTrackerManipulator::~OSGNodeTrackerManipulator() +{ + delete h; +} + +OSGNode *OSGNodeTrackerManipulator::trackNode() const +{ + return h->trackNode; +} + +void OSGNodeTrackerManipulator::setTrackNode(OSGNode *node) +{ + if (h->acceptTrackNode(node)) { + setDirty(TrackNode); + emit trackNodeChanged(node); + } +} + +TrackerMode::Enum OSGNodeTrackerManipulator::trackerMode() const +{ + return h->trackerMode; +} + +void OSGNodeTrackerManipulator::setTrackerMode(TrackerMode::Enum mode) +{ + if (h->trackerMode != mode) { + h->trackerMode = mode; + setDirty(TrackerMode); + emit trackerModeChanged(trackerMode()); + } +} + +void OSGNodeTrackerManipulator::update() +{ + Inherited::update(); + + if (isDirty(TrackNode)) { + h->updateTrackNode(); + } + if (isDirty(TrackerMode)) { + h->updateTrackerMode(); + } +} +} // namespace osgQtQuick + +#include "OSGNodeTrackerManipulator.moc" diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGNodeTrackerManipulator.hpp b/ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGNodeTrackerManipulator.hpp new file mode 100644 index 000000000..8215b6ccc --- /dev/null +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGNodeTrackerManipulator.hpp @@ -0,0 +1,72 @@ +/** + ****************************************************************************** + * + * @file OSGNodeTrackerManipulator.hpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _H_OSGQTQUICK_OSGNODETRACKERMANIPULATOR_H_ +#define _H_OSGQTQUICK_OSGNODETRACKERMANIPULATOR_H_ + +#include "../Export.hpp" +#include "OSGCameraManipulator.hpp" + +#include + +namespace osgQtQuick { +class TrackerMode : public QObject { + Q_OBJECT +public: + enum Enum { NodeCenter, NodeCenterAndAzim, NodeCenterAndRotation }; + Q_ENUMS(Enum) // TODO switch to Q_ENUM once on Qt 5.5 +}; + +class OSGQTQUICK_EXPORT OSGNodeTrackerManipulator : public OSGCameraManipulator { + Q_OBJECT Q_PROPERTY(osgQtQuick::OSGNode *trackNode READ trackNode WRITE setTrackNode NOTIFY trackNodeChanged) + Q_PROPERTY(osgQtQuick::TrackerMode::Enum trackerMode READ trackerMode WRITE setTrackerMode NOTIFY trackerModeChanged) + + typedef OSGCameraManipulator Inherited; + +public: + explicit OSGNodeTrackerManipulator(QObject *parent = 0); + virtual ~OSGNodeTrackerManipulator(); + + OSGNode *trackNode() const; + void setTrackNode(OSGNode *node); + + TrackerMode::Enum trackerMode() const; + void setTrackerMode(TrackerMode::Enum); + +signals: + void trackNodeChanged(OSGNode *node); + void trackerModeChanged(TrackerMode::Enum); + +private: + struct Hidden; + Hidden *const h; + + virtual void update(); +}; +} // namespace osgQtQuick + +#endif // _H_OSGQTQUICK_OSGNODETRACKERMANIPULATOR_H_ diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGTrackballManipulator.cpp b/ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGTrackballManipulator.cpp new file mode 100644 index 000000000..f79d533c5 --- /dev/null +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGTrackballManipulator.cpp @@ -0,0 +1,69 @@ +/** + ****************************************************************************** + * + * @file OSGTrackballManipulator.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "OSGTrackballManipulator.hpp" + +#include "../OSGNode.hpp" + +#include + +#include + +namespace osgQtQuick { +struct OSGTrackballManipulator::Hidden : public QObject { + Q_OBJECT + +private: + OSGTrackballManipulator * const self; + +public: + osg::ref_ptr manipulator; + + Hidden(OSGTrackballManipulator *self) : QObject(self), self(self) + { + manipulator = new osgGA::TrackballManipulator( + /*osgGA::StandardManipulator::COMPUTE_HOME_USING_BBOX | osgGA::StandardManipulator::DEFAULT_SETTINGS*/); + + self->setManipulator(manipulator); + } + + ~Hidden() + {} +}; + +/* class OSGTrackballManipulator */ + +OSGTrackballManipulator::OSGTrackballManipulator(QObject *parent) : Inherited(parent), h(new Hidden(this)) +{} + +OSGTrackballManipulator::~OSGTrackballManipulator() +{ + delete h; +} +} // namespace osgQtQuick + +#include "OSGTrackballManipulator.moc" diff --git a/ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGTrackballManipulator.hpp b/ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGTrackballManipulator.hpp new file mode 100644 index 000000000..75120a4ca --- /dev/null +++ b/ground/gcs/src/libs/osgearth/osgQtQuick/ga/OSGTrackballManipulator.hpp @@ -0,0 +1,52 @@ +/** + ****************************************************************************** + * + * @file OSGTrackballManipulator.hpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _H_OSGQTQUICK_OSGTRACKBALLMANIPULATOR_H_ +#define _H_OSGQTQUICK_OSGTRACKBALLMANIPULATOR_H_ + +#include "../Export.hpp" +#include "OSGCameraManipulator.hpp" + +#include + +namespace osgQtQuick { +class OSGQTQUICK_EXPORT OSGTrackballManipulator : public OSGCameraManipulator { + Q_OBJECT + + typedef OSGCameraManipulator Inherited; + +public: + explicit OSGTrackballManipulator(QObject *parent = 0); + virtual ~OSGTrackballManipulator(); + +private: + struct Hidden; + Hidden *const h; +}; +} // namespace osgQtQuick + +#endif // _H_OSGQTQUICK_OSGTRACKBALLMANIPULATOR_H_ diff --git a/ground/gcs/src/libs/osgearth/osgearth.cpp b/ground/gcs/src/libs/osgearth/osgearth.cpp index bb6b83fb4..ce1ab407a 100644 --- a/ground/gcs/src/libs/osgearth/osgearth.cpp +++ b/ground/gcs/src/libs/osgearth/osgearth.cpp @@ -2,7 +2,7 @@ ****************************************************************************** * * @file osgearth.cpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * @addtogroup * @{ * @addtogroup @@ -27,8 +27,8 @@ #include "osgearth.h" -#include "utility.h" -#include "qtwindowingsystem.h" +#include "utils/utility.h" +#include "utils/qtwindowingsystem.h" #include "utils/pathutils.h" @@ -38,11 +38,13 @@ #include #include +#ifdef USE_OSGEARTH #include #include #include #include #include +#endif #include @@ -69,10 +71,15 @@ void OsgEarth::registerQmlTypes() } registered = true; + // use "export OSG_NOTIFY_LEVEL=DEBUG" on command line to enable osg logging + // redirect osg logging to Qt + osg::setNotifyHandler(new QtNotifyHandler()); + // initialize(); // Register Qml types - osgQtQuick::registerTypes("osgQtQuick"); + qDebug() << "OsgEarth::registerQmlTypes - registering Qml types..."; + osgQtQuick::registerTypes(); } void OsgEarth::initialize() @@ -91,8 +98,8 @@ void OsgEarth::initialize() // setenv("OSG_ASSIGN_PBO_TO_IMAGES", "on", 0); // Number of threads in the DatbasePager set up, inclusive of the number of http dedicated threads. - osg::DisplaySettings::instance()->setNumOfDatabaseThreadsHint(6); - osg::DisplaySettings::instance()->setNumOfHttpDatabaseThreadsHint(3); + osg::DisplaySettings::instance()->setNumOfDatabaseThreadsHint(8); + osg::DisplaySettings::instance()->setNumOfHttpDatabaseThreadsHint(4); initializePathes(); @@ -100,12 +107,9 @@ void OsgEarth::initialize() initializeCache(); - // force early initialization of osgEarth capabilities - // Doing this too early (before main window is displayed) causes rendering glitches (black holes) - // Not sure why... See OSGViewport for when it is called (late...) - osgEarth::Registry::capabilities(); - +#ifdef OSG_VERBOSE displayInfo(); +#endif } void OsgEarth::initializePathes() @@ -123,46 +127,29 @@ void OsgEarth::initializePathes() void OsgEarth::initializeCache() { +#ifdef USE_OSGEARTH + QString cachePath = Utils::GetStoragePath() + "osgearth/cache"; - osgEarth::Drivers::FileSystemCacheOptions cacheOptions; + qputenv("OSGEARTH_CACHE_PATH", cachePath.toLatin1()); - cacheOptions.rootPath() = cachePath.toStdString(); + const osgEarth::CachePolicy cachePolicy(osgEarth::CachePolicy::USAGE_READ_WRITE); - osg::ref_ptr cache = osgEarth::CacheFactory::create(cacheOptions); - if (cache->isOK()) { - // set cache - osgEarth::Registry::instance()->setCache(cache.get()); + // The default cache policy used when no policy is set elsewhere + osgEarth::Registry::instance()->setDefaultCachePolicy(cachePolicy); - // set cache policy - const osgEarth::CachePolicy cachePolicy(osgEarth::CachePolicy::USAGE_READ_WRITE); + // The override cache policy (overrides all others if set) + // osgEarth::Registry::instance()->setOverrideCachePolicy(cachePolicy); - // The default cache policy used when no policy is set elsewhere - osgEarth::Registry::instance()->setDefaultCachePolicy(cachePolicy); - // The override cache policy (overrides all others if set) - // osgEarth::Registry::instance()->setOverrideCachePolicy(cachePolicy); - } else { - qWarning() << "OsgEarth::initializeCache - Failed to initialize cache"; - } - -// osgDB::SharedStateManager::ShareMode shareMode = osgDB::SharedStateManager::SHARE_NONE;// =osgDB::SharedStateManager::SHARE_ALL; -// shareMode = true ? static_cast(shareMode | osgDB::SharedStateManager::SHARE_STATESETS) : shareMode; -// shareMode = true ? static_cast(shareMode | osgDB::SharedStateManager::SHARE_TEXTURES) : shareMode; -// osgDB::Registry::instance()->getOrCreateSharedStateManager()->setShareMode(shareMode); - -// osgDB::Options::CacheHintOptions cacheHintOptions = osgDB::Options::CACHE_NONE; -// cacheHintOptions = static_cast(cacheHintOptions | osgDB::Options::CACHE_IMAGES); -// cacheHintOptions = static_cast(cacheHintOptions | osgDB::Options::CACHE_NODES); -// if (osgDB::Registry::instance()->getOptions() == 0) { -// osgDB::Registry::instance()->setOptions(new osgDB::Options()); -// } -// osgDB::Registry::instance()->getOptions()->setObjectCacheHint(cacheHintOptions); +#endif // ifdef USE_OSGEARTH } void OsgEarth::displayInfo() { qDebug() << "Using osg version :" << osgGetVersion(); +#ifdef USE_OSGEARTH qDebug() << "Using osgEarth version :" << osgEarthGetVersion(); +#endif // library file path list osgDB::FilePathList &libraryFilePathList = osgDB::Registry::instance()->getLibraryFilePathList(); @@ -190,7 +177,9 @@ void OsgEarth::displayInfo() qDebug() << "Platform supports threaded OpenGL:" << threadedOpenGL; #endif +#ifdef USE_OSGEARTH osgQtQuick::capabilitiesInfo(osgEarth::Registry::capabilities()); +#endif } void QtNotifyHandler::notify(osg::NotifySeverity severity, const char *message) @@ -232,7 +221,13 @@ void QtNotifyHandler::notify(osg::NotifySeverity severity, const char *message) } } +#if OSG_VERSION_GREATER_OR_EQUAL(3, 5, 3) +REGISTER_WINDOWINGSYSTEMINTERFACE(MyQt, QtWindowingSystem) +#endif + void OsgEarth::initWindowingSystem() { +#if OSG_VERSION_LESS_THAN(3, 5, 3) osg::GraphicsContext::setWindowingSystemInterface(QtWindowingSystem::getInterface()); +#endif } diff --git a/ground/gcs/src/libs/osgearth/osgearth.h b/ground/gcs/src/libs/osgearth/osgearth.h index 438c9865c..afe8b0bcd 100644 --- a/ground/gcs/src/libs/osgearth/osgearth.h +++ b/ground/gcs/src/libs/osgearth/osgearth.h @@ -2,7 +2,7 @@ ****************************************************************************** * * @file osgearth.h - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * @addtogroup * @{ * @addtogroup diff --git a/ground/gcs/src/libs/osgearth/osgearth.pri b/ground/gcs/src/libs/osgearth/osgearth.pri index 5a995f4f6..3224d5e8a 100644 --- a/ground/gcs/src/libs/osgearth/osgearth.pri +++ b/ground/gcs/src/libs/osgearth/osgearth.pri @@ -1,5 +1,8 @@ -exists( $(OSG_SDK_DIR) ) { - CONFIG += osg +osg { DEFINES += USE_OSG LIBS *= -l$$qtLibraryName(GCSOsgEarth) } + +osgearth { + DEFINES += USE_OSGEARTH +} diff --git a/ground/gcs/src/libs/osgearth/osgearth.pro b/ground/gcs/src/libs/osgearth/osgearth.pro index f8c3e4423..8780eafd2 100644 --- a/ground/gcs/src/libs/osgearth/osgearth.pro +++ b/ground/gcs/src/libs/osgearth/osgearth.pro @@ -2,6 +2,14 @@ TEMPLATE = lib TARGET = GCSOsgEarth DEFINES += OSGEARTH_LIBRARY +#DEFINES += OSG_VERBOSE + +osg:DEFINES += USE_OSG +osgQt:DEFINES += USE_OSG_QT + +osgearth:DEFINES += USE_OSGEARTH +osgearthQt:DEFINES += USE_OSGEARTH_QT + #DEFINES += OSG_USE_QT_PRIVATE QT += widgets opengl qml quick @@ -12,6 +20,8 @@ contains(DEFINES, OSG_USE_QT_PRIVATE) { include(../../library.pri) include(../utils/utils.pri) +include(osgearth_dependencies.pri) + linux { QMAKE_RPATHDIR = $$shell_quote(\$$ORIGIN/$$relative_path($$GCS_LIBRARY_PATH/osg, $$GCS_LIBRARY_PATH)) include(../../rpath.pri) @@ -23,82 +33,70 @@ macx:CONFIG += warn_off # osg and osgearth emit a lot of unused parameter warnings... QMAKE_CXXFLAGS += -Wno-unused-parameter -OSG_SDK_DIR = $$clean_path($$(OSG_SDK_DIR)) -message(Using osg from here: $$OSG_SDK_DIR) - HEADERS += \ osgearth_global.h \ - utility.h \ - qtwindowingsystem.h \ - osgearth.h + osgearth.h \ + utils/qtwindowingsystem.h \ + utils/utility.h \ + utils/shapeutils.h SOURCES += \ - utility.cpp \ - qtwindowingsystem.cpp \ - osgearth.cpp + osgearth.cpp \ + utils/qtwindowingsystem.cpp \ + utils/utility.cpp \ + utils/shapeutils.cpp HEADERS += \ osgQtQuick/Export.hpp \ + osgQtQuick/DirtySupport.hpp \ osgQtQuick/OSGNode.hpp \ osgQtQuick/OSGGroup.hpp \ osgQtQuick/OSGTransformNode.hpp \ - osgQtQuick/OSGCubeNode.hpp \ + osgQtQuick/OSGShapeNode.hpp \ + osgQtQuick/OSGImageNode.hpp \ osgQtQuick/OSGTextNode.hpp \ osgQtQuick/OSGFileNode.hpp \ - osgQtQuick/OSGModelNode.hpp \ - osgQtQuick/OSGBackgroundNode.hpp \ - osgQtQuick/OSGSkyNode.hpp \ + osgQtQuick/OSGBillboardNode.hpp \ osgQtQuick/OSGCamera.hpp \ osgQtQuick/OSGViewport.hpp SOURCES += \ + osgQtQuick/DirtySupport.cpp \ osgQtQuick/OSGNode.cpp \ osgQtQuick/OSGGroup.cpp \ osgQtQuick/OSGTransformNode.cpp \ - osgQtQuick/OSGCubeNode.cpp \ + osgQtQuick/OSGShapeNode.cpp \ + osgQtQuick/OSGImageNode.cpp \ osgQtQuick/OSGTextNode.cpp \ osgQtQuick/OSGFileNode.cpp \ - osgQtQuick/OSGModelNode.cpp \ - osgQtQuick/OSGBackgroundNode.cpp \ - osgQtQuick/OSGSkyNode.cpp \ + osgQtQuick/OSGBillboardNode.cpp \ osgQtQuick/OSGCamera.cpp \ osgQtQuick/OSGViewport.cpp -INCLUDEPATH += $$OSG_SDK_DIR/include +HEADERS += \ + osgQtQuick/ga/OSGCameraManipulator.hpp \ + osgQtQuick/ga/OSGNodeTrackerManipulator.hpp \ + osgQtQuick/ga/OSGTrackballManipulator.hpp -linux { - exists( $$OSG_SDK_DIR/lib64 ) { - LIBS += -L$$OSG_SDK_DIR/lib64 - } else { - LIBS += -L$$OSG_SDK_DIR/lib - } +SOURCES += \ + osgQtQuick/ga/OSGCameraManipulator.cpp \ + osgQtQuick/ga/OSGNodeTrackerManipulator.cpp \ + osgQtQuick/ga/OSGTrackballManipulator.cpp - LIBS +=-lOpenThreads - LIBS += -losg -losgUtil -losgDB -losgGA -losgViewer -losgText -losgQt - LIBS += -losgEarth -losgEarthUtil -losgEarthFeatures -losgEarthSymbology -losgEarthAnnotation -losgEarthQt -} +osgearth:HEADERS += \ + osgQtQuick/OSGSkyNode.hpp \ + osgQtQuick/OSGGeoTransformNode.hpp -macx { - LIBS += -L$$OSG_SDK_DIR/lib +osgearth:SOURCES += \ + osgQtQuick/OSGSkyNode.cpp \ + osgQtQuick/OSGGeoTransformNode.cpp - LIBS += -lOpenThreads - LIBS += -losg -losgUtil -losgDB -losgGA -losgViewer -losgText -losgQt - LIBS += -losgEarth -losgEarthUtil -losgEarthFeatures -losgEarthSymbology -losgEarthAnnotation -losgEarthQt -} +osgearth:HEADERS += \ + osgQtQuick/ga/OSGEarthManipulator.hpp \ + osgQtQuick/ga/OSGGeoTransformManipulator.hpp -win32 { - LIBS += -L$$OSG_SDK_DIR/lib +osgearth:SOURCES += \ + osgQtQuick/ga/OSGEarthManipulator.cpp \ + osgQtQuick/ga/OSGGeoTransformManipulator.cpp - CONFIG(release, debug|release) { - LIBS += -lOpenThreads - LIBS += -losg -losgUtil -losgDB -losgGA -losgViewer -losgText -losgQt - LIBS += -losgEarth -losgEarthUtil -losgEarthFeatures -losgEarthSymbology -losgEarthAnnotation -losgEarthQt - } - CONFIG(debug, debug|release) { - LIBS += -lOpenThreadsd - LIBS += -losgd -losgUtild -losgDBd -losgGAd -losgViewerd -losgTextd -losgQtd - LIBS += -losgEarthd -losgEarthUtild -losgEarthFeaturesd -losgEarthSymbologyd -losgEarthAnnotationd -losgEarthQtd - } -} - -include(copydata.pro) +copy_osg:include(copydata.pro) diff --git a/ground/gcs/src/libs/osgearth/osgearth_dependencies.pri b/ground/gcs/src/libs/osgearth/osgearth_dependencies.pri new file mode 100644 index 000000000..71092882e --- /dev/null +++ b/ground/gcs/src/libs/osgearth/osgearth_dependencies.pri @@ -0,0 +1,49 @@ +# osg and osgearth emit a lot of unused parameter warnings... +QMAKE_CXXFLAGS += -Wno-unused-parameter + +# set debug suffix if needed +win32:CONFIG(debug, debug|release):DS = "d" + +contains(QT_ARCH, x86_64) { + macx { + LIB_DIR_NAME = lib + } else { + LIB_DIR_NAME = lib64 + } +} else { + LIB_DIR_NAME = lib +} + +osg { + OSG_SDK_DIR = $$clean_path($$(OSG_SDK_DIR)) + message(Using osg from here: $$OSG_SDK_DIR) + + linux|macx { + INCLUDEPATH += $$OSG_SDK_DIR/include + LIBS += -L$$OSG_SDK_DIR/$$LIB_DIR_NAME + LIBS += -lOpenThreads -losg -losgUtil -losgDB -losgGA -losgFX -losgViewer -losgText + osgQt:LIBS += -losgQt + } + + win32 { + LIBS += -lOpenThreads$${DS} -losg$${DS} -losgUtil$${DS} -losgDB$${DS} -losgGA$${DS} -losgFX$${DS} -losgViewer$${DS} -losgText$${DS} + osgQt:LIBS += -losgQt$${DS} + } +} + +osgearth { + OSGEARTH_SDK_DIR = $$clean_path($$(OSGEARTH_SDK_DIR)) + message(Using osgearth from here: $$OSGEARTH_SDK_DIR) + + linux|macx { + INCLUDEPATH += $$OSGEARTH_SDK_DIR/include + LIBS += -L$$OSGEARTH_SDK_DIR/$$LIB_DIR_NAME + LIBS += -losgEarth -losgEarthUtil -losgEarthFeatures -losgEarthSymbology -losgEarthAnnotation + osgearthQt:LIBS += -losgEarthQt + } + + win32 { + LIBS += -losgEarth$${DS} -losgEarthUtil$${DS} -losgEarthFeatures$${DS} -losgEarthSymbology$${DS} -losgEarthAnnotation$${DS} + osgearthQt:LIBS += -losgEarthQt$${DS} + } +} diff --git a/ground/gcs/src/libs/osgearth/osgearth_global.h b/ground/gcs/src/libs/osgearth/osgearth_global.h index dc4fa1b11..a06c850a2 100644 --- a/ground/gcs/src/libs/osgearth/osgearth_global.h +++ b/ground/gcs/src/libs/osgearth/osgearth_global.h @@ -2,7 +2,7 @@ ****************************************************************************** * * @file osgearth_global.h - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * @addtogroup * @{ * @addtogroup diff --git a/ground/gcs/src/libs/osgearth/readme.txt b/ground/gcs/src/libs/osgearth/readme.txt index 3937dae12..b6fddbc68 100644 --- a/ground/gcs/src/libs/osgearth/readme.txt +++ b/ground/gcs/src/libs/osgearth/readme.txt @@ -4,3 +4,6 @@ References : - https://wiki.qt.io/OsgQtQuick-Demo - https://github.com/podsvirov - https://github.com/podsvirov/osgqtquick + +known issues: +- http://forum.osgearth.org/VERTEX-glCompileShader-quot-oe-mp-vertModel-quot-FAILED-tt7588106.html#none diff --git a/ground/gcs/src/libs/osgearth/qtwindowingsystem.cpp b/ground/gcs/src/libs/osgearth/utils/qtwindowingsystem.cpp similarity index 82% rename from ground/gcs/src/libs/osgearth/qtwindowingsystem.cpp rename to ground/gcs/src/libs/osgearth/utils/qtwindowingsystem.cpp index 6eac26a29..2ae29b220 100644 --- a/ground/gcs/src/libs/osgearth/qtwindowingsystem.cpp +++ b/ground/gcs/src/libs/osgearth/utils/qtwindowingsystem.cpp @@ -2,7 +2,7 @@ ****************************************************************************** * * @file qtwindowingsystem.cpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * @addtogroup * @{ * @addtogroup @@ -30,6 +30,7 @@ #include "utility.h" #include +#include #include #include @@ -85,7 +86,6 @@ protected: bool _initialized; bool _valid; bool _realized; - bool _closing; bool _owned; @@ -97,39 +97,25 @@ GraphicsWindowQt::GraphicsWindowQt(osg::GraphicsContext::Traits *traits) : _initialized(false), _valid(false), _realized(false), - _closing(false), _owned(false), _glContext(NULL), _surface(NULL) { - qDebug() << "GraphicsWindowQt::GraphicsWindowQt"; + // qDebug() << "GraphicsWindowQt::GraphicsWindowQt"; _traits = traits; - init(); - - if (valid()) { - setState(new osg::State); - getState()->setGraphicsContext(this); - - if (_traits.valid() && _traits->sharedContext.valid()) { - getState()->setContextID(_traits->sharedContext->getState()->getContextID()); - incrementContextIDUsageCount(getState()->getContextID()); - } else { - getState()->setContextID(osg::GraphicsContext::createNewContextID()); - } - } } GraphicsWindowQt::~GraphicsWindowQt() { - qDebug() << "GraphicsWindowQt::~GraphicsWindowQt"; - close(); + // qDebug() << "GraphicsWindowQt::~GraphicsWindowQt"; + close(true); } void GraphicsWindowQt::init() { - qDebug() << "GraphicsWindowQt::init"; - if (_closing || _initialized) { + // qDebug() << "GraphicsWindowQt::init"; + if (_initialized) { return; } @@ -140,6 +126,24 @@ void GraphicsWindowQt::init() // if ( !parent ) // parent = windowData ? windowData->_parent : NULL; + + setState(new osg::State); + getState()->setGraphicsContext(this); + + if (_traits.valid() && _traits->sharedContext.valid()) { + getState()->setContextID(_traits->sharedContext->getState()->getContextID()); + incrementContextIDUsageCount(getState()->getContextID()); + } else { + getState()->setContextID(osg::GraphicsContext::createNewContextID()); + } + + // make sure the event queue has the correct window rectangle size and input range +#if OSG_VERSION_GREATER_OR_EQUAL(3, 4, 0) + getEventQueue()->syncWindowRectangleWithGraphicsContext(); +#else + getEventQueue()->syncWindowRectangleWithGraphcisContext(); +#endif + _initialized = true; _valid = _initialized; @@ -193,7 +197,7 @@ bool GraphicsWindowQt::valid() const bool GraphicsWindowQt::realizeImplementation() { - qDebug() << "GraphicsWindowQt::realizeImplementation"; + // qDebug() << "GraphicsWindowQt::realizeImplementation"; // save the current context // note: this will save only Qt-based contexts @@ -211,16 +215,18 @@ bool GraphicsWindowQt::realizeImplementation() QOpenGLContext *currentContext = QOpenGLContext::currentContext(); if (!currentContext) { - qDebug() << "GraphicsWindowQt::realizeImplementation - creating owned context"; + // qDebug() << "GraphicsWindowQt::realizeImplementation - creating owned context"; _owned = true; _glContext = new QOpenGLContext(); _glContext->create(); _surface = new QOffscreenSurface(); _surface->setFormat(_glContext->format()); _surface->create(); +#ifdef OSG_VERBOSE osgQtQuick::formatInfo(_surface->format()); +#endif } else { - qDebug() << "GraphicsWindowQt::realizeImplementation - using current context"; + // qDebug() << "GraphicsWindowQt::realizeImplementation - using current context"; _glContext = currentContext; } @@ -230,22 +236,24 @@ bool GraphicsWindowQt::realizeImplementation() // make current _realized = true; - bool result = makeCurrent(); - _realized = false; + bool current = makeCurrent(); // fail if we do not have current context - if (!result) { + if (!current) { // if ( savedContext ) // const_cast< QGLContext* >( savedContext )->makeCurrent(); // qWarning() << "GraphicsWindowQt::realizeImplementation - can not make context current."; + _realized = false; return false; } - _realized = true; - -//// make sure the event queue has the correct window rectangle size and input range -// getEventQueue()->syncWindowRectangleWithGraphcisContext(); + // make sure the event queue has the correct window rectangle size and input range +#if OSG_VERSION_GREATER_OR_EQUAL(3, 4, 0) + getEventQueue()->syncWindowRectangleWithGraphicsContext(); +#else + getEventQueue()->syncWindowRectangleWithGraphcisContext(); +#endif // make this window's context not current // note: this must be done as we will probably make the context current from another thread @@ -258,7 +266,7 @@ bool GraphicsWindowQt::realizeImplementation() // if ( savedContext ) // const_cast< QGLContext* >( savedContext )->makeCurrent(); - return true; + return _realized; } bool GraphicsWindowQt::isRealizedImplementation() const @@ -282,12 +290,15 @@ void GraphicsWindowQt::runOperations() bool GraphicsWindowQt::makeCurrentImplementation() { + if (!_glContext) { + qWarning() << "GraphicsWindowQt::makeCurrentImplementation() - no context."; + return false; + } if (!_realized) { qWarning() << "GraphicsWindowQt::makeCurrentImplementation() - not realized; cannot make current."; return false; } - if (_owned && _glContext) { - // qDebug() << "GraphicsWindowQt::makeCurrentImplementation : " << _surface; + if (_owned) { if (!_glContext->makeCurrent(_surface)) { qWarning() << "GraphicsWindowQt::makeCurrentImplementation : failed to make context current"; return false; @@ -295,6 +306,7 @@ bool GraphicsWindowQt::makeCurrentImplementation() } if (_glContext != QOpenGLContext::currentContext()) { qWarning() << "GraphicsWindowQt::makeCurrentImplementation : context is not current"; + // abort(); return false; } return true; @@ -302,27 +314,33 @@ bool GraphicsWindowQt::makeCurrentImplementation() bool GraphicsWindowQt::releaseContextImplementation() { + if (!_glContext) { + qWarning() << "GraphicsWindowQt::releaseContextImplementation() - no context."; + return false; + } if (_glContext != QOpenGLContext::currentContext()) { qWarning() << "GraphicsWindowQt::releaseContextImplementation : context is not current"; return false; } - if (_owned && _glContext) { - qDebug() << "GraphicsWindowQt::releaseContextImplementation"; + if (_owned) { + // qDebug() << "GraphicsWindowQt::releaseContextImplementation"; _glContext->doneCurrent(); + if (_glContext == QOpenGLContext::currentContext()) { + qWarning() << "GraphicsWindowQt::releaseContextImplementation : context is still current"; + } } return true; } void GraphicsWindowQt::closeImplementation() { - qDebug() << "GraphicsWindowQt::closeImplementation"; - _closing = true; + // qDebug() << "GraphicsWindowQt::closeImplementation"; _initialized = false; _valid = false; _realized = false; if (_owned) { if (_glContext) { - qDebug() << "GraphicsWindowQt::closeImplementation - deleting owned context"; + // qDebug() << "GraphicsWindowQt::closeImplementation - deleting owned context"; delete _glContext; } if (_surface) { diff --git a/ground/gcs/src/libs/osgearth/qtwindowingsystem.h b/ground/gcs/src/libs/osgearth/utils/qtwindowingsystem.h similarity index 99% rename from ground/gcs/src/libs/osgearth/qtwindowingsystem.h rename to ground/gcs/src/libs/osgearth/utils/qtwindowingsystem.h index 958c04fb1..f23079f47 100644 --- a/ground/gcs/src/libs/osgearth/qtwindowingsystem.h +++ b/ground/gcs/src/libs/osgearth/utils/qtwindowingsystem.h @@ -2,7 +2,7 @@ ****************************************************************************** * * @file qtwindowingsystem.h - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * @addtogroup * @{ * @addtogroup diff --git a/ground/gcs/src/libs/osgearth/utils/shapeutils.cpp b/ground/gcs/src/libs/osgearth/utils/shapeutils.cpp new file mode 100644 index 000000000..6cd6bfb8d --- /dev/null +++ b/ground/gcs/src/libs/osgearth/utils/shapeutils.cpp @@ -0,0 +1,447 @@ +#include "utils/shapeutils.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ShapeUtils { +osg::Geode *createSphere(const osg::Vec4 &color, float radius) +{ + osg::TessellationHints *sphereHints = new osg::TessellationHints; + // sphereHints->setDetailRatio(0.1f); + // sphereHints->setCreateBody(true); + osg::Sphere *sphere = new osg::Sphere(osg::Vec3(0, 0, 0), radius); + osg::ShapeDrawable *sphereDrawable = new osg::ShapeDrawable(sphere, sphereHints); + + sphereDrawable->setColor(color); + + osg::Geode *geode = new osg::Geode; + geode->addDrawable(sphereDrawable); + + return geode; +} + +osg::Geode *createCube() +{ + // Declare a group to act as root node of a scene: + // osg::Group* root = new osg::Group(); + + // Declare a box class (derived from shape class) instance + // This constructor takes an osg::Vec3 to define the center + // and a float to define the height, width and depth. + // (an overloaded constructor allows you to specify unique + // height, width and height values.) + osg::Box *unitCube = new osg::Box(osg::Vec3(0, 0, 0), 1.0f); + + // Declare an instance of the shape drawable class and initialize + // it with the unitCube shape we created above. + // This class is derived from 'drawable' so instances of this + // class can be added to Geode instances. + osg::ShapeDrawable *unitCubeDrawable = new osg::ShapeDrawable(unitCube); + + // Declare a instance of the geode class: + osg::Geode *geode = new osg::Geode(); + + // Add the unit cube drawable to the geode: + geode->addDrawable(unitCubeDrawable); + + // osg::PolygonMode *pm = new osg::PolygonMode(); + // pm->setMode( osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE ); + // + // osg::StateSet *stateSet = new osg::StateSet(); + // stateSet->setAttributeAndModes( pm, + // osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON ); + // geode->setStateSet(stateSet); + + // Add the geode to the scene: + return geode; +} + +osg::PositionAttitudeTransform *createArrow(const osg::Vec4 &color) +{ + osg::ref_ptr geode = new osg::Geode; + + double radius = 0.04; + + osg::TessellationHints *cylinderHints = new osg::TessellationHints; + + cylinderHints->setDetailRatio(0.1f); + cylinderHints->setCreateBody(true); + // cylinderHints->setCreateFrontFace(false); + // cylinderHints->setCreateBackFace(false); + osg::Cylinder *cylinder = new osg::Cylinder(osg::Vec3(0, 0, 0.4), radius, 0.8); + // cylinder->setRotation(quat); + osg::ShapeDrawable *cylinderDrawable = new osg::ShapeDrawable(cylinder, cylinderHints); + cylinderDrawable->setColor(color); + geode->addDrawable(cylinderDrawable); + + osg::TessellationHints *coneHints = new osg::TessellationHints; + coneHints->setDetailRatio(0.5f); + coneHints->setCreateBottom(true); + osg::Cone *cone = new osg::Cone(osg::Vec3(0, 0, 0.8), radius * 2, 0.2); + // cone->setRotation(quat); + osg::ShapeDrawable *coneDrawable = new osg::ShapeDrawable(cone, coneHints); + coneDrawable->setColor(color); + geode->addDrawable(coneDrawable); + + osg::PositionAttitudeTransform *transform = new osg::PositionAttitudeTransform(); + transform->addChild(geode); + + return transform; +} + +osg::Node *create3DAxis() +{ + osg::PositionAttitudeTransform *xAxis = createArrow(osg::Vec4(1, 0, 0, 1)); + + xAxis->setAttitude(osg::Quat(M_PI / 2.0, osg::Vec3(0, 1, 0))); + + osg::PositionAttitudeTransform *yAxis = createArrow(osg::Vec4(0, 1, 0, 1)); + yAxis->setAttitude(osg::Quat(-M_PI / 2.0, osg::Vec3(1, 0, 0))); + + osg::PositionAttitudeTransform *zAxis = createArrow(osg::Vec4(0, 0, 1, 1)); + + osg::Node *center = createSphere(osg::Vec4(0.7, 0.7, .7, 1), 0.08); + + osg::Group *group = new osg::Group(); + group->addChild(xAxis); + group->addChild(yAxis); + group->addChild(zAxis); + group->addChild(center); + return group; +} + +osg::Node *createOrientatedTorus(float innerRadius, float outerRadius) +{ + osg::Node *node = createTorus(innerRadius, outerRadius, 64, 32); + + osg::PositionAttitudeTransform *transform = new osg::PositionAttitudeTransform(); + + transform->addChild(node); + + osg::Quat q = osg::Quat( + M_PI / 2, osg::Vec3d(1, 0, 0), + 0, osg::Vec3d(0, 1, 0), + 0, osg::Vec3d(0, 0, 1)); + transform->setAttitude(q); + + // transform->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON); + // node->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL, osg::StateAttribute::ON); + + return transform; +} + +osg::Geode *createTorus(float innerRadius, float outerRadius, float sweepCuts, float sphereCuts) +{ + osg::ref_ptr geode = new osg::Geode; + + bool create_body = true; + + if (create_body) { + float inner = innerRadius; + float outer = outerRadius; + float tube_radius = (outer - inner) * 0.5; + float avg_center = (inner + outer) * 0.5; + + float start_sweep = 0; // this->getStartSweep(); + float end_sweep = osg::DegreesToRadians(360.0); // this->getEndSweep(); + + int torus_sweeps = sweepCuts; + int sphere_sweeps = sphereCuts; + + float dsweep = (end_sweep - start_sweep) / (float)torus_sweeps; + float dphi = osg::DegreesToRadians(360.0) / (float)sphere_sweeps; + + for (int j = 0; j < sphere_sweeps; j++) { + osg::Vec3Array *vertices = new osg::Vec3Array; + osg::Vec3Array *normals = new osg::Vec3Array; + + float phi = dphi * (float)j; + float cosPhi = cosf(phi); + float sinPhi = sinf(phi); + float next_cosPhi = cosf(phi + dphi); + float next_sinPhi = sinf(phi + dphi); + + float z = tube_radius * sinPhi; + float yPrime = avg_center + tube_radius * cosPhi; + + float next_z = tube_radius * next_sinPhi; + float next_yPrime = avg_center + tube_radius * next_cosPhi; + + float old_x = yPrime * cosf(-dsweep); + float old_y = yPrime * sinf(-dsweep); + float old_z = z; + + for (int i = 0; i < torus_sweeps; ++i) { + float sweep = start_sweep + dsweep * i; + float cosSweep = cosf(sweep); + float sinSweep = sinf(sweep); + + float x = yPrime * cosSweep; + float y = yPrime * sinSweep; + + float next_x = next_yPrime * cosSweep; + float next_y = next_yPrime * sinSweep; + + vertices->push_back(osg::Vec3(next_x, next_y, next_z)); + vertices->push_back(osg::Vec3(x, y, z)); + + // calculate normals + osg::Vec3 lateral(next_x - x, next_y - y, next_z - z); + osg::Vec3 longitudinal(x - old_x, y - old_y, z - old_z); + osg::Vec3 normal = longitudinal ^ lateral; // cross product + normal.normalize(); + + normals->push_back(normal); + normals->push_back(normal); + + old_x = x; + old_y = y; + old_z = z; + } // end torus loop + + // the last point + float last_sweep = start_sweep + end_sweep; + float cosLastSweep = cosf(last_sweep); + float sinLastSweep = sinf(last_sweep); + + float x = yPrime * cosLastSweep; + float y = yPrime * sinLastSweep; + + float next_x = next_yPrime * cosLastSweep; + float next_y = next_yPrime * sinLastSweep; + + vertices->push_back(osg::Vec3(next_x, next_y, next_z)); + vertices->push_back(osg::Vec3(x, y, z)); + + osg::Vec3 lateral(next_x - x, next_y - y, next_z - z); + osg::Vec3 longitudinal(x - old_x, y - old_y, z - old_z); + osg::Vec3 norm = longitudinal ^ lateral; + norm.normalize(); + + normals->push_back(norm); + normals->push_back(norm); + + osg::ShadeModel *shademodel = new osg::ShadeModel; + shademodel->setMode(osg::ShadeModel::SMOOTH); + + osg::StateSet *stateset = new osg::StateSet; + stateset->setAttribute(shademodel); + + osg::ref_ptr geometry = new osg::Geometry; + geometry->setStateSet(stateset); + + geometry->setVertexArray(vertices); + + osg::Vec4Array *colors = new osg::Vec4Array; + colors->push_back(osg::Vec4(1.0, 1.0, 0.0, 1.0)); // this->getColor()); + geometry->setColorArray(colors); + geometry->setColorBinding(osg::Geometry::BIND_OVERALL); + + geometry->setNormalArray(normals); + geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); + + geometry->addPrimitiveSet( + new osg::DrawArrays(osg::PrimitiveSet::QUAD_STRIP, 0, + vertices->size())); + geode->addDrawable(geometry.get()); + } // end cirle loop + } // endif create_body + + return geode.release(); +} + +osg::Geode *createRhombicuboctahedron() +{ + // Top * + // Bottom o + // Front ^ + // Stern v + // Left < + // Right > + const double alpha = 1; // 0.65; + const osg::Vec4 colors[] = { + osg::Vec4(0.7, 0.5, 0.7, alpha), // TFR + osg::Vec4(0.9, 0.9, 0.9, alpha), // T + osg::Vec4(0.5, 0.7, 0.7, alpha), // TFL + osg::Vec4(1.0, 0.7, 0.7, alpha), // TS + osg::Vec4(0.7, 0.7, 1.0, alpha), // TF + osg::Vec4(0.5, 0.0, 0.7, alpha), // BFR + osg::Vec4(0.5, 0.5, 1.0, alpha), // F + osg::Vec4(0.1, 0.5, 0.7, alpha), // BFL + osg::Vec4(0.9, 0.5, 0.9, alpha), // TR + osg::Vec4(0.5, 0.0, 0.5, alpha), // R + osg::Vec4(1.0, 0.5, 0.7, alpha), // TSR + osg::Vec4(0.2, 0.0, 0.2, alpha), // BR + osg::Vec4(0.2, 0.2, 1.0, alpha), // BF + osg::Vec4(0.7, 0.0, 0.2, alpha), // BSR + osg::Vec4(0.1, 0.1, 0.1, alpha), // B + osg::Vec4(0.5, 0.5, 0.2, alpha), // BSL + osg::Vec4(0.9, 0.0, 0.4, alpha), // SR + osg::Vec4(1.0, 0.2, 0.2, alpha), // BS + osg::Vec4(1.0, 0.5, 0.5, alpha), // S + osg::Vec4(0.7, 0.7, 0.5, alpha), // SL + osg::Vec4(0.5, 0.9, 0.5, alpha), // TL + osg::Vec4(0.5, 0.7, 0.5, alpha), // L + osg::Vec4(1.0, 1.0, 0.7, alpha), // TSL + osg::Vec4(0.2, 0.5, 0.2, alpha), // BL + osg::Vec4(0.5, 0.0, 0.8, alpha), // FR + osg::Vec4(0.5, 0.7, 1.0, alpha) // FL + }; + + const double no = -1.0; + const double po = 1.0f; + const double ps = 1.0 + sqrt(1.0); + const double ns = -ps; + const osg::Vec3 vertices[] = { + osg::Vec3(po, po, ps), + osg::Vec3(po, no, ps), + osg::Vec3(no, po, ps), + osg::Vec3(no, no, ps), + + osg::Vec3(po, ps, po), + osg::Vec3(po, ps, no), + osg::Vec3(no, ps, po), + osg::Vec3(no, ps, no), + + osg::Vec3(ps, po, po), + osg::Vec3(ps, po, no), + osg::Vec3(ps, no, po), + osg::Vec3(ps, no, no), + + osg::Vec3(po, po, ns), + osg::Vec3(po, no, ns), + osg::Vec3(no, po, ns), + osg::Vec3(no, no, ns), + + osg::Vec3(po, ns, po), + osg::Vec3(po, ns, no), + osg::Vec3(no, ns, po), + osg::Vec3(no, ns, no), + + osg::Vec3(ns, po, po), + osg::Vec3(ns, po, no), + osg::Vec3(ns, no, po), + osg::Vec3(ns, no, no), + + // bonus vertices to map unique colors + // we have only 24 regular vertices, but 26 faces + osg::Vec3(ps, po, no), // copy from vertex 9 + osg::Vec3(no, ps, no) // copy from vertex 7 + }; + + const unsigned int indices[] = { + // PITCH ROLL YAW + 8, 4, 0, // TFR 45 -45 + + 0, 2, 1, // T1 0 0 + 3, 2, 1, // T2 + + 6, 20, 2, // TFL 45 45 + + 1, 16, 3, // TS1 -45 0 + 18, 16, 3, // TS2 + + 0, 2, 4, // TF1 45 0 + 6, 2, 4, // TF2 + + 12, 9, 5, // BFR 45 -135 + + 4, 5, 6, // F1 90 X + 7, 5, 6, // F2 + + 14, 21, 7, // BFL 45 135 + + 0, 1, 8, // TR1 0 -45 + 10, 1, 8, // TR2 + + 8, 10, 9, // R1 0 -90 + 11, 10, 9, // R2 + + 1, 16, 10, // TSR -45 -45 + // PITCH ROLL YAW + 13, 12, 11, // BR1 0 -135 + 9, 12, 11, // BR2 + + 5, 7, 12, // BF1 45 +-180 + 14, 7, 12, // BF2 + + 11, 17, 13, // BSR -45 -135 + + 12, 13, 14, // B1 0 +-180 + 15, 13, 14, // B2 + + 19, 23, 15, // BSL -45 135 + + 11, 17, 16, // SR1 -45 -90 + 11, 10, 16, // SR2 + + 13, 15, 17, // BS1 -45 +-180 + 19, 15, 17, // BS2 + + 16, 17, 18, // S1 -90 X + 19, 17, 18, // S2 + + 18, 22, 19, // SL -45 90 + 22, 23, 19, // SL + // PITCH ROLL YAW + 2, 3, 20, // TL1 0 45 + 22, 3, 20, // TL2 + + 20, 22, 21, // L1 0 90 + 23, 22, 21, // L2 + + 3, 18, 22, // TSL -45 45 + + 14, 15, 23, // BL1 0 135 + 14, 21, 23, // BL2 + + // last vertex is equal to vertex 9 to map a unique color + 4, 5, 24, // FR 45 -90 + 4, 8, 24, // FR + + // last vertex is equal to vertex 7 to map a unique color + 6, 20, 25, // FL 45 90 + 21, 20, 25 // FL + }; + + osg::ShadeModel *shademodel = new osg::ShadeModel; + + shademodel->setMode(osg::ShadeModel::FLAT); + + osg::StateSet *stateset = new osg::StateSet; + stateset->setAttribute(shademodel); + + osg::ref_ptr geom = new osg::Geometry; + + geom->setStateSet(stateset); + + unsigned int vertexCount = sizeof(vertices) / sizeof(vertices[0]); + osg::Vec3Array *vertexArray = new osg::Vec3Array(vertexCount, const_cast(&vertices[0])); + geom->setVertexArray(vertexArray); + + unsigned int indexCount = sizeof(indices) / sizeof(indices[0]); + geom->addPrimitiveSet(new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, indexCount, indices)); + + unsigned int colorCount = sizeof(colors) / sizeof(colors[0]); + osg::Vec4Array *colorArray = new osg::Vec4Array(colorCount, const_cast(&colors[0])); + geom->setColorArray(colorArray); + geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX); + + // geometry->setNormalArray(normals); + // geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); + + osg::ref_ptr geode = new osg::Geode; + geode->addDrawable(geom.get()); + + return geode.release(); +} +} diff --git a/ground/gcs/src/libs/osgearth/utils/shapeutils.h b/ground/gcs/src/libs/osgearth/utils/shapeutils.h new file mode 100644 index 000000000..c19387c62 --- /dev/null +++ b/ground/gcs/src/libs/osgearth/utils/shapeutils.h @@ -0,0 +1,22 @@ +#ifndef SHAPE_UTILS_H +#define SHAPE_UTILS_H + +#include + +namespace osg { +class Node; +class Geode; +class PositionAttitudeTransform; +} + +namespace ShapeUtils { +osg::Geode *createCube(); +osg::Geode *createSphere(const osg::Vec4 &color, float radius); +osg::PositionAttitudeTransform *createArrow(const osg::Vec4 &color); +osg::Node *create3DAxis(); +osg::Node *createOrientatedTorus(float innerRadius, float outerRadius); +osg::Geode *createTorus(float innerRadius, float outerRadius, float sweepCuts, float sphereCuts); +osg::Geode *createRhombicuboctahedron(); +} + +#endif /* SHAPE_UTILS_H */ diff --git a/ground/gcs/src/libs/osgearth/utility.cpp b/ground/gcs/src/libs/osgearth/utils/utility.cpp similarity index 84% rename from ground/gcs/src/libs/osgearth/utility.cpp rename to ground/gcs/src/libs/osgearth/utils/utility.cpp index becac109b..82981be2d 100644 --- a/ground/gcs/src/libs/osgearth/utility.cpp +++ b/ground/gcs/src/libs/osgearth/utils/utility.cpp @@ -2,7 +2,7 @@ ****************************************************************************** * * @file utility.cpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * @addtogroup * @{ * @addtogroup @@ -25,23 +25,27 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "utility.h" +#include "utils/utility.h" // osgQtQuick qml types #include "osgQtQuick/OSGNode.hpp" #include "osgQtQuick/OSGGroup.hpp" #include "osgQtQuick/OSGFileNode.hpp" #include "osgQtQuick/OSGTransformNode.hpp" -#include "osgQtQuick/OSGCubeNode.hpp" +#include "osgQtQuick/OSGShapeNode.hpp" +#include "osgQtQuick/OSGImageNode.hpp" #include "osgQtQuick/OSGTextNode.hpp" -#include "osgQtQuick/OSGModelNode.hpp" -#include "osgQtQuick/OSGBackgroundNode.hpp" -#include "osgQtQuick/OSGSkyNode.hpp" +#include "osgQtQuick/OSGBillboardNode.hpp" #include "osgQtQuick/OSGCamera.hpp" #include "osgQtQuick/OSGViewport.hpp" +#include "osgQtQuick/ga/OSGCameraManipulator.hpp" +#include "osgQtQuick/ga/OSGNodeTrackerManipulator.hpp" +#include "osgQtQuick/ga/OSGTrackballManipulator.hpp" + #include #include +#include #include #include #include @@ -53,13 +57,23 @@ #include #include #include + +#ifdef USE_OSG_QT #include +#endif // USE_OSG_QT + +#ifdef USE_OSGEARTH +#include "osgQtQuick/OSGSkyNode.hpp" +#include "osgQtQuick/OSGGeoTransformNode.hpp" + +#include "osgQtQuick/ga/OSGEarthManipulator.hpp" +#include "osgQtQuick/ga/OSGGeoTransformManipulator.hpp" #include -#include #include #include #include +#endif // USE_OSGEARTH #include #include @@ -69,14 +83,16 @@ namespace osgQtQuick { class CullCallback : public osg::NodeCallback { public: - CullCallback() {} + CullCallback() + {} - virtual ~CullCallback() {} + virtual ~CullCallback() + {} public: virtual void operator()(osg::Node *node, osg::NodeVisitor *nv) { - osgUtil::CullVisitor *cv = osgEarth::Culling::asCullVisitor(nv); + osgUtil::CullVisitor *cv = 0; // osgEarth::Culling::asCullVisitor(nv); if (cv) { OSG_DEBUG << "****** Node:" << node << " " << node->getName() << std::endl; @@ -95,12 +111,14 @@ class InsertCallbacksVisitor : public osg::NodeVisitor { public: InsertCallbacksVisitor() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} + virtual void apply(osg::Node & node) { // node.setUpdateCallback(new UpdateCallback()); node.setCullCallback(new CullCallback()); traverse(node); } + virtual void apply(osg::Geode & geode) { // geode.setUpdateCallback(new UpdateCallback()); @@ -116,6 +134,7 @@ public: // geode.getDrawable(i)->setDrawCallback(new DrawableDrawCallback()); // } } + virtual void apply(osg::Transform & node) { apply((osg::Node &)node); @@ -150,12 +169,19 @@ osgText::Font *createFont(const std::string &name) return 0; } - return new osgText::Font(new osgQt::QFontImplementation(font)); + return createFont(font); } osgText::Font *createFont(const QFont &font) { +#ifdef USE_OSG_QT return new osgText::Font(new osgQt::QFontImplementation(font)); + +#else + qWarning() << "Cannot create osgText::Font from QFont (osgQt is not available)"; + return osgText::Font::getDefaultFont(); + +#endif // USE_OSG_QT } osgText::Text *createText(const osg::Vec3 &pos, const std::string &content, float size, osgText::Font *font) @@ -250,40 +276,6 @@ int QtKeyboardMap::remapKey(QKeyEvent *event) return itr->second; } -osgEarth::GeoPoint toGeoPoint(const QVector3D &position) -{ - osgEarth::GeoPoint geoPoint(osgEarth::SpatialReference::get("wgs84"), - position.x(), position.y(), position.z(), osgEarth::ALTMODE_ABSOLUTE); - - return geoPoint; -} - -bool clampGeoPoint(osgEarth::GeoPoint &geoPoint, float offset, osgEarth::MapNode *mapNode) -{ - if (!mapNode) { - qWarning() << "Utility::clampGeoPoint - null map node"; - return false; - } - - // establish an elevation query interface based on the features' SRS. - osgEarth::ElevationQuery eq(mapNode->getMap()); - // qDebug() << "Utility::clampGeoPoint - SRS :" << QString::fromStdString(mapNode->getMap()->getSRS()->getName()); - - bool clamped = false; - double elevation; - if (eq.getElevation(geoPoint, elevation, 0.0)) { - clamped = ((geoPoint.z() - offset) < elevation); - if (clamped) { - qDebug() << "Utility::clampGeoPoint - clamping" << geoPoint.z() - offset << "/" << elevation; - geoPoint.z() = elevation + offset; - } - } else { - qDebug() << "Utility::clampGeoPoint - failed to get elevation"; - } - - return clamped; -} - QSurfaceFormat traitsToFormat(const osg::GraphicsContext::Traits *traits) { QSurfaceFormat format(QSurfaceFormat::defaultFormat()); @@ -298,9 +290,9 @@ QSurfaceFormat traitsToFormat(const osg::GraphicsContext::Traits *traits) // format.setSampleBuffers(traits->sampleBuffers); format.setSamples(traits->samples); -// format.setAlpha(traits->alpha > 0); -// format.setDepth(traits->depth > 0); -// format.setStencil(traits->stencil > 0); + // format.setAlpha(traits->alpha > 0); + // format.setDepth(traits->depth > 0); + // format.setStencil(traits->stencil > 0); format.setStereo(traits->quadBufferStereo ? 1 : 0); @@ -395,44 +387,6 @@ void traitsInfo(const osg::GraphicsContext::Traits &traits) // qDebug().nospace() << "swapInterval : " << traits.swapInterval(); } -void capabilitiesInfo(const osgEarth::Capabilities &caps) -{ - qDebug().nospace() << "capabilities ----------------------------------------"; - - qDebug().nospace() << "Vendor : " << QString::fromStdString(caps.getVendor()); - qDebug().nospace() << "Version : " << QString::fromStdString(caps.getVersion()); - qDebug().nospace() << "Renderer : " << QString::fromStdString(caps.getRenderer()); - - qDebug().nospace() << "GLSL supported : " << caps.supportsGLSL(); - qDebug().nospace() << "GLSL version : " << caps.getGLSLVersionInt(); - - qDebug().nospace() << "GLES : " << caps.isGLES(); - - qDebug().nospace() << "Num Processors : " << caps.getNumProcessors(); - - qDebug().nospace() << "MaxFFPTextureUnits : " << caps.getMaxFFPTextureUnits(); - qDebug().nospace() << "MaxGPUTextureUnits : " << caps.getMaxGPUTextureUnits(); - qDebug().nospace() << "MaxGPUAttribs : " << caps.getMaxGPUAttribs(); - qDebug().nospace() << "MaxTextureSize : " << caps.getMaxTextureSize(); - qDebug().nospace() << "MaxLights : " << caps.getMaxLights(); - qDebug().nospace() << "DepthBufferBits : " << caps.getDepthBufferBits(); - qDebug().nospace() << "TextureArrays : " << caps.supportsTextureArrays(); - qDebug().nospace() << "Texture3D : " << caps.supportsTexture3D(); - qDebug().nospace() << "MultiTexture : " << caps.supportsMultiTexture(); - qDebug().nospace() << "StencilWrap : " << caps.supportsStencilWrap(); - qDebug().nospace() << "TwoSidedStencil : " << caps.supportsTwoSidedStencil(); - qDebug().nospace() << "Texture2DLod : " << caps.supportsTexture2DLod(); - qDebug().nospace() << "MipmappedTextureUpdates : " << caps.supportsMipmappedTextureUpdates(); - qDebug().nospace() << "DepthPackedStencilBuffer : " << caps.supportsDepthPackedStencilBuffer(); - qDebug().nospace() << "OcclusionQuery : " << caps.supportsOcclusionQuery(); - qDebug().nospace() << "DrawInstanced : " << caps.supportsDrawInstanced(); - qDebug().nospace() << "UniformBufferObjects : " << caps.supportsUniformBufferObjects(); - qDebug().nospace() << "NonPowerOfTwoTextures : " << caps.supportsNonPowerOfTwoTextures(); - qDebug().nospace() << "MaxUniformBlockSize : " << caps.getMaxUniformBlockSize(); - qDebug().nospace() << "PreferDisplayListsForStaticGeometry : " << caps.preferDisplayListsForStaticGeometry(); - qDebug().nospace() << "FragDepthWrite : " << caps.supportsFragDepthWrite(); -} - QString formatProfileName(QSurfaceFormat::OpenGLContextProfile profile) { switch (profile) { @@ -499,23 +453,127 @@ QString getUsageString(osgViewer::CompositeViewer *viewer) return getUsageString(applicationUsage); } -void registerTypes(const char *uri) +#ifdef USE_OSGEARTH +osgEarth::GeoPoint toGeoPoint(const osgEarth::SpatialReference *srs, const QVector3D &position) +{ + osgEarth::GeoPoint geoPoint(srs, position.x(), position.y(), position.z(), osgEarth::ALTMODE_ABSOLUTE); + + return geoPoint; +} + +osgEarth::GeoPoint toGeoPoint(const QVector3D &position) +{ + return toGeoPoint(osgEarth::SpatialReference::get("wgs84"), position); +} + +bool clampGeoPoint(osgEarth::GeoPoint &geoPoint, float offset, osgEarth::MapNode *mapNode) +{ + if (!mapNode) { + qWarning() << "Utility::clampGeoPoint - null map node"; + return false; + } + + // establish an elevation query interface based on the features' SRS. + osgEarth::ElevationQuery eq(mapNode->getMap()); + // qDebug() << "Utility::clampGeoPoint - SRS :" << QString::fromStdString(mapNode->getMap()->getSRS()->getName()); + + bool clamped = false; + double elevation; + if (eq.getElevation(geoPoint, elevation, 0.0)) { + clamped = ((geoPoint.z() - offset) < elevation); + if (clamped) { + // qDebug() << "Utility::clampGeoPoint - clamping" << geoPoint.z() - offset << "/" << elevation; + geoPoint.z() = elevation + offset; + } + } else { + qDebug() << "Utility::clampGeoPoint - failed to get elevation"; + } + + return clamped; +} + +void capabilitiesInfo(const osgEarth::Capabilities &caps) +{ + qDebug().nospace() << "capabilities ----------------------------------------"; + + qDebug().nospace() << "Vendor : " << QString::fromStdString(caps.getVendor()); + qDebug().nospace() << "Version : " << QString::fromStdString(caps.getVersion()); + qDebug().nospace() << "Renderer : " << QString::fromStdString(caps.getRenderer()); + + qDebug().nospace() << "GLSL supported : " << caps.supportsGLSL(); + qDebug().nospace() << "GLSL version : " << caps.getGLSLVersionInt(); + + qDebug().nospace() << "GLES : " << caps.isGLES(); + + qDebug().nospace() << "Num Processors : " << caps.getNumProcessors(); + + qDebug().nospace() << "MaxFFPTextureUnits : " << caps.getMaxFFPTextureUnits(); + qDebug().nospace() << "MaxGPUTextureUnits : " << caps.getMaxGPUTextureUnits(); + qDebug().nospace() << "MaxGPUAttribs : " << caps.getMaxGPUAttribs(); + qDebug().nospace() << "MaxTextureSize : " << caps.getMaxTextureSize(); + qDebug().nospace() << "MaxLights : " << caps.getMaxLights(); + qDebug().nospace() << "DepthBufferBits : " << caps.getDepthBufferBits(); + qDebug().nospace() << "TextureArrays : " << caps.supportsTextureArrays(); + qDebug().nospace() << "Texture3D : " << caps.supportsTexture3D(); + qDebug().nospace() << "MultiTexture : " << caps.supportsMultiTexture(); + qDebug().nospace() << "StencilWrap : " << caps.supportsStencilWrap(); + qDebug().nospace() << "TwoSidedStencil : " << caps.supportsTwoSidedStencil(); + qDebug().nospace() << "Texture2DLod : " << caps.supportsTexture2DLod(); + qDebug().nospace() << "MipmappedTextureUpdates : " << caps.supportsMipmappedTextureUpdates(); + qDebug().nospace() << "DepthPackedStencilBuffer : " << caps.supportsDepthPackedStencilBuffer(); + qDebug().nospace() << "OcclusionQuery : " << caps.supportsOcclusionQuery(); + qDebug().nospace() << "DrawInstanced : " << caps.supportsDrawInstanced(); + qDebug().nospace() << "UniformBufferObjects : " << caps.supportsUniformBufferObjects(); + qDebug().nospace() << "NonPowerOfTwoTextures : " << caps.supportsNonPowerOfTwoTextures(); + qDebug().nospace() << "MaxUniformBlockSize : " << caps.getMaxUniformBlockSize(); + qDebug().nospace() << "PreferDisplayListsForStaticGeometry : " << caps.preferDisplayListsForStaticGeometry(); + qDebug().nospace() << "FragDepthWrite : " << caps.supportsFragDepthWrite(); +} +#endif // USE_OSGEARTH + +void registerTypes() { - // Q_ASSERT(uri == QLatin1String("osgQtQuick")); int maj = 1, min = 0; - // @uri osgQtQuick - qmlRegisterType(uri, maj, min, "OSGNode"); - qmlRegisterType(uri, maj, min, "OSGGroup"); - qmlRegisterType(uri, maj, min, "OSGFileNode"); - qmlRegisterType(uri, maj, min, "OSGTransformNode"); - qmlRegisterType(uri, maj, min, "OSGTextNode"); - qmlRegisterType(uri, maj, min, "OSGCubeNode"); - qmlRegisterType(uri, maj, min, "OSGViewport"); + // viewport + qmlRegisterType("OsgQtQuick", maj, min, "OSGViewport"); + qmlRegisterType("OsgQtQuick", maj, min, "UpdateMode"); - qmlRegisterType(uri, maj, min, "OSGModelNode"); - qmlRegisterType(uri, maj, min, "OSGSkyNode"); - qmlRegisterType(uri, maj, min, "OSGBackgroundNode"); - qmlRegisterType(uri, maj, min, "OSGCamera"); + // basic nodes + qmlRegisterType("OsgQtQuick", maj, min, "OSGNode"); + + qmlRegisterType("OsgQtQuick", maj, min, "OSGGroup"); + + qmlRegisterType("OsgQtQuick", maj, min, "OSGTransformNode"); + + // primitive nodes + qmlRegisterType("OsgQtQuick", maj, min, "OSGShapeNode"); + qmlRegisterType("OsgQtQuick", maj, min, "ShapeType"); + + qmlRegisterType("OsgQtQuick", maj, min, "OSGImageNode"); + + qmlRegisterType("OsgQtQuick", maj, min, "OSGTextNode"); + + qmlRegisterType("OsgQtQuick", maj, min, "OSGBillboardNode"); + + qmlRegisterType("OsgQtQuick", maj, min, "OSGFileNode"); + qmlRegisterType("OsgQtQuick", maj, min, "OptimizeMode"); + + // camera nodes + qmlRegisterType("OsgQtQuick", maj, min, "OSGCamera"); + + // camera manipulators + qmlRegisterType("OsgQtQuick", maj, min, "OSGCameraManipulator"); + qmlRegisterType("OsgQtQuick", maj, min, "OSGNodeTrackerManipulator"); + qmlRegisterType("OsgQtQuick", maj, min, "TrackerMode"); + qmlRegisterType("OsgQtQuick", maj, min, "OSGTrackballManipulator"); + +#ifdef USE_OSGEARTH + qmlRegisterType("OsgQtQuick", maj, min, "OSGSkyNode"); + qmlRegisterType("OsgQtQuick", maj, min, "OSGGeoTransformNode"); + + qmlRegisterType("OsgQtQuick", maj, min, "OSGEarthManipulator"); + qmlRegisterType("OsgQtQuick", maj, min, "OSGGeoTransformManipulator"); +#endif // USE_OSGEARTH } } // namespace osgQtQuick diff --git a/ground/gcs/src/libs/osgearth/utility.h b/ground/gcs/src/libs/osgearth/utils/utility.h similarity index 94% rename from ground/gcs/src/libs/osgearth/utility.h rename to ground/gcs/src/libs/osgearth/utils/utility.h index 8a84f70b4..2f7124847 100644 --- a/ground/gcs/src/libs/osgearth/utility.h +++ b/ground/gcs/src/libs/osgearth/utils/utility.h @@ -2,7 +2,7 @@ ****************************************************************************** * * @file utility.h - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * @addtogroup * @{ * @addtogroup @@ -33,8 +33,6 @@ #include #include -#include - #include #include #include @@ -59,10 +57,14 @@ class Text; class Font; } // namespace osgText +#ifdef USE_OSGEARTH namespace osgEarth { class Capabilities; +class GeoPoint; class MapNode; +class SpatialReference; } // namespace osgEarth +#endif QT_BEGIN_NAMESPACE class QFont; @@ -129,15 +131,11 @@ osgText::Text *createText(const osg::Vec3 &pos, float size, osgText::Font *font = 0); -osgEarth::GeoPoint toGeoPoint(const QVector3D &position); -bool clampGeoPoint(osgEarth::GeoPoint &geoPoint, float offset, osgEarth::MapNode *mapNode); - QSurfaceFormat traitsToFormat(const osg::GraphicsContext::Traits *traits); void formatToTraits(const QSurfaceFormat & format, osg::GraphicsContext::Traits *traits); void formatInfo(const QSurfaceFormat & format); void traitsInfo(const osg::GraphicsContext::Traits & traits); -void capabilitiesInfo(const osgEarth::Capabilities & caps); void openGLContextInfo(QOpenGLContext *context, const char *at); QString formatProfileName(QSurfaceFormat::OpenGLContextProfile profile); @@ -146,7 +144,14 @@ QString formatSwapBehaviorName(QSurfaceFormat::SwapBehavior swapBehavior); QString getUsageString(osgViewer::Viewer *viewer); QString getUsageString(osgViewer::CompositeViewer *viewer); -void registerTypes(const char *uri); +#ifdef USE_OSGEARTH +osgEarth::GeoPoint toGeoPoint(const QVector3D &position); +osgEarth::GeoPoint toGeoPoint(const osgEarth::SpatialReference *srs, const QVector3D &position); +bool clampGeoPoint(osgEarth::GeoPoint &geoPoint, float offset, osgEarth::MapNode *mapNode); +void capabilitiesInfo(const osgEarth::Capabilities & caps); +#endif + +void registerTypes(); } // namespace osgQtQuick #endif // OSGEARTH_UTILITY_H diff --git a/ground/gcs/src/libs/sdlgamepad/copydata.pro b/ground/gcs/src/libs/sdlgamepad/copydata.pro index af9cecbff..296060496 100644 --- a/ground/gcs/src/libs/sdlgamepad/copydata.pro +++ b/ground/gcs/src/libs/sdlgamepad/copydata.pro @@ -1,10 +1,9 @@ -equals(copydata, 1) { - win32 { - # copy SDL DLL - SDL_DLLS = \ - SDL.dll - for(dll, SDL_DLLS) { - addCopyFileTarget($${dll},$${SDL_DIR}/bin,$${GCS_APP_PATH}) - } +win32 { + # copy SDL DLL + SDL_DLLS = \ + SDL.dll + + for(dll, SDL_DLLS) { + addCopyFileTarget($${dll},$$[QT_INSTALL_BINS],$${GCS_APP_PATH}) } } diff --git a/ground/gcs/src/libs/sdlgamepad/sdlgamepad.pro b/ground/gcs/src/libs/sdlgamepad/sdlgamepad.pro index 3182f85ab..8f7211245 100644 --- a/ground/gcs/src/libs/sdlgamepad/sdlgamepad.pro +++ b/ground/gcs/src/libs/sdlgamepad/sdlgamepad.pro @@ -28,19 +28,16 @@ macx { # Ensures that SDL framework and header files are found when compiled with Qt5.2.1 INCLUDEPATH += /Library/Frameworks/SDL.framework/Headers SDL = -F/Library/Frameworks + # Add SDL to CFLAGS fixes build problems on mac QMAKE_CFLAGS += $$SDL QMAKE_CXXFLAGS += $$SDL + # Let the linker know where to find the frameworks LIBS += $$SDL LIBS += -framework OpenGL -framework SDL -framework Cocoa } -win32 { - INCLUDEPATH += $${SDL_DIR}/include - LIBS += -L$${SDL_DIR}/lib -} - !mac:LIBS += -lSDL SOURCES += \ @@ -56,4 +53,4 @@ OTHER_FILES += \ sdlgamepad.dox \ sdlgamepad.doc -include(copydata.pro) +equals(copydata, 1):include(copydata.pro) diff --git a/ground/gcs/src/libs/utils/cachedsvgitem.cpp b/ground/gcs/src/libs/utils/cachedsvgitem.cpp deleted file mode 100644 index 91627479e..000000000 --- a/ground/gcs/src/libs/utils/cachedsvgitem.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/** - ****************************************************************************** - * - * @file cachedsvgitem.h - * @author Dmytro Poplavskiy Copyright (C) 2011. - * @{ - * @brief OpenGL texture cached SVG item - *****************************************************************************/ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "cachedsvgitem.h" -#include - -#ifndef GL_CLAMP_TO_EDGE -#define GL_CLAMP_TO_EDGE 0x812F -#endif - -CachedSvgItem::CachedSvgItem(QGraphicsItem *parent) : - QGraphicsSvgItem(parent), - m_context(0), - m_texture(0), - m_scale(1.0) -{ - setCacheMode(NoCache); -} - -CachedSvgItem::CachedSvgItem(const QString & fileName, QGraphicsItem *parent) : - QGraphicsSvgItem(fileName, parent), - m_context(0), - m_texture(0), - m_scale(1.0) -{ - setCacheMode(NoCache); -} - -CachedSvgItem::~CachedSvgItem() -{ - if (m_context && m_texture) { - m_context->makeCurrent(); - glDeleteTextures(1, &m_texture); - } -} - -void CachedSvgItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) -{ - if (painter->paintEngine()->type() != QPaintEngine::OpenGL && - painter->paintEngine()->type() != QPaintEngine::OpenGL2) { - // Fallback to direct painting - QGraphicsSvgItem::paint(painter, option, widget); - return; - } - - QRectF br = boundingRect(); - QTransform transform = painter->worldTransform(); - qreal sceneScale = transform.map(QLineF(0, 0, 1, 0)).length(); - - bool stencilTestEnabled = glIsEnabled(GL_STENCIL_TEST); - bool scissorTestEnabled = glIsEnabled(GL_SCISSOR_TEST); - - painter->beginNativePainting(); - - if (stencilTestEnabled) { - glEnable(GL_STENCIL_TEST); - } - if (scissorTestEnabled) { - glEnable(GL_SCISSOR_TEST); - } - - bool dirty = false; - if (!m_texture) { - glGenTextures(1, &m_texture); - m_context = const_cast(QGLContext::currentContext()); - - dirty = true; - } - - if (!qFuzzyCompare(sceneScale, m_scale)) { - m_scale = sceneScale; - dirty = true; - } - - int textureWidth = (int(br.width() * m_scale) + 3) & ~3; - int textureHeight = (int(br.height() * m_scale) + 3) & ~3; - - if (dirty) { - // qDebug() << "re-render image"; - - QImage img(textureWidth, textureHeight, QImage::Format_ARGB32); - { - img.fill(Qt::transparent); - QPainter p; - p.begin(&img); - p.setRenderHints(painter->renderHints()); - p.translate(br.topLeft()); - p.scale(m_scale, m_scale); - QGraphicsSvgItem::paint(&p, option, 0); - p.end(); - - img = img.rgbSwapped(); - } - - glEnable(GL_TEXTURE_2D); - - glBindTexture(GL_TEXTURE_2D, m_texture); - glTexImage2D( - GL_TEXTURE_2D, - 0, - GL_RGBA, - textureWidth, - textureHeight, - 0, - GL_RGBA, - GL_UNSIGNED_BYTE, - img.bits()); - - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glDisable(GL_TEXTURE_2D); - - dirty = false; - } - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_TEXTURE_2D); - - glBindTexture(GL_TEXTURE_2D, m_texture); - - // texture may be slightly large than svn image, ensure only used area is rendered - qreal tw = br.width() * m_scale / textureWidth; - qreal th = br.height() * m_scale / textureHeight; - - glBegin(GL_QUADS); - glTexCoord2d(0, 0); glVertex3d(br.left(), br.top(), -1); - glTexCoord2d(tw, 0); glVertex3d(br.right(), br.top(), -1); - glTexCoord2d(tw, th); glVertex3d(br.right(), br.bottom(), -1); - glTexCoord2d(0, th); glVertex3d(br.left(), br.bottom(), -1); - glEnd(); - glDisable(GL_TEXTURE_2D); - - painter->endNativePainting(); -} diff --git a/ground/gcs/src/libs/utils/filelogger.h b/ground/gcs/src/libs/utils/filelogger.h new file mode 100644 index 000000000..8c5b8d3b1 --- /dev/null +++ b/ground/gcs/src/libs/utils/filelogger.h @@ -0,0 +1,141 @@ +/** + ****************************************************************************** + * + * @file filelogger.h + * @author The LibrePilot Project, http://www.openpilot.org Copyright (C) 2016. + * Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009. + * @brief + * @see The GNU Public License (GPL) Version 3 + * @defgroup + * @{ + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#pragma once + +#include "utils_global.h" + +#include +#include +#include +#include +#include + +class QTCREATOR_UTILS_EXPORT FileLogger : public QObject { + Q_OBJECT + +private: + QTextStream * logStream; + QThread *loggerThread; + bool started; + +public: + FileLogger() : QObject(), logStream(NULL), loggerThread(NULL), started(false) + {} + + virtual ~FileLogger() + { + stop(); + if (logStream) { + delete logStream; + } + } + +public: + bool start(const QString &fileName) + { + if (started) { + return false; + } + + QFile *file = new QFile(fileName); + if (!file->open(QIODevice::WriteOnly | QIODevice::Text)) { + return false; + } + + logStream = new QTextStream(file); + + loggerThread = new QThread(this); + moveToThread(loggerThread); + loggerThread->start(); + + started = true; + + return true; + } + + bool stop() + { + if (!started) { + return false; + } + // stop accepting messages + started = false; + + // make sure all messages are flushed by sending a blocking message + QtMsgType type = QtDebugMsg; + const QString msg = "stopping file logger"; + QMetaObject::invokeMethod(this, "doLog", Qt::BlockingQueuedConnection, + Q_ARG(QtMsgType, type), Q_ARG(const QString &, msg)); + + return true; + } + + void log(QtMsgType type, const QMessageLogContext &context, const QString &msg) + { + Q_UNUSED(context); + + if (!started) { + return; + } + + QMetaObject::invokeMethod(this, "doLog", Qt::QueuedConnection, + Q_ARG(QtMsgType, type), Q_ARG(const QString &, msg)); + } + +private slots: + void doLog(QtMsgType type, const QString &msg) + { + QTextStream &out = *logStream; + + // logStream << QTime::currentTime().toString("hh:mm:ss.zzz "); + + switch (type) { + case QtDebugMsg: + out << "DBG: "; + break; +#if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)) + case QtInfoMsg: + out << "INF: "; + break; +#endif + case QtWarningMsg: + out << "WRN: "; + break; + case QtCriticalMsg: + out << "CRT: "; + break; + case QtFatalMsg: + out << "FTL: "; + break; + } + + out << msg << '\n'; + out.flush(); + } +}; diff --git a/ground/gcs/src/libs/utils/filenamevalidatinglineedit.cpp b/ground/gcs/src/libs/utils/filenamevalidatinglineedit.cpp index 3f53447f4..09fad9c86 100644 --- a/ground/gcs/src/libs/utils/filenamevalidatinglineedit.cpp +++ b/ground/gcs/src/libs/utils/filenamevalidatinglineedit.cpp @@ -81,7 +81,7 @@ void FileNameValidatingLineEdit::setAllowDirectories(bool v) #endif static const char *notAllowedCharsSubDir = "?:&*\"|#%<> "; -static const char *notAllowedCharsNoSubDir = "?:&*\"|#%<> "SLASHES; +static const char *notAllowedCharsNoSubDir = "?:&*\"|#%<> " SLASHES; static const char *notAllowedSubStrings[] = { ".." }; diff --git a/ground/gcs/src/plugins/pfdqml/fonts/PTS75F.ttf b/ground/gcs/src/libs/utils/fonts/PTS75F.ttf similarity index 100% rename from ground/gcs/src/plugins/pfdqml/fonts/PTS75F.ttf rename to ground/gcs/src/libs/utils/fonts/PTS75F.ttf diff --git a/ground/gcs/src/plugins/pfdqml/fonts/Paratype PT Sans Free Font License.txt b/ground/gcs/src/libs/utils/fonts/Paratype PT Sans Free Font License.txt similarity index 100% rename from ground/gcs/src/plugins/pfdqml/fonts/Paratype PT Sans Free Font License.txt rename to ground/gcs/src/libs/utils/fonts/Paratype PT Sans Free Font License.txt diff --git a/ground/gcs/src/libs/utils/quickwidgetproxy.cpp b/ground/gcs/src/libs/utils/quickwidgetproxy.cpp index fe5a615e6..1f93c4e3c 100644 --- a/ground/gcs/src/libs/utils/quickwidgetproxy.cpp +++ b/ground/gcs/src/libs/utils/quickwidgetproxy.cpp @@ -127,16 +127,16 @@ void QuickWidgetProxy::onStatusChanged(QQuickWidget::Status status) { switch (status) { case QQuickWidget::Null: - qDebug() << "QuickWidgetProxy - status Null"; + qWarning() << "QuickWidgetProxy - status Null"; break; case QQuickWidget::Ready: - qDebug() << "QuickWidgetProxy - status Ready"; + // qDebug() << "QuickWidgetProxy - status Ready"; break; case QQuickWidget::Loading: - qDebug() << "QuickWidgetProxy - status Loading"; + // qDebug() << "QuickWidgetProxy - status Loading"; break; case QQuickWidget::Error: - qDebug() << "QuickWidgetProxy - status Error"; + qWarning() << "QuickWidgetProxy - status Error"; foreach(const QQmlError &error, errors()) { qWarning() << error.description(); } @@ -148,16 +148,16 @@ void QuickWidgetProxy::onStatusChanged(QQuickView::Status status) { switch (status) { case QQuickView::Null: - qDebug() << "QuickWidgetProxy - status Null"; + qWarning() << "QuickWidgetProxy - status Null"; break; case QQuickView::Ready: - qDebug() << "QuickWidgetProxy - status Ready"; + // qDebug() << "QuickWidgetProxy - status Ready"; break; case QQuickView::Loading: - qDebug() << "QuickWidgetProxy - status Loading"; + // qDebug() << "QuickWidgetProxy - status Loading"; break; case QQuickView::Error: - qDebug() << "QuickWidgetProxy - status Error"; + qWarning() << "QuickWidgetProxy - status Error"; foreach(const QQmlError &error, errors()) { qWarning() << error.description(); } diff --git a/ground/gcs/src/libs/utils/stringutils.cpp b/ground/gcs/src/libs/utils/stringutils.cpp new file mode 100644 index 000000000..6e2dfbf17 --- /dev/null +++ b/ground/gcs/src/libs/utils/stringutils.cpp @@ -0,0 +1,49 @@ +/** + ****************************************************************************** + * + * @file pathutils.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @brief String utilities + * + * @see The GNU Public License (GPL) Version 3 + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "stringutils.h" + +namespace Utils { +QString toLowerCamelCase(const QString & name) +{ + QString str = name; + + for (int i = 0; i < str.length(); ++i) { + if (str[i].isLower() || !str[i].isLetter()) { + break; + } + if (i > 0 && i < str.length() - 1) { + // after first, look ahead one + if (str[i + 1].isLower()) { + break; + } + } + str[i] = str[i].toLower(); + } + + return str; +} +} diff --git a/ground/gcs/src/libs/utils/settingsutils.h b/ground/gcs/src/libs/utils/stringutils.h similarity index 69% rename from ground/gcs/src/libs/utils/settingsutils.h rename to ground/gcs/src/libs/utils/stringutils.h index be85a69e7..ad633dc40 100644 --- a/ground/gcs/src/libs/utils/settingsutils.h +++ b/ground/gcs/src/libs/utils/stringutils.h @@ -1,8 +1,8 @@ /** ****************************************************************************** * - * @file settingsutils.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @file stringutils.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. * Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009. * @brief * @see The GNU Public License (GPL) Version 3 @@ -26,15 +26,24 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef SETTINGSTUTILS_H -#define SETTINGSTUTILS_H +#ifndef STRINGUTILS_H +#define STRINGUTILS_H #include "utils_global.h" -namespace Utils { -// Create a usable settings key from a category, -// for example Editor|C++ -> Editor_C__ -QTCREATOR_UTILS_EXPORT QString settingsKey(const QString &category); -} // namespace Utils +#include -#endif // SETTINGSTUTILS_H +namespace Utils { +/** + * Convert a string to lower camel case. + * Handles following cases : + * - Property -> property + * - MyProperty -> myProperty + * - MYProperty -> myProperty + * - MY_Property -> my_Property + * - MY -> my + */ +QTCREATOR_UTILS_EXPORT QString toLowerCamelCase(const QString &); +} + +#endif /* STRINGUTILS_H */ diff --git a/ground/gcs/src/libs/utils/svgimageprovider.cpp b/ground/gcs/src/libs/utils/svgimageprovider.cpp index 14804dbc5..85e2fc318 100644 --- a/ground/gcs/src/libs/utils/svgimageprovider.cpp +++ b/ground/gcs/src/libs/utils/svgimageprovider.cpp @@ -26,12 +26,14 @@ */ #include "svgimageprovider.h" + #include #include #include +#include +#include SvgImageProvider::SvgImageProvider(const QString &basePath) : - QObject(), QQuickImageProvider(QQuickImageProvider::Image), m_basePath(basePath) {} @@ -43,18 +45,15 @@ SvgImageProvider::~SvgImageProvider() QSvgRenderer *SvgImageProvider::loadRenderer(const QString &svgFile) { - QSvgRenderer *renderer = m_renderers.value(svgFile); + QSvgRenderer *renderer = m_renderers.value(svgFile, NULL); if (!renderer) { - renderer = new QSvgRenderer(svgFile); + QFileInfo fi(svgFile); - QString fn = QUrl::fromLocalFile(m_basePath).resolved(svgFile).toLocalFile(); - - // convert path to be relative to base - if (!renderer->isValid()) { - renderer->load(fn); - } + // if svgFile is relative, make it relative to base + QString fn = fi.isRelative() ? QUrl::fromLocalFile(m_basePath).resolved(svgFile).toLocalFile() : svgFile; + renderer = new QSvgRenderer(fn); if (!renderer->isValid()) { qWarning() << "Failed to load svg file:" << svgFile << fn; delete renderer; diff --git a/ground/gcs/src/libs/utils/svgimageprovider.h b/ground/gcs/src/libs/utils/svgimageprovider.h index a58b312b5..9837f0ffb 100644 --- a/ground/gcs/src/libs/utils/svgimageprovider.h +++ b/ground/gcs/src/libs/utils/svgimageprovider.h @@ -28,12 +28,12 @@ #ifndef SVGIMAGEPROVIDER_H_ #define SVGIMAGEPROVIDER_H_ -#include +#include "utils_global.h" + #include -#include #include -#include "utils_global.h" +class QSvgRenderer; class QTCREATOR_UTILS_EXPORT SvgImageProvider : public QObject, public QQuickImageProvider { Q_OBJECT @@ -41,14 +41,14 @@ public: SvgImageProvider(const QString &basePath); ~SvgImageProvider(); - QSvgRenderer *loadRenderer(const QString &svgFile); - QImage requestImage(const QString &id, QSize *size, const QSize & requestedSize); QPixmap requestPixmap(const QString &id, QSize *size, const QSize & requestedSize); Q_INVOKABLE QRectF scaledElementBounds(const QString &svgFile, const QString &elementName); private: + QSvgRenderer *loadRenderer(const QString &svgFile); + QMap m_renderers; QString m_basePath; }; diff --git a/ground/gcs/src/libs/utils/textbubbleslider.cpp b/ground/gcs/src/libs/utils/textbubbleslider.cpp new file mode 100644 index 000000000..b3ee79bad --- /dev/null +++ b/ground/gcs/src/libs/utils/textbubbleslider.cpp @@ -0,0 +1,199 @@ +/** + ****************************************************************************** + * + * @file textbubbleslider.h + * @author Tau Labs, http://taulabs.org Copyright (C) 2013. + * @brief Creates a slider with a text bubble showing the slider value + * @see The GNU Public License (GPL) Version 3 + * @defgroup + * @{ + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include + +#include "textbubbleslider.h" + +/** + * @brief TextBubbleSlider::TextBubbleSlider Constructs a regular text-bubble slider + * @param parent + */ +TextBubbleSlider::TextBubbleSlider(QWidget *parent) : + QSlider(parent) +{ + QFontDatabase::addApplicationFont(":/utils/fonts/PTS75F.ttf"); + + construct(); +} + +/** + * @brief TextBubbleSlider::TextBubbleSlider Constructs a text-bubble slider that copys + * all relevant data from the previous slider + * @param copySlider + * @param parent + */ +TextBubbleSlider::TextBubbleSlider(QSlider *copySlider, QWidget *parent) : + QSlider(parent) +{ + construct(); + + // Copy settings + setSizePolicy(copySlider->sizePolicy()); + setMinimumSize(copySlider->minimumSize()); + setMaximumSize(copySlider->maximumSize()); + setFocusPolicy(copySlider->focusPolicy()); + setOrientation(copySlider->orientation()); + setMaximum(copySlider->maximum()); + setMinimum(copySlider->minimum()); + setToolTip(copySlider->toolTip()); +} + + +/** + * @brief TextBubbleSlider::construct This function needs to be called from all constructors. It + * provides a single point where settings can be changed. + */ +void TextBubbleSlider::construct() +{ + font = QFont("PT Sans", 13, QFont::Bold); + slideHandleMargin = 2; // This is a dubious way to set the margin. In reality, it should be read from the style sheet. +} + +TextBubbleSlider::~TextBubbleSlider() +{} + + +/** + * @brief numIntegerDigits Counts the number of digits in an integer + * @param number Input integer + * @return Number of digits in input integer + */ +unsigned int numIntegerDigits(int number) +{ + unsigned int digits = 0; + + // If there is a negative sign, be sure to include it in digit count + if (number < 0) { + digits = 1; + } + + while (number) { + number /= 10; + digits++; + } + + return digits; +} + + +/** + * @brief TextBubbleSlider::setMaxPixelWidth Sets maximum pixel width for slider handle + */ +void TextBubbleSlider::setMaxPixelWidth() +{ + // Calculate maximum number of digits possible in string + int maxNumDigits = numIntegerDigits(maximum()) > numIntegerDigits(minimum()) ? numIntegerDigits(maximum()) : numIntegerDigits(minimum()); + + // Generate string with maximum pixel width. Suppose that "0" is + // the widest number in pixels. + QString maximumWidthString; + + for (int i = 0; i < maxNumDigits; i++) { + maximumWidthString.append("0"); + } + + // Calculate maximum possible pixel width for string. + QFontMetrics fontMetrics(font); + maximumFontWidth = fontMetrics.width(QString("%1").arg(maximumWidthString)); + maximumFontHeight = fontMetrics.height(); + + // Override stylesheet slider handle width + slideHandleWidth = maximumFontWidth + 6; + setStyleSheet(QString("QSlider::handle:horizontal { width: %1px; margin: -5px 0;}").arg(slideHandleWidth)); +} + + +/** + * @brief TextBubbleSlider::setMinimum Reimplements setMinimum. Ensures that the slider + * handle is the correct size for the text field. + * @param max maximum + */ +void TextBubbleSlider::setMinimum(int max) +{ + // Pass value on to QSlider + QSlider::setMinimum(max); + + // Reset handler size + setMaxPixelWidth(); +} + + +/** + * @brief TextBubbleSlider::setMaximum Reimplements setMaximum. Ensures that the slider + * handle is the correct size for the text field. + * @param max maximum + */ +void TextBubbleSlider::setMaximum(int max) +{ + // Pass value on to QSlider + QSlider::setMaximum(max); + + // Reset handler size + setMaxPixelWidth(); +} + + +/** + * @brief TextBubbleSlider::paintEvent Reimplements QSlider::paintEvent. + * @param bob + */ +void TextBubbleSlider::paintEvent(QPaintEvent *paintEvent) +{ + // Pass paint event on to QSlider + QSlider::paintEvent(paintEvent); + + /* Add numbers on top of handler */ + + // Calculate pixel position for text. + int sliderWidth = width(); + int sliderHeight = height(); + double valuePos; + + if (!invertedAppearance()) { + valuePos = (slideHandleWidth - maximumFontWidth) / 2 + slideHandleMargin + // First part centers text in handle... + (value() - minimum()) / (double)(maximum() - minimum()) * (sliderWidth - (slideHandleWidth + slideHandleMargin) - 1); // ... and second part moves text with handle + } else { + valuePos = (slideHandleWidth - maximumFontWidth) / 2 + slideHandleMargin + // First part centers text in handle... + (maximum() - value()) / (double)(maximum() - minimum()) * (sliderWidth - (slideHandleWidth + slideHandleMargin) - 1); // ... and second part moves text with handle + } + + // Create painter and set font + QPainter painter(this); + painter.setFont(font); + painter.setPen(QPen(QColor(80, 80, 80))); + + // Draw neutral value text. Vertically center it in the handle + QString neutralStringWidth = QString("%1").arg(value()); + QFontMetrics fontMetrics(font); + int textWidth = fontMetrics.width(neutralStringWidth); + painter.drawText(QRectF(valuePos + maximumFontWidth - textWidth, ceil((sliderHeight - maximumFontHeight) / 2.0), textWidth, maximumFontHeight), + neutralStringWidth); +} diff --git a/ground/gcs/src/libs/utils/cachedsvgitem.h b/ground/gcs/src/libs/utils/textbubbleslider.h similarity index 53% rename from ground/gcs/src/libs/utils/cachedsvgitem.h rename to ground/gcs/src/libs/utils/textbubbleslider.h index 2115a37a1..196b0ad85 100644 --- a/ground/gcs/src/libs/utils/cachedsvgitem.h +++ b/ground/gcs/src/libs/utils/textbubbleslider.h @@ -1,10 +1,13 @@ /** ****************************************************************************** * - * @file cachedsvgitem.h - * @author Dmytro Poplavskiy Copyright (C) 2011. + * @file textbubbleslider.h + * @author Tau Labs, http://taulabs.org Copyright (C) 2013. + * @brief Creates a slider with a text bubble showing the slider value + * @see The GNU Public License (GPL) Version 3 + * @defgroup * @{ - * @brief OpenGL texture cached SVG item + * *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify @@ -22,33 +25,36 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef CACHEDSVGITEM_H -#define CACHEDSVGITEM_H - -#include -#include -#include +#ifndef TEXTBUBBLESLIDER_H +#define TEXTBUBBLESLIDER_H #include "utils_global.h" -class QGLContext; +#include -// Cache Svg item as GL Texture. -// Texture is regenerated each time item is scaled -// but it's reused during rotation, unlike DeviceCoordinateCache mode -class QTCREATOR_UTILS_EXPORT CachedSvgItem : public QGraphicsSvgItem { +class QTCREATOR_UTILS_EXPORT TextBubbleSlider : public QSlider { Q_OBJECT -public: - CachedSvgItem(QGraphicsItem *parent = 0); - CachedSvgItem(const QString & fileName, QGraphicsItem *parent = 0); - ~CachedSvgItem(); - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); +public: + explicit TextBubbleSlider(QWidget *parent = 0); + explicit TextBubbleSlider(QSlider *, QWidget *parent = 0); + void construct(); + ~TextBubbleSlider(); + + void setMinimum(int); + void setMaximum(int); + +protected: + void paintEvent(QPaintEvent *event); private: - QGLContext *m_context; - GLuint m_texture; - qreal m_scale; + void setMaxPixelWidth(); + + QFont font; + int maximumFontWidth; + int maximumFontHeight; + int slideHandleWidth; + int slideHandleMargin; }; -#endif // ifndef CACHEDSVGITEM_H +#endif // TEXTBUBBLESLIDER_H diff --git a/ground/gcs/src/libs/utils/utils.pro b/ground/gcs/src/libs/utils/utils.pro index 17ca57c65..4e291df1b 100644 --- a/ground/gcs/src/libs/utils/utils.pro +++ b/ground/gcs/src/libs/utils/utils.pro @@ -1,7 +1,7 @@ TEMPLATE = lib TARGET = Utils -QT += network xml svg opengl gui widgets qml quick quickwidgets +QT += network xml svg gui widgets qml quick quickwidgets DEFINES += QTCREATOR_UTILS_LIB @@ -13,7 +13,7 @@ DEFINES += PLUGIN_REL_PATH=$$shell_quote(\"$$relative_path($$GCS_PLUGIN_PATH, $$ SOURCES += \ reloadpromptutils.cpp \ - settingsutils.cpp \ + stringutils.cpp \ filesearch.cpp \ pathchooser.cpp \ pathlisteditor.cpp \ @@ -52,12 +52,13 @@ SOURCES += \ mytabbedstackwidget.cpp \ mytabwidget.cpp \ quickwidgetproxy.cpp \ - cachedsvgitem.cpp \ svgimageprovider.cpp \ hostosinfo.cpp \ logfile.cpp \ crc.cpp \ - mustache.cpp + mustache.cpp \ + textbubbleslider.cpp + SOURCES += xmlconfig.cpp @@ -73,7 +74,7 @@ else:SOURCES += consoleprocess_unix.cpp HEADERS += \ utils_global.h \ reloadpromptutils.h \ - settingsutils.h \ + stringutils.h \ filesearch.h \ listutils.h \ pathchooser.h \ @@ -115,12 +116,13 @@ HEADERS += \ mytabbedstackwidget.h \ mytabwidget.h \ quickwidgetproxy.h \ - cachedsvgitem.h \ svgimageprovider.h \ hostosinfo.h \ logfile.h \ crc.h \ - mustache.h + mustache.h \ + textbubbleslider.h \ + filelogger.h HEADERS += xmlconfig.h diff --git a/ground/gcs/src/libs/utils/utils.qrc b/ground/gcs/src/libs/utils/utils.qrc index ef180b21f..ee388cc66 100644 --- a/ground/gcs/src/libs/utils/utils.qrc +++ b/ground/gcs/src/libs/utils/utils.qrc @@ -1,5 +1,6 @@ images/removesubmitfield.png + fonts/PTS75F.ttf diff --git a/ground/gcs/src/libs/utils/winutils.cpp b/ground/gcs/src/libs/utils/winutils.cpp index 67dba1bb6..3c5510a97 100644 --- a/ground/gcs/src/libs/utils/winutils.cpp +++ b/ground/gcs/src/libs/utils/winutils.cpp @@ -30,10 +30,6 @@ #include #include -#include -#include -#include -#include namespace Utils { QTCREATOR_UTILS_EXPORT QString winErrorMessage(unsigned long error) @@ -53,60 +49,4 @@ QTCREATOR_UTILS_EXPORT QString winErrorMessage(unsigned long error) } return rc; } - -QTCREATOR_UTILS_EXPORT QString winGetDLLVersion(WinDLLVersionType t, - const QString &name, - QString *errorMessage) -{ - // Resolve required symbols from the version.dll - typedef DWORD (APIENTRY * GetFileVersionInfoSizeProtoType)(LPCTSTR, LPDWORD); - typedef BOOL (APIENTRY * GetFileVersionInfoWProtoType)(LPCWSTR, DWORD, DWORD, LPVOID); - typedef BOOL (APIENTRY * VerQueryValueWProtoType)(const LPVOID, LPWSTR lpSubBlock, LPVOID, PUINT); - - const char *versionDLLC = "version.dll"; - QLibrary versionLib(QLatin1String(versionDLLC), 0); - if (!versionLib.load()) { - *errorMessage = QString::fromLatin1("Unable load %1: %2").arg(QLatin1String(versionDLLC), versionLib.errorString()); - return QString(); - } - // MinGW requires old-style casts - GetFileVersionInfoSizeProtoType getFileVersionInfoSizeW = (GetFileVersionInfoSizeProtoType)(versionLib.resolve("GetFileVersionInfoSizeW")); - GetFileVersionInfoWProtoType getFileVersionInfoW = (GetFileVersionInfoWProtoType)(versionLib.resolve("GetFileVersionInfoW")); - VerQueryValueWProtoType verQueryValueW = (VerQueryValueWProtoType)(versionLib.resolve("VerQueryValueW")); - if (!getFileVersionInfoSizeW || !getFileVersionInfoW || !verQueryValueW) { - *errorMessage = QString::fromLatin1("Unable to resolve all required symbols in %1").arg(QLatin1String(versionDLLC)); - return QString(); - } - - // Now go ahead, read version info resource - DWORD dummy = 0; - const LPCTSTR fileName = reinterpret_cast(name.utf16()); // MinGWsy - const DWORD infoSize = (*getFileVersionInfoSizeW)(fileName, &dummy); - if (infoSize == 0) { - *errorMessage = QString::fromLatin1("Unable to determine the size of the version information of %1: %2").arg(name, winErrorMessage(GetLastError())); - return QString(); - } - QByteArray dataV(infoSize + 1, '\0'); - char *data = dataV.data(); - if (!(*getFileVersionInfoW)(fileName, dummy, infoSize, data)) { - *errorMessage = QString::fromLatin1("Unable to determine the version information of %1: %2").arg(name, winErrorMessage(GetLastError())); - return QString(); - } - VS_FIXEDFILEINFO *versionInfo; - UINT len = 0; - if (!(*verQueryValueW)(data, TEXT("\\"), &versionInfo, &len)) { - *errorMessage = QString::fromLatin1("Unable to determine version string of %1: %2").arg(name, winErrorMessage(GetLastError())); - return QString(); - } - QString rc; - switch (t) { - case WinDLLFileVersion: - QTextStream(&rc) << HIWORD(versionInfo->dwFileVersionMS) << '.' << LOWORD(versionInfo->dwFileVersionMS); - break; - case WinDLLProductVersion: - QTextStream(&rc) << HIWORD(versionInfo->dwProductVersionMS) << '.' << LOWORD(versionInfo->dwProductVersionMS); - break; - } - return rc; -} } // namespace Utils diff --git a/ground/gcs/src/libs/utils/winutils.h b/ground/gcs/src/libs/utils/winutils.h index 7d268e011..f49c044b3 100644 --- a/ground/gcs/src/libs/utils/winutils.h +++ b/ground/gcs/src/libs/utils/winutils.h @@ -39,11 +39,5 @@ namespace Utils { // Helper to format a Windows error message, taking the // code as returned by the GetLastError()-API. QTCREATOR_UTILS_EXPORT QString winErrorMessage(unsigned long error); - -// Determine a DLL version -enum WinDLLVersionType { WinDLLFileVersion, WinDLLProductVersion }; -QTCREATOR_UTILS_EXPORT QString winGetDLLVersion(WinDLLVersionType t, - const QString &name, - QString *errorMessage); } // namespace Utils #endif // WINUTILS_H diff --git a/ground/gcs/src/plugin.pri b/ground/gcs/src/plugin.pri index ea4764a9e..88d8f2bce 100644 --- a/ground/gcs/src/plugin.pri +++ b/ground/gcs/src/plugin.pri @@ -7,8 +7,6 @@ LIBS += -L$$DESTDIR INCLUDEPATH += $$GCS_SOURCE_TREE/src/plugins DEPENDPATH += $$GCS_SOURCE_TREE/src/plugins -QT += widgets - # copy the plugin spec isEmpty(TARGET) { error("qtcreatorplugin.pri: You must provide a TARGET") @@ -26,7 +24,7 @@ QMAKE_EXTRA_COMPILERS += copy2build TARGET = $$qtLibraryName($$TARGET) macx { - QMAKE_LFLAGS_SONAME = -Wl,-install_name,@executable_path/../Plugins/$${PROVIDER}/ + QMAKE_LFLAGS_SONAME = -Wl,-install_name,@executable_path/../Plugins/$${PROVIDER}/ } else:linux-* { QMAKE_RPATHDIR = $$shell_quote(\$$ORIGIN) QMAKE_RPATHDIR += $$shell_quote(\$$ORIGIN/$$relative_path($$GCS_LIBRARY_PATH, $$DESTDIR)) @@ -34,7 +32,6 @@ macx { include(rpath.pri) } - contains(QT_CONFIG, reduce_exports):CONFIG += hGCS_symbols CONFIG += plugin plugin_with_soname diff --git a/ground/gcs/src/plugins/antennatrack/antennatrack.pro b/ground/gcs/src/plugins/antennatrack/antennatrack.pro index e1bc56d56..b78b029e4 100644 --- a/ground/gcs/src/plugins/antennatrack/antennatrack.pro +++ b/ground/gcs/src/plugins/antennatrack/antennatrack.pro @@ -1,26 +1,35 @@ TEMPLATE = lib TARGET = AntennaTrack + QT += serialport + include(../../plugin.pri) include(../../plugins/coreplugin/coreplugin.pri) include(antennatrack_dependencies.pri) include(../../libs/qwt/qwt.pri) -HEADERS += antennatrackplugin.h -HEADERS += gpsparser.h -HEADERS += telemetryparser.h -HEADERS += antennatrackgadget.h -HEADERS += antennatrackwidget.h -HEADERS += antennatrackgadgetfactory.h -HEADERS += antennatrackgadgetconfiguration.h -HEADERS += antennatrackgadgetoptionspage.h -SOURCES += antennatrackplugin.cpp -SOURCES += gpsparser.cpp -SOURCES += telemetryparser.cpp -SOURCES += antennatrackgadget.cpp -SOURCES += antennatrackgadgetfactory.cpp -SOURCES += antennatrackwidget.cpp -SOURCES += antennatrackgadgetconfiguration.cpp -SOURCES += antennatrackgadgetoptionspage.cpp + +HEADERS += \ + antennatrackplugin.h \ + gpsparser.h \ + telemetryparser.h \ + antennatrackgadget.h \ + antennatrackwidget.h \ + antennatrackgadgetfactory.h \ + antennatrackgadgetconfiguration.h \ + antennatrackgadgetoptionspage.h + +SOURCES += \ + antennatrackplugin.cpp \ + gpsparser.cpp \ + telemetryparser.cpp \ + antennatrackgadget.cpp \ + antennatrackgadgetfactory.cpp \ + antennatrackwidget.cpp \ + antennatrackgadgetconfiguration.cpp \ + antennatrackgadgetoptionspage.cpp + OTHER_FILES += AntennaTrack.pluginspec -FORMS += antennatrackgadgetoptionspage.ui -FORMS += antennatrackwidget.ui + +FORMS += \ + antennatrackgadgetoptionspage.ui \ + antennatrackwidget.ui diff --git a/ground/gcs/src/plugins/antennatrack/antennatrackgadget.cpp b/ground/gcs/src/plugins/antennatrack/antennatrackgadget.cpp index 2e818e612..e3dd367b2 100644 --- a/ground/gcs/src/plugins/antennatrack/antennatrackgadget.cpp +++ b/ground/gcs/src/plugins/antennatrack/antennatrackgadget.cpp @@ -89,7 +89,7 @@ void AntennaTrackGadget::loadConfiguration(IUAVGadgetConfiguration *config) } } m_widget->dataStreamGroupBox->setHidden(false); - qDebug() << "Using Telemetry parser"; + parser = new TelemetryParser(); connect(parser, SIGNAL(position(double, double, double)), m_widget, SLOT(setPosition(double, double, double))); diff --git a/ground/gcs/src/plugins/config/airframe.ui b/ground/gcs/src/plugins/config/airframe.ui index 92353fbd4..a3827553d 100644 --- a/ground/gcs/src/plugins/config/airframe.ui +++ b/ground/gcs/src/plugins/config/airframe.ui @@ -218,7 +218,7 @@ - + 0 @@ -250,26 +250,35 @@ true + + button:help + - + Send to board, but don't save permanently (flash or SD). Apply + + button:apply + - + Applies and Saves all settings to flash or SD depending on board. Save + + button:save + @@ -287,9 +296,9 @@ nameEdit vehicleSetupWizardButton - airframeHelp - saveAircraftToRAM - saveAircraftToSD + helpButton + applyButton + saveButton diff --git a/ground/gcs/src/plugins/config/airframe_fixedwing.ui b/ground/gcs/src/plugins/config/airframe_fixedwing.ui index 7e5ede296..c6901b9b3 100644 --- a/ground/gcs/src/plugins/config/airframe_fixedwing.ui +++ b/ground/gcs/src/plugins/config/airframe_fixedwing.ui @@ -6,8 +6,8 @@ 0 0 - 880 - 608 + 920 + 690 @@ -66,8 +66,8 @@ - 10 - 10 + 250 + 250 @@ -130,8 +130,8 @@ - 10 - 10 + 250 + 250 @@ -514,7 +514,7 @@ margin:1px; Output Channel Assignments - + 9 @@ -538,42 +538,6 @@ margin:1px; 6 - - - - - 70 - 0 - - - - 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; - - - Elevator 2 - - - - - - - true - - - - 0 - 0 - - - - Assign your output channel - - - @@ -755,8 +719,458 @@ margin:1px; + + + + + 70 + 0 + + + + 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; + + + Elevator 2 + + + + + + + true + + + + 0 + 0 + + + + Assign your output channel + + + + + + + QLayout::SetMaximumSize + + + 0 + + + + + Select output curve for Accessory1 RcInput + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Select output channel for Accessory0 RcInput + + + + + + + + 0 + 0 + + + + + 90 + 0 + + + + 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; + + + Accessory0 + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 90 + 16 + + + + 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; + + + RC Input + + + Qt::AlignCenter + + + + + + + + 90 + 0 + + + + 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; + + + Accessory1 + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 110 + 0 + + + + RcOutput channels + + + 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; + + + RC Output 1 + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Select output channel for Accessory2 RcInput + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Select output channel for Accessory1 RcInput + + + + + + + + 90 + 0 + + + + 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; + + + Accessory2 + + + Qt::AlignCenter + + + + + + + + 90 + 0 + + + + RcOutput curve + + + 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; + + + Curve + + + Qt::AlignCenter + + + + + + + Select output curve for Accessory0 RcInput + + + + + + + Select output curve for Accessory3 RcInput + + + + + + + Select output curve for Accessory2 RcInput + + + + + + + + 90 + 0 + + + + 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; + + + Accessory3 + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Select output channel for Accessory3 RcInput + + + + + + + + 0 + 0 + + + + + 110 + 0 + + + + RcOutput channels + + + 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; + + + RC Output 2 + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Select output channel for Accessory0 RcInput + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Select output channel for Accessory1 RcInput + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Select output channel for Accessory2 RcInput + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Select output channel for Accessory3 RcInput + + + + + + + + + Qt::Vertical + + + diff --git a/ground/gcs/src/plugins/config/airframe_multirotor.ui b/ground/gcs/src/plugins/config/airframe_multirotor.ui index 3d46b693a..a50cc8969 100644 --- a/ground/gcs/src/plugins/config/airframe_multirotor.ui +++ b/ground/gcs/src/plugins/config/airframe_multirotor.ui @@ -861,7 +861,16 @@ margin:1px; 6 - + + + + 80 + 0 + + + + Qt::AlignCenter + 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); @@ -870,7 +879,7 @@ font: bold 12px; margin:1px; - 5 + Pos5 @@ -891,7 +900,16 @@ margin:1px; - + + + + 80 + 0 + + + + Qt::AlignCenter + 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); @@ -900,7 +918,7 @@ font: bold 12px; margin:1px; - 6 + Pos6 @@ -921,7 +939,16 @@ margin:1px; - + + + + 80 + 0 + + + + Qt::AlignCenter + 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); @@ -930,7 +957,7 @@ font: bold 12px; margin:1px; - 7 + Pos7 @@ -951,7 +978,16 @@ margin:1px; - + + + + 80 + 0 + + + + Qt::AlignCenter + 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); @@ -960,7 +996,7 @@ font: bold 12px; margin:1px; - 8 + Pos8 @@ -1029,7 +1065,16 @@ margin:1px; 6 - + + + + 80 + 0 + + + + Qt::AlignCenter + 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); @@ -1038,7 +1083,7 @@ font: bold 12px; margin:1px; - 1 + Pos1 @@ -1056,7 +1101,16 @@ margin:1px; - + + + + 80 + 0 + + + + Qt::AlignCenter + 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); @@ -1065,7 +1119,7 @@ font: bold 12px; margin:1px; - 2 + Pos2 @@ -1083,7 +1137,16 @@ margin:1px; - + + + + 80 + 0 + + + + Qt::AlignCenter + 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); @@ -1092,7 +1155,7 @@ font: bold 12px; margin:1px; - 3 + Pos3 @@ -1110,7 +1173,16 @@ margin:1px; - + + + + 80 + 0 + + + + Qt::AlignCenter + 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); @@ -1119,7 +1191,7 @@ font: bold 12px; margin:1px; - 4 + Pos4 diff --git a/ground/gcs/src/plugins/config/autotune.ui b/ground/gcs/src/plugins/config/autotune.ui index 595096a2c..2cfadba55 100644 --- a/ground/gcs/src/plugins/config/autotune.ui +++ b/ground/gcs/src/plugins/config/autotune.ui @@ -23,7 +23,16 @@ 6 - + + 12 + + + 12 + + + 12 + + 12 @@ -36,11 +45,38 @@ Pre-Autotune - + + 12 + + + 12 + + + 12 + + 12 + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + QFrame::StyledPanel @@ -51,9 +87,9 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Lucida Grande'; font-size:20pt; font-weight:600; color:#ff0000;">WARNING:</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Lucida Grande'; font-size:13pt;"></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Lucida Grande'; font-size:13pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Lucida Grande'; font-size:13pt;"><br /></span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Lucida Grande'; font-size:13pt;"><br /></span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Lucida Grande'; font-size:13pt;">This is an experimental plugin for the GCS that is going to make your aircraft shake, etc, so test with lots of space and be </span><span style=" font-family:'Lucida Grande'; font-size:13pt; font-weight:600;">very very wary</span><span style=" font-family:'Lucida Grande'; font-size:13pt;"> for it creating bad tuning values.  Basically there is no reason to think this will work at all.<br /><br />To use autotuning, here are the steps:<br /></span></p> @@ -99,7 +135,16 @@ p, li { white-space: pre-wrap; } Autotune Setup - + + 0 + + + 0 + + + 0 + + 0 @@ -182,8 +227,8 @@ p, li { white-space: pre-wrap; } 0 0 - 709 - 605 + 526 + 510 @@ -199,7 +244,16 @@ p, li { white-space: pre-wrap; } 12 - + + 12 + + + 12 + + + 12 + + 12 @@ -231,7 +285,7 @@ p, li { white-space: pre-wrap; } Qt::Horizontal - + objname:RelayTuningSettings fieldname:RateGain scale:0.01 @@ -249,7 +303,7 @@ p, li { white-space: pre-wrap; } Qt::Horizontal - + objname:RelayTuningSettings fieldname:AttitudeGain scale:0.01 @@ -283,7 +337,7 @@ p, li { white-space: pre-wrap; } Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - + objname:RelayTuning fieldname:Period element:Roll @@ -300,7 +354,7 @@ p, li { white-space: pre-wrap; } Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - + objname:RelayTuning fieldname:Gain element:Roll @@ -338,7 +392,7 @@ p, li { white-space: pre-wrap; } Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - + objname:RelayTuning fieldname:Period element:Pitch @@ -355,7 +409,7 @@ p, li { white-space: pre-wrap; } Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - + objname:RelayTuning fieldname:Gain element:Pitch @@ -507,7 +561,7 @@ p, li { white-space: pre-wrap; } Qt::Horizontal - + objname:RelayTuningSettings fieldname:Amplitude scale:0.01 @@ -601,7 +655,45 @@ will alter settings for the next autotuning flight - + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + + + + + :/core/images/helpicon.svg:/core/images/helpicon.svg + + + + 25 + 25 + + + + button:help + + + + + 0 @@ -619,7 +711,7 @@ Useful if you have accidentally changed some settings. Reload Board Data - + button:reload buttongroup:10 @@ -627,7 +719,7 @@ Useful if you have accidentally changed some settings. - + 0 @@ -644,14 +736,14 @@ Useful if you have accidentally changed some settings. Apply - + button:apply - + 0 @@ -668,7 +760,7 @@ Useful if you have accidentally changed some settings. Save - + button:save @@ -678,6 +770,8 @@ Useful if you have accidentally changed some settings. - + + + diff --git a/ground/gcs/src/plugins/config/calibration/levelcalibrationmodel.cpp b/ground/gcs/src/plugins/config/calibration/levelcalibrationmodel.cpp index 51d652afb..0d2b31cab 100644 --- a/ground/gcs/src/plugins/config/calibration/levelcalibrationmodel.cpp +++ b/ground/gcs/src/plugins/config/calibration/levelcalibrationmodel.cpp @@ -28,6 +28,7 @@ #include "levelcalibrationmodel.h" #include "extensionsystem/pluginmanager.h" #include "calibration/calibrationuiutils.h" +#include "uavobjectmanager.h" #include #include diff --git a/ground/gcs/src/plugins/config/calibration/sixpointcalibrationmodel.cpp b/ground/gcs/src/plugins/config/calibration/sixpointcalibrationmodel.cpp index 276362643..52ab32409 100644 --- a/ground/gcs/src/plugins/config/calibration/sixpointcalibrationmodel.cpp +++ b/ground/gcs/src/plugins/config/calibration/sixpointcalibrationmodel.cpp @@ -2,7 +2,8 @@ ****************************************************************************** * * @file sixpointcalibrationmodel.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014. * * @brief Six point calibration for Magnetometer and Accelerometer * @see The GNU Public License (GPL) Version 3 @@ -28,6 +29,8 @@ #include "sixpointcalibrationmodel.h" #include "extensionsystem/pluginmanager.h" #include "calibration/calibrationuiutils.h" +#include "uavobjectmanager.h" +#include #include #include @@ -155,6 +158,8 @@ void SixPointCalibrationModel::start(bool calibrateAccel, bool calibrateMag) // Store and reset board rotation before calibration starts storeAndClearBoardRotation(); + UAVObjectUpdaterHelper updateHelper; + // Calibration accel AccelGyroSettings::DataFields accelGyroSettingsData = accelGyroSettings->getData(); memento.accelGyroSettingsData = accelGyroSettingsData; @@ -166,7 +171,8 @@ void SixPointCalibrationModel::start(bool calibrateAccel, bool calibrateMag) accelGyroSettingsData.accel_bias[AccelGyroSettings::ACCEL_BIAS_Y] = 0; accelGyroSettingsData.accel_bias[AccelGyroSettings::ACCEL_BIAS_Z] = 0; - accelGyroSettings->setData(accelGyroSettingsData); + accelGyroSettings->setData(accelGyroSettingsData, false); + updateHelper.doObjectAndWait(accelGyroSettings); // Calibration mag RevoCalibration::DataFields revoCalibrationData = revoCalibration->getData(); @@ -186,7 +192,8 @@ void SixPointCalibrationModel::start(bool calibrateAccel, bool calibrateMag) // Disable adaptive mag nulling revoCalibrationData.MagBiasNullingRate = 0; - revoCalibration->setData(revoCalibrationData); + revoCalibration->setData(revoCalibrationData, false); + updateHelper.doObjectAndWait(revoCalibration); // Calibration AuxMag AuxMagSettings::DataFields auxMagSettingsData = auxMagSettings->getData(); @@ -206,9 +213,8 @@ void SixPointCalibrationModel::start(bool calibrateAccel, bool calibrateMag) // Disable adaptive mag nulling auxMagSettingsData.MagBiasNullingRate = 0; - auxMagSettings->setData(auxMagSettingsData); - - QThread::usleep(100000); + auxMagSettings->setData(auxMagSettingsData, false); + updateHelper.doObjectAndWait(auxMagSettings); mag_accum_x.clear(); mag_accum_y.clear(); diff --git a/ground/gcs/src/plugins/config/calibration/thermal/thermalcalibration.h b/ground/gcs/src/plugins/config/calibration/thermal/thermalcalibration.h index 1589226f3..abfeff18f 100644 --- a/ground/gcs/src/plugins/config/calibration/thermal/thermalcalibration.h +++ b/ground/gcs/src/plugins/config/calibration/thermal/thermalcalibration.h @@ -41,13 +41,13 @@ class ThermalCalibration { static const int BARO_PRESSURE_POLY_DEGREE = 3; // TODO: determine max allowable relative error - static const double BARO_PRESSURE_MAX_REL_ERROR = 1E-6f; - static const double ACCEL_X_MAX_REL_ERROR = 1E-6f; - static const double ACCEL_Y_MAX_REL_ERROR = 1E-6f; - static const double ACCEL_Z_MAX_REL_ERROR = 1E-6f; - static const double GYRO_X_MAX_REL_ERROR = 1E-6f; - static const double GYRO_Y_MAX_REL_ERROR = 1E-6f; - static const double GYRO_Z_MAX_REL_ERROR = 1E-6f; + constexpr static const double BARO_PRESSURE_MAX_REL_ERROR = 1E-6f; + constexpr static const double ACCEL_X_MAX_REL_ERROR = 1E-6f; + constexpr static const double ACCEL_Y_MAX_REL_ERROR = 1E-6f; + constexpr static const double ACCEL_Z_MAX_REL_ERROR = 1E-6f; + constexpr static const double GYRO_X_MAX_REL_ERROR = 1E-6f; + constexpr static const double GYRO_Y_MAX_REL_ERROR = 1E-6f; + constexpr static const double GYRO_Z_MAX_REL_ERROR = 1E-6f; public: /** diff --git a/ground/gcs/src/plugins/config/calibration/thermal/thermalcalibrationhelper.h b/ground/gcs/src/plugins/config/calibration/thermal/thermalcalibrationhelper.h index 60a61d8bc..5a5560d2e 100644 --- a/ground/gcs/src/plugins/config/calibration/thermal/thermalcalibrationhelper.h +++ b/ground/gcs/src/plugins/config/calibration/thermal/thermalcalibrationhelper.h @@ -93,8 +93,8 @@ class ThermalCalibrationHelper : public QObject { Q_OBJECT public: - const static float TargetGradient = 0.20f; - const static float TargetTempDelta = 10.0f; + constexpr const static float TargetGradient = 0.20f; + constexpr const static float TargetTempDelta = 10.0f; explicit ThermalCalibrationHelper(QObject *parent = 0); diff --git a/ground/gcs/src/plugins/config/camerastabilization.ui b/ground/gcs/src/plugins/config/camerastabilization.ui index 388d147fc..33bd1ef56 100644 --- a/ground/gcs/src/plugins/config/camerastabilization.ui +++ b/ground/gcs/src/plugins/config/camerastabilization.ui @@ -72,7 +72,7 @@ 0 - -103 + 0 748 811 @@ -143,7 +143,7 @@ have to define channel output range using Output configuration tab. 20 - + objname:CameraStabSettings fieldname:OutputRange element:Yaw @@ -172,7 +172,7 @@ have to define channel output range using Output configuration tab. 20 - + objname:CameraStabSettings fieldname:OutputRange element:Pitch @@ -201,7 +201,7 @@ have to define channel output range using Output configuration tab. 20 - + objname:CameraStabSettings fieldname:OutputRange element:Roll @@ -429,7 +429,7 @@ font:bold; Don't forget to map this channel using Input configuration tab. - + objname:CameraStabSettings fieldname:Input element:Yaw @@ -454,7 +454,7 @@ Don't forget to map this channel using Input configuration tab. Don't forget to map this channel using Input configuration tab. - + objname:CameraStabSettings fieldname:Input element:Pitch @@ -479,7 +479,7 @@ Don't forget to map this channel using Input configuration tab. Don't forget to map this channel using Input configuration tab. - + objname:CameraStabSettings fieldname:Input element:Roll @@ -512,7 +512,7 @@ Attitude: camera tracks level for the axis. Input controls the deflection. AxisLock: camera remembers tracking attitude. Input controls the rate of deflection. - + objname:CameraStabSettings fieldname:StabilizationMode element:Yaw @@ -541,7 +541,7 @@ AxisLock: camera remembers tracking attitude. Input controls the rate of deflect 20 - + objname:CameraStabSettings fieldname:InputRange element:Yaw @@ -567,7 +567,7 @@ AxisLock: camera remembers tracking attitude. Input controls the rate of deflect 50 - + objname:CameraStabSettings fieldname:InputRate element:Yaw @@ -590,7 +590,7 @@ Attitude: camera tracks level for the axis. Input controls the deflection. AxisLock: camera remembers tracking attitude. Input controls the rate of deflection. - + objname:CameraStabSettings fieldname:StabilizationMode element:Pitch @@ -619,7 +619,7 @@ AxisLock: camera remembers tracking attitude. Input controls the rate of deflect 20 - + objname:CameraStabSettings fieldname:InputRange element:Pitch @@ -645,7 +645,7 @@ AxisLock: camera remembers tracking attitude. Input controls the rate of deflect 50 - + objname:CameraStabSettings fieldname:InputRate element:Pitch @@ -668,7 +668,7 @@ Attitude: camera tracks level for the axis. Input controls the deflection. AxisLock: camera remembers tracking attitude. Input controls the rate of deflection. - + objname:CameraStabSettings fieldname:StabilizationMode element:Roll @@ -697,7 +697,7 @@ AxisLock: camera remembers tracking attitude. Input controls the rate of deflect 20 - + objname:CameraStabSettings fieldname:InputRange element:Roll @@ -723,7 +723,7 @@ AxisLock: camera remembers tracking attitude. Input controls the rate of deflect 50 - + objname:CameraStabSettings fieldname:InputRate element:Roll @@ -794,7 +794,7 @@ value. 1.000000000000000 - + objname:CameraStabSettings fieldname:MaxAxisLockRate haslimits:no @@ -902,7 +902,7 @@ Smoothes estimated airframe attitude used by camera stabilization. 250 - + objname:CameraStabSettings fieldname:ResponseTime element:Roll @@ -924,7 +924,7 @@ Smoothes estimated airframe attitude used by camera stabilization. 250 - + objname:CameraStabSettings fieldname:ResponseTime element:Pitch @@ -946,7 +946,7 @@ Smoothes estimated airframe attitude used by camera stabilization. 250 - + objname:CameraStabSettings fieldname:ResponseTime element:Yaw @@ -976,7 +976,7 @@ Too high value may burn your servo! 25 - + objname:CameraStabSettings fieldname:FeedForward element:Roll @@ -1001,7 +1001,7 @@ Too high value may burn your servo! 25 - + objname:CameraStabSettings fieldname:FeedForward element:Pitch @@ -1026,7 +1026,7 @@ Too high value may burn your servo! 25 - + objname:CameraStabSettings fieldname:FeedForward element:Yaw @@ -1058,7 +1058,7 @@ Range: 0-50ms, default is 5. 5 - + objname:CameraStabSettings fieldname:AccelTime element:Roll @@ -1081,7 +1081,7 @@ Range: 0-50ms, default is 5. 5 - + objname:CameraStabSettings fieldname:AccelTime element:Pitch @@ -1104,7 +1104,7 @@ Range: 0-50ms, default is 5. 5 - + objname:CameraStabSettings fieldname:AccelTime element:Yaw @@ -1134,7 +1134,7 @@ Range: 0-50ms, default is 5. 5 - + objname:CameraStabSettings fieldname:DecelTime element:Roll @@ -1157,7 +1157,7 @@ Range: 0-50ms, default is 5. 5 - + objname:CameraStabSettings fieldname:DecelTime element:Pitch @@ -1180,7 +1180,7 @@ Range: 0-50ms, default is 5. 5 - + objname:CameraStabSettings fieldname:DecelTime element:Yaw @@ -1208,7 +1208,7 @@ Used to limit feed forward acceleration at extreme angles. Generic type provides no limit. - + objname:CameraStabSettings fieldname:GimbalType buttongroup:1 @@ -1244,7 +1244,7 @@ The same value is used for all axes. 500 - + objname:CameraStabSettings fieldname:MaxAccel buttongroup:1 @@ -1321,7 +1321,7 @@ The same value is used for all axes. - + 0 @@ -1362,14 +1362,14 @@ The same value is used for all axes. true - + button:help - + 0 @@ -1392,7 +1392,7 @@ Apply or Save button afterwards. Reset To Defaults - + button:default buttongroup:1 @@ -1400,7 +1400,7 @@ Apply or Save button afterwards. - + 0 @@ -1425,7 +1425,7 @@ Apply or Save button afterwards. Reload Board Data - + button:reload buttongroup:1 @@ -1433,7 +1433,7 @@ Apply or Save button afterwards. - + 0 @@ -1453,14 +1453,14 @@ Apply or Save button afterwards. Apply - + button:apply - + 0 @@ -1483,7 +1483,7 @@ Apply or Save button afterwards. false - + button:save @@ -1528,10 +1528,10 @@ Apply or Save button afterwards. yawDecelTime gimbalType maxAccel - camerastabilizationResetToDefaults - pushButton - camerastabilizationSaveRAM - camerastabilizationSaveSD + defaultButton + reloadButton + applyButton + saveButton diff --git a/ground/gcs/src/plugins/config/cc_hw_settings.ui b/ground/gcs/src/plugins/config/cc_hw_settings.ui index ed7a8e079..45ca67b84 100644 --- a/ground/gcs/src/plugins/config/cc_hw_settings.ui +++ b/ground/gcs/src/plugins/config/cc_hw_settings.ui @@ -254,13 +254,6 @@ - - - - Select the speed here. - - - @@ -268,19 +261,6 @@ - - - - - 55 - 0 - - - - ComUsbBridge speed: - - - @@ -476,7 +456,7 @@ - + 0 @@ -514,10 +494,13 @@ true + + button:help + - + 0 @@ -616,10 +599,13 @@ Beware of not locking yourself out! false + + button:apply + - + 0 @@ -645,6 +631,9 @@ Beware of not locking yourself out! Save + + button:save + diff --git a/ground/gcs/src/plugins/config/ccattitude.ui b/ground/gcs/src/plugins/config/ccattitude.ui index 1a659982e..3644ea55f 100644 --- a/ground/gcs/src/plugins/config/ccattitude.ui +++ b/ground/gcs/src/plugins/config/ccattitude.ui @@ -117,7 +117,7 @@ 0 0 758 - 486 + 480 @@ -157,12 +157,12 @@ font:bold; - + - -180 + -180.000000000000000 - 180 + 180.000000000000000 @@ -180,12 +180,12 @@ font:bold; - + - -180 + -180.000000000000000 - 180 + 180.000000000000000 @@ -237,12 +237,12 @@ font:bold; - + - -90 + -180.000000000000000 - 90 + 180.000000000000000 @@ -299,7 +299,7 @@ font:bold; - Place aircraft very flat, and then click level to compute the accelerometer and gyro bias + Place vehicle very flat, and then click level to compute the accelerometer and gyro bias true @@ -366,17 +366,44 @@ font:bold; + + + + + + If enabled, this option prevents gyro initialization while the board is moving. + + + Wait until the board is steady + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + If enabled, a fast recalibration of gyro zero point will be done -whenever the frame is armed. Do not move the airframe while +whenever the board is armed. Do not move the vehicle while arming it in that case! - Zero gyros while arming aircraft + Zero gyros while arming @@ -523,7 +550,7 @@ A setting of 0.00 disables the filter. - + 0 @@ -555,6 +582,9 @@ A setting of 0.00 disables the filter. true + + button:help + @@ -568,6 +598,9 @@ A setting of 0.00 disables the filter. Apply + + button:apply + @@ -584,6 +617,9 @@ A setting of 0.00 disables the filter. Save + + button:save + diff --git a/ground/gcs/src/plugins/config/ccpm_old.ui b/ground/gcs/src/plugins/config/ccpm_old.ui deleted file mode 100644 index cfc6846a7..000000000 --- a/ground/gcs/src/plugins/config/ccpm_old.ui +++ /dev/null @@ -1,3653 +0,0 @@ - - - ccpmWidget - - - - 0 - 0 - 850 - 572 - - - - - 0 - 0 - - - - - 300 - 300 - - - - Form - - - false - - - - - - - - QFormLayout::AllNonFixedFieldsGrow - - - 0 - - - - - Swashplate config: - - - - - - - Select aircraft type here - - - - - - - - - - 0 - 0 - - - - - 300 - 300 - - - - #SwashplateBox,#SwashplateBox_2,#SwashplateBox_3,#SwashplateBox_4,#ccpmSwashImageBox,#SwashLvlInstructionsBox,#SwashLvlccpmSwashImageBox,#SwashLvlccpmSliderBox,#SwashLvlStatusBox,#ThrottleCurveBox,#PitchCurveBox{ -background-color: qlineargradient(spread:pad, x1:0.507, y1:0.869318, x2:0.507, y2:0.0965909, stop:0 rgba(243, 243, 243, 255), stop:1 rgba(250, 250, 250, 255)); -border: 1px outset #999; -border-radius: 3; -font:bold; -} - -QGroupBox::title { - subcontrol-origin: margin; - subcontrol-position: top center; /* position at the top center */ - padding: 0 3px; - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #FFOECE, stop: 1 #FFFFFF); - top: 5px; - } - - - 0 - - - - Basic settings - - - - 3 - - - 0 - - - 3 - - - 3 - - - 3 - - - - - - - - 0 - 0 - - - - - 190 - 16777215 - - - - Motor outputs - - - - 3 - - - 2 - - - 3 - - - - - - 0 - 0 - - - - - 85 - 0 - - - - - 100 - 16777215 - - - - - - - - - 0 - 0 - - - - - 85 - 0 - - - - - 100 - 16777215 - - - - - - - - - 0 - 0 - - - - - 80 - 0 - - - - - 80 - 16777215 - - - - Tail Rotor - - - - - - - - 0 - 0 - - - - - 80 - 0 - - - - - 80 - 16777215 - - - - Engine - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 20 - - - - - - - - - - - - 0 - 0 - - - - - 190 - 16777215 - - - - Swashplate outputs - - - - 3 - - - 2 - - - 3 - - - - - true - - - - 1 - 1 - - - - - 80 - 0 - - - - - 80 - 16777215 - - - - Servo W - - - - - - - true - - - - 0 - 0 - - - - - 85 - 0 - - - - - 100 - 16777215 - - - - - - - - - 0 - 0 - - - - - 85 - 0 - - - - - 100 - 16777215 - - - - - - - - true - - - - 0 - 0 - - - - - 85 - 0 - - - - - 100 - 16777215 - - - - - - - - - 1 - 1 - - - - - 80 - 0 - - - - - 80 - 16777215 - - - - Servo X - - - - - - - - 0 - 0 - - - - - 85 - 0 - - - - - 100 - 16777215 - - - - - Front - - - - - Right - - - - - Rear - - - - - Left - - - - - - - - - 1 - 1 - - - - - 80 - 0 - - - - - 80 - 16777215 - - - - 1st Servo - - - - - - - - 0 - 0 - - - - - 85 - 0 - - - - - 100 - 16777215 - - - - - - - - - 1 - 1 - - - - - 80 - 0 - - - - - 80 - 16777215 - - - - Servo Z - - - - - - - true - - - - 1 - 1 - - - - - 80 - 0 - - - - - 80 - 16777215 - - - - Servo Y - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 20 - - - - - - - - - - - - 0 - 0 - - - - - 70 - 0 - - - - - 190 - 16777215 - - - - Swashplate Servo Angles - - - - 3 - - - 2 - - - 3 - - - - - - 0 - 0 - - - - - 85 - 0 - - - - - 85 - 16777215 - - - - 0 - - - 360.000000000000000 - - - 15.000000000000000 - - - - - - - true - - - - 0 - 0 - - - - - 80 - 0 - - - - - 80 - 16777215 - - - - Angle W - - - - - - - - 0 - 0 - - - - - 80 - 0 - - - - - 80 - 16777215 - - - - Angle X - - - - - - - true - - - - 0 - 0 - - - - - 80 - 0 - - - - - 80 - 16777215 - - - - Angle Y - - - - - - - - 0 - 0 - - - - - 80 - 0 - - - - - 80 - 16777215 - - - - Angle Z - - - - - - - true - - - - 0 - 0 - - - - - 80 - 0 - - - - - 80 - 16777215 - - - - Correction Angle - - - true - - - - - - - - 0 - 0 - - - - - 85 - 0 - - - - - 85 - 16777215 - - - - 0 - - - 360.000000000000000 - - - 15.000000000000000 - - - - - - - true - - - - 0 - 0 - - - - - 85 - 0 - - - - - 85 - 16777215 - - - - 0 - - - 360.000000000000000 - - - 15.000000000000000 - - - - - - - - 0 - 0 - - - - - 85 - 0 - - - - - 85 - 16777215 - - - - 0 - - - 360.000000000000000 - - - 15.000000000000000 - - - - - - - - 0 - 0 - - - - - 85 - 0 - - - - - 85 - 16777215 - - - - 0 - - - 360.000000000000000 - - - 15.000000000000000 - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 20 - - - - - - - - - - - - 0 - 0 - - - - - 190 - 16777215 - - - - CCPM Options - - - - 3 - - - 2 - - - 3 - - - - - Collective Pass through - - - - - - - Link Roll/Pitch - - - true - - - - - - - Link Cyclic/Collective - - - true - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 20 - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - 0 - - - 0 - - - - - - 1 - 1 - - - - - 200 - 200 - - - - - 600 - 600 - - - - - 10 - 10 - - - - - 200 - 200 - - - - - 75 - false - true - - - - Swashplate Layout - - - Qt::AlignHCenter|Qt::AlignTop - - - false - - - false - - - - 3 - - - 3 - - - - - Qt::Vertical - - - - - 1 - 1 - - - - - 10 - 10 - - - - - 1000 - 1000 - - - - - 10 - 10 - - - - - 200 - 200 - - - - QFrame::Box - - - QFrame::Plain - - - 1 - - - Qt::ScrollBarAlwaysOff - - - Qt::ScrollBarAlwaysOff - - - - - 112 - 184 - 138 - - - - - - - 127 - 127 - 127 - - - - - - 0.000000000000000 - 0.000000000000000 - 400.000000000000000 - 400.000000000000000 - - - - Qt::AlignCenter - - - QGraphicsView::AnchorViewCenter - - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 20 - - - - - - - - - - - - - QLayout::SetNoConstraint - - - 3 - - - 3 - - - - - true - - - - 0 - 0 - - - - - 50 - 100 - - - - - 50 - 600 - - - - - 9 - 75 - true - - - - QGroupBox::title { - 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; -margin:1px; - } - - - REVO - - - - 0 - - - 3 - - - - - Qt::Vertical - - - QSizePolicy::Minimum - - - - 20 - 7 - - - - - - - - false - - - - 7 - - - - 100% - - - Qt::AlignCenter - - - - - - - - - Qt::Horizontal - - - - 5 - 25 - - - - - - - - true - - - - 0 - 0 - - - - - 0 - 100 - - - - 100 - - - 5 - - - Qt::Vertical - - - - - - - Qt::Horizontal - - - - 5 - 25 - - - - - - - - - - false - - - - 7 - - - - 0% - - - Qt::AlignCenter - - - - - - - - - - - - - true - - - - 0 - 0 - - - - - 60 - 100 - - - - - 50 - 600 - - - - - 9 - 75 - true - - - - QGroupBox::title { - 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; -margin:1px; - } - - - CCPM - - - Qt::AlignCenter - - - - 0 - - - 3 - - - - - Qt::Vertical - - - QSizePolicy::Minimum - - - - 20 - 7 - - - - - - - - true - - - - 7 - - - - Collective - - - true - - - Qt::AlignCenter - - - - - - - - - Qt::Horizontal - - - - 5 - 25 - - - - - - - - true - - - - 0 - 0 - - - - - 0 - 100 - - - - 100 - - - 5 - - - 50 - - - Qt::Vertical - - - - - - - Qt::Horizontal - - - - 5 - 25 - - - - - - - - - - true - - - - 7 - - - - Cyclic - - - Qt::AlignCenter - - - - - - - 100 - - - 5 - - - 50 - - - - - - - - - - true - - - - 0 - 0 - - - - - 70 - 100 - - - - - 50 - 600 - - - - - 9 - 75 - true - - - - QGroupBox::title { - 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; -margin:1px; - } - - - Collective - - - Qt::AlignCenter - - - - 0 - - - 3 - - - - - Qt::Vertical - - - QSizePolicy::Minimum - - - - 20 - 7 - - - - - - - - - - Qt::Horizontal - - - - 5 - 25 - - - - - - - - true - - - - 0 - 0 - - - - - 0 - 100 - - - - 100 - - - 5 - - - 50 - - - Qt::Vertical - - - - - - - Qt::Horizontal - - - - 5 - 25 - - - - - - - - - - 100 - - - 5 - - - 50 - - - - - - - - - - true - - - - 0 - 0 - - - - - 50 - 100 - - - - - 50 - 600 - - - - - 9 - 75 - true - - - - QGroupBox::title { - 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; -margin:1px; - } - - - Cyclic - - - Qt::AlignCenter - - - false - - - - 0 - - - 3 - - - - - Qt::Vertical - - - QSizePolicy::Minimum - - - - 20 - 7 - - - - - - - - - - Qt::Horizontal - - - - 5 - 25 - - - - - - - - true - - - - 0 - 0 - - - - - 0 - 100 - - - - 100 - - - 5 - - - 50 - - - Qt::Vertical - - - - - - - Qt::Horizontal - - - - 5 - 25 - - - - - - - - - - 100 - - - 5 - - - 50 - - - - - - - - - - true - - - - 0 - 0 - - - - - 50 - 100 - - - - - 50 - 600 - - - - - 9 - 75 - true - - - - QGroupBox::title { - 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; -margin:1px; - } - - - Pitch - - - Qt::AlignCenter - - - - 0 - - - 3 - - - - - Qt::Vertical - - - QSizePolicy::Minimum - - - - 20 - 7 - - - - - - - - - - Qt::Horizontal - - - - 5 - 25 - - - - - - - - true - - - - 0 - 0 - - - - - 0 - 100 - - - - 100 - - - 5 - - - 50 - - - Qt::Vertical - - - - - - - Qt::Horizontal - - - - 5 - 25 - - - - - - - - - - 100 - - - 5 - - - 50 - - - - - - - - - - true - - - - 0 - 0 - - - - - 50 - 100 - - - - - 50 - 600 - - - - - 9 - 75 - true - - - - QGroupBox::title { - 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; -margin:1px; - } - - - Roll - - - Qt::AlignCenter - - - - 0 - - - 3 - - - - - Qt::Vertical - - - QSizePolicy::Minimum - - - - 20 - 7 - - - - - - - - - - Qt::Horizontal - - - - 5 - 25 - - - - - - - - true - - - - 0 - 0 - - - - - 0 - 100 - - - - 100 - - - 5 - - - 50 - - - Qt::Vertical - - - - - - - Qt::Horizontal - - - - 5 - 25 - - - - - - - - - - 100 - - - 5 - - - 50 - - - - - - - - - - - - - Swashplate Levelling - - - - 3 - - - 3 - - - - - 3 - - - - - - 0 - 0 - - - - - 228 - 0 - - - - Commands - - - - 3 - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 20 - - - - - - - - 0 - - - - - - 85 - 0 - - - - - 85 - 16777215 - - - - Start - - - - - - - false - - - - 85 - 0 - - - - - 85 - 16777215 - - - - Next - - - - - - - - - - 0 - 150 - - - - - 220 - 450 - - - - Qt::ScrollBarAlwaysOff - - - true - - - - - - - - - false - - - - 170 - 0 - - - - - 170 - 16777215 - - - - Cancel - - - - - - - false - - - - 170 - 0 - - - - - 170 - 16777215 - - - - Finish - - - - - - - - - - - - - 0 - 0 - - - - - 200 - 0 - - - - Status - - - - 3 - - - 2 - - - 3 - - - - - - 220 - 0 - - - - - 190 - 125 - - - - QAbstractItemView::NoEditTriggers - - - true - - - QAbstractItemView::NoSelection - - - QAbstractItemView::SelectRows - - - - Neutral - - - - :/configgadget/images/none.png - :/configgadget/images/ok.png:/configgadget/images/none.png - - - - - Max - - - - :/configgadget/images/none.png - :/configgadget/images/ok.png:/configgadget/images/none.png - - - - - Min - - - - :/configgadget/images/none.png - :/configgadget/images/ok.png:/configgadget/images/none.png - - - ItemIsSelectable|ItemIsEnabled - - - - - Verify - - - - :/configgadget/images/none.png - :/configgadget/images/ok.png:/configgadget/images/none.png - - - ItemIsEnabled - - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 20 - - - - - - - - - - - Qt::Vertical - - - QSizePolicy::MinimumExpanding - - - - 20 - 0 - - - - - - - - - - true - - - - 0 - 0 - - - - - 70 - 100 - - - - - 50 - 600 - - - - Position - - - Qt::AlignCenter - - - - 0 - - - 3 - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 20 - - - - - - - - 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; - - - Max - - - true - - - Qt::AlignCenter - - - - - - - - - Qt::Horizontal - - - - 5 - 25 - - - - - - - - true - - - - 0 - 0 - - - - - 0 - 100 - - - - 100 - - - 5 - - - 50 - - - Qt::Vertical - - - - - - - Qt::Horizontal - - - - 5 - 25 - - - - - - - - - - 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; - - - Min - - - Qt::AlignCenter - - - - - - - 100 - - - 5 - - - 50 - - - - - - - - - - - 1 - 1 - - - - - 200 - 200 - - - - - 600 - 600 - - - - - 10 - 10 - - - - - 200 - 200 - - - - Swashplate Adjustment - - - Qt::AlignHCenter|Qt::AlignTop - - - false - - - false - - - - 3 - - - 3 - - - - - Qt::Vertical - - - - - 1 - 1 - - - - - 10 - 10 - - - - - 1000 - 1000 - - - - - 10 - 10 - - - - - 200 - 200 - - - - QFrame::Box - - - QFrame::Plain - - - 1 - - - 0 - - - Qt::ScrollBarAlwaysOff - - - Qt::ScrollBarAlwaysOff - - - - - 126 - 176 - 220 - - - - - - - 0 - 0 - 0 - - - - - - 0.000000000000000 - 0.000000000000000 - 400.000000000000000 - 400.000000000000000 - - - - Qt::AlignCenter - - - QGraphicsView::AnchorViewCenter - - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 20 - - - - - - - - - - - - Curve settings - - - - 3 - - - 3 - - - - - - - - 3 - - - - - - 1 - 1 - - - - - 100 - 100 - - - - - 10 - 10 - - - - - 100 - 100 - - - - Qt::LeftToRight - - - - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - false - - - - 0 - - - 0 - - - - - - 1 - 1 - - - - - 50 - 50 - - - - - 1000 - 1000 - - - - - 10 - 10 - - - - - 200 - 200 - - - - - - - - - - - - 1 - 1 - - - - - 100 - 100 - - - - - 10 - 10 - - - - - 100 - 100 - - - - - - - - 0 - - - 0 - - - - - - 1 - 1 - - - - - 50 - 50 - - - - - 1000 - 1000 - - - - - 10 - 10 - - - - - 200 - 200 - - - - - - - - - - - - - Qt::Vertical - - - QSizePolicy::Preferred - - - - 20 - 0 - - - - - - - - - Advanced settings - - - - 3 - - - 3 - - - - - - 0 - 0 - - - - - 0 - 200 - - - - - 1000 - 300 - - - - Qt::ScrollBarAlwaysOff - - - Qt::ScrollBarAlwaysOff - - - true - - - true - - - QAbstractItemView::NoSelection - - - false - - - true - - - 75 - - - 20 - - - - Engine - - - - - Tail Rotor - - - - - Servo W - - - - - Servo X - - - - - Servo Y - - - - - Servo Z - - - - - Channel - - - - - Curve 1 - - - - - Curve 2 - - - - - Roll - - - - - Pitch - - - - - Yaw - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - Qt::Vertical - - - QSizePolicy::MinimumExpanding - - - - 20 - 40 - - - - - - - - - - - - - - - MixerCurve - QWidget -
mixercurve.h
- 1 -
-
- - ccpmType - TabObject - ccpmEngineChannel - ccpmTailChannel - ccpmServoWChannel - ccpmServoXChannel - ccpmServoYChannel - ccpmServoZChannel - ccpmSingleServo - ccpmAngleW - ccpmAngleX - ccpmAngleY - ccpmAngleZ - ccpmCorrectionAngle - ccpmRevoSlider - ccpmREVOspinBox - ccpmCollectiveSlider - ccpmCollectivespinBox - SwashplateImage - SwashLvlStartButton - SwashLvlNextButton - SwashLvlStepInstruction - SwashLvlCancelButton - SwashLvlFinishButton - SwashLvlStepList - SwashLvlPositionSlider - SwashLvlPositionSpinBox - SwashLvlSwashplateImage - ccpmAdvancedSettingsTable - - - - - ccpmCollectiveSlider - valueChanged(int) - ccpmCollectivespinBox - setValue(int) - - - 261 - 496 - - - 269 - 546 - - - - - ccpmCollectivespinBox - valueChanged(int) - ccpmCollectiveSlider - setValue(int) - - - 269 - 546 - - - 261 - 511 - - - - - ccpmREVOspinBox - valueChanged(int) - ccpmRevoSlider - setValue(int) - - - 216 - 546 - - - 208 - 511 - - - - - ccpmRevoSlider - valueChanged(int) - ccpmREVOspinBox - setValue(int) - - - 208 - 412 - - - 216 - 546 - - - - - SwashLvlPositionSlider - valueChanged(int) - SwashLvlPositionSpinBox - setValue(int) - - - 276 - 486 - - - 270 - 537 - - - - - SwashLvlPositionSpinBox - valueChanged(int) - SwashLvlPositionSlider - setValue(int) - - - 301 - 546 - - - 277 - 401 - - - - - ccpmCollectiveScaleBox - valueChanged(int) - ccpmCollectiveScale - setValue(int) - - - 296 - 534 - - - 306 - 480 - - - - - ccpmCollectiveScale - valueChanged(int) - ccpmCollectiveScaleBox - setValue(int) - - - 308 - 328 - - - 292 - 534 - - - - - ccpmCyclicScale - valueChanged(int) - ccpmCyclicScaleBox - setValue(int) - - - 358 - 306 - - - 355 - 538 - - - - - ccpmCyclicScaleBox - valueChanged(int) - ccpmCyclicScale - setValue(int) - - - 341 - 538 - - - 351 - 376 - - - - - ccpmPitchScale - valueChanged(int) - ccpmPitchScaleBox - setValue(int) - - - 417 - 306 - - - 406 - 531 - - - - - ccpmPitchScaleBox - valueChanged(int) - ccpmPitchScale - setValue(int) - - - 394 - 531 - - - 408 - 302 - - - - - ccpmRollScaleBox - valueChanged(int) - ccpmRollScale - setValue(int) - - - 455 - 529 - - - 458 - 466 - - - - - ccpmRollScale - valueChanged(int) - ccpmRollScaleBox - setValue(int) - - - 461 - 388 - - - 474 - 533 - - - - -
diff --git a/ground/gcs/src/plugins/config/cfg_vehicletypes/configccpmwidget.cpp b/ground/gcs/src/plugins/config/cfg_vehicletypes/configccpmwidget.cpp index 272702fed..8b962fb4f 100644 --- a/ground/gcs/src/plugins/config/cfg_vehicletypes/configccpmwidget.cpp +++ b/ground/gcs/src/plugins/config/cfg_vehicletypes/configccpmwidget.cpp @@ -26,6 +26,12 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "configccpmwidget.h" + +#include "ui_airframe_ccpm.h" + +#include +#include + #include "mixersettings.h" #include "systemsettings.h" #include "actuatorcommand.h" @@ -38,6 +44,9 @@ #include #include #include +#include +#include +#include #include @@ -118,8 +127,9 @@ QStringList ConfigCcpmWidget::getChannelDescriptions() } ConfigCcpmWidget::ConfigCcpmWidget(QWidget *parent) : - VehicleConfig(parent), m_aircraft(new Ui_CcpmConfigWidget()) + VehicleConfig(parent) { + m_aircraft = new Ui_CcpmConfigWidget(); m_aircraft->setupUi(this); SwashLvlConfigurationInProgress = 0; @@ -1064,23 +1074,6 @@ void ConfigCcpmWidget::setMixer() updatingToHardware = false; } -/** - Send ccpm type to the board and request saving to SD card - */ -void ConfigCcpmWidget::saveccpmUpdate() -{ - if (SwashLvlConfigurationInProgress) { - return; - } - ShowDisclaimer(0); - // Send update so that the latest value is saved - // sendccpmUpdate(); - setMixer(); - UAVDataObject *obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - Q_ASSERT(obj); - saveObjectToSD(obj); -} - void ConfigCcpmWidget::resizeEvent(QResizeEvent *event) { Q_UNUSED(event); @@ -1410,6 +1403,16 @@ void ConfigCcpmWidget::SwashLvlFinishButtonPressed() ccpmSwashplateUpdate(); } +void ConfigCcpmWidget::saveObjectToSD(UAVObject *obj) +{ + // saveObjectToSD is now handled by the UAVUtils plugin in one + // central place (and one central queue) + ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); + UAVObjectUtilManager *utilMngr = pm->getObject(); + + utilMngr->saveObjectToSD(obj); +} + int ConfigCcpmWidget::ShowDisclaimer(int messageID) { QMessageBox msgBox; diff --git a/ground/gcs/src/plugins/config/cfg_vehicletypes/configccpmwidget.h b/ground/gcs/src/plugins/config/cfg_vehicletypes/configccpmwidget.h index 09a412030..73dec0617 100644 --- a/ground/gcs/src/plugins/config/cfg_vehicletypes/configccpmwidget.h +++ b/ground/gcs/src/plugins/config/cfg_vehicletypes/configccpmwidget.h @@ -29,22 +29,22 @@ #define CONFIGccpmWIDGET_H #include "cfg_vehicletypes/vehicleconfig.h" -#include "ui_airframe_ccpm.h" + #include "../uavobjectwidgetutils/configtaskwidget.h" -#include "extensionsystem/pluginmanager.h" -#include "uavobjectmanager.h" + #include "uavobject.h" -#include -#include -#include -#include -#include +class Ui_CcpmConfigWidget; + +class QWidget; +class QSpinBox; +class QGraphicsSvgItem; +class QGraphicsEllipseItem; +class QGraphicsLineItem; +class QGraphicsTextItem; #define CCPM_MAX_SWASH_SERVOS 4 -class Ui_Widget; - typedef struct { int ServoChannels[CCPM_MAX_SWASH_SERVOS]; int Used[CCPM_MAX_SWASH_SERVOS]; @@ -68,7 +68,6 @@ public: public slots: void getMixer(); void setMixer(); - void saveccpmUpdate(); protected: void showEvent(QShowEvent *event); @@ -111,6 +110,8 @@ private: QString updateConfigObjects(); + void saveObjectToSD(UAVObject *obj); + private slots: virtual void setupUI(QString airframeType); virtual bool throwConfigError(int typeInt); diff --git a/ground/gcs/src/plugins/config/cfg_vehicletypes/configcustomwidget.cpp b/ground/gcs/src/plugins/config/cfg_vehicletypes/configcustomwidget.cpp index 714f66038..1d29742e6 100644 --- a/ground/gcs/src/plugins/config/cfg_vehicletypes/configcustomwidget.cpp +++ b/ground/gcs/src/plugins/config/cfg_vehicletypes/configcustomwidget.cpp @@ -26,6 +26,9 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "configcustomwidget.h" + +#include "ui_airframe_custom.h" + #include "mixersettings.h" #include @@ -146,9 +149,11 @@ QStringList ConfigCustomWidget::getChannelDescriptions() } ConfigCustomWidget::ConfigCustomWidget(QWidget *parent) : - VehicleConfig(parent), m_aircraft(new Ui_CustomConfigWidget()) + VehicleConfig(parent) { + m_aircraft = new Ui_CustomConfigWidget(); m_aircraft->setupUi(this); + m_aircraft->customMixerTable->setEditTriggers(QAbstractItemView::NoEditTriggers); // Put combo boxes in line one of the custom mixer table: @@ -187,6 +192,7 @@ void ConfigCustomWidget::registerWidgets(ConfigTaskWidget &parent) parent.addWidget(m_aircraft->customThrottle1Curve); parent.addWidget(m_aircraft->customThrottle2Curve->getCurveWidget()); parent.addWidget(m_aircraft->customThrottle2Curve); + // TODO why is curve2SourceCombo registered twice ? parent.addWidgetBinding("MixerSettings", "Curve2Source", m_aircraft->curve2SourceCombo); parent.addWidget(m_aircraft->curve2SourceCombo); } diff --git a/ground/gcs/src/plugins/config/cfg_vehicletypes/configcustomwidget.h b/ground/gcs/src/plugins/config/cfg_vehicletypes/configcustomwidget.h index 88392c4e0..4b55835bd 100644 --- a/ground/gcs/src/plugins/config/cfg_vehicletypes/configcustomwidget.h +++ b/ground/gcs/src/plugins/config/cfg_vehicletypes/configcustomwidget.h @@ -28,7 +28,7 @@ #define CONFIGCUSTOMWIDGET_H #include "cfg_vehicletypes/vehicleconfig.h" -#include "ui_airframe_custom.h" + #include "../uavobjectwidgetutils/configtaskwidget.h" #include "extensionsystem/pluginmanager.h" #include "uavobjectmanager.h" @@ -38,7 +38,7 @@ #include #include -class Ui_Widget; +class Ui_CustomConfigWidget; class ConfigCustomWidget : public VehicleConfig { Q_OBJECT diff --git a/ground/gcs/src/plugins/config/cfg_vehicletypes/configfixedwingwidget.cpp b/ground/gcs/src/plugins/config/cfg_vehicletypes/configfixedwingwidget.cpp index 65f5084f7..2f2decadb 100644 --- a/ground/gcs/src/plugins/config/cfg_vehicletypes/configfixedwingwidget.cpp +++ b/ground/gcs/src/plugins/config/cfg_vehicletypes/configfixedwingwidget.cpp @@ -26,6 +26,9 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "configfixedwingwidget.h" + +#include "ui_airframe_fixedwing.h" + #include "mixersettings.h" #include "systemsettings.h" #include "actuatorsettings.h" @@ -51,7 +54,8 @@ QStringList ConfigFixedWingWidget::getChannelDescriptions() } // get the gui config data - GUIConfigDataUnion configData = getConfigData(); + GUIConfigDataUnion configData = getConfigData(); + fixedGUISettingsStruct fixedwing = configData.fixedwing; if (configData.fixedwing.FixedWingPitch1 > 0) { channelDesc[configData.fixedwing.FixedWingPitch1 - 1] = QString("FixedWingPitch1"); @@ -74,16 +78,51 @@ QStringList ConfigFixedWingWidget::getChannelDescriptions() if (configData.fixedwing.FixedWingThrottle > 0) { channelDesc[configData.fixedwing.FixedWingThrottle - 1] = QString("FixedWingThrottle"); } + + if (fixedwing.Accessory0 > 0 && fixedwing.Accessory0 <= ConfigFixedWingWidget::CHANNEL_NUMELEM) { + channelDesc[fixedwing.Accessory0 - 1] = QString("Accessory0-1"); + } + if (fixedwing.Accessory1 > 0 && fixedwing.Accessory1 <= ConfigFixedWingWidget::CHANNEL_NUMELEM) { + channelDesc[fixedwing.Accessory1 - 1] = QString("Accessory1-1"); + } + if (fixedwing.Accessory2 > 0 && fixedwing.Accessory2 <= ConfigFixedWingWidget::CHANNEL_NUMELEM) { + channelDesc[fixedwing.Accessory2 - 1] = QString("Accessory2-1"); + } + if (fixedwing.Accessory3 > 0 && fixedwing.Accessory3 <= ConfigFixedWingWidget::CHANNEL_NUMELEM) { + channelDesc[fixedwing.Accessory3 - 1] = QString("Accessory3-1"); + } + + if (fixedwing.Accessory0_2 > 0 && fixedwing.Accessory0_2 <= ConfigFixedWingWidget::CHANNEL_NUMELEM) { + channelDesc[fixedwing.Accessory0_2 - 1] = QString("Accessory0-2"); + } + if (fixedwing.Accessory1_2 > 0 && fixedwing.Accessory1_2 <= ConfigFixedWingWidget::CHANNEL_NUMELEM) { + channelDesc[fixedwing.Accessory1_2 - 1] = QString("Accessory1-2"); + } + if (fixedwing.Accessory2_2 > 0 && fixedwing.Accessory2_2 <= ConfigFixedWingWidget::CHANNEL_NUMELEM) { + channelDesc[fixedwing.Accessory2_2 - 1] = QString("Accessory2-2"); + } + if (fixedwing.Accessory3_2 > 0 && fixedwing.Accessory3_2 <= ConfigFixedWingWidget::CHANNEL_NUMELEM) { + channelDesc[fixedwing.Accessory3_2 - 1] = QString("Accessory3-2"); + } + return channelDesc; } ConfigFixedWingWidget::ConfigFixedWingWidget(QWidget *parent) : - VehicleConfig(parent), m_aircraft(new Ui_FixedWingConfigWidget()) + VehicleConfig(parent) { + m_aircraft = new Ui_FixedWingConfigWidget(); m_aircraft->setupUi(this); populateChannelComboBoxes(); + QStringList mixerCurveList; + mixerCurveList << "Curve1" << "Curve2"; + m_aircraft->rcOutputCurveBoxFw1->addItems(mixerCurveList); + m_aircraft->rcOutputCurveBoxFw2->addItems(mixerCurveList); + m_aircraft->rcOutputCurveBoxFw3->addItems(mixerCurveList); + m_aircraft->rcOutputCurveBoxFw4->addItems(mixerCurveList); + QStringList fixedWingTypes; fixedWingTypes << "Aileron" << "Elevon" << "Vtail"; m_aircraft->fixedWingType->addItems(fixedWingTypes); @@ -238,6 +277,18 @@ void ConfigFixedWingWidget::registerWidgets(ConfigTaskWidget &parent) parent.addWidget(m_aircraft->elevonSlider1); parent.addWidget(m_aircraft->elevonSlider2); parent.addWidget(m_aircraft->elevonSlider3); + parent.addWidget(m_aircraft->rcOutputChannelBoxFw1); + parent.addWidget(m_aircraft->rcOutputChannelBoxFw2); + parent.addWidget(m_aircraft->rcOutputChannelBoxFw3); + parent.addWidget(m_aircraft->rcOutputChannelBoxFw4); + parent.addWidget(m_aircraft->rcOutputChannelBoxFw1_2); + parent.addWidget(m_aircraft->rcOutputChannelBoxFw2_2); + parent.addWidget(m_aircraft->rcOutputChannelBoxFw3_2); + parent.addWidget(m_aircraft->rcOutputChannelBoxFw4_2); + parent.addWidget(m_aircraft->rcOutputCurveBoxFw1); + parent.addWidget(m_aircraft->rcOutputCurveBoxFw2); + parent.addWidget(m_aircraft->rcOutputCurveBoxFw3); + parent.addWidget(m_aircraft->rcOutputCurveBoxFw4); } void ConfigFixedWingWidget::resetActuators(GUIConfigDataUnion *configData) @@ -251,6 +302,44 @@ void ConfigFixedWingWidget::resetActuators(GUIConfigDataUnion *configData) configData->fixedwing.FixedWingThrottle = 0; } +void ConfigFixedWingWidget::resetRcOutputs(GUIConfigDataUnion *configData) +{ + configData->fixedwing.Accessory0 = 0; + configData->fixedwing.Accessory1 = 0; + configData->fixedwing.Accessory2 = 0; + configData->fixedwing.Accessory3 = 0; + configData->fixedwing.Accessory0_2 = 0; + configData->fixedwing.Accessory1_2 = 0; + configData->fixedwing.Accessory2_2 = 0; + configData->fixedwing.Accessory3_2 = 0; +} + + +void ConfigFixedWingWidget::updateRcCurvesUsed() +{ + UAVDataObject *mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); + + Q_ASSERT(mixer); + + setComboCurrentIndex(m_aircraft->rcOutputCurveBoxFw1, VehicleConfig::MIXER_THROTTLECURVE1); + setComboCurrentIndex(m_aircraft->rcOutputCurveBoxFw2, VehicleConfig::MIXER_THROTTLECURVE1); + setComboCurrentIndex(m_aircraft->rcOutputCurveBoxFw3, VehicleConfig::MIXER_THROTTLECURVE1); + setComboCurrentIndex(m_aircraft->rcOutputCurveBoxFw4, VehicleConfig::MIXER_THROTTLECURVE1); + + for (int channel = 0; channel < (int)ConfigFixedWingWidget::CHANNEL_NUMELEM; channel++) { + QString mixerType = getMixerType(mixer, channel); + if (mixerType == "Accessory0" && getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE2)) { + setComboCurrentIndex(m_aircraft->rcOutputCurveBoxFw1, VehicleConfig::MIXER_THROTTLECURVE2); + } else if (mixerType == "Accessory1" && getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE2)) { + setComboCurrentIndex(m_aircraft->rcOutputCurveBoxFw2, VehicleConfig::MIXER_THROTTLECURVE2); + } else if (mixerType == "Accessory2" && getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE2)) { + setComboCurrentIndex(m_aircraft->rcOutputCurveBoxFw3, VehicleConfig::MIXER_THROTTLECURVE2); + } else if (mixerType == "Accessory3" && getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE2)) { + setComboCurrentIndex(m_aircraft->rcOutputCurveBoxFw4, VehicleConfig::MIXER_THROTTLECURVE2); + } + } +} + /** Virtual function to refresh the UI widget values */ @@ -287,6 +376,18 @@ void ConfigFixedWingWidget::refreshWidgetsValues(QString frameType) setComboCurrentIndex(m_aircraft->fwRudder1ChannelBox, fixed.FixedWingYaw1); setComboCurrentIndex(m_aircraft->fwRudder2ChannelBox, fixed.FixedWingYaw2); + setComboCurrentIndex(m_aircraft->rcOutputChannelBoxFw1, fixed.Accessory0); + setComboCurrentIndex(m_aircraft->rcOutputChannelBoxFw2, fixed.Accessory1); + setComboCurrentIndex(m_aircraft->rcOutputChannelBoxFw3, fixed.Accessory2); + setComboCurrentIndex(m_aircraft->rcOutputChannelBoxFw4, fixed.Accessory3); + + setComboCurrentIndex(m_aircraft->rcOutputChannelBoxFw1_2, fixed.Accessory0_2); + setComboCurrentIndex(m_aircraft->rcOutputChannelBoxFw2_2, fixed.Accessory1_2); + setComboCurrentIndex(m_aircraft->rcOutputChannelBoxFw3_2, fixed.Accessory2_2); + setComboCurrentIndex(m_aircraft->rcOutputChannelBoxFw4_2, fixed.Accessory3_2); + + updateRcCurvesUsed(); + // Get mixing values for GUI sliders (values stored onboard) m_aircraft->elevonSlider3->setValue(getMixerValue(mixer, "RollDifferential")); if (frameType == "FixedWingElevon" || frameType == "Elevon") { @@ -310,6 +411,13 @@ QString ConfigFixedWingWidget::updateConfigObjectsFromWidgets() Q_ASSERT(mixer); + // Reset all Mixers type + resetAllMixersType(mixer); + + QList rcOutputList; + rcOutputList << "Accessory0" << "Accessory1" << "Accessory2" << "Accessory3"; + setupRcOutputs(rcOutputList); + // Set the throttle curve setThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE1, m_aircraft->fixedWingThrottle->getCurve()); @@ -580,6 +688,118 @@ bool ConfigFixedWingWidget::setupFrameVtail(QString airframeType) return true; } +/** + Helper function: setup rc outputs. Takes a list of channel names in input. + */ +void ConfigFixedWingWidget::setupRcOutputs(QList rcOutputList) +{ + QList rcList; + rcList << m_aircraft->rcOutputChannelBoxFw1 << m_aircraft->rcOutputChannelBoxFw2 + << m_aircraft->rcOutputChannelBoxFw3 << m_aircraft->rcOutputChannelBoxFw4; + + QList rcList2; + rcList2 << m_aircraft->rcOutputChannelBoxFw1_2 << m_aircraft->rcOutputChannelBoxFw2_2 + << m_aircraft->rcOutputChannelBoxFw3_2 << m_aircraft->rcOutputChannelBoxFw4_2; + + GUIConfigDataUnion configData = getConfigData(); + resetRcOutputs(&configData); + + UAVDataObject *mixer = dynamic_cast(getObjectManager()->getObject("MixerSettings")); + Q_ASSERT(mixer); + + int curveAccessory0 = m_aircraft->rcOutputCurveBoxFw1->currentIndex(); + int curveAccessory1 = m_aircraft->rcOutputCurveBoxFw2->currentIndex(); + int curveAccessory2 = m_aircraft->rcOutputCurveBoxFw3->currentIndex(); + int curveAccessory3 = m_aircraft->rcOutputCurveBoxFw4->currentIndex(); + + foreach(QString rc_output, rcOutputList) { + int index = rcList.takeFirst()->currentIndex(); + int index2 = rcList2.takeFirst()->currentIndex(); + + if (rc_output == "Accessory0") { + // First output for Accessory0 + configData.fixedwing.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); + } + } + // Second output for Accessory0 + configData.fixedwing.Accessory0_2 = index2; + if (index2) { + setMixerType(mixer, index2 - 1, VehicleConfig::MIXERTYPE_ACCESSORY0); + if (curveAccessory0) { + setMixerVectorValue(mixer, index2 - 1, VehicleConfig::MIXERVECTOR_THROTTLECURVE2, 127); + } else { + setMixerVectorValue(mixer, index2 - 1, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127); + } + } + } else if (rc_output == "Accessory1") { + configData.fixedwing.Accessory1 = index; + configData.fixedwing.Accessory1_2 = index2; + 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); + } + } + if (index2) { + setMixerType(mixer, index2 - 1, VehicleConfig::MIXERTYPE_ACCESSORY1); + if (curveAccessory1) { + setMixerVectorValue(mixer, index2 - 1, VehicleConfig::MIXERVECTOR_THROTTLECURVE2, 127); + } else { + setMixerVectorValue(mixer, index2 - 1, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127); + } + } + } else if (rc_output == "Accessory2") { + configData.fixedwing.Accessory2 = index; + configData.fixedwing.Accessory2_2 = index2; + 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); + } + } + if (index2) { + setMixerType(mixer, index2 - 1, VehicleConfig::MIXERTYPE_ACCESSORY2); + if (curveAccessory2) { + setMixerVectorValue(mixer, index2 - 1, VehicleConfig::MIXERVECTOR_THROTTLECURVE2, 127); + } else { + setMixerVectorValue(mixer, index2 - 1, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127); + } + } + } else if (rc_output == "Accessory3") { + configData.fixedwing.Accessory3 = index; + configData.fixedwing.Accessory3_2 = index2; + if (index) { + setMixerType(mixer, index - 1, VehicleConfig::MIXERTYPE_ACCESSORY3); + if (curveAccessory3) { + setMixerVectorValue(mixer, index - 1, VehicleConfig::MIXERVECTOR_THROTTLECURVE2, 127); + } else { + setMixerVectorValue(mixer, index - 1, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127); + } + } + if (index2) { + setMixerType(mixer, index2 - 1, VehicleConfig::MIXERTYPE_ACCESSORY3); + if (curveAccessory3) { + setMixerVectorValue(mixer, index2 - 1, VehicleConfig::MIXERVECTOR_THROTTLECURVE2, 127); + } else { + setMixerVectorValue(mixer, index2 - 1, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127); + } + } + } + } + setConfigData(configData); +} + + void ConfigFixedWingWidget::enableControls(bool enable) { ConfigTaskWidget::enableControls(enable); @@ -648,6 +868,44 @@ bool ConfigFixedWingWidget::throwConfigError(QString airframeType) channelNames += (combobox->currentText() == "None") ? "" : combobox->currentText(); } } + + // Iterate through all instances of rcOutputChannelBoxFw + for (int i = 0; i < 5; i++) { + // Find widgets with his name "rcOutputChannelBoxFw.x", where x is an integer + QComboBox *combobox = this->findChild("rcOutputChannelBoxFw" + 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)ConfigFixedWingWidget::CHANNEL_NUMELEM; index++) { + combobox->setItemData(index, 0, Qt::DecorationRole); // Reset all color palettes + combobox->setToolTip(tr("Select first output channel for Accessory%1 RcInput").arg(i)); + } + } + channelNames += (combobox->currentText() == "None") ? "" : combobox->currentText(); + } + // Find duplicates in second output comboboxes + QComboBox *combobox2 = this->findChild("rcOutputChannelBoxFw" + QString::number(i + 1) + "_2"); + if (combobox2) { + if (channelNames.contains(combobox2->currentText(), Qt::CaseInsensitive)) { + int size = combobox2->style()->pixelMetric(QStyle::PM_SmallIconSize); + QPixmap pixmap(size, size); + pixmap.fill(QColor("orange")); + combobox2->setItemData(combobox2->currentIndex(), pixmap, Qt::DecorationRole); // Set color palettes + combobox2->setToolTip(tr("Channel already used")); + } else { + for (int index = 0; index < (int)ConfigFixedWingWidget::CHANNEL_NUMELEM; index++) { + combobox2->setItemData(index, 0, Qt::DecorationRole); // Reset all color palettes + combobox2->setToolTip(tr("Select second output channel for Accessory%1 RcInput").arg(i)); + } + } + channelNames += (combobox2->currentText() == "None") ? "" : combobox2->currentText(); + } + } return error; } diff --git a/ground/gcs/src/plugins/config/cfg_vehicletypes/configfixedwingwidget.h b/ground/gcs/src/plugins/config/cfg_vehicletypes/configfixedwingwidget.h index 5e25d99d3..bd7513cce 100644 --- a/ground/gcs/src/plugins/config/cfg_vehicletypes/configfixedwingwidget.h +++ b/ground/gcs/src/plugins/config/cfg_vehicletypes/configfixedwingwidget.h @@ -28,17 +28,18 @@ #define CONFIGFIXEDWINGWIDGET_H #include "cfg_vehicletypes/vehicleconfig.h" -#include "ui_airframe_fixedwing.h" + #include "../uavobjectwidgetutils/configtaskwidget.h" #include "extensionsystem/pluginmanager.h" #include "uavobjectmanager.h" #include "uavobject.h" -#include #include -#include -class Ui_Widget; +class Ui_FixedWingConfigWidget; + +class QWidget; +class QGraphicsSvgItem; class ConfigFixedWingWidget : public VehicleConfig { Q_OBJECT @@ -58,10 +59,13 @@ private: virtual void registerWidgets(ConfigTaskWidget &parent); virtual void resetActuators(GUIConfigDataUnion *configData); + virtual void resetRcOutputs(GUIConfigDataUnion *configData); bool setupFrameFixedWing(QString airframeType); bool setupFrameElevon(QString airframeType); bool setupFrameVtail(QString airframeType); + void setupRcOutputs(QList rcOutputList); + void updateRcCurvesUsed(); protected: void enableControls(bool enable); diff --git a/ground/gcs/src/plugins/config/cfg_vehicletypes/configgroundvehiclewidget.cpp b/ground/gcs/src/plugins/config/cfg_vehicletypes/configgroundvehiclewidget.cpp index ec94ba07b..e2e0099fb 100644 --- a/ground/gcs/src/plugins/config/cfg_vehicletypes/configgroundvehiclewidget.cpp +++ b/ground/gcs/src/plugins/config/cfg_vehicletypes/configgroundvehiclewidget.cpp @@ -26,6 +26,9 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "configgroundvehiclewidget.h" + +#include "ui_airframe_ground.h" + #include "mixersettings.h" #include "systemsettings.h" #include "actuatorsettings.h" @@ -70,8 +73,9 @@ QStringList ConfigGroundVehicleWidget::getChannelDescriptions() } ConfigGroundVehicleWidget::ConfigGroundVehicleWidget(QWidget *parent) : - VehicleConfig(parent), m_aircraft(new Ui_GroundConfigWidget()) + VehicleConfig(parent) { + m_aircraft = new Ui_GroundConfigWidget(); m_aircraft->setupUi(this); populateChannelComboBoxes(); diff --git a/ground/gcs/src/plugins/config/cfg_vehicletypes/configgroundvehiclewidget.h b/ground/gcs/src/plugins/config/cfg_vehicletypes/configgroundvehiclewidget.h index ff2b6c796..b9216665b 100644 --- a/ground/gcs/src/plugins/config/cfg_vehicletypes/configgroundvehiclewidget.h +++ b/ground/gcs/src/plugins/config/cfg_vehicletypes/configgroundvehiclewidget.h @@ -28,17 +28,16 @@ #define CONFIGGROUNDVEHICLEWIDGET_H #include "cfg_vehicletypes/vehicleconfig.h" -#include "ui_airframe_ground.h" + #include "../uavobjectwidgetutils/configtaskwidget.h" #include "extensionsystem/pluginmanager.h" #include "uavobjectmanager.h" #include "uavobject.h" -#include -#include -#include +class Ui_GroundConfigWidget; -class Ui_Widget; +class QWidget; +class QGraphicsSvgItem; class ConfigGroundVehicleWidget : public VehicleConfig { Q_OBJECT diff --git a/ground/gcs/src/plugins/config/cfg_vehicletypes/configmultirotorwidget.cpp b/ground/gcs/src/plugins/config/cfg_vehicletypes/configmultirotorwidget.cpp index 78a2b6b9d..2f0af653d 100644 --- a/ground/gcs/src/plugins/config/cfg_vehicletypes/configmultirotorwidget.cpp +++ b/ground/gcs/src/plugins/config/cfg_vehicletypes/configmultirotorwidget.cpp @@ -26,6 +26,9 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "configmultirotorwidget.h" + +#include "ui_airframe_multirotor.h" + #include "mixersettings.h" #include "systemsettings.h" #include "actuatorsettings.h" @@ -129,8 +132,9 @@ QStringList ConfigMultiRotorWidget::getChannelDescriptions() } ConfigMultiRotorWidget::ConfigMultiRotorWidget(QWidget *parent) : - VehicleConfig(parent), m_aircraft(new Ui_MultiRotorConfigWidget()), invertMotors(false) + VehicleConfig(parent), invertMotors(false) { + m_aircraft = new Ui_MultiRotorConfigWidget(); m_aircraft->setupUi(this); populateChannelComboBoxes(); @@ -173,8 +177,6 @@ ConfigMultiRotorWidget::ConfigMultiRotorWidget(QWidget *parent) : m_aircraft->multiThrottleCurve->setXAxisLabel(tr("Input")); m_aircraft->multiThrottleCurve->setYAxisLabel(tr("Output")); - - updateEnableControls(); } ConfigMultiRotorWidget::~ConfigMultiRotorWidget() @@ -187,15 +189,21 @@ void ConfigMultiRotorWidget::setupUI(QString frameType) Q_ASSERT(m_aircraft); Q_ASSERT(quad); + QStringList motorLabels; + if (frameType == "Tri" || frameType == "Tricopter Y") { setComboCurrentIndex(m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Tricopter Y")); + motorLabels << "NW" << "NE" << "S"; + m_aircraft->mrRollMixLevel->setValue(100); m_aircraft->mrPitchMixLevel->setValue(100); setYawMixLevel(100); } else if (frameType == "QuadX" || frameType == "Quad X") { setComboCurrentIndex(m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Quad X")); + motorLabels << "NW" << "NE" << "SE" << "SW"; + // init mixer levels m_aircraft->mrRollMixLevel->setValue(50); m_aircraft->mrPitchMixLevel->setValue(50); @@ -203,12 +211,16 @@ void ConfigMultiRotorWidget::setupUI(QString frameType) } else if (frameType == "QuadP" || frameType == "Quad +") { setComboCurrentIndex(m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Quad +")); + motorLabels << "N" << "E" << "S" << "W"; + m_aircraft->mrRollMixLevel->setValue(100); m_aircraft->mrPitchMixLevel->setValue(100); setYawMixLevel(50); } else if (frameType == "Hexa" || frameType == "Hexacopter") { setComboCurrentIndex(m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Hexacopter")); + motorLabels << "N" << "NE" << "SE" << "S" << "SW" << "NW"; + m_aircraft->mrRollMixLevel->setValue(100); // Old Roll 50 - Pitch 33 - Yaw 33 m_aircraft->mrPitchMixLevel->setValue(100); // Do not alter mixer matrix setYawMixLevel(100); @@ -216,6 +228,8 @@ void ConfigMultiRotorWidget::setupUI(QString frameType) setComboCurrentIndex(m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Hexacopter X")); + motorLabels << "NE" << "E" << "SE" << "SW" << "W" << "NW"; + m_aircraft->mrRollMixLevel->setValue(100); // Old: Roll 33 - Pitch 50 - Yaw 33 m_aircraft->mrPitchMixLevel->setValue(100); // Do not alter mixer matrix setYawMixLevel(100); @@ -223,6 +237,8 @@ void ConfigMultiRotorWidget::setupUI(QString frameType) setComboCurrentIndex(m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Hexacopter H")); + motorLabels << "NE" << "E" << "SE" << "SW" << "W" << "NW"; + m_aircraft->mrRollMixLevel->setValue(100); // Do not alter mixer matrix m_aircraft->mrPitchMixLevel->setValue(100); // All mixers RPY levels = 100% setYawMixLevel(100); @@ -230,18 +246,24 @@ void ConfigMultiRotorWidget::setupUI(QString frameType) setComboCurrentIndex(m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Hexacopter Y6")); - m_aircraft->mrRollMixLevel->setValue(100); - m_aircraft->mrPitchMixLevel->setValue(50); - setYawMixLevel(66); + motorLabels << "NW Top" << "NW Bottom" << "NE Top" << "NE Bottom" << "S Top" << "S Bottom"; + + m_aircraft->mrRollMixLevel->setValue(86); + m_aircraft->mrPitchMixLevel->setValue(100); + setYawMixLevel(100); } else if (frameType == "Octo" || frameType == "Octocopter") { setComboCurrentIndex(m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Octocopter")); + motorLabels << "N" << "NE" << "E" << "SE" << "S" << "SW" << "W" << "NW"; + m_aircraft->mrRollMixLevel->setValue(100); // Do not alter mixer matrix m_aircraft->mrPitchMixLevel->setValue(100); // All mixers RPY levels = 100% setYawMixLevel(100); } else if (frameType == "OctoX" || frameType == "Octocopter X") { setComboCurrentIndex(m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Octocopter X")); + motorLabels << "NNE" << "ENE" << "ESE" << "SSE" << "SSW" << "WSW" << "WNW" << "NNW"; + m_aircraft->mrRollMixLevel->setValue(100); // Do not alter mixer matrix m_aircraft->mrPitchMixLevel->setValue(100); // All mixers RPY levels = 100% setYawMixLevel(100); @@ -249,18 +271,25 @@ void ConfigMultiRotorWidget::setupUI(QString frameType) setComboCurrentIndex(m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Octocopter V")); + motorLabels << "N" << "NE" << "E" << "SE" << "S" << "SW" << "W" << "NW"; + m_aircraft->mrRollMixLevel->setValue(25); m_aircraft->mrPitchMixLevel->setValue(25); setYawMixLevel(25); } else if (frameType == "OctoCoaxP" || frameType == "Octo Coax +") { setComboCurrentIndex(m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Octo Coax +")); + motorLabels << "N Top" << "N Bottom" << "E Top" << "E Bottom" << "S Top" << "S Bottom" << "W Top" << "W Bottom"; + m_aircraft->mrRollMixLevel->setValue(100); m_aircraft->mrPitchMixLevel->setValue(100); setYawMixLevel(50); } else if (frameType == "OctoCoaxX" || frameType == "Octo Coax X") { setComboCurrentIndex(m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Octo Coax X")); + motorLabels << "NW Top" << "NW Bottom" << "NE Top" << "NE Bottom" << "SE Top" << "SE Bottom" << "SW Top" << "SW Bottom"; + + m_aircraft->mrRollMixLevel->setValue(50); m_aircraft->mrPitchMixLevel->setValue(50); setYawMixLevel(50); @@ -269,6 +298,9 @@ void ConfigMultiRotorWidget::setupUI(QString frameType) // Enable/Disable controls setupEnabledControls(frameType); + // Update motor position labels + updateMotorsPositionLabels(motorLabels); + // Draw the appropriate airframe updateAirframe(frameType); } @@ -373,18 +405,6 @@ void ConfigMultiRotorWidget::resetRcOutputs(GUIConfigDataUnion *configData) configData->multi.Accessory3 = 0; } -void ConfigMultiRotorWidget::resetMixers() -{ - UAVDataObject *mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - - Q_ASSERT(mixer); - - for (int channel = 0; channel < (int)ConfigMultiRotorWidget::CHANNEL_NUMELEM; channel++) { - resetMixerVector(mixer, channel); - setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_DISABLED); - } -} - void ConfigMultiRotorWidget::updateRcCurvesUsed() { UAVDataObject *mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); @@ -536,6 +556,32 @@ void ConfigMultiRotorWidget::refreshWidgetsValues(QString frameType) updateAirframe(frameType); } +/** + Helper function to update the UI MotorPositionLabels text + */ +void ConfigMultiRotorWidget::updateMotorsPositionLabels(QStringList motorLabels) +{ + QList mpList; + mpList << m_aircraft->motorPositionLabel1 << m_aircraft->motorPositionLabel2 + << m_aircraft->motorPositionLabel3 << m_aircraft->motorPositionLabel4 + << m_aircraft->motorPositionLabel5 << m_aircraft->motorPositionLabel6 + << m_aircraft->motorPositionLabel7 << m_aircraft->motorPositionLabel8; + + int motorCount = motorLabels.count(); + int uiLabelsCount = mpList.count(); + + if (motorCount < uiLabelsCount) { + // Fill labels for unused motors + for (int index = motorCount; index < uiLabelsCount; index++) { + motorLabels.insert(index, "Not used"); + } + } + + foreach(QString posLabel, motorLabels) { + mpList.takeFirst()->setText(posLabel); + } +} + /** Helper function to update the UI widget objects */ @@ -545,8 +591,8 @@ QString ConfigMultiRotorWidget::updateConfigObjectsFromWidgets() Q_ASSERT(mixer); - // Reset all Mixers - resetMixers(); + // Reset all Mixers types + resetAllMixersType(mixer); QList rcOutputList; rcOutputList << "Accessory0" << "Accessory1" << "Accessory2" << "Accessory3"; @@ -827,9 +873,10 @@ void ConfigMultiRotorWidget::reverseMultirotorMotor() void ConfigMultiRotorWidget::updateAirframe(QString frameType) { - qDebug() << "ConfigMultiRotorWidget::updateAirframe - frame type" << frameType; + // qDebug() << "ConfigMultiRotorWidget::updateAirframe - frame type" << frameType; QString elementId; + if (frameType == "Tri" || frameType == "Tricopter Y") { elementId = "tri"; } else if (frameType == "QuadX" || frameType == "Quad X") { diff --git a/ground/gcs/src/plugins/config/cfg_vehicletypes/configmultirotorwidget.h b/ground/gcs/src/plugins/config/cfg_vehicletypes/configmultirotorwidget.h index 488fd5cce..f38495913 100644 --- a/ground/gcs/src/plugins/config/cfg_vehicletypes/configmultirotorwidget.h +++ b/ground/gcs/src/plugins/config/cfg_vehicletypes/configmultirotorwidget.h @@ -28,17 +28,18 @@ #define CONFIGMULTIROTORWIDGET_H #include "cfg_vehicletypes/vehicleconfig.h" -#include "ui_airframe_multirotor.h" + #include "../uavobjectwidgetutils/configtaskwidget.h" #include "extensionsystem/pluginmanager.h" #include "uavobjectmanager.h" #include "uavobject.h" -#include -#include -#include +#include -class Ui_Widget; +class Ui_MultiRotorConfigWidget; + +class QWidget; +class QGraphicsSvgItem; class ConfigMultiRotorWidget : public VehicleConfig { Q_OBJECT @@ -73,12 +74,12 @@ private: bool setupMultiRotorMixer(double mixerFactors[8][3]); void setupMotors(QList motorList); void setupRcOutputs(QList rcOutputList); - void resetMixers(); void setupQuadMotor(int channel, double roll, double pitch, double yaw); void setYawMixLevel(int); void updateRcCurvesUsed(); void updateAirframe(QString multiRotorType); + void updateMotorsPositionLabels(QStringList motorLabels); void setupEnabledControls(QString multiRotorType); private slots: diff --git a/ground/gcs/src/plugins/config/cfg_vehicletypes/vehicleconfig.cpp b/ground/gcs/src/plugins/config/cfg_vehicletypes/vehicleconfig.cpp index 621f539eb..70848b651 100644 --- a/ground/gcs/src/plugins/config/cfg_vehicletypes/vehicleconfig.cpp +++ b/ground/gcs/src/plugins/config/cfg_vehicletypes/vehicleconfig.cpp @@ -25,13 +25,18 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "cfg_vehicletypes/vehicleconfig.h" + #include "extensionsystem/pluginmanager.h" #include "uavobjectmanager.h" #include "uavobject.h" -#include "systemsettings.h" -#include +#include "systemsettings.h" + +#include #include +#include +#include +#include VehicleConfig::VehicleConfig(QWidget *parent) : ConfigTaskWidget(parent) { @@ -115,12 +120,12 @@ QString VehicleConfig::updateConfigObjectsFromWidgets() return NULL; } -void VehicleConfig::refreshWidgetsValues(UAVObject *o) +void VehicleConfig::refreshWidgetsValuesImpl(UAVObject *obj) { - Q_UNUSED(o); + Q_UNUSED(obj); } -void VehicleConfig::updateObjectsFromWidgets() +void VehicleConfig::updateObjectsFromWidgetsImpl() {} void VehicleConfig::resetActuators(GUIConfigDataUnion *configData) @@ -232,6 +237,15 @@ void VehicleConfig::resetMotorAndServoMixers(UAVDataObject *mixer) } } +// Disable all mixers types +void VehicleConfig::resetAllMixersType(UAVDataObject *mixer) +{ + for (int channel = 0; channel < (int)VehicleConfig::CHANNEL_NUMELEM; channel++) { + resetMixerVector(mixer, channel); + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_DISABLED); + } +} + double VehicleConfig::getMixerVectorValue(UAVDataObject *mixer, int channel, MixerVectorElem elementName) { Q_ASSERT(mixer); diff --git a/ground/gcs/src/plugins/config/cfg_vehicletypes/vehicleconfig.h b/ground/gcs/src/plugins/config/cfg_vehicletypes/vehicleconfig.h index f4a9765ac..225c36b3d 100644 --- a/ground/gcs/src/plugins/config/cfg_vehicletypes/vehicleconfig.h +++ b/ground/gcs/src/plugins/config/cfg_vehicletypes/vehicleconfig.h @@ -89,10 +89,17 @@ typedef struct { uint FixedWingPitch2 : 4; uint FixedWingYaw1 : 4; uint FixedWingYaw2 : 4; - uint padding : 4; // 32 bits + uint Accessory0 : 4; // 32 bits + uint Accessory1 : 4; + uint Accessory2 : 4; + uint Accessory3 : 4; + uint Accessory0_2 : 4; + uint Accessory1_2 : 4; + uint Accessory2_2 : 4; + uint Accessory3_2 : 4; + quint32 padding : 4; // 64bits quint32 padding1; - quint32 padding2; - quint32 padding3; // 128 bits + quint32 padding2; // 128 bits } __attribute__((packed)) fixedGUISettingsStruct; typedef struct { @@ -155,8 +162,13 @@ class ConfigTaskWidget; /* * This class handles vehicle specific configuration UI and associated logic. * - * This class derives from ConfigTaskWidget and overrides its the default "binding" mechanism. - * It does not use the "dirty" state management directlyand registers its relevant widgets with ConfigTaskWidget to do so. + * VehicleConfig derives from ConfigTaskWidget but is not a top level ConfigTaskWidget. + * VehicleConfig objects are nested within the ConfigVehicleConfigWidget and have particularities: + * - bindings are added to the parent (i.e. ConfigVehicleConfigWidget) + * - auto bindings are not supported + * - as a consequence things like dirty state management are bypassed and delegated to the parent class. + * + * It does not use the "dirty" state management directly and registers its relevant widgets with ConfigTaskWidget to do so. */ class VehicleConfig : public ConfigTaskWidget { Q_OBJECT @@ -228,6 +240,7 @@ protected: void setMixerVectorValue(UAVDataObject *mixer, int channel, MixerVectorElem elementName, double value); void resetMixerVector(UAVDataObject *mixer, int channel); void resetMotorAndServoMixers(UAVDataObject *mixer); + void resetAllMixersType(UAVDataObject *mixer); QString getMixerType(UAVDataObject *mixer, int channel); void setMixerType(UAVDataObject *mixer, int channel, MixerTypeElem mixerType); void setThrottleCurve(UAVDataObject *mixer, MixerThrottleCurveElem curveType, QList curve); @@ -236,9 +249,8 @@ protected: double getCurveMin(QList *curve); double getCurveMax(QList *curve); -protected slots: - virtual void refreshWidgetsValues(UAVObject *o = NULL); - virtual void updateObjectsFromWidgets(); + virtual void refreshWidgetsValuesImpl(UAVObject *obj); + virtual void updateObjectsFromWidgetsImpl(); private: static UAVObjectManager *getUAVObjectManager(); diff --git a/ground/gcs/src/plugins/config/config.pro b/ground/gcs/src/plugins/config/config.pro index 004c10d1c..e74720999 100644 --- a/ground/gcs/src/plugins/config/config.pro +++ b/ground/gcs/src/plugins/config/config.pro @@ -2,16 +2,18 @@ TEMPLATE = lib TARGET = Config DEFINES += CONFIG_LIBRARY -QT += svg opengl qml quick +QT += widgets svg opengl qml quick + +# silence eigen warnings +QMAKE_CXXFLAGS_WARN_ON += -Wno-deprecated-declarations +win32 { + QMAKE_CXXFLAGS_WARN_ON += -Wno-ignored-attributes +} include(config_dependencies.pri) INCLUDEPATH += ../../libs/eigen -OTHER_FILES += \ - Config.pluginspec \ - calibration/WizardStepIndicator.qml - HEADERS += \ configplugin.h \ configgadgetwidget.h \ @@ -25,8 +27,7 @@ HEADERS += \ configccattitudewidget.h \ configstabilizationwidget.h \ assertions.h \ - defaultattitudewidget.h \ - defaulthwsettingswidget.h \ + defaultconfigwidget.h \ channelform.h \ inputchannelform.h \ configcamerastabilizationwidget.h \ @@ -58,7 +59,9 @@ HEADERS += \ calibration/gyrobiascalibrationmodel.h \ calibration/calibrationuiutils.h \ configoplinkwidget.h \ - configrevonanohwwidget.h + configrevonanohwwidget.h \ + configsparky2hwwidget.h \ + failsafechannelform.h SOURCES += \ configplugin.cpp \ @@ -72,8 +75,7 @@ SOURCES += \ config_cc_hw_widget.cpp \ configccattitudewidget.cpp \ configstabilizationwidget.cpp \ - defaultattitudewidget.cpp \ - defaulthwsettingswidget.cpp \ + defaultconfigwidget.cpp \ channelform.cpp \ inputchannelform.cpp \ configcamerastabilizationwidget.cpp \ @@ -99,7 +101,9 @@ SOURCES += \ calibration/levelcalibrationmodel.cpp \ calibration/gyrobiascalibrationmodel.cpp \ configoplinkwidget.cpp \ - configrevonanohwwidget.cpp + configrevonanohwwidget.cpp \ + configsparky2hwwidget.cpp \ + failsafechannelform.cpp FORMS += \ airframe.ui \ @@ -114,8 +118,7 @@ FORMS += \ input_wizard.ui \ output.ui \ ccattitude.ui \ - defaultattitude.ui \ - defaulthwsettings.ui \ + defaultconfig.ui \ inputchannelform.ui \ camerastabilization.ui \ outputchannelform.ui \ @@ -124,6 +127,12 @@ FORMS += \ mixercurve.ui \ configrevohwwidget.ui \ oplink.ui \ - configrevonanohwwidget.ui + configrevonanohwwidget.ui \ + configsparky2hwwidget.ui \ + failsafechannelform.ui + +OTHER_FILES += \ + Config.pluginspec \ + calibration/WizardStepIndicator.qml RESOURCES += configgadget.qrc diff --git a/ground/gcs/src/plugins/config/config_cc_hw_widget.cpp b/ground/gcs/src/plugins/config/config_cc_hw_widget.cpp index fc59ddc27..1b6908208 100644 --- a/ground/gcs/src/plugins/config/config_cc_hw_widget.cpp +++ b/ground/gcs/src/plugins/config/config_cc_hw_widget.cpp @@ -1,14 +1,14 @@ /** ****************************************************************************** * - * @file configtelemetrywidget.h + * @file config_cc_hw_widget.cpp * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup ConfigPlugin Config Plugin * @{ - * @brief The Configuration Gadget used to update settings in the firmware + * @brief The Configuration Gadget used to update hardware settings in the firmware *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify @@ -25,35 +25,34 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + #include "config_cc_hw_widget.h" + +#include "ui_cc_hw_settings.h" + +#include +#include + #include "hwsettings.h" + #include #include #include -#include -#include -#include -#include -#include -#include -#include - +#include ConfigCCHWWidget::ConfigCCHWWidget(QWidget *parent) : ConfigTaskWidget(parent) { m_telemetry = new Ui_CC_HW_Widget(); m_telemetry->setupUi(this); + // must be done before auto binding ! + setWikiURL("CC+Hardware+Configuration"); + + addAutoBindings(); + ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); - Core::Internal::GeneralSettings *settings = pm->getObject(); - if (!settings->useExpertMode()) { - m_telemetry->saveTelemetryToRAM->setVisible(false); - } - - - UAVObjectUtilManager *utilMngr = pm->getObject(); + UAVObjectUtilManager *utilMngr = pm->getObject(); int id = utilMngr->getBoardModel(); - switch (id) { case 0x0101: m_telemetry->label_2->setPixmap(QPixmap(":/uploader/images/deviceID-0101.svg")); @@ -74,7 +73,7 @@ ConfigCCHWWidget::ConfigCCHWWidget(QWidget *parent) : ConfigTaskWidget(parent) m_telemetry->label_2->setPixmap(QPixmap(":/configgadget/images/coptercontrol.svg")); break; } - addApplySaveButtons(m_telemetry->saveTelemetryToRAM, m_telemetry->saveTelemetryToSD); + addWidgetBinding("HwSettings", "CC_FlexiPort", m_telemetry->cbFlexi); addWidgetBinding("HwSettings", "CC_MainPort", m_telemetry->cbTele); addWidgetBinding("HwSettings", "CC_RcvrPort", m_telemetry->cbRcvr); @@ -85,21 +84,13 @@ ConfigCCHWWidget::ConfigCCHWWidget(QWidget *parent) : ConfigTaskWidget(parent) // Add Gps protocol configuration HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager()); - HwSettings::DataFields hwSettingsData = hwSettings->getData(); - if (hwSettingsData.OptionalModules[HwSettings::OPTIONALMODULES_GPS] != HwSettings::OPTIONALMODULES_ENABLED) { + if (hwSettings->getOptionalModules(HwSettings::OPTIONALMODULES_GPS) != HwSettings::OPTIONALMODULES_ENABLED) { m_telemetry->gpsProtocol->setEnabled(false); m_telemetry->gpsProtocol->setToolTip(tr("Enable GPS module and reboot the board to be able to select GPS protocol")); } else { addWidgetBinding("GPSSettings", "DataProtocol", m_telemetry->gpsProtocol); } - - addWidgetBinding("HwSettings", "ComUsbBridgeSpeed", m_telemetry->comUsbBridgeSpeed); - connect(m_telemetry->cchwHelp, SIGNAL(clicked()), this, SLOT(openHelp())); - enableSaveButtons(false); - populateWidgets(); - refreshWidgetsValues(); - forceConnectedState(); } ConfigCCHWWidget::~ConfigCCHWWidget() @@ -142,17 +133,6 @@ void ConfigCCHWWidget::widgetsContentsChanged() void ConfigCCHWWidget::enableSaveButtons(bool enable) { - m_telemetry->saveTelemetryToRAM->setEnabled(enable); - m_telemetry->saveTelemetryToSD->setEnabled(enable); + m_telemetry->applyButton->setEnabled(enable); + m_telemetry->saveButton->setEnabled(enable); } - -void ConfigCCHWWidget::openHelp() -{ - QDesktopServices::openUrl(QUrl(QString(WIKI_URL_ROOT) + QString("CC+Hardware+Configuration"), - QUrl::StrictMode)); -} - -/** - * @} - * @} - */ diff --git a/ground/gcs/src/plugins/config/config_cc_hw_widget.h b/ground/gcs/src/plugins/config/config_cc_hw_widget.h index 313231382..be0da4994 100644 --- a/ground/gcs/src/plugins/config/config_cc_hw_widget.h +++ b/ground/gcs/src/plugins/config/config_cc_hw_widget.h @@ -1,13 +1,14 @@ /** ****************************************************************************** * - * @file configtelemetrytwidget.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @file config_cc_hw_widget.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup ConfigPlugin Config Plugin * @{ - * @brief Telemetry configuration panel + * @brief The Configuration Gadget used to update hardware settings in the firmware *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify @@ -27,14 +28,11 @@ #ifndef CONFIGCCHWWIDGET_H #define CONFIGCCHWWIDGET_H -#include "ui_cc_hw_settings.h" #include "../uavobjectwidgetutils/configtaskwidget.h" -#include "extensionsystem/pluginmanager.h" -#include "uavobjectmanager.h" -#include "uavobject.h" -#include -#include -#include "smartsavebutton.h" + +class Ui_CC_HW_Widget; +class QWidget; +class QSvgRenderer; class ConfigCCHWWidget : public ConfigTaskWidget { Q_OBJECT @@ -43,7 +41,6 @@ public: ConfigCCHWWidget(QWidget *parent = 0); ~ConfigCCHWWidget(); private slots: - void openHelp(); void refreshValues(); void widgetsContentsChanged(); void enableSaveButtons(bool enable); diff --git a/ground/gcs/src/plugins/config/configautotunewidget.cpp b/ground/gcs/src/plugins/config/configautotunewidget.cpp index fea26b73f..670e7a134 100644 --- a/ground/gcs/src/plugins/config/configautotunewidget.cpp +++ b/ground/gcs/src/plugins/config/configautotunewidget.cpp @@ -1,27 +1,33 @@ #include "configautotunewidget.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "ui_autotune.h" + #include "relaytuningsettings.h" #include "relaytuning.h" #include "stabilizationsettings.h" #include "hwsettings.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + ConfigAutotuneWidget::ConfigAutotuneWidget(QWidget *parent) : ConfigTaskWidget(parent) { m_autotune = new Ui_AutotuneWidget(); m_autotune->setupUi(this); - // Connect automatic signals - autoLoadWidgets(); + // must be done before auto binding ! + // setWikiURL(""); + + addAutoBindings(); + disableMouseWheelEvents(); // Whenever any value changes compute new potential stabilization settings @@ -145,26 +151,23 @@ void ConfigAutotuneWidget::recomputeStabilization() m_autotune->pitchAttitudeKp->setText(QString().number(stabSettings.PitchPI[StabilizationSettings::PITCHPI_KP])); m_autotune->pitchAttitudeKi->setText(QString().number(stabSettings.PitchPI[StabilizationSettings::PITCHPI_KI])); } -void ConfigAutotuneWidget::refreshWidgetsValues(UAVObject *obj) + +void ConfigAutotuneWidget::refreshWidgetsValuesImpl(UAVObject *obj) { HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager()); if (obj == hwSettings) { - bool dirtyBack = isDirty(); - HwSettings::DataFields hwSettingsData = hwSettings->getData(); - m_autotune->enableAutoTune->setChecked( - hwSettingsData.OptionalModules[HwSettings::OPTIONALMODULES_AUTOTUNE] == HwSettings::OPTIONALMODULES_ENABLED); - setDirty(dirtyBack); + bool enabled = (hwSettings->getOptionalModules(HwSettings::OPTIONALMODULES_AUTOTUNE) == HwSettings::OPTIONALMODULES_ENABLED); + m_autotune->enableAutoTune->setChecked(enabled); } - ConfigTaskWidget::refreshWidgetsValues(obj); } -void ConfigAutotuneWidget::updateObjectsFromWidgets() + +void ConfigAutotuneWidget::updateObjectsFromWidgetsImpl() { HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager()); - HwSettings::DataFields hwSettingsData = hwSettings->getData(); - hwSettingsData.OptionalModules[HwSettings::OPTIONALMODULES_AUTOTUNE] = - m_autotune->enableAutoTune->isChecked() ? HwSettings::OPTIONALMODULES_ENABLED : HwSettings::OPTIONALMODULES_DISABLED; - hwSettings->setData(hwSettingsData); - ConfigTaskWidget::updateObjectsFromWidgets(); + quint8 enableModule = (m_autotune->enableAutoTune->isChecked()) ? HwSettings::OPTIONALMODULES_ENABLED : HwSettings::OPTIONALMODULES_DISABLED; + + hwSettings->setOptionalModules(HwSettings::OPTIONALMODULES_AUTOTUNE, enableModule); + ; } diff --git a/ground/gcs/src/plugins/config/configautotunewidget.h b/ground/gcs/src/plugins/config/configautotunewidget.h index 38f2df1fc..7e1d9391a 100644 --- a/ground/gcs/src/plugins/config/configautotunewidget.h +++ b/ground/gcs/src/plugins/config/configautotunewidget.h @@ -27,17 +27,20 @@ #ifndef CONFIGAUTOTUNE_H #define CONFIGAUTOTUNE_H -#include "ui_autotune.h" #include "../uavobjectwidgetutils/configtaskwidget.h" #include "extensionsystem/pluginmanager.h" #include "uavobjectmanager.h" #include "uavobject.h" + #include "stabilizationsettings.h" #include "relaytuningsettings.h" #include "relaytuning.h" -#include + +#include #include +class Ui_AutotuneWidget; + class ConfigAutotuneWidget : public ConfigTaskWidget { Q_OBJECT public: @@ -47,11 +50,10 @@ private: Ui_AutotuneWidget *m_autotune; StabilizationSettings::DataFields stabSettings; -signals: +protected: + virtual void refreshWidgetsValuesImpl(UAVObject *obj); + virtual void updateObjectsFromWidgetsImpl(); -public slots: - void refreshWidgetsValues(UAVObject *obj); - void updateObjectsFromWidgets(); private slots: void recomputeStabilization(); void saveStabilization(); diff --git a/ground/gcs/src/plugins/config/configcamerastabilizationwidget.cpp b/ground/gcs/src/plugins/config/configcamerastabilizationwidget.cpp index 801d1f935..ce0c51332 100644 --- a/ground/gcs/src/plugins/config/configcamerastabilizationwidget.cpp +++ b/ground/gcs/src/plugins/config/configcamerastabilizationwidget.cpp @@ -35,34 +35,29 @@ */ #include "configcamerastabilizationwidget.h" + +#include "ui_camerastabilization.h" + #include "camerastabsettings.h" #include "hwsettings.h" #include "mixersettings.h" #include "actuatorcommand.h" -#include -#include ConfigCameraStabilizationWidget::ConfigCameraStabilizationWidget(QWidget *parent) : ConfigTaskWidget(parent) { ui = new Ui_CameraStabilizationWidget(); ui->setupUi(this); - addApplySaveButtons(ui->camerastabilizationSaveRAM, ui->camerastabilizationSaveSD); + // must be done before auto binding ! + setWikiURL("Camera+Stabilisation+Configuration"); - ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); - Core::Internal::GeneralSettings *settings = pm->getObject(); - if (!settings->useExpertMode()) { - ui->camerastabilizationSaveRAM->setVisible(false); - } + addAutoBindings(); + disableMouseWheelEvents(); // These widgets don't have direct relation to UAVObjects // and need special processing - QComboBox *outputs[] = { - ui->rollChannel, - ui->pitchChannel, - ui->yawChannel, - }; + QComboBox *outputs[] = { ui->rollChannel, ui->pitchChannel, ui->yawChannel, }; const int NUM_OUTPUTS = sizeof(outputs) / sizeof(outputs[0]); // Populate widgets with channel numbers @@ -74,11 +69,6 @@ ConfigCameraStabilizationWidget::ConfigCameraStabilizationWidget(QWidget *parent } } - setWikiURL("Camera+Stabilisation+Configuration"); - // Load UAVObjects to widget relations from UI file - // using objrelation dynamic property - autoLoadWidgets(); - // Add some widgets to track their UI dirty state and handle smartsave addWidget(ui->enableCameraStabilization); addWidget(ui->rollChannel); @@ -97,9 +87,6 @@ ConfigCameraStabilizationWidget::ConfigCameraStabilizationWidget(QWidget *parent // To set special widgets to defaults when requested connect(this, SIGNAL(defaultRequested(int)), this, SLOT(defaultRequestedSlot(int))); - - disableMouseWheelEvents(); - updateEnableControls(); } ConfigCameraStabilizationWidget::~ConfigCameraStabilizationWidget() @@ -110,21 +97,19 @@ ConfigCameraStabilizationWidget::~ConfigCameraStabilizationWidget() /* * This overridden function refreshes widgets which have no direct relation * to any of UAVObjects. It saves their dirty state first because update comes - * from UAVObjects, and then restores it. Aftewards it calls base class - * function to take care of other widgets which were dynamically added. + * from UAVObjects, and then restores it. */ -void ConfigCameraStabilizationWidget::refreshWidgetsValues(UAVObject *obj) +void ConfigCameraStabilizationWidget::refreshWidgetsValuesImpl(UAVObject *obj) { - bool dirty = isDirty(); + Q_UNUSED(obj); // Set module enable checkbox from OptionalModules UAVObject item. // It needs special processing because ConfigTaskWidget uses TRUE/FALSE // for QCheckBox, but OptionalModules uses Enabled/Disabled enum values. HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager()); - HwSettings::DataFields hwSettingsData = hwSettings->getData(); ui->enableCameraStabilization->setChecked( - hwSettingsData.OptionalModules[HwSettings::OPTIONALMODULES_CAMERASTAB] == HwSettings::OPTIONALMODULES_ENABLED); + hwSettings->getOptionalModules(HwSettings::OPTIONALMODULES_CAMERASTAB) == HwSettings::OPTIONALMODULES_ENABLED); // Load mixer outputs which are mapped to camera controls MixerSettings *mixerSettings = MixerSettings::GetInstance(getObjectManager()); @@ -164,22 +149,16 @@ void ConfigCameraStabilizationWidget::refreshWidgetsValues(UAVObject *obj) } } } - - setDirty(dirty); - - ConfigTaskWidget::refreshWidgetsValues(obj); } /* * This overridden function updates UAVObjects which have no direct relation - * to any of widgets. Aftewards it calls base class function to take care of - * other object to widget relations which were dynamically added. + * to any of widgets. */ -void ConfigCameraStabilizationWidget::updateObjectsFromWidgets() +void ConfigCameraStabilizationWidget::updateObjectsFromWidgetsImpl() { // Save state of the module enable checkbox first. - // Do not use setData() member on whole object, if possible, since it triggers - // unnessesary UAVObect update. + // Do not use setData() member on whole object, if possible, since it triggers unnecessary UAVObect update. quint8 enableModule = ui->enableCameraStabilization->isChecked() ? HwSettings::OPTIONALMODULES_ENABLED : HwSettings::OPTIONALMODULES_DISABLED; HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager()); @@ -253,8 +232,6 @@ void ConfigCameraStabilizationWidget::updateObjectsFromWidgets() // FIXME: Should not use setData() to prevent double updates. // It should be refactored after the reformatting of MixerSettings UAVObject. mixerSettings->setData(mixerSettingsData); - - ConfigTaskWidget::updateObjectsFromWidgets(); } /* @@ -265,18 +242,6 @@ void ConfigCameraStabilizationWidget::defaultRequestedSlot(int group) { Q_UNUSED(group); - // Here is the example of how to reset the state of QCheckBox. It is - // commented out because we normally don't want to reset the module - // enable state to default "disabled" (or we don't care about values at all). - // But if you want, you could use the dirtyClone() function to get default - // values of an object and then use them to set a widget state. - // - // HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager()); - // HwSettings *hwSettingsDefault=(HwSettings*)hwSettings->dirtyClone(); - // HwSettings::DataFields hwSettingsData = hwSettingsDefault->getData(); - // m_camerastabilization->enableCameraStabilization->setChecked( - // hwSettingsData.OptionalModules[HwSettings::OPTIONALMODULES_CAMERASTAB] == HwSettings::OPTIONALMODULES_ENABLED); - // For outputs we set them all to none, so don't use any UAVObject to get defaults QComboBox *outputs[] = { ui->rollChannel, diff --git a/ground/gcs/src/plugins/config/configcamerastabilizationwidget.h b/ground/gcs/src/plugins/config/configcamerastabilizationwidget.h index 8c656f8ff..cb94725b5 100644 --- a/ground/gcs/src/plugins/config/configcamerastabilizationwidget.h +++ b/ground/gcs/src/plugins/config/configcamerastabilizationwidget.h @@ -27,13 +27,14 @@ #ifndef CONFIGCAMERASTABILIZATIONWIDGET_H #define CONFIGCAMERASTABILIZATIONWIDGET_H -#include "ui_camerastabilization.h" #include "../uavobjectwidgetutils/configtaskwidget.h" -#include "extensionsystem/pluginmanager.h" -#include "uavobjectmanager.h" + #include "uavobject.h" + #include "camerastabsettings.h" +class Ui_CameraStabilizationWidget; + class ConfigCameraStabilizationWidget : public ConfigTaskWidget { Q_OBJECT @@ -41,10 +42,12 @@ public: ConfigCameraStabilizationWidget(QWidget *parent = 0); ~ConfigCameraStabilizationWidget(); +protected: + virtual void refreshWidgetsValuesImpl(UAVObject *obj); + virtual void updateObjectsFromWidgetsImpl(); + private: Ui_CameraStabilizationWidget *ui; - void refreshWidgetsValues(UAVObject *obj); - void updateObjectsFromWidgets(); private slots: void defaultRequestedSlot(int group); diff --git a/ground/gcs/src/plugins/config/configccattitudewidget.cpp b/ground/gcs/src/plugins/config/configccattitudewidget.cpp index b14f98302..5b0397d49 100644 --- a/ground/gcs/src/plugins/config/configccattitudewidget.cpp +++ b/ground/gcs/src/plugins/config/configccattitudewidget.cpp @@ -26,50 +26,45 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "configccattitudewidget.h" + #include "ui_ccattitude.h" -#include "utils/coordinateconversions.h" + +#include +#include + #include "attitudesettings.h" -#include -#include -#include -#include -#include #include "accelstate.h" #include "accelgyrosettings.h" #include "gyrostate.h" -#include -#include -#include + +#include +#include + ConfigCCAttitudeWidget::ConfigCCAttitudeWidget(QWidget *parent) : - ConfigTaskWidget(parent), - ui(new Ui_ccattitude) + ConfigTaskWidget(parent), accelUpdates(0), gyroUpdates(0) { + ui = new Ui_ccattitude(), ui->setupUi(this); - connect(ui->zeroBias, SIGNAL(clicked()), this, SLOT(startAccelCalibration())); - ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); - Core::Internal::GeneralSettings *settings = pm->getObject(); - if (!settings->useExpertMode()) { - ui->applyButton->setVisible(false); - } + // must be done before auto binding ! + setWikiURL("CC+Attitude+Configuration"); + + addAutoBindings(); - addApplySaveButtons(ui->applyButton, ui->saveButton); addUAVObject("AttitudeSettings"); addUAVObject("AccelGyroSettings"); - // Connect the help button - connect(ui->ccAttitudeHelp, SIGNAL(clicked()), this, SLOT(openHelp())); - addWidgetBinding("AttitudeSettings", "ZeroDuringArming", ui->zeroGyroBiasOnArming); + addWidgetBinding("AttitudeSettings", "InitialZeroWhenBoardSteady", ui->initGyroWhenBoardSteady); + addWidgetBinding("AttitudeSettings", "AccelTau", ui->accelTauSpinbox); addWidgetBinding("AttitudeSettings", "BoardRotation", ui->rollBias, AttitudeSettings::BOARDROTATION_ROLL); addWidgetBinding("AttitudeSettings", "BoardRotation", ui->pitchBias, AttitudeSettings::BOARDROTATION_PITCH); addWidgetBinding("AttitudeSettings", "BoardRotation", ui->yawBias, AttitudeSettings::BOARDROTATION_YAW); addWidget(ui->zeroBias); - populateWidgets(); - refreshWidgetsValues(); - forceConnectedState(); + + connect(ui->zeroBias, SIGNAL(clicked()), this, SLOT(startAccelCalibration())); } ConfigCCAttitudeWidget::~ConfigCCAttitudeWidget() @@ -137,7 +132,8 @@ void ConfigCCAttitudeWidget::sensorsUpdated(UAVObject *obj) attitudeSettingsData.BiasCorrectGyro = AttitudeSettings::BIASCORRECTGYRO_TRUE; AttitudeSettings::GetInstance(getObjectManager())->setData(attitudeSettingsData); AccelGyroSettings::GetInstance(getObjectManager())->setData(accelGyroSettingsData); - this->setDirty(true); + + setDirty(true); // reenable controls enableControls(true); @@ -213,12 +209,6 @@ void ConfigCCAttitudeWidget::startAccelCalibration() connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); } -void ConfigCCAttitudeWidget::openHelp() -{ - QDesktopServices::openUrl(QUrl(QString(WIKI_URL_ROOT) + QString("CC+Attitude+Configuration"), - QUrl::StrictMode)); -} - void ConfigCCAttitudeWidget::setAccelFiltering(bool active) { Q_UNUSED(active); @@ -229,13 +219,12 @@ void ConfigCCAttitudeWidget::enableControls(bool enable) { ui->zeroBias->setEnabled(enable); ui->zeroGyroBiasOnArming->setEnabled(enable); + ui->initGyroWhenBoardSteady->setEnabled(enable); ui->accelTauSpinbox->setEnabled(enable); ConfigTaskWidget::enableControls(enable); } -void ConfigCCAttitudeWidget::updateObjectsFromWidgets() +void ConfigCCAttitudeWidget::updateObjectsFromWidgetsImpl() { - ConfigTaskWidget::updateObjectsFromWidgets(); - ui->zeroBiasProgress->setValue(0); } diff --git a/ground/gcs/src/plugins/config/configccattitudewidget.h b/ground/gcs/src/plugins/config/configccattitudewidget.h index b4d84a5b9..7f56ea586 100644 --- a/ground/gcs/src/plugins/config/configccattitudewidget.h +++ b/ground/gcs/src/plugins/config/configccattitudewidget.h @@ -27,15 +27,14 @@ #ifndef CCATTITUDEWIDGET_H #define CCATTITUDEWIDGET_H -#include "ui_ccattitude.h" #include "../uavobjectwidgetutils/configtaskwidget.h" -#include "extensionsystem/pluginmanager.h" -#include "uavobjectmanager.h" + #include "uavobject.h" + #include #include -class Ui_Widget; +class Ui_ccattitude; class ConfigCCAttitudeWidget : public ConfigTaskWidget { Q_OBJECT @@ -44,13 +43,13 @@ public: explicit ConfigCCAttitudeWidget(QWidget *parent = 0); ~ConfigCCAttitudeWidget(); - virtual void updateObjectsFromWidgets(); +protected: + virtual void updateObjectsFromWidgetsImpl(); private slots: void sensorsUpdated(UAVObject *obj); void timeout(); void startAccelCalibration(); - void openHelp(); void setAccelFiltering(bool active); private: @@ -65,8 +64,8 @@ private: QList x_accum, y_accum, z_accum; QList x_gyro_accum, y_gyro_accum, z_gyro_accum; - static const float DEFAULT_ENABLED_ACCEL_TAU = 0.1; static const int NUM_SENSOR_UPDATES = 300; + protected: virtual void enableControls(bool enable); }; diff --git a/ground/gcs/src/plugins/config/configgadget.cpp b/ground/gcs/src/plugins/config/configgadget.cpp index 013309e27..e67863e1b 100644 --- a/ground/gcs/src/plugins/config/configgadget.cpp +++ b/ground/gcs/src/plugins/config/configgadget.cpp @@ -2,7 +2,8 @@ ****************************************************************************** * * @file configgadget.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup ConfigPlugin Config Plugin @@ -25,8 +26,11 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "configgadget.h" + #include "configgadgetwidget.h" +#include "../uavobjectwidgetutils/configtaskwidget.h" + ConfigGadget::ConfigGadget(QString classId, ConfigGadgetWidget *widget, QWidget *parent) : IUAVGadget(classId, parent), m_widget(widget) {} @@ -40,3 +44,13 @@ void ConfigGadget::loadConfiguration(IUAVGadgetConfiguration *config) { Q_UNUSED(config); } + +void ConfigGadget::saveState(QSettings *settings) +{ + m_widget->saveState(settings); +} + +void ConfigGadget::restoreState(QSettings *settings) +{ + m_widget->restoreState(settings); +} diff --git a/ground/gcs/src/plugins/config/configgadget.h b/ground/gcs/src/plugins/config/configgadget.h index 23184b74e..c0380fad7 100644 --- a/ground/gcs/src/plugins/config/configgadget.h +++ b/ground/gcs/src/plugins/config/configgadget.h @@ -2,7 +2,8 @@ ****************************************************************************** * * @file configgadget.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup ConfigPlugin Config Plugin @@ -28,14 +29,10 @@ #define CONFIGGADGET_H #include -#include "../uavobjectwidgetutils/configtaskwidget.h" -class IUAVGadget; -// class QList; class QWidget; class QString; class ConfigGadgetWidget; -class Ui_ConfigGadget; using namespace Core; @@ -49,8 +46,12 @@ public: { return (QWidget *)m_widget; } + void loadConfiguration(IUAVGadgetConfiguration *config); + void saveState(QSettings *settings); + void restoreState(QSettings *settings); + private: ConfigGadgetWidget *m_widget; }; diff --git a/ground/gcs/src/plugins/config/configgadget.qrc b/ground/gcs/src/plugins/config/configgadget.qrc index 8c194d320..b7e9b3ec7 100644 --- a/ground/gcs/src/plugins/config/configgadget.qrc +++ b/ground/gcs/src/plugins/config/configgadget.qrc @@ -57,5 +57,6 @@ images/error.svg images/nano_top.png images/cc3d_top.png + images/sparky2_top.png diff --git a/ground/gcs/src/plugins/config/configgadgetwidget.cpp b/ground/gcs/src/plugins/config/configgadgetwidget.cpp index e658a4ff7..c121865a7 100644 --- a/ground/gcs/src/plugins/config/configgadgetwidget.cpp +++ b/ground/gcs/src/plugins/config/configgadgetwidget.cpp @@ -2,7 +2,8 @@ ****************************************************************************** * * @file configgadgetwidget.cpp - * @author E. Lafargue & The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * E. Lafargue & The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup ConfigPlugin Config Plugin @@ -39,18 +40,23 @@ #include "configoplinkwidget.h" #include "configrevowidget.h" #include "configrevonanohwwidget.h" -#include "defaultattitudewidget.h" -#include "defaulthwsettingswidget.h" -#include "uavobjectutilmanager.h" +#include "configsparky2hwwidget.h" +#include "defaultconfigwidget.h" +#include +#include #include +#include + +#include "utils/mytabbedstackwidget.h" -#include -#include #include -#include #include -#include +#include +#include +#include + +#define OPLINK_TIMEOUT 2000 ConfigGadgetWidget::ConfigGadgetWidget(QWidget *parent) : QWidget(parent) { @@ -64,85 +70,93 @@ ConfigGadgetWidget::ConfigGadgetWidget(QWidget *parent) : QWidget(parent) layout->addWidget(stackWidget); setLayout(layout); - QWidget *qwd; + ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); - QIcon *icon = new QIcon(); + QWidget *widget; + QIcon *icon; + + icon = new QIcon(); icon->addFile(":/configgadget/images/hardware_normal.png", QSize(), QIcon::Normal, QIcon::Off); icon->addFile(":/configgadget/images/hardware_selected.png", QSize(), QIcon::Selected, QIcon::Off); - qwd = new DefaultHwSettingsWidget(this); - stackWidget->insertTab(ConfigGadgetWidget::hardware, qwd, *icon, QString("Hardware")); + widget = new DefaultConfigWidget(this, tr("Hardware")); + stackWidget->insertTab(ConfigGadgetWidget::Hardware, widget, *icon, QString("Hardware")); - icon = new QIcon(); + icon = new QIcon(); icon->addFile(":/configgadget/images/vehicle_normal.png", QSize(), QIcon::Normal, QIcon::Off); icon->addFile(":/configgadget/images/vehicle_selected.png", QSize(), QIcon::Selected, QIcon::Off); - qwd = new ConfigVehicleTypeWidget(this); - stackWidget->insertTab(ConfigGadgetWidget::aircraft, qwd, *icon, QString("Vehicle")); + widget = new ConfigVehicleTypeWidget(this); + static_cast(widget)->bind(); + stackWidget->insertTab(ConfigGadgetWidget::Aircraft, widget, *icon, QString("Vehicle")); - icon = new QIcon(); + icon = new QIcon(); icon->addFile(":/configgadget/images/input_normal.png", QSize(), QIcon::Normal, QIcon::Off); icon->addFile(":/configgadget/images/input_selected.png", QSize(), QIcon::Selected, QIcon::Off); - qwd = new ConfigInputWidget(this); - stackWidget->insertTab(ConfigGadgetWidget::input, qwd, *icon, QString("Input")); + widget = new ConfigInputWidget(this); + static_cast(widget)->bind(); + stackWidget->insertTab(ConfigGadgetWidget::Input, widget, *icon, QString("Input")); - icon = new QIcon(); + icon = new QIcon(); icon->addFile(":/configgadget/images/output_normal.png", QSize(), QIcon::Normal, QIcon::Off); icon->addFile(":/configgadget/images/output_selected.png", QSize(), QIcon::Selected, QIcon::Off); - qwd = new ConfigOutputWidget(this); - stackWidget->insertTab(ConfigGadgetWidget::output, qwd, *icon, QString("Output")); + widget = new ConfigOutputWidget(this); + static_cast(widget)->bind(); + stackWidget->insertTab(ConfigGadgetWidget::Output, widget, *icon, QString("Output")); - icon = new QIcon(); + icon = new QIcon(); icon->addFile(":/configgadget/images/ins_normal.png", QSize(), QIcon::Normal, QIcon::Off); icon->addFile(":/configgadget/images/ins_selected.png", QSize(), QIcon::Selected, QIcon::Off); - qwd = new DefaultAttitudeWidget(this); - stackWidget->insertTab(ConfigGadgetWidget::sensors, qwd, *icon, QString("Attitude")); + widget = new DefaultConfigWidget(this, tr("Attitude")); + stackWidget->insertTab(ConfigGadgetWidget::Sensors, widget, *icon, QString("Attitude")); - icon = new QIcon(); + icon = new QIcon(); icon->addFile(":/configgadget/images/stabilization_normal.png", QSize(), QIcon::Normal, QIcon::Off); icon->addFile(":/configgadget/images/stabilization_selected.png", QSize(), QIcon::Selected, QIcon::Off); - qwd = new ConfigStabilizationWidget(this); - stackWidget->insertTab(ConfigGadgetWidget::stabilization, qwd, *icon, QString("Stabilization")); + widget = new ConfigStabilizationWidget(this); + static_cast(widget)->bind(); + stackWidget->insertTab(ConfigGadgetWidget::Stabilization, widget, *icon, QString("Stabilization")); - icon = new QIcon(); + icon = new QIcon(); icon->addFile(":/configgadget/images/camstab_normal.png", QSize(), QIcon::Normal, QIcon::Off); icon->addFile(":/configgadget/images/camstab_selected.png", QSize(), QIcon::Selected, QIcon::Off); - qwd = new ConfigCameraStabilizationWidget(this); - stackWidget->insertTab(ConfigGadgetWidget::camerastabilization, qwd, *icon, QString("Gimbal")); + widget = new ConfigCameraStabilizationWidget(this); + static_cast(widget)->bind(); + stackWidget->insertTab(ConfigGadgetWidget::CameraStabilization, widget, *icon, QString("Gimbal")); - icon = new QIcon(); + icon = new QIcon(); icon->addFile(":/configgadget/images/txpid_normal.png", QSize(), QIcon::Normal, QIcon::Off); icon->addFile(":/configgadget/images/txpid_selected.png", QSize(), QIcon::Selected, QIcon::Off); - qwd = new ConfigTxPIDWidget(this); - stackWidget->insertTab(ConfigGadgetWidget::txpid, qwd, *icon, QString("TxPID")); + widget = new ConfigTxPIDWidget(this); + static_cast(widget)->bind(); + stackWidget->insertTab(ConfigGadgetWidget::TxPid, widget, *icon, QString("TxPID")); - stackWidget->setCurrentIndex(ConfigGadgetWidget::hardware); + icon = new QIcon(); + icon->addFile(":/configgadget/images/pipx-normal.png", QSize(), QIcon::Normal, QIcon::Off); + icon->addFile(":/configgadget/images/pipx-selected.png", QSize(), QIcon::Selected, QIcon::Off); + widget = new DefaultConfigWidget(this, tr("OPLink Configuration")); + stackWidget->insertTab(ConfigGadgetWidget::OPLink, widget, *icon, QString("OPLink")); - // Listen to autopilot connection events - ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); - TelemetryManager *telMngr = pm->getObject(); - connect(telMngr, SIGNAL(connected()), this, SLOT(onAutopilotConnect())); - connect(telMngr, SIGNAL(disconnected()), this, SLOT(onAutopilotDisconnect())); + stackWidget->setCurrentIndex(ConfigGadgetWidget::Hardware); - // And check whether by any chance we are not already connected - if (telMngr->isConnected()) { + // connect to autopilot connection events + TelemetryManager *tm = pm->getObject(); + connect(tm, SIGNAL(connected()), this, SLOT(onAutopilotConnect())); + connect(tm, SIGNAL(disconnected()), this, SLOT(onAutopilotDisconnect())); + // check if we are already connected + if (tm->isConnected()) { onAutopilotConnect(); } + // connect to oplink manager + OPLinkManager *om = pm->getObject(); + connect(om, SIGNAL(connected()), this, SLOT(onOPLinkConnect())); + connect(om, SIGNAL(disconnected()), this, SLOT(onOPLinkDisconnect())); + // check if we are already connected + if (om->isConnected()) { + onOPLinkConnect(); + } + help = 0; connect(stackWidget, SIGNAL(currentAboutToShow(int, bool *)), this, SLOT(tabAboutToChange(int, bool *))); - - // Connect to the OPLinkStatus object updates - UAVObjectManager *objManager = pm->getObject(); - oplinkStatusObj = dynamic_cast(objManager->getObject("OPLinkStatus")); - if (oplinkStatusObj != NULL) { - connect(oplinkStatusObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(updateOPLinkStatus(UAVObject *))); - } else { - qDebug() << "Error: Object is unknown (OPLinkStatus)."; - } - - // Create the timer that is used to timeout the connection to the OPLink. - oplinkTimeout = new QTimer(this); - connect(oplinkTimeout, SIGNAL(timeout()), this, SLOT(onOPLinkDisconnect())); - oplinkConnected = false; } ConfigGadgetWidget::~ConfigGadgetWidget() @@ -152,73 +166,118 @@ ConfigGadgetWidget::~ConfigGadgetWidget() void ConfigGadgetWidget::startInputWizard() { - stackWidget->setCurrentIndex(ConfigGadgetWidget::input); - ConfigInputWidget *inputWidget = dynamic_cast(stackWidget->getWidget(ConfigGadgetWidget::input)); + stackWidget->setCurrentIndex(ConfigGadgetWidget::Input); + ConfigInputWidget *inputWidget = dynamic_cast(stackWidget->getWidget(ConfigGadgetWidget::Input)); Q_ASSERT(inputWidget); inputWidget->startInputWizard(); } +void ConfigGadgetWidget::saveState(QSettings *settings) +{ + settings->setValue("currentIndex", stackWidget->currentIndex()); +} + +void ConfigGadgetWidget::restoreState(QSettings *settings) +{ + int index = settings->value("currentIndex", 0).toInt(); + + stackWidget->setCurrentIndex(index); +} + void ConfigGadgetWidget::resizeEvent(QResizeEvent *event) { QWidget::resizeEvent(event); } -void ConfigGadgetWidget::onAutopilotDisconnect() -{ - QWidget *qwd = new DefaultAttitudeWidget(this); - - stackWidget->replaceTab(ConfigGadgetWidget::sensors, qwd); - - qwd = new DefaultHwSettingsWidget(this); - stackWidget->replaceTab(ConfigGadgetWidget::hardware, qwd); - - emit autopilotDisconnected(); -} - void ConfigGadgetWidget::onAutopilotConnect() { - qDebug() << "ConfigGadgetWidget onAutopilotConnect"; - // First of all, check what Board type we are talking to, and - // if necessary, remove/add tabs in the config gadget: + // qDebug() << "ConfigGadgetWidget::onAutopilotConnect"; + + // Check what Board type we are talking to, and if necessary, remove/add tabs in the config gadget ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); UAVObjectUtilManager *utilMngr = pm->getObject(); + if (utilMngr) { int board = utilMngr->getBoardModel(); if ((board & 0xff00) == 0x0400) { // CopterControl family - QWidget *qwd = new ConfigCCAttitudeWidget(this); - stackWidget->replaceTab(ConfigGadgetWidget::sensors, qwd); - qwd = new ConfigCCHWWidget(this); - stackWidget->replaceTab(ConfigGadgetWidget::hardware, qwd); + ConfigTaskWidget *widget; + widget = new ConfigCCAttitudeWidget(this); + widget->bind(); + stackWidget->replaceTab(ConfigGadgetWidget::Sensors, widget); + widget = new ConfigCCHWWidget(this); + widget->bind(); + stackWidget->replaceTab(ConfigGadgetWidget::Hardware, widget); } else if ((board & 0xff00) == 0x0900) { // Revolution family - QWidget *qwd = new ConfigRevoWidget(this); - stackWidget->replaceTab(ConfigGadgetWidget::sensors, qwd); - if (board == 0x0903) { - qwd = new ConfigRevoHWWidget(this); + ConfigTaskWidget *widget; + widget = new ConfigRevoWidget(this); + widget->bind(); + stackWidget->replaceTab(ConfigGadgetWidget::Sensors, widget); + if (board == 0x0903 || board == 0x0904) { + widget = new ConfigRevoHWWidget(this); } else if (board == 0x0905) { - qwd = new ConfigRevoNanoHWWidget(this); + widget = new ConfigRevoNanoHWWidget(this); } - stackWidget->replaceTab(ConfigGadgetWidget::hardware, qwd); + widget->bind(); + stackWidget->replaceTab(ConfigGadgetWidget::Hardware, widget); + } else if ((board & 0xff00) == 0x9200) { + // Sparky2 + ConfigTaskWidget *widget; + widget = new ConfigRevoWidget(this); + widget->bind(); + stackWidget->replaceTab(ConfigGadgetWidget::Sensors, widget); + widget = new ConfigSparky2HWWidget(this); + widget->bind(); + stackWidget->replaceTab(ConfigGadgetWidget::Hardware, widget); } else { // Unknown board - qDebug() << "Unknown board " << board; + qWarning() << "Unknown board " << board; } } - - emit autopilotConnected(); } -void ConfigGadgetWidget::tabAboutToChange(int i, bool *proceed) +void ConfigGadgetWidget::onAutopilotDisconnect() { - Q_UNUSED(i); + // qDebug() << "ConfigGadgetWidget::onAutopilotDiconnect"; + QWidget *widget; + + widget = new DefaultConfigWidget(this, tr("Attitude")); + stackWidget->replaceTab(ConfigGadgetWidget::Sensors, widget); + + widget = new DefaultConfigWidget(this, tr("Hardware")); + stackWidget->replaceTab(ConfigGadgetWidget::Hardware, widget); +} + +void ConfigGadgetWidget::onOPLinkConnect() +{ + // qDebug() << "ConfigGadgetWidget::onOPLinkConnect"; + + ConfigTaskWidget *widget = new ConfigOPLinkWidget(this); + + widget->bind(); + stackWidget->replaceTab(ConfigGadgetWidget::OPLink, widget); +} + +void ConfigGadgetWidget::onOPLinkDisconnect() +{ + // qDebug() << "ConfigGadgetWidget::onOPLinkDisconnect"; + + QWidget *widget = new DefaultConfigWidget(this, tr("OPLink Configuration")); + + stackWidget->replaceTab(ConfigGadgetWidget::OPLink, widget); +} + +void ConfigGadgetWidget::tabAboutToChange(int index, bool *proceed) +{ + Q_UNUSED(index); *proceed = true; ConfigTaskWidget *wid = qobject_cast(stackWidget->currentWidget()); if (!wid) { return; } if (wid->isDirty()) { - int ans = QMessageBox::warning(this, tr("Unsaved changes"), tr("The tab you are leaving has unsaved changes," + int ans = QMessageBox::warning(this, tr("Unsaved changes"), tr("The tab you are leaving has unsaved changes, " "if you proceed they will be lost.\n" "Do you still want to proceed?"), QMessageBox::Yes, QMessageBox::No); if (ans == QMessageBox::No) { @@ -228,35 +287,3 @@ void ConfigGadgetWidget::tabAboutToChange(int i, bool *proceed) } } } - -/*! - \brief Called by updates to @OPLinkStatus - */ -void ConfigGadgetWidget::updateOPLinkStatus(UAVObject *) -{ - // Restart the disconnection timer. - oplinkTimeout->start(5000); - if (!oplinkConnected) { - qDebug() << "ConfigGadgetWidget onOPLinkConnect"; - - QIcon *icon = new QIcon(); - 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 ConfigOPLinkWidget(this); - stackWidget->insertTab(ConfigGadgetWidget::oplink, qwd, *icon, QString("OPLink")); - oplinkConnected = true; - } -} - -void ConfigGadgetWidget::onOPLinkDisconnect() -{ - qDebug() << "ConfigGadgetWidget onOPLinkDisconnect"; - oplinkTimeout->stop(); - oplinkConnected = false; - - if (stackWidget->currentIndex() == ConfigGadgetWidget::oplink) { - stackWidget->setCurrentIndex(0); - } - stackWidget->removeTab(ConfigGadgetWidget::oplink); -} diff --git a/ground/gcs/src/plugins/config/configgadgetwidget.h b/ground/gcs/src/plugins/config/configgadgetwidget.h index 0a443b9e0..9997ba8d4 100644 --- a/ground/gcs/src/plugins/config/configgadgetwidget.h +++ b/ground/gcs/src/plugins/config/configgadgetwidget.h @@ -2,7 +2,8 @@ ****************************************************************************** * * @file configgadgetwidget.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup ConfigPlugin Config Plugin @@ -27,53 +28,39 @@ #ifndef CONFIGGADGETWIDGET_H #define CONFIGGADGETWIDGET_H -#include "extensionsystem/pluginmanager.h" -#include "uavobjectmanager.h" -#include "uavobject.h" -#include "objectpersistence.h" -#include "utils/pathutils.h" -#include "utils/mytabbedstackwidget.h" -#include "../uavobjectwidgetutils/configtaskwidget.h" - #include -#include -#include -#include + +class QTextBrowser; +class QSettings; +class MyTabbedStackWidget; class ConfigGadgetWidget : public QWidget { Q_OBJECT - QTextBrowser *help; public: + enum WidgetTabs { Hardware = 0, Aircraft, Input, Output, Sensors, Stabilization, CameraStabilization, TxPid, OPLink }; + ConfigGadgetWidget(QWidget *parent = 0); ~ConfigGadgetWidget(); - enum widgetTabs { hardware = 0, aircraft, input, output, sensors, stabilization, camerastabilization, txpid, oplink }; + void startInputWizard(); -public slots: - void onAutopilotConnect(); - void onAutopilotDisconnect(); - void tabAboutToChange(int i, bool *); - void updateOPLinkStatus(UAVObject *object); - void onOPLinkDisconnect(); - -signals: - void autopilotConnected(); - void autopilotDisconnected(); - void oplinkConnect(); - void oplinkDisconnect(); + void saveState(QSettings *settings); + void restoreState(QSettings *settings); protected: void resizeEvent(QResizeEvent *event); +private slots: + void onAutopilotConnect(); + void onAutopilotDisconnect(); + void onOPLinkConnect(); + void onOPLinkDisconnect(); + void tabAboutToChange(int index, bool *proceed); + private: - UAVDataObject *oplinkStatusObj; - - // A timer that timesout the connction to the OPLink. - QTimer *oplinkTimeout; - bool oplinkConnected; - MyTabbedStackWidget *stackWidget; + QTextBrowser *help; }; #endif // CONFIGGADGETWIDGET_H diff --git a/ground/gcs/src/plugins/config/configinputwidget.cpp b/ground/gcs/src/plugins/config/configinputwidget.cpp index 70f5d87d2..4ad96c107 100644 --- a/ground/gcs/src/plugins/config/configinputwidget.cpp +++ b/ground/gcs/src/plugins/config/configinputwidget.cpp @@ -2,13 +2,13 @@ ****************************************************************************** * * @file configinputwidget.cpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2016. * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup ConfigPlugin Config Plugin * @{ - * @brief Servo input/output configuration panel for the config gadget + * @brief Servo input configuration panel for the config gadget *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify @@ -28,28 +28,37 @@ #include "configinputwidget.h" -#include -#include +#include "ui_input.h" +#include "ui_input_wizard.h" + +#include "inputchannelform.h" +#include "ui_inputchannelform.h" + +#include "failsafechannelform.h" +#include "ui_failsafechannelform.h" + +#include +#include +#include + +#include #include -#include #include -#include -#include -#include -#include -#include -#include -#include #include +#include +#include #define ACCESS_MIN_MOVE -3 #define ACCESS_MAX_MOVE 3 #define STICK_MIN_MOVE -8 #define STICK_MAX_MOVE 8 +#define MIN_INPUT_US 100 +#define MAX_INPUT_US 2500 + #define CHANNEL_NUMBER_NONE 0 -#define DEFAULT_FLIGHT_MODE_NUMBER 3 +#define DEFAULT_FLIGHT_MODE_NUMBER 0 ConfigInputWidget::ConfigInputWidget(QWidget *parent) : ConfigTaskWidget(parent), @@ -68,6 +77,16 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) : accessoryDesiredObj2(NULL), accessoryDesiredObj3(NULL) { + ui = new Ui_InputWidget(); + ui->setupUi(this); + + // must be done before auto binding ! + setWikiURL("Input+Configuration"); + + addAutoBindings(); + + connect(this, SIGNAL(enableControlsChanged(bool)), this, SLOT(enableControlsChanged(bool))); + manualCommandObj = ManualControlCommand::GetInstance(getObjectManager()); manualSettingsObj = ManualControlSettings::GetInstance(getObjectManager()); flightModeSettingsObj = FlightModeSettings::GetInstance(getObjectManager()); @@ -84,54 +103,40 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) : // The other instances are populated lazily. Q_ASSERT(accessoryDesiredObj0); - ui = new Ui_InputWidget(); - ui->setupUi(this); - - wizardUi = new Ui_InputWizardWidget(); - wizardUi->setupUi(ui->wizard); - - addApplySaveButtons(ui->saveRCInputToRAM, ui->saveRCInputToSD); - - ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); - Core::Internal::GeneralSettings *settings = pm->getObject(); - if (!settings->useExpertMode()) { - ui->saveRCInputToRAM->setVisible(false); - } - - addApplySaveButtons(ui->saveRCInputToRAM, ui->saveRCInputToSD); - // Generate the rows of buttons in the input channel form GUI - unsigned int index = 0; - unsigned int indexRT = 0; + quint32 index = 0; + quint32 indexRT = 0; foreach(QString name, manualSettingsObj->getField("ChannelNumber")->getElementNames()) { Q_ASSERT(index < ManualControlSettings::CHANNELGROUPS_NUMELEM); - InputChannelForm *form = new InputChannelForm(index, this); - form->setName(name); - form->moveTo(*(ui->channelLayout)); + // Input channel setup + InputChannelForm *inputChannelForm = new InputChannelForm(index, this); + inputChannelForm->setName(name); + + inputChannelForm->moveTo(*(ui->channelLayout)); // The order of the following binding calls is important. Since the values will be populated // in reverse order of the binding order otherwise the 'Reversed' logic will floor the neutral value // to the max value ( which is smaller than the neutral value when reversed ) and the channel number // will not be set correctly. - addWidgetBinding("ManualControlSettings", "ChannelNumber", form->ui->channelNumber, index); - addWidgetBinding("ManualControlSettings", "ChannelGroups", form->ui->channelGroup, index); + addWidgetBinding("ManualControlSettings", "ChannelNumber", inputChannelForm->ui->channelNumber, index); + addWidgetBinding("ManualControlSettings", "ChannelGroups", inputChannelForm->ui->channelGroup, index); // Slider position based on real time Rcinput (allow monitoring) - addWidgetBinding("ManualControlCommand", "Channel", form->ui->channelNeutral, index); + addWidgetBinding("ManualControlCommand", "Channel", inputChannelForm->ui->channelNeutral, index); // Neutral value stored on board (SpinBox) - addWidgetBinding("ManualControlSettings", "ChannelNeutral", form->ui->neutralValue, index); - addWidgetBinding("ManualControlSettings", "ChannelMax", form->ui->channelMax, index); - addWidgetBinding("ManualControlSettings", "ChannelMin", form->ui->channelMin, index); - addWidgetBinding("ManualControlSettings", "ChannelMax", form->ui->channelMax, index); + addWidgetBinding("ManualControlSettings", "ChannelNeutral", inputChannelForm->ui->neutralValue, index); + addWidgetBinding("ManualControlSettings", "ChannelMax", inputChannelForm->ui->channelMax, index); + addWidgetBinding("ManualControlSettings", "ChannelMin", inputChannelForm->ui->channelMin, index); + addWidgetBinding("ManualControlSettings", "ChannelMax", inputChannelForm->ui->channelMax, index); - addWidget(form->ui->channelRev); + addWidget(inputChannelForm->ui->channelRev); // Reversing supported for some channels only bool reversable = ((index == ManualControlSettings::CHANNELGROUPS_THROTTLE) || (index == ManualControlSettings::CHANNELGROUPS_ROLL) || (index == ManualControlSettings::CHANNELGROUPS_PITCH) || (index == ManualControlSettings::CHANNELGROUPS_YAW)); - form->ui->channelRev->setVisible(reversable); + inputChannelForm->ui->channelRev->setVisible(reversable); // Input filter response time fields supported for some channels only switch (index) { @@ -143,21 +148,40 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) : case ManualControlSettings::CHANNELGROUPS_ACCESSORY1: case ManualControlSettings::CHANNELGROUPS_ACCESSORY2: case ManualControlSettings::CHANNELGROUPS_ACCESSORY3: - addWidgetBinding("ManualControlSettings", "ResponseTime", form->ui->channelResponseTime, indexRT); + addWidgetBinding("ManualControlSettings", "ResponseTime", inputChannelForm->ui->channelResponseTime, indexRT); ++indexRT; break; case ManualControlSettings::CHANNELGROUPS_THROTTLE: case ManualControlSettings::CHANNELGROUPS_FLIGHTMODE: - form->ui->channelResponseTime->setVisible(false); + inputChannelForm->ui->channelResponseTime->setVisible(false); break; default: Q_ASSERT(0); break; } - ++index; } + QList failsafeReloadGroup; + failsafeReloadGroup.append(555); + + addWidgetBinding("ManualControlSettings", "FailsafeFlightModeSwitchPosition", ui->failsafeFlightMode, 0, 1, true, new QList(failsafeReloadGroup)); + + // Generate the rows for the failsafe channel form GUI + index = 0; + foreach(QString name, manualSettingsObj->getField("FailsafeChannel")->getElementNames()) { + Q_ASSERT(index < ManualControlSettings::FAILSAFECHANNEL_NUMELEM); + + // Failsafe channels setup + FailsafeChannelForm *failsafeChannelForm = new FailsafeChannelForm(index, this); + addWidget(failsafeChannelForm->ui->channelValueSpinner); + failsafeChannelForm->setName(name); + failsafeChannelForm->moveTo(*(ui->failsafeChannelsLayout)); + addWidgetBinding("ManualControlSettings", "FailsafeChannel", failsafeChannelForm->ui->channelValue, index, 0.01, true, new QList(failsafeReloadGroup)); + ++index; + } + addWidget(ui->failsafeDefault); + addWidgetBinding("ManualControlSettings", "Deadband", ui->deadband, 0, 1); addWidgetBinding("ManualControlSettings", "DeadbandAssistedControl", ui->assistedControlDeadband, 0, 1); @@ -165,18 +189,17 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) : connect(ui->stackedWidget, SIGNAL(currentChanged(int)), this, SLOT(disableWizardButton(int))); connect(ui->runCalibration, SIGNAL(toggled(bool)), this, SLOT(simpleCalibration(bool))); - connect(wizardUi->wzNext, SIGNAL(clicked()), this, SLOT(wzNext())); - connect(wizardUi->wzCancel, SIGNAL(clicked()), this, SLOT(wzCancel())); - connect(wizardUi->wzBack, SIGNAL(clicked()), this, SLOT(wzBack())); + connect(ReceiverActivity::GetInstance(getObjectManager()), SIGNAL(objectUpdated(UAVObject *)), this, SLOT(updateReceiverActivityStatus())); + ui->receiverActivityStatus->setStyleSheet("QLabel { background-color: darkGreen; color: rgb(255, 255, 255); \ + border: 1px solid grey; border-radius: 5; margin:1px; font:bold;}"); ui->stackedWidget->setCurrentIndex(0); - addWidgetBinding("FlightModeSettings", "FlightModePosition", ui->fmsModePos1, 0, 1, true); - addWidgetBinding("FlightModeSettings", "FlightModePosition", ui->fmsModePos2, 1, 1, true); - addWidgetBinding("FlightModeSettings", "FlightModePosition", ui->fmsModePos3, 2, 1, true); - addWidgetBinding("FlightModeSettings", "FlightModePosition", ui->fmsModePos4, 3, 1, true); - addWidgetBinding("FlightModeSettings", "FlightModePosition", ui->fmsModePos5, 4, 1, true); - addWidgetBinding("FlightModeSettings", "FlightModePosition", ui->fmsModePos6, 5, 1, true); - addWidgetBinding("ManualControlSettings", "FlightModeNumber", ui->fmsPosNum); + QList widgets = QList() << ui->fmsModePos1 << ui->fmsModePos2 << ui->fmsModePos3 << + ui->fmsModePos4 << ui->fmsModePos5 << ui->fmsModePos6; + index = 0; + foreach(QWidget * widget, widgets) { + addWidgetBinding("FlightModeSettings", "FlightModePosition", widget, index++, 1, true); + } addWidgetBinding("FlightModeSettings", "Stabilization1Settings", ui->fmsSsPos1Roll, "Roll", 1, true); addWidgetBinding("FlightModeSettings", "Stabilization2Settings", ui->fmsSsPos2Roll, "Roll", 1, true); @@ -184,18 +207,21 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) : addWidgetBinding("FlightModeSettings", "Stabilization4Settings", ui->fmsSsPos4Roll, "Roll", 1, true); addWidgetBinding("FlightModeSettings", "Stabilization5Settings", ui->fmsSsPos5Roll, "Roll", 1, true); addWidgetBinding("FlightModeSettings", "Stabilization6Settings", ui->fmsSsPos6Roll, "Roll", 1, true); + addWidgetBinding("FlightModeSettings", "Stabilization1Settings", ui->fmsSsPos1Pitch, "Pitch", 1, true); addWidgetBinding("FlightModeSettings", "Stabilization2Settings", ui->fmsSsPos2Pitch, "Pitch", 1, true); addWidgetBinding("FlightModeSettings", "Stabilization3Settings", ui->fmsSsPos3Pitch, "Pitch", 1, true); addWidgetBinding("FlightModeSettings", "Stabilization4Settings", ui->fmsSsPos4Pitch, "Pitch", 1, true); addWidgetBinding("FlightModeSettings", "Stabilization5Settings", ui->fmsSsPos5Pitch, "Pitch", 1, true); addWidgetBinding("FlightModeSettings", "Stabilization6Settings", ui->fmsSsPos6Pitch, "Pitch", 1, true); + addWidgetBinding("FlightModeSettings", "Stabilization1Settings", ui->fmsSsPos1Yaw, "Yaw", 1, true); addWidgetBinding("FlightModeSettings", "Stabilization2Settings", ui->fmsSsPos2Yaw, "Yaw", 1, true); addWidgetBinding("FlightModeSettings", "Stabilization3Settings", ui->fmsSsPos3Yaw, "Yaw", 1, true); addWidgetBinding("FlightModeSettings", "Stabilization4Settings", ui->fmsSsPos4Yaw, "Yaw", 1, true); addWidgetBinding("FlightModeSettings", "Stabilization5Settings", ui->fmsSsPos5Yaw, "Yaw", 1, true); addWidgetBinding("FlightModeSettings", "Stabilization6Settings", ui->fmsSsPos6Yaw, "Yaw", 1, true); + addWidgetBinding("FlightModeSettings", "Stabilization1Settings", ui->fmsSsPos1Thrust, "Thrust", 1, true); addWidgetBinding("FlightModeSettings", "Stabilization2Settings", ui->fmsSsPos2Thrust, "Thrust", 1, true); addWidgetBinding("FlightModeSettings", "Stabilization3Settings", ui->fmsSsPos3Thrust, "Thrust", 1, true); @@ -203,20 +229,28 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) : addWidgetBinding("FlightModeSettings", "Stabilization5Settings", ui->fmsSsPos5Thrust, "Thrust", 1, true); addWidgetBinding("FlightModeSettings", "Stabilization6Settings", ui->fmsSsPos6Thrust, "Thrust", 1, true); + addWidgetBinding("ManualControlSettings", "FlightModeNumber", ui->fmsPosNum); + addWidgetBinding("FlightModeSettings", "Arming", ui->armControl); addWidgetBinding("FlightModeSettings", "ArmedTimeout", ui->armTimeout, 0, 1000); connect(ManualControlCommand::GetInstance(getObjectManager()), SIGNAL(objectUpdated(UAVObject *)), this, SLOT(moveFMSlider())); connect(ManualControlSettings::GetInstance(getObjectManager()), SIGNAL(objectUpdated(UAVObject *)), this, SLOT(updatePositionSlider())); + connect(SystemAlarms::GetInstance(getObjectManager()), SIGNAL(objectUpdated(UAVObject *)), this, SLOT(updateConfigAlarmStatus())); + + connect(ui->failsafeFlightMode, SIGNAL(currentIndexChanged(int)), this, SLOT(failsafeFlightModeChanged(int))); + connect(ui->failsafeFlightModeCb, SIGNAL(toggled(bool)), this, SLOT(failsafeFlightModeCbToggled(bool))); addWidget(ui->configurationWizard); addWidget(ui->runCalibration); + addWidget(ui->failsafeFlightModeCb); - autoLoadWidgets(); + // Wizard + wizardUi = new Ui_InputWizardWidget(); + wizardUi->setupUi(ui->wizard); - populateWidgets(); - refreshWidgetsValues(); - // Connect the help button - connect(ui->inputHelp, SIGNAL(clicked()), this, SLOT(openHelp())); + connect(wizardUi->wzNext, SIGNAL(clicked()), this, SLOT(wzNext())); + connect(wizardUi->wzCancel, SIGNAL(clicked()), this, SLOT(wzCancel())); + connect(wizardUi->wzBack, SIGNAL(clicked()), this, SLOT(wzBack())); wizardUi->graphicsView->setScene(new QGraphicsScene(this)); wizardUi->graphicsView->setViewportUpdateMode(QGraphicsView::FullViewportUpdate); @@ -276,6 +310,16 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) : m_txFlightMode->setElementId("flightModeCenter"); m_txFlightMode->setZValue(-10); + m_txFlightModeCountBG = new QGraphicsSvgItem(); + m_txFlightModeCountBG->setParentItem(m_txBackground); + m_txFlightModeCountBG->setSharedRenderer(m_renderer); + m_txFlightModeCountBG->setElementId("fm_count_bg"); + l_scene->addItem(m_txFlightModeCountBG); + + m_txFlightModeCountText = new QGraphicsSimpleTextItem("?", m_txFlightModeCountBG); + m_txFlightModeCountText->setBrush(QColor(40, 40, 40)); + m_txFlightModeCountText->setFont(QFont("Arial Bold")); + m_txArrows = new QGraphicsSvgItem(); m_txArrows->setParentItem(m_txBackground); m_txArrows->setSharedRenderer(m_renderer); @@ -315,6 +359,20 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) : orig = Matrix.mapRect(orig); m_txFlightModeROrig.translate(orig.x(), orig.y()); + orig = m_renderer->boundsOnElement("fm_count_bg"); + Matrix = m_renderer->matrixForElement("fm_count_bg"); + orig = Matrix.mapRect(orig); + m_txFlightModeCountBGOrig.translate(orig.x(), orig.y()); + m_txFlightModeCountBG->setTransform(m_txFlightModeCountBGOrig, false); + + QRectF flightModeBGRect = m_txFlightModeCountBG->boundingRect(); + QRectF flightModeTextRect = m_txFlightModeCountText->boundingRect(); + qreal scale = 2.5; + m_txFlightModeCountTextOrig.translate(flightModeBGRect.width() - (flightModeBGRect.height() / 2), flightModeBGRect.height() / 2); + m_txFlightModeCountTextOrig.scale(scale, scale); + m_txFlightModeCountTextOrig.translate(-flightModeTextRect.width() / 2, -flightModeTextRect.height() / 2); + m_txFlightModeCountText->setTransform(m_txFlightModeCountTextOrig, false); + orig = m_renderer->boundsOnElement("rjoy"); Matrix = m_renderer->matrixForElement("rjoy"); orig = Matrix.mapRect(orig); @@ -373,8 +431,17 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) : groundChannelOrder << ManualControlSettings::CHANNELGROUPS_THROTTLE << ManualControlSettings::CHANNELGROUPS_YAW << ManualControlSettings::CHANNELGROUPS_ACCESSORY0; +} - updateEnableControls(); +void ConfigInputWidget::buildOptionComboBox(QComboBox *combo, UAVObjectField *field, int index, bool applyLimits) +{ + if (combo == ui->failsafeFlightMode) { + for (quint32 i = 0; i < FlightModeSettings::FLIGHTMODEPOSITION_NUMELEM; i++) { + ui->failsafeFlightMode->addItem(QString("Position %1").arg(i + 1), QVariant(i)); + } + } else { + ConfigTaskWidget::buildOptionComboBox(combo, field, index, applyLimits); + } } void ConfigInputWidget::resetTxControls() @@ -388,6 +455,9 @@ void ConfigInputWidget::resetTxControls() m_txFlightMode->setElementId("flightModeCenter"); m_txFlightMode->setTransform(m_txFlightModeCOrig, false); m_txArrows->setVisible(false); + m_txFlightModeCountText->setText("?"); + m_txFlightModeCountText->setVisible(false); + m_txFlightModeCountBG->setVisible(false); } ConfigInputWidget::~ConfigInputWidget() @@ -399,6 +469,9 @@ void ConfigInputWidget::enableControls(bool enable) if (enable) { updatePositionSlider(); + } else { + // Hide configAlarmStatus when disconnected + ui->configAlarmStatus->setVisible(false); } } @@ -409,12 +482,6 @@ void ConfigInputWidget::resizeEvent(QResizeEvent *event) wizardUi->graphicsView->fitInView(m_txBackground, Qt::KeepAspectRatio); } -void ConfigInputWidget::openHelp() -{ - QDesktopServices::openUrl(QUrl(QString(WIKI_URL_ROOT) + QString("Input+Configuration"), - QUrl::StrictMode)); -} - void ConfigInputWidget::goToWizard() { QMessageBox msgBox; @@ -562,6 +629,7 @@ void ConfigInputWidget::wzNext() } break; case wizardIdentifyCenter: + resetFlightModeSettings(); wizardSetUpStep(wizardIdentifyLimits); break; case wizardIdentifyLimits: @@ -592,7 +660,7 @@ void ConfigInputWidget::wzNext() manualSettingsObj->setData(manualSettingsData); // move to Arming Settings tab ui->stackedWidget->setCurrentIndex(0); - ui->tabWidget->setCurrentIndex(2); + ui->tabWidget->setCurrentIndex(3); break; default: Q_ASSERT(0); @@ -608,7 +676,7 @@ void ConfigInputWidget::wzBack() wizardTearDownStep(wizardStep); } - // State transitions for next button + // State transitions for back button switch (wizardStep) { case wizardChooseType: wizardSetUpStep(wizardWelcome); @@ -630,6 +698,7 @@ void ConfigInputWidget::wzBack() wizardSetUpStep(wizardIdentifyCenter); break; case wizardIdentifyInverted: + resetFlightModeSettings(); wizardSetUpStep(wizardIdentifyLimits); break; case wizardFinish: @@ -746,6 +815,10 @@ void ConfigInputWidget::wizardSetUpStep(enum wizardSteps step) manualSettingsData.ChannelMax[i] = manualSettingsData.ChannelNeutral[i]; } } + UAVObjectUpdaterHelper updateHelper; + manualSettingsObj->setData(manualSettingsData, false); + updateHelper.doObjectAndWait(manualSettingsObj); + connect(manualCommandObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(identifyLimits())); connect(manualCommandObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(moveSticks())); connect(flightStatusObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(moveSticks())); @@ -788,6 +861,8 @@ void ConfigInputWidget::wizardSetUpStep(enum wizardSteps step) void ConfigInputWidget::wizardTearDownStep(enum wizardSteps step) { + UAVObjectUpdaterHelper updateHelper; + Q_ASSERT(step == wizardStep); switch (step) { case wizardWelcome: @@ -835,9 +910,15 @@ void ConfigInputWidget::wizardTearDownStep(enum wizardSteps step) manualCommandData = manualCommandObj->getData(); manualSettingsData = manualSettingsObj->getData(); for (unsigned int i = 0; i < ManualControlCommand::CHANNEL_NUMELEM; ++i) { - manualSettingsData.ChannelNeutral[i] = manualCommandData.Channel[i]; + // Set Accessory neutral to middle range + if (i >= ManualControlSettings::CHANNELNUMBER_ACCESSORY0) { + manualSettingsData.ChannelNeutral[i] = manualSettingsData.ChannelMin[i] + ((manualSettingsData.ChannelMax[i] - manualSettingsData.ChannelMin[i]) / 2); + } else { + manualSettingsData.ChannelNeutral[i] = manualCommandData.Channel[i]; + } } - manualSettingsObj->setData(manualSettingsData); + manualSettingsObj->setData(manualSettingsData, false); + updateHelper.doObjectAndWait(manualSettingsObj); setTxMovement(nothing); break; case wizardIdentifyLimits: @@ -845,7 +926,8 @@ void ConfigInputWidget::wizardTearDownStep(enum wizardSteps step) disconnect(manualCommandObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(moveSticks())); disconnect(flightStatusObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(moveSticks())); disconnect(accessoryDesiredObj0, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(moveSticks())); - manualSettingsObj->setData(manualSettingsData); + manualSettingsObj->setData(manualSettingsData, false); + updateHelper.doObjectAndWait(manualSettingsObj); setTxMovement(nothing); break; case wizardIdentifyInverted: @@ -1080,27 +1162,77 @@ void ConfigInputWidget::identifyControls() void ConfigInputWidget::identifyLimits() { + uint16_t inputValue; + bool newLimitValue = false; + bool newFlightModeValue = false; + manualCommandData = manualCommandObj->getData(); for (uint i = 0; i < ManualControlSettings::CHANNELMAX_NUMELEM; ++i) { - if (manualSettingsData.ChannelMin[i] <= manualSettingsData.ChannelMax[i]) { - // Non inverted channel - if (manualSettingsData.ChannelMin[i] > manualCommandData.Channel[i]) { - manualSettingsData.ChannelMin[i] = manualCommandData.Channel[i]; + inputValue = manualCommandData.Channel[i]; + // Check if channel is already detected and prevent glitches + if ((manualSettingsData.ChannelNumber[i] != CHANNEL_NUMBER_NONE) && + (inputValue > MIN_INPUT_US) && (inputValue < MAX_INPUT_US)) { + if (manualSettingsData.ChannelMin[i] <= manualSettingsData.ChannelMax[i]) { + // Non inverted channel + if (manualSettingsData.ChannelMin[i] > inputValue) { + manualSettingsData.ChannelMin[i] = inputValue; + newLimitValue = true; + } + if (manualSettingsData.ChannelMax[i] < inputValue) { + manualSettingsData.ChannelMax[i] = inputValue; + newLimitValue = true; + } + } else { + // Inverted channel + if (manualSettingsData.ChannelMax[i] > inputValue) { + manualSettingsData.ChannelMax[i] = inputValue; + newLimitValue = true; + } + if (manualSettingsData.ChannelMin[i] < inputValue) { + manualSettingsData.ChannelMin[i] = inputValue; + newLimitValue = true; + } } - if (manualSettingsData.ChannelMax[i] < manualCommandData.Channel[i]) { - manualSettingsData.ChannelMax[i] = manualCommandData.Channel[i]; - } - } else { - // Inverted channel - if (manualSettingsData.ChannelMax[i] > manualCommandData.Channel[i]) { - manualSettingsData.ChannelMax[i] = manualCommandData.Channel[i]; - } - if (manualSettingsData.ChannelMin[i] < manualCommandData.Channel[i]) { - manualSettingsData.ChannelMin[i] = manualCommandData.Channel[i]; + // Flightmode channel + if (i == ManualControlSettings::CHANNELGROUPS_FLIGHTMODE) { + // Avoid duplicate values too close and error due to RcTx drift + int minSpacing = 100; // 100µs + for (int pos = 0; pos < manualSettingsData.FlightModeNumber + 1; ++pos) { + if (flightModeSignalValue[pos] == 0) { + newFlightModeValue = true; + // A new flightmode value can be set now + for (int checkpos = 0; checkpos < manualSettingsData.FlightModeNumber + 1; ++checkpos) { + // Check if value is already used, MinSpacing needed between values. + if ((flightModeSignalValue[checkpos] < inputValue + minSpacing) && + (flightModeSignalValue[checkpos] > inputValue - minSpacing)) { + newFlightModeValue = false; + } + } + // Be sure FlightModeNumber is < FlightModeSettings::FLIGHTMODEPOSITION_NUMELEM (6) + if ((manualSettingsData.FlightModeNumber < FlightModeSettings::FLIGHTMODEPOSITION_NUMELEM) && newFlightModeValue) { + // Start from 0, erase previous count + if (pos == 0) { + manualSettingsData.FlightModeNumber = 0; + } + // Store new value and increase FlightModeNumber + flightModeSignalValue[pos] = inputValue; + manualSettingsData.FlightModeNumber++; + // Show flight mode number + m_txFlightModeCountText->setText(QString().number(manualSettingsData.FlightModeNumber)); + m_txFlightModeCountText->setVisible(true); + m_txFlightModeCountBG->setVisible(true); + } + } + } } } } - manualSettingsObj->setData(manualSettingsData); + // Save only if something changed + if (newLimitValue || newFlightModeValue) { + UAVObjectUpdaterHelper updateHelper; + manualSettingsObj->setData(manualSettingsData, false); + updateHelper.doObjectAndWait(manualSettingsObj); + } } void ConfigInputWidget::setMoveFromCommand(int command) @@ -1488,13 +1620,16 @@ void ConfigInputWidget::moveSticks() Q_ASSERT(0); break; } - if (flightStatusData.FlightMode == flightModeSettingsData.FlightModePosition[0]) { + if ((flightStatusData.FlightMode == flightModeSettingsData.FlightModePosition[0]) || + (flightStatusData.FlightMode == flightModeSettingsData.FlightModePosition[5])) { m_txFlightMode->setElementId("flightModeLeft"); m_txFlightMode->setTransform(m_txFlightModeLOrig, false); - } else if (flightStatusData.FlightMode == flightModeSettingsData.FlightModePosition[1]) { + } else if ((flightStatusData.FlightMode == flightModeSettingsData.FlightModePosition[1]) || + (flightStatusData.FlightMode == flightModeSettingsData.FlightModePosition[4])) { m_txFlightMode->setElementId("flightModeCenter"); m_txFlightMode->setTransform(m_txFlightModeCOrig, false); - } else if (flightStatusData.FlightMode == flightModeSettingsData.FlightModePosition[2]) { + } else if ((flightStatusData.FlightMode == flightModeSettingsData.FlightModePosition[2]) || + (flightStatusData.FlightMode == flightModeSettingsData.FlightModePosition[3])) { m_txFlightMode->setElementId("flightModeRight"); m_txFlightMode->setTransform(m_txFlightModeROrig, false); } @@ -1538,7 +1673,9 @@ void ConfigInputWidget::invertControls() } } } - manualSettingsObj->setData(manualSettingsData); + UAVObjectUpdaterHelper updateHelper; + manualSettingsObj->setData(manualSettingsData, false); + updateHelper.doObjectAndWait(manualSettingsObj); } void ConfigInputWidget::moveFMSlider() @@ -1581,6 +1718,51 @@ void ConfigInputWidget::moveFMSlider() pos = manualSettingsDataPriv.FlightModeNumber - 1; } ui->fmsSlider->setValue(pos); + highlightStabilizationMode(pos); +} + +void ConfigInputWidget::highlightStabilizationMode(int pos) +{ + QComboBox *comboboxFm = this->findChild("fmsModePos" + QString::number(pos + 1)); + QString customStyleSheet = "QComboBox:editable:!on{background: #feb103;}"; + + if (comboboxFm) { + QString flightModeText = comboboxFm->currentText(); + comboboxFm->setStyleSheet(""); + for (uint8_t i = 0; i < FlightModeSettings::FLIGHTMODEPOSITION_NUMELEM; i++) { + QLabel *label = this->findChild("stab" + QString::number(i + 1) + "_label"); + QComboBox *comboRoll = this->findChild("fmsSsPos" + QString::number(i + 1) + "Roll"); + QComboBox *comboPitch = this->findChild("fmsSsPos" + QString::number(i + 1) + "Pitch"); + QComboBox *comboYaw = this->findChild("fmsSsPos" + QString::number(i + 1) + "Yaw"); + QComboBox *comboThrust = this->findChild("fmsSsPos" + QString::number(i + 1) + "Thrust"); + QComboBox *comboboxFm2 = this->findChild("fmsModePos" + QString::number(i + 1)); + comboboxFm2->setStyleSheet(""); + + // Highlight current stabilization mode if any. + if ((flightModeText.contains("Stabilized", Qt::CaseInsensitive)) && (flightModeText.contains(QString::number(i + 1), Qt::CaseInsensitive))) { + label->setStyleSheet("border-radius: 4px; border:3px solid #feb103;"); + comboRoll->setStyleSheet(customStyleSheet); + comboPitch->setStyleSheet(customStyleSheet); + comboYaw->setStyleSheet(customStyleSheet); + comboThrust->setStyleSheet(customStyleSheet); + } else { + label->setStyleSheet(""); + comboRoll->setStyleSheet(""); + comboPitch->setStyleSheet(""); + comboYaw->setStyleSheet(""); + comboThrust->setStyleSheet(""); + if (!flightModeText.contains("Stabilized", Qt::CaseInsensitive)) { + // Highlight PosHold, Return to Base, ... flightmodes + comboboxFm->setStyleSheet(customStyleSheet); + } + } + } + } +} + +void setComboBoxItemEnabled(QComboBox *combo, int index, bool enabled = true) +{ + combo->setItemData(index, enabled ? QVariant(1 | 32) : QVariant(0), Qt::UserRole - 1); } void ConfigInputWidget::updatePositionSlider() @@ -1593,31 +1775,37 @@ void ConfigInputWidget::updatePositionSlider() ui->fmsModePos6->setEnabled(true); ui->pidBankSs1_5->setEnabled(true); ui->assistControlPos6->setEnabled(true); + setComboBoxItemEnabled(ui->failsafeFlightMode, 5); // pass through case 5: ui->fmsModePos5->setEnabled(true); ui->pidBankSs1_4->setEnabled(true); ui->assistControlPos5->setEnabled(true); + setComboBoxItemEnabled(ui->failsafeFlightMode, 4); // pass through case 4: ui->fmsModePos4->setEnabled(true); ui->pidBankSs1_3->setEnabled(true); ui->assistControlPos4->setEnabled(true); + setComboBoxItemEnabled(ui->failsafeFlightMode, 3); // pass through case 3: ui->fmsModePos3->setEnabled(true); ui->pidBankSs1_2->setEnabled(true); ui->assistControlPos3->setEnabled(true); + setComboBoxItemEnabled(ui->failsafeFlightMode, 2); // pass through case 2: ui->fmsModePos2->setEnabled(true); ui->pidBankSs1_1->setEnabled(true); ui->assistControlPos2->setEnabled(true); + setComboBoxItemEnabled(ui->failsafeFlightMode, 1); // pass through case 1: ui->fmsModePos1->setEnabled(true); ui->pidBankSs1_0->setEnabled(true); ui->assistControlPos1->setEnabled(true); + setComboBoxItemEnabled(ui->failsafeFlightMode, 0); // pass through case 0: break; @@ -1628,31 +1816,37 @@ void ConfigInputWidget::updatePositionSlider() ui->fmsModePos1->setEnabled(false); ui->pidBankSs1_0->setEnabled(false); ui->assistControlPos1->setEnabled(false); + setComboBoxItemEnabled(ui->failsafeFlightMode, 0, false); // pass through case 1: ui->fmsModePos2->setEnabled(false); ui->pidBankSs1_1->setEnabled(false); ui->assistControlPos2->setEnabled(false); + setComboBoxItemEnabled(ui->failsafeFlightMode, 1, false); // pass through case 2: ui->fmsModePos3->setEnabled(false); ui->pidBankSs1_2->setEnabled(false); ui->assistControlPos3->setEnabled(false); + setComboBoxItemEnabled(ui->failsafeFlightMode, 2, false); // pass through case 3: ui->fmsModePos4->setEnabled(false); ui->pidBankSs1_3->setEnabled(false); ui->assistControlPos4->setEnabled(false); + setComboBoxItemEnabled(ui->failsafeFlightMode, 3, false); // pass through case 4: ui->fmsModePos5->setEnabled(false); ui->pidBankSs1_4->setEnabled(false); ui->assistControlPos5->setEnabled(false); + setComboBoxItemEnabled(ui->failsafeFlightMode, 4, false); // pass through case 5: ui->fmsModePos6->setEnabled(false); ui->pidBankSs1_5->setEnabled(false); ui->assistControlPos6->setEnabled(false); + setComboBoxItemEnabled(ui->failsafeFlightMode, 5, false); // pass through case 6: default: @@ -1666,12 +1860,15 @@ void ConfigInputWidget::updatePositionSlider() if (sp->objectName() == "channelNeutral") { if (count == 4) { sp->setStyleSheet( - "QSlider::groove:horizontal {border: 2px solid rgb(196, 196, 196); height: 12px; border-radius: 4px; " + "QSlider::groove:horizontal {border: 2px solid rgb(196, 196, 196); margin: 0px 23px 0px 23px; height: 12px; border-radius: 5px; " "border-image:url(:/configgadget/images/flightmode_bg" + fmNumber + ".png); }" "QSlider::add-page:horizontal { background: none; border: none; }" "QSlider::sub-page:horizontal { background: none; border: none; }" - "QSlider::handle:horizontal { background: rgba(196, 196, 196, 255); width: 10px; height: 28px; " - "margin: -3px -2px; border-radius: 3px; border: 1px solid #777; }"); + "QSlider::handle:horizontal { background: qlineargradient(x1:0, y1:0, x2:1, y2:0, " + "stop: 0 rgba(196, 196, 196, 180), stop: 0.45 rgba(196, 196, 196, 180), " + "stop: 0.46 rgba(255,0,0,100), stop: 0.54 rgba(255,0,0,100), " + "stop: 0.55 rgba(196, 196, 196, 180), stop: 1 rgba(196, 196, 196, 180)); " + "width: 46px; height: 28px; margin: -6px -23px -6px -23px; border-radius: 5px; border: 1px solid #777; }"); count++; } else { count++; @@ -1680,6 +1877,32 @@ void ConfigInputWidget::updatePositionSlider() } } +void ConfigInputWidget::updateConfigAlarmStatus() +{ + SystemAlarms *systemAlarmsObj = SystemAlarms::GetInstance(getObjectManager()); + SystemAlarms::DataFields systemAlarms = systemAlarmsObj->getData(); + + QString message = tr("Config OK"); + QString tooltipMessage = tr("All fine, no config alarm!"); + QString bgColor = "green"; + + if (systemAlarms.Alarm[SystemAlarms::ALARM_SYSTEMCONFIGURATION] > SystemAlarms::ALARM_WARNING) { + switch (systemAlarms.ExtendedAlarmStatus[SystemAlarms::EXTENDEDALARMSTATUS_SYSTEMCONFIGURATION]) { + case SystemAlarms::EXTENDEDALARMSTATUS_FLIGHTMODE: + message = tr("Config error"); + tooltipMessage = tr("There is something wrong with your config,\nusually a Thrust mode or Assisted mode not supported.\n\n" + "Tip: Reduce the Flight Mode Count to find the culprit."); + bgColor = "red"; + } + } + ui->configAlarmStatus->setVisible(true); + ui->configAlarmStatus->setStyleSheet( + "QLabel { background-color: " + bgColor + ";" + "color: rgb(255, 255, 255); border-radius: 5; margin:1px; font:bold; }"); + ui->configAlarmStatus->setText(message); + ui->configAlarmStatus->setToolTip(tooltipMessage); +} + void ConfigInputWidget::updateCalibration() { manualCommandData = manualCommandObj->getData(); @@ -1695,11 +1918,17 @@ void ConfigInputWidget::updateCalibration() if ((i == ManualControlSettings::CHANNELNUMBER_FLIGHTMODE) || (i == ManualControlSettings::CHANNELNUMBER_THROTTLE)) { adjustSpecialNeutrals(); } else { - manualSettingsData.ChannelNeutral[i] = manualCommandData.Channel[i]; + // Set Accessory neutral to middle range + if (i >= ManualControlSettings::CHANNELNUMBER_ACCESSORY0) { + manualSettingsData.ChannelNeutral[i] = manualSettingsData.ChannelMin[i] + ((manualSettingsData.ChannelMax[i] - manualSettingsData.ChannelMin[i]) / 2); + } else { + manualSettingsData.ChannelNeutral[i] = manualCommandData.Channel[i]; + } } } - - manualSettingsObj->setData(manualSettingsData); + UAVObjectUpdaterHelper updateHelper; + manualSettingsObj->setData(manualSettingsData, false); + updateHelper.doObjectAndWait(manualSettingsObj); manualSettingsObj->updated(); } @@ -1707,8 +1936,8 @@ void ConfigInputWidget::simpleCalibration(bool enable) { if (enable) { ui->configurationWizard->setEnabled(false); - ui->saveRCInputToRAM->setEnabled(false); - ui->saveRCInputToSD->setEnabled(false); + ui->applyButton->setEnabled(false); + ui->saveButton->setEnabled(false); ui->runCalibration->setText(tr("Stop Manual Calibration")); throttleError = false; @@ -1771,7 +2000,12 @@ void ConfigInputWidget::simpleCalibration(bool enable) adjustSpecialNeutrals(); checkThrottleRange(); } else { - manualSettingsData.ChannelNeutral[i] = manualCommandData.Channel[i]; + // Set Accessory neutral to middle range + if (i >= ManualControlSettings::CHANNELNUMBER_ACCESSORY0) { + manualSettingsData.ChannelNeutral[i] = manualSettingsData.ChannelMin[i] + ((manualSettingsData.ChannelMax[i] - manualSettingsData.ChannelMin[i]) / 2); + } else { + manualSettingsData.ChannelNeutral[i] = manualCommandData.Channel[i]; + } } } manualSettingsObj->setData(manualSettingsData); @@ -1780,8 +2014,8 @@ void ConfigInputWidget::simpleCalibration(bool enable) actuatorSettingsObj->setData(memento.actuatorSettingsData); ui->configurationWizard->setEnabled(true); - ui->saveRCInputToRAM->setEnabled(true); - ui->saveRCInputToSD->setEnabled(true); + ui->applyButton->setEnabled(true); + ui->saveButton->setEnabled(true); ui->runCalibration->setText(tr("Start Manual Calibration")); disconnect(manualCommandObj, SIGNAL(objectUnpacked(UAVObject *)), this, SLOT(updateCalibration())); @@ -1838,8 +2072,22 @@ void ConfigInputWidget::resetChannelSettings() for (unsigned int channel = 0; channel < ManualControlSettings::CHANNELNUMBER_NUMELEM; channel++) { manualSettingsData.ChannelGroups[channel] = ManualControlSettings::CHANNELGROUPS_NONE; manualSettingsData.ChannelNumber[channel] = CHANNEL_NUMBER_NONE; - manualSettingsData.FlightModeNumber = DEFAULT_FLIGHT_MODE_NUMBER; - manualSettingsObj->setData(manualSettingsData); + UAVObjectUpdaterHelper updateHelper; + manualSettingsObj->setData(manualSettingsData, false); + updateHelper.doObjectAndWait(manualSettingsObj); + } + resetFlightModeSettings(); +} + +void ConfigInputWidget::resetFlightModeSettings() +{ + // Reset FlightMode settings + manualSettingsData.FlightModeNumber = DEFAULT_FLIGHT_MODE_NUMBER; + UAVObjectUpdaterHelper updateHelper; + manualSettingsObj->setData(manualSettingsData, false); + updateHelper.doObjectAndWait(manualSettingsObj); + for (uint8_t pos = 0; pos < FlightModeSettings::FLIGHTMODEPOSITION_NUMELEM; pos++) { + flightModeSignalValue[pos] = 0; } } @@ -1854,7 +2102,7 @@ void ConfigInputWidget::resetActuatorSettings() // Clear all output data : Min, max, neutral at same value // 1000 for motors and 1500 for all others (Reversable motor included) - for (unsigned int output = 0; output < 12; output++) { + for (unsigned int output = 0; output < ActuatorSettings::CHANNELMAX_NUMELEM; output++) { QString mixerNumType = QString("Mixer%1Type").arg(output + 1); UAVObjectField *field = mixer->getField(mixerNumType); Q_ASSERT(field); @@ -1871,7 +2119,9 @@ void ConfigInputWidget::resetActuatorSettings() actuatorSettingsData.ChannelMin[output] = 1500; actuatorSettingsData.ChannelNeutral[output] = 1500; } - actuatorSettingsObj->setData(actuatorSettingsData); + UAVObjectUpdaterHelper updateHelper; + actuatorSettingsObj->setData(actuatorSettingsData, false); + updateHelper.doObjectAndWait(actuatorSettingsObj); } } @@ -1881,3 +2131,45 @@ void ConfigInputWidget::forceOneFlightMode() manualSettingsData.FlightModeNumber = 1; manualSettingsObj->setData(manualSettingsData); } + +void ConfigInputWidget::updateReceiverActivityStatus() +{ + ReceiverActivity *receiverActivity = ReceiverActivity::GetInstance(getObjectManager()); + + Q_ASSERT(receiverActivity); + + UAVObjectField *activeGroup = receiverActivity->getField(QString("ActiveGroup")); + Q_ASSERT(activeGroup); + + UAVObjectField *activeChannel = receiverActivity->getField(QString("ActiveChannel")); + Q_ASSERT(activeChannel); + + QString activeGroupText = activeGroup->getValue().toString(); + QString activeChannelText = activeChannel->getValue().toString(); + + if (activeGroupText != "None") { + ui->receiverActivityStatus->setText(tr("%1 input - Channel %2").arg(activeGroupText).arg(activeChannelText)); + ui->receiverActivityStatus->setStyleSheet("QLabel { background-color: green; color: rgb(255, 255, 255); \ + border: 1px solid grey; border-radius: 5; margin:1px; font:bold;}"); + } else { + ui->receiverActivityStatus->setText(tr("No activity")); + ui->receiverActivityStatus->setStyleSheet("QLabel { background-color: darkGreen; color: rgb(255, 255, 255); \ + border: 1px solid grey; border-radius: 5; margin:1px; font:bold;}"); + } +} + +void ConfigInputWidget::failsafeFlightModeChanged(int index) +{ + ui->failsafeFlightMode->setEnabled(index != -1); + ui->failsafeFlightModeCb->setChecked(index != -1); +} + +void ConfigInputWidget::failsafeFlightModeCbToggled(bool checked) +{ + ui->failsafeFlightMode->setCurrentIndex(checked ? 0 : -1); +} + +void ConfigInputWidget::enableControlsChanged(bool enabled) +{ + ui->failsafeFlightMode->setEnabled(enabled && (ui->failsafeFlightMode->currentIndex() != -1)); +} diff --git a/ground/gcs/src/plugins/config/configinputwidget.h b/ground/gcs/src/plugins/config/configinputwidget.h index 097ebd96f..c55de2e1c 100644 --- a/ground/gcs/src/plugins/config/configinputwidget.h +++ b/ground/gcs/src/plugins/config/configinputwidget.h @@ -8,7 +8,7 @@ * @{ * @addtogroup ConfigPlugin Config Plugin * @{ - * @brief Servo input/output configuration panel for the config gadget + * @brief Servo input configuration panel for the config gadget *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify @@ -28,32 +28,32 @@ #ifndef CONFIGINPUTWIDGET_H #define CONFIGINPUTWIDGET_H -#include "ui_input.h" -#include "ui_input_wizard.h" -#include "../uavobjectwidgetutils/configtaskwidget.h" -#include "extensionsystem/pluginmanager.h" -#include "uavobjectmanager.h" +#include "uavobjectwidgetutils/configtaskwidget.h" + #include "uavobject.h" -#include -#include -#include "inputchannelform.h" -#include "ui_inputchannelform.h" -#include + #include "manualcontrolcommand.h" #include "manualcontrolsettings.h" #include "actuatorsettings.h" #include "mixersettings.h" #include "flightmodesettings.h" #include "receiveractivity.h" -#include -#include -#include #include "flightstatus.h" #include "accessorydesired.h" -#include #include "systemsettings.h" +#include +#include +#include +#include + class Ui_InputWidget; +class Ui_InputWizardWidget; + +class QEventLoop; +class QSvgRenderer; +class QGraphicsSvgItem; +class QGraphicsSimpleTextItem; class ConfigInputWidget : public ConfigTaskWidget { Q_OBJECT @@ -115,6 +115,8 @@ private: QList acroChannelOrder; QList groundChannelOrder; + uint16_t flightModeSignalValue[FlightModeSettings::FLIGHTMODEPOSITION_NUMELEM]; + UAVObject::Metadata manualControlMdata; ManualControlCommand *manualCommandObj; ManualControlCommand::DataFields manualCommandData; @@ -161,6 +163,8 @@ private: QGraphicsSvgItem *m_txAccess2; QGraphicsSvgItem *m_txAccess3; QGraphicsSvgItem *m_txFlightMode; + QGraphicsSvgItem *m_txFlightModeCountBG; + QGraphicsSimpleTextItem *m_txFlightModeCountText; QGraphicsSvgItem *m_txBackground; QGraphicsSvgItem *m_txArrows; QTransform m_txLeftStickOrig; @@ -172,6 +176,8 @@ private: QTransform m_txFlightModeCOrig; QTransform m_txFlightModeLOrig; QTransform m_txFlightModeROrig; + QTransform m_txFlightModeCountBGOrig; + QTransform m_txFlightModeCountTextOrig; QTransform m_txMainBodyOrig; QTransform m_txArrowsOrig; QTimer *animate; @@ -196,6 +202,8 @@ private: AccessoryDesired *getAccessoryDesiredInstance(int instance); float getAccessoryDesiredValue(int instance); + void highlightStabilizationMode(int pos); + private slots: void wzNext(); void wzNextDelayed(); @@ -203,7 +211,6 @@ private slots: void wzCancel(); void goToWizard(); void disableWizardButton(int); - void openHelp(); void identifyControls(); void identifyLimits(); void moveTxControls(); @@ -211,17 +218,25 @@ private slots: void dimOtherControls(bool value); void moveFMSlider(); void updatePositionSlider(); + void updateConfigAlarmStatus(); void invertControls(); void simpleCalibration(bool state); void adjustSpecialNeutrals(); void checkThrottleRange(); void updateCalibration(); void resetChannelSettings(); + void resetFlightModeSettings(); void resetActuatorSettings(); void forceOneFlightMode(); + void updateReceiverActivityStatus(); + + void failsafeFlightModeChanged(int index); + void failsafeFlightModeCbToggled(bool checked); + void enableControlsChanged(bool enabled); protected: void resizeEvent(QResizeEvent *event); + void buildOptionComboBox(QComboBox *combo, UAVObjectField *field, int index, bool applyLimits); }; #endif // ifndef CONFIGINPUTWIDGET_H diff --git a/ground/gcs/src/plugins/config/configoplinkwidget.cpp b/ground/gcs/src/plugins/config/configoplinkwidget.cpp index f1c7a3d10..611cb7a17 100644 --- a/ground/gcs/src/plugins/config/configoplinkwidget.cpp +++ b/ground/gcs/src/plugins/config/configoplinkwidget.cpp @@ -1,15 +1,15 @@ /** - ****************************************************************************** + **************************************************************************************** * - * @file configtxpidswidget.cpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @file configoplinkwidget.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2016. * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup ConfigPlugin Config Plugin * @{ - * @brief The Configuration Gadget used to configure the PipXtreme - *****************************************************************************/ + * @brief The Configuration Gadget used to configure the OPLink, Revo and Sparky2 modems + ***************************************************************************************/ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,10 +28,15 @@ #include "configoplinkwidget.h" -#include +#include "ui_oplink.h" + +#include + #include #include + #include +#include // Channel range and Frequency display static const int MAX_CHANNEL_NUM = 250; @@ -39,41 +44,45 @@ static const int MIN_CHANNEL_RANGE = 10; static const float FIRST_FREQUENCY = 430.000; static const float FREQUENCY_STEP = 0.040; -ConfigOPLinkWidget::ConfigOPLinkWidget(QWidget *parent) : ConfigTaskWidget(parent) +ConfigOPLinkWidget::ConfigOPLinkWidget(QWidget *parent) : ConfigTaskWidget(parent, false), statusUpdated(false) { m_oplink = new Ui_OPLinkWidget(); m_oplink->setupUi(this); - // Connect to the OPLinkStatus object updates - ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); - UAVObjectManager *objManager = pm->getObject(); - oplinkStatusObj = dynamic_cast(objManager->getObject("OPLinkStatus")); + // must be done before auto binding ! + setWikiURL("OPLink+Configuration"); + + addAutoBindings(); + + disableMouseWheelEvents(); + + connect(this, SIGNAL(connected()), this, SLOT(connected())); + + oplinkStatusObj = dynamic_cast(getObject("OPLinkStatus")); Q_ASSERT(oplinkStatusObj); - connect(oplinkStatusObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(updateStatus(UAVObject *))); - // Connect to the OPLinkSettings object updates - oplinkSettingsObj = dynamic_cast(objManager->getObject("OPLinkSettings")); + oplinkSettingsObj = dynamic_cast(getObject("OPLinkSettings")); Q_ASSERT(oplinkSettingsObj); - connect(oplinkSettingsObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(updateSettings(UAVObject *))); - Core::Internal::GeneralSettings *settings = pm->getObject(); - if (!settings->useExpertMode()) { - m_oplink->Apply->setVisible(false); - } - addApplySaveButtons(m_oplink->Apply, m_oplink->Save); + addWidget(m_oplink->FirmwareVersion); + addWidget(m_oplink->SerialNumber); + addWidget(m_oplink->MinFreq); + addWidget(m_oplink->MaxFreq); + addWidget(m_oplink->UnbindButton); + addWidget(m_oplink->PairSignalStrengthBar1); + addWidget(m_oplink->PairSignalStrengthLabel1); + addWidgetBinding("OPLinkSettings", "Protocol", m_oplink->Protocol); + addWidgetBinding("OPLinkSettings", "LinkType", m_oplink->LinkType); + addWidgetBinding("OPLinkSettings", "CoordID", m_oplink->CoordID); + addWidgetBinding("OPLinkSettings", "CustomDeviceID", m_oplink->CustomDeviceID); + addWidgetBinding("OPLinkSettings", "MinChannel", m_oplink->MinimumChannel); + addWidgetBinding("OPLinkSettings", "MaxChannel", m_oplink->MaximumChannel); + addWidgetBinding("OPLinkSettings", "MaxRFPower", m_oplink->MaxRFTxPower); + addWidgetBinding("OPLinkSettings", "ComSpeed", m_oplink->ComSpeed); addWidgetBinding("OPLinkSettings", "MainPort", m_oplink->MainPort); addWidgetBinding("OPLinkSettings", "FlexiPort", m_oplink->FlexiPort); addWidgetBinding("OPLinkSettings", "VCPPort", m_oplink->VCPPort); - addWidgetBinding("OPLinkSettings", "MaxRFPower", m_oplink->MaxRFTxPower); - addWidgetBinding("OPLinkSettings", "MinChannel", m_oplink->MinimumChannel); - addWidgetBinding("OPLinkSettings", "MaxChannel", m_oplink->MaximumChannel); - addWidgetBinding("OPLinkSettings", "CoordID", m_oplink->CoordID); - addWidgetBinding("OPLinkSettings", "Coordinator", m_oplink->Coordinator); - addWidgetBinding("OPLinkSettings", "OneWay", m_oplink->OneWayLink); - addWidgetBinding("OPLinkSettings", "PPMOnly", m_oplink->PPMOnly); - addWidgetBinding("OPLinkSettings", "PPM", m_oplink->PPM); - addWidgetBinding("OPLinkSettings", "ComSpeed", m_oplink->ComSpeed); addWidgetBinding("OPLinkStatus", "DeviceID", m_oplink->DeviceID); addWidgetBinding("OPLinkStatus", "RxGood", m_oplink->Good); @@ -93,243 +102,181 @@ ConfigOPLinkWidget::ConfigOPLinkWidget(QWidget *parent) : ConfigTaskWidget(paren addWidgetBinding("OPLinkStatus", "TXSeq", m_oplink->TXSeq); addWidgetBinding("OPLinkStatus", "RXRate", m_oplink->RXRate); addWidgetBinding("OPLinkStatus", "TXRate", m_oplink->TXRate); + addWidgetBinding("OPLinkStatus", "RXPacketRate", m_oplink->RXPacketRate); + addWidgetBinding("OPLinkStatus", "TXPacketRate", m_oplink->TXPacketRate); - // Connect the bind buttons - connect(m_oplink->Bind1, SIGNAL(clicked()), this, SLOT(bind())); - connect(m_oplink->Bind2, SIGNAL(clicked()), this, SLOT(bind())); - connect(m_oplink->Bind3, SIGNAL(clicked()), this, SLOT(bind())); - connect(m_oplink->Bind4, SIGNAL(clicked()), this, SLOT(bind())); + // initially hide port combo boxes + setPortsVisible(false); // Connect the selection changed signals. - connect(m_oplink->PPMOnly, SIGNAL(toggled(bool)), this, SLOT(ppmOnlyChanged())); + connect(m_oplink->Protocol, SIGNAL(currentIndexChanged(int)), this, SLOT(protocolChanged())); + connect(m_oplink->LinkType, SIGNAL(currentIndexChanged(int)), this, SLOT(linkTypeChanged())); connect(m_oplink->MinimumChannel, SIGNAL(valueChanged(int)), this, SLOT(minChannelChanged())); connect(m_oplink->MaximumChannel, SIGNAL(valueChanged(int)), this, SLOT(maxChannelChanged())); + connect(m_oplink->MainPort, SIGNAL(currentIndexChanged(int)), this, SLOT(mainPortChanged())); + connect(m_oplink->FlexiPort, SIGNAL(currentIndexChanged(int)), this, SLOT(flexiPortChanged())); + connect(m_oplink->VCPPort, SIGNAL(currentIndexChanged(int)), this, SLOT(vcpPortChanged())); + + // Connect the Unbind button + connect(m_oplink->UnbindButton, SIGNAL(released()), this, SLOT(unbind())); + + // all upper case hex + m_oplink->CustomDeviceID->setInputMask(">HHHHHHHH"); + m_oplink->CustomDeviceID->setPlaceholderText("AutoGen"); + + m_oplink->CoordID->setInputMask(">HHHHHHHH"); m_oplink->MinimumChannel->setKeyboardTracking(false); m_oplink->MaximumChannel->setKeyboardTracking(false); m_oplink->MaximumChannel->setMaximum(MAX_CHANNEL_NUM); m_oplink->MinimumChannel->setMaximum(MAX_CHANNEL_NUM - MIN_CHANNEL_RANGE); - - // Request and update of the setting object. - settingsUpdated = false; - setWikiURL("OPLink+Configuration"); - autoLoadWidgets(); - disableMouseWheelEvents(); - updateEnableControls(); } ConfigOPLinkWidget::~ConfigOPLinkWidget() {} -/*! - \brief Called by updates to @OPLinkStatus - */ -void ConfigOPLinkWidget::updateStatus(UAVObject *object) +void ConfigOPLinkWidget::connected() { + // qDebug() << "ConfigOPLinkWidget::connected()"; + statusUpdated = false; + // Request and update of the setting object if we haven't received it yet. - if (!settingsUpdated) { - oplinkSettingsObj->requestUpdate(); + // this is only really needed for OPLM + oplinkSettingsObj->requestUpdate(); + + updateSettings(); +} + +void ConfigOPLinkWidget::refreshWidgetsValuesImpl(UAVObject *obj) +{ + // qDebug() << "ConfigOPLinkWidget::refreshWidgetsValuesImpl()" << obj; + if (obj == oplinkStatusObj) { + updateStatus(); + } else if (obj == oplinkSettingsObj) { + updateSettings(); } +} + +void ConfigOPLinkWidget::updateStatus() +{ + // qDebug() << "ConfigOPLinkWidget::updateStatus"; // Update the link state - UAVObjectField *linkField = object->getField("LinkState"); + UAVObjectField *linkField = oplinkStatusObj->getField("LinkState"); + m_oplink->LinkState->setText(linkField->getValue().toString()); - bool linkConnected = (linkField->getValue() == linkField->getOptions().at(OPLinkStatus::LINKSTATE_CONNECTED)); - bool modemEnabled = linkConnected || (linkField->getValue() == linkField->getOptions().at(OPLinkStatus::LINKSTATE_DISCONNECTED)) || - (linkField->getValue() == linkField->getOptions().at(OPLinkStatus::LINKSTATE_ENABLED)); + bool linkConnected = (oplinkStatusObj->linkState() == OPLinkStatus_LinkState::Connected); - UAVObjectField *pairRssiField = object->getField("PairSignalStrengths"); - - bool bound; - bool ok; - quint32 boundPairId = m_oplink->CoordID->text().toUInt(&ok, 16); - - // Update the detected devices. - UAVObjectField *pairIdField = object->getField("PairIDs"); - quint32 pairid = pairIdField->getValue(0).toUInt(); - bound = (pairid == boundPairId); - m_oplink->PairID1->setText(QString::number(pairid, 16).toUpper()); - m_oplink->PairID1->setEnabled(false); - m_oplink->Bind1->setText(bound ? tr("Unbind") : tr("Bind")); - m_oplink->Bind1->setEnabled(pairid && modemEnabled); - m_oplink->PairSignalStrengthBar1->setValue(((bound && !linkConnected) || !modemEnabled) ? -127 : pairRssiField->getValue(0).toInt()); + m_oplink->PairSignalStrengthBar1->setValue(linkConnected ? m_oplink->RSSI->text().toInt() : -127); m_oplink->PairSignalStrengthLabel1->setText(QString("%1dB").arg(m_oplink->PairSignalStrengthBar1->value())); - pairid = pairIdField->getValue(1).toUInt(); - bound = (pairid == boundPairId); - m_oplink->PairID2->setText(QString::number(pairid, 16).toUpper()); - m_oplink->PairID2->setEnabled(false); - m_oplink->Bind2->setText(bound ? tr("Unbind") : tr("Bind")); - m_oplink->Bind2->setEnabled(pairid && modemEnabled); - m_oplink->PairSignalStrengthBar2->setValue(((bound && !linkConnected) || !modemEnabled) ? -127 : pairRssiField->getValue(1).toInt()); - m_oplink->PairSignalStrengthLabel2->setText(QString("%1dB").arg(m_oplink->PairSignalStrengthBar2->value())); + // Enable components based on the board type connected. + switch (oplinkStatusObj->boardType()) { + case 0x09: // Revolution, DiscoveryF4Bare, RevoNano, RevoProto + case 0x92: // Sparky2 + setPortsVisible(false); + break; + case 0x03: // OPLinkMini + setPortsVisible(true); + break; + default: + // This shouldn't happen. + break; + } - pairid = pairIdField->getValue(2).toUInt(); - bound = (pairid == boundPairId); - m_oplink->PairID3->setText(QString::number(pairid, 16).toUpper()); - m_oplink->PairID3->setEnabled(false); - m_oplink->Bind3->setText(bound ? tr("Unbind") : tr("Bind")); - m_oplink->Bind3->setEnabled(pairid && modemEnabled); - m_oplink->PairSignalStrengthBar3->setValue(((bound && !linkConnected) || !modemEnabled) ? -127 : pairRssiField->getValue(2).toInt()); - m_oplink->PairSignalStrengthLabel3->setText(QString("%1dB").arg(m_oplink->PairSignalStrengthBar3->value())); + if (!statusUpdated) { + statusUpdated = true; + // update static info + updateInfo(); + } +} - pairid = pairIdField->getValue(3).toUInt(); - bound = (pairid == boundPairId); - m_oplink->PairID4->setText(QString::number(pairid, 16).toUpper()); - m_oplink->PairID4->setEnabled(false); - m_oplink->Bind4->setText(bound ? tr("Unbind") : tr("Bind")); - m_oplink->Bind4->setEnabled(pairid && modemEnabled); - m_oplink->PairSignalStrengthBar4->setValue(((bound && !linkConnected) || !modemEnabled) ? -127 : pairRssiField->getValue(3).toInt()); - m_oplink->PairSignalStrengthLabel4->setText(QString("%1dB").arg(m_oplink->PairSignalStrengthBar4->value())); +void ConfigOPLinkWidget::setPortsVisible(bool visible) +{ + m_oplink->MainPort->setVisible(visible); + m_oplink->MainPortLabel->setVisible(visible); + m_oplink->FlexiPort->setVisible(visible); + m_oplink->FlexiPortLabel->setVisible(visible); + m_oplink->VCPPort->setVisible(visible); + m_oplink->VCPPortLabel->setVisible(visible); +} + +void ConfigOPLinkWidget::updateInfo() +{ + // qDebug() << "ConfigOPLinkWidget::updateInfo"; // Update the Description field - // TODO use UAVObjectUtilManager::descriptionToStructure() - UAVObjectField *descField = object->getField("Description"); - if (descField->getValue(0) != QChar(255)) { - /* - * This looks like a binary with a description at the end: - * 4 bytes: header: "OpFw". - * 4 bytes: GIT commit tag (short version of SHA1). - * 4 bytes: Unix timestamp of compile time. - * 2 bytes: target platform. Should follow same rule as BOARD_TYPE and BOARD_REVISION in board define files. - * 26 bytes: commit tag if it is there, otherwise branch name. '-dirty' may be added if needed. Zero-padded. - * 20 bytes: SHA1 sum of the firmware. - * 20 bytes: SHA1 sum of the uavo definitions. - * 20 bytes: free for now. - */ - char buf[OPLinkStatus::DESCRIPTION_NUMELEM]; - for (unsigned int i = 0; i < 26; ++i) { - buf[i] = descField->getValue(i + 14).toChar().toLatin1(); - } - buf[26] = '\0'; - QString descstr(buf); - quint32 gitDate = descField->getValue(11).toChar().toLatin1() & 0xFF; - for (int i = 1; i < 4; i++) { - gitDate = gitDate << 8; - gitDate += descField->getValue(11 - i).toChar().toLatin1() & 0xFF; - } - QString date = QDateTime::fromTime_t(gitDate).toUTC().toString("yyyy-MM-dd HH:mm"); - m_oplink->FirmwareVersion->setText(descstr + " " + date); + + // extract desc into byte array + OPLinkStatus::DataFields oplinkStatusData = oplinkStatusObj->getData(); + quint8 *desc = oplinkStatusData.Description; + QByteArray ba; + + for (unsigned int i = 0; i < OPLinkStatus::DESCRIPTION_NUMELEM; i++) { + ba.append(desc[i]); + } + + // parse byte array into device descriptor + deviceDescriptorStruct dds; + UAVObjectUtilManager::descriptionToStructure(ba, dds); + + // update UI + if (!dds.gitTag.isEmpty()) { + m_oplink->FirmwareVersion->setText(dds.gitTag + " " + dds.gitDate); } else { m_oplink->FirmwareVersion->setText(tr("Unknown")); } // Update the serial number field - UAVObjectField *serialField = object->getField("CPUSerial"); char buf[OPLinkStatus::CPUSERIAL_NUMELEM * 2 + 1]; for (unsigned int i = 0; i < OPLinkStatus::CPUSERIAL_NUMELEM; ++i) { - unsigned char val = serialField->getValue(i).toUInt() >> 4; + unsigned char val = oplinkStatusObj->cpuSerial(i) >> 4; buf[i * 2] = ((val < 10) ? '0' : '7') + val; - val = serialField->getValue(i).toUInt() & 0xf; + val = oplinkStatusObj->cpuSerial(i) & 0xf; buf[i * 2 + 1] = ((val < 10) ? '0' : '7') + val; } buf[OPLinkStatus::CPUSERIAL_NUMELEM * 2] = '\0'; m_oplink->SerialNumber->setText(buf); - - updateEnableControls(); } -/*! - \brief Called by updates to @OPLinkSettings - */ -void ConfigOPLinkWidget::updateSettings(UAVObject *object) +void ConfigOPLinkWidget::updateSettings() { - Q_UNUSED(object); + // qDebug() << "ConfigOPLinkWidget::updateSettings"; - if (!settingsUpdated) { - settingsUpdated = true; + bool is_enabled = !isComboboxOptionSelected(m_oplink->Protocol, OPLinkSettings::PROTOCOL_DISABLED); + bool is_coordinator = isComboboxOptionSelected(m_oplink->Protocol, OPLinkSettings::PROTOCOL_OPLINKCOORDINATOR); + bool is_receiver = isComboboxOptionSelected(m_oplink->Protocol, OPLinkSettings::PROTOCOL_OPLINKRECEIVER); + bool is_openlrs = isComboboxOptionSelected(m_oplink->Protocol, OPLinkSettings::PROTOCOL_OPENLRS); + bool is_ppm_only = isComboboxOptionSelected(m_oplink->LinkType, OPLinkSettings::LINKTYPE_CONTROL); + bool is_bound = (m_oplink->CoordID->text() != ""); - // Enable components based on the board type connected. - UAVObjectField *board_type_field = oplinkStatusObj->getField("BoardType"); - switch (board_type_field->getValue().toInt()) { - case 0x09: // Revolution - m_oplink->MainPort->setVisible(false); - m_oplink->MainPortLabel->setVisible(false); - m_oplink->FlexiPort->setVisible(false); - m_oplink->FlexiPortLabel->setVisible(false); - m_oplink->VCPPort->setVisible(false); - m_oplink->VCPPortLabel->setVisible(false); - m_oplink->FlexiIOPort->setVisible(false); - m_oplink->FlexiIOPortLabel->setVisible(false); - m_oplink->PPM->setVisible(true); - break; - case 0x03: // OPLinkMini - m_oplink->MainPort->setVisible(true); - m_oplink->MainPortLabel->setVisible(true); - m_oplink->FlexiPort->setVisible(true); - m_oplink->FlexiPortLabel->setVisible(true); - m_oplink->VCPPort->setVisible(true); - m_oplink->VCPPortLabel->setVisible(true); - m_oplink->FlexiIOPort->setVisible(false); - m_oplink->FlexiIOPortLabel->setVisible(false); - m_oplink->PPM->setVisible(false); - break; - case 0x0A: // OPLink? - m_oplink->MainPort->setVisible(true); - m_oplink->MainPortLabel->setVisible(true); - m_oplink->FlexiPort->setVisible(true); - m_oplink->FlexiPortLabel->setVisible(true); - m_oplink->VCPPort->setVisible(true); - m_oplink->VCPPortLabel->setVisible(true); - m_oplink->FlexiIOPort->setVisible(true); - m_oplink->FlexiIOPortLabel->setVisible(true); - m_oplink->PPM->setVisible(false); - break; - default: - // This shouldn't happen. - break; - } - updateEnableControls(); + m_oplink->ComSpeed->setEnabled(is_enabled && !is_ppm_only && !is_openlrs); + m_oplink->CoordID->setEnabled(is_enabled && is_receiver); + m_oplink->UnbindButton->setEnabled(is_enabled && is_bound && !is_coordinator); + m_oplink->CustomDeviceID->setEnabled(is_coordinator); + + m_oplink->MinimumChannel->setEnabled(is_receiver || is_coordinator); + m_oplink->MaximumChannel->setEnabled(is_receiver || is_coordinator); + + enableComboBoxOptionItem(m_oplink->VCPPort, OPLinkSettings::VCPPORT_SERIAL, (is_receiver || is_coordinator)); + + if (isComboboxOptionSelected(m_oplink->VCPPort, OPLinkSettings::VCPPORT_SERIAL) && !(is_receiver || is_coordinator)) { + setComboboxSelectedOption(m_oplink->VCPPort, OPLinkSettings::VCPPORT_DISABLED); } + + m_oplink->LinkType->setEnabled(is_enabled && !is_openlrs); + m_oplink->MaxRFTxPower->setEnabled(is_enabled && !is_openlrs); } -void ConfigOPLinkWidget::updateEnableControls() +void ConfigOPLinkWidget::protocolChanged() { - enableControls(true); - ppmOnlyChanged(); + updateSettings(); } -void ConfigOPLinkWidget::disconnected() +void ConfigOPLinkWidget::linkTypeChanged() { - if (settingsUpdated) { - settingsUpdated = false; - } -} - -void ConfigOPLinkWidget::bind() -{ - QPushButton *bindButton = qobject_cast(sender()); - - if (bindButton) { - QLineEdit *editField = NULL; - if (bindButton == m_oplink->Bind1) { - editField = m_oplink->PairID1; - } else if (bindButton == m_oplink->Bind2) { - editField = m_oplink->PairID2; - } else if (bindButton == m_oplink->Bind3) { - editField = m_oplink->PairID3; - } else if (bindButton == m_oplink->Bind4) { - editField = m_oplink->PairID4; - } - Q_ASSERT(editField); - bool ok; - quint32 pairid = editField->text().toUInt(&ok, 16); - if (ok) { - quint32 boundPairId = m_oplink->CoordID->text().toUInt(&ok, 16); - (pairid != boundPairId) ? m_oplink->CoordID->setText(QString::number(pairid, 16).toUpper()) : m_oplink->CoordID->setText("0"); - } - QMessageBox::information(this, tr("Information"), tr("To apply the changes when binding/unbinding the board must be rebooted or power cycled."), QMessageBox::Ok); - } -} - -void ConfigOPLinkWidget::ppmOnlyChanged() -{ - bool is_ppm_only = m_oplink->PPMOnly->isChecked(); - - m_oplink->PPM->setEnabled(!is_ppm_only); - m_oplink->OneWayLink->setEnabled(!is_ppm_only); - m_oplink->ComSpeed->setEnabled(!is_ppm_only); + updateSettings(); } void ConfigOPLinkWidget::minChannelChanged() @@ -376,7 +323,81 @@ void ConfigOPLinkWidget::channelChanged(bool isMax) m_oplink->MaxFreq->setText("(" + QString::number(maxFrequency, 'f', 3) + " MHz)"); } -/** - @} - @} - */ +void ConfigOPLinkWidget::mainPortChanged() +{ + switch (getComboboxSelectedOption(m_oplink->MainPort)) { + case OPLinkSettings::MAINPORT_TELEMETRY: + case OPLinkSettings::MAINPORT_SERIAL: + if (isComboboxOptionSelected(m_oplink->FlexiPort, OPLinkSettings::FLEXIPORT_TELEMETRY) + || isComboboxOptionSelected(m_oplink->FlexiPort, OPLinkSettings::FLEXIPORT_SERIAL)) { + setComboboxSelectedOption(m_oplink->FlexiPort, OPLinkSettings::FLEXIPORT_DISABLED); + } + break; + case OPLinkSettings::MAINPORT_COMBRIDGE: + if (isComboboxOptionSelected(m_oplink->FlexiPort, OPLinkSettings::FLEXIPORT_COMBRIDGE)) { + setComboboxSelectedOption(m_oplink->FlexiPort, OPLinkSettings::FLEXIPORT_DISABLED); + } + break; + case OPLinkSettings::MAINPORT_PPM: + if (isComboboxOptionSelected(m_oplink->FlexiPort, OPLinkSettings::FLEXIPORT_PPM)) { + setComboboxSelectedOption(m_oplink->FlexiPort, OPLinkSettings::FLEXIPORT_DISABLED); + } + break; + } +} + +void ConfigOPLinkWidget::flexiPortChanged() +{ + switch (getComboboxSelectedOption(m_oplink->FlexiPort)) { + case OPLinkSettings::FLEXIPORT_TELEMETRY: + case OPLinkSettings::FLEXIPORT_SERIAL: + if (isComboboxOptionSelected(m_oplink->MainPort, OPLinkSettings::MAINPORT_TELEMETRY) + || isComboboxOptionSelected(m_oplink->MainPort, OPLinkSettings::MAINPORT_SERIAL)) { + setComboboxSelectedOption(m_oplink->MainPort, OPLinkSettings::MAINPORT_DISABLED); + } + break; + case OPLinkSettings::FLEXIPORT_COMBRIDGE: + if (isComboboxOptionSelected(m_oplink->MainPort, OPLinkSettings::MAINPORT_COMBRIDGE)) { + setComboboxSelectedOption(m_oplink->MainPort, OPLinkSettings::MAINPORT_DISABLED); + } + break; + case OPLinkSettings::FLEXIPORT_PPM: + if (isComboboxOptionSelected(m_oplink->MainPort, OPLinkSettings::MAINPORT_PPM)) { + setComboboxSelectedOption(m_oplink->MainPort, OPLinkSettings::MAINPORT_DISABLED); + } + break; + } +} + +void ConfigOPLinkWidget::vcpPortChanged() +{ + bool vcpComBridgeEnabled = isComboboxOptionSelected(m_oplink->VCPPort, OPLinkSettings::VCPPORT_COMBRIDGE); + + enableComboBoxOptionItem(m_oplink->MainPort, OPLinkSettings::MAINPORT_COMBRIDGE, vcpComBridgeEnabled); + enableComboBoxOptionItem(m_oplink->FlexiPort, OPLinkSettings::FLEXIPORT_COMBRIDGE, vcpComBridgeEnabled); + + if (!vcpComBridgeEnabled) { + if (isComboboxOptionSelected(m_oplink->MainPort, OPLinkSettings::MAINPORT_COMBRIDGE)) { + setComboboxSelectedOption(m_oplink->MainPort, OPLinkSettings::MAINPORT_DISABLED); + } + if (isComboboxOptionSelected(m_oplink->FlexiPort, OPLinkSettings::FLEXIPORT_COMBRIDGE)) { + setComboboxSelectedOption(m_oplink->FlexiPort, OPLinkSettings::FLEXIPORT_DISABLED); + } + } +} + +void ConfigOPLinkWidget::unbind() +{ + // Clear the coordinator ID + oplinkSettingsObj->setCoordID(0); + m_oplink->CoordID->clear(); + + // Clear the OpenLRS settings + oplinkSettingsObj->setVersion((quint16)0); + oplinkSettingsObj->setSerialBaudrate(0); + oplinkSettingsObj->setRFFrequency(0); + oplinkSettingsObj->setRFPower((quint16)0); + oplinkSettingsObj->setRFChannelSpacing((quint16)0); + oplinkSettingsObj->setModemParams((quint16)0); + oplinkSettingsObj->setFlags((quint16)0); +} diff --git a/ground/gcs/src/plugins/config/configoplinkwidget.h b/ground/gcs/src/plugins/config/configoplinkwidget.h index bda71c46e..70043e257 100644 --- a/ground/gcs/src/plugins/config/configoplinkwidget.h +++ b/ground/gcs/src/plugins/config/configoplinkwidget.h @@ -1,13 +1,14 @@ /** ****************************************************************************** * - * @file configpipxtremewidget.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. + * @file configoplinkwidget.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup ConfigPlugin Config Plugin * @{ - * @brief The Configuration Gadget used to configure PipXtreme + * @brief The Configuration Gadget used to configure the OPLink, Revo and Sparky2 modems *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify @@ -24,14 +25,16 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef CONFIGPIPXTREMEWIDGET_H -#define CONFIGPIPXTREMEWIDGET_H +#ifndef CONFIGOPLINKWIDGET_H +#define CONFIGOPLINKWIDGET_H -#include - -#include "ui_oplink.h" #include "configtaskwidget.h" +class OPLinkStatus; +class OPLinkSettings; + +class Ui_OPLinkWidget; + class ConfigOPLinkWidget : public ConfigTaskWidget { Q_OBJECT @@ -39,32 +42,39 @@ public: ConfigOPLinkWidget(QWidget *parent = 0); ~ConfigOPLinkWidget(); -public slots: - void updateStatus(UAVObject *object1); - void updateSettings(UAVObject *object1); +protected: + virtual void refreshWidgetsValuesImpl(UAVObject *obj); private: Ui_OPLinkWidget *m_oplink; - // The OPLink status UAVObject - UAVDataObject *oplinkStatusObj; - - // The OPLink ssettins UAVObject + OPLinkStatus *oplinkStatusObj; OPLinkSettings *oplinkSettingsObj; - // Are the settings current? - bool settingsUpdated; + // Is the status current? + bool statusUpdated; -protected: - void updateEnableControls(); + void updateStatus(); + void updateInfo(); + void updateSettings(); + + void setPortsVisible(bool visible); private slots: - void disconnected(); - void bind(); - void ppmOnlyChanged(); + void connected(); + + void protocolChanged(); + void linkTypeChanged(); + void minChannelChanged(); void maxChannelChanged(); void channelChanged(bool isMax); + + void mainPortChanged(); + void flexiPortChanged(); + void vcpPortChanged(); + + void unbind(); }; -#endif // CONFIGTXPIDWIDGET_H +#endif // CONFIGOPLINKWIDGET_H diff --git a/ground/gcs/src/plugins/config/configoutputwidget.cpp b/ground/gcs/src/plugins/config/configoutputwidget.cpp index 7da880e85..0c7613f5b 100644 --- a/ground/gcs/src/plugins/config/configoutputwidget.cpp +++ b/ground/gcs/src/plugins/config/configoutputwidget.cpp @@ -27,50 +27,49 @@ */ #include "configoutputwidget.h" + +#include "ui_output.h" +#include "ui_outputchannelform.h" + #include "outputchannelform.h" #include "configvehicletypewidget.h" +#include "uavsettingsimportexport/uavsettingsimportexportfactory.h" +#include +#include + #include "mixersettings.h" #include "actuatorcommand.h" #include "actuatorsettings.h" +#include "flightmodesettings.h" +#include "flightstatus.h" #include "systemsettings.h" -#include "uavsettingsimportexport/uavsettingsimportexportfactory.h" -#include -#include #include #include #include #include -#include -#include #include -#include -#include ConfigOutputWidget::ConfigOutputWidget(QWidget *parent) : ConfigTaskWidget(parent) { m_ui = new Ui_OutputWidget(); m_ui->setupUi(this); + // must be done before auto binding ! + setWikiURL("Output+Configuration"); + + addAutoBindings(); + m_ui->gvFrame->setVisible(false); ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); - Core::Internal::GeneralSettings *settings = pm->getObject(); - if (!settings->useExpertMode()) { - m_ui->saveRCOutputToRAM->setVisible(false); - } - UAVSettingsImportExportFactory *importexportplugin = pm->getObject(); connect(importexportplugin, SIGNAL(importAboutToBegin()), this, SLOT(stopTests())); connect(m_ui->channelOutTest, SIGNAL(clicked(bool)), this, SLOT(runChannelTests(bool))); // Configure the task widget - // Connect the help button - connect(m_ui->outputHelp, SIGNAL(clicked()), this, SLOT(openHelp())); - - addApplySaveButtons(m_ui->saveRCOutputToRAM, m_ui->saveRCOutputToSD); // Track the ActuatorSettings object addUAVObject("ActuatorSettings"); @@ -84,16 +83,22 @@ ConfigOutputWidget::ConfigOutputWidget(QWidget *parent) : ConfigTaskWidget(paren connect(m_ui->channelOutTest, SIGNAL(toggled(bool)), form, SLOT(enableChannelTest(bool))); connect(form, SIGNAL(channelChanged(int, int)), this, SLOT(sendChannelTest(int, int))); - addWidget(form->ui.actuatorMin); - addWidget(form->ui.actuatorNeutral); - addWidget(form->ui.actuatorMax); - addWidget(form->ui.actuatorRev); - addWidget(form->ui.actuatorLink); + addWidget(form->ui->actuatorMin); + addWidget(form->ui->actuatorNeutral); + addWidget(form->ui->actuatorMax); + addWidget(form->ui->actuatorRev); + addWidget(form->ui->actuatorLink); } - // Associate the buttons with their UAVO fields addWidget(m_ui->spinningArmed); + connect(m_ui->spinningArmed, SIGNAL(clicked(bool)), this, SLOT(updateSpinStabilizeCheckComboBoxes())); + + addUAVObject("FlightModeSettings"); + addWidgetBinding("FlightModeSettings", "AlwaysStabilizeWhenArmedSwitch", m_ui->alwaysStabilizedSwitch); + + connect(FlightStatus::GetInstance(getObjectManager()), SIGNAL(objectUpdated(UAVObject *)), this, SLOT(updateAlwaysStabilizeStatus())); + MixerSettings *mixer = MixerSettings::GetInstance(getObjectManager()); Q_ASSERT(mixer); m_banks << OutputBankControls(mixer, m_ui->chBank1, QColor("#C6ECAE"), m_ui->cb_outputRate1, m_ui->cb_outputMode1); @@ -122,12 +127,8 @@ ConfigOutputWidget::ConfigOutputWidget(QWidget *parent) : ConfigTaskWidget(paren SystemAlarms *systemAlarmsObj = SystemAlarms::GetInstance(getObjectManager()); connect(systemAlarmsObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(updateWarnings(UAVObject *))); + // TODO why do we do that ? disconnect(this, SLOT(refreshWidgetsValues(UAVObject *))); - - populateWidgets(); - refreshWidgetsValues(); - - updateEnableControls(); } ConfigOutputWidget::~ConfigOutputWidget() @@ -299,11 +300,9 @@ void ConfigOutputWidget::setColor(QWidget *widget, const QColor color) /** Request the current config from the board (RC Output) */ -void ConfigOutputWidget::refreshWidgetsValues(UAVObject *obj) +void ConfigOutputWidget::refreshWidgetsValuesImpl(UAVObject *obj) { - bool dirty = isDirty(); - - ConfigTaskWidget::refreshWidgetsValues(obj); + Q_UNUSED(obj); // Get Actuator Settings ActuatorSettings *actuatorSettings = ActuatorSettings::GetInstance(getObjectManager()); @@ -367,6 +366,10 @@ void ConfigOutputWidget::refreshWidgetsValues(UAVObject *obj) // Revolution Nano bankLabels << "1 (1)" << "2 (2,7,11)" << "3 (3)" << "4 (4)" << "5 (5-6)" << "6 (8-10,12)"; channelBanks << 1 << 2 << 3 << 4 << 5 << 5 << 2 << 6 << 6 << 6 << 2 << 6; + } else if (board == 0x9201) { + // Sparky2 + 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; } } @@ -402,16 +405,14 @@ void ConfigOutputWidget::refreshWidgetsValues(UAVObject *obj) outputChannelForm->setNeutral(neutral); } - setDirty(dirty); + updateSpinStabilizeCheckComboBoxes(); } /** * Sends the config to the board, without saving to the SD card (RC Output) */ -void ConfigOutputWidget::updateObjectsFromWidgets() +void ConfigOutputWidget::updateObjectsFromWidgetsImpl() { - ConfigTaskWidget::updateObjectsFromWidgets(); - ActuatorSettings *actuatorSettings = ActuatorSettings::GetInstance(getObjectManager()); Q_ASSERT(actuatorSettings); @@ -439,14 +440,44 @@ void ConfigOutputWidget::updateObjectsFromWidgets() ActuatorSettings::MOTORSSPINWHILEARMED_FALSE; // Apply settings - actuatorSettings->setData(actuatorSettingsData); + UAVObjectUpdaterHelper updateHelper; + actuatorSettings->setData(actuatorSettingsData, false); + updateHelper.doObjectAndWait(actuatorSettings); + } + + FlightModeSettings *flightModeSettings = FlightModeSettings::GetInstance(getObjectManager()); + Q_ASSERT(flightModeSettings); + + if (flightModeSettings) { + FlightModeSettings::DataFields flightModeSettingsData = flightModeSettings->getData(); + flightModeSettingsData.AlwaysStabilizeWhenArmedSwitch = m_ui->alwaysStabilizedSwitch->currentIndex(); + + // Apply settings + flightModeSettings->setData(flightModeSettingsData); } } -void ConfigOutputWidget::openHelp() +void ConfigOutputWidget::updateSpinStabilizeCheckComboBoxes() { - QDesktopServices::openUrl(QUrl(QString(WIKI_URL_ROOT) + QString("Output+Configuration"), - QUrl::StrictMode)); + m_ui->alwayStabilizedLabel1->setEnabled(m_ui->spinningArmed->isChecked()); + m_ui->alwayStabilizedLabel2->setEnabled(m_ui->spinningArmed->isChecked()); + m_ui->alwaysStabilizedSwitch->setEnabled(m_ui->spinningArmed->isChecked()); + + if (!m_ui->spinningArmed->isChecked()) { + m_ui->alwaysStabilizedSwitch->setCurrentIndex(FlightModeSettings::ALWAYSSTABILIZEWHENARMEDSWITCH_DISABLED); + } +} + +void ConfigOutputWidget::updateAlwaysStabilizeStatus() +{ + FlightStatus *flightStatusObj = FlightStatus::GetInstance(getObjectManager()); + FlightStatus::DataFields flightStatus = flightStatusObj->getData(); + + if (flightStatus.AlwaysStabilizeWhenArmed == FlightStatus::ALWAYSSTABILIZEWHENARMED_TRUE) { + m_ui->alwayStabilizedLabel2->setText(tr("AlwaysStabilizeWhenArmed is ACTIVE. This prevents arming!.")); + } else { + m_ui->alwayStabilizedLabel2->setText(tr("(Really be careful!).")); + } } void ConfigOutputWidget::onBankTypeChange() diff --git a/ground/gcs/src/plugins/config/configoutputwidget.h b/ground/gcs/src/plugins/config/configoutputwidget.h index d64762833..bca11ddb0 100644 --- a/ground/gcs/src/plugins/config/configoutputwidget.h +++ b/ground/gcs/src/plugins/config/configoutputwidget.h @@ -27,23 +27,27 @@ #ifndef CONFIGOUTPUTWIDGET_H #define CONFIGOUTPUTWIDGET_H -#include "ui_output.h" +#include "cfg_vehicletypes/vehicleconfig.h" + #include "../uavobjectwidgetutils/configtaskwidget.h" #include "extensionsystem/pluginmanager.h" #include "uavobjectmanager.h" #include "uavobject.h" #include "uavobjectutilmanager.h" -#include "cfg_vehicletypes/vehicleconfig.h" -#include -#include -#include #include "systemalarms.h" +#include +#include + class Ui_OutputWidget; class OutputChannelForm; class MixerSettings; +class QLabel; +class QCheckBox; +class QWidget; + class OutputBankControls { public: OutputBankControls(MixerSettings *mixer, QLabel *label, QColor color, QComboBox *rateCombo, QComboBox *modeCombo); @@ -85,6 +89,9 @@ protected: void enableControls(bool enable); void setWarning(QString message); + virtual void refreshWidgetsValuesImpl(UAVObject *obj); + virtual void updateObjectsFromWidgetsImpl(); + private: Ui_OutputWidget *m_ui; QList m_sliders; @@ -100,12 +107,11 @@ private: private slots: void updateWarnings(UAVObject *); + void updateSpinStabilizeCheckComboBoxes(); + void updateAlwaysStabilizeStatus(); void stopTests(); - virtual void refreshWidgetsValues(UAVObject *obj = NULL); - void updateObjectsFromWidgets(); void runChannelTests(bool state); void sendChannelTest(int index, int value); - void openHelp(); void onBankTypeChange(); }; diff --git a/ground/gcs/src/plugins/config/configplugin.cpp b/ground/gcs/src/plugins/config/configplugin.cpp index 1768e1f60..0fca675e7 100644 --- a/ground/gcs/src/plugins/config/configplugin.cpp +++ b/ground/gcs/src/plugins/config/configplugin.cpp @@ -1,8 +1,9 @@ /** ****************************************************************************** * - * @file configplugin.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @file configplugin.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup ConfigPlugin Config Plugin @@ -25,12 +26,15 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "configplugin.h" + #include "configgadgetfactory.h" + +#include +#include + #include #include #include -#include -#include "objectpersistence.h" ConfigPlugin::ConfigPlugin() { @@ -46,7 +50,8 @@ bool ConfigPlugin::initialize(const QStringList & args, QString *errMsg) { Q_UNUSED(args); Q_UNUSED(errMsg); - cf = new ConfigGadgetFactory(this); + + ConfigGadgetFactory *cf = new ConfigGadgetFactory(this); addAutoReleasedObject(cf); return true; diff --git a/ground/gcs/src/plugins/config/configplugin.h b/ground/gcs/src/plugins/config/configplugin.h index 2f8ead7e2..84efd7c80 100644 --- a/ground/gcs/src/plugins/config/configplugin.h +++ b/ground/gcs/src/plugins/config/configplugin.h @@ -1,8 +1,9 @@ /** ****************************************************************************** * - * @file configgadgetplugin.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @file configplugin.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup ConfigPlugin Config Plugin @@ -28,14 +29,11 @@ #define CONFIGPLUGIN_H #include -#include -#include -#include -#include "objectpersistence.h" -#include +#include +#include -class ConfigGadgetFactory; +class UAVObjectManager; class ConfigPlugin : public ExtensionSystem::IPlugin { Q_OBJECT @@ -49,9 +47,6 @@ public: void extensionsInitialized(); bool initialize(const QStringList & arguments, QString *errorString); void shutdown(); - -private: - ConfigGadgetFactory *cf; }; #endif // CONFIGPLUGIN_H diff --git a/ground/gcs/src/plugins/config/configrevohwwidget.cpp b/ground/gcs/src/plugins/config/configrevohwwidget.cpp index d58bc659e..e5e3bc151 100644 --- a/ground/gcs/src/plugins/config/configrevohwwidget.cpp +++ b/ground/gcs/src/plugins/config/configrevohwwidget.cpp @@ -2,7 +2,7 @@ ****************************************************************************** * * @file configrevohwwidget.cpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ @@ -27,28 +27,23 @@ */ #include "configrevohwwidget.h" -#include -#include -#include +#include "ui_configrevohwwidget.h" + #include "hwsettings.h" -#include -#include -#include +#include -ConfigRevoHWWidget::ConfigRevoHWWidget(QWidget *parent) : ConfigTaskWidget(parent), m_refreshing(true) +ConfigRevoHWWidget::ConfigRevoHWWidget(QWidget *parent) : ConfigTaskWidget(parent) { m_ui = new Ui_RevoHWWidget(); m_ui->setupUi(this); - ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); - Core::Internal::GeneralSettings *settings = pm->getObject(); - if (!settings->useExpertMode()) { - m_ui->saveTelemetryToRAM->setEnabled(false); - m_ui->saveTelemetryToRAM->setVisible(false); - } + // must be done before auto binding ! + setWikiURL("Revolution+Configuration"); - addApplySaveButtons(m_ui->saveTelemetryToRAM, m_ui->saveTelemetryToSD); + addAutoBindings(); + + addUAVObject("HwSettings"); addWidgetBinding("HwSettings", "RM_FlexiPort", m_ui->cbFlexi); addWidgetBinding("HwSettings", "RM_MainPort", m_ui->cbMain); @@ -56,31 +51,22 @@ ConfigRevoHWWidget::ConfigRevoHWWidget(QWidget *parent) : ConfigTaskWidget(paren addWidgetBinding("HwSettings", "USB_HIDPort", m_ui->cbUSBHIDFunction); addWidgetBinding("HwSettings", "USB_VCPPort", m_ui->cbUSBVCPFunction); - addWidgetBinding("HwSettings", "ComUsbBridgeSpeed", m_ui->cbUSBVCPSpeed); addWidgetBinding("HwSettings", "TelemetrySpeed", m_ui->cbFlexiTelemSpeed); addWidgetBinding("HwSettings", "GPSSpeed", m_ui->cbFlexiGPSSpeed); - addWidgetBinding("HwSettings", "ComUsbBridgeSpeed", m_ui->cbFlexiComSpeed); addWidgetBinding("HwSettings", "TelemetrySpeed", m_ui->cbMainTelemSpeed); addWidgetBinding("HwSettings", "GPSSpeed", m_ui->cbMainGPSSpeed); - addWidgetBinding("HwSettings", "ComUsbBridgeSpeed", m_ui->cbMainComSpeed); addWidgetBinding("HwSettings", "TelemetrySpeed", m_ui->cbRcvrTelemSpeed); - addWidgetBinding("HwSettings", "ComUsbBridgeSpeed", m_ui->cbRcvrComSpeed); + addWidgetBinding("HwSettings", "GPSSpeed", m_ui->cbRcvrGPSSpeed); // Add Gps protocol configuration addWidgetBinding("GPSSettings", "DataProtocol", m_ui->cbMainGPSProtocol); addWidgetBinding("GPSSettings", "DataProtocol", m_ui->cbFlexiGPSProtocol); - - connect(m_ui->cchwHelp, SIGNAL(clicked()), this, SLOT(openHelp())); + addWidgetBinding("GPSSettings", "DataProtocol", m_ui->cbRcvrGPSProtocol); setupCustomCombos(); - enableControls(true); - populateWidgets(); - refreshWidgetsValues(); - forceConnectedState(); - m_refreshing = false; } ConfigRevoHWWidget::~ConfigRevoHWWidget() @@ -102,35 +88,29 @@ void ConfigRevoHWWidget::setupCustomCombos() connect(m_ui->cbRcvr, SIGNAL(currentIndexChanged(int)), this, SLOT(rcvrPortChanged(int))); } -void ConfigRevoHWWidget::refreshWidgetsValues(UAVObject *obj) +void ConfigRevoHWWidget::refreshWidgetsValuesImpl(UAVObject *obj) { - m_refreshing = true; - ConfigTaskWidget::refreshWidgetsValues(obj); + Q_UNUSED(obj); usbVCPPortChanged(0); mainPortChanged(0); flexiPortChanged(0); rcvrPortChanged(0); - m_refreshing = false; } -void ConfigRevoHWWidget::updateObjectsFromWidgets() +void ConfigRevoHWWidget::updateObjectsFromWidgetsImpl() { - ConfigTaskWidget::updateObjectsFromWidgets(); - - HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager()); - HwSettings::DataFields data = hwSettings->getData(); - // If any port is configured to be GPS port, enable GPS module if it is not enabled. // Otherwise disable GPS module. + quint8 enableModule = HwSettings::OPTIONALMODULES_DISABLED; + if (isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_GPS) || isComboboxOptionSelected(m_ui->cbMain, HwSettings::RM_MAINPORT_GPS)) { - data.OptionalModules[HwSettings::OPTIONALMODULES_GPS] = HwSettings::OPTIONALMODULES_ENABLED; - } else { - data.OptionalModules[HwSettings::OPTIONALMODULES_GPS] = HwSettings::OPTIONALMODULES_DISABLED; + enableModule = HwSettings::OPTIONALMODULES_ENABLED; } - hwSettings->setData(data); + HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager()); + hwSettings->setOptionalModules(HwSettings::OPTIONALMODULES_GPS, enableModule); } void ConfigRevoHWWidget::usbVCPPortChanged(int index) @@ -139,9 +119,6 @@ void ConfigRevoHWWidget::usbVCPPortChanged(int index) bool vcpComBridgeEnabled = isComboboxOptionSelected(m_ui->cbUSBVCPFunction, HwSettings::USB_VCPPORT_COMBRIDGE); - m_ui->lblUSBVCPSpeed->setVisible(vcpComBridgeEnabled); - m_ui->cbUSBVCPSpeed->setVisible(vcpComBridgeEnabled); - if (!vcpComBridgeEnabled && isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_COMBRIDGE)) { setComboboxSelectedOption(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_DISABLED); } @@ -155,7 +132,12 @@ void ConfigRevoHWWidget::usbVCPPortChanged(int index) if (!vcpComBridgeEnabled && isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_COMBRIDGE)) { setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_DISABLED); } + if (!vcpComBridgeEnabled && isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPMCOMBRIDGE)) { + setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPM); + } + enableComboBoxOptionItem(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_COMBRIDGE, vcpComBridgeEnabled); + enableComboBoxOptionItem(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPMCOMBRIDGE, vcpComBridgeEnabled); // _DEBUGCONSOLE modes are mutual exclusive if (isComboboxOptionSelected(m_ui->cbUSBVCPFunction, HwSettings::USB_VCPPORT_DEBUGCONSOLE)) { @@ -165,6 +147,12 @@ void ConfigRevoHWWidget::usbVCPPortChanged(int index) if (isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_DEBUGCONSOLE)) { setComboboxSelectedOption(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_DISABLED); } + if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_DEBUGCONSOLE)) { + setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_DISABLED); + } + if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPMDEBUGCONSOLE)) { + setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPM); + } } // _USBTELEMETRY modes are mutual exclusive @@ -191,7 +179,6 @@ void ConfigRevoHWWidget::flexiPortChanged(int index) m_ui->cbFlexiTelemSpeed->setVisible(false); m_ui->cbFlexiGPSSpeed->setVisible(false); - m_ui->cbFlexiComSpeed->setVisible(false); m_ui->lblFlexiSpeed->setVisible(true); // Add Gps protocol configuration @@ -204,8 +191,10 @@ void ConfigRevoHWWidget::flexiPortChanged(int index) if (isComboboxOptionSelected(m_ui->cbMain, HwSettings::RM_MAINPORT_TELEMETRY)) { setComboboxSelectedOption(m_ui->cbMain, HwSettings::RM_MAINPORT_DISABLED); } - if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPMTELEMETRY) - || isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_TELEMETRY)) { + if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPMTELEMETRY)) { + setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPM); + } + if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_TELEMETRY)) { setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_DISABLED); } break; @@ -218,24 +207,70 @@ void ConfigRevoHWWidget::flexiPortChanged(int index) if (isComboboxOptionSelected(m_ui->cbMain, HwSettings::RM_MAINPORT_GPS)) { setComboboxSelectedOption(m_ui->cbMain, HwSettings::RM_MAINPORT_DISABLED); } + if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPMGPS)) { + setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPM); + } + if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_GPS)) { + setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_DISABLED); + } + break; case HwSettings::RM_FLEXIPORT_COMBRIDGE: - m_ui->cbFlexiComSpeed->setVisible(true); + m_ui->lblFlexiSpeed->setVisible(false); if (isComboboxOptionSelected(m_ui->cbMain, HwSettings::RM_MAINPORT_COMBRIDGE)) { setComboboxSelectedOption(m_ui->cbMain, HwSettings::RM_MAINPORT_DISABLED); } if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_COMBRIDGE)) { setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_DISABLED); } + if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPMCOMBRIDGE)) { + setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPM); + } break; case HwSettings::RM_FLEXIPORT_DEBUGCONSOLE: - m_ui->cbFlexiComSpeed->setVisible(true); + m_ui->lblFlexiSpeed->setVisible(false); if (isComboboxOptionSelected(m_ui->cbMain, HwSettings::RM_MAINPORT_DEBUGCONSOLE)) { setComboboxSelectedOption(m_ui->cbMain, HwSettings::RM_MAINPORT_DISABLED); } if (isComboboxOptionSelected(m_ui->cbUSBVCPFunction, HwSettings::USB_VCPPORT_DEBUGCONSOLE)) { setComboboxSelectedOption(m_ui->cbUSBVCPFunction, HwSettings::USB_VCPPORT_DISABLED); } + if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPMDEBUGCONSOLE)) { + setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPM); + } + if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_DEBUGCONSOLE)) { + setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_DISABLED); + } + break; + case HwSettings::RM_FLEXIPORT_OSDHK: + m_ui->lblFlexiSpeed->setVisible(false); + if (isComboboxOptionSelected(m_ui->cbMain, HwSettings::RM_MAINPORT_OSDHK)) { + setComboboxSelectedOption(m_ui->cbMain, HwSettings::RM_MAINPORT_DISABLED); + } + break; + case HwSettings::RM_FLEXIPORT_MSP: + m_ui->lblFlexiSpeed->setVisible(false); + if (isComboboxOptionSelected(m_ui->cbMain, HwSettings::RM_MAINPORT_MSP)) { + setComboboxSelectedOption(m_ui->cbMain, HwSettings::RM_MAINPORT_DISABLED); + } + if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_MSP)) { + setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_DISABLED); + } + if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPMMSP)) { + setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPM); + } + break; + case HwSettings::RM_FLEXIPORT_MAVLINK: + m_ui->lblFlexiSpeed->setVisible(false); + if (isComboboxOptionSelected(m_ui->cbMain, HwSettings::RM_MAINPORT_MAVLINK)) { + setComboboxSelectedOption(m_ui->cbMain, HwSettings::RM_MAINPORT_DISABLED); + } + if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_MAVLINK)) { + setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_DISABLED); + } + if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPMMAVLINK)) { + setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPM); + } break; default: m_ui->lblFlexiSpeed->setVisible(false); @@ -249,7 +284,6 @@ void ConfigRevoHWWidget::mainPortChanged(int index) m_ui->cbMainTelemSpeed->setVisible(false); m_ui->cbMainGPSSpeed->setVisible(false); - m_ui->cbMainComSpeed->setVisible(false); m_ui->lblMainSpeed->setVisible(true); // Add Gps protocol configuration @@ -262,8 +296,10 @@ void ConfigRevoHWWidget::mainPortChanged(int index) if (isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_TELEMETRY)) { setComboboxSelectedOption(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_DISABLED); } - if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPMTELEMETRY) - || isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_TELEMETRY)) { + if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPMTELEMETRY)) { + setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPM); + } + if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_TELEMETRY)) { setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_DISABLED); } break; @@ -276,24 +312,69 @@ void ConfigRevoHWWidget::mainPortChanged(int index) if (isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_GPS)) { setComboboxSelectedOption(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_DISABLED); } + if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPMGPS)) { + setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPM); + } + if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_GPS)) { + setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_DISABLED); + } break; case HwSettings::RM_MAINPORT_COMBRIDGE: - m_ui->cbMainComSpeed->setVisible(true); + m_ui->lblMainSpeed->setVisible(false); if (isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_COMBRIDGE)) { setComboboxSelectedOption(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_DISABLED); } if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_COMBRIDGE)) { setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_DISABLED); } + if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPMCOMBRIDGE)) { + setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPM); + } break; case HwSettings::RM_MAINPORT_DEBUGCONSOLE: - m_ui->cbMainComSpeed->setVisible(true); + m_ui->lblMainSpeed->setVisible(false); if (isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_DEBUGCONSOLE)) { setComboboxSelectedOption(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_DISABLED); } if (isComboboxOptionSelected(m_ui->cbUSBVCPFunction, HwSettings::USB_VCPPORT_DEBUGCONSOLE)) { setComboboxSelectedOption(m_ui->cbUSBVCPFunction, HwSettings::USB_VCPPORT_DISABLED); } + if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPMDEBUGCONSOLE)) { + setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPM); + } + if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_DEBUGCONSOLE)) { + setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_DISABLED); + } + break; + case HwSettings::RM_MAINPORT_OSDHK: + m_ui->lblMainSpeed->setVisible(false); + if (isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_OSDHK)) { + setComboboxSelectedOption(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_DISABLED); + } + break; + case HwSettings::RM_MAINPORT_MSP: + m_ui->lblMainSpeed->setVisible(false); + if (isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_MSP)) { + setComboboxSelectedOption(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_DISABLED); + } + if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_MSP)) { + setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_DISABLED); + } + if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPMMSP)) { + setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPM); + } + break; + case HwSettings::RM_MAINPORT_MAVLINK: + m_ui->lblMainSpeed->setVisible(false); + if (isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_MAVLINK)) { + setComboboxSelectedOption(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_DISABLED); + } + if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_MAVLINK)) { + setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_DISABLED); + } + if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPMMAVLINK)) { + setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPM); + } break; default: m_ui->lblMainSpeed->setVisible(false); @@ -306,7 +387,11 @@ void ConfigRevoHWWidget::rcvrPortChanged(int index) Q_UNUSED(index); m_ui->lblRcvrSpeed->setVisible(true); m_ui->cbRcvrTelemSpeed->setVisible(false); - m_ui->cbRcvrComSpeed->setVisible(false); + m_ui->cbRcvrGPSSpeed->setVisible(false); + + // Add Gps protocol configuration + m_ui->cbRcvrGPSProtocol->setVisible(false); + m_ui->lblRcvrGPSProtocol->setVisible(false); switch (getComboboxSelectedOption(m_ui->cbRcvr)) { case HwSettings::RM_RCVRPORT_TELEMETRY: @@ -321,7 +406,8 @@ void ConfigRevoHWWidget::rcvrPortChanged(int index) } break; case HwSettings::RM_RCVRPORT_COMBRIDGE: - m_ui->cbRcvrComSpeed->setVisible(true); + case HwSettings::RM_RCVRPORT_PPMCOMBRIDGE: + m_ui->lblRcvrSpeed->setVisible(false); if (isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_COMBRIDGE)) { setComboboxSelectedOption(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_DISABLED); } @@ -329,14 +415,52 @@ void ConfigRevoHWWidget::rcvrPortChanged(int index) setComboboxSelectedOption(m_ui->cbMain, HwSettings::RM_MAINPORT_DISABLED); } break; + case HwSettings::RM_RCVRPORT_DEBUGCONSOLE: + case HwSettings::RM_RCVRPORT_PPMDEBUGCONSOLE: + if (isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_DEBUGCONSOLE)) { + setComboboxSelectedOption(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_DISABLED); + } + if (isComboboxOptionSelected(m_ui->cbMain, HwSettings::RM_MAINPORT_DEBUGCONSOLE)) { + setComboboxSelectedOption(m_ui->cbMain, HwSettings::RM_MAINPORT_DISABLED); + } + break; + case HwSettings::RM_RCVRPORT_GPS: + case HwSettings::RM_RCVRPORT_PPMGPS: + // Add Gps protocol configuration + m_ui->cbRcvrGPSProtocol->setVisible(true); + m_ui->lblRcvrGPSProtocol->setVisible(true); + + m_ui->cbRcvrGPSSpeed->setVisible(true); + + if (isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_GPS)) { + setComboboxSelectedOption(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_DISABLED); + } + if (isComboboxOptionSelected(m_ui->cbMain, HwSettings::RM_MAINPORT_GPS)) { + setComboboxSelectedOption(m_ui->cbMain, HwSettings::RM_MAINPORT_DISABLED); + } + break; + case HwSettings::RM_RCVRPORT_MSP: + case HwSettings::RM_RCVRPORT_PPMMSP: + m_ui->lblRcvrSpeed->setVisible(false); + if (isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_MSP)) { + setComboboxSelectedOption(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_DISABLED); + } + if (isComboboxOptionSelected(m_ui->cbMain, HwSettings::RM_MAINPORT_MSP)) { + setComboboxSelectedOption(m_ui->cbMain, HwSettings::RM_MAINPORT_DISABLED); + } + break; + case HwSettings::RM_RCVRPORT_MAVLINK: + case HwSettings::RM_RCVRPORT_PPMMAVLINK: + m_ui->lblRcvrSpeed->setVisible(false); + if (isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_MAVLINK)) { + setComboboxSelectedOption(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_DISABLED); + } + if (isComboboxOptionSelected(m_ui->cbMain, HwSettings::RM_MAINPORT_MAVLINK)) { + setComboboxSelectedOption(m_ui->cbMain, HwSettings::RM_MAINPORT_DISABLED); + } + break; default: m_ui->lblRcvrSpeed->setVisible(false); break; } } - -void ConfigRevoHWWidget::openHelp() -{ - QDesktopServices::openUrl(QUrl(QString(WIKI_URL_ROOT) + QString("Revolution+Configuration"), - QUrl::StrictMode)); -} diff --git a/ground/gcs/src/plugins/config/configrevohwwidget.h b/ground/gcs/src/plugins/config/configrevohwwidget.h index 436982fef..6f50b809b 100644 --- a/ground/gcs/src/plugins/config/configrevohwwidget.h +++ b/ground/gcs/src/plugins/config/configrevohwwidget.h @@ -2,7 +2,8 @@ ****************************************************************************** * * @file configrevohwwidget.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup ConfigPlugin Config Plugin @@ -27,14 +28,13 @@ #ifndef CONFIGREVOHWWIDGET_H #define CONFIGREVOHWWIDGET_H -#include "ui_configrevohwwidget.h" #include "../uavobjectwidgetutils/configtaskwidget.h" -#include "extensionsystem/pluginmanager.h" -#include "uavobjectmanager.h" -#include "uavobject.h" -#include -#include +class Ui_RevoHWWidget; + +class UAVObject; + +class QWidget; class ConfigRevoHWWidget : public ConfigTaskWidget { Q_OBJECT @@ -43,14 +43,14 @@ public: ConfigRevoHWWidget(QWidget *parent = 0); ~ConfigRevoHWWidget(); -private: - bool m_refreshing; - Ui_RevoHWWidget *m_ui; - void setupCustomCombos(); +protected: + virtual void refreshWidgetsValuesImpl(UAVObject *obj); + virtual void updateObjectsFromWidgetsImpl(); -protected slots: - void refreshWidgetsValues(UAVObject *obj = NULL); - void updateObjectsFromWidgets(); +private: + Ui_RevoHWWidget *m_ui; + + void setupCustomCombos(); private slots: void usbVCPPortChanged(int index); @@ -58,7 +58,6 @@ private slots: void flexiPortChanged(int index); void mainPortChanged(int index); void rcvrPortChanged(int index); - void openHelp(); }; #endif // CONFIGREVOHWWIDGET_H diff --git a/ground/gcs/src/plugins/config/configrevohwwidget.ui b/ground/gcs/src/plugins/config/configrevohwwidget.ui index d09ef0373..3ab3da94c 100644 --- a/ground/gcs/src/plugins/config/configrevohwwidget.ui +++ b/ground/gcs/src/plugins/config/configrevohwwidget.ui @@ -121,9 +121,9 @@ 0 - -148 + 0 796 - 804 + 807 @@ -248,9 +248,6 @@ - - - @@ -551,7 +548,7 @@ - :/configgadget/images/revolution_top.png + :/configgadget/images/revolution_top.png false @@ -579,9 +576,6 @@ - - - @@ -653,38 +647,34 @@ - + + + + + + + 0 + 0 + + + + Protocol + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + - - - - true - - - - - - - - 0 - 0 - - - - Speed - - - Qt::AlignBottom|Qt::AlignHCenter - - - @@ -749,7 +739,7 @@ - + 0 @@ -787,10 +777,13 @@ true + + button:help + - + 0 @@ -889,10 +882,13 @@ Beware of not locking yourself out! false + + button:apply + - + 0 @@ -918,6 +914,9 @@ Beware of not locking yourself out! Save + + button:save + diff --git a/ground/gcs/src/plugins/config/configrevonanohwwidget.cpp b/ground/gcs/src/plugins/config/configrevonanohwwidget.cpp index 218880e6f..2d5ed119e 100644 --- a/ground/gcs/src/plugins/config/configrevonanohwwidget.cpp +++ b/ground/gcs/src/plugins/config/configrevonanohwwidget.cpp @@ -1,14 +1,14 @@ /** ****************************************************************************** * - * @file configrevohwwidget.cpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @file configrevonanohwwidget.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup ConfigPlugin Config Plugin * @{ - * @brief Revolution hardware configuration panel + * @brief Revolution Nano hardware configuration panel *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify @@ -27,30 +27,23 @@ */ #include "configrevonanohwwidget.h" -#include -#include -#include +#include "ui_configrevonanohwwidget.h" + #include "hwsettings.h" -#include -#include -#include +#include -ConfigRevoNanoHWWidget::ConfigRevoNanoHWWidget(QWidget *parent) : ConfigTaskWidget(parent), m_refreshing(true) +ConfigRevoNanoHWWidget::ConfigRevoNanoHWWidget(QWidget *parent) : ConfigTaskWidget(parent) { m_ui = new Ui_RevoNanoHWWidget(); m_ui->setupUi(this); - ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); - Core::Internal::GeneralSettings *settings = pm->getObject(); - if (!settings->useExpertMode()) { - m_ui->saveTelemetryToRAM->setEnabled(false); - m_ui->saveTelemetryToRAM->setVisible(false); - } + // must be done before auto binding ! + setWikiURL("Revo+Nano+Configuration"); - addApplySaveButtons(m_ui->saveTelemetryToRAM, m_ui->saveTelemetryToSD); + addAutoBindings(); - forceConnectedState(); + addUAVObject("HwSettings"); addWidgetBinding("HwSettings", "RM_FlexiPort", m_ui->cbFlexi); addWidgetBinding("HwSettings", "RM_MainPort", m_ui->cbMain); @@ -58,30 +51,18 @@ ConfigRevoNanoHWWidget::ConfigRevoNanoHWWidget(QWidget *parent) : ConfigTaskWidg addWidgetBinding("HwSettings", "USB_HIDPort", m_ui->cbUSBHIDFunction); addWidgetBinding("HwSettings", "USB_VCPPort", m_ui->cbUSBVCPFunction); - addWidgetBinding("HwSettings", "ComUsbBridgeSpeed", m_ui->cbUSBVCPSpeed); addWidgetBinding("HwSettings", "TelemetrySpeed", m_ui->cbFlexiTelemSpeed); addWidgetBinding("HwSettings", "GPSSpeed", m_ui->cbFlexiGPSSpeed); - addWidgetBinding("HwSettings", "ComUsbBridgeSpeed", m_ui->cbFlexiComSpeed); addWidgetBinding("HwSettings", "TelemetrySpeed", m_ui->cbMainTelemSpeed); addWidgetBinding("HwSettings", "GPSSpeed", m_ui->cbMainGPSSpeed); - addWidgetBinding("HwSettings", "ComUsbBridgeSpeed", m_ui->cbMainComSpeed); - - addWidgetBinding("HwSettings", "TelemetrySpeed", m_ui->cbRcvrTelemSpeed); - addWidgetBinding("HwSettings", "ComUsbBridgeSpeed", m_ui->cbRcvrComSpeed); // Add Gps protocol configuration addWidgetBinding("GPSSettings", "DataProtocol", m_ui->cbMainGPSProtocol); addWidgetBinding("GPSSettings", "DataProtocol", m_ui->cbFlexiGPSProtocol); - connect(m_ui->cchwHelp, SIGNAL(clicked()), this, SLOT(openHelp())); setupCustomCombos(); - enableControls(true); - populateWidgets(); - refreshWidgetsValues(); - setDirty(false); - m_refreshing = false; } ConfigRevoNanoHWWidget::~ConfigRevoNanoHWWidget() @@ -99,35 +80,29 @@ void ConfigRevoNanoHWWidget::setupCustomCombos() connect(m_ui->cbRcvr, SIGNAL(currentIndexChanged(int)), this, SLOT(rcvrPortChanged(int))); } -void ConfigRevoNanoHWWidget::refreshWidgetsValues(UAVObject *obj) +void ConfigRevoNanoHWWidget::refreshWidgetsValuesImpl(UAVObject *obj) { - m_refreshing = true; - ConfigTaskWidget::refreshWidgetsValues(obj); + Q_UNUSED(obj); usbVCPPortChanged(0); mainPortChanged(0); flexiPortChanged(0); rcvrPortChanged(0); - m_refreshing = false; } -void ConfigRevoNanoHWWidget::updateObjectsFromWidgets() +void ConfigRevoNanoHWWidget::updateObjectsFromWidgetsImpl() { - ConfigTaskWidget::updateObjectsFromWidgets(); - - HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager()); - HwSettings::DataFields data = hwSettings->getData(); - // If any port is configured to be GPS port, enable GPS module if it is not enabled. // Otherwise disable GPS module. + quint8 enableModule = HwSettings::OPTIONALMODULES_DISABLED; + if (isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_GPS) || isComboboxOptionSelected(m_ui->cbMain, HwSettings::RM_MAINPORT_GPS)) { - data.OptionalModules[HwSettings::OPTIONALMODULES_GPS] = HwSettings::OPTIONALMODULES_ENABLED; - } else { - data.OptionalModules[HwSettings::OPTIONALMODULES_GPS] = HwSettings::OPTIONALMODULES_DISABLED; + enableModule = HwSettings::OPTIONALMODULES_ENABLED; } - hwSettings->setData(data); + HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager()); + hwSettings->setOptionalModules(HwSettings::OPTIONALMODULES_GPS, enableModule); } void ConfigRevoNanoHWWidget::usbVCPPortChanged(int index) @@ -136,9 +111,6 @@ void ConfigRevoNanoHWWidget::usbVCPPortChanged(int index) bool vcpComBridgeEnabled = isComboboxOptionSelected(m_ui->cbUSBVCPFunction, HwSettings::USB_VCPPORT_COMBRIDGE); - m_ui->lblUSBVCPSpeed->setVisible(vcpComBridgeEnabled); - m_ui->cbUSBVCPSpeed->setVisible(vcpComBridgeEnabled); - if (!vcpComBridgeEnabled && isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_COMBRIDGE)) { setComboboxSelectedOption(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_DISABLED); } @@ -149,11 +121,6 @@ void ConfigRevoNanoHWWidget::usbVCPPortChanged(int index) } enableComboBoxOptionItem(m_ui->cbMain, HwSettings::RM_MAINPORT_COMBRIDGE, vcpComBridgeEnabled); - if (!vcpComBridgeEnabled && isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_COMBRIDGE)) { - setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_DISABLED); - } - enableComboBoxOptionItem(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_COMBRIDGE, vcpComBridgeEnabled); - // _DEBUGCONSOLE modes are mutual exclusive if (isComboboxOptionSelected(m_ui->cbUSBVCPFunction, HwSettings::USB_VCPPORT_DEBUGCONSOLE)) { if (isComboboxOptionSelected(m_ui->cbMain, HwSettings::RM_MAINPORT_DEBUGCONSOLE)) { @@ -188,7 +155,6 @@ void ConfigRevoNanoHWWidget::flexiPortChanged(int index) m_ui->cbFlexiTelemSpeed->setVisible(false); m_ui->cbFlexiGPSSpeed->setVisible(false); - m_ui->cbFlexiComSpeed->setVisible(false); m_ui->lblFlexiSpeed->setVisible(true); // Add Gps protocol configuration @@ -201,10 +167,6 @@ void ConfigRevoNanoHWWidget::flexiPortChanged(int index) if (isComboboxOptionSelected(m_ui->cbMain, HwSettings::RM_MAINPORT_TELEMETRY)) { setComboboxSelectedOption(m_ui->cbMain, HwSettings::RM_MAINPORT_DISABLED); } - if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPMTELEMETRY) - || isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_TELEMETRY)) { - setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_DISABLED); - } break; case HwSettings::RM_FLEXIPORT_GPS: // Add Gps protocol configuration @@ -217,16 +179,13 @@ void ConfigRevoNanoHWWidget::flexiPortChanged(int index) } break; case HwSettings::RM_FLEXIPORT_COMBRIDGE: - m_ui->cbFlexiComSpeed->setVisible(true); + m_ui->lblFlexiSpeed->setVisible(false); if (isComboboxOptionSelected(m_ui->cbMain, HwSettings::RM_MAINPORT_COMBRIDGE)) { setComboboxSelectedOption(m_ui->cbMain, HwSettings::RM_MAINPORT_DISABLED); } - if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_COMBRIDGE)) { - setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_DISABLED); - } break; case HwSettings::RM_FLEXIPORT_DEBUGCONSOLE: - m_ui->cbFlexiComSpeed->setVisible(true); + m_ui->lblFlexiSpeed->setVisible(false); if (isComboboxOptionSelected(m_ui->cbMain, HwSettings::RM_MAINPORT_DEBUGCONSOLE)) { setComboboxSelectedOption(m_ui->cbMain, HwSettings::RM_MAINPORT_DISABLED); } @@ -246,7 +205,6 @@ void ConfigRevoNanoHWWidget::mainPortChanged(int index) m_ui->cbMainTelemSpeed->setVisible(false); m_ui->cbMainGPSSpeed->setVisible(false); - m_ui->cbMainComSpeed->setVisible(false); m_ui->lblMainSpeed->setVisible(true); // Add Gps protocol configuration @@ -259,10 +217,6 @@ void ConfigRevoNanoHWWidget::mainPortChanged(int index) if (isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_TELEMETRY)) { setComboboxSelectedOption(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_DISABLED); } - if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_PPMTELEMETRY) - || isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_TELEMETRY)) { - setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_DISABLED); - } break; case HwSettings::RM_MAINPORT_GPS: // Add Gps protocol configuration @@ -275,16 +229,13 @@ void ConfigRevoNanoHWWidget::mainPortChanged(int index) } break; case HwSettings::RM_MAINPORT_COMBRIDGE: - m_ui->cbMainComSpeed->setVisible(true); + m_ui->lblMainSpeed->setVisible(false); if (isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_COMBRIDGE)) { setComboboxSelectedOption(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_DISABLED); } - if (isComboboxOptionSelected(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_COMBRIDGE)) { - setComboboxSelectedOption(m_ui->cbRcvr, HwSettings::RM_RCVRPORT_DISABLED); - } break; case HwSettings::RM_MAINPORT_DEBUGCONSOLE: - m_ui->cbMainComSpeed->setVisible(true); + m_ui->lblMainSpeed->setVisible(false); if (isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_DEBUGCONSOLE)) { setComboboxSelectedOption(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_DISABLED); } @@ -301,40 +252,5 @@ void ConfigRevoNanoHWWidget::mainPortChanged(int index) void ConfigRevoNanoHWWidget::rcvrPortChanged(int index) { Q_UNUSED(index); - - m_ui->lblRcvrSpeed->setVisible(true); - m_ui->cbRcvrTelemSpeed->setVisible(false); - m_ui->cbRcvrComSpeed->setVisible(false); - - switch (getComboboxSelectedOption(m_ui->cbRcvr)) { - case HwSettings::RM_RCVRPORT_TELEMETRY: - case HwSettings::RM_RCVRPORT_PPMTELEMETRY: - m_ui->cbRcvrTelemSpeed->setVisible(true); - - if (isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_TELEMETRY)) { - setComboboxSelectedOption(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_DISABLED); - } - if (isComboboxOptionSelected(m_ui->cbMain, HwSettings::RM_MAINPORT_TELEMETRY)) { - setComboboxSelectedOption(m_ui->cbMain, HwSettings::RM_MAINPORT_DISABLED); - } - break; - case HwSettings::RM_RCVRPORT_COMBRIDGE: - m_ui->cbRcvrComSpeed->setVisible(true); - if (isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_COMBRIDGE)) { - setComboboxSelectedOption(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_DISABLED); - } - if (isComboboxOptionSelected(m_ui->cbMain, HwSettings::RM_MAINPORT_COMBRIDGE)) { - setComboboxSelectedOption(m_ui->cbMain, HwSettings::RM_MAINPORT_DISABLED); - } - break; - default: - m_ui->lblRcvrSpeed->setVisible(false); - break; - } -} - -void ConfigRevoNanoHWWidget::openHelp() -{ - QDesktopServices::openUrl(QUrl(QString(WIKI_URL_ROOT) + QString("Revo+Nano+Configuration"), - QUrl::StrictMode)); + /* Nano has no USART at rcvrPort */ } diff --git a/ground/gcs/src/plugins/config/configrevonanohwwidget.h b/ground/gcs/src/plugins/config/configrevonanohwwidget.h index 7efebd326..7ded26532 100644 --- a/ground/gcs/src/plugins/config/configrevonanohwwidget.h +++ b/ground/gcs/src/plugins/config/configrevonanohwwidget.h @@ -1,8 +1,9 @@ /** ****************************************************************************** * - * @file configrevohwwidget.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @file configrevonanohwwidget.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup ConfigPlugin Config Plugin @@ -27,14 +28,13 @@ #ifndef CONFIGREVONANOHWWIDGET_H #define CONFIGREVONANOHWWIDGET_H -#include "ui_configrevonanohwwidget.h" #include "../uavobjectwidgetutils/configtaskwidget.h" -#include "extensionsystem/pluginmanager.h" -#include "uavobjectmanager.h" -#include "uavobject.h" -#include -#include +class Ui_RevoNanoHWWidget; + +class UAVObject; + +class QWidget; class ConfigRevoNanoHWWidget : public ConfigTaskWidget { Q_OBJECT @@ -43,14 +43,14 @@ public: ConfigRevoNanoHWWidget(QWidget *parent = 0); ~ConfigRevoNanoHWWidget(); -private: - bool m_refreshing; - Ui_RevoNanoHWWidget *m_ui; - void setupCustomCombos(); +protected: + virtual void refreshWidgetsValuesImpl(UAVObject *obj); + virtual void updateObjectsFromWidgetsImpl(); -protected slots: - void refreshWidgetsValues(UAVObject *obj = NULL); - void updateObjectsFromWidgets(); +private: + Ui_RevoNanoHWWidget *m_ui; + + void setupCustomCombos(); private slots: void usbVCPPortChanged(int index); @@ -58,7 +58,6 @@ private slots: void flexiPortChanged(int index); void mainPortChanged(int index); void rcvrPortChanged(int index); - void openHelp(); }; #endif // CONFIGREVONANOHWWIDGET_H diff --git a/ground/gcs/src/plugins/config/configrevonanohwwidget.ui b/ground/gcs/src/plugins/config/configrevonanohwwidget.ui index fc249ddf6..905396883 100644 --- a/ground/gcs/src/plugins/config/configrevonanohwwidget.ui +++ b/ground/gcs/src/plugins/config/configrevonanohwwidget.ui @@ -233,22 +233,6 @@ - - - - - 0 - 0 - - - - Speed - - - Qt::AlignBottom|Qt::AlignHCenter - - - @@ -270,7 +254,7 @@ - :/configgadget/images/nano_top.png + :/configgadget/images/nano_top.png false @@ -302,13 +286,6 @@ - - - - true - - - @@ -325,22 +302,6 @@ - - - - - 0 - 0 - - - - Speed - - - Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft - - - @@ -401,12 +362,9 @@ - - - - + @@ -419,7 +377,7 @@ - + Protocol @@ -450,9 +408,6 @@ - - - @@ -475,35 +430,6 @@ - - - - 0 - - - 0 - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - @@ -533,7 +459,7 @@ - + 0 @@ -571,10 +497,13 @@ true + + button:help + - + 0 @@ -673,10 +602,13 @@ Beware of not locking yourself out! false + + button:apply + - + 0 @@ -702,6 +634,9 @@ Beware of not locking yourself out! Save + + button:save + diff --git a/ground/gcs/src/plugins/config/configrevowidget.cpp b/ground/gcs/src/plugins/config/configrevowidget.cpp index 87c1bc29a..2fb72481e 100644 --- a/ground/gcs/src/plugins/config/configrevowidget.cpp +++ b/ground/gcs/src/plugins/config/configrevowidget.cpp @@ -1,8 +1,9 @@ /** ****************************************************************************** * - * @file ConfigRevoWidget.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @file configrevowidget.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup ConfigPlugin Config Plugin @@ -26,6 +27,11 @@ */ #include "configrevowidget.h" +#include "ui_revosensors.h" + +#include +#include + #include #include #include @@ -34,34 +40,24 @@ #include #include -#include -#include - #include "assertions.h" #include "calibration.h" #include "calibration/calibrationutils.h" -#include "math.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include -#include +#include +#include +#include +#include // #define DEBUG +#define MAG_ALARM_THRESHOLD 5 + // Uncomment this to enable 6 point calibration on the accels -#define NOISE_SAMPLES 50 +#define NOISE_SAMPLES 50 class Thread : public QThread { public: @@ -72,20 +68,16 @@ public: }; ConfigRevoWidget::ConfigRevoWidget(QWidget *parent) : - ConfigTaskWidget(parent), - m_ui(new Ui_RevoSensorsWidget()), - isBoardRotationStored(false) + ConfigTaskWidget(parent), isBoardRotationStored(false) { + m_ui = new Ui_RevoSensorsWidget(); m_ui->setupUi(this); m_ui->tabWidget->setCurrentIndex(0); - addApplySaveButtons(m_ui->revoCalSettingsSaveRAM, m_ui->revoCalSettingsSaveSD); + // must be done before auto binding ! + setWikiURL("Revo+Attitude+Configuration"); - ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); - Core::Internal::GeneralSettings *settings = pm->getObject(); - if (!settings->useExpertMode()) { - m_ui->revoCalSettingsSaveRAM->setVisible(false); - } + addAutoBindings(); // Initialization of the visual help m_ui->calibrationVisualHelp->setScene(new QGraphicsScene(this)); @@ -102,7 +94,6 @@ ConfigRevoWidget::ConfigRevoWidget(QWidget *parent) : addUAVObject("RevoSettings"); addUAVObject("AccelGyroSettings"); addUAVObject("AuxMagSettings"); - autoLoadWidgets(); // accel calibration m_accelCalibrationModel = new OpenPilot::SixPointCalibrationModel(this); @@ -193,13 +184,31 @@ ConfigRevoWidget::ConfigRevoWidget(QWidget *parent) : addWidgetBinding("AttitudeSettings", "BoardRotation", m_ui->yawRotation, AttitudeSettings::BOARDROTATION_YAW); addWidgetBinding("AttitudeSettings", "AccelTau", m_ui->accelTau); - populateWidgets(); + addWidgetBinding("AttitudeSettings", "ZeroDuringArming", m_ui->zeroGyroBiasOnArming); + addWidgetBinding("AttitudeSettings", "InitialZeroWhenBoardSteady", m_ui->initGyroWhenBoardSteady); + + addWidgetBinding("AuxMagSettings", "Usage", m_ui->auxMagUsage, 0, 1, true); + addWidgetBinding("AuxMagSettings", "Type", m_ui->auxMagType, 0, 1, true); + + addWidgetBinding("RevoSettings", "MagnetometerMaxDeviation", m_ui->maxDeviationWarning, RevoSettings::MAGNETOMETERMAXDEVIATION_WARNING); + addWidgetBinding("RevoSettings", "MagnetometerMaxDeviation", m_ui->maxDeviationError, RevoSettings::MAGNETOMETERMAXDEVIATION_ERROR); + + addWidgetBinding("AuxMagSettings", "BoardRotation", m_ui->auxMagRollRotation, AuxMagSettings::BOARDROTATION_ROLL); + addWidgetBinding("AuxMagSettings", "BoardRotation", m_ui->auxMagPitchRotation, AuxMagSettings::BOARDROTATION_PITCH); + addWidgetBinding("AuxMagSettings", "BoardRotation", m_ui->auxMagYawRotation, AuxMagSettings::BOARDROTATION_YAW); + + connect(m_ui->tabWidget, SIGNAL(currentChanged(int)), this, SLOT(onBoardAuxMagError())); + connect(MagSensor::GetInstance(getObjectManager()), SIGNAL(objectUpdated(UAVObject *)), this, SLOT(onBoardAuxMagError())); + connect(MagState::GetInstance(getObjectManager()), SIGNAL(objectUpdated(UAVObject *)), this, SLOT(updateMagStatus())); + connect(HomeLocation::GetInstance(getObjectManager()), SIGNAL(objectUpdated(UAVObject *)), this, SLOT(updateMagBeVector())); + + addWidget(m_ui->internalAuxErrorX); + addWidget(m_ui->internalAuxErrorY); + addWidget(m_ui->internalAuxErrorZ); + + displayMagError = false; + enableAllCalibrations(); - - updateEnableControls(); - - forceConnectedState(); - refreshWidgetsValues(); } ConfigRevoWidget::~ConfigRevoWidget() @@ -227,6 +236,8 @@ void ConfigRevoWidget::updateVisualHelp() void ConfigRevoWidget::storeAndClearBoardRotation() { if (!isBoardRotationStored) { + UAVObjectUpdaterHelper updateHelper; + // Store current board rotation isBoardRotationStored = true; AttitudeSettings *attitudeSettings = AttitudeSettings::GetInstance(getObjectManager()); @@ -240,23 +251,33 @@ void ConfigRevoWidget::storeAndClearBoardRotation() data.BoardRotation[AttitudeSettings::BOARDROTATION_YAW] = 0; data.BoardRotation[AttitudeSettings::BOARDROTATION_ROLL] = 0; data.BoardRotation[AttitudeSettings::BOARDROTATION_PITCH] = 0; - attitudeSettings->setData(data); + + attitudeSettings->setData(data, false); + updateHelper.doObjectAndWait(attitudeSettings); // Store current aux mag board rotation AuxMagSettings *auxMagSettings = AuxMagSettings::GetInstance(getObjectManager()); Q_ASSERT(auxMagSettings); AuxMagSettings::DataFields auxMagData = auxMagSettings->getData(); - auxMagStoredBoardRotation = auxMagData.Orientation; + auxMagStoredBoardRotation[AuxMagSettings::BOARDROTATION_YAW] = auxMagData.BoardRotation[AuxMagSettings::BOARDROTATION_YAW]; + auxMagStoredBoardRotation[AuxMagSettings::BOARDROTATION_ROLL] = auxMagData.BoardRotation[AuxMagSettings::BOARDROTATION_ROLL]; + auxMagStoredBoardRotation[AuxMagSettings::BOARDROTATION_PITCH] = auxMagData.BoardRotation[AuxMagSettings::BOARDROTATION_PITCH]; // Set aux mag board rotation to no rotation - auxMagData.Orientation = 0.0f; - auxMagSettings->setData(auxMagData); + auxMagData.BoardRotation[AuxMagSettings::BOARDROTATION_YAW] = 0; + auxMagData.BoardRotation[AuxMagSettings::BOARDROTATION_ROLL] = 0; + auxMagData.BoardRotation[AuxMagSettings::BOARDROTATION_PITCH] = 0; + + auxMagSettings->setData(auxMagData, false); + updateHelper.doObjectAndWait(auxMagSettings); } } void ConfigRevoWidget::recallBoardRotation() { if (isBoardRotationStored) { + UAVObjectUpdaterHelper updateHelper; + // Recall current board rotation isBoardRotationStored = false; @@ -267,14 +288,20 @@ void ConfigRevoWidget::recallBoardRotation() data.BoardRotation[AttitudeSettings::BOARDROTATION_YAW] = storedBoardRotation[AttitudeSettings::BOARDROTATION_YAW]; data.BoardRotation[AttitudeSettings::BOARDROTATION_ROLL] = storedBoardRotation[AttitudeSettings::BOARDROTATION_ROLL]; data.BoardRotation[AttitudeSettings::BOARDROTATION_PITCH] = storedBoardRotation[AttitudeSettings::BOARDROTATION_PITCH]; - attitudeSettings->setData(data); + + attitudeSettings->setData(data, false); + updateHelper.doObjectAndWait(attitudeSettings); // Restore the aux mag board rotation AuxMagSettings *auxMagSettings = AuxMagSettings::GetInstance(getObjectManager()); Q_ASSERT(auxMagSettings); AuxMagSettings::DataFields auxMagData = auxMagSettings->getData(); - auxMagData.Orientation = auxMagStoredBoardRotation; - auxMagSettings->setData(auxMagData); + auxMagData.BoardRotation[AuxMagSettings::BOARDROTATION_YAW] = auxMagStoredBoardRotation[AuxMagSettings::BOARDROTATION_YAW]; + auxMagData.BoardRotation[AuxMagSettings::BOARDROTATION_ROLL] = auxMagStoredBoardRotation[AuxMagSettings::BOARDROTATION_ROLL]; + auxMagData.BoardRotation[AuxMagSettings::BOARDROTATION_PITCH] = auxMagStoredBoardRotation[AuxMagSettings::BOARDROTATION_PITCH]; + + auxMagSettings->setData(auxMagData, false); + updateHelper.doObjectAndWait(auxMagSettings); } } @@ -363,9 +390,9 @@ void ConfigRevoWidget::displayTemperatureRange(float temperatureRange) * Called by the ConfigTaskWidget parent when RevoCalibration is updated * to update the UI */ -void ConfigRevoWidget::refreshWidgetsValues(UAVObject *object) +void ConfigRevoWidget::refreshWidgetsValuesImpl(UAVObject *obj) { - ConfigTaskWidget::refreshWidgetsValues(object); + Q_UNUSED(obj); m_ui->isSetCheckBox->setEnabled(false); @@ -375,12 +402,13 @@ void ConfigRevoWidget::refreshWidgetsValues(UAVObject *object) QString beStr = QString("%1:%2:%3").arg(QString::number(homeLocationData.Be[0]), QString::number(homeLocationData.Be[1]), QString::number(homeLocationData.Be[2])); m_ui->beBox->setText(beStr); + + updateMagBeVector(); + onBoardAuxMagError(); } -void ConfigRevoWidget::updateObjectsFromWidgets() +void ConfigRevoWidget::updateObjectsFromWidgetsImpl() { - ConfigTaskWidget::updateObjectsFromWidgets(); - if (m_accelCalibrationModel->dirty()) { m_accelCalibrationModel->save(); } @@ -441,3 +469,222 @@ void ConfigRevoWidget::enableAllCalibrations() m_ui->gyroBiasStart->setEnabled(true); m_ui->thermalBiasStart->setEnabled(true); } + +void ConfigRevoWidget::onBoardAuxMagError() +{ + MagSensor *magSensor = MagSensor::GetInstance(getObjectManager()); + + Q_ASSERT(magSensor); + AuxMagSensor *auxMagSensor = AuxMagSensor::GetInstance(getObjectManager()); + Q_ASSERT(auxMagSensor); + + if (m_ui->tabWidget->currentIndex() != 2) { + // Apply default metadata + if (displayMagError) { + magSensor->setMetadata(magSensor->getDefaultMetadata()); + auxMagSensor->setMetadata(auxMagSensor->getDefaultMetadata()); + displayMagError = false; + } + return; + } + + if (!displayMagError) { + // Apply new rates + UAVObject::Metadata mdata = magSensor->getMetadata(); + UAVObject::SetFlightTelemetryUpdateMode(mdata, UAVObject::UPDATEMODE_PERIODIC); + mdata.flightTelemetryUpdatePeriod = 300; + magSensor->setMetadata(mdata); + + mdata = auxMagSensor->getMetadata(); + UAVObject::SetFlightTelemetryUpdateMode(mdata, UAVObject::UPDATEMODE_PERIODIC); + mdata.flightTelemetryUpdatePeriod = 300; + auxMagSensor->setMetadata(mdata); + + displayMagError = true; + return; + } + + float onboardMag[3]; + float auxMag[3]; + + onboardMag[0] = magSensor->x(); + onboardMag[1] = magSensor->y(); + onboardMag[2] = magSensor->z(); + + float normalizedMag[3]; + float normalizedAuxMag[3]; + float xDiff = 0.0f; + float yDiff = 0.0f; + float zDiff = 0.0f; + + // Smooth Mag readings + float alpha = 0.7f; + float inv_alpha = (1.0f - alpha); + // Onboard mag + onboardMagFiltered[0] = (onboardMagFiltered[0] * alpha) + (onboardMag[0] * inv_alpha); + onboardMagFiltered[1] = (onboardMagFiltered[1] * alpha) + (onboardMag[1] * inv_alpha); + onboardMagFiltered[2] = (onboardMagFiltered[2] * alpha) + (onboardMag[2] * inv_alpha); + + // Normalize vector + float magLength = sqrt((onboardMagFiltered[0] * onboardMagFiltered[0]) + + (onboardMagFiltered[1] * onboardMagFiltered[1]) + + (onboardMagFiltered[2] * onboardMagFiltered[2])); + + normalizedMag[0] = onboardMagFiltered[0] / magLength; + normalizedMag[1] = onboardMagFiltered[1] / magLength; + normalizedMag[2] = onboardMagFiltered[2] / magLength; + + if (auxMagSensor->status() > (int)AuxMagSensor::STATUS_NONE) { + auxMag[0] = auxMagSensor->x(); + auxMag[1] = auxMagSensor->y(); + auxMag[2] = auxMagSensor->z(); + + auxMagFiltered[0] = (auxMagFiltered[0] * alpha) + (auxMag[0] * inv_alpha); + auxMagFiltered[1] = (auxMagFiltered[1] * alpha) + (auxMag[1] * inv_alpha); + auxMagFiltered[2] = (auxMagFiltered[2] * alpha) + (auxMag[2] * inv_alpha); + + // Normalize vector + float auxMagLength = sqrt((auxMagFiltered[0] * auxMagFiltered[0]) + + (auxMagFiltered[1] * auxMagFiltered[1]) + + (auxMagFiltered[2] * auxMagFiltered[2])); + + normalizedAuxMag[0] = auxMagFiltered[0] / auxMagLength; + normalizedAuxMag[1] = auxMagFiltered[1] / auxMagLength; + normalizedAuxMag[2] = auxMagFiltered[2] / auxMagLength; + + // Calc diff and scale + xDiff = (normalizedMag[0] - normalizedAuxMag[0]) * 25.0f; + yDiff = (normalizedMag[1] - normalizedAuxMag[1]) * 25.0f; + zDiff = (normalizedMag[2] - normalizedAuxMag[2]) * 25.0f; + } else { + auxMag[0] = auxMag[1] = auxMag[2] = 0.0f; + auxMagFiltered[0] = auxMagFiltered[1] = auxMagFiltered[2] = 0.0f; + } + + // Display Mag/AuxMag diff for every axis + m_ui->internalAuxErrorX->setValue(xDiff > 50.0f ? 50.0f : xDiff < -50.0f ? -50.0f : xDiff); + m_ui->internalAuxErrorY->setValue(yDiff > 50.0f ? 50.0f : yDiff < -50.0f ? -50.0f : yDiff); + m_ui->internalAuxErrorZ->setValue(zDiff > 50.0f ? 50.0f : zDiff < -50.0f ? -50.0f : zDiff); + + updateMagAlarm(getMagError(onboardMag), (auxMagSensor->status() == (int)AuxMagSensor::STATUS_NONE) ? -1.0f : getMagError(auxMag)); +} + +void ConfigRevoWidget::updateMagAlarm(float errorMag, float errorAuxMag) +{ + RevoSettings *revoSettings = RevoSettings::GetInstance(getObjectManager()); + + Q_ASSERT(revoSettings); + RevoSettings::DataFields revoSettingsData = revoSettings->getData(); + + QStringList AlarmColor; + AlarmColor << "grey" << "green" << "orange" << "red"; + enum magAlarmState { MAG_NOT_FOUND = 0, MAG_OK = 1, MAG_WARNING = 2, MAG_ERROR = 3 }; + + QString bgColorMag = AlarmColor[MAG_OK]; + QString bgColorAuxMag = AlarmColor[MAG_OK]; + + // Onboard Mag + if (errorMag < revoSettingsData.MagnetometerMaxDeviation[RevoSettings::MAGNETOMETERMAXDEVIATION_WARNING]) { + magWarningCount = 0; + magErrorCount = 0; + } + + if (errorMag < revoSettingsData.MagnetometerMaxDeviation[RevoSettings::MAGNETOMETERMAXDEVIATION_ERROR]) { + magErrorCount = 0; + if (magWarningCount > MAG_ALARM_THRESHOLD) { + bgColorMag = AlarmColor[MAG_WARNING]; + } else { + magWarningCount++; + } + } + + if (magErrorCount > MAG_ALARM_THRESHOLD) { + bgColorMag = AlarmColor[MAG_ERROR]; + } else { + magErrorCount++; + } + + // Auxiliary Mag + if (errorAuxMag > -1.0f) { + if (errorAuxMag < revoSettingsData.MagnetometerMaxDeviation[RevoSettings::MAGNETOMETERMAXDEVIATION_WARNING]) { + auxMagWarningCount = 0; + auxMagErrorCount = 0; + } + + if (errorAuxMag < revoSettingsData.MagnetometerMaxDeviation[RevoSettings::MAGNETOMETERMAXDEVIATION_ERROR]) { + auxMagErrorCount = 0; + if (auxMagWarningCount > MAG_ALARM_THRESHOLD) { + bgColorAuxMag = AlarmColor[MAG_WARNING]; + } else { + auxMagWarningCount++; + } + } + + if (auxMagErrorCount > MAG_ALARM_THRESHOLD) { + bgColorAuxMag = AlarmColor[MAG_ERROR]; + } else { + auxMagErrorCount++; + } + errorAuxMag = ((errorAuxMag * 100.0f) <= 100.0f) ? errorAuxMag * 100.0f : 100.0f; + m_ui->auxMagStatus->setText("AuxMag\n" + QString::number(errorAuxMag, 'f', 1) + "%"); + } else { + // Disable aux mag alarm + bgColorAuxMag = AlarmColor[MAG_NOT_FOUND]; + m_ui->auxMagStatus->setText("AuxMag\nnot found"); + } + + errorMag = ((errorMag * 100.0f) <= 100.0f) ? errorMag * 100.0f : 100.0f; + m_ui->onBoardMagStatus->setText("Onboard\n" + QString::number(errorMag, 'f', 1) + "%"); + m_ui->onBoardMagStatus->setStyleSheet( + "QLabel { background-color: " + bgColorMag + ";" + "color: rgb(255, 255, 255); border-radius: 5; margin:1px; font:bold; }"); + m_ui->auxMagStatus->setStyleSheet( + "QLabel { background-color: " + bgColorAuxMag + ";" + "color: rgb(255, 255, 255); border-radius: 5; margin:1px; font:bold; }"); +} + +float ConfigRevoWidget::getMagError(float mag[3]) +{ + float magnitude = sqrt((mag[0] * mag[0]) + (mag[1] * mag[1]) + (mag[2] * mag[2])); + float magnitudeBe = sqrt((magBe[0] * magBe[0]) + (magBe[1] * magBe[1]) + (magBe[2] * magBe[2])); + float invMagnitudeBe = 1.0f / magnitudeBe; + // Absolute value of relative error against Be + float error = fabsf(magnitude - magnitudeBe) * invMagnitudeBe; + + return error; +} + +void ConfigRevoWidget::updateMagBeVector() +{ + HomeLocation *homeLocation = HomeLocation::GetInstance(getObjectManager()); + + Q_ASSERT(homeLocation); + HomeLocation::DataFields homeLocationData = homeLocation->getData(); + + magBe[0] = homeLocationData.Be[0]; + magBe[1] = homeLocationData.Be[1]; + magBe[2] = homeLocationData.Be[2]; +} + +void ConfigRevoWidget::updateMagStatus() +{ + MagState *magState = MagState::GetInstance(getObjectManager()); + + Q_ASSERT(magState); + + MagState::DataFields magStateData = magState->getData(); + + if (magStateData.Source == MagState::SOURCE_INVALID) { + m_ui->magStatusSource->setText(tr("Source invalid")); + m_ui->magStatusSource->setToolTip(tr("Currently no attitude estimation algorithm uses magnetometer or there is something wrong")); + } else if (magStateData.Source == MagState::SOURCE_ONBOARD) { + m_ui->magStatusSource->setText(tr("Onboard magnetometer")); + m_ui->magStatusSource->setToolTip(""); + } else if (magStateData.Source == MagState::SOURCE_AUX) { + m_ui->magStatusSource->setText(tr("Auxiliary magnetometer")); + m_ui->magStatusSource->setToolTip(""); + } else { + m_ui->magStatusSource->setText(tr("Unknown")); + m_ui->magStatusSource->setToolTip(""); + } +} diff --git a/ground/gcs/src/plugins/config/configrevowidget.h b/ground/gcs/src/plugins/config/configrevowidget.h index 175832b4b..896cabd60 100644 --- a/ground/gcs/src/plugins/config/configrevowidget.h +++ b/ground/gcs/src/plugins/config/configrevowidget.h @@ -1,8 +1,9 @@ /** ****************************************************************************** * - * @file configahrstwidget.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @file configrevowidget.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup ConfigPlugin Config Plugin @@ -27,24 +28,18 @@ #ifndef CONFIGREVOWIDGET_H #define CONFIGREVOWIDGET_H -#include "ui_revosensors.h" #include "configtaskwidget.h" -#include "extensionsystem/pluginmanager.h" -#include "uavobjectmanager.h" + #include "uavobject.h" + #include "calibration/thermal/thermalcalibrationmodel.h" #include "calibration/sixpointcalibrationmodel.h" #include "calibration/levelcalibrationmodel.h" #include "calibration/gyrobiascalibrationmodel.h" -#include -#include -#include -#include -#include -#include +class Ui_RevoSensorsWidget; -class Ui_Widget; +class QWidget; class ConfigRevoWidget : public ConfigTaskWidget { Q_OBJECT @@ -53,6 +48,10 @@ public: ConfigRevoWidget(QWidget *parent = 0); ~ConfigRevoWidget(); +protected: + virtual void refreshWidgetsValuesImpl(UAVObject *obj); + virtual void updateObjectsFromWidgetsImpl(); + private: OpenPilot::SixPointCalibrationModel *m_accelCalibrationModel; OpenPilot::SixPointCalibrationModel *m_magCalibrationModel; @@ -64,9 +63,20 @@ private: // Board rotation store/recall for FC and for aux mag qint16 storedBoardRotation[3]; - float auxMagStoredBoardRotation; + qint16 auxMagStoredBoardRotation[3]; bool isBoardRotationStored; + bool displayMagError; + + float onboardMagFiltered[3]; + float auxMagFiltered[3]; + float magBe[3]; + + int magWarningCount; + int magErrorCount; + int auxMagWarningCount; + int auxMagErrorCount; + private slots: void storeAndClearBoardRotation(); void recallBoardRotation(); @@ -77,16 +87,19 @@ private slots: void displayTemperatureGradient(float temparetureGradient); void displayTemperatureRange(float temparetureRange); - // ! Overriden method from the configTaskWidget to update UI - virtual void refreshWidgetsValues(UAVObject *object = NULL); - virtual void updateObjectsFromWidgets(); - // Slot for clearing home location void clearHomeLocation(); void disableAllCalibrations(); void enableAllCalibrations(); + void onBoardAuxMagError(); + void updateMagStatus(); + void updateMagBeVector(); + void updateMagAlarm(float errorMag, float errorAuxMag); + + float getMagError(float mag[3]); + void updateVisualHelp(); protected: diff --git a/ground/gcs/src/plugins/config/configsparky2hwwidget.cpp b/ground/gcs/src/plugins/config/configsparky2hwwidget.cpp new file mode 100644 index 000000000..178d9d504 --- /dev/null +++ b/ground/gcs/src/plugins/config/configsparky2hwwidget.cpp @@ -0,0 +1,253 @@ +/** + ****************************************************************************** + * + * @file configsparky2hwwidget.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @addtogroup GCSPlugins GCS Plugins + * @{ + * @addtogroup ConfigPlugin Config Plugin + * @{ + * @brief Sparky2 hardware configuration panel + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include "configsparky2hwwidget.h" + +#include "ui_configsparky2hwwidget.h" + +#include "hwsettings.h" + +#include + +ConfigSparky2HWWidget::ConfigSparky2HWWidget(QWidget *parent) : ConfigTaskWidget(parent) +{ + m_ui = new Ui_Sparky2HWWidget(); + m_ui->setupUi(this); + + // must be done before auto binding ! + setWikiURL("Sparky2+Configuration"); + + addAutoBindings(); + + addUAVObject("HwSettings"); + + addWidgetBinding("HwSettings", "SPK2_FlexiPort", m_ui->cbFlexi); + addWidgetBinding("HwSettings", "SPK2_MainPort", m_ui->cbMain); + addWidgetBinding("HwSettings", "SPK2_RcvrPort", m_ui->cbRcvr); + addWidgetBinding("HwSettings", "SPK2_I2CPort", m_ui->cbI2C); + + addWidgetBinding("HwSettings", "USB_HIDPort", m_ui->cbUSBHIDFunction); + addWidgetBinding("HwSettings", "USB_VCPPort", m_ui->cbUSBVCPFunction); + + addWidgetBinding("HwSettings", "TelemetrySpeed", m_ui->cbFlexiTelemSpeed); + addWidgetBinding("HwSettings", "GPSSpeed", m_ui->cbFlexiGPSSpeed); + + addWidgetBinding("HwSettings", "TelemetrySpeed", m_ui->cbMainTelemSpeed); + addWidgetBinding("HwSettings", "GPSSpeed", m_ui->cbMainGPSSpeed); + + // Add Gps protocol configuration + addWidgetBinding("GPSSettings", "DataProtocol", m_ui->cbMainGPSProtocol); + addWidgetBinding("GPSSettings", "DataProtocol", m_ui->cbFlexiGPSProtocol); + + setupCustomCombos(); +} + +ConfigSparky2HWWidget::~ConfigSparky2HWWidget() +{ + // Do nothing +} + +void ConfigSparky2HWWidget::setupCustomCombos() +{ + connect(m_ui->cbUSBHIDFunction, SIGNAL(currentIndexChanged(int)), this, SLOT(usbHIDPortChanged(int))); + connect(m_ui->cbUSBVCPFunction, SIGNAL(currentIndexChanged(int)), this, SLOT(usbVCPPortChanged(int))); + + // m_ui->cbSonar->addItem(tr("Disabled")); + // m_ui->cbSonar->setCurrentIndex(0); + // m_ui->cbSonar->setEnabled(false); + + connect(m_ui->cbFlexi, SIGNAL(currentIndexChanged(int)), this, SLOT(flexiPortChanged(int))); + connect(m_ui->cbMain, SIGNAL(currentIndexChanged(int)), this, SLOT(mainPortChanged(int))); +} + +void ConfigSparky2HWWidget::refreshWidgetsValuesImpl(UAVObject *obj) +{ + Q_UNUSED(obj); + + usbVCPPortChanged(0); + mainPortChanged(0); + flexiPortChanged(0); +} + +void ConfigSparky2HWWidget::updateObjectsFromWidgetsImpl() +{ + // If any port is configured to be GPS port, enable GPS module if it is not enabled. + // Otherwise disable GPS module. + quint8 enableModule = HwSettings::OPTIONALMODULES_DISABLED; + + if (isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::SPK2_FLEXIPORT_GPS) + || isComboboxOptionSelected(m_ui->cbMain, HwSettings::SPK2_MAINPORT_GPS)) { + enableModule = HwSettings::OPTIONALMODULES_ENABLED; + } + + HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager()); + hwSettings->setOptionalModules(HwSettings::OPTIONALMODULES_GPS, enableModule); +} + +void ConfigSparky2HWWidget::usbVCPPortChanged(int index) +{ + Q_UNUSED(index); + + bool vcpComBridgeEnabled = isComboboxOptionSelected(m_ui->cbUSBVCPFunction, HwSettings::USB_VCPPORT_COMBRIDGE); + + if (!vcpComBridgeEnabled && isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::SPK2_FLEXIPORT_COMBRIDGE)) { + setComboboxSelectedOption(m_ui->cbFlexi, HwSettings::SPK2_FLEXIPORT_DISABLED); + } + enableComboBoxOptionItem(m_ui->cbFlexi, HwSettings::SPK2_FLEXIPORT_COMBRIDGE, vcpComBridgeEnabled); + + if (!vcpComBridgeEnabled && isComboboxOptionSelected(m_ui->cbMain, HwSettings::SPK2_MAINPORT_COMBRIDGE)) { + setComboboxSelectedOption(m_ui->cbMain, HwSettings::SPK2_MAINPORT_DISABLED); + } + enableComboBoxOptionItem(m_ui->cbMain, HwSettings::SPK2_MAINPORT_COMBRIDGE, vcpComBridgeEnabled); + + // _DEBUGCONSOLE modes are mutual exclusive + if (isComboboxOptionSelected(m_ui->cbUSBVCPFunction, HwSettings::USB_VCPPORT_DEBUGCONSOLE)) { + if (isComboboxOptionSelected(m_ui->cbMain, HwSettings::SPK2_MAINPORT_DEBUGCONSOLE)) { + setComboboxSelectedOption(m_ui->cbMain, HwSettings::SPK2_MAINPORT_DISABLED); + } + if (isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::SPK2_FLEXIPORT_DEBUGCONSOLE)) { + setComboboxSelectedOption(m_ui->cbFlexi, HwSettings::SPK2_FLEXIPORT_DISABLED); + } + } + + // _USBTELEMETRY modes are mutual exclusive + if (isComboboxOptionSelected(m_ui->cbUSBVCPFunction, HwSettings::USB_VCPPORT_USBTELEMETRY) + && isComboboxOptionSelected(m_ui->cbUSBHIDFunction, HwSettings::USB_HIDPORT_USBTELEMETRY)) { + setComboboxSelectedOption(m_ui->cbUSBHIDFunction, HwSettings::USB_HIDPORT_DISABLED); + } +} + +void ConfigSparky2HWWidget::usbHIDPortChanged(int index) +{ + Q_UNUSED(index); + + // _USBTELEMETRY modes are mutual exclusive + if (isComboboxOptionSelected(m_ui->cbUSBHIDFunction, HwSettings::USB_HIDPORT_USBTELEMETRY) + && isComboboxOptionSelected(m_ui->cbUSBVCPFunction, HwSettings::USB_VCPPORT_USBTELEMETRY)) { + setComboboxSelectedOption(m_ui->cbUSBVCPFunction, HwSettings::USB_VCPPORT_DISABLED); + } +} + +void ConfigSparky2HWWidget::flexiPortChanged(int index) +{ + Q_UNUSED(index); + + m_ui->cbFlexiTelemSpeed->setVisible(false); + m_ui->cbFlexiGPSSpeed->setVisible(false); + m_ui->lblFlexiSpeed->setVisible(true); + + // Add Gps protocol configuration + m_ui->cbFlexiGPSProtocol->setVisible(false); + m_ui->lbFlexiGPSProtocol->setVisible(false); + + switch (getComboboxSelectedOption(m_ui->cbFlexi)) { + case HwSettings::SPK2_FLEXIPORT_TELEMETRY: + m_ui->cbFlexiTelemSpeed->setVisible(true); + if (isComboboxOptionSelected(m_ui->cbMain, HwSettings::SPK2_MAINPORT_TELEMETRY)) { + setComboboxSelectedOption(m_ui->cbMain, HwSettings::SPK2_MAINPORT_DISABLED); + } + break; + case HwSettings::SPK2_FLEXIPORT_GPS: + // Add Gps protocol configuration + m_ui->cbFlexiGPSProtocol->setVisible(true); + m_ui->lbFlexiGPSProtocol->setVisible(true); + + m_ui->cbFlexiGPSSpeed->setVisible(true); + if (isComboboxOptionSelected(m_ui->cbMain, HwSettings::SPK2_MAINPORT_GPS)) { + setComboboxSelectedOption(m_ui->cbMain, HwSettings::SPK2_MAINPORT_DISABLED); + } + break; + case HwSettings::SPK2_FLEXIPORT_COMBRIDGE: + m_ui->lblFlexiSpeed->setVisible(false); + if (isComboboxOptionSelected(m_ui->cbMain, HwSettings::SPK2_MAINPORT_COMBRIDGE)) { + setComboboxSelectedOption(m_ui->cbMain, HwSettings::SPK2_MAINPORT_DISABLED); + } + break; + case HwSettings::SPK2_FLEXIPORT_DEBUGCONSOLE: + m_ui->lblFlexiSpeed->setVisible(false); + if (isComboboxOptionSelected(m_ui->cbMain, HwSettings::SPK2_MAINPORT_DEBUGCONSOLE)) { + setComboboxSelectedOption(m_ui->cbMain, HwSettings::SPK2_MAINPORT_DISABLED); + } + if (isComboboxOptionSelected(m_ui->cbUSBVCPFunction, HwSettings::USB_VCPPORT_DEBUGCONSOLE)) { + setComboboxSelectedOption(m_ui->cbUSBVCPFunction, HwSettings::USB_VCPPORT_DISABLED); + } + break; + default: + m_ui->lblFlexiSpeed->setVisible(false); + break; + } +} + +void ConfigSparky2HWWidget::mainPortChanged(int index) +{ + Q_UNUSED(index); + + m_ui->cbMainTelemSpeed->setVisible(false); + m_ui->cbMainGPSSpeed->setVisible(false); + m_ui->lblMainSpeed->setVisible(true); + + // Add Gps protocol configuration + m_ui->cbMainGPSProtocol->setVisible(false); + m_ui->lbMainGPSProtocol->setVisible(false); + + switch (getComboboxSelectedOption(m_ui->cbMain)) { + case HwSettings::SPK2_MAINPORT_TELEMETRY: + m_ui->cbMainTelemSpeed->setVisible(true); + if (isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::SPK2_FLEXIPORT_TELEMETRY)) { + setComboboxSelectedOption(m_ui->cbFlexi, HwSettings::SPK2_FLEXIPORT_DISABLED); + } + break; + case HwSettings::SPK2_MAINPORT_GPS: + // Add Gps protocol configuration + m_ui->cbMainGPSProtocol->setVisible(true); + m_ui->lbMainGPSProtocol->setVisible(true); + + m_ui->cbMainGPSSpeed->setVisible(true); + if (isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::SPK2_FLEXIPORT_GPS)) { + setComboboxSelectedOption(m_ui->cbFlexi, HwSettings::SPK2_FLEXIPORT_DISABLED); + } + break; + case HwSettings::SPK2_MAINPORT_COMBRIDGE: + m_ui->lblMainSpeed->setVisible(false); + if (isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::SPK2_FLEXIPORT_COMBRIDGE)) { + setComboboxSelectedOption(m_ui->cbFlexi, HwSettings::SPK2_FLEXIPORT_DISABLED); + } + break; + case HwSettings::SPK2_MAINPORT_DEBUGCONSOLE: + m_ui->lblMainSpeed->setVisible(false); + if (isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::SPK2_FLEXIPORT_DEBUGCONSOLE)) { + setComboboxSelectedOption(m_ui->cbFlexi, HwSettings::SPK2_FLEXIPORT_DISABLED); + } + if (isComboboxOptionSelected(m_ui->cbUSBVCPFunction, HwSettings::USB_VCPPORT_DEBUGCONSOLE)) { + setComboboxSelectedOption(m_ui->cbUSBVCPFunction, HwSettings::USB_VCPPORT_DISABLED); + } + break; + default: + m_ui->lblMainSpeed->setVisible(false); + break; + } +} diff --git a/ground/gcs/src/plugins/config/defaulthwsettingswidget.h b/ground/gcs/src/plugins/config/configsparky2hwwidget.h similarity index 56% rename from ground/gcs/src/plugins/config/defaulthwsettingswidget.h rename to ground/gcs/src/plugins/config/configsparky2hwwidget.h index 7d0cbceba..f4e484500 100644 --- a/ground/gcs/src/plugins/config/defaulthwsettingswidget.h +++ b/ground/gcs/src/plugins/config/configsparky2hwwidget.h @@ -1,13 +1,14 @@ /** ****************************************************************************** * - * @file defaultccattitudewidget.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @file configsparky2hwwidget.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup ConfigPlugin Config Plugin * @{ - * @brief Placeholder for attitude settings widget until board connected. + * @brief Sparky2 hardware configuration panel *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify @@ -24,31 +25,38 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef DEFAULTHWSETTINGSt_H -#define DEFAULTHWSETTINGSt_H +#ifndef CONFIGSPARKY2HWWIDGET_H +#define CONFIGSPARKY2HWWIDGET_H -#include "ui_defaulthwsettings.h" #include "../uavobjectwidgetutils/configtaskwidget.h" -#include "extensionsystem/pluginmanager.h" -#include "uavobjectmanager.h" -#include "uavobject.h" -#include -#include -#include -class Ui_Widget; +class Ui_Sparky2HWWidget; -class DefaultHwSettingsWidget : public QWidget { +class UAVObject; + +class QWidget; + +class ConfigSparky2HWWidget : public ConfigTaskWidget { Q_OBJECT public: - explicit DefaultHwSettingsWidget(QWidget *parent = 0); - ~DefaultHwSettingsWidget(); + ConfigSparky2HWWidget(QWidget *parent = 0); + ~ConfigSparky2HWWidget(); -private slots: +protected: + virtual void refreshWidgetsValuesImpl(UAVObject *obj); + virtual void updateObjectsFromWidgetsImpl(); private: - Ui_defaulthwsettings *ui; + Ui_Sparky2HWWidget *m_ui; + + void setupCustomCombos(); + +private slots: + void usbVCPPortChanged(int index); + void usbHIDPortChanged(int index); + void flexiPortChanged(int index); + void mainPortChanged(int index); }; -#endif // DEFAULTHWSETTINGSt_H +#endif // CONFIGSPARKY2HWWIDGET_H diff --git a/ground/gcs/src/plugins/config/configsparky2hwwidget.ui b/ground/gcs/src/plugins/config/configsparky2hwwidget.ui new file mode 100644 index 000000000..97d32924b --- /dev/null +++ b/ground/gcs/src/plugins/config/configsparky2hwwidget.ui @@ -0,0 +1,747 @@ + + + Sparky2HWWidget + + + + 0 + 0 + 834 + 742 + + + + Form + + + + + + 0 + + + + true + + + HW settings + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + 255 + 255 + 255 + + + + + + + 232 + 232 + 232 + + + + + + + + + 255 + 255 + 255 + + + + + + + 232 + 232 + 232 + + + + + + + + + 232 + 232 + 232 + + + + + + + 232 + 232 + 232 + + + + + + + + border-color: rgb(255, 0, 0); + + + QFrame::NoFrame + + + QFrame::Plain + + + true + + + + + 0 + 0 + 796 + 731 + + + + + 12 + + + 12 + + + 12 + + + 12 + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + 75 + true + + + + Changes on this page only take effect after board reset or power cycle + + + Qt::AlignCenter + + + true + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 10 + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 80 + 10 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 120 + 10 + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 120 + 10 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 70 + 10 + + + + + + + + I2C (under) + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 120 + 10 + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 50 + 10 + + + + + + + + + + 0 + + + + + + 0 + 0 + + + + Speed + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + + + + + + + + + + + + + + + + + 0 + 0 + + + + USB VCP Function + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + + 0 + 0 + + + + USB HID Function + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + + 0 + 0 + + + + + 350 + 350 + + + + + + + :/configgadget/images/sparky2_top.png + + + false + + + Qt::AlignCenter + + + Qt::NoTextInteraction + + + + + + + Receiver Port + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + Flexi Port + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + + + + + + + + + + + + + + Speed + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + Protocol + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + Protocol + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + + + + + + + Main Port + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + + + + + + + + + + + 4 + + + + + Qt::Horizontal + + + + 369 + 20 + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + Takes you to the wiki page + + + + + + + :/core/images/helpicon.svg:/core/images/helpicon.svg + + + + 25 + 25 + + + + true + + + button:help + + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + + + + + 255 + 255 + 255 + + + + + + + 232 + 232 + 232 + + + + + + + + + 255 + 255 + 255 + + + + + + + 232 + 232 + 232 + + + + + + + + + 232 + 232 + 232 + + + + + + + 232 + 232 + 232 + + + + + + + + Send to board but don't write in SD. +Beware of not locking yourself out! + + + false + + + + + + Apply + + + + 16 + 16 + + + + false + + + button:apply + + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Applies and Saves all settings to SD. +Beware of not locking yourself out! + + + false + + + + + + Save + + + button:save + + + + + + + + + + + + + diff --git a/ground/gcs/src/plugins/config/configstabilizationwidget.cpp b/ground/gcs/src/plugins/config/configstabilizationwidget.cpp index 17a1f728b..f4691a9cc 100644 --- a/ground/gcs/src/plugins/config/configstabilizationwidget.cpp +++ b/ground/gcs/src/plugins/config/configstabilizationwidget.cpp @@ -2,7 +2,7 @@ ****************************************************************************** * * @file configstabilizationwidget.cpp - * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. * E. Lafargue & The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ @@ -27,23 +27,11 @@ */ #include "configstabilizationwidget.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "ui_stabilization.h" + +#include +#include "objectpersistence.h" -#include -#include #include "altitudeholdsettings.h" #include "stabilizationsettings.h" @@ -52,26 +40,33 @@ #include "qwt/src/qwt_plot_canvas.h" #include "qwt/src/qwt_scale_widget.h" +#include +#include +#include +#include +#include +#include +#include +#include + ConfigStabilizationWidget::ConfigStabilizationWidget(QWidget *parent) : ConfigTaskWidget(parent), - boardModel(0), m_stabSettingsBankCount(0), m_currentStabSettingsBank(0) + m_stabSettingsBankCount(0), m_currentStabSettingsBank(0) { ui = new Ui_StabilizationWidget(); ui->setupUi(this); + // must be done before auto binding ! setWikiURL("Stabilization+Configuration"); - setupExpoPlot(); - setupStabBanksGUI(); - ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); - Core::Internal::GeneralSettings *settings = pm->getObject(); + addAutoBindings(); - if (!settings->useExpertMode()) { - ui->saveStabilizationToRAM_6->setVisible(false); - } + disableMouseWheelEvents(); - autoLoadWidgets(); + connect(this, SIGNAL(enableControlsChanged(bool)), this, SLOT(enableControlsChanged(bool))); + + setupExpoPlot(); realtimeUpdates = new QTimer(this); connect(realtimeUpdates, SIGNAL(timeout()), this, SLOT(apply())); @@ -107,13 +102,17 @@ ConfigStabilizationWidget::ConfigStabilizationWidget(QWidget *parent) : ConfigTa addWidget(ui->pushButton_9); addWidget(ui->pushButton_10); addWidget(ui->pushButton_11); + addWidget(ui->pushButton_12); + addWidget(ui->pushButton_13); + addWidget(ui->pushButton_14); addWidget(ui->pushButton_20); + addWidget(ui->pushButton_21); addWidget(ui->pushButton_22); - addWidget(ui->pushButton_23); addWidget(ui->basicResponsivenessGroupBox); addWidget(ui->basicResponsivenessCheckBox); connect(ui->basicResponsivenessCheckBox, SIGNAL(toggled(bool)), this, SLOT(linkCheckBoxes(bool))); + addWidget(ui->advancedResponsivenessGroupBox); addWidget(ui->advancedResponsivenessCheckBox); connect(ui->advancedResponsivenessCheckBox, SIGNAL(toggled(bool)), this, SLOT(linkCheckBoxes(bool))); @@ -136,15 +135,12 @@ ConfigStabilizationWidget::ConfigStabilizationWidget(QWidget *parent) : ConfigTa addWidget(ui->thrustPIDScalingCurve); connect(this, SIGNAL(widgetContentsChanged(QWidget *)), this, SLOT(processLinkedWidgets(QWidget *))); - connect(this, SIGNAL(autoPilotConnected()), this, SLOT(onBoardConnected())); - addWidget(ui->expoPlot); connect(ui->expoSpinnerRoll, SIGNAL(valueChanged(int)), this, SLOT(replotExpoRoll(int))); connect(ui->expoSpinnerPitch, SIGNAL(valueChanged(int)), this, SLOT(replotExpoPitch(int))); connect(ui->expoSpinnerYaw, SIGNAL(valueChanged(int)), this, SLOT(replotExpoYaw(int))); - disableMouseWheelEvents(); - updateEnableControls(); + ui->AltitudeHold->setEnabled(false); } void ConfigStabilizationWidget::setupStabBanksGUI() @@ -239,20 +235,31 @@ ConfigStabilizationWidget::~ConfigStabilizationWidget() // Do nothing } -void ConfigStabilizationWidget::refreshWidgetsValues(UAVObject *o) +void ConfigStabilizationWidget::refreshWidgetsValuesImpl(UAVObject *obj) { - ConfigTaskWidget::refreshWidgetsValues(o); + Q_UNUSED(obj); updateThrottleCurveFromObject(); - ui->basicResponsivenessCheckBox->setChecked(ui->rateRollKp_3->value() == ui->ratePitchKp_4->value() && - ui->rateRollKi_3->value() == ui->ratePitchKi_4->value()); + // Check and update basic/advanced checkboxes only if something connected + // if something not "basic": Rate value out of slider limits or different Pitch/Roll values + if (ui->lowThrottleZeroIntegral_8->isEnabled() && !realtimeUpdates->isActive()) { + if ((ui->attitudeRollResponse->value() == ui->attitudePitchResponse->value()) && + (ui->rateRollResponse->value() == ui->ratePitchResponse->value()) && + (ui->rateRollResponse->value() <= ui->RateResponsivenessSlider->maximum()) && + (ui->ratePitchResponse->value() <= ui->RateResponsivenessSlider->maximum())) { + ui->basicResponsivenessCheckBox->setChecked(true); + ui->advancedResponsivenessCheckBox->setChecked(false); + } else { + ui->basicResponsivenessCheckBox->setChecked(false); + ui->advancedResponsivenessCheckBox->setChecked(true); + } + } } -void ConfigStabilizationWidget::updateObjectsFromWidgets() +void ConfigStabilizationWidget::updateObjectsFromWidgetsImpl() { updateObjectFromThrottleCurve(); - ConfigTaskWidget::updateObjectsFromWidgets(); } void ConfigStabilizationWidget::updateThrottleCurveFromObject() @@ -275,7 +282,7 @@ void ConfigStabilizationWidget::updateThrottleCurveFromObject() field = stabBank->getField("EnableThrustPIDScaling"); Q_ASSERT(field); - bool enabled = field->getValue() == "TRUE"; + bool enabled = field->getValue() == "True"; ui->enableThrustPIDScalingCheckBox->setChecked(enabled); ui->thrustPIDScalingCurve->setEnabled(enabled); setDirty(dirty); @@ -297,7 +304,7 @@ void ConfigStabilizationWidget::updateObjectFromThrottleCurve() field = stabBank->getField("EnableThrustPIDScaling"); Q_ASSERT(field); - field->setValue(ui->enableThrustPIDScalingCheckBox->isChecked() ? "TRUE" : "FALSE"); + field->setValue(ui->enableThrustPIDScalingCheckBox->isChecked() ? "True" : "False"); } void ConfigStabilizationWidget::setupExpoPlot() @@ -371,7 +378,7 @@ void ConfigStabilizationWidget::resetThrottleCurveToDefault() field = defaultStabBank->getField("EnableThrustPIDScaling"); Q_ASSERT(field); - bool enabled = field->getValue() == "TRUE"; + bool enabled = field->getValue() == "True"; ui->enableThrustPIDScalingCheckBox->setChecked(enabled); ui->thrustPIDScalingCurve->setEnabled(enabled); @@ -611,9 +618,11 @@ void ConfigStabilizationWidget::processLinkedWidgets(QWidget *widget) if (ui->basicResponsivenessCheckBox->isChecked()) { if (widget == ui->AttitudeResponsivenessSlider) { - ui->ratePitchKp_4->setValue(ui->AttitudeResponsivenessSlider->value()); + ui->attitudePitchResponse->setValue(ui->AttitudeResponsivenessSlider->value()); + ui->attitudeRollResponse->setValue(ui->AttitudeResponsivenessSlider->value()); } else if (widget == ui->RateResponsivenessSlider) { - ui->ratePitchKi_4->setValue(ui->RateResponsivenessSlider->value()); + ui->ratePitchResponse->setValue(ui->RateResponsivenessSlider->value()); + ui->rateRollResponse->setValue(ui->RateResponsivenessSlider->value()); } } if (ui->checkBoxLinkAcroFactors->isChecked()) { @@ -625,21 +634,20 @@ void ConfigStabilizationWidget::processLinkedWidgets(QWidget *widget) } } -void ConfigStabilizationWidget::onBoardConnected() +void ConfigStabilizationWidget::enableControlsChanged(bool enable) { - ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); - UAVObjectUtilManager *utilMngr = pm->getObject(); + // If Revolution/Sparky2 board enable Althold tab, otherwise disable it + bool enableAltitudeHold = (((boardModel() & 0xff00) == 0x0900) || ((boardModel() & 0xff00) == 0x9200)); - Q_ASSERT(utilMngr); - boardModel = utilMngr->getBoardModel(); - // If Revolution board enable Althold tab, otherwise disable it - ui->AltitudeHold->setEnabled((boardModel & 0xff00) == 0x0900); + ui->AltitudeHold->setEnabled(enable && enableAltitudeHold); } void ConfigStabilizationWidget::stabBankChanged(int index) { bool dirty = isDirty(); + disconnect(this, SIGNAL(widgetContentsChanged(QWidget *)), this, SLOT(processLinkedWidgets(QWidget *))); + updateObjectFromThrottleCurve(); foreach(QTabBar * tabBar, m_stabTabBars) { disconnect(tabBar, SIGNAL(currentChanged(int)), this, SLOT(stabBankChanged(int))); @@ -655,13 +663,15 @@ void ConfigStabilizationWidget::stabBankChanged(int index) m_currentStabSettingsBank = index; updateThrottleCurveFromObject(); + + connect(this, SIGNAL(widgetContentsChanged(QWidget *)), this, SLOT(processLinkedWidgets(QWidget *))); setDirty(dirty); } bool ConfigStabilizationWidget::shouldObjectBeSaved(UAVObject *object) { - // AltitudeHoldSettings should only be saved for Revolution board to avoid error. - if ((boardModel & 0xff00) != 0x0900) { + // AltitudeHoldSettings should only be saved for Revolution/Sparky2 board to avoid error. + if (((boardModel() & 0xff00) != 0x0900) && ((boardModel() & 0xff00) != 0x9200)) { return dynamic_cast(object) == 0; } else { return true; diff --git a/ground/gcs/src/plugins/config/configstabilizationwidget.h b/ground/gcs/src/plugins/config/configstabilizationwidget.h index 1698af188..f0a12b451 100644 --- a/ground/gcs/src/plugins/config/configstabilizationwidget.h +++ b/ground/gcs/src/plugins/config/configstabilizationwidget.h @@ -2,7 +2,8 @@ ****************************************************************************** * * @file configstabilizationwidget.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup ConfigPlugin Config Plugin @@ -27,26 +28,36 @@ #ifndef CONFIGSTABILIZATIONWIDGET_H #define CONFIGSTABILIZATIONWIDGET_H -#include "ui_stabilization.h" #include "../uavobjectwidgetutils/configtaskwidget.h" -#include "extensionsystem/pluginmanager.h" -#include "uavobjectmanager.h" + #include "uavobject.h" -#include "stabilizationsettings.h" -#include -#include -#include + #include "qwt/src/qwt_plot_curve.h" #include "qwt/src/qwt_plot_grid.h" +#include +#include + +class Ui_StabilizationWidget; + +class QWidget; +class QTabBar; + class ConfigStabilizationWidget : public ConfigTaskWidget { Q_OBJECT public: ConfigStabilizationWidget(QWidget *parent = 0); ~ConfigStabilizationWidget(); + bool shouldObjectBeSaved(UAVObject *object); +protected: + QString mapObjectName(const QString objectName); + + virtual void refreshWidgetsValuesImpl(UAVObject *obj); + virtual void updateObjectsFromWidgetsImpl(); + private: Ui_StabilizationWidget *ui; QTimer *realtimeUpdates; @@ -57,9 +68,8 @@ private: static const int AUTOMATIC_UPDATE_RATE = 500; static const int EXPO_CURVE_POINTS_COUNT = 100; - static const double EXPO_CURVE_CONSTANT = 1.00695; + constexpr static const double EXPO_CURVE_CONSTANT = 1.01395948; - int boardModel; int m_stabSettingsBankCount; int m_currentStabSettingsBank; @@ -80,18 +90,12 @@ private: void resetStabBank(int bank); void restoreStabBank(int bank); -protected: - QString mapObjectName(const QString objectName); - -protected slots: - void refreshWidgetsValues(UAVObject *o = NULL); - void updateObjectsFromWidgets(); - private slots: + void enableControlsChanged(bool enable); + void realtimeUpdatesSlot(bool value); void linkCheckBoxes(bool value); void processLinkedWidgets(QWidget *); - void onBoardConnected(); void stabBankChanged(int index); void resetThrottleCurveToDefault(); void throttleCurveUpdated(); diff --git a/ground/gcs/src/plugins/config/configtxpidwidget.cpp b/ground/gcs/src/plugins/config/configtxpidwidget.cpp index 59acb17a6..9d1336068 100644 --- a/ground/gcs/src/plugins/config/configtxpidwidget.cpp +++ b/ground/gcs/src/plugins/config/configtxpidwidget.cpp @@ -27,6 +27,9 @@ */ #include "configtxpidwidget.h" + +#include "ui_txpid.h" + #include "txpidsettings.h" #include "hwsettings.h" #include "attitudesettings.h" @@ -34,33 +37,20 @@ #include "stabilizationsettingsbank1.h" #include "stabilizationsettingsbank2.h" #include "stabilizationsettingsbank3.h" -#include -#include ConfigTxPIDWidget::ConfigTxPIDWidget(QWidget *parent) : ConfigTaskWidget(parent) { m_txpid = new Ui_TxPIDWidget(); m_txpid->setupUi(this); + // must be done before auto binding ! setWikiURL("TxPID"); - ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); - Core::Internal::GeneralSettings *settings = pm->getObject(); - if (!settings->useExpertMode()) { - m_txpid->Apply->setVisible(false); - } - autoLoadWidgets(); - addApplySaveButtons(m_txpid->Apply, m_txpid->Save); - // Cannot use addUAVObjectToWidgetRelation() for OptionaModules enum because - // QCheckBox returns bool (0 or -1) and this value is then set to enum instead - // or enum options - connect(HwSettings::GetInstance(getObjectManager()), SIGNAL(objectUpdated(UAVObject *)), this, SLOT(refreshValues())); - connect(m_txpid->Apply, SIGNAL(clicked()), this, SLOT(applySettings())); - connect(m_txpid->Save, SIGNAL(clicked()), this, SLOT(saveSettings())); + addAutoBindings(); - connect(m_txpid->PID1, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSpinBoxProperties(int))); - connect(m_txpid->PID2, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSpinBoxProperties(int))); - connect(m_txpid->PID3, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSpinBoxProperties(int))); + disableMouseWheelEvents(); + + addUAVObject("HwSettings"); addWidgetBinding("TxPIDSettings", "BankNumber", m_txpid->pidBank, 0, 1, true); @@ -90,15 +80,14 @@ ConfigTxPIDWidget::ConfigTxPIDWidget(QWidget *parent) : ConfigTaskWidget(parent) addWidgetBinding("TxPIDSettings", "UpdateMode", m_txpid->UpdateMode); - connect(this, SIGNAL(widgetContentsChanged(QWidget *)), this, SLOT(processLinkedWidgets(QWidget *))); - addWidget(m_txpid->TxPIDEnable); addWidget(m_txpid->enableAutoCalcYaw); - enableControls(false); - populateWidgets(); - refreshWidgetsValues(); - disableMouseWheelEvents(); + connect(m_txpid->PID1, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSpinBoxProperties(int))); + connect(m_txpid->PID2, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSpinBoxProperties(int))); + connect(m_txpid->PID3, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSpinBoxProperties(int))); + + connect(this, SIGNAL(widgetContentsChanged(QWidget *)), this, SLOT(processLinkedWidgets(QWidget *))); } ConfigTxPIDWidget::~ConfigTxPIDWidget() @@ -106,6 +95,40 @@ ConfigTxPIDWidget::~ConfigTxPIDWidget() // Do nothing } +/* + * This overridden function refreshes widgets which have no direct relation + * to any of UAVObjects. It saves their dirty state first because update comes + * from UAVObjects, and then restores it. + */ +void ConfigTxPIDWidget::refreshWidgetsValuesImpl(UAVObject *obj) +{ + Q_UNUSED(obj); + + // Set module enable checkbox from OptionalModules UAVObject item. + // It needs special processing because ConfigTaskWidget uses TRUE/FALSE + // for QCheckBox, but OptionalModules uses Enabled/Disabled enum values. + HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager()); + + m_txpid->TxPIDEnable->setChecked( + hwSettings->getOptionalModules(HwSettings::OPTIONALMODULES_TXPID) == HwSettings::OPTIONALMODULES_ENABLED); +} + +/* + * This overridden function updates UAVObjects which have no direct relation + * to any of widgets. + */ +void ConfigTxPIDWidget::updateObjectsFromWidgetsImpl() +{ + // Save state of the module enable checkbox first. + // Do not use setData() member on whole object, if possible, since it triggers unnecessary UAVObect update. + quint8 enableModule = m_txpid->TxPIDEnable->isChecked() ? + HwSettings::OPTIONALMODULES_ENABLED : HwSettings::OPTIONALMODULES_DISABLED; + HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager()); + + hwSettings->setOptionalModules(HwSettings::OPTIONALMODULES_TXPID, enableModule); +} + + static bool isResponsivenessOption(int pidOption) { switch (pidOption) { @@ -419,12 +442,12 @@ void ConfigTxPIDWidget::updateSpinBoxProperties(int selectedPidOption) minPID->setDecimals(0); maxPID->setDecimals(0); } else if (isAcroPlusFactorOption(selectedPidOption)) { - minPID->setRange(0, 1); - maxPID->setRange(0, 1); - minPID->setSingleStep(0.01); - maxPID->setSingleStep(0.01); - minPID->setDecimals(2); - maxPID->setDecimals(2); + minPID->setRange(0, 100); + maxPID->setRange(0, 100); + minPID->setSingleStep(1); + maxPID->setSingleStep(1); + minPID->setDecimals(0); + maxPID->setDecimals(0); } else { minPID->setRange(0, 99.99); maxPID->setRange(0, 99.99); @@ -440,32 +463,6 @@ void ConfigTxPIDWidget::updateSpinBoxProperties(int selectedPidOption) maxPID->setValue(value); } -void ConfigTxPIDWidget::refreshValues() -{ - HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager()); - HwSettings::DataFields hwSettingsData = hwSettings->getData(); - - m_txpid->TxPIDEnable->setChecked( - hwSettingsData.OptionalModules[HwSettings::OPTIONALMODULES_TXPID] == HwSettings::OPTIONALMODULES_ENABLED); -} - -void ConfigTxPIDWidget::applySettings() -{ - HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager()); - HwSettings::DataFields hwSettingsData = hwSettings->getData(); - - hwSettingsData.OptionalModules[HwSettings::OPTIONALMODULES_TXPID] = - m_txpid->TxPIDEnable->isChecked() ? HwSettings::OPTIONALMODULES_ENABLED : HwSettings::OPTIONALMODULES_DISABLED; - hwSettings->setData(hwSettingsData); -} - -void ConfigTxPIDWidget::saveSettings() -{ - applySettings(); - UAVObject *obj = HwSettings::GetInstance(getObjectManager()); - saveObjectToSD(obj); -} - void ConfigTxPIDWidget::processLinkedWidgets(QWidget *widget) { Q_UNUSED(widget); diff --git a/ground/gcs/src/plugins/config/configtxpidwidget.h b/ground/gcs/src/plugins/config/configtxpidwidget.h index 2073fd438..87e0a2513 100644 --- a/ground/gcs/src/plugins/config/configtxpidwidget.h +++ b/ground/gcs/src/plugins/config/configtxpidwidget.h @@ -27,24 +27,28 @@ #ifndef CONFIGTXPIDWIDGET_H #define CONFIGTXPIDWIDGET_H -#include "ui_txpid.h" #include "configtaskwidget.h" +class Ui_TxPIDWidget; + class ConfigTxPIDWidget : public ConfigTaskWidget { Q_OBJECT public: ConfigTxPIDWidget(QWidget *parent = 0); ~ConfigTxPIDWidget(); + +protected: + virtual void refreshWidgetsValuesImpl(UAVObject *obj); + virtual void updateObjectsFromWidgetsImpl(); + private: Ui_TxPIDWidget *m_txpid; + private slots: void processLinkedWidgets(QWidget *widget); void updateSpinBoxProperties(int selectedPidOption); float getDefaultValueForPidOption(int pidOption); - void refreshValues(); - void applySettings(); - void saveSettings(); }; #endif // CONFIGTXPIDWIDGET_H diff --git a/ground/gcs/src/plugins/config/configvehicletypewidget.cpp b/ground/gcs/src/plugins/config/configvehicletypewidget.cpp index 8d2e15cca..69ec26829 100644 --- a/ground/gcs/src/plugins/config/configvehicletypewidget.cpp +++ b/ground/gcs/src/plugins/config/configvehicletypewidget.cpp @@ -26,9 +26,14 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "configvehicletypewidget.h" + +#include "ui_airframe.h" + +#include "configgadgetfactory.h" +#include + #include "systemsettings.h" #include "actuatorsettings.h" -#include "configgadgetfactory.h" #include "cfg_vehicletypes/configccpmwidget.h" #include "cfg_vehicletypes/configfixedwingwidget.h" @@ -41,14 +46,7 @@ #include #include #include -#include -#include #include -#include -#include - -#include -#include /** Static function to get currently assigned channelDescriptions @@ -117,12 +115,14 @@ ConfigVehicleTypeWidget::ConfigVehicleTypeWidget(QWidget *parent) : ConfigTaskWi m_aircraft = new Ui_AircraftWidget(); m_aircraft->setupUi(this); - ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); - Core::Internal::GeneralSettings *settings = pm->getObject(); - if (!settings->useExpertMode()) { - m_aircraft->saveAircraftToRAM->setVisible(false); - } + // must be done before auto binding ! + setWikiURL("Vehicle+Configuration"); + addAutoBindings(); + + disableMouseWheelEvents(); + + ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); ConfigGadgetFactory *configGadgetFactory = pm->getObject(); connect(m_aircraft->vehicleSetupWizardButton, SIGNAL(clicked()), configGadgetFactory, SIGNAL(onOpenVehicleConfigurationWizard())); @@ -130,31 +130,22 @@ ConfigVehicleTypeWidget::ConfigVehicleTypeWidget(QWidget *parent) : ConfigTaskWi Q_ASSERT(syssettings); m_aircraft->nameEdit->setMaxLength(syssettings->VEHICLENAME_NUMELEM); - addApplySaveButtons(m_aircraft->saveAircraftToRAM, m_aircraft->saveAircraftToSD); - addUAVObject("SystemSettings"); addUAVObject("MixerSettings"); addUAVObject("ActuatorSettings"); - // The order of the tabs is important since they correspond with the AirframCategory enum + addWidget(m_aircraft->nameEdit); + + // The order of the tabs is important since they correspond with the AirframeCategory enum m_aircraft->aircraftType->addTab(tr("Multirotor")); m_aircraft->aircraftType->addTab(tr("Fixed Wing")); m_aircraft->aircraftType->addTab(tr("Helicopter")); m_aircraft->aircraftType->addTab(tr("Ground")); m_aircraft->aircraftType->addTab(tr("Custom")); + // switchAirframeType(0); // Connect aircraft type selection dropbox to callback function connect(m_aircraft->aircraftType, SIGNAL(currentChanged(int)), this, SLOT(switchAirframeType(int))); - - // Connect the help pushbutton - connect(m_aircraft->airframeHelp, SIGNAL(clicked()), this, SLOT(openHelp())); - - refreshWidgetsValues(); - - addWidget(m_aircraft->nameEdit); - - disableMouseWheelEvents(); - updateEnableControls(); } /** @@ -168,23 +159,22 @@ ConfigVehicleTypeWidget::~ConfigVehicleTypeWidget() void ConfigVehicleTypeWidget::switchAirframeType(int index) { m_aircraft->airframesWidget->setCurrentWidget(getVehicleConfigWidget(index)); + setDirty(true); } /** - Refreshes the current value of the SystemSettings which holds the aircraft type - Note: The default behavior of ConfigTaskWidget is bypassed. - Therefore no automatic synchronization of UAV Objects to UI is done. + Refreshes the current value of the SystemSettings which holds the aircraft type. + Note: no widgets are bound so the default behavior of ConfigTaskWidget will not do much. + Almost everything is handled here to the exception of one case (see ConfigCustomWidget...) */ -void ConfigVehicleTypeWidget::refreshWidgetsValues(UAVObject *object) +void ConfigVehicleTypeWidget::refreshWidgetsValuesImpl(UAVObject *obj) { - ConfigTaskWidget::refreshWidgetsValues(object); + Q_UNUSED(obj); if (!allObjectsUpdated()) { return; } - bool dirty = isDirty(); - // Get the Airframe type from the system settings: UAVDataObject *system = dynamic_cast(getObjectManager()->getObject(QString("SystemSettings"))); Q_ASSERT(system); @@ -230,8 +220,6 @@ void ConfigVehicleTypeWidget::refreshWidgetsValues(UAVObject *object) } } m_aircraft->nameEdit->setText(name); - - setDirty(dirty); } /** @@ -240,11 +228,8 @@ void ConfigVehicleTypeWidget::refreshWidgetsValues(UAVObject *object) We do all the tasks common to all airframes, or family of airframes, and we call additional methods for specific frames, so that we do not have a code that is too heavy. - - Note: The default behavior of ConfigTaskWidget is bypassed. - Therefore no automatic synchronization of UI to UAV Objects is done. */ -void ConfigVehicleTypeWidget::updateObjectsFromWidgets() +void ConfigVehicleTypeWidget::updateObjectsFromWidgetsImpl() { // Airframe type defaults to Custom QString airframeType = "Custom"; @@ -259,7 +244,7 @@ void ConfigVehicleTypeWidget::updateObjectsFromWidgets() UAVDataObject *system = dynamic_cast(getObjectManager()->getObject(QString("SystemSettings"))); Q_ASSERT(system); - QPointer field = system->getField(QString("AirframeType")); + UAVObjectField *field = system->getField(QString("AirframeType")); if (field) { field->setValue(airframeType); } @@ -276,8 +261,8 @@ void ConfigVehicleTypeWidget::updateObjectsFromWidgets() } // call refreshWidgetsValues() to reflect actual saved values + // TODO is this needed ? refreshWidgetsValues(); - ConfigTaskWidget::updateObjectsFromWidgets(); } int ConfigVehicleTypeWidget::frameCategory(QString frameType) @@ -308,46 +293,52 @@ int ConfigVehicleTypeWidget::frameCategory(QString frameType) VehicleConfig *ConfigVehicleTypeWidget::getVehicleConfigWidget(int frameCategory) { - VehicleConfig *vehiculeConfig; + VehicleConfig *vehicleConfig; if (!m_vehicleIndexMap.contains(frameCategory)) { // create config widget - vehiculeConfig = createVehicleConfigWidget(frameCategory); - // bind config widget "field" to this ConfigTaskWodget - // this is necessary to get "dirty" state management - vehiculeConfig->registerWidgets(*this); + vehicleConfig = createVehicleConfigWidget(frameCategory); // add config widget to UI - int index = m_aircraft->airframesWidget->insertWidget(m_aircraft->airframesWidget->count(), vehiculeConfig); + int index = m_aircraft->airframesWidget->insertWidget(m_aircraft->airframesWidget->count(), vehicleConfig); m_vehicleIndexMap[frameCategory] = index; + + // and enable controls (needed?) updateEnableControls(); } int index = m_vehicleIndexMap.value(frameCategory); - vehiculeConfig = (VehicleConfig *)m_aircraft->airframesWidget->widget(index); - return vehiculeConfig; + vehicleConfig = (VehicleConfig *)m_aircraft->airframesWidget->widget(index); + return vehicleConfig; } VehicleConfig *ConfigVehicleTypeWidget::createVehicleConfigWidget(int frameCategory) { - if (frameCategory == ConfigVehicleTypeWidget::FIXED_WING) { - return new ConfigFixedWingWidget(); - } else if (frameCategory == ConfigVehicleTypeWidget::MULTIROTOR) { - return new ConfigMultiRotorWidget(); - } else if (frameCategory == ConfigVehicleTypeWidget::HELICOPTER) { - return new ConfigCcpmWidget(); - } else if (frameCategory == ConfigVehicleTypeWidget::GROUND) { - return new ConfigGroundVehicleWidget(); - } else if (frameCategory == ConfigVehicleTypeWidget::CUSTOM) { - return new ConfigCustomWidget(); - } - return NULL; -} + VehicleConfig *vehicleConfig; -/** - Opens the wiki from the user's default browser - */ -void ConfigVehicleTypeWidget::openHelp() -{ - QDesktopServices::openUrl(QUrl(QString(WIKI_URL_ROOT) + QString("Vehicle+Configuration"), - QUrl::StrictMode)); + switch (frameCategory) { + case ConfigVehicleTypeWidget::FIXED_WING: + vehicleConfig = new ConfigFixedWingWidget(); + break; + case ConfigVehicleTypeWidget::MULTIROTOR: + vehicleConfig = new ConfigMultiRotorWidget(); + break; + case ConfigVehicleTypeWidget::HELICOPTER: + vehicleConfig = new ConfigCcpmWidget(); + break; + case ConfigVehicleTypeWidget::GROUND: + vehicleConfig = new ConfigGroundVehicleWidget(); + break; + case ConfigVehicleTypeWidget::CUSTOM: + vehicleConfig = new ConfigCustomWidget(); + break; + default: + vehicleConfig = NULL; + break; + } + if (vehicleConfig) { + // bind config widget "field" to this ConfigTaskWodget + // this is necessary to get "dirty" state management + vehicleConfig->registerWidgets(*this); + } + return vehicleConfig; } diff --git a/ground/gcs/src/plugins/config/configvehicletypewidget.h b/ground/gcs/src/plugins/config/configvehicletypewidget.h index 28e8beaf7..1885cdbb7 100644 --- a/ground/gcs/src/plugins/config/configvehicletypewidget.h +++ b/ground/gcs/src/plugins/config/configvehicletypewidget.h @@ -28,28 +28,20 @@ #ifndef CONFIGVEHICLETYPEWIDGET_H #define CONFIGVEHICLETYPEWIDGET_H -#include "ui_airframe.h" #include "cfg_vehicletypes/vehicleconfig.h" #include "uavobject.h" #include "../uavobjectwidgetutils/configtaskwidget.h" -#include #include #include #include -#include -#include -#include -#include +class Ui_AircraftWidget; -class Ui_Widget; +class QWidget; /* - * This class derives from ConfigTaskWidget and overrides its default "binding" mechanism. - * This widget bypasses automatic synchronization of UAVObjects and UI by providing its own implementations of - * virtual void refreshWidgetsValues(UAVObject *obj = NULL); - * virtual void updateObjectsFromWidgets(); + * This class derives from ConfigTaskWidget but almost bypasses the need its default "binding" mechanism. * * It does use the "dirty" state management and registers its relevant widgets with ConfigTaskWidget to do so. * @@ -57,7 +49,6 @@ class Ui_Widget; * Note: for "dirty" state management it is important to register the fields of child widgets with the parent * ConfigVehicleTypeWidget class. * - * TODO consider to call "super" to benefit from default logic... * TODO improve handling of relationship with VehicleConfig derived classes (i.e. ConfigTaskWidget within ConfigTaskWidget) */ class ConfigVehicleTypeWidget : public ConfigTaskWidget { @@ -69,9 +60,9 @@ public: ConfigVehicleTypeWidget(QWidget *parent = 0); ~ConfigVehicleTypeWidget(); -protected slots: - virtual void refreshWidgetsValues(UAVObject *object = NULL); - virtual void updateObjectsFromWidgets(); +protected: + virtual void refreshWidgetsValuesImpl(UAVObject *obj); + virtual void updateObjectsFromWidgetsImpl(); private: Ui_AircraftWidget *m_aircraft; @@ -89,7 +80,6 @@ private: private slots: void switchAirframeType(int index); - void openHelp(); }; #endif // CONFIGVEHICLETYPEWIDGET_H diff --git a/ground/gcs/src/plugins/config/defaultattitude.ui b/ground/gcs/src/plugins/config/defaultattitude.ui deleted file mode 100644 index 06676035e..000000000 --- a/ground/gcs/src/plugins/config/defaultattitude.ui +++ /dev/null @@ -1,77 +0,0 @@ - - - defaultattitude - - - - 0 - 0 - 400 - 300 - - - - Form - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt; font-weight:600;">Attitude Calibration</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu'; font-size:11pt; font-weight:600;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt;">This panel will be updated to provide the relevant controls to let you calibrate your flight controller, depending on the board which is detected once telemetry is connected and running.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu'; font-size:11pt;"><br /></p></body></html> - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - diff --git a/ground/gcs/src/plugins/config/defaultconfig.ui b/ground/gcs/src/plugins/config/defaultconfig.ui new file mode 100644 index 000000000..5ce839fac --- /dev/null +++ b/ground/gcs/src/plugins/config/defaultconfig.ui @@ -0,0 +1,267 @@ + + + defaultconfig + + + + 0 + 0 + 646 + 596 + + + + Form + + + + + + 0 + + + + <place holder - do not translate> + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + 255 + 255 + 255 + + + + + + + 232 + 232 + 232 + + + + + + + + + 255 + 255 + 255 + + + + + + + 232 + 232 + 232 + + + + + + + + + 232 + 232 + 232 + + + + + + + 232 + 232 + 232 + + + + + + + + QFrame::NoFrame + + + QFrame::Plain + + + true + + + + + 0 + 0 + 622 + 519 + + + + + 12 + + + 12 + + + 12 + + + 12 + + + + + Qt::Vertical + + + + 20 + 25 + + + + + + + + + 0 + 0 + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + QAbstractScrollArea::AdjustToContents + + + QTextEdit::WidgetWidth + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">This panel will be updated to provide the relevant controls to let you configure your device once it is connected and running.</span></p></body></html> + + + + + + + + + + + + + + + 4 + + + + + Qt::Horizontal + + + + 369 + 20 + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + Takes you to the wiki page + + + + + + + :/core/images/helpicon.svg:/core/images/helpicon.svg + + + + 25 + 25 + + + + true + + + + + + + Apply + + + + + + + Save + + + + + + + + + + + + diff --git a/ground/gcs/src/plugins/config/defaultattitudewidget.h b/ground/gcs/src/plugins/config/defaultconfigwidget.cpp similarity index 56% rename from ground/gcs/src/plugins/config/defaultattitudewidget.h rename to ground/gcs/src/plugins/config/defaultconfigwidget.cpp index 5703e4498..4c3d93900 100644 --- a/ground/gcs/src/plugins/config/defaultattitudewidget.h +++ b/ground/gcs/src/plugins/config/defaultconfigwidget.cpp @@ -1,13 +1,13 @@ /** ****************************************************************************** * - * @file defaultccattitudewidget.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @file defaultconfigwidget.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup ConfigPlugin Config Plugin * @{ - * @brief Placeholder for attitude settings widget until board connected. + * @brief Placeholder for config widget until board connected. *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify @@ -24,31 +24,24 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef DEFAULTATTITUDEWIDGET_H -#define DEFAULTATTITUDEWIDGET_H +#include "defaultconfigwidget.h" -#include "ui_defaultattitude.h" -#include "../uavobjectwidgetutils/configtaskwidget.h" -#include "extensionsystem/pluginmanager.h" -#include "uavobjectmanager.h" -#include "uavobject.h" -#include -#include -#include +#include "ui_defaultconfig.h" -class Ui_Widget; +DefaultConfigWidget::DefaultConfigWidget(QWidget *parent, QString title) : QWidget(parent) +{ + ui = new Ui_defaultconfig(); + ui->setupUi(this); -class DefaultAttitudeWidget : public QWidget { - Q_OBJECT + ui->tabWidget->setTabText(0, title); -public: - explicit DefaultAttitudeWidget(QWidget *parent = 0); - ~DefaultAttitudeWidget(); + ui->helpButton->setEnabled(false); + ui->saveButton->setEnabled(false); + ui->applyButton->setVisible(false); + ui->applyButton->setEnabled(false); +} -private slots: - -private: - Ui_defaultattitude *ui; -}; - -#endif // DEFAULTATTITUDEWIDGET_H +DefaultConfigWidget::~DefaultConfigWidget() +{ + delete ui; +} diff --git a/ground/gcs/src/plugins/config/defaultattitudewidget.cpp b/ground/gcs/src/plugins/config/defaultconfigwidget.h similarity index 64% rename from ground/gcs/src/plugins/config/defaultattitudewidget.cpp rename to ground/gcs/src/plugins/config/defaultconfigwidget.h index e221aebe2..7079fdc93 100644 --- a/ground/gcs/src/plugins/config/defaultattitudewidget.cpp +++ b/ground/gcs/src/plugins/config/defaultconfigwidget.h @@ -1,13 +1,13 @@ /** ****************************************************************************** * - * @file defaultattitudewidget.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @file defaultconfigwidget.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup ConfigPlugin Config Plugin * @{ - * @brief Placeholder for attitude panel until board is connected. + * @brief Placeholder for config widget until board connected. *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify @@ -24,20 +24,22 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "defaultattitudewidget.h" -#include "ui_defaultattitude.h" -#include -#include -#include +#ifndef DEFAULTCONFIGWIDGET_H +#define DEFAULTCONFIGWIDGET_H -DefaultAttitudeWidget::DefaultAttitudeWidget(QWidget *parent) : - QWidget(parent), - ui(new Ui_defaultattitude) -{ - ui->setupUi(this); -} +#include -DefaultAttitudeWidget::~DefaultAttitudeWidget() -{ - delete ui; -} +class Ui_defaultconfig; + +class DefaultConfigWidget : public QWidget { + Q_OBJECT + +public: + explicit DefaultConfigWidget(QWidget *parent, QString title); + ~DefaultConfigWidget(); + +private: + Ui_defaultconfig *ui; +}; + +#endif // DEFAULTCONFIGWIDGET_H diff --git a/ground/gcs/src/plugins/config/defaulthwsettings.ui b/ground/gcs/src/plugins/config/defaulthwsettings.ui deleted file mode 100644 index b4272ab22..000000000 --- a/ground/gcs/src/plugins/config/defaulthwsettings.ui +++ /dev/null @@ -1,80 +0,0 @@ - - - defaulthwsettings - - - - 0 - 0 - 400 - 300 - - - - Form - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - true - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt; font-weight:600;">Hardware Configuration</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu'; font-size:11pt; font-weight:600;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt;">This panel will be updated to provide the relevant controls to let you configure your hardware once telemetry is connected and running.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu'; font-size:11pt;"><br /></p></body></html> - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - diff --git a/ground/gcs/src/plugins/config/failsafechannelform.cpp b/ground/gcs/src/plugins/config/failsafechannelform.cpp new file mode 100644 index 000000000..5db5fdf0c --- /dev/null +++ b/ground/gcs/src/plugins/config/failsafechannelform.cpp @@ -0,0 +1,24 @@ +#include "failsafechannelform.h" +#include "ui_failsafechannelform.h" + +FailsafeChannelForm::FailsafeChannelForm(const int index, QWidget *parent) : + ChannelForm(index, parent), ui(new Ui::FailsafeChannelForm) +{ + ui->setupUi(this); + disableMouseWheelEvents(); +} + +FailsafeChannelForm::~FailsafeChannelForm() +{ + delete ui; +} + +QString FailsafeChannelForm::name() +{ + return ui->channelName->text(); +} + +void FailsafeChannelForm::setName(const QString &name) +{ + ui->channelName->setText(name); +} diff --git a/ground/gcs/src/plugins/config/failsafechannelform.h b/ground/gcs/src/plugins/config/failsafechannelform.h new file mode 100644 index 000000000..0e4f3b341 --- /dev/null +++ b/ground/gcs/src/plugins/config/failsafechannelform.h @@ -0,0 +1,29 @@ +#ifndef FAILSAFECHANNELFORM_H +#define FAILSAFECHANNELFORM_H + +#include "channelform.h" +#include "configinputwidget.h" + +#include + +namespace Ui { +class FailsafeChannelForm; +} + +class FailsafeChannelForm : public ChannelForm { + Q_OBJECT + +public: + explicit FailsafeChannelForm(const int index, QWidget *parent = NULL); + ~FailsafeChannelForm(); + + friend class ConfigInputWidget; + + virtual QString name(); + virtual void setName(const QString &name); + +private: + Ui::FailsafeChannelForm *ui; +}; + +#endif // FAILSAFECHANNELFORM_H diff --git a/ground/gcs/src/plugins/config/failsafechannelform.ui b/ground/gcs/src/plugins/config/failsafechannelform.ui new file mode 100644 index 000000000..5ee101f9e --- /dev/null +++ b/ground/gcs/src/plugins/config/failsafechannelform.ui @@ -0,0 +1,284 @@ + + + FailsafeChannelForm + + + + 0 + 0 + 993 + 57 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 12 + + + + + true + + + + 0 + 0 + + + + + 0 + 20 + + + + + -1 + 75 + false + true + + + + Channel value + + + 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; + + + QFrame::StyledPanel + + + Channel Value relative to channel Neutral + + + Qt::AlignCenter + + + + + + + Channel value + + + 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; + + + Value + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + Qt::StrongFocus + + + Channel value in % + + + + + + + + + Qt::ImhNone + + + -100 + + + 100 + + + Qt::Horizontal + + + QSlider::TicksBothSides + + + 10 + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + false + + + % + + + -100 + + + 100 + + + 0 + + + + + + + true + + + + 0 + 0 + + + + + 0 + 20 + + + + + -1 + 75 + false + true + + + + Channel function + + + 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; + + + QFrame::StyledPanel + + + Function + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + + 16777215 + 16777215 + + + + Text + + + + + + + + TextBubbleSlider + QSlider +
utils/textbubbleslider.h
+
+
+ + channelValue + + + + + channelValue + valueChanged(int) + channelValueSpinner + setValue(int) + + + 530 + 43 + + + 965 + 43 + + + + + channelValueSpinner + valueChanged(int) + channelValue + setValue(int) + + + 965 + 43 + + + 530 + 43 + + + + +
diff --git a/ground/gcs/src/plugins/config/images/AHRS-v1.3.png b/ground/gcs/src/plugins/config/images/AHRS-v1.3.png index a12089c6f..7fff066e5 100644 Binary files a/ground/gcs/src/plugins/config/images/AHRS-v1.3.png and b/ground/gcs/src/plugins/config/images/AHRS-v1.3.png differ diff --git a/ground/gcs/src/plugins/config/images/Airframe.png b/ground/gcs/src/plugins/config/images/Airframe.png index b2a181c94..b338a0974 100644 Binary files a/ground/gcs/src/plugins/config/images/Airframe.png and b/ground/gcs/src/plugins/config/images/Airframe.png differ diff --git a/ground/gcs/src/plugins/config/images/PipXtreme.png b/ground/gcs/src/plugins/config/images/PipXtreme.png index cd9396e6c..c53214811 100644 Binary files a/ground/gcs/src/plugins/config/images/PipXtreme.png and b/ground/gcs/src/plugins/config/images/PipXtreme.png differ diff --git a/ground/gcs/src/plugins/config/images/Servo.png b/ground/gcs/src/plugins/config/images/Servo.png index c70b46f61..bc6a3e251 100644 Binary files a/ground/gcs/src/plugins/config/images/Servo.png and b/ground/gcs/src/plugins/config/images/Servo.png differ diff --git a/ground/gcs/src/plugins/config/images/TX2.svg b/ground/gcs/src/plugins/config/images/TX2.svg index 2a740fc2c..cb5167c4c 100644 --- a/ground/gcs/src/plugins/config/images/TX2.svg +++ b/ground/gcs/src/plugins/config/images/TX2.svg @@ -13,9 +13,9 @@ version="1.1" x="0px" y="0px" - width="720" - height="828.73706" - viewBox="0 0 720 828.73706" + width="750" + height="849.99951" + viewBox="0 0 750 849.99951" enable-background="new 0 0 864 864" xml:space="preserve" id="svg2" @@ -23,8 +23,16 @@ sodipodi:docname="TX2.svg">image/svg+xml \ No newline at end of file diff --git a/ground/gcs/src/plugins/config/images/Transmitter.png b/ground/gcs/src/plugins/config/images/Transmitter.png index 55bb1ce15..a67d07b4e 100644 Binary files a/ground/gcs/src/plugins/config/images/Transmitter.png and b/ground/gcs/src/plugins/config/images/Transmitter.png differ diff --git a/ground/gcs/src/plugins/config/images/autotune_normal.png b/ground/gcs/src/plugins/config/images/autotune_normal.png index 5c7ca95f1..697e6cc9f 100644 Binary files a/ground/gcs/src/plugins/config/images/autotune_normal.png and b/ground/gcs/src/plugins/config/images/autotune_normal.png differ diff --git a/ground/gcs/src/plugins/config/images/autotune_selected.png b/ground/gcs/src/plugins/config/images/autotune_selected.png index 53fe7cf0c..b70b3d156 100644 Binary files a/ground/gcs/src/plugins/config/images/autotune_selected.png and b/ground/gcs/src/plugins/config/images/autotune_selected.png differ diff --git a/ground/gcs/src/plugins/config/images/calibration/board-dwn.png b/ground/gcs/src/plugins/config/images/calibration/board-dwn.png index 342c9a6a8..b40e5b7ab 100644 Binary files a/ground/gcs/src/plugins/config/images/calibration/board-dwn.png and b/ground/gcs/src/plugins/config/images/calibration/board-dwn.png differ diff --git a/ground/gcs/src/plugins/config/images/calibration/board-enu.png b/ground/gcs/src/plugins/config/images/calibration/board-enu.png index 52f5b5a3f..21d03b094 100644 Binary files a/ground/gcs/src/plugins/config/images/calibration/board-enu.png and b/ground/gcs/src/plugins/config/images/calibration/board-enu.png differ diff --git a/ground/gcs/src/plugins/config/images/calibration/board-ned.png b/ground/gcs/src/plugins/config/images/calibration/board-ned.png index 3fce51213..bbd90e31f 100644 Binary files a/ground/gcs/src/plugins/config/images/calibration/board-ned.png and b/ground/gcs/src/plugins/config/images/calibration/board-ned.png differ diff --git a/ground/gcs/src/plugins/config/images/calibration/board-suw.png b/ground/gcs/src/plugins/config/images/calibration/board-suw.png index 7ff62b13d..374403e44 100644 Binary files a/ground/gcs/src/plugins/config/images/calibration/board-suw.png and b/ground/gcs/src/plugins/config/images/calibration/board-suw.png differ diff --git a/ground/gcs/src/plugins/config/images/calibration/board-swd.png b/ground/gcs/src/plugins/config/images/calibration/board-swd.png index 8de324180..3271e5299 100644 Binary files a/ground/gcs/src/plugins/config/images/calibration/board-swd.png and b/ground/gcs/src/plugins/config/images/calibration/board-swd.png differ diff --git a/ground/gcs/src/plugins/config/images/calibration/board-use.png b/ground/gcs/src/plugins/config/images/calibration/board-use.png index 0fffb6cd6..bbb48c69b 100644 Binary files a/ground/gcs/src/plugins/config/images/calibration/board-use.png and b/ground/gcs/src/plugins/config/images/calibration/board-use.png differ diff --git a/ground/gcs/src/plugins/config/images/calibration/board-wds.png b/ground/gcs/src/plugins/config/images/calibration/board-wds.png index db013fae5..78c7ee3bc 100644 Binary files a/ground/gcs/src/plugins/config/images/calibration/board-wds.png and b/ground/gcs/src/plugins/config/images/calibration/board-wds.png differ diff --git a/ground/gcs/src/plugins/config/images/calibration/empty.png b/ground/gcs/src/plugins/config/images/calibration/empty.png index 061783952..5011ee372 100644 Binary files a/ground/gcs/src/plugins/config/images/calibration/empty.png and b/ground/gcs/src/plugins/config/images/calibration/empty.png differ diff --git a/ground/gcs/src/plugins/config/images/calibration/plane-dwn.png b/ground/gcs/src/plugins/config/images/calibration/plane-dwn.png index 371ef59dd..b31aa0a23 100644 Binary files a/ground/gcs/src/plugins/config/images/calibration/plane-dwn.png and b/ground/gcs/src/plugins/config/images/calibration/plane-dwn.png differ diff --git a/ground/gcs/src/plugins/config/images/calibration/plane-enu.png b/ground/gcs/src/plugins/config/images/calibration/plane-enu.png index dd0b28315..e0e61ac41 100644 Binary files a/ground/gcs/src/plugins/config/images/calibration/plane-enu.png and b/ground/gcs/src/plugins/config/images/calibration/plane-enu.png differ diff --git a/ground/gcs/src/plugins/config/images/calibration/plane-horizontal-rotated.png b/ground/gcs/src/plugins/config/images/calibration/plane-horizontal-rotated.png index 4e1601d84..7a8caf95a 100644 Binary files a/ground/gcs/src/plugins/config/images/calibration/plane-horizontal-rotated.png and b/ground/gcs/src/plugins/config/images/calibration/plane-horizontal-rotated.png differ diff --git a/ground/gcs/src/plugins/config/images/calibration/plane-ned.png b/ground/gcs/src/plugins/config/images/calibration/plane-ned.png index 56f7a2c38..1c6466595 100644 Binary files a/ground/gcs/src/plugins/config/images/calibration/plane-ned.png and b/ground/gcs/src/plugins/config/images/calibration/plane-ned.png differ diff --git a/ground/gcs/src/plugins/config/images/calibration/plane-suw.png b/ground/gcs/src/plugins/config/images/calibration/plane-suw.png index 0a3ff7fab..92b3f1d90 100644 Binary files a/ground/gcs/src/plugins/config/images/calibration/plane-suw.png and b/ground/gcs/src/plugins/config/images/calibration/plane-suw.png differ diff --git a/ground/gcs/src/plugins/config/images/calibration/plane-swd.png b/ground/gcs/src/plugins/config/images/calibration/plane-swd.png index 8786e37e2..07a782efe 100644 Binary files a/ground/gcs/src/plugins/config/images/calibration/plane-swd.png and b/ground/gcs/src/plugins/config/images/calibration/plane-swd.png differ diff --git a/ground/gcs/src/plugins/config/images/calibration/plane-use.png b/ground/gcs/src/plugins/config/images/calibration/plane-use.png index fb3ca76d1..389281b22 100644 Binary files a/ground/gcs/src/plugins/config/images/calibration/plane-use.png and b/ground/gcs/src/plugins/config/images/calibration/plane-use.png differ diff --git a/ground/gcs/src/plugins/config/images/calibration/plane-wds.png b/ground/gcs/src/plugins/config/images/calibration/plane-wds.png index 942118cb9..a1418217b 100644 Binary files a/ground/gcs/src/plugins/config/images/calibration/plane-wds.png and b/ground/gcs/src/plugins/config/images/calibration/plane-wds.png differ diff --git a/ground/gcs/src/plugins/config/images/camera.png b/ground/gcs/src/plugins/config/images/camera.png index b412c28d6..0962907e8 100644 Binary files a/ground/gcs/src/plugins/config/images/camera.png and b/ground/gcs/src/plugins/config/images/camera.png differ diff --git a/ground/gcs/src/plugins/config/images/camstab_normal.png b/ground/gcs/src/plugins/config/images/camstab_normal.png index 07cf6c6c4..61122daa1 100644 Binary files a/ground/gcs/src/plugins/config/images/camstab_normal.png and b/ground/gcs/src/plugins/config/images/camstab_normal.png differ diff --git a/ground/gcs/src/plugins/config/images/camstab_selected.png b/ground/gcs/src/plugins/config/images/camstab_selected.png index 30b82f0fe..3d565fe9a 100644 Binary files a/ground/gcs/src/plugins/config/images/camstab_selected.png and b/ground/gcs/src/plugins/config/images/camstab_selected.png differ diff --git a/ground/gcs/src/plugins/config/images/cc3d_top.png b/ground/gcs/src/plugins/config/images/cc3d_top.png index 50fac5ed0..b037c8150 100644 Binary files a/ground/gcs/src/plugins/config/images/cc3d_top.png and b/ground/gcs/src/plugins/config/images/cc3d_top.png differ diff --git a/ground/gcs/src/plugins/config/images/fixedwing-shapes.svg b/ground/gcs/src/plugins/config/images/fixedwing-shapes.svg index 1d36aa374..d9c88d775 100644 --- a/ground/gcs/src/plugins/config/images/fixedwing-shapes.svg +++ b/ground/gcs/src/plugins/config/images/fixedwing-shapes.svg @@ -487,13 +487,13 @@ inkscape:window-height="928" id="namedview4099" showgrid="false" - inkscape:zoom="1.0458791" - inkscape:cx="384.95499" - inkscape:cy="955.071" + inkscape:zoom="2.0917582" + inkscape:cx="391.2913" + inkscape:cy="1188.8255" inkscape:window-x="0" inkscape:window-y="27" inkscape:window-maximized="1" - inkscape:current-layer="elevon" + inkscape:current-layer="aileron-frame" showborder="true" inkscape:showpageshadow="false" inkscape:object-paths="true" @@ -767,32 +767,7 @@ id="path4400-5-6" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:125%;font-family:Prototype;-inkscape-font-specification:Prototype;letter-spacing:0px;word-spacing:0px;fill:#ff6000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="m 961.2594,723.76703 q 0,-0.8 0.9106,-0.8 l 7.4667,0 q 0.9106,0 0.9106,-0.8 l 0,-8.15999 q 0,-0.8 -0.9106,-0.8 l -7.4667,0 q -0.9106,0 -0.9106,-0.8 l 0,-10 q 0,-0.8 -0.9106,-0.8 l -9.2879,0 q -0.9106,0 -0.9106,0.8 l 0,10 q 0,0.8 -0.9105,0.8 l -4.8261,0 q -0.9106,0 -0.9106,0.8 l 0,8.15999 q 0,0.8 0.9106,0.8 l 4.8261,0 q 0.9105,0 0.9105,0.8 l 0,24.96001 q 0,2.48 2.2765,4.32 q 2.2764,1.84 5.7366,1.84 l 11.4733,0 q 0.9106,0 0.9106,-0.8 l 0,-8.16 q 0,-0.72 -0.7285,-0.8 l -7.6488,0 q -0.9106,0 -0.9106,-0.8 l 0,-20.56001 z" - inkscape:connector-curvature="0" />N +NE +SE +S +SW +NW +W +NE +SE +E +SW +NW +N +S +NW +NE +W +NE +SE +E +SW +NW +N +S +NE +W +NE +SE +E +SW +NW +NNE +ENE +ESE +SSE +SSW +WSW +WNW +NNW +SE +S +ENE + + \ No newline at end of file + d="M 1001.67,1438.583 L 1004.365,1438.583 L 1004.365,1421.855 L 1021.094,1421.855 L 1021.094,1438.583 L 1024.082,1438.583 L 1012.877,1449.788 L 1001.67,1438.583 z" /> \ No newline at end of file diff --git a/ground/gcs/src/plugins/config/images/nano_top.png b/ground/gcs/src/plugins/config/images/nano_top.png index 4138c6696..f408c3672 100644 Binary files a/ground/gcs/src/plugins/config/images/nano_top.png and b/ground/gcs/src/plugins/config/images/nano_top.png differ diff --git a/ground/gcs/src/plugins/config/images/output_normal.png b/ground/gcs/src/plugins/config/images/output_normal.png index f5754786c..96de72120 100644 Binary files a/ground/gcs/src/plugins/config/images/output_normal.png and b/ground/gcs/src/plugins/config/images/output_normal.png differ diff --git a/ground/gcs/src/plugins/config/images/output_selected.png b/ground/gcs/src/plugins/config/images/output_selected.png index 016272b5e..8b67f19a4 100644 Binary files a/ground/gcs/src/plugins/config/images/output_selected.png and b/ground/gcs/src/plugins/config/images/output_selected.png differ diff --git a/ground/gcs/src/plugins/config/images/pipx-normal.png b/ground/gcs/src/plugins/config/images/pipx-normal.png index 74f074689..5df0a1985 100644 Binary files a/ground/gcs/src/plugins/config/images/pipx-normal.png and b/ground/gcs/src/plugins/config/images/pipx-normal.png differ diff --git a/ground/gcs/src/plugins/config/images/pipx-selected.png b/ground/gcs/src/plugins/config/images/pipx-selected.png index ef9818a83..155705aac 100644 Binary files a/ground/gcs/src/plugins/config/images/pipx-selected.png and b/ground/gcs/src/plugins/config/images/pipx-selected.png differ diff --git a/ground/gcs/src/plugins/config/images/revolution_top.png b/ground/gcs/src/plugins/config/images/revolution_top.png index 3a6b8fbd6..9e760bbfb 100644 Binary files a/ground/gcs/src/plugins/config/images/revolution_top.png and b/ground/gcs/src/plugins/config/images/revolution_top.png differ diff --git a/ground/gcs/src/plugins/config/images/sparky2_top.png b/ground/gcs/src/plugins/config/images/sparky2_top.png new file mode 100644 index 000000000..f163756ac Binary files /dev/null and b/ground/gcs/src/plugins/config/images/sparky2_top.png differ diff --git a/ground/gcs/src/plugins/config/images/stabilization_normal.png b/ground/gcs/src/plugins/config/images/stabilization_normal.png index 7d6c750cd..8e4dc9dc0 100644 Binary files a/ground/gcs/src/plugins/config/images/stabilization_normal.png and b/ground/gcs/src/plugins/config/images/stabilization_normal.png differ diff --git a/ground/gcs/src/plugins/config/images/stabilization_selected.png b/ground/gcs/src/plugins/config/images/stabilization_selected.png index 7394f23ed..49fb0d8b9 100644 Binary files a/ground/gcs/src/plugins/config/images/stabilization_selected.png and b/ground/gcs/src/plugins/config/images/stabilization_selected.png differ diff --git a/ground/gcs/src/plugins/config/images/txpid.png b/ground/gcs/src/plugins/config/images/txpid.png index 7b2f6f035..58cea3c19 100644 Binary files a/ground/gcs/src/plugins/config/images/txpid.png and b/ground/gcs/src/plugins/config/images/txpid.png differ diff --git a/ground/gcs/src/plugins/config/images/txpid_normal.png b/ground/gcs/src/plugins/config/images/txpid_normal.png index 79d2d1d7f..c63ecd16d 100644 Binary files a/ground/gcs/src/plugins/config/images/txpid_normal.png and b/ground/gcs/src/plugins/config/images/txpid_normal.png differ diff --git a/ground/gcs/src/plugins/config/images/txpid_selected.png b/ground/gcs/src/plugins/config/images/txpid_selected.png index 0e4fe57d1..5e7d3db48 100644 Binary files a/ground/gcs/src/plugins/config/images/txpid_selected.png and b/ground/gcs/src/plugins/config/images/txpid_selected.png differ diff --git a/ground/gcs/src/plugins/config/images/vehicle_normal.png b/ground/gcs/src/plugins/config/images/vehicle_normal.png index ef96bb78d..98a732c7a 100644 Binary files a/ground/gcs/src/plugins/config/images/vehicle_normal.png and b/ground/gcs/src/plugins/config/images/vehicle_normal.png differ diff --git a/ground/gcs/src/plugins/config/images/vehicle_selected.png b/ground/gcs/src/plugins/config/images/vehicle_selected.png index 292c6026e..685fc521f 100644 Binary files a/ground/gcs/src/plugins/config/images/vehicle_selected.png and b/ground/gcs/src/plugins/config/images/vehicle_selected.png differ diff --git a/ground/gcs/src/plugins/config/input.ui b/ground/gcs/src/plugins/config/input.ui index 3d55eea17..99788d227 100644 --- a/ground/gcs/src/plugins/config/input.ui +++ b/ground/gcs/src/plugins/config/input.ui @@ -21,7 +21,7 @@ - RC Input + Remote Control Input @@ -116,8 +116,8 @@ 0 0 - 1220 - 655 + 1228 + 669 @@ -136,7 +136,7 @@ 6 - + Input Channel Configuration @@ -281,114 +281,171 @@ - - - Calibration and Configuration Options + + + 0 - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 210 - 0 - - - - Start Transmitter Setup Wizard - - - false - - - false - - - false - - - false - - - false - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - true - - - - 0 - 0 - - - - - 210 - 0 - - - - false - - - Start Manual Calibration - - - true - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - + + + + Calibration and Configuration Options + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 240 + 0 + + + + Start Transmitter Setup Wizard + + + false + + + false + + + false + + + false + + + false + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + true + + + + 0 + 0 + + + + + 240 + 0 + + + + false + + + Start Manual Calibration + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Receiver Activity + + + + + + true + + + + 300 + 30 + + + + Show receiver activity, input and channel +while moving one stick or switch at once. + + + border: 1px solid grey; +border-radius: 5; +margin:1px; +font:bold; + + + No activity + + + Qt::AlignCenter + + + + + + + @@ -490,8 +547,8 @@ 0 0 - 1220 - 655 + 773 + 587 @@ -752,62 +809,62 @@ font:bold; 1 - + Stabilized 1 - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + Qt::AlignCenter - + Stabilized 2 - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + Qt::AlignCenter - + Stabilized 3 - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + Qt::AlignCenter - + Stabilized 4 - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + Qt::AlignCenter - + Stabilized 5 - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + Qt::AlignCenter - + Stabilized 6 - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + Qt::AlignCenter @@ -1154,7 +1211,76 @@ font:bold; 6 - + + + + + 0 + 0 + + + + + 0 + 50 + + + + + 16777215 + 50 + + + + + 14 + 75 + false + true + + + + background-color: green; +color: rgb(255, 255, 255); +border-radius: 5; +margin:1px; +font:bold; + + + Config Status + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 10 + 75 + true + + + + <html><head/><body><p>Never select &quot;Manual&quot; as Flight Mode when flying a multitrotor! Never select &quot;Altitude&quot; or &quot;CruiseControl&quot; in Stabilization Modes when using a fixed wing!</p></body></html> + + + Qt::AlignCenter + + + true + + + + @@ -1392,7 +1518,7 @@ Setup the flight mode channel on the RC Input tab if you have not done so alread - + @@ -1503,7 +1629,7 @@ Setup the flight mode channel on the RC Input tab if you have not done so alread - + @@ -1545,7 +1671,7 @@ Setup the flight mode channel on the RC Input tab if you have not done so alread <html><head/><body><p>Select which set of roll rates / max bank angles / PIDs you want active on this switch position.</p></body></html> - + objname:StabilizationSettings fieldname:FlightModeMap index:0 @@ -1571,7 +1697,7 @@ Setup the flight mode channel on the RC Input tab if you have not done so alread <html><head/><body><p>Select which set of roll rates / max bank angles / PIDs you want active on this switch position.</p></body></html> - + objname:StabilizationSettings fieldname:FlightModeMap index:1 @@ -1597,7 +1723,7 @@ Setup the flight mode channel on the RC Input tab if you have not done so alread <html><head/><body><p>Select which set of roll rates / max bank angles / PIDs you want active on this switch position.</p></body></html> - + objname:StabilizationSettings fieldname:FlightModeMap index:2 @@ -1626,7 +1752,7 @@ Setup the flight mode channel on the RC Input tab if you have not done so alread <html><head/><body><p>Select which set of roll rates / max bank angles / PIDs you want active on this switch position.</p></body></html> - + objname:StabilizationSettings fieldname:FlightModeMap index:3 @@ -1655,7 +1781,7 @@ Setup the flight mode channel on the RC Input tab if you have not done so alread <html><head/><body><p>Select which set of roll rates / max bank angles / PIDs you want active on this switch position.</p></body></html> - + objname:StabilizationSettings fieldname:FlightModeMap index:4 @@ -1684,7 +1810,7 @@ Setup the flight mode channel on the RC Input tab if you have not done so alread <html><head/><body><p>Select which set of roll rates / max bank angles / PIDs you want active on this switch position.</p></body></html> - + objname:StabilizationSettings fieldname:FlightModeMap index:5 @@ -1785,32 +1911,6 @@ channel value for each flight mode. - - - - - 0 - 0 - - - - - 10 - 75 - true - - - - <html><head/><body><p>Never select &quot;Manual&quot; as Flight Mode when flying a multitrotor! Never select &quot;Altitude&quot; or &quot;CruiseControl&quot; in Stabilization Modes when using a fixed wing!</p></body></html> - - - Qt::AlignCenter - - - true - - - @@ -1859,7 +1959,7 @@ channel value for each flight mode. - + Qt::Vertical @@ -1921,7 +2021,7 @@ font:bold; - + @@ -1963,7 +2063,7 @@ font:bold; <html><head/><body><p>GPSAssist adds a brake/hold sequence to Stabilization when pitch & roll is centered, and on initiation of PositionHold. GPSAssist also enables pitch & roll control during the auto landing flight mode.</p></body></html> - + objname:StabilizationSettings fieldname:FlightModeAssistMap index:0 @@ -1989,7 +2089,7 @@ font:bold; <html><head/><body><p>GPSAssist adds a brake/hold sequence to Stabilization when pitch & roll is centered, and on initiation of PositionHold. GPSAssist also enables pitch & roll control during the auto landing flight mode.</p></body></html> - + objname:StabilizationSettings fieldname:FlightModeAssistMap index:1 @@ -2015,7 +2115,7 @@ font:bold; <html><head/><body><p>GPSAssist adds a brake/hold sequence to Stabilization when pitch & roll is centered, and on initiation of PositionHold. GPSAssist also enables pitch & roll control during the auto landing flight mode.</p></body></html> - + objname:StabilizationSettings fieldname:FlightModeAssistMap index:2 @@ -2044,7 +2144,7 @@ font:bold; <html><head/><body><p>GPSAssist adds a brake/hold sequence to Stabilization when pitch & roll is centered, and on initiation of PositionHold. GPSAssist also enables pitch & roll control during the auto landing flight mode.</p></body></html> - + objname:StabilizationSettings fieldname:FlightModeAssistMap index:3 @@ -2073,7 +2173,7 @@ font:bold; <html><head/><body><p>GPSAssist adds a brake/hold sequence to Stabilization when pitch & roll is centered, and on initiation of PositionHold. GPSAssist also enables pitch & roll control during the auto landing flight mode.</p></body></html> - + objname:StabilizationSettings fieldname:FlightModeAssistMap index:4 @@ -2102,7 +2202,7 @@ font:bold; <html><head/><body><p>GPSAssist adds a brake/hold sequence to Stabilization when pitch & roll is centered, and on initiation of PositionHold. GPSAssist also enables pitch & roll control during the auto landing flight mode.</p></body></html> - + objname:StabilizationSettings fieldname:FlightModeAssistMap index:5 @@ -2125,6 +2225,278 @@ font:bold; + + + Failsafe Settings + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + 255 + 255 + 255 + + + + + + + 232 + 232 + 232 + + + + + + + + + 255 + 255 + 255 + + + + + + + 232 + 232 + 232 + + + + + + + + + 232 + 232 + 232 + + + + + + + 232 + 232 + 232 + + + + + + + + QFrame::NoFrame + + + true + + + + + 0 + 0 + 616 + 351 + + + + + 12 + + + 12 + + + 12 + + + 12 + + + + + Failsafe Settings + + + + 9 + + + 9 + + + 9 + + + 9 + + + 6 + + + + + + + On failsafe change flight mode to: + + + + + + + + 200 + 0 + + + + Qt::StrongFocus + + + When triggering failsafe switch to this flight mode. + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Default + + + + objname:ManualControlSettings + button:default + buttongroup:555 + + + + + + + + + + 10 + + + + + + + Channel input settings on failsafe: + + + + + + + + + + + 0 + 0 + + + + Failsafe Information + + + false + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + true + + + Failsafe is a function that is triggered when the connection between the transmitter and receiver is lost. Failsafe gives the user a chance to configure some basic behaviour and specify what input the flight controller should get even if no control signals from the transmitter is present. +The failsafe is triggered differently for different receivers. Failsafe should always be tested before every flight. + + + false + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Arming Settings @@ -2219,8 +2591,8 @@ font:bold; 0 0 - 1220 - 655 + 564 + 159 @@ -2389,7 +2761,7 @@ Set to 0 to disable (recommended for soaring fixed wings). - + 0 @@ -2421,10 +2793,13 @@ Set to 0 to disable (recommended for soaring fixed wings). true + + button:help + - + 0 @@ -2447,10 +2822,13 @@ Be sure to set the Neutral position on all sliders before sending! Apply + + button:apply + - + 0 @@ -2473,6 +2851,9 @@ Applies and Saves all settings to SD Save + + button:save + @@ -2484,9 +2865,9 @@ Applies and Saves all settings to SD deadband armControl armTimeout - inputHelp - saveRCInputToRAM - saveRCInputToSD + helpButton + applyButton + saveButton diff --git a/ground/gcs/src/plugins/config/inputchannelform.cpp b/ground/gcs/src/plugins/config/inputchannelform.cpp index 962bb7006..75265878f 100644 --- a/ground/gcs/src/plugins/config/inputchannelform.cpp +++ b/ground/gcs/src/plugins/config/inputchannelform.cpp @@ -12,7 +12,6 @@ InputChannelForm::InputChannelForm(const int index, QWidget *parent) : connect(ui->channelMin, SIGNAL(valueChanged(int)), this, SLOT(minMaxUpdated())); connect(ui->channelMax, SIGNAL(valueChanged(int)), this, SLOT(minMaxUpdated())); connect(ui->neutralValue, SIGNAL(valueChanged(int)), this, SLOT(neutralUpdated())); - connect(ui->channelNeutral, SIGNAL(valueChanged(int)), this, SLOT(updateTooltip())); connect(ui->channelGroup, SIGNAL(currentIndexChanged(int)), this, SLOT(groupUpdated())); connect(ui->channelRev, SIGNAL(toggled(bool)), this, SLOT(reversedUpdated())); @@ -58,13 +57,6 @@ void InputChannelForm::minMaxUpdated() updateNeutralMark(); } -void InputChannelForm::updateTooltip() -{ - int currentValue = ui->channelNeutral->value(); - - ui->channelNeutral->setToolTip(QString::number(currentValue)); -} - void InputChannelForm::neutralUpdated() { int neutralValue = ui->neutralValue->value(); @@ -98,13 +90,17 @@ void InputChannelForm::updateNeutralMark() float neutralPosition = offset / range; ui->channelNeutral->setStyleSheet( - "QSlider::groove:horizontal { border: 1px solid rgb(196, 196, 196); height: 6px; border-radius: 2px; " - "background: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop:" + QString::number(neutralPosition - 0.01) + " transparent, stop:" - + QString::number(neutralPosition) + " red, stop:" + QString::number(neutralPosition + 0.01) + " transparent); }" - "QSlider::add-page:horizontal { background: rgba(255,255,255,180); border: 1px solid #777; margin: 0px 0px 0px 2px; border-radius: 4px; }" - "QSlider::sub-page:horizontal { background: rgba(78,147,246,180); border: 1px solid #777; margin: 0px 2px 0px 0px; border-radius: 4px; }" - "QSlider::handle:horizontal { background: rgba(196,196,196,180); width: 18px; height: 28px; margin: -2px 0px; border-radius: 3px; " - "border: 1px solid #777; }" + "QSlider::groove:horizontal { border: 1px solid rgb(196, 196, 196); margin: 0px 23px 0px 23px; height: 6px; border-radius: 2px; " + "background: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop:" + QString::number(qBound(0., neutralPosition - 0.01, 1.)) + " transparent, stop:" + + QString::number(qBound(0., neutralPosition, 1.)) + " red, stop:" + QString::number(qBound(0., neutralPosition + 0.01, 1.)) + " transparent); }" + "QSlider::add-page:horizontal { background: rgba(255,255,255,120); border: 1px solid #777; margin: 0px 23px 0px 2px; border-radius: 4px; }" + "QSlider::sub-page:horizontal { background: rgba(78,147,246,120); border: 1px solid #777; margin: 0px 2px 0px 23px; border-radius: 4px; }" + + "QSlider::handle:horizontal { background: qlineargradient(x1:0, y1:0, x2:1, y2:0, " + "stop: 0 rgba(196, 196, 196, 180), stop: 0.45 rgba(196, 196, 196, 180), " + "stop: 0.46 rgba(255,0,0,100), stop: 0.54 rgba(255,0,0,100), " + "stop: 0.55 rgba(196, 196, 196, 180), stop: 1 rgba(196, 196, 196, 180)); " + "width: 46px; height: 28px; margin: -6px -23px -6px -23px; border-radius: 6px; border: 1px solid #777; }" ); } @@ -147,19 +143,28 @@ void InputChannelForm::groupUpdated() count = 0; break; case ManualControlSettings::CHANNELGROUPS_PWM: + case ManualControlSettings::CHANNELGROUPS_OPLINK: count = 8; // Need to make this 6 for CC break; - case ManualControlSettings::CHANNELGROUPS_PPM: - case ManualControlSettings::CHANNELGROUPS_OPLINK: + case ManualControlSettings::CHANNELGROUPS_IBUS: + count = 10; + break; case ManualControlSettings::CHANNELGROUPS_DSMMAINPORT: case ManualControlSettings::CHANNELGROUPS_DSMFLEXIPORT: + case ManualControlSettings::CHANNELGROUPS_DSMRCVRPORT: count = 12; break; + case ManualControlSettings::CHANNELGROUPS_PPM: + case ManualControlSettings::CHANNELGROUPS_SRXL: + case ManualControlSettings::CHANNELGROUPS_EXBUS: + case ManualControlSettings::CHANNELGROUPS_OPENLRS: + count = 16; + break; case ManualControlSettings::CHANNELGROUPS_SBUS: count = 18; break; - case ManualControlSettings::CHANNELGROUPS_SRXL: - count = 16; + case ManualControlSettings::CHANNELGROUPS_HOTT: + count = 32; break; case ManualControlSettings::CHANNELGROUPS_GCS: count = GCSReceiver::CHANNEL_NUMELEM; diff --git a/ground/gcs/src/plugins/config/inputchannelform.h b/ground/gcs/src/plugins/config/inputchannelform.h index 7763e0d4b..7c4464d8c 100644 --- a/ground/gcs/src/plugins/config/inputchannelform.h +++ b/ground/gcs/src/plugins/config/inputchannelform.h @@ -24,7 +24,6 @@ public: private slots: void updateNeutralMark(); - void updateTooltip(); void minMaxUpdated(); void neutralUpdated(); void reversedUpdated(); diff --git a/ground/gcs/src/plugins/config/inputchannelform.ui b/ground/gcs/src/plugins/config/inputchannelform.ui index 156d653ac..bc097770b 100644 --- a/ground/gcs/src/plugins/config/inputchannelform.ui +++ b/ground/gcs/src/plugins/config/inputchannelform.ui @@ -6,8 +6,8 @@ 0 0 - 923 - 57 + 993 + 100 @@ -141,7 +141,7 @@ margin:1px; - 110 + 120 0 @@ -169,7 +169,7 @@ margin:1px; - 100 + 80 0 @@ -737,7 +737,7 @@ margin:1px; - + 0 @@ -746,13 +746,16 @@ margin:1px; - 50 + 200 0 Qt::StrongFocus + + Channel input value (µs) + @@ -841,6 +844,20 @@ margin:1px; + + + TextBubbleSlider + QSlider +
utils/textbubbleslider.h
+
+
+ + channelGroup + channelNumber + channelMin + channelNeutral + channelMax + diff --git a/ground/gcs/src/plugins/config/mixercurve.cpp b/ground/gcs/src/plugins/config/mixercurve.cpp index b2cc03a64..ce93206b0 100644 --- a/ground/gcs/src/plugins/config/mixercurve.cpp +++ b/ground/gcs/src/plugins/config/mixercurve.cpp @@ -25,11 +25,15 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "mixercurve.h" + +#include "ui_mixercurve.h" + +#include "dblspindelegate.h" + #include #include #include -#include "mixercurve.h" -#include "dblspindelegate.h" MixerCurve::MixerCurve(QWidget *parent) : QFrame(parent), diff --git a/ground/gcs/src/plugins/config/mixercurve.h b/ground/gcs/src/plugins/config/mixercurve.h index faa581fcc..3c578a92c 100644 --- a/ground/gcs/src/plugins/config/mixercurve.h +++ b/ground/gcs/src/plugins/config/mixercurve.h @@ -27,22 +27,21 @@ #ifndef MIXERCURVE_H #define MIXERCURVE_H -#include -#include -#include -#include - -#include "ui_mixercurve.h" #include "mixercurvewidget.h" #include "dblspindelegate.h" #include "uavobjectwidgetutils_global.h" #include "uavobjectwidgetutils/popupwidget.h" +#include +#include namespace Ui { class MixerCurve; } +class QWidget; +class QTableWidget; + class MixerCurve : public QFrame { Q_OBJECT diff --git a/ground/gcs/src/plugins/config/mixercurve.ui b/ground/gcs/src/plugins/config/mixercurve.ui index bdddb1e80..945addc1e 100644 --- a/ground/gcs/src/plugins/config/mixercurve.ui +++ b/ground/gcs/src/plugins/config/mixercurve.ui @@ -139,17 +139,17 @@ - 4 + 4 - 3 + 3 - 2 + 2 @@ -167,27 +167,27 @@ - 1.0 + 1.0 - .75 + .75 - .50 + .50 - .25 + .25 - .00 + .00 diff --git a/ground/gcs/src/plugins/config/oplink.ui b/ground/gcs/src/plugins/config/oplink.ui index 8e3af2033..546fd0a37 100644 --- a/ground/gcs/src/plugins/config/oplink.ui +++ b/ground/gcs/src/plugins/config/oplink.ui @@ -18,9 +18,12 @@ - OPLink configuration + OPLink Configuration - + + + 0 + 0 @@ -33,10 +36,7 @@ 0 - - 0 - - + QFrame::NoFrame @@ -49,670 +49,725 @@ 0 0 - 812 - 566 + 947 + 575 - - - - - - 0 - 0 - - - - - 50 - false - - - - Configuration - - - - - - Com speed in bps. - - - - - - - - 50 - false - - - - Com Speed - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 50 - false - - - - VCP Port - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 16777215 - 16777215 - - - - Choose the function for the flexi port - - - - - - - - 50 - false - - - - Main Port - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 16777215 - 16777215 - - - - Choose the function for the main port - - - - - - - - 16777215 - 16777215 - - - - Choose the function for the USB virtual com port - - - - - - - - 16777215 - 16777215 - - - - Set the maximum TX output power the modem will use (mW) - - - Qt::LeftToRight - - - 0 - - - - - - - - 50 - false - - - - Max Power - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - 50 - false - - - - FlexiIO Port - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 60 - 16777215 - - - - - 50 - false - - - - Channel 0 is 430 MHz, channel 250 is 440 MHz, and the channel spacing is 40 KHz. - - - 250 - - - - - - - - 50 - false - - - - Flexi Port - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 50 - false - - - - Max Chan - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 50 - false - - - - Min Chan - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 60 - 16777215 - - - - - 50 - false - - - - Channel 0 is 430 MHz, channel 250 is 440 MHz, and the channel spacing is 40 KHz. - - - 250 - - - - - - - - 50 - false - - - - This modem will be a coordinator and other modems will bind to it. - - - Coordinator - - - - - - - - 110 - 16777215 - - - - 440.000 (MHz) - - - - - - - - 110 - 16777215 - - - - 430.000 (MHz) - - - - - - - - 50 - false - - - - false - - - If selected, data will only be transmitted from the coordinator to the Rx modem. - - - One-Way - - - - - - - - 50 - false - - - - Only PPM packets will be transmitted. - - - PPM Only - - - - - - - - 50 - false - - - - PPM packets will be received by this modem. Must be selected if Coordinator modem is configured for PPM. - - - PPM - - - - - - + - - - Remote modems + + + 0 - - - - - - 50 - false - - - - -100dB - - - - - - - -127 - - - 0 - - - 0 - - - false - - - %v dBm - - - - - - - - 50 - false - - - - -100dB - - - - - - - - 100 - 16777215 - - - - - 50 - false - - - - - - - - -127 - - - 0 - - - 0 - - - false - - - %v dBm - - - - - - - - 100 - 16777215 - - - - - 50 - false - - - - - - - - -127 - - - 0 - - - -127 - - - false - - - %v dBm - - - - - - - - 50 - false - - - - -100dB - - - - - - - -127 - - - 0 - - - 0 - - - false - - - %v dBm - - - - - - - - 50 - false - - - - -100dB - - - - - - - - 100 - 16777215 - - - - - 50 - false - - - - - - - - - 100 - 16777215 - - - - - 50 - false - - - - 12345678 - - - - - - - - 50 - false - - - - Bind - - - - - - - - 50 - false - - - - Bind - - - - - - - - 50 - false - - - - Bind - - - - - - - - 50 - false - - - - Bind - - - - - - - - 50 - false - - - - Qt::LeftToRight - - - Coordinator ID - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 100 - 16777215 - - - - - 50 - false - - - - <html><head/><body><p>This is the coordinator id we currently are bound to.</p><p>To manually bind to a specific coordinator, just type</p><p>or paste its device id in this box and save.</p><p>The device must be rebooted for the binding to take place.</p></body></html> - - - 8 - - - - - + + 0 + + + 0 + + + 0 + + + + + true + + + + 0 + 0 + + + + + 900 + 16777215 + + + + + 50 + false + + + + Configuration + + + + + + + 50 + false + + + + Flexi Port + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 90 + 16777215 + + + + + 50 + false + + + + This is the coordinator ID we currently are bound to. +To manually bind to a specific coordinator, just type +or paste its device ID in this box and save. +The device must be rebooted for the binding to take place. + + + 8 + + + Qt::LogicalMoveStyle + + + false + + + + + + + Clear the binding/coordinator ID + + + Unbind + + + + + + + + + + 0 + 0 + + + + + 60 + 16777215 + + + + + 50 + false + + + + Channel 0 is 430 MHz, channel 250 is 440 MHz, and the channel spacing is 40 KHz. + + + 250 + + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + 440.000 (MHz) + + + + + + + + + + 50 + false + + + + VCP Port + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 80 + 0 + + + + + 50 + false + + + + Max Chan + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 80 + 0 + + + + + 50 + false + + + + Min Chan + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 16777215 + 16777215 + + + + Choose the function for the flexi port. + + + + + + + + 16777215 + 16777215 + + + + Set the modem protocol + + + Qt::LeftToRight + + + 0 + + + + + + + + 16777215 + 16777215 + + + + Choose the function for the USB virtual com port. + + + + + + + Com speed in bps. + + + + + + + + + + 0 + 0 + + + + + 60 + 16777215 + + + + + 50 + false + + + + Channel 0 is 430 MHz, channel 250 is 440 MHz, and the channel spacing is 40 KHz. + + + 250 + + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + 430.000 (MHz) + + + + + + + + + + 50 + false + + + + Protocol + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 50 + false + + + + Com Speed + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 16777215 + 16777215 + + + + Set the maximum TX output power the modem will use (mW) +0 to disable the modem. + + + Qt::LeftToRight + + + 0 + + + + + + + + 50 + false + + + + Link Type + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 50 + false + + + + Device ID + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 16777215 + 16777215 + + + + Configure what type of packets will be sent over the link + + + Qt::LeftToRight + + + 0 + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 90 + 16777215 + + + + + 50 + false + + + + Qt::StrongFocus + + + Enter your custom ID for this device as a hexadecimal value, +this allows device clones. Be sure only one device with this +ID transmits at the same time! +Leave blank to use autogenerated Device ID. + + + 8 + + + true + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + false + + + + + + Qt::LogicalMoveStyle + + + false + + + + + + + + 0 + 0 + + + + + 50 + false + + + + Max Power + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 50 + false + + + + Main Port + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 16777215 + 16777215 + + + + Choose the function for the main port. + + + + + + + + 50 + false + + + + Qt::LeftToRight + + + Coordinator ID + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 0 + 0 + + + + + 150 + 16777215 + + + + RX Level + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + + 50 + false + + + + -100dB + + + Qt::AlignCenter + + + + + + + + + + 0 + 0 + + + + + 30 + 16777215 + + + + + 0 + 0 + + + + Qt::RightToLeft + + + false + + + -127 + + + 0 + + + -127 + + + Qt::AlignCenter + + + false + + + Qt::Vertical + + + false + + + %v dBm + + + + + + + + + - - + + + + Qt::Vertical + + + + 20 + 40 + + + + + + 430 0 + + + 1050 + 16777215 + + 50 @@ -738,7 +793,67 @@ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - + + + + + + 50 + false + + + + Device ID + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + 50 + false + false + + + + false + + + The modems serial number + + + true + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + true + + + @@ -759,6 +874,9 @@ false + + 8 + false @@ -769,7 +887,7 @@ true - 12345678 + @@ -816,7 +934,7 @@ - The modems current state + The modems current state. Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter @@ -825,7 +943,23 @@ true - Disconnected + + + + + + + + + 50 + false + + + + RX Corrected + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -873,38 +1007,6 @@
- - - - - 50 - false - - - - RX Corrected - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 50 - false - - - - RX Seq. No. - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - @@ -977,30 +1079,8 @@ - - - - - 101 - 16777215 - - - - - 50 - false - - - - false - - - true - - - - - + + 50 @@ -1008,7 +1088,7 @@ - RX Good + RX Seq. No. Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -1052,8 +1132,8 @@ - - + + 50 @@ -1061,13 +1141,35 @@ - RX Errors + RX Good Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + 101 + 16777215 + + + + + 50 + false + + + + false + + + true + + + @@ -1105,104 +1207,6 @@ - - - - - 50 - false - - - - RX Missed - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 50 - false - - - - UAVTalk Errors - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 101 - 16777215 - - - - - 50 - false - - - - false - - - true - - - - - - - - 0 - 0 - - - - - 101 - 16777215 - - - - - 50 - false - - - - false - - - true - - - - - - - - 50 - false - - - - Resets - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - @@ -1225,6 +1229,38 @@ + + + + + 50 + false + + + + RX Errors + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 50 + false + + + + RX Missed + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + @@ -1282,52 +1318,8 @@ - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - - 50 - false - false - - - - false - - - The modems serial number - - - true - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - true - - - - - + + 50 @@ -1335,23 +1327,7 @@ - Device ID - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 50 - false - - - - Link Quality + TX Rate (B/s) Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -1396,8 +1372,8 @@ - - + + 50 @@ -1405,7 +1381,7 @@ - TX Rate (B/s) + Link Quality Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -1524,41 +1500,6 @@ - - - - - 50 - false - - - - Free Heap - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 101 - 16777215 - - - - - 50 - false - - - - true - - - @@ -1581,8 +1522,27 @@ - - + + + + + 101 + 16777215 + + + + + 50 + false + + + + true + + + + + 50 @@ -1590,7 +1550,23 @@ - Tx Failure + Free Heap + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 50 + false + + + + TX Dropped Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -1628,8 +1604,8 @@ - - + + 50 @@ -1637,15 +1613,15 @@ - TX Dropped + TX Failure Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + 50 @@ -1653,7 +1629,7 @@ - RX Failure + Resets Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -1697,18 +1673,176 @@ + + + + + 50 + false + + + + RX Failure + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 101 + 16777215 + + + + + 50 + false + + + + false + + + true + + + + + + + + 101 + 16777215 + + + + + 50 + false + + + + false + + + true + + + + + + + + 50 + false + + + + UAVTalk Errors + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 50 + false + + + + TX Packet Rate + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 101 + 16777215 + + + + + 50 + false + + + + false + + + true + + + + + + + + 101 + 16777215 + + + + + 50 + false + + + + false + + + true + + + + + + + + 50 + false + + + + RX Packet Rate + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + - - + + - Qt::Vertical + Qt::Horizontal - 20 - 40 + 40 + 20 @@ -1740,7 +1874,7 @@ - + 0 @@ -1776,26 +1910,29 @@ true - + button:help - + - Send settings to the board but do not save to the non-volatile memory + Send settings to the board but do not save to the non-volatile memory. Apply + + button:apply + - + - Send settings to the board and save to the non-volatile memory + Send settings to the board and save to the non-volatile memory. Save @@ -1803,6 +1940,9 @@ false + + button:save + @@ -1810,14 +1950,10 @@ - PairID1 - PairID2 - PairID3 - PairID4 FirmwareVersion SerialNumber - Apply - Save + applyButton + saveButton diff --git a/ground/gcs/src/plugins/config/output.ui b/ground/gcs/src/plugins/config/output.ui index 1f5c9577f..d806189bd 100644 --- a/ground/gcs/src/plugins/config/output.ui +++ b/ground/gcs/src/plugins/config/output.ui @@ -817,10 +817,79 @@ - Motors spin at neutral output when armed and throttle below zero (be careful) + Motors spin at neutral output when armed and throttle below zero (Be careful). + + + + 6 + + + 0 + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + Multirotor is Always Stabilized When Armed using: + + + + + + + + 0 + 0 + + + + + 120 + 0 + + + + + + + + (Really be careful!). + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + @@ -900,7 +969,7 @@ - + 0 @@ -938,10 +1007,13 @@ true + + button:help + - + 0 @@ -964,10 +1036,13 @@ Be sure to set the Neutral position on all sliders before sending! Apply + + button:apply + - + 0 @@ -990,6 +1065,9 @@ Applies and Saves all settings to SD Save + + button:save + @@ -997,8 +1075,8 @@ Applies and Saves all settings to SD - saveRCOutputToRAM - saveRCOutputToSD + applyButton + saveButton diff --git a/ground/gcs/src/plugins/config/outputchannelform.cpp b/ground/gcs/src/plugins/config/outputchannelform.cpp index ea8636250..b093956a1 100644 --- a/ground/gcs/src/plugins/config/outputchannelform.cpp +++ b/ground/gcs/src/plugins/config/outputchannelform.cpp @@ -27,34 +27,36 @@ #include "outputchannelform.h" +#include "ui_outputchannelform.h" + #define MAXOUTPUT_VALUE 2500 #define MINOUTPUT_VALUE 500 OutputChannelForm::OutputChannelForm(const int index, QWidget *parent) : - ChannelForm(index, parent), ui(), m_inChannelTest(false) + ChannelForm(index, parent), ui(new Ui::outputChannelForm), m_inChannelTest(false) { - ui.setupUi(this); + 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())); - connect(ui.actuatorRev, SIGNAL(toggled(bool)), this, SLOT(reverseChannel(bool))); + connect(ui->actuatorMin, SIGNAL(editingFinished()), this, SLOT(setChannelRange())); + connect(ui->actuatorMax, SIGNAL(editingFinished()), this, SLOT(setChannelRange())); + connect(ui->actuatorRev, SIGNAL(toggled(bool)), this, SLOT(reverseChannel(bool))); // Now connect the channel out sliders to our signal to send updates in test mode - connect(ui.actuatorNeutral, SIGNAL(valueChanged(int)), this, SLOT(sendChannelTest(int))); + connect(ui->actuatorNeutral, SIGNAL(valueChanged(int)), this, SLOT(sendChannelTest(int))); - ui.actuatorLink->setChecked(false); - connect(ui.actuatorLink, SIGNAL(toggled(bool)), this, SLOT(linkToggled(bool))); + ui->actuatorLink->setChecked(false); + connect(ui->actuatorLink, SIGNAL(toggled(bool)), this, SLOT(linkToggled(bool))); // Set limits - ui.actuatorMin->setMaximum(MAXOUTPUT_VALUE); - ui.actuatorMax->setMaximum(MAXOUTPUT_VALUE); - ui.actuatorValue->setMaximum(MAXOUTPUT_VALUE); - ui.actuatorMin->setMinimum(MINOUTPUT_VALUE); - ui.actuatorMax->setMinimum(MINOUTPUT_VALUE); - ui.actuatorValue->setMinimum(MINOUTPUT_VALUE); + ui->actuatorMin->setMaximum(MAXOUTPUT_VALUE); + ui->actuatorMax->setMaximum(MAXOUTPUT_VALUE); + ui->actuatorValue->setMaximum(MAXOUTPUT_VALUE); + ui->actuatorMin->setMinimum(MINOUTPUT_VALUE); + ui->actuatorMax->setMinimum(MINOUTPUT_VALUE); + ui->actuatorValue->setMinimum(MINOUTPUT_VALUE); setChannelRange(); @@ -63,17 +65,17 @@ OutputChannelForm::OutputChannelForm(const int index, QWidget *parent) : OutputChannelForm::~OutputChannelForm() { - // Do nothing + delete ui; } QString OutputChannelForm::name() { - return ui.actuatorName->text(); + return ui->actuatorName->text(); } QString OutputChannelForm::bank() { - return ui.actuatorBankNumber->text(); + return ui->actuatorBankNumber->text(); } /** @@ -81,18 +83,18 @@ QString OutputChannelForm::bank() */ void OutputChannelForm::setName(const QString &name) { - ui.actuatorName->setText(name); + ui->actuatorName->setText(name); } void OutputChannelForm::setColor(const QColor &color) { - QString stylesheet = ui.actuatorNumberFrame->styleSheet(); + 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); + ui->actuatorNumberFrame->setStyleSheet(stylesheet); } /** @@ -100,7 +102,7 @@ void OutputChannelForm::setColor(const QColor &color) */ void OutputChannelForm::setBank(const QString &bank) { - ui.actuatorBankNumber->setText(bank); + ui->actuatorBankNumber->setText(bank); } /** @@ -116,14 +118,14 @@ void OutputChannelForm::enableChannelTest(bool state) if (m_inChannelTest) { // Prevent stupid users from touching the minimum & maximum ranges while // moving the sliders. Thanks Ivan for the tip :) - ui.actuatorMin->setEnabled(false); - ui.actuatorMax->setEnabled(false); - ui.actuatorRev->setEnabled(false); + ui->actuatorMin->setEnabled(false); + ui->actuatorMax->setEnabled(false); + ui->actuatorRev->setEnabled(false); } else if (m_mixerType != "Disabled") { - ui.actuatorMin->setEnabled(true); - ui.actuatorMax->setEnabled(true); + ui->actuatorMin->setEnabled(true); + ui->actuatorMax->setEnabled(true); if (m_mixerType != "Motor") { - ui.actuatorRev->setEnabled(true); + ui->actuatorRev->setEnabled(true); } } } @@ -147,13 +149,13 @@ void OutputChannelForm::linkToggled(bool state) QList outputChannelForms = parent()->findChildren(); // set the linked channels of the parent widget to the same value foreach(OutputChannelForm * outputChannelForm, outputChannelForms) { - if (!outputChannelForm->ui.actuatorLink->checkState()) { + if (!outputChannelForm->ui->actuatorLink->checkState()) { continue; } if (this == outputChannelForm) { continue; } - int value = outputChannelForm->ui.actuatorNeutral->value(); + int value = outputChannelForm->ui->actuatorNeutral->value(); if (min > value) { min = value; } @@ -165,16 +167,16 @@ void OutputChannelForm::linkToggled(bool state) } // set the linked channels to the same value foreach(OutputChannelForm * outputChannelForm, outputChannelForms) { - if (!outputChannelForm->ui.actuatorLink->checkState()) { + if (!outputChannelForm->ui->actuatorLink->checkState()) { continue; } - outputChannelForm->ui.actuatorNeutral->setValue(min); + outputChannelForm->ui->actuatorNeutral->setValue(min); } } int OutputChannelForm::max() const { - return ui.actuatorMax->value(); + return ui->actuatorMax->value(); } /** @@ -182,12 +184,12 @@ int OutputChannelForm::max() const */ void OutputChannelForm::setMax(int maximum) { - setRange(ui.actuatorMax->value(), maximum); + setRange(ui->actuatorMax->value(), maximum); } int OutputChannelForm::min() const { - return ui.actuatorMin->value(); + return ui->actuatorMin->value(); } /** @@ -195,12 +197,12 @@ int OutputChannelForm::min() const */ void OutputChannelForm::setMin(int minimum) { - setRange(minimum, ui.actuatorMin->value()); + setRange(minimum, ui->actuatorMin->value()); } int OutputChannelForm::neutral() const { - return ui.actuatorNeutral->value(); + return ui->actuatorNeutral->value(); } /** @@ -208,7 +210,7 @@ int OutputChannelForm::neutral() const */ void OutputChannelForm::setNeutral(int value) { - ui.actuatorNeutral->setValue(value); + ui->actuatorNeutral->setValue(value); } /** @@ -216,8 +218,8 @@ void OutputChannelForm::setNeutral(int value) */ void OutputChannelForm::setRange(int minimum, int maximum) { - ui.actuatorMin->setValue(minimum); - ui.actuatorMax->setValue(maximum); + ui->actuatorMin->setValue(minimum); + ui->actuatorMax->setValue(maximum); setChannelRange(); } @@ -230,70 +232,70 @@ void OutputChannelForm::setRange(int minimum, int maximum) */ void OutputChannelForm::setChannelRange() { - int minValue = ui.actuatorMin->value(); - int maxValue = ui.actuatorMax->value(); + int minValue = ui->actuatorMin->value(); + int maxValue = ui->actuatorMax->value(); - int oldMini = ui.actuatorNeutral->minimum(); - int oldMaxi = ui.actuatorNeutral->maximum(); + int oldMini = ui->actuatorNeutral->minimum(); + int oldMaxi = ui->actuatorNeutral->maximum(); m_mixerType = outputMixerType(); // Red handle for Motors if ((m_mixerType == "Motor") || (m_mixerType == "ReversableMotor")) { - ui.actuatorNeutral->setStyleSheet("QSlider::handle:horizontal { background: rgb(255, 100, 100); width: 18px; height: 28px;" - "margin: -3px 0; border-radius: 3px; border: 1px solid #777; }"); + ui->actuatorNeutral->setStyleSheet("QSlider::handle:horizontal { background: rgb(255, 100, 100); width: 18px; height: 28px;" + "margin: -3px 0; border-radius: 3px; border: 1px solid #777; }"); } else { - ui.actuatorNeutral->setStyleSheet("QSlider::handle:horizontal { background: rgb(196, 196, 196); width: 18px; height: 28px;" - "margin: -3px 0; border-radius: 3px; border: 1px solid #777; }"); + ui->actuatorNeutral->setStyleSheet("QSlider::handle:horizontal { background: rgb(196, 196, 196); width: 18px; height: 28px;" + "margin: -3px 0; border-radius: 3px; border: 1px solid #777; }"); } // Normal motor will be *** never *** reversed : without arming a "Min" value (like 1900) can be applied ! if (m_mixerType == "Motor") { if (minValue >= maxValue) { // Keep old values - ui.actuatorMin->setValue(oldMini); - ui.actuatorMax->setValue(oldMaxi); + ui->actuatorMin->setValue(oldMini); + ui->actuatorMax->setValue(oldMaxi); } - ui.actuatorRev->setChecked(false); - ui.actuatorRev->setEnabled(false); - ui.actuatorNeutral->setInvertedAppearance(false); - ui.actuatorNeutral->setRange(ui.actuatorMin->value(), ui.actuatorMax->value()); + ui->actuatorRev->setChecked(false); + ui->actuatorRev->setEnabled(false); + ui->actuatorNeutral->setInvertedAppearance(false); + ui->actuatorNeutral->setRange(ui->actuatorMin->value(), ui->actuatorMax->value()); } else { // Others output (!Motor) // Auto check reverse checkbox SpinBox Min/Max changes - ui.actuatorRev->setEnabled(true); + ui->actuatorRev->setEnabled(true); if (minValue <= maxValue) { - ui.actuatorRev->setChecked(false); - ui.actuatorNeutral->setInvertedAppearance(false); - ui.actuatorNeutral->setRange(minValue, maxValue); + ui->actuatorRev->setChecked(false); + ui->actuatorNeutral->setInvertedAppearance(false); + ui->actuatorNeutral->setRange(minValue, maxValue); } else { - ui.actuatorRev->setChecked(true); - ui.actuatorNeutral->setInvertedAppearance(true); - ui.actuatorNeutral->setRange(maxValue, minValue); + ui->actuatorRev->setChecked(true); + ui->actuatorNeutral->setInvertedAppearance(true); + ui->actuatorNeutral->setRange(maxValue, minValue); } } // If old neutral was Min, stay Min - if (ui.actuatorNeutral->value() == oldMini) { - ui.actuatorNeutral->setValue(ui.actuatorNeutral->minimum()); + if (ui->actuatorNeutral->value() == oldMini) { + ui->actuatorNeutral->setValue(ui->actuatorNeutral->minimum()); } // Enable only outputs already set in mixer if (m_mixerType != "Disabled") { - ui.actuatorMin->setEnabled(true); - ui.actuatorMax->setEnabled(true); - ui.actuatorNeutral->setEnabled(true); - ui.actuatorValue->setEnabled(true); - ui.actuatorLink->setEnabled(true); + ui->actuatorMin->setEnabled(true); + ui->actuatorMax->setEnabled(true); + ui->actuatorNeutral->setEnabled(true); + ui->actuatorValue->setEnabled(true); + ui->actuatorLink->setEnabled(true); } else { - ui.actuatorMin->setEnabled(false); - ui.actuatorMax->setEnabled(false); - ui.actuatorRev->setEnabled(false); - ui.actuatorLink->setEnabled(false); - ui.actuatorMin->setValue(1000); - ui.actuatorMax->setValue(1000); - ui.actuatorNeutral->setRange(minValue, maxValue); - ui.actuatorNeutral->setValue(minValue); - ui.actuatorValue->setEnabled(false); + ui->actuatorMin->setEnabled(false); + ui->actuatorMax->setEnabled(false); + ui->actuatorRev->setEnabled(false); + ui->actuatorLink->setEnabled(false); + ui->actuatorMin->setValue(1000); + ui->actuatorMax->setValue(1000); + ui->actuatorNeutral->setRange(minValue, maxValue); + ui->actuatorNeutral->setValue(minValue); + ui->actuatorValue->setEnabled(false); } } @@ -303,13 +305,13 @@ void OutputChannelForm::setChannelRange() void OutputChannelForm::reverseChannel(bool state) { // if 'state' (reverse channel requested) apply only if not already reversed - if ((state && (ui.actuatorMax->value() > ui.actuatorMin->value())) - || (!state && (ui.actuatorMax->value() < ui.actuatorMin->value()))) { + if ((state && (ui->actuatorMax->value() > ui->actuatorMin->value())) + || (!state && (ui->actuatorMax->value() < ui->actuatorMin->value()))) { // Now, swap the min & max values (spin boxes) - int temp = ui.actuatorMax->value(); - ui.actuatorMax->setValue(ui.actuatorMin->value()); - ui.actuatorMin->setValue(temp); - ui.actuatorNeutral->setInvertedAppearance(state); + int temp = ui->actuatorMax->value(); + ui->actuatorMax->setValue(ui->actuatorMin->value()); + ui->actuatorMin->setValue(temp); + ui->actuatorNeutral->setInvertedAppearance(state); setChannelRange(); return; @@ -331,9 +333,9 @@ void OutputChannelForm::sendChannelTest(int value) } // update the label - ui.actuatorValue->setValue(value); + ui->actuatorValue->setValue(value); - if (ui.actuatorLink->checkState() && parent()) { + if (ui->actuatorLink->checkState() && parent()) { // the channel is linked to other channels QList outputChannelForms = parent()->findChildren(); // set the linked channels of the parent widget to the same value @@ -341,24 +343,24 @@ void OutputChannelForm::sendChannelTest(int value) if (this == outputChannelForm) { continue; } - if (!outputChannelForm->ui.actuatorLink->checkState()) { + if (!outputChannelForm->ui->actuatorLink->checkState()) { continue; } int val = in_value; - if (val < outputChannelForm->ui.actuatorNeutral->minimum()) { - val = outputChannelForm->ui.actuatorNeutral->minimum(); + if (val < outputChannelForm->ui->actuatorNeutral->minimum()) { + val = outputChannelForm->ui->actuatorNeutral->minimum(); } - if (val > outputChannelForm->ui.actuatorNeutral->maximum()) { - val = outputChannelForm->ui.actuatorNeutral->maximum(); + if (val > outputChannelForm->ui->actuatorNeutral->maximum()) { + val = outputChannelForm->ui->actuatorNeutral->maximum(); } - if (outputChannelForm->ui.actuatorNeutral->value() == val) { + if (outputChannelForm->ui->actuatorNeutral->value() == val) { continue; } - outputChannelForm->ui.actuatorNeutral->setValue(val); - outputChannelForm->ui.actuatorValue->setValue(val); + outputChannelForm->ui->actuatorNeutral->setValue(val); + outputChannelForm->ui->actuatorValue->setValue(val); } } diff --git a/ground/gcs/src/plugins/config/outputchannelform.h b/ground/gcs/src/plugins/config/outputchannelform.h index e10891c2a..25cd5375a 100644 --- a/ground/gcs/src/plugins/config/outputchannelform.h +++ b/ground/gcs/src/plugins/config/outputchannelform.h @@ -29,9 +29,12 @@ #include "channelform.h" #include "configoutputwidget.h" -#include "ui_outputchannelform.h" -#include +namespace Ui { +class outputChannelForm; +} + +class QWidget; class OutputChannelForm : public ChannelForm { Q_OBJECT @@ -64,7 +67,7 @@ signals: void channelChanged(int index, int value); private: - Ui::outputChannelForm ui; + Ui::outputChannelForm *ui; bool m_inChannelTest; QString m_mixerType; diff --git a/ground/gcs/src/plugins/config/revosensors.ui b/ground/gcs/src/plugins/config/revosensors.ui index 21b5da221..3bfab0ebc 100644 --- a/ground/gcs/src/plugins/config/revosensors.ui +++ b/ground/gcs/src/plugins/config/revosensors.ui @@ -6,8 +6,8 @@ 0 0 - 1014 - 725 + 954 + 726 @@ -435,11 +435,11 @@ QAbstractScrollArea::AdjustIgnored - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600;"><br /></p></body></html> +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-weight:600;"><br /></p></body></html> Qt::NoTextInteraction @@ -487,6 +487,204 @@ p, li { white-space: pre-wrap; } 6 + + + + + 0 + 0 + + + + Home Location + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + QLayout::SetDefaultConstraint + + + + + Gravity acceleration: + + + + + + + Latitude: + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + + objname:HomeLocation + fieldname:g_e + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + + objname:HomeLocation + fieldname:Latitude + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + + + + + Altitude: + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + + objname:HomeLocation + fieldname:Altitude + + + + + + + + Magnetic field vector: + + + + + + + <html><head/><body><p>This information must be set to enable calibration the Revolution controller's sensors. <br/>Set home location using context menu in the map widget.</p></body></html> + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + + objname:HomeLocation + fieldname:Longitude + + + + + + + + false + + + Is Set + + + true + + + + objname:HomeLocation + fieldname:Set + + + + + + + + Longitude: + + + + + + + + 0 + 0 + + + + Clear + + + + + + + Qt::Vertical + + + + 20 + 0 + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 50 + 20 + + + + @@ -509,10 +707,10 @@ p, li { white-space: pre-wrap; } - -90.000000000000000 + -180.000000000000000 - 90.000000000000000 + 180.000000000000000 @@ -634,6 +832,94 @@ font:bold; + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Attitude Estimation Algorithm + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + 0 + 0 + + + + Selects the sensor integration algorithm to be used by the Revolution board. + + + + + + + Qt::Vertical + + + QSizePolicy::MinimumExpanding + + + + 20 + 40 + + + + + + + + + + + Gyro Initialization + + + + + + If enabled, a fast recalibration of gyro zero point will be done +whenever the board is armed. Do not move the vehicle while +arming it in that case! + + + Zero gyros while arming + + + + + + + If enabled, this option prevents gyro initialization while the board is moving. + + + Wait until the board is steady + + + + + + + + @@ -685,251 +971,6 @@ A setting of 0.00 disables the filter. - - - - - 0 - 0 - - - - Attitude Estimation Algorithm - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - - - 0 - 0 - - - - Selects the sensor integration algorithm to be used by the Revolution board. - - - - - - - Qt::Vertical - - - QSizePolicy::MinimumExpanding - - - - 20 - 0 - - - - - - - - - - - - 0 - 0 - - - - Home Location - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - QLayout::SetDefaultConstraint - - - - - Gravity acceleration: - - - - - - - Latitude: - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - objname:HomeLocation - fieldname:g_e - - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - objname:HomeLocation - fieldname:Latitude - - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - - - - Altitude: - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - objname:HomeLocation - fieldname:Altitude - - - - - - - - Magnetic field vector: - - - - - - - <html><head/><body><p>This information must be set to enable calibration the Revolution controllers sensors. <br/>Set home location using context menu in the map widget.</p></body></html> - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - objname:HomeLocation - fieldname:Longitude - - - - - - - - false - - - Is Set - - - true - - - - objname:HomeLocation - fieldname:Set - - - - - - - - Longitude: - - - - - - - - 0 - 0 - - - - Clear - - - - - - - Qt::Vertical - - - - 20 - 0 - - - - - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 50 - 20 - - - - @@ -950,6 +991,705 @@ A setting of 0.00 disables the filter. + + + true + + + Magnetometer + + + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + 0 + 0 + + + + + 500 + 0 + + + + Auxiliary Magnetometer Orientation Help + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + 80 + 30 + + + + + 16777215 + 30 + + + + 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; +margin:1px; +font:bold; + + + Y axis + + + Qt::AlignCenter + + + + + + + + 80 + 30 + + + + + 16777215 + 30 + + + + 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; +margin:1px; +font:bold; + + + Z axis + + + Qt::AlignCenter + + + + + + + Difference on Z axis + + + -50 + + + 50 + + + 0 + + + Qt::AlignCenter + + + %v + + + + + + + Difference on Y axis + + + -50 + + + 50 + + + 0 + + + Qt::AlignCenter + + + %v + + + + + + + + 0 + 0 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">The bargraphs show the difference between the onboard and auxiliary magnetometer measurements. </span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">When the auxiliary magnetometer rotation is set correctlly, all bargraphs should show all zero (bargraph centered) </span><a name="result_box"></a><span style=" font-family:'Cantarell';">w</span><span style=" font-family:'Cantarell';">hatever the vehicle's orientation.</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">This assumes both magnetometers are calibrated and without alarm.</span></p></body></html> + + + Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Difference on X axis + + + -50 + + + 50 + + + 0 + + + Qt::AlignCenter + + + true + + + %v + + + + + + + + 80 + 30 + + + + + 16777215 + 30 + + + + 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; +margin:1px; +font:bold; + + + X axis + + + Qt::AlignCenter + + + + + + + + + + QLayout::SetDefaultConstraint + + + 0 + + + + + + 0 + 0 + + + + Magnetometer Settings + + + + QLayout::SetMinimumSize + + + + + + 80 + 0 + + + + Mag type: + + + + + + + + 80 + 0 + + + + Mag usage: + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + Select the magnetometer type. + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + Select how to use available magnetometers. + + + + + + + Warning level in percent (default 5%) + + + 0.010000000000000 + + + 0.150000000000000 + + + 0.010000000000000 + + + 0.050000000000000 + + + + + + + Error level in percent (default 15%) + + + 0.150000000000000 + + + 0.300000000000000 + + + 0.010000000000000 + + + + + + + Warning / Error levels: + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + + + + + + 0 + 0 + + + + Magnetometer Status + + + + QLayout::SetMinimumSize + + + + + + 0 + 0 + + + + + 100 + 35 + + + + background-color: green; +color: rgb(255, 255, 255); +border-radius: 5; +margin:1px; +font:bold; + + + Onboard + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 100 + 40 + + + + background-color: green; +color: rgb(255, 255, 255); +border-radius: 5; +margin:1px; +font:bold; + + + AuxMag + + + Qt::AlignCenter + + + + + + + + 110 + 20 + + + + Mag source: + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Mag alarms: + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + external + + + + + + + + + + + 0 + 0 + + + + Auxiliary Magnetometer Orientation + + + + QLayout::SetMinimumSize + + + + + + 70 + 30 + + + + + 0 + 30 + + + + 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; +margin:1px; +font:bold; + + + Roll + + + Qt::AlignCenter + + + + + + + 0 + + + -180.000000000000000 + + + 180.000000000000000 + + + + + + + 0 + + + -180.000000000000000 + + + 180.000000000000000 + + + + + + + + 0 + 0 + + + + + 70 + 30 + + + + + 0 + 30 + + + + 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; +margin:1px; +font:bold; + + + Pitch + + + Qt::AlignCenter + + + + + + + + + + 0 + + + -180.000000000000000 + + + 180.000000000000000 + + + + + + + + 0 + 0 + + + + + 70 + 30 + + + + + 0 + 30 + + + + 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; +margin:1px; +font:bold; + + + Yaw + + + Qt::AlignCenter + + + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 40 + + + + + + Help @@ -967,38 +1707,38 @@ A setting of 0.00 disables the filter. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:14pt; font-weight:600;">Help</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">Steps 1, 2 and 3 are necessary.</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">Step 4 is optional but may help achieve the best possible results.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600; font-style:italic;">Step 1: Accelerometer and Magnetometer calibration</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">This step will calibrate the scale for the Magnetometer and the Accelerometer sensors. </span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">Press </span><span style=" font-size:11pt; font-style:italic;">Start</span><span style=" font-size:11pt;"> to begin, and follow the instructions for each step. </span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">For best results with the accelerometer calibration, it is advised that it be performed with a free unmounted flight controller as this allows one to accurately position the board for each orientation in the sequence.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">The magnetometer calibration must be performed with the board mounted in the airframe in order for the measurements to incorporate any bias produced by local onboard metal/magnetic elements.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">Note 1: Before the magnetometer or the accelerometer calibration is performed your Home Location must be set. This step is needed in order to determine the local magnetic field vector (Be) and acceleration due to gravity (g_e).</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">Note 2: There is no need to align the airframe exactly south, north, east or west during the individual steps. The directions indicated serve only to tell you in which direction the airframe should be positioned relative to some point. One can simply assume that North is in front of you, East is to the right, West is to the left and South is pointing at you.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600; font-style:italic;">Step 2: Board level calibration</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">This step will ensure that board leveling is accurate. Place the airframe as horizontally as possible (use a spirit level if necessary), then press </span><span style=" font-size:11pt; font-style:italic;">Start</span><span style=" font-size:11pt;">. Do not move the airframe at all until the end of the calibration.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600; font-style:italic;">Step 3: Gyro bias calculation</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">This step will allow you to calibrate the gyro measured value when the board is steady. To perform the calibration leave the board/airframe completely stationary and press </span><span style=" font-size:11pt; font-style:italic;">Start</span><span style=" font-size:11pt;">. </span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600; font-style:italic;">Step 4: Thermal calibration</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">The calibration will compute sensors bias variations at different temperatures while the board warms up.</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">This allows a certain amount of correction of those bias variations against temperature changes. It improves altitude hold accuracy and reduces yaw drift.</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">To perform this calibration disconnect any power from the board and leave it to cool down at room temperature for 15-20 minutes. Then attach the usb connector to the board and press </span><span style=" font-size:11pt; font-style:italic;">Start</span><span style=" font-size:11pt;">, leaving the board completely stationary. Wait until complete.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p></body></html> +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:14pt; font-weight:600;">Help</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">Steps 1, 2 and 3 are necessary.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">Step 4 is optional but may help achieve the best possible results.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:12pt; font-weight:600; font-style:italic;">Step 1: Accelerometer and Magnetometer calibration</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">This step will calibrate the scale for the Magnetometer and the Accelerometer sensors. </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">Press </span><span style=" font-family:'MS Shell Dlg 2'; font-style:italic;">Start</span><span style=" font-family:'MS Shell Dlg 2';"> to begin, and follow the instructions for each step. </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">For best results with the accelerometer calibration, it is advised that it be performed with a free unmounted flight controller as this allows one to accurately position the board for each orientation in the sequence.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">The magnetometer calibration must be performed with the board mounted in the airframe in order for the measurements to incorporate any bias produced by local onboard metal/magnetic elements.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">Note 1: Before the magnetometer or the accelerometer calibration is performed your Home Location must be set. This step is needed in order to determine the local magnetic field vector (Be) and acceleration due to gravity (g_e).</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">Note 2: There is no need to align the airframe exactly south, north, east or west during the individual steps. The directions indicated serve only to tell you in which direction the airframe should be positioned relative to some point. One can simply assume that North is in front of you, East is to the right, West is to the left and South is pointing at you.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:12pt; font-weight:600; font-style:italic;">Step 2: Board level calibration</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">This step will ensure that board leveling is accurate. Place the airframe as horizontally as possible (use a spirit level if necessary), then press </span><span style=" font-family:'MS Shell Dlg 2'; font-style:italic;">Start</span><span style=" font-family:'MS Shell Dlg 2';">. Do not move the airframe at all until the end of the calibration.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:12pt; font-weight:600; font-style:italic;">Step 3: Gyro bias calculation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">This step will allow you to calibrate the gyro measured value when the board is steady. To perform the calibration leave the board/airframe completely stationary and press </span><span style=" font-family:'MS Shell Dlg 2'; font-style:italic;">Start</span><span style=" font-family:'MS Shell Dlg 2';">. </span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:12pt; font-weight:600; font-style:italic;">Step 4: Thermal calibration</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">The calibration will compute sensors bias variations at different temperatures while the board warms up.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">This allows a certain amount of correction of those bias variations against temperature changes. It improves altitude hold accuracy and reduces yaw drift.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">To perform this calibration disconnect any power from the board and leave it to cool down at room temperature for 15-20 minutes. Then attach the usb connector to the board and press </span><span style=" font-family:'MS Shell Dlg 2'; font-style:italic;">Start</span><span style=" font-family:'MS Shell Dlg 2';">, leaving the board completely stationary. Wait until complete.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p></body></html> Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse @@ -1011,6 +1751,9 @@ p, li { white-space: pre-wrap; } + + 4 + @@ -1025,7 +1768,7 @@ p, li { white-space: pre-wrap; } - + 0 @@ -1066,14 +1809,12 @@ p, li { white-space: pre-wrap; } true - - button:help - + button:help - + Save settings to the board (RAM only). @@ -1084,12 +1825,12 @@ specific calibration button on top of the screen. Apply - button:apply + button:apply - + Send settings to the board, and save to the non-volatile memory. @@ -1100,7 +1841,7 @@ specific calibration button on top of the screen. false - button:save + button:save diff --git a/ground/gcs/src/plugins/config/stabilization.ui b/ground/gcs/src/plugins/config/stabilization.ui index 811b6735d..9969ed4ec 100644 --- a/ground/gcs/src/plugins/config/stabilization.ui +++ b/ground/gcs/src/plugins/config/stabilization.ui @@ -6,7 +6,7 @@ 0 0 - 974 + 901 755 @@ -136,8 +136,8 @@ 0 0 - 950 - 775 + 863 + 821 @@ -149,6 +149,12 @@ + + + 0 + 0 + + ArrowCursor @@ -167,16 +173,22 @@ margin-top: -1px; + + + 0 + 0 + + 0 - 340 + 400 16777215 - 340 + 400 @@ -189,288 +201,32 @@ margin-top: -1px; 0 - - - - Acro+ + + 9 + + + 10 + + + + + true - - - - - + 0 0 - - Qt::StrongFocus + + + 0 + 0 + - - <html><head/><body><p>Link roll &amp; pitch sliders to move together</p></body></html> - - - - - - Link Roll and Pitch - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - Reset all values to GCS defaults - - - false - - - - - - Default - - - - button:default - buttongroup:77 - - - - - - - - 0 - - - - - - 0 - 25 - - - - <html><head/><body><p>The Acro + slider can be adjusted to change the amount of manual control blending.</p></body></html> - - - 0 - - - 100 - - - 1 - - - 50 - - - Qt::Horizontal - - - QSlider::TicksBelow - - - 5 - - - - objname:StabilizationSettingsBankX - fieldname:AcroInsanityFactor - scale:1 - buttongroup:77 - element:Roll - - - - - - - - - 60 - 22 - - - - - 60 - 22 - - - - 0 - - - 100 - - - 50 - - - - objname:StabilizationSettingsBankX - fieldname:AcroInsanityFactor - scale:1 - buttongroup:77 - element:Roll - - - - - - - - - 0 - 0 - - - - - 80 - 0 - - - - Roll Factor - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 25 - - - - <html><head/><body><p>The Acro + slider can be adjusted to change the amount of manual control blending.</p></body></html> - - - 0 - - - 100 - - - 1 - - - 50 - - - Qt::Horizontal - - - QSlider::TicksBelow - - - 5 - - - - objname:StabilizationSettingsBankX - fieldname:AcroInsanityFactor - scale:1 - buttongroup:77 - element:Pitch - - - - - - - - - 60 - 22 - - - - - 60 - 22 - - - - 0 - - - 100 - - - 50 - - - - objname:StabilizationSettingsBankX - fieldname:AcroInsanityFactor - scale:1 - buttongroup:77 - element:Pitch - - - - - - - - - 0 - 0 - - - - - 80 - 0 - - - - Pitch Factor - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - 300 + 260 16777215 @@ -526,7 +282,7 @@ margin-top: -1px; 0 - + objname:StabilizationSettingsBankX fieldname:StickExpo haslimits:yes @@ -614,7 +370,7 @@ margin-top: -1px; 0 - + objname:StabilizationSettingsBankX fieldname:StickExpo haslimits:yes @@ -628,11 +384,29 @@ margin-top: -1px; - + 0 0 + + + 220 + 220 + + + + + 0 + 0 + + + + + 0 + 0 + + <html><head/><body><p>This graph shows the Expo curves for all axis. The color of the curves corresponds with the colors of the slider labels below.</p></body></html> @@ -715,7 +489,7 @@ margin-top: -1px; 0 - + objname:StabilizationSettingsBankX fieldname:StickExpo haslimits:yes @@ -809,7 +583,7 @@ margin-top: -1px; 20 - + objname:StabilizationSettingsBankX fieldname:StickExpo haslimits:yes @@ -850,7 +624,7 @@ margin-top: -1px; 20 - + objname:StabilizationSettingsBankX fieldname:StickExpo haslimits:yes @@ -891,7 +665,7 @@ margin-top: -1px; 20 - + objname:StabilizationSettingsBankX fieldname:StickExpo haslimits:yes @@ -920,7 +694,7 @@ margin-top: -1px; Default - + objname:StabilizationSettings button:default buttongroup:66 @@ -935,7 +709,7 @@ margin-top: -1px; - 550 + 450 0 @@ -988,7 +762,7 @@ margin-top: -1px; Default - + objname:StabilizationSettings button:default buttongroup:6 @@ -998,11 +772,14 @@ margin-top: -1px; + + <html><head/><body><p>When this option is selected the simplified version of the configuration view will be used. </p><p>This view hides some settings that are considered advanced and will make it easier for users to get a first working configuration.</p></body></html> + - Use Basic Configuration + Use Basic Configuration View - true + false @@ -1016,7 +793,7 @@ margin-top: -1px; 0 - 0 + 6 @@ -1036,13 +813,13 @@ margin-top: -1px; 100 - 800 + 5000 400 - + objname:StabilizationSettingsBankX fieldname:ManualRate element:Roll @@ -1064,7 +841,7 @@ margin-top: -1px; 80 - 16 + 0 @@ -1639,11 +1416,11 @@ border-radius: 5; 80 - 16 + 0 - Rate yaw + Rate Yaw Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -2227,7 +2004,7 @@ border-radius: 5; 83 - + objname:StabilizationSettingsBankX fieldname:RollMax haslimits:no @@ -2252,7 +2029,7 @@ border-radius: 5; 100 - 800 + 1000 400 @@ -2267,7 +2044,7 @@ border-radius: 5; 20 - + objname:StabilizationSettingsBankX fieldname:ManualRate element:Roll @@ -2296,13 +2073,13 @@ border-radius: 5; 100 - 800 + 5000 400 - + objname:StabilizationSettingsBankX fieldname:ManualRate element:Yaw @@ -2324,7 +2101,7 @@ border-radius: 5; 80 - 16 + 0 @@ -2368,7 +2145,7 @@ border-radius: 5; 10 - + objname:StabilizationSettingsBankX fieldname:RollMax haslimits:no @@ -2961,7 +2738,7 @@ border-radius: 5; 20 - + objname:StabilizationSettingsBankX fieldname:ManualRate element:Yaw @@ -3004,6 +2781,387 @@ border-radius: 5; + + + + + 0 + 0 + + + + Acro+ + + + + + + + 0 + 0 + + + + Qt::StrongFocus + + + <html><head/><body><p>Link roll &amp; pitch sliders to move together</p></body></html> + + + + + + Link Roll and Pitch + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Reset all values to GCS defaults + + + false + + + + + + Default + + + + button:default + buttongroup:77 + + + + + + + + 0 + + + + + + 0 + 25 + + + + <html><head/><body><p>The Acro+ slider can be adjusted to change the amount of manual control blending.</p></body></html> + + + 0 + + + 100 + + + 1 + + + 50 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 5 + + + + objname:StabilizationSettingsBankX + fieldname:AcroInsanityFactor + scale:1 + buttongroup:77 + element:Roll + + + + + + + + + 60 + 22 + + + + + 60 + 22 + + + + 0 + + + 100 + + + 50 + + + + objname:StabilizationSettingsBankX + fieldname:AcroInsanityFactor + scale:1 + buttongroup:77 + element:Roll + + + + + + + + + 0 + 0 + + + + + 80 + 0 + + + + Roll Factor + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 25 + + + + <html><head/><body><p>The Acro+ slider can be adjusted to change the amount of manual control blending.</p></body></html> + + + 0 + + + 100 + + + 1 + + + 50 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 5 + + + + objname:StabilizationSettingsBankX + fieldname:AcroInsanityFactor + scale:1 + buttongroup:77 + element:Pitch + + + + + + + + + 60 + 22 + + + + + 60 + 22 + + + + 0 + + + 100 + + + 50 + + + + objname:StabilizationSettingsBankX + fieldname:AcroInsanityFactor + scale:1 + buttongroup:77 + element:Pitch + + + + + + + + + 0 + 0 + + + + + 80 + 0 + + + + Pitch Factor + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 60 + 22 + + + + + 60 + 22 + + + + 0 + + + 100 + + + 50 + + + + objname:StabilizationSettingsBankX + fieldname:AcroInsanityFactor + scale:1 + buttongroup:77 + element:Yaw + + + + + + + + + 0 + 25 + + + + <html><head/><body><p>The Acro+ slider can be adjusted to change the amount of manual control blending.</p></body></html> + + + 0 + + + 100 + + + 1 + + + 50 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 5 + + + + objname:StabilizationSettingsBankX + fieldname:AcroInsanityFactor + scale:1 + buttongroup:77 + element:Yaw + + + + + + + + + 0 + 0 + + + + + 80 + 0 + + + + Yaw Factor + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + @@ -3107,7 +3265,7 @@ border-radius: 5; Default - + button:default buttongroup:1 @@ -3577,7 +3735,7 @@ border-radius: 5; 20 - + objname:StabilizationSettingsBankX fieldname:RollRatePID element:Ki @@ -3613,7 +3771,7 @@ value as the Kp. 200 - + objname:StabilizationSettingsBankX fieldname:PitchRatePID element:Ki @@ -3649,7 +3807,7 @@ value as the Kp. 200 - + objname:StabilizationSettingsBankX fieldname:RollRatePID element:Ki @@ -3718,7 +3876,7 @@ value as the Kp. 20 - + objname:StabilizationSettingsBankX fieldname:PitchRatePID element:Kp @@ -3762,7 +3920,7 @@ value as the Kp. 20 - + objname:StabilizationSettingsBankX fieldname:YawRatePID element:Kp @@ -5481,7 +5639,7 @@ border-radius: 5; 20 - + objname:StabilizationSettingsBankX fieldname:PitchRatePID element:Ki @@ -5517,7 +5675,7 @@ value as the Kp. 200 - + objname:StabilizationSettingsBankX fieldname:YawRatePID element:Ki @@ -5553,7 +5711,7 @@ Then lower the value by 5 or so. 200 - + objname:StabilizationSettingsBankX fieldname:PitchRatePID element:Kp @@ -5597,7 +5755,7 @@ Then lower the value by 5 or so. 20 - + objname:StabilizationSettingsBankX fieldname:YawRatePID element:Ki @@ -5644,7 +5802,7 @@ Then lower the value by 5 or so. 20 - + objname:StabilizationSettingsBankX fieldname:RollRatePID element:Kp @@ -5680,7 +5838,7 @@ Then lower the value by 5 or so. 200 - + objname:StabilizationSettingsBankX fieldname:RollRatePID element:Kp @@ -5716,7 +5874,7 @@ Then lower the value by 5 or so. 200 - + objname:StabilizationSettingsBankX fieldname:YawRatePID element:Kp @@ -5802,7 +5960,7 @@ Then lower the value by 5 or so. Default - + button:default buttongroup:2 @@ -6248,7 +6406,7 @@ Then lower the value by 5 or so. - + 0 @@ -7358,556 +7516,6 @@ border-radius: 5; - - - - - 0 - 0 - - - - - 0 - 20 - - - - - - - - - 255 - 255 - 255 - - - - - - - - - 74 - 74 - 74 - - - - - 36 - 36 - 36 - - - - - - - - - 58 - 58 - 58 - - - - - - - 48 - 48 - 48 - - - - - - - 19 - 19 - 19 - - - - - - - 26 - 26 - 26 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - - - 74 - 74 - 74 - - - - - 36 - 36 - 36 - - - - - - - - - - - 74 - 74 - 74 - - - - - 36 - 36 - 36 - - - - - - - - - 0 - 0 - 0 - - - - - - - 19 - 19 - 19 - - - - - - - 255 - 255 - 220 - - - - - - - 0 - 0 - 0 - - - - - - - - - 255 - 255 - 255 - - - - - - - - - 74 - 74 - 74 - - - - - 36 - 36 - 36 - - - - - - - - - 58 - 58 - 58 - - - - - - - 48 - 48 - 48 - - - - - - - 19 - 19 - 19 - - - - - - - 26 - 26 - 26 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - - - 74 - 74 - 74 - - - - - 36 - 36 - 36 - - - - - - - - - - - 74 - 74 - 74 - - - - - 36 - 36 - 36 - - - - - - - - - 0 - 0 - 0 - - - - - - - 19 - 19 - 19 - - - - - - - 255 - 255 - 220 - - - - - - - 0 - 0 - 0 - - - - - - - - - 255 - 255 - 255 - - - - - - - - - 74 - 74 - 74 - - - - - 36 - 36 - 36 - - - - - - - - - 58 - 58 - 58 - - - - - - - 48 - 48 - 48 - - - - - - - 19 - 19 - 19 - - - - - - - 26 - 26 - 26 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - - - 74 - 74 - 74 - - - - - 36 - 36 - 36 - - - - - - - - - - - 74 - 74 - 74 - - - - - 36 - 36 - 36 - - - - - - - - - 0 - 0 - 0 - - - - - - - 39 - 39 - 39 - - - - - - - 255 - 255 - 220 - - - - - - - 0 - 0 - 0 - - - - - - - - - 75 - true - - - - false - - - 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; - - - Yaw - - - Qt::AlignCenter - - - @@ -7966,7 +7574,7 @@ border-radius: 5; 20 - + objname:StabilizationSettingsBankX fieldname:RollPI element:Kp @@ -7998,7 +7606,7 @@ border-radius: 5; 200 - + objname:StabilizationSettingsBankX fieldname:RollPI element:Kp @@ -8042,7 +7650,7 @@ border-radius: 5; 20 - + objname:StabilizationSettingsBankX fieldname:PitchPI element:Kp @@ -8074,7 +7682,7 @@ border-radius: 5; 200 - + objname:StabilizationSettingsBankX fieldname:PitchPI element:Kp @@ -8085,83 +7693,39 @@ border-radius: 5; - - - - - 0 - 0 - - - - - 0 - 25 - - - - <html><head/><body><p>This adjusts how much leveling stability is set into Attitude mode (outer loop). Too much will make your vehicle oscillate in Attitude Mode.</p></body></html> - - - 100 - - - 50 - + + Qt::Horizontal - - QSlider::TicksBelow + + QSizePolicy::Minimum - - 20 + + + 60 + 20 + - - - objname:StabilizationSettingsBankX - fieldname:YawPI - element:Kp - scale:0.1 - haslimits:yes - buttongroup:2,10 - + + + + + + Qt::Horizontal - + + QSizePolicy::Minimum + + + + 10 + 20 + + + - - - - 60 - 22 - - - - - 60 - 22 - - - - 200 - - - 200 - - - - objname:StabilizationSettingsBankX - fieldname:YawPI - element:Kp - scale:0.1 - haslimits:yes - buttongroup:2,10 - - - - - Qt::Horizontal @@ -8169,7 +7733,7 @@ border-radius: 5; 40 - 1 + 20 @@ -8258,7 +7822,7 @@ border-radius: 5; Zero the integral when throttle is low - + objname:StabilizationSettings fieldname:LowThrottleZeroIntegral @@ -8368,8 +7932,8 @@ border-radius: 5; 0 0 - 950 - 736 + 776 + 706 @@ -8468,8 +8032,11 @@ border-radius: 5; 0 + + <html><head/><body><p>When this option is selected the advanced version of the configuration view will be used. </p><p>This view shows all settings that are considered advanced and will enable users to to tweak all possible settings to fine tune configuration.</p></body></html> + - Use Advanced Configuration + Use Advanced Configuration View @@ -8503,7 +8070,7 @@ border-radius: 5; Default - + objname:StabilizationSettings button:default buttongroup:6 @@ -9504,7 +9071,7 @@ border-radius: 5;
- + 0 @@ -9545,7 +9112,7 @@ border-radius: 5; 1.000000000000000 - + objname:StabilizationSettingsBankX fieldname:PitchMax haslimits:no @@ -9584,7 +9151,7 @@ response (deg/s) - + 0 @@ -9619,13 +9186,13 @@ response (deg/s) 0 - 1000000.000000000000000 + 2000.000000000000000 1.000000000000000 - + objname:StabilizationSettingsBankX fieldname:ManualRate element:Roll @@ -9637,7 +9204,7 @@ response (deg/s) - + 0 @@ -9672,13 +9239,13 @@ response (deg/s) 0 - 1000000.000000000000000 + 2000.000000000000000 1.000000000000000 - + objname:StabilizationSettingsBankX fieldname:MaximumRate element:Roll @@ -9703,58 +9270,6 @@ response (deg) - - - - - 0 - 0 - - - - - 0 - 22 - - - - - 16777215 - 22 - - - - Qt::StrongFocus - - - <html><head/><body><p>This sets the maximum deg your vehicle will tilt at full stick input when in Attitude mode.</p></body></html> - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 0 - - - 180.000000000000000 - - - 1.000000000000000 - - - - objname:StabilizationSettingsBankX - fieldname:YawMax - haslimits:no - scale:1 - buttongroup:6,20 - - - - @@ -10306,7 +9821,7 @@ border-radius: 5; - + 0 @@ -10341,13 +9856,13 @@ border-radius: 5; 0 - 1000000.000000000000000 + 2000.000000000000000 1.000000000000000 - + objname:StabilizationSettingsBankX fieldname:ManualRate element:Yaw @@ -10909,7 +10424,7 @@ border-radius: 5; - + 0 @@ -10953,7 +10468,7 @@ border-radius: 5; 1.000000000000000 - + objname:StabilizationSettingsBankX fieldname:RollMax haslimits:no @@ -10964,7 +10479,7 @@ border-radius: 5; - + 0 @@ -10999,13 +10514,13 @@ border-radius: 5; 0 - 1000000.000000000000000 + 2000.000000000000000 1.000000000000000 - + objname:StabilizationSettingsBankX fieldname:MaximumRate element:Pitch @@ -11017,7 +10532,7 @@ border-radius: 5; - + 0 @@ -11052,13 +10567,13 @@ border-radius: 5; 0 - 1000000.000000000000000 + 2000.000000000000000 1.000000000000000 - + objname:StabilizationSettingsBankX fieldname:ManualRate element:Pitch @@ -11070,7 +10585,7 @@ border-radius: 5; - + 0 @@ -11105,13 +10620,13 @@ border-radius: 5; 0 - 1000000.000000000000000 + 2000.000000000000000 1.000000000000000 - + objname:StabilizationSettingsBankX fieldname:MaximumRate element:Yaw @@ -11194,7 +10709,7 @@ border-radius: 5; Enable TPS - + objname:StabilizationSettingsBankX fieldname:EnableThrustPIDScaling buttongroup:99 @@ -11755,7 +11270,7 @@ border-radius: 5; - + objname:StabilizationSettingsBankX fieldname:ThrustPIDScaleSource buttongroup:99 @@ -12316,7 +11831,7 @@ border-radius: 5; - + objname:StabilizationSettingsBankX fieldname:ThrustPIDScaleTarget buttongroup:99 @@ -12877,7 +12392,7 @@ border-radius: 5; - + objname:StabilizationSettingsBankX fieldname:ThrustPIDScaleAxes buttongroup:99 @@ -12900,7 +12415,7 @@ border-radius: 5; Default - + objname:StabilizationSettings button:default buttongroup:99 @@ -13017,7 +12532,7 @@ border-radius: 5; Default - + objname:StabilizationSettings button:default buttongroup:4 @@ -13510,7 +13025,7 @@ border-radius: 5; 0.000100000000000 - + objname:StabilizationSettingsBankX fieldname:RollRatePID element:Ki @@ -14110,7 +13625,7 @@ border-radius: 5; 0.000100000000000 - + objname:StabilizationSettingsBankX fieldname:YawRatePID element:Ki @@ -14160,7 +13675,7 @@ border-radius: 5; 0.000100000000000 - + objname:StabilizationSettingsBankX fieldname:YawRatePID element:Kp @@ -14760,7 +14275,7 @@ border-radius: 5; 0.000100000000000 - + objname:StabilizationSettingsBankX fieldname:PitchRatePID element:Ki @@ -14811,7 +14326,7 @@ border-radius: 5; 0.000001000000000 - + objname:StabilizationSettingsBankX fieldname:PitchRatePID element:Kd @@ -14880,7 +14395,7 @@ border-radius: 5; 0.000100000000000 - + objname:StabilizationSettingsBankX fieldname:PitchRatePID element:Kp @@ -14930,7 +14445,7 @@ border-radius: 5; 0.000001000000000 - + objname:StabilizationSettingsBankX fieldname:YawRatePID element:Kd @@ -15561,7 +15076,7 @@ border-radius: 5; 0.000100000000000 - + objname:StabilizationSettingsBankX fieldname:RollRatePID element:Kp @@ -15611,7 +15126,7 @@ border-radius: 5; 0.000001000000000 - + objname:StabilizationSettingsBankX fieldname:RollRatePID element:Kd @@ -15731,7 +15246,7 @@ border-radius: 5; Default - + objname:StabilizationSettings button:default buttongroup:5 @@ -16169,7 +15684,7 @@ border-radius: 5; - + 0 @@ -16218,7 +15733,7 @@ border-radius: 5; 0.100000000000000 - + objname:StabilizationSettingsBankX fieldname:PitchPI element:Kp @@ -16229,56 +15744,6 @@ border-radius: 5; - - - - - 0 - 0 - - - - - 85 - 22 - - - - - 16777215 - 22 - - - - Qt::StrongFocus - - - <html><head/><body><p>This adjusts how much leveling stability is set into Attitude mode (outer loop). Too much will make your vehicle oscillate in Attitude Mode.</p></body></html> - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 3 - - - 0.100000000000000 - - - - objname:StabilizationSettingsBankX - fieldname:YawPI - element:Kp - haslimits:no - scale:1 - buttongroup:5,20 - - - - @@ -16893,7 +16358,7 @@ border-radius: 5; 0.100000000000000 - + objname:StabilizationSettingsBankX fieldname:RollPI element:Kp @@ -16904,606 +16369,6 @@ border-radius: 5; - - - - - 0 - 0 - - - - - 0 - 20 - - - - - - - - - 255 - 255 - 255 - - - - - - - - - 74 - 74 - 74 - - - - - 36 - 36 - 36 - - - - - - - - - 58 - 58 - 58 - - - - - - - 48 - 48 - 48 - - - - - - - 19 - 19 - 19 - - - - - - - 26 - 26 - 26 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - - - 74 - 74 - 74 - - - - - 36 - 36 - 36 - - - - - - - - - - - 74 - 74 - 74 - - - - - 36 - 36 - 36 - - - - - - - - - 0 - 0 - 0 - - - - - - - 19 - 19 - 19 - - - - - - - 255 - 255 - 220 - - - - - - - 0 - 0 - 0 - - - - - - - - - 255 - 255 - 255 - - - - - - - - - 74 - 74 - 74 - - - - - 36 - 36 - 36 - - - - - - - - - 58 - 58 - 58 - - - - - - - 48 - 48 - 48 - - - - - - - 19 - 19 - 19 - - - - - - - 26 - 26 - 26 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - - - 74 - 74 - 74 - - - - - 36 - 36 - 36 - - - - - - - - - - - 74 - 74 - 74 - - - - - 36 - 36 - 36 - - - - - - - - - 0 - 0 - 0 - - - - - - - 19 - 19 - 19 - - - - - - - 255 - 255 - 220 - - - - - - - 0 - 0 - 0 - - - - - - - - - 255 - 255 - 255 - - - - - - - - - 74 - 74 - 74 - - - - - 36 - 36 - 36 - - - - - - - - - 58 - 58 - 58 - - - - - - - 48 - 48 - 48 - - - - - - - 19 - 19 - 19 - - - - - - - 26 - 26 - 26 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - - - 74 - 74 - 74 - - - - - 36 - 36 - 36 - - - - - - - - - - - 74 - 74 - 74 - - - - - 36 - 36 - 36 - - - - - - - - - 0 - 0 - 0 - - - - - - - 39 - 39 - 39 - - - - - - - 255 - 255 - 220 - - - - - - - 0 - 0 - 0 - - - - - - - - - 75 - true - - - - false - - - 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; - - - Yaw - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - - 0 - 22 - - - - - 16777215 - 22 - - - - Qt::StrongFocus - - - <html><head/><body><p>This adjusts how much stability your vehicle will have when flying tilted (ie forward flight) in Attitude Mode. Adding Ki in Attitude when Ki is present in Rate is not recommended.</p></body></html> - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 3 - - - 0.100000000000000 - - - - objname:StabilizationSettingsBankX - fieldname:YawPI - element:Ki - haslimits:no - scale:1 - buttongroup:5,20 - - - - @@ -17543,7 +16408,7 @@ border-radius: 5; 0.100000000000000 - + objname:StabilizationSettingsBankX fieldname:PitchPI element:Ki @@ -17593,7 +16458,7 @@ border-radius: 5; 0.100000000000000 - + objname:StabilizationSettingsBankX fieldname:RollPI element:Ki @@ -18195,53 +17060,182 @@ border-radius: 5; - - - Pirouette Compensation + + + 20 - - - - - - 0 - 27 - + + + + Pirouette Compensation + + + + + + + 0 + 27 + + + + Enable pirouette compensation + + + + objname:StabilizationSettingsBankX + fieldname:EnablePiroComp + buttongroup:55 + + + + + + + + Reset all values to GCS defaults + + + + + + Default + + + + objname:StabilizationSettings + button:default + buttongroup:55 + + + + + + + + + + + FPV Camera Tilt Compensation + + + + 9 - - Enable pirouette compensation + + 9 - - - objname:StabilizationSettingsBankX - fieldname:EnablePiroComp - buttongroup:55 - + + 9 - - - - - - Reset all values to GCS defaults + + 9 - - - - - Default - - - - objname:StabilizationSettings - button:default - buttongroup:55 - - - - - - + + + + Reset value to GCS defaults + + + + + + Default + + + + objname:StabilizationSettings + button:default + buttongroup:56 + + + + + + + + Camera Tilt Angle (deg) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 80 + 22 + + + + + 80 + 22 + + + + Qt::StrongFocus + + + Camera tilt angle from 0 to 50 degrees (0 to disable compensation). + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + 0 + + + 0.000000000000000 + + + 50.000000000000000 + + + 0.000000000000000 + + + + objname:StabilizationSettingsBankX + fieldname:FpvCamTiltCompensation + haslimits:no + scale:1 + buttongroup:56 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 40 + 20 + + + + + + + + @@ -18360,8 +17354,8 @@ border-radius: 5; 0 0 - 950 - 671 + 797 + 604 @@ -18403,7 +17397,7 @@ border-radius: 5; Default - + objname:StabilizationSettings button:default buttongroup:25 @@ -18459,7 +17453,7 @@ border-radius: 5; 1.000000000000000 - + objname:StabilizationSettings fieldname:MaxWeakLevelingRate haslimits:no @@ -19618,7 +18612,7 @@ font:bold; 0.010000000000000 - + objname:StabilizationSettings fieldname:WeakLevelingKp haslimits:no @@ -19670,7 +18664,7 @@ font:bold; Default - + objname:StabilizationSettings button:default buttongroup:31 @@ -19729,7 +18723,7 @@ font:bold; 1.000000000000000 - + objname:StabilizationSettings fieldname:MaxAxisLock haslimits:no @@ -20888,7 +19882,7 @@ font:bold; 1.000000000000000 - + objname:StabilizationSettings fieldname:MaxAxisLockRate haslimits:no @@ -20941,7 +19935,7 @@ font:bold; Default - + objname:StabilizationSettings button:default buttongroup:15 @@ -21069,7 +20063,7 @@ border-radius: 5; 80.000000000000000 - + objname:StabilizationSettings fieldname:RattitudeModeTransition haslimits:no @@ -21185,7 +20179,7 @@ border-radius: 5; 5.000000000000000 - + objname:StabilizationSettings fieldname:CruiseControlMinThrust haslimits:no @@ -21228,7 +20222,7 @@ border-radius: 5; 90.000000000000000 - + objname:StabilizationSettings fieldname:CruiseControlMaxThrust haslimits:no @@ -21292,7 +20286,7 @@ border-radius: 5; <html><head/><body><p>CP helis can set this to Reversed to automatically reverse the direction of thrust when inverted. Fixed pitch copters, including multicopters, should leave this set at Unreversed. Unreversed direction with Boosted power may be dangerous because it adds power and the thrust direction moves the aircraft towards the ground.</p></body></html> - + objname:StabilizationSettings fieldname:CruiseControlInvertedThrustReversing haslimits:no @@ -21374,7 +20368,7 @@ border-radius: 5; 105.000000000000000 - + objname:StabilizationSettings fieldname:CruiseControlMaxAngle haslimits:no @@ -21462,7 +20456,7 @@ border-radius: 5; 3.000000000000000 - + objname:StabilizationSettings fieldname:CruiseControlMaxPowerFactor haslimits:no @@ -21595,7 +20589,7 @@ border-radius: 5; <html><head/><body><p>The amount of power used when in inverted mode. Zero (min throttle stick for fixed pitch copters includding multicopters, neutral collective for CP), Normal (uses stick value), or Boosted (boosted according to bank angle). Beginning multicopter pilots should leave this set to Zero to automatically reduce throttle during flips. Boosted power with Unreversed direction may be dangerous because it adds power and the thrust direction moves the aircraft towards the ground.</p></body></html> - + objname:StabilizationSettings fieldname:CruiseControlInvertedPowerOutput haslimits:no @@ -21644,7 +20638,7 @@ border-radius: 5; 100.000000000000000 - + objname:StabilizationSettings fieldname:CruiseControlPowerTrim haslimits:no @@ -21762,7 +20756,7 @@ border-radius: 5; 0.250000000000000 - + objname:StabilizationSettings fieldname:CruiseControlPowerDelayComp haslimits:no @@ -21784,7 +20778,7 @@ border-radius: 5; Default - + objname:StabilizationSettings button:default buttongroup:16 @@ -21848,7 +20842,7 @@ border-radius: 5; Default - + objname:StabilizationSettings button:default buttongroup:8 @@ -22880,7 +21874,7 @@ font:bold; 0.000100000000000 - + objname:AttitudeSettings fieldname:AccelKi haslimits:no @@ -22932,7 +21926,7 @@ font:bold; 0.010000000000000 - + objname:AttitudeSettings fieldname:AccelKp haslimits:no @@ -23536,7 +22530,7 @@ font:bold; 0.001000000000000 - + objname:StabilizationSettings fieldname:GyroTau haslimits:no @@ -24206,8 +23200,8 @@ font:bold; 0 0 - 950 - 671 + 500 + 600 @@ -24286,7 +23280,7 @@ font:bold; Default - + objname:AltitudeHoldSettings button:default buttongroup:98 @@ -25331,7 +24325,7 @@ border-radius: 5; 51 - + objname:AltitudeHoldSettings fieldname:VerticalPosP scale:0.01 @@ -25437,7 +24431,7 @@ border-radius: 5; QSlider::TicksBelow - + objname:AltitudeHoldSettings fieldname:VerticalVelPID element:Ki @@ -25484,7 +24478,7 @@ border-radius: 5; 25 - + objname:AltitudeHoldSettings fieldname:VerticalVelPID element:Ki @@ -25544,7 +24538,7 @@ border-radius: 5; QSlider::TicksBelow - + objname:AltitudeHoldSettings fieldname:VerticalVelPID element:Kd @@ -25591,7 +24585,7 @@ border-radius: 5; 51 - + objname:AltitudeHoldSettings fieldname:VerticalVelPID element:Kd @@ -25657,7 +24651,7 @@ border-radius: 5; QSlider::TicksBelow - + objname:AltitudeHoldSettings fieldname:VerticalVelPID element:Beta @@ -25707,7 +24701,7 @@ border-radius: 5; 90 - + objname:AltitudeHoldSettings fieldname:VerticalVelPID element:Beta @@ -25747,6 +24741,9 @@ border-radius: 5; Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + 1 + 100 @@ -25754,7 +24751,7 @@ border-radius: 5; 50 - + objname:AltitudeHoldSettings fieldname:VerticalVelPID element:Kp @@ -25798,6 +24795,9 @@ border-radius: 5; <html><head/><body><p>How much the vehicle should throttle up or down to compensate or achieve a certain vertical speed. Higher values lead to more aggressive throttle changes and could lead to oscillations. This is the most likely candidate to change depending on the crafts engine thrust. Heavy craft with weak engines might require higher values.</p></body></html> + + 1 + 100 @@ -25811,7 +24811,7 @@ border-radius: 5; QSlider::TicksBelow - + objname:AltitudeHoldSettings fieldname:VerticalVelPID element:Kp @@ -25903,7 +24903,7 @@ border-radius: 5; Default - + objname:AltitudeHoldSettings button:default buttongroup:99 @@ -26407,7 +25407,7 @@ border-radius: 5; 128.000000000000000 - + objname:AltitudeHoldSettings fieldname:ThrustExp haslimits:no @@ -26481,7 +25481,7 @@ border-radius: 5; 3.000000000000000 - + objname:AltitudeHoldSettings fieldname:ThrustRate haslimits:no @@ -26506,7 +25506,7 @@ border-radius: 5; QSlider::TicksBelow - + objname:AltitudeHoldSettings fieldname:ThrustExp haslimits:no @@ -27090,7 +26090,7 @@ border-radius: 5; 0 - + objname:AltitudeHoldSettings fieldname:ThrustRate haslimits:no @@ -27220,7 +26220,7 @@ border-radius: 5; - + 0 @@ -27262,14 +26262,14 @@ border-radius: 5; true - + button:help - + 0 @@ -27305,7 +26305,7 @@ Useful if you have accidentally changed some settings. - + button:reload buttongroup:10 @@ -27313,7 +26313,7 @@ Useful if you have accidentally changed some settings. - + 0 @@ -27342,14 +26342,14 @@ Useful if you have accidentally changed some settings. Apply - + button:apply - + 0 @@ -27378,7 +26378,7 @@ Useful if you have accidentally changed some settings. Save - + button:save @@ -27410,19 +26410,18 @@ Useful if you have accidentally changed some settings. - tabWidget - scrollArea basicResponsivenessCheckBox - pushButton - AttitudeResponsivenessSlider - spinBox RateResponsivenessSlider + spinBox spinBox_2 RateYawResponsivenessSlider spinBox_5 pushButton_21 + pushButton + FpvCamTiltCompensation AcroFactorRollSlider AcroFactorRollSpinBox + pushButton_14 AcroFactorPitchSlider AcroFactorPitchSpinBox pushButton_12 @@ -27452,22 +26451,19 @@ Useful if you have accidentally changed some settings. spinBox_13 horizontalSlider_83 spinBox_14 - horizontalSlider_84 - spinBox_15 lowThrottleZeroIntegral_8 realTimeUpdates_8 scrollArea_2 advancedResponsivenessCheckBox pushButton_3 - rateRollKp_3 - ratePitchKp_4 - rateYawKp_3 - rateRollKi_3 - ratePitchKi_4 - rateYawKi_3 - rateRollILimit_3 - ratePitchILimit_4 - rateYawILimit_3 + attitudeRollResponse + attitudePitchResponse + rateRollResponse + ratePitchResponse + rateYawResponse + maxRateRollLimit + maxRatePitchLimit + maxRateYawLimit enableThrustPIDScalingCheckBox ThrustPIDSource ThrustPIDTarget @@ -27488,10 +26484,8 @@ Useful if you have accidentally changed some settings. pushButton_2 AttitudeRollKp AttitudePitchKp_2 - AttitudeYawKp AttitudeRollKi AttitudePitchKi_2 - AttitudeYawKi enableThrustPIDScalingCheckBox_2 pushButton_13 realTimeUpdates_12 @@ -27532,10 +26526,18 @@ Useful if you have accidentally changed some settings. AltThrRateSlider_2 AltThrRate_2 realTimeUpdates_7 - pushButton_23 - stabilizationReloadBoardData_6 - saveStabilizationToRAM_6 - saveStabilizationToSD_6 + helpButton + reloadButton + applyButton + saveButton + checkBoxLinkAcroFactors + tabWidget + AttitudeResponsivenessSlider + scrollArea + VelKdSlider + VelKd + VelBetaSlider + VelBeta diff --git a/ground/gcs/src/plugins/config/txpid.ui b/ground/gcs/src/plugins/config/txpid.ui index 13d64514d..b0b201697 100644 --- a/ground/gcs/src/plugins/config/txpid.ui +++ b/ground/gcs/src/plugins/config/txpid.ui @@ -118,9 +118,9 @@ 0 - -391 - 754 - 783 + 0 + 751 + 768 @@ -813,7 +813,7 @@ font:bold; Default - + button:default buttongroup:10 @@ -881,7 +881,7 @@ font:bold; 5 - + objname:TxPIDSettings fieldname:EasyTunePitchRollRateFactors scale:0.1 @@ -892,7 +892,7 @@ font:bold; - + 0 @@ -946,7 +946,7 @@ font:bold; 0.013500000000000 - + objname:TxPIDSettings fieldname:EasyTunePitchRollRateFactors scale:1 @@ -971,7 +971,7 @@ font:bold; AutoCalc Yaw - + objname:TxPIDSettings fieldname:EasyTuneRatePIDRecalculateYaw buttongroup:11 @@ -1037,7 +1037,7 @@ font:bold; 5 - + objname:TxPIDSettings fieldname:EasyTuneYawRateFactors scale:0.1 @@ -1099,7 +1099,7 @@ font:bold; 1.900000000000000 - + objname:TxPIDSettings fieldname:EasyTuneYawRateFactors scale:1 @@ -1164,7 +1164,7 @@ font:bold; 0.008500000000000 - + objname:TxPIDSettings fieldname:EasyTuneYawRateFactors scale:1 @@ -1242,7 +1242,7 @@ font:bold; Default - + button:default buttongroup:11 @@ -1282,7 +1282,7 @@ font:bold; 2.500000000000000 - + objname:TxPIDSettings fieldname:EasyTuneYawRateFactors scale:1 @@ -1322,7 +1322,7 @@ font:bold; 4.000000000000000 - + objname:TxPIDSettings fieldname:EasyTunePitchRollRateFactors scale:1 @@ -1426,7 +1426,7 @@ font:bold; - + 0 @@ -1477,14 +1477,14 @@ font:bold; true - + button:help - + 0 @@ -1500,10 +1500,13 @@ font:bold; Apply + + button:apply + - + 0 @@ -1522,6 +1525,9 @@ font:bold; false + + button:save + @@ -1529,8 +1535,8 @@ font:bold; - Apply - Save + applyButton + saveButton scrollArea PID1 Input1 diff --git a/ground/gcs/src/plugins/consolegadget/consolegadget.pro b/ground/gcs/src/plugins/consolegadget/consolegadget.pro index 6662fafaf..fd8a2e0a3 100644 --- a/ground/gcs/src/plugins/consolegadget/consolegadget.pro +++ b/ground/gcs/src/plugins/consolegadget/consolegadget.pro @@ -1,15 +1,21 @@ TEMPLATE = lib TARGET = ConsoleGadget + include(../../plugin.pri) include(../../plugins/coreplugin/coreplugin.pri) -HEADERS += consoleplugin.h \ - texteditloggerengine.h -HEADERS += consolegadget.h -HEADERS += consolegadgetwidget.h -HEADERS += consolegadgetfactory.h -SOURCES += consoleplugin.cpp \ - texteditloggerengine.cpp -SOURCES += consolegadget.cpp -SOURCES += consolegadgetfactory.cpp -SOURCES += consolegadgetwidget.cpp + +HEADERS += \ + consoleplugin.h \ + texteditloggerengine.h \ + consolegadget.h \ + consolegadgetwidget.h \ + consolegadgetfactory.h + +SOURCES += \ + consoleplugin.cpp \ + texteditloggerengine.cpp \ + consolegadget.cpp \ + consolegadgetfactory.cpp \ + consolegadgetwidget.cpp + OTHER_FILES += ConsoleGadget.pluginspec diff --git a/ground/gcs/src/plugins/coreplugin/aboutdialog.cpp b/ground/gcs/src/plugins/coreplugin/aboutdialog.cpp index e50cbae47..21c90ae7f 100644 --- a/ground/gcs/src/plugins/coreplugin/aboutdialog.cpp +++ b/ground/gcs/src/plugins/coreplugin/aboutdialog.cpp @@ -58,8 +58,8 @@ AboutDialog::AboutDialog(QWidget *parent) : "Built on %4 at %5
" "Based on Qt %6 (%7 bit)
" "
" - "© The %8 Project, %9. All rights reserved.
" - "© The OpenPilot Project 2010-2015. All rights reserved.
" + "\u00A9 The %8 Project, 2015-%9. All rights reserved.
" + "\u00A9 The OpenPilot Project, 2010-2015. All rights reserved.
" ).arg( VersionInfo::revision().left(60), // %1 VersionInfo::uavoHash().left(8), // %2 @@ -72,9 +72,35 @@ AboutDialog::AboutDialog(QWidget *parent) : VersionInfo::year() // %9 ); + // %1 = name, %2 = description, %3 = url, %4 = image url (not used) + //
+ QString creditRow = ""; + + // uses Text.StyledText (see http://doc.qt.io/qt-5/qml-qtquick-text.html#textFormat-prop) + const QString credits = "
%1%2
%3
" + + creditRow.arg("Tau Labs", "", "http://www.taulabs.org") + + creditRow.arg("dRonin", "", "http://www.dronin.org") + + creditRow.arg("OpenSceneGraph", "
Open source high performance 3D graphics toolkit", "http://www.openscenegraph.org") + + creditRow.arg("osgEarth", "
Geospatial SDK for OpenSceneGraph", "http://osgearth.org") + + creditRow.arg("MSYS2", "
An independent rewrite of MSYS", "https://sourceforge.net/p/msys2/wiki/Home") + + creditRow.arg("The Qt Company", "", "http://www.qt.io") + + "
"; + + // uses Text.StyledText (see http://doc.qt.io/qt-5/qml-qtquick-text.html#textFormat-prop) + const QString license = tr("This program is free software; you can redistribute it and/or " + "modify it under the terms of the GNU General Public License " + "as published by the Free Software Foundation; either version 3 " + "of the License, or (at your option) any later version.\n" + "The program is provided AS IS with NO WARRANTY OF ANY KIND, " + "INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE." + ); + + QQuickView *view = new QQuickView(); view->rootContext()->setContextProperty("dialog", this); view->rootContext()->setContextProperty("version", description); + view->rootContext()->setContextProperty("credits", credits); + view->rootContext()->setContextProperty("license", license); view->setResizeMode(QQuickView::SizeRootObjectToView); view->setSource(QUrl("qrc:/core/qml/AboutDialog.qml")); diff --git a/ground/gcs/src/plugins/coreplugin/connectionmanager.cpp b/ground/gcs/src/plugins/coreplugin/connectionmanager.cpp index a225b97e6..e068ea5bf 100644 --- a/ground/gcs/src/plugins/coreplugin/connectionmanager.cpp +++ b/ground/gcs/src/plugins/coreplugin/connectionmanager.cpp @@ -2,7 +2,8 @@ ****************************************************************************** * * @file connectionmanager.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009. * @addtogroup GCSPlugins GCS Plugins * @{ @@ -71,9 +72,11 @@ ConnectionManager::ConnectionManager(Internal::MainWindow *mainWindow) : QObject::connect(m_availableDevList, SIGNAL(currentIndexChanged(int)), this, SLOT(onDeviceSelectionChanged(int))); // setup our reconnect timers + // TODO these are never started because telemetryConnected is not called anymore reconnect = new QTimer(this); - reconnectCheck = new QTimer(this); connect(reconnect, SIGNAL(timeout()), this, SLOT(reconnectSlot())); + + reconnectCheck = new QTimer(this); connect(reconnectCheck, SIGNAL(timeout()), this, SLOT(reconnectCheckSlot())); } @@ -91,7 +94,6 @@ void ConnectionManager::init() QObject::connect(ExtensionSystem::PluginManager::instance(), SIGNAL(aboutToRemoveObject(QObject *)), this, SLOT(aboutToRemoveObject(QObject *))); } - // TODO needs documentation? void ConnectionManager::addWidget(QWidget *widget) { @@ -271,7 +273,7 @@ void ConnectionManager::onConnectClicked() */ void ConnectionManager::telemetryConnected() { - qDebug() << "TelemetryMonitor: connected"; + qDebug() << "ConnectionManager::telemetryConnected"; if (reconnectCheck->isActive()) { reconnectCheck->stop(); @@ -283,7 +285,7 @@ void ConnectionManager::telemetryConnected() */ void ConnectionManager::telemetryDisconnected() { - qDebug() << "TelemetryMonitor: disconnected"; + qDebug() << "ConnectionManager::telemetryDisconnected"; if (m_ioDev) { if (m_connectionDevice.connection->shortName() == "Serial") { @@ -296,17 +298,18 @@ void ConnectionManager::telemetryDisconnected() void ConnectionManager::reconnectSlot() { - qDebug() << "reconnect"; + qDebug() << "ConnectionManager::reconnectSlot"; + if (m_ioDev->isOpen()) { m_ioDev->close(); } if (m_ioDev->open(QIODevice::ReadWrite)) { - qDebug() << "reconnect successfull"; + qDebug() << "ConnectionManager::reconnectSlot - reconnect successful"; reconnect->stop(); reconnectCheck->start(20000); } else { - qDebug() << "reconnect NOT successfull"; + qDebug() << "ConnectionManager::reconnectSlot - reconnect NOT successful"; } } @@ -327,7 +330,7 @@ DevListItem ConnectionManager::findDevice(const QString &devName) } } - qDebug() << "findDevice: cannot find " << devName << " in device list"; + qWarning() << "ConnectionManager::findDevice - cannot find " << devName << " in device list"; DevListItem d; d.connection = NULL; @@ -441,7 +444,7 @@ void ConnectionManager::devChanged(IConnection *connection) updateConnectionDropdown(); - qDebug() << "# devices " << m_devList.count(); + qDebug() << "ConnectionManager::devChanged - device count:" << m_devList.count(); emit availableDevicesChanged(m_devList); @@ -464,9 +467,8 @@ void ConnectionManager::updateConnectionDropdown() m_availableDevList->setCurrentIndex(m_availableDevList->count() - 1); } if (m_mainWindow->generalSettings()->autoConnect() && polling) { - qDebug() << "Automatically opening device"; + qDebug() << "ConnectionManager::updateConnectionDropdown - auto-connecting USB device"; connectDevice(d); - qDebug() << "ConnectionManager::updateConnectionDropdown autoconnected USB device"; } } } diff --git a/ground/gcs/src/plugins/coreplugin/core.qrc b/ground/gcs/src/plugins/coreplugin/core.qrc index 35744c4dc..0a7e4c4a4 100644 --- a/ground/gcs/src/plugins/coreplugin/core.qrc +++ b/ground/gcs/src/plugins/coreplugin/core.qrc @@ -64,6 +64,5 @@ qml/images/tab.png qml/AboutDialog.qml ../../../../../build/gcs-synthetics/AuthorsModel.qml - images/opie_90x120.gif diff --git a/ground/gcs/src/plugins/coreplugin/coreplugin.pro b/ground/gcs/src/plugins/coreplugin/coreplugin.pro index 78433edc0..427565091 100644 --- a/ground/gcs/src/plugins/coreplugin/coreplugin.pro +++ b/ground/gcs/src/plugins/coreplugin/coreplugin.pro @@ -1,14 +1,9 @@ TEMPLATE = lib TARGET = Core + DEFINES += CORE_LIBRARY - -QT += qml \ - quick \ - xml \ - network \ - script \ - svg \ - sql + +QT += widgets qml quick xml network script svg sql include(../../plugin.pri) include(../../libs/utils/utils.pri) @@ -17,15 +12,18 @@ include(../../shared/scriptwrapper/scriptwrapper.pri) include(coreplugin_dependencies.pri) include(authorsdialog.pri) -INCLUDEPATH += dialogs \ +INCLUDEPATH += \ + dialogs \ uavgadgetmanager \ actionmanager -DEPENDPATH += dialogs \ +DEPENDPATH += \ + dialogs \ uavgadgetmanager \ actionmanager -SOURCES += mainwindow.cpp \ +SOURCES += \ + mainwindow.cpp \ tabpositionindicator.cpp \ fancyactionbar.cpp \ fancytabwidget.cpp \ @@ -72,7 +70,8 @@ SOURCES += mainwindow.cpp \ uavconfiginfo.cpp \ aboutdialog.cpp \ -HEADERS += mainwindow.h \ +HEADERS += \ + mainwindow.h \ tabpositionindicator.h \ fancyactionbar.h \ fancytabwidget.h \ @@ -132,13 +131,15 @@ HEADERS += mainwindow.h \ iconfigurableplugin.h \ aboutdialog.h -FORMS += dialogs/settingsdialog.ui \ +FORMS += \ + dialogs/settingsdialog.ui \ dialogs/shortcutsettings.ui \ generalsettings.ui \ uavgadgetoptionspage.ui \ workspacesettings.ui -RESOURCES += core.qrc \ +RESOURCES += \ + core.qrc \ fancyactionbar.qrc unix:!macx { diff --git a/ground/gcs/src/plugins/coreplugin/dialogs/settingsdialog.cpp b/ground/gcs/src/plugins/coreplugin/dialogs/settingsdialog.cpp index 5382cdc1f..1ffa5bc98 100644 --- a/ground/gcs/src/plugins/coreplugin/dialogs/settingsdialog.cpp +++ b/ground/gcs/src/plugins/coreplugin/dialogs/settingsdialog.cpp @@ -215,7 +215,7 @@ Q_DECLARE_METATYPE(::PageData) SettingsDialog::SettingsDialog(QWidget *parent, c SettingsDialog::~SettingsDialog() { foreach(QString category, m_categoryItemsMap.keys()) { - QList *categoryItemList = m_categoryItemsMap.value(category); + QList *categoryItemList = m_categoryItemsMap.value(category, NULL); delete categoryItemList; } // delete place holders @@ -237,7 +237,7 @@ QTreeWidgetItem *SettingsDialog::addPage(IOptionsPage *page) QString category = page->category(); - QList *categoryItemList = m_categoryItemsMap.value(category); + QList *categoryItemList = m_categoryItemsMap.value(category, NULL); if (!categoryItemList) { categoryItemList = new QList(); m_categoryItemsMap.insert(category, categoryItemList); @@ -346,7 +346,7 @@ void SettingsDialog::deletePage() PageData data = item->data(0, Qt::UserRole).value(); QString category = data.category; - QList *categoryItemList = m_categoryItemsMap.value(category); + QList *categoryItemList = m_categoryItemsMap.value(category, NULL); if (categoryItemList) { categoryItemList->removeOne(item); QTreeWidgetItem *parentItem = item->parent(); @@ -382,7 +382,7 @@ void SettingsDialog::insertPage(IOptionsPage *page) // If this category has no child right now // we need to add the "default child" - QList *categoryItemList = m_categoryItemsMap.value(page->category()); + QList *categoryItemList = m_categoryItemsMap.value(page->category(), NULL); if (categoryItem->childCount() == 1) { QTreeWidgetItem *defaultItem = categoryItemList->at(0); defaultItem->setHidden(false); diff --git a/ground/gcs/src/plugins/coreplugin/generalsettings.cpp b/ground/gcs/src/plugins/coreplugin/generalsettings.cpp index 436692f84..b3b276729 100644 --- a/ground/gcs/src/plugins/coreplugin/generalsettings.cpp +++ b/ground/gcs/src/plugins/coreplugin/generalsettings.cpp @@ -29,17 +29,17 @@ #include "generalsettings.h" +#include "ui_generalsettings.h" + #include #include #include #include + #include -#include - -#include -#include - -#include "ui_generalsettings.h" +#include +#include +#include using namespace Utils; using namespace Core::Internal; diff --git a/ground/gcs/src/plugins/coreplugin/generalsettings.h b/ground/gcs/src/plugins/coreplugin/generalsettings.h index d6828704c..c07b234df 100644 --- a/ground/gcs/src/plugins/coreplugin/generalsettings.h +++ b/ground/gcs/src/plugins/coreplugin/generalsettings.h @@ -30,7 +30,8 @@ #define GENERALSETTINGS_H #include -#include + +#include #include #include diff --git a/ground/gcs/src/plugins/coreplugin/images/ah.png b/ground/gcs/src/plugins/coreplugin/images/ah.png index 646f24ad6..29258b41e 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/ah.png and b/ground/gcs/src/plugins/coreplugin/images/ah.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/clean_pane_small.png b/ground/gcs/src/plugins/coreplugin/images/clean_pane_small.png index 341e23861..d5f68eaec 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/clean_pane_small.png and b/ground/gcs/src/plugins/coreplugin/images/clean_pane_small.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/clear.png b/ground/gcs/src/plugins/coreplugin/images/clear.png index 72279e1c6..1f16d745d 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/clear.png and b/ground/gcs/src/plugins/coreplugin/images/clear.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/closebutton.png b/ground/gcs/src/plugins/coreplugin/images/closebutton.png index c978cf51a..e661a9ceb 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/closebutton.png and b/ground/gcs/src/plugins/coreplugin/images/closebutton.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/cog.png b/ground/gcs/src/plugins/coreplugin/images/cog.png index 97b835c58..0b375f240 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/cog.png and b/ground/gcs/src/plugins/coreplugin/images/cog.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/config.png b/ground/gcs/src/plugins/coreplugin/images/config.png index 650a00365..bb01b8a62 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/config.png and b/ground/gcs/src/plugins/coreplugin/images/config.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/cpu.png b/ground/gcs/src/plugins/coreplugin/images/cpu.png index 37e979422..50ff76074 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/cpu.png and b/ground/gcs/src/plugins/coreplugin/images/cpu.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/darkclosebutton.png b/ground/gcs/src/plugins/coreplugin/images/darkclosebutton.png index 1077663b2..c17f2c80d 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/darkclosebutton.png and b/ground/gcs/src/plugins/coreplugin/images/darkclosebutton.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/dir.png b/ground/gcs/src/plugins/coreplugin/images/dir.png index 57cec6bcd..01f175912 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/dir.png and b/ground/gcs/src/plugins/coreplugin/images/dir.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/editcopy.png b/ground/gcs/src/plugins/coreplugin/images/editcopy.png index ceb520e30..b64bdab63 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/editcopy.png and b/ground/gcs/src/plugins/coreplugin/images/editcopy.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/editcut.png b/ground/gcs/src/plugins/coreplugin/images/editcut.png index 700ccb0cf..7d0735b07 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/editcut.png and b/ground/gcs/src/plugins/coreplugin/images/editcut.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/editpaste.png b/ground/gcs/src/plugins/coreplugin/images/editpaste.png index 7238fae7f..8777672f1 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/editpaste.png and b/ground/gcs/src/plugins/coreplugin/images/editpaste.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/empty14.png b/ground/gcs/src/plugins/coreplugin/images/empty14.png index 7346e5808..386354af4 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/empty14.png and b/ground/gcs/src/plugins/coreplugin/images/empty14.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/exiticon.png b/ground/gcs/src/plugins/coreplugin/images/exiticon.png index cf3e654d1..c427b29b1 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/exiticon.png and b/ground/gcs/src/plugins/coreplugin/images/exiticon.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/extension.png b/ground/gcs/src/plugins/coreplugin/images/extension.png index 40c2ee30d..6aba19bdd 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/extension.png and b/ground/gcs/src/plugins/coreplugin/images/extension.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/filenew.png b/ground/gcs/src/plugins/coreplugin/images/filenew.png index dd795cfff..9dcfc2ca3 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/filenew.png and b/ground/gcs/src/plugins/coreplugin/images/filenew.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/fileopen.png b/ground/gcs/src/plugins/coreplugin/images/fileopen.png index 58d70149e..31c739cbd 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/fileopen.png and b/ground/gcs/src/plugins/coreplugin/images/fileopen.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/filesave.png b/ground/gcs/src/plugins/coreplugin/images/filesave.png index 604ee3b83..e722febdd 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/filesave.png and b/ground/gcs/src/plugins/coreplugin/images/filesave.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/find.png b/ground/gcs/src/plugins/coreplugin/images/find.png index cbe2f3152..0636063f3 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/find.png and b/ground/gcs/src/plugins/coreplugin/images/find.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/findnext.png b/ground/gcs/src/plugins/coreplugin/images/findnext.png index a2889e439..8b18b678e 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/findnext.png and b/ground/gcs/src/plugins/coreplugin/images/findnext.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/flight.png b/ground/gcs/src/plugins/coreplugin/images/flight.png index 419a0b7af..936ff14d7 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/flight.png and b/ground/gcs/src/plugins/coreplugin/images/flight.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/helpicon.png b/ground/gcs/src/plugins/coreplugin/images/helpicon.png index 4996b5421..7d9223d10 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/helpicon.png and b/ground/gcs/src/plugins/coreplugin/images/helpicon.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/home.png b/ground/gcs/src/plugins/coreplugin/images/home.png index fed62219f..0865b94ce 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/home.png and b/ground/gcs/src/plugins/coreplugin/images/home.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/inputfield.png b/ground/gcs/src/plugins/coreplugin/images/inputfield.png index 40bdfc4a0..13271f5aa 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/inputfield.png and b/ground/gcs/src/plugins/coreplugin/images/inputfield.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/inputfield_disabled.png b/ground/gcs/src/plugins/coreplugin/images/inputfield_disabled.png index b713a59c8..818a26c73 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/inputfield_disabled.png and b/ground/gcs/src/plugins/coreplugin/images/inputfield_disabled.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/joystick.png b/ground/gcs/src/plugins/coreplugin/images/joystick.png index 960ba9465..7e1f843ed 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/joystick.png and b/ground/gcs/src/plugins/coreplugin/images/joystick.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/librepilot_logo_128.png b/ground/gcs/src/plugins/coreplugin/images/librepilot_logo_128.png index ba5f8e7d3..38f17c0c8 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/librepilot_logo_128.png and b/ground/gcs/src/plugins/coreplugin/images/librepilot_logo_128.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/librepilot_logo_256.png b/ground/gcs/src/plugins/coreplugin/images/librepilot_logo_256.png index 6fa0603fc..34a807b34 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/librepilot_logo_256.png and b/ground/gcs/src/plugins/coreplugin/images/librepilot_logo_256.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/librepilot_logo_32.png b/ground/gcs/src/plugins/coreplugin/images/librepilot_logo_32.png index 4af6fbfc3..de7d352bb 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/librepilot_logo_32.png and b/ground/gcs/src/plugins/coreplugin/images/librepilot_logo_32.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/librepilot_logo_500.png b/ground/gcs/src/plugins/coreplugin/images/librepilot_logo_500.png index 3ce6a7e15..7cf7e1d6c 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/librepilot_logo_500.png and b/ground/gcs/src/plugins/coreplugin/images/librepilot_logo_500.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/librepilot_logo_64.png b/ground/gcs/src/plugins/coreplugin/images/librepilot_logo_64.png index 779c271db..3b43e09db 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/librepilot_logo_64.png and b/ground/gcs/src/plugins/coreplugin/images/librepilot_logo_64.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/librepiloticon.png b/ground/gcs/src/plugins/coreplugin/images/librepiloticon.png index 442b06172..48b7a2dda 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/librepiloticon.png and b/ground/gcs/src/plugins/coreplugin/images/librepiloticon.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/linkicon.png b/ground/gcs/src/plugins/coreplugin/images/linkicon.png index 4e4d4f7b7..e42f5fdd9 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/linkicon.png and b/ground/gcs/src/plugins/coreplugin/images/linkicon.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/locked.png b/ground/gcs/src/plugins/coreplugin/images/locked.png index 0ff602714..f3f0821ea 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/locked.png and b/ground/gcs/src/plugins/coreplugin/images/locked.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/magnifier.png b/ground/gcs/src/plugins/coreplugin/images/magnifier.png index 0e652c945..74d558d15 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/magnifier.png and b/ground/gcs/src/plugins/coreplugin/images/magnifier.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/minus.png b/ground/gcs/src/plugins/coreplugin/images/minus.png index 446684466..f932c2102 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/minus.png and b/ground/gcs/src/plugins/coreplugin/images/minus.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/mode_Debug.png b/ground/gcs/src/plugins/coreplugin/images/mode_Debug.png index e6ab1e40e..78f63c6b6 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/mode_Debug.png and b/ground/gcs/src/plugins/coreplugin/images/mode_Debug.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/mode_Edit.png b/ground/gcs/src/plugins/coreplugin/images/mode_Edit.png index c43fd4251..396929252 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/mode_Edit.png and b/ground/gcs/src/plugins/coreplugin/images/mode_Edit.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/mode_Output.png b/ground/gcs/src/plugins/coreplugin/images/mode_Output.png index 25e403c78..5e4e08b0d 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/mode_Output.png and b/ground/gcs/src/plugins/coreplugin/images/mode_Output.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/mode_Project.png b/ground/gcs/src/plugins/coreplugin/images/mode_Project.png index 20f54e786..cd0b3fb13 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/mode_Project.png and b/ground/gcs/src/plugins/coreplugin/images/mode_Project.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/mode_Reference.png b/ground/gcs/src/plugins/coreplugin/images/mode_Reference.png index 7d6a46a48..32dab43a9 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/mode_Reference.png and b/ground/gcs/src/plugins/coreplugin/images/mode_Reference.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/next.png b/ground/gcs/src/plugins/coreplugin/images/next.png index 7700d6fce..3ab3198f1 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/next.png and b/ground/gcs/src/plugins/coreplugin/images/next.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/opie_90x120.gif b/ground/gcs/src/plugins/coreplugin/images/opie_90x120.gif deleted file mode 100644 index 417e4c032..000000000 Binary files a/ground/gcs/src/plugins/coreplugin/images/opie_90x120.gif and /dev/null differ diff --git a/ground/gcs/src/plugins/coreplugin/images/optionsicon.png b/ground/gcs/src/plugins/coreplugin/images/optionsicon.png index 7168665c2..1b5536072 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/optionsicon.png and b/ground/gcs/src/plugins/coreplugin/images/optionsicon.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/panel_button.png b/ground/gcs/src/plugins/coreplugin/images/panel_button.png index 76793ca29..f5590bf69 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/panel_button.png and b/ground/gcs/src/plugins/coreplugin/images/panel_button.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/panel_button_checked.png b/ground/gcs/src/plugins/coreplugin/images/panel_button_checked.png index 67f9fbbd6..255bb81a6 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/panel_button_checked.png and b/ground/gcs/src/plugins/coreplugin/images/panel_button_checked.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/panel_button_checked_hover.png b/ground/gcs/src/plugins/coreplugin/images/panel_button_checked_hover.png index 0a820b3f6..504bd9db0 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/panel_button_checked_hover.png and b/ground/gcs/src/plugins/coreplugin/images/panel_button_checked_hover.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/panel_button_hover.png b/ground/gcs/src/plugins/coreplugin/images/panel_button_hover.png index d9c99409d..648d1a4d8 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/panel_button_hover.png and b/ground/gcs/src/plugins/coreplugin/images/panel_button_hover.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/panel_button_pressed.png b/ground/gcs/src/plugins/coreplugin/images/panel_button_pressed.png index dc522d238..b1440c9f0 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/panel_button_pressed.png and b/ground/gcs/src/plugins/coreplugin/images/panel_button_pressed.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/pluginicon.png b/ground/gcs/src/plugins/coreplugin/images/pluginicon.png index 11c6eff2a..ee783644d 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/pluginicon.png and b/ground/gcs/src/plugins/coreplugin/images/pluginicon.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/plus.png b/ground/gcs/src/plugins/coreplugin/images/plus.png index be8c961df..469632874 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/plus.png and b/ground/gcs/src/plugins/coreplugin/images/plus.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/prev.png b/ground/gcs/src/plugins/coreplugin/images/prev.png index 99dc8733c..27e289475 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/prev.png and b/ground/gcs/src/plugins/coreplugin/images/prev.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/pushbutton.png b/ground/gcs/src/plugins/coreplugin/images/pushbutton.png index a9efaf252..6078ae05b 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/pushbutton.png and b/ground/gcs/src/plugins/coreplugin/images/pushbutton.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/pushbutton_hover.png b/ground/gcs/src/plugins/coreplugin/images/pushbutton_hover.png index 910f6980b..efaa2611c 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/pushbutton_hover.png and b/ground/gcs/src/plugins/coreplugin/images/pushbutton_hover.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/pushbutton_pressed.png b/ground/gcs/src/plugins/coreplugin/images/pushbutton_pressed.png index 7a5a4768f..b3383e0b6 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/pushbutton_pressed.png and b/ground/gcs/src/plugins/coreplugin/images/pushbutton_pressed.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/qtwatermark.png b/ground/gcs/src/plugins/coreplugin/images/qtwatermark.png index d5eec355d..3efd36b31 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/qtwatermark.png and b/ground/gcs/src/plugins/coreplugin/images/qtwatermark.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/redo.png b/ground/gcs/src/plugins/coreplugin/images/redo.png index 9d679fe6f..54914f549 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/redo.png and b/ground/gcs/src/plugins/coreplugin/images/redo.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/replace.png b/ground/gcs/src/plugins/coreplugin/images/replace.png index baa05997b..b1055ed56 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/replace.png and b/ground/gcs/src/plugins/coreplugin/images/replace.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/reset.png b/ground/gcs/src/plugins/coreplugin/images/reset.png index cc0d6a26b..56eb4cd92 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/reset.png and b/ground/gcs/src/plugins/coreplugin/images/reset.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/scopes.png b/ground/gcs/src/plugins/coreplugin/images/scopes.png index 99434575f..da339b95a 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/scopes.png and b/ground/gcs/src/plugins/coreplugin/images/scopes.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/sidebaricon.png b/ground/gcs/src/plugins/coreplugin/images/sidebaricon.png index b79514158..3cfa42456 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/sidebaricon.png and b/ground/gcs/src/plugins/coreplugin/images/sidebaricon.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/splitbutton_horizontal.png b/ground/gcs/src/plugins/coreplugin/images/splitbutton_horizontal.png index c85a093f2..206eb8488 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/splitbutton_horizontal.png and b/ground/gcs/src/plugins/coreplugin/images/splitbutton_horizontal.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/statusbar.png b/ground/gcs/src/plugins/coreplugin/images/statusbar.png index dd426ef78..d56b4f013 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/statusbar.png and b/ground/gcs/src/plugins/coreplugin/images/statusbar.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/undo.png b/ground/gcs/src/plugins/coreplugin/images/undo.png index eee23d24a..7cbce2357 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/undo.png and b/ground/gcs/src/plugins/coreplugin/images/undo.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/unknownfile.png b/ground/gcs/src/plugins/coreplugin/images/unknownfile.png index 88f77592d..2b40b4e4b 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/unknownfile.png and b/ground/gcs/src/plugins/coreplugin/images/unknownfile.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/unlocked.png b/ground/gcs/src/plugins/coreplugin/images/unlocked.png index 72f659d09..5c1d4445c 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/unlocked.png and b/ground/gcs/src/plugins/coreplugin/images/unlocked.png differ diff --git a/ground/gcs/src/plugins/coreplugin/images/world.png b/ground/gcs/src/plugins/coreplugin/images/world.png index 68f21d301..eb7966d2f 100644 Binary files a/ground/gcs/src/plugins/coreplugin/images/world.png and b/ground/gcs/src/plugins/coreplugin/images/world.png differ diff --git a/ground/gcs/src/plugins/coreplugin/iuavgadget.h b/ground/gcs/src/plugins/coreplugin/iuavgadget.h index 46cd22146..5ea7c0af9 100644 --- a/ground/gcs/src/plugins/coreplugin/iuavgadget.h +++ b/ground/gcs/src/plugins/coreplugin/iuavgadget.h @@ -31,12 +31,11 @@ #include #include -#include -#include QT_BEGIN_NAMESPACE class QWidget; class QComboBox; +class QSettings; QT_END_NAMESPACE namespace Core { diff --git a/ground/gcs/src/plugins/coreplugin/mainwindow.cpp b/ground/gcs/src/plugins/coreplugin/mainwindow.cpp index 29844a53d..7fa1be779 100644 --- a/ground/gcs/src/plugins/coreplugin/mainwindow.cpp +++ b/ground/gcs/src/plugins/coreplugin/mainwindow.cpp @@ -882,7 +882,7 @@ GeneralSettings *MainWindow::generalSettings() const IContext *MainWindow::contextObject(QWidget *widget) { - return m_contextWidgets.value(widget); + return m_contextWidgets.value(widget, NULL); } void MainWindow::addContextObject(IContext *context) @@ -955,7 +955,7 @@ void MainWindow::updateFocusWidget(QWidget *old, QWidget *now) IContext *context = 0; QWidget *p = focusWidget(); while (p) { - context = m_contextWidgets.value(p); + context = m_contextWidgets.value(p, NULL); if (context) { newContext = context; break; diff --git a/ground/gcs/src/plugins/coreplugin/qml/AboutDialog.qml b/ground/gcs/src/plugins/coreplugin/qml/AboutDialog.qml index 96505f789..1c8d02bd9 100644 --- a/ground/gcs/src/plugins/coreplugin/qml/AboutDialog.qml +++ b/ground/gcs/src/plugins/coreplugin/qml/AboutDialog.qml @@ -2,7 +2,8 @@ ****************************************************************************** * * @file aboutdialog.qml - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2013. + * @author The LibrePilot Team http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2013. * *****************************************************************************/ /* @@ -20,23 +21,21 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -import QtQuick 2.1 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 1.0 +import QtQuick 2.6 +import QtQuick.Layouts 1.2 +import QtQuick.Controls 1.2 Rectangle { id: container width: 600 - height: 400 + height: 480 property AuthorsModel authors: AuthorsModel {} ColumnLayout { - id: columnLayout1 anchors.fill: parent spacing: 10 RowLayout { - id: rowLayout1 opacity: 1 Image { id: logo @@ -57,17 +56,6 @@ Rectangle { } } } - AnimatedImage { - id: opie - anchors.left: parent.left - anchors.leftMargin: 10 - anchors.top: logo.bottom - anchors.topMargin: 10 - source: "../images/opie_90x120.gif" - z: 100 - fillMode: Image.PreserveAspectFit - visible: false - } Rectangle { anchors.left: logo.right @@ -83,19 +71,10 @@ Rectangle { anchors.fill: parent Text { id: headerLabel - text: qsTr("LibrePilot Ground Control Station") Layout.fillWidth: true font.pixelSize: 14 font.bold: true - MouseArea { - id: easter_egg - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { - opie.visible = !opie.visible - } - } + text: qsTr("LibrePilot Ground Control Station") } Text { id: versionLabel @@ -104,56 +83,66 @@ Rectangle { wrapMode: Text.WordWrap text: version } - Text { - id: licenseLabel - Layout.fillWidth: true - font.pixelSize: 9 - wrapMode: Text.WordWrap - text: qsTr("This program is free software; you can redistribute it and/or " + - "modify it under the terms of the GNU General Public License " + - "as published by the Free Software Foundation; either version 3 " + - "of the License, or (at your option) any later version.\n" + - "The program is provided AS IS with NO WARRANTY OF ANY KIND, " + - "INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.") - } - - Text { - id: contributorLabel - text: qsTr("Contributors") - Layout.fillWidth: true - font.pixelSize: 14 - font.bold: true - - } - ScrollView { + TabView { Layout.fillWidth: true Layout.fillHeight: true - frameVisible: true - ListView { - id: authorsView - anchors.fill: parent - - spacing: 3 - model: authors - delegate: Text { - font.pixelSize: 12 - text: name + Tab { + title: qsTr("Contributors") + anchors.leftMargin: 6 + ScrollView { + frameVisible: false + ListView { + id: authorsView + anchors.fill: parent + spacing: 3 + model: authors + delegate: Text { + font.pixelSize: 12 + text: name + } + clip: true + } } - clip: true } + Tab { + title: qsTr("Credits") + // margin hack to fix broken UI when frameVisible is false + anchors.margins: 1 + anchors.rightMargin: 0 + TextArea { + readOnly: true + frameVisible: false + wrapMode: TextEdit.WordWrap + textFormat: TextEdit.RichText + text: credits + onLinkActivated: Qt.openUrlExternally(link) + } + } + Tab { + title: qsTr("License") + // margin hack to fix broken UI when frameVisible is false + anchors.margins: 1 + anchors.rightMargin: 0 + TextArea { + readOnly: true + frameVisible: false + wrapMode: TextEdit.WordWrap + textFormat: TextEdit.RichText + text: license + onLinkActivated: Qt.openUrlExternally(link) + } + } + } + Button { + id: button + anchors.right: parent.right + anchors.bottom: parent.bottom + text: qsTr("Ok") + activeFocusOnPress: true + onClicked: dialog.close() } } } } - Button { - id: button - text: qsTr("Ok") - activeFocusOnPress: true - anchors.right: parent.right - anchors.rightMargin: 10 - anchors.bottom: parent.bottom - anchors.bottomMargin: 10 - onClicked: dialog.close() - } } } diff --git a/ground/gcs/src/plugins/coreplugin/qml/images/tab.png b/ground/gcs/src/plugins/coreplugin/qml/images/tab.png index ad8021605..88c422f7f 100644 Binary files a/ground/gcs/src/plugins/coreplugin/qml/images/tab.png and b/ground/gcs/src/plugins/coreplugin/qml/images/tab.png differ diff --git a/ground/gcs/src/plugins/coreplugin/sidebar.cpp b/ground/gcs/src/plugins/coreplugin/sidebar.cpp index c4b7bf717..0661e4aa9 100644 --- a/ground/gcs/src/plugins/coreplugin/sidebar.cpp +++ b/ground/gcs/src/plugins/coreplugin/sidebar.cpp @@ -94,7 +94,7 @@ SideBarItem *SideBar::item(const QString &title) { if (m_itemMap.contains(title)) { m_availableItems.removeAll(title); - return m_itemMap.value(title); + return m_itemMap.value(title, NULL); } return 0; } diff --git a/ground/gcs/src/plugins/coreplugin/uavgadgetinstancemanager.cpp b/ground/gcs/src/plugins/coreplugin/uavgadgetinstancemanager.cpp index 17bf5a187..6aa57bda0 100644 --- a/ground/gcs/src/plugins/coreplugin/uavgadgetinstancemanager.cpp +++ b/ground/gcs/src/plugins/coreplugin/uavgadgetinstancemanager.cpp @@ -41,7 +41,6 @@ #include #include - using namespace Core; static const UAVConfigVersion m_versionUAVGadgetConfigurations = UAVConfigVersion("1.2.0"); @@ -116,7 +115,7 @@ void UAVGadgetInstanceManager::readConfigs_1_2_0(QSettings *qs) configs = qs->childGroups(); foreach(QString configName, configs) { - qDebug() << "Loading config: " << classId << "," << configName; + // qDebug() << "Loading config: " << classId << "," << configName; qs->beginGroup(configName); configInfo.read(qs); configInfo.setNameOfConfigurable(classId + "-" + configName); @@ -166,7 +165,7 @@ void UAVGadgetInstanceManager::readConfigs_1_1_0(QSettings *qs) configs = qs->childGroups(); foreach(QString configName, configs) { - qDebug().nospace() << "Loading config: " << classId << ", " << configName; + // qDebug().nospace() << "Loading config: " << classId << ", " << configName; qs->beginGroup(configName); bool locked = qs->value("config.locked").toBool(); configInfo.setNameOfConfigurable(classId + "-" + configName); @@ -250,8 +249,8 @@ void UAVGadgetInstanceManager::createOptionsPages() m_pm->addObject(page); } else { qWarning() - << "UAVGadgetInstanceManager::createOptionsPages - failed to create options page for configuration " - + config->classId() + ":" + config->name() + ", configuration will be removed."; + << "UAVGadgetInstanceManager::createOptionsPages - failed to create options page for configuration" + << (config->classId() + ":" + config->name()) << ", configuration will be removed."; // The m_optionsPages list and m_configurations list must be in synch otherwise nasty issues happen later // so if we fail to create an options page we must remove the associated configuration ite.remove(); diff --git a/ground/gcs/src/plugins/coreplugin/uavgadgetmanager/splitterorview.cpp b/ground/gcs/src/plugins/coreplugin/uavgadgetmanager/splitterorview.cpp index ed84b65d7..ba92dfe13 100644 --- a/ground/gcs/src/plugins/coreplugin/uavgadgetmanager/splitterorview.cpp +++ b/ground/gcs/src/plugins/coreplugin/uavgadgetmanager/splitterorview.cpp @@ -301,34 +301,45 @@ void SplitterOrView::unsplit(IUAVGadget *gadget) if (!m_splitter) { return; } - SplitterOrView *view = findView(gadget); - if (!view || view == this) { + SplitterOrView *gadgetView = findView(gadget); + if (!gadgetView || gadgetView == this) { return; } // find the other gadgets // TODO handle case where m_splitter->count() > 2 - SplitterOrView *splitterOrView = NULL; + SplitterOrView *otherView = NULL; for (int i = 0; i < m_splitter->count(); ++i) { - splitterOrView = qobject_cast(m_splitter->widget(i)); - if (splitterOrView && (splitterOrView != view)) { + SplitterOrView *view = qobject_cast(m_splitter->widget(i)); + if (view && (view != gadgetView)) { + otherView = view; break; } } - if (splitterOrView) { - if (splitterOrView->isView()) { - layout()->addWidget(splitterOrView->m_view); + if (otherView) { + // update UI + if (otherView->isView()) { + layout()->addWidget(otherView->m_view); } else { - layout()->addWidget(splitterOrView->m_splitter); + layout()->addWidget(otherView->m_splitter); } layout()->removeWidget(m_splitter); - m_uavGadgetManager->emptyView(view->m_view); - delete view; - delete m_splitter; + // transfer other view to this view + QSplitter *oldSplitter = m_splitter; - m_view = splitterOrView->m_view; - m_splitter = splitterOrView->m_splitter; + m_view = otherView->m_view; + m_splitter = otherView->m_splitter; + + // cleanup gadget view + m_uavGadgetManager->emptyView(gadgetView->m_view); + + // delete child views (not necessary...) + delete gadgetView; + delete otherView; + + // delete old splitter (and remaining SplitterOrView children...) + delete oldSplitter; } } diff --git a/ground/gcs/src/plugins/debuggadget/debuggadget.pro b/ground/gcs/src/plugins/debuggadget/debuggadget.pro index 32cd8bab9..6c9fb4419 100644 --- a/ground/gcs/src/plugins/debuggadget/debuggadget.pro +++ b/ground/gcs/src/plugins/debuggadget/debuggadget.pro @@ -1,18 +1,24 @@ TEMPLATE = lib TARGET = DebugGadget +QT += widgets + include(../../plugin.pri) include(../../plugins/coreplugin/coreplugin.pri) -HEADERS += debugplugin.h \ - debugengine.h -HEADERS += debuggadget.h -HEADERS += debuggadgetwidget.h -HEADERS += debuggadgetfactory.h -SOURCES += debugplugin.cpp \ - debugengine.cpp -SOURCES += debuggadget.cpp -SOURCES += debuggadgetfactory.cpp -SOURCES += debuggadgetwidget.cpp + +HEADERS += \ + debugplugin.h \ + debugengine.h \ + debuggadget.h \ + debuggadgetwidget.h \ + debuggadgetfactory.h + +SOURCES += \ + debugplugin.cpp \ + debugengine.cpp \ + debuggadget.cpp \ + debuggadgetfactory.cpp \ + debuggadgetwidget.cpp OTHER_FILES += DebugGadget.pluginspec diff --git a/ground/gcs/src/plugins/debuggadget/debuggadgetwidget.cpp b/ground/gcs/src/plugins/debuggadget/debuggadgetwidget.cpp index 1958f3d0e..11c417d78 100644 --- a/ground/gcs/src/plugins/debuggadget/debuggadgetwidget.cpp +++ b/ground/gcs/src/plugins/debuggadget/debuggadgetwidget.cpp @@ -52,6 +52,12 @@ void DebugGadgetWidget::customMessageHandler(QtMsgType type, const QMessageLogCo txt = QString("Debug: %1").arg(msg); color = Qt::black; break; +#if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)) + case QtInfoMsg: + txt = QString("Info: %1").arg(msg); + color = Qt::blue; + break; +#endif case QtWarningMsg: txt = QString("Warning: %1").arg(msg); color = Qt::red; diff --git a/ground/gcs/src/plugins/dial/dial.pro b/ground/gcs/src/plugins/dial/dial.pro index 73cd4606d..aec83d8d7 100644 --- a/ground/gcs/src/plugins/dial/dial.pro +++ b/ground/gcs/src/plugins/dial/dial.pro @@ -1,22 +1,30 @@ TEMPLATE = lib TARGET = DialGadget -QT += svg -QT += opengl + +QT += svg opengl + include(../../plugin.pri) include(../../plugins/coreplugin/coreplugin.pri) include(dial_dependencies.pri) -HEADERS += dialplugin.h -HEADERS += dialgadget.h -HEADERS += dialgadgetwidget.h -HEADERS += dialgadgetfactory.h -HEADERS += dialgadgetconfiguration.h -HEADERS += dialgadgetoptionspage.h -SOURCES += dialplugin.cpp -SOURCES += dialgadget.cpp -SOURCES += dialgadgetfactory.cpp -SOURCES += dialgadgetwidget.cpp -SOURCES += dialgadgetconfiguration.cpp -SOURCES += dialgadgetoptionspage.cpp + +HEADERS += \ + dialplugin.h \ + dialgadget.h \ + dialgadgetwidget.h \ + dialgadgetfactory.h \ + dialgadgetconfiguration.h \ + dialgadgetoptionspage.h + +SOURCES += \ + dialplugin.cpp \ + dialgadget.cpp \ + dialgadgetfactory.cpp \ + dialgadgetwidget.cpp \ + dialgadgetconfiguration.cpp \ + dialgadgetoptionspage.cpp + OTHER_FILES += DialGadget.pluginspec + FORMS += dialgadgetoptionspage.ui + RESOURCES += dial.qrc diff --git a/ground/gcs/src/plugins/dial/dialgadgetwidget.cpp b/ground/gcs/src/plugins/dial/dialgadgetwidget.cpp index 14bfba5cb..ac7f9e46b 100644 --- a/ground/gcs/src/plugins/dial/dialgadgetwidget.cpp +++ b/ground/gcs/src/plugins/dial/dialgadgetwidget.cpp @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include DialGadgetWidget::DialGadgetWidget(QWidget *parent) : QGraphicsView(parent) @@ -75,7 +75,7 @@ DialGadgetWidget::~DialGadgetWidget() void DialGadgetWidget::enableOpenGL(bool flag) { if (flag) { - setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); + setViewport(new QOpenGLWidget()); // QGLFormat(QGL::SampleBuffers))); } else { setViewport(new QWidget); } diff --git a/ground/gcs/src/plugins/donothing/donothing.pro b/ground/gcs/src/plugins/donothing/donothing.pro index 0acdc385a..57e2ce16f 100644 --- a/ground/gcs/src/plugins/donothing/donothing.pro +++ b/ground/gcs/src/plugins/donothing/donothing.pro @@ -1,11 +1,13 @@ - TEMPLATE = lib TARGET = DoNothing include(../../plugin.pri) include(../../plugins/coreplugin/coreplugin.pri) -HEADERS += donothingplugin.h -SOURCES += donothingplugin.cpp +HEADERS += \ + donothingplugin.h +SOURCES += \ + donothingplugin.cpp + OTHER_FILES += DoNothing.pluginspec \ No newline at end of file diff --git a/ground/gcs/src/plugins/emptygadget/emptygadget.pro b/ground/gcs/src/plugins/emptygadget/emptygadget.pro index 050141d34..b5ec37f4d 100644 --- a/ground/gcs/src/plugins/emptygadget/emptygadget.pro +++ b/ground/gcs/src/plugins/emptygadget/emptygadget.pro @@ -1,16 +1,21 @@ TEMPLATE = lib TARGET = EmptyGadget +QT += widgets + include(../../plugin.pri) include(../../plugins/coreplugin/coreplugin.pri) -HEADERS += emptyplugin.h -HEADERS += emptygadget.h -HEADERS += emptygadgetwidget.h -HEADERS += emptygadgetfactory.h -SOURCES += emptyplugin.cpp -SOURCES += emptygadget.cpp -SOURCES += emptygadgetfactory.cpp -SOURCES += emptygadgetwidget.cpp +HEADERS += \ + emptyplugin.h \ + emptygadget.h \ + emptygadgetwidget.h \ + emptygadgetfactory.h + +SOURCES += \ + emptyplugin.cpp \ + emptygadget.cpp \ + emptygadgetfactory.cpp \ + emptygadgetwidget.cpp OTHER_FILES += EmptyGadget.pluginspec diff --git a/ground/gcs/src/plugins/flightlog/flightlog.pro b/ground/gcs/src/plugins/flightlog/flightlog.pro index ac2d6d88f..34c362f9e 100644 --- a/ground/gcs/src/plugins/flightlog/flightlog.pro +++ b/ground/gcs/src/plugins/flightlog/flightlog.pro @@ -1,7 +1,7 @@ TEMPLATE = lib TARGET = FlightLog -QT += qml quick +QT += widgets qml quick include(../../plugin.pri) include(../../plugins/coreplugin/coreplugin.pri) @@ -9,12 +9,16 @@ include(../../plugins/uavobjects/uavobjects.pri) include(../../plugins/uavobjectutil/uavobjectutil.pri) include(../../plugins/uavtalk/uavtalk.pri) -HEADERS += flightlogplugin.h \ +HEADERS += \ + flightlogplugin.h \ flightlogmanager.h -SOURCES += flightlogplugin.cpp \ + +SOURCES += \ + flightlogplugin.cpp \ flightlogmanager.cpp -OTHER_FILES += Flightlog.pluginspec \ +OTHER_FILES += \ + Flightlog.pluginspec \ FlightLogDialog.qml \ functions.js diff --git a/ground/gcs/src/plugins/flightlog/flightlogmanager.cpp b/ground/gcs/src/plugins/flightlog/flightlogmanager.cpp index c43aa8fc3..02a3b0f55 100644 --- a/ground/gcs/src/plugins/flightlog/flightlogmanager.cpp +++ b/ground/gcs/src/plugins/flightlog/flightlogmanager.cpp @@ -603,7 +603,7 @@ void FlightLogManager::connectionStatusChanged() if (m_telemtryManager->isConnected()) { ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); UAVObjectUtilManager *utilMngr = pm->getObject(); - setBoardConnected(utilMngr->getBoardModel() == 0x0903); + setBoardConnected(utilMngr->getBoardModel() == 0x0903 || utilMngr->getBoardModel() == 0x0904 || utilMngr->getBoardModel() == 0x0905 || utilMngr->getBoardModel() == 0x9201); } else { setBoardConnected(false); } diff --git a/ground/gcs/src/plugins/gcscontrol/joystickcontrol.cpp b/ground/gcs/src/plugins/gcscontrol/joystickcontrol.cpp index 2d8dfdd6c..6d0a44ce7 100644 --- a/ground/gcs/src/plugins/gcscontrol/joystickcontrol.cpp +++ b/ground/gcs/src/plugins/gcscontrol/joystickcontrol.cpp @@ -29,7 +29,7 @@ #include "extensionsystem/pluginmanager.h" #include #include -#include +#include #include /** @@ -85,7 +85,7 @@ JoystickControl::~JoystickControl() void JoystickControl::enableOpenGL(bool flag) { if (flag) { - setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); + setViewport(new QOpenGLWidget()); // QGLFormat(QGL::SampleBuffers))); } else { setViewport(new QWidget); } diff --git a/ground/gcs/src/plugins/gpsdisplay/gpsdisplay.pro b/ground/gcs/src/plugins/gpsdisplay/gpsdisplay.pro index 10d8f5e53..31b1218d5 100644 --- a/ground/gcs/src/plugins/gpsdisplay/gpsdisplay.pro +++ b/ground/gcs/src/plugins/gpsdisplay/gpsdisplay.pro @@ -1,36 +1,45 @@ TEMPLATE = lib TARGET = GpsDisplayGadget -QT += svg -QT += serialport + +QT += svg serialport + include(../../plugin.pri) include(../../plugins/coreplugin/coreplugin.pri) include(gpsdisplay_dependencies.pri) include(../../libs/qwt/qwt.pri) -HEADERS += gpsdisplayplugin.h -HEADERS += gpsconstellationwidget.h -HEADERS += gpsparser.h -HEADERS += telemetryparser.h -HEADERS += gpssnrwidget.h -HEADERS += buffer.h -HEADERS += nmeaparser.h -HEADERS += gpsdisplaygadget.h -HEADERS += gpsdisplaywidget.h -HEADERS += gpsdisplaygadgetfactory.h -HEADERS += gpsdisplaygadgetconfiguration.h -HEADERS += gpsdisplaygadgetoptionspage.h -SOURCES += gpsdisplayplugin.cpp -SOURCES += gpsconstellationwidget.cpp -SOURCES += gpsparser.cpp -SOURCES += telemetryparser.cpp -SOURCES += gpssnrwidget.cpp -SOURCES += buffer.cpp -SOURCES += nmeaparser.cpp -SOURCES += gpsdisplaygadget.cpp -SOURCES += gpsdisplaygadgetfactory.cpp -SOURCES += gpsdisplaywidget.cpp -SOURCES += gpsdisplaygadgetconfiguration.cpp -SOURCES += gpsdisplaygadgetoptionspage.cpp + +HEADERS += \ + gpsdisplayplugin.h \ + gpsconstellationwidget.h \ + gpsparser.h \ + telemetryparser.h \ + gpssnrwidget.h \ + buffer.h \ + nmeaparser.h \ + gpsdisplaygadget.h \ + gpsdisplaywidget.h \ + gpsdisplaygadgetfactory.h \ + gpsdisplaygadgetconfiguration.h \ + gpsdisplaygadgetoptionspage.h + +SOURCES += \ + gpsdisplayplugin.cpp \ + gpsconstellationwidget.cpp \ + gpsparser.cpp \ + telemetryparser.cpp \ + gpssnrwidget.cpp \ + buffer.cpp \ + nmeaparser.cpp \ + gpsdisplaygadget.cpp \ + gpsdisplaygadgetfactory.cpp \ + gpsdisplaywidget.cpp \ + gpsdisplaygadgetconfiguration.cpp \ + gpsdisplaygadgetoptionspage.cpp + OTHER_FILES += GpsDisplayGadget.pluginspec -FORMS += gpsdisplaygadgetoptionspage.ui -FORMS += gpsdisplaywidget.ui + +FORMS += \ + gpsdisplaygadgetoptionspage.ui \ + gpsdisplaywidget.ui + RESOURCES += widgetresources.qrc diff --git a/ground/gcs/src/plugins/gpsdisplay/gpsdisplaygadget.cpp b/ground/gcs/src/plugins/gpsdisplay/gpsdisplaygadget.cpp index 9763b7d0c..8e1b7b17e 100644 --- a/ground/gcs/src/plugins/gpsdisplay/gpsdisplaygadget.cpp +++ b/ground/gcs/src/plugins/gpsdisplay/gpsdisplaygadget.cpp @@ -91,7 +91,6 @@ void GpsDisplayGadget::loadConfiguration(IUAVGadgetConfiguration *config) } m_widget->dataStreamGroupBox->setHidden(false); } else if (gpsDisplayConfig->connectionMode() == "Telemetry") { - qDebug() << "Using Telemetry parser"; parser = new TelemetryParser(); m_widget->disconnectButton->setHidden(true); m_widget->connectButton->setHidden(true); diff --git a/ground/gcs/src/plugins/gpsdisplay/images/flatEarth.png b/ground/gcs/src/plugins/gpsdisplay/images/flatEarth.png index d4b34a08d..a18d9e368 100644 Binary files a/ground/gcs/src/plugins/gpsdisplay/images/flatEarth.png and b/ground/gcs/src/plugins/gpsdisplay/images/flatEarth.png differ diff --git a/ground/gcs/src/plugins/hitl/aerosimrc/src/copydata.pro b/ground/gcs/src/plugins/hitl/aerosimrc/src/copydata.pro new file mode 100644 index 000000000..6174ea728 --- /dev/null +++ b/ground/gcs/src/plugins/hitl/aerosimrc/src/copydata.pro @@ -0,0 +1,36 @@ +# Windows only + +# set debug suffix if needed +win32:CONFIG(debug, debug|release):DS = "d" + +win32 { + # resources and sample configuration + PLUGIN_RESOURCES = \ + cc_off.tga \ + cc_off_hover.tga \ + cc_on.tga \ + cc_on_hover.tga \ + cc_plugin.ini \ + plugin.txt + + for(res, PLUGIN_RESOURCES) { + addCopyFileTarget($${res},$${RES_DIR},$${PLUGIN_DIR}) + } + + # Qt DLLs + QT_DLLS = \ + Qt5Core$${DS}.dll \ + Qt5Network$${DS}.dll + + for(dll, QT_DLLS) { + addCopyFileTarget($${dll},$$[QT_INSTALL_BINS],$${SIM_DIR}) + } + + # MinGW DLLs + #MINGW_DLLS = \ + # libgcc_s_dw2-1.dll \ + # mingwm10.dll + #for(dll, MINGW_DLLS) { + # addCopyFileTarget($${dll},$$(QTMINGW),$${SIM_DIR}) + #} +} diff --git a/ground/gcs/src/plugins/hitl/aerosimrc/src/plugin.pro b/ground/gcs/src/plugins/hitl/aerosimrc/src/plugin.pro index d9016bea8..9d292abeb 100644 --- a/ground/gcs/src/plugins/hitl/aerosimrc/src/plugin.pro +++ b/ground/gcs/src/plugins/hitl/aerosimrc/src/plugin.pro @@ -1,15 +1,15 @@ +TEMPLATE = lib +TARGET = plugin_AeroSIMRC + +QT += network +QT -= gui + !win32 { error("AeroSimRC plugin is only available for win32 platform") } include(../../../../../gcs.pri) -QT += network -QT -= gui - -TEMPLATE = lib -TARGET = plugin_AeroSIMRC - RES_DIR = $${PWD}/resources SIM_DIR = $$GCS_BUILD_TREE/misc/AeroSIM-RC PLUGIN_DIR = $$SIM_DIR/Plugin/CopterControl @@ -30,37 +30,4 @@ SOURCES = \ settings.cpp # Resemble the AeroSimRC directory structure and copy plugin files and resources -equals(copydata, 1) { - - # Windows release only - win32:CONFIG(release, debug|release) { - - # resources and sample configuration - PLUGIN_RESOURCES = \ - cc_off.tga \ - cc_off_hover.tga \ - cc_on.tga \ - cc_on_hover.tga \ - cc_plugin.ini \ - plugin.txt - for(res, PLUGIN_RESOURCES) { - addCopyFileTarget($${res},$${RES_DIR},$${PLUGIN_DIR}) - } - - # Qt DLLs - QT_DLLS = \ - Qt5Core.dll \ - Qt5Network.dll - for(dll, QT_DLLS) { - addCopyFileTarget($${dll},$$[QT_INSTALL_BINS],$${SIM_DIR}) - } - - # MinGW DLLs - #MINGW_DLLS = \ - # libgcc_s_dw2-1.dll \ - # mingwm10.dll - #for(dll, MINGW_DLLS) { - # addCopyFileTarget($${dll},$$(QTMINGW),$${SIM_DIR}) - #} - } -} +equals(copydata, 1):include(copydata.pro) diff --git a/ground/gcs/src/plugins/hitl/aerosimrc/src/qdebughandler.cpp b/ground/gcs/src/plugins/hitl/aerosimrc/src/qdebughandler.cpp index e1c39084b..3c3ad4c67 100644 --- a/ground/gcs/src/plugins/hitl/aerosimrc/src/qdebughandler.cpp +++ b/ground/gcs/src/plugins/hitl/aerosimrc/src/qdebughandler.cpp @@ -29,6 +29,7 @@ void myQDebugHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) { + Q_UNUSED(context); static bool firstRun = true; QString txt; @@ -36,6 +37,11 @@ void myQDebugHandler(QtMsgType type, const QMessageLogContext &context, const QS case QtDebugMsg: txt = QString("Debug: %1").arg(msg); break; +#if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)) + case QtInfoMsg: + txt = QString("Info: %1").arg(msg); + break; +#endif case QtWarningMsg: txt = QString("Warning: %1").arg(msg); break; diff --git a/ground/gcs/src/plugins/hitl/aerosimrc/src/udpconnect.cpp b/ground/gcs/src/plugins/hitl/aerosimrc/src/udpconnect.cpp index c15d34cea..307929488 100644 --- a/ground/gcs/src/plugins/hitl/aerosimrc/src/udpconnect.cpp +++ b/ground/gcs/src/plugins/hitl/aerosimrc/src/udpconnect.cpp @@ -210,8 +210,8 @@ void UdpReceiver::onReadyRead() while (inSocket->hasPendingDatagrams()) { QByteArray datagram; datagram.resize(inSocket->pendingDatagramSize()); - quint64 datagramSize; - datagramSize = inSocket->readDatagram(datagram.data(), datagram.size()); + // quint64 datagramSize; + /*datagramSize =*/ inSocket->readDatagram(datagram.data(), datagram.size()); processDatagram(datagram); } diff --git a/ground/gcs/src/plugins/hitl/aerosimrc/src/udptest.pro b/ground/gcs/src/plugins/hitl/aerosimrc/src/udptest.pro index 6bb532455..c3520302c 100644 --- a/ground/gcs/src/plugins/hitl/aerosimrc/src/udptest.pro +++ b/ground/gcs/src/plugins/hitl/aerosimrc/src/udptest.pro @@ -1,9 +1,9 @@ -include(../../../../../gcs.pri) +TEMPLATE = app +TARGET = udp_test QT += core gui network widgets -TEMPLATE = app -TARGET = udp_test +include(../../../../../gcs.pri) HEADERS += \ udptestwidget.h diff --git a/ground/gcs/src/plugins/hitl/fgsimulator.cpp b/ground/gcs/src/plugins/hitl/fgsimulator.cpp index eb53b75fb..92301da20 100644 --- a/ground/gcs/src/plugins/hitl/fgsimulator.cpp +++ b/ground/gcs/src/plugins/hitl/fgsimulator.cpp @@ -2,7 +2,8 @@ ****************************************************************************** * * @file flightgearbridge.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2015. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup HITLPlugin HITL Plugin @@ -269,7 +270,7 @@ void FGSimulator::processUpdate(const QByteArray & inp) // Get pressure (kpa) float pressure = fields[20].toFloat() * INHG2KPA; // Get VelocityState Down (m/s) - float velocityStateDown = -fields[21].toFloat() * FPS2CMPS * 1e-2f; + float velocityStateDown = fields[21].toFloat() * FPS2CMPS * 1e-2f; // Get VelocityState East (m/s) float velocityStateEast = fields[22].toFloat() * FPS2CMPS * 1e-2f; // Get VelocityState Down (m/s) diff --git a/ground/gcs/src/plugins/hitl/hitlwidget.cpp b/ground/gcs/src/plugins/hitl/hitlwidget.cpp index 045d37485..063a8dbfb 100644 --- a/ground/gcs/src/plugins/hitl/hitlwidget.cpp +++ b/ground/gcs/src/plugins/hitl/hitlwidget.cpp @@ -25,12 +25,8 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "hitlwidget.h" + #include "ui_hitlwidget.h" -#include -#include -#include -#include -#include #include #include @@ -38,6 +34,11 @@ #include "coreplugin/icore.h" #include "coreplugin/threadmanager.h" +#include +#include +#include +#include +#include QStringList Simulator::instances; diff --git a/ground/gcs/src/plugins/hitl/hitlwidget.h b/ground/gcs/src/plugins/hitl/hitlwidget.h index 15fcbcf81..2157e28c1 100644 --- a/ground/gcs/src/plugins/hitl/hitlwidget.h +++ b/ground/gcs/src/plugins/hitl/hitlwidget.h @@ -28,10 +28,10 @@ #ifndef HITLWIDGET_H #define HITLWIDGET_H -#include -#include #include "simulator.h" +#include + class Ui_HITLWidget; class HITLWidget : public QWidget { diff --git a/ground/gcs/src/plugins/hitl/il2simulator.cpp b/ground/gcs/src/plugins/hitl/il2simulator.cpp index 6341124e3..c8841327f 100644 --- a/ground/gcs/src/plugins/hitl/il2simulator.cpp +++ b/ground/gcs/src/plugins/hitl/il2simulator.cpp @@ -65,7 +65,7 @@ #include "extensionsystem/pluginmanager.h" #include #include -#include +#include const float IL2Simulator::FT2M = 12 * .254; const float IL2Simulator::KT2MPS = 0.514444444; @@ -194,13 +194,13 @@ void IL2Simulator::processUpdate(const QByteArray & inp) current.Y = old.Y + (current.dY * current.dT); // accelerations (filtered) - if (isnan(old.ddX) || isinf(old.ddX)) { + if (std::isnan(old.ddX) || std::isinf(old.ddX)) { old.ddX = 0; } - if (isnan(old.ddY) || isinf(old.ddY)) { + if (std::isnan(old.ddY) || std::isinf(old.ddY)) { old.ddY = 0; } - if (isnan(old.ddZ) || isinf(old.ddZ)) { + if (std::isnan(old.ddZ) || std::isinf(old.ddZ)) { old.ddZ = 0; } #define SPEED_FILTER 10 @@ -210,13 +210,13 @@ void IL2Simulator::processUpdate(const QByteArray & inp) #define TURN_FILTER 10 // turn speeds (filtered) - if (isnan(old.dAzimuth) || isinf(old.dAzimuth)) { + if (std::isnan(old.dAzimuth) || std::isinf(old.dAzimuth)) { old.dAzimuth = 0; } - if (isnan(old.dPitch) || isinf(old.dPitch)) { + if (std::isnan(old.dPitch) || std::isinf(old.dPitch)) { old.dPitch = 0; } - if (isnan(old.dRoll) || isinf(old.dRoll)) { + if (std::isnan(old.dRoll) || std::isinf(old.dRoll)) { old.dRoll = 0; } current.dAzimuth = (angleDifference(current.azimuth, old.azimuth) / current.dT + TURN_FILTER * (old.dAzimuth)) / (TURN_FILTER + 1); diff --git a/ground/gcs/src/plugins/hitl/images/arrow-down.png b/ground/gcs/src/plugins/hitl/images/arrow-down.png index a8f65c44d..ce4e9c7d8 100644 Binary files a/ground/gcs/src/plugins/hitl/images/arrow-down.png and b/ground/gcs/src/plugins/hitl/images/arrow-down.png differ diff --git a/ground/gcs/src/plugins/hitl/images/arrow-down2.png b/ground/gcs/src/plugins/hitl/images/arrow-down2.png index a0a651ef3..4958698aa 100644 Binary files a/ground/gcs/src/plugins/hitl/images/arrow-down2.png and b/ground/gcs/src/plugins/hitl/images/arrow-down2.png differ diff --git a/ground/gcs/src/plugins/hitl/images/arrow-right.png b/ground/gcs/src/plugins/hitl/images/arrow-right.png index 207f7fcf2..b397e3689 100644 Binary files a/ground/gcs/src/plugins/hitl/images/arrow-right.png and b/ground/gcs/src/plugins/hitl/images/arrow-right.png differ diff --git a/ground/gcs/src/plugins/hitl/images/arrow-up.png b/ground/gcs/src/plugins/hitl/images/arrow-up.png index 96aba8222..2713fc239 100644 Binary files a/ground/gcs/src/plugins/hitl/images/arrow-up.png and b/ground/gcs/src/plugins/hitl/images/arrow-up.png differ diff --git a/ground/gcs/src/plugins/hitl/images/arrow-up2.png b/ground/gcs/src/plugins/hitl/images/arrow-up2.png index 1152971cc..2dfb4877b 100644 Binary files a/ground/gcs/src/plugins/hitl/images/arrow-up2.png and b/ground/gcs/src/plugins/hitl/images/arrow-up2.png differ diff --git a/ground/gcs/src/plugins/hitl/images/bullet_arrow_down.png b/ground/gcs/src/plugins/hitl/images/bullet_arrow_down.png index 1b12b9e52..dd776c068 100644 Binary files a/ground/gcs/src/plugins/hitl/images/bullet_arrow_down.png and b/ground/gcs/src/plugins/hitl/images/bullet_arrow_down.png differ diff --git a/ground/gcs/src/plugins/hitl/images/bullet_arrow_up.png b/ground/gcs/src/plugins/hitl/images/bullet_arrow_up.png index 86adcf2fa..a413fa313 100644 Binary files a/ground/gcs/src/plugins/hitl/images/bullet_arrow_up.png and b/ground/gcs/src/plugins/hitl/images/bullet_arrow_up.png differ diff --git a/ground/gcs/src/plugins/hitl/images/list_bullet_arrow.png b/ground/gcs/src/plugins/hitl/images/list_bullet_arrow.png index acf9f5da5..fc7b04dbf 100644 Binary files a/ground/gcs/src/plugins/hitl/images/list_bullet_arrow.png and b/ground/gcs/src/plugins/hitl/images/list_bullet_arrow.png differ diff --git a/ground/gcs/src/plugins/hitl/images/scrollbarvertical_down_arrow.png b/ground/gcs/src/plugins/hitl/images/scrollbarvertical_down_arrow.png index 5c42554cf..0880ded0f 100644 Binary files a/ground/gcs/src/plugins/hitl/images/scrollbarvertical_down_arrow.png and b/ground/gcs/src/plugins/hitl/images/scrollbarvertical_down_arrow.png differ diff --git a/ground/gcs/src/plugins/hitl/images/scrollbarvertical_up_arrow.png b/ground/gcs/src/plugins/hitl/images/scrollbarvertical_up_arrow.png index 61b39c1f7..5580b9448 100644 Binary files a/ground/gcs/src/plugins/hitl/images/scrollbarvertical_up_arrow.png and b/ground/gcs/src/plugins/hitl/images/scrollbarvertical_up_arrow.png differ diff --git a/ground/gcs/src/plugins/hitl/plugin.pro b/ground/gcs/src/plugins/hitl/plugin.pro index b6448e25e..de50497ac 100644 --- a/ground/gcs/src/plugins/hitl/plugin.pro +++ b/ground/gcs/src/plugins/hitl/plugin.pro @@ -1,11 +1,13 @@ TEMPLATE = lib TARGET = HITL -QT += network + +QT += widgets network include(../../plugin.pri) include(hitl_dependencies.pri) -HEADERS += hitlplugin.h \ +HEADERS += \ + hitlplugin.h \ hitlwidget.h \ hitloptionspage.h \ hitlfactory.h \ @@ -18,7 +20,9 @@ HEADERS += hitlplugin.h \ il2simulator.h \ xplanesimulator9.h \ xplanesimulator10.h -SOURCES += hitlplugin.cpp \ + +SOURCES += \ + hitlplugin.cpp \ hitlwidget.cpp \ hitloptionspage.cpp \ hitlfactory.cpp \ @@ -31,9 +35,13 @@ SOURCES += hitlplugin.cpp \ il2simulator.cpp \ xplanesimulator9.cpp \ xplanesimulator10.cpp + OTHER_FILES += hitl.pluginspec -FORMS += hitloptionspage.ui \ + +FORMS += \ + hitloptionspage.ui \ hitlwidget.ui + RESOURCES += hitlresources.qrc diff --git a/ground/gcs/src/plugins/importexport/importexport.pro b/ground/gcs/src/plugins/importexport/importexport.pro index 360ab7513..cd690330d 100644 --- a/ground/gcs/src/plugins/importexport/importexport.pro +++ b/ground/gcs/src/plugins/importexport/importexport.pro @@ -1,15 +1,25 @@ TEMPLATE = lib TARGET = ImportExportGadget + DEFINES += IMPORTEXPORT_LIBRARY -QT += xml + +QT += xml widgets + include(../../plugin.pri) include(importexport_dependencies.pri) -HEADERS += importexportplugin.h \ + +HEADERS += \ + importexportplugin.h \ importexportgadgetwidget.h \ importexportdialog.h -SOURCES += importexportplugin.cpp \ + +SOURCES += \ + importexportplugin.cpp \ importexportgadgetwidget.cpp \ importexportdialog.cpp + OTHER_FILES += ImportExportGadget.pluginspec -FORMS += importexportgadgetwidget.ui \ + +FORMS += \ + importexportgadgetwidget.ui \ importexportdialog.ui diff --git a/ground/gcs/src/plugins/ipconnection/ipconnection.pro b/ground/gcs/src/plugins/ipconnection/ipconnection.pro index 2bd94335b..4dbc3047c 100644 --- a/ground/gcs/src/plugins/ipconnection/ipconnection.pro +++ b/ground/gcs/src/plugins/ipconnection/ipconnection.pro @@ -1,17 +1,27 @@ TEMPLATE = lib TARGET = IPconnection + +QT += network widgets + +DEFINES += IPconnection_LIBRARY + include(../../plugin.pri) include(ipconnection_dependencies.pri) -HEADERS += ipconnectionplugin.h \ + +HEADERS += \ + ipconnectionplugin.h \ ipconnection_global.h \ ipconnectionconfiguration.h \ ipconnectionoptionspage.h \ ipconnection_internal.h -SOURCES += ipconnectionplugin.cpp \ + +SOURCES += \ + ipconnectionplugin.cpp \ ipconnectionconfiguration.cpp \ ipconnectionoptionspage.cpp + FORMS += ipconnectionoptionspage.ui + RESOURCES += -DEFINES += IPconnection_LIBRARY + OTHER_FILES += IPconnection.pluginspec -QT += network diff --git a/ground/gcs/src/plugins/lineardial/lineardial.pro b/ground/gcs/src/plugins/lineardial/lineardial.pro index b8fa90592..89557ce43 100644 --- a/ground/gcs/src/plugins/lineardial/lineardial.pro +++ b/ground/gcs/src/plugins/lineardial/lineardial.pro @@ -1,22 +1,30 @@ TEMPLATE = lib TARGET = LineardialGadget -QT += svg -QT += opengl + +QT += widgets svg opengl + include(../../plugin.pri) include(../../plugins/coreplugin/coreplugin.pri) include(lineardial_dependencies.pri) -HEADERS += lineardialplugin.h -HEADERS += lineardialgadget.h -HEADERS += lineardialgadgetwidget.h -HEADERS += lineardialgadgetfactory.h -HEADERS += lineardialgadgetconfiguration.h -HEADERS += lineardialgadgetoptionspage.h -SOURCES += lineardialplugin.cpp -SOURCES += lineardialgadget.cpp -SOURCES += lineardialgadgetfactory.cpp -SOURCES += lineardialgadgetwidget.cpp -SOURCES += lineardialgadgetconfiguration.cpp -SOURCES += lineardialgadgetoptionspage.cpp + +HEADERS += \ + lineardialplugin.h \ + lineardialgadget.h \ + lineardialgadgetwidget.h \ + lineardialgadgetfactory.h \ + lineardialgadgetconfiguration.h \ + lineardialgadgetoptionspage.h + +SOURCES += \ + lineardialplugin.cpp \ + lineardialgadget.cpp \ + lineardialgadgetfactory.cpp \ + lineardialgadgetwidget.cpp \ + lineardialgadgetconfiguration.cpp \ + lineardialgadgetoptionspage.cpp + OTHER_FILES += LineardialGadget.pluginspec + FORMS += lineardialgadgetoptionspage.ui + RESOURCES += lineardial.qrc diff --git a/ground/gcs/src/plugins/lineardial/lineardialgadgetwidget.cpp b/ground/gcs/src/plugins/lineardial/lineardialgadgetwidget.cpp index 8bc583ff6..9bfb4a84f 100644 --- a/ground/gcs/src/plugins/lineardial/lineardialgadgetwidget.cpp +++ b/ground/gcs/src/plugins/lineardial/lineardialgadgetwidget.cpp @@ -28,7 +28,7 @@ #include "lineardialgadgetwidget.h" #include #include -#include +#include #include LineardialGadgetWidget::LineardialGadgetWidget(QWidget *parent) : QGraphicsView(parent) @@ -66,7 +66,7 @@ LineardialGadgetWidget::~LineardialGadgetWidget() void LineardialGadgetWidget::enableOpenGL(bool flag) { if (flag) { - setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); + setViewport(new QOpenGLWidget()); // QGLFormat(QGL::SampleBuffers))); } else { setViewport(new QWidget); } diff --git a/ground/gcs/src/plugins/logging/logging.pro b/ground/gcs/src/plugins/logging/logging.pro index d3494cbed..66c61a34b 100644 --- a/ground/gcs/src/plugins/logging/logging.pro +++ b/ground/gcs/src/plugins/logging/logging.pro @@ -1,17 +1,21 @@ TEMPLATE = lib - TARGET = LoggingGadget + DEFINES += LOGGING_LIBRARY + QT += svg include(../../plugin.pri) include(logging_dependencies.pri) -HEADERS += loggingplugin.h \ + +HEADERS += \ + loggingplugin.h \ logginggadgetwidget.h \ logginggadget.h \ logginggadgetfactory.h -SOURCES += loggingplugin.cpp \ +SOURCES += \ + loggingplugin.cpp \ logginggadgetwidget.cpp \ logginggadget.cpp \ logginggadgetfactory.cpp diff --git a/ground/gcs/src/plugins/logging/loggingplugin.cpp b/ground/gcs/src/plugins/logging/loggingplugin.cpp index e6238b87f..da3efbe9b 100644 --- a/ground/gcs/src/plugins/logging/loggingplugin.cpp +++ b/ground/gcs/src/plugins/logging/loggingplugin.cpp @@ -237,7 +237,7 @@ void LoggingThread::retrieveSettings() } } // Start retrieving - qDebug() << tr("Logging: retrieve settings objects from the autopilot (%1 objects)") + qDebug() << QString("Logging: retrieve settings objects from the autopilot (%1 objects)") .arg(queue.length()); retrieveNextObject(); } diff --git a/ground/gcs/src/plugins/magicwaypoint/magicwaypoint.pro b/ground/gcs/src/plugins/magicwaypoint/magicwaypoint.pro index 4eb15ee03..886aec685 100644 --- a/ground/gcs/src/plugins/magicwaypoint/magicwaypoint.pro +++ b/ground/gcs/src/plugins/magicwaypoint/magicwaypoint.pro @@ -1,22 +1,25 @@ TEMPLATE = lib TARGET = MagicWaypoint + QT += svg include(../../plugin.pri) include(../../plugins/coreplugin/coreplugin.pri) include(../../plugins/uavobjects/uavobjects.pri) -HEADERS += magicwaypointgadget.h -HEADERS += magicwaypointgadgetwidget.h -HEADERS += magicwaypointgadgetfactory.h -HEADERS += magicwaypointplugin.h -HEADERS += positionfield.h +HEADERS += \ + magicwaypointgadget.h \ + magicwaypointgadgetwidget.h \ + magicwaypointgadgetfactory.h \ + magicwaypointplugin.h \ + positionfield.h -SOURCES += magicwaypointgadget.cpp -SOURCES += magicwaypointgadgetwidget.cpp -SOURCES += magicwaypointgadgetfactory.cpp -SOURCES += magicwaypointplugin.cpp -SOURCES += positionfield.cpp +SOURCES += \ + magicwaypointgadget.cpp \ + magicwaypointgadgetwidget.cpp \ + magicwaypointgadgetfactory.cpp \ + magicwaypointplugin.cpp \ + positionfield.cpp OTHER_FILES += MagicWaypoint.pluginspec diff --git a/ground/gcs/src/plugins/modelview/ModelViewGadget.pluginspec b/ground/gcs/src/plugins/modelview/ModelViewGadget.pluginspec deleted file mode 100644 index ada1faacd..000000000 --- a/ground/gcs/src/plugins/modelview/ModelViewGadget.pluginspec +++ /dev/null @@ -1,10 +0,0 @@ - - The OpenPilot Project - (C) 2010 David "Buzz" Carlson - The GNU Public License (GPL) Version 3 - A 3D model view gadget - http://www.openpilot.org - - - - diff --git a/ground/gcs/src/plugins/modelview/models/black.jpg b/ground/gcs/src/plugins/modelview/models/black.jpg deleted file mode 100644 index e82821d3b..000000000 Binary files a/ground/gcs/src/plugins/modelview/models/black.jpg and /dev/null differ diff --git a/ground/gcs/src/plugins/modelview/models/warning_sign.mtl b/ground/gcs/src/plugins/modelview/models/warning_sign.mtl deleted file mode 100644 index 796b75465..000000000 --- a/ground/gcs/src/plugins/modelview/models/warning_sign.mtl +++ /dev/null @@ -1,48 +0,0 @@ -# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware -# File Created: 14.10.2010 00:38:26 - -newmtl red - Ns 10.0000 - Ni 1.5000 - d 1.0000 - Tr 0.0000 - Tf 1.0000 1.0000 1.0000 - illum 2 - Ka 1.0000 0.0000 0.0000 - Kd 1.0000 0.0000 0.0000 - Ks 0.0000 0.0000 0.0000 - Ke 0.0000 0.0000 0.0000 - -newmtl white - Ns 10.0000 - Ni 1.5000 - d 1.0000 - Tr 0.0000 - Tf 1.0000 1.0000 1.0000 - illum 2 - Ka 1.0000 1.0000 1.0000 - Kd 1.0000 1.0000 1.0000 - Ks 0.0000 0.0000 0.0000 - Ke 0.0000 0.0000 0.0000 - -newmtl black - Ns 10.0000 - Ni 1.5000 - d 1.0000 - Tr 0.0000 - Tf 1.0000 1.0000 1.0000 - illum 2 - Ka 0.0000 0.0000 0.0000 - Kd 0.0000 0.0000 0.0000 - Ks 0.0000 0.0000 0.0000 - Ke 0.0000 0.0000 0.0000 - -newmtl wire_000000000 - Ns 32 - d 1 - Tr 0 - Tf 1 1 1 - illum 2 - Ka 0.0000 0.0000 0.0000 - Kd 0.0000 0.0000 0.0000 - Ks 0.3500 0.3500 0.3500 diff --git a/ground/gcs/src/plugins/modelview/models/warning_sign.obj b/ground/gcs/src/plugins/modelview/models/warning_sign.obj deleted file mode 100644 index 83461669a..000000000 --- a/ground/gcs/src/plugins/modelview/models/warning_sign.obj +++ /dev/null @@ -1,21424 +0,0 @@ -# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware -# File Created: 14.10.2010 00:38:26 - -mtllib warning_sign.mtl - -# -# object check_config_text -# - -v 7.1301 -0.5906 -7.3210 -v 7.1279 -0.5906 -8.2198 -v 7.1296 0.5906 -8.1406 -v 6.4844 -0.5906 -7.7415 -v 6.4880 -0.5906 -7.8417 -v 6.4881 0.5906 -7.8350 -v 6.3251 -0.5906 -7.8008 -v 6.3272 -0.5906 -7.7152 -v 6.3274 0.5906 -7.7190 -v 6.9856 -0.5906 -7.8373 -v 6.9881 -0.5906 -7.7383 -v 6.9876 0.5906 -7.7448 -v 7.1301 0.5906 -7.3210 -v 6.3271 0.5906 -7.8273 -v -8.9595 0.5906 -7.3807 -v -8.9830 0.5906 -7.4040 -v -8.9707 -0.5906 -7.3899 -v -8.5101 0.5906 -7.7306 -v -8.6456 0.5906 -7.6902 -v -8.6179 -0.5906 -7.6977 -v -9.2488 -0.5906 -7.5564 -v -9.2471 -0.5906 -7.6262 -v -9.2478 0.5906 -7.5938 -v -9.8316 -0.5906 -8.2461 -v -9.8973 -0.5906 -8.2245 -v -9.8933 0.5906 -8.2253 -v -9.7270 -0.5906 -8.1324 -v -9.6485 -0.5906 -8.1328 -v -9.7035 0.5906 -8.1336 -v -9.4414 -0.5906 -8.0145 -v -9.4192 -0.5906 -7.9717 -v -9.4318 0.5906 -7.9975 -v 9.0897 -0.5906 -8.2461 -v 9.0240 -0.5906 -8.2245 -v 9.0280 0.5906 -8.2253 -v 9.1943 -0.5906 -8.1324 -v 9.2727 -0.5906 -8.1328 -v 9.2177 0.5906 -8.1336 -v 9.4799 -0.5906 -8.0145 -v 9.5020 -0.5906 -7.9717 -v 9.4895 0.5906 -7.9975 -v 9.6742 -0.5906 -7.6259 -v 9.6747 -0.5906 -7.9618 -v 9.6749 0.5906 -7.9334 -v -8.8221 -0.5906 -7.6396 -v -8.5945 -0.5906 -7.8694 -v -8.7958 -0.5906 -7.8159 -v -8.7413 0.5906 -7.8308 -v -10.0315 0.5906 -8.0709 -v -10.0157 0.5906 -8.1120 -v -10.0157 -0.5906 -8.1120 -v -9.2464 0.5906 -7.9334 -v 9.6782 0.5906 -8.0634 -v 8.8897 0.5906 -8.0709 -v 8.9055 0.5906 -8.1120 -v 8.9055 -0.5906 -8.1120 -v -0.3721 -0.5906 -7.7091 -v -0.3748 -0.5906 -7.8086 -v -0.3742 0.5906 -7.8024 -v 0.1595 -0.5906 -7.8440 -v 0.1621 -0.5906 -7.7433 -v 0.1616 0.5906 -7.7497 -v 0.3216 -0.5906 -7.7331 -v 0.3193 -0.5906 -7.8437 -v 0.3192 0.5906 -7.8375 -v -0.5346 -0.5906 -7.8063 -v -0.5275 -0.5906 -7.6675 -v -0.5316 0.5906 -7.7089 -v 4.3413 -0.5906 -7.7331 -v 4.3389 -0.5906 -7.8437 -v 4.3388 0.5906 -7.8375 -v 3.4851 -0.5906 -7.8063 -v 3.4922 -0.5906 -7.6675 -v 3.4881 0.5906 -7.7089 -v 3.6476 -0.5906 -7.7091 -v 3.6449 -0.5906 -7.8086 -v 3.6455 0.5906 -7.8024 -v 4.1792 -0.5906 -7.8440 -v 4.1818 -0.5906 -7.7433 -v 4.1813 0.5906 -7.7497 -v 11.5933 -0.5906 -7.7331 -v 11.5909 -0.5906 -7.8437 -v 11.5908 0.5906 -7.8375 -v 10.7370 -0.5906 -7.8063 -v 10.7442 -0.5906 -7.6675 -v 10.7401 0.5906 -7.7089 -v 10.8996 -0.5906 -7.7090 -v 10.8969 -0.5906 -7.8086 -v 10.8974 0.5906 -7.8024 -v 11.4311 -0.5906 -7.8440 -v 11.4338 -0.5906 -7.7433 -v 11.4333 0.5906 -7.7497 -v -3.5699 0.5906 -7.9720 -v -3.5901 0.5906 -7.8957 -v -3.5898 -0.5906 -7.9021 -v -3.5743 0.5906 -7.3653 -v -3.6253 0.5906 -7.4038 -v -3.6237 -0.5906 -7.4014 -v 2.8041 0.5906 -7.9720 -v 2.7840 0.5906 -7.8957 -v 2.7842 -0.5906 -7.9021 -v 2.7997 0.5906 -7.3653 -v 2.7487 0.5906 -7.4038 -v 2.7503 -0.5906 -7.4013 -v -6.4168 0.5906 -7.3653 -v -6.4678 0.5906 -7.4038 -v -6.4662 -0.5906 -7.4014 -v -6.4124 0.5906 -7.9720 -v -6.4326 0.5906 -7.8957 -v -6.4323 -0.5906 -7.9021 -v -6.4162 -0.5906 -7.3641 -v -6.4391 -0.5906 -7.7064 -v -6.4417 -0.5906 -7.8093 -v -6.4412 0.5906 -7.8031 -v -3.5737 -0.5906 -7.3641 -v -3.5966 -0.5906 -7.7064 -v -3.5992 -0.5906 -7.8093 -v -3.5987 0.5906 -7.8031 -v 2.8003 -0.5906 -7.3641 -v 2.7774 -0.5906 -7.7064 -v 2.7748 -0.5906 -7.8093 -v 2.7753 0.5906 -7.8031 -v -4.7452 -0.5906 -7.8143 -v -4.7393 -0.5906 -7.6849 -v -4.7439 0.5906 -7.7546 -v -4.5783 -0.5906 -7.8849 -v -4.5589 -0.5906 -7.9553 -v -4.5596 0.5906 -7.9510 -v -11.0208 -0.5906 -7.8143 -v -11.0149 -0.5906 -7.6849 -v -11.0195 0.5906 -7.7546 -v -10.8539 -0.5906 -7.8849 -v -10.8345 -0.5906 -7.9553 -v -10.8352 0.5906 -7.9510 -v -8.1783 -0.5906 -7.8143 -v -8.1723 -0.5906 -7.6849 -v -8.1769 0.5906 -7.7546 -v -8.0114 -0.5906 -7.8849 -v -7.9920 -0.5906 -7.9553 -v -7.9927 0.5906 -7.9510 -v 9.5164 -0.5906 -7.7794 -v 9.3742 -0.5906 -7.8179 -v 9.4105 0.5906 -7.8094 -v 9.1448 -0.5906 -7.7222 -v 9.3779 -0.5906 -7.6902 -v 9.3174 0.5906 -7.6990 -v -9.7764 -0.5906 -7.7222 -v -9.5434 -0.5906 -7.6902 -v -9.6039 0.5906 -7.6990 -v -9.4049 -0.5906 -7.7794 -v -9.5470 -0.5906 -7.8179 -v -9.5108 0.5906 -7.8094 -v -4.7391 0.5906 -7.8768 -v -4.5856 0.5906 -7.8190 -v -3.9034 0.5906 -7.8190 -v -3.9028 -0.5906 -7.8190 -v -11.0147 0.5906 -7.8768 -v -10.8612 0.5906 -7.8190 -v -10.1790 0.5906 -7.8190 -v -10.1784 -0.5906 -7.8190 -v -8.0187 0.5906 -7.8190 -v -7.3365 0.5906 -7.8190 -v -7.3359 -0.5906 -7.8190 -v -8.1722 0.5906 -7.8768 -v 4.3391 0.5906 -7.7056 -v 3.5456 0.5906 -8.0539 -v 3.5722 0.5906 -8.0957 -v 3.5722 -0.5906 -8.0957 -v 11.5911 0.5906 -7.7056 -v 10.7976 0.5906 -8.0539 -v 10.8241 0.5906 -8.0957 -v 10.8241 -0.5906 -8.0957 -v -0.4741 0.5906 -8.0539 -v -0.4475 0.5906 -8.0957 -v -0.4475 -0.5906 -8.0957 -v 0.3194 0.5906 -7.7056 -v -8.8725 0.5906 -8.2251 -v -8.7949 0.5906 -8.2462 -v -8.8008 -0.5906 -8.2460 -v -12.5167 -0.5906 -8.2364 -v -12.5167 -0.5906 -6.9746 -v -12.5167 0.5906 -6.9746 -v -11.6178 0.5906 -7.5626 -v -11.5875 0.5906 -7.5081 -v -11.5875 -0.5906 -7.5081 -v 9.3031 0.5906 -7.3017 -v 9.2390 0.5906 -7.3056 -v 9.2108 -0.5906 -7.3082 -v -6.2627 0.5906 -8.2498 -v -6.1652 0.5906 -8.2551 -v -6.1687 -0.5906 -8.2562 -v -3.4202 0.5906 -8.2498 -v -3.3227 0.5906 -8.2551 -v -3.3262 -0.5906 -8.2562 -v 2.9538 0.5906 -8.2498 -v 3.0513 0.5906 -8.2551 -v 3.0478 -0.5906 -8.2562 -v -9.4448 0.5906 -7.6685 -v -9.5162 0.5906 -7.6844 -v -0.2637 0.5906 -8.0738 -v -0.3086 0.5906 -8.0275 -v -0.3082 -0.5906 -8.0298 -v 0.0506 0.5906 -7.4836 -v 0.0957 0.5906 -7.5298 -v 0.0952 -0.5906 -7.5276 -v 11.3228 0.5906 -8.0735 -v 11.2848 0.5906 -8.0995 -v 11.2848 -0.5906 -8.0995 -v 11.0080 0.5906 -7.4833 -v 11.0460 0.5906 -7.4576 -v 11.0460 -0.5906 -7.4576 -v 4.0708 0.5906 -8.0735 -v 4.0329 0.5906 -8.0995 -v 4.0329 -0.5906 -8.0995 -v 3.7560 0.5906 -7.4833 -v 3.7941 0.5906 -7.4576 -v 3.7941 -0.5906 -7.4576 -v -8.4999 -0.5906 -8.2257 -v -8.6072 -0.5906 -8.2526 -v -8.5768 0.5906 -8.2465 -v -8.7214 -0.5906 -8.1263 -v -8.6617 -0.5906 -8.1280 -v -8.6649 0.5906 -8.1277 -v 6.8581 -0.5906 -8.5910 -v 6.7722 -0.5906 -8.6045 -v 6.8100 0.5906 -8.5996 -v 6.9535 -0.5906 -8.3453 -v 6.9665 -0.5906 -8.3017 -v 6.9649 0.5906 -8.3072 -v -8.8176 0.5906 -7.8086 -v -8.7547 -0.5906 -7.3030 -v -8.6554 -0.5906 -7.3024 -v -8.6917 0.5906 -7.3016 -v -8.6581 -0.5906 -7.4301 -v -8.7427 -0.5906 -7.4310 -v -8.7386 0.5906 -7.4311 -v 6.9571 0.5906 -7.5865 -v 6.9784 0.5906 -7.6589 -v 6.9782 -0.5906 -7.6533 -v 6.5027 0.5906 -7.9181 -v -6.2023 -0.5906 -8.1281 -v -6.1469 -0.5906 -8.1254 -v -6.1498 0.5906 -8.1253 -v -6.0879 -0.5906 -8.2458 -v -3.3598 -0.5906 -8.1281 -v -3.3044 -0.5906 -8.1254 -v -3.3073 0.5906 -8.1253 -v -3.2454 -0.5906 -8.2458 -v 3.0143 -0.5906 -8.1281 -v 3.0696 -0.5906 -8.1254 -v 3.0667 0.5906 -8.1253 -v 3.1286 -0.5906 -8.2458 -v 9.1003 -0.5906 -7.3368 -v 9.1796 0.5906 -7.3148 -v 9.3146 -0.5906 -7.4293 -v 9.2501 -0.5906 -7.4312 -v 9.2542 0.5906 -7.4312 -v -1.4478 0.5906 -7.3210 -v -1.0994 0.5906 -8.2379 -v -1.0994 -0.5906 -8.2379 -v -0.9783 0.5906 -8.3100 -v -0.6100 0.5906 -7.3210 -v -0.6100 -0.5906 -7.3210 -v 9.4764 0.5906 -7.6685 -v 9.4050 0.5906 -7.6844 -v -9.8209 -0.5906 -7.3368 -v -9.7105 -0.5906 -7.3082 -v -9.7416 0.5906 -7.3148 -v -9.6067 -0.5906 -7.4293 -v -9.6712 -0.5906 -7.4312 -v -9.6671 0.5906 -7.4312 -v -11.7507 -0.5906 -7.2333 -v -11.7852 -0.5906 -7.1842 -v -11.7601 0.5906 -7.2180 -v -11.9748 -0.5906 -7.1246 -v -12.3494 -0.5906 -7.1242 -v -12.3494 0.5906 -7.1242 -v -11.6078 -0.5906 -7.1373 -v -11.5769 -0.5906 -7.2040 -v -11.5780 0.5906 -7.2021 -v -11.9772 -0.5906 -6.9751 -v -11.9914 0.5906 -6.9754 -v 7.8094 0.5906 -8.1000 -v 7.7538 0.5906 -8.1175 -v 7.8026 -0.5906 -8.1036 -v 7.5129 0.5906 -8.2205 -v 7.5532 0.5906 -8.2368 -v 7.5707 -0.5906 -8.2432 -v 0.9471 0.5906 -8.1000 -v 0.8916 0.5906 -8.1175 -v 0.9403 -0.5906 -8.1036 -v 0.6507 0.5906 -8.2205 -v 0.6910 0.5906 -8.2368 -v 0.7085 -0.5906 -8.2432 -v 10.0961 0.5906 -8.0026 -v 10.0955 0.5906 -7.4411 -v 10.0955 -0.5906 -7.4411 -v 9.9400 0.5906 -7.4411 -v 9.9419 0.5906 -8.0380 -v 9.9407 -0.5906 -8.0317 -v 6.7319 0.5906 -8.4781 -v 6.6762 0.5906 -8.4763 -v 6.7041 -0.5906 -8.4785 -v 12.3660 0.5906 -7.3355 -v 12.3262 0.5906 -7.3198 -v 12.3090 -0.5906 -7.3137 -v 12.1050 0.5906 -7.4435 -v 12.1580 0.5906 -7.4358 -v 12.1535 -0.5906 -7.4355 -v 5.1140 0.5906 -7.3355 -v 5.0742 0.5906 -7.3198 -v 5.0570 -0.5906 -7.3137 -v 4.8530 0.5906 -7.4435 -v 4.9060 0.5906 -7.4358 -v 4.9015 -0.5906 -7.4355 -v -9.6182 0.5906 -7.3017 -v -9.6822 0.5906 -7.3056 -v -5.4156 0.5906 -7.4763 -v -5.3811 0.5906 -7.4574 -v -5.3658 -0.5906 -7.4499 -v -5.2044 0.5906 -7.3034 -v -5.2922 0.5906 -7.3039 -v -5.2712 -0.5906 -7.3016 -v 7.7378 -0.5906 -8.1211 -v 7.4899 -0.5906 -8.2096 -v 0.6277 -0.5906 -8.2096 -v 0.8756 -0.5906 -8.1211 -v 9.9400 -0.5906 -7.4411 -v 10.0966 -0.5906 -8.0298 -v -1.4478 -0.5906 -7.3210 -v -0.9845 -0.5906 -8.3274 -v -5.0876 -0.5906 -8.2364 -v -5.0882 -0.5906 -7.6308 -v -5.0881 0.5906 -7.6412 -v -5.1721 -0.5906 -7.3062 -v 7.0919 -0.5906 -8.4032 -v 12.2713 -0.5906 -7.4576 -v 12.2126 -0.5906 -7.4378 -v 12.2295 0.5906 -7.4423 -v 11.9648 -0.5906 -7.3895 -v 12.0404 -0.5906 -7.3363 -v 12.0170 0.5906 -7.3502 -v 5.0193 -0.5906 -7.4576 -v 4.9606 -0.5906 -7.4378 -v 4.9775 0.5906 -7.4423 -v 4.7128 -0.5906 -7.3895 -v 4.7884 -0.5906 -7.3363 -v 4.7650 0.5906 -7.3502 -v 11.0515 0.5906 -7.3148 -v 10.9889 0.5906 -7.3345 -v 10.9889 -0.5906 -7.3345 -v 3.7996 0.5906 -7.3148 -v 3.7369 0.5906 -7.3345 -v 3.7369 -0.5906 -7.3345 -v -0.2201 0.5906 -7.3148 -v -0.2828 0.5906 -7.3345 -v -0.2828 -0.5906 -7.3345 -v -10.3662 0.5906 -7.3651 -v -10.4062 0.5906 -7.3421 -v -10.4062 -0.5906 -7.3421 -v -4.0906 0.5906 -7.3651 -v -4.1306 0.5906 -7.3421 -v -4.1306 -0.5906 -7.3421 -v -7.5237 0.5906 -7.3651 -v -7.5637 0.5906 -7.3421 -v -7.5637 -0.5906 -7.3421 -v -8.6706 0.5906 -7.4301 -v 6.6507 0.5906 -8.6027 -v 6.7367 0.5906 -8.6059 -v 6.6880 -0.5906 -8.6062 -v -10.7622 -0.5906 -7.3311 -v -10.6686 -0.5906 -7.3061 -v -10.6962 0.5906 -7.3117 -v -10.1825 -0.5906 -7.6882 -v -4.4866 -0.5906 -7.3311 -v -4.3930 -0.5906 -7.3061 -v -4.4207 0.5906 -7.3117 -v -3.9069 -0.5906 -7.6882 -v -7.9197 -0.5906 -7.3311 -v -7.8261 -0.5906 -7.3061 -v -7.8537 0.5906 -7.3117 -v -7.3400 -0.5906 -7.6882 -v 5.6954 0.5906 -8.2364 -v 5.6954 0.5906 -7.4411 -v 5.6954 -0.5906 -7.4411 -v 5.5399 0.5906 -7.4411 -v 5.5399 0.5906 -8.2364 -v 5.5399 -0.5906 -8.2364 -v 5.5399 -0.5906 -7.3210 -v 5.5407 -0.5906 -7.1774 -v 5.5411 0.5906 -7.1881 -v 5.6945 -0.5906 -7.1997 -v 5.6935 -0.5906 -7.3210 -v 5.6935 0.5906 -7.3210 -v -8.7735 0.5906 -8.1157 -v -8.8069 0.5906 -8.1032 -v -8.7840 -0.5906 -8.1135 -v -12.5167 0.5906 -8.2364 -v -12.3494 -0.5906 -7.7246 -v -12.3494 -0.5906 -8.2364 -v -12.3494 0.5906 -8.2364 -v 9.5167 0.5906 -7.7777 -v 9.1313 0.5906 -8.1168 -v 9.0989 0.5906 -8.0984 -v 9.1002 -0.5906 -8.1000 -v -9.4045 0.5906 -7.7777 -v -9.7899 0.5906 -8.1168 -v -9.8224 0.5906 -8.0984 -v -9.8211 -0.5906 -8.1000 -v 11.1199 -0.5906 -8.1249 -v 11.1855 -0.5906 -8.1279 -v 11.1819 0.5906 -8.1272 -v 11.3397 -0.5906 -8.2229 -v 11.2782 -0.5906 -8.2430 -v 11.2807 0.5906 -8.2418 -v -0.1517 -0.5906 -8.1249 -v -0.0861 -0.5906 -8.1279 -v -0.0898 0.5906 -8.1272 -v 0.0680 -0.5906 -8.2229 -v 0.0065 -0.5906 -8.2430 -v 0.0090 0.5906 -8.2418 -v 3.8680 -0.5906 -8.1249 -v 3.9336 -0.5906 -8.1279 -v 3.9299 0.5906 -8.1272 -v 4.0877 -0.5906 -8.2229 -v 4.0262 -0.5906 -8.2430 -v 4.0287 0.5906 -8.2418 -v -4.1649 0.5906 -8.2363 -v -4.1112 0.5906 -8.2165 -v -4.1112 -0.5906 -8.2165 -v -7.5980 0.5906 -8.2363 -v -7.5442 0.5906 -8.2165 -v -7.5442 -0.5906 -8.2165 -v -10.4405 0.5906 -8.2363 -v -10.3867 0.5906 -8.2165 -v -10.3867 -0.5906 -8.2165 -v -9.5902 0.5906 -7.4304 -v 9.3310 0.5906 -7.4304 -v -12.3494 -0.5906 -7.5750 -v -11.9865 -0.5906 -7.5743 -v -12.0010 0.5906 -7.5743 -v -11.9742 -0.5906 -7.7237 -v -12.3494 0.5906 -7.7246 -v 3.9590 -0.5906 -7.4325 -v 3.8941 -0.5906 -7.4295 -v 3.8976 0.5906 -7.4302 -v 3.8024 -0.5906 -7.3130 -v 3.8941 -0.5906 -7.3012 -v 3.8901 0.5906 -7.3024 -v -0.0607 -0.5906 -7.4325 -v -0.1256 -0.5906 -7.4295 -v -0.1220 0.5906 -7.4302 -v -0.2173 -0.5906 -7.3130 -v -0.1256 -0.5906 -7.3012 -v -0.1296 0.5906 -7.3024 -v 11.2110 -0.5906 -7.4325 -v 11.1461 -0.5906 -7.4295 -v 11.1496 0.5906 -7.4302 -v 11.0543 -0.5906 -7.3130 -v 11.1461 -0.5906 -7.3012 -v 11.1421 0.5906 -7.3024 -v 6.5747 0.5906 -8.2114 -v 6.6199 0.5906 -8.2253 -v 6.6380 -0.5906 -8.2298 -v -6.1944 0.5906 -7.4301 -v -6.1460 0.5906 -7.4317 -v -6.1473 -0.5906 -7.4310 -v 3.0221 0.5906 -7.4301 -v 3.0705 0.5906 -7.4317 -v 3.0692 -0.5906 -7.4310 -v -3.3519 0.5906 -7.4301 -v -3.3035 0.5906 -7.4317 -v -3.3048 -0.5906 -7.4310 -v -9.6387 0.5906 -8.2483 -v -9.5730 0.5906 -8.2315 -v -9.5686 -0.5906 -8.2314 -v -10.8533 -0.5906 -7.6911 -v -10.3415 -0.5906 -7.6911 -v -10.3415 0.5906 -7.6911 -v -10.5160 -0.5906 -7.4396 -v -10.5775 -0.5906 -7.4292 -v -10.5763 0.5906 -7.4302 -v -10.5623 -0.5906 -7.3017 -v -10.8612 -0.5906 -7.8190 -v -4.5856 -0.5906 -7.8190 -v -4.2867 -0.5906 -7.3017 -v -4.3019 -0.5906 -7.4292 -v -4.2404 -0.5906 -7.4396 -v -4.5778 -0.5906 -7.6911 -v -4.0659 -0.5906 -7.6911 -v -4.0659 0.5906 -7.6911 -v -4.3007 0.5906 -7.4302 -v -8.0187 -0.5906 -7.8190 -v -8.0108 -0.5906 -7.6911 -v -7.4990 -0.5906 -7.6911 -v -7.4990 0.5906 -7.6911 -v -7.6734 -0.5906 -7.4396 -v -7.7350 -0.5906 -7.4292 -v -7.7337 0.5906 -7.4302 -v -7.7198 -0.5906 -7.3017 -v 9.2825 0.5906 -8.2483 -v 9.3482 0.5906 -8.2315 -v 9.3527 -0.5906 -8.2314 -v 6.6933 -0.5906 -8.1054 -v 6.7543 -0.5906 -8.1082 -v 6.7509 0.5906 -8.1076 -v 6.5489 -0.5906 -8.2010 -v 6.4737 -0.5906 -8.1506 -v 6.4946 0.5906 -8.1670 -v -10.6614 0.5906 -8.1175 -v -10.7032 0.5906 -8.1021 -v -10.7032 -0.5906 -8.1021 -v -5.6742 -0.5906 -8.2364 -v -5.6742 -0.5906 -6.9746 -v -5.6742 0.5906 -6.9746 -v -5.4547 -0.5906 -7.5077 -v -5.4815 -0.5906 -7.5439 -v -5.4804 0.5906 -7.5428 -v -4.3245 -0.5906 -8.1281 -v -4.2711 -0.5906 -8.1260 -v -4.2737 0.5906 -8.1258 -v -4.1670 -0.5906 -8.2378 -v -4.2465 -0.5906 -8.2532 -v -4.2443 0.5906 -8.2521 -v -10.4426 -0.5906 -8.2378 -v -10.5221 -0.5906 -8.2532 -v -10.5199 0.5906 -8.2521 -v -10.6001 -0.5906 -8.1281 -v -10.5466 -0.5906 -8.1260 -v -10.5493 0.5906 -8.1258 -v -7.6001 -0.5906 -8.2378 -v -7.6795 -0.5906 -8.2532 -v -7.6773 0.5906 -8.2521 -v -7.7576 -0.5906 -8.1281 -v -7.7041 -0.5906 -8.1260 -v -7.7068 0.5906 -8.1258 -v -8.3216 0.5906 -8.0420 -v -8.3105 0.5906 -7.9779 -v -8.3107 -0.5906 -7.9925 -v 6.8338 -0.5906 -7.3189 -v 6.8878 -0.5906 -7.3444 -v 6.8878 0.5906 -7.3444 -v 6.8288 -0.5906 -7.4491 -v 6.7751 -0.5906 -7.4324 -v 6.7770 0.5906 -7.4336 -v -2.8308 0.5906 -6.9746 -v -2.8308 0.5906 -8.2364 -v -2.8308 -0.5906 -8.2364 -v -2.0738 0.5906 -8.2364 -v -2.4580 0.5906 -7.6610 -v -2.4580 -0.5906 -7.6610 -v -2.6753 -0.5906 -7.8728 -v -2.6753 -0.5906 -8.2364 -v -2.6753 0.5906 -8.2364 -v -2.8308 -0.5906 -6.9746 -v 1.6368 0.5906 -8.2364 -v 1.6388 0.5906 -7.7093 -v 1.6376 -0.5906 -7.7133 -v 1.4813 0.5906 -7.3210 -v 1.4813 0.5906 -8.2364 -v 1.4813 -0.5906 -8.2364 -v 8.3435 0.5906 -7.3210 -v 8.3435 0.5906 -8.2364 -v 8.3435 -0.5906 -8.2364 -v 8.4990 0.5906 -8.2364 -v 8.5010 0.5906 -7.7093 -v 8.4998 -0.5906 -7.7133 -v -6.5989 0.5906 -7.7206 -v -6.5991 0.5906 -7.8453 -v -6.6012 -0.5906 -7.8150 -v -3.7564 0.5906 -7.7206 -v -3.7565 0.5906 -7.8453 -v -3.7587 -0.5906 -7.8150 -v 2.6177 0.5906 -7.7206 -v 2.6175 0.5906 -7.8453 -v 2.6153 -0.5906 -7.8150 -v -9.4021 0.5906 -7.8547 -v -9.2463 0.5906 -7.9480 -v -9.2388 0.5906 -8.1157 -v 9.5192 0.5906 -7.8547 -v 9.6749 0.5906 -7.9480 -v 9.6825 0.5906 -8.1157 -v -7.6235 0.5906 -8.1003 -v -7.6631 0.5906 -8.1167 -v -7.6608 -0.5906 -8.1165 -v -4.1905 0.5906 -8.1003 -v -4.2300 0.5906 -8.1167 -v -4.2278 -0.5906 -8.1165 -v 5.7259 0.5906 -6.9579 -v 5.6808 0.5906 -6.9685 -v 5.6816 -0.5906 -6.9677 -v 6.6078 0.5906 -7.3167 -v 6.5499 0.5906 -7.3388 -v 6.5520 -0.5906 -7.3371 -v 5.2645 -0.5906 -7.6252 -v 5.2648 -0.5906 -8.2364 -v 5.2648 0.5906 -8.2364 -v 12.5164 -0.5906 -7.6251 -v 12.5167 -0.5906 -8.2364 -v 12.5167 0.5906 -8.2364 -v -0.2637 0.5906 -7.4833 -v -0.2256 0.5906 -7.4576 -v -0.2256 -0.5906 -7.4576 -v -12.3494 0.5906 -7.5750 -v -11.7356 0.5906 -7.2719 -v -11.7274 0.5906 -7.3125 -v -11.7303 -0.5906 -7.2874 -v 3.7560 0.5906 -8.0738 -v 3.7111 0.5906 -8.0275 -v 3.7115 -0.5906 -8.0298 -v 11.0080 0.5906 -8.0738 -v 10.9630 0.5906 -8.0275 -v 10.9635 -0.5906 -8.0298 -v -11.8109 0.5906 -6.9947 -v -11.8818 0.5906 -6.9823 -v -11.8756 -0.5906 -6.9821 -v 4.0702 0.5906 -7.4836 -v 4.1153 0.5906 -7.5298 -v 4.1149 -0.5906 -7.5276 -v 11.3222 0.5906 -7.4836 -v 11.3673 0.5906 -7.5298 -v 11.3669 -0.5906 -7.5276 -v 1.6368 -0.5906 -8.2364 -v 1.4813 -0.5906 -7.3210 -v 8.3435 -0.5906 -7.3210 -v 8.4990 -0.5906 -8.2364 -v 11.4005 0.5906 -8.1917 -v 11.4524 0.5906 -8.1542 -v 11.4508 -0.5906 -8.1564 -v 4.1485 0.5906 -8.1917 -v 4.2004 0.5906 -8.1542 -v 4.1988 -0.5906 -8.1564 -v -3.7565 -0.5906 -7.7161 -v 2.6175 -0.5906 -7.7161 -v -6.5990 -0.5906 -7.7160 -v 1.2411 0.5906 -8.2364 -v 1.2411 0.5906 -7.3210 -v 1.2411 -0.5906 -7.3210 -v 8.1033 0.5906 -8.2364 -v 8.1033 0.5906 -7.3210 -v 8.1033 -0.5906 -7.3210 -v 0.1288 0.5906 -8.1917 -v 0.1807 0.5906 -8.1542 -v 0.1792 -0.5906 -8.1564 -v 0.0511 0.5906 -8.0735 -v 0.0132 0.5906 -8.0995 -v 0.0132 -0.5906 -8.0995 -v 11.7746 0.5906 -7.3210 -v 11.7746 0.5906 -8.2364 -v 11.7746 -0.5906 -8.2364 -v 4.5226 0.5906 -7.3210 -v 4.5226 0.5906 -8.2364 -v 4.5226 -0.5906 -8.2364 -v 7.3612 0.5906 -7.3210 -v 7.3619 0.5906 -7.9330 -v 7.3616 -0.5906 -7.9325 -v -5.6742 0.5906 -8.2364 -v 1.2411 -0.5906 -8.2364 -v 1.0848 -0.5906 -7.8636 -v 1.0856 -0.5906 -7.3210 -v 1.0856 0.5906 -7.3210 -v 8.1033 -0.5906 -8.2364 -v 7.9470 -0.5906 -7.8636 -v 7.9478 -0.5906 -7.3210 -v 7.9478 0.5906 -7.3210 -v 0.4990 0.5906 -7.3210 -v 0.4997 0.5906 -7.9330 -v 0.4993 -0.5906 -7.9325 -v -4.9321 0.5906 -8.2364 -v -4.9327 0.5906 -7.6198 -v -4.9332 -0.5906 -7.5962 -v 9.3407 -0.5906 -7.3008 -v 9.5201 -0.5906 -7.8524 -v -9.4009 -0.5906 -7.5969 -v -9.5806 -0.5906 -7.3008 -v -2.2646 -0.5906 -8.2364 -v -2.5679 -0.5906 -7.7681 -v -2.5679 0.5906 -7.7681 -v -2.0738 -0.5906 -8.2364 -v -1.0677 0.5906 -7.9149 -v -1.2816 0.5906 -7.3210 -v -1.2816 -0.5906 -7.3210 -v -4.2385 0.5906 -7.4411 -v -4.1835 0.5906 -7.4666 -v -4.1855 -0.5906 -7.4642 -v -4.5778 0.5906 -7.6911 -v -10.8533 0.5906 -7.6911 -v -10.5141 0.5906 -7.4411 -v -10.4591 0.5906 -7.4666 -v -10.4611 -0.5906 -7.4642 -v -7.6716 0.5906 -7.4411 -v -7.6166 0.5906 -7.4666 -v -7.6186 -0.5906 -7.4642 -v -8.0108 0.5906 -7.6911 -v 5.2639 0.5906 -7.6192 -v 12.5159 0.5906 -7.6192 -v -8.7566 0.5906 -7.3042 -v -9.0167 -0.5906 -7.6782 -v -9.0390 -0.5906 -7.6181 -v -9.0231 0.5906 -7.6629 -v -3.2203 0.5906 -8.0935 -v -3.2613 0.5906 -8.1139 -v -3.2589 -0.5906 -8.1137 -v -6.0628 0.5906 -8.0935 -v -6.1038 0.5906 -8.1139 -v -6.1014 -0.5906 -8.1137 -v 3.1537 0.5906 -8.0935 -v 3.1127 0.5906 -8.1139 -v 3.1151 -0.5906 -8.1137 -v 0.6545 -0.5906 -7.3210 -v 0.6550 -0.5906 -7.8896 -v 0.6552 0.5906 -7.8742 -v 0.4990 -0.5906 -7.3210 -v 7.5167 -0.5906 -7.3210 -v 7.5172 -0.5906 -7.8896 -v 7.5174 0.5906 -7.8742 -v 7.3612 -0.5906 -7.3210 -v 8.8826 -0.5906 -7.9449 -v 8.9019 -0.5906 -7.8865 -v 8.8868 0.5906 -7.9304 -v 9.2121 -0.5906 -7.8439 -v -9.7091 -0.5906 -7.8439 -v -10.0386 -0.5906 -7.9450 -v -10.0194 -0.5906 -7.8865 -v -10.0345 0.5906 -7.9304 -v -11.3652 -0.5906 -8.2364 -v -11.3652 -0.5906 -6.9746 -v -11.3652 0.5906 -6.9746 -v -11.2096 -0.5906 -6.9746 -v -11.2096 -0.5906 -8.2364 -v -11.2096 0.5906 -8.2364 -v -11.2096 0.5906 -6.9746 -v -11.3652 0.5906 -8.2364 -v 6.8829 0.5906 -8.0572 -v 6.8472 0.5906 -8.0815 -v 6.8472 -0.5906 -8.0815 -v 3.2642 -0.5906 -7.3687 -v 3.3151 -0.5906 -7.4154 -v 3.2881 0.5906 -7.3893 -v 2.9188 -0.5906 -7.4566 -v 2.8793 -0.5906 -7.4820 -v 2.8815 0.5906 -7.4814 -v -3.1098 -0.5906 -7.3687 -v -3.0590 -0.5906 -7.4154 -v -3.0859 0.5906 -7.3893 -v -3.4552 -0.5906 -7.4566 -v -3.4947 -0.5906 -7.4820 -v -3.4925 0.5906 -7.4814 -v -5.9523 -0.5906 -7.3687 -v -5.9015 -0.5906 -7.4154 -v -5.9041 0.5906 -7.4137 -v -6.2978 -0.5906 -7.4566 -v -6.3372 -0.5906 -7.4820 -v -6.3350 0.5906 -7.4814 -v 5.5399 -0.5906 -7.4411 -v 5.6954 -0.5906 -8.2364 -v -8.3135 -0.5906 -7.9148 -v -5.0876 0.5906 -8.2364 -v 6.5897 0.5906 -7.4816 -v 6.6250 0.5906 -7.4567 -v 6.6352 -0.5906 -7.4509 -v 7.5167 0.5906 -7.3210 -v -4.9321 -0.5906 -8.2364 -v 4.6787 -0.5906 -7.7025 -v 4.6782 -0.5906 -8.2364 -v 4.6782 0.5906 -8.2364 -v 4.5226 -0.5906 -7.3210 -v 11.9307 -0.5906 -7.7025 -v 11.9301 -0.5906 -8.2364 -v 11.9301 0.5906 -8.2364 -v 11.7746 -0.5906 -7.3210 -v 0.6545 0.5906 -7.3210 -v 5.1080 0.5906 -7.6426 -v 5.1093 0.5906 -8.2364 -v 5.1093 -0.5906 -8.2364 -v 12.3599 0.5906 -7.6426 -v 12.3612 0.5906 -8.2364 -v 12.3612 -0.5906 -8.2364 -v 6.7646 -0.5906 -8.4764 -v 6.6068 -0.5906 -8.4611 -v 6.6520 -0.5906 -8.4734 -v 6.6275 0.5906 -8.4673 -v -5.9553 0.5906 -7.3676 -v -3.1269 0.5906 -7.3575 -v 3.2471 0.5906 -7.3575 -v -0.7648 0.5906 -7.3210 -v -0.9775 0.5906 -7.9063 -v -0.9856 -0.5906 -7.9282 -v 11.9316 0.5906 -7.6888 -v 4.6796 0.5906 -7.6888 -v -9.3605 -0.5906 -8.2360 -v -9.2172 -0.5906 -8.2001 -v -9.4011 -0.5906 -7.8524 -v -9.1998 -0.5906 -8.2364 -v -9.3593 0.5906 -8.2364 -v -0.7648 -0.5906 -7.3210 -v 9.7198 -0.5906 -8.2360 -v 9.5607 -0.5906 -8.2360 -v 9.5620 0.5906 -8.2364 -v -11.9531 0.5906 -7.7223 -v 9.4365 0.5906 -8.0632 -v 9.4008 0.5906 -8.0890 -v 9.4403 -0.5906 -8.0616 -v -9.4848 0.5906 -8.0632 -v -9.5204 0.5906 -8.0890 -v -9.4810 -0.5906 -8.0616 -v 5.7084 0.5906 -7.1461 -v 5.7273 0.5906 -7.1207 -v 5.7179 -0.5906 -7.1298 -v -5.5187 -0.5906 -6.9746 -v -5.5187 0.5906 -6.9746 -v -5.5187 -0.5906 -7.4274 -v 7.9459 0.5906 -7.8650 -v 1.0837 0.5906 -7.8650 -v -4.5910 0.5906 -7.3949 -v -4.6263 0.5906 -7.4286 -v -4.6409 -0.5906 -7.4441 -v -8.0240 0.5906 -7.3949 -v -8.0594 0.5906 -7.4286 -v -8.0740 -0.5906 -7.4441 -v -10.8665 0.5906 -7.3949 -v -10.9019 0.5906 -7.4286 -v -10.9165 -0.5906 -7.4441 -v -5.5187 0.5906 -8.2364 -v -5.5167 0.5906 -7.6861 -v -5.5178 -0.5906 -7.6878 -v -0.9822 0.5906 -8.3203 -v -1.0614 0.5906 -8.4896 -v -1.1765 0.5906 -8.4114 -v -1.1530 0.5906 -8.3765 -v 10.4026 -0.5906 -8.2364 -v 10.4026 -0.5906 -7.3210 -v 10.4026 0.5906 -7.3210 -v 10.5581 -0.5906 -7.3210 -v 10.5581 -0.5906 -8.2364 -v 10.5581 0.5906 -8.2364 -v 5.9931 0.5906 -7.3210 -v 5.9931 0.5906 -8.2364 -v 5.9931 -0.5906 -8.2364 -v 6.1486 0.5906 -8.2364 -v 6.1486 0.5906 -7.3210 -v 6.1486 -0.5906 -7.3210 -v 10.4026 0.5906 -8.2364 -v 10.5581 0.5906 -7.3210 -v 6.1486 -0.5906 -8.2364 -v 5.9931 -0.5906 -7.3210 -v 10.0059 0.5906 -8.2091 -v 10.0315 0.5906 -8.2250 -v 10.0304 -0.5906 -8.2249 -v 1.9225 0.5906 -7.4932 -v 1.9774 0.5906 -7.3504 -v 1.9774 -0.5906 -7.3504 -v 8.7847 0.5906 -7.4932 -v 8.8396 0.5906 -7.3504 -v 8.8396 -0.5906 -7.3504 -v -8.4721 0.5906 -8.0075 -v -8.4827 0.5906 -8.0377 -v -8.4814 -0.5906 -8.0364 -v 10.2530 -0.5906 -8.0984 -v 10.2726 -0.5906 -8.2345 -v 10.2726 0.5906 -8.2345 -v 12.3603 -0.5906 -7.6317 -v 5.1084 -0.5906 -7.6317 -v -2.6753 -0.5906 -6.9746 -v -2.6753 -0.5906 -7.6914 -v -2.6753 0.5906 -7.6914 -v 9.1412 -0.5906 -8.1216 -v 9.0462 -0.5906 -7.9635 -v -9.7801 -0.5906 -8.1216 -v -9.8750 -0.5906 -7.9635 -v -1.0240 -0.5906 -8.0597 -v -1.3652 -0.5906 -8.5877 -v -1.3829 -0.5906 -8.4431 -v -1.3829 0.5906 -8.4431 -v -1.3652 0.5906 -8.5877 -v 5.7965 -0.5906 -6.9524 -v 5.8839 -0.5906 -6.9592 -v 5.8412 0.5906 -6.9553 -v -11.9690 0.5906 -7.1253 -v -2.6753 0.5906 -6.9746 -v 1.6211 -0.5906 -7.3210 -v 1.6211 0.5906 -7.3210 -v 8.4833 -0.5906 -7.3210 -v 8.4833 0.5906 -7.3210 -v -1.0567 -0.5906 -7.9448 -v 5.0337 0.5906 -7.4674 -v 5.1079 0.5906 -7.6361 -v 5.2641 0.5906 -7.6253 -v 12.3598 0.5906 -7.6361 -v 12.5161 0.5906 -7.6253 -v 12.2856 0.5906 -7.4674 -v 9.6741 0.5906 -7.6180 -v 9.5148 0.5906 -7.5550 -v 9.5022 0.5906 -7.5169 -v 9.6635 0.5906 -7.4936 -v -9.2472 0.5906 -7.6180 -v -9.4065 0.5906 -7.5550 -v -9.4191 0.5906 -7.5169 -v -9.2578 0.5906 -7.4936 -v -8.8831 -0.5906 -7.5907 -v -5.2201 -0.5906 -7.4414 -v -4.5117 0.5906 -8.2158 -v -4.4662 0.5906 -8.2334 -v -4.4479 -0.5906 -8.2395 -v -7.9447 0.5906 -8.2158 -v -7.8993 0.5906 -8.2334 -v -7.8810 -0.5906 -8.2395 -v -10.7873 0.5906 -8.2158 -v -10.7418 0.5906 -8.2334 -v -10.7235 -0.5906 -8.2395 -v 11.3999 0.5906 -7.3643 -v 11.3587 0.5906 -7.3416 -v 11.3416 -0.5906 -7.3334 -v 4.1479 0.5906 -7.3643 -v 4.1067 0.5906 -7.3416 -v 4.0896 -0.5906 -7.3333 -v 0.1283 0.5906 -7.3643 -v 0.0871 0.5906 -7.3416 -v 0.0699 -0.5906 -7.3334 -v 1.9225 -0.5906 -7.4932 -v 1.6211 -0.5906 -7.4599 -v 1.6701 -0.5906 -7.5543 -v 8.7847 -0.5906 -7.4932 -v 8.4833 -0.5906 -7.4599 -v 8.5323 -0.5906 -7.5543 -v 6.4527 -0.5906 -7.4088 -v 6.4992 -0.5906 -7.3685 -v 6.4973 0.5906 -7.3707 -v -0.4161 -0.5906 -8.1331 -v 10.8555 -0.5906 -8.1331 -v 3.6036 -0.5906 -8.1331 -v 10.7384 0.5906 -7.8106 -v 3.4864 0.5906 -7.8106 -v -0.5332 0.5906 -7.8106 -v 0.9335 0.5906 -8.1053 -v 0.9544 0.5906 -8.2275 -v 1.1014 0.5906 -8.1007 -v 7.9636 0.5906 -8.1007 -v 7.7957 0.5906 -8.1053 -v 7.8166 0.5906 -8.2275 -v -11.7261 0.5906 -7.3604 -v -11.5561 0.5906 -7.3006 -v -11.9828 0.5906 -6.9755 -v -11.9753 0.5906 -7.1250 -v -8.4696 -0.5906 -7.9743 -v -8.5624 -0.5906 -8.1094 -v -9.0567 -0.5906 -8.0197 -v -9.0699 -0.5906 -7.9627 -v -9.0699 0.5906 -7.9627 -v -8.7112 -0.5906 -8.2557 -v 7.5175 0.5906 -7.8825 -v 0.6553 0.5906 -7.8825 -v 7.5963 -0.5906 -8.0942 -v 0.7341 -0.5906 -8.0942 -v -4.7314 -0.5906 -7.9300 -v -4.5375 -0.5906 -8.2034 -v -4.6141 -0.5906 -8.1472 -v -4.5924 0.5906 -8.1654 -v -11.0070 -0.5906 -7.9300 -v -10.8131 -0.5906 -8.2034 -v -10.8896 -0.5906 -8.1472 -v -10.8679 0.5906 -8.1654 -v -7.9705 -0.5906 -8.2034 -v -8.0471 -0.5906 -8.1472 -v -8.0254 0.5906 -8.1654 -v -8.1645 -0.5906 -7.9300 -v 6.9329 0.5906 -8.3837 -v 6.9070 0.5906 -8.4153 -v 6.9087 -0.5906 -8.4143 -v -2.2646 0.5906 -8.2364 -v -9.0051 0.5906 -7.6950 -v -11.5639 0.5906 -7.2501 -v -3.6680 0.5906 -7.4513 -v -3.5358 0.5906 -7.5259 -v -3.5620 0.5906 -7.5688 -v -6.5105 0.5906 -7.4513 -v -6.3784 0.5906 -7.5259 -v -6.4045 0.5906 -7.5688 -v 2.7061 0.5906 -7.4513 -v 2.8382 0.5906 -7.5259 -v 2.8120 0.5906 -7.5688 -v 5.5467 0.5906 -7.1258 -v -2.6753 0.5906 -7.8728 -v -8.4951 0.5906 -7.5769 -v -8.3435 0.5906 -7.5572 -v -8.3435 -0.5906 -7.5572 -v 11.2491 -0.5906 -7.3073 -v 3.9971 -0.5906 -7.3073 -v -0.0226 -0.5906 -7.3073 -v 7.0924 0.5906 -8.4000 -v 6.9721 0.5906 -8.2412 -v 6.9746 0.5906 -8.1163 -v 7.1292 0.5906 -8.1699 -v -10.1833 0.5906 -7.9608 -v -10.3433 0.5906 -7.9411 -v -10.3433 -0.5906 -7.9411 -v 6.7400 -0.5906 -8.2364 -v 6.9746 -0.5906 -8.1163 -v 6.9254 -0.5906 -8.1656 -v 6.9284 0.5906 -8.1616 -v -5.0886 0.5906 -7.6253 -v -4.9345 0.5906 -7.5946 -v -9.9394 0.5906 -7.4175 -v -9.9656 0.5906 -7.4533 -v -9.9511 -0.5906 -7.4297 -v 8.9818 0.5906 -7.4175 -v 8.9557 0.5906 -7.4533 -v 8.9701 -0.5906 -7.4297 -v -9.3909 -0.5906 -8.1243 -v -9.6663 -0.5906 -8.2533 -v 9.5303 -0.5906 -8.1243 -v 9.2550 -0.5906 -8.2533 -v -8.4951 -0.5906 -7.5769 -v 9.5204 -0.5906 -7.5969 -v 9.5196 -0.5906 -7.6569 -v 9.5202 0.5906 -7.6023 -v -9.4016 -0.5906 -7.6569 -v -9.4010 0.5906 -7.6023 -v 6.6041 -0.5906 -8.5965 -v 6.4127 -0.5906 -8.4957 -v 6.3775 -0.5906 -8.4386 -v 6.3795 0.5906 -8.4402 -v 0.9721 -0.5906 -8.2199 -v 1.1014 -0.5906 -8.1007 -v 1.0486 -0.5906 -8.1647 -v 1.0693 0.5906 -8.1419 -v 7.8343 -0.5906 -8.2199 -v 7.9636 -0.5906 -8.1007 -v 7.9108 -0.5906 -8.1647 -v 7.9315 0.5906 -8.1419 -v 5.5504 0.5906 -7.1101 -v 5.7103 0.5906 -7.1437 -v 5.6957 0.5906 -7.1998 -v -10.7075 -0.5906 -7.4531 -v -7.8649 -0.5906 -7.4531 -v -4.4319 -0.5906 -7.4531 -v -5.5187 0.5906 -7.4274 -v 9.6128 0.5906 -7.3923 -v 9.5737 0.5906 -7.3600 -v 9.5845 -0.5906 -7.3666 -v -5.9199 0.5906 -8.1539 -v -5.8814 0.5906 -8.1109 -v -5.8814 -0.5906 -8.1109 -v -3.0774 0.5906 -8.1539 -v -3.0389 0.5906 -8.1109 -v -3.0389 -0.5906 -8.1109 -v 3.2966 0.5906 -8.1539 -v 3.3351 0.5906 -8.1109 -v 3.3351 -0.5906 -8.1109 -v -8.6363 0.5906 -7.4345 -v -8.6333 0.5906 -7.3054 -v -8.5791 0.5906 -7.3143 -v 10.0955 0.5906 -7.3210 -v 10.0955 0.5906 -7.0019 -v 10.0955 -0.5906 -7.0019 -v 10.2530 0.5906 -8.0977 -v -9.9759 0.5906 -7.8221 -v -9.9974 0.5906 -7.8493 -v -9.9859 -0.5906 -7.8325 -v 8.9454 0.5906 -7.8221 -v 8.9239 0.5906 -7.8493 -v 8.9354 -0.5906 -7.8325 -v 10.0955 -0.5906 -7.3210 -v 6.5061 0.5906 -8.3309 -v 6.3565 0.5906 -8.3112 -v 6.3565 -0.5906 -8.3112 -v 8.6963 0.5906 -7.4624 -v 8.6652 0.5906 -7.4611 -v 8.6919 0.5906 -7.3018 -v 1.8341 0.5906 -7.4624 -v 1.8030 0.5906 -7.4611 -v 1.8297 0.5906 -7.3018 -v -1.1787 0.5906 -8.5916 -v -1.1456 0.5906 -8.5756 -v -1.1326 -0.5906 -8.5685 -v -9.3084 0.5906 -7.3923 -v -9.3475 0.5906 -7.3600 -v -9.3368 -0.5906 -7.3666 -v -8.8926 0.5906 -7.5304 -v -8.8925 0.5906 -7.5652 -v -9.0439 0.5906 -7.5742 -v -8.8241 0.5906 -7.6381 -v -8.8768 0.5906 -7.7883 -v -8.9195 0.5906 -7.7695 -v 9.9414 0.5906 -8.0304 -v 10.0961 0.5906 -8.0071 -v -5.9577 -0.5906 -7.9017 -v -5.8061 -0.5906 -7.9214 -v -5.8061 0.5906 -7.9214 -v -3.1152 -0.5906 -7.9017 -v -2.9636 -0.5906 -7.9214 -v -2.9636 0.5906 -7.9214 -v 3.2589 -0.5906 -7.9017 -v 3.4104 -0.5906 -7.9214 -v 3.4104 0.5906 -7.9214 -v 4.1157 0.5906 -8.0270 -v -4.5106 0.5906 -8.0364 -v -4.5386 0.5906 -7.9973 -v -4.5386 -0.5906 -7.9973 -v -7.9436 0.5906 -8.0364 -v -7.9717 0.5906 -7.9973 -v -7.9717 -0.5906 -7.9973 -v -0.0255 -0.5906 -8.1164 -v 11.2461 -0.5906 -8.1164 -v 3.9941 -0.5906 -8.1164 -v 11.2430 0.5906 -8.1165 -v 11.2161 0.5906 -8.2532 -v -3.1826 -0.5906 -7.4959 -v -2.9774 -0.5906 -7.5946 -v -3.1270 -0.5906 -7.6143 -v -3.1270 0.5906 -7.6143 -v -6.0251 -0.5906 -7.4959 -v -5.8199 -0.5906 -7.5946 -v -5.9695 -0.5906 -7.6143 -v -5.9695 0.5906 -7.6143 -v 3.1914 -0.5906 -7.4959 -v 3.3967 -0.5906 -7.5946 -v 3.2470 -0.5906 -7.6143 -v 3.2470 0.5906 -7.6143 -v -4.0677 -0.5906 -7.9411 -v -3.9077 -0.5906 -7.9608 -v -3.9077 0.5906 -7.9608 -v -10.5033 -0.5906 -8.1165 -v -10.1833 -0.5906 -7.9608 -v -7.5007 -0.5906 -7.9411 -v -7.3408 -0.5906 -7.9608 -v -7.3408 0.5906 -7.9608 -v 9.0644 -0.5906 -7.9175 -v 9.0538 0.5906 -7.9416 -v -9.8569 -0.5906 -7.9175 -v -9.8675 0.5906 -7.9416 -v -8.9163 0.5906 -7.9391 -v -0.3711 0.5906 -7.7076 -v 3.6486 0.5906 -7.7076 -v 10.9006 0.5906 -7.7076 -v 11.4302 0.5906 -7.8454 -v 4.1782 0.5906 -7.8454 -v 0.1585 0.5906 -7.8454 -v -9.7218 -0.5906 -7.4394 -v -9.8632 -0.5906 -7.6025 -v -10.0148 -0.5906 -7.5828 -v -10.0148 0.5906 -7.5828 -v 9.0581 -0.5906 -7.6025 -v 8.9065 -0.5906 -7.5828 -v 8.9065 0.5906 -7.5828 -v 9.1995 -0.5906 -7.4394 -v 5.0636 0.5906 -7.4935 -v 12.3156 0.5906 -7.4935 -v -9.1998 0.5906 -8.2364 -v 9.7215 0.5906 -8.2364 -v 11.1391 0.5906 -8.2548 -v 11.2136 -0.5906 -8.2540 -v 3.8872 0.5906 -8.2548 -v 3.9641 0.5906 -8.2532 -v 3.9617 -0.5906 -8.2540 -v -8.3121 0.5906 -7.9941 -v -8.4395 0.5906 -7.7573 -v -8.4060 0.5906 -7.7764 -v -8.5201 0.5906 -7.8979 -v 6.5879 -0.5906 -7.4821 -v 1.7958 0.5906 -7.3029 -v 1.7828 -0.5906 -7.3041 -v 8.6580 0.5906 -7.3029 -v 8.6450 -0.5906 -7.3041 -v -0.1867 -0.5906 -7.4408 -v 11.0849 -0.5906 -7.4408 -v 3.8329 -0.5906 -7.4408 -v -0.1325 0.5906 -8.2548 -v -0.0555 0.5906 -8.2532 -v -0.0580 -0.5906 -8.2540 -v 7.0096 0.5906 -8.5129 -v 7.0401 0.5906 -8.4835 -v 7.0292 -0.5906 -8.4956 -v 9.0692 0.5906 -7.9123 -v -9.8521 0.5906 -7.9123 -v -6.4232 0.5906 -7.6216 -v -6.4045 -0.5906 -7.5688 -v 2.7933 0.5906 -7.6216 -v 2.8120 -0.5906 -7.5688 -v -3.5807 0.5906 -7.6216 -v -3.5620 -0.5906 -7.5688 -v -4.0677 0.5906 -7.9411 -v -7.5007 0.5906 -7.9411 -v -8.8937 0.5906 -7.5334 -v -8.8830 0.5906 -7.5026 -v -8.8786 -0.5906 -7.4931 -v 4.2378 0.5906 -7.4434 -v 4.2915 0.5906 -7.5254 -v -10.3937 0.5906 -7.5273 -v -10.4343 0.5906 -7.4848 -v -10.3475 0.5906 -7.3791 -v -7.5512 0.5906 -7.5273 -v -7.5918 0.5906 -7.4848 -v -7.5050 0.5906 -7.3791 -v -4.1181 0.5906 -7.5273 -v -4.1587 0.5906 -7.4848 -v -4.0719 0.5906 -7.3791 -v 0.3206 0.5906 -7.7357 -v 0.1522 0.5906 -7.6630 -v 0.2181 0.5906 -7.4434 -v 0.2718 0.5906 -7.5254 -v 6.3387 0.5906 -7.9027 -v 1.6942 0.5906 -7.5164 -v 1.7256 0.5906 -7.4873 -v 1.7179 -0.5906 -7.4923 -v 8.5564 0.5906 -7.5164 -v 8.5878 0.5906 -7.4873 -v 8.5801 -0.5906 -7.4923 -v 6.5908 -0.5906 -8.0596 -v 8.6290 0.5906 -7.3092 -v 1.7668 0.5906 -7.3092 -v 0.7073 0.5906 -8.0711 -v 0.6870 0.5906 -8.0458 -v 0.6922 -0.5906 -8.0547 -v 7.6765 0.5906 -8.1204 -v 7.7244 0.5906 -8.2529 -v 7.6565 0.5906 -8.2553 -v 0.8143 0.5906 -8.1204 -v 0.8622 0.5906 -8.2529 -v 0.7943 0.5906 -8.2553 -v 5.9137 0.5906 -7.1032 -v 5.9369 0.5906 -6.9684 -v 5.9369 -0.5906 -6.9684 -v 4.7497 0.5906 -7.4981 -v 4.7307 0.5906 -7.5183 -v 4.6624 0.5906 -7.4509 -v 12.0017 0.5906 -7.4981 -v 11.9827 0.5906 -7.5183 -v 11.9144 0.5906 -7.4509 -v -3.5140 -0.5906 -7.3342 -v -6.3566 -0.5906 -7.3342 -v 2.8600 -0.5906 -7.3342 -v 7.8581 0.5906 -8.2053 -v 7.8964 0.5906 -8.1768 -v 0.9959 0.5906 -8.2053 -v 1.0342 0.5906 -8.1768 -v -2.3095 -0.5906 -7.3210 -v -2.3095 0.5906 -7.3210 -v -2.1093 -0.5906 -7.3210 -v 12.3888 -0.5906 -7.3460 -v 5.1368 -0.5906 -7.3460 -v 3.3967 0.5906 -7.5946 -v -2.9774 0.5906 -7.5946 -v 11.9791 0.5906 -7.3776 -v 4.7272 0.5906 -7.3776 -v -9.4066 -0.5906 -7.5517 -v 9.5146 -0.5906 -7.5517 -v 5.8071 -0.5906 -7.0942 -v 5.9134 -0.5906 -7.1020 -v -5.5187 -0.5906 -8.2364 -v 6.5338 0.5906 -8.5757 -v 6.4686 0.5906 -8.5426 -v 6.5530 0.5906 -8.4295 -v 2.6733 0.5906 -8.0548 -v 2.6988 0.5906 -8.0963 -v 2.7098 -0.5906 -8.1120 -v -6.5433 0.5906 -8.0548 -v -6.5177 0.5906 -8.0963 -v -6.5068 -0.5906 -8.1120 -v -3.7007 0.5906 -8.0548 -v -3.6752 0.5906 -8.0963 -v -3.6642 -0.5906 -8.1120 -v -8.5235 0.5906 -8.2328 -v -9.8632 0.5906 -7.6025 -v 9.0581 0.5906 -7.6025 -v 6.3683 0.5906 -7.9960 -v 7.6096 0.5906 -8.1005 -v 7.5817 0.5906 -8.0821 -v -8.0431 0.5906 -8.1490 -v -7.8986 0.5906 -8.0785 -v -8.1770 0.5906 -7.8173 -v -4.6100 0.5906 -8.1490 -v -4.4655 0.5906 -8.0785 -v -4.7439 0.5906 -7.8173 -v -10.8856 0.5906 -8.1490 -v -10.7862 0.5906 -8.0364 -v -10.7411 0.5906 -8.0785 -v -11.0195 0.5906 -7.8173 -v -8.6338 0.5906 -8.2541 -v -8.7034 0.5906 -8.2553 -v -8.3382 0.5906 -8.0830 -v -5.8199 0.5906 -7.5946 -v -7.9879 -0.5906 -7.5856 -v -7.9602 -0.5906 -7.5351 -v -7.9864 0.5906 -7.5840 -v -10.8027 -0.5906 -7.5351 -v -10.8304 -0.5906 -7.5856 -v -10.8289 0.5906 -7.5840 -v -4.5271 -0.5906 -7.5351 -v -4.5549 -0.5906 -7.5856 -v -4.5534 0.5906 -7.5840 -v -8.4714 -0.5906 -8.0063 -v -8.4699 0.5906 -7.9760 -v 9.3708 0.5906 -7.8173 -v -9.5505 0.5906 -7.8173 -v -11.6187 -0.5906 -7.5659 -v -11.7522 -0.5906 -7.4639 -v -6.0161 0.5906 -7.3333 -v -6.0704 0.5906 -7.4582 -v -6.1063 0.5906 -7.4411 -v -3.1735 0.5906 -7.3333 -v -3.2279 0.5906 -7.4582 -v -3.2638 0.5906 -7.4411 -v 3.2005 0.5906 -7.3333 -v 3.1461 0.5906 -7.4582 -v 3.1102 0.5906 -7.4411 -v -4.4154 0.5906 -7.4475 -v -4.3612 0.5906 -7.4329 -v -4.3645 -0.5906 -7.4327 -v -7.8485 0.5906 -7.4475 -v -7.7943 0.5906 -7.4329 -v -7.7976 -0.5906 -7.4327 -v -10.6910 0.5906 -7.4475 -v -10.6368 0.5906 -7.4329 -v -10.6401 -0.5906 -7.4327 -v -11.9789 0.5906 -7.5737 -v -8.6832 0.5906 -7.4297 -v -8.8661 0.5906 -7.4801 -v -8.9931 0.5906 -7.4170 -v -8.9470 0.5906 -7.3710 -v -5.2890 -0.5906 -7.4344 -v -5.2662 0.5906 -7.4357 -v -11.8318 0.5906 -7.1515 -v -11.7640 0.5906 -7.0093 -v -11.7219 0.5906 -7.0285 -v 6.6915 0.5906 -8.1042 -v 6.6372 0.5906 -8.0873 -v 6.6391 -0.5906 -8.0892 -v -1.2074 0.5906 -8.4367 -v -5.0232 0.5906 -7.3740 -v -5.0606 0.5906 -7.3474 -v -5.0582 -0.5906 -7.3483 -v -5.1787 0.5906 -7.4573 -v -5.1451 0.5906 -7.4811 -v -5.1456 -0.5906 -7.4797 -v -9.5905 0.5906 -8.2372 -v -9.6290 0.5906 -8.1288 -v -9.5831 0.5906 -8.1176 -v -9.2278 0.5906 -8.1661 -v 9.3308 0.5906 -8.2372 -v 9.2922 0.5906 -8.1288 -v 9.3382 0.5906 -8.1176 -v 9.6934 0.5906 -8.1661 -v -10.5056 0.5906 -8.1167 -v -10.2028 0.5906 -8.0177 -v -10.2376 0.5906 -8.0851 -v -10.3597 0.5906 -7.9803 -v -7.3603 0.5906 -8.0177 -v -7.3951 0.5906 -8.0851 -v -7.5172 0.5906 -7.9803 -v -3.9272 0.5906 -8.0177 -v -3.9621 0.5906 -8.0851 -v -4.0841 0.5906 -7.9803 -v -8.5015 0.5906 -7.5487 -v -8.3643 0.5906 -7.4779 -v -9.9485 0.5906 -8.1923 -v -9.8545 0.5906 -8.0641 -v 8.9728 0.5906 -8.1923 -v 9.0668 0.5906 -8.0641 -v -11.5552 0.5906 -7.3626 -v -11.5677 0.5906 -7.4487 -v -10.4661 0.5906 -8.1003 -v 5.8726 0.5906 -7.3210 -v -9.0429 0.5906 -7.5390 -v -5.0114 0.5906 -7.3856 -v -5.2191 0.5906 -7.4422 -v -5.2693 0.5906 -7.3026 -v 9.9400 0.5906 -7.0948 -v 9.9400 0.5906 -7.3210 -v 9.9400 -0.5906 -7.3210 -v -7.8965 -0.5906 -8.0811 -v -7.7793 -0.5906 -8.2555 -v -4.4634 -0.5906 -8.0811 -v -4.3462 -0.5906 -8.2555 -v -10.7390 -0.5906 -8.0811 -v -10.6218 -0.5906 -8.2555 -v -6.0383 0.5906 -7.4829 -v 3.2612 0.5906 -7.3676 -v 3.3124 0.5906 -7.4137 -v 3.1782 0.5906 -7.4829 -v -3.1128 0.5906 -7.3676 -v -3.0616 0.5906 -7.4137 -v -3.1958 0.5906 -7.4829 -v 9.9400 -0.5906 -7.0948 -v 6.9236 0.5906 -7.3686 -v -6.0038 0.5906 -8.0360 -v -3.1613 0.5906 -8.0360 -v 3.2127 0.5906 -8.0360 -v -9.4898 -0.5906 -8.1948 -v -9.4742 0.5906 -8.1846 -v 9.4314 -0.5906 -8.1948 -v 9.4470 0.5906 -8.1846 -v 8.8798 0.5906 -8.0105 -v 8.8805 0.5906 -7.9664 -v 9.0448 0.5906 -7.9987 -v 8.9297 0.5906 -8.1489 -v -10.0415 0.5906 -8.0105 -v -10.0408 0.5906 -7.9664 -v -9.8765 0.5906 -7.9987 -v -9.9916 0.5906 -8.1489 -v -8.4304 0.5906 -7.3811 -v -8.4648 0.5906 -7.3572 -v -8.4792 -0.5906 -7.3480 -v -5.9577 0.5906 -7.9017 -v -3.1152 0.5906 -7.9017 -v 3.2589 0.5906 -7.9017 -v -8.8168 0.5906 -8.0978 -v -8.9364 0.5906 -8.1919 -v -8.9872 0.5906 -8.1467 -v -8.8674 0.5906 -8.0563 -v -1.2988 0.5906 -8.6036 -v -1.3232 0.5906 -8.4547 -v -1.2735 0.5906 -8.4556 -v 4.7641 -0.5906 -7.4849 -v 4.7307 -0.5906 -7.5183 -v 4.7402 0.5906 -7.5082 -v 12.0161 -0.5906 -7.4849 -v 11.9827 -0.5906 -7.5183 -v 11.9922 0.5906 -7.5082 -v 11.5923 0.5906 -7.7357 -v 11.4238 0.5906 -7.6630 -v 11.5800 0.5906 -7.9229 -v 4.3280 0.5906 -7.9229 -v 4.3403 0.5906 -7.7357 -v 4.1719 0.5906 -7.6630 -v -9.8510 0.5906 -7.5640 -v -10.0045 0.5906 -7.5430 -v -9.9872 0.5906 -7.4951 -v 9.0703 0.5906 -7.5640 -v 8.9167 0.5906 -7.5430 -v 8.9340 0.5906 -7.4951 -v 9.5223 -0.5906 -7.3327 -v 9.4820 -0.5906 -7.4867 -v -9.7855 0.5906 -7.4674 -v -9.8066 0.5906 -7.4868 -v -9.8679 0.5906 -7.3603 -v -9.8219 0.5906 -7.3385 -v 9.1358 0.5906 -7.4674 -v 9.0533 0.5906 -7.3603 -v 9.0994 0.5906 -7.3385 -v 9.1146 0.5906 -7.4868 -v -6.1641 0.5906 -7.3021 -v -6.2345 0.5906 -7.3042 -v -6.2320 -0.5906 -7.3034 -v 6.8310 0.5906 -7.4510 -v -1.2262 0.5906 -8.4458 -v -1.2445 -0.5906 -8.4524 -v 1.8319 -0.5906 -7.3015 -v 1.7864 -0.5906 -7.4618 -v 8.6941 -0.5906 -7.3015 -v 8.6486 -0.5906 -7.4618 -v -8.1721 0.5906 -7.6929 -v -8.1479 0.5906 -7.5823 -v -8.0042 0.5906 -7.6424 -v -11.0146 0.5906 -7.6929 -v -10.9904 0.5906 -7.5823 -v -10.8467 0.5906 -7.6424 -v -4.7390 0.5906 -7.6929 -v -4.7148 0.5906 -7.5823 -v -4.5711 0.5906 -7.6424 -v 4.7818 0.5906 -7.4743 -v 12.0337 0.5906 -7.4743 -v -7.5332 0.5906 -7.5561 -v -7.4364 0.5906 -7.4451 -v -7.3949 0.5906 -7.5059 -v -4.1001 0.5906 -7.5561 -v -4.0033 0.5906 -7.4451 -v -3.9618 0.5906 -7.5059 -v -10.3757 0.5906 -7.5561 -v -10.2789 0.5906 -7.4451 -v -10.2374 0.5906 -7.5059 -v -9.9089 0.5906 -7.7694 -v -9.8613 0.5906 -7.7470 -v -9.8197 0.5906 -7.8814 -v -9.9478 0.5906 -7.7960 -v -9.8468 0.5906 -7.9058 -v 8.9734 0.5906 -7.7960 -v 9.1016 0.5906 -7.8814 -v 9.0744 0.5906 -7.9058 -v 9.0124 0.5906 -7.7694 -v 9.0600 0.5906 -7.7470 -v 2.9538 0.5906 -8.1171 -v 2.9135 0.5906 -8.1009 -v 2.9135 -0.5906 -8.1009 -v -6.2627 0.5906 -8.1171 -v -6.3031 0.5906 -8.1009 -v -6.3031 -0.5906 -8.1009 -v -3.4202 0.5906 -8.1171 -v -3.4605 0.5906 -8.1009 -v -3.4605 -0.5906 -8.1009 -v -9.4079 0.5906 -7.9233 -v -9.4075 -0.5906 -7.9228 -v 9.5134 0.5906 -7.9233 -v 9.5138 -0.5906 -7.9228 -v -9.3989 -0.5906 -7.3327 -v -9.4393 -0.5906 -7.4867 -v 3.4924 0.5906 -7.6767 -v 3.6642 0.5906 -7.6255 -v -0.5272 0.5906 -7.6767 -v -0.3555 0.5906 -7.6255 -v 5.7491 0.5906 -7.1072 -v 5.7783 0.5906 -6.9533 -v 5.8128 0.5906 -7.0949 -v 5.7776 0.5906 -7.0986 -v 6.5061 -0.5906 -8.3309 -v 6.5289 -0.5906 -8.4023 -v -10.2161 0.5906 -7.5520 -v -10.2374 -0.5906 -7.5059 -v -3.9405 0.5906 -7.5520 -v -3.9618 -0.5906 -7.5059 -v -7.3736 0.5906 -7.5520 -v -7.3949 -0.5906 -7.5059 -v 0.2759 0.5906 -8.0280 -v 0.2438 0.5906 -8.0842 -v 0.1234 0.5906 -7.9828 -v 0.0960 0.5906 -8.0270 -v -11.7677 0.5906 -7.4864 -v -11.8041 0.5906 -7.5227 -v -11.7828 -0.5906 -7.5053 -v 1.1014 -0.5906 -8.2364 -v 7.9636 -0.5906 -8.2364 -v 6.8079 0.5906 -8.0975 -v 6.8781 0.5906 -8.1972 -v 6.8227 0.5906 -8.2204 -v 10.7444 0.5906 -7.6767 -v 10.8974 0.5906 -7.7541 -v 10.7529 0.5906 -7.9296 -v 10.9006 0.5906 -7.8489 -v 10.9162 0.5906 -7.9311 -v -0.2332 0.5906 -8.2397 -v -0.4161 0.5906 -8.1331 -v -0.2119 0.5906 -8.1058 -v -0.1536 0.5906 -8.1237 -v 3.6036 0.5906 -8.1331 -v 3.8078 0.5906 -8.1058 -v 3.8661 0.5906 -8.1237 -v 3.7865 0.5906 -8.2397 -v -1.2067 -0.5906 -8.4374 -v -1.1979 -0.5906 -8.5990 -v 6.6948 0.5906 -8.6057 -v 6.6510 0.5906 -8.4727 -v 6.7031 0.5906 -8.4780 -v 6.8439 0.5906 -8.5933 -v 6.7742 0.5906 -8.6038 -v 6.7608 0.5906 -8.4763 -v 6.8294 0.5906 -7.3188 -v -7.9658 0.5906 -8.2044 -v -7.7705 0.5906 -8.2548 -v -7.7580 0.5906 -8.1273 -v -4.3374 0.5906 -8.2548 -v -4.3250 0.5906 -8.1273 -v -4.5327 0.5906 -8.2044 -v -10.8083 0.5906 -8.2044 -v -10.6130 0.5906 -8.2548 -v -10.6006 0.5906 -8.1273 -v 1.8326 -0.5906 -7.4619 -v 8.6948 -0.5906 -7.4619 -v -2.1093 0.5906 -7.3210 -v 10.2239 -0.5906 -8.2433 -v 10.1553 -0.5906 -8.2486 -v 10.1945 0.5906 -8.2461 -v 10.1865 -0.5906 -8.1047 -v -9.8267 0.5906 -8.2463 -v 9.0946 0.5906 -8.2463 -v 11.1181 0.5906 -7.4337 -v 11.0598 0.5906 -7.4514 -v 6.3894 0.5906 -8.0393 -v 6.4285 0.5906 -8.1003 -v 6.4127 -0.5906 -8.0795 -v -0.1536 0.5906 -7.4337 -v -0.0286 0.5906 -7.3076 -v -0.0291 0.5906 -7.4409 -v -0.0899 0.5906 -7.4302 -v 3.8661 0.5906 -7.4337 -v 3.9911 0.5906 -7.3076 -v 3.9905 0.5906 -7.4409 -v 3.9298 0.5906 -7.4302 -v -4.0683 -0.5906 -7.3801 -v -7.5014 -0.5906 -7.3801 -v -10.3439 -0.5906 -7.3801 -v 10.8555 0.5906 -8.1331 -v 11.0385 0.5906 -8.2397 -v -8.9272 -0.5906 -7.3562 -v -8.9224 0.5906 -7.3542 -v 6.4118 0.5906 -7.4602 -v 6.3795 0.5906 -7.5172 -v 6.3810 -0.5906 -7.5129 -v 11.4943 -0.5906 -7.4465 -v 11.4229 -0.5906 -7.3793 -v 11.4739 0.5906 -7.4248 -v 4.2423 -0.5906 -7.4465 -v 4.1709 -0.5906 -7.3793 -v 4.2219 0.5906 -7.4248 -v 0.1513 -0.5906 -7.3792 -v 0.2226 -0.5906 -7.4465 -v 0.2022 0.5906 -7.4248 -v -3.3216 0.5906 -7.3021 -v -3.3919 0.5906 -7.3042 -v -3.3895 -0.5906 -7.3034 -v 3.0524 0.5906 -7.3021 -v 2.9821 0.5906 -7.3042 -v 2.9846 -0.5906 -7.3034 -v -8.3194 0.5906 -7.8943 -v -8.3330 0.5906 -7.8586 -v -8.3320 -0.5906 -7.8597 -v 10.1189 0.5906 -8.0840 -v 10.0627 0.5906 -8.2370 -v 10.1399 0.5906 -8.0973 -v 2.8363 -0.5906 -8.0344 -v 2.7779 -0.5906 -8.1787 -v 2.7291 0.5906 -8.1335 -v -6.3802 -0.5906 -8.0344 -v -6.4387 -0.5906 -8.1787 -v -6.4875 0.5906 -8.1335 -v -3.5961 -0.5906 -8.1787 -v -3.6449 0.5906 -8.1335 -v -3.5377 -0.5906 -8.0344 -v 5.5412 0.5906 -7.1818 -v -9.0233 -0.5906 -7.4649 -v -8.8944 -0.5906 -7.5338 -v 2.6163 0.5906 -7.8137 -v -3.7577 0.5906 -7.8137 -v -6.6002 0.5906 -7.8137 -v 6.8600 0.5906 -8.2057 -v 3.1861 0.5906 -8.2271 -v 3.1311 0.5906 -8.2443 -v -6.0304 0.5906 -8.2271 -v -6.0855 0.5906 -8.2443 -v -3.2430 0.5906 -8.2443 -v -3.1879 0.5906 -8.2271 -v 6.6443 0.5906 -8.2294 -v 6.5887 0.5906 -8.0569 -v 6.5538 0.5906 -8.2017 -v 6.4772 0.5906 -8.1517 -v 6.9235 0.5906 -7.5276 -v 6.8800 0.5906 -7.4824 -v 6.9883 0.5906 -7.4332 -v -8.3560 -0.5906 -7.4993 -v -8.3904 -0.5906 -7.4236 -v -8.5159 -0.5906 -7.5133 -v 5.0662 0.5906 -7.4960 -v 5.0821 0.5906 -7.5190 -v 5.0818 -0.5906 -7.5177 -v 12.3181 0.5906 -7.4960 -v 12.3341 0.5906 -7.5190 -v 12.3337 -0.5906 -7.5177 -v 8.4833 0.5906 -7.4599 -v 1.6211 0.5906 -7.4599 -v -4.4676 0.5906 -7.3247 -v -7.9006 0.5906 -7.3247 -v -10.7431 0.5906 -7.3247 -v -5.4908 0.5906 -7.5638 -v -8.5654 0.5906 -8.1100 -v -8.6106 0.5906 -8.1224 -v -8.6070 -0.5906 -8.1222 -v 8.6089 0.5906 -7.4753 -v 8.5448 0.5906 -7.3676 -v 1.7467 0.5906 -7.4753 -v 1.6826 0.5906 -7.3676 -v 2.8617 0.5906 -8.2248 -v 2.7816 0.5906 -8.1798 -v 2.7140 0.5906 -8.1149 -v 2.8358 0.5906 -8.0319 -v -3.5123 0.5906 -8.2248 -v -3.5924 0.5906 -8.1798 -v -3.6601 0.5906 -8.1149 -v -3.5382 0.5906 -8.0319 -v -6.3548 0.5906 -8.2248 -v -6.4349 0.5906 -8.1798 -v -6.5026 0.5906 -8.1149 -v -6.3808 0.5906 -8.0319 -v 11.9144 -0.5906 -7.3210 -v 11.9144 0.5906 -7.3210 -v 4.6624 -0.5906 -7.3210 -v 4.6624 0.5906 -7.3210 -v 12.4891 0.5906 -7.4618 -v 12.4737 0.5906 -7.4305 -v 12.4652 -0.5906 -7.4151 -v 5.2372 0.5906 -7.4618 -v 5.2217 0.5906 -7.4305 -v 5.2132 -0.5906 -7.4151 -v 7.0303 0.5906 -8.4936 -v 7.0655 0.5906 -8.4503 -v 6.9525 0.5906 -8.3465 -v 6.3603 0.5906 -8.3708 -v -8.4302 0.5906 -8.1878 -v -8.4740 0.5906 -8.2130 -v -8.5291 0.5906 -8.0906 -v 6.5119 0.5906 -8.3594 -v -9.4631 0.5906 -7.4679 -v -9.4953 0.5906 -7.4512 -v -9.4219 0.5906 -7.3252 -v -9.4390 0.5906 -7.4879 -v -9.3815 0.5906 -7.3414 -v -9.3368 0.5906 -7.3678 -v 9.4823 0.5906 -7.4879 -v 9.5398 0.5906 -7.3414 -v 9.5845 0.5906 -7.3678 -v 9.4581 0.5906 -7.4679 -v 9.4259 0.5906 -7.4512 -v 9.4994 0.5906 -7.3252 -v -7.5054 0.5906 -7.6447 -v -7.3653 0.5906 -7.5771 -v -7.3416 0.5906 -7.6858 -v -10.3479 0.5906 -7.6447 -v -10.2078 0.5906 -7.5771 -v -10.1841 0.5906 -7.6858 -v -4.0723 0.5906 -7.6447 -v -3.9322 0.5906 -7.5771 -v -3.9085 0.5906 -7.6858 -v 11.4898 0.5906 -7.4434 -v 11.5435 0.5906 -7.5254 -v 11.4191 0.5906 -7.3782 -v -3.1579 -0.5906 -7.5313 -v -3.1815 0.5906 -7.4980 -v 3.2161 -0.5906 -7.5313 -v 3.1925 0.5906 -7.4980 -v -6.0004 -0.5906 -7.5313 -v -6.0240 0.5906 -7.4980 -v 0.3060 0.5906 -7.6229 -v 11.9601 0.5906 -7.5580 -v 4.7081 0.5906 -7.5580 -v -8.8910 -0.5906 -8.0222 -v -8.8665 -0.5906 -8.0582 -v -8.9897 -0.5906 -8.1453 -v -10.8541 0.5906 -7.8797 -v -7.9194 0.5906 -7.4911 -v -7.9580 0.5906 -7.5335 -v -8.0751 0.5906 -7.4479 -v -8.0049 0.5906 -7.3806 -v -4.4863 0.5906 -7.4911 -v -4.6421 0.5906 -7.4479 -v -4.5718 0.5906 -7.3806 -v -4.5250 0.5906 -7.5335 -v -10.7619 0.5906 -7.4911 -v -10.8006 0.5906 -7.5335 -v -10.9177 0.5906 -7.4479 -v -10.8474 0.5906 -7.3806 -v -9.0554 0.5906 -8.0214 -v -9.0268 0.5906 -8.0899 -v -9.0287 -0.5906 -8.0884 -v 10.4026 -0.5906 -7.1517 -v 10.4026 -0.5906 -6.9746 -v 10.4026 0.5906 -6.9746 -v 10.5581 -0.5906 -6.9746 -v 10.5581 -0.5906 -7.1517 -v 10.5581 0.5906 -7.1517 -v 5.9931 0.5906 -6.9746 -v 5.9931 0.5906 -7.1517 -v 5.9931 -0.5906 -7.1517 -v 6.1486 0.5906 -7.1517 -v 6.1486 0.5906 -6.9746 -v 6.1486 -0.5906 -6.9746 -v 10.5581 0.5906 -6.9746 -v 10.4026 0.5906 -7.1517 -v 5.9931 -0.5906 -6.9746 -v 6.1486 -0.5906 -7.1517 -v 6.8848 -0.5906 -8.0566 -v 6.9157 -0.5906 -8.0261 -v 6.9254 0.5906 -8.0134 -v 3.2271 -0.5906 -8.0130 -v 3.2952 -0.5906 -8.1566 -v -3.1469 -0.5906 -8.0129 -v -3.0788 -0.5906 -8.1566 -v -5.9214 -0.5906 -8.1566 -v -5.9894 -0.5906 -8.0129 -v -8.8775 -0.5906 -8.2242 -v -11.7974 0.5906 -7.1746 -v -0.4849 0.5906 -8.0308 -v -0.3430 0.5906 -7.9669 -v 3.5347 0.5906 -8.0308 -v 3.6767 0.5906 -7.9669 -v -8.5627 0.5906 -7.4631 -v -8.5359 0.5906 -7.4866 -v -8.5365 -0.5906 -7.4852 -v 6.5443 -0.5906 -7.5287 -v 6.5474 0.5906 -7.5261 -v 7.3896 0.5906 -8.0948 -v 7.4049 0.5906 -8.1260 -v 7.4131 -0.5906 -8.1408 -v 0.5274 0.5906 -8.0948 -v 0.5427 0.5906 -8.1260 -v 0.5509 -0.5906 -8.1408 -v -10.6714 0.5906 -7.3078 -v -10.5683 0.5906 -7.3026 -v -10.4718 0.5906 -7.3179 -v -4.2927 0.5906 -7.3026 -v -4.1962 0.5906 -7.3179 -v -4.3958 0.5906 -7.3078 -v -7.8288 0.5906 -7.3078 -v -7.7258 0.5906 -7.3026 -v -7.6293 0.5906 -7.3179 -v -9.7730 -0.5906 -7.4585 -v 9.1482 -0.5906 -7.4585 -v 8.7285 0.5906 -7.4691 -v 8.7416 -0.5906 -7.4723 -v 1.8663 0.5906 -7.4691 -v 1.8794 -0.5906 -7.4723 -v 6.5148 0.5906 -7.5841 -v -8.1290 0.5906 -8.0313 -v -8.1626 0.5906 -7.9324 -v -10.9715 0.5906 -8.0313 -v -11.0051 0.5906 -7.9324 -v -4.6959 0.5906 -8.0313 -v -4.7295 0.5906 -7.9324 -v 10.8092 0.5906 -7.4834 -v 10.9630 0.5906 -7.5294 -v 10.9287 0.5906 -7.5899 -v 10.8409 0.5906 -7.4404 -v -3.1570 0.5906 -7.5339 -v -3.1379 0.5906 -7.5772 -v -3.1385 -0.5906 -7.5741 -v 3.2170 0.5906 -7.5339 -v 3.2361 0.5906 -7.5772 -v 3.2355 -0.5906 -7.5741 -v -5.9995 0.5906 -7.5339 -v -5.9804 0.5906 -7.5772 -v -5.9810 -0.5906 -7.5741 -v -4.6588 0.5906 -8.0953 -v -4.6276 0.5906 -8.1326 -v -8.0918 0.5906 -8.0953 -v -8.0607 0.5906 -8.1326 -v -10.9344 0.5906 -8.0953 -v -10.9032 0.5906 -8.1326 -v 6.9713 0.5906 -8.2553 -v 6.9738 -0.5906 -8.2155 -v 6.9846 0.5906 -7.8386 -v 11.3677 0.5906 -8.0270 -v 0.0706 0.5906 -8.2213 -v -0.0287 0.5906 -8.1165 -v -10.2038 -0.5906 -8.0221 -v -7.3613 -0.5906 -8.0221 -v -3.9282 -0.5906 -8.0221 -v 1.1014 0.5906 -8.2364 -v 7.9636 0.5906 -8.2364 -v -0.3933 0.5906 -7.4028 -v -0.3086 0.5906 -7.5294 -v -0.4624 0.5906 -7.4834 -v -0.4307 0.5906 -7.4404 -v 3.5573 0.5906 -7.4834 -v 3.5889 0.5906 -7.4404 -v 3.7111 0.5906 -7.5294 -v 3.6264 0.5906 -7.4028 -v 7.5492 0.5906 -8.0458 -v 7.4475 0.5906 -8.1786 -v 7.4237 0.5906 -8.1537 -v 7.5728 0.5906 -8.0737 -v 0.5853 0.5906 -8.1786 -v 0.5615 0.5906 -8.1537 -v 0.7105 0.5906 -8.0737 -v 5.8726 -0.5906 -7.3210 -v 5.8726 -0.5906 -7.4411 -v -9.6065 0.5906 -7.4298 -v -9.6508 0.5906 -7.3030 -v -9.5853 0.5906 -7.3016 -v 9.3147 0.5906 -7.4298 -v 9.2705 0.5906 -7.3030 -v 9.3360 0.5906 -7.3016 -v -3.1236 -0.5906 -7.9470 -v -3.0095 -0.5906 -8.0652 -v -3.1244 0.5906 -7.9481 -v -5.9661 -0.5906 -7.9470 -v -5.8520 -0.5906 -8.0652 -v -5.9670 0.5906 -7.9481 -v 3.2504 -0.5906 -7.9470 -v 3.2496 0.5906 -7.9481 -v 3.3645 -0.5906 -8.0652 -v -11.8441 0.5906 -7.1451 -v -11.8119 0.5906 -7.1632 -v -11.8371 -0.5906 -7.1474 -v 5.5399 0.5906 -7.3210 -v 5.4041 0.5906 -7.3210 -v 5.4041 -0.5906 -7.3210 -v -9.0371 0.5906 -7.5059 -v -9.0409 -0.5906 -7.5194 -v -11.7284 0.5906 -7.6676 -v -11.6891 0.5906 -7.6425 -v -11.6766 -0.5906 -7.6333 -v -4.3858 0.5906 -8.1175 -v -4.4276 0.5906 -8.1021 -v -4.4276 -0.5906 -8.1021 -v -7.8189 0.5906 -8.1175 -v -7.8607 0.5906 -8.1021 -v -7.8607 -0.5906 -8.1021 -v 2.9605 0.5906 -7.4404 -v -3.4135 0.5906 -7.4404 -v -6.2560 0.5906 -7.4404 -v 11.5325 0.5906 -7.5030 -v 11.5056 0.5906 -7.4620 -v 4.2805 0.5906 -7.5030 -v 4.2537 0.5906 -7.4620 -v 0.2608 0.5906 -7.5030 -v 0.2340 0.5906 -7.4620 -v 10.2530 0.5906 -7.4411 -v 10.2530 -0.5906 -7.4411 -v 10.8092 -0.5906 -7.4834 -v -0.4624 -0.5906 -7.4834 -v 3.5573 -0.5906 -7.4834 -v -7.5191 0.5906 -7.5907 -v -7.5057 -0.5906 -7.6406 -v -4.0860 0.5906 -7.5907 -v -4.0726 -0.5906 -7.6406 -v -10.3616 0.5906 -7.5907 -v -10.3482 -0.5906 -7.6406 -v -11.8147 0.5906 -7.5307 -v -11.7844 0.5906 -7.5056 -v 7.6593 -0.5906 -8.1189 -v 7.6412 0.5906 -8.1133 -v 0.7971 -0.5906 -8.1189 -v 0.7790 0.5906 -8.1133 -v 10.2530 -0.5906 -7.3210 -v 10.2530 0.5906 -7.3210 -v 6.9883 -0.5906 -7.4332 -v 6.9232 -0.5906 -7.5257 -v 6.9883 -0.5906 -7.3210 -v 11.9144 -0.5906 -7.4509 -v 4.6624 -0.5906 -7.4509 -v 4.9455 0.5906 -7.4366 -v 4.9702 0.5906 -7.3021 -v 12.1974 0.5906 -7.4366 -v 12.2222 0.5906 -7.3021 -v 6.6766 0.5906 -7.4361 -v 6.6376 0.5906 -7.4507 -v -7.5532 0.5906 -8.0395 -v -10.3957 0.5906 -8.0395 -v -4.1201 0.5906 -8.0395 -v 10.1239 -0.5906 -8.0897 -v -8.4976 0.5906 -7.9150 -v -8.4755 0.5906 -7.9489 -v -8.4928 -0.5906 -7.9187 -v 5.5996 -0.5906 -7.0177 -v 5.5680 -0.5906 -7.0614 -v 5.5872 0.5906 -7.0334 -v 12.4952 0.5906 -7.4789 -v 5.2432 0.5906 -7.4789 -v 6.9432 0.5906 -7.9861 -v 6.9157 0.5906 -8.0261 -v 7.0645 -0.5906 -8.4528 -v -4.1147 -0.5906 -8.0346 -v -4.0090 -0.5906 -8.1451 -v -3.9634 -0.5906 -8.0887 -v -4.0074 0.5906 -8.1422 -v -7.3965 -0.5906 -8.0887 -v -7.4421 -0.5906 -8.1451 -v -7.4405 0.5906 -8.1422 -v -7.5478 -0.5906 -8.0346 -v -10.2390 -0.5906 -8.0887 -v -10.2846 -0.5906 -8.1451 -v -10.2830 0.5906 -8.1422 -v -10.3903 -0.5906 -8.0346 -v -9.3907 0.5906 -8.1222 -v -9.3793 0.5906 -8.1833 -v -9.3843 -0.5906 -8.1655 -v 9.5305 0.5906 -8.1222 -v 9.5420 0.5906 -8.1833 -v 9.5369 -0.5906 -8.1655 -v 11.1181 0.5906 -8.1237 -v 11.0598 0.5906 -8.1058 -v 11.0619 -0.5906 -8.1078 -v 3.8099 -0.5906 -8.1078 -v 9.4520 0.5906 -8.0485 -v 9.4785 0.5906 -8.0157 -v -9.4692 0.5906 -8.0485 -v -9.4427 0.5906 -8.0157 -v -5.4696 0.5906 -7.3798 -v -5.3451 0.5906 -7.4443 -v -5.4158 0.5906 -7.3425 -v -5.3563 0.5906 -7.3181 -v -0.2098 -0.5906 -8.1078 -v 11.2129 0.5906 -7.4337 -v 11.2706 0.5906 -7.4515 -v 11.2685 -0.5906 -7.4496 -v 3.9609 0.5906 -7.4337 -v 4.0186 0.5906 -7.4515 -v 4.0165 -0.5906 -7.4496 -v -0.0588 0.5906 -7.4337 -v -0.0011 0.5906 -7.4515 -v -0.0032 -0.5906 -7.4496 -v 5.8540 0.5906 -7.0960 -v 8.5765 0.5906 -7.4960 -v 1.7143 0.5906 -7.4960 -v 5.8726 0.5906 -7.4411 -v 5.4041 -0.5906 -7.4411 -v 5.4041 0.5906 -7.4411 -v -6.1586 -0.5906 -7.3016 -v -6.1992 -0.5906 -7.4296 -v -3.3160 -0.5906 -7.3016 -v -3.3567 -0.5906 -7.4296 -v 3.0580 -0.5906 -7.3016 -v 3.0173 -0.5906 -7.4296 -v -10.3587 -0.5906 -7.9793 -v -7.5162 -0.5906 -7.9793 -v -4.0831 -0.5906 -7.9793 -v -4.9911 -0.5906 -7.4069 -v -4.9679 -0.5906 -7.4437 -v -4.9692 0.5906 -7.4422 -v -5.1143 -0.5906 -7.5191 -v 10.1437 0.5906 -8.2479 -v 10.1962 0.5906 -8.1041 -v -0.3012 0.5906 -8.2159 -v -0.2569 0.5906 -8.2335 -v -0.2389 -0.5906 -8.2396 -v 8.5401 0.5906 -7.5406 -v 1.6779 0.5906 -7.5406 -v 1.7293 0.5906 -7.3264 -v 1.6996 0.5906 -7.3488 -v 1.7016 -0.5906 -7.3464 -v 8.5915 0.5906 -7.3264 -v 8.5619 0.5906 -7.3488 -v 8.5638 -0.5906 -7.3463 -v 6.9448 -0.5906 -7.9852 -v 10.9705 0.5906 -8.2159 -v 11.0148 0.5906 -8.2335 -v 11.0328 -0.5906 -8.2396 -v 3.7185 0.5906 -8.2159 -v 3.7628 0.5906 -8.2335 -v 3.7808 -0.5906 -8.2396 -v -5.3769 0.5906 -7.3245 -v -5.4158 -0.5906 -7.3425 -v -10.3824 -0.5906 -7.5433 -v -10.3622 -0.5906 -7.5872 -v -10.3814 0.5906 -7.5461 -v -4.0866 -0.5906 -7.5872 -v -4.1068 -0.5906 -7.5433 -v -4.1059 0.5906 -7.5461 -v -7.5399 -0.5906 -7.5433 -v -7.5197 -0.5906 -7.5872 -v -7.5389 0.5906 -7.5461 -v 7.9097 0.5906 -8.0143 -v 7.8749 0.5906 -8.0576 -v 7.8840 -0.5906 -8.0496 -v 1.0475 0.5906 -8.0143 -v 1.0127 0.5906 -8.0576 -v 1.0218 -0.5906 -8.0496 -v -8.8824 0.5906 -7.5899 -v -8.8937 0.5906 -7.5592 -v -8.8932 -0.5906 -7.5645 -v -8.8025 0.5906 -7.4427 -v -8.8183 0.5906 -7.3141 -v 9.1135 -0.5906 -7.4871 -v 9.0893 -0.5906 -7.5210 -v 9.0902 0.5906 -7.5206 -v -9.8319 -0.5906 -7.5211 -v -9.8077 -0.5906 -7.4871 -v -9.8310 0.5906 -7.5206 -v 11.5154 0.5906 -8.0842 -v 11.5406 0.5906 -8.0432 -v 11.5536 -0.5906 -8.0177 -v 4.2635 0.5906 -8.0842 -v 4.2886 0.5906 -8.0432 -v 4.3016 -0.5906 -8.0177 -v 0.2689 0.5906 -8.0432 -v 0.2819 -0.5906 -8.0177 -v -8.3929 0.5906 -8.1575 -v -8.3939 -0.5906 -8.1592 -v -9.9955 -0.5906 -7.5124 -v 8.9258 -0.5906 -7.5124 -v -6.5448 0.5906 -7.5079 -v -6.5433 -0.5906 -7.5035 -v -3.7023 0.5906 -7.5079 -v -3.7008 -0.5906 -7.5035 -v 2.6717 0.5906 -7.5079 -v 2.6732 -0.5906 -7.5035 -v 9.8258 -0.5906 -7.4411 -v 9.8258 -0.5906 -7.3210 -v 9.8258 0.5906 -7.3210 -v 9.8258 0.5906 -7.4411 -v -6.3371 -0.5906 -8.0790 -v -6.3390 0.5906 -8.0763 -v 2.8795 -0.5906 -8.0790 -v 2.8776 0.5906 -8.0763 -v -3.4945 -0.5906 -8.0790 -v -3.4965 0.5906 -8.0763 -v -9.6532 0.5906 -8.1320 -v 9.2680 0.5906 -8.1320 -v 6.9883 0.5906 -7.3210 -v 9.5198 0.5906 -7.6557 -v -9.4015 0.5906 -7.6557 -v 3.2311 0.5906 -8.0018 -v -3.1429 0.5906 -8.0018 -v -5.9854 0.5906 -8.0018 -v 5.5675 0.5906 -7.0630 -v 9.9922 -0.5906 -8.1989 -v 9.9595 -0.5906 -8.1547 -v 9.9685 0.5906 -8.1690 -v -11.6230 0.5906 -7.1163 -v -11.6519 0.5906 -7.0814 -v -11.6504 -0.5906 -7.0824 -v 11.0058 -0.5906 -7.4839 -v 10.9344 -0.5906 -7.3614 -v 10.8597 -0.5906 -7.4191 -v 10.9315 0.5906 -7.3645 -v -0.4120 -0.5906 -7.4191 -v -0.3372 -0.5906 -7.3614 -v -0.3401 0.5906 -7.3645 -v -0.2658 -0.5906 -7.4839 -v 3.7539 -0.5906 -7.4839 -v 3.6825 -0.5906 -7.3614 -v 3.6077 -0.5906 -7.4191 -v 3.6795 0.5906 -7.3645 -v 0.1475 0.5906 -7.3782 -v 4.1671 0.5906 -7.3782 -v -5.0942 0.5906 -7.5826 -v -5.1085 0.5906 -7.5343 -v -4.9455 0.5906 -7.5109 -v 0.8834 -0.5906 -8.2503 -v 7.7456 -0.5906 -8.2503 -v 9.0506 0.5906 -8.0314 -v 9.0445 -0.5906 -8.0016 -v -9.8707 0.5906 -8.0314 -v -9.8767 -0.5906 -8.0017 -v 0.1234 -0.5906 -7.9828 -v 0.0992 -0.5906 -8.0245 -v 0.2328 -0.5906 -8.1012 -v 11.3708 -0.5906 -8.0245 -v 11.3950 -0.5906 -7.9828 -v 11.3950 0.5906 -7.9828 -v 11.5045 -0.5906 -8.1012 -v 4.1430 -0.5906 -7.9828 -v 4.1189 -0.5906 -8.0245 -v 4.2525 -0.5906 -8.1012 -v 4.1430 0.5906 -7.9828 -v 6.5858 0.5906 -8.4511 -v 4.9004 0.5906 -7.3044 -v 4.8783 -0.5906 -7.3069 -v 12.1524 0.5906 -7.3044 -v 12.1303 -0.5906 -7.3069 -v -0.3117 -0.5906 -7.5318 -v -0.3360 -0.5906 -7.5729 -v -0.3360 0.5906 -7.5729 -v 10.9599 -0.5906 -7.5318 -v 10.9357 -0.5906 -7.5729 -v 10.9357 0.5906 -7.5729 -v 3.7079 -0.5906 -7.5318 -v 3.6837 -0.5906 -7.5729 -v 3.6837 0.5906 -7.5729 -v 6.4999 0.5906 -8.5606 -v 6.5702 0.5906 -8.5877 -v 6.5294 -0.5906 -8.5749 -v 9.6474 0.5906 -7.4455 -v -9.2739 0.5906 -7.4455 -v 0.0483 -0.5906 -7.4807 -v 4.0680 -0.5906 -7.4807 -v 11.3200 -0.5906 -7.4807 -v -0.2615 -0.5906 -8.0767 -v 11.0102 -0.5906 -8.0767 -v 3.7582 -0.5906 -8.0767 -v -9.4268 0.5906 -8.1515 -v -9.4918 0.5906 -8.1948 -v -9.5019 0.5906 -8.0767 -v 9.4945 0.5906 -8.1515 -v 9.4295 0.5906 -8.1948 -v 9.4194 0.5906 -8.0767 -v -8.8917 0.5906 -8.0197 -v -8.9085 0.5906 -7.9762 -v -8.9082 -0.5906 -7.9792 -v -1.1443 0.5906 -8.3573 -v -1.1480 -0.5906 -8.3690 -v -9.7183 0.5906 -7.4390 -v -9.7125 0.5906 -7.3096 -v 9.2030 0.5906 -7.4390 -v 9.2088 0.5906 -7.3096 -v -9.7850 0.5906 -8.1183 -v 9.1363 0.5906 -8.1183 -v 1.0636 0.5906 -7.9799 -v 7.9258 0.5906 -7.9799 -v 10.1704 0.5906 -8.1037 -v -1.0239 0.5906 -8.0600 -v -8.8417 0.5906 -7.4597 -v 6.4851 0.5906 -7.7400 -v 6.3260 0.5906 -7.8006 -v -8.4846 0.5906 -7.3466 -v -3.4552 0.5906 -7.4566 -v -6.2978 0.5906 -7.4566 -v 2.9188 0.5906 -7.4566 -v -9.8707 -0.5906 -8.0331 -v -10.0329 -0.5906 -8.0690 -v 9.0506 -0.5906 -8.0331 -v 8.8883 -0.5906 -8.0690 -v 3.3656 0.5906 -8.0610 -v -3.0084 0.5906 -8.0610 -v -5.8509 0.5906 -8.0610 -v -8.4909 0.5906 -7.9229 -v 0.7329 0.5906 -8.0920 -v 3.3818 0.5906 -7.5377 -v 3.3526 0.5906 -7.4705 -v 3.3546 -0.5906 -7.4722 -v -2.9923 0.5906 -7.5377 -v -3.0214 0.5906 -7.4705 -v -3.0194 -0.5906 -7.4722 -v 1.6932 -0.5906 -7.5171 -v 8.5555 -0.5906 -7.5170 -v 9.0688 -0.5906 -8.0693 -v 9.0598 0.5906 -8.0539 -v -9.8524 -0.5906 -8.0693 -v -9.8615 0.5906 -8.0539 -v 9.0755 0.5906 -7.3489 -v 9.0329 0.5906 -7.3729 -v 9.0243 -0.5906 -7.3778 -v -9.8458 0.5906 -7.3489 -v -9.8884 0.5906 -7.3729 -v -9.8969 -0.5906 -7.3778 -v 6.6687 0.5906 -8.2336 -v 6.8765 -0.5906 -8.4408 -v 6.8290 -0.5906 -8.4637 -v 6.9328 -0.5906 -8.5635 -v 6.8749 0.5906 -8.4412 -v -8.1394 0.5906 -7.5567 -v -8.1563 0.5906 -7.6078 -v -8.1471 -0.5906 -7.5756 -v -10.9819 0.5906 -7.5567 -v -10.9989 0.5906 -7.6078 -v -10.9896 -0.5906 -7.5756 -v -4.7063 0.5906 -7.5567 -v -4.7233 0.5906 -7.6078 -v -4.7140 -0.5906 -7.5756 -v 0.0650 0.5906 -7.3328 -v 4.0847 0.5906 -7.3328 -v 11.2431 0.5906 -7.3076 -v 11.3367 0.5906 -7.3328 -v 11.2425 0.5906 -7.4409 -v -11.6984 -0.5906 -7.0411 -v -11.7815 -0.5906 -7.0020 -v -4.1094 0.5906 -8.0253 -v -7.5425 0.5906 -8.0253 -v -10.3850 0.5906 -8.0253 -v -8.5638 -0.5906 -7.4617 -v -1.2549 0.5906 -8.6061 -v -1.2704 -0.5906 -8.6069 -v 2.8002 0.5906 -8.1935 -v 2.8402 0.5906 -8.2160 -v 2.8568 -0.5906 -8.2242 -v -6.4164 0.5906 -8.1935 -v -6.3763 0.5906 -8.2160 -v -6.3597 -0.5906 -8.2242 -v -3.5739 0.5906 -8.1935 -v -3.5338 0.5906 -8.2160 -v -3.5172 -0.5906 -8.2242 -v -9.8737 0.5906 -7.9625 -v 9.0476 0.5906 -7.9625 -v -10.9601 -0.5906 -7.5098 -v -10.9334 0.5906 -7.4671 -v -4.6845 -0.5906 -7.5098 -v -4.6578 0.5906 -7.4671 -v -8.1176 -0.5906 -7.5098 -v -8.0909 0.5906 -7.4671 -v -8.3510 0.5906 -7.5211 -v -8.9817 0.5906 -7.7238 -v 8.9887 -0.5906 -7.7829 -v -9.9325 -0.5906 -7.7829 -v -9.4955 0.5906 -7.3084 -v -9.4766 -0.5906 -7.3108 -v 9.4258 0.5906 -7.3084 -v 9.4447 -0.5906 -7.3108 -v 4.8760 0.5906 -7.3090 -v 12.1280 0.5906 -7.3090 -v 6.7438 0.5906 -7.3027 -v 6.6708 0.5906 -7.3044 -v 6.6729 -0.5906 -7.3036 -v -0.1416 -0.5906 -8.2555 -v -0.2095 0.5906 -8.2460 -v 11.1301 -0.5906 -8.2555 -v 11.0621 0.5906 -8.2460 -v 3.8781 -0.5906 -8.2555 -v 3.8102 0.5906 -8.2460 -v -10.0211 0.5906 -7.8923 -v -9.8635 0.5906 -7.9314 -v 8.9001 0.5906 -7.8923 -v 9.0577 0.5906 -7.9314 -v -8.3286 -0.5906 -8.0654 -v -8.3634 -0.5906 -8.1247 -v -8.3621 0.5906 -8.1222 -v 6.5470 -0.5906 -8.0150 -v 6.5466 0.5906 -8.0129 -v 8.5244 -0.5906 -7.3918 -v 8.6108 -0.5906 -7.4738 -v 1.6622 -0.5906 -7.3918 -v 1.7486 -0.5906 -7.4738 -v -4.5785 0.5906 -7.8797 -v -8.0115 0.5906 -7.8797 -v -8.9163 -0.5906 -7.9391 -v -8.5758 0.5906 -7.7101 -v 5.6941 0.5906 -7.2145 -v 7.7721 0.5906 -8.2434 -v 0.9099 0.5906 -8.2434 -v -9.4848 -0.5906 -7.4545 -v 9.4364 -0.5906 -7.4545 -v -1.0280 0.5906 -8.4281 -v -1.0323 -0.5906 -8.4390 -v -9.8222 -0.5906 -7.8818 -v -9.8599 -0.5906 -7.7454 -v 9.0991 -0.5906 -7.8818 -v 9.0614 -0.5906 -7.7454 -v -4.9801 0.5906 -7.4233 -v -4.9599 0.5906 -7.4627 -v -8.8660 0.5906 -7.3283 -v -8.8820 -0.5906 -7.3335 -v 6.5242 0.5906 -8.3922 -v 6.5121 -0.5906 -8.3619 -v -8.4177 -0.5906 -7.7677 -v -8.3611 -0.5906 -7.8145 -v -8.3769 0.5906 -7.7996 -v 7.1119 0.5906 -8.3339 -v 7.1243 0.5906 -8.2474 -v -3.1658 0.5906 -7.5200 -v 3.2082 0.5906 -7.5200 -v -5.8639 0.5906 -7.4705 -v -6.0084 0.5906 -7.5200 -v -5.4457 0.5906 -7.4998 -v 10.2054 0.5906 -8.1034 -v 6.8761 0.5906 -8.5848 -v 6.9214 0.5906 -8.5685 -v -9.2391 -0.5906 -8.1226 -v 6.7421 0.5906 -8.2351 -v 12.4969 -0.5906 -7.4798 -v 5.2449 -0.5906 -7.4798 -v -5.8348 0.5906 -7.5377 -v 0.3083 0.5906 -7.9229 -v 0.1429 0.5906 -7.9293 -v 11.4145 0.5906 -7.9293 -v 4.1626 0.5906 -7.9293 -v 2.6628 0.5906 -8.0318 -v 2.6303 0.5906 -7.9315 -v -6.5537 0.5906 -8.0318 -v -6.5863 0.5906 -7.9315 -v -3.7112 0.5906 -8.0318 -v -3.7437 0.5906 -7.9315 -v -5.4702 0.5906 -7.5274 -v -4.4896 0.5906 -7.3338 -v -7.9226 0.5906 -7.3338 -v -10.7652 0.5906 -7.3338 -v 6.9869 0.5906 -8.5307 -v 6.9352 0.5906 -8.5616 -v 7.3820 -0.5906 -8.0769 -v 7.5544 -0.5906 -8.0547 -v 0.5198 -0.5906 -8.0769 -v 8.6119 0.5906 -7.4736 -v 8.6377 0.5906 -7.4648 -v 1.7497 0.5906 -7.4736 -v 1.7755 0.5906 -7.4648 -v -5.8619 -0.5906 -7.4722 -v 3.1861 -0.5906 -8.2271 -v -3.1879 -0.5906 -8.2271 -v -6.0304 -0.5906 -8.2271 -v 6.7523 -0.5906 -7.3021 -v 6.7157 -0.5906 -7.4295 -v 9.6684 0.5906 -7.5175 -v 9.6595 0.5906 -7.4774 -v 9.6654 -0.5906 -7.4959 -v 6.5604 -0.5906 -8.4367 -v 6.4637 -0.5906 -8.5405 -v 5.7643 0.5906 -6.9537 -v 8.7426 0.5906 -7.3096 -v 8.8051 0.5906 -7.3318 -v 1.8803 0.5906 -7.3096 -v 1.9429 0.5906 -7.3318 -v -8.5620 -0.5906 -7.3177 -v -8.5062 0.5906 -7.3369 -v -8.5969 -0.5906 -7.4448 -v 6.5305 0.5906 -8.4025 -v 6.8777 -0.5906 -7.4795 -v -1.0384 0.5906 -8.4500 -v 0.7474 0.5906 -8.1005 -v 0.7332 0.5906 -8.2481 -v 7.5955 0.5906 -8.2481 -v 1.0487 -0.5906 -8.0132 -v 1.0707 -0.5906 -7.9611 -v 7.9109 -0.5906 -8.0132 -v 7.9329 -0.5906 -7.9611 -v 1.6653 0.5906 -7.5687 -v 1.6476 0.5906 -7.6374 -v 8.5275 0.5906 -7.5687 -v 8.5098 0.5906 -7.6374 -v -4.5098 -0.5906 -8.0387 -v -7.9429 -0.5906 -8.0387 -v -10.7854 -0.5906 -8.0387 -v -5.3535 -0.5906 -7.3158 -v -8.4347 0.5906 -7.3782 -v -7.8749 0.5906 -8.2397 -v -10.7174 0.5906 -8.2397 -v -4.4418 0.5906 -8.2397 -v -10.0407 0.5906 -8.0264 -v -10.0422 -0.5906 -8.0109 -v 8.8806 0.5906 -8.0264 -v 8.8790 -0.5906 -8.0109 -v 6.8036 0.5906 -8.2266 -v 6.8036 -0.5906 -8.2266 -v 10.9162 0.5906 -7.6255 -v -11.7344 0.5906 -7.4168 -v -11.7333 -0.5906 -7.4155 -v -8.9395 -0.5906 -8.1910 -v 3.9910 0.5906 -8.1165 -v 4.3257 0.5906 -7.6229 -v 11.5776 0.5906 -7.6229 -v 10.9287 0.5906 -7.9669 -v 10.9068 0.5906 -7.8918 -v 10.9071 -0.5906 -7.8977 -v -0.3648 0.5906 -7.8918 -v -0.3646 -0.5906 -7.8977 -v 3.6548 0.5906 -7.8918 -v 3.6551 -0.5906 -7.8977 -v -6.4382 0.5906 -7.7052 -v 2.7783 0.5906 -7.7052 -v -3.5957 0.5906 -7.7052 -v -6.0458 0.5906 -7.4758 -v -6.0635 -0.5906 -7.4615 -v -3.2033 0.5906 -7.4758 -v -3.2210 -0.5906 -7.4615 -v 3.1708 0.5906 -7.4758 -v 3.1530 -0.5906 -7.4615 -v -9.2529 0.5906 -7.5175 -v -9.2618 0.5906 -7.4774 -v -9.2559 -0.5906 -7.4959 -v -4.9928 0.5906 -7.4056 -v 6.9698 0.5906 -7.9199 -v 6.9513 0.5906 -7.9714 -v 11.1817 0.5906 -7.4302 -v -10.3388 0.5906 -8.1889 -v -7.4963 0.5906 -8.1889 -v -4.0632 0.5906 -8.1889 -v 0.1302 0.5906 -7.5897 -v 0.1520 -0.5906 -7.6575 -v 4.1499 0.5906 -7.5897 -v 4.1717 -0.5906 -7.6575 -v 11.4019 0.5906 -7.5897 -v 11.4236 -0.5906 -7.6575 -v -11.5547 -0.5906 -7.3707 -v -1.2964 -0.5906 -8.4572 -v -1.3281 -0.5906 -8.5989 -v 6.3657 -0.5906 -7.9927 -v 6.3369 -0.5906 -7.8995 -v 6.5033 -0.5906 -7.9237 -v -2.9782 0.5906 -7.9852 -v -2.9788 -0.5906 -7.9903 -v -5.8208 0.5906 -7.9852 -v -5.8213 -0.5906 -7.9903 -v 3.3958 0.5906 -7.9852 -v 3.3952 -0.5906 -7.9903 -v 6.8462 0.5906 -8.4565 -v -11.7519 -0.5906 -7.6799 -v -11.8147 -0.5906 -7.5307 -v 5.0207 0.5906 -7.4595 -v 12.2727 0.5906 -7.4595 -v 9.9564 0.5906 -8.1440 -v 9.9479 0.5906 -8.1073 -v 10.1052 0.5906 -8.0653 -v -8.4998 -0.5906 -8.0641 -v -8.5280 -0.5906 -8.0905 -v -8.4313 -0.5906 -8.1891 -v -8.5016 0.5906 -8.0655 -v 7.5341 0.5906 -8.0162 -v 7.5228 0.5906 -7.9677 -v 7.5233 -0.5906 -7.9789 -v -8.8176 0.5906 -7.4472 -v -8.8033 -0.5906 -7.4415 -v 6.8353 0.5906 -8.4605 -v 6.4940 0.5906 -7.6554 -v 6.4929 -0.5906 -7.6567 -v -4.2189 0.5906 -7.3115 -v -7.6520 0.5906 -7.3115 -v -10.4945 0.5906 -7.3115 -v 3.5009 0.5906 -7.9296 -v -0.5188 0.5906 -7.9296 -v 10.7867 0.5906 -8.0308 -v -6.0857 0.5906 -7.3115 -v -6.0811 -0.5906 -7.3116 -v -9.7486 0.5906 -8.2553 -v -9.7278 0.5906 -8.1319 -v 9.1727 0.5906 -8.2553 -v 9.1934 0.5906 -8.1319 -v -5.1797 -0.5906 -7.4561 -v -5.1016 -0.5906 -7.3267 -v 1.8973 0.5906 -7.3138 -v 1.8882 -0.5906 -7.3103 -v 8.7595 0.5906 -7.3138 -v 8.7504 -0.5906 -7.3103 -v 3.3832 -0.5906 -7.5395 -v -2.9908 -0.5906 -7.5395 -v -5.8333 -0.5906 -7.5395 -v -11.8544 0.5906 -7.5498 -v -11.9201 0.5906 -7.5670 -v -11.9143 -0.5906 -7.5667 -v 4.2956 0.5906 -8.0280 -v 11.5476 0.5906 -8.0280 -v 6.3588 0.5906 -7.9738 -v 5.7449 -0.5906 -7.1077 -v 5.6451 -0.5906 -6.9836 -v -10.2745 -0.5906 -7.4483 -v -7.4320 -0.5906 -7.4482 -v -3.9989 -0.5906 -7.4482 -v -10.9742 -0.5906 -8.0289 -v -10.9991 0.5906 -7.9591 -v -4.6986 -0.5906 -8.0289 -v -4.7235 0.5906 -7.9591 -v -8.1317 -0.5906 -8.0289 -v -8.1566 0.5906 -7.9591 -v -10.7282 0.5906 -7.4656 -v -7.8857 0.5906 -7.4656 -v -4.4526 0.5906 -7.4656 -v 0.6719 0.5906 -8.0162 -v 0.5214 0.5906 -8.0775 -v 0.5051 0.5906 -8.0088 -v 7.3836 0.5906 -8.0775 -v 7.3673 0.5906 -8.0088 -v -9.5575 -0.5906 -8.1095 -v 9.3637 -0.5906 -8.1095 -v -11.7254 -0.5906 -7.3599 -v -11.5576 -0.5906 -7.2776 -v 6.7189 0.5906 -7.4301 -v 9.3741 -0.5906 -7.4354 -v -9.5471 -0.5906 -7.4354 -v -11.7714 0.5906 -7.2021 -v -5.0944 -0.5906 -7.5786 -v 10.9068 0.5906 -7.6648 -v -4.4886 -0.5906 -7.4921 -v -4.5688 -0.5906 -7.3766 -v -10.7642 -0.5906 -7.4921 -v -10.8444 -0.5906 -7.3766 -v -7.9216 -0.5906 -7.4921 -v -8.0018 -0.5906 -7.3766 -v -1.1651 0.5906 -8.3977 -v -1.1910 0.5906 -8.4252 -v -1.1750 -0.5906 -8.4111 -v 9.6884 -0.5906 -8.1513 -v 9.6930 0.5906 -8.1662 -v -6.5091 -0.5906 -7.4483 -v 2.7074 -0.5906 -7.4483 -v -3.6666 -0.5906 -7.4483 -v 6.6058 0.5906 -8.4601 -v -0.2119 0.5906 -7.4514 -v 3.8078 0.5906 -7.4514 -v 9.6415 -0.5906 -7.4317 -v 9.5016 -0.5906 -7.5143 -v 4.9750 -0.5906 -7.3014 -v 12.2270 -0.5906 -7.3014 -v 3.0134 0.5906 -8.1273 -v -6.2031 0.5906 -8.1273 -v -3.3606 0.5906 -8.1273 -v 9.1111 0.5906 -7.8749 -v 9.1482 0.5906 -7.8597 -v 9.1413 -0.5906 -7.8609 -v -9.8102 0.5906 -7.8749 -v -9.7730 0.5906 -7.8597 -v -9.7800 -0.5906 -7.8609 -v 10.1045 -0.5906 -8.0657 -v -7.5688 0.5906 -7.5067 -v -10.4113 0.5906 -7.5067 -v -4.1357 0.5906 -7.5067 -v -3.2431 0.5906 -7.3115 -v 3.1309 0.5906 -7.3115 -v 6.3370 0.5906 -7.6483 -v -11.7538 0.5906 -7.4652 -v -9.4552 0.5906 -8.0327 -v 9.4660 0.5906 -8.0327 -v -5.1041 0.5906 -7.3262 -v -4.7067 0.5906 -8.0086 -v -4.6851 0.5906 -8.0540 -v -8.1398 0.5906 -8.0086 -v -8.1182 0.5906 -8.0540 -v -10.9823 0.5906 -8.0086 -v -10.9607 0.5906 -8.0540 -v 5.0975 -0.5906 -7.5550 -v 12.3494 -0.5906 -7.5550 -v 3.5070 0.5906 -7.9571 -v 3.5239 0.5906 -8.0077 -v 3.5321 -0.5906 -8.0286 -v 10.7589 0.5906 -7.9571 -v 10.7758 0.5906 -8.0077 -v 10.7840 -0.5906 -8.0286 -v 11.3422 0.5906 -8.2213 -v -0.5127 0.5906 -7.9571 -v -0.4958 0.5906 -8.0077 -v -0.4876 -0.5906 -8.0286 -v 4.0903 0.5906 -8.2213 -v -10.7759 0.5906 -8.0485 -v 6.4132 -0.5906 -7.4570 -v 6.5133 -0.5906 -7.5853 -v 4.8366 -0.5906 -7.4470 -v 12.0886 -0.5906 -7.4470 -v -8.8588 0.5906 -7.6171 -v 0.6723 -0.5906 -8.0181 -v 7.5345 -0.5906 -8.0181 -v -1.3452 -0.5906 -8.4520 -v -8.8593 -0.5906 -7.6180 -v 6.4511 0.5906 -7.4113 -v -9.2798 -0.5906 -7.4318 -v -9.4197 -0.5906 -7.5143 -v 1.6490 -0.5906 -7.6273 -v 8.5113 -0.5906 -7.6273 -v -8.5498 0.5906 -7.8848 -v -8.5155 0.5906 -7.5151 -v -8.5017 -0.5906 -7.5464 -v 6.6092 0.5906 -8.5967 -v -9.9071 0.5906 -7.3866 -v 9.0141 0.5906 -7.3866 -v -11.8273 0.5906 -7.7041 -v -11.7745 0.5906 -7.6881 -v -8.9083 -0.5906 -7.7760 -v -8.9714 -0.5906 -7.7353 -v -8.9532 0.5906 -7.7486 -v -11.7503 0.5906 -7.2351 -v -11.7839 0.5906 -7.1876 -v 11.5715 0.5906 -7.5966 -v 11.5544 0.5906 -7.5479 -v 11.5463 -0.5906 -7.5279 -v 4.3196 0.5906 -7.5966 -v 4.3025 0.5906 -7.5479 -v 4.2943 -0.5906 -7.5279 -v 0.2999 0.5906 -7.5966 -v 0.2828 0.5906 -7.5479 -v 0.2746 -0.5906 -7.5279 -v -1.2363 0.5906 -8.4496 -v 3.1557 -0.5906 -8.0930 -v -3.2183 -0.5906 -8.0930 -v -6.0609 -0.5906 -8.0930 -v -6.2982 0.5906 -7.3155 -v -6.3591 0.5906 -7.3359 -v -3.4557 0.5906 -7.3155 -v -3.5166 0.5906 -7.3359 -v 2.9183 0.5906 -7.3155 -v 2.8574 0.5906 -7.3359 -v 2.6361 0.5906 -7.9587 -v 2.6524 0.5906 -8.0089 -v 2.6603 -0.5906 -8.0297 -v -6.5805 0.5906 -7.9587 -v -6.5642 0.5906 -8.0089 -v -6.5563 -0.5906 -8.0297 -v -3.7379 0.5906 -7.9587 -v -3.7217 0.5906 -8.0089 -v -3.7137 -0.5906 -8.0297 -v 1.9445 -0.5906 -7.3321 -v 8.8067 -0.5906 -7.3321 -v -9.9508 -0.5906 -8.1916 -v 8.9705 -0.5906 -8.1916 -v -0.1835 0.5906 -7.4408 -v 11.0881 0.5906 -7.4408 -v 3.8362 0.5906 -7.4408 -v 6.9856 -0.5906 -8.5324 -v 6.9621 0.5906 -8.5470 -v 12.0680 0.5906 -7.4557 -v 4.8160 0.5906 -7.4557 -v 4.8065 0.5906 -7.3288 -v 12.0585 0.5906 -7.3288 -v -5.4665 -0.5906 -7.3756 -v -5.4179 -0.5906 -7.4773 -v -4.9363 0.5906 -7.5694 -v -4.9506 0.5906 -7.4922 -v -4.9477 -0.5906 -7.4979 -v 0.3079 -0.5906 -7.6253 -v 0.1293 -0.5906 -7.5852 -v 11.5796 -0.5906 -7.6253 -v 11.4010 -0.5906 -7.5852 -v 4.3276 -0.5906 -7.6253 -v 4.1490 -0.5906 -7.5852 -v 2.6457 0.5906 -7.5727 -v 2.6277 0.5906 -7.6436 -v 2.6279 -0.5906 -7.6395 -v -6.5708 0.5906 -7.5727 -v -6.5889 0.5906 -7.6436 -v -6.5886 -0.5906 -7.6395 -v -3.7283 0.5906 -7.5727 -v -3.7463 0.5906 -7.6436 -v -3.7461 -0.5906 -7.6395 -v 2.8051 -0.5906 -7.9772 -v 2.6285 -0.5906 -7.9293 -v -6.5881 -0.5906 -7.9293 -v -6.4114 -0.5906 -7.9772 -v -3.5689 -0.5906 -7.9772 -v -3.7455 -0.5906 -7.9293 -v 4.0627 0.5906 -7.3240 -v 11.3147 0.5906 -7.3240 -v 0.0430 0.5906 -7.3240 -v 2.9477 -0.5906 -8.2501 -v 2.8833 0.5906 -8.2335 -v 2.9556 -0.5906 -8.1185 -v -3.4185 -0.5906 -8.1185 -v -3.4263 -0.5906 -8.2501 -v -3.4908 0.5906 -8.2335 -v -6.2688 -0.5906 -8.2501 -v -6.3333 0.5906 -8.2335 -v -6.2610 -0.5906 -8.1185 -v -5.0211 -0.5906 -7.3752 -v 12.4309 0.5906 -7.3770 -v 12.4013 0.5906 -7.3547 -v 5.1789 0.5906 -7.3770 -v 5.1493 0.5906 -7.3547 -v 3.6580 0.5906 -8.1795 -v -0.3617 0.5906 -8.1795 -v 10.9100 0.5906 -8.1795 -v 6.4046 0.5906 -8.4847 -v 6.6634 0.5906 -7.4404 -v 3.2363 0.5906 -8.2008 -v -3.1377 0.5906 -8.2008 -v -5.9802 0.5906 -8.2008 -v 5.0936 0.5906 -7.5453 -v 12.3456 0.5906 -7.5453 -v -7.8170 -0.5906 -8.1189 -v -7.8505 0.5906 -8.2460 -v -4.4174 0.5906 -8.2460 -v -4.3839 -0.5906 -8.1189 -v -10.6930 0.5906 -8.2460 -v -10.6595 -0.5906 -8.1189 -v 0.6151 0.5906 -8.2008 -v 7.4773 0.5906 -8.2008 -v 3.1354 -0.5906 -7.3116 -v -3.2386 -0.5906 -7.3116 -v 6.4147 0.5906 -8.0803 -v -8.7226 0.5906 -8.1256 -v 11.9396 0.5906 -7.6261 -v 4.6876 0.5906 -7.6261 -v 10.7742 -0.5906 -7.5512 -v -0.4975 -0.5906 -7.5512 -v 3.5222 -0.5906 -7.5512 -v 2.8352 -0.5906 -7.5281 -v -6.3813 -0.5906 -7.5282 -v -3.5388 -0.5906 -7.5282 -v -4.1963 0.5906 -7.4584 -v -10.4719 0.5906 -7.4584 -v -7.6294 0.5906 -7.4584 -v -8.5237 -0.5906 -7.8954 -v -8.5146 0.5906 -7.9010 -v 1.6722 0.5906 -7.3799 -v 8.5344 0.5906 -7.3799 -v -9.0250 0.5906 -7.4705 -v 0.8529 0.5906 -8.1218 -v 6.3545 0.5906 -7.5810 -v 6.3372 -0.5906 -7.6449 -v 7.8443 0.5906 -8.0811 -v 7.8845 0.5906 -8.0474 -v 0.9821 0.5906 -8.0811 -v 1.0223 0.5906 -8.0474 -v 6.6766 -0.5906 -7.4361 -v 6.6099 -0.5906 -7.3154 -v -11.8571 0.5906 -7.7098 -v -1.0766 -0.5906 -8.5130 -v -9.6888 0.5906 -8.2545 -v 9.2324 0.5906 -8.2545 -v 6.4158 0.5906 -8.4975 -v 10.0989 0.5906 -8.0431 -v -9.5462 0.5906 -7.4362 -v 9.3751 0.5906 -7.4362 -v -11.8776 0.5906 -7.1339 -v 10.0751 -0.5906 -8.2412 -v -11.8883 -0.5906 -7.1311 -v -11.8858 0.5906 -7.1326 -v 10.7631 0.5906 -7.5854 -v 3.5112 0.5906 -7.5854 -v -0.5085 0.5906 -7.5854 -v -9.0398 0.5906 -7.6111 -v 0.6606 0.5906 -7.9677 -v 0.6611 -0.5906 -7.9789 -v 6.3590 -0.5906 -8.3694 -v 5.1017 0.5906 -7.5780 -v 12.3537 0.5906 -7.5780 -v -4.1885 -0.5906 -8.0999 -v -7.6216 -0.5906 -8.0999 -v -10.4642 -0.5906 -8.0999 -v 1.0750 0.5906 -7.9379 -v 7.9372 0.5906 -7.9379 -v -5.5080 0.5906 -7.6175 -v -5.5038 -0.5906 -7.5957 -v -8.5962 0.5906 -7.4456 -v -9.4691 0.5906 -7.3129 -v 9.4521 0.5906 -7.3129 -v -5.1521 0.5906 -7.3115 -v -4.1909 -0.5906 -7.3180 -v -7.6240 -0.5906 -7.3180 -v -10.4665 -0.5906 -7.3180 -v 6.5329 0.5906 -8.1919 -v 3.4991 -0.5906 -7.9274 -v 3.6776 -0.5906 -7.9716 -v -0.3421 -0.5906 -7.9716 -v -0.5206 -0.5906 -7.9274 -v 10.7510 -0.5906 -7.9274 -v 10.9296 -0.5906 -7.9716 -v 5.6432 0.5906 -6.9853 -v 5.6124 0.5906 -7.0074 -v 4.3086 0.5906 -7.9960 -v 4.3276 -0.5906 -7.9284 -v 0.2889 0.5906 -7.9960 -v 0.3079 -0.5906 -7.9284 -v 11.5606 0.5906 -7.9960 -v 11.5796 -0.5906 -7.9284 -v -11.8578 -0.5906 -7.7113 -v -11.8497 -0.5906 -7.5489 -v -8.4030 0.5906 -7.4086 -v -8.3816 0.5906 -7.4404 -v -8.8427 -0.5906 -7.4598 -v -9.5613 0.5906 -8.1097 -v -9.6056 0.5906 -8.1240 -v 9.3599 0.5906 -8.1097 -v 9.3156 0.5906 -8.1240 -v -8.9069 0.5906 -7.3454 -v -8.8665 0.5906 -7.3282 -v 10.7487 0.5906 -7.6445 -v -0.5229 0.5906 -7.6445 -v 3.4968 0.5906 -7.6445 -v -8.5611 0.5906 -7.8811 -v 11.9588 -0.5906 -7.5581 -v 4.7068 -0.5906 -7.5581 -v -9.4219 0.5906 -7.9757 -v 9.4993 0.5906 -7.9757 -v -9.0365 0.5906 -7.6244 -v 9.1249 0.5906 -7.3293 -v -9.7964 0.5906 -7.3293 -v 10.8784 0.5906 -7.4028 -v -9.8115 0.5906 -7.7305 -v -9.7021 0.5906 -7.8431 -v 9.1097 0.5906 -7.7305 -v 9.2192 0.5906 -7.8431 -v -8.8355 0.5906 -8.0858 -v -7.5706 -0.5906 -7.5034 -v -10.4132 -0.5906 -7.5034 -v -4.1376 -0.5906 -7.5034 -v 6.9562 -0.5906 -7.5820 -v -9.0032 0.5906 -7.4301 -v -9.0200 0.5906 -7.4591 -v 9.0738 0.5906 -8.0742 -v -9.8475 0.5906 -8.0742 -v 6.8571 -0.5906 -8.2085 -v 6.8108 -0.5906 -8.0975 -v 5.2573 0.5906 -7.5303 -v 12.5093 0.5906 -7.5303 -v 10.8908 0.5906 -8.1657 -v 10.9292 0.5906 -8.1933 -v 10.9061 -0.5906 -8.1784 -v 3.6389 0.5906 -8.1657 -v 3.6772 0.5906 -8.1933 -v 3.6541 -0.5906 -8.1784 -v -0.3808 0.5906 -8.1657 -v -0.3425 0.5906 -8.1933 -v -0.3656 -0.5906 -8.1784 -v -7.4518 0.5906 -7.4262 -v -7.4864 0.5906 -7.3931 -v -4.0187 0.5906 -7.4262 -v -4.0533 0.5906 -7.3931 -v -10.2943 0.5906 -7.4262 -v -10.3289 0.5906 -7.3931 -v 6.3550 -0.5906 -7.5778 -v -5.3077 0.5906 -7.4370 -v 6.9404 0.5906 -7.3834 -v -6.1077 -0.5906 -7.4401 -v -6.0123 -0.5906 -7.3340 -v -3.1698 -0.5906 -7.3340 -v -3.2652 -0.5906 -7.4401 -v 3.1088 -0.5906 -7.4401 -v 3.2042 -0.5906 -7.3340 -v 3.1897 0.5906 -8.0640 -v -3.1843 0.5906 -8.0640 -v -6.0268 0.5906 -8.0640 -v -8.1176 0.5906 -7.5098 -v -10.9601 0.5906 -7.5098 -v -4.6845 0.5906 -7.5098 -v 9.1986 0.5906 -7.7146 -v 9.1177 0.5906 -7.7288 -v -9.7226 0.5906 -7.7146 -v -9.8035 0.5906 -7.7288 -v 11.3991 -0.5906 -8.1932 -v 11.3249 -0.5906 -8.0729 -v 4.0729 -0.5906 -8.0729 -v 4.1471 -0.5906 -8.1932 -v 0.0532 -0.5906 -8.0729 -v 0.1274 -0.5906 -8.1932 -v -1.1155 0.5906 -8.5536 -v -1.0875 0.5906 -8.5249 -v -8.8138 0.5906 -7.3128 -v -8.8202 -0.5906 -7.3140 -v 9.3809 0.5906 -8.1001 -v -9.5404 0.5906 -8.1001 -v 8.5751 0.5906 -7.3373 -v 8.6014 0.5906 -7.3205 -v 1.7129 0.5906 -7.3373 -v 1.7392 0.5906 -7.3205 -v 8.9056 0.5906 -7.8800 -v -10.0156 0.5906 -7.8800 -v 7.6520 -0.5906 -8.2560 -v 0.7898 -0.5906 -8.2560 -v 6.5210 0.5906 -7.9704 -v 6.5210 -0.5906 -7.9705 -v -8.8343 -0.5906 -8.0875 -v -9.7601 0.5906 -7.4530 -v 9.1612 0.5906 -7.4530 -v 9.6319 0.5906 -7.4172 -v -9.2894 0.5906 -7.4172 -v 10.1001 0.5906 -8.2446 -v 6.9656 0.5906 -8.3022 -v 6.8092 0.5906 -7.3121 -v -8.3525 0.5906 -7.8270 -v 3.2338 -0.5906 -8.2035 -v -3.1402 -0.5906 -8.2035 -v -5.9827 -0.5906 -8.2035 -v 9.2580 0.5906 -7.7068 -v -9.6633 0.5906 -7.7068 -v -0.3012 -0.5906 -8.2159 -v 10.9705 -0.5906 -8.2159 -v 3.7185 -0.5906 -8.2159 -v 7.3677 0.5906 -8.0134 -v 7.3776 0.5906 -8.0603 -v 0.5055 0.5906 -8.0134 -v 0.5154 0.5906 -8.0603 -v 3.3239 0.5906 -7.4266 -v -3.0502 0.5906 -7.4266 -v 6.8125 0.5906 -8.4675 -v -9.7696 0.5906 -7.3214 -v 9.1517 0.5906 -7.3214 -v 7.8467 -0.5906 -8.0800 -v 0.9845 -0.5906 -8.0800 -v 7.7151 0.5906 -8.1218 -v 8.9271 -0.5906 -8.1469 -v -9.9942 -0.5906 -8.1469 -v 12.1036 0.5906 -7.3135 -v 4.8516 0.5906 -7.3135 -v -4.5721 -0.5906 -7.6440 -v -8.0052 -0.5906 -7.6440 -v -10.8477 -0.5906 -7.6440 -v 5.2583 0.5906 -7.5384 -v 5.2492 0.5906 -7.4960 -v 6.9711 -0.5906 -7.9190 -v 12.5103 0.5906 -7.5384 -v 12.5012 0.5906 -7.4960 -v -7.5880 0.5906 -8.0766 -v -4.1550 0.5906 -8.0766 -v -10.4306 0.5906 -8.0766 -v 0.6627 0.5906 -7.9846 -v 7.5249 0.5906 -7.9846 -v -8.4755 -0.5906 -7.9474 -v -8.4283 -0.5906 -7.3823 -v -10.4287 -0.5906 -8.0757 -v -10.3413 -0.5906 -8.1916 -v -4.1531 -0.5906 -8.0757 -v -4.0657 -0.5906 -8.1916 -v -7.4987 -0.5906 -8.1916 -v -7.5862 -0.5906 -8.0757 -v 10.1680 0.5906 -8.1036 -v 10.1534 -0.5906 -8.1020 -v 4.6867 -0.5906 -7.6265 -v 11.9386 -0.5906 -7.6265 -v -11.7476 0.5906 -7.4541 -v -8.3119 0.5906 -7.9343 -v -6.2957 -0.5906 -7.3143 -v -6.2594 -0.5906 -7.4405 -v -3.4169 -0.5906 -7.4405 -v -3.4532 -0.5906 -7.3143 -v 2.9572 -0.5906 -7.4405 -v 2.9208 -0.5906 -7.3143 -v 9.9849 0.5906 -8.1904 -v 9.9496 0.5906 -8.1184 -v 9.9477 -0.5906 -8.1082 -v -4.5537 0.5906 -8.1931 -v -7.9868 0.5906 -8.1931 -v -10.8293 0.5906 -8.1931 -v 6.4403 0.5906 -8.5216 -v 6.7876 0.5906 -8.4728 -v -6.4245 -0.5906 -7.6225 -v -6.5702 -0.5906 -7.5689 -v -3.7277 -0.5906 -7.5689 -v -3.5820 -0.5906 -7.6225 -v 2.6463 -0.5906 -7.5689 -v 2.7921 -0.5906 -7.6225 -v -6.4534 0.5906 -8.1660 -v 2.7631 0.5906 -8.1660 -v -3.6109 0.5906 -8.1660 -v 10.9357 0.5906 -7.9838 -v 0.1667 0.5906 -7.3920 -v 4.1863 0.5906 -7.3920 -v 11.4383 0.5906 -7.3920 -v -4.5116 0.5906 -7.3429 -v -4.5527 0.5906 -7.3663 -v -10.7872 0.5906 -7.3429 -v -10.8283 0.5906 -7.3663 -v -7.9446 0.5906 -7.3429 -v -7.9858 0.5906 -7.3663 -v 7.1112 -0.5906 -8.3406 -v 5.0069 0.5906 -7.4526 -v 5.0319 0.5906 -7.3089 -v 12.2589 0.5906 -7.4526 -v 12.2839 0.5906 -7.3089 -v 5.6988 0.5906 -7.1760 -v 5.7052 -0.5906 -7.1530 -v 6.9432 -0.5906 -7.3842 -v -7.3570 0.5906 -7.6022 -v -7.3631 -0.5906 -7.5794 -v -3.9239 0.5906 -7.6022 -v -3.9300 -0.5906 -7.5794 -v -10.1995 0.5906 -7.6022 -v -10.2056 -0.5906 -7.5794 -v -4.1309 0.5906 -8.0537 -v -7.5640 0.5906 -8.0537 -v -10.4065 0.5906 -8.0537 -v 10.7469 0.5906 -7.9021 -v 3.4949 0.5906 -7.9021 -v -0.5248 0.5906 -7.9021 -v 9.0454 0.5906 -7.9732 -v -9.8759 0.5906 -7.9732 -v 8.5952 -0.5906 -7.3232 -v 1.7330 -0.5906 -7.3232 -v -8.4957 -0.5906 -7.7346 -v -9.5210 0.5906 -8.2107 -v 9.4003 0.5906 -8.2107 -v -9.7564 -0.5906 -8.2557 -v 9.1648 -0.5906 -8.2557 -v -7.8039 0.5906 -7.3039 -v -4.3709 0.5906 -7.3039 -v -10.6465 0.5906 -7.3039 -v -11.6564 0.5906 -7.6129 -v 12.4326 -0.5906 -7.3780 -v 12.3128 -0.5906 -7.4893 -v 5.1806 -0.5906 -7.3780 -v 5.0609 -0.5906 -7.4893 -v 11.2843 0.5906 -7.4578 -v 4.0323 0.5906 -7.4578 -v 0.0126 0.5906 -7.4578 -v -10.8053 0.5906 -8.0108 -v -8.1685 0.5906 -7.6631 -v -4.7354 0.5906 -7.6631 -v -11.0110 0.5906 -7.6631 -v 0.5835 -0.5906 -8.1774 -v 7.4457 -0.5906 -8.1774 -v 6.9342 -0.5906 -8.3826 -v 6.9572 0.5906 -7.3982 -v -10.8142 0.5906 -7.9973 -v 11.4864 0.5906 -8.1215 -v 4.2344 0.5906 -8.1215 -v 0.2147 0.5906 -8.1215 -v -9.2492 0.5906 -7.5606 -v 9.6721 0.5906 -7.5606 -v -8.0918 -0.5906 -8.0953 -v -4.6588 -0.5906 -8.0953 -v -10.9344 -0.5906 -8.0953 -v -5.1243 0.5906 -7.5045 -v 4.6930 0.5906 -7.4112 -v 11.9449 0.5906 -7.4112 -v 11.4159 -0.5906 -7.9281 -v 4.1639 -0.5906 -7.9281 -v 0.1442 -0.5906 -7.9281 -v 5.0456 0.5906 -7.4762 -v 12.2976 0.5906 -7.4762 -v 9.0695 -0.5906 -7.5647 -v -9.8517 -0.5906 -7.5647 -v -9.5535 0.5906 -7.3027 -v 9.3677 0.5906 -7.3027 -v -8.5293 0.5906 -7.3281 -v 3.1920 -0.5906 -8.0627 -v -6.0246 -0.5906 -8.0627 -v -3.1821 -0.5906 -8.0627 -v -11.6848 0.5906 -7.0523 -v -9.5440 0.5906 -8.2211 -v 9.3772 0.5906 -8.2211 -v -9.0443 -0.5906 -7.5731 -v -1.2151 0.5906 -8.6017 -v -11.5981 0.5906 -7.1568 -v 9.6734 0.5906 -7.5938 -v -5.3357 0.5906 -7.3116 -v 11.5837 0.5906 -7.6491 -v 4.3318 0.5906 -7.6491 -v 0.3121 0.5906 -7.6491 -v -9.6782 0.5906 -8.1336 -v 9.2430 0.5906 -8.1336 -v 2.6245 0.5906 -7.9042 -v -6.5921 0.5906 -7.9042 -v -3.7496 0.5906 -7.9042 -v -11.8868 0.5906 -7.7154 -v 0.2948 0.5906 -7.9793 -v 4.3145 0.5906 -7.9793 -v 11.5665 0.5906 -7.9793 -v -9.3075 -0.5906 -7.3929 -v 9.6138 -0.5906 -7.3929 -v 5.5507 -0.5906 -7.1033 -v 7.3668 -0.5906 -8.0109 -v 0.5046 -0.5906 -8.0109 -v -9.7503 0.5906 -8.1286 -v 9.1710 0.5906 -8.1286 -v 10.9148 -0.5906 -7.6267 -v -0.3568 -0.5906 -7.6267 -v 3.6629 -0.5906 -7.6267 -v 5.5541 0.5906 -7.0945 -v -9.0025 -0.5906 -7.4287 -v -8.8444 0.5906 -8.0794 -v 5.2595 -0.5906 -7.5422 -v 12.5115 -0.5906 -7.5421 -v 6.8918 0.5906 -8.5801 -v 10.7833 0.5906 -7.5317 -v 3.5313 0.5906 -7.5317 -v -0.4884 0.5906 -7.5317 -v -11.5678 -0.5906 -7.4532 -v 8.9834 0.5906 -7.7880 -v -9.9378 0.5906 -7.7880 -v 5.7268 -0.5906 -6.9573 -v -9.5902 0.5906 -7.8252 -v 9.3310 0.5906 -7.8252 -v 5.2028 0.5906 -7.4023 -v 12.4548 0.5906 -7.4023 -v -9.2431 0.5906 -8.0634 -v -9.2465 -0.5906 -7.9619 -v -9.8292 0.5906 -7.8880 -v 9.0921 0.5906 -7.8880 -v 9.3977 0.5906 -7.3050 -v -9.5236 0.5906 -7.3050 -v -10.8142 -0.5906 -7.9973 -v -5.4965 0.5906 -7.5769 -v 6.4598 0.5906 -8.1364 -v 9.5041 0.5906 -7.9633 -v -9.4172 0.5906 -7.9633 -v 9.6796 -0.5906 -8.0907 -v 9.6837 0.5906 -8.1256 -v -3.9879 0.5906 -7.4640 -v -10.2635 0.5906 -7.4640 -v -7.4210 0.5906 -7.4640 -v 9.6724 -0.5906 -7.5564 -v 6.8497 0.5906 -7.3256 -v -4.1734 0.5906 -7.3243 -v -7.6065 0.5906 -7.3243 -v -10.4490 0.5906 -7.3243 -v -8.7873 0.5906 -7.4382 -# 3114 vertices - -vn 1.0000 -0.0013 -0.0024 -vn 0.9994 -0.0003 0.0358 -vn -0.9997 0.0002 0.0251 -vn -0.9997 -0.0003 0.0254 -vn 1.0000 -0.0000 -0.0005 -vn -1.0000 0.0018 0.0028 -vn -0.7040 0.0011 0.7102 -vn 0.2861 0.0006 0.9582 -vn 0.9997 -0.0001 0.0249 -vn -0.3123 0.0004 -0.9500 -vn 0.0041 0.0009 1.0000 -vn -0.8881 0.0006 0.4597 -vn 1.0000 -0.0002 0.0017 -vn 0.2735 0.0003 0.9619 -vn -0.2569 -0.0004 -0.9664 -vn -0.9334 0.0000 -0.3587 -vn 1.0000 0.0005 0.0043 -vn 0.9997 -0.0008 0.0254 -vn 0.9996 -0.0003 -0.0270 -vn -0.9997 -0.0003 0.0264 -vn 0.9998 0.0002 -0.0213 -vn -0.9987 -0.0016 0.0513 -vn -0.9987 -0.0016 0.0514 -vn 0.9996 -0.0003 -0.0271 -vn 0.9668 -0.0012 0.2554 -vn -0.6022 0.0008 0.7983 -vn -0.5969 0.0005 0.8023 -vn 0.9997 -0.0003 -0.0255 -vn -0.9990 -0.0012 0.0457 -vn 0.9641 -0.0004 0.2656 -vn 0.9641 -0.0004 0.2657 -vn 0.2615 -0.0010 -0.9652 -vn -0.1360 0.0004 0.9907 -vn -0.9992 0.0031 -0.0391 -vn 0.0000 -0.0000 -1.0000 -vn 1.0000 0.0019 -0.0020 -vn -0.8439 -0.0000 -0.5366 -vn -0.8439 0.0000 -0.5365 -vn -0.8439 -0.0000 -0.5365 -vn -0.2626 0.0011 -0.9649 -vn -1.0000 0.0000 0.0000 -vn 0.8739 0.0000 -0.4862 -vn -0.0616 -0.0007 0.9981 -vn -0.0548 0.0011 -0.9985 -vn -0.2179 0.0003 0.9760 -vn 0.7174 -0.0011 0.6967 -vn -0.7159 -0.0011 -0.6982 -vn -0.5646 -0.0000 0.8254 -vn 0.5596 0.0000 -0.8287 -vn -0.5646 0.0000 0.8254 -vn 0.2435 -0.0013 -0.9699 -vn 0.0293 -0.0002 0.9996 -vn 0.1553 -0.0008 -0.9879 -vn -0.9580 0.0000 0.2868 -vn -0.2794 0.0008 -0.9602 -vn -0.0062 -0.0008 1.0000 -vn 0.0111 -0.0001 -0.9999 -vn -0.9591 -0.0012 -0.2830 -vn 0.9848 -0.0011 0.1736 -vn -0.0483 -0.0003 0.9988 -vn 0.1275 0.0005 -0.9918 -vn -0.2511 -0.0011 0.9680 -vn 0.0290 -0.0001 -0.9996 -vn -0.9348 0.0000 -0.3552 -vn 0.9371 0.0000 -0.3490 -vn -0.8182 0.0009 -0.5750 -vn -0.0011 -0.0000 -1.0000 -vn 0.9071 0.0002 0.4210 -vn 0.0011 0.0003 1.0000 -vn -0.3005 -0.0012 0.9538 -vn -0.3751 -0.0005 -0.9270 -vn 1.0000 -0.0000 0.0011 -vn -1.0000 0.0010 -0.0032 -vn 0.0323 -0.0012 0.9995 -vn 0.3654 -0.0005 0.9309 -vn 0.1437 -0.0008 -0.9896 -vn 0.4799 0.0006 -0.8773 -vn -0.0060 0.0018 1.0000 -vn -0.2610 0.0006 0.9654 -vn -0.3841 -0.0010 -0.9233 -vn -0.2610 0.0006 0.9653 -vn -1.0000 -0.0000 -0.0012 -vn 1.0000 0.0004 0.0020 -vn 0.9372 0.0002 -0.3488 -vn -1.0000 0.0000 -0.0009 -vn 0.0467 -0.0011 0.9989 -vn 0.0000 -1.0000 -0.0000 -vn -0.3206 0.0009 -0.9472 -vn -0.5758 -0.0018 0.8176 -vn -0.3205 0.0009 -0.9472 -vn -0.2997 -0.0000 0.9540 -vn -0.2997 0.0000 0.9540 -vn 0.4971 -0.0000 0.8677 -vn 0.0146 0.0002 -0.9999 -vn -0.0375 0.0017 -0.9993 -vn -0.2584 -0.0014 0.9660 -vn 0.9995 0.0005 0.0315 -vn 1.0000 0.0000 0.0000 -vn -1.0000 0.0004 0.0055 -vn 1.0000 0.0000 -0.0086 -vn 0.3487 -0.0014 0.9372 -vn 0.2855 0.0013 -0.9584 -vn 0.4944 -0.0007 0.8692 -vn 0.0453 -0.0004 0.9990 -vn 0.3103 0.0003 -0.9507 -vn 0.3102 0.0003 -0.9507 -vn 0.3452 0.0000 -0.9385 -vn 0.0114 -0.0011 -0.9999 -vn -0.0019 0.0000 1.0000 -vn 0.0022 0.0000 -1.0000 -vn -0.0460 -0.0004 -0.9989 -vn -0.1283 0.0006 0.9917 -vn -0.2932 -0.0008 -0.9561 -vn -0.0313 -0.0005 -0.9995 -vn 0.2478 0.0008 -0.9688 -vn 0.0000 -0.0000 1.0000 -vn -0.1651 -0.0006 -0.9863 -vn 0.0001 0.0000 -1.0000 -vn 0.0463 -0.0004 0.9989 -vn -0.5569 -0.0016 -0.8306 -vn 0.3466 -0.0000 0.9380 -vn 0.8047 -0.0002 -0.5936 -vn -0.0394 -0.0002 0.9992 -vn 0.1895 0.0005 -0.9819 -vn 0.9854 0.0019 -0.1701 -vn 0.4275 -0.0000 0.9040 -vn -0.2962 -0.0005 -0.9551 -vn 0.8316 -0.0000 0.5554 -vn 1.0000 -0.0010 -0.0037 -vn -1.0000 0.0019 0.0014 -vn 0.0000 1.0000 0.0000 -vn -0.3826 -0.0006 0.9239 -vn -0.2303 0.0005 0.9731 -vn -0.3573 0.0008 0.9340 -vn 1.0000 0.0000 0.0005 -vn -0.0018 -0.0000 1.0000 -vn -0.9803 -0.0018 -0.1973 -vn 0.1722 0.0010 0.9851 -vn 1.0000 0.0000 -0.0015 -vn 0.5855 0.0007 -0.8106 -vn -0.9997 0.0002 0.0224 -vn 1.0000 -0.0000 -0.0000 -vn -1.0000 0.0003 -0.0012 -vn -1.0000 -0.0000 0.0016 -vn 1.0000 -0.0003 0.0011 -vn -0.8394 0.0000 -0.5436 -vn 0.9408 -0.0000 0.3389 -vn -0.4207 -0.0011 -0.9072 -vn 1.0000 0.0005 0.0014 -vn -0.0387 0.0009 0.9992 -vn -0.9375 -0.0006 -0.3481 -vn -0.4451 -0.0007 0.8955 -vn 1.0000 -0.0002 0.0008 -vn -1.0000 0.0000 -0.0005 -vn 1.0000 -0.0002 0.0009 -vn -1.0000 -0.0000 -0.0005 -vn -0.9499 -0.0005 0.3124 -vn -0.5635 0.0000 0.8261 -vn 0.6767 -0.0008 0.7363 -vn 0.5413 -0.0006 -0.8409 -vn 0.5413 -0.0006 -0.8408 -vn 0.6767 0.0005 0.7363 -vn 0.9994 -0.0006 0.0357 -vn 0.5765 0.0010 -0.8171 -vn 1.0000 -0.0000 0.0012 -vn 1.0000 -0.0000 0.0017 -vn 1.0000 0.0000 -0.0010 -vn -1.0000 0.0000 -0.0022 -vn 0.2620 0.0005 0.9651 -vn 0.6695 0.0010 0.7428 -vn 0.6133 0.0014 0.7898 -vn -0.9398 0.0000 0.3417 -vn 1.0000 -0.0008 -0.0027 -vn -0.0023 -0.0003 -1.0000 -vn -0.9398 -0.0000 0.3417 -vn -0.0003 -0.0003 -1.0000 -vn 0.0057 0.0011 -1.0000 -vn -0.5867 -0.0009 0.8098 -vn -0.5868 -0.0008 0.8098 -vn 0.8019 -0.0018 -0.5974 -vn -1.0000 -0.0009 0.0036 -vn -0.6906 -0.0010 0.7233 -vn 1.0000 -0.0009 -0.0036 -vn -1.0000 -0.0000 -0.0000 -vn -0.5271 0.0004 -0.8498 -vn 0.9334 0.0000 -0.3587 -vn 0.9334 -0.0000 -0.3587 -vn -0.9443 -0.0006 0.3291 -vn 0.9897 0.0000 0.1431 -vn -1.0000 -0.0004 -0.0014 -vn -0.9926 0.0000 -0.1216 -vn 0.0777 -0.0005 0.9970 -vn -0.0030 -0.0006 -1.0000 -vn 0.9407 0.0002 0.3392 -vn -0.3618 -0.0008 -0.9322 -vn 0.4821 -0.0008 0.8761 -vn 0.9335 0.0000 -0.3587 -vn -0.6540 0.0003 0.7565 -vn -0.9999 0.0012 0.0164 -vn -0.9745 0.0000 -0.2246 -vn -0.5921 -0.0015 -0.8059 -vn -0.7743 -0.0006 0.6328 -vn -0.8717 0.0016 -0.4901 -vn 0.9597 0.0005 0.2812 -vn -0.9959 0.0011 0.0904 -vn 0.1288 0.0000 -0.9917 -vn 0.1222 -0.0000 0.9925 -vn 0.7085 0.0006 -0.7057 -vn -0.8074 0.0019 0.5901 -vn -0.8073 0.0019 0.5901 -vn -0.9999 -0.0001 0.0126 -vn -0.9999 -0.0001 0.0125 -vn -0.8518 0.0007 -0.5239 -vn 0.7711 -0.0013 -0.6367 -vn 0.6370 0.0015 0.7708 -vn 0.7448 0.0000 -0.6673 -vn 0.7448 -0.0000 -0.6673 -vn 0.9898 -0.0001 0.1424 -vn -0.7850 0.0012 0.6195 -vn 0.1305 0.0000 0.9915 -vn 0.4353 -0.0006 -0.9003 -vn 0.1288 -0.0000 0.9917 -vn 0.8132 -0.0000 0.5820 -vn 0.1305 0.0000 -0.9915 -vn 0.9303 0.0009 -0.3668 -vn -0.1521 -0.0000 0.9884 -vn 0.9995 -0.0008 -0.0329 -vn -0.9995 -0.0008 0.0326 -vn -0.1288 0.0000 -0.9917 -vn 0.0000 0.0000 -1.0000 -vn 0.0000 -0.0003 -1.0000 -vn 0.0207 0.0006 -0.9998 -vn -0.0317 -0.0007 0.9995 -vn 0.6939 0.0009 -0.7200 -vn 0.8848 -0.0015 -0.4660 -vn 0.9426 0.0000 -0.3339 -vn 0.9426 -0.0000 -0.3339 -vn 0.9442 0.0009 -0.3294 -vn 0.6793 -0.0013 -0.7339 -vn 0.6793 -0.0013 -0.7338 -vn 0.7786 -0.0013 0.6275 -vn 0.9855 -0.0000 -0.1697 -vn 0.5974 -0.0009 -0.8019 -vn -0.7114 -0.0000 0.7028 -vn 0.6981 0.0000 -0.7160 -vn 0.3751 -0.0011 0.9270 -vn -0.5875 -0.0010 0.8092 -vn -0.9491 -0.0007 -0.3148 -vn -0.9491 -0.0007 -0.3149 -vn 0.9849 -0.0004 -0.1733 -vn -0.8515 -0.0009 -0.5244 -vn 0.2498 -0.0008 -0.9683 -vn -0.1288 -0.0000 -0.9917 -vn 0.5512 -0.0017 0.8344 -vn 0.8764 -0.0005 -0.4816 -vn 0.8764 -0.0005 -0.4817 -vn -0.9985 -0.0002 0.0549 -vn 0.8800 0.0007 -0.4750 -vn 0.2592 -0.0009 -0.9658 -vn -0.1008 0.0008 -0.9949 -vn 0.2968 -0.0010 0.9549 -vn -0.7656 -0.0000 -0.6434 -vn -0.7656 0.0000 -0.6434 -vn 0.5800 0.0006 0.8146 -vn -0.5773 -0.0007 -0.8165 -vn 0.5601 -0.0000 0.8284 -vn 0.5805 -0.0006 -0.8142 -vn 0.5709 -0.0006 0.8210 -vn 0.7079 0.0004 -0.7063 -vn 0.4790 -0.0005 0.8778 -vn -0.0291 0.0006 0.9996 -vn -0.3069 -0.0010 -0.9517 -vn -0.2040 -0.0023 0.9790 -vn -0.0534 0.0002 0.9986 -vn 0.3718 -0.0000 0.9283 -vn -0.9965 -0.0003 0.0841 -vn 0.1305 -0.0000 0.9915 -vn 0.9074 -0.0000 0.4203 -vn 0.9074 0.0000 0.4203 -vn 0.9074 -0.0000 0.4204 -vn -0.7067 -0.0023 0.7075 -vn 0.4234 -0.0012 -0.9059 -vn -0.0036 0.0006 -1.0000 -vn 0.0770 -0.0004 -0.9970 -vn -0.3008 0.0011 -0.9537 -vn -0.8423 0.0018 -0.5390 -vn 0.5206 -0.0011 0.8538 -vn -0.6123 0.0011 0.7906 -vn -0.8039 0.0008 0.5948 -vn -0.8702 0.0007 0.4926 -vn 0.6858 -0.0015 0.7278 -vn 0.9352 0.0005 0.3542 -vn -0.6995 -0.0016 -0.7147 -vn -0.6994 -0.0016 -0.7147 -vn 0.9325 -0.0004 -0.3613 -vn 0.5421 0.0015 -0.8403 -vn 0.9103 -0.0011 0.4141 -vn -0.8209 -0.0004 -0.5711 -vn -0.2669 -0.0009 0.9637 -vn -0.2635 -0.0007 0.9647 -vn -0.3678 0.0005 0.9299 -vn 0.8966 -0.0007 0.4429 -vn -0.9636 0.0013 -0.2674 -vn -0.8197 -0.0003 -0.5729 -vn -0.8196 -0.0003 -0.5729 -vn 0.8401 -0.0021 -0.5425 -vn 0.8266 -0.0003 0.5627 -vn 0.9669 -0.0010 0.2553 -vn -0.9229 0.0010 -0.3849 -vn -0.7029 -0.0019 0.7113 -vn 0.7531 0.0006 -0.6579 -vn -0.2736 0.0004 -0.9619 -vn 0.6980 0.0000 -0.7161 -vn -0.6583 -0.0005 -0.7528 -vn 0.7307 -0.0004 -0.6827 -vn -0.8974 -0.0006 -0.4411 -vn 0.6757 0.0016 -0.7372 -vn -0.3951 -0.0019 -0.9186 -vn -0.9151 -0.0006 -0.4033 -vn -0.7673 -0.0009 -0.6412 -vn -0.7673 -0.0009 -0.6413 -vn -0.9997 -0.0013 0.0233 -vn -0.9995 -0.0008 0.0314 -vn 0.8884 0.0010 -0.4591 -vn -0.9427 -0.0004 0.3337 -vn -0.4907 -0.0012 -0.8713 -vn -0.9853 0.0012 0.1706 -vn 0.5373 -0.0009 -0.8434 -vn 0.0016 -0.0000 1.0000 -vn 0.8367 -0.0009 0.5476 -vn -0.8047 -0.0000 0.5937 -vn -0.8047 0.0000 0.5936 -vn -0.8047 -0.0000 0.5936 -vn -0.9694 -0.0006 -0.2454 -vn 0.3652 0.0012 0.9309 -vn 0.5339 -0.0018 0.8456 -vn -0.8377 -0.0017 -0.5462 -vn -0.8102 -0.0007 0.5862 -vn 0.9568 -0.0008 -0.2908 -vn 0.8753 0.0003 -0.4835 -vn 0.7772 0.0005 -0.6292 -vn 0.7773 0.0005 -0.6292 -vn -0.9829 0.0014 -0.1844 -vn 0.2923 -0.0011 0.9563 -vn -0.2948 -0.0011 -0.9556 -vn -0.0734 0.0014 -0.9973 -vn -0.0239 0.0003 0.9997 -vn -0.8682 -0.0003 0.4963 -vn 0.8458 0.0003 0.5336 -vn 0.0359 0.0010 -0.9994 -vn -0.0944 0.0003 0.9955 -vn -0.3685 -0.0008 -0.9296 -vn -0.6035 0.0006 0.7974 -vn -0.3686 -0.0008 -0.9296 -vn -0.4201 -0.0000 0.9075 -vn -0.9087 -0.0003 -0.4174 -vn -0.0245 -0.0005 -0.9997 -vn -0.7785 -0.0018 0.6277 -vn 0.9388 -0.0011 0.3443 -vn 0.8141 -0.0004 -0.5807 -vn 0.8142 -0.0004 -0.5806 -vn 0.8525 -0.0019 -0.5227 -vn 0.6299 0.0005 -0.7767 -vn -0.8813 -0.0014 0.4726 -vn -0.8552 0.0009 0.5182 -vn 0.7183 -0.0004 0.6957 -vn -0.0313 -0.0008 0.9995 -vn -0.9457 0.0001 0.3252 -vn -0.8338 0.0005 0.5521 -vn -0.8047 -0.0011 -0.5937 -vn 0.7700 0.0005 0.6380 -vn -0.6108 0.0006 0.7918 -vn -0.6108 0.0005 0.7918 -vn 0.0350 -0.0016 -0.9994 -vn 0.9846 -0.0006 0.1746 -vn -0.8649 -0.0000 0.5020 -vn -0.8649 0.0000 0.5020 -vn -0.8649 -0.0000 0.5019 -vn 0.3608 -0.0014 0.9326 -vn -0.0329 -0.0015 0.9995 -vn 0.8616 -0.0000 -0.5075 -vn 0.8617 0.0000 -0.5075 -vn -0.3591 0.0023 -0.9333 -vn 0.8717 -0.0012 -0.4900 -vn -0.7073 -0.0004 -0.7069 -vn 0.7085 -0.0004 0.7057 -vn 0.9331 -0.0007 0.3595 -vn -0.9359 -0.0005 0.3522 -vn 0.5538 -0.0000 -0.8326 -vn 0.5538 0.0000 -0.8326 -vn -0.9281 0.0005 -0.3724 -vn 0.8618 -0.0007 -0.5072 -vn 0.8618 -0.0007 -0.5073 -vn 0.4204 -0.0013 0.9073 -vn 0.9176 0.0009 0.3975 -vn 0.8492 0.0005 -0.5281 -vn 0.8931 0.0010 0.4499 -vn 0.8930 0.0010 0.4500 -vn -0.4916 -0.0001 0.8708 -vn -0.0655 -0.0015 -0.9979 -vn -0.4343 -0.0003 0.9008 -vn -0.9491 0.0012 0.3150 -vn 0.4262 -0.0012 0.9046 -vn -0.8718 0.0001 0.4898 -vn 0.5726 -0.0015 -0.8198 -vn 0.5726 -0.0015 -0.8199 -vn -0.6513 -0.0003 -0.7589 -vn -0.0571 0.0015 -0.9984 -vn -0.4900 -0.0008 -0.8717 -vn -0.8333 -0.0012 0.5529 -vn 0.9558 0.0014 0.2941 -vn -0.4260 -0.0018 0.9047 -vn 0.2233 0.0016 0.9747 -vn -0.9375 -0.0000 0.3479 -vn -0.0237 0.0007 0.9997 -vn -0.1362 -0.0006 -0.9907 -vn -0.1611 -0.0014 -0.9869 -vn 0.8628 0.0002 -0.5056 -vn 0.7134 -0.0004 0.7008 -vn 0.7228 -0.0011 0.6911 -vn -0.7557 0.0001 0.6549 -vn 1.0000 0.0003 -0.0056 -vn 0.3240 -0.0017 -0.9460 -vn -0.4585 -0.0016 -0.8887 -vn 0.0520 0.0012 0.9986 -vn 0.8789 0.0012 -0.4770 -vn -0.4589 0.0007 0.8885 -vn -0.5128 -0.0000 0.8585 -vn -0.4159 0.0017 0.9094 -vn 0.9362 -0.0005 0.3516 -vn 0.6369 -0.0012 0.7710 -vn 0.9899 -0.0003 -0.1420 -vn 0.7790 -0.0018 -0.6270 -vn -0.0266 -0.0003 -0.9996 -vn 0.3399 -0.0007 -0.9405 -vn 0.9773 -0.0015 0.2119 -vn 0.8984 -0.0008 0.4392 -vn 0.9993 0.0012 0.0380 -vn -0.5763 0.0014 -0.8173 -vn -0.5762 0.0014 -0.8173 -vn -0.8994 -0.0008 -0.4371 -vn 0.3210 0.0005 -0.9471 -vn -0.5128 0.0000 0.8585 -vn 0.2986 0.0000 -0.9544 -vn 0.2986 -0.0000 -0.9544 -vn -0.0184 0.0004 0.9998 -vn 0.9763 0.0015 0.2162 -vn -0.4633 -0.0009 -0.8862 -vn 0.0209 0.0017 0.9998 -vn 0.3443 -0.0010 0.9389 -vn 0.0289 0.0008 -0.9996 -vn -0.7121 -0.0004 -0.7021 -vn -0.9208 0.0006 0.3901 -vn -0.9207 0.0006 0.3902 -vn 0.6747 -0.0004 0.7381 -vn 0.6748 -0.0004 0.7380 -vn -0.3938 -0.0010 0.9192 -vn -0.9960 -0.0006 0.0898 -vn -1.0000 0.0013 -0.0015 -vn 0.1381 0.0000 -0.9904 -vn -0.9395 0.0000 0.3426 -vn -0.9395 -0.0000 0.3426 -vn 0.9374 -0.0000 -0.3482 -vn 0.9374 0.0000 -0.3482 -vn -0.9893 -0.0008 0.1460 -vn -0.6642 0.0012 -0.7476 -vn -0.9515 -0.0004 0.3075 -vn 0.9601 -0.0012 0.2798 -vn 0.9995 -0.0008 -0.0308 -vn -0.5803 -0.0011 -0.8144 -vn 0.8411 0.0006 0.5409 -vn -0.9410 0.0012 0.3384 -vn -0.9578 -0.0012 -0.2873 -vn 0.9896 0.0014 -0.1441 -vn -0.1388 -0.0005 -0.9903 -vn -0.9555 0.0007 -0.2951 -vn 0.9293 0.0011 -0.3693 -vn 0.5257 -0.0016 -0.8506 -vn -0.3690 -0.0010 -0.9294 -vn -0.7207 -0.0010 -0.6933 -vn -0.6837 -0.0002 0.7298 -vn 0.9739 -0.0017 0.2268 -vn 0.2187 -0.0010 -0.9758 -vn 0.4627 0.0014 -0.8865 -vn -0.9475 -0.0008 -0.3199 -vn -0.4382 -0.0001 0.8989 -vn -0.1125 -0.0005 0.9937 -vn 0.6248 -0.0005 0.7807 -vn 0.9945 -0.0008 -0.1045 -vn 0.1201 0.0014 0.9928 -vn -0.9009 0.0016 -0.4340 -vn 0.2992 0.0010 0.9542 -vn -0.5692 -0.0004 -0.8222 -vn 0.3674 -0.0001 0.9301 -vn 0.9715 -0.0000 0.2369 -vn 0.9239 0.0004 0.3826 -vn 0.1977 -0.0016 0.9803 -vn -0.2535 -0.0010 0.9673 -vn -0.9623 -0.0013 -0.2719 -vn 0.6342 0.0009 -0.7731 -vn 0.9624 0.0009 0.2718 -vn 0.8409 -0.0000 0.5412 -vn 0.8409 0.0000 0.5412 -vn 0.2961 0.0016 0.9552 -vn -0.9493 -0.0014 -0.3143 -vn 0.6027 0.0021 -0.7980 -vn 0.6027 0.0021 -0.7979 -vn -0.5299 0.0019 0.8480 -vn -0.5299 0.0019 0.8481 -vn -0.9977 0.0010 -0.0671 -vn 0.0960 -0.0005 0.9954 -vn -0.9591 -0.0008 -0.2832 -vn 0.5664 -0.0004 -0.8241 -vn -0.7289 -0.0017 0.6846 -vn 0.9381 0.0007 0.3465 -vn -0.8501 0.0004 0.5265 -vn -0.8501 0.0004 0.5266 -vn 0.9372 -0.0008 0.3489 -vn -0.0573 0.0004 0.9984 -vn 0.9268 -0.0012 0.3756 -vn -0.0372 -0.0008 0.9993 -vn 0.3798 -0.0013 -0.9251 -vn 0.7779 0.0003 0.6284 -vn -0.7975 -0.0008 -0.6033 -vn 0.9085 -0.0005 -0.4179 -vn -0.8317 -0.0012 0.5552 -vn -0.8317 -0.0012 0.5553 -vn -0.6727 0.0005 -0.7399 -vn -0.9032 0.0012 -0.4292 -vn -0.9216 -0.0001 -0.3882 -vn -0.9216 -0.0001 -0.3881 -vn -0.9485 -0.0010 -0.3167 -vn 0.6536 0.0010 0.7568 -vn -0.8661 0.0003 0.4999 -vn 0.1744 0.0005 -0.9847 -vn 0.8779 0.0003 0.4789 -vn 0.1915 -0.0013 0.9815 -vn 0.9995 0.0002 0.0313 -vn 0.9255 0.0005 -0.3789 -vn 0.9254 0.0005 -0.3789 -vn 0.5187 -0.0009 0.8550 -vn -0.6600 0.0007 0.7513 -vn 0.9372 -0.0008 0.3488 -vn 0.9926 0.0002 -0.1216 -vn -0.9232 -0.0006 -0.3844 -vn 0.1056 0.0003 0.9944 -vn 0.7280 -0.0011 0.6856 -vn -0.0285 -0.0007 0.9996 -vn 0.2891 -0.0011 -0.9573 -vn -0.5423 -0.0011 -0.8402 -vn -0.7887 -0.0008 -0.6147 -vn 0.9436 -0.0009 0.3310 -vn -0.3986 0.0003 0.9171 -vn 0.7532 -0.0008 0.6578 -vn -0.4541 -0.0003 0.8909 -vn -0.3173 0.0007 0.9483 -vn -0.9513 -0.0009 -0.3084 -vn 0.3617 0.0003 0.9323 -vn -0.7090 0.0010 -0.7052 -vn -0.1731 -0.0011 0.9849 -vn 0.3165 0.0007 -0.9486 -vn 0.1704 -0.0011 -0.9854 -vn 0.5081 -0.0006 -0.8613 -vn 0.4774 0.0018 -0.8787 -vn -0.9407 0.0016 0.3392 -vn 0.4658 -0.0001 -0.8849 -vn 0.9834 0.0015 0.1814 -vn 0.6417 0.0010 -0.7670 -vn 0.9462 -0.0014 0.3235 -vn 0.9462 -0.0014 0.3236 -vn -0.9692 0.0007 0.2462 -vn -0.9534 -0.0014 -0.3019 -vn -0.9534 -0.0014 -0.3018 -vn 0.2711 -0.0014 0.9625 -vn -0.2739 -0.0015 -0.9617 -vn 0.5872 0.0002 0.8094 -vn 0.6013 -0.0005 0.7990 -vn -0.6565 0.0016 -0.7544 -vn -0.8712 -0.0013 -0.4910 -vn -0.4013 0.0000 0.9159 -vn -0.4013 -0.0000 0.9159 -vn -0.4014 -0.0000 0.9159 -vn 0.1824 -0.0010 -0.9832 -vn 0.0166 -0.0009 -0.9999 -vn 0.3965 0.0000 -0.9180 -vn 0.3966 0.0000 -0.9180 -vn -0.1741 -0.0010 0.9847 -vn -0.1558 -0.0014 -0.9878 -vn -0.5991 -0.0005 -0.8006 -vn 0.0354 -0.0005 0.9994 -vn 0.4436 0.0007 -0.8962 -vn -0.6742 -0.0006 0.7385 -vn -0.8885 -0.0000 0.4589 -vn -0.8885 0.0000 0.4589 -vn 0.8681 -0.0000 -0.4964 -vn 0.8681 0.0000 -0.4964 -vn -0.6029 0.0008 -0.7979 -vn -0.8425 0.0017 0.5386 -vn -0.1121 -0.0015 0.9937 -vn -0.9682 0.0006 0.2502 -vn -1.0000 -0.0000 0.0078 -vn 0.3357 0.0003 -0.9420 -vn 0.4149 -0.0005 0.9099 -vn 0.8579 -0.0009 -0.5138 -vn 0.0132 -0.0008 -0.9999 -vn 0.9620 0.0012 0.2732 -vn -0.3434 0.0002 -0.9392 -vn -0.3027 -0.0006 -0.9531 -vn -0.9937 -0.0000 -0.1120 -vn -0.9991 -0.0000 -0.0431 -vn -0.9954 -0.0012 -0.0961 -vn 0.8536 -0.0008 -0.5209 -vn -0.3910 -0.0003 0.9204 -vn -0.9930 0.0013 0.1181 -vn 0.9920 0.0012 -0.1265 -vn -0.2676 -0.0005 -0.9635 -vn 0.2930 -0.0007 0.9561 -vn 0.1681 -0.0014 0.9858 -vn -0.5465 -0.0009 -0.8375 -vn -0.9508 -0.0014 -0.3100 -vn -0.9508 -0.0014 -0.3099 -vn 0.8814 0.0009 -0.4725 -vn -0.5827 -0.0008 0.8127 -vn 0.9664 0.0009 -0.2570 -vn 0.9664 0.0008 -0.2570 -vn -0.1731 -0.0010 -0.9849 -vn -0.2662 -0.0003 0.9639 -vn 0.4205 -0.0003 -0.9073 -vn -0.3085 -0.0009 0.9512 -vn -0.9770 -0.0002 -0.2135 -vn -0.9715 -0.0009 0.2369 -vn 0.8295 0.0018 0.5585 -vn 0.9565 -0.0004 0.2916 -vn 0.9565 -0.0004 0.2917 -vn -0.3935 -0.0014 -0.9193 -vn 0.9579 -0.0010 -0.2872 -vn -0.9543 -0.0004 -0.2990 -vn -0.9542 -0.0004 -0.2990 -vn -0.6914 -0.0006 0.7225 -vn 0.2881 -0.0006 -0.9576 -vn -0.2559 -0.0008 0.9667 -vn -0.9533 -0.0005 0.3019 -vn 0.6802 -0.0007 0.7331 -vn 0.9636 -0.0004 0.2675 -vn -0.6326 -0.0005 -0.7745 -vn -0.9556 -0.0004 -0.2948 -vn 0.7919 -0.0021 0.6106 -vn -0.8652 -0.0000 0.5014 -vn -0.6959 -0.0000 0.7182 -vn 0.8234 -0.0011 0.5675 -vn 0.3205 0.0000 -0.9473 -vn -0.5847 0.0012 -0.8112 -vn -0.5847 0.0012 -0.8113 -vn 0.6921 -0.0009 0.7218 -vn 0.9618 -0.0006 -0.2739 -vn 0.1914 0.0008 -0.9815 -vn 0.9486 0.0004 -0.3165 -vn 0.3091 0.0004 0.9510 -vn 0.8719 -0.0009 -0.4897 -vn 0.4665 0.0003 0.8845 -vn 0.4664 0.0003 0.8846 -vn -0.1724 0.0016 0.9850 -vn 0.5804 0.0004 -0.8143 -vn 0.7145 -0.0005 -0.6996 -vn -1.0000 0.0001 0.0077 -vn -0.1502 -0.0001 0.9886 -vn -0.5848 -0.0019 0.8112 -vn -0.0876 -0.0011 -0.9962 -vn -0.9366 0.0011 0.3504 -vn 0.6248 0.0003 -0.7808 -vn -0.9484 0.0006 -0.3171 -vn -0.3008 -0.0001 0.9537 -vn 0.0611 0.0004 -0.9981 -vn 0.8559 -0.0000 0.5171 -vn -0.1138 -0.0007 -0.9935 -vn 0.4589 0.0012 0.8885 -vn 0.3180 -0.0007 -0.9481 -vn -0.1999 0.0014 -0.9798 -vn -0.0353 0.0004 0.9994 -vn 0.1427 0.0015 0.9898 -vn -0.6835 -0.0015 0.7300 -vn 0.2281 -0.0007 -0.9736 -vn -0.6807 -0.0007 0.7325 -vn 0.4432 0.0000 -0.8964 -vn 0.4433 -0.0000 -0.8964 -vn -0.9799 -0.0006 -0.1994 -vn -0.0431 -0.0004 -0.9991 -vn -0.5036 -0.0011 -0.8639 -vn -0.9785 -0.0007 -0.2064 -vn -0.9785 -0.0007 -0.2063 -vn 0.8361 -0.0010 0.5486 -vn -0.8803 -0.0015 0.4744 -vn -0.4029 0.0013 -0.9153 -vn -0.7591 -0.0013 -0.6510 -vn 0.5170 0.0002 -0.8560 -vn -0.6320 0.0003 0.7750 -vn 0.9287 -0.0023 0.3708 -vn -0.7173 0.0004 -0.6968 -vn 0.8773 0.0012 0.4799 -vn 0.8773 0.0012 0.4800 -vn -0.4352 -0.0003 -0.9003 -vn 0.3352 -0.0010 -0.9421 -vn -0.3203 -0.0011 0.9473 -vn 0.9930 0.0000 -0.1184 -vn -0.4368 -0.0000 -0.8996 -vn -0.4368 0.0000 -0.8996 -vn 0.9125 -0.0013 -0.4091 -vn 0.9780 -0.0007 0.2085 -vn -0.9298 -0.0007 0.3681 -vn 0.9780 -0.0007 0.2086 -vn 0.8642 -0.0007 0.5031 -vn 0.7901 -0.0007 0.6130 -vn 0.9482 -0.0007 0.3176 -vn 0.3496 0.0005 -0.9369 -vn 0.9575 0.0016 0.2886 -vn 0.5592 0.0002 0.8290 -vn 0.4806 0.0000 -0.8770 -vn 0.4805 0.0000 -0.8770 -vn 0.2177 0.0018 -0.9760 -vn 0.9609 0.0005 -0.2768 -vn 0.2202 -0.0014 0.9755 -vn -0.3504 0.0004 0.9366 -vn -0.2333 0.0019 -0.9724 -vn -0.2830 0.0002 -0.9591 -vn 0.0301 0.0002 -0.9995 -vn 0.2844 -0.0015 -0.9587 -vn 0.9591 -0.0007 -0.2830 -vn 0.3860 -0.0006 0.9225 -vn 0.3859 -0.0006 0.9225 -vn -0.9429 0.0009 0.3331 -vn -0.7041 0.0007 0.7101 -vn 0.9995 -0.0008 0.0325 -vn 0.1580 -0.0003 -0.9874 -vn -0.4018 0.0000 0.9157 -vn -0.3111 0.0003 0.9504 -vn 0.6141 0.0011 -0.7893 -vn -0.8482 -0.0000 0.5297 -vn -0.8422 0.0009 0.5392 -vn -0.9954 0.0008 -0.0957 -vn -0.7197 -0.0010 0.6943 -vn 0.7166 -0.0010 -0.6975 -vn -0.5827 -0.0009 -0.8127 -vn 0.7157 -0.0010 -0.6984 -vn 0.3597 -0.0005 0.9331 -vn -0.5481 0.0026 -0.8364 -vn -0.2497 -0.0013 0.9683 -vn -0.9676 0.0003 0.2524 -vn -0.6110 -0.0005 0.7916 -vn -0.6907 -0.0009 -0.7231 -vn -0.1157 0.0011 -0.9933 -vn 0.2903 0.0006 -0.9569 -vn 0.9798 -0.0003 0.2001 -vn 0.6772 -0.0009 0.7358 -vn -0.4941 -0.0009 0.8694 -vn -0.4942 -0.0009 0.8694 -vn 0.9905 0.0001 -0.1376 -vn -0.4290 0.0000 -0.9033 -vn -0.4291 0.0000 -0.9033 -vn 0.9527 -0.0008 -0.3038 -vn 0.7361 -0.0000 0.6769 -vn 0.1097 0.0011 0.9940 -vn -0.0211 0.0011 -0.9998 -vn -0.9825 0.0020 -0.1861 -vn -0.9825 0.0020 -0.1860 -vn -0.9914 -0.0002 -0.1310 -vn 0.9834 -0.0016 0.1813 -vn -0.7175 -0.0009 0.6966 -vn -0.7964 -0.0011 0.6048 -vn -0.9958 -0.0015 -0.0920 -vn -0.9958 -0.0015 -0.0921 -vn 0.9668 -0.0014 -0.2555 -vn -0.4164 0.0011 0.9092 -vn 0.3535 0.0012 0.9354 -vn 0.3719 0.0013 -0.9283 -vn 0.0259 0.0001 -0.9997 -vn -0.9442 -0.0003 -0.3294 -vn -0.9442 -0.0003 -0.3295 -vn -0.9985 -0.0008 0.0544 -vn -0.9985 -0.0008 0.0543 -vn -0.0169 -0.0015 0.9999 -vn 0.6830 -0.0010 0.7304 -vn 0.7935 0.0011 -0.6085 -vn -0.2245 0.0014 -0.9745 -vn 0.2228 0.0014 0.9749 -vn 0.9885 -0.0007 -0.1512 -vn -0.2752 -0.0002 0.9614 -vn 0.6387 -0.0005 -0.7695 -vn 0.1356 0.0016 0.9908 -vn -0.9668 0.0003 0.2555 -vn 0.2063 -0.0009 0.9785 -vn 0.5899 0.0001 0.8074 -vn 0.5900 0.0001 0.8074 -vn 0.9999 -0.0010 0.0146 -vn 0.8943 -0.0011 0.4475 -vn -0.9957 0.0016 0.0924 -vn 0.9892 -0.0007 0.1467 -vn -0.5884 0.0001 -0.8086 -vn -0.1095 0.0014 -0.9940 -vn -0.7798 -0.0003 0.6260 -vn 0.7465 -0.0009 0.6654 -vn 0.4982 0.0005 -0.8671 -vn -0.9612 -0.0002 -0.2759 -vn -0.9612 -0.0002 -0.2760 -vn -0.1134 0.0014 -0.9936 -vn 0.6934 -0.0018 -0.7205 -vn 0.7364 0.0005 0.6765 -vn -1.0000 0.0000 0.0088 -vn 0.1641 -0.0011 -0.9864 -vn 0.1610 -0.0005 0.9869 -vn -0.7571 0.0000 -0.6533 -vn -0.8834 -0.0017 -0.4686 -vn 0.4810 -0.0006 0.8767 -vn 0.4809 -0.0006 0.8768 -vn -0.7924 0.0000 0.6100 -vn 0.9602 -0.0005 -0.2795 -vn 0.9601 -0.0005 -0.2795 -vn -0.5559 -0.0006 -0.8312 -vn -0.5559 -0.0007 -0.8312 -vn 0.9572 0.0000 -0.2894 -vn 0.9572 0.0000 -0.2895 -vn 0.0964 -0.0005 0.9953 -vn -0.9995 -0.0009 -0.0316 -vn 0.7894 -0.0000 -0.6138 -vn 0.7894 0.0000 -0.6138 -vn -0.8167 0.0013 0.5770 -vn -0.9743 -0.0015 0.2251 -vn -0.9743 -0.0015 0.2252 -vn 0.2825 -0.0006 0.9593 -vn -0.8254 0.0006 -0.5646 -vn -0.2848 -0.0005 -0.9586 -vn -0.3578 -0.0008 0.9338 -vn -0.2333 0.0007 -0.9724 -vn 0.9783 0.0009 0.2071 -vn 0.9783 0.0009 0.2072 -vn -0.2286 0.0012 0.9735 -vn -0.5046 -0.0023 0.8634 -vn 0.2794 0.0002 0.9602 -vn -0.2931 -0.0004 -0.9561 -vn 0.6634 -0.0006 0.7482 -vn 0.8510 -0.0007 0.5252 -vn 0.7444 -0.0017 0.6677 -vn 0.8208 0.0005 0.5711 -vn 0.8208 0.0005 0.5712 -vn 0.7535 -0.0008 0.6574 -vn -0.1360 0.0012 0.9907 -vn -0.9574 0.0011 0.2889 -vn -0.9979 0.0010 -0.0641 -vn 0.3867 0.0007 0.9222 -vn -0.9980 -0.0006 0.0625 -vn 0.2868 -0.0005 0.9580 -vn -0.6060 0.0010 -0.7955 -vn -0.6059 0.0010 -0.7955 -vn -0.9692 -0.0005 -0.2464 -vn 0.2688 0.0017 -0.9632 -vn 0.9134 -0.0007 0.4070 -vn 0.8701 -0.0013 0.4929 -vn -0.2479 0.0018 0.9688 -vn -0.1746 -0.0009 0.9846 -vn 0.9992 0.0003 0.0391 -vn 0.9917 -0.0009 0.1288 -vn 0.8840 -0.0013 0.4674 -vn -0.8662 -0.0013 -0.4996 -vn -0.8663 -0.0013 -0.4996 -vn 0.1467 0.0014 -0.9892 -vn -0.9931 -0.0009 -0.1177 -vn -0.4617 0.0013 -0.8870 -vn -0.8687 -0.0013 -0.4953 -vn -0.9645 -0.0005 0.2642 -vn -0.9644 -0.0005 0.2643 -vn 0.1026 -0.0010 -0.9947 -vn -0.9598 0.0001 0.2807 -vn 0.8143 -0.0005 0.5804 -vn 0.8143 -0.0005 0.5805 -vn -0.6342 -0.0007 0.7732 -vn -0.9911 -0.0008 0.1332 -vn 0.0274 0.0012 0.9996 -vn 0.2122 0.0016 -0.9772 -vn 0.1351 0.0010 -0.9908 -vn -0.8204 0.0011 -0.5717 -vn 0.9602 -0.0010 -0.2794 -vn -0.9744 0.0003 -0.2249 -vn -0.5136 0.0012 -0.8580 -vn 0.4633 0.0010 -0.8862 -vn -0.9831 -0.0009 0.1830 -vn 0.2843 -0.0015 0.9587 -vn 0.9824 -0.0009 -0.1868 -vn -0.7217 0.0004 -0.6922 -vn 0.1985 0.0012 -0.9801 -vn -0.6424 -0.0011 -0.7663 -vn -0.6425 -0.0011 -0.7663 -vn 0.5826 0.0015 -0.8127 -vn -0.7729 -0.0013 0.6345 -vn -0.7729 -0.0013 0.6346 -vn -0.9315 -0.0005 0.3638 -vn 0.0172 0.0004 -0.9999 -vn -0.9194 -0.0003 0.3933 -vn 0.9746 0.0009 -0.2240 -vn -0.8247 -0.0008 -0.5655 -vn -0.8248 -0.0008 -0.5655 -vn -0.7841 -0.0012 -0.6207 -vn 0.5261 -0.0011 0.8504 -vn -0.6576 0.0016 0.7534 -vn 0.8158 0.0010 0.5784 -vn 0.0557 -0.0010 0.9984 -vn -0.4437 -0.0000 0.8962 -vn -0.4436 0.0000 0.8962 -vn -0.4732 -0.0012 0.8810 -vn -0.0563 -0.0010 -0.9984 -vn 0.4916 0.0011 0.8708 -vn 0.0627 0.0010 0.9980 -vn -0.5276 -0.0011 -0.8495 -vn 0.9844 -0.0009 -0.1760 -vn 0.9844 -0.0009 -0.1761 -vn 0.1749 0.0016 0.9846 -vn -0.7311 0.0010 0.6823 -vn -0.7732 -0.0005 0.6341 -vn -0.9838 -0.0009 0.1791 -vn 0.7250 -0.0009 -0.6888 -vn -0.0200 0.0007 -0.9998 -vn 0.3908 -0.0009 0.9205 -vn 0.7041 -0.0012 -0.7101 -vn 0.1686 -0.0010 0.9857 -vn 0.9735 0.0003 0.2288 -vn 0.9735 0.0003 0.2289 -vn 0.7005 0.0000 -0.7136 -vn 0.1954 0.0009 -0.9807 -vn 0.1953 0.0009 -0.9807 -vn 0.7831 0.0010 -0.6219 -vn -0.0600 -0.0009 -0.9982 -vn -0.3006 0.0010 0.9537 -vn 0.9990 -0.0001 -0.0448 -vn -0.9162 0.0003 -0.4006 -vn -0.9162 0.0003 -0.4007 -vn 0.5318 -0.0010 0.8469 -vn 0.0568 -0.0009 0.9984 -vn -0.9884 0.0011 -0.1522 -vn -0.7933 -0.0005 -0.6088 -vn -0.9103 -0.0019 -0.4139 -vn -0.8812 -0.0010 0.4727 -vn -0.8812 -0.0010 0.4728 -vn -0.5390 -0.0010 -0.8423 -vn -0.0568 -0.0011 0.9984 -vn 0.9877 0.0005 -0.1567 -vn -0.7258 -0.0005 0.6880 -vn -0.7258 -0.0005 0.6879 -vn 0.9946 -0.0010 0.1042 -vn -0.6676 0.0002 0.7445 -vn 0.7220 -0.0005 -0.6919 -vn -0.8568 -0.0006 -0.5157 -vn 0.6320 -0.0025 -0.7749 -vn 0.6320 -0.0025 -0.7750 -vn 0.0176 -0.0017 0.9998 -vn 0.1582 -0.0009 0.9874 -vn -0.9941 -0.0010 -0.1080 -vn -0.3102 -0.0017 0.9507 -vn -0.9682 -0.0018 0.2500 -vn 0.5856 -0.0018 -0.8106 -vn -0.0701 -0.0008 0.9975 -vn 0.1581 -0.0003 -0.9874 -vn -0.1834 0.0021 -0.9830 -vn -0.9944 -0.0010 -0.1060 -vn -0.9707 0.0008 -0.2404 -vn 0.0449 -0.0008 -0.9990 -vn 0.9370 0.0006 0.3492 -vn 0.1089 -0.0007 -0.9941 -vn -0.2857 0.0002 -0.9583 -vn 0.1184 0.0010 0.9930 -vn -0.5789 0.0014 -0.8154 -vn 0.9674 0.0008 0.2531 -vn 0.9957 -0.0009 0.0928 -vn -0.0985 0.0010 -0.9951 -vn 0.9995 -0.0007 0.0307 -vn 0.9712 -0.0011 -0.2384 -vn 0.7389 -0.0009 -0.6738 -vn -0.4749 -0.0010 0.8800 -vn -0.9839 -0.0006 0.1785 -vn 0.8070 -0.0007 0.5905 -vn -0.5563 -0.0006 0.8310 -vn 0.9833 -0.0006 -0.1822 -vn 0.9833 -0.0006 -0.1821 -vn -0.8558 0.0000 0.5173 -vn -0.8558 -0.0000 0.5173 -vn 0.9776 -0.0000 0.2106 -vn -0.1146 0.0011 -0.9934 -vn 0.7711 -0.0006 -0.6367 -vn 0.9851 -0.0006 -0.1719 -vn -0.3067 -0.0016 -0.9518 -vn -0.9898 -0.0007 0.1425 -vn 0.9983 -0.0009 0.0578 -vn -0.9061 -0.0005 0.4232 -vn -0.9060 -0.0005 0.4232 -vn 0.7172 0.0006 -0.6969 -vn -0.0487 -0.0004 -0.9988 -vn -0.8257 -0.0006 -0.5642 -vn 0.6860 0.0013 0.7276 -vn 0.6861 0.0010 0.7275 -vn 0.9829 -0.0004 0.1843 -vn 0.9976 0.0008 0.0692 -vn -0.7443 0.0009 0.6678 -vn 0.7006 -0.0016 0.7135 -vn 0.9216 0.0008 -0.3881 -vn 0.8213 -0.0006 0.5705 -vn -0.8569 -0.0015 -0.5154 -vn 0.8213 0.0004 0.5705 -vn 0.8428 -0.0015 0.5383 -vn 0.9039 -0.0005 -0.4278 -vn 0.9592 0.0010 -0.2827 -vn 0.1773 -0.0004 -0.9842 -vn -0.9974 0.0007 -0.0719 -vn 0.9618 0.0000 0.2736 -vn -0.6595 0.0013 -0.7517 -vn -0.8889 -0.0017 0.4581 -vn -0.9197 -0.0012 0.3925 -vn -0.4844 -0.0015 0.8748 -vn -0.3733 -0.0015 -0.9277 -vn -0.4604 -0.0018 0.8877 -vn 0.7589 -0.0017 -0.6512 -vn 0.9895 0.0008 0.1446 -vn -0.4999 -0.0015 -0.8661 -vn 0.9977 -0.0002 0.0683 -vn -0.0411 0.0006 0.9992 -vn 0.4916 -0.0014 0.8708 -vn 0.9908 -0.0007 -0.1355 -vn 0.9989 0.0010 0.0464 -vn -0.9521 0.0012 -0.3059 -vn -0.9795 0.0009 -0.2016 -vn 1.0000 -0.0005 0.0014 -vn -0.9934 0.0008 -0.1150 -vn 0.8490 -0.0009 0.5283 -vn 0.8491 -0.0009 0.5283 -vn 0.9978 0.0012 0.0662 -vn 0.9749 -0.0010 0.2226 -vn -0.5182 0.0007 0.8553 -vn -0.0921 -0.0009 -0.9958 -vn 0.9746 0.0000 -0.2239 -vn -0.1916 0.0007 0.9815 -vn -0.2680 -0.0007 0.9634 -vn -0.4546 0.0007 0.8907 -vn -0.1209 -0.0010 -0.9927 -vn -0.9930 -0.0011 -0.1185 -vn -0.9987 0.0004 -0.0513 -vn -0.9355 0.0009 -0.3533 -vn 0.4428 -0.0009 0.8966 -vn -0.3508 -0.0007 -0.9365 -vn 0.9919 -0.0008 -0.1272 -vn 0.9919 -0.0008 -0.1271 -vn 0.3849 -0.0008 0.9229 -vn -0.1562 -0.0009 -0.9877 -vn 0.2015 -0.0014 0.9795 -vn 0.7282 0.0000 -0.6853 -vn -0.7794 0.0007 0.6266 -vn 0.9764 0.0005 -0.2158 -vn -0.9483 -0.0003 0.3173 -vn 0.6323 -0.0008 0.7748 -vn 0.5313 0.0007 -0.8472 -vn 0.0593 0.0006 0.9982 -vn -0.5703 0.0014 0.8215 -vn 0.1491 -0.0009 0.9888 -vn 0.6808 0.0009 -0.7325 -vn -0.8792 -0.0011 -0.4764 -vn -0.5814 -0.0008 0.8136 -vn -0.9277 0.0007 0.3734 -vn -0.0907 -0.0011 0.9959 -vn 0.7268 0.0004 0.6869 -vn 0.4526 0.0006 -0.8917 -vn 0.9921 0.0007 -0.1255 -vn -0.0607 0.0006 -0.9982 -vn 0.1614 -0.0005 0.9869 -vn 0.8329 -0.0007 0.5534 -vn -0.4723 -0.0008 0.8815 -vn 0.9920 -0.0011 0.1260 -vn 0.9684 -0.0009 -0.2493 -vn -0.1700 -0.0011 0.9854 -vn 0.1455 -0.0005 -0.9894 -vn -0.2394 -0.0007 0.9709 -vn -0.8076 -0.0003 -0.5897 -vn 0.4220 -0.0011 -0.9066 -vn 0.8914 -0.0005 0.4531 -vn -0.9934 -0.0011 -0.1146 -vn -0.9659 0.0008 -0.2590 -vn 0.9459 0.0000 -0.3243 -vn 0.9459 0.0000 -0.3244 -vn 0.6149 -0.0005 -0.7886 -vn 0.1916 0.0001 0.9815 -vn 0.1740 0.0006 -0.9848 -vn 0.8105 -0.0006 -0.5858 -vn 0.8104 -0.0006 -0.5858 -vn -0.3339 -0.0009 -0.9426 -vn 0.3465 0.0013 -0.9380 -vn 0.2713 -0.0008 0.9625 -vn 0.5504 -0.0016 0.8349 -vn -0.9900 0.0008 -0.1408 -vn -0.1748 0.0006 0.9846 -vn -0.9901 0.0008 -0.1407 -vn 0.0860 0.0014 -0.9963 -vn -0.7186 0.0016 -0.6954 -vn 0.4704 -0.0008 -0.8825 -vn -0.7660 0.0009 0.6429 -vn 0.9931 -0.0000 0.1173 -vn 0.9931 -0.0000 0.1174 -vn -0.7832 -0.0004 -0.6218 -vn -0.9135 -0.0007 -0.4069 -vn -0.9135 -0.0007 -0.4068 -vn -0.5993 0.0002 0.8006 -vn -0.6597 -0.0010 -0.7515 -vn -0.9389 0.0010 0.3442 -vn -0.9805 -0.0005 0.1963 -vn -0.8495 -0.0007 0.5276 -vn -0.6273 -0.0006 0.7788 -vn -0.9355 0.0004 -0.3534 -vn 0.9939 -0.0004 0.1104 -vn 0.9939 -0.0004 0.1103 -vn -0.9305 0.0006 0.3663 -vn 0.7172 0.0003 -0.6968 -vn 0.7172 0.0003 -0.6969 -vn -0.4641 -0.0006 -0.8858 -vn -0.9916 0.0006 0.1290 -vn -0.9917 0.0006 0.1289 -vn 0.1813 -0.0013 0.9834 -vn -0.9058 0.0015 -0.4236 -vn 0.1061 -0.0007 -0.9944 -vn 0.0235 0.0004 -0.9997 -vn -0.9996 -0.0006 -0.0282 -vn 0.6928 0.0001 0.7211 -vn 0.9486 0.0012 -0.3164 -vn -0.4638 0.0012 0.8859 -vn 0.7230 -0.0005 -0.6908 -vn 0.7230 -0.0005 -0.6909 -vn 0.6066 0.0005 -0.7950 -vn 0.8640 -0.0006 0.5034 -vn -0.9976 -0.0006 0.0690 -vn -0.9929 -0.0010 -0.1189 -vn 0.8404 0.0002 0.5419 -vn 0.7200 0.0006 0.6939 -vn -0.4066 0.0006 0.9136 -vn 0.9997 -0.0001 0.0250 -vn -0.2325 -0.0006 -0.9726 -vn 0.8777 -0.0006 0.4792 -vn 0.8777 -0.0006 0.4793 -vn 0.3454 -0.0004 -0.9385 -vn 0.7364 -0.0007 0.6766 -vn 0.9675 -0.0007 0.2528 -vn -0.8604 -0.0006 -0.5097 -vn -0.4725 0.0006 -0.8813 -vn -0.9946 -0.0009 -0.1037 -vn 0.6515 0.0002 0.7586 -vn -0.8846 -0.0005 0.4663 -vn -0.8259 -0.0006 0.5639 -vn -0.2686 -0.0019 -0.9633 -vn -0.9908 0.0006 0.1356 -vn 0.7541 0.0006 -0.6568 -vn -0.1309 -0.0004 0.9914 -vn -0.8631 -0.0006 -0.5051 -vn -0.8137 -0.0006 -0.5813 -vn -0.4101 -0.0006 -0.9120 -vn -0.0972 -0.0006 0.9953 -vn 0.4948 -0.0003 -0.8690 -vn 0.4947 -0.0003 -0.8690 -vn 0.9440 -0.0011 0.3300 -vn -0.2846 0.0006 0.9586 -vn -0.8502 -0.0012 0.5264 -vn -0.7865 -0.0014 0.6175 -vn -0.7866 -0.0014 0.6175 -vn 0.8769 -0.0006 -0.4807 -vn -0.0387 -0.0001 -0.9993 -vn -0.9935 -0.0007 -0.1139 -vn 0.8469 -0.0011 -0.5317 -vn 0.8533 -0.0012 -0.5214 -vn -0.2042 -0.0006 0.9789 -vn 0.4656 0.0008 0.8850 -vn 0.2004 -0.0003 0.9797 -vn -0.1326 -0.0006 -0.9912 -vn -0.9851 0.0014 0.1721 -vn -0.0941 -0.0012 0.9956 -vn -0.9873 0.0004 -0.1588 -vn 0.1070 -0.0012 0.9943 -vn -0.9873 0.0004 -0.1587 -vn 0.4372 0.0005 0.8994 -vn -0.5235 0.0006 -0.8520 -vn 0.9186 0.0006 -0.3952 -vn -0.8506 -0.0015 0.5258 -vn -0.6391 0.0005 0.7691 -vn 0.8530 0.0011 -0.5220 -vn -0.0919 0.0005 0.9958 -vn 0.6367 -0.0004 -0.7711 -vn 0.5157 -0.0005 0.8568 -vn 0.9766 -0.0006 0.2151 -vn -0.3440 0.0005 -0.9390 -vn 0.6348 0.0005 -0.7727 -vn -0.5170 -0.0005 -0.8560 -vn -0.5171 -0.0005 -0.8560 -vn -0.1852 -0.0005 0.9827 -vn 0.5005 0.0005 0.8657 -vn 0.5005 -0.0010 0.8657 -vn -0.7179 -0.0014 0.6961 -vn 0.1822 -0.0005 -0.9833 -vn -0.7180 -0.0014 0.6961 -vn 0.1504 -0.0006 -0.9886 -vn 0.1503 -0.0006 -0.9886 -vn 0.5264 -0.0015 -0.8502 -vn 0.9266 0.0019 -0.3760 -vn 0.4635 0.0010 -0.8861 -vn 0.9988 0.0019 -0.0497 -vn -0.9255 0.0006 -0.3789 -vn -0.6561 -0.0014 -0.7547 -vn 0.6992 -0.0002 0.7150 -vn 0.6991 -0.0002 0.7150 -vn 0.9535 -0.0004 -0.3013 -vn -0.9846 -0.0006 0.1749 -vn 0.3715 0.0019 -0.9284 -vn 0.5037 -0.0003 0.8639 -vn 0.7081 0.0005 0.7061 -vn 0.5212 -0.0005 0.8534 -vn -0.6673 0.0010 -0.7448 -vn 0.9203 0.0005 0.3912 -vn -0.4509 -0.0013 0.8926 -vn 0.9912 -0.0006 -0.1321 -vn -0.2783 -0.0008 -0.9605 -vn -0.5282 -0.0004 -0.8491 -vn -0.9223 -0.0004 0.3864 -vn -0.1860 -0.0004 0.9825 -vn -0.3761 -0.0010 0.9266 -vn 0.5500 -0.0005 -0.8352 -vn 0.9935 -0.0004 0.1135 -vn 0.1614 -0.0006 0.9869 -vn 0.3714 -0.0010 -0.9285 -vn 0.0309 -0.0018 -0.9995 -vn 0.1543 0.0018 0.9880 -vn -0.1928 0.0008 0.9812 -vn 0.9102 -0.0010 0.4141 -vn 0.3625 -0.0010 -0.9320 -vn 0.8840 0.0004 -0.4675 -vn -0.9930 -0.0004 -0.1177 -vn 0.4999 0.0010 -0.8661 -vn 0.4998 0.0010 -0.8661 -vn -0.9925 -0.0008 0.1223 -vn 0.7886 -0.0012 0.6149 -vn 0.8009 -0.0018 -0.5988 -vn 0.4598 0.0010 0.8880 -vn -0.5611 -0.0006 -0.8277 -vn 0.5656 -0.0010 0.8247 -vn -0.3675 0.0018 0.9300 -vn -0.3676 0.0018 0.9300 -vn 0.7224 0.0012 0.6915 -vn 0.0551 -0.0003 -0.9985 -vn -0.8583 -0.0012 -0.5131 -vn 0.9827 0.0017 0.1850 -vn -0.9933 -0.0004 -0.1157 -vn 0.0182 -0.0006 0.9998 -vn -0.1655 -0.0013 0.9862 -vn -0.8373 0.0009 -0.5467 -vn -0.8374 0.0009 -0.5466 -vn -0.0755 -0.0003 -0.9971 -vn 0.2000 0.0007 0.9798 -vn 0.9949 -0.0003 0.1012 -vn -0.8574 -0.0011 -0.5147 -vn 0.3754 0.0007 0.9269 -vn 0.1329 0.0017 -0.9911 -vn 0.9949 -0.0005 -0.1005 -vn 0.1280 0.0004 0.9918 -vn 0.4732 0.0004 0.8809 -vn 0.9883 0.0017 0.1528 -vn -0.8881 -0.0005 0.4597 -vn -0.9875 -0.0008 -0.1576 -vn -0.9875 -0.0008 -0.1578 -vn -0.3768 -0.0009 0.9263 -vn -0.7178 0.0017 0.6962 -vn 0.1519 -0.0006 0.9884 -vn 0.7450 -0.0004 -0.6670 -vn -0.1079 0.0004 -0.9942 -vn 0.8524 0.0017 0.5229 -vn 0.3904 -0.0012 -0.9207 -vn 0.5279 -0.0009 0.8493 -vn 0.5393 0.0017 0.8421 -vn -0.6674 0.0000 -0.7447 -vn 0.9781 -0.0000 0.2082 -vn -0.9124 -0.0000 0.4093 -vn 0.9017 -0.0000 0.4323 -vn -0.9650 -0.0017 0.2622 -vn 0.9175 -0.0011 0.3977 -vn 0.9373 0.0006 0.3486 -vn -0.9965 0.0007 0.0841 -vn 0.7506 -0.0005 0.6608 -vn 0.7505 -0.0005 0.6608 -vn -0.7765 -0.0006 -0.6301 -vn -0.7462 -0.0006 -0.6657 -vn -0.7462 -0.0006 -0.6658 -vn 0.5908 0.0017 -0.8068 -vn 0.3021 -0.0001 -0.9533 -vn -0.2169 -0.0001 -0.9762 -vn 0.9622 -0.0016 -0.2724 -vn 0.1551 0.0006 0.9879 -vn 0.4413 0.0016 0.8974 -vn -0.1261 0.0004 -0.9920 -vn 0.7455 0.0016 0.6665 -vn 0.9589 -0.0005 -0.2839 -vn 0.9588 -0.0005 -0.2839 -vn 0.1088 -0.0007 -0.9941 -vn 0.1707 0.0004 -0.9853 -vn 0.9082 -0.0008 0.4185 -vn -0.4743 0.0000 0.8804 -vn 0.3712 -0.0000 0.9285 -vn 0.5831 -0.0010 0.8124 -vn -0.3553 0.0000 -0.9348 -vn -0.3553 -0.0000 -0.9348 -vn 0.2334 -0.0004 -0.9724 -vn -0.7501 -0.0003 0.6613 -vn -0.9245 0.0002 0.3812 -vn -0.7383 0.0004 0.6745 -vn -0.7383 0.0004 0.6744 -vn -0.8489 -0.0011 0.5285 -vn 0.0366 0.0007 0.9993 -vn -0.1534 0.0015 0.9882 -vn -0.6346 -0.0001 -0.7728 -vn 0.2802 -0.0008 0.9599 -vn -0.3586 -0.0004 -0.9335 -vn -0.9741 0.0001 0.2259 -vn -0.9742 0.0001 0.2259 -vn 0.3420 -0.0015 -0.9397 -vn -0.5267 -0.0003 -0.8501 -vn -0.5474 -0.0000 0.8369 -vn -0.9901 -0.0005 0.1405 -vn -0.7922 -0.0004 -0.6103 -vn 0.0689 0.0005 0.9976 -vn -0.8048 -0.0002 0.5935 -vn -0.8048 -0.0002 0.5936 -vn 0.4393 -0.0018 -0.8983 -vn 0.2968 0.0015 0.9549 -vn -0.2893 0.0000 -0.9572 -vn 0.9560 0.0004 -0.2934 -vn 0.4874 0.0011 -0.8732 -vn 0.4875 0.0011 -0.8731 -vn -0.1266 -0.0013 -0.9919 -vn 0.9933 -0.0004 0.1156 -vn 0.9207 0.0017 -0.3902 -vn -0.7478 0.0019 -0.6640 -vn -0.9907 0.0000 -0.1363 -vn -0.1654 0.0007 0.9862 -vn 0.5654 -0.0010 -0.8248 -vn 0.4942 0.0015 0.8693 -vn 0.9945 0.0004 -0.1044 -vn -0.6414 -0.0003 0.7672 -vn -0.5116 0.0004 0.8592 -vn 0.9336 -0.0007 0.3583 -vn 0.1535 0.0008 -0.9882 -vn 0.6354 0.0003 -0.7722 -vn 0.8042 0.0014 -0.5943 -vn 0.9194 0.0003 -0.3934 -vn -0.9593 0.0000 -0.2824 -vn -0.4486 0.0003 0.8937 -vn -0.6956 -0.0010 -0.7184 -vn -0.1084 0.0004 0.9941 -vn 0.0193 -0.0006 -0.9998 -vn 0.7931 0.0004 0.6090 -vn 0.3721 0.0014 0.9282 -vn 0.7932 0.0004 0.6090 -vn -0.9749 0.0000 -0.2226 -vn 0.4789 0.0014 0.8779 -vn -0.9666 -0.0002 -0.2563 -vn 0.9960 -0.0009 0.0888 -vn -0.2600 0.0014 -0.9656 -vn -0.8282 0.0013 -0.5604 -vn -0.1854 0.0004 0.9827 -vn 0.8293 -0.0004 -0.5588 -vn -0.4707 -0.0001 0.8823 -vn -0.7742 0.0003 0.6329 -vn 0.8309 0.0013 0.5564 -vn 0.6726 -0.0003 0.7400 -vn -0.9831 -0.0000 0.1829 -vn 0.1037 -0.0011 -0.9946 -vn -0.4488 0.0003 0.8937 -vn -0.9249 0.0003 0.3802 -vn -0.2118 0.0014 0.9773 -vn 0.0646 0.0014 0.9979 -vn 0.2500 0.0014 0.9682 -vn -0.3429 -0.0004 -0.9394 -vn 0.1221 0.0013 -0.9925 -vn 0.8572 -0.0008 -0.5150 -vn -0.7084 0.0015 0.7058 -vn -0.8160 -0.0004 -0.5781 -vn -0.8161 -0.0004 -0.5780 -vn -0.7738 -0.0007 0.6334 -vn -0.4829 0.0013 -0.8757 -vn -0.2019 0.0005 -0.9794 -vn 0.0166 0.0013 0.9999 -vn 0.3129 -0.0016 -0.9498 -vn 0.4470 0.0003 -0.8945 -vn 0.9975 -0.0011 0.0705 -vn 0.9912 0.0003 -0.1325 -vn 0.1352 -0.0013 -0.9908 -vn 0.9912 0.0003 -0.1326 -vn 0.1787 0.0000 -0.9839 -vn -0.9995 0.0003 0.0308 -vn -0.1757 -0.0013 -0.9844 -vn 0.9800 -0.0000 0.1990 -vn 0.6449 -0.0005 -0.7643 -vn 0.9790 -0.0003 0.2040 -vn -0.6658 0.0013 -0.7462 -vn -0.3114 0.0007 0.9503 -vn 0.1706 -0.0000 0.9853 -vn 0.9620 -0.0002 0.2730 -vn 0.9409 0.0000 -0.3386 -vn -0.2498 -0.0003 0.9683 -vn -0.6382 -0.0006 -0.7699 -vn -0.9723 -0.0002 0.2338 -vn -0.8596 -0.0000 0.5110 -vn -0.8595 -0.0000 0.5111 -vn -0.9362 0.0014 0.3516 -vn 0.7889 0.0015 -0.6146 -vn 0.4066 0.0014 -0.9136 -vn 0.9982 0.0002 0.0592 -vn 0.9983 0.0002 0.0591 -vn 0.9815 -0.0002 0.1913 -vn -0.9978 0.0003 -0.0665 -vn -0.9978 0.0003 -0.0666 -vn -0.4578 0.0014 0.8890 -vn -0.9958 0.0006 -0.0916 -vn 0.2302 -0.0000 0.9732 -vn 0.4722 0.0014 -0.8815 -vn 0.9997 0.0005 -0.0242 -vn 0.9997 0.0005 -0.0243 -vn 0.6304 0.0013 -0.7763 -vn 0.6303 0.0013 -0.7763 -vn -0.4824 -0.0004 0.8760 -vn 0.1681 0.0003 -0.9858 -vn 0.1680 0.0003 -0.9858 -vn 0.9924 -0.0012 -0.1231 -vn 0.4926 -0.0014 -0.8703 -vn -0.5943 0.0003 0.8042 -vn -0.5943 0.0003 0.8043 -vn 0.5195 -0.0007 0.8545 -vn 0.1956 0.0014 -0.9807 -vn 0.9291 -0.0003 0.3699 -vn -0.1688 0.0003 0.9856 -vn -0.1042 -0.0003 0.9946 -vn -0.0748 -0.0001 -0.9972 -vn -0.7006 0.0013 0.7136 -vn -0.7006 0.0013 0.7135 -vn -0.9930 0.0002 -0.1178 -vn -0.9708 -0.0012 -0.2400 -vn -0.1027 0.0005 -0.9947 -vn 0.7952 0.0006 -0.6064 -vn -0.1845 0.0013 0.9828 -vn 0.6724 0.0013 -0.7402 -vn 0.4665 0.0008 -0.8845 -vn -0.9282 0.0002 0.3721 -vn -0.2838 -0.0009 0.9589 -vn -0.9344 -0.0007 0.3563 -vn -0.6355 -0.0003 0.7721 -vn 0.6677 0.0002 0.7444 -vn -0.8148 0.0004 0.5797 -vn 0.6677 0.0002 0.7445 -vn 0.7041 0.0013 -0.7101 -vn 0.9322 -0.0007 -0.3619 -vn 0.9349 -0.0005 0.3550 -vn 0.9375 -0.0007 -0.3479 -vn 0.8408 0.0000 -0.5414 -vn 0.8408 -0.0000 -0.5414 -vn 0.9975 0.0011 0.0713 -vn 0.1951 0.0011 -0.9808 -vn -0.8054 0.0002 -0.5927 -vn -0.4218 0.0013 -0.9067 -vn -0.7919 0.0003 0.6107 -vn -0.9909 0.0003 0.1348 -vn 0.3104 0.0006 -0.9506 -vn -0.5631 -0.0003 0.8264 -vn 0.7086 -0.0002 -0.7056 -vn 0.0793 0.0004 0.9968 -vn -0.9049 0.0013 -0.4257 -vn -0.9911 0.0012 0.1329 -vn -0.9737 0.0011 0.2278 -vn 0.9993 0.0003 0.0379 -vn -0.9448 0.0011 -0.3278 -vn 0.9353 -0.0000 0.3539 -vn -0.7737 0.0012 0.6336 -vn -0.8431 0.0000 -0.5377 -vn -0.4561 -0.0003 -0.8899 -vn -0.7553 -0.0010 -0.6554 -vn -0.9685 -0.0000 0.2492 -vn -0.9685 0.0000 0.2492 -vn 0.9430 0.0011 0.3328 -vn -0.7760 0.0012 -0.6307 -vn 0.8982 0.0012 0.4397 -vn 0.8981 0.0012 0.4397 -vn 0.7264 0.0003 0.6873 -vn -0.9098 0.0012 -0.4151 -vn -0.9067 -0.0008 0.4217 -vn -0.6806 0.0012 -0.7327 -vn 0.2836 -0.0012 -0.9589 -vn 0.7747 0.0012 0.6323 -vn -0.9671 -0.0002 -0.2542 -vn -0.9672 -0.0002 -0.2542 -vn -0.5521 -0.0006 0.8338 -vn 0.5472 -0.0006 -0.8370 -vn 0.7607 0.0012 0.6491 -vn -0.4747 0.0012 -0.8802 -vn 0.1879 0.0012 -0.9822 -vn -0.8333 -0.0003 0.5528 -vn 0.3880 0.0000 -0.9217 -vn -0.1055 -0.0002 0.9944 -vn 0.3880 -0.0000 -0.9217 -vn -0.2249 -0.0003 -0.9744 -vn -0.1684 0.0012 -0.9857 -vn -0.9269 -0.0000 0.3753 -vn 0.3563 0.0006 -0.9344 -vn -0.9470 -0.0009 -0.3213 -vn 0.9103 -0.0003 -0.4139 -vn -0.6787 -0.0009 -0.7344 -vn 0.5422 -0.0000 0.8402 -vn 0.5423 -0.0000 0.8402 -vn -0.6233 0.0003 0.7820 -vn -0.9900 0.0003 0.1410 -vn -0.3818 0.0012 0.9242 -vn -0.7148 -0.0006 -0.6993 -vn -0.7148 -0.0006 -0.6994 -vn 0.9495 0.0012 0.3138 -vn 0.9495 0.0012 0.3139 -vn -0.8881 -0.0003 0.4597 -vn -0.1635 -0.0010 0.9865 -vn -0.5985 0.0012 0.8011 -vn 0.7486 0.0003 -0.6631 -vn -0.5400 0.0012 0.8417 -vn -0.4797 0.0000 -0.8774 -vn -0.4798 0.0000 -0.8774 -vn -0.4798 -0.0000 -0.8774 -vn -0.5399 0.0012 0.8417 -vn -0.5962 0.0012 -0.8028 -vn 0.8774 0.0005 -0.4798 -vn -0.9768 0.0011 -0.2143 -vn 0.3155 0.0011 0.9489 -vn -0.6896 -0.0006 0.7242 -vn -0.9112 -0.0002 -0.4119 -vn -0.9112 -0.0002 -0.4120 -vn -0.8517 0.0000 -0.5240 -vn 0.8999 -0.0000 0.4361 -vn 0.8999 -0.0018 0.4361 -vn -0.8518 0.0000 -0.5239 -vn -0.2131 -0.0002 0.9770 -vn -0.9769 -0.0002 -0.2138 -vn 0.6009 0.0011 0.7993 -vn 0.5852 0.0011 0.8109 -vn 0.9741 0.0011 0.2262 -vn 0.4444 0.0002 0.8958 -vn 0.0985 0.0004 0.9951 -vn -0.3768 0.0011 -0.9263 -vn 0.3719 0.0011 0.9283 -vn -0.3250 -0.0002 -0.9457 -vn -0.1547 0.0011 0.9880 -vn -0.9189 -0.0002 -0.3946 -vn -0.2498 0.0011 -0.9683 -vn 0.6621 0.0011 0.7494 -vn -0.9919 -0.0002 -0.1269 -vn 0.1674 -0.0017 -0.9859 -vn -0.2980 0.0011 0.9546 -vn -0.5512 -0.0005 0.8344 -vn -0.2257 0.0003 0.9742 -vn 0.5059 -0.0000 0.8626 -vn 0.2696 0.0011 0.9630 -vn 0.9820 -0.0003 0.1890 -vn -0.9780 0.0011 -0.2085 -vn 0.9820 -0.0003 0.1891 -vn -0.9929 -0.0002 -0.1187 -vn -0.8673 0.0001 0.4977 -vn -0.2563 0.0011 -0.9666 -vn -0.9768 -0.0007 0.2139 -vn -0.9768 -0.0007 0.2140 -vn 0.9255 -0.0005 0.3788 -vn 0.9255 -0.0005 0.3789 -vn 0.2892 0.0003 0.9573 -vn 0.1597 -0.0002 -0.9872 -vn 0.9967 -0.0007 0.0815 -vn 0.4846 -0.0000 0.8747 -# 1572 vertex normals - -g check_config_text -usemtl red -s off -f 1//1 2//1 3//1 -f 4//2 5//2 6//2 -f 7//3 8//3 9//3 -f 10//4 11//4 12//4 -f 3//5 13//5 1//5 -f 9//6 14//6 7//6 -f 15//7 16//7 17//7 -f 18//8 19//8 20//8 -f 21//9 22//9 23//9 -f 24//10 25//10 26//10 -f 27//11 28//11 29//11 -f 30//12 31//12 32//12 -f 33//10 34//10 35//10 -f 36//11 37//11 38//11 -f 39//12 40//12 41//12 -f 42//13 43//13 44//13 -f 45//14 20//14 19//14 -f 46//15 47//15 48//15 -f 49//16 50//16 51//16 -f 52//17 23//17 22//17 -f 53//18 44//18 43//18 -f 54//16 55//16 56//16 -f 57//19 58//19 59//19 -f 60//20 61//20 62//20 -f 63//21 64//21 65//21 -f 66//22 67//22 68//22 -f 69//21 70//21 71//21 -f 72//23 73//23 74//23 -f 75//19 76//19 77//19 -f 78//20 79//20 80//20 -f 81//21 82//21 83//21 -f 84//23 85//23 86//23 -f 87//24 88//24 89//24 -f 90//20 91//20 92//20 -f 93//25 94//25 95//25 -f 96//26 97//26 98//26 -f 99//25 100//25 101//25 -f 102//26 103//26 104//26 -f 105//26 106//26 107//26 -f 108//25 109//25 110//25 -f 107//27 111//27 105//27 -f 112//28 113//28 114//28 -f 98//27 115//27 96//27 -f 116//28 117//28 118//28 -f 104//27 119//27 102//27 -f 120//28 121//28 122//28 -f 123//29 124//29 125//29 -f 126//30 127//30 128//30 -f 129//29 130//29 131//29 -f 132//30 133//30 134//30 -f 135//29 136//29 137//29 -f 138//31 139//31 140//31 -f 141//32 142//32 143//32 -f 144//33 145//33 146//33 -f 147//33 148//33 149//33 -f 150//32 151//32 152//32 -f 125//34 153//34 123//34 -f 154//35 155//35 156//35 -f 131//34 157//34 129//34 -f 158//35 159//35 160//35 -f 161//35 162//35 163//35 -f 137//34 164//34 135//34 -f 71//36 165//36 69//36 -f 166//37 167//37 168//37 -f 83//36 169//36 81//36 -f 170//38 171//38 172//38 -f 173//39 174//39 175//39 -f 65//36 176//36 63//36 -f 177//40 178//40 179//40 -f 180//41 181//41 182//41 -f 183//42 184//42 185//42 -f 186//43 187//43 188//43 -f 189//44 190//44 191//44 -f 192//44 193//44 194//44 -f 195//44 196//44 197//44 -f 198//45 199//45 148//45 -f 200//46 201//46 202//46 -f 203//47 204//47 205//47 -f 206//48 207//48 208//48 -f 209//49 210//49 211//49 -f 212//50 213//50 214//50 -f 215//49 216//49 217//49 -f 218//51 219//51 220//51 -f 221//52 222//52 223//52 -f 224//53 225//53 226//53 -f 227//54 228//54 229//54 -f 230//55 48//55 47//55 -f 231//56 232//56 233//56 -f 234//57 235//57 236//57 -f 237//58 238//58 239//58 -f 240//59 6//59 5//59 -f 241//60 242//60 243//60 -f 244//61 191//61 190//61 -f 245//60 246//60 247//60 -f 248//61 194//61 193//61 -f 249//60 250//60 251//60 -f 252//61 197//61 196//61 -f 253//62 188//62 254//62 -f 255//63 256//63 257//63 -f 258//64 259//64 260//64 -f 261//65 262//65 263//65 -f 264//45 265//45 145//45 -f 266//62 267//62 268//62 -f 269//63 270//63 271//63 -f 272//66 273//66 274//66 -f 275//67 276//67 277//67 -f 278//68 279//68 280//68 -f 181//69 281//69 282//69 -f 283//70 284//70 285//70 -f 286//71 287//71 288//71 -f 289//70 290//70 291//70 -f 292//71 293//71 294//71 -f 295//72 296//72 297//72 -f 298//73 299//73 300//73 -f 301//74 302//74 303//74 -f 304//75 305//75 306//75 -f 307//76 308//76 309//76 -f 310//75 311//75 312//75 -f 313//76 314//76 315//76 -f 316//43 317//43 267//43 -f 318//77 319//77 320//77 -f 321//78 322//78 323//78 -f 324//79 285//79 284//79 -f 288//80 325//80 286//80 -f 294//80 326//80 292//80 -f 327//81 291//81 290//81 -f 300//82 328//82 298//82 -f 297//83 329//83 295//83 -f 260//64 330//64 258//64 -f 263//84 331//84 261//84 -f 332//85 333//85 334//85 -f 323//86 335//86 321//86 -s 1 -f 228//87 227//87 336//87 -f 11//87 10//87 336//87 -s off -f 337//88 338//88 339//88 -f 340//89 341//89 342//89 -f 343//90 344//90 345//90 -f 346//89 347//89 348//89 -f 349//91 350//91 351//91 -f 352//92 353//92 354//92 -f 355//91 356//91 357//91 -f 358//93 359//93 360//93 -f 361//93 362//93 363//93 -f 364//93 365//93 366//93 -f 236//94 367//94 234//94 -f 368//95 369//95 370//95 -f 371//96 372//96 373//96 -f 374//97 160//97 159//97 -f 375//96 376//96 377//96 -f 378//97 156//97 155//97 -f 379//96 380//96 381//96 -f 382//97 163//97 162//97 -f 383//98 384//98 385//98 -f 386//41 387//41 388//41 -f 389//99 390//99 391//99 -f 392//100 393//100 394//100 -f 395//101 396//101 397//101 -f 182//41 398//41 180//41 -f 399//98 400//98 401//98 -f 143//102 402//102 141//102 -f 403//103 404//103 405//103 -f 152//102 406//102 150//102 -f 407//103 408//103 409//103 -f 410//104 411//104 412//104 -f 413//105 414//105 415//105 -f 416//104 417//104 418//104 -f 419//106 420//106 421//106 -f 422//104 423//104 424//104 -f 425//106 426//106 427//106 -f 428//107 429//107 430//107 -f 431//107 432//107 433//107 -f 434//107 435//107 436//107 -f 271//108 437//108 269//108 -f 257//108 438//108 255//108 -f 439//109 440//109 441//109 -f 442//110 399//110 443//110 -f 444//111 445//111 446//111 -f 447//112 448//112 449//112 -f 450//111 451//111 452//111 -f 453//112 454//112 455//112 -f 456//111 457//111 458//111 -f 459//112 460//112 461//112 -f 462//113 463//113 464//113 -f 465//114 466//114 467//114 -f 468//114 469//114 470//114 -f 471//114 472//114 473//114 -f 474//115 475//115 476//115 -f 477//116 478//116 479//116 -f 480//117 481//117 482//117 -s 1 -f 483//87 481//87 480//87 -s off -f 160//118 484//118 158//118 -f 156//118 485//118 154//118 -s 1 -f 486//87 487//87 488//87 -s off -f 489//116 490//116 491//116 -f 488//117 487//117 492//117 -f 163//118 493//118 161//118 -f 494//116 495//116 496//116 -f 497//117 498//117 499//117 -s 1 -f 500//87 498//87 497//87 -s off -f 501//115 502//115 503//115 -f 504//119 505//119 506//119 -f 507//120 508//120 509//120 -f 510//121 511//121 512//121 -f 513//41 514//41 515//41 -f 516//122 517//122 518//122 -f 519//123 520//123 521//123 -f 522//124 523//124 524//124 -f 525//124 526//124 527//124 -f 528//123 529//123 530//123 -f 531//124 532//124 533//124 -f 534//123 535//123 536//123 -f 537//125 538//125 539//125 -f 540//126 541//126 542//126 -f 543//127 544//127 545//127 -f 546//41 547//41 548//41 -f 549//128 550//128 551//128 -f 552//98 553//98 554//98 -f 548//41 555//41 546//41 -f 556//129 557//129 558//129 -f 559//41 560//41 561//41 -f 562//41 563//41 564//41 -f 565//129 566//129 567//129 -f 568//130 569//130 570//130 -f 571//130 572//130 573//130 -f 574//130 575//130 576//130 -s 1 -f 577//131 578//131 579//131 -f 580//131 581//131 582//131 -s off -f 583//132 584//132 585//132 -f 586//132 587//132 588//132 -f 589//133 590//133 591//133 -f 592//134 593//134 594//134 -s 1 -f 312//87 344//87 343//87 -s off -f 595//135 596//135 597//135 -s 1 -f 306//87 338//87 337//87 -s off -f 598//135 599//135 600//135 -f 601//49 602//49 603//49 -f 441//136 604//136 439//136 -f 605//137 606//137 607//137 -f 608//46 609//46 610//46 -f 611//46 612//46 613//46 -f 614//138 615//138 616//138 -f 617//47 618//47 619//47 -f 620//47 621//47 622//47 -f 558//139 623//139 556//139 -f 561//41 624//41 559//41 -f 564//41 625//41 562//41 -f 567//139 626//139 565//139 -f 627//140 628//140 629//140 -f 630//140 631//140 632//140 -s 1 -f 117//87 116//87 633//87 -s off -f 573//141 633//141 571//141 -s 1 -f 121//87 120//87 634//87 -s off -f 576//141 634//141 574//141 -f 570//141 635//141 568//141 -s 1 -f 113//87 112//87 635//87 -s off -f 636//98 637//98 638//98 -f 639//142 640//142 641//142 -f 642//140 643//140 644//140 -f 645//48 646//48 647//48 -f 648//41 649//41 650//41 -f 651//41 652//41 653//41 -f 654//143 655//143 656//143 -f 515//41 657//41 513//41 -f 638//98 658//98 636//98 -f 659//144 660//144 661//144 -f 641//142 662//142 639//142 -f 663//144 664//144 665//144 -f 666//143 667//143 668//143 -f 669//145 670//145 671//145 -s 1 -f 672//87 256//87 255//87 -f 43//87 42//87 673//87 -f 22//87 21//87 674//87 -f 675//87 270//87 269//87 -s off -f 676//146 677//146 678//146 -f 551//128 679//128 549//128 -f 680//147 681//147 682//147 -f 683//148 684//148 685//148 -f 491//116 686//116 489//116 -f 479//116 687//116 477//116 -f 688//148 689//148 690//148 -f 691//148 692//148 693//148 -f 496//116 694//116 494//116 -f 597//149 695//149 595//149 -f 600//149 696//149 598//149 -f 233//150 697//150 231//150 -s 1 -f 47//87 20//87 45//87 -s off -f 698//151 699//151 700//151 -f 701//152 702//152 703//152 -f 704//152 705//152 706//152 -f 707//152 708//152 709//152 -f 710//153 711//153 712//153 -f 668//154 713//154 666//154 -f 714//155 715//155 716//155 -f 656//156 717//156 654//156 -f 718//157 719//157 720//157 -s 1 -f 721//87 145//87 144//87 -f 722//87 148//87 147//87 -s off -f 723//157 724//157 725//157 -s 1 -f 182//131 443//131 401//131 -s off -f 726//41 727//41 728//41 -f 729//98 730//98 731//98 -f 731//98 732//98 729//98 -f 728//41 733//41 726//41 -f 734//158 735//158 736//158 -f 737//159 738//159 739//159 -f 740//160 741//160 742//160 -f 743//159 744//159 745//159 -f 746//161 747//161 748//161 -f 749//162 750//162 751//162 -f 752//160 753//160 754//160 -f 388//41 755//41 386//41 -f 385//98 756//98 383//98 -s 1 -f 47//87 46//87 20//87 -s off -f 757//163 539//163 538//163 -f 334//85 758//85 332//85 -f 759//164 760//164 761//164 -f 716//165 762//165 714//165 -f 671//166 763//166 669//166 -s 1 -f 332//87 671//87 333//87 -s off -f 764//167 765//167 766//167 -f 653//41 767//41 651//41 -f 768//167 769//167 770//167 -f 650//41 771//41 648//41 -f 712//165 772//165 710//165 -f 773//168 774//168 775//168 -f 776//168 777//168 778//168 -s 1 -f 779//87 225//87 224//87 -s off -f 780//169 781//169 782//169 -f 751//170 783//170 749//170 -f 745//171 784//171 743//171 -f 739//171 785//171 737//171 -f 786//172 787//172 788//172 -f 770//173 789//173 768//173 -f 766//173 790//173 764//173 -s 1 -f 791//87 792//87 793//87 -s off -f 794//174 791//174 795//174 -f 788//175 796//175 786//175 -s 1 -f 331//87 796//87 788//87 -s off -f 797//176 798//176 799//176 -s 1 -f 798//87 797//87 673//87 -s off -f 443//177 800//177 442//177 -s 1 -f 557//131 556//131 559//131 -f 566//131 565//131 562//131 -f 687//131 479//131 158//131 -f 686//131 491//131 154//131 -f 694//131 496//131 161//131 -s off -f 801//178 802//178 803//178 -f 804//179 805//179 806//179 -f 807//180 808//180 809//180 -f 514//116 810//116 811//116 -s 1 -f 812//87 514//87 517//87 -s off -f 665//181 813//181 663//181 -f 661//181 814//181 659//181 -f 815//182 816//182 817//182 -f 818//182 819//182 820//182 -f 821//182 822//182 823//182 -f 824//183 825//183 826//183 -s 1 -f 827//131 787//131 786//131 -f 828//131 829//131 830//131 -s off -f 831//41 832//41 833//41 -f 834//98 835//98 836//98 -f 837//184 838//184 839//184 -f 840//142 841//142 842//142 -f 833//41 843//41 831//41 -f 836//98 844//98 834//98 -f 842//142 845//142 840//142 -f 839//184 846//184 837//184 -f 847//185 848//185 849//185 -f 850//186 851//186 852//186 -f 853//187 854//187 855//187 -f 856//188 857//188 858//188 -f 859//189 860//189 861//189 -s 1 -f 329//87 328//87 300//87 -f 778//87 598//87 862//87 -s off -f 778//190 862//190 776//190 -f 775//190 863//190 773//190 -s 1 -f 775//87 595//87 863//87 -f 399//87 442//87 440//87 -f 279//87 278//87 272//87 -f 555//87 553//87 552//87 -s off -f 864//98 865//98 866//98 -s 1 -f 867//87 34//87 33//87 -f 868//87 719//87 718//87 -f 869//87 25//87 24//87 -f 870//87 724//87 723//87 -f 331//87 871//87 260//87 -s off -f 872//191 873//191 874//191 -f 874//191 875//191 872//191 -f 876//192 877//192 878//192 -s 1 -f 393//87 392//87 390//87 -s off -f 277//193 879//193 275//193 -f 866//98 880//98 864//98 -f 624//116 881//116 882//116 -s 1 -f 624//87 623//87 558//87 -s off -f 625//116 883//116 884//116 -s 1 -f 625//87 626//87 567//87 -f 885//87 682//87 260//87 -s off -f 682//194 885//194 680//194 -s 1 -f 886//131 311//131 310//131 -f 774//131 887//131 888//131 -f 777//131 889//131 890//131 -f 891//131 305//131 304//131 -f 580//131 402//131 892//131 -f 893//131 894//131 895//131 -f 577//131 406//131 896//131 -f 897//131 898//131 899//131 -f 699//87 698//87 900//87 -f 232//87 231//87 235//87 -f 335//87 323//87 901//87 -f 812//87 517//87 516//87 -s off -f 902//195 903//195 904//195 -f 905//195 906//195 907//195 -f 908//195 909//195 910//195 -f 911//196 912//196 913//196 -f 914//196 915//196 916//196 -f 917//196 918//196 919//196 -f 852//186 920//186 850//186 -s 1 -f 921//87 624//87 922//87 -s off -f 855//197 923//197 853//197 -s 1 -f 924//87 625//87 925//87 -s off -f 926//198 927//198 928//198 -s 1 -f 8//87 7//87 4//87 -f 58//87 67//87 66//87 -f 929//87 417//87 416//87 -f 930//87 411//87 410//87 -f 88//87 85//87 84//87 -f 76//87 73//87 72//87 -f 931//87 423//87 422//87 -s off -f 86//199 932//199 84//199 -f 74//199 933//199 72//199 -f 68//199 934//199 66//199 -s 1 -f 290//131 935//131 936//131 -f 814//131 661//131 937//131 -f 813//131 665//131 938//131 -f 284//131 939//131 940//131 -f 941//131 606//131 942//131 -f 943//131 944//131 277//131 -f 945//87 539//87 757//87 -f 946//87 219//87 218//87 -s off -f 947//200 948//200 949//200 -s 1 -f 222//87 221//87 950//87 -f 762//131 951//131 655//131 -f 772//131 952//131 667//131 -f 325//87 288//87 953//87 -f 714//87 656//87 715//87 -f 710//87 668//87 711//87 -f 326//87 294//87 954//87 -f 127//87 126//87 955//87 -s off -f 956//201 957//201 958//201 -s 1 -f 133//87 132//87 959//87 -s off -f 960//201 961//201 962//201 -f 963//201 964//201 965//201 -s 1 -f 139//87 138//87 966//87 -s off -f 967//202 968//202 969//202 -f 678//146 970//146 676//146 -f 700//203 971//203 698//203 -f 972//204 280//204 279//204 -s 1 -f 973//131 974//131 975//131 -f 976//131 977//131 978//131 -f 979//131 980//131 981//131 -s off -f 982//205 391//205 390//205 -s 1 -f 546//131 983//131 554//131 -f 546//131 880//131 866//131 -s off -f 984//206 985//206 986//206 -s 1 -f 278//87 273//87 272//87 -f 276//87 275//87 281//87 -f 457//87 456//87 987//87 -f 91//87 82//87 81//87 -f 445//87 444//87 988//87 -f 79//87 70//87 69//87 -f 61//87 64//87 63//87 -f 451//87 450//87 989//87 -f 990//131 991//131 992//131 -f 13//131 993//131 12//131 -s off -f 994//207 995//207 996//207 -s 1 -f 997//87 505//87 504//87 -s off -f 998//208 999//208 1000//208 -s 1 -f 758//131 1001//131 1002//131 -s off -f 1003//209 1004//209 1005//209 -f 1006//210 1007//210 1008//210 -s 1 -f 121//87 634//87 576//87 -f 250//87 249//87 197//87 -f 113//87 635//87 570//87 -f 242//87 241//87 191//87 -f 117//87 633//87 573//87 -f 246//87 245//87 194//87 -f 31//87 30//87 1009//87 -f 28//87 27//87 1010//87 -f 40//87 39//87 1011//87 -f 37//87 36//87 1012//87 -s off -f 986//206 1013//206 984//206 -s 1 -f 232//87 235//87 234//87 -f 42//87 1014//87 1015//87 -s off -f 1015//211 1014//211 1016//211 -s 1 -f 22//87 674//87 1017//87 -s off -f 1017//212 674//212 1018//212 -s 1 -f 781//87 780//87 1019//87 -s off -f 1020//213 1021//213 1022//213 -s 1 -f 1023//87 291//87 327//87 -s off -f 1024//214 1025//214 1026//214 -s 1 -f 1027//87 285//87 324//87 -s off -f 1028//214 1029//214 1030//214 -s 1 -f 1031//131 1032//131 1033//131 -f 372//87 371//87 1034//87 -f 477//87 130//87 129//87 -f 494//87 136//87 135//87 -f 380//87 379//87 1035//87 -f 489//87 124//87 123//87 -f 376//87 375//87 1036//87 -s off -f 1037//98 811//98 810//98 -f 1038//215 1039//215 1040//215 -f 1041//216 1042//216 1043//216 -f 1044//217 1045//217 1046//217 -f 1047//217 1048//217 1049//217 -s 1 -f 1050//131 1051//131 1052//131 -s off -f 1053//142 1054//142 1055//142 -f 861//218 1056//218 859//218 -f 276//98 439//98 604//98 -s 1 -f 181//87 400//87 399//87 -s off -f 1057//219 1058//219 1059//219 -f 1060//219 1061//219 1062//219 -s 1 -f 329//87 297//87 328//87 -s off -f 1055//142 1063//142 1053//142 -f 1064//220 1065//220 1066//220 -s 1 -f 1067//131 1068//131 1069//131 -f 1070//131 1071//131 1072//131 -s off -f 1073//221 1074//221 1075//221 -f 1076//215 1077//215 1078//215 -s 1 -f 1079//131 1080//131 1081//131 -f 1082//131 1083//131 1084//131 -f 1085//131 298//131 1086//131 -f 242//87 191//87 244//87 -s off -f 1087//222 1088//222 1089//222 -s 1 -f 246//87 194//87 248//87 -s off -f 1090//222 1091//222 1092//222 -s 1 -f 250//87 197//87 252//87 -s off -f 1093//222 1094//222 1095//222 -s 1 -f 631//131 212//131 1096//131 -s off -f 1097//223 1098//223 1099//223 -f 1100//223 1101//223 1102//223 -s 1 -f 61//87 60//87 64//87 -f 1103//87 420//87 419//87 -f 1104//87 414//87 413//87 -f 91//87 90//87 82//87 -f 79//87 78//87 70//87 -f 1105//87 426//87 425//87 -f 412//131 1106//131 1107//131 -f 1108//87 744//87 743//87 -s off -f 1109//224 1110//224 1111//224 -s 1 -f 1112//87 750//87 749//87 -s off -f 1113//224 1114//224 1115//224 -s 1 -f 1116//87 738//87 737//87 -s off -f 1117//224 1118//224 1119//224 -f 1120//207 1121//207 1122//207 -s 1 -f 588//87 523//87 522//87 -f 1123//87 526//87 525//87 -s off -f 996//207 1124//207 994//207 -f 1125//207 1126//207 1127//207 -s 1 -f 585//87 532//87 531//87 -f 868//87 1128//87 719//87 -s off -f 1128//225 868//225 1129//225 -f 1130//225 870//225 1131//225 -s 1 -f 870//87 1130//87 724//87 -s off -f 1132//226 949//226 948//226 -f 59//227 1133//227 57//227 -f 77//227 1134//227 75//227 -f 89//227 1135//227 87//227 -f 92//228 1136//228 90//228 -f 80//228 1137//228 78//228 -f 62//228 1138//228 60//228 -s 1 -f 267//87 266//87 1139//87 -s off -f 1140//229 1141//229 1142//229 -f 1143//229 1144//229 1145//229 -s 1 -f 188//87 253//87 1146//87 -f 1147//131 886//131 310//131 -f 1148//131 891//131 304//131 -s off -f 795//230 1149//230 794//230 -f 799//231 1150//231 797//231 -f 1151//232 1107//232 1152//232 -f 1153//232 1154//232 1155//232 -s 1 -f 1156//131 537//131 856//131 -f 1157//131 1158//131 1159//131 -f 540//87 544//87 543//87 -f 927//87 926//87 1160//87 -s off -f 1072//233 1161//233 1162//233 -f 1069//233 1163//233 1164//233 -s 1 -f 1165//87 454//87 453//87 -f 58//87 57//87 67//87 -f 88//87 87//87 85//87 -f 1166//87 460//87 459//87 -f 76//87 75//87 73//87 -f 1167//87 448//87 447//87 -s off -f 1168//232 1169//232 1170//232 -f 1171//234 1172//234 1173//234 -s 1 -f 515//131 811//131 1037//131 -f 825//131 824//131 515//131 -s off -f 1129//235 1174//235 1128//235 -f 1131//235 1175//235 1130//235 -f 1176//236 978//236 1177//236 -f 1178//237 981//237 1179//237 -s 1 -f 755//87 756//87 385//87 -f 393//87 390//87 389//87 -s off -f 1180//236 975//236 1181//236 -f 1122//207 1182//207 1120//207 -f 1127//207 1183//207 1125//207 -f 1184//238 1185//238 1186//238 -s 1 -f 1187//131 1188//131 618//131 -f 1189//131 1190//131 1191//131 -f 1192//131 1193//131 1194//131 -f 1195//131 1196//131 1197//131 -f 1198//131 62//131 1199//131 -f 1200//131 1201//131 204//131 -f 6//131 240//131 1202//131 -s off -f 1203//239 1204//239 1205//239 -f 1206//240 1207//240 1208//240 -s 1 -f 7//87 5//87 4//87 -f 508//87 507//87 1209//87 -f 1068//131 1210//131 1163//131 -f 1071//131 1211//131 1161//131 -s off -f 1212//241 1213//241 1214//241 -s 1 -f 1215//131 1216//131 1217//131 -f 1218//131 1219//131 1220//131 -s off -f 1221//242 1222//242 1223//242 -s 1 -f 1224//131 1225//131 1226//131 -f 790//131 766//131 651//131 -f 1227//131 1228//131 1229//131 -f 789//131 770//131 648//131 -f 747//87 746//87 1230//87 -f 747//87 115//87 98//87 -f 753//87 752//87 1231//87 -f 753//87 111//87 107//87 -f 741//87 740//87 1232//87 -f 741//87 119//87 104//87 -s off -f 1233//243 1234//243 1029//243 -f 1235//243 1236//243 1025//243 -f 401//98 443//98 399//98 -f 865//244 1237//244 1238//244 -f 1239//245 551//245 550//245 -s 1 -f 1240//87 306//87 337//87 -s off -f 306//246 1240//246 304//246 -s 1 -f 1241//87 312//87 343//87 -s off -f 312//246 1241//246 310//246 -f 1119//224 1242//224 1117//224 -f 1111//224 1243//224 1109//224 -f 342//247 1244//247 340//247 -f 348//247 1245//247 346//247 -f 898//248 897//248 1246//248 -f 894//249 893//249 1247//249 -s 1 -f 1248//87 877//87 876//87 -s off -f 1223//250 1249//250 1221//250 -s 1 -f 514//87 1250//87 826//87 -s off -f 826//139 1250//139 824//139 -s 1 -f 1251//131 1252//131 1253//131 -s off -f 1254//251 1255//251 1256//251 -f 1257//251 1258//251 1259//251 -f 1260//251 1261//251 1262//251 -f 220//252 1263//252 218//252 -f 1142//229 1264//229 1140//229 -f 1145//253 1265//253 1143//253 -s 1 -f 240//131 1266//131 1202//131 -s off -f 1267//254 1268//254 953//254 -f 554//98 983//98 552//98 -s 1 -f 1269//131 1100//131 1270//131 -f 1271//131 694//131 161//131 -f 1272//131 1097//131 1273//131 -f 1274//131 686//131 154//131 -f 1275//131 1276//131 1277//131 -f 1278//131 687//131 158//131 -f 1279//131 1280//131 223//131 -f 1281//131 857//131 856//131 -s off -f 1238//244 866//244 865//244 -f 1115//224 1282//224 1113//224 -s 1 -f 820//87 1283//87 1284//87 -s off -f 1284//255 1283//255 1285//255 -f 1286//255 1287//255 1288//255 -s 1 -f 823//87 1287//87 1286//87 -s off -f 1289//256 1290//256 1291//256 -s 1 -f 817//87 1290//87 1289//87 -s off -f 1292//257 945//257 1293//257 -s 1 -f 945//87 1292//87 539//87 -f 298//131 296//131 1086//131 -f 631//131 630//131 212//131 -f 265//131 402//131 1294//131 -f 199//131 406//131 1295//131 -f 1296//87 185//87 1297//87 -s off -f 185//258 1296//258 183//258 -s 1 -f 106//131 105//131 754//131 -f 1298//131 1299//131 1300//131 -f 1301//131 1302//131 1303//131 -f 97//131 96//131 748//131 -f 103//131 102//131 742//131 -f 1304//131 1305//131 1306//131 -f 485//87 156//87 490//87 -f 156//87 378//87 490//87 -f 493//87 163//87 495//87 -f 163//87 382//87 495//87 -f 484//87 160//87 478//87 -f 160//87 374//87 478//87 -s off -f 1307//259 1308//259 1309//259 -f 1310//259 1311//259 1312//259 -f 1313//259 1314//259 1315//259 -s 1 -f 1316//131 800//131 443//131 -f 1050//131 1317//131 1051//131 -f 1318//131 1319//131 1320//131 -f 323//87 1321//87 901//87 -s off -f 901//260 1321//260 1322//260 -s 1 -f 1323//131 1324//131 1325//131 -s off -f 1326//261 1327//261 1328//261 -s 1 -f 929//87 202//87 175//87 -s off -f 929//262 175//262 174//262 -s 1 -f 931//87 610//87 168//87 -s off -f 931//262 168//262 167//262 -f 930//263 172//263 171//263 -s 1 -f 930//87 613//87 172//87 -f 1074//131 1073//131 1329//131 -s off -f 1330//264 1331//264 1332//264 -f 1333//265 1334//265 1335//265 -s 1 -f 1336//131 1337//131 1338//131 -f 795//131 577//131 1339//131 -f 1340//131 1341//131 1342//131 -f 799//131 580//131 1343//131 -f 434//131 527//131 1344//131 -f 1345//131 1346//131 1347//131 -f 431//131 533//131 584//131 -f 1348//131 1349//131 1350//131 -f 428//131 524//131 587//131 -f 1351//131 1352//131 1353//131 -f 1354//131 1355//131 985//131 -f 1336//131 474//131 1337//131 -f 1356//131 1357//131 408//131 -f 1358//131 1359//131 404//131 -f 1340//131 501//131 1341//131 -f 941//131 1360//131 1361//131 -s off -f 1362//132 1344//132 1123//132 -f 1363//116 394//116 393//116 -s 1 -f 1079//131 1081//131 1364//131 -f 1334//131 1331//131 1365//131 -f 1366//131 1322//131 1367//131 -s off -f 1368//184 1369//184 1370//184 -s 1 -f 1371//87 964//87 963//87 -f 535//87 534//87 1372//87 -f 1373//87 957//87 956//87 -f 520//87 519//87 1374//87 -f 1375//87 961//87 960//87 -f 529//87 528//87 1376//87 -f 783//131 751//131 1377//131 -f 1378//131 1379//131 1380//131 -f 1381//131 1382//131 1383//131 -f 1063//87 1384//87 1370//87 -s off -f 1370//184 1384//184 1368//184 -s 1 -f 541//87 540//87 543//87 -f 1//87 11//87 2//87 -s off -f 1385//266 542//266 541//266 -s 1 -f 1042//131 1041//131 1386//131 -f 1045//131 1044//131 1387//131 -f 1048//131 1047//131 1388//131 -s off -f 1009//267 1389//267 1390//267 -s 1 -f 806//87 1389//87 1009//87 -s off -f 1011//267 1391//267 1392//267 -s 1 -f 803//87 1391//87 1011//87 -f 1393//131 1394//131 1395//131 -f 1358//131 1396//131 1359//131 -f 1397//131 1398//131 1399//131 -f 1356//131 1400//131 1357//131 -s off -f 1401//268 1402//268 1403//268 -f 1089//222 1404//222 1087//222 -f 1092//222 1405//222 1090//222 -f 1095//222 1406//222 1093//222 -s 1 -f 178//131 1407//131 395//131 -f 1408//131 1409//131 1410//131 -f 1411//131 1412//131 1413//131 -s off -f 1414//269 1415//269 1416//269 -s 1 -f 347//87 346//87 1414//87 -s off -f 1417//269 1418//269 1419//269 -s 1 -f 341//87 340//87 1417//87 -f 1420//131 92//131 1421//131 -f 83//131 1422//131 1136//131 -f 71//131 1423//131 1137//131 -f 1424//131 80//131 1425//131 -f 1426//131 1427//131 1428//131 -f 1429//131 1430//131 1431//131 -f 1040//87 1432//87 1433//87 -s off -f 1432//270 1040//270 1039//270 -s 1 -f 1369//131 1368//131 1053//131 -f 1434//131 1435//131 1436//131 -f 1434//131 1436//131 1437//131 -f 1438//131 1439//131 1440//131 -f 1438//131 1441//131 1439//131 -s off -f 1442//271 1443//271 1444//271 -f 545//272 1445//272 543//272 -f 1446//273 1413//273 1447//273 -s 1 -f 1448//87 1162//87 1449//87 -s off -f 1162//274 1448//274 1072//274 -s 1 -f 1450//87 1164//87 1451//87 -s off -f 1164//274 1450//274 1069//274 -s 1 -f 1452//131 1453//131 1454//131 -f 1455//131 1456//131 1457//131 -f 1458//131 1459//131 1460//131 -f 1461//131 1245//131 348//131 -f 1462//131 1244//131 342//131 -f 1463//131 1464//131 1465//131 -f 1466//131 1467//131 1468//131 -f 1469//131 1470//131 1471//131 -f 1472//131 1473//131 1474//131 -f 1475//131 1474//131 1476//131 -f 1477//131 1478//131 1479//131 -f 1480//131 1481//131 1478//131 -s off -f 1482//275 1483//275 1484//275 -f 1485//275 1486//275 1487//275 -f 1488//275 1489//275 1490//275 -f 577//276 1491//276 1492//276 -f 580//276 1493//276 1494//276 -s 1 -f 1078//87 1495//87 1496//87 -s off -f 1495//270 1078//270 1077//270 -s 1 -f 1497//131 1498//131 1134//131 -f 933//131 1497//131 77//131 -f 1499//131 1500//131 1133//131 -f 934//131 1499//131 59//131 -f 590//131 589//131 1501//131 -f 1502//131 1503//131 1504//131 -s off -f 1066//277 1505//277 1064//277 -s 1 -f 1506//87 1021//87 1020//87 -s off -f 1507//278 1471//278 1508//278 -f 1509//279 1468//279 1510//279 -f 1511//280 1465//280 1512//280 -s 1 -f 1513//131 1514//131 1515//131 -f 643//131 645//131 1516//131 -s off -f 1517//281 1518//281 1519//281 -s 1 -f 1024//87 658//87 638//87 -s off -f 1520//41 1024//41 937//41 -s 1 -f 1028//87 662//87 641//87 -s off -f 1521//41 1028//41 938//41 -s 1 -f 1522//131 1523//131 1524//131 -f 932//131 1525//131 1526//131 -f 1527//131 1528//131 1529//131 -f 418//131 1168//131 1530//131 -f 1531//131 1532//131 1533//131 -f 1534//131 1535//131 1536//131 -f 424//131 1153//131 1537//131 -f 1538//87 1539//87 1075//87 -s off -f 1075//282 1539//282 1073//282 -s 1 -f 1540//131 1541//131 1542//131 -f 1543//131 1544//131 1545//131 -f 1445//131 1546//131 542//131 -f 1547//131 1269//131 1270//131 -f 1548//131 1549//131 536//131 -f 1550//131 1551//131 521//131 -f 1552//131 1272//131 1273//131 -f 1553//131 1275//131 1277//131 -f 1554//131 1555//131 530//131 -s off -f 604//98 277//98 276//98 -f 1556//283 1449//283 1071//283 -s 1 -f 1448//87 1449//87 1556//87 -s off -f 1557//283 1451//283 1068//283 -s 1 -f 1450//87 1451//87 1557//87 -s off -f 550//245 1558//245 1239//245 -s 1 -f 812//87 810//87 514//87 -s off -f 810//98 812//98 1037//98 -f 1559//284 1560//284 1561//284 -s 1 -f 1562//87 1560//87 1559//87 -s off -f 26//285 1563//285 24//285 -f 35//285 1564//285 33//285 -s 1 -f 349//131 1565//131 1566//131 -f 349//131 461//131 1565//131 -s off -f 1567//286 1568//286 1569//286 -s 1 -f 355//131 455//131 1570//131 -f 1571//131 1572//131 1573//131 -f 352//131 449//131 1574//131 -f 1575//131 1576//131 1577//131 -f 1578//87 363//87 685//87 -s off -f 363//287 1578//287 361//287 -s 1 -f 1579//87 366//87 693//87 -s off -f 366//287 1579//287 364//287 -f 360//287 1580//287 358//287 -s 1 -f 1580//87 360//87 690//87 -f 1581//131 171//131 612//131 -f 412//131 1151//131 1582//131 -f 1583//87 17//87 1186//87 -s off -f 17//288 1583//288 1584//288 -f 1519//289 1297//289 1517//289 -s 1 -f 1296//87 1297//87 1519//87 -s off -f 1585//290 1586//290 1587//290 -s 1 -f 622//87 1588//87 1589//87 -s off -f 1589//291 1588//291 1590//291 -s 1 -f 619//87 1591//87 1592//87 -s off -f 1592//291 1591//291 1593//291 -f 1594//291 1595//291 1596//291 -s 1 -f 205//87 1595//87 1594//87 -s off -f 1597//271 1598//271 1599//271 -f 1600//271 1601//271 1602//271 -f 1603//292 1604//292 1605//292 -s 1 -f 1443//131 1442//131 465//131 -f 1598//131 1597//131 471//131 -f 1601//131 1600//131 468//131 -f 848//131 847//131 1606//131 -f 1607//131 1606//131 1608//131 -f 151//87 150//87 148//87 -f 22//87 1017//87 150//87 -f 1609//87 1256//87 1610//87 -s off -f 1610//293 1256//293 1611//293 -s 1 -f 1612//87 1259//87 1613//87 -s off -f 1613//294 1259//294 1614//294 -f 1615//293 1262//293 1616//293 -s 1 -f 1617//87 1262//87 1615//87 -f 1618//131 1031//131 1033//131 -f 384//131 383//131 386//131 -f 1619//87 1620//87 1186//87 -s off -f 1186//295 1620//295 1184//295 -s 1 -f 1621//131 122//131 100//131 -f 1621//131 574//131 122//131 -f 1622//131 118//131 94//131 -f 1622//131 571//131 118//131 -f 1623//131 114//131 109//131 -f 1623//131 568//131 114//131 -s off -f 1624//296 1000//296 999//296 -s 1 -f 1625//131 708//131 707//131 -f 1626//131 196//131 251//131 -f 1627//131 705//131 704//131 -f 1628//131 190//131 243//131 -f 1629//131 193//131 247//131 -f 1630//131 702//131 701//131 -f 1327//131 1326//131 1631//131 -f 1632//131 1633//131 1634//131 -f 1635//131 1636//131 1637//131 -f 13//131 12//131 238//131 -f 1638//87 1639//87 1640//87 -s off -f 1639//297 1638//297 1355//297 -f 1641//298 1642//298 1643//298 -f 1644//298 1645//298 1646//298 -f 1647//142 884//142 883//142 -f 1648//98 882//98 881//98 -f 377//299 1649//299 375//299 -f 381//299 1650//299 379//299 -f 373//299 1651//299 371//299 -s 1 -f 1652//131 515//131 1037//131 -s off -f 1653//300 1654//300 1655//300 -s 1 -f 1656//131 1647//131 1657//131 -f 1658//131 1648//131 1659//131 -f 1538//87 1447//87 1539//87 -s off -f 1447//301 1538//301 1446//301 -s 1 -f 1660//131 1483//131 1482//131 -f 1661//131 1662//131 1663//131 -f 1664//131 1489//131 1488//131 -f 1665//131 1666//131 1667//131 -f 1668//131 1486//131 1485//131 -f 1669//131 1670//131 1671//131 -s off -f 771//116 1672//116 1673//116 -s 1 -f 771//87 769//87 768//87 -s off -f 767//116 1674//116 1675//116 -s 1 -f 767//87 765//87 764//87 -s off -f 1676//302 1677//302 1678//302 -f 1679//302 1680//302 1681//302 -s 1 -f 1682//131 968//131 967//131 -f 990//131 1683//131 1684//131 -s off -f 1685//303 1022//303 1021//303 -s 1 -f 1686//131 1687//131 1688//131 -f 1022//131 1685//131 1689//131 -f 142//87 141//87 145//87 -f 42//87 1015//87 141//87 -f 1690//131 1691//131 1692//131 -f 1693//131 1694//131 1695//131 -f 1696//131 1697//131 1698//131 -f 1699//131 1700//131 1701//131 -f 496//131 162//131 161//131 -f 1702//131 1703//131 1704//131 -f 479//131 159//131 158//131 -f 1705//131 1706//131 1707//131 -f 1708//131 1709//131 1710//131 -f 491//131 155//131 154//131 -f 1711//131 1712//131 621//131 -f 1713//131 621//131 620//131 -s off -f 1714//304 1108//304 1715//304 -s 1 -f 1108//87 1714//87 744//87 -s off -f 1716//305 1116//305 1717//305 -s 1 -f 1116//87 1716//87 738//87 -s off -f 1718//304 1112//304 1719//304 -s 1 -f 1112//87 1718//87 750//87 -f 1720//131 1198//131 1199//131 -s off -f 1721//306 1419//306 1418//306 -f 1722//306 1416//306 1415//306 -f 1723//307 1724//307 1410//307 -s 1 -f 1724//87 1723//87 1725//87 -s off -f 134//308 1726//308 132//308 -s 1 -f 1727//131 1728//131 1729//131 -f 1727//131 1729//131 1730//131 -f 1731//131 1732//131 1733//131 -f 1731//131 1734//131 1732//131 -f 1735//131 1736//131 1737//131 -f 1735//131 1737//131 1738//131 -f 935//131 1236//131 1235//131 -f 939//131 1234//131 1233//131 -s off -f 1739//309 1740//309 1741//309 -f 1742//41 1743//41 1744//41 -f 1745//98 1746//98 1747//98 -f 1748//184 1749//184 1750//184 -f 1751//142 1752//142 1753//142 -f 1747//98 1754//98 1745//98 -f 1744//41 1755//41 1742//41 -f 1750//184 1756//184 1748//184 -f 1753//142 1757//142 1751//142 -s 1 -f 999//87 998//87 1758//87 -s off -f 1758//310 1759//310 1760//310 -s 1 -f 1761//87 1762//87 1049//87 -s off -f 1049//311 1762//311 1047//311 -s 1 -f 1763//87 1764//87 1046//87 -s off -f 1046//311 1764//311 1044//311 -f 1043//311 1765//311 1041//311 -s 1 -f 1766//87 1765//87 1043//87 -f 397//87 1767//87 179//87 -s off -f 179//312 1767//312 177//312 -s 1 -f 551//87 1237//87 865//87 -s off -f 677//313 552//313 983//313 -s 1 -f 1768//131 1323//131 1325//131 -f 1769//131 1770//131 201//131 -f 1531//131 174//131 201//131 -f 1534//131 167//131 609//131 -f 1771//131 1772//131 609//131 -s off -f 1773//314 1774//314 1775//314 -f 1160//315 1776//315 1777//315 -s 1 -f 926//87 1776//87 1160//87 -f 605//131 280//131 972//131 -s off -f 1778//316 1779//316 1780//316 -f 1781//316 1782//316 1783//316 -s 1 -f 220//131 1654//131 1653//131 -f 482//131 1314//131 1784//131 -f 688//131 1785//131 1786//131 -f 683//131 1787//131 1788//131 -f 492//131 1308//131 1789//131 -f 499//131 1311//131 1790//131 -f 691//131 1791//131 1792//131 -s off -f 1435//317 1434//317 1793//317 -f 1441//317 1438//317 1794//317 -s 1 -f 1581//131 612//131 611//131 -s off -f 1795//318 853//318 1796//318 -f 1797//318 850//318 1798//318 -s 1 -f 1777//131 1799//131 1585//131 -f 1799//131 1586//131 1585//131 -f 1800//131 1801//131 140//131 -f 1802//131 1803//131 134//131 -f 1804//131 1805//131 128//131 -f 1806//131 1807//131 1808//131 -f 1806//131 1809//131 1807//131 -s off -f 1810//319 1811//319 1812//319 -f 1813//319 1814//319 1815//319 -f 1816//319 1817//319 1818//319 -f 1819//320 1820//320 957//320 -f 1821//320 1822//320 964//320 -f 1823//321 1824//321 961//321 -f 992//322 1825//322 1826//322 -f 12//323 1827//323 10//323 -s 1 -f 628//131 206//131 1828//131 -f 628//131 627//131 206//131 -f 1829//131 421//131 1830//131 -s off -f 1346//324 1345//324 1831//324 -f 1349//324 1348//324 1832//324 -f 1352//324 1351//324 1833//324 -f 937//41 1834//41 1520//41 -f 938//41 1835//41 1521//41 -s 1 -f 1836//131 601//131 1837//131 -f 1838//131 1839//131 1837//131 -f 1840//131 1841//131 1842//131 -f 1843//131 215//131 1842//131 -f 1844//131 1845//131 1846//131 -f 1844//131 1847//131 1845//131 -f 1213//131 1848//131 1849//131 -f 1213//131 1850//131 1848//131 -s off -f 393//116 1851//116 1363//116 -f 1852//230 385//230 384//230 -s 1 -f 1853//131 1854//131 1855//131 -f 1856//131 1857//131 1858//131 -f 1859//87 1763//87 1860//87 -s off -f 1763//325 1859//325 1861//325 -s 1 -f 1862//87 1766//87 1863//87 -s off -f 1766//325 1862//325 1864//325 -f 1761//325 1865//325 1866//325 -s 1 -f 1865//87 1761//87 1867//87 -s off -f 1868//326 1869//326 1870//326 -f 1229//142 1673//142 1672//142 -f 1226//142 1675//142 1674//142 -f 1871//116 1872//116 1873//116 -f 1874//327 1364//327 1875//327 -f 1876//328 1877//328 1878//328 -f 282//329 182//329 181//329 -f 1879//121 1880//121 1881//121 -f 1882//121 1883//121 1884//121 -s 1 -f 1601//131 468//131 1885//131 -f 1598//131 471//131 1886//131 -f 1443//131 465//131 1887//131 -s off -f 1888//330 1889//330 1588//330 -f 1890//330 1891//330 1591//330 -f 1892//330 1893//330 1595//330 -f 296//230 1894//230 1895//230 -f 1809//331 1806//331 1896//331 -f 1839//332 1838//332 1897//332 -f 1841//333 1840//333 1898//333 -f 1899//334 1702//334 1900//334 -f 1901//334 1708//334 1902//334 -f 1903//334 1705//334 1904//334 -s 1 -f 1905//131 1877//131 1876//131 -f 1905//131 1906//131 1877//131 -f 288//87 1907//87 953//87 -s off -f 953//335 1907//335 1908//335 -f 954//335 1909//335 1910//335 -s 1 -f 294//87 1909//87 954//87 -s off -f 1895//230 297//230 296//230 -f 1063//116 1911//116 1912//116 -s 1 -f 1//87 1913//87 1914//87 -s off -f 1915//116 1//116 13//116 -s 1 -f 1916//87 771//87 1418//87 -f 1916//87 1418//87 1417//87 -f 1917//87 1415//87 1414//87 -f 1917//87 767//87 1415//87 -f 1918//131 314//131 1919//131 -f 1920//131 308//131 1921//131 -f 637//131 636//131 937//131 -f 640//131 639//131 938//131 -f 1922//131 1923//131 592//131 -f 1923//131 593//131 592//131 -f 1349//131 1924//131 1350//131 -f 1346//131 1925//131 1347//131 -f 1352//131 1926//131 1353//131 -s off -f 1608//336 1606//336 1927//336 -f 1928//337 1929//337 1930//337 -s 1 -f 809//87 1931//87 1932//87 -s off -f 1932//338 1931//338 1933//338 -s 1 -f 1645//131 1677//131 1934//131 -f 1642//131 1680//131 1935//131 -f 298//131 1369//131 1053//131 -s off -f 1460//339 1291//339 1290//339 -f 1454//339 1285//339 1283//339 -f 1457//339 1288//339 1287//339 -s 1 -f 990//131 992//131 1936//131 -f 1937//131 1936//131 992//131 -f 1225//131 651//131 1226//131 -f 1228//131 648//131 1229//131 -f 227//87 1938//87 336//87 -s off -f 336//340 1938//340 1683//340 -s 1 -f 1939//87 1940//87 1941//87 -s off -f 1941//341 1940//341 1942//341 -f 1943//341 1944//341 1945//341 -s 1 -f 1946//87 1944//87 1943//87 -s off -f 1947//342 1948//342 1949//342 -s 1 -f 1950//87 1948//87 1947//87 -f 866//131 1238//131 550//131 -s off -f 1951//343 1952//343 1953//343 -f 1954//343 1955//343 1956//343 -f 1957//344 1958//344 1959//344 -f 1536//344 1535//344 1960//344 -s 1 -f 1954//131 1961//131 1962//131 -f 1951//131 1963//131 1964//131 -f 319//131 318//131 1965//131 -f 1966//131 1967//131 1968//131 -s off -f 1533//344 1532//344 1969//344 -f 1970//345 1971//345 1972//345 -f 1973//345 1974//345 1975//345 -f 1976//345 1977//345 1978//345 -f 1249//346 1248//346 1979//346 -s 1 -f 1248//87 1249//87 877//87 -f 1656//131 1980//131 1647//131 -f 1658//131 1981//131 1648//131 -s off -f 384//230 1982//230 1852//230 -f 1873//116 389//116 1871//116 -f 755//230 1983//230 1984//230 -f 1444//347 1985//347 1442//347 -s 1 -f 1986//87 1985//87 1444//87 -s off -f 1599//347 1987//347 1597//347 -s 1 -f 1988//87 1987//87 1599//87 -s off -f 1602//347 1989//347 1600//347 -s 1 -f 1990//87 1989//87 1602//87 -s off -f 1950//348 1991//348 1347//348 -s 1 -f 1991//87 1950//87 1947//87 -s off -f 1946//348 1992//348 1350//348 -s 1 -f 1992//87 1946//87 1943//87 -f 1993//87 1939//87 1941//87 -s off -f 1939//348 1993//348 1353//348 -f 1994//349 1995//349 1996//349 -s 1 -f 1995//87 1994//87 1997//87 -s off -f 1998//350 1561//350 1560//350 -s 1 -f 859//87 1562//87 1559//87 -s off -f 1562//351 859//351 1999//351 -f 2000//352 2001//352 2002//352 -s 1 -f 2003//131 562//131 1647//131 -f 2004//131 559//131 1648//131 -s off -f 2005//353 2006//353 2007//353 -f 2008//353 2009//353 2010//353 -s 1 -f 998//87 1759//87 1758//87 -f 2011//87 998//87 336//87 -s off -f 2012//354 2013//354 2014//354 -f 2015//352 2016//352 2017//352 -f 2018//355 1967//355 2019//355 -s 1 -f 1508//87 2020//87 2021//87 -s off -f 2021//356 2020//356 2022//356 -f 2023//356 2024//356 2025//356 -s 1 -f 1510//87 2024//87 2023//87 -f 1512//87 2026//87 2027//87 -s off -f 2027//356 2026//356 2028//356 -f 1503//357 1979//357 1248//357 -f 2029//358 2030//358 2031//358 -f 2032//358 2033//358 2034//358 -f 2035//359 2036//359 2037//359 -s 1 -f 2038//131 2039//131 697//131 -s off -f 2040//360 2041//360 2042//360 -s 1 -f 1008//87 2041//87 2040//87 -f 1005//87 2043//87 2044//87 -s off -f 2044//361 2043//361 2045//361 -f 2046//362 2047//362 2048//362 -f 2049//362 2050//362 2051//362 -f 1514//362 2052//362 2053//362 -f 1686//363 2054//363 2055//363 -s 1 -f 1005//87 2056//87 2043//87 -s off -f 2056//364 1005//364 1004//364 -s 1 -f 1008//87 2057//87 2041//87 -s off -f 2057//364 1008//364 1007//364 -f 976//365 2058//365 2059//365 -f 973//365 2060//365 2061//365 -f 979//365 2062//365 2063//365 -f 1912//116 1053//116 1063//116 -f 2064//184 2065//184 2066//184 -s 1 -f 1063//87 1370//87 328//87 -s off -f 2066//184 2067//184 2064//184 -f 1612//366 2068//366 2069//366 -s 1 -f 2068//87 1612//87 1613//87 -s off -f 1609//366 2070//366 2071//366 -s 1 -f 2070//87 1609//87 1610//87 -s off -f 1617//366 2072//366 2073//366 -s 1 -f 2072//87 1617//87 1615//87 -s off -f 2074//367 29//367 28//367 -f 2075//367 38//367 37//367 -f 13//116 2076//116 1915//116 -s 1 -f 265//131 2077//131 402//131 -f 402//131 2077//131 892//131 -f 199//131 2078//131 406//131 -f 406//131 2078//131 896//131 -s off -f 1866//368 2079//368 1761//368 -f 1861//368 2080//368 1763//368 -f 1864//368 2081//368 1766//368 -f 1933//369 2082//369 1932//369 -s 1 -f 636//131 1834//131 937//131 -f 639//131 1835//131 938//131 -s off -f 2083//370 2084//370 2085//370 -s 1 -f 1927//87 2084//87 2083//87 -s off -f 2086//371 2087//371 2088//371 -s 1 -f 2089//87 2090//87 2091//87 -s off -f 2091//372 2090//372 2092//372 -f 2093//373 2094//373 2095//373 -s 1 -f 2096//87 2094//87 2093//87 -f 2097//87 2098//87 2099//87 -s off -f 2099//373 2098//373 2100//373 -s 1 -f 2101//131 204//131 203//131 -f 2102//131 618//131 617//131 -f 2103//131 2104//131 2105//131 -s off -f 1220//374 1219//374 2106//374 -f 1217//374 1216//374 2107//374 -f 2108//375 1395//375 2109//375 -f 2110//375 1399//375 2111//375 -s 1 -f 2112//87 2113//87 2114//87 -s off -f 2113//376 2112//376 1515//376 -f 2115//377 2116//377 2117//377 -s 1 -f 2116//87 2115//87 2118//87 -f 2119//87 2120//87 2121//87 -s off -f 2120//378 2119//378 2122//378 -f 782//379 2123//379 780//379 -f 1919//380 2124//380 2125//380 -f 1921//380 2126//380 2127//380 -s 1 -f 13//131 1637//131 2076//131 -f 13//131 1635//131 1637//131 -s off -f 2128//381 2129//381 2130//381 -s 1 -f 2129//87 2128//87 1897//87 -s off -f 2131//382 2132//382 2133//382 -s 1 -f 2132//87 2131//87 1896//87 -s off -f 2134//381 2135//381 2136//381 -s 1 -f 2135//87 2134//87 1898//87 -f 651//131 1675//131 1226//131 -f 648//131 1673//131 1229//131 -s off -f 2137//383 2138//383 2139//383 -s 1 -f 1604//131 1603//131 1929//131 -s off -f 1984//230 386//230 755//230 -s 1 -f 894//131 2140//131 895//131 -f 898//131 2141//131 899//131 -s off -f 1799//384 1777//384 1776//384 -f 205//385 2142//385 203//385 -s 1 -f 2142//87 205//87 1594//87 -s off -f 619//385 2143//385 617//385 -s 1 -f 2143//87 619//87 1592//87 -f 2144//87 622//87 1589//87 -s off -f 622//385 2144//385 620//385 -s 1 -f 181//87 276//87 281//87 -f 181//87 439//87 276//87 -s off -f 202//386 2145//386 200//386 -s 1 -f 929//87 2145//87 202//87 -s off -f 613//386 2146//386 611//386 -s 1 -f 930//87 2146//87 613//87 -s off -f 610//386 2147//386 608//386 -s 1 -f 931//87 2147//87 610//87 -f 2148//131 2149//131 2150//131 -f 2151//131 2152//131 2153//131 -s off -f 2154//387 2155//387 2156//387 -f 259//388 2157//388 2158//388 -s 1 -f 271//131 2159//131 2160//131 -f 257//131 2161//131 2162//131 -f 1563//131 26//131 2163//131 -f 1564//131 35//131 2164//131 -f 2032//131 2165//131 937//131 -f 2029//131 2166//131 938//131 -f 1561//131 1998//131 2167//131 -f 827//131 259//131 2168//131 -f 259//131 681//131 680//131 -f 2169//131 1318//131 1320//131 -f 2170//131 2171//131 9//131 -f 1774//131 1773//131 2172//131 -s off -f 748//389 2173//389 746//389 -f 754//390 2174//390 752//390 -f 742//389 2175//389 740//389 -s 1 -f 2176//87 2177//87 51//87 -s off -f 51//391 2177//391 49//391 -s 1 -f 2178//87 2179//87 56//87 -s off -f 56//391 2179//391 54//391 -f 2053//392 2114//392 1514//392 -s 1 -f 2112//87 2114//87 2053//87 -s off -f 2051//393 2121//393 2049//393 -s 1 -f 2119//87 2121//87 2051//87 -s off -f 2048//392 2118//392 2046//392 -s 1 -f 2116//87 2118//87 2048//87 -f 2180//131 2079//131 1866//131 -f 2181//131 2080//131 1861//131 -f 2182//131 2081//131 1864//131 -f 1604//131 1929//131 2183//131 -f 1366//131 1367//131 321//131 -f 182//131 401//131 398//131 -s off -f 1910//394 2184//394 954//394 -f 2185//395 2186//395 2187//395 -f 2188//395 2189//395 2190//395 -s 1 -f 2058//131 976//131 978//131 -f 2062//131 979//131 981//131 -f 2060//131 973//131 975//131 -f 921//87 922//87 2191//87 -s off -f 2191//396 922//396 2004//396 -f 2192//396 925//396 2003//396 -s 1 -f 924//87 925//87 2192//87 -f 2193//87 2178//87 56//87 -s off -f 2178//397 2193//397 2194//397 -f 2176//398 2195//398 2196//398 -s 1 -f 2195//87 2176//87 51//87 -s off -f 2197//399 2198//399 2199//399 -f 2200//399 2201//399 2202//399 -s 1 -f 1024//87 660//87 659//87 -f 1025//87 1024//87 2034//87 -f 1028//87 664//87 663//87 -f 1029//87 1028//87 2031//87 -s off -f 997//400 464//400 2203//400 -s 1 -f 464//87 997//87 504//87 -f 2204//87 2205//87 2206//87 -s off -f 2205//401 2204//401 2207//401 -f 2208//402 2209//402 2210//402 -f 2211//402 2212//402 2213//402 -f 2214//402 2215//402 2216//402 -s 1 -f 1571//131 2217//131 1572//131 -f 1575//131 2218//131 1576//131 -f 2219//131 2220//131 2221//131 -f 550//131 549//131 970//131 -f 2222//87 2223//87 1870//87 -s off -f 2223//403 2222//403 1325//403 -s 1 -f 562//131 884//131 1647//131 -f 559//131 882//131 1648//131 -s off -f 1353//404 2224//404 1939//404 -f 1350//404 2225//404 1946//404 -f 1347//404 2226//404 1950//404 -f 1390//405 2148//405 1009//405 -f 1392//406 2151//406 1011//406 -s 1 -f 182//131 277//131 604//131 -f 182//131 943//131 277//131 -s off -f 1775//407 2227//407 1773//407 -s 1 -f 1403//87 2227//87 1775//87 -s off -f 1411//408 2228//408 2229//408 -f 2230//409 2231//409 2232//409 -f 2233//409 2234//409 2235//409 -f 2236//409 2237//409 2238//409 -s 1 -f 1398//131 2239//131 1399//131 -f 1394//131 2240//131 1395//131 -f 1287//87 823//87 2241//87 -s off -f 2241//410 823//410 2242//410 -f 2243//410 817//410 2244//410 -s 1 -f 1290//87 817//87 2243//87 -f 1283//87 820//87 2245//87 -s off -f 2245//410 820//410 2246//410 -s 1 -f 259//131 258//131 681//131 -s off -f 2247//411 1355//411 1638//411 -s 1 -f 2035//131 2248//131 971//131 -f 383//131 387//131 386//131 -f 833//131 844//131 836//131 -f 837//131 841//131 840//131 -f 565//131 563//131 562//131 -f 770//131 649//131 648//131 -f 731//131 733//131 728//131 -f 556//131 560//131 559//131 -f 1748//131 1752//131 1751//131 -f 758//131 1002//131 669//131 -f 1747//131 1755//131 1744//131 -f 1744//131 1754//131 1747//131 -f 1368//131 1054//131 1053//131 -f 772//131 667//131 666//131 -f 774//131 888//131 597//131 -f 766//131 652//131 651//131 -f 836//131 843//131 833//131 -f 762//131 655//131 654//131 -f 840//131 838//131 837//131 -f 824//131 657//131 515//131 -f 777//131 890//131 600//131 -f 1751//131 1749//131 1748//131 -f 728//131 732//131 731//131 -f 546//131 554//131 547//131 -s off -f 1481//412 1480//412 2249//412 -f 1473//412 1472//412 2250//412 -f 1692//413 2251//413 2252//413 -f 1701//413 2253//413 2254//413 -s 1 -f 314//131 2255//131 1919//131 -f 308//131 2256//131 1921//131 -f 260//87 2158//87 331//87 -s off -f 2158//414 260//414 259//414 -f 2257//415 2258//415 2259//415 -f 1322//416 1366//416 901//416 -f 2260//417 2002//417 2261//417 -s 1 -f 2002//87 2260//87 417//87 -s off -f 2262//417 2014//417 2263//417 -s 1 -f 2014//87 2262//87 411//87 -s off -f 2264//417 2017//417 2265//417 -s 1 -f 2017//87 2264//87 423//87 -f 2266//131 1058//131 2267//131 -f 2268//131 1061//131 2269//131 -s off -f 2270//418 2271//418 2272//418 -s 1 -f 858//87 2271//87 2270//87 -s off -f 2273//419 1209//419 1632//419 -s 1 -f 508//87 1209//87 2273//87 -s off -f 1632//420 2274//420 2273//420 -s 1 -f 827//131 786//131 262//131 -f 2010//87 2275//87 2276//87 -s off -f 2275//421 2010//421 2009//421 -f 2277//421 2007//421 2006//421 -s 1 -f 2007//87 2277//87 2278//87 -f 1803//131 1726//131 134//131 -f 1805//131 2279//131 128//131 -f 1801//131 2280//131 140//131 -s off -f 398//230 401//230 400//230 -f 948//226 2281//226 1132//226 -s 1 -f 2281//87 948//87 947//87 -f 1082//131 2282//131 1083//131 -f 1740//131 2155//131 2154//131 -f 1238//131 1558//131 550//131 -s off -f 394//422 2283//422 392//422 -s 1 -f 2107//87 1027//87 324//87 -s off -f 1027//423 2107//423 2284//423 -f 1023//423 2106//423 2285//423 -s 1 -f 2106//87 1023//87 327//87 -s off -f 1691//424 1690//424 2286//424 -f 1700//424 1699//424 2287//424 -s 1 -f 2082//131 1933//131 1032//131 -s off -f 2219//425 461//425 460//425 -f 1571//425 455//425 454//425 -f 1575//425 449//425 448//425 -f 970//230 549//230 679//230 -s 1 -f 1740//131 1739//131 2155//131 -s off -f 400//230 180//230 398//230 -s 1 -f 181//87 180//87 400//87 -s off -f 828//426 2288//426 2289//426 -s 1 -f 2290//87 2291//87 2250//87 -s off -f 2250//427 2291//427 1473//427 -s 1 -f 2292//87 2293//87 2249//87 -s off -f 2249//427 2293//427 1481//427 -f 681//116 258//116 330//116 -f 1755//35 1747//35 1746//35 -f 772//116 666//116 713//116 -f 1752//116 1748//116 1756//116 -f 563//230 565//230 626//230 -f 652//230 766//230 765//230 -f 1054//428 1368//428 1384//428 -f 657//230 824//230 1250//230 -f 637//116 661//116 660//116 -f 843//230 836//230 835//230 -f 640//116 665//116 664//116 -f 844//116 833//116 832//116 -f 777//230 600//230 599//230 -f 880//116 546//116 555//116 -f 774//230 597//230 596//230 -f 838//230 840//230 845//230 -f 560//230 556//230 623//230 -f 762//116 654//116 717//116 -f 649//230 770//230 769//230 -f 1754//116 1744//116 1743//116 -f 1749//35 1751//35 1757//35 -f 841//116 837//116 846//116 -f 811//116 515//116 514//116 -f 547//230 554//230 553//230 -f 387//230 383//230 756//230 -f 732//116 728//116 727//116 -f 758//230 669//230 763//230 -f 733//230 731//230 730//230 -s 1 -f 2104//131 2294//131 2295//131 -s off -f 2296//429 1584//429 2297//429 -f 2298//430 1689//430 2299//430 -f 2300//431 2301//431 2302//431 -s 1 -f 1930//87 2301//87 2300//87 -s off -f 2303//432 2304//432 2//432 -s 1 -f 2228//131 1411//131 1413//131 -f 2189//131 1811//131 2305//131 -f 2186//131 1814//131 2306//131 -f 2307//131 1817//131 2308//131 -s off -f 518//433 2309//433 516//433 -s 1 -f 861//131 2310//131 1056//131 -s off -f 473//434 1988//434 471//434 -s 1 -f 1988//87 473//87 1987//87 -f 1986//87 467//87 1985//87 -s off -f 467//434 1986//434 465//434 -f 470//434 1990//434 468//434 -s 1 -f 1990//87 470//87 1989//87 -s off -f 2311//435 2312//435 2206//435 -f 1339//436 579//436 2313//436 -s 1 -f 1326//131 2314//131 1631//131 -f 2315//87 1678//87 1646//87 -s off -f 1678//437 2315//437 1676//437 -f 1681//437 2316//437 1679//437 -s 1 -f 2316//87 1681//87 1643//87 -f 2186//131 2185//131 1814//131 -f 2189//131 2188//131 1811//131 -f 2307//131 2317//131 1817//131 -f 2318//131 2319//131 1138//131 -f 1422//131 2320//131 1136//131 -f 1423//131 2321//131 1137//131 -f 676//87 679//87 551//87 -s off -f 679//230 676//230 970//230 -s 1 -f 2322//131 2323//131 99//131 -f 2324//131 2325//131 108//131 -f 2326//131 2327//131 93//131 -s off -f 162//438 1704//438 382//438 -f 159//438 1707//438 374//438 -f 155//438 1710//438 378//438 -s 1 -f 2328//131 1652//131 1037//131 -f 1307//131 2329//131 1789//131 -f 1310//131 2330//131 1790//131 -f 1313//131 2331//131 1784//131 -s off -f 1433//439 2287//439 1699//439 -s 1 -f 1432//87 2287//87 1433//87 -f 1495//87 2286//87 1496//87 -s off -f 1496//440 2286//440 1690//440 -s 1 -f 2332//131 2333//131 2207//131 -s off -f 1780//441 2334//441 1778//441 -s 1 -f 2334//87 1780//87 2335//87 -s off -f 1783//441 2336//441 1781//441 -s 1 -f 2336//87 1783//87 1214//87 -s off -f 330//116 682//116 681//116 -s 1 -f 682//87 330//87 260//87 -s off -f 2337//442 2338//442 1451//442 -f 2339//442 2340//442 1449//442 -s 1 -f 767//87 653//87 765//87 -s off -f 765//230 653//230 652//230 -f 626//230 564//230 563//230 -s 1 -f 625//87 564//87 626//87 -f 1743//87 1742//87 1746//87 -s off -f 1746//35 1742//35 1755//35 -f 756//230 388//230 387//230 -s 1 -f 755//87 388//87 756//87 -f 1746//87 1745//87 1743//87 -s off -f 1743//116 1745//116 1754//116 -s 1 -f 832//87 831//87 835//87 -s off -f 835//230 831//230 843//230 -f 596//230 775//230 774//230 -s 1 -f 775//87 596//87 595//87 -s off -f 832//116 834//116 844//116 -s 1 -f 835//87 834//87 832//87 -s off -f 599//230 778//230 777//230 -s 1 -f 778//87 599//87 598//87 -f 771//87 650//87 769//87 -s off -f 769//230 650//230 649//230 -s 1 -f 727//87 726//87 730//87 -s off -f 730//230 726//230 733//230 -s 1 -f 1024//87 638//87 660//87 -s off -f 660//116 638//116 637//116 -s 1 -f 710//87 713//87 668//87 -s off -f 713//116 710//116 772//116 -f 623//230 561//230 560//230 -s 1 -f 624//87 561//87 623//87 -f 555//87 865//87 864//87 -s off -f 555//116 864//116 880//116 -f 763//230 332//230 758//230 -s 1 -f 332//87 763//87 671//87 -s off -f 1250//230 513//230 657//230 -s 1 -f 514//87 513//87 1250//87 -s off -f 553//230 548//230 547//230 -s 1 -f 555//87 548//87 553//87 -f 730//87 729//87 727//87 -s off -f 727//116 729//116 732//116 -s 1 -f 1028//87 641//87 664//87 -s off -f 664//116 641//116 640//116 -f 1756//116 1753//116 1752//116 -s 1 -f 1757//87 1753//87 1756//87 -f 1063//87 1055//87 1384//87 -s off -f 1384//443 1055//443 1054//443 -s 1 -f 714//87 717//87 656//87 -s off -f 717//116 714//116 762//116 -s 1 -f 1756//87 1750//87 1757//87 -s off -f 1757//35 1750//35 1749//35 -f 846//116 842//116 841//116 -s 1 -f 845//87 842//87 846//87 -f 846//87 839//87 845//87 -s off -f 845//230 839//230 838//230 -f 2317//395 2307//395 2341//395 -f 262//116 786//116 796//116 -f 1626//444 1625//444 2342//444 -f 1629//445 1630//445 2343//445 -f 1628//444 1627//444 2344//444 -s 1 -f 2345//87 2259//87 2346//87 -s off -f 2259//446 2345//446 2257//446 -s 1 -f 2324//131 108//131 1671//131 -f 2326//131 93//131 1667//131 -f 2322//131 99//131 1663//131 -s off -f 2347//447 2348//447 2349//447 -s 1 -f 2350//87 2351//87 2139//87 -s off -f 2139//448 2351//448 2137//448 -s 1 -f 677//87 676//87 551//87 -f 677//87 551//87 865//87 -s off -f 878//449 2352//449 876//449 -f 1558//116 1238//116 1237//116 -s 1 -f 1795//131 2353//131 2354//131 -f 1797//131 2355//131 2356//131 -f 195//131 1660//131 1482//131 -f 189//131 1668//131 1485//131 -f 192//131 1664//131 1488//131 -s off -f 2357//450 1403//450 2358//450 -s 1 -f 1403//87 2357//87 2359//87 -f 1022//131 1689//131 2360//131 -f 399//87 440//87 439//87 -f 181//87 399//87 439//87 -f 493//87 495//87 494//87 -f 493//87 494//87 135//87 -f 484//87 478//87 477//87 -f 484//87 477//87 129//87 -f 485//87 490//87 489//87 -f 485//87 489//87 123//87 -s off -f 882//116 559//116 624//116 -f 1834//230 636//230 658//230 -f 1675//116 651//116 767//116 -f 1835//230 639//230 662//230 -f 884//116 562//116 625//116 -f 1673//116 648//116 771//116 -s 1 -f 1952//131 1951//131 1491//131 -f 1955//131 1954//131 1493//131 -f 1982//131 394//131 1363//131 -f 1053//131 1912//131 1894//131 -f 386//131 1984//131 1872//131 -s off -f 1554//451 527//451 526//451 -f 1548//451 533//451 532//451 -f 1550//451 524//451 523//451 -s 1 -f 1913//87 2361//87 1914//87 -s off -f 1914//452 2361//452 1636//452 -s 1 -f 2362//131 828//131 830//131 -f 2363//131 1910//131 2364//131 -f 1267//131 1908//131 2365//131 -s off -f 2366//453 2367//453 2165//453 -s 1 -f 1024//87 2367//87 2366//87 -s off -f 2368//454 2369//454 2166//454 -s 1 -f 1028//87 2369//87 2368//87 -f 331//87 263//87 796//87 -s off -f 796//116 263//116 262//116 -s 1 -f 2370//131 2371//131 559//131 -f 2372//131 2373//131 562//131 -f 1373//87 2374//87 957//87 -s off -f 2374//455 1373//455 1273//455 -f 2375//456 1371//456 1270//456 -s 1 -f 1371//87 2375//87 964//87 -f 1375//87 2376//87 961//87 -s off -f 2376//456 1375//456 1277//456 -f 2019//457 2377//457 2018//457 -s 1 -f 2377//87 2019//87 320//87 -f 1774//131 2172//131 2378//131 -f 798//87 673//87 1494//87 -s off -f 1494//458 673//458 580//458 -s 1 -f 791//87 793//87 1492//87 -s off -f 1492//458 793//458 577//458 -s 1 -f 1548//131 2379//131 1882//131 -f 1554//131 2380//131 510//131 -f 1550//131 2381//131 1879//131 -s off -f 1398//459 2382//459 2383//459 -f 1394//459 2384//459 2385//459 -f 1237//116 1239//116 1558//116 -s 1 -f 551//87 1239//87 1237//87 -s off -f 2314//460 2386//460 2387//460 -f 2320//461 2117//461 2116//461 -f 2319//462 1515//462 2112//462 -f 2321//462 2122//462 2119//462 -s 1 -f 298//131 2067//131 2066//131 -s off -f 2076//41 1637//41 1913//41 -f 658//230 1520//230 1834//230 -s 1 -f 1024//87 1520//87 658//87 -f 1028//87 1521//87 662//87 -s off -f 662//230 1521//230 1835//230 -f 1500//463 2130//463 2129//463 -f 2388//464 2133//464 2132//464 -f 1498//463 2136//463 2135//463 -f 941//465 2389//465 2390//465 -f 1409//466 1408//466 2391//466 -s 1 -f 2274//131 1632//131 1634//131 -f 1619//87 1875//87 1620//87 -s off -f 1875//467 1619//467 1874//467 -s 1 -f 418//131 1830//131 1169//131 -f 424//131 2392//131 1154//131 -f 2393//131 1424//131 1425//131 -f 2394//131 1420//131 1421//131 -s off -f 2395//468 2396//468 2397//468 -f 1770//468 2398//468 2399//468 -f 1772//468 2400//468 2401//468 -f 114//469 2402//469 112//469 -f 122//469 2403//469 120//469 -f 118//469 2404//469 116//469 -f 1299//470 2405//470 2406//470 -f 1302//470 2407//470 2408//470 -f 1305//470 2409//470 2410//470 -f 2411//447 2412//447 2413//447 -s 1 -f 661//131 637//131 937//131 -f 665//131 640//131 938//131 -s off -f 1996//471 2414//471 1994//471 -f 2415//472 2416//472 2011//472 -s 1 -f 2219//131 2221//131 2417//131 -f 1522//131 735//131 1000//131 -f 431//131 584//131 583//131 -f 434//131 1344//131 1362//131 -f 428//131 587//131 586//131 -f 1949//131 2418//131 1925//131 -f 1945//131 2419//131 1924//131 -f 1942//131 2420//131 1926//131 -f 2363//131 2364//131 293//131 -f 1267//131 2365//131 287//131 -s off -f 2421//473 1199//473 2422//473 -f 2423//473 1425//473 2424//473 -f 2425//473 1421//473 2426//473 -f 1361//474 1360//474 2427//474 -s 1 -f 1445//131 545//131 1546//131 -f 2428//87 2429//87 2229//87 -s off -f 2229//475 2429//475 1411//475 -s 1 -f 384//131 1871//131 394//131 -f 1982//131 384//131 394//131 -s off -f 2430//476 2431//476 1202//476 -s 1 -f 2431//87 2430//87 2432//87 -s off -f 2181//477 2433//477 2434//477 -f 2182//477 2435//477 2436//477 -f 2180//477 2437//477 2438//477 -f 983//313 678//313 677//313 -s 1 -f 2333//131 2439//131 2207//131 -f 550//131 970//131 678//131 -f 866//131 550//131 678//131 -f 182//131 604//131 443//131 -f 604//131 1316//131 443//131 -f 2440//87 1878//87 2441//87 -s off -f 1878//478 2440//478 1876//478 -f 345//479 2442//479 343//479 -f 339//479 2443//479 337//479 -f 1636//480 1635//480 1914//480 -s 1 -f 2444//131 2445//131 2446//131 -f 555//87 552//87 865//87 -f 552//87 677//87 865//87 -f 2447//87 2448//87 2449//87 -s off -f 2448//481 2447//481 2450//481 -f 2451//482 2452//482 2453//482 -s 1 -f 28//87 1010//87 476//87 -s off -f 476//483 1010//483 474//483 -f 503//483 1012//483 501//483 -s 1 -f 37//87 1012//87 503//87 -s off -f 1913//41 1915//41 2076//41 -s 1 -f 1//87 1915//87 1913//87 -s off -f 1872//41 1984//41 1983//41 -f 1894//98 1912//98 1911//98 -f 1982//98 1363//98 1851//98 -f 2169//484 2454//484 2455//484 -f 791//485 1953//485 1952//485 -s 1 -f 1492//87 1953//87 791//87 -f 1494//87 1956//87 798//87 -s off -f 798//485 1956//485 1955//485 -f 2207//486 2456//486 2205//486 -s 1 -f 1502//131 878//131 1503//131 -f 1705//131 1903//131 1706//131 -f 1702//131 1899//131 1703//131 -f 1708//131 1901//131 1709//131 -s off -f 1056//487 1999//487 859//487 -f 2302//488 1158//488 2300//488 -f 2170//489 2457//489 2458//489 -f 2459//490 1787//490 486//490 -f 2460//490 1791//490 500//490 -f 2461//490 1785//490 483//490 -s 1 -f 1771//131 2462//131 1772//131 -f 1769//131 2463//131 1770//131 -f 2464//131 1527//131 1529//131 -s off -f 2444//491 2085//491 2084//491 -f 2067//230 298//230 328//230 -f 1369//116 2066//116 2065//116 -f 1298//492 2465//492 2466//492 -s 1 -f 1852//87 393//87 385//87 -f 393//87 389//87 385//87 -s off -f 1851//98 1852//98 1982//98 -s 1 -f 1852//87 1851//87 393//87 -f 297//87 1895//87 1063//87 -f 297//87 1063//87 328//87 -s off -f 1983//41 1873//41 1872//41 -s 1 -f 1873//87 1983//87 755//87 -f 389//87 1873//87 755//87 -f 389//87 755//87 385//87 -s off -f 1911//98 1895//98 1894//98 -s 1 -f 1895//87 1911//87 1063//87 -s off -f 128//308 2279//308 126//308 -f 140//308 2280//308 138//308 -s 1 -f 2467//131 2163//131 2468//131 -f 2469//131 2164//131 2470//131 -s off -f 1335//493 2471//493 1333//493 -s 1 -f 2472//87 2471//87 1335//87 -f 65//131 2318//131 1138//131 -s off -f 2356//494 2473//494 2474//494 -f 2354//494 2475//494 2476//494 -s 1 -f 1118//87 1117//87 2477//87 -s off -f 2477//495 1117//495 1242//495 -s 1 -f 1110//87 1109//87 2478//87 -s off -f 2478//495 1109//495 1243//495 -f 2479//495 1113//495 1282//495 -s 1 -f 1114//87 1113//87 2479//87 -s off -f 2299//496 1506//496 2298//496 -s 1 -f 1506//87 2299//87 1021//87 -f 2433//131 2181//131 1861//131 -f 2435//131 2182//131 1864//131 -f 2437//131 2180//131 1866//131 -s off -f 1215//497 1908//497 1907//497 -f 1672//142 1916//142 1229//142 -s 1 -f 1916//87 1672//87 771//87 -s off -f 1674//142 1917//142 1226//142 -s 1 -f 1917//87 1674//87 767//87 -s off -f 2480//498 2481//498 2482//498 -s 1 -f 924//87 883//87 625//87 -s off -f 883//142 924//142 1647//142 -f 881//98 921//98 1648//98 -s 1 -f 921//87 881//87 624//87 -f 2483//131 2049//131 2122//131 -f 2484//131 2046//131 2117//131 -f 1456//131 1288//131 1457//131 -f 1459//131 1291//131 1460//131 -f 1453//131 1285//131 1454//131 -s off -f 1202//499 2485//499 2430//499 -f 2486//500 809//500 808//500 -s 1 -f 809//87 2486//87 2487//87 -s off -f 328//230 2064//230 2067//230 -s 1 -f 2065//87 2064//87 328//87 -s off -f 2065//116 1370//116 1369//116 -s 1 -f 1370//87 2065//87 328//87 -s off -f 2313//501 792//501 1339//501 -s 1 -f 792//87 2313//87 793//87 -f 1508//87 2488//87 2020//87 -s off -f 2488//502 1508//502 1471//502 -s 1 -f 1512//87 2489//87 2026//87 -s off -f 2489//502 1512//502 1465//502 -s 1 -f 1510//87 2490//87 2024//87 -s off -f 2490//503 1510//503 1468//503 -f 2358//504 1052//504 2357//504 -f 2491//505 959//505 2492//505 -s 1 -f 133//87 959//87 2491//87 -s off -f 2493//505 955//505 2494//505 -s 1 -f 127//87 955//87 2493//87 -f 139//87 966//87 2495//87 -s off -f 2495//505 966//505 2496//505 -s 1 -f 384//131 386//131 1871//131 -f 386//131 1872//131 1871//131 -f 546//131 866//131 983//131 -f 866//131 678//131 983//131 -s off -f 1735//506 2497//506 1034//506 -f 1727//507 2498//507 1035//507 -f 1731//507 2499//507 1036//507 -s 1 -f 2500//131 2501//131 2502//131 -f 2451//131 2503//131 2504//131 -f 1190//131 359//131 1191//131 -f 1193//131 365//131 1194//131 -f 1196//131 362//131 1197//131 -f 178//131 177//131 1407//131 -f 806//87 2505//87 1389//87 -s off -f 2505//508 806//508 805//508 -s 1 -f 803//87 2506//87 1391//87 -s off -f 2506//509 803//509 802//509 -s 1 -f 990//131 2415//131 1827//131 -s off -f 2507//510 607//510 606//510 -s 1 -f 2508//87 607//87 2507//87 -f 2509//131 2258//131 2257//131 -f 2254//87 672//87 2510//87 -s off -f 672//511 2254//511 2253//511 -f 675//511 2252//511 2251//511 -s 1 -f 2252//87 675//87 2511//87 -f 2512//131 2087//131 2086//131 -f 795//131 1339//131 1149//131 -f 799//131 1343//131 1150//131 -s off -f 2104//512 2103//512 2513//512 -s 1 -f 1525//131 2514//131 1526//131 -f 934//131 59//131 2398//131 -f 933//131 77//131 2400//131 -s off -f 1036//513 2515//513 1731//513 -s 1 -f 2516//87 2515//87 1036//87 -s off -f 1034//513 2517//513 1735//513 -s 1 -f 2518//87 2517//87 1034//87 -s off -f 1035//513 2519//513 1727//513 -s 1 -f 2520//87 2519//87 1035//87 -s off -f 2521//514 2522//514 2523//514 -f 2524//515 797//515 2525//515 -s 1 -f 797//87 2524//87 673//87 -f 1177//87 2526//87 2059//87 -s off -f 2059//516 2526//516 976//516 -f 2063//517 2527//517 979//517 -s 1 -f 1179//87 2527//87 2063//87 -s off -f 2061//517 2528//517 973//517 -s 1 -f 1181//87 2528//87 2061//87 -f 643//131 642//131 645//131 -f 1581//131 1958//131 1957//131 -f 1251//131 1253//131 2529//131 -f 298//131 1053//131 296//131 -f 1053//131 1894//131 296//131 -f 355//131 1570//131 2530//131 -f 352//131 1574//131 2531//131 -f 2272//131 2054//131 2450//131 -f 2349//87 2532//87 2533//87 -s off -f 2532//518 2349//518 2348//518 -f 2125//519 2534//519 1919//519 -s 1 -f 2534//87 2125//87 315//87 -s off -f 2127//519 2535//519 1921//519 -s 1 -f 2535//87 2127//87 309//87 -s off -f 1150//520 2525//520 797//520 -f 251//521 2536//521 249//521 -f 243//521 2537//521 241//521 -f 247//521 2538//521 245//521 -f 2539//522 2540//522 2541//522 -f 2542//522 2543//522 2544//522 -f 2545//523 1927//523 1606//523 -s 1 -f 1927//87 2545//87 2084//87 -s off -f 2546//524 2028//524 2026//524 -f 2547//524 2022//524 2020//524 -f 2548//524 2025//524 2024//524 -s 1 -f 2465//131 1298//131 1300//131 -f 2549//131 1301//131 1303//131 -f 2550//131 1304//131 1306//131 -f 2457//131 2170//131 2551//131 -s off -f 1426//525 2045//525 2043//525 -f 1429//525 2042//525 2041//525 -s 1 -f 2552//131 184//131 183//131 -f 298//131 2066//131 1369//131 -s off -f 32//526 2553//526 30//526 -f 41//527 2554//527 39//527 -f 2391//528 1725//528 1409//528 -s 1 -f 1724//87 1725//87 2391//87 -f 1334//131 1333//131 2555//131 -s off -f 2556//529 2557//529 2493//529 -f 2558//529 2559//529 2495//529 -f 2560//529 2561//529 2491//529 -s 1 -f 2095//131 356//131 601//131 -f 2100//131 353//131 215//131 -f 2092//131 350//131 209//131 -s off -f 2562//530 1643//530 1642//530 -s 1 -f 2316//87 1643//87 2562//87 -s off -f 2563//531 1646//531 1645//531 -s 1 -f 2315//87 1646//87 2563//87 -s off -f 2564//532 2565//532 2566//532 -f 2567//532 2568//532 2569//532 -s 1 -f 2570//131 415//131 1106//131 -s off -f 2571//532 2572//532 2573//532 -s 1 -f 2574//131 427//131 2392//131 -s off -f 1277//533 2575//533 2376//533 -f 1587//534 2576//534 1585//534 -s 1 -f 2576//87 1587//87 2577//87 -s off -f 315//535 2578//535 313//535 -s 1 -f 2125//87 2578//87 315//87 -s off -f 309//535 2579//535 307//535 -s 1 -f 2127//87 2579//87 309//87 -f 2035//131 2580//131 2248//131 -s off -f 2581//536 1214//536 1213//536 -s 1 -f 2336//87 1214//87 2581//87 -s off -f 2582//536 2335//536 1844//536 -s 1 -f 2334//87 2335//87 2582//87 -s off -f 1412//537 874//537 2583//537 -s 1 -f 2427//87 2508//87 2507//87 -s off -f 2508//538 2427//538 1360//538 -f 2436//539 1863//539 2182//539 -s 1 -f 1862//87 1863//87 2436//87 -f 1859//87 1860//87 2434//87 -s off -f 2434//540 1860//540 2181//540 -s 1 -f 1865//87 1867//87 2438//87 -s off -f 2438//540 1867//540 2180//540 -f 1082//541 2580//541 2584//541 -f 928//542 2585//542 926//542 -s 1 -f 2413//87 2586//87 2587//87 -s off -f 2586//543 2413//543 2412//543 -f 557//544 2371//544 2588//544 -f 566//544 2373//544 2589//544 -s 1 -f 2282//131 2590//131 48//131 -f 2552//131 2389//131 184//131 -s off -f 2591//545 1354//545 2592//545 -s 1 -f 1540//131 2593//131 1541//131 -s off -f 2583//546 2428//546 1412//546 -s 1 -f 2428//87 2583//87 2429//87 -s off -f 2071//547 1663//547 1609//547 -f 2073//547 1667//547 1617//547 -f 2069//547 1671//547 1612//547 -f 536//548 1549//548 534//548 -f 521//548 1551//548 519//548 -f 530//548 1555//548 528//548 -s 1 -f 1435//131 1003//131 2594//131 -f 1441//131 1006//131 2595//131 -s off -f 2596//549 2597//549 2440//549 -f 2598//550 2599//550 2600//550 -s 1 -f 2599//87 2598//87 2584//87 -f 2601//131 2512//131 2086//131 -s off -f 2602//551 274//551 273//551 -f 2603//552 2604//552 2605//552 -f 2606//552 2607//552 2608//552 -f 2609//552 2610//552 2611//552 -s 1 -f 2486//87 591//87 2487//87 -s off -f 2487//553 591//553 590//553 -s 1 -f 2045//131 1426//131 1428//131 -f 2042//131 1429//131 1431//131 -f 2599//87 2584//87 900//87 -s off -f 900//554 2584//554 2580//554 -s 1 -f 1073//131 2612//131 1329//131 -f 2613//87 709//87 2342//87 -s off -f 709//555 2613//555 707//555 -s 1 -f 2614//87 703//87 2343//87 -s off -f 703//555 2614//555 701//555 -f 706//555 2615//555 704//555 -s 1 -f 2615//87 706//87 2344//87 -s off -f 2616//556 2617//556 1231//556 -f 2618//556 2619//556 1230//556 -f 2620//556 2621//556 1232//556 -f 2622//557 2623//557 2624//557 -f 2625//557 2626//557 2627//557 -f 2628//557 2629//557 2630//557 -s 1 -f 2631//87 2474//87 1798//87 -s off -f 2474//558 2631//558 2356//558 -s 1 -f 2632//87 2476//87 1796//87 -s off -f 2476//558 2632//558 2354//558 -f 1400//559 1356//559 2633//559 -f 1396//559 1358//559 2634//559 -s 1 -f 2101//131 1200//131 204//131 -f 2102//131 1187//131 618//131 -f 1713//131 1711//131 621//131 -s off -f 1106//560 412//560 411//560 -f 2392//560 424//560 423//560 -f 1830//560 418//560 417//560 -f 415//561 2570//561 413//561 -f 427//561 2574//561 425//561 -f 421//561 1829//561 419//561 -f 2635//562 452//562 451//562 -f 2636//562 458//562 457//562 -f 2637//562 446//562 445//562 -s 1 -f 2204//87 2206//87 2638//87 -s off -f 2638//563 2206//563 2639//563 -f 1462//564 2640//564 2579//564 -f 1461//564 2641//564 2578//564 -f 1431//565 1430//565 2057//565 -f 1428//565 1427//565 2056//565 -s 1 -f 313//131 2641//131 2642//131 -f 307//131 2640//131 2643//131 -f 2644//87 2645//87 320//87 -s off -f 320//566 2645//566 318//566 -f 2646//567 2647//567 2648//567 -f 2418//568 1949//568 1948//568 -f 2419//568 1945//568 1944//568 -f 2420//568 1942//568 1940//568 -s 1 -f 196//131 2536//131 251//131 -f 193//131 2538//131 247//131 -f 190//131 2537//131 243//131 -s off -f 2611//569 2649//569 2609//569 -s 1 -f 2650//87 2649//87 2611//87 -s off -f 2605//570 2651//570 2603//570 -s 1 -f 2652//87 2651//87 2605//87 -s off -f 2608//569 2653//569 2606//569 -s 1 -f 2654//87 2653//87 2608//87 -s off -f 2655//571 2656//571 2657//571 -f 2658//571 2659//571 2660//571 -f 2661//571 2662//571 2663//571 -s 1 -f 2664//87 2665//87 2624//87 -s off -f 2624//572 2665//572 2622//572 -f 2627//573 2666//573 2625//573 -s 1 -f 2667//87 2666//87 2627//87 -f 2668//87 2669//87 2630//87 -s off -f 2630//573 2669//573 2628//573 -s 1 -f 1975//87 916//87 988//87 -s off -f 988//574 916//574 2670//574 -s 1 -f 1972//87 913//87 987//87 -s off -f 987//574 913//574 2671//574 -f 989//574 919//574 2672//574 -s 1 -f 1978//87 919//87 989//87 -s off -f 2673//575 2232//575 2674//575 -s 1 -f 2675//87 2232//87 2673//87 -f 2676//87 2238//87 2677//87 -s off -f 2677//575 2238//575 2678//575 -f 2679//575 2235//575 2680//575 -s 1 -f 2681//87 2235//87 2679//87 -s off -f 1332//576 2682//576 1330//576 -s 1 -f 2682//87 1332//87 1335//87 -s off -f 2683//577 2684//577 1240//577 -f 2685//577 2686//577 1241//577 -f 2248//578 2600//578 2599//578 -s 1 -f 424//131 2015//131 2687//131 -f 418//131 2000//131 2688//131 -f 412//131 2012//131 2689//131 -s off -f 1022//579 2690//579 1020//579 -s 1 -f 214//87 1105//87 425//87 -s off -f 1105//580 214//580 213//580 -s 1 -f 647//87 1103//87 419//87 -s off -f 1103//581 647//581 646//581 -f 1104//582 208//582 207//582 -s 1 -f 208//87 1104//87 413//87 -s off -f 2691//583 2509//583 2346//583 -f 1280//584 1279//584 219//584 -s 1 -f 211//87 1166//87 459//87 -s off -f 1166//585 211//585 210//585 -s 1 -f 217//87 1167//87 447//87 -s off -f 1167//586 217//586 216//586 -s 1 -f 603//87 1165//87 453//87 -s off -f 1165//586 603//586 602//586 -f 1522//587 506//587 505//587 -s 1 -f 2692//131 1625//131 707//131 -f 2693//131 1630//131 701//131 -f 2694//131 1627//131 704//131 -f 2695//131 1642//131 1935//131 -f 2696//131 1645//131 1934//131 -f 236//131 2038//131 697//131 -f 2697//87 907//87 1372//87 -s off -f 1372//588 907//588 2698//588 -f 1374//588 904//588 2699//588 -s 1 -f 2700//87 904//87 1374//87 -s off -f 1376//588 910//588 2701//588 -s 1 -f 2702//87 910//87 1376//87 -s off -f 1848//589 2703//589 326//589 -f 1845//589 2704//589 325//589 -f 1304//492 2550//492 2705//492 -f 1301//492 2549//492 2706//492 -s 1 -f 1803//131 1278//131 1726//131 -f 1801//131 1271//131 2280//131 -f 1805//131 1274//131 2279//131 -f 2274//131 1634//131 2707//131 -s off -f 223//590 2708//590 221//590 -s 1 -f 2290//87 2544//87 2291//87 -s off -f 2544//591 2290//591 2542//591 -s 1 -f 2292//87 2541//87 2293//87 -s off -f 2541//591 2292//591 2539//591 -s 1 -f 2656//131 1178//131 2403//131 -f 2659//131 1176//131 2402//131 -f 2662//131 1180//131 2404//131 -s off -f 2450//592 1688//592 2448//592 -s 1 -f 1721//131 2709//131 648//131 -f 1722//131 2710//131 651//131 -f 2132//87 1896//87 2711//87 -s off -f 2711//593 1896//593 1806//593 -f 2712//594 1897//594 1838//594 -s 1 -f 2129//87 1897//87 2712//87 -f 2135//87 1898//87 2713//87 -s off -f 2713//593 1898//593 1840//593 -s 1 -f 759//131 2585//131 928//131 -f 2621//131 2175//131 742//131 -f 2619//131 2173//131 748//131 -f 2617//131 2174//131 754//131 -s off -f 2714//595 1179//595 981//595 -s 1 -f 1179//87 2714//87 2527//87 -f 1177//87 2715//87 2526//87 -s off -f 2715//596 1177//596 978//596 -f 2716//596 1181//596 975//596 -s 1 -f 1181//87 2716//87 2528//87 -f 2717//131 683//131 1788//131 -f 2718//131 688//131 1786//131 -f 2719//131 691//131 1792//131 -s off -f 1930//597 2720//597 2721//597 -s 1 -f 2720//87 1930//87 2300//87 -s off -f 2722//598 1648//598 2277//598 -f 2723//598 1647//598 2275//598 -s 1 -f 1185//131 2724//131 1319//131 -s off -f 290//599 2725//599 327//599 -f 2726//600 2551//600 2727//600 -s 1 -f 2728//131 2729//131 1030//131 -f 2730//131 2731//131 1026//131 -f 998//87 1826//87 336//87 -s off -f 1826//601 998//601 992//601 -f 2732//602 761//602 2691//602 -s 1 -f 2733//87 761//87 2732//87 -s off -f 1325//603 1324//603 2223//603 -s 1 -f 2480//131 2597//131 2734//131 -f 2158//87 2735//87 2289//87 -s off -f 2289//604 2735//604 828//604 -f 2467//605 2736//605 1010//605 -f 2469//605 2737//605 1012//605 -s 1 -f 2738//131 1022//131 2360//131 -f 1354//131 2591//131 1355//131 -f 2617//131 2616//131 1887//131 -f 2619//131 2618//131 1886//131 -f 2621//131 2620//131 1885//131 -s off -f 2446//606 2739//606 329//606 -s 1 -f 2740//131 1853//131 1855//131 -f 2741//131 1856//131 1858//131 -f 615//131 614//131 2742//131 -f 1927//87 849//87 2743//87 -s off -f 2743//607 849//607 848//607 -s 1 -f 55//131 54//131 2108//131 -f 50//131 49//131 2110//131 -f 2744//87 1870//87 2223//87 -s off -f 1870//608 2744//608 2745//608 -s 1 -f 1525//131 2746//131 2514//131 -f 1497//131 2747//131 1498//131 -f 1499//131 2748//131 1500//131 -f 2656//131 2655//131 1178//131 -f 2662//131 2661//131 1180//131 -f 2659//131 2658//131 1176//131 -s off -f 1081//609 2749//609 699//609 -f 2500//482 2750//482 2751//482 -f 2752//610 1066//610 1065//610 -s 1 -f 1505//87 1066//87 2752//87 -f 2304//131 2303//131 12//131 -s off -f 2753//611 773//611 863//611 -f 2754//611 776//611 862//611 -s 1 -f 2380//131 511//131 510//131 -f 2379//131 1883//131 1882//131 -f 2381//131 1880//131 1879//131 -s off -f 2272//612 1281//612 2270//612 -f 588//613 2755//613 586//613 -s 1 -f 2755//87 588//87 522//87 -s off -f 585//613 2756//613 583//613 -s 1 -f 2756//87 585//87 531//87 -s off -f 1123//613 2757//613 1362//613 -s 1 -f 2757//87 1123//87 525//87 -s off -f 814//614 2758//614 2367//614 -f 813//614 2759//614 2369//614 -f 825//615 2760//615 2761//615 -f 1050//616 2762//616 2359//616 -s 1 -f 827//131 830//131 259//131 -f 1691//131 2763//131 1692//131 -f 1700//131 2764//131 1701//131 -s off -f 2555//617 2765//617 335//617 -f 486//618 2766//618 2459//618 -s 1 -f 2766//87 486//87 488//87 -f 2767//87 500//87 497//87 -s off -f 500//618 2767//618 2460//618 -f 483//618 2768//618 2461//618 -s 1 -f 2768//87 483//87 480//87 -f 590//131 1501//131 808//131 -s off -f 509//619 2769//619 507//619 -f 2566//620 2770//620 2564//620 -s 1 -f 2771//87 2770//87 2566//87 -f 2772//87 2773//87 2573//87 -s off -f 2573//621 2773//621 2571//621 -f 2569//621 2774//621 2567//621 -s 1 -f 2775//87 2774//87 2569//87 -f 1148//131 2684//131 2683//131 -f 1147//131 2686//131 2685//131 -f 1686//131 1688//131 2450//131 -s off -f 1683//622 990//622 336//622 -f 2776//623 2777//623 1931//623 -s 1 -f 2481//131 2480//131 2734//131 -f 1280//131 2708//131 223//131 -s off -f 2778//624 1423//624 2779//624 -f 2780//624 2318//624 2781//624 -f 2782//625 1422//625 2783//625 -f 499//626 691//626 497//626 -f 492//626 683//626 488//626 -f 482//626 688//626 480//626 -s 1 -f 2784//87 2785//87 2482//87 -s off -f 2482//627 2785//627 2480//627 -s 1 -f 2591//131 2786//131 2787//131 -f 1313//131 2497//131 2331//131 -f 1310//131 2498//131 2330//131 -f 1307//131 2499//131 2329//131 -f 2297//87 2788//87 2455//87 -s off -f 2455//628 2788//628 2169//628 -f 2789//629 2790//629 2505//629 -f 2791//629 2792//629 2506//629 -s 1 -f 2457//131 2551//131 2726//131 -f 2169//131 2793//131 2794//131 -f 2736//131 2467//131 2468//131 -f 2737//131 2469//131 2470//131 -f 1013//87 1638//87 2592//87 -s off -f 1013//630 2592//630 1354//630 -f 2746//631 2795//631 85//631 -f 2748//631 2796//631 67//631 -f 2747//631 2797//631 73//631 -f 2787//632 2786//632 1639//632 -s 1 -f 1188//131 2423//131 618//131 -f 1201//131 2421//131 204//131 -f 1712//131 2425//131 621//131 -f 2775//87 2397//87 2774//87 -s off -f 2397//633 2775//633 2395//633 -f 2401//634 2771//634 1772//634 -s 1 -f 2771//87 2401//87 2770//87 -f 2772//87 2399//87 2773//87 -s off -f 2399//633 2772//633 1770//633 -f 2798//635 2721//635 2720//635 -f 2709//636 1721//636 2799//636 -f 2710//636 1722//636 2800//636 -f 2426//637 2652//637 2425//637 -s 1 -f 2652//87 2426//87 2651//87 -f 2650//87 2422//87 2649//87 -s off -f 2422//638 2650//638 2421//638 -f 2424//638 2654//638 2423//638 -s 1 -f 2654//87 2424//87 2653//87 -f 1951//131 2801//131 1491//131 -f 1954//131 2802//131 1493//131 -f 2202//87 1005//87 2044//87 -s off -f 1005//639 2202//639 1003//639 -s 1 -f 2199//87 1008//87 2040//87 -s off -f 1008//639 2199//639 1006//639 -s 1 -f 13//131 237//131 1635//131 -s off -f 1501//640 1504//640 2486//640 -s 1 -f 2035//131 700//131 2803//131 -s off -f 254//641 2804//641 253//641 -f 268//641 2805//641 266//641 -s 1 -f 1534//131 609//131 608//131 -f 1531//131 201//131 200//131 -f 2806//131 209//131 1807//131 -f 2807//131 2808//131 2543//131 -f 2809//131 2810//131 2540//131 -s off -f 229//642 1684//642 227//642 -f 2811//643 1410//643 1724//643 -s 1 -f 2667//87 110//87 2666//87 -s off -f 110//644 2667//644 108//644 -f 101//644 2664//644 99//644 -s 1 -f 2664//87 101//87 2665//87 -f 2668//87 95//87 2669//87 -s off -f 95//644 2668//644 93//644 -f 2812//645 693//645 692//645 -s 1 -f 1579//87 693//87 2812//87 -s off -f 2813//645 690//645 689//645 -s 1 -f 1580//87 690//87 2813//87 -f 1578//87 685//87 2814//87 -s off -f 2814//645 685//645 684//645 -f 239//646 2815//646 237//646 -s 1 -f 1//87 2815//87 239//87 -s off -f 1253//647 2298//647 1506//647 -f 2816//648 2817//648 1619//648 -s 1 -f 850//131 1797//131 2356//131 -f 853//131 1795//131 2354//131 -s off -f 1965//649 1037//649 812//649 -f 2818//650 2194//650 2193//650 -f 2819//650 2196//650 2195//650 -s 1 -f 2387//87 2820//87 2821//87 -s off -f 2820//651 2387//651 2386//651 -s 1 -f 2445//131 2739//131 2446//131 -f 2695//131 1935//131 2822//131 -f 2696//131 1934//131 2823//131 -s off -f 2824//652 2825//652 2826//652 -f 2827//653 2828//653 2829//653 -f 2830//653 2831//653 2832//653 -f 2833//654 2834//654 1579//654 -f 2835//654 2836//654 1578//654 -f 2837//654 2838//654 1580//654 -s 1 -f 2839//87 2458//87 2577//87 -s off -f 2577//655 2458//655 2457//655 -f 1966//656 2840//656 1321//656 -s 1 -f 1833//87 1121//87 1120//87 -s off -f 1121//657 1833//657 1351//657 -f 1126//657 1832//657 1348//657 -s 1 -f 1832//87 1126//87 1125//87 -f 1831//87 1124//87 996//87 -s off -f 1124//657 1831//657 1345//657 -s 1 -f 1636//131 2841//131 1637//131 -f 2842//87 2843//87 2466//87 -s off -f 2466//658 2843//658 1298//658 -f 2706//658 2844//658 1301//658 -s 1 -f 2845//87 2844//87 2706//87 -f 2846//87 2847//87 2705//87 -s off -f 2705//658 2847//658 1304//658 -s 1 -f 1047//131 2848//131 1388//131 -f 1044//131 2849//131 1387//131 -f 1041//131 2850//131 1386//131 -f 1269//131 1821//131 1100//131 -f 1272//131 1819//131 1097//131 -f 1275//131 1823//131 1276//131 -f 1333//131 2765//131 2555//131 -s off -f 1288//659 1736//659 1286//659 -f 1285//659 1728//659 1284//659 -f 1291//659 1734//659 1289//659 -s 1 -f 867//87 405//87 34//87 -s off -f 405//660 867//660 403//660 -s 1 -f 869//87 409//87 25//87 -s off -f 409//661 869//661 407//661 -s 1 -f 2851//131 1729//131 1285//131 -f 2852//131 1737//131 1288//131 -f 2853//131 1732//131 1291//131 -s off -f 2854//662 2855//662 144//662 -f 2856//662 2857//662 147//662 -s 1 -f 1618//131 1033//131 394//131 -s off -f 629//663 2858//663 627//663 -s 1 -f 2859//87 2858//87 629//87 -f 2860//87 2861//87 632//87 -s off -f 632//663 2861//663 630//663 -s 1 -f 2862//87 2863//87 644//87 -s off -f 644//663 2863//663 642//663 -s 1 -f 759//131 1777//131 2585//131 -s off -f 2864//664 2865//664 2735//664 -f 1016//665 2077//665 1015//665 -f 1018//665 2078//665 1017//665 -s 1 -f 2309//131 1037//131 1965//131 -s off -f 697//666 2866//666 2867//666 -s 1 -f 2152//131 2868//131 2153//131 -f 2149//131 2869//131 2150//131 -f 2338//131 2870//131 2871//131 -f 2340//131 2872//131 2873//131 -s off -f 2100//667 1843//667 2099//667 -f 2095//667 1836//667 2093//667 -f 2092//667 2806//667 2091//667 -f 879//668 2745//668 2744//668 -s 1 -f 2777//131 2776//131 808//131 -f 1326//131 506//131 2314//131 -s off -f 2874//669 720//669 719//669 -f 2875//669 725//669 724//669 -f 2055//670 2449//670 1686//670 -s 1 -f 2447//87 2449//87 2055//87 -f 2648//87 1997//87 2513//87 -s off -f 2513//671 1997//671 2104//671 -s 1 -f 2867//87 2297//87 2455//87 -s off -f 2297//672 2867//672 2296//672 -s 1 -f 2876//87 2107//87 1907//87 -s off -f 2107//673 2876//673 1217//673 -f 2106//673 2877//673 1220//673 -s 1 -f 2877//87 2106//87 1909//87 -f 1263//131 220//131 1653//131 -s off -f 2274//674 2878//674 2879//674 -s 1 -f 734//131 992//131 1000//131 -f 781//87 1019//87 370//87 -s off -f 370//675 1019//675 368//675 -s 1 -f 2760//131 825//131 515//131 -f 1206//131 2003//131 1647//131 -f 1203//131 2004//131 1648//131 -s off -f 2880//676 397//676 396//676 -s 1 -f 397//87 2880//87 1767//87 -s off -f 2881//677 2159//677 1139//677 -f 2882//677 2161//677 1146//677 -s 1 -f 1696//131 1038//131 2883//131 -f 1693//131 1076//131 2884//131 -s off -f 1607//678 2885//678 2743//678 -s 1 -f 990//131 1684//131 2886//131 -f 2103//131 2105//131 1002//131 -s off -f 303//679 779//679 301//679 -s 1 -f 779//87 303//87 225//87 -s off -f 2887//680 2257//680 2345//680 -s 1 -f 2077//131 1016//131 892//131 -s off -f 820//681 2520//681 818//681 -s 1 -f 2520//87 820//87 2519//87 -f 2518//87 823//87 2517//87 -s off -f 823//681 2518//681 821//681 -s 1 -f 2516//87 817//87 2515//87 -s off -f 817//681 2516//681 815//681 -s 1 -f 2078//131 1018//131 896//131 -s off -f 2543//682 2808//682 722//682 -f 2540//682 2810//682 721//682 -s 1 -f 1158//131 2183//131 1159//131 -f 2302//131 2888//131 2183//131 -f 1130//87 2250//87 1059//87 -s off -f 1059//683 2250//683 1057//683 -f 1062//683 2249//683 1060//683 -s 1 -f 1128//87 2249//87 1062//87 -f 2613//87 2342//87 2889//87 -s off -f 2889//684 2342//684 1625//684 -s 1 -f 2614//87 2343//87 2890//87 -s off -f 2890//685 2343//685 1630//685 -f 2891//684 2344//684 1627//684 -s 1 -f 2615//87 2344//87 2891//87 -s off -f 1929//686 1293//686 945//686 -f 1071//687 1070//687 1556//687 -f 1068//687 1067//687 1557//687 -s 1 -f 2809//131 2892//131 2810//131 -f 2807//131 2893//131 2808//131 -f 2832//87 2894//87 417//87 -s off -f 2894//688 2832//688 2831//688 -s 1 -f 2826//87 2895//87 411//87 -s off -f 2895//688 2826//688 2825//688 -s 1 -f 2829//87 2896//87 423//87 -s off -f 2896//688 2829//688 2828//688 -f 2897//689 2898//689 2334//689 -f 2899//690 2900//690 2336//690 -f 2186//691 2901//691 738//691 -f 2189//691 2902//691 744//691 -f 2079//692 1388//692 1761//692 -f 2080//692 1387//692 1763//692 -f 2081//692 1386//692 1766//692 -s 1 -f 1543//131 1545//131 2903//131 -f 2159//131 2904//131 2160//131 -f 2161//131 2905//131 2162//131 -f 2840//131 1966//131 1968//131 -s off -f 1084//693 1083//693 2598//693 -s 1 -f 1569//87 508//87 2273//87 -s off -f 508//694 1569//694 1568//694 -f 2278//695 1205//695 1204//695 -s 1 -f 2277//87 1205//87 2278//87 -s off -f 2276//695 1208//695 1207//695 -s 1 -f 2275//87 1208//87 2276//87 -f 1029//87 2031//87 2906//87 -s off -f 2906//696 2031//696 2030//696 -s 1 -f 1025//87 2034//87 2907//87 -s off -f 2907//696 2034//696 2033//696 -s 1 -f 1215//131 2908//131 1216//131 -f 1218//131 2725//131 1219//131 -f 2865//131 2864//131 1329//131 -s off -f 1149//697 1339//697 792//697 -s 1 -f 1057//131 1475//131 1476//131 -f 1060//131 1477//131 1479//131 -s off -f 2634//698 2909//698 1396//698 -s 1 -f 2193//87 2909//87 2634//87 -f 2195//87 2910//87 2633//87 -s off -f 2633//698 2910//698 1400//698 -f 2140//699 2883//699 2532//699 -f 2141//700 2884//700 2586//700 -s 1 -f 2842//87 2406//87 2843//87 -s off -f 2406//701 2842//701 1300//701 -f 2408//701 2845//701 1303//701 -s 1 -f 2845//87 2408//87 2844//87 -s off -f 2410//701 2846//701 1306//701 -s 1 -f 2846//87 2410//87 2847//87 -s off -f 2285//702 936//702 1023//702 -f 2284//702 940//702 1027//702 -f 2911//703 2643//703 341//703 -f 2912//703 2642//703 347//703 -f 2913//704 489//704 686//704 -s 1 -f 489//87 2913//87 124//87 -s off -f 2914//704 494//704 694//704 -s 1 -f 494//87 2914//87 136//87 -f 477//87 2915//87 130//87 -s off -f 2915//704 477//704 687//704 -f 923//705 1796//705 853//705 -s 1 -f 1796//87 923//87 855//87 -s off -f 920//706 1798//706 850//706 -s 1 -f 1798//87 920//87 852//87 -s off -f 2372//707 2003//707 925//707 -f 2370//707 2004//707 922//707 -f 2916//708 2917//708 2316//708 -s 1 -f 2918//87 2011//87 336//87 -s off -f 2011//709 2918//709 2415//709 -f 2919//710 2920//710 2315//710 -s 1 -f 2419//131 2921//131 1924//131 -f 2420//131 2922//131 1926//131 -f 2418//131 2923//131 1925//131 -s off -f 2879//711 2273//711 2274//711 -s 1 -f 1569//87 2273//87 2879//87 -f 751//131 2308//131 1377//131 -f 1382//131 2305//131 1383//131 -f 1379//131 2306//131 1380//131 -f 278//87 2088//87 273//87 -s off -f 2088//712 278//712 2086//712 -s 1 -f 2924//131 2500//131 2502//131 -f 2925//131 2451//131 2504//131 -f 2926//87 757//87 1605//87 -s off -f 1605//713 757//713 1603//713 -s 1 -f 266//87 1793//87 1139//87 -s off -f 1139//714 1793//714 2881//714 -s 1 -f 253//87 1794//87 1146//87 -s off -f 1146//714 1794//714 2882//714 -f 2168//715 680//715 885//715 -s 1 -f 2927//87 1403//87 1775//87 -s off -f 1403//716 2927//716 1401//716 -s 1 -f 412//131 1107//131 1151//131 -f 424//131 1154//131 1153//131 -f 2928//87 436//87 2929//87 -s off -f 2929//717 436//717 435//717 -s 1 -f 2930//87 430//87 2931//87 -s off -f 2931//718 430//718 429//718 -f 2932//718 433//718 432//718 -s 1 -f 2933//87 433//87 2932//87 -s off -f 226//719 2311//719 224//719 -s 1 -f 624//87 2588//87 922//87 -s off -f 922//720 2588//720 2370//720 -f 925//720 2589//720 2372//720 -s 1 -f 625//87 2589//87 925//87 -s off -f 2934//721 1608//721 2935//721 -f 594//722 2733//722 592//722 -s 1 -f 2733//87 594//87 761//87 -s off -f 875//723 1411//723 2429//723 -s 1 -f 2885//131 1607//131 1608//131 -s off -f 2740//724 1691//724 2286//724 -f 2741//724 1700//724 2287//724 -f 219//725 950//725 1280//725 -s 1 -f 222//87 950//87 219//87 -s off -f 2440//726 2784//726 2596//726 -s 1 -f 2784//87 2440//87 2785//87 -s off -f 2800//727 2936//727 2710//727 -s 1 -f 767//87 2936//87 2800//87 -s off -f 2799//727 2937//727 2709//727 -s 1 -f 771//87 2937//87 2799//87 -f 418//131 1169//131 1168//131 -s off -f 1490//728 2676//728 1488//728 -s 1 -f 2676//87 1490//87 2238//87 -s off -f 1487//729 2681//729 1485//729 -s 1 -f 2681//87 1487//87 2235//87 -s off -f 1484//728 2675//728 1482//728 -s 1 -f 2675//87 1484//87 2232//87 -s off -f 2389//730 2938//730 1297//730 -s 1 -f 2644//87 812//87 516//87 -s off -f 812//731 2644//731 1965//731 -f 538//732 2939//732 757//732 -s 1 -f 50//131 2110//131 1357//131 -f 55//131 2108//131 1359//131 -f 1850//131 292//131 2703//131 -f 1847//131 286//131 2704//131 -f 722//87 151//87 148//87 -s off -f 151//733 722//733 2808//733 -f 142//733 721//733 2810//733 -s 1 -f 721//87 142//87 145//87 -s off -f 2821//734 736//734 735//734 -s 1 -f 999//87 736//87 2821//87 -s off -f 1231//735 2940//735 2616//735 -s 1 -f 2941//87 2940//87 1231//87 -f 2942//87 2943//87 1230//87 -s off -f 1230//735 2943//735 2618//735 -s 1 -f 2944//87 2945//87 1232//87 -s off -f 1232//735 2945//735 2620//735 -f 2692//736 1047//736 1762//736 -f 2693//736 1044//736 1764//736 -f 2694//736 1041//736 1765//736 -s 1 -f 2946//131 2085//131 1606//131 -f 2758//131 814//131 937//131 -f 2759//131 813//131 938//131 -f 2939//131 1156//131 1293//131 -s off -f 2244//737 2853//737 2243//737 -f 2246//737 2851//737 2245//737 -f 2242//737 2852//737 2241//737 -f 2523//738 2158//738 2521//738 -s 1 -f 2158//87 2523//87 2735//87 -f 491//131 1710//131 155//131 -f 479//131 1707//131 159//131 -f 496//131 1704//131 162//131 -s off -f 299//739 2947//739 2948//739 -s 1 -f 1683//131 1682//131 967//131 -s off -f 1828//740 206//740 2859//740 -f 1096//740 212//740 2860//740 -f 1516//740 645//740 2862//740 -f 977//741 754//741 753//741 -f 980//741 742//741 741//741 -f 974//741 748//741 747//741 -f 958//742 2949//742 956//742 -f 965//742 2950//742 963//742 -f 962//742 2951//742 960//742 -s 1 -f 1669//131 1671//131 2069//131 -f 1665//131 1667//131 2073//131 -f 1661//131 1663//131 2071//131 -s off -f 1842//743 215//743 2097//743 -f 1837//743 601//743 2096//743 -f 1807//743 209//743 2089//743 -s 1 -f 2702//87 512//87 910//87 -s off -f 512//744 2702//744 510//744 -f 1884//744 2697//744 1882//744 -s 1 -f 2697//87 1884//87 907//87 -f 2700//87 1881//87 904//87 -s off -f 1881//744 2700//744 1879//744 -f 2952//745 2137//745 2351//745 -f 2456//746 2953//746 2205//746 -s 1 -f 2954//87 2955//87 2660//87 -s off -f 2660//747 2955//747 2658//747 -f 2663//747 2956//747 2661//747 -s 1 -f 2957//87 2956//87 2663//87 -s off -f 2657//747 2958//747 2655//747 -s 1 -f 2959//87 2958//87 2657//87 -s off -f 2030//748 2728//748 2906//748 -f 2033//748 2730//748 2907//748 -s 1 -f 1514//131 1516//131 1515//131 -s off -f 1614//749 2960//749 1613//749 -s 1 -f 2046//131 1828//131 2117//131 -s off -f 1611//749 2961//749 1610//749 -s 1 -f 2049//131 1096//131 2122//131 -s off -f 1616//749 2962//749 1615//749 -f 2365//750 1217//750 2876//750 -f 2364//750 1220//750 2877//750 -s 1 -f 380//87 1035//87 1312//87 -s off -f 1312//751 1035//751 1310//751 -f 1309//751 1036//751 1307//751 -s 1 -f 376//87 1036//87 1309//87 -s off -f 1315//751 1034//751 1313//751 -s 1 -f 372//87 1034//87 1315//87 -f 2156//87 2281//87 947//87 -s off -f 2281//752 2156//752 2155//752 -s 1 -f 1838//131 1837//131 2130//131 -f 1840//131 1842//131 2136//131 -f 2464//131 2963//131 612//131 -s off -f 1596//753 2964//753 1594//753 -f 1593//753 2965//753 1592//753 -f 1590//753 2966//753 1589//753 -f 2967//754 2968//754 2516//754 -f 2969//755 2970//755 2518//755 -f 2971//754 2972//754 2520//754 -s 1 -f 11//87 2973//87 2//87 -s off -f 2//756 2973//756 2303//756 -s 1 -f 2974//131 345//131 2975//131 -f 2976//131 339//131 2977//131 -s off -f 1306//757 1305//757 2410//757 -f 1300//758 1299//758 2406//758 -f 1303//757 1302//757 2408//757 -s 1 -f 1409//131 2154//131 1410//131 -s off -f 2978//759 807//759 2979//759 -f 2980//760 1913//760 1637//760 -s 1 -f 1913//87 2980//87 2361//87 -s off -f 2975//761 1919//761 2534//761 -f 2977//761 1921//761 2535//761 -s 1 -f 2268//131 2269//131 2240//131 -f 2266//131 2267//131 2239//131 -f 1222//131 1221//131 1979//131 -s off -f 2203//762 2314//762 997//762 -f 153//763 2494//763 955//763 -f 164//763 2496//763 966//763 -f 157//764 2492//764 959//764 -s 1 -f 2878//131 2274//131 2707//131 -f 382//87 1900//87 495//87 -s off -f 495//765 1900//765 1702//765 -f 490//765 1902//765 1708//765 -s 1 -f 378//87 1902//87 490//87 -f 374//87 1904//87 478//87 -s off -f 478//765 1904//765 1705//765 -f 1704//766 2981//766 2982//766 -f 1710//766 2983//766 2984//766 -f 1707//766 2985//766 2986//766 -f 1760//767 734//767 1758//767 -f 2224//768 2987//768 1939//768 -f 2225//768 2988//768 1946//768 -f 2226//768 2989//768 1950//768 -s 1 -f 1070//131 1072//131 2355//131 -f 1067//131 1069//131 2353//131 -s off -f 932//769 2990//769 2774//769 -f 933//770 2991//770 2770//770 -f 934//770 2992//770 2773//770 -f 2993//771 1129//771 868//771 -f 2994//771 1131//771 870//771 -f 1210//772 2008//772 2995//772 -f 1211//772 2005//772 2996//772 -s 1 -f 1185//131 1079//131 2724//131 -f 290//131 936//131 2285//131 -f 284//131 940//131 2284//131 -s off -f 1157//773 18//773 2997//773 -f 475//774 2998//774 476//774 -f 502//774 2999//774 503//774 -s 1 -f 27//87 3000//87 1010//87 -s off -f 1010//775 3000//775 2467//775 -s 1 -f 36//87 3001//87 1012//87 -s off -f 1012//775 3001//775 2469//775 -s 1 -f 307//131 2643//131 2256//131 -f 313//131 2642//131 2255//131 -s off -f 1247//776 2533//776 894//776 -s 1 -f 2349//87 2533//87 1247//87 -s off -f 1246//777 2587//777 898//777 -s 1 -f 2413//87 2587//87 1246//87 -f 2109//87 718//87 2385//87 -s off -f 2385//778 718//778 1394//778 -s 1 -f 2111//87 723//87 2383//87 -s off -f 2383//779 723//779 1398//779 -f 1791//780 3002//780 380//780 -f 1787//780 3003//780 376//780 -f 1785//780 3004//780 372//780 -f 1273//781 1097//781 2374//781 -f 1270//781 1100//781 2375//781 -s 1 -f 259//131 680//131 2168//131 -s off -f 284//599 2908//599 324//599 -f 3005//782 183//782 1296//782 -f 2680//783 189//783 2679//783 -f 2674//783 195//783 2673//783 -f 2678//783 192//783 2677//783 -s 1 -f 545//131 2509//131 2257//131 -s off -f 2671//784 2219//784 987//784 -f 2670//784 1575//784 988//784 -f 2672//784 1571//784 989//784 -f 2761//785 826//785 825//785 -s 1 -f 514//87 826//87 2761//87 -f 946//87 1655//87 219//87 -s off -f 1655//786 946//786 1653//786 -f 1318//787 2169//787 2788//787 -f 1222//788 878//788 877//788 -s 1 -f 1829//131 1830//131 646//131 -f 2570//131 1106//131 207//131 -f 2574//131 2392//131 213//131 -f 1213//131 1782//131 2501//131 -f 1844//131 1779//131 2503//131 -f 615//131 2742//131 944//131 -s off -f 2727//789 2839//789 2726//789 -s 1 -f 2839//87 2727//87 2458//87 -f 2744//87 2223//87 616//87 -s off -f 616//790 2223//790 614//790 -f 1240//791 3006//791 2683//791 -s 1 -f 3006//87 1240//87 3007//87 -s off -f 1241//792 3008//792 2685//792 -s 1 -f 3008//87 1241//87 3009//87 -f 2220//131 3010//131 2221//131 -f 2218//131 3011//131 1576//131 -f 2217//131 3012//131 1572//131 -s off -f 1360//793 942//793 2508//793 -s 1 -f 2420//131 429//131 2922//131 -f 2419//131 432//131 2921//131 -f 2418//131 435//131 2923//131 -s off -f 3013//794 134//794 133//794 -f 3014//795 137//795 136//795 -f 3015//795 125//795 124//795 -f 3016//795 131//795 130//795 -s 1 -f 671//87 2648//87 2513//87 -s off -f 2648//796 671//796 2646//796 -f 326//797 3017//797 1848//797 -s 1 -f 3017//87 326//87 1214//87 -f 3018//87 325//87 2335//87 -s off -f 325//797 3018//797 1845//797 -f 2701//798 1554//798 1376//798 -f 2699//798 1550//798 1374//798 -f 2698//798 1548//798 1372//798 -f 969//799 3019//799 967//799 -s 1 -f 3019//87 969//87 1173//87 -s off -f 1637//800 3020//800 2980//800 -s 1 -f 1819//131 1098//131 1097//131 -f 1823//131 3021//131 1276//131 -f 1821//131 1101//131 1100//131 -s off -f 1687//801 1686//801 2449//801 -s 1 -f 1815//87 1118//87 2477//87 -s off -f 1118//802 1815//802 1814//802 -f 1110//802 1812//802 1811//802 -s 1 -f 1812//87 1110//87 2478//87 -f 1818//87 1114//87 2479//87 -s off -f 1114//803 1818//803 1817//803 -f 2263//804 1151//804 2262//804 -f 2261//804 1168//804 2260//804 -f 2265//804 1153//804 2264//804 -f 628//805 3022//805 2118//805 -f 631//805 3023//805 2121//805 -f 643//805 3024//805 2114//805 -f 1506//806 2350//806 1253//806 -s 1 -f 2350//87 1506//87 2351//87 -s off -f 391//807 1871//807 389//807 -s 1 -f 1597//131 472//131 471//131 -f 1442//131 466//131 465//131 -f 1600//131 469//131 468//131 -f 1327//131 1631//131 1633//131 -f 897//131 899//131 3025//131 -f 893//131 895//131 3026//131 -s off -f 1886//808 471//808 1988//808 -f 1887//808 465//808 1986//808 -f 1885//808 468//808 1990//808 -f 1052//809 1051//809 232//809 -s 1 -f 2375//87 3027//87 964//87 -s off -f 964//810 3027//810 1821//810 -f 957//810 3028//810 1819//810 -s 1 -f 2374//87 3028//87 957//87 -s off -f 961//810 3029//810 1823//810 -s 1 -f 2376//87 3029//87 961//87 -f 1411//131 875//131 1412//131 -f 1670//131 2324//131 1671//131 -f 1666//131 2326//131 1667//131 -f 1662//131 2322//131 1663//131 -s off -f 3030//811 2104//811 1997//811 -s 1 -f 941//131 942//131 1360//131 -s off -f 1039//812 1697//812 1432//812 -f 1077//813 1694//813 1495//813 -f 3031//814 1226//814 1917//814 -f 3032//814 1229//814 1916//814 -f 2783//815 2048//815 2782//815 -s 1 -f 3033//87 2048//87 2783//87 -f 3034//87 2051//87 2779//87 -s off -f 2779//816 2051//816 2778//816 -f 2781//816 2053//816 2780//816 -s 1 -f 3035//87 2053//87 2781//87 -s off -f 2442//817 3036//817 343//817 -f 2443//818 3037//818 337//818 -s 1 -f 2057//87 1143//87 3038//87 -s off -f 3038//819 1143//819 1265//819 -s 1 -f 2056//87 1140//87 3039//87 -s off -f 3039//820 1140//820 1264//820 -f 2251//821 3040//821 675//821 -f 2253//821 3041//821 672//821 -s 1 -f 1189//131 1191//131 1470//131 -f 1192//131 1194//131 1464//131 -f 1195//131 1197//131 1467//131 -f 345//131 1919//131 2975//131 -f 339//131 1921//131 2977//131 -f 2379//131 1547//131 1883//131 -f 2381//131 1552//131 1880//131 -f 2380//131 1553//131 511//131 -f 1712//131 2394//131 2425//131 -f 1201//131 1720//131 2421//131 -f 1188//131 2393//131 2423//131 -f 2499//131 1733//131 2329//131 -f 2497//131 1738//131 2331//131 -f 2498//131 1730//131 2330//131 -s off -f 402//822 580//822 673//822 -s 1 -f 1773//131 2762//131 3042//131 -s off -f 406//822 577//822 793//822 -f 1030//823 938//823 1028//823 -f 1026//824 937//824 1024//824 -f 3043//825 1761//825 1388//825 -s 1 -f 1761//87 3043//87 1762//87 -f 1766//87 3044//87 1765//87 -s off -f 3044//825 1766//825 1386//825 -s 1 -f 1763//87 3045//87 1764//87 -s off -f 3045//825 1763//825 1387//825 -s 1 -f 2914//87 2210//87 136//87 -s off -f 136//826 2210//826 2209//826 -f 124//826 2216//826 2215//826 -s 1 -f 2913//87 2216//87 124//87 -f 2915//87 2213//87 130//87 -s off -f 130//827 2213//827 2212//827 -s 1 -f 929//87 416//87 1969//87 -s off -f 1969//828 416//828 1533//828 -s 1 -f 931//87 422//87 1960//87 -s off -f 1960//828 422//828 1536//828 -s 1 -f 930//87 410//87 1959//87 -s off -f 1959//828 410//828 1957//828 -s 1 -f 2282//131 1157//131 2590//131 -f 1660//131 1661//131 2071//131 -f 1668//131 1669//131 2069//131 -f 1664//131 1665//131 2073//131 -f 1224//131 1226//131 3031//131 -f 1227//131 1229//131 3032//131 -s off -f 1725//829 1741//829 1740//829 -s 1 -f 1723//87 1741//87 1725//87 -f 444//87 1975//87 988//87 -s off -f 1975//830 444//830 1973//830 -s 1 -f 456//87 1972//87 987//87 -s off -f 1972//830 456//830 1970//830 -s 1 -f 450//87 1978//87 989//87 -s off -f 1978//830 450//830 1976//830 -s 1 -f 1162//87 2996//87 1449//87 -s off -f 2996//831 1162//831 1211//831 -s 1 -f 1164//87 2995//87 1451//87 -s off -f 2995//831 1164//831 1210//831 -s 1 -f 1906//131 183//131 3005//131 -f 236//131 697//131 233//131 -f 1836//131 2095//131 601//131 -f 1843//131 2100//131 215//131 -f 2806//131 2092//131 209//131 -f 2220//131 1713//131 620//131 -f 2217//131 2101//131 203//131 -f 2218//131 2102//131 617//131 -s off -f 2359//832 234//832 1050//832 -s 1 -f 2357//87 234//87 2359//87 -f 378//87 2984//87 1902//87 -s off -f 2984//833 378//833 1710//833 -s 1 -f 382//87 2982//87 1900//87 -s off -f 2982//833 382//833 1704//833 -s 1 -f 1156//131 856//131 1293//131 -f 374//87 2986//87 1904//87 -s off -f 2986//834 374//834 1707//834 -s 1 -f 141//87 1015//87 145//87 -s off -f 145//835 1015//835 264//835 -s 1 -f 150//87 1017//87 148//87 -s off -f 148//835 1017//835 198//835 -f 2522//836 1446//836 1538//836 -s 1 -f 1871//131 1618//131 394//131 -f 2472//87 335//87 2471//87 -s off -f 335//837 2472//837 2555//837 -f 2287//838 2510//838 2741//838 -s 1 -f 2254//87 2510//87 2287//87 -s off -f 2286//838 2511//838 2740//838 -s 1 -f 2252//87 2511//87 2286//87 -s off -f 2087//839 3046//839 2222//839 -s 1 -f 2729//131 938//131 1030//131 -f 2731//131 937//131 1026//131 -f 2149//131 3047//131 1338//131 -f 2152//131 3048//131 1342//131 -s off -f 1604//840 2888//840 2301//840 -f 1268//841 1844//841 2335//841 -f 738//842 2187//842 2186//842 -s 1 -f 1716//87 2187//87 738//87 -s off -f 744//843 2190//843 2189//843 -s 1 -f 1714//87 2190//87 744//87 -f 1718//87 2341//87 750//87 -s off -f 750//843 2341//843 2307//843 -f 2580//844 2035//844 900//844 -f 455//845 355//845 453//845 -f 449//845 352//845 447//845 -f 461//845 349//845 459//845 -s 1 -f 499//131 1790//131 1791//131 -f 492//131 1789//131 1787//131 -f 482//131 1784//131 1785//131 -f 1527//131 932//131 1528//131 -f 2462//131 933//131 2400//131 -f 2463//131 934//131 2398//131 -s off -f 787//846 2168//846 788//846 -s 1 -f 887//131 2753//131 2822//131 -f 889//131 2754//131 2823//131 -f 545//131 2257//131 1546//131 -s off -f 1065//847 1685//847 2752//847 -s 1 -f 2935//87 1927//87 2743//87 -s off -f 1927//848 2935//848 1608//848 -s 1 -f 1875//87 3049//87 1620//87 -s off -f 3049//849 1875//849 1364//849 -s 1 -f 1998//131 1608//131 2167//131 -s off -f 1328//850 504//850 1326//850 -s 1 -f 464//87 504//87 1328//87 -f 1281//131 2272//131 857//131 -s off -f 3007//851 337//851 3037//851 -s 1 -f 1240//87 337//87 3007//87 -f 1241//87 343//87 3009//87 -s off -f 3009//852 343//852 3036//852 -s 1 -f 2545//87 2948//87 2084//87 -s off -f 2084//853 2948//853 2947//853 -f 3050//854 1073//854 1539//854 -f 280//855 3051//855 278//855 -s 1 -f 605//131 2601//131 280//131 -s off -f 1218//497 1910//497 1909//497 -s 1 -f 1278//131 1455//131 687//131 -f 1271//131 1452//131 694//131 -f 1274//131 1458//131 686//131 -s off -f 612//856 2395//856 2775//856 -f 609//856 1772//856 2771//856 -f 201//856 1770//856 2772//856 -s 1 -f 2505//87 28//87 476//87 -s off -f 28//857 2505//857 2790//857 -s 1 -f 2506//87 37//87 503//87 -s off -f 37//857 2506//857 2792//857 -f 44//17 3052//17 42//17 -s 1 -f 1322//131 1968//131 1367//131 -s off -f 322//858 3053//858 2377//858 -s 1 -f 1473//131 2543//131 1474//131 -f 1481//131 2540//131 1478//131 -f 3049//87 2037//87 1620//87 -s off -f 1620//859 2037//859 2036//859 -f 169//860 3054//860 2651//860 -f 165//860 3055//860 2653//860 -f 176//860 3056//860 2649//860 -f 1663//861 99//861 2664//861 -f 1667//861 93//861 2668//861 -f 1671//861 108//861 2667//861 -s 1 -f 2736//131 2468//131 3057//131 -f 2737//131 2470//131 3058//131 -s off -f 618//862 2423//862 2654//862 -f 621//863 2425//863 2652//863 -f 204//862 2421//862 2650//862 -s 1 -f 725//131 2266//131 2239//131 -f 720//131 2268//131 2240//131 -f 506//131 1524//131 2314//131 -f 2323//131 1621//131 100//131 -f 2325//131 1623//131 109//131 -f 2327//131 1622//131 94//131 -f 878//131 1222//131 1979//131 -s off -f 1561//864 861//864 1559//864 -s 1 -f 2042//131 1007//131 1006//131 -f 2045//131 1004//131 1003//131 -s off -f 575//865 3059//865 2665//865 -f 569//865 3060//865 2666//865 -f 572//865 3061//865 2669//865 -f 1408//866 177//866 1767//866 -s 1 -f 461//131 2219//131 2417//131 -f 449//131 1575//131 1577//131 -f 455//131 1571//131 1573//131 -s off -f 1635//867 237//867 2815//867 -s 1 -f 2056//87 1141//87 1140//87 -s off -f 1141//868 2056//868 1427//868 -f 1144//869 2057//869 1430//869 -s 1 -f 2057//87 1144//87 1143//87 -f 3030//131 1334//131 1365//131 -f 2338//131 1656//131 1657//131 -f 2340//131 1658//131 1659//131 -s off -f 800//870 3062//870 2784//870 -f 871//871 788//871 2168//871 -s 1 -f 331//87 788//87 871//87 -f 2512//131 3046//131 2087//131 -f 2309//131 2328//131 1037//131 -f 3063//131 1513//131 2319//131 -f 3064//131 2483//131 2321//131 -f 3065//131 2484//131 2320//131 -f 2586//87 3066//87 1496//87 -s off -f 3066//872 2586//872 2884//872 -f 3067//873 2532//873 2883//873 -s 1 -f 2532//87 3067//87 1433//87 -f 2878//131 2707//131 1266//131 -s off -f 2848//874 707//874 2613//874 -f 2850//874 704//874 2615//874 -f 2849//874 701//874 2614//874 -f 390//875 3068//875 982//875 -s 1 -f 392//87 3068//87 390//87 -s off -f 1907//876 324//876 2908//876 -s 1 -f 2107//87 324//87 1907//87 -f 2106//87 327//87 1909//87 -s off -f 1909//876 327//876 2725//876 -s 1 -f 193//131 192//131 2538//131 -f 196//131 195//131 2536//131 -f 190//131 189//131 2537//131 -s off -f 1248//877 2486//877 1504//877 -s 1 -f 2486//87 1248//87 876//87 -s off -f 193//878 1629//878 248//878 -f 190//878 1628//878 244//878 -f 196//878 1626//878 252//878 -f 1740//879 1409//879 1725//879 -f 2457//880 1799//880 2577//880 -s 1 -f 3069//87 2334//87 2582//87 -s off -f 2334//881 3069//881 2897//881 -s 1 -f 3070//87 2336//87 2581//87 -s off -f 2336//881 3070//881 2899//881 -f 1358//882 35//882 34//882 -f 1356//882 26//882 25//882 -s 1 -f 341//87 1417//87 2579//87 -s off -f 2579//883 1417//883 1462//883 -f 2578//883 1414//883 1461//883 -s 1 -f 347//87 1414//87 2578//87 -s off -f 1138//884 2319//884 3035//884 -f 1137//884 2321//884 3034//884 -f 1136//884 2320//884 3033//884 -f 3071//885 407//885 869//885 -f 3072//885 403//885 867//885 -f 1135//886 2388//886 3073//886 -f 1133//886 1500//886 3074//886 -f 1134//886 1498//886 3075//886 -f 1846//887 1845//887 3018//887 -f 1849//887 1848//887 3017//887 -s 1 -f 2377//87 320//87 1321//87 -s off -f 1321//888 320//888 1966//888 -s 1 -f 2601//131 3051//131 280//131 -s off -f 692//889 2546//889 2812//889 -f 684//889 2548//889 2814//889 -f 689//890 2547//890 2813//890 -f 2639//891 1171//891 2638//891 -s 1 -f 1252//131 2738//131 2360//131 -f 340//87 1916//87 1417//87 -s off -f 1916//892 340//892 3032//892 -f 1917//893 346//893 3031//893 -s 1 -f 346//87 1917//87 1414//87 -f 827//131 2168//131 787//131 -f 185//87 2390//87 1297//87 -s off -f 1297//894 2390//894 2389//894 -f 1152//895 2262//895 1151//895 -s 1 -f 2262//87 1152//87 411//87 -s off -f 1170//895 2260//895 1168//895 -s 1 -f 2260//87 1170//87 417//87 -s off -f 1155//895 2264//895 1153//895 -s 1 -f 2264//87 1155//87 423//87 -s off -f 2082//896 3076//896 3068//896 -s 1 -f 392//87 2979//87 3068//87 -s off -f 2979//897 392//897 2978//897 -f 1693//898 898//898 2587//898 -f 1696//899 894//899 2533//899 -s 1 -f 698//87 2599//87 900//87 -s off -f 2599//900 698//900 971//900 -s 1 -f 3024//131 643//131 1516//131 -f 3022//131 628//131 1828//131 -f 3023//131 631//131 1096//131 -s off -f 1532//901 200//901 2145//901 -f 1535//901 608//901 2147//901 -f 1958//901 611//901 2146//901 -f 2201//902 1003//902 2202//902 -f 2198//902 1006//902 2199//902 -s 1 -f 1079//131 1874//131 2724//131 -s off -f 2307//903 751//903 750//903 -f 412//904 1957//904 410//904 -f 424//904 1536//904 422//904 -f 418//904 1533//904 416//904 -f 2090//905 351//905 350//905 -s 1 -f 2089//87 351//87 2090//87 -f 2096//87 357//87 2094//87 -s off -f 2094//905 357//905 356//905 -f 2098//906 354//906 353//906 -s 1 -f 2097//87 354//87 2098//87 -s off -f 1518//907 2480//907 2785//907 -f 452//908 1976//908 450//908 -f 446//908 1973//908 444//908 -f 783//909 1298//909 2843//909 -f 458//908 1970//908 456//908 -s 1 -f 1252//131 2360//131 1253//131 -s off -f 615//910 282//910 281//910 -f 1974//911 617//911 2143//911 -f 1971//911 620//911 2144//911 -f 1977//911 203//911 2142//911 -f 2403//912 1178//912 2959//912 -f 2402//913 1176//913 2954//913 -f 2404//912 1180//912 2957//912 -f 2473//914 1072//914 2474//914 -f 2475//914 1069//914 2476//914 -s 1 -f 1939//87 2930//87 2931//87 -s off -f 2930//915 1939//915 2987//915 -f 2933//915 1946//915 2988//915 -s 1 -f 1946//87 2933//87 2932//87 -s off -f 2928//915 1950//915 2989//915 -s 1 -f 1950//87 2928//87 2929//87 -s off -f 3077//916 17//916 16//916 -s 1 -f 17//87 3077//87 1186//87 -f 614//131 1323//131 2742//131 -s off -f 1827//917 2415//917 2918//917 -f 1777//918 759//918 1160//918 -s 1 -f 1073//131 3050//131 2612//131 -s off -f 308//919 1920//919 338//919 -f 314//919 1918//919 344//919 -f 2997//920 2300//920 1157//920 -s 1 -f 2720//87 2300//87 2997//87 -s off -f 2735//921 1075//921 2864//921 -s 1 -f 1538//87 1075//87 2735//87 -f 2161//131 2882//131 2905//131 -f 2159//131 2881//131 2904//131 -f 177//131 3078//131 1407//131 -f 2580//131 2600//131 2248//131 -s off -f 2536//922 1482//922 2675//922 -f 2537//922 1485//922 2681//922 -f 2538//922 1488//922 2676//922 -s 1 -f 3079//87 2316//87 2562//87 -s off -f 2316//923 3079//923 2916//923 -s 1 -f 3080//87 2315//87 2563//87 -s off -f 2315//924 3080//924 2919//924 -f 1000//925 992//925 998//925 -f 527//926 434//926 525//926 -f 533//927 431//927 531//927 -f 524//927 428//927 522//927 -s 1 -f 861//131 1561//131 2310//131 -s off -f 1949//928 1346//928 1947//928 -f 1945//928 1349//928 1943//928 -f 1942//928 1352//928 1941//928 -f 2509//929 545//929 544//929 -s 1 -f 1773//131 3042//131 2172//131 -f 875//131 874//131 1412//131 -s off -f 2855//930 1481//930 2293//930 -f 2857//930 1473//930 2291//930 -s 1 -f 2333//131 3081//131 2439//131 -f 2109//87 868//87 718//87 -s off -f 868//931 2109//931 1395//931 -s 1 -f 2111//87 870//87 723//87 -s off -f 870//931 2111//931 1399//931 -f 1645//932 2696//932 2563//932 -f 1642//933 2695//933 2562//933 -f 1327//934 1632//934 1209//934 -f 506//935 1326//935 504//935 -f 14//936 1202//936 2431//936 -s 1 -f 6//131 1202//131 2171//131 -s off -f 2085//937 2946//937 2083//937 -f 274//938 605//938 272//938 -f 1806//939 3082//939 2711//939 -f 1840//940 3083//940 2713//940 -f 1838//940 3084//940 2712//940 -f 1445//941 1636//941 2361//941 -f 188//942 672//942 186//942 -s 1 -f 672//87 188//87 256//87 -f 675//87 267//87 270//87 -s off -f 267//942 675//942 316//942 -s 1 -f 3085//87 2427//87 2507//87 -s off -f 2427//943 3085//943 1361//943 -f 2860//944 2120//944 1096//944 -s 1 -f 2120//87 2860//87 632//87 -f 2113//87 2862//87 644//87 -s off -f 2862//945 2113//945 1516//945 -f 2859//945 2115//945 1828//945 -s 1 -f 2115//87 2859//87 629//87 -s off -f 2396//946 89//946 88//946 -f 2398//946 59//946 58//946 -f 2400//946 77//946 76//946 -s 1 -f 2865//131 1329//131 829//131 -s off -f 3086//947 1060//947 2249//947 -f 3087//947 1057//947 2250//947 -s 1 -f 2131//87 2089//87 2091//87 -s off -f 2089//948 2131//948 1807//948 -s 1 -f 2128//87 2096//87 2093//87 -s off -f 2096//948 2128//948 1837//948 -s 1 -f 2134//87 2097//87 2099//87 -s off -f 2097//948 2134//948 1842//948 -s 1 -f 1930//87 2926//87 1605//87 -s off -f 2926//949 1930//949 1929//949 -f 1419//950 1462//950 1417//950 -f 1416//951 1461//951 1414//951 -f 1413//952 1412//952 2428//952 -f 1549//953 1882//953 2697//953 -f 1555//953 510//953 2702//953 -f 1551//953 1879//953 2700//953 -f 1199//954 62//954 61//954 -f 1425//954 80//954 79//954 -f 1421//954 92//954 91//954 -s 1 -f 990//131 1936//131 2415//131 -f 734//131 1937//131 992//131 -f 177//131 1408//131 3078//131 -s off -f 341//955 2127//955 2911//955 -s 1 -f 2127//87 341//87 2579//87 -s off -f 347//955 2125//955 2912//955 -s 1 -f 2125//87 347//87 2578//87 -f 3074//87 2712//87 67//87 -s off -f 67//956 2712//956 2748//956 -f 73//956 2713//956 2747//956 -s 1 -f 3075//87 2713//87 73//87 -s off -f 1029//957 1027//957 1233//957 -s 1 -f 1027//87 1029//87 285//87 -f 1023//87 1025//87 291//87 -s off -f 1025//957 1023//957 1235//957 -f 85//956 2711//956 2746//956 -s 1 -f 3073//87 2711//87 85//87 -s off -f 3088//958 876//958 2352//958 -s 1 -f 2486//87 876//87 3088//87 -f 952//131 2924//131 667//131 -f 951//131 2925//131 655//131 -s off -f 2808//959 3089//959 151//959 -f 2138//960 368//960 1019//960 -f 2810//959 3090//959 142//959 -s 1 -f 1047//131 2692//131 2848//131 -f 1044//131 2693//131 2849//131 -f 1041//131 2694//131 2850//131 -s off -f 238//961 12//961 11//961 -f 949//962 1739//962 947//962 -f 1311//963 499//963 498//963 -f 1308//963 492//963 487//963 -f 1314//963 482//963 481//963 -s 1 -f 106//131 754//131 977//131 -f 97//131 748//131 974//131 -f 103//131 742//131 980//131 -s off -f 2647//964 1996//964 1995//964 -s 1 -f 2746//131 1808//131 2514//131 -f 2462//131 2400//131 1772//131 -f 2463//131 2398//131 1770//131 -f 1469//131 1189//131 1470//131 -f 1463//131 1192//131 1464//131 -f 1466//131 1195//131 1467//131 -f 1447//87 2229//87 1539//87 -s off -f 1539//965 2229//965 2228//965 -f 2745//966 1868//966 1870//966 -f 2550//967 1600//967 1989//967 -f 2549//967 1597//967 1987//967 -f 2465//967 1442//967 1985//967 -f 273//968 1870//968 1869//968 -s 1 -f 2222//87 1870//87 273//87 -f 527//131 1554//131 530//131 -f 533//131 1548//131 536//131 -f 524//131 1550//131 521//131 -f 2394//131 1421//131 2425//131 -f 1720//131 1199//131 2421//131 -f 2393//131 1425//131 2423//131 -s off -f 1243//969 2188//969 2478//969 -f 1282//969 2317//969 2479//969 -f 1242//969 2185//969 2477//969 -f 109//970 114//970 113//970 -f 94//970 118//970 117//970 -f 100//970 122//970 121//970 -f 178//971 1280//971 950//971 -f 6//972 2170//972 4//972 -f 539//973 2270//973 537//973 -s 1 -f 1292//87 2270//87 539//87 -f 1147//131 2685//131 3091//131 -f 1148//131 2683//131 3092//131 -s off -f 1736//974 1735//974 2517//974 -f 1734//974 1731//974 2515//974 -f 1728//974 1727//974 2519//974 -s 1 -f 2481//131 2734//131 800//131 -f 1685//131 1065//131 1064//131 -f 266//87 2202//87 2044//87 -s off -f 2202//975 266//975 2200//975 -s 1 -f 253//87 2199//87 2040//87 -s off -f 2199//975 253//975 2197//975 -f 3033//976 90//976 1136//976 -s 1 -f 90//87 3033//87 2783//87 -s off -f 3034//976 78//976 1137//976 -s 1 -f 78//87 3034//87 2779//87 -f 60//87 3035//87 2781//87 -s off -f 3035//976 60//976 1138//976 -s 1 -f 35//131 1358//131 404//131 -s off -f 1606//977 2446//977 2545//977 -s 1 -f 26//131 1356//131 408//131 -s off -f 2921//978 583//978 2756//978 -f 2922//978 586//978 2755//978 -f 2923//978 1362//978 2757//978 -s 1 -f 2323//131 100//131 99//131 -f 2325//131 109//131 108//131 -f 2327//131 94//131 93//131 -f 13//131 238//131 237//131 -s off -f 3074//979 57//979 1133//979 -s 1 -f 57//87 3074//87 67//87 -f 75//87 3075//87 73//87 -s off -f 3075//980 75//980 1134//980 -f 3073//979 87//979 1135//979 -s 1 -f 87//87 3073//87 85//87 -s off -f 924//981 2275//981 1647//981 -s 1 -f 2275//87 924//87 1208//87 -s off -f 921//982 2277//982 1648//982 -s 1 -f 2277//87 921//87 1205//87 -f 1409//131 1740//131 2154//131 -s off -f 3093//18 52//18 3094//18 -s 1 -f 1013//87 986//87 1638//87 -s off -f 1638//983 986//983 985//983 -f 1563//984 2467//984 3000//984 -f 1564//984 2469//984 3001//984 -s 1 -f 3019//87 1173//87 1938//87 -s off -f 1938//985 1173//985 1172//985 -s 1 -f 683//131 492//131 1787//131 -f 691//131 499//131 1791//131 -f 688//131 482//131 1785//131 -f 112//87 2954//87 2660//87 -s off -f 2954//986 112//986 2402//986 -f 2959//986 120//986 2403//986 -s 1 -f 120//87 2959//87 2657//87 -s off -f 2957//986 116//986 2404//986 -s 1 -f 116//87 2957//87 2663//87 -f 1531//131 200//131 1532//131 -f 1534//131 608//131 1535//131 -f 1581//131 611//131 1958//131 -f 507//87 464//87 1328//87 -s off -f 464//987 507//987 462//987 -s 1 -f 1028//87 663//87 2369//87 -s off -f 2369//988 663//988 813//988 -f 2367//988 659//988 814//988 -s 1 -f 1024//87 659//87 2367//87 -f 1799//131 2457//131 2726//131 -f 350//131 1566//131 209//131 -f 353//131 2531//131 215//131 -f 356//131 2530//131 601//131 -s off -f 2750//989 712//989 711//989 -f 2452//989 716//989 715//989 -f 2166//990 2029//990 2368//990 -f 2165//991 2032//991 2366//991 -f 2290//992 1130//992 3095//992 -s 1 -f 1130//87 2290//87 2250//87 -f 2345//87 2346//87 544//87 -s off -f 544//993 2346//993 2509//993 -f 2292//992 1128//992 3096//992 -s 1 -f 1128//87 2292//87 2249//87 -s off -f 1719//994 1816//994 1718//994 -f 1715//994 1810//994 1714//994 -f 1717//994 1813//994 1716//994 -s 1 -f 3083//131 1840//131 2136//131 -f 3084//131 1838//131 2130//131 -f 3082//131 1806//131 1808//131 -f 35//131 404//131 2164//131 -f 26//131 408//131 2163//131 -f 1298//131 783//131 1299//131 -f 1301//131 1381//131 1302//131 -f 1304//131 1378//131 1305//131 -f 326//87 954//87 1214//87 -s off -f 1214//995 954//995 1212//995 -s 1 -f 325//87 953//87 2335//87 -s off -f 2335//996 953//996 1268//996 -s 1 -f 1031//131 2082//131 1032//131 -f 2580//131 1082//131 1084//131 -f 580//131 582//131 1343//131 -f 577//131 579//131 1339//131 -f 2741//131 3097//131 2764//131 -f 2740//131 3098//131 2763//131 -s off -f 5//997 2432//997 240//997 -s 1 -f 2431//87 2432//87 5//87 -f 1581//131 1957//131 412//131 -f 1534//131 1536//131 424//131 -f 1531//131 1533//131 418//131 -f 1379//131 2186//131 2306//131 -f 1382//131 2189//131 2305//131 -f 751//131 2307//131 2308//131 -s off -f 695//998 2916//998 3079//998 -f 696//998 2919//998 3080//998 -s 1 -f 455//131 1573//131 1570//131 -f 449//131 1577//131 1574//131 -f 461//131 2417//131 1565//131 -s off -f 106//999 976//999 2526//999 -f 103//999 979//999 2527//999 -f 97//999 973//999 2528//999 -f 1580//1000 2488//1000 2837//1000 -s 1 -f 2488//87 1580//87 2813//87 -s off -f 1579//1000 2489//1000 2833//1000 -s 1 -f 2489//87 1579//87 2812//87 -s off -f 1578//1000 2490//1000 2835//1000 -s 1 -f 2490//87 1578//87 2814//87 -s off -f 2288//1001 261//1001 331//1001 -s 1 -f 1018//131 3025//131 896//131 -f 1016//131 3026//131 892//131 -s off -f 1099//1002 2374//1002 1097//1002 -s 1 -f 2374//87 1099//87 3028//87 -s off -f 1259//1003 2627//1003 1257//1003 -s 1 -f 1612//87 2627//87 1259//87 -f 1617//87 2630//87 1262//87 -s off -f 1262//1003 2630//1003 1260//1003 -s 1 -f 1609//87 2624//87 1256//87 -s off -f 1256//1003 2624//1003 1254//1003 -s 1 -f 2376//87 3099//87 3029//87 -s off -f 3099//1004 2376//1004 3013//1004 -s 1 -f 2375//87 1102//87 3027//87 -s off -f 1102//1002 2375//1002 1100//1002 -s 1 -f 205//87 2611//87 1595//87 -s off -f 1595//1005 2611//1005 1892//1005 -s 1 -f 619//87 2608//87 1591//87 -s off -f 1591//1005 2608//1005 1890//1005 -f 1588//1005 2605//1005 1888//1005 -s 1 -f 622//87 2605//87 1588//87 -s off -f 3100//1006 518//1006 517//1006 -s 1 -f 3030//131 1365//131 2294//131 -s off -f 990//1007 2303//1007 2973//1007 -s 1 -f 1346//131 1949//131 1925//131 -f 1349//131 1945//131 1924//131 -f 1352//131 1942//131 1926//131 -f 2942//87 1988//87 1599//87 -s off -f 1988//1008 2942//1008 1886//1008 -s 1 -f 2944//87 1990//87 1602//87 -s off -f 1990//1008 2944//1008 1885//1008 -s 1 -f 2941//87 1986//87 1444//87 -s off -f 1986//1008 2941//1008 1887//1008 -s 1 -f 827//131 2362//131 830//131 -s off -f 655//1009 2897//1009 3069//1009 -f 667//1009 2899//1009 3070//1009 -s 1 -f 871//87 885//87 260//87 -s off -f 885//1010 871//1010 2168//1010 -s 1 -f 2038//131 2169//131 2794//131 -s off -f 3101//1011 509//1011 508//1011 -f 2157//1012 2521//1012 2158//1012 -f 3102//1013 41//1013 40//1013 -f 3103//1013 32//1013 31//1013 -f 2516//1014 375//1014 2967//1014 -s 1 -f 375//87 2516//87 1036//87 -s off -f 2518//1014 371//1014 2969//1014 -s 1 -f 371//87 2518//87 1034//87 -f 379//87 2520//87 1035//87 -s off -f 2520//1014 379//1014 2971//1014 -s 1 -f 2593//131 1251//131 2529//131 -f 1632//131 1327//131 1633//131 -f 1884//87 963//87 907//87 -s off -f 907//1015 963//1015 905//1015 -f 904//1015 956//1015 902//1015 -s 1 -f 1881//87 956//87 904//87 -s off -f 910//1015 960//1015 908//1015 -s 1 -f 512//87 960//87 910//87 -f 2282//131 48//131 1083//131 -s off -f 2785//1016 2441//1016 1518//1016 -s 1 -f 2440//87 2441//87 2785//87 -f 943//131 615//131 944//131 -f 189//131 1485//131 2537//131 -f 195//131 1482//131 2536//131 -f 192//131 1488//131 2538//131 -s off -f 1296//1017 1878//1017 3005//1017 -s 1 -f 1878//87 1296//87 1519//87 -f 1636//131 1445//131 2841//131 -f 898//131 1693//131 2884//131 -f 894//131 1696//131 2883//131 -s off -f 3104//1018 2524//1018 3105//1018 -s 1 -f 2524//87 3104//87 673//87 -f 2070//87 1610//87 2232//87 -s off -f 2232//1019 1610//1019 2230//1019 -s 1 -f 2072//87 1615//87 2238//87 -s off -f 2238//1019 1615//1019 2236//1019 -f 2235//1019 1613//1019 2233//1019 -s 1 -f 2068//87 1613//87 2235//87 -f 506//131 1522//131 1524//131 -f 1923//131 759//131 593//131 -f 668//87 2751//87 711//87 -s off -f 711//1020 2751//1020 2750//1020 -s 1 -f 656//87 2453//87 715//87 -s off -f 715//1020 2453//1020 2452//1020 -s 1 -f 500//87 380//87 498//87 -s off -f 380//1021 500//1021 1791//1021 -s 1 -f 483//87 372//87 481//87 -s off -f 372//1021 483//1021 1785//1021 -f 376//1021 486//1021 1787//1021 -s 1 -f 486//87 376//87 487//87 -s off -f 913//1022 1589//1022 911//1022 -s 1 -f 2144//87 1589//87 913//87 -s off -f 916//1022 1592//1022 914//1022 -s 1 -f 2143//87 1592//87 916//87 -f 2142//87 1594//87 919//87 -s off -f 919//1022 1594//1022 917//1022 -f 171//263 1581//263 930//263 -f 174//263 1531//263 929//263 -f 167//263 1534//263 931//263 -s 1 -f 65//131 1138//131 62//131 -f 71//131 1137//131 80//131 -s off -f 686//1023 1460//1023 2913//1023 -s 1 -f 83//131 1136//131 92//131 -s off -f 687//1023 1457//1023 2915//1023 -f 694//1023 1454//1023 2914//1023 -s 1 -f 1461//131 1224//131 3031//131 -f 1462//131 1227//131 3032//131 -f 1906//131 2552//131 183//131 -s off -f 3094//1024 2313//1024 3093//1024 -s 1 -f 2313//87 3094//87 793//87 -f 1499//131 1133//131 59//131 -f 1497//131 1134//131 77//131 -f 932//131 1526//131 1528//131 -s off -f 2749//1025 700//1025 699//1025 -s 1 -f 54//131 1393//131 2108//131 -f 49//131 1397//131 2110//131 -s off -f 2384//1026 54//1026 2179//1026 -f 2382//1026 49//1026 2177//1026 -f 2036//1027 1184//1027 1620//1027 -s 1 -f 2401//87 72//87 2770//87 -s off -f 2770//1028 72//1028 933//1028 -s 1 -f 2397//87 84//87 2774//87 -s off -f 2774//1028 84//1028 932//1028 -f 2773//1028 66//1028 934//1028 -s 1 -f 2399//87 66//87 2773//87 -s off -f 1468//1029 3106//1029 2490//1029 -f 1471//1030 3107//1030 2488//1030 -f 1465//1030 3108//1030 2489//1030 -f 23//1031 2411//1031 21//1031 -f 3052//1031 2347//1031 3109//1031 -s 1 -f 1280//131 178//131 2708//131 -s off -f 2525//1032 3105//1032 2524//1032 -s 1 -f 1554//131 510//131 1555//131 -f 1548//131 1882//131 1549//131 -f 1550//131 1879//131 1551//131 -f 1600//131 2550//131 469//131 -f 1597//131 2549//131 472//131 -f 1442//131 2465//131 466//131 -f 2777//131 808//131 1032//131 -s off -f 593//1033 928//1033 927//1033 -s 1 -f 889//131 2823//131 890//131 -f 887//131 2822//131 888//131 -f 2935//87 2743//87 1560//87 -s off -f 1560//1034 2743//1034 2885//1034 -f 2437//1035 1095//1035 1094//1035 -f 2433//1035 1092//1035 1091//1035 -f 2435//1035 1089//1035 1088//1035 -s 1 -f 2169//131 1320//131 2793//131 -f 990//131 1827//131 12//131 -f 1420//131 83//131 92//131 -f 1424//131 71//131 80//131 -f 1198//131 65//131 62//131 -f 574//131 2403//131 122//131 -f 571//131 2404//131 118//131 -f 568//131 2402//131 114//131 -s off -f 2258//1036 592//1036 2733//1036 -f 2293//1037 144//1037 2855//1037 -s 1 -f 2541//87 144//87 2293//87 -s off -f 2291//1037 147//1037 2857//1037 -s 1 -f 2544//87 147//87 2291//87 -f 2467//131 1563//131 2163//131 -f 2469//131 1564//131 2164//131 -f 2170//131 6//131 2171//131 -s off -f 2617//1038 105//1038 111//1038 -f 2619//1038 96//1038 115//1038 -f 2621//1038 102//1038 119//1038 -f 1979//1039 1221//1039 1249//1039 -f 959//1040 129//1040 157//1040 -s 1 -f 132//87 129//87 959//87 -s off -f 955//1040 123//1040 153//1040 -s 1 -f 126//87 123//87 955//87 -f 138//87 135//87 966//87 -s off -f 966//1040 135//1040 164//1040 -f 673//1041 141//1041 402//1041 -s 1 -f 42//87 141//87 673//87 -s off -f 793//1041 150//1041 406//1041 -s 1 -f 22//87 150//87 793//87 -f 174//131 1769//131 201//131 -f 167//131 1771//131 609//131 -f 171//131 2464//131 612//131 -s off -f 1952//1042 795//1042 791//1042 -f 1955//1042 799//1042 798//1042 -s 1 -f 1736//131 1288//131 1737//131 -f 1728//131 1285//131 1729//131 -f 1734//131 1291//131 1732//131 -s off -f 542//1043 3110//1043 540//1043 -f 1366//1044 1333//1044 2471//1044 -f 789//1045 2709//1045 2937//1045 -f 790//1046 2710//1046 2936//1046 -f 362//1047 3111//1047 2766//1047 -f 365//1047 3112//1047 2767//1047 -f 359//1047 3113//1047 2768//1047 -f 2876//1048 288//1048 2365//1048 -s 1 -f 288//87 2876//87 1907//87 -f 294//87 2877//87 1909//87 -s off -f 2877//1048 294//1048 2364//1048 -s 1 -f 540//87 2345//87 544//87 -s off -f 2345//1049 540//1049 2887//1049 -f 1174//1050 3096//1050 1128//1050 -f 1175//1050 3095//1050 1130//1050 -f 2585//1051 1585//1051 2576//1051 -s 1 -f 2437//131 1406//131 1095//131 -f 2433//131 1405//131 1092//131 -f 2435//131 1404//131 1089//131 -f 1481//131 2809//131 2540//131 -f 1473//131 2807//131 2543//131 -s off -f 1094//1052 2438//1052 2437//1052 -s 1 -f 2438//87 1094//87 1093//87 -s off -f 1091//1052 2434//1052 2433//1052 -s 1 -f 2434//87 1091//87 1090//87 -f 2436//87 1088//87 1087//87 -s off -f 1088//1052 2436//1052 2435//1052 -f 858//1053 1292//1053 856//1053 -s 1 -f 1292//87 858//87 2270//87 -f 1850//131 2363//131 292//131 -f 1847//131 1267//131 286//131 -f 2085//131 2446//131 1606//131 -s off -f 2184//1054 1212//1054 954//1054 -s 1 -f 1819//131 1804//131 1098//131 -f 1821//131 1800//131 1101//131 -f 1823//131 1802//131 3021//131 -s off -f 999//1055 2820//1055 1624//1055 -s 1 -f 2820//87 999//87 2821//87 -f 445//87 988//87 448//87 -s off -f 448//1056 988//1056 1575//1056 -f 454//1056 989//1056 1571//1056 -s 1 -f 451//87 989//87 454//87 -f 457//87 987//87 460//87 -s off -f 460//1056 987//1056 2219//1056 -s 1 -f 2893//131 1295//131 2808//131 -f 1308//131 1307//131 1789//131 -f 1314//131 1313//131 1784//131 -f 1311//131 1310//131 1790//131 -f 2892//131 1294//131 2810//131 -s off -f 1967//1057 1965//1057 2644//1057 -s 1 -f 306//87 2535//87 338//87 -s off -f 2535//1058 306//1058 2977//1058 -f 2534//1058 312//1058 2975//1058 -s 1 -f 312//87 2534//87 344//87 -f 2303//131 990//131 12//131 -s off -f 2788//1059 1186//1059 1318//1059 -s 1 -f 1583//87 1186//87 2788//87 -s off -f 1569//1060 2430//1060 1567//1060 -s 1 -f 2430//87 1569//87 2879//87 -s off -f 1584//1061 15//1061 17//1061 -f 2062//1062 2655//1062 2958//1062 -f 2060//1062 2661//1062 2956//1062 -f 2058//1062 2658//1062 2955//1062 -f 2481//1063 441//1063 440//1063 -s 1 -f 1534//131 424//131 2687//131 -f 1531//131 418//131 2688//131 -f 1581//131 412//131 2689//131 -f 2729//131 2029//131 938//131 -f 2731//131 2032//131 937//131 -f 1453//131 2851//131 1285//131 -f 1459//131 2853//131 1291//131 -f 1456//131 2852//131 1288//131 -f 1774//131 2378//131 2786//131 -f 1954//131 1962//131 2802//131 -f 1951//131 1964//131 2801//131 -s off -f 3091//1064 2685//1064 3008//1064 -f 3092//1064 2683//1064 3006//1064 -f 2570//1065 627//1065 2858//1065 -f 1423//1066 71//1066 70//1066 -f 1829//1065 642//1065 2863//1065 -f 2574//1065 630//1065 2861//1065 -f 194//1067 2677//1067 192//1067 -s 1 -f 245//87 2677//87 194//87 -f 241//87 2679//87 191//87 -s off -f 191//1067 2679//1067 189//1067 -f 2318//1066 65//1066 64//1066 -s 1 -f 249//87 2673//87 197//87 -s off -f 197//1067 2673//1067 195//1067 -f 1422//1066 83//1066 82//1066 -f 232//1068 2357//1068 1052//1068 -s 1 -f 2357//87 232//87 234//87 -f 1652//131 2760//131 515//131 -f 979//131 103//131 980//131 -f 976//131 106//131 977//131 -f 973//131 97//131 974//131 -f 1080//131 2035//131 2803//131 -s off -f 1410//1069 2154//1069 1723//1069 -s 1 -f 1901//131 1468//131 1709//131 -f 1899//131 1465//131 1703//131 -f 1903//131 1471//131 1706//131 -s off -f 1688//1070 1653//1070 946//1070 -s 1 -f 2389//131 941//131 1361//131 -f 2426//87 81//87 2651//87 -s off -f 2651//1071 81//1071 169//1071 -f 2649//1071 63//1071 176//1071 -s 1 -f 2422//87 63//87 2649//87 -f 2424//87 69//87 2653//87 -s off -f 2653//1071 69//1071 165//1071 -f 2373//1072 2372//1072 2589//1072 -s 1 -f 323//87 2377//87 1321//87 -s off -f 2377//1073 323//1073 322//1073 -f 2371//1072 2370//1072 2588//1072 -f 3114//1074 236//1074 235//1074 -f 702//1075 247//1075 246//1075 -f 708//1075 251//1075 250//1075 -f 705//1075 243//1075 242//1075 -f 1640//1076 1775//1076 1774//1076 -s 1 -f 1639//87 1775//87 1640//87 -s off -f 1391//1077 503//1077 2999//1077 -s 1 -f 2506//87 503//87 1391//87 -s off -f 1389//1077 476//1077 2998//1077 -s 1 -f 2505//87 476//87 1389//87 -s off -f 1844//1078 2451//1078 2582//1078 -f 2665//1079 576//1079 575//1079 -s 1 -f 101//87 576//87 2665//87 -s off -f 2666//1079 570//1079 569//1079 -s 1 -f 110//87 570//87 2666//87 -s off -f 2669//1079 573//1079 572//1079 -s 1 -f 95//87 573//87 2669//87 -f 2299//87 2752//87 1021//87 -s off -f 1021//1080 2752//1080 1685//1080 -f 1351//1081 1122//1081 1121//1081 -f 1348//1082 1127//1082 1126//1082 -f 1345//1082 994//1082 1124//1082 -s 1 -f 1739//131 949//131 1132//131 -s off -f 2309//1083 318//1083 2645//1083 -f 2708//1084 395//1084 397//1084 -s 1 -f 2717//131 1788//131 362//131 -f 2718//131 1786//131 359//131 -f 2719//131 1792//131 365//131 -f 412//131 1582//131 2012//131 -f 418//131 1530//131 2000//131 -f 424//131 1537//131 2015//131 -s off -f 1107//1085 415//1085 414//1085 -f 1169//1085 421//1085 420//1085 -f 1154//1085 427//1085 426//1085 -f 2045//1086 1435//1086 2044//1086 -f 2042//1087 1441//1087 2040//1087 -f 47//1088 2598//1088 1083//1088 -s 1 -f 2598//87 47//87 45//87 -s off -f 2386//1089 1624//1089 2820//1089 -s 1 -f 795//131 1952//131 1491//131 -f 799//131 1955//131 1493//131 -f 1432//87 2254//87 2287//87 -s off -f 2254//1090 1432//1090 1701//1090 -s 1 -f 1495//87 2252//87 2286//87 -s off -f 2252//1090 1495//1090 1692//1090 -f 2123//1091 1253//1091 2350//1091 -f 863//1092 2562//1092 2753//1092 -s 1 -f 3079//87 2562//87 863//87 -s off -f 1598//1093 2618//1093 2943//1093 -f 1601//1093 2620//1093 2945//1093 -f 1443//1093 2616//1093 2940//1093 -s 1 -f 3080//87 2563//87 862//87 -s off -f 862//1094 2563//1094 2754//1094 -s 1 -f 1445//131 542//131 2841//131 -f 2924//131 2502//131 667//131 -f 2925//131 2504//131 655//131 -f 2188//131 1243//131 1111//131 -f 2317//131 1282//131 1115//131 -f 2185//131 1242//131 1119//131 -s off -f 369//1095 226//1095 225//1095 -f 2690//1096 2952//1096 1020//1096 -s 1 -f 939//131 2728//131 1234//131 -f 935//131 2730//131 1236//131 -f 2448//87 218//87 2449//87 -s off -f 2449//1097 218//1097 1687//1097 -f 803//1098 39//1098 2554//1098 -s 1 -f 39//87 803//87 1011//87 -s off -f 806//1098 30//1098 2553//1098 -s 1 -f 30//87 806//87 1009//87 -s off -f 1726//1099 158//1099 484//1099 -f 2280//1099 161//1099 493//1099 -f 2279//1100 154//1100 485//1100 -f 1997//1101 1335//1101 1334//1101 -s 1 -f 2682//87 1335//87 1997//87 -s off -f 2022//1102 1903//1102 2021//1102 -f 2028//1103 1899//1103 2027//1103 -f 2025//1103 1901//1103 2023//1103 -f 1931//1104 2487//1104 2776//1104 -s 1 -f 809//87 2487//87 1931//87 -f 1351//131 1182//131 1122//131 -f 1348//131 1183//131 1127//131 -f 1345//131 995//131 994//131 -f 319//131 1965//131 1967//131 -f 1506//87 1020//87 2351//87 -s off -f 2351//1105 1020//1105 2952//1105 -f 2817//1106 1874//1106 1619//1106 -f 1404//1107 1864//1107 1862//1107 -f 1406//1107 1866//1107 1865//1107 -f 1405//1107 1861//1107 1859//1107 -s 1 -f 1128//87 1062//87 719//87 -s off -f 719//1108 1062//1108 1061//1108 -s 1 -f 1130//87 1059//87 724//87 -s off -f 724//1108 1059//1108 1058//1108 -s 1 -f 2371//131 557//131 559//131 -f 2373//131 566//131 562//131 -s off -f 968//1109 2207//1109 2204//1109 -s 1 -f 279//87 272//87 607//87 -s off -f 607//1110 272//1110 605//1110 -s 1 -f 1700//131 2741//131 2764//131 -f 1691//131 2740//131 2763//131 -f 138//87 493//87 135//87 -s off -f 493//1111 138//1111 2280//1111 -f 484//1112 132//1112 1726//1112 -s 1 -f 132//87 484//87 129//87 -f 126//87 485//87 123//87 -s off -f 485//1111 126//1111 2279//1111 -s 1 -f 759//131 928//131 593//131 -f 1278//131 158//131 1726//131 -f 1271//131 161//131 2280//131 -f 1274//131 154//131 2279//131 -s off -f 1586//1113 2726//1113 2839//1113 -s 1 -f 1080//131 2803//131 1081//131 -f 1910//131 1220//131 2364//131 -f 1908//131 1217//131 2365//131 -f 2693//131 701//131 2849//131 -f 2692//131 707//131 2848//131 -f 2694//131 704//131 2850//131 -f 2115//87 629//87 2118//87 -s off -f 2118//1114 629//1114 628//1114 -s 1 -f 2113//87 644//87 2114//87 -s off -f 2114//1114 644//1114 643//1114 -f 2121//1115 632//1115 631//1115 -s 1 -f 2120//87 632//87 2121//87 -f 2445//131 1085//131 2739//131 -f 1922//131 592//131 2258//131 -s off -f 2762//1116 1773//1116 2227//1116 -f 2659//1117 568//1117 635//1117 -f 2662//1117 571//1117 633//1117 -f 2656//1118 574//1118 634//1118 -s 1 -f 1777//131 1585//131 2585//131 -s off -f 302//1119 782//1119 781//1119 -s 1 -f 1522//131 1000//131 1523//131 -s off -f 2485//1120 1567//1120 2430//1120 -s 1 -f 2338//131 1657//131 2870//131 -f 2340//131 1659//131 2872//131 -f 442//87 2784//87 2482//87 -s off -f 2784//1121 442//1121 800//1121 -s 1 -f 529//87 1376//87 526//87 -s off -f 526//1122 1376//1122 1554//1122 -f 532//1122 1372//1122 1548//1122 -s 1 -f 535//87 1372//87 532//87 -s off -f 523//1122 1374//1122 1550//1122 -s 1 -f 520//87 1374//87 523//87 -f 96//131 2619//131 748//131 -f 105//131 2617//131 754//131 -f 102//131 2621//131 742//131 -f 308//131 307//131 2256//131 -f 314//131 313//131 2255//131 -s off -f 606//1123 941//1123 2507//1123 -f 404//1124 2818//1124 2193//1124 -f 408//1124 2819//1124 2195//1124 -s 1 -f 2655//131 2062//131 1178//131 -f 2661//131 2060//131 1180//131 -f 2658//131 2058//131 1176//131 -f 1333//131 1366//131 2765//131 -s off -f 184//1125 1361//1125 3085//1125 -f 350//1126 2092//1126 2090//1126 -f 353//1126 2100//1126 2098//1126 -f 356//1126 2095//1126 2094//1126 -s 1 -f 2716//87 747//87 98//87 -s off -f 747//1127 2716//1127 974//1127 -f 753//1128 2715//1128 977//1128 -s 1 -f 2715//87 753//87 107//87 -f 2714//87 741//87 104//87 -s off -f 741//1128 2714//1128 980//1128 -f 1762//1129 2889//1129 2692//1129 -s 1 -f 3043//87 2889//87 1762//87 -s off -f 1764//1129 2890//1129 2693//1129 -s 1 -f 3045//87 2890//87 1764//87 -s off -f 1765//1129 2891//1129 2694//1129 -s 1 -f 3044//87 2891//87 1765//87 -f 613//87 2775//87 2569//87 -s off -f 2775//1130 613//1130 612//1130 -s 1 -f 202//87 2772//87 2573//87 -s off -f 2772//1130 202//1130 201//1130 -s 1 -f 610//87 2771//87 2566//87 -s off -f 2771//1130 610//1130 609//1130 -f 1293//1131 856//1131 1292//1131 -s 1 -f 7//87 2431//87 5//87 -s off -f 2431//1132 7//1132 14//1132 -s 1 -f 795//131 1491//131 577//131 -f 799//131 1493//131 580//131 -f 1930//87 1605//87 2301//87 -s off -f 2301//1133 1605//1133 1604//1133 -f 2414//1134 1330//1134 2682//1134 -s 1 -f 2709//131 789//131 648//131 -f 2710//131 790//131 651//131 -f 1544//131 1540//131 1542//131 -s off -f 590//1135 2776//1135 2487//1135 -f 3109//1136 42//1136 3052//1136 -s 1 -f 42//87 3109//87 1014//87 -s off -f 466//1137 1300//1137 2842//1137 -f 472//1137 1303//1137 2845//1137 -f 469//1137 1306//1137 2846//1137 -f 2667//1138 1612//1138 1671//1138 -s 1 -f 1612//87 2667//87 2627//87 -f 1609//87 2664//87 2624//87 -s off -f 2664//1139 1609//1139 1663//1139 -s 1 -f 1617//87 2668//87 2630//87 -s off -f 2668//1138 1617//1138 1667//1138 -f 2206//1140 224//1140 2311//1140 -s 1 -f 2205//87 224//87 2206//87 -f 1639//87 2927//87 1775//87 -s off -f 2927//1141 1639//1141 2786//1141 -f 279//1142 2508//1142 972//1142 -s 1 -f 2508//87 279//87 607//87 -s off -f 2650//1143 205//1143 204//1143 -s 1 -f 205//87 2650//87 2611//87 -f 619//87 2654//87 2608//87 -s off -f 2654//1143 619//1143 618//1143 -s 1 -f 622//87 2652//87 2605//87 -s off -f 2652//1143 622//1143 621//1143 -f 1767//1144 2391//1144 1408//1144 -s 1 -f 2880//87 2391//87 1767//87 -s off -f 2103//1145 334//1145 333//1145 -f 2222//1146 2088//1146 2087//1146 -s 1 -f 2088//87 2222//87 273//87 -f 1458//131 1460//131 686//131 -f 1455//131 1457//131 687//131 -f 1452//131 1454//131 694//131 -s off -f 1684//1147 967//1147 3019//1147 -s 1 -f 1682//131 2332//131 968//131 -f 1687//131 1653//131 1688//131 -s off -f 857//1148 2450//1148 2447//1148 -s 1 -f 627//131 2570//131 206//131 -f 630//131 2574//131 212//131 -f 642//131 1829//131 645//131 -f 1629//131 247//131 702//131 -f 1626//131 251//131 708//131 -f 1628//131 243//131 705//131 -s off -f 48//1149 2798//1149 46//1149 -f 2551//1150 9//1150 8//1150 -f 2054//1151 2272//1151 2271//1151 -f 146//1152 2854//1152 144//1152 -f 149//1152 2856//1152 147//1152 -f 2815//1153 1914//1153 1635//1153 -s 1 -f 1//87 1914//87 2815//87 -s off -f 1774//1154 2591//1154 1640//1154 -s 1 -f 2767//87 497//87 693//87 -s off -f 693//1155 497//1155 691//1155 -f 685//1155 488//1155 683//1155 -s 1 -f 2766//87 488//87 685//87 -f 2768//87 480//87 690//87 -s off -f 690//1155 480//1155 688//1155 -f 1654//1156 223//1156 222//1156 -f 1207//1157 2337//1157 2276//1157 -f 1204//1158 2339//1158 2278//1158 -f 2878//1159 240//1159 2432//1159 -f 2866//1160 2296//1160 2867//1160 -f 2117//1161 1828//1161 2115//1161 -f 2122//1161 1096//1161 2120//1161 -f 1515//1161 1516//1161 2113//1161 -s 1 -f 2128//87 2093//87 1897//87 -s off -f 1897//1162 2093//1162 1839//1162 -f 1896//1162 2091//1162 1809//1162 -s 1 -f 2131//87 2091//87 1896//87 -s off -f 1898//1163 2099//1163 1841//1163 -s 1 -f 2134//87 2099//87 1898//87 -s off -f 1776//1164 2577//1164 1799//1164 -s 1 -f 2576//87 2577//87 1776//87 -f 1693//131 1695//131 1076//131 -f 1696//131 1698//131 1038//131 -s off -f 338//1165 309//1165 308//1165 -s 1 -f 2535//87 309//87 338//87 -s off -f 344//1165 315//1165 314//1165 -s 1 -f 2534//87 315//87 344//87 -s off -f 893//1166 1016//1166 1014//1166 -f 2130//1167 1837//1167 2128//1167 -f 2136//1167 1842//1167 2134//1167 -f 2133//1167 1807//1167 2131//1167 -f 978//1168 977//1168 2715//1168 -f 897//1166 1018//1166 674//1166 -f 975//1168 974//1168 2716//1168 -f 981//1168 980//1168 2714//1168 -f 584//1169 536//1169 535//1169 -f 587//1169 521//1169 520//1169 -f 1344//1169 530//1169 529//1169 -s 1 -f 780//87 2350//87 2139//87 -s off -f 2350//1170 780//1170 2123//1170 -f 397//1171 221//1171 2708//1171 -s 1 -f 221//87 397//87 179//87 -s off -f 438//1172 2741//1172 2510//1172 -f 437//1172 2740//1172 2511//1172 -f 725//1173 1398//1173 723//1173 -f 720//1173 1394//1173 718//1173 -f 2953//1174 301//1174 779//1174 -s 1 -f 1106//131 415//131 1107//131 -f 1830//131 421//131 1169//131 -f 2392//131 427//131 1154//131 -s off -f 1956//1175 1011//1175 1954//1175 -s 1 -f 1494//87 1011//87 1956//87 -s off -f 29//1176 3071//1176 27//1176 -f 38//1176 3072//1176 36//1176 -s 1 -f 2389//131 1361//131 184//131 -f 1492//87 1009//87 1953//87 -s off -f 1953//1177 1009//1177 1951//1177 -s 1 -f 1645//131 1148//131 3092//131 -s off -f 1331//1178 2555//1178 2472//1178 -s 1 -f 1642//131 1147//131 3091//131 -s off -f 34//1179 2634//1179 1358//1179 -s 1 -f 405//87 2634//87 34//87 -f 409//87 2633//87 25//87 -s off -f 25//1179 2633//1179 1356//1179 -s 1 -f 350//131 349//131 1566//131 -f 353//131 352//131 2531//131 -f 356//131 355//131 2530//131 -f 514//87 2761//87 517//87 -s off -f 517//1180 2761//1180 3100//1180 -s 1 -f 1225//131 1722//131 651//131 -f 1228//131 1721//131 648//131 -s off -f 2416//1181 1760//1181 2011//1181 -s 1 -f 2618//131 1598//131 1886//131 -f 2620//131 1601//131 1885//131 -f 2616//131 1443//131 1887//131 -f 2523//87 1538//87 2735//87 -s off -f 1538//1182 2523//1182 2522//1182 -f 1042//1183 2182//1183 1863//1183 -f 1045//1183 2181//1183 1860//1183 -f 1048//1183 2180//1183 1867//1183 -f 2428//1184 1447//1184 1413//1184 -s 1 -f 1447//87 2428//87 2229//87 -f 266//87 2044//87 1793//87 -s off -f 1793//1185 2044//1185 1435//1185 -s 1 -f 178//131 395//131 2708//131 -s off -f 2145//1186 1969//1186 1532//1186 -s 1 -f 929//87 1969//87 2145//87 -f 931//87 1960//87 2147//87 -s off -f 2147//1186 1960//1186 1535//1186 -f 2146//1186 1959//1186 1958//1186 -s 1 -f 930//87 1959//87 2146//87 -f 253//87 2040//87 1794//87 -s off -f 1794//1185 2040//1185 1441//1185 -s 1 -f 2545//87 329//87 2948//87 -s off -f 329//1187 2545//1187 2446//1187 -f 2720//1188 46//1188 2798//1188 -s 1 -f 46//87 2720//87 2997//87 -f 1946//87 2932//87 1944//87 -s off -f 1944//1189 2932//1189 2419//1189 -s 1 -f 1950//87 2929//87 1948//87 -s off -f 1948//1189 2929//1189 2418//1189 -s 1 -f 1939//87 2931//87 1940//87 -s off -f 1940//1189 2931//1189 2420//1189 -s 1 -f 2892//131 265//131 1294//131 -f 2893//131 199//131 1295//131 -f 3050//131 1413//131 2612//131 -f 1435//131 2045//131 1003//131 -f 1441//131 2042//131 1006//131 -f 1975//87 2143//87 916//87 -s off -f 2143//1190 1975//1190 1974//1190 -s 1 -f 1978//87 2142//87 919//87 -s off -f 2142//1191 1978//1191 1977//1191 -s 1 -f 1972//87 2144//87 913//87 -s off -f 2144//1191 1972//1191 1971//1191 -s 1 -f 1152//87 1104//87 411//87 -s off -f 411//1192 1104//1192 1106//1192 -s 1 -f 1155//87 1105//87 423//87 -s off -f 423//1192 1105//1192 2392//1192 -f 417//1192 1103//1192 1830//1192 -s 1 -f 1170//87 1103//87 417//87 -s off -f 2843//1193 749//1193 783//1193 -s 1 -f 2406//87 749//87 2843//87 -f 2408//87 743//87 2844//87 -s off -f 2844//1194 743//1194 784//1194 -f 2847//1194 737//1194 785//1194 -s 1 -f 2410//87 737//87 2847//87 -s off -f 2553//1195 804//1195 806//1195 -s 1 -f 1167//87 445//87 448//87 -s off -f 445//1196 1167//1196 2637//1196 -f 451//1196 1165//1196 2635//1196 -s 1 -f 1165//87 451//87 454//87 -s off -f 2554//1197 801//1197 803//1197 -f 457//1196 1166//1196 2636//1196 -s 1 -f 1166//87 457//87 460//87 -s off -f 2159//1198 271//1198 270//1198 -f 2161//1199 257//1199 256//1199 -f 808//1200 1501//1200 2486//1200 -f 1281//1201 537//1201 2270//1201 -f 1627//1202 2694//1202 2891//1202 -f 1625//1202 2692//1202 2889//1202 -f 1630//1202 2693//1202 2890//1202 -f 2304//1203 3//1203 2//1203 -s 1 -f 1799//131 2726//131 1586//131 -s off -f 1741//1204 947//1204 1739//1204 -s 1 -f 2156//87 947//87 1741//87 -s off -f 1869//1205 2602//1205 273//1205 -s 1 -f 1157//131 1159//131 2590//131 -f 405//87 2193//87 2634//87 -s off -f 2193//1206 405//1206 404//1206 -f 2195//1207 409//1207 408//1207 -s 1 -f 409//87 2195//87 2633//87 -s off -f 1264//1208 1426//1208 3039//1208 -f 1265//1208 1429//1208 3038//1208 -s 1 -f 2332//131 2207//131 968//131 -s off -f 2918//1209 10//1209 1827//1209 -s 1 -f 10//87 2918//87 336//87 -s off -f 1263//1210 1687//1210 218//1210 -s 1 -f 2598//87 45//87 2584//87 -s off -f 2584//1211 45//1211 1082//1211 -f 2786//1212 1401//1212 2927//1212 -s 1 -f 507//87 1328//87 1209//87 -s off -f 1209//1213 1328//1213 1327//1213 -s 1 -f 2593//131 2529//131 1541//131 -f 2406//87 1112//87 749//87 -s off -f 1112//1214 2406//1214 2405//1214 -f 1116//1214 2410//1214 2409//1214 -s 1 -f 2410//87 1116//87 737//87 -s off -f 1108//1214 2408//1214 2407//1214 -s 1 -f 2408//87 1108//87 743//87 -f 1812//87 2478//87 2190//87 -s off -f 2190//1215 2478//1215 2188//1215 -s 1 -f 1815//87 2477//87 2187//87 -s off -f 2187//1215 2477//1215 2185//1215 -f 2341//1215 2479//1215 2317//1215 -s 1 -f 1818//87 2479//87 2341//87 -s off -f 805//1216 2789//1216 2505//1216 -s 1 -f 568//131 2659//131 2402//131 -f 571//131 2662//131 2404//131 -s off -f 802//1216 2791//1216 2506//1216 -s 1 -f 574//131 2656//131 2403//131 -f 624//87 558//87 2588//87 -s off -f 2588//1217 558//1217 557//1217 -s 1 -f 625//87 567//87 2589//87 -s off -f 2589//1217 567//1217 566//1217 -s 1 -f 780//87 2139//87 1019//87 -s off -f 1019//1218 2139//1218 2138//1218 -f 2361//1219 543//1219 1445//1219 -s 1 -f 2980//87 543//87 2361//87 -s off -f 1183//1220 1350//1220 1992//1220 -f 1182//1220 1353//1220 1993//1220 -f 995//1220 1347//1220 1991//1220 -f 505//1221 2821//1221 1522//1221 -s 1 -f 2387//87 2821//87 505//87 -s off -f 213//1222 2392//1222 1105//1222 -f 646//1222 1830//1222 1103//1222 -f 207//1222 1106//1222 1104//1222 -s 1 -f 594//87 1160//87 761//87 -s off -f 761//1223 1160//1223 759//1223 -f 88//1224 2397//1224 2396//1224 -s 1 -f 2397//87 88//87 84//87 -s off -f 76//1224 2401//1224 2400//1224 -s 1 -f 2401//87 76//87 72//87 -s off -f 58//1224 2399//1224 2398//1224 -s 1 -f 2399//87 58//87 66//87 -s off -f 2681//1225 241//1225 2537//1225 -s 1 -f 241//87 2681//87 2679//87 -f 245//87 2676//87 2677//87 -s off -f 2676//1225 245//1225 2538//1225 -s 1 -f 249//87 2675//87 2673//87 -s off -f 2675//1225 249//1225 2536//1225 -f 210//1226 2636//1226 1166//1226 -f 602//1226 2635//1226 1165//1226 -f 216//1226 2637//1226 1167//1226 -f 2840//1227 1322//1227 1321//1227 -f 2765//1228 321//1228 335//1228 -s 1 -f 435//131 1362//131 2923//131 -f 432//131 583//131 2921//131 -f 429//131 586//131 2922//131 -f 783//131 1377//131 1299//131 -f 1378//131 1380//131 1305//131 -f 1381//131 1383//131 1302//131 -f 2205//87 779//87 224//87 -s off -f 779//1229 2205//1229 2953//1229 -f 1101//1230 140//1230 139//1230 -f 2173//1231 1886//1231 2942//1231 -f 2175//1231 1885//1231 2944//1231 -f 1098//1230 128//1230 127//1230 -f 2174//1231 1887//1231 2941//1231 -f 1833//1232 1941//1232 1352//1232 -s 1 -f 1993//87 1941//87 1833//87 -f 1992//87 1943//87 1832//87 -s off -f 1832//1232 1943//1232 1349//1232 -s 1 -f 1991//87 1947//87 1831//87 -s off -f 1831//1232 1947//1232 1346//1232 -s 1 -f 2181//131 1045//131 2080//131 -f 2182//131 1042//131 2081//131 -f 2180//131 1048//131 2079//131 -s off -f 79//1233 2424//1233 1425//1233 -s 1 -f 2424//87 79//87 69//87 -f 2422//87 61//87 63//87 -s off -f 61//1233 2422//1233 1199//1233 -s 1 -f 2426//87 91//87 81//87 -s off -f 91//1233 2426//1233 1421//1233 -f 429//1234 2420//1234 2931//1234 -f 435//1234 2418//1234 2929//1234 -f 432//1235 2419//1235 2932//1235 -f 1825//1236 229//1236 228//1236 -f 2575//1237 3013//1237 2376//1237 -f 1185//1238 1318//1238 1186//1238 -f 785//1239 1304//1239 2847//1239 -f 784//1239 1301//1239 2844//1239 -f 849//1240 2083//1240 847//1240 -s 1 -f 1927//87 2083//87 849//87 -s off -f 1489//1241 2073//1241 2072//1241 -f 1483//1241 2071//1241 2070//1241 -f 1486//1241 2069//1241 2068//1241 -f 2804//1242 2197//1242 253//1242 -f 2805//1243 2200//1243 266//1243 -f 2901//1244 739//1244 738//1244 -f 2902//1244 745//1244 744//1244 -f 498//1245 1312//1245 1311//1245 -s 1 -f 380//87 1312//87 498//87 -f 372//87 1315//87 481//87 -s off -f 481//1245 1315//1245 1314//1245 -s 1 -f 376//87 1309//87 487//87 -s off -f 487//1245 1309//1245 1308//1245 -s 1 -f 613//87 2569//87 172//87 -s off -f 172//1246 2569//1246 170//1246 -f 175//1246 2573//1246 173//1246 -s 1 -f 202//87 2573//87 175//87 -f 610//87 2566//87 168//87 -s off -f 168//1246 2566//1246 166//1246 -s 1 -f 1513//131 1515//131 2319//131 -f 2483//131 2122//131 2321//131 -f 2484//131 2117//131 2320//131 -f 1316//131 2481//131 800//131 -f 3084//131 2130//131 1500//131 -f 3083//131 2136//131 1498//131 -s off -f 2939//1247 1603//1247 757//1247 -s 1 -f 2464//131 1529//131 2963//131 -f 1//87 239//87 11//87 -s off -f 11//1248 239//1248 238//1248 -f 1999//1249 2934//1249 1562//1249 -f 2792//1250 2075//1250 37//1250 -f 2790//1250 2074//1250 28//1250 -s 1 -f 1630//131 1629//131 702//131 -f 1625//131 1626//131 708//131 -f 1627//131 1628//131 705//131 -s off -f 55//1251 1396//1251 2909//1251 -s 1 -f 1016//131 893//131 3026//131 -s off -f 50//1252 1400//1252 2910//1252 -s 1 -f 1018//131 897//131 3025//131 -s off -f 2744//1253 275//1253 879//1253 -s 1 -f 275//87 2744//87 616//87 -f 2272//131 2450//131 857//131 -f 2058//131 978//131 1176//131 -f 2060//131 975//131 1180//131 -f 2062//131 981//131 1178//131 -f 27//87 869//87 3000//87 -s off -f 869//1254 27//1254 3071//1254 -s 1 -f 36//87 867//87 3001//87 -s off -f 867//1254 36//1254 3072//1254 -s 1 -f 1279//131 223//131 1654//131 -f 2776//131 590//131 808//131 -f 1196//131 2717//131 362//131 -f 1193//131 2719//131 365//131 -f 1190//131 2718//131 359//131 -f 2465//131 1300//131 466//131 -f 2550//131 1306//131 469//131 -f 2549//131 1303//131 472//131 -s off -f 117//1255 95//1255 94//1255 -s 1 -f 95//87 117//87 573//87 -s off -f 121//1255 101//1255 100//1255 -s 1 -f 101//87 121//87 576//87 -s off -f 113//1255 110//1255 109//1255 -s 1 -f 110//87 113//87 570//87 -s off -f 3028//1256 2493//1256 2557//1256 -s 1 -f 1099//87 2493//87 3028//87 -s off -f 3029//1256 2491//1256 2561//1256 -s 1 -f 3099//87 2491//87 3029//87 -f 1102//87 2495//87 3027//87 -s off -f 3027//1256 2495//1256 2559//1256 -f 1908//1257 1267//1257 953//1257 -f 1279//1258 220//1258 219//1258 -s 1 -f 2170//131 9//131 2551//131 -f 2727//87 4//87 2458//87 -s off -f 2458//1259 4//1259 2170//1259 -f 1985//1260 2466//1260 2465//1260 -s 1 -f 467//87 2466//87 1985//87 -f 470//87 2705//87 1989//87 -s off -f 1989//1260 2705//1260 2550//1260 -s 1 -f 473//87 2706//87 1987//87 -s off -f 1987//1260 2706//1260 2549//1260 -f 851//1261 2356//1261 2631//1261 -f 854//1261 2354//1261 2632//1261 -f 942//1262 972//1262 2508//1262 -s 1 -f 240//131 2878//131 1266//131 -f 2104//131 2295//131 2105//131 -s off -f 1004//1263 1428//1263 2056//1263 -f 1007//1263 1431//1263 2057//1263 -s 1 -f 2435//131 1864//131 1404//131 -f 2437//131 1866//131 1406//131 -f 2433//131 1861//131 1405//131 -s off -f 1213//1078 2500//1078 2581//1078 -s 1 -f 1683//131 967//131 1684//131 -s off -f 2179//1264 2385//1264 2384//1264 -s 1 -f 2178//87 2385//87 2179//87 -s off -f 2177//1265 2383//1265 2382//1265 -s 1 -f 2176//87 2383//87 2177//87 -s off -f 735//1266 1522//1266 2821//1266 -f 2777//1267 1933//1267 1931//1267 -s 1 -f 528//87 2702//87 1376//87 -s off -f 2702//1268 528//1268 1555//1268 -f 2697//1268 534//1268 1549//1268 -s 1 -f 534//87 2697//87 1372//87 -f 519//87 2700//87 1374//87 -s off -f 2700//1268 519//1268 1551//1268 -f 2517//1269 1286//1269 1736//1269 -s 1 -f 823//87 1286//87 2517//87 -f 817//87 1289//87 2515//87 -s off -f 2515//1269 1289//1269 1734//1269 -f 2519//1269 1284//1269 1728//1269 -s 1 -f 820//87 1284//87 2519//87 -s off -f 950//1270 179//1270 178//1270 -s 1 -f 221//87 179//87 950//87 -f 2054//131 1686//131 2450//131 -s off -f 3051//1271 2086//1271 278//1271 -f 760//1272 2691//1272 761//1272 -s 1 -f 2591//131 1774//131 2786//131 -s off -f 1880//1273 1273//1273 1373//1273 -f 511//1273 1277//1273 1375//1273 -f 1883//1273 1270//1273 1371//1273 -f 3046//1274 1325//1274 2222//1274 -s 1 -f 2762//131 1050//131 1052//131 -f 930//87 2826//87 411//87 -s off -f 2826//1275 930//1275 1581//1275 -s 1 -f 929//87 2832//87 417//87 -s off -f 2832//1275 929//1275 1531//1275 -s 1 -f 931//87 2829//87 423//87 -s off -f 2829//1275 931//1275 1534//1275 -f 2155//1276 1132//1276 2281//1276 -f 2210//1277 2245//1277 2851//1277 -s 1 -f 1283//87 2245//87 2210//87 -s off -f 2216//1277 2243//1277 2853//1277 -s 1 -f 1290//87 2243//87 2216//87 -f 1287//87 2241//87 2213//87 -s off -f 2213//1277 2241//1277 2852//1277 -s 1 -f 533//131 536//131 584//131 -f 524//131 521//131 587//131 -f 527//131 530//131 1344//131 -f 1561//131 2167//131 2310//131 -s off -f 792//1278 794//1278 1149//1278 -s 1 -f 791//87 794//87 792//87 -s off -f 2759//1279 2166//1279 2369//1279 -f 2758//1279 2165//1279 2367//1279 -f 1510//1280 2984//1280 1509//1280 -s 1 -f 2984//87 1510//87 2023//87 -f 2986//87 1508//87 2021//87 -s off -f 1508//1280 2986//1280 1507//1280 -f 1512//1280 2982//1280 1511//1280 -s 1 -f 2982//87 1512//87 2027//87 -f 1397//131 1399//131 2110//131 -f 1393//131 1395//131 2108//131 -f 2648//87 1995//87 1997//87 -s off -f 1995//1281 2648//1281 2647//1281 -s 1 -f 2619//131 1886//131 2173//131 -f 2621//131 1885//131 2175//131 -f 2617//131 1887//131 2174//131 -s off -f 228//1282 1826//1282 1825//1282 -s 1 -f 1826//87 228//87 336//87 -s off -f 3006//1283 1678//1283 3092//1283 -s 1 -f 1678//87 3006//87 3007//87 -f 1681//87 3008//87 3009//87 -s off -f 3008//1284 1681//1284 3091//1284 -f 971//1285 2248//1285 2599//1285 -f 3018//1286 1780//1286 1846//1286 -s 1 -f 1780//87 3018//87 2335//87 -s off -f 3017//1287 1783//1287 1849//1287 -s 1 -f 1783//87 3017//87 1214//87 -f 2570//131 207//131 206//131 -f 2939//131 1293//131 1929//131 -f 1829//131 646//131 645//131 -s off -f 1074//1288 2864//1288 1075//1288 -s 1 -f 2574//131 213//131 212//131 -s off -f 1451//1289 2276//1289 2337//1289 -s 1 -f 2010//87 2276//87 1451//87 -s off -f 1449//1289 2278//1289 2339//1289 -s 1 -f 2007//87 2278//87 1449//87 -f 1477//131 1480//131 1478//131 -f 1475//131 1472//131 1474//131 -f 1334//131 2555//131 1331//131 -f 1664//131 2073//131 1489//131 -f 1668//131 2069//131 1486//131 -f 1660//131 2071//131 1483//131 -f 2220//131 620//131 3010//131 -f 2218//131 617//131 3011//131 -f 2217//131 203//131 3012//131 -f 1544//131 1542//131 1545//131 -f 1853//131 271//131 1854//131 -f 1856//131 257//131 1857//131 -f 2476//87 1557//87 1796//87 -s off -f 1796//1290 1557//1290 1067//1290 -f 1798//1290 1556//1290 1070//1290 -s 1 -f 2474//87 1556//87 1798//87 -s off -f 2760//1291 3100//1291 2761//1291 -s 1 -f 435//131 434//131 1362//131 -f 429//131 428//131 586//131 -f 432//131 431//131 583//131 -f 2476//87 1450//87 1557//87 -s off -f 1450//1292 2476//1292 1069//1292 -s 1 -f 2474//87 1448//87 1556//87 -s off -f 1448//1292 2474//1292 1072//1292 -f 1402//1293 2358//1293 1403//1293 -f 3001//1294 33//1294 1564//1294 -s 1 -f 867//87 33//87 3001//87 -f 869//87 24//87 3000//87 -s off -f 3000//1294 24//1294 1563//1294 -s 1 -f 1739//131 1132//131 2155//131 -f 2480//131 1905//131 1876//131 -s off -f 2888//1295 2302//1295 2301//1295 -f 1283//1296 2914//1296 1454//1296 -s 1 -f 2914//87 1283//87 2210//87 -s off -f 1287//1296 2915//1296 1457//1296 -s 1 -f 2915//87 1287//87 2213//87 -f 2913//87 1290//87 2216//87 -s off -f 1290//1297 2913//1297 1460//1297 -f 2228//1298 3050//1298 1539//1298 -s 1 -f 1400//131 50//131 1357//131 -f 1396//131 55//131 1359//131 -f 1441//131 2595//131 1439//131 -f 1435//131 2594//131 1436//131 -f 231//87 2455//87 235//87 -s off -f 235//1299 2455//1299 3114//1299 -f 1355//1300 2787//1300 1639//1300 -f 2728//1301 283//1301 285//1301 -f 2730//1301 289//1301 291//1301 -f 2766//1302 363//1302 362//1302 -s 1 -f 363//87 2766//87 685//87 -s off -f 2767//1302 366//1302 365//1302 -s 1 -f 366//87 2767//87 693//87 -s off -f 2768//1302 360//1302 359//1302 -s 1 -f 360//87 2768//87 690//87 -f 2980//87 541//87 543//87 -s off -f 541//1303 2980//1303 1385//1303 -f 2017//1304 2896//1304 2015//1304 -s 1 -f 2896//87 2017//87 423//87 -s off -f 2002//1305 2894//1305 2000//1305 -s 1 -f 2894//87 2002//87 417//87 -s off -f 2014//1304 2895//1304 2012//1304 -s 1 -f 2895//87 2014//87 411//87 -f 1802//131 134//131 3021//131 -f 1804//131 128//131 1098//131 -f 1800//131 140//131 1101//131 -s off -f 721//1306 2541//1306 2540//1306 -s 1 -f 2541//87 721//87 144//87 -s off -f 722//1306 2544//1306 2543//1306 -s 1 -f 2544//87 722//87 147//87 -s off -f 2009//1307 2723//1307 2275//1307 -f 2006//1307 2722//1307 2277//1307 -f 3068//1308 1932//1308 2082//1308 -s 1 -f 2979//87 1932//87 3068//87 -f 2151//131 2153//131 1961//131 -s off -f 2527//1309 104//1309 103//1309 -s 1 -f 2714//87 104//87 2527//87 -f 2715//87 107//87 2526//87 -s off -f 2526//1310 107//1310 106//1310 -s 1 -f 2148//131 2150//131 1963//131 -f 2716//87 98//87 2528//87 -s off -f 2528//1310 98//1310 97//1310 -f 2938//1311 1517//1311 1297//1311 -f 2908//1312 1215//1312 1907//1312 -f 2725//1312 1218//1312 1909//1312 -f 317//1313 268//1313 267//1313 -f 187//1313 254//1313 188//1313 -s 1 -f 537//131 1281//131 856//131 -s off -f 2721//1314 1928//1314 1930//1314 -s 1 -f 1553//131 1277//131 511//131 -f 1547//131 1270//131 1883//131 -f 1552//131 1273//131 1880//131 -f 2509//131 1922//131 2258//131 -s off -f 19//1315 1082//1315 45//1315 -s 1 -f 2512//131 1768//131 3046//131 -s off -f 848//1316 1607//1316 2743//1316 -f 1491//1317 3103//1317 31//1317 -f 1493//1318 3102//1318 40//1318 -s 1 -f 735//131 734//131 1000//131 -s off -f 319//1319 1966//1319 320//1319 -f 2600//1320 1084//1320 2598//1320 -s 1 -f 2019//87 2644//87 320//87 -s off -f 2644//1321 2019//1321 1967//1321 -s 1 -f 3085//87 2507//87 2390//87 -s off -f 2390//1322 2507//1322 941//1322 -f 2024//1323 2814//1323 2548//1323 -s 1 -f 2490//87 2814//87 2024//87 -s off -f 2020//1323 2813//1323 2547//1323 -s 1 -f 2488//87 2813//87 2020//87 -s off -f 2026//1323 2812//1323 2546//1323 -s 1 -f 2489//87 2812//87 2026//87 -f 1687//131 1263//131 1653//131 -f 2003//131 2372//131 562//131 -f 2004//131 2370//131 559//131 -f 1366//131 321//131 2765//131 -s off -f 281//1324 616//1324 615//1324 -s 1 -f 275//87 616//87 281//87 -f 1057//131 1476//131 2267//131 -f 1060//131 1479//131 2269//131 -s off -f 2034//1325 2366//1325 2032//1325 -s 1 -f 1024//87 2366//87 2034//87 -f 1028//87 2368//87 2031//87 -s off -f 2031//1326 2368//1326 2029//1326 -s 1 -f 2149//131 1338//131 2869//131 -s off -f 2498//1327 1310//1327 1035//1327 -s 1 -f 606//131 605//131 972//131 -f 2152//131 1342//131 2868//131 -s off -f 2499//1327 1307//1327 1036//1327 -f 2497//1327 1313//1327 1034//1327 -s 1 -f 1318//131 1185//131 1319//131 -s off -f 1324//1328 614//1328 2223//1328 -f 2429//1329 872//1329 875//1329 -s 1 -f 2583//87 872//87 2429//87 -f 11//87 336//87 2973//87 -s off -f 2973//1330 336//1330 990//1330 -f 2998//1331 1390//1331 1389//1331 -f 2999//1332 1392//1332 1391//1332 -f 367//1333 1050//1333 234//1333 -s 1 -f 990//131 2886//131 991//131 -f 21//87 2413//87 1246//87 -s off -f 2413//1334 21//1334 2411//1334 -f 2052//1335 2780//1335 2053//1335 -f 2050//1335 2778//1335 2051//1335 -f 2047//1335 2782//1335 2048//1335 -f 1334//1336 3030//1336 1997//1336 -s 1 -f 3109//87 2349//87 1247//87 -s off -f 2349//1334 3109//1334 2347//1334 -s 1 -f 1322//131 2840//131 1968//131 -s off -f 1708//1337 491//1337 490//1337 -f 1702//1337 496//1337 495//1337 -f 1705//1337 479//1337 478//1337 -s 1 -f 231//87 2867//87 2455//87 -s off -f 2867//1338 231//1338 697//1338 -s 1 -f 1001//131 2103//131 1002//131 -f 2888//131 1604//131 2183//131 -s off -f 3095//1339 2542//1339 2290//1339 -f 3096//1339 2539//1339 2292//1339 -f 1158//1340 1157//1340 2300//1340 -s 1 -f 767//87 764//87 2936//87 -s off -f 2936//1341 764//1341 790//1341 -f 2937//1341 768//1341 789//1341 -s 1 -f 771//87 768//87 2937//87 -s off -f 2614//1342 3045//1342 2849//1342 -s 1 -f 3045//87 2614//87 2890//87 -s off -f 2613//1342 3043//1342 2848//1342 -s 1 -f 3043//87 2613//87 2889//87 -s off -f 2615//1342 3044//1342 2850//1342 -s 1 -f 3044//87 2615//87 2891//87 -f 594//87 927//87 1160//87 -s off -f 927//1343 594//1343 593//1343 -s 1 -f 589//131 1504//131 1501//131 -f 474//131 3057//131 1337//131 -f 501//131 3058//131 1341//131 -f 1317//131 236//131 233//131 -f 699//87 900//87 2037//87 -s off -f 2037//1344 900//1344 2035//1344 -f 2387//1345 997//1345 2314//1345 -s 1 -f 997//87 2387//87 505//87 -f 2045//131 1428//131 1004//131 -f 2042//131 1431//131 1007//131 -s off -f 2645//1346 516//1346 2309//1346 -s 1 -f 2644//87 516//87 2645//87 -f 1603//131 2939//131 1929//131 -s off -f 2865//1347 828//1347 2735//1347 -s 1 -f 589//131 1502//131 1504//131 -f 2158//87 2289//87 331//87 -s off -f 331//1348 2289//1348 2288//1348 -s 1 -f 318//131 2309//131 1965//131 -f 2500//131 1213//131 2501//131 -f 2451//131 1844//131 2503//131 -s off -f 1811//1349 1111//1349 1110//1349 -f 1814//1349 1119//1349 1118//1349 -s 1 -f 491//131 1708//131 1710//131 -f 496//131 1702//131 1704//131 -f 479//131 1705//131 1707//131 -s off -f 1817//1349 1115//1349 1114//1349 -f 115//1350 1230//1350 2619//1350 -s 1 -f 747//87 1230//87 115//87 -f 753//87 1231//87 111//87 -s off -f 111//1350 1231//1350 2617//1350 -s 1 -f 741//87 1232//87 119//87 -s off -f 119//1350 1232//1350 2621//1350 -f 3036//1351 1641//1351 3009//1351 -f 2352//1352 589//1352 3088//1352 -f 3037//1351 1644//1351 3007//1351 -s 1 -f 303//87 370//87 225//87 -s off -f 225//1353 370//1353 369//1353 -f 2883//1354 1038//1354 3067//1354 -f 1697//1355 1701//1355 1432//1355 -f 1694//1355 1692//1355 1495//1355 -s 1 -f 1768//131 1325//131 3046//131 -s off -f 2884//1356 1076//1356 3066//1356 -s 1 -f 2497//131 1735//131 1738//131 -f 2498//131 1727//131 1730//131 -f 2499//131 1731//131 1733//131 -s off -f 1354//1357 984//1357 1013//1357 -s 1 -f 606//131 972//131 942//131 -f 220//131 1279//131 1654//131 -s off -f 2684//1358 304//1358 1240//1358 -f 2686//1358 310//1358 1241//1358 -s 1 -f 2881//131 1437//131 2904//131 -f 2882//131 1440//131 2905//131 -s off -f 2947//1359 2444//1359 2084//1359 -f 3105//1360 53//1360 3104//1360 -f 293//1361 2364//1361 294//1361 -f 287//1361 2365//1361 288//1361 -f 1782//1362 1849//1362 1783//1362 -f 1779//1362 1846//1362 1780//1362 -s 1 -f 2259//87 2733//87 2732//87 -s off -f 2733//1363 2259//1363 2258//1363 -s 1 -f 1933//131 2777//131 1032//131 -f 2165//131 2758//131 937//131 -f 2166//131 2759//131 938//131 -f 2601//131 2086//131 3051//131 -f 2864//131 1074//131 1329//131 -s off -f 2003//1364 1206//1364 2192//1364 -f 2004//1364 1203//1364 2191//1364 -s 1 -f 1029//87 2906//87 285//87 -s off -f 285//1365 2906//1365 2728//1365 -s 1 -f 1025//87 2907//87 291//87 -s off -f 291//1365 2907//1365 2730//1365 -s 1 -f 926//87 2576//87 1776//87 -s off -f 2576//1366 926//1366 2585//1366 -f 1677//1367 3092//1367 1678//1367 -f 1680//1367 3091//1367 1681//1367 -s 1 -f 1429//131 1265//131 1430//131 -f 1426//131 1264//131 1427//131 -f 2880//87 1724//87 2391//87 -s off -f 1724//1368 2880//1368 2811//1368 -f 1862//1369 1087//1369 1404//1369 -s 1 -f 2436//87 1087//87 1862//87 -f 2438//87 1093//87 1865//87 -s off -f 1865//1369 1093//1369 1406//1369 -s 1 -f 2434//87 1090//87 1859//87 -s off -f 1859//1369 1090//1369 1405//1369 -f 1504//1370 1503//1370 1248//1370 -s 1 -f 2297//87 1583//87 2788//87 -s off -f 1583//1371 2297//1371 1584//1371 -f 2956//1372 2061//1372 2060//1372 -s 1 -f 2957//87 2061//87 2956//87 -f 2959//87 2063//87 2958//87 -s off -f 2958//1372 2063//1372 2062//1372 -s 1 -f 2954//87 2059//87 2955//87 -s off -f 2955//1372 2059//1372 2058//1372 -f 1161//1373 1211//1373 1162//1373 -f 1163//1373 1210//1373 1164//1373 -f 1051//1374 233//1374 232//1374 -f 311//1375 2975//1375 312//1375 -f 305//1375 2977//1375 306//1375 -s 1 -f 2185//131 1119//131 1814//131 -f 2188//131 1111//131 1811//131 -f 2317//131 1115//131 1817//131 -f 335//87 901//87 2471//87 -s off -f 2471//1376 901//1376 1366//1376 -f 2736//1377 474//1377 1010//1377 -f 2737//1377 501//1377 1012//1377 -f 1415//1378 2800//1378 1722//1378 -s 1 -f 767//87 2800//87 1415//87 -f 771//87 2799//87 1418//87 -s off -f 1418//1378 2799//1378 1721//1378 -f 1843//1379 1841//1379 2099//1379 -f 1836//1379 1839//1379 2093//1379 -f 2806//1379 1809//1379 2091//1379 -s 1 -f 2586//87 1496//87 2587//87 -s off -f 2587//1380 1496//1380 1693//1380 -s 1 -f 2532//87 1433//87 2533//87 -s off -f 2533//1381 1433//1381 1696//1381 -f 1388//1382 2848//1382 3043//1382 -f 1387//1382 2849//1382 3045//1382 -f 1386//1382 2850//1382 3044//1382 -s 1 -f 984//131 1354//131 985//131 -s off -f 2703//1383 292//1383 326//1383 -f 2704//1383 286//1383 325//1383 -s 1 -f 1908//131 1215//131 1217//131 -f 1910//131 1218//131 1220//131 -s off -f 1067//1384 1795//1384 1796//1384 -f 1070//1384 1797//1384 1798//1384 -s 1 -f 1348//131 1350//131 1183//131 -f 1351//131 1353//131 1182//131 -f 1345//131 1347//131 995//131 -s off -f 3041//1385 186//1385 672//1385 -f 3040//1385 316//1385 675//1385 -f 2640//1386 307//1386 2579//1386 -f 2641//1386 313//1386 2578//1386 -s 1 -f 2860//87 425//87 2861//87 -s off -f 2861//1387 425//1387 2574//1387 -s 1 -f 2859//87 413//87 2858//87 -s off -f 2858//1387 413//1387 2570//1387 -f 2863//1387 419//1387 1829//1387 -s 1 -f 2862//87 419//87 2863//87 -s off -f 2739//1388 295//1388 329//1388 -f 70//1389 2779//1389 1423//1389 -s 1 -f 78//87 2779//87 70//87 -s off -f 2338//1390 1068//1390 1451//1390 -f 2340//1390 1071//1390 1449//1390 -f 82//1391 2783//1391 1422//1391 -s 1 -f 90//87 2783//87 82//87 -s off -f 64//1389 2781//1389 2318//1389 -s 1 -f 60//87 2781//87 64//87 -f 860//87 859//87 1559//87 -s off -f 860//1392 1559//1392 861//1392 -f 1364//1393 1081//1393 3049//1393 -f 1920//1394 339//1394 338//1394 -f 1918//1394 345//1394 344//1394 -s 1 -f 993//131 2304//131 12//131 -s off -f 1689//1395 1064//1395 1505//1395 -s 1 -f 969//87 2638//87 1173//87 -s off -f 1173//1396 2638//1396 1171//1396 -f 985//1397 2247//1397 1638//1397 -s 1 -f 3050//131 2228//131 1413//131 -s off -f 2946//1398 847//1398 2083//1398 -s 1 -f 2035//131 971//131 700//131 -f 211//87 459//87 351//87 -s off -f 351//1399 459//1399 349//1399 -s 1 -f 217//87 447//87 354//87 -s off -f 354//1399 447//1399 352//1399 -f 357//1399 453//1399 355//1399 -s 1 -f 603//87 453//87 357//87 -f 1249//87 1223//87 877//87 -s off -f 877//1400 1223//1400 1222//1400 -s 1 -f 3070//87 2581//87 2751//87 -s off -f 2751//1401 2581//1401 2500//1401 -s 1 -f 1607//131 848//131 1606//131 -s off -f 3085//1402 185//1402 184//1402 -s 1 -f 185//87 3085//87 2390//87 -f 703//87 246//87 248//87 -s off -f 246//1403 703//1403 702//1403 -f 250//1403 709//1403 708//1403 -s 1 -f 709//87 250//87 252//87 -f 3069//87 2582//87 2453//87 -s off -f 2453//1401 2582//1401 2451//1401 -s 1 -f 706//87 242//87 244//87 -s off -f 242//1403 706//1403 705//1403 -s 1 -f 1158//131 2302//131 2183//131 -f 2591//131 2787//131 1355//131 -s off -f 1690//1404 1693//1404 1496//1404 -f 1699//1404 1696//1404 1433//1404 -f 31//1405 1492//1405 1491//1405 -s 1 -f 1492//87 31//87 1009//87 -f 1494//87 40//87 1011//87 -s off -f 40//1405 1494//1405 1493//1405 -s 1 -f 2580//131 1084//131 2600//131 -s off -f 1058//1406 2875//1406 724//1406 -f 1061//1407 2874//1407 719//1407 -f 3083//1408 2747//1408 2713//1408 -f 3084//1408 2748//1408 2712//1408 -f 3082//1408 2746//1408 2711//1408 -f 3022//1409 2046//1409 2118//1409 -f 3023//1409 2049//1409 2121//1409 -f 3024//1409 1514//1409 2114//1409 -f 2597//1410 1876//1410 2440//1410 -s 1 -f 2762//131 1052//131 3042//131 -s off -f 3080//1411 598//1411 696//1411 -s 1 -f 598//87 3080//87 862//87 -f 1068//131 1163//131 1069//131 -f 1071//131 1161//131 1072//131 -f 2104//131 3030//131 2294//131 -f 595//87 3079//87 863//87 -s off -f 3079//1412 595//1412 695//1412 -s 1 -f 2085//131 2444//131 2446//131 -f 2299//87 1505//87 2752//87 -s off -f 1505//1413 2299//1413 1689//1413 -f 3069//1414 656//1414 655//1414 -s 1 -f 656//87 3069//87 2453//87 -s off -f 3070//1415 668//1415 667//1415 -s 1 -f 668//87 3070//87 2751//87 -s off -f 2643//1416 342//1416 341//1416 -f 2642//1416 348//1416 347//1416 -s 1 -f 2908//131 284//131 2284//131 -f 2725//131 290//131 2285//131 -s off -f 2948//1417 300//1417 299//1417 -s 1 -f 329//87 300//87 2948//87 -f 2583//87 873//87 872//87 -s off -f 873//1418 2583//1418 874//1418 -s 1 -f 1966//131 319//131 1967//131 -f 1685//131 1064//131 1689//131 -s off -f 936//1419 1235//1419 1023//1419 -f 940//1419 1233//1419 1027//1419 -f 1395//1420 2993//1420 868//1420 -f 1399//1421 2994//1421 870//1421 -s 1 -f 850//131 2356//131 851//131 -f 853//131 2354//131 854//131 -f 1323//131 614//131 1324//131 -s off -f 2151//1422 1954//1422 1011//1422 -f 2148//1423 1951//1423 1009//1423 -f 946//1424 2448//1424 1688//1424 -s 1 -f 2448//87 946//87 218//87 -s off -f 414//1425 1152//1425 1107//1425 -s 1 -f 1152//87 414//87 1104//87 -s off -f 420//1426 1170//1426 1169//1426 -s 1 -f 1170//87 420//87 1103//87 -s off -f 426//1426 1155//1426 1154//1426 -s 1 -f 1155//87 426//87 1105//87 -s off -f 2283//1427 2978//1427 392//1427 -f 1434//1428 2881//1428 1793//1428 -f 1438//1428 2882//1428 1794//1428 -s 1 -f 2996//87 2007//87 1449//87 -s off -f 2007//1429 2996//1429 2005//1429 -s 1 -f 2995//87 2010//87 1451//87 -s off -f 2010//1430 2995//1430 2008//1430 -f 396//1431 2811//1431 2880//1431 -f 1219//1432 2285//1432 2106//1432 -f 1216//1432 2284//1432 2107//1432 -f 2156//1433 1723//1433 2154//1433 -s 1 -f 1723//87 2156//87 1741//87 -f 257//131 2162//131 1857//131 -f 271//131 2160//131 1854//131 -f 2942//87 1599//87 2943//87 -s off -f 2943//1434 1599//1434 1598//1434 -s 1 -f 2944//87 1602//87 2945//87 -s off -f 2945//1434 1602//1434 1601//1434 -f 2940//1434 1444//1434 1443//1434 -s 1 -f 2941//87 1444//87 2940//87 -f 1693//131 1690//131 1694//131 -f 2641//131 1461//131 348//131 -f 1696//131 1699//131 1697//131 -f 2640//131 1462//131 342//131 -f 3094//87 22//87 793//87 -s off -f 22//13 3094//13 52//13 -f 440//1435 2482//1435 2481//1435 -s 1 -f 442//87 2482//87 440//87 -s off -f 2885//1436 1998//1436 1560//1436 -f 1245//1437 3031//1437 346//1437 -f 1244//1438 3032//1438 340//1438 -s 1 -f 3049//87 699//87 2037//87 -s off -f 699//1439 3049//1439 1081//1439 -f 2696//1440 2754//1440 2563//1440 -s 1 -f 672//87 255//87 2510//87 -s off -f 2510//1441 255//1441 438//1441 -s 1 -f 675//87 269//87 2511//87 -s off -f 2511//1441 269//1441 437//1441 -f 2695//1440 2753//1440 2562//1440 -f 1172//1442 1683//1442 1938//1442 -f 2126//1443 2911//1443 2127//1443 -f 2124//1443 2912//1443 2125//1443 -f 1877//1444 3005//1444 1878//1444 -f 2312//1445 2639//1445 2206//1445 -s 1 -f 2318//131 3063//131 2319//131 -f 1423//131 3064//131 2321//131 -f 1422//131 3065//131 2320//131 -f 1850//131 2703//131 1848//131 -f 1847//131 2704//131 1845//131 -f 2038//131 2794//131 2039//131 -f 1587//87 2839//87 2577//87 -s off -f 2839//1446 1587//1446 1586//1446 -s 1 -f 3048//131 1340//131 1342//131 -f 3047//131 1336//131 1338//131 -s off -f 2078//1447 198//1447 1017//1447 -f 2077//1447 264//1447 1015//1447 -s 1 -f 3035//87 2112//87 2053//87 -s off -f 2112//1448 3035//1448 2319//1448 -s 1 -f 3033//87 2116//87 2048//87 -s off -f 2116//1448 3033//1448 2320//1448 -s 1 -f 2046//131 3022//131 1828//131 -s off -f 2119//1448 3034//1448 2321//1448 -s 1 -f 3034//87 2119//87 2051//87 -f 2049//131 3023//131 1096//131 -f 828//131 2865//131 829//131 -f 1514//131 3024//131 1516//131 -f 969//87 2204//87 2638//87 -s off -f 2204//1449 969//1449 968//1449 -s 1 -f 1045//131 1387//131 2080//131 -f 1048//131 1388//131 2079//131 -f 1042//131 1386//131 2081//131 -f 3066//87 1078//87 1496//87 -s off -f 1078//1450 3066//1450 1076//1450 -s 1 -f 998//87 2011//87 1759//87 -s off -f 1759//1451 2011//1451 1760//1451 -s 1 -f 3067//87 1040//87 1433//87 -s off -f 1040//1452 3067//1452 1038//1452 -f 1234//1453 1030//1453 1029//1453 -f 1236//1453 1026//1453 1025//1453 -f 2135//1454 3075//1454 1498//1454 -s 1 -f 3075//87 2135//87 2713//87 -f 3074//87 2129//87 2712//87 -s off -f 2129//1454 3074//1454 1500//1454 -s 1 -f 3073//87 2132//87 2711//87 -s off -f 2132//1454 3073//1454 2388//1454 -s 1 -f 580//131 892//131 581//131 -s off -f 2412//1455 2141//1455 2586//1455 -f 2348//1455 2140//1455 2532//1455 -s 1 -f 577//131 896//131 578//131 -f 2959//87 1179//87 2063//87 -s off -f 1179//1456 2959//1456 1178//1456 -f 1177//1456 2954//1456 1176//1456 -s 1 -f 2954//87 1177//87 2059//87 -f 2957//87 1181//87 2061//87 -s off -f 1181//1456 2957//1456 1180//1456 -s 1 -f 878//131 1979//131 1503//131 -s off -f 1863//1457 1043//1457 1042//1457 -s 1 -f 1766//87 1043//87 1863//87 -s off -f 1867//1458 1049//1458 1048//1458 -s 1 -f 1761//87 1049//87 1867//87 -s off -f 1860//1458 1046//1458 1045//1458 -s 1 -f 1763//87 1046//87 1860//87 -s off -f 670//1459 2646//1459 671//1459 -f 3090//1460 143//1460 142//1460 -f 3089//1460 152//1460 151//1460 -s 1 -f 1148//131 304//131 2684//131 -s off -f 1646//1461 3007//1461 1644//1461 -s 1 -f 1678//87 3007//87 1646//87 -f 1147//131 310//131 2686//131 -s off -f 1643//1461 3009//1461 1641//1461 -s 1 -f 1681//87 3009//87 1643//87 -s off -f 2769//1462 462//1462 507//1462 -s 1 -f 1408//131 1410//131 3078//131 -s off -f 16//1463 2816//1463 3077//1463 -f 633//1464 2663//1464 2662//1464 -s 1 -f 116//87 2663//87 633//87 -f 112//87 2660//87 635//87 -s off -f 635//1464 2660//1464 2659//1464 -s 1 -f 120//87 2657//87 634//87 -s off -f 634//1464 2657//1464 2656//1464 -s 1 -f 1699//131 1701//131 1697//131 -f 1690//131 1692//131 1694//131 -s off -f 2344//1465 244//1465 1628//1465 -s 1 -f 706//87 244//87 2344//87 -s off -f 2342//1465 252//1465 1626//1465 -s 1 -f 709//87 252//87 2342//87 -s off -f 2343//1465 248//1465 1629//1465 -s 1 -f 703//87 248//87 2343//87 -f 2928//87 2757//87 436//87 -s off -f 2757//1466 2928//1466 2923//1466 -f 2755//1466 2930//1466 2922//1466 -s 1 -f 2930//87 2755//87 430//87 -f 2933//87 2756//87 433//87 -s off -f 2756//1466 2933//1466 2921//1466 -f 1205//1467 2191//1467 1203//1467 -s 1 -f 921//87 2191//87 1205//87 -s off -f 1208//1467 2192//1467 1206//1467 -s 1 -f 924//87 2192//87 1208//87 -s off -f 2935//1468 1562//1468 2934//1468 -s 1 -f 1562//87 2935//87 1560//87 -s off -f 2565//1469 166//1469 2566//1469 -f 2572//1469 173//1469 2573//1469 -s 1 -f 1317//131 233//131 1051//131 -s off -f 2568//1469 170//1469 2569//1469 -f 2796//1470 68//1470 67//1470 -f 2797//1470 74//1470 73//1470 -f 2795//1470 86//1470 85//1470 -f 3076//1471 982//1471 3068//1471 -s 1 -f 3104//87 43//87 673//87 -s off -f 43//1472 3104//1472 53//1472 -s 1 -f 1980//131 1206//131 1647//131 -s off -f 2898//1473 1778//1473 2334//1473 -f 2900//1473 1781//1473 2336//1473 -s 1 -f 1981//131 1203//131 1648//131 -s off -f 2432//1474 2879//1474 2878//1474 -s 1 -f 2430//87 2879//87 2432//87 -s off -f 819//1475 2246//1475 820//1475 -f 822//1475 2242//1475 823//1475 -f 816//1475 2244//1475 817//1475 -s 1 -f 1398//131 725//131 2239//131 -f 1394//131 720//131 2240//131 -s off -f 2561//1476 1823//1476 3029//1476 -f 2557//1476 1819//1476 3028//1476 -f 2559//1476 1821//1476 3027//1476 -s 1 -f 1267//131 287//131 286//131 -f 2363//131 293//131 292//131 -f 2974//131 2975//131 311//131 -f 2976//131 2977//131 305//131 -f 886//131 2974//131 311//131 -f 891//131 2976//131 305//131 -f 1068//131 2871//131 1210//131 -f 1071//131 2873//131 1211//131 -f 1213//131 1849//131 1782//131 -f 1844//131 1846//131 1779//131 -s off -f 2227//1477 2359//1477 2762//1477 -s 1 -f 1403//87 2359//87 2227//87 -s off -f 1568//1478 3101//1478 508//1478 -s 1 -f 1797//131 1070//131 2355//131 -f 1795//131 1067//131 2353//131 -s off -f 1427//1479 1142//1479 1141//1479 -f 1430//1480 1145//1480 1144//1480 -f 2917//1481 1679//1481 2316//1481 -f 2920//1481 1676//1481 2315//1481 -f 1258//1482 1614//1482 1259//1482 -f 1255//1482 1611//1482 1256//1482 -f 1261//1482 1616//1482 1262//1482 -f 2604//1483 1888//1483 2605//1483 -f 2607//1484 1890//1484 2608//1484 -f 2610//1484 1892//1484 2611//1484 -s 1 -f 474//131 2736//131 3057//131 -f 501//131 2737//131 3058//131 -s off -f 2682//1485 1994//1485 2414//1485 -s 1 -f 1994//87 2682//87 1997//87 -s off -f 2626//1486 1257//1486 2627//1486 -f 2629//1486 1260//1486 2630//1486 -f 2623//1486 1254//1486 2624//1486 -f 2853//1487 2214//1487 2216//1487 -f 2851//1487 2208//1487 2210//1487 -f 2852//1487 2211//1487 2213//1487 -f 1820//1488 958//1488 957//1488 -f 1822//1488 965//1488 964//1488 -f 1824//1488 962//1488 961//1488 -s 1 -f 1068//131 2338//131 2871//131 -f 1071//131 2340//131 2873//131 -f 3081//131 1543//131 2903//131 -f 1645//131 3092//131 1677//131 -f 1642//131 3091//131 1680//131 -s off -f 2454//1489 3114//1489 2455//1489 -s 1 -f 1954//131 2151//131 1961//131 -f 1951//131 2148//131 1963//131 -s off -f 3107//1490 2837//1490 2488//1490 -f 3106//1490 2835//1490 2490//1490 -f 3108//1490 2833//1490 2489//1490 -s 1 -f 2984//87 2023//87 1902//87 -s off -f 1902//1491 2023//1491 1901//1491 -f 1900//1491 2027//1491 1899//1491 -s 1 -f 2982//87 2027//87 1900//87 -s off -f 1904//1492 2021//1492 1903//1492 -s 1 -f 2986//87 2021//87 1904//87 -f 2862//87 647//87 419//87 -s off -f 647//1493 2862//1493 645//1493 -s 1 -f 2859//87 208//87 413//87 -s off -f 208//1493 2859//1493 206//1493 -s 1 -f 2860//87 214//87 425//87 -s off -f 214//1493 2860//1493 212//1493 -f 211//1494 2089//1494 209//1494 -s 1 -f 2089//87 211//87 351//87 -s off -f 603//1494 2096//1494 601//1494 -s 1 -f 2096//87 603//87 357//87 -f 2097//87 217//87 354//87 -s off -f 217//1494 2097//1494 215//1494 -s 1 -f 2741//131 1858//131 3097//131 -f 2740//131 1855//131 3098//131 -s off -f 1893//1495 1596//1495 1595//1495 -f 1891//1495 1593//1495 1591//1495 -f 1889//1495 1590//1495 1588//1495 -f 2950//1496 905//1496 963//1496 -f 2949//1496 902//1496 956//1496 -f 2951//1496 908//1496 960//1496 -s 1 -f 1841//131 1843//131 1842//131 -f 1839//131 1836//131 1837//131 -s off -f 3062//1497 2596//1497 2784//1497 -s 1 -f 1809//131 2806//131 1807//131 -f 858//87 2447//87 2271//87 -s off -f 2447//1498 858//1498 857//1498 -f 2941//1499 752//1499 2174//1499 -s 1 -f 752//87 2941//87 1231//87 -s off -f 222//1500 1655//1500 1654//1500 -s 1 -f 1655//87 222//87 219//87 -f 746//87 2942//87 1230//87 -s off -f 2942//1501 746//1501 2173//1501 -s 1 -f 740//87 2944//87 1232//87 -s off -f 2944//1501 740//1501 2175//1501 -f 2842//1502 467//1502 466//1502 -s 1 -f 467//87 2842//87 2466//87 -f 473//87 2845//87 2706//87 -s off -f 2845//1502 473//1502 472//1502 -s 1 -f 470//87 2846//87 2705//87 -s off -f 2846//1502 470//1502 469//1502 -s 1 -f 847//131 2946//131 1606//131 -s off -f 463//1503 2203//1503 464//1503 -f 1992//1504 1125//1504 1183//1504 -s 1 -f 1125//87 1992//87 1832//87 -f 996//87 1991//87 1831//87 -s off -f 1991//1504 996//1504 995//1504 -f 1993//1504 1120//1504 1182//1504 -s 1 -f 1120//87 1993//87 1833//87 -f 2747//131 3083//131 1498//131 -f 2748//131 3084//131 1500//131 -f 2746//131 3082//131 1808//131 -f 2755//87 522//87 430//87 -s off -f 430//1505 522//1505 428//1505 -s 1 -f 2757//87 525//87 436//87 -s off -f 436//1505 525//1505 434//1505 -s 1 -f 2756//87 531//87 433//87 -s off -f 433//1505 531//1505 431//1505 -f 2494//1506 2556//1506 2493//1506 -f 2041//1507 3038//1507 1429//1507 -s 1 -f 2057//87 3038//87 2041//87 -s off -f 2496//1506 2558//1506 2495//1506 -f 2492//1506 2560//1506 2491//1506 -f 2043//1507 3039//1507 1426//1507 -s 1 -f 2056//87 3039//87 2043//87 -s off -f 1531//1508 2830//1508 2832//1508 -f 1534//1508 2827//1508 2829//1508 -f 1581//1508 2824//1508 2826//1508 -s 1 -f 1490//87 2072//87 2238//87 -s off -f 2072//1509 1490//1509 1489//1509 -s 1 -f 1484//87 2070//87 2232//87 -s off -f 2070//1510 1484//1510 1483//1510 -s 1 -f 1487//87 2068//87 2235//87 -s off -f 2068//1509 1487//1509 1486//1509 -s 1 -f 1878//87 1519//87 2441//87 -s off -f 2441//1511 1519//1511 1518//1511 -f 8//1512 2727//1512 2551//1512 -s 1 -f 2727//87 8//87 4//87 -s off -f 1651//1513 2969//1513 371//1513 -f 1649//1513 2967//1513 375//1513 -f 1650//1513 2971//1513 379//1513 -s 1 -f 1264//131 1142//131 1427//131 -s off -f 2405//1514 1719//1514 1112//1514 -f 2407//1515 1715//1515 1108//1515 -s 1 -f 2881//131 1434//131 1437//131 -s off -f 2409//1515 1717//1515 1116//1515 -s 1 -f 2882//131 1438//131 1440//131 -s off -f 2981//1516 1511//1516 2982//1516 -f 2983//1516 1509//1516 2984//1516 -f 2985//1517 1507//1517 2986//1517 -s 1 -f 1265//131 1145//131 1430//131 -f 227//87 3019//87 1938//87 -s off -f 3019//1518 227//1518 1684//1518 -s 1 -f 339//131 1920//131 1921//131 -f 345//131 1918//131 1919//131 -s off -f 199//1519 149//1519 148//1519 -f 265//1519 146//1519 145//1519 -f 2968//1520 815//1520 2516//1520 -f 2970//1520 821//1520 2518//1520 -f 2972//1520 818//1520 2520//1520 -s 1 -f 2447//87 2055//87 2271//87 -s off -f 2271//1521 2055//1521 2054//1521 -f 1472//1522 3087//1522 2250//1522 -f 2825//1523 2012//1523 2895//1523 -f 2828//1524 2015//1524 2896//1524 -f 2831//1525 2000//1525 2894//1525 -f 1480//1526 3086//1526 2249//1526 -f 2960//1527 2233//1527 1613//1527 -f 2962//1527 2236//1527 1615//1527 -f 2961//1527 2230//1527 1610//1527 -f 809//1528 2979//1528 807//1528 -s 1 -f 2979//87 809//87 1932//87 -f 2754//131 2696//131 2823//131 -f 2753//131 2695//131 2822//131 -s off -f 2990//1529 2567//1529 2774//1529 -f 2991//1529 2564//1529 2770//1529 -f 2992//1529 2571//1529 2773//1529 -f 3110//1530 2887//1530 540//1530 -f 2987//1531 2922//1531 2930//1531 -f 2988//1531 2921//1531 2933//1531 -f 2989//1531 2923//1531 2928//1531 -s 1 -f 1998//131 2885//131 1608//131 -f 1714//87 1812//87 2190//87 -s off -f 1812//1532 1714//1532 1810//1532 -s 1 -f 1716//87 1815//87 2187//87 -s off -f 1815//1533 1716//1533 1813//1533 -s 1 -f 2193//87 56//87 2909//87 -s off -f 2909//1534 56//1534 55//1534 -f 127//1535 1099//1535 1098//1535 -s 1 -f 1099//87 127//87 2493//87 -s off -f 1818//1533 1718//1533 1816//1533 -s 1 -f 1718//87 1818//87 2341//87 -s off -f 133//1536 3099//1536 3013//1536 -s 1 -f 3099//87 133//87 2491//87 -s off -f 139//1535 1102//1535 1101//1535 -s 1 -f 1102//87 139//87 2495//87 -s off -f 2910//1537 51//1537 50//1537 -s 1 -f 2195//87 51//87 2910//87 -f 588//87 520//87 523//87 -s off -f 520//1538 588//1538 587//1538 -f 529//1538 1123//1538 1344//1538 -s 1 -f 1123//87 529//87 526//87 -f 585//87 535//87 532//87 -s off -f 535//1538 585//1538 584//1538 -s 1 -f 2640//131 342//131 2643//131 -f 2641//131 348//131 2642//131 -s off -f 945//1539 2926//1539 1929//1539 -s 1 -f 2926//87 945//87 757//87 -s off -f 2838//1540 358//1540 1580//1540 -f 2836//1540 361//1540 1578//1540 -f 2834//1540 364//1540 1579//1540 -f 2965//1541 914//1541 1592//1541 -f 2964//1541 917//1541 1594//1541 -f 2966//1541 911//1541 1589//1541 -s 1 -f 935//131 1235//131 936//131 -s off -f 3054//1542 2603//1542 2651//1542 -s 1 -f 939//131 1233//131 940//131 -s off -f 3056//1542 2609//1542 2649//1542 -f 3055//1542 2606//1542 2653//1542 -f 2472//1543 1332//1543 1331//1543 -s 1 -f 1332//87 2472//87 1335//87 -s off -f 781//1544 303//1544 302//1544 -s 1 -f 303//87 781//87 370//87 -s off -f 2234//1545 2680//1545 2235//1545 -f 2231//1545 2674//1545 2232//1545 -f 2237//1545 2678//1545 2238//1545 -f 912//1546 2671//1546 913//1546 -f 918//1546 2672//1546 919//1546 -f 915//1546 2670//1546 916//1546 -s 1 -f 2480//131 1876//131 2597//131 -f 1085//131 1086//131 2739//131 -s off -f 1083//1547 230//1547 47//1547 -s 1 -f 1906//131 3005//131 1877//131 -s off -f 3003//1548 377//1548 376//1548 -f 3002//1548 381//1548 380//1548 -f 3004//1548 373//1548 372//1548 -f 2592//1549 1640//1549 2591//1549 -s 1 -f 1638//87 1640//87 2592//87 -f 1079//131 1364//131 1874//131 -s off -f 903//1550 2699//1550 904//1550 -f 909//1550 2701//1550 910//1550 -f 906//1550 2698//1550 907//1550 -f 3020//1551 1385//1551 2980//1551 -f 674//1552 1246//1552 897//1552 -s 1 -f 21//87 1246//87 674//87 -f 3109//87 1247//87 1014//87 -s off -f 1014//1552 1247//1552 893//1552 -s 1 -f 1461//131 3031//131 1245//131 -s off -f 2346//1553 2732//1553 2691//1553 -s 1 -f 2259//87 2732//87 2346//87 -f 1462//131 3032//131 1244//131 -s off -f 3053//1554 2018//1554 2377//1554 -s 1 -f 999//87 1758//87 736//87 -s off -f 736//1555 1758//1555 734//1555 -s 1 -f 2486//87 3088//87 591//87 -s off -f 591//1556 3088//1556 589//1556 -s 1 -f 1881//87 1373//87 956//87 -s off -f 1373//1557 1881//1557 1880//1557 -f 1371//1557 1884//1557 1883//1557 -s 1 -f 1884//87 1371//87 963//87 -s off -f 1375//1557 512//1557 511//1557 -s 1 -f 512//87 1375//87 960//87 -s off -f 3112//1558 2460//1558 2767//1558 -f 3111//1558 2459//1558 2766//1558 -f 3113//1558 2461//1558 2768//1558 -f 2109//1559 2178//1559 2108//1559 -s 1 -f 2178//87 2109//87 2385//87 -s off -f 3059//1560 2622//1560 2665//1560 -f 3060//1560 2625//1560 2666//1560 -f 3061//1560 2628//1560 2669//1560 -f 2111//1561 2176//1561 2110//1561 -s 1 -f 2176//87 2111//87 2383//87 -f 671//87 2513//87 333//87 -s off -f 333//1562 2513//1562 2103//1562 -s 1 -f 894//131 2883//131 2140//131 -f 898//131 2884//131 2141//131 -f 3077//87 1619//87 1186//87 -s off -f 1619//1563 3077//1563 2816//1563 -f 2013//1564 2263//1564 2014//1564 -f 2016//1564 2265//1564 2017//1564 -f 2001//1564 2261//1564 2002//1564 -s 1 -f 2725//131 2285//131 1219//131 -f 2908//131 2284//131 1216//131 -s off -f 2209//1565 3014//1565 136//1565 -f 2212//1566 3016//1566 130//1566 -f 2215//1565 3015//1565 124//1565 -s 1 -f 1058//131 1057//131 2267//131 -s off -f 2194//1567 2108//1567 2178//1567 -f 2196//1568 2110//1568 2176//1568 -s 1 -f 1061//131 1060//131 2269//131 -f 1903//131 1469//131 1471//131 -s off -f 20//1569 2997//1569 18//1569 -s 1 -f 46//87 2997//87 20//87 -f 1899//131 1463//131 1465//131 -f 1901//131 1466//131 1468//131 -s off -f 270//1570 1139//1570 2159//1570 -s 1 -f 267//87 1139//87 270//87 -s off -f 256//1570 1146//1570 2161//1570 -s 1 -f 188//87 1146//87 256//87 -s off -f 579//1571 3093//1571 2313//1571 -f 2631//1572 852//1572 851//1572 -s 1 -f 1798//87 852//87 2631//87 -f 1796//87 855//87 2632//87 -s off -f 2632//1572 855//1572 854//1572 -s 1 -f 3081//131 2903//131 2439//131 -f 2728//131 1030//131 1234//131 -f 2730//131 1026//131 1236//131 -# 0 polygons - 5275 triangles - -# -# object not_valid_text -# - -v -9.9419 0.5906 -5.7930 -v -9.8609 0.5906 -5.6852 -v -9.8619 -0.5906 -5.6906 -v -10.1173 0.5906 -4.5659 -v -10.1318 0.5906 -4.6477 -v -10.1299 -0.5906 -4.6460 -v -10.1277 0.5906 -5.6683 -v -10.1900 -0.5906 -5.7272 -v -10.1237 -0.5906 -5.6655 -v -10.0480 0.5906 -5.8835 -v -9.9443 -0.5906 -5.7982 -v -10.0525 -0.5906 -5.8888 -v 8.1117 0.5906 -5.6001 -v 8.0973 -0.5906 -5.6255 -v 8.1305 -0.5906 -5.5612 -v 7.4194 0.5906 -5.9417 -v 7.5120 -0.5906 -5.9729 -v 7.4134 -0.5906 -5.9405 -v 8.3876 0.5906 -4.9944 -v 8.3861 -0.5906 -4.9384 -v 8.3887 -0.5906 -5.0429 -v 7.7040 0.5906 -5.8041 -v 7.6689 -0.5906 -5.8024 -v 7.7865 -0.5906 -5.8029 -v 7.2121 0.5906 -5.7101 -v 7.2358 0.5906 -5.7717 -v 7.2358 -0.5906 -5.7717 -v 8.3898 0.5906 -5.5038 -v -3.5356 0.5906 -5.2284 -v -3.5388 -0.5906 -5.3697 -v -3.5348 -0.5906 -5.2187 -v -4.5754 0.5906 -5.1671 -v -4.5800 -0.5906 -5.3132 -v -4.5693 -0.5906 -5.1051 -v -4.3394 0.5906 -5.3074 -v -4.3362 -0.5906 -5.1674 -v -4.3402 -0.5906 -5.3167 -v -3.2993 0.5906 -5.3601 -v -3.2956 -0.5906 -5.2034 -v -3.2992 -0.5906 -5.3693 -v 4.0560 0.5906 -5.3601 -v 4.0597 -0.5906 -5.2034 -v 4.0562 -0.5906 -5.3693 -v 3.8197 0.5906 -5.2284 -v 3.8165 -0.5906 -5.3697 -v 3.8205 -0.5906 -5.2187 -v 2.7799 0.5906 -5.1671 -v 2.7753 -0.5906 -5.3132 -v 2.7860 -0.5906 -5.1051 -v 3.0159 0.5906 -5.3074 -v 3.0191 -0.5906 -5.1674 -v 3.0151 -0.5906 -5.3167 -v -1.6281 0.5906 -5.2356 -v -1.6301 -0.5906 -5.3252 -v -1.6212 -0.5906 -5.1312 -v -1.3518 0.5906 -5.5302 -v -1.3798 -0.5906 -5.4311 -v -1.3507 -0.5906 -5.5367 -v -3.0668 0.5906 -4.9744 -v -3.0916 -0.5906 -5.0721 -v -3.0660 -0.5906 -4.9693 -v -2.2403 0.5906 -4.8792 -v -2.2013 -0.5906 -4.9362 -v -2.2403 -0.5906 -4.8792 -v -1.9222 0.5906 -5.9583 -v -1.9222 -0.5906 -4.0656 -v -1.9222 -0.5906 -5.9583 -v -2.8689 0.5906 -5.3087 -v -2.8661 -0.5906 -5.1652 -v -2.8697 -0.5906 -5.3192 -v 9.8780 0.5906 -4.9744 -v 9.8533 -0.5906 -5.0721 -v 9.8788 -0.5906 -4.9694 -v 10.7046 0.5906 -4.8792 -v 10.7436 -0.5906 -4.9362 -v 10.7046 -0.5906 -4.8792 -v 11.0226 0.5906 -5.9583 -v 11.0226 -0.5906 -4.0656 -v 11.0226 -0.5906 -5.9583 -v 10.0759 0.5906 -5.3087 -v 10.0788 -0.5906 -5.1651 -v 10.0752 -0.5906 -5.3192 -v 7.8535 0.5906 -5.1522 -v 7.5947 -0.5906 -5.1870 -v 7.9443 -0.5906 -5.1390 -v 7.9932 0.5906 -5.3178 -v 8.1520 -0.5906 -5.2729 -v 7.9388 -0.5906 -5.3307 -v -1.3907 0.5906 -5.3323 -v -0.3674 0.5906 -5.3323 -v -0.3665 -0.5906 -5.3323 -v -1.6209 0.5906 -5.4190 -v -9.4606 0.5906 -4.0656 -v -9.4606 -0.5906 -5.9583 -v -9.4606 -0.5906 -4.0656 -v -9.2096 0.5906 -5.7339 -v -9.2096 -0.5906 -4.2900 -v -9.2096 -0.5906 -5.7339 -v -8.2126 0.5906 -5.3828 -v -8.2618 -0.5906 -5.4952 -v -8.1952 -0.5906 -5.3349 -v -7.9114 0.5906 -5.2047 -v -7.9048 -0.5906 -5.1611 -v -7.9360 -0.5906 -5.3401 -v -1.9222 0.5906 -4.0656 -v -2.9427 0.5906 -5.7890 -v -2.8770 0.5906 -5.8552 -v -2.8807 -0.5906 -5.8532 -v 11.0226 0.5906 -4.0656 -v 10.0021 0.5906 -5.7890 -v 10.0679 0.5906 -5.8552 -v 10.0642 -0.5906 -5.8532 -v -6.1656 0.5906 -4.5639 -v -6.2352 0.5906 -4.5813 -v -6.2639 -0.5906 -4.5899 -v -5.4089 0.5906 -4.7693 -v -5.3320 0.5906 -4.7575 -v -5.3389 -0.5906 -4.7570 -v -4.4892 0.5906 -5.6846 -v -4.4493 0.5906 -5.7473 -v -4.4493 -0.5906 -5.7473 -v -3.2989 0.5906 -5.1621 -v 2.8661 0.5906 -5.6846 -v 2.9060 0.5906 -5.7473 -v 2.9060 -0.5906 -5.7473 -v 4.0564 0.5906 -5.1621 -v -9.8805 0.5906 -4.4938 -v -9.9018 -0.5906 -4.3934 -v -9.8795 -0.5906 -4.4967 -v -10.1601 0.5906 -4.3839 -v -10.1385 -0.5906 -4.4241 -v -10.1808 -0.5906 -4.3537 -v -8.1122 0.5906 -5.7038 -v -8.0668 0.5906 -5.6433 -v -8.0574 -0.5906 -5.6307 -v -9.4606 0.5906 -5.9583 -v -5.2367 0.5906 -4.7661 -v -5.1826 -0.5906 -4.7865 -v -5.2587 -0.5906 -4.7600 -v -5.4010 0.5906 -4.5753 -v -5.4912 -0.5906 -4.6112 -v -5.4010 -0.5906 -4.5753 -v -10.0955 0.5906 -5.1864 -v -10.0646 0.5906 -5.2384 -v -10.0502 -0.5906 -5.2699 -v -9.8946 0.5906 -4.4230 -v 8.0921 0.5906 -5.1065 -v 7.9850 0.5906 -5.1304 -v -9.2096 0.5906 -4.2900 -v -8.1962 0.5906 -4.6740 -v -8.1684 0.5906 -4.8042 -v -8.1687 -0.5906 -4.7943 -v 3.1818 0.5906 -4.8287 -v 3.2388 0.5906 -4.7902 -v 3.2388 -0.5906 -4.7902 -v 3.6539 0.5906 -5.7141 -v 3.5970 0.5906 -5.7530 -v 3.5970 -0.5906 -5.7530 -v -3.7014 0.5906 -5.7141 -v -3.7583 0.5906 -5.7530 -v -3.7583 -0.5906 -5.7530 -v -4.1735 0.5906 -4.8287 -v -4.1165 0.5906 -4.7902 -v -4.1165 -0.5906 -4.7902 -v 10.1278 0.5906 -4.9581 -v 10.1649 0.5906 -4.8936 -v 10.1606 -0.5906 -4.8972 -v 10.8119 0.5906 -5.3269 -v 10.7989 0.5906 -5.4568 -v 10.8005 -0.5906 -5.4550 -v -2.8171 0.5906 -4.9581 -v -2.7800 0.5906 -4.8936 -v -2.7843 -0.5906 -4.8972 -v -2.1330 0.5906 -5.3269 -v -2.1460 0.5906 -5.4568 -v -2.1444 -0.5906 -5.4550 -v 10.2967 0.5906 -4.5676 -v 10.2308 0.5906 -4.5848 -v 10.2791 -0.5906 -4.5697 -v -2.6481 0.5906 -4.5676 -v -2.7141 0.5906 -4.5848 -v -2.6658 -0.5906 -4.5697 -v -8.2132 0.5906 -4.2149 -v -8.3232 0.5906 -4.1456 -v -8.2260 -0.5906 -4.2033 -v -6.3590 0.5906 -4.8515 -v -6.3002 -0.5906 -4.8033 -v -6.3610 -0.5906 -4.8528 -v -6.1261 -0.5906 -4.5567 -v 7.6469 0.5906 -4.5760 -v 7.5280 -0.5906 -4.6090 -v 7.6936 -0.5906 -4.5660 -v 7.7587 0.5906 -4.7506 -v 7.8494 -0.5906 -4.7477 -v 7.7063 -0.5906 -4.7551 -v 4.3730 0.5906 -4.7654 -v 4.3759 0.5906 -5.6607 -v 4.3741 -0.5906 -5.6515 -v 4.6072 0.5906 -5.6077 -v 4.6063 0.5906 -4.7654 -v 4.6063 -0.5906 -4.7654 -v 2.2779 0.5906 -4.6070 -v 2.2181 0.5906 -4.5835 -v 2.1923 -0.5906 -4.5744 -v 1.8863 0.5906 -4.7691 -v 1.9658 0.5906 -4.7575 -v 1.9591 -0.5906 -4.7570 -v -6.3934 0.5906 -4.8947 -v 7.8321 0.5906 -4.5563 -v 7.7360 0.5906 -4.5622 -v 4.3730 -0.5906 -4.7654 -v 4.6080 -0.5906 -5.6484 -v -2.3944 0.5906 -5.7794 -v -2.4138 -0.5906 -5.7858 -v -2.3530 -0.5906 -5.7639 -v -2.1378 0.5906 -5.9583 -v -2.1378 -0.5906 -5.9583 -v 10.5505 0.5906 -5.7794 -v 10.5311 -0.5906 -5.7858 -v 10.5919 -0.5906 -5.7639 -v 10.8071 0.5906 -5.9583 -v 10.8071 -0.5906 -5.9583 -v 2.0730 0.5906 -4.7673 -v 2.1358 -0.5906 -4.7902 -v 2.0477 -0.5906 -4.7604 -v 1.7543 0.5906 -4.6290 -v 1.6761 -0.5906 -4.6880 -v 1.7894 -0.5906 -4.6082 -v -4.1082 0.5906 -4.5760 -v -4.2022 0.5906 -4.6055 -v -4.2022 -0.5906 -4.6055 -v 3.2471 0.5906 -4.5760 -v 3.1531 0.5906 -4.6055 -v 3.1531 -0.5906 -4.6055 -v -0.6482 0.5906 -4.6514 -v -0.7083 0.5906 -4.6169 -v -0.7083 -0.5906 -4.6169 -v -1.1433 0.5906 -4.5713 -v -1.2423 -0.5906 -4.6004 -v -1.1019 -0.5906 -4.5629 -v -0.3727 -0.5906 -5.1361 -v -5.1762 0.5906 -4.5615 -v -5.2593 0.5906 -4.5558 -v -5.2972 -0.5906 -4.5561 -v 8.1526 0.5906 -5.2703 -v 7.5745 0.5906 -5.7790 -v 7.5258 0.5906 -5.7513 -v 7.5277 -0.5906 -5.7538 -v -3.7645 0.5906 -5.9665 -v -3.6760 -0.5906 -5.9382 -v -3.7683 -0.5906 -5.9683 -v -3.9128 0.5906 -5.7946 -v -4.0056 -0.5906 -5.7911 -v -3.9072 -0.5906 -5.7955 -v 3.5908 0.5906 -5.9665 -v 3.6793 -0.5906 -5.9382 -v 3.5870 -0.5906 -5.9683 -v 3.4426 0.5906 -5.7946 -v 3.3497 -0.5906 -5.7911 -v 3.4481 -0.5906 -5.7955 -v -0.7596 0.5906 -5.9582 -v -0.6790 0.5906 -5.9286 -v -0.6790 -0.5906 -5.9286 -v 7.8740 0.5906 -4.7493 -v -10.7371 0.5906 -4.1366 -v -10.8056 0.5906 -4.1851 -v -10.7801 -0.5906 -4.1639 -v 3.3942 0.5906 -4.7490 -v 3.4863 -0.5906 -4.7525 -v 3.3889 -0.5906 -4.7480 -v 3.3829 0.5906 -4.5573 -v 3.2513 -0.5906 -4.5733 -v 3.3889 -0.5906 -4.5555 -v -3.9611 0.5906 -4.7490 -v -3.8691 -0.5906 -4.7525 -v -3.9664 -0.5906 -4.7480 -v -3.9724 0.5906 -4.5573 -v -4.1040 -0.5906 -4.5733 -v -3.9665 -0.5906 -4.5555 -v -10.0964 -0.5906 -5.1831 -v -9.8090 0.5906 -5.2302 -v -9.8402 -0.5906 -5.1506 -v -9.8071 -0.5906 -5.2329 -v 7.8013 0.5906 -5.9763 -v 7.8998 0.5906 -5.9511 -v 7.9065 -0.5906 -5.9509 -v -0.6112 0.5906 -5.1404 -v -1.3789 -0.5906 -5.1404 -v -0.6112 -0.5906 -5.1404 -v -0.9633 0.5906 -4.7491 -v -0.8729 -0.5906 -4.7631 -v -0.9652 -0.5906 -4.7476 -v -0.9424 -0.5906 -4.5563 -v -1.3907 -0.5906 -5.3323 -v -10.1932 0.5906 -5.7281 -v -10.2680 0.5906 -5.7698 -v -10.2639 -0.5906 -5.7694 -v -0.9229 0.5906 -5.7925 -v -0.9991 -0.5906 -5.7959 -v -0.9189 -0.5906 -5.7927 -v -0.8787 0.5906 -5.9819 -v -0.7628 -0.5906 -5.9605 -v -0.8820 -0.5906 -5.9835 -v -8.7115 -0.5906 -4.2914 -v -8.7228 0.5906 -4.0675 -v -8.6978 -0.5906 -4.0669 -v 10.3851 0.5906 -5.7893 -v 10.3070 0.5906 -5.7627 -v 10.3103 -0.5906 -5.7658 -v -2.5598 0.5906 -5.7893 -v -2.6379 0.5906 -5.7627 -v -2.6346 -0.5906 -5.7658 -v -10.6091 0.5906 -4.3015 -v -10.5645 0.5906 -4.2764 -v -10.5377 -0.5906 -4.2647 -v -0.7980 0.5906 -5.7543 -v -0.8574 0.5906 -5.7788 -v -0.8539 -0.5906 -5.7785 -v -5.6486 0.5906 -5.9583 -v -5.6479 -0.5906 -5.1200 -v -5.6486 -0.5906 -5.9583 -v -5.8825 0.5906 -5.0453 -v -5.8819 -0.5906 -5.9583 -v -5.8846 -0.5906 -4.9882 -v 8.4012 0.5906 -5.7773 -v 8.1562 0.5906 -5.3859 -v 8.3899 0.5906 -5.5257 -v 2.5039 0.5906 -5.9583 -v 2.5035 -0.5906 -5.0414 -v 2.5039 -0.5906 -5.9583 -v 3.1818 0.5906 -5.7145 -v 3.1143 0.5906 -5.6450 -v 3.1150 -0.5906 -5.6485 -v -4.1735 0.5906 -5.7145 -v -4.2410 0.5906 -5.6450 -v -4.2403 -0.5906 -5.6485 -v 3.6531 0.5906 -4.8291 -v 3.7207 0.5906 -4.8985 -v 3.7201 -0.5906 -4.8951 -v -3.7022 0.5906 -4.8291 -v -3.6346 0.5906 -4.8985 -v -3.6353 -0.5906 -4.8951 -v -5.8819 0.5906 -5.9583 -v -2.8052 -0.5906 -5.9083 -v -2.3595 -0.5906 -5.9642 -v 10.1396 -0.5906 -5.9083 -v 10.5853 -0.5906 -5.9642 -v -9.9546 -0.5906 -4.2901 -v -10.2023 0.5906 -4.0981 -v -10.3156 -0.5906 -4.0647 -v -10.1987 -0.5906 -4.0988 -v -3.5848 0.5906 -5.8913 -v -3.5070 0.5906 -5.8351 -v -3.5093 -0.5906 -5.8384 -v 3.7705 0.5906 -5.8913 -v 3.8483 0.5906 -5.8351 -v 3.8460 -0.5906 -5.8383 -v -10.8983 0.5906 -5.7749 -v -10.8108 0.5906 -5.8624 -v -10.8624 -0.5906 -5.8177 -v 6.8302 0.5906 -4.5853 -v 6.4991 0.5906 -5.4960 -v 6.4857 -0.5906 -5.5331 -v 5.8081 0.5906 -4.5853 -v 6.3246 0.5906 -5.9583 -v 6.3246 -0.5906 -5.9583 -v 1.3907 0.5906 -4.5853 -v 1.3907 0.5906 -5.9583 -v 1.3907 -0.5906 -5.9583 -v 7.8885 -0.5906 -4.5549 -v 8.1581 -0.5906 -4.9991 -v -7.9911 -0.5906 -5.5050 -v -8.7020 -0.5906 -5.9573 -v -0.8700 0.5906 -4.7655 -v -0.7875 0.5906 -4.8037 -v -0.7906 -0.5906 -4.8001 -v -1.3789 0.5906 -5.1404 -v -5.0685 0.5906 -5.0396 -v -5.0669 -0.5906 -5.9583 -v -5.0680 -0.5906 -5.0229 -v -4.8337 0.5906 -5.9583 -v -4.8345 -0.5906 -4.9713 -v -4.8337 -0.5906 -5.9583 -v 2.5026 0.5906 -5.0326 -v -4.8359 0.5906 -4.9521 -v 7.6957 -0.5906 -5.3696 -v 7.2076 0.5906 -5.4994 -v 7.2014 -0.5906 -5.5212 -v 7.2302 -0.5906 -5.4335 -v 6.8302 -0.5906 -4.5853 -v 6.5505 0.5906 -5.9583 -v 7.0689 -0.5906 -4.5853 -v 6.5505 -0.5906 -5.9583 -v -6.6969 0.5906 -4.5853 -v -6.6969 0.5906 -5.9583 -v -6.6969 -0.5906 -5.9583 -v -2.7732 -0.5906 -4.6085 -v -2.1560 -0.5906 -4.7406 -v 10.1716 -0.5906 -4.6085 -v 10.7889 -0.5906 -4.7406 -v 9.8530 0.5906 -5.0777 -v -3.0919 0.5906 -5.0777 -v -7.8994 0.5906 -4.9660 -v -7.9085 0.5906 -4.8283 -v -7.9072 -0.5906 -4.8327 -v -6.4636 0.5906 -5.9583 -v -6.4623 -0.5906 -5.1615 -v -6.4636 -0.5906 -5.9583 -v -6.6969 -0.5906 -4.5853 -v -8.1602 -0.5906 -5.1399 -v 1.6240 0.5906 -5.9583 -v 1.6248 -0.5906 -5.1576 -v 1.6240 -0.5906 -5.9583 -v 1.3907 -0.5906 -4.5853 -v 8.7402 0.5906 -4.0656 -v 8.7402 -0.5906 -5.9583 -v 8.7402 -0.5906 -4.0656 -v 8.9734 0.5906 -5.9583 -v 8.9734 0.5906 -4.0656 -v 8.9734 -0.5906 -4.0656 -v 8.9734 -0.5906 -5.9583 -v 8.7402 0.5906 -5.9583 -v -0.0886 0.5906 -4.0656 -v -0.0886 -0.5906 -5.9583 -v -0.0886 -0.5906 -4.0656 -v 0.1447 0.5906 -5.9583 -v 0.1447 0.5906 -4.0656 -v 0.1447 -0.5906 -4.0656 -v 0.1447 -0.5906 -5.9583 -v -0.0886 0.5906 -5.9583 -v 2.2687 0.5906 -5.0677 -v 2.2707 0.5906 -5.9583 -v 2.2707 -0.5906 -5.9583 -v -5.7395 0.5906 -4.6948 -v -5.7918 -0.5906 -4.6397 -v -5.7373 -0.5906 -4.6965 -v -5.0669 0.5906 -5.9583 -v -10.2867 0.5906 -4.8114 -v -10.3342 0.5906 -5.0402 -v -10.3604 0.5906 -4.8398 -v 6.3800 0.5906 -5.4946 -v 6.0575 0.5906 -4.5853 -v 6.0575 -0.5906 -4.5853 -v 1.6262 0.5906 -5.1370 -v -5.6467 0.5906 -5.1028 -v 8.2205 0.5906 -5.9583 -v 8.4596 -0.5906 -5.9583 -v 8.2186 -0.5906 -5.9578 -v 8.4336 -0.5906 -5.9039 -v 8.1577 -0.5906 -5.3823 -v -10.5382 0.5906 -4.8569 -v -10.5639 -0.5906 -5.0607 -v -10.5372 -0.5906 -4.8580 -v -9.8885 -0.5906 -5.0779 -v 6.3940 -0.5906 -5.5335 -v 5.8081 -0.5906 -4.5853 -v 8.0322 0.5906 -5.6985 -v 7.9787 0.5906 -5.7373 -v 8.0379 -0.5906 -5.6962 -v -10.7065 0.5906 -5.9289 -v -10.5958 -0.5906 -5.9710 -v -10.7125 -0.5906 -5.9278 -v -10.7894 0.5906 -5.4298 -v -11.0226 -0.5906 -5.4593 -v -10.7894 -0.5906 -5.4298 -v -9.8428 0.5906 -5.1480 -v 7.0689 0.5906 -4.5853 -v -1.3987 0.5906 -4.6960 -v -1.4518 0.5906 -4.7467 -v -1.4737 -0.5906 -4.7700 -v 9.5669 0.5906 -5.9583 -v 9.5669 -0.5906 -4.5853 -v 9.5669 -0.5906 -5.9583 -v 9.3337 0.5906 -4.5853 -v 9.3337 -0.5906 -5.9583 -v 9.3337 -0.5906 -4.5853 -v 9.5669 0.5906 -4.5853 -v 9.3337 0.5906 -5.9583 -v 4.4719 0.5906 -5.9175 -v 4.5103 0.5906 -5.9413 -v 4.5087 -0.5906 -5.9411 -v 4.8720 0.5906 -5.9555 -v 4.8425 -0.5906 -5.7513 -v 4.8720 -0.5906 -5.9555 -v -8.4698 0.5906 -5.6827 -v -8.5291 0.5906 -5.7037 -v -8.5541 -0.5906 -5.7118 -v 2.2694 -0.5906 -5.0513 -v -10.3033 -0.5906 -4.2683 -v -10.9753 0.5906 -4.4522 -v -10.9990 -0.5906 -4.5469 -v -10.9742 -0.5906 -4.4446 -v 7.5892 -0.5906 -5.7862 -v 7.4468 -0.5906 -5.5490 -v 10.5029 0.5906 -4.7544 -v 10.5833 0.5906 -4.7812 -v 10.5802 -0.5906 -4.7782 -v -2.4420 0.5906 -4.7544 -v -2.3615 0.5906 -4.7812 -v -2.3647 -0.5906 -4.7782 -v -10.6111 0.5906 -5.7450 -v -10.6542 0.5906 -5.7124 -v -10.6238 -0.5906 -5.7386 -v -5.8830 0.5906 -5.0240 -v -8.7114 -0.5906 -5.7323 -v -8.7319 0.5906 -5.7314 -v -10.0603 0.5906 -4.1771 -v -10.1272 0.5906 -4.1332 -v -10.1230 -0.5906 -4.1348 -v 2.1573 0.5906 -4.8048 -v 2.2686 0.5906 -5.0579 -v 2.5030 0.5906 -5.0417 -v 8.3885 0.5906 -5.0308 -v 8.3727 0.5906 -4.8442 -v 8.1497 0.5906 -4.9363 -v 8.1307 0.5906 -4.8791 -v -1.2798 0.5906 -5.9274 -v -1.2117 0.5906 -5.9538 -v -1.1842 -0.5906 -5.9630 -v 3.7697 0.5906 -4.6502 -v 3.7078 0.5906 -4.6162 -v 3.6822 -0.5906 -4.6038 -v -3.5857 0.5906 -4.6502 -v -3.6475 0.5906 -4.6162 -v -3.6731 -0.5906 -4.6038 -v -4.4022 -0.5906 -5.8033 -v 2.9531 -0.5906 -5.8033 -v -4.5779 0.5906 -5.3197 -v 2.7774 0.5906 -5.3197 -v -10.0316 0.5906 -5.3810 -v -9.7873 0.5906 -5.4326 -v -10.0362 0.5906 -5.4725 -v -3.1060 -0.5906 -5.1811 -v -2.7060 -0.5906 -5.7194 -v 9.8389 -0.5906 -5.1811 -v 10.2389 -0.5906 -5.7194 -v -2.8418 0.5906 -5.5016 -v -3.0777 0.5906 -5.5232 -v -2.8644 0.5906 -5.3784 -v 10.1031 0.5906 -5.5016 -v 9.8672 0.5906 -5.5232 -v 10.0805 0.5906 -5.3784 -v 10.3556 0.5906 -5.9832 -v 10.4941 0.5906 -5.9837 -v 10.4605 -0.5906 -5.9876 -v -2.5892 0.5906 -5.9832 -v -2.4508 0.5906 -5.9837 -v -2.4844 -0.5906 -5.9876 -v -1.6094 -0.5906 -5.4988 -v -1.4008 0.5906 -5.8518 -v -1.3185 -0.5906 -5.9089 -v -1.4334 -0.5906 -5.8245 -v -8.6962 0.5906 -5.9558 -v -8.7190 0.5906 -5.7312 -v -10.1203 -0.5906 -4.4873 -v -10.2834 -0.5906 -4.8107 -v -10.2562 -0.5906 -5.0592 -v -10.1334 -0.5906 -4.9322 -v -4.9961 0.5906 -4.6261 -v -5.0726 -0.5906 -4.5853 -v -4.9916 -0.5906 -4.6275 -v -10.2418 0.5906 -4.3008 -v -10.1909 0.5906 -4.3448 -v -3.8119 -0.5906 -4.5647 -v 3.5434 -0.5906 -4.5647 -v 10.7894 0.5906 -4.0656 -v 10.7894 0.5906 -4.7438 -v -2.1555 0.5906 -4.0656 -v -2.1555 0.5906 -4.7438 -v 7.3502 0.5906 -4.7299 -v 7.3110 0.5906 -4.7837 -v 7.3327 -0.5906 -4.7483 -v 8.1729 -0.5906 -5.7902 -v 7.7599 -0.5906 -5.9837 -v 10.0996 -0.5906 -5.0389 -v 10.2771 -0.5906 -4.7889 -v -2.8453 -0.5906 -5.0389 -v -2.6678 -0.5906 -4.7889 -v 8.1569 -0.5906 -5.0891 -v 8.1578 0.5906 -5.0071 -v -1.1601 -0.5906 -4.7835 -v -5.9888 0.5906 -4.7890 -v -5.9563 0.5906 -4.8135 -v -5.9412 -0.5906 -4.8287 -v 4.6063 0.5906 -4.5853 -v 4.6063 0.5906 -4.1066 -v 4.6063 -0.5906 -4.1066 -v -10.7527 -0.5906 -4.5215 -v -10.7176 -0.5906 -4.4236 -v -10.9270 -0.5906 -4.3339 -v -10.7514 0.5906 -4.5198 -v 4.8425 0.5906 -5.7503 -v 7.2955 0.5906 -5.3369 -v 7.2633 0.5906 -5.3778 -v 7.2806 -0.5906 -5.3525 -v 4.6063 -0.5906 -4.5853 -v -8.0627 -0.5906 -4.3759 -v -8.1320 -0.5906 -4.2890 -v -8.2996 -0.5906 -4.4738 -v -8.0661 0.5906 -4.3727 -v -8.2966 0.5906 -4.4792 -v -8.2398 -0.5906 -4.5636 -v 8.2967 0.5906 -4.6923 -v 8.2381 0.5906 -4.6438 -v 8.2542 -0.5906 -4.6537 -v -6.4607 0.5906 -5.1593 -v 4.6072 0.5906 -5.6145 -v 4.3752 0.5906 -5.6494 -v -2.3565 0.5906 -5.7642 -v -2.3563 0.5906 -5.9607 -v -2.4138 0.5906 -5.7858 -v 10.5884 0.5906 -5.7642 -v 10.5886 0.5906 -5.9607 -v 10.5311 0.5906 -5.7858 -v 10.0895 0.5906 -5.4427 -v -2.8554 0.5906 -5.4427 -v -2.1555 -0.5906 -4.0656 -v 10.7894 -0.5906 -4.0656 -v -3.6340 0.5906 -5.6442 -v 3.7213 0.5906 -5.6442 -v -10.4567 0.5906 -5.9893 -v -10.3087 0.5906 -5.9820 -v -10.3129 -0.5906 -5.9844 -v -8.7106 0.5906 -4.2930 -v -8.5567 0.5906 -4.3097 -v -8.5334 -0.5906 -4.3133 -v -1.2782 0.5906 -5.6584 -v -1.3202 0.5906 -5.5997 -v -1.3202 -0.5906 -5.5997 -v -3.8164 -0.5906 -5.7784 -v 3.5389 -0.5906 -5.7784 -v -8.1682 0.5906 -5.1955 -v -8.1864 0.5906 -5.2944 -v -5.2576 0.5906 -4.7623 -v -5.2957 0.5906 -4.5582 -v -5.0687 0.5906 -5.0300 -v -0.3739 0.5906 -5.5449 -v -0.6138 -0.5906 -5.5154 -v -0.3739 -0.5906 -5.5449 -v 7.4740 -0.5906 -5.4800 -v 7.4581 0.5906 -5.5161 -v 3.0206 0.5906 -5.1652 -v -4.3347 0.5906 -5.1652 -v 3.8150 0.5906 -5.3719 -v -3.5403 0.5906 -5.3719 -v 7.2372 0.5906 -4.9780 -v 7.4646 -0.5906 -5.0075 -v 7.2372 -0.5906 -4.9780 -v 2.2022 0.5906 -4.8441 -v 8.4596 0.5906 -5.9583 -v 3.3785 0.5906 -5.9860 -v 3.4939 0.5906 -5.9836 -v 3.4902 -0.5906 -5.9848 -v -3.9769 0.5906 -5.9860 -v -3.8614 0.5906 -5.9836 -v -3.8651 -0.5906 -5.9848 -v -4.0582 -0.5906 -4.7650 -v 3.2972 -0.5906 -4.7650 -v -10.3013 0.5906 -4.2700 -v -10.2439 -0.5906 -4.2983 -v -8.0208 0.5906 -5.5640 -v -8.2648 0.5906 -5.4966 -v -8.2284 0.5906 -5.4232 -v -8.2105 0.5906 -5.8019 -v -8.3583 0.5906 -5.6139 -v -8.1362 0.5906 -5.7302 -v 7.4812 0.5906 -5.4723 -v -0.6138 0.5906 -5.5154 -v -8.0083 0.5906 -4.4709 -v -8.2399 0.5906 -4.5662 -v -7.9179 0.5906 -5.2447 -v -8.1580 0.5906 -5.0862 -v -7.9012 0.5906 -5.0915 -v -6.1969 -0.5906 -4.7627 -v -3.4509 0.5906 -4.7688 -v -3.3703 0.5906 -4.8919 -v 3.9044 0.5906 -4.7688 -v 3.9850 0.5906 -4.8919 -v -10.4152 0.5906 -5.0355 -v -0.6202 0.5906 -4.6724 -v -0.6895 0.5906 -4.8948 -v -0.7503 0.5906 -4.8310 -v -8.1361 0.5906 -4.2861 -v -8.3608 0.5906 -4.4096 -v -8.2395 0.5906 -4.1960 -v -8.7076 0.5906 -4.0677 -v -5.7835 0.5906 -4.6485 -v -5.8223 0.5906 -4.6189 -v 1.6004 0.5906 -4.7801 -v 1.7314 0.5906 -4.8509 -v 1.7029 0.5906 -4.8813 -v -5.7050 0.5906 -4.7493 -v -5.9311 0.5906 -4.8459 -v -5.9080 0.5906 -4.5799 -v -6.0418 0.5906 -4.7668 -v -10.5639 0.5906 -5.0607 -v -2.2197 -0.5906 -5.6486 -v -2.1378 -0.5906 -5.7830 -v -2.1318 -0.5906 -5.3247 -v 10.8131 -0.5906 -5.3247 -v 10.7252 -0.5906 -5.6486 -v 10.8071 -0.5906 -5.7830 -v 2.3120 -0.5906 -4.6228 -v 1.6975 0.5906 -4.6702 -v 8.1494 -0.5906 -4.9313 -v 7.4646 0.5906 -5.0075 -v -10.9990 0.5906 -4.5469 -v -10.7657 0.5906 -4.5882 -v -10.7657 -0.5906 -4.5882 -v -1.6281 0.5906 -5.3296 -v -1.2106 0.5906 -5.7216 -v -1.4273 0.5906 -5.8273 -v -1.3446 -0.5906 -4.9822 -v -1.3029 -0.5906 -4.9064 -v -1.3423 0.5906 -4.9798 -v -11.0226 0.5906 -5.4593 -v 7.9336 0.5906 -5.3296 -v -1.1354 0.5906 -4.7750 -v -1.0542 0.5906 -4.7531 -v -1.0591 -0.5906 -4.7528 -v 10.4158 0.5906 -4.7490 -v 10.5001 -0.5906 -4.7525 -v 10.4111 -0.5906 -4.7480 -v 10.5038 -0.5906 -4.5621 -v -2.5338 -0.5906 -4.7480 -v -2.4448 -0.5906 -4.7525 -v -2.4411 -0.5906 -4.5621 -v -2.5290 0.5906 -4.7490 -v -5.1691 -0.5906 -4.5613 -v 7.8847 0.5906 -5.7802 -v 7.8736 0.5906 -5.9596 -v 7.8158 0.5906 -5.7970 -v 8.4176 0.5906 -5.8530 -v -10.6672 0.5906 -5.6989 -v -10.8571 0.5906 -5.8208 -v -10.7041 0.5906 -5.6540 -v -10.3566 -0.5906 -4.8395 -v -10.3366 -0.5906 -5.0387 -v -0.6384 0.5906 -5.5742 -v -0.4032 0.5906 -5.6303 -v -0.4554 0.5906 -5.7314 -v -10.1170 0.5906 -4.5260 -v -10.1463 0.5906 -4.6835 -v -9.9082 0.5906 -4.7044 -v -9.9528 0.5906 -4.7857 -v -6.1656 0.5906 -4.7592 -v 7.3366 0.5906 -5.8922 -v 7.4776 0.5906 -5.6999 -v -10.0856 0.5906 -4.9042 -v -10.0247 0.5906 -4.8618 -v -10.0128 -0.5906 -4.8534 -v 4.3730 0.5906 -4.2459 -v 4.3730 0.5906 -4.5853 -v 4.3730 -0.5906 -4.5853 -v -1.1878 -0.5906 -5.7399 -v -1.0317 -0.5906 -5.9870 -v 4.3730 -0.5906 -4.2459 -v 8.0246 -0.5906 -5.8959 -v 8.0480 0.5906 -5.8807 -v 7.4446 0.5906 -5.6018 -v 7.1971 0.5906 -5.6195 -v 7.1982 0.5906 -5.5534 -v 7.2720 0.5906 -5.8271 -v -10.5278 -0.5906 -5.7852 -v -10.5644 0.5906 -5.7706 -v 1.7171 0.5906 -4.8661 -v 1.7529 -0.5906 -4.8311 -v 1.7029 -0.5906 -4.8813 -v -3.5498 0.5906 -5.0983 -v -3.2971 0.5906 -5.2073 -v -3.3155 0.5906 -5.4881 -v 3.8056 0.5906 -5.0983 -v 4.0582 0.5906 -5.2073 -v 4.0398 0.5906 -5.4881 -v 7.2785 0.5906 -4.8464 -v 7.4828 0.5906 -4.9497 -v 7.2526 0.5906 -4.9183 -v 7.5266 0.5906 -4.6115 -v 7.5811 0.5906 -4.8049 -v 7.4574 0.5906 -4.6442 -v 7.5494 0.5906 -4.8339 -v -10.6962 0.5906 -4.3890 -v -10.8647 0.5906 -4.2455 -v -10.6622 0.5906 -4.3466 -v -10.9288 0.5906 -4.3403 -v -2.8563 0.5906 -5.0974 -v -2.8266 0.5906 -4.9836 -v -2.9834 0.5906 -4.7919 -v 10.0886 0.5906 -5.0974 -v 10.1183 0.5906 -4.9836 -v 9.9614 0.5906 -4.7919 -v -6.4872 0.5906 -4.5853 -v -6.4872 -0.5906 -4.5853 -v -1.3689 0.5906 -5.0674 -v -1.6208 0.5906 -5.1431 -v -1.5845 0.5906 -4.9771 -v 1.7794 0.5906 -4.8153 -v -0.4550 0.5906 -4.8626 -v -0.6519 0.5906 -4.9639 -v -0.5173 0.5906 -4.7714 -v 10.5293 0.5906 -4.5691 -v 10.5969 0.5906 -4.5917 -v -2.4156 0.5906 -4.5691 -v -2.3480 0.5906 -4.5917 -v 7.5299 0.5906 -5.4259 -v 7.3960 0.5906 -5.2579 -v 7.4675 0.5906 -5.2243 -v 7.4891 0.5906 -5.4625 -v 7.3376 0.5906 -5.2977 -v 8.1475 0.5906 -5.4888 -v 8.1482 -0.5906 -5.4879 -v 8.1609 -0.5906 -4.6028 -v 8.1004 -0.5906 -4.8338 -v 2.7864 0.5906 -5.1188 -v 3.0440 0.5906 -5.0420 -v -4.5689 0.5906 -5.1188 -v -4.3113 0.5906 -5.0420 -v 10.4593 0.5906 -5.9858 -v -2.4856 0.5906 -5.9858 -v -10.4390 0.5906 -5.7980 -v -10.7864 0.5906 -5.8821 -v -0.4230 0.5906 -4.9317 -v -0.4550 -0.5906 -4.8626 -v -5.6085 0.5906 -4.9369 -v -5.5697 -0.5906 -4.8708 -v -5.6105 -0.5906 -4.9380 -v -5.4327 -0.5906 -4.7747 -v 10.6586 0.5906 -5.7185 -v 10.6069 0.5906 -5.7553 -v -2.2863 0.5906 -5.7185 -v -2.3380 0.5906 -5.7553 -v -2.1374 0.5906 -5.1790 -v -2.1373 -0.5906 -5.1685 -v 10.8075 0.5906 -5.1790 -v 10.8076 -0.5906 -5.1685 -v -9.8776 0.5906 -4.5657 -v -10.1222 0.5906 -4.6085 -v -4.4022 0.5906 -5.8033 -v -4.0958 0.5906 -5.7625 -v -4.0085 0.5906 -5.7892 -v -4.1278 0.5906 -5.9634 -v 2.9531 0.5906 -5.8033 -v 3.2595 0.5906 -5.7625 -v 3.3469 0.5906 -5.7892 -v 3.2275 0.5906 -5.9634 -v -10.1626 -0.5906 -4.7139 -v -1.3113 0.5906 -5.9104 -v -1.0184 0.5906 -5.9860 -v -0.9998 0.5906 -5.7947 -v 10.4733 -0.5906 -5.7956 -v -2.4716 -0.5906 -5.7956 -v -10.4437 0.5906 -4.2495 -v -10.3709 -0.5906 -4.2518 -v -10.4481 -0.5906 -4.2489 -v -5.5266 0.5906 -4.6340 -v -5.5834 0.5906 -4.6780 -v -5.6046 -0.5906 -4.6964 -v 4.7429 -0.5906 -5.7607 -v 4.6961 -0.5906 -5.9767 -v 4.7990 -0.5906 -5.9688 -v 4.7548 0.5906 -5.9729 -v -10.6880 0.5906 -4.1104 -v -10.5808 0.5906 -4.0738 -v -10.2817 0.5906 -4.0737 -v 7.5193 0.5906 -5.9732 -v -4.0085 0.5906 -4.7543 -v -3.9129 0.5906 -4.7490 -v -3.8210 0.5906 -4.5652 -v -3.8218 0.5906 -4.7650 -v 3.3469 0.5906 -4.7543 -v 3.4424 0.5906 -4.7490 -v 3.5344 0.5906 -4.5652 -v 3.5335 0.5906 -4.7650 -v -0.6148 -0.5906 -4.6739 -v -4.8798 0.5906 -4.7657 -v -4.9293 0.5906 -4.6862 -v -4.9254 -0.5906 -4.6885 -v -8.2269 -0.5906 -5.8156 -v -8.1398 -0.5906 -5.7373 -v -8.3475 -0.5906 -5.6068 -v -6.4855 -0.5906 -4.7718 -v -6.4031 -0.5906 -4.9084 -v 10.6721 0.5906 -4.6319 -v 10.6185 0.5906 -4.6010 -v 10.6071 -0.5906 -4.5945 -v -2.2728 0.5906 -4.6319 -v -2.3264 0.5906 -4.6010 -v -2.3378 -0.5906 -4.5945 -v -3.4747 0.5906 -4.7409 -v -3.5512 -0.5906 -4.6726 -v -3.4441 -0.5906 -4.7735 -v 3.9112 -0.5906 -4.7735 -v 3.8042 -0.5906 -4.6726 -v 3.8806 0.5906 -4.7409 -v -10.3652 0.5906 -4.0601 -v -10.4929 0.5906 -4.0594 -v -10.4608 -0.5906 -4.0568 -v -10.0591 0.5906 -5.5575 -v -9.8094 0.5906 -5.5651 -v 4.6415 0.5906 -5.7298 -v 4.6729 0.5906 -5.7497 -v 4.5571 0.5906 -5.9593 -v -3.0993 0.5906 -5.4169 -v -3.0795 -0.5906 -5.5197 -v 9.8456 0.5906 -5.4169 -v 9.8654 -0.5906 -5.5197 -v 10.7455 0.5906 -4.9432 -v -2.1994 0.5906 -4.9432 -v 2.2060 0.5906 -4.8478 -v 2.2300 0.5906 -4.8822 -v 2.2294 -0.5906 -4.8803 -v -6.4872 0.5906 -4.7785 -v -1.2136 0.5906 -4.5908 -v -10.0511 0.5906 -5.5374 -v -10.0373 -0.5906 -5.4912 -v -5.1012 0.5906 -4.8678 -v -5.0866 0.5906 -4.9024 -v -5.0819 -0.5906 -4.9148 -v -10.0444 0.5906 -5.2962 -v 1.6004 0.5906 -4.5853 -v 1.6004 -0.5906 -4.5853 -v 2.4626 0.5906 -4.7964 -v 2.4394 0.5906 -4.7496 -v 2.4266 -0.5906 -4.7264 -v -5.9898 -0.5906 -4.7872 -v -8.3531 0.5906 -5.8860 -v -8.2918 0.5906 -5.8564 -v -8.2937 -0.5906 -5.8580 -v -10.1210 0.5906 -5.1543 -v -10.0696 0.5906 -4.9526 -v -9.9892 0.5906 -4.9917 -v 8.2542 0.5906 -4.6554 -v 8.1009 0.5906 -4.8356 -v 8.1871 0.5906 -4.6159 -v 8.1266 0.5906 -4.5916 -v 8.0646 0.5906 -4.8056 -v 8.0163 0.5906 -4.7806 -v -0.3750 0.5906 -5.1325 -v -0.6208 0.5906 -5.0709 -v -0.4106 0.5906 -4.9694 -v 6.4384 -0.5906 -5.6839 -v 10.2258 0.5906 -4.8263 -v 10.0198 0.5906 -4.7187 -v 10.0893 0.5906 -4.6583 -v 10.2956 0.5906 -4.7799 -v 10.3531 0.5906 -4.7580 -v -2.7191 0.5906 -4.8263 -v -2.9250 0.5906 -4.7187 -v -2.8555 0.5906 -4.6583 -v -2.6493 0.5906 -4.7799 -v -2.5918 0.5906 -4.7580 -v -10.6845 -0.5906 -4.1072 -v -10.5773 -0.5906 -4.0716 -v -7.9296 0.5906 -4.6998 -v -7.9629 0.5906 -4.5804 -v 1.6689 0.5906 -4.9407 -v -1.3700 0.5906 -4.6746 -v -1.2417 0.5906 -4.8404 -v -1.4754 0.5906 -4.7756 -v -1.2998 0.5906 -4.9040 -v -8.4318 0.5906 -4.3572 -v -8.3640 -0.5906 -4.4054 -v -10.5133 0.5906 -5.7874 -v 10.2354 0.5906 -5.7149 -v 10.1713 -0.5906 -5.6486 -v -2.7736 -0.5906 -5.6486 -v -2.7095 0.5906 -5.7149 -v 9.5669 0.5906 -4.3314 -v 9.5669 -0.5906 -4.0656 -v 9.5669 -0.5906 -4.3314 -v 9.3337 0.5906 -4.0656 -v 9.3337 -0.5906 -4.3314 -v 9.3337 -0.5906 -4.0656 -v 9.3337 0.5906 -4.3314 -v 9.5669 0.5906 -4.0656 -v -4.5055 0.5906 -5.6500 -v -4.2925 0.5906 -5.5540 -v 2.8498 0.5906 -5.6500 -v 3.0628 0.5906 -5.5540 -v -1.1060 0.5906 -4.5655 -v -0.8066 0.5906 -4.5806 -v -0.9514 0.5906 -4.5577 -v 7.5998 -0.5906 -4.7915 -v -5.5655 0.5906 -4.8677 -v -5.0815 0.5906 -4.9248 -v -1.5562 0.5906 -5.6507 -v -1.6065 0.5906 -5.5023 -v -11.0055 0.5906 -5.5558 -v -10.9670 -0.5906 -5.6688 -v -11.0080 -0.5906 -5.5521 -v -10.7681 -0.5906 -5.5153 -v -10.4181 -0.5906 -5.0349 -v -6.1067 0.5906 -4.7573 -v -6.1072 -0.5906 -4.7565 -v -1.5005 0.5906 -5.7468 -v -1.4537 0.5906 -5.8027 -v -10.0643 -0.5906 -4.9535 -v -0.4046 -0.5906 -5.6370 -v -4.2410 0.5906 -4.8979 -v -4.4717 0.5906 -4.8288 -v -4.4242 0.5906 -4.7644 -v -4.3680 0.5906 -4.7080 -v 3.1143 0.5906 -4.8979 -v 2.9873 0.5906 -4.7080 -v 2.8836 0.5906 -4.8288 -v 2.9311 0.5906 -4.7644 -v 7.8815 0.5906 -4.5562 -v 7.8496 0.5906 -4.7485 -v 7.7832 0.5906 -4.5582 -v 10.0222 -0.5906 -4.7149 -v -2.9227 -0.5906 -4.7149 -v -2.2242 0.5906 -5.6524 -v -2.1378 0.5906 -5.7830 -v 10.7207 0.5906 -5.6524 -v 10.8071 0.5906 -5.7830 -v -10.5154 0.5906 -4.2599 -v -10.4615 0.5906 -4.0581 -v 6.4385 0.5906 -5.6842 -v -1.0910 0.5906 -5.7801 -v -1.1537 0.5906 -5.7569 -v 3.9685 0.5906 -4.8582 -v 3.9282 0.5906 -4.7967 -v -3.3868 0.5906 -4.8582 -v -3.4271 0.5906 -4.7967 -v 4.8425 0.5906 -4.7654 -v 4.8425 -0.5906 -4.7654 -v -4.4717 -0.5906 -4.8288 -v 2.8836 -0.5906 -4.8288 -v -0.6413 0.5906 -4.9899 -v -0.6212 -0.5906 -5.0647 -v 10.1711 0.5906 -5.6457 -v -2.7738 0.5906 -5.6457 -v 4.8425 0.5906 -4.5853 -v 4.8425 -0.5906 -4.5853 -v -5.6849 -0.5906 -4.7953 -v -5.9064 -0.5906 -4.8953 -v -6.3968 0.5906 -4.9011 -v 1.6004 -0.5906 -4.7801 -v 2.0621 0.5906 -4.5569 -v 2.0250 0.5906 -4.7587 -v -0.6925 0.5906 -5.6630 -v 4.6489 -0.5906 -5.7382 -v -10.1825 0.5906 -5.0996 -v -10.1376 0.5906 -4.9317 -v -10.2537 0.5906 -5.0614 -v 2.4716 0.5906 -4.8221 -v -7.9422 0.5906 -5.3595 -v -6.0094 0.5906 -4.5590 -v -8.1745 0.5906 -5.2332 -v -0.5234 0.5906 -5.8170 -v -0.4574 -0.5906 -5.7368 -v -0.5258 -0.5906 -5.8214 -v -0.6844 -0.5906 -5.6557 -v 8.1732 0.5906 -5.7871 -v 8.1904 0.5906 -5.8788 -v 8.1829 -0.5906 -5.8520 -v -5.6849 0.5906 -4.7953 -v -5.9056 0.5906 -4.8997 -v -4.0927 -0.5906 -5.7654 -v 3.2626 -0.5906 -5.7654 -v 8.0952 0.5906 -5.6273 -v 8.0555 0.5906 -5.6765 -v -3.8662 0.5906 -4.7544 -v -3.7796 0.5906 -4.7811 -v -3.7828 -0.5906 -4.7781 -v 3.4891 0.5906 -4.7544 -v 3.5757 0.5906 -4.7811 -v 3.5725 -0.5906 -4.7781 -v -10.1706 0.5906 -5.9468 -v -0.6370 -0.5906 -5.5727 -v 4.6787 0.5906 -5.9756 -v -10.7694 0.5906 -5.5082 -v -10.9634 0.5906 -5.6725 -v 4.7575 0.5906 -5.7600 -v 10.2771 0.5906 -4.7889 -v -2.6678 0.5906 -4.7889 -v -5.4615 0.5906 -4.7880 -v -5.6098 0.5906 -4.7049 -v -3.1006 -0.5906 -5.4132 -v -2.8550 -0.5906 -5.4516 -v 10.0899 -0.5906 -5.4515 -v 9.8443 -0.5906 -5.4132 -v 3.1255 0.5906 -5.9276 -v 3.2190 -0.5906 -5.9631 -v -4.2298 0.5906 -5.9276 -v -4.1363 -0.5906 -5.9631 -v -0.6725 -0.5906 -4.9187 -v -0.6423 -0.5906 -4.9846 -v -0.6711 0.5906 -4.9230 -v 7.5128 0.5906 -4.8846 -v 7.5478 -0.5906 -4.8345 -v 7.5115 -0.5906 -4.8854 -v -3.4124 0.5906 -5.7301 -v -3.3747 0.5906 -5.6685 -v -3.3551 -0.5906 -5.6303 -v 3.9429 0.5906 -5.7301 -v 3.9806 0.5906 -5.6685 -v 4.0002 -0.5906 -5.6303 -v 7.2661 -0.5906 -4.8724 -v 4.2018 0.5906 -4.5853 -v 4.2018 -0.5906 -4.7654 -v 4.2018 -0.5906 -4.5853 -v 4.2018 0.5906 -4.7654 -v 7.7795 0.5906 -5.8018 -v 8.1572 0.5906 -5.0873 -v -10.7236 0.5906 -4.4401 -v 4.4024 -0.5906 -5.8358 -v 4.4513 -0.5906 -5.9022 -v 4.4158 0.5906 -5.8572 -v -4.2883 0.5906 -4.6505 -v -4.3960 -0.5906 -4.7324 -v -4.2839 -0.5906 -4.6459 -v -4.1768 -0.5906 -4.8296 -v 3.1785 -0.5906 -4.8296 -v 3.0715 -0.5906 -4.6459 -v 2.9593 -0.5906 -4.7324 -v 3.0671 0.5906 -4.6505 -v 3.7984 0.5906 -4.6710 -v -3.5569 0.5906 -4.6710 -v -7.8986 -0.5906 -4.9682 -v -8.1560 -0.5906 -4.9420 -v -8.1565 0.5906 -4.9568 -v -10.3515 0.5906 -5.7931 -v -10.4357 -0.5906 -5.7990 -v -9.9179 0.5906 -4.7274 -v -9.8857 0.5906 -4.6331 -v -9.8893 -0.5906 -4.6540 -v 7.4533 0.5906 -5.6509 -v 7.4465 -0.5906 -5.6332 -v -3.5930 0.5906 -5.5780 -v -3.6293 -0.5906 -5.6405 -v -3.5930 -0.5906 -5.5780 -v -3.4289 -0.5906 -5.7555 -v 3.7623 0.5906 -5.5780 -v 3.7260 -0.5906 -5.6405 -v 3.7623 -0.5906 -5.5780 -v 3.9265 -0.5906 -5.7555 -v -7.9719 0.5906 -5.4522 -v 1.9574 0.5906 -4.5603 -v 1.9242 -0.5906 -4.5642 -v -4.2820 0.5906 -4.9632 -v -4.2457 -0.5906 -4.9015 -v -4.2820 -0.5906 -4.9632 -v 3.0733 -0.5906 -4.9632 -v 3.1096 -0.5906 -4.9015 -v 3.0733 0.5906 -4.9632 -v 8.3369 0.5906 -4.7508 -v 3.6498 -0.5906 -4.8248 -v -3.7055 -0.5906 -4.8248 -v 10.3890 0.5906 -4.5567 -v -2.5559 0.5906 -4.5567 -v -4.1703 -0.5906 -5.7188 -v 3.1850 -0.5906 -5.7188 -v -8.2458 0.5906 -5.4611 -v -8.2854 0.5906 -5.5295 -v 8.0066 0.5906 -5.7188 -v 8.1192 0.5906 -5.8310 -v 8.0217 0.5906 -5.8960 -v 7.6906 0.5906 -4.5681 -v 7.6819 0.5906 -4.7623 -v 7.5819 0.5906 -5.7812 -v -2.3265 0.5906 -5.9502 -v -2.2718 0.5906 -5.9209 -v -2.2718 -0.5906 -5.9209 -v 10.6184 0.5906 -5.9502 -v 10.6731 0.5906 -5.9209 -v 10.6731 -0.5906 -5.9209 -v -8.3869 0.5906 -5.8983 -v -10.0034 0.5906 -4.2289 -v -2.8171 -0.5906 -4.9581 -v -2.9814 -0.5906 -4.7872 -v 10.1278 -0.5906 -4.9581 -v 9.9634 -0.5906 -4.7872 -v 4.7188 0.5906 -5.7593 -v 10.1212 0.5906 -5.5551 -v 10.1226 -0.5906 -5.5623 -v -2.8236 0.5906 -5.5551 -v -2.8223 -0.5906 -5.5623 -v -8.5348 0.5906 -5.9376 -v 7.2099 -0.5906 -5.7073 -v -9.9647 -0.5906 -5.0056 -v -10.1696 -0.5906 -5.1065 -v 7.4807 -0.5906 -5.7078 -v 7.4907 0.5906 -4.6270 -v 7.4268 0.5906 -4.6631 -v 7.4139 -0.5906 -4.6705 -v -2.2251 0.5906 -4.6681 -v -2.2893 0.5906 -4.8295 -v 10.7198 0.5906 -4.6681 -v 10.6556 0.5906 -4.8295 -v -1.5718 0.5906 -4.9388 -v -1.6063 0.5906 -5.0570 -v -1.5833 -0.5906 -4.9672 -v -3.6805 0.5906 -4.6030 -v 3.6748 0.5906 -4.6030 -v -0.6764 0.5906 -5.6417 -v -6.3000 0.5906 -4.6088 -v -6.2186 0.5906 -4.7697 -v -6.2692 0.5906 -4.7887 -v 7.4489 0.5906 -5.5475 -v -1.4990 0.5906 -4.8044 -v -1.5390 -0.5906 -4.8684 -v -9.9544 -0.5906 -4.7890 -v -10.7353 0.5906 -5.5979 -v 7.3606 -0.5906 -5.2781 -v 8.0161 0.5906 -4.5663 -v 8.0445 -0.5906 -4.5700 -v -9.7901 0.5906 -5.3225 -v -9.7889 -0.5906 -5.3252 -v 1.9208 0.5906 -4.5672 -v -6.4118 0.5906 -4.6881 -v -6.4574 0.5906 -4.7375 -v -3.9904 -0.5906 -5.9869 -v 3.3649 -0.5906 -5.9869 -v 7.4641 0.5906 -5.5009 -v 7.2277 0.5906 -5.4423 -v 7.2794 0.5906 -5.3574 -v -7.9279 -0.5906 -4.7039 -v -10.6922 0.5906 -5.6697 -v -10.7335 -0.5906 -5.6039 -v -10.6899 -0.5906 -5.6744 -v -1.3800 0.5906 -5.4233 -v -9.8094 -0.5906 -5.5719 -v -8.3883 -0.5906 -5.9011 -v -8.4366 -0.5906 -5.6688 -v 8.0321 -0.5906 -4.7856 -v -5.1985 0.5906 -4.7799 -v 7.4696 -0.5906 -5.2218 -v 7.5261 -0.5906 -5.4264 -v -8.5049 0.5906 -4.3235 -v -8.4911 0.5906 -4.0891 -v -8.4063 0.5906 -4.1119 -v 4.7712 0.5906 -5.7589 -v 8.3980 0.5906 -5.7381 -v 8.4007 -0.5906 -5.7876 -v 2.4741 -0.5906 -4.8235 -v -3.5637 0.5906 -5.4977 -v 3.7916 0.5906 -5.4977 -v -1.2466 0.5906 -4.6045 -v -10.5885 0.5906 -5.9712 -v -6.3170 0.5906 -4.8161 -v -6.0911 0.5906 -4.5564 -v -1.2770 -0.5906 -5.6618 -v 10.4643 0.5906 -4.5584 -v -2.4806 0.5906 -4.5584 -v -1.1751 0.5906 -5.9633 -v 7.1984 0.5906 -5.6434 -v 7.1960 -0.5906 -5.6201 -v -10.0308 -0.5906 -5.3760 -v -9.7863 -0.5906 -5.4443 -v -5.1811 0.5906 -4.7897 -v -2.2836 -0.5906 -5.7178 -v 10.6613 -0.5906 -5.7178 -v -3.8211 0.5906 -5.7785 -v 3.5342 0.5906 -5.7785 -v 4.0362 0.5906 -5.0381 -v -3.3191 0.5906 -5.0381 -v 3.0300 0.5906 -5.4415 -v 3.0304 -0.5906 -5.4503 -v -4.3253 0.5906 -5.4415 -v -4.3250 -0.5906 -5.4503 -v -10.4640 -0.5906 -5.9904 -v 8.3800 0.5906 -4.8800 -v 8.3667 0.5906 -4.8199 -v 8.3755 -0.5906 -4.8476 -v -8.4015 -0.5906 -4.1127 -v -8.5157 -0.5906 -4.0833 -v -0.6071 0.5906 -5.8870 -v -3.5827 0.5906 -4.9884 -v -3.5501 -0.5906 -5.0899 -v 3.7726 0.5906 -4.9884 -v 3.8052 -0.5906 -5.0899 -v -2.6559 0.5906 -5.9713 -v 10.2890 0.5906 -5.9713 -v 2.1378 0.5906 -4.7930 -v 4.6209 0.5906 -5.7017 -v 4.3977 0.5906 -5.8197 -v 4.3849 0.5906 -5.7647 -v 10.7853 0.5906 -5.0489 -v -2.1595 0.5906 -5.0489 -v -5.0784 0.5906 -4.5846 -v -10.0051 0.5906 -4.8438 -v -10.1765 0.5906 -4.7312 -v -10.1991 0.5906 -5.0879 -v 2.7991 0.5906 -5.4981 -v -4.5562 0.5906 -5.4981 -v 7.6676 0.5906 -5.8016 -v 7.6365 0.5906 -5.9867 -v -9.9564 0.5906 -4.2886 -v -10.0004 -0.5906 -4.2310 -v -10.0567 -0.5906 -4.1790 -v -3.3641 0.5906 -5.6457 -v 3.9912 0.5906 -5.6457 -v -9.9185 -0.5906 -4.7301 -v -10.1657 0.5906 -4.7159 -v -10.2188 0.5906 -4.7703 -v -10.2122 -0.5906 -4.7667 -v -0.5107 -0.5906 -4.7761 -v -1.5603 -0.5906 -5.6472 -v -1.5976 0.5906 -5.5425 -v -10.7833 0.5906 -4.1681 -v -1.1912 0.5906 -4.8022 -v 7.9230 -0.5906 -5.7680 -v 7.9387 -0.5906 -4.7569 -v -1.2452 -0.5906 -4.8419 -v -1.3655 -0.5906 -4.6686 -v -6.4420 0.5906 -5.0159 -v -6.4204 0.5906 -4.9457 -v -6.4417 -0.5906 -5.0051 -v -2.1764 0.5906 -5.5653 -v 10.7685 0.5906 -5.5653 -v -10.3465 -0.5906 -5.7934 -v 3.2595 0.5906 -4.7809 -v -4.0958 0.5906 -4.7809 -v -10.6119 -0.5906 -4.3023 -v 2.0694 -0.5906 -4.5558 -v -10.6652 -0.5906 -4.3484 -v -10.8624 -0.5906 -4.2405 -v -5.6362 0.5906 -4.7318 -v 7.5441 0.5906 -5.4162 -v 7.5998 0.5906 -5.3933 -v 7.5894 -0.5906 -5.3951 -v -2.7218 -0.5906 -4.8270 -v -2.8536 -0.5906 -4.6557 -v 10.2231 -0.5906 -4.8270 -v 10.0912 -0.5906 -4.6557 -v -8.5369 -0.5906 -5.9399 -v -8.4946 0.5906 -5.9303 -v 4.6199 -0.5906 -5.7024 -v -0.7158 0.5906 -4.8638 -v 10.0759 0.5906 -5.2351 -v 9.8391 0.5906 -5.1871 -v -2.8690 0.5906 -5.2351 -v -3.1058 0.5906 -5.1871 -v -5.8631 -0.5906 -4.5959 -v -5.9292 -0.5906 -4.5722 -v -5.8668 0.5906 -4.5950 -v 8.0765 0.5906 -5.6528 -v -5.8894 0.5906 -4.9662 -v -8.4207 0.5906 -5.9107 -v -8.4350 -0.5906 -4.3541 -v -1.5724 0.5906 -5.6166 -v -1.5400 0.5906 -5.6847 -v 2.2530 -0.5906 -4.9362 -v 2.8082 0.5906 -5.5394 -v 2.8335 0.5906 -5.6153 -v 2.8459 -0.5906 -5.6467 -v -4.5471 0.5906 -5.5394 -v -4.5218 0.5906 -5.6153 -v -4.5095 -0.5906 -5.6467 -v 3.6831 0.5906 -5.9357 -v -3.6722 0.5906 -5.9357 -v -6.3844 -0.5906 -4.6619 -v -10.6627 0.5906 -4.0987 -v 1.8617 -0.5906 -4.7743 -v 8.3397 -0.5906 -4.7514 -v 8.1298 -0.5906 -4.8752 -v 10.0801 0.5906 -5.1633 -v 10.1013 0.5906 -5.0376 -v -2.8648 0.5906 -5.1633 -v -2.8436 0.5906 -5.0376 -v -8.3076 0.5906 -5.5599 -v -4.8775 -0.5906 -4.7673 -v -5.1017 -0.5906 -4.8661 -v 7.3987 0.5906 -4.6837 -v -2.7198 0.5906 -5.9501 -v -2.6181 -0.5906 -5.9806 -v 10.2251 0.5906 -5.9501 -v 10.3267 -0.5906 -5.9806 -v -8.5701 0.5906 -4.0770 -v -8.5773 0.5906 -4.3062 -v -3.0307 0.5906 -4.8778 -v -3.0285 -0.5906 -4.8710 -v 9.9142 0.5906 -4.8778 -v 9.9163 -0.5906 -4.8710 -v 4.0271 0.5906 -4.9986 -v 4.0015 0.5906 -4.9256 -v 3.9892 -0.5906 -4.8956 -v -3.3282 0.5906 -4.9986 -v -3.3539 0.5906 -4.9256 -v -3.3661 -0.5906 -4.8956 -v -6.4479 0.5906 -5.0422 -v -10.0742 0.5906 -5.2207 -v -2.1775 0.5906 -5.8373 -v -2.2035 -0.5906 -5.8672 -v 10.7674 0.5906 -5.8373 -v 10.7414 -0.5906 -5.8672 -v -7.9609 -0.5906 -4.5835 -v -3.0439 0.5906 -5.6217 -v -2.9984 0.5906 -5.7110 -v -3.0010 -0.5906 -5.7085 -v 9.9010 0.5906 -5.6217 -v 9.9464 0.5906 -5.7110 -v 9.9439 -0.5906 -5.7086 -v 7.3332 -0.5906 -5.8912 -v -4.0534 0.5906 -4.7650 -v 3.3020 0.5906 -4.7650 -v 1.8308 0.5906 -4.7873 -v 1.8165 0.5906 -4.5970 -v -3.5841 -0.5906 -4.9815 -v -3.3162 -0.5906 -5.0417 -v 4.0392 -0.5906 -5.0417 -v 3.7712 -0.5906 -4.9815 -v -5.5091 0.5906 -4.8165 -v -9.8916 0.5906 -5.0760 -v -9.9365 0.5906 -5.0296 -v 3.6418 0.5906 -4.5898 -v -3.7135 0.5906 -4.5898 -v -2.6113 0.5906 -4.7644 -v 10.3336 0.5906 -4.7644 -v 2.3751 0.5906 -4.6692 -v 2.3308 0.5906 -4.6358 -v -4.3205 0.5906 -5.8730 -v 3.0348 0.5906 -5.8730 -v 10.4691 0.5906 -5.7946 -v -2.4758 0.5906 -5.7946 -v 2.2473 0.5906 -4.9218 -v -1.1384 0.5906 -5.9727 -v -1.0882 -0.5906 -5.7822 -v -8.0064 0.5906 -5.5357 -v 10.6523 -0.5906 -4.8251 -v 10.7015 -0.5906 -4.6513 -v 10.7617 0.5906 -4.7095 -v -2.2926 -0.5906 -4.8251 -v -2.2433 -0.5906 -4.6513 -v -2.1832 0.5906 -4.7095 -v 1.6383 0.5906 -5.0430 -v -4.5242 -0.5906 -4.9305 -v 2.8311 -0.5906 -4.9305 -v 10.3295 -0.5906 -4.7645 -v -2.6154 -0.5906 -4.7645 -v -5.8367 0.5906 -4.6105 -v -0.8068 0.5906 -4.7914 -v -10.0774 0.5906 -5.5966 -v -2.5568 -0.5906 -5.7912 -v 10.3880 -0.5906 -5.7912 -v 9.8364 0.5906 -5.3026 -v 9.8356 -0.5906 -5.2993 -v -3.1085 0.5906 -5.3026 -v -3.1093 -0.5906 -5.2993 -v -10.1522 0.5906 -4.3981 -v -9.9199 0.5906 -4.3545 -v -10.1276 0.5906 -4.4585 -v -10.9175 -0.5906 -5.7511 -v -10.3690 0.5906 -4.2529 -v 7.7261 0.5906 -5.9855 -v -10.4389 0.5906 -4.8556 -v 4.6115 0.5906 -5.6685 -v -2.8135 0.5906 -5.5804 -v 10.1314 0.5906 -5.5804 -v 7.9401 0.5906 -4.7581 -v 4.5758 -0.5906 -5.9656 -v 2.8145 0.5906 -4.9818 -v -4.5408 0.5906 -4.9818 -v 2.2594 0.5906 -4.9708 -v -0.7951 -0.5906 -5.7536 -v -5.4658 0.5906 -4.5998 -v -3.0463 -0.5906 -5.6181 -v 9.8986 -0.5906 -5.6181 -v 8.0556 0.5906 -4.5730 -v -0.7987 -0.5906 -4.5808 -v -10.0877 0.5906 -5.6157 -v -4.2911 -0.5906 -5.5612 -v -4.5590 -0.5906 -5.4948 -v 2.7963 -0.5906 -5.4948 -v 3.0642 -0.5906 -5.5612 -v -8.3729 0.5906 -5.6268 -v -8.4178 0.5906 -5.6571 -v -3.3447 0.5906 -5.5978 -v -3.3161 -0.5906 -5.4963 -v 4.0106 0.5906 -5.5978 -v 4.0392 -0.5906 -5.4963 -v -10.4742 0.5906 -5.0414 -v 7.9174 0.5906 -5.7682 -v 7.8509 0.5906 -5.7898 -v -10.1381 0.5906 -4.4274 -v -10.1205 0.5906 -4.4913 -v -4.5624 0.5906 -5.0704 -v 2.7929 0.5906 -5.0704 -v 10.2213 -0.5906 -5.9495 -v -2.7236 -0.5906 -5.9495 -v -6.3594 0.5906 -4.6451 -v 1.6670 -0.5906 -4.9409 -v -8.1602 0.5906 -5.7567 -v 8.1265 0.5906 -5.5674 -v 7.5648 0.5906 -4.5978 -v 7.5420 0.5906 -5.1995 -v 7.7062 0.5906 -5.3684 -v -0.7187 -0.5906 -4.8588 -v -5.1637 0.5906 -4.7996 -v -5.1342 0.5906 -4.8239 -v -5.1285 -0.5906 -4.8287 -v -10.4986 -0.5906 -5.0451 -v 7.4881 0.5906 -5.7151 -v -4.8483 0.5906 -4.8651 -v 2.4928 0.5906 -4.8992 -v 3.0060 0.5906 -5.8523 -v 3.0635 0.5906 -5.8937 -v 3.0289 -0.5906 -5.8713 -v -4.3493 0.5906 -5.8523 -v -4.2918 0.5906 -5.8937 -v -4.3264 -0.5906 -5.8713 -v -10.4346 -0.5906 -4.8558 -v -0.5404 0.5906 -4.7431 -v -0.5922 0.5906 -4.6934 -v 10.7706 -0.5906 -5.5638 -v -2.1743 -0.5906 -5.5637 -v 10.7451 0.5906 -5.8603 -v -2.1998 0.5906 -5.8603 -v -1.5390 0.5906 -4.8684 -v 7.6754 0.5906 -5.1757 -v 7.5540 0.5906 -5.1970 -v 3.6571 -0.5906 -5.7132 -v 3.7684 -0.5906 -5.8936 -v -3.6982 -0.5906 -5.7132 -v -3.5869 -0.5906 -5.8936 -v 7.9488 0.5906 -5.7539 -v 7.2359 0.5906 -5.4238 -v -2.7767 0.5906 -4.6112 -v 10.1681 0.5906 -4.6112 -v -10.1161 -0.5906 -4.5646 -v -5.6359 0.5906 -5.0250 -v -8.1975 -0.5906 -4.6655 -v 7.6193 0.5906 -4.7833 -v 4.6133 0.5906 -5.9707 -v -5.1250 0.5906 -4.8343 -v -5.9336 0.5906 -4.5719 -v 7.7644 0.5906 -5.1640 -v -4.2298 -0.5906 -5.9276 -v 3.1255 -0.5906 -5.9276 -v 7.6050 0.5906 -4.5859 -v -8.3190 -0.5906 -4.1469 -v 7.2680 -0.5906 -5.8242 -v 8.3485 0.5906 -4.7720 -v 8.3253 0.5906 -4.7295 -v 1.8842 0.5906 -4.5741 -v -1.3705 -0.5906 -5.0698 -v 2.4942 0.5906 -4.9114 -v 2.4806 0.5906 -4.8477 -v -0.7448 0.5906 -5.7186 -v -8.5997 0.5906 -5.7193 -v 10.3907 -0.5906 -4.5558 -v -2.5542 -0.5906 -4.5558 -v -9.8771 -0.5906 -4.5693 -v -2.8014 0.5906 -5.9095 -v 10.1434 0.5906 -5.9095 -v -0.6108 -0.5906 -5.8912 -v -0.7420 -0.5906 -5.7173 -v 4.7152 0.5906 -5.7592 -v 4.6931 -0.5906 -5.7568 -v -10.1749 -0.5906 -5.9505 -v 1.6368 -0.5906 -5.0435 -v -10.9175 0.5906 -5.7511 -v -8.0056 -0.5906 -4.4742 -v 4.4405 0.5906 -5.8894 -v 4.3875 0.5906 -5.7814 -v 4.3846 -0.5906 -5.7661 -v -1.3429 0.5906 -5.8934 -v -8.2708 0.5906 -5.8438 -v -8.4893 0.5906 -4.3287 -v 3.8272 0.5906 -4.6918 -v -3.5281 0.5906 -4.6918 -v -1.2797 0.5906 -4.6181 -v -1.3414 0.5906 -4.6532 -v -10.0744 -0.5906 -5.5937 -v 2.1547 0.5906 -4.5671 -v 2.1172 0.5906 -4.7827 -v -5.5121 -0.5906 -4.8173 -v -0.3981 0.5906 -5.0070 -v -0.4073 -0.5906 -4.9728 -v -6.4311 0.5906 -4.9745 -v -0.7087 0.5906 -5.6842 -v -4.5652 0.5906 -5.4568 -v 2.7901 0.5906 -5.4568 -v 7.4455 0.5906 -5.5636 -v 7.9779 0.5906 -5.9198 -v 7.6247 -0.5906 -5.9872 -v -1.0686 0.5906 -4.5597 -v -8.1985 0.5906 -5.3399 -v 2.3777 -0.5906 -4.6708 -v 2.1981 -0.5906 -4.8377 -v 3.5962 0.5906 -4.7904 -v -3.7591 0.5906 -4.7904 -v -8.5749 0.5906 -5.9448 -v 3.8993 0.5906 -5.7860 -v -3.4560 0.5906 -5.7860 -v 8.3856 0.5906 -4.9447 -v -1.5005 -0.5906 -5.7468 -v -6.0044 -0.5906 -4.5588 -v 1.6462 0.5906 -4.7206 -v 3.7936 -0.5906 -5.4960 -v -3.5617 -0.5906 -5.4960 -v 2.1752 0.5906 -4.8180 -v -10.1504 0.5906 -5.1251 -v 10.7844 -0.5906 -5.0400 -v -2.1605 -0.5906 -5.0400 -v 7.4817 -0.5906 -4.9507 -v 7.9291 0.5906 -4.5579 -v -5.0764 0.5906 -4.9471 -v -2.3861 0.5906 -5.9711 -v 10.5587 0.5906 -5.9711 -v 7.9433 0.5906 -5.9354 -v -8.3314 0.5906 -5.5878 -v 4.0454 0.5906 -5.0775 -v -3.3099 0.5906 -5.0775 -v 7.7420 0.5906 -5.8042 -v -5.7033 -0.5906 -4.7511 -v -3.3358 0.5906 -5.5727 -v 4.0195 0.5906 -5.5727 -v 8.2982 -0.5906 -4.6931 -v -4.8466 -0.5906 -4.8668 -v 7.6339 0.5906 -5.7966 -v -4.3133 -0.5906 -5.0438 -v 3.0420 -0.5906 -5.0438 -v -10.7864 -0.5906 -5.8821 -v 2.4961 -0.5906 -4.9170 -v 2.8447 0.5906 -4.9013 -v -4.5106 0.5906 -4.9013 -v -5.6373 -0.5906 -5.0263 -v 7.3526 0.5906 -5.2857 -v 7.8740 0.5906 -5.3415 -v -5.2784 0.5906 -4.7585 -v 2.4110 0.5906 -4.7071 -v 8.3895 -0.5906 -5.5467 -v -2.9458 -0.5906 -5.7867 -v 9.9990 -0.5906 -5.7867 -v 7.5156 0.5906 -5.4357 -v -6.0428 -0.5906 -4.7656 -v 7.9739 0.5906 -4.5612 -v 10.7227 0.5906 -5.8833 -v -2.2221 0.5906 -5.8833 -v 8.1336 0.5906 -5.5487 -v -0.4942 0.5906 -4.7998 -v -5.3321 0.5906 -4.5606 -# 1634 vertices - -vn 0.7994 0.0021 -0.6008 -vn -0.9847 -0.0014 0.1745 -vn -0.6809 -0.0006 0.7323 -vn 0.6420 0.0010 -0.7667 -vn -0.8881 0.0010 0.4596 -vn -0.3124 0.0006 -0.9500 -vn 0.9997 -0.0001 0.0250 -vn 0.0041 0.0013 1.0000 -vn -0.9334 0.0000 -0.3587 -vn 1.0000 0.0008 0.0043 -vn -0.9997 -0.0005 0.0264 -vn -0.9987 -0.0025 0.0514 -vn 0.9996 -0.0005 -0.0270 -vn 0.9998 0.0003 -0.0213 -vn -0.9990 -0.0018 0.0457 -vn 0.9641 -0.0006 0.2656 -vn -0.9705 0.0004 0.2410 -vn -0.8252 0.0000 -0.5648 -vn 1.0000 0.0000 0.0000 -vn 0.9997 -0.0004 -0.0232 -vn -0.9705 0.0004 0.2409 -vn -0.1360 0.0006 0.9907 -vn 0.2615 -0.0015 -0.9652 -vn 0.0000 -0.0001 -1.0000 -vn -0.9992 0.0046 -0.0391 -vn -1.0000 0.0000 0.0000 -vn -0.9234 0.0019 0.3837 -vn 0.9851 -0.0008 -0.1720 -vn -0.7094 0.0011 -0.7048 -vn -0.2433 -0.0011 0.9700 -vn 0.1515 -0.0013 -0.9885 -vn -0.8439 0.0000 -0.5366 -vn 1.0000 0.0029 -0.0020 -vn -0.8439 -0.0000 -0.5365 -vn 0.9774 0.0003 0.2114 -vn -0.8570 0.0019 -0.5153 -vn 0.8002 -0.0000 -0.5998 -vn -0.3284 0.0012 -0.9445 -vn -0.3701 -0.0000 0.9290 -vn -0.8601 0.0031 -0.5102 -vn 0.9808 -0.0011 0.1950 -vn -0.2179 0.0004 0.9760 -vn -0.9780 -0.0015 -0.2088 -vn 0.5596 -0.0000 -0.8287 -vn -0.5646 -0.0000 0.8254 -vn 0.5596 0.0000 -0.8287 -vn 0.8670 -0.0017 -0.4983 -vn -0.9950 -0.0012 0.0999 -vn -0.2532 0.0020 0.9674 -vn 0.5328 0.0025 0.8463 -vn 0.6313 -0.0003 -0.7755 -vn -0.2340 -0.0019 0.9722 -vn -0.2511 -0.0017 0.9680 -vn 0.0519 0.0015 -0.9987 -vn -1.0000 0.0015 -0.0032 -vn 1.0000 -0.0000 0.0011 -vn 0.3654 -0.0008 0.9309 -vn 0.1437 -0.0012 -0.9896 -vn 0.7818 -0.0007 -0.6235 -vn -0.0616 -0.0010 0.9981 -vn -1.0000 0.0000 -0.0012 -vn 1.0000 0.0007 0.0020 -vn -0.3383 0.0005 0.9410 -vn 0.0000 0.0000 -1.0000 -vn -0.3206 0.0014 -0.9472 -vn -0.5758 -0.0027 0.8176 -vn -0.2997 0.0000 0.9540 -vn 0.4971 0.0000 0.8677 -vn -0.2584 -0.0021 0.9660 -vn 0.9995 0.0008 0.0315 -vn 0.0693 -0.0025 0.9976 -vn 0.2855 0.0020 -0.9584 -vn 0.4944 -0.0010 0.8692 -vn 0.3102 0.0005 -0.9507 -vn 0.0453 -0.0006 0.9990 -vn 0.3452 -0.0000 -0.9385 -vn 0.0114 -0.0016 -0.9999 -vn -0.5779 0.0022 0.8161 -vn -0.0460 -0.0006 -0.9989 -vn -0.1283 0.0009 0.9917 -vn -0.8829 -0.0006 -0.4696 -vn 0.9276 0.0006 0.3736 -vn 0.2478 0.0013 -0.9688 -vn 0.0000 0.0000 1.0000 -vn -0.1651 -0.0009 -0.9863 -vn 0.0000 -1.0000 -0.0000 -vn 0.0001 0.0000 -1.0000 -vn -0.4876 -0.0014 0.8731 -vn -0.0394 -0.0003 0.9992 -vn 0.1895 0.0008 -0.9819 -vn -0.0027 -0.0000 -1.0000 -vn 0.0017 0.0006 1.0000 -vn 0.3221 -0.0016 0.9467 -vn 0.4911 0.0025 -0.8711 -vn -0.3826 -0.0009 0.9239 -vn 1.0000 0.0000 -0.0008 -vn -1.0000 0.0017 -0.0028 -vn 0.0000 1.0000 0.0000 -vn -0.0000 -1.0000 -0.0000 -vn 1.0000 -0.0000 0.0005 -vn 0.7174 -0.0016 0.6967 -vn -0.7159 -0.0016 -0.6982 -vn -1.0000 0.0000 -0.0006 -vn -0.5896 0.0005 -0.8077 -vn 0.2800 0.0003 0.9600 -vn 0.5855 0.0011 -0.8106 -vn -0.7069 0.0041 -0.7073 -vn -0.9398 -0.0000 0.3417 -vn -0.9360 0.0000 -0.3521 -vn -0.0000 -1.0000 0.0000 -vn 0.0013 0.0000 -1.0000 -vn -0.4207 -0.0017 -0.9072 -vn -1.0000 -0.0004 -0.0012 -vn 1.0000 -0.0000 0.0008 -vn 1.0000 0.0007 0.0014 -vn 1.0000 0.0012 0.0022 -vn -0.9499 -0.0007 0.3124 -vn -0.9398 -0.0000 0.3416 -vn 0.9355 0.0000 -0.3532 -vn -0.3393 -0.0018 0.9407 -vn -0.9719 0.0009 0.2356 -vn 0.9978 0.0008 0.0657 -vn 1.0000 0.0000 -0.0016 -vn 1.0000 0.0000 -0.0010 -vn -1.0000 0.0000 -0.0022 -vn 0.7213 0.0004 0.6926 -vn -1.0000 0.0000 -0.0018 -vn 0.9425 -0.0000 0.3343 -vn 1.0000 -0.0011 -0.0027 -vn 1.0000 -0.0010 -0.0023 -vn -0.0023 -0.0005 -1.0000 -vn -0.9915 -0.0009 0.1304 -vn 0.9424 0.0001 0.3345 -vn -0.5868 -0.0013 0.8098 -vn -0.3473 0.0009 -0.9377 -vn -0.1256 -0.0000 0.9921 -vn 0.9247 0.0012 0.3808 -vn -0.6906 -0.0014 0.7233 -vn -0.5270 0.0006 -0.8498 -vn 0.9897 0.0000 0.1431 -vn -0.3333 0.0006 0.9428 -vn -1.0000 -0.0005 -0.0014 -vn -0.9718 0.0007 0.2356 -vn -0.3165 -0.0016 -0.9486 -vn 0.6042 -0.0021 0.7968 -vn -0.0033 -0.0008 1.0000 -vn 0.5485 0.0009 0.8362 -vn -0.3618 -0.0012 -0.9322 -vn 0.4821 -0.0013 0.8761 -vn -0.9999 0.0019 0.0164 -vn -0.0031 0.0034 -1.0000 -vn -0.5921 -0.0023 -0.8059 -vn 0.4618 0.0007 0.8870 -vn 0.0000 -1.0000 0.0000 -vn -1.0000 0.0004 0.0000 -vn -0.8073 0.0028 0.5901 -vn 0.0032 0.0012 -1.0000 -vn -0.9999 -0.0002 0.0126 -vn -0.6032 0.0025 -0.7976 -vn 0.9412 -0.0005 -0.3377 -vn 0.9898 -0.0001 0.1424 -vn -0.7850 0.0018 0.6195 -vn 0.7817 0.0006 0.6236 -vn -0.8321 -0.0004 -0.5546 -vn 0.6370 0.0023 0.7708 -vn 1.0000 -0.0013 -0.0036 -vn 0.0026 -0.0000 1.0000 -vn 0.9949 -0.0015 0.1009 -vn 0.0000 -0.0000 1.0000 -vn 0.0492 0.0019 -0.9988 -vn -0.1083 0.0008 -0.9941 -vn 0.8132 -0.0000 0.5820 -vn -0.9834 0.0011 0.1814 -vn 0.1222 -0.0000 0.9925 -vn 0.9303 0.0013 -0.3669 -vn 0.9995 -0.0012 -0.0329 -vn -0.9995 -0.0012 0.0326 -vn -0.1288 -0.0000 -0.9917 -vn 0.0207 0.0010 -0.9998 -vn -0.4595 -0.0011 -0.8882 -vn 0.8848 -0.0023 -0.4660 -vn 0.6066 0.0016 0.7950 -vn -0.9921 -0.0000 0.1254 -vn 0.3751 -0.0016 0.9270 -vn -0.5875 -0.0015 0.8093 -vn -0.9491 -0.0011 -0.3149 -vn -0.1745 0.0000 -0.9847 -vn 0.8764 -0.0007 -0.4817 -vn -1.0000 -0.0000 0.0007 -vn -1.0000 -0.0000 0.0006 -vn 0.2592 -0.0014 -0.9658 -vn -0.0505 -0.0006 -0.9987 -vn -0.7656 0.0000 -0.6434 -vn -0.7656 -0.0000 -0.6434 -vn -0.3668 -0.0005 0.9303 -vn 0.5714 -0.0001 -0.8207 -vn -0.3598 -0.0009 0.9330 -vn 0.5805 -0.0010 -0.8142 -vn 0.4370 0.0025 0.8994 -vn -0.0573 -0.0011 -0.9984 -vn 0.7079 0.0006 -0.7063 -vn -0.9965 -0.0005 0.0841 -vn 0.4790 -0.0008 0.8778 -vn 0.9074 0.0000 0.4203 -vn 0.8554 -0.0009 -0.5180 -vn -0.5801 0.0014 0.8146 -vn -0.9994 -0.0004 -0.0348 -vn 0.5472 -0.0023 -0.8370 -vn 0.1845 -0.0020 -0.9828 -vn -0.0372 -0.0004 -0.9993 -vn -0.6125 -0.0013 0.7904 -vn 0.0771 -0.0006 -0.9970 -vn -0.3008 0.0016 -0.9537 -vn 0.5206 -0.0016 0.8538 -vn 0.8489 0.0018 0.5286 -vn 0.6687 -0.0006 -0.7435 -vn 0.4998 -0.0000 0.8662 -vn 0.6858 -0.0023 0.7278 -vn 0.0060 0.0023 1.0000 -vn -0.9801 0.0009 -0.1984 -vn -0.9801 0.0009 -0.1985 -vn -0.8424 -0.0018 -0.5388 -vn -0.8209 -0.0006 -0.5710 -vn -0.2669 -0.0013 0.9637 -vn -0.9747 -0.0026 0.2234 -vn -0.9215 0.0004 -0.3885 -vn 0.8966 -0.0010 0.4428 -vn -0.6493 -0.0006 -0.7605 -vn 0.4349 0.0005 -0.9005 -vn 0.8619 0.0011 0.5070 -vn -0.3158 0.0008 0.9488 -vn 0.8401 -0.0031 -0.5425 -vn -0.0052 -0.0000 1.0000 -vn -0.5939 -0.0013 -0.8045 -vn 0.7234 -0.0005 0.6904 -vn 0.6757 0.0023 -0.7372 -vn 0.8490 -0.0017 -0.5283 -vn -0.9436 0.0010 -0.3312 -vn -0.0463 -0.0004 -0.9989 -vn 0.0313 -0.0007 -0.9995 -vn -0.7673 -0.0014 -0.6412 -vn 0.4375 0.0013 0.8992 -vn 0.8884 0.0015 -0.4591 -vn -0.6561 0.0012 0.7547 -vn 0.3466 0.0035 0.9380 -vn 0.8367 -0.0013 0.5476 -vn -0.8047 0.0000 0.5936 -vn -0.9694 -0.0009 -0.2454 -vn 0.2992 -0.0008 0.9542 -vn 0.5339 -0.0027 0.8456 -vn 0.9808 0.0019 -0.1950 -vn 0.9568 -0.0012 -0.2908 -vn 0.7772 0.0007 -0.6292 -vn -0.9829 0.0021 -0.1844 -vn 0.2923 -0.0016 0.9563 -vn -0.2948 -0.0016 -0.9556 -vn -0.8682 -0.0004 0.4963 -vn 0.0359 0.0015 -0.9994 -vn -0.0944 0.0005 0.9955 -vn 0.5891 0.0000 -0.8081 -vn 0.5891 -0.0000 -0.8081 -vn -0.9810 0.0005 -0.1938 -vn -0.3310 0.0022 -0.9436 -vn -0.9087 -0.0004 -0.4174 -vn 0.8142 -0.0005 -0.5806 -vn 0.8525 -0.0028 -0.5227 -vn -0.8813 -0.0020 0.4725 -vn -0.0313 -0.0011 0.9995 -vn -0.9237 0.0017 0.3831 -vn 0.9441 0.0002 -0.3297 -vn -0.8047 -0.0016 -0.5936 -vn -0.6108 0.0008 0.7918 -vn -0.9998 -0.0001 0.0212 -vn -0.0562 -0.0010 0.9984 -vn 0.9463 0.0029 -0.3233 -vn 0.9846 -0.0031 0.1746 -vn -0.8649 0.0000 0.5020 -vn -0.8649 -0.0000 0.5020 -vn -0.0329 -0.0023 0.9995 -vn 0.8617 0.0000 -0.5075 -vn 0.8616 -0.0000 -0.5075 -vn -0.7073 -0.0006 -0.7069 -vn 0.7085 -0.0006 0.7057 -vn -0.8653 -0.0027 0.5012 -vn 0.4720 -0.0000 -0.8816 -vn 0.4720 0.0000 -0.8816 -vn 0.8808 0.0000 -0.4736 -vn 0.8764 -0.0019 0.4816 -vn -0.9281 0.0008 -0.3724 -vn 0.8618 -0.0011 -0.5072 -vn 0.4634 -0.0008 0.8861 -vn 0.9089 0.0010 0.4170 -vn -0.4916 -0.0001 0.8708 -vn -0.9598 0.0027 0.2805 -vn -0.8718 0.0002 0.4898 -vn 0.5726 -0.0022 -0.8198 -vn -0.7852 -0.0021 -0.6193 -vn -0.8333 -0.0018 0.5529 -vn -0.9009 -0.0009 0.4340 -vn 0.9347 -0.0011 0.3556 -vn -0.4260 -0.0027 0.9047 -vn 0.2233 0.0023 0.9747 -vn 0.9997 0.0010 0.0260 -vn -0.7351 -0.0022 0.6780 -vn -0.1611 0.0010 -0.9869 -vn 0.9873 0.0005 0.1587 -vn 0.8508 -0.0005 0.5255 -vn -0.9408 0.0018 -0.3390 -vn 0.4591 0.0022 -0.8884 -vn 0.9147 0.0011 -0.4042 -vn -0.3435 0.0014 0.9392 -vn -0.4585 -0.0024 -0.8887 -vn 0.0520 0.0018 0.9986 -vn -0.3383 0.0007 -0.9410 -vn -0.4589 0.0010 0.8885 -vn -0.5128 -0.0000 0.8585 -vn 0.9857 -0.0048 0.1682 -vn 0.8984 -0.0013 0.4393 -vn 0.9993 0.0018 0.0380 -vn -0.5763 0.0020 -0.8173 -vn -0.5128 0.0000 0.8585 -vn -0.3373 0.0019 -0.9414 -vn 0.0318 -0.0012 0.9995 -vn 0.0289 0.0013 -0.9996 -vn 0.6587 0.0010 0.7524 -vn 0.1616 0.0023 0.9869 -vn -0.9960 -0.0010 0.0898 -vn 1.0000 0.0015 0.0089 -vn -1.0000 0.0020 -0.0015 -vn -0.9395 0.0000 0.3426 -vn -0.9395 -0.0000 0.3426 -vn -0.9984 -0.0004 0.0566 -vn 0.9374 -0.0000 -0.3482 -vn 0.9374 0.0000 -0.3482 -vn -0.7344 -0.0007 0.6787 -vn 0.9601 -0.0018 0.2798 -vn 0.0400 0.0007 -0.9992 -vn 0.9763 0.0022 0.2162 -vn 0.2499 0.0003 0.9683 -vn -0.9578 -0.0018 -0.2873 -vn -0.3690 -0.0015 -0.9294 -vn -0.9858 -0.0016 -0.1677 -vn -0.9858 -0.0016 -0.1676 -vn 0.4501 0.0017 0.8930 -vn 0.2187 -0.0015 -0.9758 -vn -0.9474 -0.0012 -0.3199 -vn 0.0684 0.0011 -0.9977 -vn -0.1125 -0.0008 0.9936 -vn -0.4375 0.0032 -0.8992 -vn 0.1565 0.0023 0.9877 -vn 0.1851 0.0007 -0.9827 -vn -0.9009 0.0024 -0.4340 -vn 0.9669 -0.0015 0.2553 -vn 0.7862 0.0009 0.6180 -vn 0.6787 0.0004 0.7344 -vn 0.1435 -0.0011 -0.9896 -vn 0.2589 -0.0006 0.9659 -vn 0.8445 0.0008 0.5356 -vn 0.9335 0.0004 -0.3585 -vn 0.9624 0.0013 0.2718 -vn -0.7156 -0.0019 0.6985 -vn 0.8409 0.0000 0.5412 -vn -0.9493 -0.0021 -0.3142 -vn 0.6027 0.0032 -0.7979 -vn -0.5299 0.0029 0.8480 -vn -0.8377 -0.0013 -0.5462 -vn 0.0960 -0.0008 0.9954 -vn 0.5664 -0.0006 -0.8241 -vn 0.9556 -0.0024 -0.2947 -vn -0.8767 -0.0018 0.4810 -vn -0.2789 -0.0006 0.9603 -vn 0.4518 -0.0005 -0.8921 -vn -0.0573 0.0006 0.9984 -vn -0.6814 -0.0015 0.7319 -vn -0.7763 -0.0019 0.6303 -vn 0.3798 -0.0019 -0.9251 -vn -0.6504 0.0006 0.7596 -vn -0.6503 0.0006 0.7596 -vn 0.2529 -0.0012 -0.9675 -vn 0.7779 0.0004 0.6284 -vn -0.7975 -0.0012 -0.6033 -vn 0.3367 0.0004 0.9416 -vn 0.9085 -0.0008 -0.4179 -vn -0.8317 -0.0018 0.5553 -vn -0.9715 0.0005 -0.2370 -vn 0.2570 -0.0008 -0.9664 -vn -0.5856 -0.0006 -0.8106 -vn -0.9032 0.0018 -0.4292 -vn -0.9216 -0.0002 -0.3882 -vn -0.9485 -0.0015 -0.3167 -vn -0.7358 -0.0021 0.6772 -vn -0.2906 -0.0016 0.9568 -vn 0.1745 0.0007 -0.9847 -vn 0.9372 -0.0012 0.3488 -vn 0.9861 -0.0013 -0.1663 -vn -0.0059 -0.0014 -1.0000 -vn 0.8543 0.0010 0.5197 -vn -0.0285 -0.0010 0.9996 -vn -0.3147 -0.0025 -0.9492 -vn -0.8762 0.0012 0.4820 -vn 0.9436 -0.0014 0.3310 -vn 0.9190 0.0022 -0.3944 -vn 0.7886 -0.0018 -0.6149 -vn 0.9633 0.0009 0.2684 -vn -0.8913 0.0009 -0.4533 -vn -0.7090 0.0015 -0.7052 -vn -0.1731 -0.0016 0.9849 -vn 0.3165 0.0010 -0.9486 -vn -0.9263 -0.0002 -0.3767 -vn 0.1704 -0.0016 -0.9854 -vn 0.4774 0.0028 -0.8787 -vn -0.9407 0.0024 0.3392 -vn 0.6417 0.0015 -0.7670 -vn 0.9462 -0.0021 0.3235 -vn 0.5134 0.0029 -0.8582 -vn 0.7182 -0.0030 0.6959 -vn 0.2711 -0.0022 0.9625 -vn 0.1848 -0.0015 -0.9828 -vn 0.6013 -0.0007 0.7990 -vn -0.4013 -0.0000 0.9159 -vn -0.1840 -0.0015 0.9829 -vn 0.3965 0.0000 -0.9180 -vn 0.3965 -0.0000 -0.9180 -vn -0.1558 -0.0021 -0.9878 -vn 0.8845 -0.0007 -0.4666 -vn 0.4436 0.0010 -0.8962 -vn 0.7144 -0.0019 0.6997 -vn -0.8885 0.0000 0.4589 -vn 0.4237 0.0000 -0.9058 -vn 0.4237 -0.0000 -0.9058 -vn -0.8186 -0.0014 0.5744 -vn 0.3516 0.0009 -0.9362 -vn 0.3105 -0.0008 0.9506 -vn 0.3106 -0.0008 0.9506 -vn -0.9997 0.0008 0.0234 -vn -0.9999 0.0013 0.0119 -vn -0.7707 -0.0004 -0.6372 -vn 0.0132 -0.0011 -0.9999 -vn -0.0137 -0.0009 0.9999 -vn -0.9888 -0.0013 -0.1491 -vn 0.9619 0.0018 0.2732 -vn 0.3115 -0.0021 0.9503 -vn -0.3434 0.0003 -0.9392 -vn 0.9241 0.0020 -0.3822 -vn -0.9954 -0.0019 -0.0961 -vn -0.3910 -0.0004 0.9204 -vn 0.2938 -0.0011 0.9559 -vn -0.3528 -0.0015 0.9357 -vn 0.9289 0.0019 -0.3703 -vn 0.7320 -0.0015 0.6813 -vn -0.8939 0.0005 -0.4483 -vn 0.1681 0.0010 0.9858 -vn -0.9508 -0.0022 -0.3099 -vn -0.4790 -0.0006 -0.8778 -vn -0.5595 0.0007 0.8288 -vn 0.9664 0.0013 -0.2570 -vn -0.1731 -0.0016 -0.9849 -vn 0.9998 0.0006 0.0212 -vn -0.3085 -0.0013 0.9512 -vn -0.9642 -0.0011 -0.2652 -vn -0.9715 -0.0013 0.2369 -vn -0.2828 0.0005 -0.9592 -vn 0.9565 -0.0006 0.2916 -vn -0.5223 -0.0010 0.8528 -vn 0.9579 -0.0015 -0.2872 -vn -0.7930 0.0018 0.6092 -vn 0.6685 -0.0006 -0.7437 -vn -0.9543 -0.0007 -0.2990 -vn -0.9542 -0.0007 -0.2990 -vn -0.6914 -0.0009 0.7224 -vn -0.2559 -0.0012 0.9667 -vn -0.6326 -0.0007 -0.7745 -vn -0.6360 0.0000 -0.7717 -vn 0.7032 -0.0008 0.7110 -vn 0.9590 -0.0006 0.2833 -vn 0.0404 0.0004 0.9992 -vn 0.2098 -0.0013 -0.9777 -vn 0.8790 -0.0026 0.4768 -vn 0.9533 0.0015 0.3021 -vn -0.5847 0.0017 -0.8113 -vn -0.0211 -0.0003 0.9998 -vn 0.6921 -0.0013 0.7218 -vn 0.8078 0.0000 -0.5895 -vn -0.9643 -0.0009 0.2648 -vn 0.9486 0.0006 -0.3165 -vn 0.8719 -0.0013 -0.4897 -vn 0.4664 0.0004 0.8846 -vn -0.1724 0.0024 0.9850 -vn 0.5804 0.0006 -0.8143 -vn -1.0000 0.0002 0.0077 -vn -0.4505 -0.0006 -0.8928 -vn -0.5848 -0.0029 0.8112 -vn -0.9366 0.0016 0.3504 -vn -0.9985 -0.0004 -0.0544 -vn 0.9549 -0.0013 -0.2970 -vn -0.9760 -0.0005 -0.2179 -vn 0.3180 0.0008 -0.9481 -vn -0.1999 0.0021 -0.9798 -vn -0.6835 -0.0023 0.7300 -vn 0.2281 -0.0010 -0.9736 -vn 0.3278 0.0009 0.9448 -vn -0.6807 -0.0010 0.7325 -vn -0.5036 -0.0016 -0.8639 -vn 0.7777 0.0011 0.6287 -vn 0.5187 0.0009 0.8550 -vn 0.8811 -0.0021 -0.4729 -vn 0.9287 -0.0034 0.3708 -vn -0.5560 -0.0016 -0.8312 -vn -0.7173 0.0006 -0.6968 -vn 0.8773 0.0018 0.4799 -vn -0.3203 -0.0016 0.9473 -vn 0.9930 -0.0000 -0.1184 -vn -0.2449 -0.0010 -0.9695 -vn 0.9780 -0.0011 0.2085 -vn -0.0910 -0.0023 0.9959 -vn 0.0558 -0.0012 0.9984 -vn 0.9929 0.0008 -0.1187 -vn 0.9705 -0.0004 0.2411 -vn -0.5841 0.0010 -0.8117 -vn 0.0542 -0.0016 0.9985 -vn 0.3229 0.0012 -0.9464 -vn -0.5450 -0.0007 -0.8385 -vn 0.4805 -0.0000 -0.8770 -vn -0.9736 -0.0002 -0.2283 -vn 0.2202 -0.0021 0.9755 -vn -0.2830 0.0002 -0.9591 -vn 0.4501 0.0011 -0.8930 -vn -0.1221 -0.0013 -0.9925 -vn 0.9591 -0.0011 -0.2829 -vn 0.9256 0.0006 0.3786 -vn 0.1580 -0.0004 -0.9874 -vn -0.8482 0.0000 0.5297 -vn -0.8717 0.0005 0.4900 -vn -0.9954 0.0012 -0.0957 -vn -0.1173 -0.0000 0.9931 -vn -0.7197 -0.0014 0.6943 -vn -0.5827 -0.0013 -0.8127 -vn 0.7157 -0.0014 -0.6984 -vn 0.3908 -0.0007 0.9205 -vn -0.4450 -0.0012 -0.8955 -vn 0.2903 0.0008 -0.9569 -vn -0.8283 0.0017 0.5603 -vn 0.6772 -0.0013 0.7358 -vn -0.4941 -0.0013 0.8694 -vn -0.9402 0.0023 0.3405 -vn 0.4729 -0.0006 -0.8811 -vn 0.9959 0.0023 -0.0903 -vn 0.1097 0.0016 0.9940 -vn -0.9825 0.0030 -0.1861 -vn -0.9914 -0.0003 -0.1310 -vn 0.9834 -0.0024 0.1813 -vn 0.0615 0.0018 0.9981 -vn -0.7964 -0.0017 0.6047 -vn -0.9958 -0.0023 -0.0921 -vn 0.9668 -0.0021 -0.2555 -vn 0.3719 0.0020 -0.9283 -vn 0.0259 0.0002 -0.9997 -vn -0.9442 -0.0004 -0.3295 -vn -0.9985 -0.0012 0.0543 -vn -0.0169 -0.0022 0.9999 -vn 0.6830 -0.0015 0.7304 -vn 0.8745 0.0008 0.4850 -vn 0.2228 0.0021 0.9749 -vn 0.6886 0.0006 0.7251 -vn 0.5900 0.0002 0.8074 -vn -0.9996 0.0003 0.0279 -vn 0.7272 0.0025 -0.6865 -vn 0.2317 0.0000 -0.9728 -vn -0.9926 0.0049 0.1212 -vn 0.1483 -0.0004 0.9889 -vn 0.0906 -0.0012 -0.9959 -vn -0.1095 0.0021 -0.9940 -vn 0.2468 0.0021 -0.9691 -vn 0.6489 0.0020 -0.7609 -vn -0.1480 0.0025 -0.9890 -vn 0.6934 -0.0027 -0.7205 -vn 0.4420 -0.0018 -0.8970 -vn 0.9916 -0.0009 -0.1293 -vn 0.8906 -0.0014 0.4548 -vn -0.7571 -0.0000 -0.6533 -vn -0.7936 -0.0000 0.6085 -vn 0.0174 0.0002 0.9998 -vn 0.9864 0.0024 -0.1645 -vn 0.4810 -0.0009 0.8767 -vn -0.7924 0.0000 0.6100 -vn 0.9602 -0.0008 -0.2795 -vn -0.5559 -0.0010 -0.8312 -vn -0.7448 -0.0013 -0.6672 -vn -0.9308 -0.0007 -0.3656 -vn -0.8225 0.0008 0.5688 -vn 0.9572 -0.0000 -0.2895 -vn 0.0964 -0.0008 0.9953 -vn -0.9964 -0.0016 -0.0847 -vn -0.3852 -0.0011 -0.9228 -vn 0.1905 -0.0015 -0.9817 -vn -0.9995 -0.0013 -0.0316 -vn -0.9743 -0.0018 0.2251 -vn 0.2825 -0.0008 0.9593 -vn 0.8207 0.0019 -0.5713 -vn -0.2848 -0.0008 -0.9586 -vn 0.6451 0.0008 -0.7641 -vn 0.9783 0.0013 0.2071 -vn -0.2286 0.0018 0.9735 -vn -0.5375 0.0019 -0.8432 -vn -0.2931 -0.0006 -0.9561 -vn 0.9995 -0.0012 -0.0319 -vn -0.1360 0.0017 0.9907 -vn -0.8440 0.0029 -0.5364 -vn 0.3867 0.0011 0.9222 -vn -0.6060 0.0015 -0.7955 -vn -0.9692 -0.0008 -0.2465 -vn -0.9588 -0.0026 0.2842 -vn -0.1362 0.0018 -0.9907 -vn 0.8701 -0.0020 0.4930 -vn 0.8701 -0.0020 0.4929 -vn -0.2479 0.0027 0.9688 -vn -0.5132 -0.0019 0.8583 -vn -0.7853 0.0008 0.6192 -vn 0.9557 0.0016 0.2945 -vn 0.9917 -0.0013 0.1288 -vn 0.9917 -0.0013 0.1287 -vn -0.8662 -0.0019 -0.4996 -vn 0.1467 0.0020 -0.9892 -vn -0.9645 -0.0008 0.2642 -vn -0.9358 -0.0019 -0.3526 -vn 0.6690 0.0017 0.7433 -vn -0.5132 0.0010 0.8582 -vn -0.5133 0.0010 0.8582 -vn 0.9235 -0.0000 0.3835 -vn -0.9846 0.0015 -0.1750 -vn 0.8143 -0.0008 0.5805 -vn 0.6469 -0.0010 -0.7625 -vn 0.9551 0.0009 0.2961 -vn -0.5136 0.0017 -0.8580 -vn 0.4633 0.0015 -0.8862 -vn 0.8571 -0.0013 0.5151 -vn -0.9831 -0.0014 0.1830 -vn 0.2843 -0.0023 0.9587 -vn -0.6154 0.0011 -0.7882 -vn -0.9629 -0.0014 0.2700 -vn 0.9824 -0.0014 -0.1868 -vn -0.9843 0.0017 0.1763 -vn -0.6424 -0.0017 -0.7663 -vn -0.8957 -0.0016 0.4446 -vn 0.3654 0.0019 -0.9309 -vn 0.4148 -0.0008 -0.9099 -vn -0.7729 -0.0020 0.6345 -vn -0.7287 -0.0008 0.6848 -vn 0.0172 0.0006 -0.9999 -vn 0.9624 -0.0017 0.2716 -vn -0.8248 -0.0012 -0.5655 -vn -0.5257 0.0033 -0.8507 -vn 0.5261 -0.0016 0.8504 -vn 0.5261 -0.0017 0.8504 -vn 0.7412 -0.0013 -0.6713 -vn -0.6576 0.0024 0.7534 -vn 0.0557 -0.0014 0.9984 -vn -0.4436 0.0000 0.8962 -vn -0.4437 0.0000 0.8962 -vn -0.0563 -0.0014 -0.9984 -vn -0.5276 -0.0016 -0.8495 -vn -0.7311 0.0015 0.6823 -vn -0.0621 -0.0014 -0.9981 -vn -0.0200 0.0011 -0.9998 -vn -0.7288 -0.0013 0.6847 -vn 0.9735 0.0005 0.2288 -vn 0.1954 0.0014 -0.9807 -vn -0.9268 -0.0017 -0.3756 -vn 0.0639 -0.0014 0.9980 -vn 0.7831 0.0015 -0.6219 -vn -0.3006 0.0014 0.9537 -vn 1.0000 0.0017 -0.0039 -vn -0.9162 0.0005 -0.4007 -vn -0.7933 -0.0007 -0.6088 -vn -0.8812 -0.0015 0.4727 -vn -0.0568 -0.0016 0.9984 -vn 0.2295 0.0016 0.9733 -vn 0.9566 -0.0008 -0.2914 -vn 0.7408 0.0009 -0.6717 -vn -0.7258 -0.0007 0.6879 -vn 0.9946 -0.0015 0.1042 -vn -0.6676 0.0003 0.7446 -vn 0.5556 -0.0015 0.8314 -vn 0.7220 -0.0007 -0.6919 -vn 0.6320 -0.0038 -0.7749 -vn 0.1582 -0.0014 0.9874 -vn -0.9941 -0.0015 -0.1080 -vn -0.3102 -0.0025 0.9507 -vn 0.9899 -0.0005 -0.1419 -vn -0.9682 -0.0027 0.2500 -vn 0.1581 -0.0004 -0.9874 -vn -0.0173 0.0010 -0.9998 -vn -0.6736 -0.0013 0.7390 -vn -0.6004 -0.0026 0.7997 -vn 0.0449 -0.0013 -0.9990 -vn -0.2679 -0.0014 0.9634 -vn 0.7465 -0.0007 -0.6653 -vn 0.7465 -0.0007 -0.6654 -vn -0.9995 -0.0010 -0.0300 -vn 0.9996 -0.0011 -0.0286 -vn 0.9996 -0.0011 -0.0287 -vn 0.7389 -0.0013 -0.6738 -vn -0.9038 -0.0010 -0.4280 -vn -0.4749 -0.0015 0.8800 -vn -0.9839 -0.0009 0.1785 -vn 0.8071 -0.0010 0.5905 -vn -0.5563 -0.0009 0.8310 -vn 0.6732 -0.0012 -0.7394 -vn -0.5713 0.0016 0.8208 -vn 0.9833 -0.0009 -0.1821 -vn 0.9833 -0.0009 -0.1822 -vn 0.9994 -0.0015 0.0349 -vn -0.9987 0.0001 0.0507 -vn -0.1146 0.0016 -0.9934 -vn -0.2552 -0.0013 -0.9669 -vn -0.7144 0.0005 -0.6998 -vn 0.7172 0.0009 -0.6969 -vn 0.0522 -0.0006 0.9986 -vn -0.3770 -0.0006 -0.9262 -vn 0.9976 0.0013 0.0692 -vn 0.9914 -0.0011 -0.1307 -vn 0.7006 -0.0023 0.7135 -vn 0.8281 0.0012 0.5606 -vn 0.8213 -0.0009 0.5705 -vn 0.8428 -0.0023 0.5383 -vn -0.1617 0.0014 0.9868 -vn 0.3369 0.0019 0.9415 -vn 0.9867 -0.0009 -0.1625 -vn 0.3766 0.0009 0.9264 -vn 0.6039 -0.0013 -0.7970 -vn -0.9197 -0.0018 0.3925 -vn -0.4844 -0.0022 0.8748 -vn -0.3733 -0.0023 -0.9277 -vn 0.8577 0.0007 -0.5141 -vn -0.0411 0.0009 0.9992 -vn 0.4916 -0.0022 0.8708 -vn 0.9798 0.0011 0.1999 -vn -0.0523 -0.0009 -0.9986 -vn 0.9908 -0.0010 -0.1355 -vn -0.9970 -0.0014 -0.0778 -vn 0.9989 0.0004 0.0464 -vn -0.9795 0.0013 -0.2016 -vn -0.9991 -0.0011 -0.0427 -vn -0.9934 0.0011 -0.1150 -vn -0.1292 0.0014 0.9916 -vn 0.8490 -0.0013 0.5283 -vn 0.9978 0.0019 0.0662 -vn -0.7816 0.0012 0.6237 -vn -0.0921 -0.0014 -0.9957 -vn -0.7351 -0.0012 -0.6780 -vn -0.5176 -0.0009 0.8556 -vn -0.7232 0.0009 -0.6906 -vn 0.8718 0.0017 -0.4898 -vn -0.2680 -0.0011 0.9634 -vn 0.9485 -0.0013 -0.3168 -vn -0.9930 -0.0017 -0.1184 -vn -0.9987 0.0006 -0.0514 -vn 0.2931 0.0006 0.9561 -vn -0.9355 0.0013 -0.3533 -vn 0.9919 -0.0012 -0.1272 -vn 0.9236 0.0010 0.3833 -vn 0.3466 0.0022 0.9380 -vn 0.7282 0.0001 -0.6854 -vn 0.7938 0.0011 -0.6082 -vn -0.9699 -0.0000 0.2434 -vn -0.6541 0.0001 -0.7564 -vn 0.2390 0.0011 -0.9710 -vn 0.5159 -0.0012 0.8567 -vn 0.5158 -0.0012 0.8567 -vn 0.0593 0.0009 0.9982 -vn 0.1413 0.0001 0.9900 -vn 0.9900 0.0012 0.1408 -vn 0.1491 -0.0013 0.9888 -vn -0.3833 0.0023 -0.9236 -vn -0.4448 0.0010 -0.8956 -vn 0.5548 0.0004 0.8320 -vn -0.9518 0.0012 0.3067 -vn 0.6784 -0.0001 0.7347 -vn -0.9836 0.0009 -0.1802 -vn -0.8136 0.0010 -0.5815 -vn 0.9591 0.0000 0.2831 -vn 0.7268 0.0007 0.6869 -vn 0.4526 0.0010 -0.8917 -vn 0.4525 0.0010 -0.8917 -vn 0.9921 0.0011 -0.1255 -vn 0.9920 -0.0016 0.1260 -vn -0.0456 -0.0009 -0.9990 -vn 0.4220 -0.0016 -0.9066 -vn 0.9840 0.0010 -0.1781 -vn 0.9459 0.0000 -0.3243 -vn -0.1448 -0.0009 -0.9895 -vn 0.5569 0.0019 -0.8306 -vn 0.1740 0.0010 -0.9847 -vn 0.8105 -0.0009 -0.5858 -vn -0.9457 0.0010 -0.3250 -vn 0.2713 -0.0012 0.9625 -vn -0.9900 0.0012 -0.1408 -vn 0.7914 -0.0011 -0.6114 -vn -0.7660 0.0014 0.6429 -vn 0.9931 -0.0000 0.1174 -vn 0.0894 -0.0012 0.9960 -vn -0.9135 -0.0011 -0.4068 -vn -0.9877 0.0000 -0.1562 -vn 0.6964 0.0020 0.7176 -vn 0.9867 0.0009 0.1625 -vn -0.8495 -0.0011 0.5276 -vn -0.7989 -0.0014 -0.6014 -vn 0.9906 -0.0010 -0.1369 -vn -0.2083 -0.0000 0.9781 -vn 0.9939 -0.0005 0.1104 -vn -0.9366 0.0009 0.3504 -vn 0.1048 0.0007 -0.9945 -vn -0.6600 -0.0004 -0.7513 -vn -0.1971 -0.0009 0.9804 -vn 0.7172 0.0005 -0.6968 -vn 0.7172 0.0005 -0.6969 -vn -0.9968 0.0009 -0.0805 -vn 0.9788 -0.0008 -0.2047 -vn -0.1460 0.0008 -0.9893 -vn 0.0235 0.0006 -0.9997 -vn 0.6928 0.0001 0.7211 -vn -0.4638 0.0017 0.8859 -vn -0.4638 0.0017 0.8860 -vn 0.8640 -0.0010 0.5034 -vn -0.9919 0.0011 -0.1267 -vn 0.6778 0.0008 0.7352 -vn 0.6730 0.0009 0.7396 -vn -0.8604 -0.0010 -0.5097 -vn 0.7255 -0.0000 0.6882 -vn 0.6737 0.0005 0.7390 -vn 0.1736 0.0007 -0.9848 -vn -0.5096 -0.0013 0.8604 -vn -0.1309 -0.0005 0.9914 -vn 0.8708 -0.0010 0.4916 -vn -0.1240 0.0006 0.9923 -vn -0.4101 -0.0008 -0.9120 -vn -0.8865 0.0008 -0.4628 -vn -0.8502 -0.0017 0.5264 -vn -0.8817 -0.0010 0.4717 -vn -0.8817 -0.0010 0.4718 -vn -0.7865 -0.0020 0.6175 -vn -0.7866 -0.0020 0.6175 -vn -0.0387 -0.0002 -0.9993 -vn 0.8469 -0.0017 -0.5317 -vn -0.9935 -0.0010 -0.1139 -vn -0.2042 -0.0009 0.9789 -vn -0.9920 0.0008 0.1260 -vn -0.1326 -0.0009 -0.9912 -vn -0.9851 0.0020 0.1721 -vn 0.4234 0.0008 0.9059 -vn -0.9873 0.0007 -0.1587 -vn 0.1070 -0.0017 0.9943 -vn -0.5235 0.0009 -0.8520 -vn 0.2944 0.0006 0.9557 -vn 0.1676 0.0008 0.9859 -vn 0.6367 -0.0006 -0.7711 -vn 0.5157 -0.0008 0.8568 -vn 0.9766 -0.0010 0.2151 -vn 0.6348 0.0007 -0.7727 -vn -0.9198 0.0007 0.3924 -vn 0.9992 0.0008 0.0396 -vn -0.5171 -0.0007 -0.8559 -vn -0.1852 -0.0007 0.9827 -vn -0.7179 -0.0021 0.6961 -vn 0.1822 -0.0007 -0.9833 -vn -0.3055 -0.0008 -0.9522 -vn 0.1605 0.0029 0.9870 -vn 0.9379 0.0029 0.3469 -vn 0.1503 -0.0029 -0.9886 -vn 0.9166 0.0007 0.3999 -vn 0.9486 0.0000 -0.3165 -vn -0.7143 0.0015 0.6998 -vn 0.6991 -0.0003 0.7150 -vn -0.0372 -0.0002 -0.9993 -vn 0.9535 -0.0006 -0.3013 -vn -0.7116 0.0000 -0.7026 -vn 0.0233 0.0008 0.9997 -vn -0.4546 0.0019 0.8907 -vn 0.1973 -0.0007 -0.9803 -vn -0.3901 0.0028 0.9208 -vn -0.9840 -0.0005 -0.1780 -vn -0.4509 -0.0020 0.8926 -vn -0.1257 -0.0013 0.9921 -vn 0.2414 0.0006 0.9704 -vn -0.9223 -0.0006 0.3864 -vn -0.3761 -0.0015 0.9266 -vn -0.9859 -0.0009 0.1672 -vn 0.9935 -0.0005 0.1135 -vn 0.3714 -0.0015 -0.9285 -vn -0.1000 0.0027 0.9950 -vn 0.9102 -0.0014 0.4141 -vn 0.5446 -0.0006 0.8387 -vn 0.8840 0.0006 -0.4675 -vn 0.5235 -0.0015 0.8520 -vn -0.9930 -0.0005 -0.1178 -vn 0.4999 0.0015 -0.8661 -vn -0.5535 -0.0008 0.8328 -vn -0.9234 -0.0009 -0.3837 -vn 0.8840 -0.0019 -0.4675 -vn -0.5611 -0.0009 -0.8277 -vn -0.3676 0.0026 0.9300 -vn 0.4676 0.0021 -0.8839 -vn 0.0551 -0.0005 -0.9985 -vn -0.8583 -0.0017 -0.5131 -vn 0.6183 0.0000 -0.7860 -vn 0.6183 -0.0000 -0.7860 -vn -0.2703 -0.0024 -0.9628 -vn -0.9209 0.0012 0.3899 -vn 0.0182 -0.0009 0.9998 -vn -0.1655 -0.0019 0.9862 -vn -0.8374 0.0014 -0.5467 -vn 0.6803 -0.0006 -0.7329 -vn -0.4963 -0.0007 0.8681 -vn 0.2000 0.0011 0.9798 -vn -0.1819 -0.0016 0.9833 -vn 0.9939 -0.0005 0.1103 -vn 0.9692 -0.0000 0.2464 -vn 0.9999 0.0007 -0.0144 -vn -0.8574 -0.0017 -0.5147 -vn -0.8248 -0.0006 0.5654 -vn 0.3978 -0.0014 -0.9175 -vn -0.9542 0.0002 0.2992 -vn -0.8881 -0.0008 0.4597 -vn -0.9875 -0.0011 -0.1577 -vn 0.1519 -0.0009 0.9884 -vn -0.9954 -0.0008 0.0962 -vn -0.9954 -0.0008 0.0961 -vn 0.7450 -0.0006 -0.6670 -vn 0.5279 -0.0030 0.8493 -vn -0.6674 0.0000 -0.7447 -vn -0.9124 0.0000 0.4093 -vn 0.9018 -0.0000 0.4322 -vn 0.9175 -0.0016 0.3977 -vn -0.3934 -0.0017 0.9194 -vn 0.7506 -0.0008 0.6608 -vn -0.6334 0.0024 0.7738 -vn -0.1261 0.0005 -0.9920 -vn -0.9957 -0.0024 0.0923 -vn -0.2470 -0.0007 -0.9690 -vn 0.9588 -0.0007 -0.2839 -vn 0.4970 -0.0024 -0.8678 -vn -0.9962 -0.0024 -0.0875 -vn -0.0627 -0.0006 0.9980 -vn 0.3712 0.0000 0.9285 -vn -0.3553 0.0000 -0.9348 -vn -0.3553 -0.0000 -0.9348 -vn 0.2334 -0.0006 -0.9724 -vn 0.8328 0.0006 0.5535 -vn -0.9142 -0.0013 0.4054 -vn -0.1534 0.0023 0.9882 -vn -0.6838 -0.0024 0.7297 -vn -0.3586 -0.0007 -0.9335 -vn -0.9741 0.0002 0.2259 -vn -0.7922 -0.0007 -0.6103 -vn -0.6061 -0.0027 -0.7954 -vn -0.9438 -0.0027 -0.3304 -vn 0.4393 -0.0027 -0.8983 -vn -0.5254 -0.0003 0.8509 -vn 0.1953 -0.0023 -0.9807 -vn 0.7974 0.0004 -0.6035 -vn 0.4874 0.0016 -0.8731 -vn 0.9525 -0.0000 -0.3046 -vn 0.9207 0.0026 -0.3902 -vn 0.9933 -0.0006 0.1156 -vn -0.9907 -0.0000 -0.1363 -vn -0.9963 -0.0005 -0.0858 -vn 0.9811 0.0006 0.1937 -vn 0.5840 0.0026 0.8118 -vn 0.5654 -0.0015 -0.8248 -vn 0.9945 0.0007 -0.1043 -vn -0.7285 -0.0005 -0.6850 -vn -0.7763 0.0005 0.6304 -vn 0.7467 -0.0012 0.6651 -vn 0.8648 0.0006 0.5020 -vn 0.6539 -0.0005 -0.7565 -vn 0.9933 -0.0007 0.1155 -vn -0.5068 0.0005 0.8621 -vn -0.6956 -0.0015 -0.7184 -vn 0.7932 0.0006 0.6090 -vn 0.3721 0.0020 0.9282 -vn 0.4789 0.0021 0.8779 -vn -0.2161 -0.0021 0.9764 -vn -0.9666 -0.0003 -0.2564 -vn 0.3342 -0.0024 -0.9425 -vn 0.8309 0.0020 0.5564 -vn 0.2500 0.0020 0.9682 -vn 0.1221 0.0020 -0.9925 -vn 0.8572 -0.0013 -0.5151 -vn -0.7084 0.0022 0.7058 -vn -0.8160 -0.0006 -0.5780 -vn -0.4511 0.0005 -0.8925 -vn 0.0166 0.0019 0.9999 -vn -0.9611 -0.0005 -0.2764 -vn 0.6048 0.0020 0.7964 -vn 0.3129 -0.0023 -0.9498 -vn 0.6047 0.0020 0.7964 -vn 0.4470 0.0005 -0.8945 -vn -0.7895 -0.0022 -0.6138 -vn 0.9975 -0.0017 0.0705 -vn 0.9912 0.0004 -0.1326 -vn 0.9912 0.0004 -0.1325 -vn -0.2373 -0.0006 -0.9714 -vn 0.1787 -0.0000 -0.9839 -vn -0.1757 -0.0019 -0.9844 -vn 0.9815 0.0000 -0.1916 -vn -0.8171 0.0005 -0.5765 -vn -0.6463 -0.0006 -0.7631 -vn -0.6658 0.0019 -0.7461 -vn -0.3114 0.0010 0.9503 -vn -0.6382 -0.0010 -0.7699 -vn -0.9723 -0.0004 0.2337 -vn 0.9312 -0.0004 0.3645 -vn -0.8595 -0.0000 0.5111 -vn 0.7805 -0.0010 -0.6251 -vn -0.9362 0.0021 0.3516 -vn 0.7889 0.0023 -0.6146 -vn 0.9982 0.0003 0.0592 -vn -0.8569 0.0010 -0.5155 -vn -0.4578 0.0021 0.8890 -vn -0.9958 0.0008 -0.0917 -vn 0.9644 0.0005 0.2644 -vn -0.4432 -0.0019 0.8964 -vn 0.4809 -0.0004 0.8768 -vn 0.9997 0.0008 -0.0242 -vn 0.6303 0.0019 -0.7763 -vn 0.9937 0.0006 -0.1123 -vn 0.1680 0.0005 -0.9858 -vn 0.7776 0.0014 0.6288 -vn 0.4926 -0.0021 -0.8703 -vn -0.8925 -0.0010 -0.4511 -vn -0.4905 0.0021 0.8715 -vn 0.3175 -0.0022 -0.9483 -vn -0.9475 0.0005 -0.3198 -vn 1.0000 -0.0003 0.0017 -vn 0.1000 -0.0007 -0.9950 -vn -0.1399 -0.0006 -0.9902 -vn -0.3876 0.0010 0.9218 -vn -0.0748 -0.0002 -0.9972 -vn -0.7006 0.0020 0.7135 -vn -0.9708 -0.0018 -0.2400 -vn -0.1027 0.0008 -0.9947 -vn -0.1770 0.0021 -0.9842 -vn -0.1845 0.0020 0.9828 -vn -0.9344 0.0003 0.3563 -vn -0.9343 0.0003 0.3564 -vn 0.3424 0.0018 -0.9395 -vn -0.4941 -0.0018 -0.8694 -vn -0.2838 -0.0014 0.9589 -vn -0.9344 -0.0011 0.3563 -vn -0.9344 -0.0011 0.3564 -vn 0.1523 0.0017 0.9883 -vn 0.7407 0.0018 -0.6719 -vn 0.6676 0.0003 0.7445 -vn 0.9322 -0.0010 -0.3619 -vn 0.9349 -0.0008 0.3550 -vn 0.1259 0.0005 -0.9920 -vn -0.1805 -0.0017 -0.9836 -vn 0.1951 0.0017 -0.9808 -vn -0.8054 0.0003 -0.5927 -vn -0.2049 -0.0004 0.9788 -vn 0.3307 0.0019 -0.9437 -vn -0.7139 0.0019 0.7003 -vn -0.5631 -0.0004 0.8264 -vn -0.8091 0.0022 0.5877 -vn 0.0793 0.0006 0.9969 -vn -0.9049 0.0019 -0.4257 -vn -0.9911 0.0019 0.1329 -vn -0.7737 0.0019 0.6336 -vn -0.9971 0.0005 -0.0765 -vn -0.9971 0.0005 -0.0766 -vn -0.8431 -0.0000 -0.5377 -vn 0.1776 0.0016 -0.9841 -vn 0.9440 -0.0010 -0.3301 -vn 0.7174 0.0018 -0.6967 -vn -0.9750 -0.0016 -0.2223 -vn -0.9685 0.0000 0.2492 -vn -0.7192 -0.0006 -0.6948 -vn 0.9430 0.0016 0.3328 -vn 0.8981 0.0018 0.4397 -vn -0.9067 -0.0012 0.4217 -vn -0.6805 0.0018 -0.7327 -vn -0.0669 0.0019 0.9978 -vn 0.7747 0.0018 0.6323 -vn -0.9671 -0.0003 -0.2543 -vn -0.5521 -0.0009 0.8338 -vn 0.5472 -0.0009 -0.8370 -vn 0.7903 0.0005 0.6127 -vn 0.7607 0.0018 0.6491 -vn -0.4747 0.0018 -0.8802 -vn 0.9980 0.0005 0.0629 -vn -0.9269 -0.0000 0.3753 -vn 0.8486 0.0004 0.5290 -vn 0.3563 0.0009 -0.9344 -vn -0.9470 -0.0014 -0.3213 -vn 0.9103 -0.0005 -0.4139 -vn -0.6787 -0.0013 -0.7344 -vn -0.3818 0.0018 0.9242 -vn 0.9495 0.0017 0.3138 -vn -0.1635 -0.0015 0.9865 -vn 0.3827 0.0004 0.9239 -vn -0.5985 0.0017 0.8011 -vn 0.5351 0.0002 -0.8448 -vn -0.4797 -0.0000 -0.8774 -vn -0.4798 0.0000 -0.8774 -vn -0.5400 0.0018 0.8417 -vn -0.9768 0.0017 -0.2142 -vn -0.9768 0.0017 -0.2143 -vn -0.6895 -0.0008 0.7242 -vn 0.4718 0.0008 0.8817 -vn 0.4294 0.0003 0.9031 -vn 0.8999 -0.0000 0.4361 -vn -0.8518 0.0000 -0.5239 -vn -0.2131 -0.0004 0.9770 -vn -0.9913 0.0004 0.1313 -vn 0.6009 0.0017 0.7993 -vn 0.5852 0.0017 0.8109 -vn 0.8540 0.0004 -0.5202 -vn 0.9741 0.0017 0.2262 -vn 0.3719 0.0017 0.9283 -vn -0.1547 0.0017 0.9880 -vn -0.2498 0.0017 -0.9683 -vn 0.1759 0.0003 0.9844 -vn -0.8123 -0.0005 -0.5833 -vn 0.5764 -0.0008 -0.8172 -vn -0.9919 -0.0003 -0.1269 -vn -0.1685 -0.0025 0.9857 -vn 0.9995 0.0003 0.0321 -# 1127 vertex normals - -g not_valid_text -usemtl red -s off -f 3115//1573 3116//1573 3117//1573 -f 3118//1574 3119//1574 3120//1574 -f 3121//1575 3122//1575 3123//1575 -f 3124//1576 3125//1576 3126//1576 -f 3127//1577 3128//1577 3129//1577 -f 3130//1578 3131//1578 3132//1578 -f 3133//1579 3134//1579 3135//1579 -f 3136//1580 3137//1580 3138//1580 -f 3139//1581 3140//1581 3141//1581 -f 3142//1582 3133//1582 3135//1582 -f 3143//1583 3144//1583 3145//1583 -f 3146//1584 3147//1584 3148//1584 -f 3149//1585 3150//1585 3151//1585 -f 3152//1586 3153//1586 3154//1586 -f 3155//1586 3156//1586 3157//1586 -f 3158//1583 3159//1583 3160//1583 -f 3161//1584 3162//1584 3163//1584 -f 3164//1585 3165//1585 3166//1585 -f 3167//1587 3168//1587 3169//1587 -f 3170//1588 3171//1588 3172//1588 -f 3173//1589 3174//1589 3175//1589 -f 3176//1590 3177//1590 3178//1590 -f 3179//1591 3180//1591 3181//1591 -f 3182//1592 3183//1592 3184//1592 -f 3185//1593 3186//1593 3187//1593 -f 3188//1590 3189//1590 3190//1590 -f 3191//1591 3192//1591 3193//1591 -f 3194//1592 3195//1592 3196//1592 -f 3197//1594 3198//1594 3199//1594 -f 3200//1595 3201//1595 3202//1595 -f 3203//1596 3204//1596 3205//1596 -f 3167//1597 3206//1597 3168//1597 -f 3207//1598 3208//1598 3209//1598 -f 3210//1591 3211//1591 3212//1591 -f 3213//1599 3214//1599 3215//1599 -f 3216//1600 3217//1600 3218//1600 -f 3179//1591 3219//1591 3180//1591 -f 3220//1601 3221//1601 3222//1601 -f 3191//1591 3223//1591 3192//1591 -f 3224//1601 3225//1601 3226//1601 -f 3227//1602 3228//1602 3229//1602 -f 3230//1603 3231//1603 3232//1603 -f 3233//1604 3234//1604 3235//1604 -f 3152//1605 3236//1605 3153//1605 -f 3237//1606 3238//1606 3239//1606 -f 3155//1605 3240//1605 3156//1605 -f 3241//1607 3242//1607 3243//1607 -f 3244//1608 3245//1608 3246//1608 -f 3247//1609 3248//1609 3249//1609 -f 3207//1598 3250//1598 3208//1598 -f 3251//1610 3252//1610 3253//1610 -f 3254//1611 3255//1611 3256//1611 -f 3257//1612 3258//1612 3259//1612 -f 3241//1613 3260//1613 3242//1613 -f 3261//1614 3262//1614 3199//1614 -f 3210//1591 3263//1591 3211//1591 -f 3264//1615 3265//1615 3266//1615 -f 3267//1616 3268//1616 3269//1616 -f 3270//1617 3271//1617 3272//1617 -f 3273//1617 3274//1617 3275//1617 -f 3276//1618 3277//1618 3278//1618 -f 3279//1619 3280//1619 3281//1619 -f 3282//1620 3283//1620 3284//1620 -f 3285//1619 3286//1619 3287//1619 -f 3288//1620 3289//1620 3290//1620 -f 3291//1621 3292//1621 3293//1621 -f 3294//1621 3295//1621 3296//1621 -f 3297//1622 3298//1622 3299//1622 -f 3300//1623 3301//1623 3302//1623 -f 3227//1624 3229//1624 3303//1624 -f 3304//1625 3305//1625 3306//1625 -f 3307//1626 3308//1626 3309//1626 -f 3310//1627 3311//1627 3312//1627 -f 3313//1628 3314//1628 3315//1628 -f 3316//1629 3317//1629 3318//1629 -f 3319//1630 3320//1630 3321//1630 -f 3322//1631 3300//1631 3302//1631 -f 3323//1632 3324//1632 3306//1632 -f 3310//1633 3312//1633 3325//1633 -f 3313//1634 3315//1634 3326//1634 -f 3327//1635 3328//1635 3329//1635 -f 3330//1636 3181//1636 3331//1636 -f 3332//1635 3333//1635 3334//1635 -f 3335//1636 3193//1636 3336//1636 -f 3337//1637 3338//1637 3339//1637 -f 3340//1638 3341//1638 3342//1638 -f 3343//1639 3344//1639 3345//1639 -f 3346//1639 3347//1639 3348//1639 -f 3349//1640 3350//1640 3351//1640 -f 3352//1641 3353//1641 3354//1641 -f 3204//1642 3355//1642 3205//1642 -f 3356//1643 3357//1643 3358//1643 -f 3200//1644 3359//1644 3201//1644 -f 3360//1645 3361//1645 3362//1645 -f 3363//1646 3364//1646 3365//1646 -f 3366//1647 3367//1647 3368//1647 -f 3369//1646 3370//1646 3371//1646 -f 3372//1647 3373//1647 3374//1647 -f 3375//1648 3376//1648 3377//1648 -f 3307//1649 3378//1649 3308//1649 -f 3379//1650 3380//1650 3381//1650 -f 3382//1651 3383//1651 3384//1651 -f 3385//1652 3386//1652 3387//1652 -f 3388//1651 3389//1651 3390//1651 -f 3391//1652 3392//1652 3393//1652 -f 3257//1653 3259//1653 3394//1653 -f 3395//1654 3396//1654 3397//1654 -f 3398//1655 3399//1655 3400//1655 -f 3401//1656 3402//1656 3403//1656 -f 3404//1657 3405//1657 3406//1657 -s 1 -f 3407//1658 3406//1658 3405//1658 -s off -f 3203//1659 3205//1659 3408//1659 -f 3409//1660 3410//1660 3411//1660 -f 3412//1661 3413//1661 3414//1661 -f 3415//1662 3416//1662 3417//1662 -f 3263//1663 3418//1663 3211//1663 -f 3419//1664 3209//1664 3420//1664 -f 3421//1665 3422//1665 3423//1665 -f 3424//1665 3425//1665 3426//1665 -f 3427//1666 3428//1666 3429//1666 -f 3430//1667 3431//1667 3432//1667 -f 3433//1668 3434//1668 3435//1668 -f 3436//1669 3437//1669 3438//1669 -s 1 -f 3439//1670 3440//1670 3441//1670 -f 3318//1658 3339//1671 3338//1658 -s off -f 3442//1672 3443//1672 3444//1672 -f 3445//1673 3446//1673 3447//1673 -f 3448//1673 3449//1673 3450//1673 -f 3451//1674 3452//1674 3453//1674 -f 3454//1674 3455//1674 3456//1674 -f 3436//1675 3457//1675 3437//1675 -f 3221//1676 3458//1676 3222//1676 -s 1 -f 3329//1658 3328//1658 3459//1658 -s off -f 3225//1676 3460//1676 3226//1676 -s 1 -f 3334//1658 3333//1658 3461//1658 -f 3246//1658 3245//1658 3462//1658 -s off -f 3463//1677 3464//1677 3465//1677 -f 3466//1678 3467//1678 3468//1678 -f 3469//1678 3470//1678 3471//1678 -f 3472//1679 3473//1679 3474//1679 -f 3475//1680 3476//1680 3477//1680 -f 3478//1681 3479//1681 3480//1681 -f 3481//1598 3482//1598 3483//1598 -s 1 -f 3484//1658 3309//1682 3308//1658 -f 3135//1658 3134//1658 3485//1658 -f 3486//1658 3215//1658 3214//1658 -s off -f 3250//1683 3487//1683 3208//1683 -f 3488//1684 3489//1684 3490//1684 -f 3401//1656 3491//1656 3402//1656 -f 3492//1685 3493//1685 3494//1685 -f 3495//1686 3496//1686 3497//1686 -f 3442//1687 3498//1687 3443//1687 -f 3495//1688 3499//1688 3496//1688 -s 1 -f 3500//1658 3199//1671 3198//1658 -s off -f 3501//1689 3502//1689 3503//1689 -f 3475//1690 3477//1690 3504//1690 -f 3505//1691 3506//1691 3507//1691 -f 3508//1598 3509//1598 3510//1598 -f 3295//1692 3511//1692 3296//1692 -s 1 -f 3512//1682 3178//1658 3177//1671 -s off -f 3292//1692 3513//1692 3293//1692 -s 1 -f 3514//1682 3190//1658 3189//1671 -s off -f 3185//1693 3515//1693 3186//1693 -f 3173//1693 3516//1693 3174//1693 -f 3517//1694 3518//1694 3519//1694 -f 3520//1695 3521//1695 3522//1695 -f 3508//1598 3510//1598 3523//1598 -s 1 -f 3218//1658 3217//1658 3524//1658 -f 3211//1671 3418//1658 3420//1658 -s off -f 3525//1696 3526//1696 3527//1696 -f 3481//1598 3483//1598 3528//1598 -f 3529//1598 3530//1598 3531//1598 -f 3532//1591 3533//1591 3534//1591 -f 3532//1591 3534//1591 3535//1591 -f 3529//1598 3536//1598 3530//1598 -f 3537//1598 3538//1598 3539//1598 -f 3540//1591 3541//1591 3542//1591 -f 3540//1591 3542//1591 3543//1591 -f 3537//1598 3544//1598 3538//1598 -f 3545//1697 3546//1697 3547//1697 -f 3548//1698 3549//1698 3550//1698 -s 1 -f 3438//1658 3437//1658 3434//1658 -s off -f 3492//1699 3551//1699 3493//1699 -s 1 -f 3552//1670 3553//1670 3554//1670 -s off -f 3555//1700 3556//1700 3557//1700 -f 3525//1701 3558//1701 3526//1701 -f 3433//1702 3559//1702 3434//1702 -f 3560//1703 3561//1703 3562//1703 -s 1 -f 3562//1658 3563//1658 3564//1658 -s off -f 3565//1704 3566//1704 3567//1704 -s 1 -f 3394//1658 3259//1658 3568//1658 -s off -f 3555//1705 3557//1705 3569//1705 -f 3478//1681 3480//1681 3570//1681 -s 1 -f 3203//1670 3491//1670 3401//1670 -s off -f 3571//1706 3572//1706 3573//1706 -f 3574//1707 3575//1707 3576//1707 -f 3577//1708 3578//1708 3579//1708 -f 3395//1709 3580//1709 3396//1709 -f 3505//1691 3581//1691 3506//1691 -f 3582//1710 3583//1710 3584//1710 -f 3585//1591 3586//1591 3587//1591 -f 3588//1598 3589//1598 3590//1598 -f 3585//1591 3591//1591 3586//1591 -f 3588//1598 3592//1598 3589//1598 -f 3593//1711 3594//1711 3595//1711 -s 1 -f 3326//1658 3325//1658 3312//1658 -s off -f 3596//1712 3597//1712 3598//1712 -f 3599//1713 3600//1713 3601//1713 -s 1 -f 3547//1658 3443//1658 3602//1658 -s off -f 3545//1714 3547//1714 3602//1714 -s 1 -f 3603//1658 3465//1658 3464//1658 -s off -f 3604//1715 3605//1715 3606//1715 -s 1 -f 3607//1658 3132//1658 3131//1658 -f 3608//1658 3503//1658 3502//1658 -s off -f 3609//1716 3610//1716 3611//1716 -f 3612//1716 3613//1716 3614//1716 -f 3615//1717 3616//1717 3617//1717 -s 1 -f 3618//1670 3559//1670 3457//1670 -f 3487//1658 3619//1658 3208//1658 -s off -f 3620//1718 3212//1718 3619//1718 -f 3621//1719 3622//1719 3623//1719 -s 1 -f 3316//1670 3624//1670 3317//1670 -f 3546//1670 3625//1670 3626//1670 -f 3627//1670 3440//1670 3359//1670 -f 3628//1670 3629//1670 3630//1670 -s off -f 3631//1720 3632//1720 3633//1720 -f 3634//1721 3635//1721 3636//1721 -f 3637//1721 3638//1721 3639//1721 -s 1 -f 3151//1671 3148//1671 3147//1671 -f 3640//1658 3368//1658 3367//1658 -f 3641//1658 3374//1658 3373//1658 -f 3166//1671 3163//1658 3162//1658 -s off -f 3146//1722 3642//1722 3147//1722 -f 3161//1722 3643//1722 3162//1722 -s 1 -f 3644//1670 3645//1670 3646//1670 -f 3184//1658 3183//1658 3647//1658 -f 3648//1658 3222//1658 3458//1658 -f 3196//1658 3195//1658 3649//1658 -f 3650//1658 3226//1658 3460//1658 -f 3651//1670 3652//1670 3653//1670 -f 3654//1670 3655//1670 3656//1670 -s off -f 3657//1723 3658//1723 3659//1723 -f 3660//1723 3661//1723 3662//1723 -s 1 -f 3172//1658 3171//1658 3663//1658 -s off -f 3664//1724 3665//1724 3666//1724 -s 1 -f 3667//1670 3250//1670 3668//1670 -f 3669//1658 3243//1658 3242//1658 -f 3670//1658 3671//1658 3672//1658 -f 3555//1670 3478//1670 3556//1670 -s off -f 3673//1725 3674//1725 3675//1725 -s 1 -f 3493//1658 3496//1658 3494//1658 -f 3676//1670 3621//1670 3677//1670 -f 3390//1658 3389//1658 3678//1726 -f 3145//1658 3154//1658 3153//1658 -f 3384//1658 3383//1658 3679//1726 -f 3160//1658 3157//1658 3156//1658 -s off -f 3680//1727 3681//1727 3514//1727 -f 3682//1727 3683//1727 3512//1727 -f 3684//1728 3685//1728 3686//1728 -f 3250//1729 3667//1729 3487//1729 -s 1 -f 3129//1658 3128//1658 3687//1658 -f 3138//1658 3137//1658 3688//1658 -f 3689//1658 3187//1658 3186//1658 -f 3690//1671 3293//1671 3513//1671 -f 3691//1658 3175//1658 3174//1658 -f 3692//1671 3296//1671 3511//1671 -f 3135//1658 3485//1658 3693//1658 -s off -f 3694//1730 3693//1730 3485//1730 -s 1 -f 3402//1671 3169//1671 3168//1671 -f 3354//1658 3353//1658 3695//1658 -s off -f 3696//1731 3697//1731 3698//1731 -f 3699//1591 3700//1591 3701//1591 -s 1 -f 3702//1658 3703//1658 3704//1658 -s off -f 3705//1732 3703//1732 3702//1732 -f 3596//1733 3706//1733 3597//1733 -s 1 -f 3123//1658 3122//1658 3126//1658 -f 3617//1658 3576//1658 3575//1658 -s off -f 3707//1734 3708//1734 3709//1734 -f 3699//1591 3701//1591 3710//1591 -s 1 -f 3326//1658 3315//1658 3325//1658 -f 3711//1658 3712//1658 3713//1658 -s off -f 3714//1735 3712//1735 3711//1735 -f 3715//1736 3716//1736 3713//1736 -s 1 -f 3711//1658 3713//1658 3716//1658 -s off -f 3717//1737 3718//1737 3719//1737 -f 3520//1738 3720//1738 3521//1738 -s 1 -f 3721//1670 3722//1670 3310//1670 -s off -f 3419//1739 3207//1739 3209//1739 -s 1 -f 3288//1670 3179//1670 3289//1670 -f 3723//1670 3724//1670 3725//1670 -f 3726//1670 3727//1670 3728//1670 -f 3282//1670 3191//1670 3283//1670 -s off -f 3729//1740 3194//1740 3196//1740 -f 3730//1740 3182//1740 3184//1740 -f 3219//1741 3731//1741 3180//1741 -s 1 -f 3180//1671 3512//1682 3177//1671 -s off -f 3223//1741 3732//1741 3192//1741 -s 1 -f 3192//1671 3514//1682 3189//1671 -f 3733//1670 3467//1670 3273//1670 -f 3734//1670 3470//1670 3270//1670 -s off -f 3735//1742 3736//1742 3737//1742 -f 3738//1743 3739//1743 3740//1743 -f 3741//1744 3742//1744 3743//1744 -s 1 -f 3145//1658 3144//1658 3154//1658 -f 3744//1658 3365//1658 3364//1658 -f 3160//1658 3159//1658 3157//1658 -f 3745//1658 3371//1658 3370//1658 -s off -f 3746//1745 3747//1745 3215//1745 -s 1 -f 3356//1670 3748//1670 3749//1670 -f 3551//1670 3750//1670 3499//1670 -s off -f 3751//1746 3752//1746 3753//1746 -s 1 -f 3432//1726 3417//1726 3416//1726 -f 3608//1658 3754//1658 3503//1658 -s off -f 3755//1747 3754//1747 3608//1747 -s 1 -f 3123//1658 3126//1658 3125//1658 -f 3259//1658 3397//1658 3396//1658 -s off -f 3164//1748 3756//1748 3165//1748 -f 3149//1748 3757//1748 3150//1748 -f 3158//1749 3758//1749 3159//1749 -f 3143//1749 3759//1749 3144//1749 -f 3760//1750 3761//1750 3762//1750 -s 1 -f 3306//1671 3305//1682 3309//1682 -f 3316//1670 3763//1670 3624//1670 -s off -f 3560//1636 3764//1636 3561//1636 -f 3765//1751 3766//1751 3767//1751 -f 3768//1751 3769//1751 3770//1751 -s 1 -f 3771//1658 3393//1658 3392//1671 -f 3151//1671 3150//1671 3148//1671 -f 3166//1671 3165//1658 3163//1658 -f 3772//1658 3387//1658 3386//1671 -s off -f 3773//1752 3676//1752 3774//1752 -s 1 -f 3775//1670 3776//1670 3777//1670 -f 3778//1670 3779//1670 3780//1670 -s off -f 3755//1753 3781//1753 3754//1753 -f 3751//1746 3782//1746 3752//1746 -s 1 -f 3783//1670 3264//1670 3784//1670 -f 3785//1670 3786//1670 3787//1670 -f 3550//1658 3549//1658 3698//1658 -f 3303//1658 3229//1671 3788//1658 -f 3223//1670 3681//1670 3680//1670 -f 3223//1670 3191//1670 3282//1670 -f 3219//1670 3683//1670 3682//1670 -f 3219//1670 3179//1670 3288//1670 -f 3455//1670 3789//1670 3790//1670 -f 3452//1670 3791//1670 3792//1670 -f 3554//1670 3553//1670 3793//1670 -f 3794//1670 3795//1670 3796//1670 -f 3797//1670 3798//1670 3799//1670 -f 3263//1670 3800//1670 3738//1670 -s off -f 3801//1754 3802//1754 3549//1754 -s 1 -f 3803//1670 3804//1670 3805//1670 -f 3481//1670 3558//1670 3525//1670 -f 3806//1670 3807//1670 3548//1670 -f 3808//1670 3696//1670 3809//1670 -s off -f 3565//1755 3810//1755 3566//1755 -s 1 -f 3811//1658 3812//1658 3181//1671 -f 3180//1671 3813//1671 3181//1671 -f 3192//1671 3814//1671 3193//1671 -f 3815//1658 3816//1658 3193//1671 -s off -f 3316//1756 3318//1756 3817//1756 -s 1 -f 3817//1658 3318//1658 3338//1658 -s off -f 3340//1757 3818//1757 3341//1757 -f 3630//1758 3629//1758 3819//1758 -f 3760//1750 3820//1750 3761//1750 -f 3821//1759 3822//1759 3823//1759 -s 1 -f 3203//1670 3824//1670 3491//1670 -f 3825//1670 3826//1670 3741//1670 -f 3584//1658 3827//1658 3828//1658 -s off -f 3829//1760 3828//1760 3827//1760 -s 1 -f 3721//1670 3310//1670 3314//1670 -s off -f 3577//1708 3830//1708 3578//1708 -s 1 -f 3270//1670 3470//1670 3469//1670 -f 3273//1670 3467//1670 3466//1670 -f 3831//1670 3262//1670 3359//1670 -s off -f 3682//1761 3512//1761 3731//1761 -s 1 -f 3180//1671 3731//1658 3512//1682 -s off -f 3680//1762 3514//1762 3732//1762 -s 1 -f 3192//1671 3732//1658 3514//1682 -f 3408//1671 3205//1658 3403//1658 -f 3205//1658 3355//1658 3403//1658 -s off -f 3832//1763 3833//1763 3834//1763 -f 3835//1764 3836//1764 3837//1764 -s 1 -f 3837//1658 3836//1658 3838//1658 -f 3839//1658 3840//1671 3841//1671 -s off -f 3842//1764 3840//1764 3839//1764 -f 3234//1765 3640//1765 3235//1765 -s 1 -f 3640//1658 3450//1658 3235//1658 -f 3641//1658 3447//1658 3239//1658 -s off -f 3238//1766 3641//1766 3239//1766 -s 1 -f 3675//1658 3674//1658 3252//1658 -f 3843//1671 3253//1671 3252//1658 -f 3844//1670 3845//1670 3846//1670 -f 3560//1670 3440//1670 3847//1670 -f 3848//1670 3849//1670 3850//1670 -f 3670//1658 3851//1658 3852//1658 -s off -f 3552//1767 3851//1767 3670//1767 -s 1 -f 3431//1670 3375//1670 3415//1670 -f 3853//1670 3854//1670 3855//1670 -f 3856//1670 3260//1670 3241//1670 -f 3857//1670 3858//1670 3859//1670 -f 3227//1670 3860//1670 3228//1670 -f 3846//1670 3845//1670 3398//1670 -f 3361//1670 3861//1670 3862//1670 -s off -f 3863//1768 3864//1768 3865//1768 -f 3866//1598 3867//1598 3868//1598 -s 1 -f 3869//1682 3666//1658 3665//1682 -f 3414//1682 3413//1726 3870//1726 -f 3710//1658 3871//1658 3868//1658 -s off -f 3866//1598 3868//1598 3871//1598 -f 3552//1769 3554//1769 3851//1769 -s 1 -f 3573//1658 3872//1658 3687//1658 -s off -f 3873//1770 3687//1770 3872//1770 -s 1 -f 3874//1670 3875//1670 3876//1670 -f 3862//1670 3861//1670 3877//1670 -f 3878//1658 3617//1658 3575//1658 -s off -f 3879//1771 3617//1771 3878//1771 -f 3793//1772 3553//1772 3852//1772 -f 3880//1773 3881//1773 3882//1773 -s 1 -f 3342//1671 3341//1658 3881//1658 -f 3883//1670 3884//1670 3143//1670 -f 3759//1670 3152//1670 3885//1670 -f 3886//1670 3887//1670 3158//1670 -f 3758//1670 3155//1670 3888//1670 -f 3889//1670 3890//1670 3891//1670 -f 3699//1670 3867//1670 3866//1670 -f 3892//1670 3893//1670 3894//1670 -f 3894//1670 3893//1670 3895//1670 -f 3896//1670 3897//1670 3898//1670 -f 3705//1670 3604//1670 3899//1670 -f 3900//1670 3516//1670 3173//1670 -f 3901//1670 3902//1670 3286//1670 -f 3903//1670 3515//1670 3185//1670 -f 3904//1670 3905//1670 3280//1670 -f 3254//1670 3231//1670 3230//1670 -s off -f 3906//1741 3523//1741 3907//1741 -s 1 -f 3523//1658 3522//1658 3521//1658 -f 3908//1670 3909//1670 3910//1670 -f 3340//1670 3911//1670 3818//1670 -f 3912//1670 3913//1670 3914//1670 -f 3609//1670 3915//1670 3916//1670 -f 3612//1670 3917//1670 3918//1670 -f 3919//1670 3920//1670 3921//1670 -f 3922//1670 3923//1670 3919//1670 -s off -f 3440//1774 3924//1774 3925//1774 -f 3718//1775 3926//1775 3719//1775 -s 1 -f 3719//1682 3926//1726 3927//1682 -f 3756//1670 3928//1670 3929//1670 -f 3164//1670 3643//1670 3928//1670 -f 3149//1670 3642//1670 3930//1670 -f 3757//1670 3930//1670 3931//1670 -f 3421//1670 3932//1670 3657//1670 -f 3424//1670 3933//1670 3660//1670 -f 3934//1670 3736//1670 3735//1670 -f 3848//1670 3935//1670 3849//1670 -s off -f 3936//1776 3912//1776 3937//1776 -f 3938//1777 3939//1777 3940//1777 -s 1 -f 3256//1671 3255//1671 3941//1671 -s off -f 3942//1778 3943//1778 3334//1778 -f 3944//1778 3945//1778 3329//1778 -f 3946//1779 3813//1779 3947//1779 -s 1 -f 3180//1671 3947//1671 3813//1671 -s off -f 3948//1779 3814//1779 3949//1779 -s 1 -f 3192//1671 3949//1671 3814//1671 -f 3856//1670 3950//1670 3951//1670 -f 3952//1670 3953//1670 3954//1670 -f 3955//1670 3366//1670 3768//1670 -f 3956//1670 3957//1670 3958//1670 -f 3959//1670 3372//1670 3765//1670 -s off -f 3863//1780 3865//1780 3672//1780 -s 1 -f 3960//1658 3672//1658 3865//1658 -f 3825//1670 3961//1670 3826//1670 -f 3412//1670 3962//1670 3963//1670 -f 3964//1658 3659//1658 3461//1658 -s off -f 3658//1781 3461//1781 3659//1781 -f 3661//1781 3459//1781 3662//1781 -s 1 -f 3965//1658 3662//1658 3459//1658 -s off -f 3966//1782 3967//1782 3968//1782 -s 1 -f 3968//1658 3967//1658 3464//1658 -s off -f 3969//1783 3970//1783 3971//1783 -s 1 -f 3972//1658 3973//1658 3974//1658 -s off -f 3975//1784 3974//1784 3973//1784 -s 1 -f 3428//1670 3976//1670 3977//1670 -f 3773//1670 3978//1670 3463//1670 -s off -f 3130//1785 3979//1785 3131//1785 -s 1 -f 3980//1670 3343//1670 3391//1670 -f 3981//1670 3982//1670 3983//1670 -f 3984//1670 3346//1670 3385//1670 -f 3985//1670 3986//1670 3987//1670 -s off -f 3349//1786 3351//1786 3988//1786 -s 1 -f 3988//1658 3351//1658 3490//1658 -s off -f 3989//1787 3990//1787 3991//1787 -s 1 -f 3992//1658 3993//1658 3994//1658 -s off -f 3778//1788 3993//1788 3992//1788 -s 1 -f 3995//1726 3302//1658 3301//1671 -f 3995//1726 3523//1658 3996//1658 -s off -f 3997//1789 3998//1789 3999//1789 -f 4000//1789 4001//1789 4002//1789 -f 4003//1790 4004//1790 4005//1790 -s 1 -f 3456//1658 4005//1658 4004//1682 -f 3453//1658 4006//1658 4007//1682 -s off -f 4008//1790 4007//1790 4006//1790 -f 4009//1791 4010//1791 4011//1791 -s 1 -f 3121//1670 3124//1670 3409//1670 -f 4012//1670 4013//1670 3116//1670 -f 4014//1670 3594//1670 3593//1670 -f 4015//1670 4016//1670 4014//1670 -f 3202//1671 3201//1658 3199//1671 -f 3135//1658 3693//1658 3201//1658 -s off -f 4017//1792 3652//1792 4018//1792 -f 4019//1793 3655//1793 4020//1793 -f 3188//1794 4021//1794 3189//1794 -f 3176//1794 4022//1794 3177//1794 -f 4023//1795 4024//1795 4025//1795 -f 4026//1591 3906//1591 3907//1591 -f 3352//1796 4027//1796 3353//1796 -f 3646//1797 4028//1797 4029//1797 -f 4030//1798 4031//1798 4032//1798 -s 1 -f 4033//1670 3580//1670 3395//1670 -f 3528//1658 3527//1658 3526//1658 -s off -f 4034//1741 3528//1741 4035//1741 -f 4036//1799 4037//1799 4038//1799 -f 3696//1800 3698//1800 4039//1800 -s 1 -f 3549//1658 4039//1658 3698//1658 -s off -f 4040//1801 4041//1801 4042//1801 -s 1 -f 4043//1670 4044//1670 4045//1670 -f 3508//1670 3720//1670 3520//1670 -f 4026//1670 3508//1670 3906//1670 -f 4046//1670 4047//1670 4048//1670 -f 4049//1670 4050//1670 4051//1670 -f 4052//1670 4053//1670 4054//1670 -f 3203//1670 3401//1670 3204//1670 -f 3507//1671 3504//1671 3477//1671 -f 4055//1658 3570//1658 3480//1658 -f 4056//1670 4057//1670 4058//1670 -f 4059//1670 3291//1670 4060//1670 -f 4061//1670 4062//1670 4063//1670 -f 4064//1670 3294//1670 4065//1670 -s off -f 3783//1802 3714//1802 3711//1802 -f 3977//1803 4066//1803 4067//1803 -s 1 -f 3429//1658 4067//1658 4066//1658 -f 4068//1670 3264//1670 4069//1670 -s off -f 4070//1804 3880//1804 3882//1804 -s 1 -f 3989//1670 4030//1670 3990//1670 -s off -f 3620//1805 3210//1805 3212//1805 -s 1 -f 4071//1670 4072//1670 4073//1670 -f 4073//1670 4072//1670 4074//1670 -s off -f 4075//1806 3798//1806 4076//1806 -s 1 -f 3934//1670 3735//1670 4077//1670 -s off -f 4078//1807 4079//1807 3650//1807 -s 1 -f 3650//1658 4079//1658 3226//1658 -f 3648//1658 4080//1658 3222//1658 -s off -f 4081//1807 4080//1807 3648//1807 -f 4082//1591 4083//1591 4084//1591 -f 4085//1598 4086//1598 4087//1598 -f 4085//1598 4088//1598 4086//1598 -f 4082//1591 4089//1591 4083//1591 -s 1 -f 3653//1670 3652//1670 4017//1670 -f 3656//1670 3655//1670 4019//1670 -f 3952//1670 3234//1670 3449//1670 -f 3449//1670 4090//1670 4091//1670 -f 3446//1670 4092//1670 4093//1670 -f 3956//1670 3238//1670 3446//1670 -s off -f 3330//1636 3179//1636 3181//1636 -f 3335//1636 3191//1636 3193//1636 -s 1 -f 4094//1670 3404//1670 3833//1670 -f 4095//1670 3488//1670 4096//1670 -s off -f 3895//1808 3893//1808 4097//1808 -f 3938//1809 4098//1809 3939//1809 -s 1 -f 3989//1670 4099//1670 4030//1670 -f 3170//1670 4100//1670 4101//1670 -s off -f 4102//1810 4103//1810 4104//1810 -s 1 -f 4105//1658 4104//1658 4103//1658 -s off -f 3793//1811 3852//1811 4106//1811 -s 1 -f 3851//1658 4106//1658 3852//1658 -s off -f 3860//1812 4107//1812 4108//1812 -f 4109//1813 4110//1813 3666//1813 -f 4045//1814 4044//1814 4111//1814 -f 3855//1815 3854//1815 4112//1815 -s 1 -f 4113//1670 4114//1670 4115//1670 -f 4113//1670 4116//1670 3276//1670 -f 4117//1670 4118//1670 3267//1670 -f 4117//1670 4119//1670 4120//1670 -f 4121//1670 4122//1670 4123//1670 -s off -f 4058//1816 4057//1816 4124//1816 -f 4063//1816 4062//1816 4125//1816 -s 1 -f 4126//1670 3179//1670 4127//1670 -f 4128//1670 3191//1670 4129//1670 -s off -f 3803//1591 4034//1591 4035//1591 -s 1 -f 4130//1670 4131//1670 3966//1670 -f 3505//1670 3476//1670 3475//1670 -f 4132//1670 3479//1670 3478//1670 -s off -f 4133//1817 4134//1817 3869//1817 -f 4135//1818 4136//1818 4006//1818 -f 4137//1818 4138//1818 4005//1818 -f 3314//1636 4139//1636 4140//1636 -f 4115//1819 4114//1819 4141//1819 -f 4120//1819 4119//1819 4142//1819 -f 4143//1820 4053//1820 4144//1820 -s 1 -f 4078//1670 3225//1670 4145//1670 -f 4145//1670 3225//1670 3224//1670 -f 4146//1670 3221//1670 3220//1670 -f 4081//1670 3221//1670 4146//1670 -s off -f 3917//1821 3841//1821 4002//1821 -s 1 -f 3840//1671 4002//1658 3841//1671 -s off -f 3915//1821 3838//1821 3999//1821 -s 1 -f 3836//1658 3999//1658 3838//1658 -s off -f 4147//1741 3710//1741 4148//1741 -f 3314//1636 4140//1636 3315//1636 -s 1 -f 4149//1658 3940//1658 3939//1658 -f 4149//1658 4150//1658 3940//1658 -f 4026//1670 3300//1670 4151//1670 -f 4026//1670 4151//1670 3508//1670 -f 4152//1726 3882//1658 3881//1658 -f 4152//1726 3528//1658 3882//1658 -f 4153//1670 4154//1670 3320//1670 -f 3853//1670 3855//1670 4155//1670 -f 3223//1670 4021//1670 3681//1670 -f 3681//1670 4021//1670 3188//1670 -f 3219//1670 4022//1670 3683//1670 -f 3683//1670 4022//1670 3176//1670 -s off -f 4015//1822 4014//1822 4156//1822 -s 1 -f 4157//1670 4044//1670 4043//1670 -f 3552//1670 4158//1670 4159//1670 -f 4160//1670 4024//1670 4037//1670 -s off -f 4161//1823 3216//1823 3218//1823 -s 1 -f 3699//1670 3310//1670 3867//1670 -s off -f 3908//1824 3829//1824 3827//1824 -s 1 -f 3803//1670 3805//1670 3481//1670 -f 3808//1670 3809//1670 4162//1670 -f 3785//1670 4163//1670 3786//1670 -s off -f 4164//1825 4165//1825 4166//1825 -s 1 -f 4167//1658 4166//1658 4165//1658 -s off -f 4168//1826 4169//1826 4170//1826 -s 1 -f 4171//1670 3938//1670 4172//1670 -s off -f 3954//1827 3953//1827 4173//1827 -f 3958//1827 3957//1827 4174//1827 -s 1 -f 4175//1670 4168//1670 4176//1670 -s off -f 4177//1828 4178//1828 4179//1828 -f 4180//1828 4181//1828 4182//1828 -s 1 -f 3409//1670 3124//1670 4183//1670 -s off -f 3853//1829 4167//1829 4184//1829 -s 1 -f 4184//1658 4167//1658 4165//1658 -s off -f 4185//1830 3975//1830 3973//1830 -s 1 -f 4186//1670 4187//1670 4102//1670 -f 3597//1658 3972//1658 3974//1658 -s off -f 4188//1831 3972//1831 3597//1831 -s 1 -f 4127//1670 3179//1670 3330//1670 -f 4129//1670 3191//1670 3335//1670 -s off -f 4056//1832 4189//1832 3690//1832 -f 4061//1833 4190//1833 3692//1833 -s 1 -f 4171//1670 4098//1670 3938//1670 -f 3969//1670 4191//1670 4192//1670 -s off -f 4017//1834 4018//1834 4193//1834 -s 1 -f 4194//1658 4193//1658 4018//1658 -f 4195//1658 4196//1658 4020//1658 -s off -f 4019//1834 4020//1834 4196//1834 -f 4197//1835 3959//1835 4198//1835 -f 4199//1835 3955//1835 4200//1835 -s 1 -f 3937//1658 4201//1658 4202//1658 -s off -f 4203//1836 4202//1836 4201//1836 -f 4204//1837 4205//1837 4206//1837 -s 1 -f 3686//1658 4206//1658 4205//1726 -s off -f 4207//1838 4208//1838 4209//1838 -f 4210//1838 4211//1838 4212//1838 -s 1 -f 3686//1658 4213//1658 4206//1658 -s off -f 3685//1839 4213//1839 3686//1839 -f 4147//1741 3699//1741 3710//1741 -f 4214//1598 4215//1598 4216//1598 -s 1 -f 3710//1658 3868//1658 3325//1658 -s off -f 4214//1598 4217//1598 4215//1598 -f 4218//1840 3136//1840 3138//1840 -f 3899//1841 3604//1841 3606//1841 -s 1 -f 3359//1670 3262//1670 4219//1670 -f 3627//1670 3359//1670 4219//1670 -f 3606//1658 3605//1658 3823//1658 -s off -f 3821//1759 3823//1759 3605//1759 -f 3705//1842 4220//1842 3703//1842 -s 1 -f 4156//1658 4221//1658 4222//1658 -s off -f 4223//1843 4222//1843 4221//1843 -s 1 -f 3799//1670 3798//1670 4075//1670 -s off -f 4224//1844 4225//1844 4226//1844 -s 1 -f 4227//1726 4226//1726 4225//1658 -f 4228//1726 4229//1726 4230//1658 -s off -f 4231//1844 4230//1844 4229//1844 -s 1 -f 3451//1670 4232//1670 3452//1670 -f 3454//1670 4233//1670 3455//1670 -f 4234//1658 4235//1658 3524//1658 -s off -f 4236//1845 3524//1845 4235//1845 -f 4237//1846 3934//1846 4238//1846 -f 4239//1847 4240//1847 4241//1847 -f 4242//1848 3874//1848 4243//1848 -f 4244//1849 4245//1849 4246//1849 -s 1 -f 4246//1658 4245//1658 4247//1658 -s off -f 4248//1850 4249//1850 4250//1850 -s 1 -f 4250//1658 4249//1658 4251//1658 -f 3775//1670 3777//1670 4252//1670 -s off -f 4153//1851 4253//1851 4254//1851 -f 4255//1852 4256//1852 4257//1852 -s 1 -f 4257//1658 4256//1658 4141//1658 -f 4258//1658 4259//1658 4142//1658 -s off -f 4260//1853 4259//1853 4258//1853 -s 1 -f 3803//1670 3481//1670 4034//1670 -f 3628//1670 3630//1670 4261//1670 -f 4262//1682 3453//1658 4007//1682 -s off -f 3451//1854 3453//1854 4262//1854 -f 3454//1854 3456//1854 4263//1854 -s 1 -f 4263//1682 3456//1658 4004//1682 -f 4060//1670 3291//1670 4264//1670 -f 4065//1670 3294//1670 4265//1670 -f 3619//1658 3212//1658 3208//1658 -f 3212//1658 3209//1671 3208//1658 -f 3212//1658 3211//1671 3209//1671 -f 3211//1671 3420//1658 3209//1671 -f 3640//1658 4266//1658 3450//1658 -s off -f 3448//1855 3450//1855 4266//1855 -s 1 -f 3641//1658 4267//1658 3447//1658 -s off -f 3445//1855 3447//1855 4267//1855 -f 4268//1856 4269//1856 3214//1856 -s 1 -f 4270//1670 4271//1670 4272//1670 -f 4273//1670 3307//1670 4274//1670 -f 4275//1670 3979//1670 3130//1670 -s off -f 4276//1857 4277//1857 4278//1857 -f 4279//1858 4280//1858 4281//1858 -s 1 -f 4282//1670 3600//1670 3599//1670 -f 3677//1670 3621//1670 4283//1670 -s off -f 3285//1859 3287//1859 4284//1859 -s 1 -f 4284//1658 3287//1658 4285//1658 -f 4286//1658 3281//1658 4287//1658 -s off -f 3279//1859 3281//1859 4286//1859 -s 1 -f 3726//1670 4280//1670 3727//1670 -f 3723//1670 4277//1670 3724//1670 -f 4288//1670 3975//1670 4185//1670 -s off -f 4145//1860 4289//1860 4290//1860 -f 4146//1860 4291//1860 4292//1860 -s 1 -f 4293//1670 3600//1670 4282//1670 -f 4243//1658 4294//1658 3141//1658 -s off -f 3139//1861 3141//1861 4294//1861 -f 4210//1862 4212//1862 4251//1862 -s 1 -f 4250//1658 4251//1658 4212//1658 -s off -f 4207//1862 4209//1862 4247//1862 -s 1 -f 4246//1658 4247//1658 4209//1658 -s off -f 4045//1863 4111//1863 4295//1863 -s 1 -f 4296//1658 4295//1658 4111//1658 -s off -f 4242//1864 4243//1864 4297//1864 -s 1 -f 4297//1658 4243//1658 3141//1658 -s off -f 4298//1865 4299//1865 4300//1865 -s 1 -f 3613//1670 4301//1670 4302//1670 -f 3610//1670 4303//1670 4304//1670 -s off -f 4305//1866 4306//1866 4307//1866 -s 1 -f 3983//1670 3982//1670 4308//1670 -f 3987//1670 3986//1670 4309//1670 -s off -f 3853//1867 4310//1867 4167//1867 -s 1 -f 4311//1670 4312//1670 4313//1670 -s off -f 3873//1868 4271//1868 3687//1868 -s 1 -f 3210//1670 3207//1670 3263//1670 -f 3263//1670 3207//1670 3800//1670 -f 3668//1670 3250//1670 3210//1670 -f 3210//1670 3250//1670 3207//1670 -s off -f 3677//1869 3244//1869 3246//1869 -s 1 -f 3874//1670 3876//1670 4314//1670 -s off -f 4315//1870 4316//1870 3584//1870 -s 1 -f 3827//1658 3584//1658 4316//1658 -f 3120//1671 3960//1658 4317//1658 -s off -f 3119//1871 3960//1871 3120//1871 -s 1 -f 3529//1670 3532//1670 3536//1670 -f 3532//1670 3529//1670 3533//1670 -f 3546//1670 3626//1670 3442//1670 -f 3457//1670 3559//1670 3433//1670 -f 3537//1670 3540//1670 3544//1670 -f 3508//1670 3520//1670 3509//1670 -f 3699//1670 3866//1670 3700//1670 -f 3551//1670 3499//1670 3495//1670 -f 3481//1670 3525//1670 3482//1670 -f 3540//1670 3537//1670 3541//1670 -f 4085//1670 4082//1670 4088//1670 -f 3588//1670 3585//1670 3592//1670 -f 4082//1670 4085//1670 4089//1670 -f 3585//1670 3588//1670 3591//1670 -s off -f 4318//1872 4186//1872 4105//1872 -f 3921//1873 3920//1873 4319//1873 -f 4049//1874 4320//1874 4321//1874 -f 3645//1875 4322//1875 4323//1875 -s 1 -f 4153//1670 3320//1670 4324//1670 -s off -f 4325//1876 4326//1876 3995//1876 -s 1 -f 3505//1670 3475//1670 3581//1670 -s off -f 3955//1877 4327//1877 4200//1877 -s 1 -f 4200//1658 4327//1658 3368//1658 -f 4198//1658 4328//1658 3374//1658 -s off -f 3959//1877 4328//1877 4198//1877 -s 1 -f 4329//1670 4330//1670 4331//1670 -f 3519//1658 4332//1658 3266//1658 -s off -f 3518//1878 4332//1878 3519//1878 -f 4333//1879 4334//1879 4335//1879 -s 1 -f 4335//1658 4334//1658 3474//1658 -s off -f 4102//1880 4187//1880 4103//1880 -s 1 -f 3170//1670 4101//1670 4336//1670 -s off -f 4183//1881 3124//1881 3126//1881 -s 1 -f 4029//1658 3117//1658 4337//1658 -s off -f 3116//1882 4337//1882 3117//1882 -s 1 -f 4338//1658 4339//1658 3601//1658 -s off -f 3599//1883 3601//1883 4339//1883 -f 4051//1884 4050//1884 4340//1884 -s 1 -f 4128//1670 4129//1670 3942//1670 -f 4126//1670 4127//1670 3944//1670 -s off -f 3986//1885 3385//1885 3387//1885 -f 3982//1885 3391//1885 3393//1885 -f 3251//1886 4341//1886 3252//1886 -f 3556//1741 3478//1741 3570//1741 -f 3921//1887 4319//1887 4342//1887 -s 1 -f 4343//1671 4342//1671 4319//1671 -s off -f 3223//1741 3680//1741 3732//1741 -f 3536//1636 3532//1636 3535//1636 -f 3546//1636 3442//1636 3444//1636 -f 3533//1741 3529//1741 3531//1741 -f 3219//1741 3682//1741 3731//1741 -f 3551//1636 3495//1636 3497//1636 -f 3457//1636 3433//1636 3435//1636 -f 3541//1741 3537//1741 3539//1741 -f 3509//1636 3520//1636 3522//1636 -f 3482//1636 3525//1636 3527//1636 -f 3544//1636 3540//1636 3543//1636 -f 3700//1888 3866//1888 3871//1888 -f 3591//1741 3588//1741 3590//1741 -f 3592//1636 3585//1636 3587//1636 -f 4088//1636 4082//1636 4084//1636 -f 4089//1741 4085//1741 4087//1741 -s 1 -f 4344//1670 4345//1670 4346//1670 -f 3706//1670 3596//1670 4347//1670 -s off -f 3847//1889 4348//1889 4349//1889 -f 4036//1890 4038//1890 4350//1890 -s 1 -f 4350//1658 4038//1658 4025//1658 -f 3759//1670 3885//1670 4351//1670 -f 3758//1670 3888//1670 4352//1670 -s off -f 3204//1891 4052//1891 3355//1891 -f 3581//1741 3475//1741 3504//1741 -s 1 -f 4094//1670 3832//1670 4353//1670 -f 3926//1726 4340//1726 3927//1682 -s off -f 4050//1892 3927//1892 4340//1892 -s 1 -f 3569//1726 3557//1658 3570//1658 -s off -f 3556//1741 3570//1741 3557//1741 -s 1 -f 3535//1658 3534//1658 3531//1658 -s off -f 3533//1741 3531//1741 3534//1741 -s 1 -f 3547//1658 3444//1658 3443//1658 -s off -f 3546//1636 3444//1636 3547//1636 -s 1 -f 3531//1658 3530//1658 3535//1658 -s off -f 3536//1636 3535//1636 3530//1636 -f 3700//1893 3871//1893 3701//1893 -s 1 -f 3710//1658 3701//1658 3871//1658 -s off -f 3509//1636 3522//1636 3510//1636 -s 1 -f 3523//1658 3510//1658 3522//1658 -s off -f 3544//1636 3543//1636 3538//1636 -s 1 -f 3539//1658 3538//1658 3543//1658 -f 3528//1658 3483//1658 3527//1658 -s off -f 3482//1636 3527//1636 3483//1636 -s 1 -f 3437//1658 3435//1658 3434//1658 -s off -f 3457//1636 3435//1636 3437//1636 -s 1 -f 3543//1658 3542//1658 3539//1658 -s off -f 3541//1741 3539//1741 3542//1741 -s 1 -f 3493//1658 3497//1658 3496//1658 -s off -f 3551//1636 3497//1636 3493//1636 -f 4088//1636 4084//1636 4086//1636 -s 1 -f 4087//1658 4086//1658 4084//1658 -f 3587//1658 3586//1658 3590//1658 -s off -f 3591//1741 3590//1741 3586//1741 -f 4089//1741 4087//1741 4083//1741 -s 1 -f 4084//1658 4083//1658 4087//1658 -f 3590//1658 3589//1658 3587//1658 -s off -f 3592//1636 3587//1636 3589//1636 -f 3574//1894 4354//1894 3575//1894 -f 4127//1598 3330//1598 3331//1598 -f 4129//1598 3335//1598 3336//1598 -s 1 -f 4325//1670 4355//1670 4326//1670 -s off -f 3479//1636 3505//1636 3507//1636 -f 4162//1895 4356//1895 3303//1895 -f 3581//1741 3504//1741 3506//1741 -s 1 -f 3507//1671 3506//1658 3504//1671 -f 3408//1671 3403//1658 3402//1671 -f 3408//1671 3402//1671 3168//1671 -s off -f 4034//1741 3481//1741 3528//1741 -f 3906//1741 3508//1741 3523//1741 -s 1 -f 3924//1670 4169//1670 4168//1670 -f 4139//1670 3699//1670 4147//1670 -s off -f 3962//1896 3415//1896 3417//1896 -f 3825//1897 4357//1897 3869//1897 -s 1 -f 3869//1682 4357//1658 3666//1658 -s off -f 3915//1898 4358//1898 3838//1898 -f 3917//1898 4359//1898 3841//1898 -s 1 -f 3562//1658 3564//1658 3925//1658 -s off -f 3440//1899 3925//1899 3564//1899 -s 1 -f 3995//1726 3907//1658 3523//1658 -s off -f 4026//1900 3907//1900 3995//1900 -s 1 -f 4133//1670 3962//1670 4360//1670 -s off -f 3876//1901 4361//1901 4362//1901 -f 4351//1902 4244//1902 4246//1902 -f 4352//1903 4248//1903 4250//1903 -f 3644//1904 4029//1904 4363//1904 -s 1 -f 4363//1658 4029//1658 4364//1658 -f 4214//1670 3310//1670 4217//1670 -f 3356//1670 4365//1670 3748//1670 -s off -f 3929//1905 4260//1905 4258//1905 -f 3931//1906 4255//1906 4257//1906 -f 4126//1907 4366//1907 3811//1907 -s 1 -f 3811//1658 4366//1658 3812//1658 -s off -f 4128//1907 4367//1907 3815//1907 -s 1 -f 3815//1658 4367//1658 3816//1658 -f 3769//1670 3366//1670 4368//1670 -f 3766//1670 3372//1670 4369//1670 -f 3886//1670 4370//1670 3887//1670 -f 3883//1670 4371//1670 3884//1670 -s off -f 4093//1908 4372//1908 4373//1908 -f 4091//1908 4374//1908 4375//1908 -s 1 -f 4238//1658 4376//1658 3737//1658 -s off -f 3735//1909 3737//1909 4376//1909 -f 4377//1910 4378//1910 4379//1910 -s 1 -f 3740//1658 4380//1658 4381//1658 -s off -f 4346//1911 4381//1911 4380//1911 -s 1 -f 3430//1670 3375//1670 3431//1670 -f 4155//1670 4164//1670 4382//1670 -s off -f 3479//1636 3507//1636 3480//1636 -s 1 -f 3507//1671 4055//1658 3480//1658 -s off -f 4383//1912 3883//1912 4384//1912 -f 4385//1912 3886//1912 4386//1912 -s 1 -f 3424//1670 4387//1670 3425//1670 -f 3421//1670 4388//1670 3422//1670 -s off -f 3337//1913 4389//1913 3338//1913 -s 1 -f 4390//1670 4391//1670 4392//1670 -s off -f 4393//1914 3948//1914 3949//1914 -f 4394//1915 3946//1915 3947//1915 -f 3673//1916 4395//1916 3674//1916 -s 1 -f 3138//1658 3688//1658 3400//1658 -s off -f 3398//1917 3400//1917 3688//1917 -s 1 -f 3857//1670 4396//1670 4397//1670 -f 3806//1670 4172//1670 3807//1670 -s off -f 4139//1591 4147//1591 4148//1591 -f 4169//1918 3562//1918 4170//1918 -s 1 -f 3925//1658 4170//1658 3562//1658 -f 4054//1670 4053//1670 3913//1670 -f 3303//1658 3788//1658 4108//1671 -s off -f 3860//1919 4108//1919 3788//1919 -f 3706//1920 4188//1920 3597//1920 -f 4159//1921 4398//1921 4296//1921 -f 4127//1598 3331//1598 3812//1598 -s 1 -f 3812//1658 3331//1658 3181//1671 -f 3816//1658 3336//1658 3193//1671 -s off -f 4129//1598 3336//1598 3816//1598 -s 1 -f 4397//1670 4396//1670 3863//1670 -s off -f 4095//1922 4096//1922 3407//1922 -s 1 -f 4093//1670 4092//1670 4399//1670 -f 4091//1670 4090//1670 4400//1670 -f 3505//1670 3479//1670 4132//1670 -s off -f 3230//1923 3232//1923 3941//1923 -s 1 -f 3256//1671 3941//1671 3232//1658 -s off -f 4391//1924 4223//1924 4221//1924 -f 3867//1741 4214//1741 4216//1741 -f 4217//1636 3310//1636 3325//1636 -f 4139//1591 4148//1591 4140//1591 -s 1 -f 4140//1658 4148//1658 3710//1658 -f 3315//1658 4140//1658 3710//1658 -f 3315//1658 3710//1658 3325//1658 -s off -f 3170//1925 4336//1925 3171//1925 -s 1 -f 4401//1670 4402//1670 4275//1670 -s off -f 4403//1926 4283//1926 4404//1926 -f 4283//1927 4405//1927 4404//1927 -s 1 -f 3246//1658 4404//1658 4405//1658 -s off -f 4130//1928 3966//1928 3968//1928 -f 4346//1929 4345//1929 4381//1929 -f 3806//1930 3548//1930 3550//1930 -s 1 -f 4152//1726 4035//1658 3528//1658 -s off -f 3803//1591 4035//1591 4152//1591 -s 1 -f 4244//1670 4406//1670 4207//1670 -f 4248//1670 4407//1670 4210//1670 -f 3908//1670 3910//1670 3829//1670 -s off -f 3867//1741 4216//1741 3868//1741 -s 1 -f 3868//1658 4216//1658 3325//1658 -f 4216//1658 4215//1658 3325//1658 -s off -f 4217//1636 3325//1636 4215//1636 -s 1 -f 3120//1671 4408//1658 4241//1671 -s off -f 4239//1931 4241//1931 4408//1931 -f 3847//1932 4349//1932 3563//1932 -s 1 -f 3563//1658 4349//1658 3564//1658 -s off -f 4409//1933 4410//1933 4411//1933 -s 1 -f 3937//1658 4412//1658 4201//1658 -s off -f 3912//1934 4412//1934 3937//1934 -s 1 -f 3172//1658 3663//1658 4413//1658 -s off -f 4414//1935 4413//1935 3663//1935 -s 1 -f 3898//1670 3897//1670 4415//1670 -s off -f 4072//1936 4416//1936 3695//1936 -s 1 -f 3794//1670 3796//1670 3350//1670 -s off -f 3572//1937 4417//1937 3573//1937 -s 1 -f 3573//1658 4417//1658 3872//1658 -s off -f 3715//1938 3784//1938 3716//1938 -s 1 -f 3219//1670 3946//1670 4394//1670 -f 3223//1670 3948//1670 4393//1670 -s off -f 4320//1939 3484//1939 4321//1939 -s 1 -f 4321//1658 3484//1658 4418//1658 -f 3673//1670 4365//1670 4395//1670 -f 3560//1670 3847//1670 3764//1670 -f 4374//1670 3642//1670 3149//1670 -f 4372//1670 3643//1670 3164//1670 -s off -f 4072//1940 3695//1940 4419//1940 -s 1 -f 4420//1658 4419//1658 3695//1658 -s off -f 4421//1941 4422//1941 4423//1941 -f 4424//1942 4126//1942 3811//1942 -f 4425//1942 4128//1942 3815//1942 -s 1 -f 3411//1658 4426//1658 3737//1658 -s off -f 3410//1943 4426//1943 3411//1943 -s 1 -f 4304//1670 4303//1670 3681//1670 -f 4302//1670 4301//1670 3683//1670 -f 3314//1670 3699//1670 4139//1670 -f 3314//1670 3310//1670 3699//1670 -f 4427//1670 3346//1670 3984//1670 -f 4428//1670 3343//1670 3980//1670 -f 3644//1670 4322//1670 3645//1670 -s off -f 3427//1944 3429//1944 4429//1944 -s 1 -f 4429//1658 3429//1658 4066//1658 -f 4430//1671 4254//1671 3321//1658 -s off -f 4153//1945 4254//1945 4430//1945 -s 1 -f 4431//1658 3381//1658 4432//1658 -s off -f 3380//1946 4432//1946 3381//1946 -f 4433//1947 4149//1947 3971//1947 -s 1 -f 3971//1658 4149//1658 3939//1658 -s off -f 4434//1948 4435//1948 4436//1948 -s 1 -f 4437//1658 4438//1658 4125//1658 -s off -f 4063//1949 4125//1949 4438//1949 -s 1 -f 4439//1658 4440//1658 4124//1658 -s off -f 4058//1950 4124//1950 4440//1950 -s 1 -f 4441//1658 4338//1658 3601//1658 -s off -f 4442//1951 4338//1951 4441//1951 -s 1 -f 4156//1658 4443//1658 4221//1658 -s off -f 4014//1952 4443//1952 4156//1952 -f 4444//1953 4203//1953 4201//1953 -s 1 -f 4445//1670 4446//1670 3903//1670 -f 4447//1670 4448//1670 3900//1670 -f 4449//1658 4450//1658 4039//1658 -s off -f 4451//1954 4450//1954 4449//1954 -f 3890//1955 4204//1955 4206//1955 -s 1 -f 3867//1670 3310//1670 4214//1670 -s off -f 3127//1956 4452//1956 3128//1956 -f 4172//1957 4453//1957 3438//1957 -f 4442//1958 4454//1958 4338//1958 -s 1 -f 3299//1658 4455//1658 4076//1658 -s off -f 4075//1959 4076//1959 4455//1959 -f 4456//1960 4457//1960 4413//1960 -s 1 -f 3276//1670 4224//1670 3344//1670 -f 3267//1670 4231//1670 3347//1670 -f 4350//1658 4025//1658 4458//1658 -s off -f 4024//1961 4458//1961 4025//1961 -f 4459//1962 4460//1962 4461//1962 -f 4462//1962 4463//1962 4464//1962 -s 1 -f 4369//1670 4465//1670 3369//1670 -f 4368//1670 4466//1670 3363//1670 -s off -f 4325//1963 3995//1963 4467//1963 -s 1 -f 4467//1671 3995//1726 3301//1671 -s off -f 3977//1964 4468//1964 4066//1964 -s 1 -f 4254//1671 4469//1671 3321//1658 -s off -f 3319//1965 3321//1965 4469//1965 -s 1 -f 3615//1670 4354//1670 3574//1670 -f 4379//1658 4470//1658 4471//1658 -s off -f 4378//1966 4470//1966 4379//1966 -f 4472//1967 4473//1967 3689//1967 -f 4474//1967 4475//1967 3691//1967 -f 3263//1968 3738//1968 3418//1968 -s 1 -f 3780//1670 3779//1670 4476//1670 -f 3410//1670 3736//1670 4237//1670 -f 4477//1658 3991//1658 4478//1658 -s off -f 3989//1969 3991//1969 4477//1969 -f 3412//1970 3963//1970 3413//1970 -s 1 -f 4479//1670 3895//1670 3684//1670 -s off -f 4480//1971 4387//1971 4481//1971 -f 4482//1971 4388//1971 4483//1971 -s 1 -f 3738//1670 4484//1670 4485//1670 -s off -f 3902//1972 4486//1972 4487//1972 -f 3905//1972 4488//1972 4489//1972 -f 4490//1973 4491//1973 4492//1973 -f 4493//1973 4494//1973 4495//1973 -s 1 -f 3889//1670 4204//1670 3890//1670 -s off -f 3116//1974 4013//1974 4337//1974 -s 1 -f 3508//1670 4496//1670 3720//1670 -f 4497//1670 3580//1670 4033//1670 -s off -f 4498//1975 3812//1975 4499//1975 -s 1 -f 4366//1658 4499//1658 3812//1658 -s off -f 4500//1975 3816//1975 4501//1975 -s 1 -f 4367//1658 4501//1658 3816//1658 -s off -f 4068//1976 4069//1976 4502//1976 -f 4503//1977 4504//1977 4505//1977 -f 4506//1977 4507//1977 4508//1977 -f 3877//1978 3861//1978 4509//1978 -s 1 -f 3455//1670 4233//1670 3789//1670 -f 3452//1670 4232//1670 3791//1670 -s off -f 4368//1979 3366//1979 3368//1979 -f 4369//1979 3372//1979 3374//1979 -f 3369//1980 4465//1980 3370//1980 -f 3363//1980 4466//1980 3364//1980 -f 4030//1981 4032//1981 4478//1981 -s 1 -f 4477//1658 4478//1658 4032//1658 -s off -f 4510//1982 3388//1982 3390//1982 -f 4511//1982 3382//1982 3384//1982 -f 3911//1983 4512//1983 4469//1983 -f 3889//1984 3891//1984 4213//1984 -s 1 -f 4513//1670 3319//1670 4512//1670 -s off -f 4382//1985 4164//1985 4166//1985 -s 1 -f 4514//1658 4515//1658 4495//1658 -s off -f 4493//1986 4495//1986 4515//1986 -f 4490//1986 4492//1986 4516//1986 -s 1 -f 4517//1658 4516//1658 4492//1658 -s off -f 4518//1987 4191//1987 3941//1987 -f 4519//1988 4520//1988 4295//1988 -f 4521//1989 3679//1989 3636//1989 -s 1 -f 4182//1726 3636//1726 3679//1726 -s off -f 4522//1989 3678//1989 3639//1989 -s 1 -f 4179//1726 3639//1726 3678//1726 -s off -f 4523//1990 3842//1990 3839//1990 -f 4524//1990 3835//1990 3837//1990 -f 4525//1991 4526//1991 3817//1991 -s 1 -f 4527//1670 3366//1670 4199//1670 -f 4528//1670 3372//1670 4197//1670 -f 4318//1670 4187//1670 4186//1670 -f 3518//1670 4236//1670 3265//1670 -f 3842//1670 4359//1670 3612//1670 -f 3835//1670 4358//1670 3609//1670 -f 3275//1658 3744//1658 3364//1658 -s off -f 3274//1992 3744//1992 3275//1992 -f 3271//1992 3745//1992 3272//1992 -s 1 -f 3272//1658 3745//1658 3370//1658 -s off -f 3332//1993 4529//1993 3964//1993 -f 3327//1993 4530//1993 3965//1993 -s 1 -f 3278//1682 3771//1658 3392//1671 -s off -f 3277//1994 3771//1994 3278//1994 -f 3268//1995 3772//1995 3269//1995 -s 1 -f 3269//1682 3772//1658 3386//1671 -f 4160//1670 4531//1670 4024//1670 -s off -f 4532//1996 3870//1996 3633//1996 -s 1 -f 4533//1726 3633//1682 3870//1726 -f 3249//1658 3486//1658 3214//1658 -s off -f 4534//1997 3486//1997 3249//1997 -s 1 -f 4336//1670 4101//1670 3824//1670 -f 4343//1671 4436//1658 4342//1671 -s off -f 4434//1998 4436//1998 4343//1998 -s 1 -f 3783//1670 3784//1670 3714//1670 -f 4535//1658 3514//1682 4536//1658 -s off -f 4537//1999 4536//1999 3514//1999 -s 1 -f 4538//1658 3512//1682 4539//1658 -s off -f 4540//1999 4539//1999 3512//1999 -s 1 -f 3481//1670 4070//1670 4541//1670 -s off -f 4114//2000 4542//2000 4141//2000 -s 1 -f 4257//1658 4141//1658 4542//1658 -s off -f 4119//2000 4543//2000 4142//2000 -s 1 -f 4258//1658 4142//1658 4543//1658 -s off -f 4189//2001 4544//2001 3690//2001 -s 1 -f 3690//1671 4544//1658 3293//1671 -s off -f 4190//2002 4545//2002 3692//2002 -s 1 -f 3692//1671 4545//1658 3296//1671 -f 3705//1670 3899//1670 4220//1670 -f 3121//1670 3115//1670 3124//1670 -f 3801//1670 3697//1670 4546//1670 -f 4095//1670 4547//1670 3488//1670 -s off -f 4548//2003 3121//2003 3123//2003 -f 4313//2004 4312//2004 3788//2004 -s 1 -f 3966//1670 4131//1670 4009//1670 -f 3901//1670 4486//1670 3902//1670 -f 3904//1670 4488//1670 3905//1670 -f 4549//1658 3426//1658 4481//1658 -s off -f 3424//2005 3426//2005 4549//2005 -s 1 -f 4550//1658 3423//1658 4483//1658 -s off -f 3421//2006 3423//2006 4550//2006 -f 4446//2007 4551//2007 4552//2007 -f 4448//2007 4553//2007 4554//2007 -f 4236//2008 3786//2008 3524//2008 -s 1 -f 4555//1670 4556//1670 4557//1670 -f 4334//1658 4558//1658 3474//1658 -s off -f 3472//2009 3474//2009 4558//2009 -s 1 -f 4559//1670 3978//1670 3773//1670 -s off -f 4402//2010 4560//2010 3688//2010 -f 4561//2011 3565//2011 3567//2011 -s 1 -f 3425//1670 4387//1670 4480//1670 -f 3422//1670 4388//1670 4482//1670 -s off -f 4033//2012 3644//2012 4363//2012 -f 4390//2013 4562//2013 3326//2013 -s 1 -f 4563//1670 4504//1670 4503//1670 -f 4564//1670 4507//1670 4506//1670 -s off -f 4077//2014 3879//2014 3878//2014 -s 1 -f 4121//1670 4565//1670 4122//1670 -f 4156//1658 3595//1658 4566//1658 -s off -f 3594//2015 4566//2015 3595//2015 -s 1 -f 4242//1670 3140//1670 3139//1670 -f 3929//1670 3928//1670 4567//1670 -f 3931//1670 3930//1670 4568//1670 -s off -f 4534//2016 4252//2016 3486//2016 -f 4569//2017 3545//2017 3602//2017 -s 1 -f 4133//1670 4360//1670 4134//1670 -f 4570//1658 3432//1726 3416//1726 -s off -f 3430//2018 3432//2018 4570//2018 -f 3463//2019 3978//2019 3464//2019 -f 3254//2020 4571//2020 3255//2020 -s 1 -f 3523//1658 4423//1658 3996//1658 -s off -f 4422//2021 3996//2021 4423//2021 -f 4078//2022 4145//2022 4079//2022 -f 4081//2022 4146//2022 4080//2022 -s 1 -f 4292//1658 4572//1658 4505//1658 -s off -f 4503//2023 4505//2023 4572//2023 -f 4506//2023 4508//2023 4573//2023 -s 1 -f 4290//1658 4573//1658 4508//1658 -f 4049//1670 4051//1670 4574//1670 -f 4575//1658 3407//1658 3405//1658 -s off -f 4095//2024 3407//2024 4575//2024 -s 1 -f 4012//1670 3116//1670 4576//1670 -f 4577//1658 4578//1658 4464//1658 -s off -f 4462//2025 4464//2025 4578//2025 -f 4459//2025 4461//2025 4579//2025 -s 1 -f 4580//1658 4579//1658 4461//1658 -f 3671//1658 4296//1658 3672//1658 -s off -f 4159//2026 4296//2026 3671//2026 -s 1 -f 4525//1670 3763//1670 4526//1670 -s off -f 4581//2027 4582//2027 4339//2027 -f 4583//2028 3885//2028 4584//2028 -f 4585//2028 3888//2028 4586//2028 -s 1 -f 4561//1670 4587//1670 3565//1670 -s off -f 3404//2029 3488//2029 3405//2029 -f 3645//2030 4323//2030 4364//2030 -s 1 -f 4363//1658 4364//1658 4323//1658 -f 4353//1670 3832//1670 4416//1670 -s off -f 4588//2031 4589//2031 4417//2031 -s 1 -f 4401//1670 4560//1670 4402//1670 -f 4192//1670 4191//1670 4518//1670 -s off -f 4590//2032 4591//2032 3669//2032 -s 1 -f 4497//1670 4520//1670 4519//1670 -s off -f 4568//2033 4592//2033 3148//2033 -f 4567//2033 4593//2033 3163//2033 -s 1 -f 4447//1670 4553//1670 4448//1670 -f 4445//1670 4551//1670 4446//1670 -f 3452//1670 3792//1670 4385//1670 -f 3455//1670 3790//1670 4383//1670 -f 3423//1658 4594//1658 4483//1658 -s off -f 4482//2034 4483//2034 4594//2034 -s 1 -f 3426//1658 4595//1658 4481//1658 -s off -f 4480//2034 4481//2034 4595//2034 -f 4091//2035 4375//2035 4577//2035 -s 1 -f 4577//1658 4375//1658 4578//1658 -s off -f 4093//2035 4373//2035 4580//2035 -s 1 -f 4580//1658 4373//1658 4579//1658 -s off -f 4311//2036 4596//2036 4467//2036 -f 4541//2037 4070//2037 4597//2037 -f 4269//2038 3994//2038 3214//2038 -s 1 -f 3993//1658 3214//1658 3994//1658 -s off -f 3778//2039 4598//2039 3993//2039 -s 1 -f 4514//1658 4384//1658 4515//1658 -s off -f 4383//2040 4384//2040 4514//2040 -s 1 -f 4517//1658 4386//1658 4516//1658 -s off -f 4385//2041 4386//2041 4517//2041 -s 1 -f 3924//1670 4168//1670 4599//1670 -f 4300//1726 3686//1658 4205//1726 -s off -f 3684//2042 3686//2042 4300//2042 -s 1 -f 3517//1670 4236//1670 3518//1670 -f 3254//1670 3230//1670 4571//1670 -s off -f 3304//2043 4600//2043 3305//2043 -s 1 -f 3952//1670 3449//1670 3448//1670 -f 3956//1670 3446//1670 3445//1670 -f 4435//1670 4601//1670 4602//1670 -f 3988//1658 3490//1658 4603//1658 -s off -f 3489//2044 4603//2044 3490//2044 -f 4604//2045 4605//2045 4606//2045 -s 1 -f 4555//1670 4403//1670 4556//1670 -s off -f 4537//2046 4303//2046 4536//2046 -f 4540//2046 4301//2046 4539//2046 -f 4291//2047 4194//2047 4292//2047 -s 1 -f 4292//1658 4194//1658 4572//1658 -s off -f 4289//2047 4195//2047 4290//2047 -s 1 -f 4290//1658 4195//1658 4573//1658 -f 3843//1671 3358//1658 3253//1671 -s off -f 3356//2048 3358//2048 3843//2048 -f 3810//2049 4587//2049 4607//2049 -f 4608//2050 4242//2050 4297//2050 -s 1 -f 4425//1670 3191//1670 4128//1670 -f 4424//1670 3179//1670 4126//1670 -f 4390//1670 4392//1670 4562//1670 -s off -f 4609//2051 3989//2051 4477//2051 -s 1 -f 4610//1670 4531//1670 4160//1670 -s off -f 4611//2052 4612//2052 4613//2052 -f 4614//2052 4615//2052 4616//2052 -f 4561//2053 3567//2053 4617//2053 -s 1 -f 4617//1658 3567//1658 4607//1658 -s off -f 4618//2054 4619//2054 3988//2054 -f 4500//2055 4129//2055 3816//2055 -f 4498//2055 4127//2055 3812//2055 -s 1 -f 3284//1658 4620//1658 3193//1671 -s off -f 3283//2056 4620//2056 3284//2056 -s 1 -f 3290//1658 4621//1658 3181//1671 -s off -f 3289//2056 4621//2056 3290//2056 -f 3854//2057 3753//2057 4112//2057 -s 1 -f 4112//1658 3753//1658 3752//1658 -f 3942//1670 4129//1670 4622//1670 -f 3944//1670 4127//1670 4623//1670 -f 3741//1670 3826//1670 4109//1670 -f 3286//1670 4062//1670 4061//1670 -f 3280//1670 4057//1670 4056//1670 -s off -f 3829//2058 4074//2058 3828//2058 -s 1 -f 3607//1658 3362//1658 3132//1658 -s off -f 3360//2059 3362//2059 3607//2059 -s 1 -f 3829//1670 4624//1670 4073//1670 -s off -f 4625//2060 4626//2060 3198//2060 -s 1 -f 3227//1670 4107//1670 3860//1670 -f 4627//1658 4628//1658 3471//1658 -s off -f 3469//2061 3471//2061 4628//2061 -s 1 -f 4629//1658 4630//1658 3468//1658 -s off -f 3466//2061 3468//2061 4630//2061 -s 1 -f 3879//1670 4354//1670 3615//1670 -s off -f 3694//2062 4219//2062 3693//2062 -s 1 -f 3603//1658 3774//1658 3465//1658 -s off -f 3773//2063 3774//2063 3603//2063 -s 1 -f 4270//1670 4272//1670 4631//1670 -s off -f 4224//2064 4116//2064 4225//2064 -f 4231//2064 4118//2064 4230//2064 -s 1 -f 3951//1670 4240//1670 3858//1670 -s off -f 4632//2065 3501//2065 3503//2065 -s 1 -f 4064//1670 4633//1670 3295//1670 -f 4059//1670 4634//1670 3292//1670 -f 3427//1670 3976//1670 3428//1670 -f 3669//1658 4635//1671 3243//1658 -s off -f 4591//2066 4635//2066 3669//2066 -f 4636//2067 3938//2067 3940//2067 -s 1 -f 4332//1658 4637//1658 3266//1658 -s off -f 3264//2068 3266//2068 4637//2068 -f 4638//2069 4274//2069 3309//2069 -s 1 -f 4261//1670 4047//1670 3717//1670 -s off -f 4016//2070 4639//2070 4566//2070 -s 1 -f 4311//1670 4313//1670 4596//1670 -f 3780//1670 4476//1670 3248//1670 -f 3627//1670 4219//1670 3694//1670 -f 4420//1658 3584//1658 4419//1658 -s off -f 3582//2071 3584//2071 4420//2071 -f 4435//2072 4602//2072 3500//2072 -s 1 -f 3673//1670 4640//1670 4365//1670 -f 4159//1670 4158//1670 4157//1670 -s off -f 4451//2073 4641//2073 4450//2073 -s 1 -f 4609//1670 4099//1670 3989//1670 -f 3754//1658 4319//1671 3709//1658 -s off -f 3707//2074 3709//2074 4319//2074 -s 1 -f 4602//1670 4601//1670 4642//1670 -f 4616//1658 4643//1658 3368//1658 -s off -f 4615//2075 4643//2075 4616//2075 -s 1 -f 4613//1658 4644//1658 3374//1658 -s off -f 4612//2075 4644//2075 4613//2075 -s 1 -f 4273//1670 4274//1670 4645//1670 -s off -f 3714//2076 3797//2076 3712//2076 -f 3298//2077 4646//2077 3299//2077 -s 1 -f 3299//1658 4646//1658 4455//1658 -f 3714//1670 3784//1670 3715//1670 -s off -f 4220//2078 3896//2078 3703//2078 -f 3764//2079 3847//2079 3563//2079 -f 3613//2080 4302//2080 4538//2080 -f 3610//2080 4304//2080 4535//2080 -s 1 -f 3922//1670 4331//1670 3923//1670 -f 4297//1658 4647//1658 4509//1658 -s off -f 3877//2081 4509//2081 4647//2081 -f 4648//2082 4649//2082 4470//2082 -f 4650//2083 4513//2083 3342//2083 -s 1 -f 3402//1671 4651//1658 3169//1671 -s off -f 3491//2084 4651//2084 3402//2084 -f 4559//2085 3773//2085 3603//2085 -s 1 -f 3565//1670 4587//1670 3810//1670 -s off -f 4652//2086 4653//2086 4350//2086 -s 1 -f 4155//1670 4382//1670 4654//1670 -s off -f 4655//2087 3620//2087 3619//2087 -s 1 -f 3837//1658 3838//1658 4656//1658 -s off -f 4358//2088 4656//2088 3838//2088 -s 1 -f 3839//1658 3841//1671 4657//1658 -s off -f 4359//2088 4657//2088 3841//2088 -f 4240//2089 3950//2089 4658//2089 -f 4186//2090 3579//2090 4105//2090 -s 1 -f 4105//1658 3579//1658 4104//1658 -s off -f 3221//2091 4659//2091 3458//2091 -f 3225//2091 4660//2091 3460//2091 -f 4009//2092 4011//2092 3464//2092 -s 1 -f 3968//1658 3464//1658 4011//1658 -f 3305//1682 4097//1682 3309//1682 -s off -f 4638//2093 3309//2093 4097//2093 -s 1 -f 3611//1658 4535//1658 4536//1658 -s off -f 3610//2094 4535//2094 3611//2094 -f 3613//2094 4538//2094 3614//2094 -s 1 -f 3614//1658 4538//1658 4539//1658 -f 3768//1670 3366//1670 3769//1670 -f 3765//1670 3372//1670 3766//1670 -s off -f 3376//2095 4661//2095 3377//2095 -s 1 -f 4662//1658 3377//1658 4661//1658 -s off -f 4172//2096 3438//2096 4150//2096 -s 1 -f 4150//1658 3438//1658 3940//1658 -s off -f 4663//2097 4015//2097 4664//2097 -s 1 -f 4015//1670 4639//1670 4016//1670 -s off -f 4565//2098 4051//2098 4340//2098 -s 1 -f 3799//1670 4075//1670 3298//1670 -f 3122//1658 4665//1658 3126//1658 -s off -f 4183//2099 3126//2099 4665//2099 -s 1 -f 4453//1670 3938//1670 4636//1670 -f 3418//1658 3740//1658 4381//1658 -s off -f 3738//2100 3740//2100 3418//2100 -s 1 -f 3528//1658 4666//1658 4597//1658 -s off -f 4541//2101 4597//2101 4666//2101 -s 1 -f 4318//1670 4667//1670 4187//1670 -f 3862//1670 3140//1670 4242//1670 -f 4502//1658 4668//1658 4637//1658 -s off -f 4069//2102 4668//2102 4502//2102 -s 1 -f 3500//1658 3202//1671 3199//1671 -s off -f 4602//2103 3202//2103 3500//2103 -s 1 -f 4014//1670 4669//1670 4223//1670 -s off -f 4315//2104 4624//2104 4316//2104 -s 1 -f 3204//1670 3401//1670 4052//1670 -f 4284//1658 4285//1658 4487//1658 -s off -f 3902//2105 4487//2105 4285//2105 -s 1 -f 4286//1658 4287//1658 4489//1658 -s off -f 3905//2105 4489//2105 4287//2105 -f 3311//2106 4670//2106 4671//2106 -f 4264//2107 3291//2107 3293//2107 -f 4265//2107 3294//2107 3296//2107 -f 3733//2108 3273//2108 4629//2108 -f 3734//2108 3270//2108 4627//2108 -s 1 -f 4081//1670 4659//1670 3221//1670 -f 4078//1670 4660//1670 3225//1670 -s off -f 3664//2109 4672//2109 3665//2109 -s 1 -f 4282//1670 4582//1670 4673//1670 -s off -f 4117//2110 3267//2110 4228//2110 -f 4113//2110 3276//2110 4227//2110 -f 4133//2111 3869//2111 4533//2111 -s 1 -f 4533//1726 3869//1682 3633//1682 -s off -f 4674//2112 4075//2112 4455//2112 -s 1 -f 4248//1670 4210//1670 3734//1670 -f 4244//1670 4207//1670 3733//1670 -f 3354//1658 3695//1658 3834//1658 -s off -f 3832//2113 3834//2113 3695//2113 -f 3897//2114 3899//2114 3704//2114 -s 1 -f 4255//1670 4114//1670 4113//1670 -f 4260//1670 4119//1670 4117//1670 -s off -f 4008//2115 4675//2115 4007//2115 -f 4003//2115 4676//2115 4004//2115 -f 4677//2116 4678//2116 4420//2116 -f 4028//2117 4679//2117 4029//2117 -s 1 -f 4029//1658 4679//1658 3117//1658 -f 4680//1670 4681//1670 3337//1670 -f 3971//1658 4682//1658 3941//1671 -s off -f 4518//2118 3941//2118 4682//2118 -f 3216//2119 3787//2119 3217//2119 -f 4680//2120 4153//2120 4430//2120 -s 1 -f 4314//1670 4330//1670 4329//1670 -s off -f 3206//2121 4414//2121 3663//2121 -f 4053//2122 3403//2122 4144//2122 -s 1 -f 3355//1658 4144//1658 3403//1658 -s off -f 4052//2123 4683//2123 4684//2123 -s 1 -f 4145//1670 4507//1670 4564//1670 -f 4146//1670 4504//1670 4563//1670 -s off -f 4484//2124 3419//2124 3420//2124 -s 1 -f 3508//1670 4151//1670 4685//1670 -s off -f 4310//2125 4686//2125 4167//2125 -f 3642//2126 4687//2126 4578//2126 -f 3643//2126 4688//2126 4579//2126 -f 4689//2127 3755//2127 3608//2127 -f 3399//2128 4690//2128 3400//2128 -f 4402//2129 3688//2129 4691//2129 -s 1 -f 3137//1658 4691//1658 3688//1658 -f 4324//1670 3319//1670 4513//1670 -s off -f 3630//2130 3819//2130 4471//2130 -s 1 -f 4379//1658 4471//1658 3819//1658 -f 4243//1658 3502//1658 4362//1658 -s off -f 3876//2131 4362//2131 3502//2131 -f 4096//2132 4692//2132 3354//2132 -f 3825//2133 3741//2133 4357//2133 -f 4556//2134 4403//2134 3462//2134 -f 4522//2135 3982//2135 3678//2135 -f 4521//2135 3986//2135 3679//2135 -s 1 -f 4529//1670 3932//1670 3421//1670 -f 4530//1670 3933//1670 3424//1670 -s off -f 4519//2136 4295//2136 3568//2136 -s 1 -f 3394//1658 3568//1658 4295//1658 -f 3274//1670 4466//1670 4368//1670 -f 3271//1670 4465//1670 4369//1670 -f 4161//1670 4693//1670 4163//1670 -f 4694//1658 3817//1658 4695//1658 -s off -f 4525//2137 3817//2137 4694//2137 -s 1 -f 3987//1670 4309//1670 4696//1670 -f 3983//1670 4308//1670 4697//1670 -f 3667//1670 3668//1670 4655//1670 -f 4654//1670 4382//1670 3376//1670 -f 3196//1658 3649//1658 4552//1658 -s off -f 4446//2138 4552//2138 3649//2138 -s 1 -f 3184//1658 3647//1658 4554//1658 -s off -f 4448//2138 4554//2138 3647//2138 -f 3864//2139 3859//2139 3865//2139 -s 1 -f 4344//1670 4346//1670 4075//1670 -f 3567//1658 3566//1658 4607//1658 -s off -f 3810//2140 4607//2140 3566//2140 -f 4306//2141 3167//2141 3169//2141 -s 1 -f 4238//1658 3878//1658 4376//1658 -s off -f 3934//2142 3878//2142 4238//2142 -f 3667//2143 4698//2143 4441//2143 -f 4532//2144 3962//2144 3870//2144 -s 1 -f 3741//1670 4109//1670 3742//1670 -s off -f 3736//2145 4183//2145 4665//2145 -f 3124//2146 3115//2146 3125//2146 -f 3959//2147 3765//2147 4328//2147 -f 3955//2147 3768//2147 4327//2147 -f 3470//2148 4699//2148 4251//2148 -f 3467//2148 4700//2148 4247//2148 -s 1 -f 3334//1658 3461//1658 4281//1658 -s off -f 4279//2149 4281//2149 3461//2149 -s 1 -f 3329//1658 3459//1658 4278//1658 -s off -f 4276//2149 4278//2149 3459//2149 -f 3720//2150 4421//2150 4423//2150 -s 1 -f 4701//1670 3629//1670 3628//1670 -f 3245//1658 3242//1658 3462//1658 -s off -f 4556//2151 3462//2151 3242//2151 -f 4109//2152 3666//2152 4702//2152 -s 1 -f 4357//1658 4702//1658 3666//1658 -s off -f 4433//2153 4171//2153 4149//2153 -f 4162//2154 3303//2154 4703//2154 -s 1 -f 4703//1671 3303//1658 4108//1671 -s off -f 4013//2155 3645//2155 4364//2155 -f 3718//2156 4048//2156 3926//2156 -f 4704//2157 3803//2157 4152//2157 -f 4585//2158 4586//2158 4212//2158 -s 1 -f 4705//1658 4212//1658 4586//1658 -f 4706//1658 4209//1658 4584//1658 -s off -f 4583//2158 4584//2158 4209//2158 -f 4389//2159 4707//2159 3338//2159 -s 1 -f 4410//1670 4158//1670 3552//1670 -f 3610//1670 3916//1670 3997//1670 -f 3613//1670 3918//1670 4000//1670 -s off -f 4708//2160 3257//2160 3394//2160 -s 1 -f 3192//1671 3189//1671 4709//1671 -s off -f 4021//2161 4709//2161 3189//2161 -f 4022//2161 4710//2161 3177//2161 -s 1 -f 3180//1671 3177//1671 4710//1671 -s off -f 3897//2162 3704//2162 4432//2162 -s 1 -f 3703//1658 4432//1658 3704//1658 -f 4213//1658 3761//1658 4711//1658 -s off -f 3820//2163 4711//2163 3761//2163 -f 4320//2164 4712//2164 3484//2164 -s 1 -f 4530//1670 3724//1670 3933//1670 -f 4529//1670 3727//1670 3932//1670 -s off -f 4713//2165 3492//2165 3494//2165 -f 3809//2166 3696//2166 4039//2166 -f 3661//2167 4714//2167 3459//2167 -f 3658//2167 4715//2167 3461//2167 -s 1 -f 3914//1670 3795//1670 3794//1670 -f 4680//1670 3337//1670 4153//1670 -f 4134//1670 4360//1670 3961//1670 -f 4385//1670 3792//1670 4370//1670 -f 4383//1670 3790//1670 4371//1670 -f 4353//1670 4416//1670 4071//1670 -s off -f 3359//2168 3440//2168 3564//2168 -s 1 -f 4161//1670 4163//1670 3785//1670 -f 3676//1670 3622//1670 3621//1670 -s off -f 4306//2169 3169//2169 4307//2169 -s 1 -f 4651//1658 4307//1658 3169//1671 -s off -f 3954//2170 4173//2170 3367//2170 -s 1 -f 3640//1658 3367//1658 4173//1658 -f 3641//1658 3373//1658 4174//1658 -s off -f 3958//2170 4174//2170 3373//2170 -s 1 -f 4704//1670 3804//1670 3803//1670 -f 3703//1658 4431//1658 4432//1658 -s off -f 3896//2171 4431//2171 3703//2171 -s 1 -f 3383//1658 4182//1726 3679//1726 -s off -f 4180//2172 4182//2172 3383//2172 -f 4177//2172 4179//2172 3389//2172 -s 1 -f 3389//1658 4179//1726 3678//1726 -f 4192//1670 4098//1670 4171//1670 -f 3276//1670 4116//1670 4224//1670 -f 3267//1670 4118//1670 4231//1670 -f 3451//1670 4309//1670 4232//1670 -f 3454//1670 4308//1670 4233//1670 -s off -f 3300//2173 4355//2173 3301//2173 -s 1 -f 3355//1658 4684//1658 4144//1658 -s off -f 4052//2174 4684//2174 3355//2174 -f 3261//2175 3199//2175 3693//2175 -s 1 -f 3201//1658 3693//1658 3199//1671 -s off -f 3473//2176 3574//2176 3576//2176 -f 4565//2177 4340//2177 4418//2177 -s 1 -f 4321//1658 4418//1658 4340//1726 -s off -f 3787//2178 4234//2178 3217//2178 -s 1 -f 3217//1658 4234//1658 3524//1658 -f 3844//1670 4272//1670 4716//1670 -s off -f 3385//2179 3346//2179 3386//2179 -f 3391//2179 3343//2179 3392//2179 -s 1 -f 4096//1670 3404//1670 4094//1670 -f 4372//1670 4399//1670 3643//1670 -f 4374//1670 4400//1670 3642//1670 -s off -f 4187//2180 3472//2180 4558//2180 -s 1 -f 3738//1670 3800//1670 4484//1670 -f 4610//1670 3625//1670 4569//1670 -s off -f 4015//2181 4156//2181 4664//2181 -s 1 -f 4664//1658 4156//1658 4566//1658 -f 4288//1670 4185//1670 4015//1670 -f 4673//1670 4582//1670 3779//1670 -s off -f 4707//2182 4695//2182 3338//2182 -s 1 -f 3817//1658 3338//1658 4695//1658 -s off -f 4670//2183 4221//2183 4671//2183 -s 1 -f 4443//1658 4671//1658 4221//1658 -s off -f 3747//2184 3213//2184 3215//2184 -s 1 -f 3856//1670 3241//1670 3950//1670 -f 3491//1670 3824//1670 3909//1670 -s off -f 4354//2185 3735//2185 4376//2185 -f 3446//2186 4093//2186 4580//2186 -f 3449//2187 4091//2187 4577//2187 -s 1 -f 4417//1658 3138//1658 3400//1658 -s off -f 4589//2188 3138//2188 4417//2188 -f 4311//2189 4467//2189 3229//2189 -s 1 -f 3229//1671 4467//1671 3301//1671 -s off -f 4269//2190 4717//2190 3994//2190 -f 4132//2191 3555//2191 3569//2191 -s 1 -f 3919//1670 3921//1670 4435//1670 -f 3667//1670 3600//1670 4293//1670 -s off -f 3240//2192 4718//2192 4516//2192 -f 3236//2193 4719//2193 4515//2193 -s 1 -f 4576//1670 3116//1670 3115//1670 -f 3410//1670 4183//1670 3736//1670 -f 4720//1670 4560//1670 4401//1670 -s off -f 3455//2194 4383//2194 4514//2194 -f 3452//2194 4385//2194 4517//2194 -s 1 -f 4314//1670 3501//1670 4330//1670 -f 4162//1670 4107//1670 4356//1670 -s off -f 3975//2195 3596//2195 3974//2195 -s 1 -f 3684//1670 4204//1670 3685//1670 -f 3985//1670 3385//1670 3986//1670 -f 3981//1670 3391//1670 3982//1670 -s off -f 3891//2196 3762//2196 4213//2196 -s 1 -f 4213//1658 3762//1658 3761//1658 -s off -f 4022//2197 4394//2197 4710//2197 -f 4021//2197 4393//2197 4709//2197 -s 1 -f 3646//1670 3645//1670 4013//1670 -s off -f 3990//2198 3673//2198 3675//2198 -f 4634//2199 4058//2199 4440//2199 -f 4633//2200 4063//2200 4438//2200 -f 4171//2201 4721//2201 4149//2201 -s 1 -f 4149//1658 4721//1658 4150//1658 -s off -f 3830//2202 4102//2202 4104//2202 -s 1 -f 4351//1670 4722//1670 4406//1670 -f 4352//1670 4723//1670 4407//1670 -f 4470//1658 4724//1658 3927//1682 -s off -f 4649//2203 4724//2203 4470//2203 -f 3898//2204 3427//2204 4429//2204 -f 4609//2205 4477//2205 4725//2205 -s 1 -f 4725//1658 4477//1658 4032//1658 -f 4326//1670 4355//1670 3300//1670 -s off -f 3861//2206 3130//2206 3132//2206 -f 3911//2207 4469//2207 3881//2207 -s 1 -f 3342//1671 3881//1658 4469//1671 -s off -f 4333//2208 4318//2208 4334//2208 -f 3759//2209 4351//2209 4706//2209 -f 3758//2209 4352//2209 4705//2209 -f 4726//2210 3360//2210 3607//2210 -f 4604//2211 4606//2211 3252//2211 -s 1 -f 3675//1658 3252//1658 4606//1658 -s off -f 3289//2212 4424//2212 4621//2212 -f 3283//2212 4425//2212 4620//2212 -f 3757//2213 3931//2213 4727//2213 -f 3756//2213 3929//2213 4728//2213 -f 3746//2214 3215//2214 3524//2214 -s 1 -f 3218//1658 3524//1658 3215//1658 -s off -f 3489//2215 4444//2215 4603//2215 -f 3119//2216 4409//2216 3960//2216 -s 1 -f 3842//1670 4265//1670 4359//1670 -f 3835//1670 4264//1670 4358//1670 -s off -f 4313//2217 3788//2217 3301//2217 -s 1 -f 3229//1671 3301//1671 3788//1658 -f 4338//1658 4042//1658 4339//1658 -s off -f 4040//2218 4042//2218 4338//2218 -f 4704//2219 4152//2219 3341//2219 -s 1 -f 3341//1658 4152//1726 3881//1658 -f 3960//1658 4411//1658 3672//1658 -s off -f 4409//2220 4411//2220 3960//2220 -f 3768//2221 3770//2221 4327//2221 -s 1 -f 4327//1658 3770//1658 3368//1658 -s off -f 3765//2221 3767//2221 4328//2221 -s 1 -f 4328//1658 3767//1658 3374//1658 -s off -f 4291//2222 3730//2222 4194//2222 -f 4289//2222 3729//2222 4195//2222 -f 4047//2223 3630//2223 4471//2223 -s 1 -f 4172//1670 3938//1670 4453//1670 -f 3617//1658 4729//1658 3576//1658 -s off -f 3473//2224 3576//2224 4729//2224 -s 1 -f 3733//1670 4700//1670 3467//1670 -f 3734//1670 4699//1670 3470//1670 -s off -f 3953//2225 3448//2225 4266//2225 -f 3957//2226 3445//2226 4267//2226 -s 1 -f 3499//1670 3750//1670 4099//1670 -s off -f 3280//2227 4056//2227 4439//2227 -f 3286//2227 4061//2227 4437//2227 -f 4299//2228 3684//2228 4300//2228 -s 1 -f 4546//1670 3697//1670 3696//1670 -s off -f 3366//2229 3954//2229 3367//2229 -f 3372//2229 3958//2229 3373//2229 -s 1 -f 4227//1726 3345//1682 4226//1726 -s off -f 3344//2230 4226//2230 3345//2230 -f 3347//2231 4229//2231 3348//2231 -s 1 -f 4228//1726 3348//1682 4229//1726 -s off -f 3388//2232 4177//2232 3389//2232 -f 3382//2232 4180//2232 3383//2232 -f 4181//2233 3451//2233 4262//2233 -f 4178//2233 3454//2233 4263//2233 -s 1 -f 4167//1658 4662//1658 4661//1658 -s off -f 4686//2234 4662//2234 4167//2234 -f 3842//2235 3612//2235 3840//2235 -f 3835//2235 3609//2235 3836//2235 -f 3320//2236 4154//2236 3339//2236 -f 4126//2237 3944//2237 4366//2237 -f 4128//2237 3942//2237 4367//2237 -s 1 -f 4645//1670 4274//1670 4638//1670 -s off -f 4652//2238 4350//2238 4730//2238 -s 1 -f 4730//1658 4350//1658 4458//1658 -s off -f 3415//2239 3375//2239 3416//2239 -s 1 -f 4347//1670 3596//1670 3975//1670 -s off -f 3784//2240 3264//2240 4637//2240 -f 4529//2241 3421//2241 4550//2241 -f 4530//2241 3424//2241 4549//2241 -f 4164//2242 3855//2242 4165//2242 -f 4626//2243 3921//2243 4342//2243 -s 1 -f 4243//1658 3608//1658 3502//1658 -s off -f 3874//2244 3608//2244 4243//2244 -f 4024//2245 4531//2245 4458//2245 -s 1 -f 4077//1670 3735//1670 4354//1670 -s off -f 4223//2246 4669//2246 4222//2246 -f 4119//2247 4731//2247 4543//2247 -f 4114//2247 4732//2247 4542//2247 -s 1 -f 3484//1658 3306//1671 3309//1682 -s off -f 3323//2248 3306//2248 3484//2248 -f 4395//2249 3356//2249 3843//2249 -f 4636//2250 3940//2250 4733//2250 -s 1 -f 3438//1658 4733//1658 3940//1658 -f 3960//1658 3865//1658 4317//1658 -s off -f 3859//2251 4317//2251 3865//2251 -f 3733//2252 4629//2252 4245//2252 -s 1 -f 4245//1658 4629//1658 3468//1658 -s off -f 3734//2252 4627//2252 4249//2252 -s 1 -f 4249//1658 4627//1658 3471//1658 -f 3219//1670 4394//1670 4022//1670 -f 3223//1670 4393//1670 4021//1670 -s off -f 4372//2253 3164//2253 3166//2253 -f 4374//2253 3149//2253 3151//2253 -f 4734//2254 3707//2254 4319//2254 -f 3425//2255 4081//2255 3648//2255 -f 3422//2255 4078//2255 3650//2255 -s 1 -f 4259//1658 4228//1726 4230//1658 -s off -f 4117//2256 4228//2256 4259//2256 -f 4113//2256 4227//2256 4256//2256 -s 1 -f 4256//1658 4227//1726 4225//1658 -s off -f 3880//2257 3911//2257 3881//2257 -f 3963//2258 4133//2258 4533//2258 -f 3886//2259 3158//2259 3160//2259 -f 3883//2259 3143//2259 3145//2259 -s 1 -f 4132//1670 3478//1670 3555//1670 -f 4254//1671 3342//1671 4469//1671 -s off -f 4650//2260 3342//2260 4254//2260 -f 4240//2261 4658//2261 4241//2261 -s 1 -f 4635//1671 4241//1671 4658//1671 -f 4727//1658 4542//1658 3148//1671 -s off -f 4568//2262 3148//2262 4542//2262 -s 1 -f 4728//1658 4543//1658 3163//1658 -s off -f 4567//2262 3163//2262 4543//2262 -f 4602//2263 4735//2263 3202//2263 -f 3231//2264 4736//2264 3253//2264 -s 1 -f 3990//1670 4640//1670 3673//1670 -s off -f 3121//2265 3409//2265 3122//2265 -s 1 -f 3255//1671 3971//1658 3941//1671 -s off -f 3969//2266 3971//2266 3255//2266 -f 3833//2267 3404//2267 3406//2267 -s 1 -f 4093//1670 4399//1670 4372//1670 -f 4091//1670 4400//1670 4374//1670 -s off -f 3410//2268 4237//2268 4426//2268 -s 1 -f 3914//1670 3913//1670 3795//1670 -f 3287//1658 4437//1658 4125//1658 -s off -f 3286//2269 4437//2269 3287//2269 -s 1 -f 3281//1658 4439//1658 4124//1658 -s off -f 3280//2270 4439//2270 3281//2270 -s 1 -f 4220//1670 3899//1670 3897//1670 -f 3412//1670 3415//1670 3962//1670 -f 3427//1670 4415//1670 3976//1670 -f 4385//1670 4370//1670 3886//1670 -f 4383//1670 4371//1670 3883//1670 -s off -f 3948//2271 3282//2271 3814//2271 -f 3946//2271 3288//2271 3813//2271 -f 3194//2272 4472//2272 3195//2272 -f 3182//2273 4474//2273 3183//2273 -s 1 -f 4737//1670 3763//1670 4525//1670 -s off -f 4074//2274 4072//2274 4419//2274 -f 3807//2275 4172//2275 4150//2275 -f 4298//2276 4300//2276 3305//2276 -s 1 -f 3305//1682 4300//1726 4205//1726 -f 3159//1658 4705//1658 4586//1658 -s off -f 3758//2277 4705//2277 3159//2277 -s 1 -f 3144//1658 4706//1658 4584//1658 -s off -f 3759//2277 4706//2277 3144//2277 -s 1 -f 3361//1670 3130//1670 3861//1670 -s off -f 4014//2278 4390//2278 4443//2278 -f 4654//2279 3430//2279 4570//2279 -f 4098//2280 4518//2280 4682//2280 -s 1 -f 3992//1658 3994//1658 4339//1658 -s off -f 4581//2281 4339//2281 3994//2281 -f 3756//2282 4728//2282 3165//2282 -s 1 -f 3165//1658 4728//1658 3163//1658 -f 3150//1671 4727//1658 3148//1671 -s off -f 3757//2283 4727//2283 3150//2283 -f 4348//2284 3142//2284 4738//2284 -f 3644//2285 3646//2285 4029//2285 -f 3979//2286 4402//2286 4691//2286 -f 3553//2287 4159//2287 3671//2287 -s 1 -f 4080//1658 4739//1658 3222//1658 -s off -f 3220//2288 3222//2288 4739//2288 -s 1 -f 4079//1658 4740//1658 3226//1658 -s off -f 3224//2288 3226//2288 4740//2288 -s 1 -f 4096//1670 3488//1670 3404//1670 -f 3903//1670 3185//1670 3904//1670 -f 3900//1670 3173//1670 3901//1670 -f 3952//1670 3448//1670 3953//1670 -f 3956//1670 3445//1670 3957//1670 -f 3283//1670 3191//1670 4425//1670 -f 3289//1670 3179//1670 4424//1670 -f 3267//1670 3347//1670 4427//1670 -f 3276//1670 3344//1670 4428//1670 -s off -f 4741//2289 4343//2289 3754//2289 -s 1 -f 3754//1658 4343//1671 4319//1671 -f 4260//1670 4731//1670 4119//1670 -f 4255//1670 4732//1670 4114//1670 -f 4275//1670 3130//1670 3361//1670 -f 3964//1658 4550//1658 3659//1658 -s off -f 4529//2290 4550//2290 3964//2290 -f 4530//2290 4549//2290 3965//2290 -s 1 -f 3965//1658 4549//1658 3662//1658 -f 3847//1670 3440//1670 3439//1670 -s off -f 3809//2291 4039//2291 4742//2291 -s 1 -f 4450//1658 4742//1671 4039//1658 -f 4574//1670 4565//1670 4743//1670 -f 3612//1670 3918//1670 3613//1670 -f 3609//1670 3916//1670 3610//1670 -f 3952//1670 3954//1670 3366//1670 -f 3956//1670 3958//1670 3372//1670 -f 3749//1670 3748//1670 3231//1670 -s off -f 3498//2292 4652//2292 4730//2292 -s 1 -f 3980//1670 3391//1670 3981//1670 -f 3984//1670 3385//1670 3985//1670 -f 3523//1658 3521//1658 4423//1658 -s off -f 3720//2293 4423//2293 3521//2293 -f 4618//2294 3988//2294 4412//2294 -s 1 -f 4412//1658 3988//1658 4603//1658 -f 3951//1670 3858//1670 3857//1670 -s off -f 3580//2295 4519//2295 3568//2295 -s 1 -f 3627//1670 3694//1670 4701//1670 -f 4357//1658 3743//1658 4702//1658 -s off -f 3741//2296 3743//2296 4357//2296 -s 1 -f 3456//1658 4495//1658 4005//1658 -s off -f 4137//2297 4005//2297 4495//2297 -f 4135//2297 4006//2297 4492//2297 -s 1 -f 3453//1658 4492//1658 4006//1658 -s off -f 4010//2298 3977//2298 4067//2298 -s 1 -f 4130//1670 3977//1670 4131//1670 -s off -f 4001//2299 3917//2299 4002//2299 -f 3998//2299 3915//2299 3999//2299 -s 1 -f 3183//1658 3691//1658 3174//1658 -s off -f 4474//2300 3691//2300 3183//2300 -f 4472//2300 3689//2300 3195//2300 -s 1 -f 3195//1658 3689//1658 3186//1658 -s off -f 3298//2301 4346//2301 4380//2301 -s 1 -f 4155//1670 3855//1670 4164//1670 -f 4546//1670 3696//1670 3808//1670 -s off -f 4280//2302 4744//2302 4501//2302 -f 4277//2302 4745//2302 4499//2302 -f 4746//2303 3127//2303 3129//2303 -s 1 -f 3353//1658 4420//1658 3695//1658 -s off -f 4677//2304 4420//2304 3353//2304 -s 1 -f 4395//1670 4365//1670 3356//1670 -f 3869//1682 3665//1682 3633//1682 -s off -f 3631//2305 3633//2305 3665//2305 -s 1 -f 4061//1670 4633//1670 4064//1670 -f 4056//1670 4634//1670 4059//1670 -f 3577//1670 4102//1670 3830//1670 -f 4261//1670 3630//1670 4047//1670 -s off -f 3859//2306 4239//2306 4408//2306 -s 1 -f 3425//1670 4659//1670 4081//1670 -f 3422//1670 4660//1670 4078//1670 -f 3407//1658 3354//1658 3406//1658 -s off -f 4096//2307 3354//2307 3407//2307 -f 3634//2308 3636//2308 4007//2308 -s 1 -f 4262//1682 4007//1682 3636//1726 -f 4263//1682 4004//1682 3639//1726 -s off -f 3637//2308 3639//2308 4004//2308 -f 4322//2309 3395//2309 3397//2309 -f 3238//1765 3956//1765 3641//1765 -f 3234//1765 3952//1765 3640//1765 -f 3660//2310 3662//2310 4481//2310 -s 1 -f 4549//1658 4481//1658 3662//1658 -s off -f 3657//2310 3659//2310 4483//2310 -s 1 -f 4550//1658 4483//1658 3659//1658 -f 3944//1670 4623//1670 3723//1670 -f 3942//1670 4622//1670 3726//1670 -f 3143//1670 3152//1670 3759//1670 -f 3158//1670 3155//1670 3758//1670 -s off -f 3491//2311 3908//2311 4651//2311 -s 1 -f 3857//1670 3859//1670 4396//1670 -s off -f 3265//2312 4236//2312 4235//2312 -s 1 -f 4704//1670 3911//1670 3804//1670 -s off -f 4348//2313 4738//2313 4349//2313 -s 1 -f 4349//1658 4738//1671 3564//1658 -f 3164//1670 3928//1670 3756//1670 -f 3149//1670 3930//1670 3757//1670 -f 4068//1670 3265//1670 3264//1670 -f 4242//1670 3139//1670 3875//1670 -s off -f 4361//2314 3139//2314 4294//2314 -f 4591//2315 3118//2315 4635//2315 -f 3643//2316 4579//2316 3162//2316 -s 1 -f 4373//1658 3162//1658 4579//1658 -s off -f 3642//2316 4578//2316 3147//2316 -s 1 -f 4375//1658 3147//1671 4578//1658 -s off -f 4655//2317 3619//2317 3601//2317 -s 1 -f 3487//1658 3601//1658 3619//1658 -s off -f 3912//2318 4747//2318 4412//2318 -f 3133//2319 4377//2319 3134//2319 -s 1 -f 3963//1670 3962//1670 4133//1670 -f 3409//1670 4183//1670 3410//1670 -s off -f 4062//2320 3902//2320 4285//2320 -f 4057//2320 3905//2320 4287//2320 -s 1 -f 3626//1670 3625//1670 4610//1670 -s off -f 4639//2321 3973//2321 4566//2321 -s 1 -f 4664//1658 4566//1658 3973//1658 -s off -f 3798//2322 3715//2322 3713//2322 -f 4410//2323 3552//2323 3670//2323 -s 1 -f 4296//1658 3394//1658 4295//1658 -s off -f 4708//2324 3394//2324 4296//2324 -s 1 -f 3158//1670 3887//1670 3155//1670 -f 3143//1670 3884//1670 3152//1670 -s off -f 3248//2325 4534//2325 3249//2325 -s 1 -f 3646//1670 4013//1670 4012//1670 -s off -f 4626//2326 4342//2326 3198//2326 -s 1 -f 4436//1658 3198//1658 4342//1671 -f 4275//1670 4402//1670 3979//1670 -f 3223//1670 3282//1670 3948//1670 -f 3219//1670 3288//1670 3946//1670 -f 3653//1670 4553//1670 4447//1670 -f 3656//1670 4551//1670 4445//1670 -s off -f 4252//2327 3218//2327 3486//2327 -s 1 -f 3486//1658 3218//1658 3215//1658 -s off -f 3206//2328 3663//2328 3168//2328 -s 1 -f 3171//1658 3168//1671 3663//1658 -s off -f 3359//2329 3564//2329 3201//2329 -s 1 -f 3135//1658 3201//1658 3564//1658 -f 4192//1670 4518//1670 4098//1670 -s off -f 4044//2330 4158//2330 3672//2330 -s 1 -f 3446//1670 3238//1670 4092//1670 -f 3449//1670 3234//1670 4090//1670 -f 3726//1670 4622//1670 4280//1670 -f 3723//1670 4623//1670 4277//1670 -s off -f 4169//2331 3560//2331 3562//2331 -s 1 -f 4073//1670 4074//1670 3829//1670 -s off -f 3558//2332 4541//2332 4666//2332 -f 4069//2333 3783//2333 4668//2333 -f 3350//2334 4095//2334 4575//2334 -s 1 -f 3749//1670 3231//1670 3254//1670 -s off -f 3781//2335 4741//2335 3754//2335 -f 3115//2336 3117//2336 3125//2336 -s 1 -f 4679//1658 3125//1658 3117//1658 -s off -f 3604//2337 3821//2337 3605//2337 -s 1 -f 4435//1670 3921//1670 4601//1670 -s off -f 3676//2338 3677//2338 3246//2338 -s 1 -f 4043//1670 4520//1670 4497//1670 -f 4014//1670 4223//1670 4390//1670 -s off -f 3736//2339 4665//2339 3737//2339 -s 1 -f 3411//1658 3737//1658 4665//1658 -f 3742//1670 4109//1670 4100//1670 -s off -f 4000//2340 4002//2340 4539//2340 -s 1 -f 3614//1658 4539//1658 4002//1658 -f 3611//1658 4536//1658 3999//1658 -s off -f 3997//2341 3999//2341 4536//2341 -s 1 -f 3384//1658 3679//1726 3387//1658 -s off -f 3986//2342 3387//2342 3679//2342 -f 3982//2342 3393//2342 3678//2342 -s 1 -f 3390//1658 3678//1726 3393//1658 -f 4094//1670 3833//1670 3832//1670 -f 4602//1670 4642//1670 3831//1670 -s off -f 3934//2343 4077//2343 3878//2343 -f 3499//2344 4609//2344 4725//2344 -s 1 -f 3318//1658 4430//1671 3339//1671 -s off -f 4680//2345 4430//2345 3318//2345 -s 1 -f 3740//1658 4455//1658 4380//1658 -s off -f 4674//2346 4455//2346 3740//2346 -f 4660//2347 4482//2347 4594//2347 -f 4659//2347 4480//2347 4595//2347 -s 1 -f 3774//1658 4405//1658 3623//1658 -s off -f 3621//2348 3623//2348 4405//2348 -s 1 -f 3552//1670 4159//1670 3553//1670 -s off -f 3476//2349 4132//2349 3477//2349 -f 3797//2350 3297//2350 3299//2350 -s 1 -f 3956//1670 3372//1670 4528//1670 -f 3952//1670 3366//1670 4527//1670 -f 3259//1658 4363//1658 4323//1658 -s off -f 4033//2351 4363//2351 3259//2351 -f 4507//2352 3224//2352 4740//2352 -f 4504//2352 3220//2352 4739//2352 -s 1 -f 4055//1658 3569//1726 3570//1658 -s off -f 4132//2353 3569//2353 4055//2353 -s 1 -f 3829//1670 3910//1670 4624//1670 -f 4599//1670 4168//1670 4175//1670 -f 3604//1670 3822//1670 3821//1670 -s off -f 4737//2354 4525//2354 4694//2354 -f 4465//2355 3469//2355 4628//2355 -f 4466//2356 3466//2356 4630//2356 -f 3888//2357 3155//2357 3157//2357 -f 3885//2357 3152//2357 3154//2357 -s 1 -f 4033//1670 4322//1670 3644//1670 -f 4054//1670 3913//1670 3912//1670 -f 4497//1670 4519//1670 3580//1670 -s off -f 3236//2358 4515//2358 3153//2358 -s 1 -f 4384//1658 3153//1658 4515//1658 -f 4386//1658 3156//1658 4516//1658 -s off -f 3240//2358 4516//2358 3156//2358 -f 3966//2359 4559//2359 3967//2359 -s 1 -f 4237//1670 3736//1670 3934//1670 -s off -f 4690//2360 3872//2360 3400//2360 -s 1 -f 4417//1658 3400//1658 3872//1658 -f 4029//1658 4337//1658 4364//1658 -s off -f 4013//2361 4364//2361 4337//2361 -f 3854//2362 3751//2362 3753//2362 -f 4107//2363 3809//2363 4742//2363 -s 1 -f 3350//1670 4547//1670 4095//1670 -s off -f 4041//2364 3778//2364 3992//2364 -s 1 -f 4199//1670 3366//1670 3955//1670 -f 4197//1670 3372//1670 3959//1670 -s off -f 3769//2365 3363//2365 3365//2365 -f 3766//2365 3369//2365 3371//2365 -f 4204//2366 3895//2366 4205//2366 -f 3652//2367 4503//2367 4572//2367 -f 3655//2367 4506//2367 4573//2367 -s 1 -f 3924//1670 3560//1670 4169//1670 -f 3926//1726 4321//1658 4340//1726 -s off -f 4049//2368 4321//2368 3926//2368 -f 4569//2369 3602//2369 4458//2369 -s 1 -f 4730//1658 4458//1658 3602//1658 -s off -f 3247//2370 3249//2370 3993//2370 -s 1 -f 3993//1658 3249//1658 3214//1658 -s off -f 4452//2371 3573//2371 3128//2371 -s 1 -f 3128//1658 3573//1658 3687//1658 -s off -f 4336//2372 3203//2372 3408//2372 -s 1 -f 3418//1658 4381//1658 3420//1658 -s off -f 4484//2373 3420//2373 4381//2373 -f 4203//2374 4143//2374 4202//2374 -s 1 -f 3854//1670 3782//1670 3751//1670 -f 4157//1670 4158//1670 4044//1670 -f 3579//1658 3578//1658 4104//1658 -s off -f 3830//2375 4104//2375 3578//2375 -f 3616//2376 4335//2376 3617//2376 -s 1 -f 3617//1658 4335//1658 4729//1658 -f 3714//1670 3715//1670 3797//1670 -f 4033//1670 3395//1670 4322//1670 -s off -f 3518//2377 4068//2377 4332//2377 -s 1 -f 3797//1670 3715//1670 3798//1670 -s off -f 3708//2378 3503//2378 3709//2378 -s 1 -f 3754//1658 3709//1658 3503//1658 -s off -f 4605//2379 4030//2379 4606//2379 -s 1 -f 3615//1670 3574//1670 3848//1670 -f 3286//1670 3902//1670 4062//1670 -f 3280//1670 3905//1670 4057//1670 -s off -f 3559//2380 4636//2380 4733//2380 -f 4748//2381 3254//2381 3256//2381 -s 1 -f 4574//1670 4051//1670 4565//1670 -f 3171//1658 3408//1671 3168//1671 -s off -f 4336//2382 3408//2382 3171//2382 -s 1 -f 4336//1670 3824//1670 3203//1670 -s off -f 4488//2383 3185//2383 3187//2383 -f 4486//2383 3173//2383 3175//2383 -f 3667//2384 4441//2384 3487//2384 -s 1 -f 3487//1658 4441//1658 3601//1658 -f 3774//1658 3246//1658 4405//1658 -s off -f 3676//2385 3246//2385 3774//2385 -f 3554//2386 4561//2386 4617//2386 -s 1 -f 4249//1658 3471//1658 4251//1658 -s off -f 3470//2387 4251//2387 3471//2387 -f 3467//2388 4247//2388 3468//2388 -s 1 -f 4245//1658 3468//1658 4247//1658 -s off -f 4551//2389 4019//2389 4196//2389 -f 4553//2389 4017//2389 4193//2389 -s 1 -f 4562//1670 4392//1670 3722//1670 -s off -f 3822//2390 3705//2390 3702//2390 -s 1 -f 3878//1658 3575//1658 4376//1658 -s off -f 4354//2391 4376//2391 3575//2391 -s 1 -f 3898//1670 4415//1670 3427//1670 -f 4061//1670 4063//1670 4633//1670 -f 4056//1670 4058//1670 4634//1670 -f 3505//1670 4132//1670 3476//1670 -s off -f 3962//2392 3417//2392 3870//2392 -s 1 -f 3414//1682 3870//1726 3417//1726 -f 4324//1670 3320//1670 3319//1670 -f 3773//1670 3463//1670 3676//1670 -s off -f 3361//2393 4608//2393 4297//2393 -s 1 -f 4069//1670 3264//1670 3783//1670 -f 3677//1670 4283//1670 4555//1670 -s off -f 3347//2394 4231//2394 4229//2394 -f 3344//2395 4224//2395 4226//2395 -s 1 -f 3447//1658 4580//1658 4461//1658 -s off -f 3446//2396 4580//2396 3447//2396 -f 3449//2396 4577//2396 3450//2396 -s 1 -f 3450//1658 4577//1658 4464//1658 -f 3560//1670 3924//1670 3440//1670 -f 3481//1670 4541//1670 3558//1670 -s off -f 4713//2397 3494//2397 4032//2397 -s 1 -f 3496//1658 4032//1658 3494//1658 -f 3991//1658 3675//1658 4606//1658 -s off -f 3990//2398 3675//2398 3991//2398 -f 4283//2399 3621//2399 4405//2399 -s 1 -f 3422//1670 4482//1670 4660//1670 -f 3425//1670 4480//1670 4659//1670 -s off -f 3455//2400 4514//2400 3456//2400 -s 1 -f 3456//1658 4514//1658 4495//1658 -f 3453//1658 4517//1658 4492//1658 -s off -f 3452//2400 4517//2400 3453//2400 -s 1 -f 4557//1670 3260//1670 3856//1670 -s off -f 3548//2401 3801//2401 3549//2401 -s 1 -f 3712//1658 3299//1658 4076//1658 -s off -f 3797//2402 3299//2402 3712//2402 -s 1 -f 3491//1670 3909//1670 3908//1670 -f 4145//1670 3224//1670 4507//1670 -f 4146//1670 3220//1670 4504//1670 -f 3499//1670 4099//1670 4609//1670 -f 3429//1658 3968//1658 4011//1658 -s off -f 4130//2403 3968//2403 3429//2403 -s 1 -f 3270//1670 3469//1670 4465//1670 -f 3273//1670 3466//1670 4466//1670 -s off -f 3379//2404 3381//2404 4066//2404 -s 1 -f 4429//1658 4066//1658 3381//1658 -s off -f 3197//2405 4625//2405 3198//2405 -s 1 -f 4079//1658 4290//1658 4508//1658 -s off -f 4145//2406 4290//2406 4079//2406 -s 1 -f 4080//1658 4292//1658 4505//1658 -s off -f 4146//2406 4292//2406 4080//2406 -s 1 -f 4545//1658 4657//1658 3296//1671 -s off -f 4265//2407 3296//2407 4657//2407 -f 4264//2407 3293//2407 4656//2407 -s 1 -f 4544//1658 4656//1658 3293//1671 -s off -f 3488//2408 3490//2408 3405//2408 -s 1 -f 4575//1658 3405//1658 3490//1658 -s off -f 3807//2409 4150//2409 3698//2409 -s 1 -f 4721//1658 3698//1658 4150//1658 -f 3966//1670 4009//1670 4559//1670 -s off -f 4244//2410 3733//2410 4245//2410 -f 4248//2410 3734//2410 4249//2410 -f 4424//2411 3811//2411 4621//2411 -s 1 -f 4621//1658 3811//1658 3181//1671 -s off -f 4425//2412 3815//2412 4620//2412 -s 1 -f 4620//1658 3815//1658 3193//1671 -f 3248//1670 3776//1670 3775//1670 -s off -f 4120//2413 4142//2413 4230//2413 -s 1 -f 4259//1658 4230//1658 4142//1658 -f 4256//1658 4225//1658 4141//1658 -s off -f 4115//2414 4141//2414 4225//2414 -s 1 -f 3848//1670 3574//1670 3935//1670 -f 3717//1670 4047//1670 4046//1670 -f 4430//1671 3321//1658 3339//1671 -s off -f 3320//2415 3339//2415 3321//2415 -f 4260//2416 4117//2416 4259//2416 -f 4255//2416 4113//2416 4256//2416 -f 3629//2417 3694//2417 3485//2417 -f 3431//2418 3412//2418 3414//2418 -f 3516//2419 4448//2419 3647//2419 -f 3515//2419 4446//2419 3649//2419 -s 1 -f 4162//1670 3809//1670 4107//1670 -s off -f 3378//2420 4565//2420 4418//2420 -f 3501//2421 3876//2421 3502//2421 -f 3622//2422 3463//2422 3465//2422 -s 1 -f 3769//1670 4368//1670 3363//1670 -f 3766//1670 4369//1670 3369//1670 -s off -f 4168//2423 4170//2423 3687//2423 -s 1 -f 3925//1658 3687//1658 4170//1658 -s off -f 3136//2424 4726//2424 3137//2424 -f 3861//2425 3132//2425 4509//2425 -s 1 -f 3362//1658 4509//1658 3132//1658 -f 4737//1670 4024//1670 3763//1670 -f 3651//1670 4503//1670 3652//1670 -f 3654//1670 4506//1670 3655//1670 -f 4427//1670 3347//1670 3346//1670 -f 4428//1670 3344//1670 3343//1670 -f 3481//1670 3805//1670 4070//1670 -f 4296//1658 4111//1658 3672//1658 -s off -f 4044//2426 3672//2426 4111//2426 -f 4641//2427 4162//2427 4703//2427 -f 3895//2428 4097//2428 4205//2428 -s 1 -f 3305//1682 4205//1726 4097//1682 -s off -f 3953//2429 4266//2429 4173//2429 -s 1 -f 3640//1658 4173//1658 4266//1658 -s off -f 3957//2429 4267//2429 4174//2429 -s 1 -f 3641//1658 4174//1658 4267//1658 -f 4443//1658 3326//1658 4671//1658 -s off -f 4390//2430 3326//2430 4443//2430 -s 1 -f 4318//1670 3849//1670 4667//1670 -f 4167//1658 4661//1658 4166//1658 -s off -f 4382//2431 4166//2431 4661//2431 -s 1 -f 3831//1670 4642//1670 3262//1670 -f 3702//1658 3704//1658 3606//1658 -s off -f 3899//2432 3606//2432 3704//2432 -s 1 -f 3684//1670 3895//1670 4204//1670 -s off -f 3950//2433 3241//2433 3243//2433 -s 1 -f 4182//1726 4262//1682 3636//1726 -s off -f 4181//2434 4262//2434 4182//2434 -s 1 -f 4179//1726 4263//1682 3639//1726 -s off -f 4178//2434 4263//2434 4179//2434 -f 4368//2435 3368//2435 3744//2435 -s 1 -f 3770//1658 3744//1658 3368//1658 -s off -f 4369//2435 3374//2435 3745//2435 -s 1 -f 3767//1658 3745//1658 3374//1658 -s off -f 4452//2436 3571//2436 3573//2436 -f 4511//2437 3384//2437 3772//2437 -s 1 -f 3772//1658 3384//1658 3387//1658 -f 3771//1658 3390//1658 3393//1658 -s off -f 4510//2437 3390//2437 3771//2437 -s 1 -f 3840//1671 3614//1658 4002//1658 -s off -f 3612//2438 3614//2438 3840//2438 -f 3609//2438 3611//2438 3836//2438 -s 1 -f 3836//1658 3611//1658 3999//1658 -s off -f 3978//2439 4009//2439 3464//2439 -f 3260//2440 4556//2440 3242//2440 -f 4274//2441 3307//2441 3309//2441 -s 1 -f 3904//1670 3185//1670 4488//1670 -f 3901//1670 3173//1670 4486//1670 -s off -f 4171//2442 3806//2442 4721//2442 -f 4475//2443 3285//2443 4284//2443 -f 4473//2443 3279//2443 4286//2443 -f 3380//2444 3897//2444 4432//2444 -s 1 -f 3518//1670 3265//1670 4068//1670 -s off -f 3361//2445 4297//2445 3362//2445 -s 1 -f 3362//1658 4297//1658 4509//1658 -s off -f 3231//2446 3253//2446 3232//2446 -s 1 -f 3358//1658 3232//1658 3253//1671 -s off -f 3820//2447 3890//2447 4711//2447 -f 4302//2448 3176//2448 3178//2448 -f 4304//2448 3188//2448 3190//2448 -f 4359//2449 4265//2449 4657//2449 -f 4358//2449 4264//2449 4656//2449 -f 4468//2450 3379//2450 4066//2450 -s 1 -f 4544//1658 3837//1658 4656//1658 -s off -f 4524//2451 3837//2451 4544//2451 -s 1 -f 4545//1658 3839//1658 4657//1658 -s off -f 4523//2451 3839//2451 4545//2451 -s 1 -f 3554//1670 3793//1670 4561//1670 -s off -f 3228//2452 4311//2452 3229//2452 -s 1 -f 3180//1671 4710//1671 3947//1671 -s off -f 4394//2453 3947//2453 4710//2453 -f 4393//2453 3949//2453 4709//2453 -s 1 -f 3192//1671 4709//1671 3949//1671 -s off -f 3572//2454 4588//2454 4417//2454 -s 1 -f 3618//1670 4636//1670 3559//1670 -f 3429//1658 4011//1658 4067//1658 -s off -f 4010//2455 4067//2455 4011//2455 -s 1 -f 3674//1658 3843//1671 3252//1658 -s off -f 4395//2456 3843//2456 3674//2456 -f 3782//2457 3853//2457 4184//2457 -f 3274//2458 4368//2458 3744//2458 -f 3271//2458 4369//2458 3745//2458 -f 3118//2459 3120//2459 4635//2459 -s 1 -f 4635//1671 3120//1671 4241//1671 -s off -f 4372//2460 3166//2460 4373//2460 -s 1 -f 4373//1658 3166//1671 3162//1658 -s off -f 4374//2460 3151//2460 4375//2460 -s 1 -f 4375//1658 3151//1671 3147//1671 -s off -f 3268//2461 4511//2461 3772//2461 -f 3277//2461 4510//2461 3771//2461 -s 1 -f 3656//1670 4019//1670 4551//1670 -f 4654//1670 3376//1670 3430//1670 -f 3653//1670 4017//1670 4553//1670 -s off -f 4356//2462 3227//2462 3303//2462 -s 1 -f 4673//1670 3779//1670 3778//1670 -s off -f 3742//2463 3170//2463 3172//2463 -s 1 -f 3426//1658 3648//1658 3458//1658 -s off -f 3425//2464 3648//2464 3426//2464 -s 1 -f 3423//1658 3650//1658 3460//1658 -s off -f 3422//2464 3650//2464 3423//2464 -f 3855//2465 4112//2465 4165//2465 -s 1 -f 4184//1658 4165//1658 4112//1658 -s off -f 3802//2466 4449//2466 3549//2466 -s 1 -f 3549//1658 4449//1658 4039//1658 -s off -f 3883//2467 3145//2467 4384//2467 -s 1 -f 4384//1658 3145//1658 3153//1658 -f 4386//1658 3160//1658 3156//1658 -s off -f 3886//2467 3160//2467 4386//2467 -f 3376//2468 4382//2468 4661//2468 -f 3942//2469 3334//2469 4367//2469 -s 1 -f 4367//1658 3334//1658 4501//1658 -f 4366//1658 3329//1658 4499//1658 -s off -f 3944//2469 3329//2469 4366//2469 -s 1 -f 4668//1658 3716//1658 4637//1658 -s off -f 3784//2470 4637//2470 3716//2470 -f 4422//2471 3322//2471 3996//2471 -f 3593//2472 3595//2472 4222//2472 -s 1 -f 4156//1658 4222//1658 3595//1658 -s off -f 4600//2473 4298//2473 3305//2473 -f 4158//2474 3863//2474 3672//2474 -s 1 -f 3354//1658 3834//1658 3406//1658 -s off -f 3833//2475 3406//2475 3834//2475 -s 1 -f 3447//1658 4461//1658 3239//1658 -s off -f 3237//2476 3239//2476 4461//2476 -s 1 -f 3450//1658 4464//1658 3235//1658 -s off -f 3233//2476 3235//2476 4464//2476 -s 1 -f 4352//1670 4407//1670 4248//1670 -f 4351//1670 4406//1670 4244//1670 -f 3931//1670 4732//1670 4255//1670 -f 3929//1670 4731//1670 4260//1670 -f 3334//1658 4281//1658 4501//1658 -s off -f 4280//2477 4501//2477 4281//2477 -s 1 -f 3329//1658 4278//1658 4499//1658 -s off -f 4277//2478 4499//2478 4278//2478 -f 3739//2479 4674//2479 3740//2479 -s 1 -f 4555//1670 4283//1670 4403//1670 -s off -f 3213//2480 4268//2480 3214//2480 -f 4188//2481 4663//2481 3972//2481 -f 4589//2482 4218//2482 3138//2482 -f 3140//2483 3877//2483 4647//2483 -s 1 -f 4701//1670 3694//1670 3629//1670 -f 3971//1658 3939//1658 4682//1658 -s off -f 4098//2484 4682//2484 3939//2484 -s 1 -f 3122//1658 3411//1658 4665//1658 -s off -f 3409//2485 3411//2485 3122//2485 -s 1 -f 3137//1658 3607//1658 4691//1658 -s off -f 4726//2486 3607//2486 3137//2486 -s 1 -f 3990//1670 4030//1670 4640//1670 -s off -f 4748//2487 3256//2487 3358//2487 -s 1 -f 3358//1658 3256//1671 3232//1658 -s off -f 3729//2488 3196//2488 4195//2488 -s 1 -f 4195//1658 3196//1658 4196//1658 -s off -f 3730//2488 3184//2488 4194//2488 -s 1 -f 4194//1658 3184//1658 4193//1658 -f 3548//1670 3807//1670 3801//1670 -s off -f 4186//2489 3577//2489 3579//2489 -s 1 -f 3350//1670 3796//1670 4547//1670 -s off -f 3787//2490 3517//2490 4234//2490 -f 4457//2491 4702//2491 4413//2491 -s 1 -f 3743//1658 4413//1658 4702//1658 -f 4679//1658 3123//1658 3125//1658 -s off -f 4548//2492 3123//2492 4679//2492 -f 4190//2493 4523//2493 4545//2493 -f 4189//2493 4524//2493 4544//2493 -f 4132//2494 4055//2494 3477//2494 -s 1 -f 3507//1671 3477//1671 4055//1658 -f 4564//1670 4506//1670 3654//1670 -f 4563//1670 4503//1670 3651//1670 -s off -f 3685//2495 3889//2495 4213//2495 -s 1 -f 4075//1670 4346//1670 3298//1670 -f 4243//1658 4362//1658 4294//1658 -s off -f 4361//2496 4294//2496 4362//2496 -f 3963//2497 4533//2497 3413//2497 -s 1 -f 3413//1726 4533//1726 3870//1726 -f 3814//1671 3284//1658 3193//1671 -s off -f 3282//2498 3284//2498 3814//2498 -f 3288//2499 3290//2499 3813//2499 -s 1 -f 3813//1671 3290//1658 3181//1671 -f 3584//1658 3828//1658 4419//1658 -s off -f 4074//2500 4419//2500 3828//2500 -f 4134//2501 3825//2501 3869//2501 -f 3956//2502 4613//2502 3641//2502 -s 1 -f 3641//1658 4613//1658 3374//1658 -f 3640//1658 4616//1658 3368//1658 -s off -f 3952//2502 4616//2502 3640//2502 -f 4624//2503 4307//2503 4316//2503 -s 1 -f 3827//1658 4316//1658 4307//1658 -f 3431//1670 3415//1670 3412//1670 -f 4347//1670 3975//1670 4288//1670 -s off -f 3764//2504 3563//2504 3561//2504 -s 1 -f 3562//1658 3561//1658 3563//1658 -f 3900//1670 4448//1670 3516//1670 -f 3903//1670 4446//1670 3515//1670 -s off -f 3936//2505 3937//2505 4684//2505 -s 1 -f 4684//1658 3937//1658 4202//1658 -s off -f 3945//2506 3327//2506 3329//2506 -f 3943//2506 3332//2506 3334//2506 -s 1 -f 4242//1670 3875//1670 3874//1670 -f 4186//1670 4102//1670 3577//1670 -f 3681//1670 3188//1670 4304//1670 -f 3683//1670 3176//1670 4302//1670 -s off -f 4737//2507 4694//2507 4038//2507 -s 1 -f 4038//1658 4694//1658 4695//1658 -f 3270//1670 4465//1670 3271//1670 -f 3273//1670 4466//1670 3274//1670 -f 3676//1670 3463//1670 3622//1670 -f 3919//1670 3923//1670 3920//1670 -f 4696//1670 4309//1670 3451//1670 -f 4697//1670 4308//1670 3454//1670 -f 4123//1670 4122//1670 3307//1670 -f 3604//1670 3705//1670 3822//1670 -f 4485//1670 4345//1670 4344//1670 -f 3430//1670 3376//1670 3375//1670 -s off -f 4596//2508 4325//2508 4467//2508 -s 1 -f 3607//1658 3131//1658 4691//1658 -s off -f 3979//2509 4691//2509 3131//2509 -f 3786//2510 3746//2510 3524//2510 -f 3553//2511 3671//2511 3852//2511 -s 1 -f 3670//1658 3852//1658 3671//1658 -f 4651//1658 3827//1658 4307//1658 -s off -f 3908//2512 3827//2512 4651//2512 -s 1 -f 3862//1670 3877//1670 3140//1670 -f 3894//1670 3895//1670 4479//1670 -f 4559//1670 4009//1670 3978//1670 -s off -f 4355//2513 4313//2513 3301//2513 -s 1 -f 4557//1670 4556//1670 3260//1670 -s off -f 4453//2514 3436//2514 3438//2514 -f 4237//2515 4238//2515 4426//2515 -s 1 -f 4426//1658 4238//1658 3737//1658 -s off -f 3350//2516 4575//2516 3351//2516 -s 1 -f 3351//1658 4575//1658 3490//1658 -f 4643//1658 4200//1658 3368//1658 -s off -f 4199//2517 4200//2517 4643//2517 -s 1 -f 4644//1658 4198//1658 3374//1658 -s off -f 4197//2518 4198//2518 4644//2518 -s 1 -f 3742//1670 4100//1670 3170//1670 -f 3517//1670 3786//1670 4236//1670 -f 4436//1658 3500//1658 3198//1658 -s off -f 4435//2519 3500//2519 4436//2519 -s 1 -f 4176//1670 4271//1670 4270//1670 -f 3259//1658 3396//1658 3568//1658 -s off -f 3580//2520 3568//2520 3396//2520 -f 4028//2521 4548//2521 4679//2521 -f 3324//2522 3304//2522 3306//2522 -s 1 -f 4065//1670 4265//1670 3842//1670 -f 4060//1670 4264//1670 3835//1670 -f 3951//1670 3950//1670 4240//1670 -f 4134//1670 3961//1670 3825//1670 -s off -f 4717//2523 4581//2523 3994//2523 -s 1 -f 3725//1670 3724//1670 4530//1670 -f 3728//1670 3727//1670 4529//1670 -s off -f 3594//2524 4016//2524 4566//2524 -f 3924//2525 4746//2525 3129//2525 -s 1 -f 3248//1670 4476//1670 3776//1670 -f 3228//1670 4312//1670 4311//1670 -s off -f 4444//2526 4201//2526 4603//2526 -s 1 -f 4412//1658 4603//1658 4201//1658 -f 4397//1670 3863//1670 4410//1670 -s off -f 4398//2527 4708//2527 4296//2527 -f 3258//2528 4033//2528 3259//2528 -s 1 -f 4329//1670 4331//1670 3922//1670 -f 4631//1670 4272//1670 3844//1670 -s off -f 4416//2529 3832//2529 3695//2529 -f 4410//2530 3670//2530 4411//2530 -s 1 -f 4411//1658 3670//1658 3672//1658 -s off -f 4312//2531 3860//2531 3788//2531 -f 3322//2532 3302//2532 3996//2532 -s 1 -f 3995//1726 3996//1658 3302//1658 -s off -f 4690//2533 3873//2533 3872//2533 -f 4252//2534 4161//2534 3218//2534 -f 4208//2535 4583//2535 4209//2535 -f 4211//2535 4585//2535 4212//2535 -f 4377//2536 4379//2536 3134//2536 -s 1 -f 3134//1658 4379//1658 3819//1658 -f 4356//1670 4107//1670 3227//1670 -s off -f 4053//2537 3401//2537 3403//2537 -f 3265//2538 4235//2538 3266//2538 -s 1 -f 3519//1658 3266//1658 4235//1658 -f 4576//1670 3115//1670 3121//1670 -f 3259//1658 4323//1658 3397//1658 -s off -f 4322//2539 3397//2539 4323//2539 -f 4520//2540 4045//2540 4295//2540 -f 4741//2541 4434//2541 4343//2541 -s 1 -f 3528//1658 3526//1658 4666//1658 -s off -f 3558//2542 4666//2542 3526//2542 -f 3798//2543 3713//2543 4076//2543 -s 1 -f 3712//1658 4076//1658 3713//1658 -s off -f 4057//2544 4287//2544 4124//2544 -s 1 -f 3281//1658 4124//1658 4287//1658 -s off -f 4062//2544 4285//2544 4125//2544 -s 1 -f 3287//1658 4125//1658 4285//1658 -f 3846//1670 3398//1670 4720//1670 -s off -f 3616//2545 4333//2545 4335//2545 -f 3783//2546 3711//2546 4668//2546 -s 1 -f 4668//1658 3711//1658 3716//1658 -f 3685//1670 4204//1670 3889//1670 -f 4252//1670 3777//1670 4693//1670 -s off -f 3898//2547 4429//2547 4431//2547 -s 1 -f 4431//1658 4429//1658 3381//1658 -s off -f 3499//2548 4725//2548 3496//2548 -s 1 -f 3496//1658 4725//1658 4032//1658 -f 4052//1670 3401//1670 4053//1670 -f 4437//1658 3511//1671 4438//1658 -s off -f 4633//2549 4438//2549 3511//2549 -s 1 -f 4439//1658 3513//1671 4440//1658 -s off -f 4634//2549 4440//2549 3513//2549 -f 4707//2550 4023//2550 4695//2550 -s 1 -f 4171//1670 4172//1670 3806//1670 -s off -f 4649//2551 3717//2551 4724//2551 -f 4048//2552 4049//2552 3926//2552 -s 1 -f 4071//1670 4416//1670 4072//1670 -f 3787//1670 3786//1670 3517//1670 -s off -f 4526//2553 3316//2553 3817//2553 -s 1 -f 4645//1670 4638//1670 3892//1670 -s off -f 3600//2554 4655//2554 3601//2554 -f 4670//2555 4391//2555 4221//2555 -f 4191//2556 3230//2556 3941//2556 -f 4037//2557 4737//2557 4038//2557 -s 1 -f 3891//1670 3890//1670 3820//1670 -s off -f 3317//2558 4680//2558 3318//2558 -s 1 -f 3508//1670 4685//1670 4496//1670 -s off -f 4560//2559 3398//2559 3688//2559 -s 1 -f 3528//1658 4597//1658 3882//1658 -s off -f 4070//2560 3882//2560 4597//2560 -f 4116//2561 4115//2561 4225//2561 -f 4118//2561 4120//2561 4230//2561 -s 1 -f 4470//1658 3927//1682 4471//1658 -s off -f 4047//2562 4471//2562 3927//2562 -s 1 -f 4043//1670 4045//1670 4520//1670 -f 4596//1670 4313//1670 4355//1670 -f 3782//1670 3854//1670 3853//1670 -f 3423//1658 3460//1658 4594//1658 -s off -f 4660//2563 4594//2563 3460//2563 -s 1 -f 3426//1658 3458//1658 4595//1658 -s off -f 4659//2563 4595//2563 3458//2563 -f 4712//2564 3323//2564 3484//2564 -s 1 -f 3245//1658 3669//1658 3242//1658 -s off -f 4590//2565 3669//2565 3245//2565 -s 1 -f 4596//1670 4355//1670 4325//1670 -s off -f 4303//2566 3997//2566 4536//2566 -f 4512//2567 3319//2567 4469//2567 -f 4301//2568 4000//2568 4539//2568 -f 4465//2569 4628//2569 3370//2569 -s 1 -f 4627//1658 3370//1658 4628//1658 -s off -f 4466//2569 4630//2569 3364//2569 -s 1 -f 4629//1658 3364//1658 4630//1658 -s off -f 3697//2570 3807//2570 3698//2570 -f 4562//2571 3313//2571 3326//2571 -f 3888//2572 3157//2572 4586//2572 -s 1 -f 3159//1658 4586//1658 3157//1658 -s off -f 3885//2573 3154//2573 4584//2573 -s 1 -f 3144//1658 4584//1658 3154//1658 -s off -f 4559//2574 3603//2574 3967//2574 -s 1 -f 3967//1658 3603//1658 3464//1658 -f 3598//1658 3597//1658 3974//1658 -s off -f 3596//2575 3598//2575 3974//2575 -f 4154//2576 3337//2576 3339//2576 -s 1 -f 3606//1658 3823//1658 3702//1658 -s off -f 3822//2577 3702//2577 3823//2577 -f 4504//2578 4739//2578 4505//2578 -s 1 -f 4080//1658 4505//1658 4739//1658 -f 4079//1658 4508//1658 4740//1658 -s off -f 4507//2578 4740//2578 4508//2578 -s 1 -f 4410//1670 3863//1670 4158//1670 -f 4335//1658 3474//1658 4729//1658 -s off -f 3473//2579 4729//2579 3474//2579 -s 1 -f 3612//1670 4359//1670 3917//1670 -f 3609//1670 4358//1670 3915//1670 -s off -f 4669//2580 3593//2580 4222//2580 -s 1 -f 3269//1682 3386//1671 3348//1682 -s off -f 3346//2581 3348//2581 3386//2581 -f 3343//2581 3345//2581 3392//2581 -s 1 -f 3278//1682 3392//1671 3345//1682 -f 4014//1670 4016//1670 3594//1670 -s off -f 4050//2582 4047//2582 3927//2582 -f 3924//2583 3129//2583 3925//2583 -s 1 -f 3925//1658 3129//1658 3687//1658 -s off -f 4318//2584 4105//2584 4334//2584 -s 1 -f 4334//1658 4105//1658 4103//1658 -s off -f 3708//2585 4632//2585 3503//2585 -f 3896//2586 3898//2586 4431//2586 -f 4732//2587 4568//2587 4542//2587 -f 4731//2587 4567//2587 4543//2587 -f 4700//2588 4207//2588 4247//2588 -f 4699//2588 4210//2588 4251//2588 -s 1 -f 3443//1658 4730//1658 3602//1658 -s off -f 3498//2589 4730//2589 3443//2589 -s 1 -f 3969//1670 3230//1670 4191//1670 -f 4390//1670 4223//1670 4391//1670 -s off -f 4187//2590 4558//2590 4103//2590 -s 1 -f 4334//1658 4103//1658 4558//1658 -s off -f 4513//2591 3340//2591 3342//2591 -f 3311//2592 4671//2592 3312//2592 -s 1 -f 3326//1658 3312//1658 4671//1658 -s off -f 4068//2593 4502//2593 4332//2593 -s 1 -f 4332//1658 4502//1658 4637//1658 -s off -f 4582//2594 3599//2594 4339//2594 -f 3879//2595 3615//2595 3617//2595 -f 3874//2596 4689//2596 3608//2596 -f 4271//2597 4168//2597 3687//2597 -s 1 -f 3438//1658 3434//1658 4733//1658 -s off -f 3559//2598 4733//2598 3434//2598 -f 3769//2599 3365//2599 3770//2599 -s 1 -f 3770//1658 3365//1658 3744//1658 -f 3767//1658 3371//1658 3745//1658 -s off -f 3766//2599 3371//2599 3767//2599 -f 3681//2600 4537//2600 3514//2600 -f 3683//2600 4540//2600 3512//2600 -f 3893//2601 4638//2601 4097//2601 -f 3244//2602 4590//2602 3245//2602 -f 4571//2603 3969//2603 3255//2603 -s 1 -f 3228//1670 3860//1670 4312//1670 -s off -f 3428//2604 4130//2604 3429//2604 -f 3652//2605 4572//2605 4018//2605 -s 1 -f 4194//1658 4018//1658 4572//1658 -s off -f 3655//2605 4573//2605 4020//2605 -s 1 -f 4195//1658 4020//1658 4573//1658 -f 4123//1670 3307//1670 4273//1670 -s off -f 3142//2606 3135//2606 4738//2606 -s 1 -f 4738//1671 3135//1658 3564//1658 -f 4048//1670 4047//1670 4050//1670 -f 3340//1670 4512//1670 3911//1670 -s off -f 4587//2607 3793//2607 4106//2607 -f 4107//2608 4742//2608 4108//2608 -s 1 -f 4703//1671 4108//1671 4742//1671 -s off -f 3295//2609 4633//2609 3511//2609 -f 3292//2609 4634//2609 3513//2609 -f 4639//2610 4185//2610 3973//2610 -f 3818//2611 4704//2611 3341//2611 -f 4531//2612 4569//2612 4458//2612 -s 1 -f 3484//1658 3308//1658 4418//1658 -s off -f 3378//2613 4418//2613 3308//2613 -f 4387//2614 3660//2614 4481//2614 -f 4388//2614 3657//2614 4483//2614 -f 4253//2615 4650//2615 4254//2615 -f 4488//2616 3187//2616 4489//2616 -s 1 -f 3689//1658 4489//1658 3187//1658 -s off -f 4486//2617 3175//2617 4487//2617 -s 1 -f 3691//1658 4487//1658 3175//1658 -s off -f 4454//2618 4040//2618 4338//2618 -s 1 -f 4351//1670 3885//1670 4722//1670 -f 4352//1670 3888//1670 4723//1670 -s off -f 4341//2619 4604//2619 3252//2619 -s 1 -f 4252//1670 4693//1670 4161//1670 -f 3844//1670 4716//1670 3845//1670 -s off -f 4219//2620 3261//2620 3693//2620 -s 1 -f 4705//1658 4250//1658 4212//1658 -s off -f 4352//2621 4250//2621 4705//2621 -f 4351//2622 4246//2622 4706//2622 -s 1 -f 4706//1658 4246//1658 4209//1658 -f 3734//1670 4210//1670 4699//1670 -f 3733//1670 4207//1670 4700//1670 -s off -f 4345//2623 4484//2623 4381//2623 -f 4598//2624 3247//2624 3993//2624 -f 3717//2625 3719//2625 4724//2625 -s 1 -f 4724//1658 3719//1682 3927//1682 -s off -f 3929//2626 4258//2626 4728//2626 -s 1 -f 4728//1658 4258//1658 4543//1658 -f 4727//1658 4257//1658 4542//1658 -s off -f 3931//2626 4257//2626 4727//2626 -s 1 -f 3441//1670 3440//1670 3627//1670 -f 3850//1670 3849//1670 4318//1670 -s off -f 4378//2627 4648//2627 4470//2627 -f 4587//2628 4106//2628 4607//2628 -s 1 -f 4617//1658 4607//1658 4106//1658 -f 3667//1670 4655//1670 3600//1670 -s off -f 4736//2629 3251//2629 3253//2629 -f 4735//2630 3200//2630 3202//2630 -s 1 -f 4526//1670 3763//1670 3316//1670 -s off -f 4023//2631 4025//2631 4695//2631 -s 1 -f 4038//1658 4695//1658 4025//1658 -s off -f 3554//2632 4617//2632 3851//2632 -s 1 -f 3851//1658 4617//1658 4106//1658 -s off -f 4714//2633 4276//2633 3459//2633 -f 4715//2633 4279//2633 3461//2633 -s 1 -f 4077//1670 4354//1670 3879//1670 -s off -f 3970//2634 4433//2634 3971//2634 -s 1 -f 4048//1670 4050//1670 4049//1670 -f 4059//1670 3292//1670 3291//1670 -f 4064//1670 3295//1670 3294//1670 -f 4662//1658 4570//1658 3377//1658 -s off -f 4654//2635 4570//2635 4662//2635 -f 4326//2636 4026//2636 3995//2636 -f 4663//2637 4664//2637 3972//2637 -s 1 -f 3972//1658 4664//1658 3973//1658 -s off -f 4463//2638 3233//2638 4464//2638 -f 4460//2638 3237//2638 4461//2638 -s 1 -f 4220//1670 3897//1670 3896//1670 -s off -f 4592//2639 3146//2639 3148//2639 -f 4593//2639 3161//2639 3163//2639 -s 1 -f 3428//1670 3977//1670 4130//1670 -f 3424//1670 3660//1670 4387//1670 -f 3421//1670 3657//1670 4388//1670 -f 3801//1670 3807//1670 3697//1670 -s off -f 3583//2640 4315//2640 3584//2640 -s 1 -f 4314//1670 3876//1670 3501//1670 -s off -f 4551//2641 4196//2641 4552//2641 -s 1 -f 3196//1658 4552//1658 4196//1658 -s off -f 4553//2642 4193//2642 4554//2642 -s 1 -f 3184//1658 4554//1658 4193//1658 -s off -f 4457//2643 4109//2643 4702//2643 -f 4698//2644 4442//2644 4441//2644 -s 1 -f 3317//1670 4681//1670 4680//1670 -s off -f 4475//2645 4284//2645 3691//2645 -s 1 -f 3691//1658 4284//1658 4487//1658 -s off -f 4473//2645 4286//2645 3689//2645 -s 1 -f 3689//1658 4286//1658 4489//1658 -f 3317//1670 3624//1670 4681//1670 -s off -f 4744//2646 4500//2646 4501//2646 -f 4745//2646 4498//2646 4499//2646 -f 4031//2647 4713//2647 4032//2647 -f 3891//2648 3760//2648 3762//2648 -s 1 -f 3512//1682 4538//1658 3178//1658 -s off -f 4302//2649 3178//2649 4538//2649 -f 4304//2649 3190//2649 4535//2649 -s 1 -f 3514//1682 4535//1658 3190//1658 -s off -f 4653//2650 4036//2650 4350//2650 -s 1 -f 4453//1670 4636//1670 3618//1670 -s off -f 4491//2651 4135//2651 4492//2651 -f 4494//2651 4137//2651 4495//2651 -s 1 -f 4720//1670 3398//1670 4560//1670 -f 4561//1670 3793//1670 4587//1670 -s off -f 4624//2652 4305//2652 4307//2652 -f 4110//2653 3664//2653 3666//2653 -s 1 -f 4037//1670 4024//1670 4737//1670 -f 3610//1670 3997//1670 4303//1670 -f 3613//1670 4000//1670 4301//1670 -s off -f 3357//2654 4748//2654 3358//2654 -s 1 -f 4326//1670 3300//1670 4026//1670 -f 4176//1670 4168//1670 4271//1670 -s off -f 4747//2655 4618//2655 4412//2655 -s 1 -f 4684//1658 4202//1658 4144//1658 -s off -f 4143//2656 4144//2656 4202//2656 -s 1 -f 4627//1658 3272//1658 3370//1658 -s off -f 3270//2657 3272//2657 4627//2657 -s 1 -f 4629//1658 3275//1658 3364//1658 -s off -f 3273//2657 3275//2657 4629//2657 -f 3276//2658 3278//2658 4227//2658 -s 1 -f 4227//1726 3278//1682 3345//1682 -s off -f 3267//2658 3269//2658 4228//2658 -s 1 -f 4228//1726 3269//1682 3348//1682 -f 4743//1670 4565//1670 4121//1670 -f 3246//1658 3462//1658 4404//1658 -s off -f 4403//2659 4404//2659 3462//2659 -f 4138//2660 4003//2660 4005//2660 -f 4136//2660 4008//2660 4006//2660 -f 4672//2661 3631//2661 3665//2661 -s 1 -f 4113//1670 4115//1670 4116//1670 -f 4117//1670 4120//1670 4118//1670 -f 4014//1670 3593//1670 4669//1670 -f 4234//1658 3519//1658 4235//1658 -s off -f 3517//2662 3519//2662 4234//2662 -f 3782//2663 4184//2663 3752//2663 -s 1 -f 3752//1658 4184//1658 4112//1658 -f 3929//1670 4567//1670 4731//1670 -f 3931//1670 4568//1670 4732//1670 -f 4721//1658 3550//1658 3698//1658 -s off -f 3806//2664 3550//2664 4721//2664 -s 1 -f 4570//1658 3416//1726 3377//1658 -s off -f 3375//2665 3377//2665 3416//2665 -f 4414//2666 4456//2666 4413//2666 -s 1 -f 4213//1658 4711//1658 4206//1658 -s off -f 3890//2667 4206//2667 4711//2667 -f 3952//2668 4614//2668 4616//2668 -f 3956//2668 4611//2668 4613//2668 -f 4027//2669 4677//2669 3353//2669 -s 1 -f 3892//1670 4638//1670 3893//1670 -s off -f 4683//2670 3936//2670 4684//2670 -s 1 -f 3891//1670 3820//1670 3760//1670 -f 4153//1670 3337//1670 4154//1670 -s off -f 3262//2671 3197//2671 3199//2671 -f 3298//2672 4380//2672 4646//2672 -s 1 -f 4455//1658 4646//1658 4380//1658 -s off -f 4678//2673 3582//2673 4420//2673 -f 4041//2674 3992//2674 4042//2674 -s 1 -f 4042//1658 3992//1658 4339//1658 -s off -f 4612//2675 4197//2675 4644//2675 -f 4615//2676 4199//2676 4643//2676 -f 3920//2677 4734//2677 4319//2677 -s 1 -f 4610//1670 4569//1670 4531//1670 -s off -f 4687//2678 4462//2678 4578//2678 -f 4688//2679 4459//2679 4579//2679 -s 1 -f 4282//1670 3599//1670 4582//1670 -s off -f 4686//2680 4654//2680 4662//2680 -s 1 -f 4015//1670 4185//1670 4639//1670 -s off -f 3802//2681 4451//2681 4449//2681 -s 1 -f 3774//1658 3623//1658 3465//1658 -s off -f 3622//2682 3465//2682 3623//2682 -f 3742//2683 3172//2683 3743//2683 -s 1 -f 3743//1658 3172//1658 4413//1658 -s off -f 3140//2684 4647//2684 3141//2684 -s 1 -f 4297//1658 3141//1658 4647//1658 -f 3432//1726 3414//1682 3417//1726 -s off -f 3431//2685 3414//2685 3432//2685 -s 1 -f 4513//1670 4512//1670 3340//1670 -f 3183//1658 3174//1658 3647//1658 -s off -f 3516//2686 3647//2686 3174//2686 -s 1 -f 3195//1658 3186//1658 3649//1658 -s off -f 3515//2686 3649//2686 3186//2686 -f 4619//2687 3349//2687 3988//2687 -f 4675//2688 3634//2688 4007//2688 -f 4676//2688 3637//2688 4004//2688 -f 3859//2689 4408//2689 4317//2689 -s 1 -f 3120//1671 4317//1658 4408//1658 -s off -f 4718//2690 4490//2690 4516//2690 -f 4719//2690 4493//2690 4515//2690 -f 3638//2691 4522//2691 3639//2691 -f 3635//2691 4521//2691 3636//2691 -s 1 -f 4571//1670 3230//1670 3969//1670 -f 4562//1670 3722//1670 3721//1670 -f 4485//1670 4484//1670 4345//1670 -s off -f 4692//2692 3352//2692 3354//2692 -f 3632//2693 4532//2693 3633//2693 -s 1 -f 4450//1658 4703//1671 4742//1671 -s off -f 4641//2694 4703//2694 4450//2694 -s 1 -f 3991//1658 4606//1658 4478//1658 -s off -f 4030//2695 4478//2695 4606//2695 -s 1 -f 4437//1658 3692//1671 3511//1671 -s off -f 4061//2696 3692//2696 4437//2696 -f 4056//2696 3690//2696 4439//2696 -s 1 -f 4439//1658 3690//1671 3513//1671 -s off -f 3629//2697 3485//2697 3819//2697 -s 1 -f 3134//1658 3819//1658 3485//1658 -f 3328//1658 3965//1658 3459//1658 -s off -f 3327//2698 3965//2698 3328//2698 -f 3332//2698 3964//2698 3333//2698 -s 1 -f 3333//1658 3964//1658 3461//1658 -f 3818//1670 3911//1670 4704//1670 -f 4635//1671 4658//1671 3243//1658 -s off -f 3950//2699 3243//2699 4658//2699 -# 0 polygons - 2797 triangles - -# -# object outter_tri -# - -v 0.4062 0.5906 8.4518 -v 0.3630 0.5906 8.4843 -v 0.3630 -0.5906 8.4843 -v 0.4062 -0.5906 8.4518 -v 0.3191 0.5906 8.5129 -v 0.3191 -0.5906 8.5129 -v 0.2970 0.5906 8.5258 -v 0.2970 -0.5906 8.5258 -v 0.2746 0.5906 8.5377 -v 0.2746 -0.5906 8.5377 -v 0.2522 0.5906 8.5487 -v 0.2522 -0.5906 8.5487 -v 0.2297 0.5906 8.5587 -v 0.2297 -0.5906 8.5587 -v 0.2070 0.5906 8.5678 -v 0.2070 -0.5906 8.5678 -v 0.1842 0.5906 8.5759 -v 0.1842 -0.5906 8.5759 -v 0.1614 0.5906 8.5831 -v 0.1614 -0.5906 8.5831 -v 0.1385 0.5906 8.5893 -v 0.1385 -0.5906 8.5893 -v 0.1155 0.5906 8.5945 -v 0.1155 -0.5906 8.5945 -v 0.0925 0.5906 8.5988 -v 0.0925 -0.5906 8.5988 -v 0.0694 0.5906 8.6022 -v 0.0694 -0.5906 8.6022 -v 0.0463 0.5906 8.6045 -v 0.0463 -0.5906 8.6045 -v 0.0231 0.5906 8.6060 -v 0.0231 -0.5906 8.6060 -v -0.0000 0.5906 8.6064 -v -0.0000 -0.5906 8.6064 -v -0.0231 0.5906 8.6060 -v -0.0231 -0.5906 8.6060 -v -0.0463 0.5906 8.6045 -v -0.0463 -0.5906 8.6045 -v -0.0694 0.5906 8.6022 -v -0.0694 -0.5906 8.6022 -v -0.0925 0.5906 8.5988 -v -0.0925 -0.5906 8.5988 -v -0.1155 0.5906 8.5945 -v -0.1155 -0.5906 8.5945 -v -0.1385 0.5906 8.5893 -v -0.1385 -0.5906 8.5893 -v -0.1614 0.5906 8.5831 -v -0.1614 -0.5906 8.5831 -v -0.1842 0.5906 8.5759 -v -0.1842 -0.5906 8.5759 -v -0.2070 0.5906 8.5678 -v -0.2070 -0.5906 8.5678 -v -0.2297 0.5906 8.5587 -v -0.2297 -0.5906 8.5587 -v -0.2522 0.5906 8.5487 -v -0.2522 -0.5906 8.5487 -v -0.2747 0.5906 8.5377 -v -0.2747 -0.5906 8.5377 -v -0.2970 0.5906 8.5258 -v -0.2970 -0.5906 8.5258 -v -0.3191 0.5906 8.5129 -v -0.3191 -0.5906 8.5129 -v -0.3630 0.5906 8.4843 -v -0.3630 -0.5906 8.4843 -v -0.4062 0.5906 8.4518 -v -0.4062 -0.5906 8.4518 -v -0.4486 0.5906 8.4155 -v -0.4486 -0.5906 8.4155 -v -0.4901 0.5906 8.3754 -v -0.4901 -0.5906 8.3754 -v -0.5307 0.5906 8.3315 -v -0.5307 -0.5906 8.3315 -v -0.5703 0.5906 8.2838 -v -0.5703 -0.5906 8.2838 -v -0.6087 0.5906 8.2322 -v -0.6087 -0.5906 8.2322 -v -0.6460 0.5906 8.1769 -v -0.6460 -0.5906 8.1769 -v -0.6819 0.5906 8.1177 -v -0.6819 -0.5906 8.1177 -v -6.1372 0.5906 -1.3312 -v -6.1372 -0.5906 -1.3312 -v -6.1705 0.5906 -1.3919 -v -6.1705 -0.5906 -1.3919 -v -6.1998 0.5906 -1.4518 -v -6.1998 -0.5906 -1.4518 -v -6.2252 0.5906 -1.5109 -v -6.2252 -0.5906 -1.5109 -v -6.2468 0.5906 -1.5690 -v -6.2468 -0.5906 -1.5690 -v -6.2645 0.5906 -1.6261 -v -6.2645 -0.5906 -1.6261 -v -6.2785 0.5906 -1.6822 -v -6.2785 -0.5906 -1.6822 -v -6.2887 0.5906 -1.7370 -v -6.2887 -0.5906 -1.7370 -v -6.2952 0.5906 -1.7906 -v -6.2952 -0.5906 -1.7906 -v -6.2981 0.5906 -1.8430 -v -6.2981 -0.5906 -1.8430 -v -6.2982 0.5906 -1.8686 -v -6.2982 -0.5906 -1.8686 -v -6.2973 0.5906 -1.8939 -v -6.2973 -0.5906 -1.8939 -v -6.2956 0.5906 -1.9188 -v -6.2956 -0.5906 -1.9188 -v -6.2930 0.5906 -1.9433 -v -6.2930 -0.5906 -1.9433 -v -6.2896 0.5906 -1.9675 -v -6.2896 -0.5906 -1.9675 -v -6.2852 0.5906 -1.9913 -v -6.2852 -0.5906 -1.9913 -v -6.2800 0.5906 -2.0146 -v -6.2800 -0.5906 -2.0146 -v -6.2739 0.5906 -2.0376 -v -6.2739 -0.5906 -2.0376 -v -6.2670 0.5906 -2.0601 -v -6.2670 -0.5906 -2.0601 -v -6.2592 0.5906 -2.0822 -v -6.2592 -0.5906 -2.0822 -v -6.2505 0.5906 -2.1039 -v -6.2505 -0.5906 -2.1039 -v -6.2410 0.5906 -2.1251 -v -6.2410 -0.5906 -2.1251 -v -6.2307 0.5906 -2.1458 -v -6.2307 -0.5906 -2.1458 -v -6.2195 0.5906 -2.1661 -v -6.2195 -0.5906 -2.1661 -v -6.2075 0.5906 -2.1859 -v -6.2075 -0.5906 -2.1859 -v -6.1947 0.5906 -2.2052 -v -6.1947 -0.5906 -2.2052 -v -6.1811 0.5906 -2.2240 -v -6.1811 -0.5906 -2.2240 -v -6.1667 0.5906 -2.2424 -v -6.1667 -0.5906 -2.2424 -v -6.1514 0.5906 -2.2602 -v -6.1514 -0.5906 -2.2602 -v -6.1354 0.5906 -2.2774 -v -6.1354 -0.5906 -2.2774 -v -6.1186 0.5906 -2.2942 -v -6.1186 -0.5906 -2.2942 -v -6.1010 0.5906 -2.3104 -v -6.1010 -0.5906 -2.3104 -v -6.0825 0.5906 -2.3260 -v -6.0825 -0.5906 -2.3260 -v -6.0634 0.5906 -2.3411 -v -6.0634 -0.5906 -2.3411 -v -6.0434 0.5906 -2.3556 -v -6.0434 -0.5906 -2.3556 -v -6.0227 0.5906 -2.3696 -v -6.0227 -0.5906 -2.3696 -v -6.0012 0.5906 -2.3829 -v -6.0012 -0.5906 -2.3829 -v -5.9790 0.5906 -2.3957 -v -5.9790 -0.5906 -2.3957 -v -5.9322 0.5906 -2.4194 -v -5.9322 -0.5906 -2.4194 -v -5.8825 0.5906 -2.4405 -v -5.8825 -0.5906 -2.4405 -v -5.8299 0.5906 -2.4591 -v -5.8299 -0.5906 -2.4591 -v -5.7744 0.5906 -2.4750 -v -5.7744 -0.5906 -2.4750 -v -5.7161 0.5906 -2.4882 -v -5.7161 -0.5906 -2.4882 -v -5.6550 0.5906 -2.4986 -v -5.6550 -0.5906 -2.4986 -v -5.5911 0.5906 -2.5062 -v -5.5911 -0.5906 -2.5062 -v -5.5245 0.5906 -2.5107 -v -5.5245 -0.5906 -2.5107 -v -5.4553 0.5906 -2.5123 -v -5.4553 -0.5906 -2.5123 -v 5.4553 0.5906 -2.5123 -v 5.4553 -0.5905 -2.5123 -v 5.5245 0.5906 -2.5107 -v 5.5245 -0.5905 -2.5107 -v 5.5911 0.5906 -2.5062 -v 5.5911 -0.5905 -2.5062 -v 5.6550 0.5906 -2.4986 -v 5.6550 -0.5905 -2.4986 -v 5.7161 0.5906 -2.4882 -v 5.7161 -0.5905 -2.4882 -v 5.7744 0.5906 -2.4750 -v 5.7744 -0.5905 -2.4750 -v 5.8299 0.5906 -2.4591 -v 5.8299 -0.5905 -2.4591 -v 5.8825 0.5906 -2.4405 -v 5.8825 -0.5905 -2.4405 -v 5.9322 0.5906 -2.4194 -v 5.9322 -0.5905 -2.4194 -v 5.9790 0.5906 -2.3957 -v 5.9790 -0.5905 -2.3957 -v 6.0012 0.5906 -2.3829 -v 6.0012 -0.5905 -2.3829 -v 6.0227 0.5906 -2.3696 -v 6.0227 -0.5905 -2.3696 -v 6.0434 0.5906 -2.3556 -v 6.0434 -0.5905 -2.3556 -v 6.0634 0.5906 -2.3411 -v 6.0634 -0.5905 -2.3411 -v 6.0825 0.5906 -2.3260 -v 6.0825 -0.5905 -2.3260 -v 6.1010 0.5906 -2.3104 -v 6.1010 -0.5905 -2.3104 -v 6.1186 0.5906 -2.2942 -v 6.1186 -0.5905 -2.2942 -v 6.1354 0.5906 -2.2774 -v 6.1354 -0.5905 -2.2774 -v 6.1514 0.5906 -2.2602 -v 6.1514 -0.5905 -2.2602 -v 6.1667 0.5906 -2.2424 -v 6.1667 -0.5905 -2.2424 -v 6.1811 0.5906 -2.2240 -v 6.1811 -0.5905 -2.2240 -v 6.1947 0.5906 -2.2052 -v 6.1947 -0.5905 -2.2052 -v 6.2075 0.5906 -2.1859 -v 6.2075 -0.5905 -2.1859 -v 6.2195 0.5906 -2.1661 -v 6.2195 -0.5905 -2.1661 -v 6.2307 0.5906 -2.1458 -v 6.2307 -0.5905 -2.1458 -v 6.2410 0.5906 -2.1251 -v 6.2410 -0.5905 -2.1251 -v 6.2505 0.5906 -2.1039 -v 6.2505 -0.5905 -2.1039 -v 6.2592 0.5906 -2.0822 -v 6.2592 -0.5905 -2.0822 -v 6.2670 0.5906 -2.0601 -v 6.2670 -0.5905 -2.0601 -v 6.2739 0.5906 -2.0376 -v 6.2739 -0.5905 -2.0376 -v 6.2800 0.5906 -2.0146 -v 6.2800 -0.5905 -2.0146 -v 6.2852 0.5906 -1.9913 -v 6.2852 -0.5905 -1.9913 -v 6.2896 0.5906 -1.9675 -v 6.2896 -0.5905 -1.9675 -v 6.2930 0.5906 -1.9433 -v 6.2930 -0.5905 -1.9433 -v 6.2956 0.5906 -1.9188 -v 6.2956 -0.5905 -1.9188 -v 6.2973 0.5906 -1.8939 -v 6.2973 -0.5905 -1.8939 -v 6.2982 0.5906 -1.8686 -v 6.2982 -0.5905 -1.8686 -v 6.2981 0.5906 -1.8430 -v 6.2981 -0.5905 -1.8430 -v 6.2952 0.5906 -1.7906 -v 6.2952 -0.5905 -1.7906 -v 6.2887 0.5906 -1.7370 -v 6.2887 -0.5905 -1.7370 -v 6.2785 0.5906 -1.6822 -v 6.2785 -0.5905 -1.6822 -v 6.2645 0.5906 -1.6261 -v 6.2645 -0.5905 -1.6261 -v 6.2468 0.5906 -1.5690 -v 6.2468 -0.5905 -1.5690 -v 6.2252 0.5906 -1.5109 -v 6.2252 -0.5905 -1.5109 -v 6.1998 0.5906 -1.4518 -v 6.1998 -0.5905 -1.4518 -v 6.1705 0.5906 -1.3919 -v 6.1705 -0.5905 -1.3919 -v 6.1372 0.5906 -1.3312 -v 6.1372 -0.5905 -1.3312 -v 0.6819 0.5906 8.1177 -v 0.6819 -0.5906 8.1177 -v 0.6460 0.5906 8.1769 -v 0.6460 -0.5906 8.1769 -v 0.6087 0.5906 8.2322 -v 0.6087 -0.5906 8.2322 -v 0.5703 0.5906 8.2838 -v 0.5703 -0.5906 8.2838 -v 0.5307 0.5906 8.3315 -v 0.5307 -0.5906 8.3315 -v 0.4901 0.5906 8.3754 -v 0.4901 -0.5906 8.3754 -v 0.4486 0.5906 8.4155 -v 0.4486 -0.5906 8.4155 -v -0.0000 -0.5906 7.3303 -v 5.1143 -0.5906 -1.5280 -v -5.1143 -0.5906 -1.5280 -v -0.0000 0.1969 7.3303 -v -5.1143 0.1969 -1.5280 -v 5.1143 0.1969 -1.5280 -# 288 vertices - -vn 0.6009 0.0000 0.7993 -vn 0.5467 0.0000 0.8373 -vn 0.5026 0.0000 0.8645 -vn 0.4718 0.0000 0.8817 -vn 0.4396 0.0000 0.8982 -vn 0.4062 -0.0000 0.9138 -vn 0.3716 -0.0000 0.9284 -vn 0.3359 -0.0000 0.9419 -vn 0.2991 -0.0000 0.9542 -vn 0.2614 -0.0000 0.9652 -vn 0.2227 -0.0000 0.9749 -vn 0.1834 -0.0000 0.9830 -vn 0.1432 -0.0000 0.9897 -vn 0.1028 -0.0000 0.9947 -vn 0.0618 -0.0000 0.9981 -vn 0.0206 -0.0000 0.9998 -vn -0.0206 -0.0000 0.9998 -vn -0.0618 -0.0000 0.9981 -vn -0.1027 -0.0000 0.9947 -vn -0.1433 -0.0000 0.9897 -vn -0.1833 -0.0000 0.9831 -vn -0.2227 -0.0000 0.9749 -vn -0.2613 -0.0000 0.9652 -vn -0.2991 -0.0000 0.9542 -vn -0.3359 -0.0000 0.9419 -vn -0.3716 -0.0000 0.9284 -vn -0.4062 -0.0000 0.9138 -vn -0.4396 -0.0000 0.8982 -vn -0.4718 -0.0000 0.8817 -vn -0.5026 -0.0000 0.8645 -vn -0.5467 -0.0000 0.8373 -vn -0.6009 -0.0000 0.7993 -vn -0.6501 -0.0000 0.7599 -vn -0.6945 -0.0000 0.7195 -vn -0.7343 -0.0000 0.6788 -vn -0.7699 -0.0000 0.6381 -vn -0.8016 -0.0000 0.5978 -vn -0.8298 -0.0000 0.5581 -vn -0.8547 -0.0000 0.5191 -vn -0.8660 -0.0000 0.5000 -vn -0.8769 -0.0000 0.4806 -vn -0.8982 -0.0000 0.4396 -vn -0.9185 -0.0000 0.3953 -vn -0.9376 -0.0000 0.3477 -vn -0.9550 -0.0000 0.2965 -vn -0.9704 -0.0000 0.2417 -vn -0.9831 -0.0000 0.1831 -vn -0.9927 -0.0000 0.1207 -vn -0.9985 -0.0000 0.0548 -vn -1.0000 -0.0000 0.0031 -vn -0.9995 0.0000 -0.0323 -vn -0.9977 0.0000 -0.0684 -vn -0.9945 0.0000 -0.1052 -vn -0.9898 0.0000 -0.1424 -vn -0.9837 0.0000 -0.1801 -vn -0.9759 0.0000 -0.2181 -vn -0.9666 0.0000 -0.2563 -vn -0.9556 0.0000 -0.2946 -vn -0.9430 0.0000 -0.3327 -vn -0.9287 0.0000 -0.3708 -vn -0.9128 0.0000 -0.4084 -vn -0.8953 0.0000 -0.4455 -vn -0.8762 0.0000 -0.4820 -vn -0.8555 0.0000 -0.5177 -vn -0.8335 0.0000 -0.5526 -vn -0.8101 0.0000 -0.5863 -vn -0.7855 0.0000 -0.6189 -vn -0.7597 0.0000 -0.6503 -vn -0.7329 0.0000 -0.6803 -vn -0.7052 0.0000 -0.7090 -vn -0.6768 0.0000 -0.7361 -vn -0.6478 0.0000 -0.7618 -vn -0.6182 0.0000 -0.7860 -vn -0.5883 0.0000 -0.8087 -vn -0.5581 0.0000 -0.8298 -vn -0.5277 0.0000 -0.8494 -vn -0.4973 0.0000 -0.8676 -vn -0.4518 0.0000 -0.8921 -vn -0.3918 0.0000 -0.9201 -vn -0.3330 0.0000 -0.9429 -vn -0.2759 0.0000 -0.9612 -vn -0.2207 0.0000 -0.9753 -vn -0.1677 0.0000 -0.9858 -vn -0.1169 0.0000 -0.9931 -vn -0.0684 0.0000 -0.9977 -vn -0.0222 0.0000 -0.9998 -vn 0.0000 0.0000 -1.0000 -vn 0.0222 0.0000 -0.9998 -vn 0.0684 0.0000 -0.9977 -vn 0.1169 0.0000 -0.9931 -vn 0.1677 0.0000 -0.9858 -vn 0.2207 0.0000 -0.9753 -vn 0.2759 0.0000 -0.9612 -vn 0.3330 0.0000 -0.9429 -vn 0.3918 0.0000 -0.9200 -vn 0.4518 0.0000 -0.8921 -vn 0.4973 0.0000 -0.8676 -vn 0.5278 0.0000 -0.8494 -vn 0.5581 0.0000 -0.8298 -vn 0.5883 0.0000 -0.8086 -vn 0.6182 0.0000 -0.7860 -vn 0.6478 0.0000 -0.7618 -vn 0.6768 0.0000 -0.7361 -vn 0.7053 0.0000 -0.7090 -vn 0.7329 0.0000 -0.6803 -vn 0.7597 0.0000 -0.6503 -vn 0.7855 0.0000 -0.6189 -vn 0.8101 0.0000 -0.5863 -vn 0.8335 0.0000 -0.5525 -vn 0.8555 0.0000 -0.5178 -vn 0.8762 0.0000 -0.4820 -vn 0.8953 0.0000 -0.4455 -vn 0.9128 0.0000 -0.4084 -vn 0.9287 0.0000 -0.3707 -vn 0.9430 0.0000 -0.3328 -vn 0.9556 0.0000 -0.2945 -vn 0.9666 0.0000 -0.2563 -vn 0.9759 0.0000 -0.2181 -vn 0.9837 0.0000 -0.1801 -vn 0.9898 0.0000 -0.1424 -vn 0.9945 0.0000 -0.1052 -vn 0.9977 0.0000 -0.0684 -vn 0.9995 0.0000 -0.0323 -vn 1.0000 -0.0000 0.0031 -vn 0.9985 -0.0000 0.0548 -vn 0.9927 -0.0000 0.1207 -vn 0.9831 -0.0000 0.1830 -vn 0.9704 -0.0000 0.2417 -vn 0.9550 -0.0000 0.2965 -vn 0.9376 -0.0000 0.3477 -vn 0.9185 -0.0000 0.3953 -vn 0.8982 -0.0000 0.4396 -vn 0.8769 -0.0000 0.4806 -vn 0.8660 -0.0000 0.5000 -vn 0.8547 0.0000 0.5191 -vn 0.8298 0.0000 0.5581 -vn 0.8016 0.0000 0.5978 -vn 0.7699 0.0000 0.6382 -vn 0.7343 0.0000 0.6788 -vn 0.6945 0.0000 0.7195 -vn 0.6501 0.0000 0.7599 -vn 0.0000 1.0000 0.0000 -vn -0.0000 1.0000 -0.0000 -vn -0.0000 1.0000 0.0000 -vn 0.0000 1.0000 -0.0000 -vn -0.0000 -1.0000 0.0000 -vn 0.0000 -1.0000 -0.0000 -vn 0.0000 -1.0000 0.0000 -vn -0.0000 -1.0000 -0.0000 -vn 0.0001 -1.0000 0.0001 -vn -0.0001 -1.0000 0.0001 -vn -0.0000 -0.0000 1.0000 -vn 0.8660 -0.0000 -0.5000 -vn -0.8660 -0.0000 -0.5000 -# 154 vertex normals - -vt 0.6373 0.4793 0.5000 -vt 0.6382 0.4821 0.5000 -vt 0.6382 0.4821 1.5000 -vt 0.6373 0.4793 1.5000 -vt 0.6389 0.4849 0.5000 -vt 0.6389 0.4849 1.5000 -vt 0.6392 0.4864 0.5000 -vt 0.6392 0.4864 1.5000 -vt 0.6395 0.4878 0.5000 -vt 0.6395 0.4878 1.5000 -vt 0.6398 0.4893 0.5000 -vt 0.6398 0.4893 1.5000 -vt 0.6401 0.4907 0.5000 -vt 0.6401 0.4907 1.5000 -vt 0.6403 0.4922 0.5000 -vt 0.6403 0.4922 1.5000 -vt 0.6405 0.4936 0.5000 -vt 0.6405 0.4936 1.5000 -vt 0.6407 0.4951 0.5000 -vt 0.6407 0.4951 1.5000 -vt 0.6409 0.4966 0.5000 -vt 0.6409 0.4966 1.5000 -vt 0.6410 0.4981 0.5000 -vt 0.6410 0.4981 1.5000 -vt 0.6411 0.4996 0.5000 -vt 0.6411 0.4996 1.5000 -vt 0.6412 0.5011 0.5000 -vt 0.6412 0.5011 1.5000 -vt 0.6413 0.5025 0.5000 -vt 0.6413 0.5025 1.5000 -vt 0.6413 0.5040 0.5000 -vt 0.6413 0.5040 1.5000 -vt 0.6413 0.5055 0.5000 -vt 0.6413 0.5055 1.5000 -vt 0.6413 0.5070 0.5000 -vt 0.6413 0.5070 1.5000 -vt 0.6413 0.5085 0.5000 -vt 0.6413 0.5085 1.5000 -vt 0.6412 0.5100 0.5000 -vt 0.6412 0.5100 1.5000 -vt 0.6411 0.5115 0.5000 -vt 0.6411 0.5115 1.5000 -vt 0.6410 0.5130 0.5000 -vt 0.6410 0.5130 1.5000 -vt 0.6409 0.5145 0.5000 -vt 0.6409 0.5145 1.5000 -vt 0.6407 0.5159 0.5000 -vt 0.6407 0.5159 1.5000 -vt 0.6405 0.5174 0.5000 -vt 0.6405 0.5174 1.5000 -vt 0.6403 0.5189 0.5000 -vt 0.6403 0.5189 1.5000 -vt 0.6401 0.5203 0.5000 -vt 0.6401 0.5203 1.5000 -vt 0.6398 0.5218 0.5000 -vt 0.6398 0.5218 1.5000 -vt 0.6395 0.5232 0.5000 -vt 0.6395 0.5232 1.5000 -vt 0.6392 0.5247 0.5000 -vt 0.6392 0.5247 1.5000 -vt 0.6389 0.5261 0.5000 -vt 0.6389 0.5261 1.5000 -vt 0.6382 0.5289 0.5000 -vt 0.6382 0.5289 1.5000 -vt 0.6373 0.5317 0.5000 -vt 0.6373 0.5317 1.5000 -vt 0.6364 0.5344 0.5000 -vt 0.6364 0.5344 1.5000 -vt 0.6353 0.5371 0.5000 -vt 0.6353 0.5371 1.5000 -vt 0.6342 0.5397 0.5000 -vt 0.6342 0.5397 1.5000 -vt 0.6329 0.5423 0.5000 -vt 0.6329 0.5423 1.5000 -vt 0.6316 0.5448 0.5000 -vt 0.6316 0.5448 1.5000 -vt 0.6302 0.5472 0.5000 -vt 0.6302 0.5472 1.5000 -vt 0.6286 0.5495 0.5000 -vt 0.6286 0.5495 1.5000 -vt 0.3829 0.9012 0.5000 -vt 0.3829 0.9012 1.5000 -vt 0.3813 0.9034 0.5000 -vt 0.3813 0.9034 1.5000 -vt 0.3797 0.9053 0.5000 -vt 0.3797 0.9053 1.5000 -vt 0.3782 0.9069 0.5000 -vt 0.3782 0.9069 1.5000 -vt 0.3767 0.9083 0.5000 -vt 0.3767 0.9083 1.5000 -vt 0.3752 0.9094 0.5000 -vt 0.3752 0.9094 1.5000 -vt 0.3738 0.9103 0.5000 -vt 0.3738 0.9103 1.5000 -vt 0.3723 0.9110 0.5000 -vt 0.3723 0.9110 1.5000 -vt 0.3709 0.9114 0.5000 -vt 0.3709 0.9114 1.5000 -vt 0.3696 0.9116 0.5000 -vt 0.3696 0.9116 1.5000 -vt 0.3689 0.9116 0.5000 -vt 0.3689 0.9116 1.5000 -vt 0.3682 0.9116 0.5000 -vt 0.3682 0.9116 1.5000 -vt 0.3676 0.9114 0.5000 -vt 0.3676 0.9114 1.5000 -vt 0.3670 0.9113 0.5000 -vt 0.3670 0.9113 1.5000 -vt 0.3663 0.9111 0.5000 -vt 0.3663 0.9111 1.5000 -vt 0.3657 0.9108 0.5000 -vt 0.3657 0.9108 1.5000 -vt 0.3651 0.9104 0.5000 -vt 0.3651 0.9104 1.5000 -vt 0.3645 0.9100 0.5000 -vt 0.3645 0.9100 1.5000 -vt 0.3639 0.9096 0.5000 -vt 0.3639 0.9096 1.5000 -vt 0.3633 0.9091 0.5000 -vt 0.3633 0.9091 1.5000 -vt 0.3628 0.9085 0.5000 -vt 0.3628 0.9085 1.5000 -vt 0.3622 0.9079 0.5000 -vt 0.3622 0.9079 1.5000 -vt 0.3617 0.9073 0.5000 -vt 0.3617 0.9073 1.5000 -vt 0.3612 0.9065 0.5000 -vt 0.3612 0.9065 1.5000 -vt 0.3607 0.9058 0.5000 -vt 0.3607 0.9058 1.5000 -vt 0.3601 0.9049 0.5000 -vt 0.3601 0.9049 1.5000 -vt 0.3597 0.9041 0.5000 -vt 0.3597 0.9041 1.5000 -vt 0.3592 0.9031 0.5000 -vt 0.3592 0.9031 1.5000 -vt 0.3587 0.9021 0.5000 -vt 0.3587 0.9021 1.5000 -vt 0.3583 0.9011 0.5000 -vt 0.3583 0.9011 1.5000 -vt 0.3578 0.9000 0.5000 -vt 0.3578 0.9000 1.5000 -vt 0.3574 0.8989 0.5000 -vt 0.3574 0.8989 1.5000 -vt 0.3570 0.8977 0.5000 -vt 0.3570 0.8977 1.5000 -vt 0.3566 0.8965 0.5000 -vt 0.3566 0.8965 1.5000 -vt 0.3562 0.8952 0.5000 -vt 0.3562 0.8952 1.5000 -vt 0.3559 0.8938 0.5000 -vt 0.3559 0.8938 1.5000 -vt 0.3555 0.8925 0.5000 -vt 0.3555 0.8925 1.5000 -vt 0.3552 0.8910 0.5000 -vt 0.3552 0.8910 1.5000 -vt 0.3546 0.8880 0.5000 -vt 0.3546 0.8880 1.5000 -vt 0.3540 0.8848 0.5000 -vt 0.3540 0.8848 1.5000 -vt 0.3535 0.8814 0.5000 -vt 0.3535 0.8814 1.5000 -vt 0.3531 0.8778 0.5000 -vt 0.3531 0.8778 1.5000 -vt 0.3528 0.8741 0.5000 -vt 0.3528 0.8741 1.5000 -vt 0.3525 0.8701 0.5000 -vt 0.3525 0.8701 1.5000 -vt 0.3523 0.8660 0.5000 -vt 0.3523 0.8660 1.5000 -vt 0.3522 0.8617 0.5000 -vt 0.3522 0.8617 1.5000 -vt 0.3522 0.8573 0.5000 -vt 0.3522 0.8573 1.5000 -vt 0.3522 0.1538 0.5000 -vt 0.3522 0.1538 1.5000 -vt 0.3522 0.1493 0.5000 -vt 0.3522 0.1493 1.5000 -vt 0.3523 0.1450 0.5000 -vt 0.3523 0.1450 1.5000 -vt 0.3525 0.1409 0.5000 -vt 0.3525 0.1409 1.5000 -vt 0.3528 0.1370 0.5000 -vt 0.3528 0.1370 1.5000 -vt 0.3531 0.1332 0.5000 -vt 0.3531 0.1332 1.5000 -vt 0.3535 0.1296 0.5000 -vt 0.3535 0.1296 1.5000 -vt 0.3540 0.1262 0.5000 -vt 0.3540 0.1262 1.5000 -vt 0.3546 0.1230 0.5000 -vt 0.3546 0.1230 1.5000 -vt 0.3552 0.1200 0.5000 -vt 0.3552 0.1200 1.5000 -vt 0.3555 0.1186 0.5000 -vt 0.3555 0.1186 1.5000 -vt 0.3559 0.1172 0.5000 -vt 0.3559 0.1172 1.5000 -vt 0.3562 0.1159 0.5000 -vt 0.3562 0.1159 1.5000 -vt 0.3566 0.1146 0.5000 -vt 0.3566 0.1146 1.5000 -vt 0.3570 0.1133 0.5000 -vt 0.3570 0.1133 1.5000 -vt 0.3574 0.1122 0.5000 -vt 0.3574 0.1122 1.5000 -vt 0.3578 0.1110 0.5000 -vt 0.3578 0.1110 1.5000 -vt 0.3583 0.1099 0.5000 -vt 0.3583 0.1099 1.5000 -vt 0.3587 0.1089 0.5000 -vt 0.3587 0.1089 1.5000 -vt 0.3592 0.1079 0.5000 -vt 0.3592 0.1079 1.5000 -vt 0.3597 0.1070 0.5000 -vt 0.3597 0.1070 1.5000 -vt 0.3601 0.1061 0.5000 -vt 0.3601 0.1061 1.5000 -vt 0.3607 0.1053 0.5000 -vt 0.3607 0.1053 1.5000 -vt 0.3612 0.1045 0.5000 -vt 0.3612 0.1045 1.5000 -vt 0.3617 0.1038 0.5000 -vt 0.3617 0.1038 1.5000 -vt 0.3622 0.1031 0.5000 -vt 0.3622 0.1031 1.5000 -vt 0.3628 0.1025 0.5000 -vt 0.3628 0.1025 1.5000 -vt 0.3633 0.1020 0.5000 -vt 0.3633 0.1020 1.5000 -vt 0.3639 0.1015 0.5000 -vt 0.3639 0.1015 1.5000 -vt 0.3645 0.1010 0.5000 -vt 0.3645 0.1010 1.5000 -vt 0.3651 0.1006 0.5000 -vt 0.3651 0.1006 1.5000 -vt 0.3657 0.1003 0.5000 -vt 0.3657 0.1003 1.5000 -vt 0.3663 0.1000 0.5000 -vt 0.3663 0.1000 1.5000 -vt 0.3670 0.0998 0.5000 -vt 0.3670 0.0998 1.5000 -vt 0.3676 0.0996 0.5000 -vt 0.3676 0.0996 1.5000 -vt 0.3682 0.0995 0.5000 -vt 0.3682 0.0995 1.5000 -vt 0.3689 0.0994 0.5000 -vt 0.3689 0.0994 1.5000 -vt 0.3696 0.0994 0.5000 -vt 0.3696 0.0994 1.5000 -vt 0.3709 0.0996 0.5000 -vt 0.3709 0.0996 1.5000 -vt 0.3723 0.1001 0.5000 -vt 0.3723 0.1001 1.5000 -vt 0.3738 0.1007 0.5000 -vt 0.3738 0.1007 1.5000 -vt 0.3752 0.1016 0.5000 -vt 0.3752 0.1016 1.5000 -vt 0.3767 0.1028 0.5000 -vt 0.3767 0.1028 1.5000 -vt 0.3782 0.1041 0.5000 -vt 0.3782 0.1041 1.5000 -vt 0.3797 0.1058 0.5000 -vt 0.3797 0.1058 1.5000 -vt 0.3813 0.1077 0.5000 -vt 0.3813 0.1077 1.5000 -vt 0.3829 0.1098 0.5000 -vt 0.3829 0.1098 1.5000 -vt 0.6286 0.4616 0.5000 -vt 0.6286 0.4616 1.5000 -vt 0.6302 0.4639 0.5000 -vt 0.6302 0.4639 1.5000 -vt 0.6316 0.4663 0.5000 -vt 0.6316 0.4663 1.5000 -vt 0.6329 0.4688 0.5000 -vt 0.6329 0.4688 1.5000 -vt 0.6342 0.4713 0.5000 -vt 0.6342 0.4713 1.5000 -vt 0.6353 0.4739 0.5000 -vt 0.6353 0.4739 1.5000 -vt 0.6364 0.4766 0.5000 -vt 0.6364 0.4766 1.5000 -vt 0.6081 0.5055 1.5000 -vt 0.3778 0.1758 1.5000 -vt 0.3778 0.8353 1.5000 -vt 0.6081 0.5055 0.8333 -vt 0.3778 0.8353 0.8333 -vt 0.3778 0.1758 0.8333 -# 288 texture coords - -g outter_tri -usemtl red -s off -f 4749/1/2700 4750/2/2700 4751/3/2700 4752/4/2700 -f 4750/2/2701 4753/5/2701 4754/6/2701 4751/3/2701 -f 4753/5/2702 4755/7/2702 4756/8/2702 4754/6/2702 -f 4755/7/2703 4757/9/2703 4758/10/2703 4756/8/2703 -f 4757/9/2704 4759/11/2704 4760/12/2704 4758/10/2704 -f 4759/11/2705 4761/13/2705 4762/14/2705 4760/12/2705 -f 4761/13/2706 4763/15/2706 4764/16/2706 4762/14/2706 -f 4763/15/2707 4765/17/2707 4766/18/2707 4764/16/2707 -f 4765/17/2708 4767/19/2708 4768/20/2708 4766/18/2708 -f 4767/19/2709 4769/21/2709 4770/22/2709 4768/20/2709 -f 4769/21/2710 4771/23/2710 4772/24/2710 4770/22/2710 -f 4771/23/2711 4773/25/2711 4774/26/2711 4772/24/2711 -f 4773/25/2712 4775/27/2712 4776/28/2712 4774/26/2712 -f 4775/27/2713 4777/29/2713 4778/30/2713 4776/28/2713 -f 4777/29/2714 4779/31/2714 4780/32/2714 4778/30/2714 -f 4779/31/2715 4781/33/2715 4782/34/2715 4780/32/2715 -f 4781/33/2716 4783/35/2716 4784/36/2716 4782/34/2716 -f 4783/35/2717 4785/37/2717 4786/38/2717 4784/36/2717 -f 4785/37/2718 4787/39/2718 4788/40/2718 4786/38/2718 -f 4787/39/2719 4789/41/2719 4790/42/2719 4788/40/2719 -f 4789/41/2720 4791/43/2720 4792/44/2720 4790/42/2720 -f 4791/43/2721 4793/45/2721 4794/46/2721 4792/44/2721 -f 4793/45/2722 4795/47/2722 4796/48/2722 4794/46/2722 -f 4795/47/2723 4797/49/2723 4798/50/2723 4796/48/2723 -f 4797/49/2724 4799/51/2724 4800/52/2724 4798/50/2724 -f 4799/51/2725 4801/53/2725 4802/54/2725 4800/52/2725 -f 4801/53/2726 4803/55/2726 4804/56/2726 4802/54/2726 -f 4803/55/2727 4805/57/2727 4806/58/2727 4804/56/2727 -f 4805/57/2728 4807/59/2728 4808/60/2728 4806/58/2728 -f 4807/59/2729 4809/61/2729 4810/62/2729 4808/60/2729 -f 4809/61/2730 4811/63/2730 4812/64/2730 4810/62/2730 -f 4811/63/2731 4813/65/2731 4814/66/2731 4812/64/2731 -f 4813/65/2732 4815/67/2732 4816/68/2732 4814/66/2732 -f 4815/67/2733 4817/69/2733 4818/70/2733 4816/68/2733 -f 4817/69/2734 4819/71/2734 4820/72/2734 4818/70/2734 -f 4819/71/2735 4821/73/2735 4822/74/2735 4820/72/2735 -f 4821/73/2736 4823/75/2736 4824/76/2736 4822/74/2736 -f 4823/75/2737 4825/77/2737 4826/78/2737 4824/76/2737 -f 4825/77/2738 4827/79/2738 4828/80/2738 4826/78/2738 -f 4827/79/2739 4829/81/2739 4830/82/2739 4828/80/2739 -f 4829/81/2740 4831/83/2740 4832/84/2740 4830/82/2740 -f 4831/83/2741 4833/85/2741 4834/86/2741 4832/84/2741 -f 4833/85/2742 4835/87/2742 4836/88/2742 4834/86/2742 -f 4835/87/2743 4837/89/2743 4838/90/2743 4836/88/2743 -f 4837/89/2744 4839/91/2744 4840/92/2744 4838/90/2744 -f 4839/91/2745 4841/93/2745 4842/94/2745 4840/92/2745 -f 4841/93/2746 4843/95/2746 4844/96/2746 4842/94/2746 -f 4843/95/2747 4845/97/2747 4846/98/2747 4844/96/2747 -f 4845/97/2748 4847/99/2748 4848/100/2748 4846/98/2748 -f 4847/99/2749 4849/101/2749 4850/102/2749 4848/100/2749 -f 4849/101/2750 4851/103/2750 4852/104/2750 4850/102/2750 -f 4851/103/2751 4853/105/2751 4854/106/2751 4852/104/2751 -f 4853/105/2752 4855/107/2752 4856/108/2752 4854/106/2752 -f 4855/107/2753 4857/109/2753 4858/110/2753 4856/108/2753 -f 4857/109/2754 4859/111/2754 4860/112/2754 4858/110/2754 -f 4859/111/2755 4861/113/2755 4862/114/2755 4860/112/2755 -f 4861/113/2756 4863/115/2756 4864/116/2756 4862/114/2756 -f 4863/115/2757 4865/117/2757 4866/118/2757 4864/116/2757 -f 4865/117/2758 4867/119/2758 4868/120/2758 4866/118/2758 -f 4867/119/2759 4869/121/2759 4870/122/2759 4868/120/2759 -f 4869/121/2760 4871/123/2760 4872/124/2760 4870/122/2760 -f 4871/123/2761 4873/125/2761 4874/126/2761 4872/124/2761 -f 4873/125/2762 4875/127/2762 4876/128/2762 4874/126/2762 -f 4875/127/2763 4877/129/2763 4878/130/2763 4876/128/2763 -f 4877/129/2764 4879/131/2764 4880/132/2764 4878/130/2764 -f 4879/131/2765 4881/133/2765 4882/134/2765 4880/132/2765 -f 4881/133/2766 4883/135/2766 4884/136/2766 4882/134/2766 -f 4883/135/2767 4885/137/2767 4886/138/2767 4884/136/2767 -f 4885/137/2768 4887/139/2768 4888/140/2768 4886/138/2768 -f 4887/139/2769 4889/141/2769 4890/142/2769 4888/140/2769 -f 4889/141/2770 4891/143/2770 4892/144/2770 4890/142/2770 -f 4891/143/2771 4893/145/2771 4894/146/2771 4892/144/2771 -f 4893/145/2772 4895/147/2772 4896/148/2772 4894/146/2772 -f 4895/147/2773 4897/149/2773 4898/150/2773 4896/148/2773 -f 4897/149/2774 4899/151/2774 4900/152/2774 4898/150/2774 -f 4899/151/2775 4901/153/2775 4902/154/2775 4900/152/2775 -f 4901/153/2776 4903/155/2776 4904/156/2776 4902/154/2776 -f 4903/155/2777 4905/157/2777 4906/158/2777 4904/156/2777 -f 4905/157/2778 4907/159/2778 4908/160/2778 4906/158/2778 -f 4907/159/2779 4909/161/2779 4910/162/2779 4908/160/2779 -f 4909/161/2780 4911/163/2780 4912/164/2780 4910/162/2780 -f 4911/163/2781 4913/165/2781 4914/166/2781 4912/164/2781 -f 4913/165/2782 4915/167/2782 4916/168/2782 4914/166/2782 -f 4915/167/2783 4917/169/2783 4918/170/2783 4916/168/2783 -f 4917/169/2784 4919/171/2784 4920/172/2784 4918/170/2784 -f 4919/171/2785 4921/173/2785 4922/174/2785 4920/172/2785 -f 4921/173/2786 4923/175/2786 4924/176/2786 4922/174/2786 -f 4923/175/2787 4925/177/2787 4926/178/2787 4924/176/2787 -f 4925/177/2788 4927/179/2788 4928/180/2788 4926/178/2788 -f 4927/179/2789 4929/181/2789 4930/182/2789 4928/180/2789 -f 4929/181/2790 4931/183/2790 4932/184/2790 4930/182/2790 -f 4931/183/2791 4933/185/2791 4934/186/2791 4932/184/2791 -f 4933/185/2792 4935/187/2792 4936/188/2792 4934/186/2792 -f 4935/187/2793 4937/189/2793 4938/190/2793 4936/188/2793 -f 4937/189/2794 4939/191/2794 4940/192/2794 4938/190/2794 -f 4939/191/2795 4941/193/2795 4942/194/2795 4940/192/2795 -f 4941/193/2796 4943/195/2796 4944/196/2796 4942/194/2796 -f 4943/195/2797 4945/197/2797 4946/198/2797 4944/196/2797 -f 4945/197/2798 4947/199/2798 4948/200/2798 4946/198/2798 -f 4947/199/2799 4949/201/2799 4950/202/2799 4948/200/2799 -f 4949/201/2800 4951/203/2800 4952/204/2800 4950/202/2800 -f 4951/203/2801 4953/205/2801 4954/206/2801 4952/204/2801 -f 4953/205/2802 4955/207/2802 4956/208/2802 4954/206/2802 -f 4955/207/2803 4957/209/2803 4958/210/2803 4956/208/2803 -f 4957/209/2804 4959/211/2804 4960/212/2804 4958/210/2804 -f 4959/211/2805 4961/213/2805 4962/214/2805 4960/212/2805 -f 4961/213/2806 4963/215/2806 4964/216/2806 4962/214/2806 -f 4963/215/2807 4965/217/2807 4966/218/2807 4964/216/2807 -f 4965/217/2808 4967/219/2808 4968/220/2808 4966/218/2808 -f 4967/219/2809 4969/221/2809 4970/222/2809 4968/220/2809 -f 4969/221/2810 4971/223/2810 4972/224/2810 4970/222/2810 -f 4971/223/2811 4973/225/2811 4974/226/2811 4972/224/2811 -f 4973/225/2812 4975/227/2812 4976/228/2812 4974/226/2812 -f 4975/227/2813 4977/229/2813 4978/230/2813 4976/228/2813 -f 4977/229/2814 4979/231/2814 4980/232/2814 4978/230/2814 -f 4979/231/2815 4981/233/2815 4982/234/2815 4980/232/2815 -f 4981/233/2816 4983/235/2816 4984/236/2816 4982/234/2816 -f 4983/235/2817 4985/237/2817 4986/238/2817 4984/236/2817 -f 4985/237/2818 4987/239/2818 4988/240/2818 4986/238/2818 -f 4987/239/2819 4989/241/2819 4990/242/2819 4988/240/2819 -f 4989/241/2820 4991/243/2820 4992/244/2820 4990/242/2820 -f 4991/243/2821 4993/245/2821 4994/246/2821 4992/244/2821 -f 4993/245/2822 4995/247/2822 4996/248/2822 4994/246/2822 -f 4995/247/2823 4997/249/2823 4998/250/2823 4996/248/2823 -f 4997/249/2824 4999/251/2824 5000/252/2824 4998/250/2824 -f 4999/251/2825 5001/253/2825 5002/254/2825 5000/252/2825 -f 5001/253/2826 5003/255/2826 5004/256/2826 5002/254/2826 -f 5003/255/2827 5005/257/2827 5006/258/2827 5004/256/2827 -f 5005/257/2828 5007/259/2828 5008/260/2828 5006/258/2828 -f 5007/259/2829 5009/261/2829 5010/262/2829 5008/260/2829 -f 5009/261/2830 5011/263/2830 5012/264/2830 5010/262/2830 -f 5011/263/2831 5013/265/2831 5014/266/2831 5012/264/2831 -f 5013/265/2832 5015/267/2832 5016/268/2832 5014/266/2832 -f 5015/267/2833 5017/269/2833 5018/270/2833 5016/268/2833 -f 5017/269/2834 5019/271/2834 5020/272/2834 5018/270/2834 -f 5019/271/2835 5021/273/2835 5022/274/2835 5020/272/2835 -f 5021/273/2836 5023/275/2836 5024/276/2836 5022/274/2836 -f 5023/275/2837 5025/277/2837 5026/278/2837 5024/276/2837 -f 5025/277/2838 5027/279/2838 5028/280/2838 5026/278/2838 -f 5027/279/2839 5029/281/2839 5030/282/2839 5028/280/2839 -f 5029/281/2840 4749/1/2840 4752/4/2840 5030/282/2840 -f 4749/1/2841 5029/281/2841 5027/279/2841 5023/275/2841 -f 5027/279/2841 5025/277/2841 5023/275/2841 -f 5023/275/2842 5021/273/2842 5019/271/2842 5015/267/2842 -f 5019/271/2842 5017/269/2842 5015/267/2842 -f 4749/1/2841 5023/275/2841 5015/267/2841 4999/251/2841 -f 5015/267/2841 5013/265/2841 5011/263/2841 5007/259/2841 -f 5011/263/2841 5009/261/2841 5007/259/2841 -f 5007/259/2841 5005/257/2841 5003/255/2841 4999/251/2841 -f 5003/255/2841 5001/253/2841 4999/251/2841 -f 5015/267/2841 5007/259/2841 4999/251/2841 -f 4749/1/2841 4999/251/2841 4997/249/2841 4995/247/2841 -f 4749/1/2841 4995/247/2841 4993/245/2841 4991/243/2841 -f 4749/1/2841 4991/243/2841 4989/241/2841 4987/239/2841 -f 4749/1/2841 4987/239/2841 4985/237/2841 4983/235/2841 -f 4749/1/2841 4983/235/2841 4981/233/2841 4979/231/2841 -f 4749/1/2841 4979/231/2841 4977/229/2841 4975/227/2841 -f 4749/1/2843 4975/227/2843 4973/225/2843 4785/37/2843 -f 4941/193/2841 4939/191/2841 4937/189/2841 4943/195/2841 -f 4945/197/2841 4943/195/2841 4937/189/2841 4947/199/2841 -f 4949/201/2841 4947/199/2841 4937/189/2841 4951/203/2841 -f 4953/205/2844 4951/203/2844 4937/189/2844 4955/207/2844 -f 4957/209/2843 4955/207/2843 4937/189/2843 4959/211/2843 -f 4961/213/2843 4959/211/2843 4937/189/2843 4963/215/2843 -f 4965/217/2843 4963/215/2843 4937/189/2843 4967/219/2843 -f 4969/221/2843 4967/219/2843 4937/189/2843 4971/223/2843 -f 4973/225/2842 4971/223/2842 4937/189/2842 4879/131/2842 -f 4937/189/2841 4935/187/2841 4933/185/2841 4929/181/2841 -f 4933/185/2841 4931/183/2841 4929/181/2841 -f 4929/181/2843 4927/179/2843 4925/177/2843 4921/173/2843 -f 4925/177/2843 4923/175/2843 4921/173/2843 -f 4937/189/2842 4929/181/2842 4921/173/2842 4905/157/2842 -f 4921/173/2841 4919/171/2841 4917/169/2841 4913/165/2841 -f 4917/169/2841 4915/167/2841 4913/165/2841 -f 4913/165/2841 4911/163/2841 4909/161/2841 4905/157/2841 -f 4909/161/2841 4907/159/2841 4905/157/2841 -f 4921/173/2841 4913/165/2841 4905/157/2841 -f 4937/189/2842 4905/157/2842 4903/155/2842 4901/153/2842 -f 4937/189/2842 4901/153/2842 4899/151/2842 4897/149/2842 -f 4937/189/2842 4897/149/2842 4895/147/2842 4893/145/2842 -f 4937/189/2842 4893/145/2842 4891/143/2842 4889/141/2842 -f 4937/189/2843 4889/141/2843 4887/139/2843 4885/137/2843 -f 4937/189/2843 4885/137/2843 4883/135/2843 4881/133/2843 -f 4937/189/2843 4881/133/2843 4879/131/2843 -f 4847/99/2841 4845/97/2841 4843/95/2841 4849/101/2841 -f 4851/103/2841 4849/101/2841 4843/95/2841 4853/105/2841 -f 4855/107/2841 4853/105/2841 4843/95/2841 4857/109/2841 -f 4859/111/2841 4857/109/2841 4843/95/2841 4861/113/2841 -f 4863/115/2841 4861/113/2841 4843/95/2841 4865/117/2841 -f 4867/119/2841 4865/117/2841 4843/95/2841 4869/121/2841 -f 4871/123/2841 4869/121/2841 4843/95/2841 4873/125/2841 -f 4875/127/2841 4873/125/2841 4843/95/2841 4877/129/2841 -f 4879/131/2843 4877/129/2843 4843/95/2843 4785/37/2843 -f 4843/95/2841 4841/93/2841 4839/91/2841 4835/87/2841 -f 4839/91/2841 4837/89/2841 4835/87/2841 -f 4835/87/2843 4833/85/2843 4831/83/2843 4827/79/2843 -f 4831/83/2843 4829/81/2843 4827/79/2843 -f 4843/95/2844 4835/87/2844 4827/79/2844 4811/63/2844 -f 4827/79/2841 4825/77/2841 4823/75/2841 4819/71/2841 -f 4823/75/2841 4821/73/2841 4819/71/2841 -f 4819/71/2841 4817/69/2841 4815/67/2841 4811/63/2841 -f 4815/67/2841 4813/65/2841 4811/63/2841 -f 4827/79/2841 4819/71/2841 4811/63/2841 -f 4843/95/2844 4811/63/2844 4809/61/2844 4807/59/2844 -f 4843/95/2844 4807/59/2844 4805/57/2844 4803/55/2844 -f 4843/95/2844 4803/55/2844 4801/53/2844 4799/51/2844 -f 4843/95/2844 4799/51/2844 4797/49/2844 4795/47/2844 -f 4843/95/2844 4795/47/2844 4793/45/2844 4791/43/2844 -f 4843/95/2843 4791/43/2843 4789/41/2843 4787/39/2843 -f 4843/95/2844 4787/39/2844 4785/37/2844 -f 4973/225/2842 4879/131/2842 4785/37/2842 -f 4749/1/2841 4785/37/2841 4783/35/2841 4781/33/2841 -f 4749/1/2841 4781/33/2841 4779/31/2841 4777/29/2841 -f 4749/1/2841 4777/29/2841 4775/27/2841 4773/25/2841 -f 4749/1/2841 4773/25/2841 4771/23/2841 4769/21/2841 -f 4749/1/2841 4769/21/2841 4767/19/2841 4765/17/2841 -f 4749/1/2841 4765/17/2841 4763/15/2841 4761/13/2841 -f 4749/1/2841 4761/13/2841 4759/11/2841 4757/9/2841 -f 4749/1/2841 4757/9/2841 4755/7/2841 4753/5/2841 -f 4749/1/2841 4753/5/2841 4750/2/2841 -s 1 -f 5031/283/2845 5032/284/2846 5008/260/2846 5010/262/2847 -f 5010/262/2847 5012/264/2846 5014/266/2847 5031/283/2845 -f 5014/266/2847 5016/268/2848 5018/270/2846 5031/283/2845 -f 5018/270/2846 5020/272/2848 5022/274/2846 5031/283/2845 -f 5031/283/2845 5022/274/2846 5024/276/2847 5026/278/2847 -f 5033/285/2845 5031/283/2845 5026/278/2847 5030/282/2845 -f 5026/278/2847 5028/280/2846 5030/282/2845 -f 5030/282/2845 4752/4/2846 4751/3/2848 4756/8/2847 -f 4751/3/2848 4754/6/2847 4756/8/2847 -f 4756/8/2847 4758/10/2846 4760/12/2846 4764/16/2847 -f 4760/12/2846 4762/14/2846 4764/16/2847 -f 5030/282/2845 4756/8/2847 4764/16/2847 4780/32/2845 -f 4764/16/2847 4766/18/2846 4768/20/2846 4772/24/2846 -f 4768/20/2846 4770/22/2846 4772/24/2846 -f 4772/24/2846 4774/26/2846 4776/28/2846 4780/32/2845 -f 4776/28/2846 4778/30/2846 4780/32/2845 -f 4764/16/2847 4772/24/2846 4780/32/2845 -f 4780/32/2845 4782/34/2846 4784/36/2846 4788/40/2846 -f 4784/36/2846 4786/38/2846 4788/40/2846 -f 4788/40/2846 4790/42/2846 4792/44/2846 4796/48/2846 -f 4792/44/2846 4794/46/2846 4796/48/2846 -f 4780/32/2845 4788/40/2846 4796/48/2846 4812/64/2845 -f 4796/48/2846 4798/50/2846 4800/52/2846 4804/56/2846 -f 4800/52/2846 4802/54/2846 4804/56/2846 -f 4804/56/2846 4806/58/2846 4808/60/2846 4812/64/2845 -f 4808/60/2846 4810/62/2846 4812/64/2845 -f 4796/48/2846 4804/56/2846 4812/64/2845 -f 4812/64/2845 4814/66/2846 4816/68/2846 4820/72/2845 -f 4816/68/2846 4818/70/2846 4820/72/2845 -f 4820/72/2845 4822/74/2846 4824/76/2845 4828/80/2846 -f 4824/76/2845 4826/78/2845 4828/80/2846 -f 4812/64/2845 4820/72/2845 4828/80/2846 4844/96/2846 -f 4828/80/2846 4830/82/2846 4832/84/2846 4836/88/2846 -f 4832/84/2846 4834/86/2846 4836/88/2846 -f 4836/88/2846 4838/90/2846 4840/92/2846 4844/96/2846 -f 4840/92/2846 4842/94/2846 4844/96/2846 -f 4828/80/2846 4836/88/2846 4844/96/2846 -f 4780/32/2845 4812/64/2845 4844/96/2846 4908/160/2848 -f 4844/96/2846 4846/98/2846 4848/100/2846 4852/104/2846 -f 4848/100/2846 4850/102/2846 4852/104/2846 -f 4852/104/2846 4854/106/2846 4856/108/2846 4860/112/2846 -f 4856/108/2846 4858/110/2846 4860/112/2846 -f 4844/96/2846 4852/104/2846 4860/112/2846 4876/128/2847 -f 4860/112/2846 4862/114/2846 4864/116/2846 4868/120/2846 -f 4864/116/2846 4866/118/2846 4868/120/2846 -f 4868/120/2846 4870/122/2846 4872/124/2846 4876/128/2847 -f 4872/124/2846 4874/126/2846 4876/128/2847 -f 4860/112/2846 4868/120/2846 4876/128/2847 -f 4876/128/2847 4878/130/2846 4880/132/2846 4884/136/2847 -f 4880/132/2846 4882/134/2846 4884/136/2847 -f 4884/136/2847 4886/138/2849 4888/140/2848 4892/144/2848 -f 4888/140/2848 4890/142/2846 4892/144/2848 -f 4876/128/2847 4884/136/2847 4892/144/2848 4908/160/2848 -f 4892/144/2848 4894/146/2846 4896/148/2846 4900/152/2846 -f 4896/148/2846 4898/150/2846 4900/152/2846 -f 4900/152/2846 4902/154/2846 4904/156/2846 4908/160/2848 -f 4904/156/2846 4906/158/2846 4908/160/2848 -f 4892/144/2848 4900/152/2846 4908/160/2848 -f 4844/96/2846 4876/128/2847 4908/160/2848 -f 5030/282/2845 4780/32/2845 4908/160/2848 5033/285/2845 -f 4908/160/2848 4910/162/2846 4912/164/2848 5033/285/2845 -f 5033/285/2845 4912/164/2848 4914/166/2848 4916/168/2848 -f 4916/168/2848 4918/170/2846 4920/172/2847 4924/176/2847 -f 4920/172/2847 4922/174/2847 4924/176/2847 -f 4924/176/2847 4926/178/2846 4928/180/2846 4932/184/2846 -f 4928/180/2846 4930/182/2846 4932/184/2846 -f 4916/168/2848 4924/176/2847 4932/184/2846 4948/200/2845 -f 4932/184/2846 4934/186/2846 4936/188/2845 4940/192/2845 -f 4936/188/2845 4938/190/2846 4940/192/2845 -f 4940/192/2845 4942/194/2846 4944/196/2846 4948/200/2845 -f 4944/196/2846 4946/198/2846 4948/200/2845 -f 4932/184/2846 4940/192/2845 4948/200/2845 -f 4948/200/2845 4950/202/2846 4952/204/2846 4956/208/2845 -f 4952/204/2846 4954/206/2846 4956/208/2845 -f 4956/208/2845 4958/210/2850 4960/212/2846 4964/216/2846 -f 4960/212/2846 4962/214/2846 4964/216/2846 -f 4948/200/2845 4956/208/2845 4964/216/2846 4980/232/2846 -f 4964/216/2846 4966/218/2846 4968/220/2846 4972/224/2846 -f 4968/220/2846 4970/222/2846 4972/224/2846 -f 4972/224/2846 4974/226/2846 4976/228/2846 4980/232/2846 -f 4976/228/2846 4978/230/2846 4980/232/2846 -f 4964/216/2846 4972/224/2846 4980/232/2846 -f 4980/232/2846 4982/234/2846 4984/236/2846 4988/240/2846 -f 4984/236/2846 4986/238/2846 4988/240/2846 -f 4988/240/2846 4990/242/2846 4992/244/2846 4996/248/2847 -f 4992/244/2846 4994/246/2846 4996/248/2847 -f 4980/232/2846 4988/240/2846 4996/248/2847 4948/200/2845 -f 4916/168/2848 4948/200/2845 4996/248/2847 5004/256/2846 -f 4996/248/2847 4998/250/2846 5000/252/2846 5004/256/2846 -f 5000/252/2846 5002/254/2846 5004/256/2846 -f 5004/256/2846 5006/258/2846 5008/260/2846 4916/168/2848 -f 4916/168/2848 5008/260/2846 5032/284/2846 5033/285/2845 -usemtl white -s off -f 5034/286/2846 5035/287/2846 5036/288/2846 -f 5035/287/2851 5033/285/2851 5032/284/2851 5036/288/2851 -f 5034/286/2852 5031/283/2852 5033/285/2852 5035/287/2852 -f 5036/288/2853 5032/284/2853 5031/283/2853 5034/286/2853 -# 256 polygons - 60 triangles - -# -# object exclamation -# - -v -0.7667 -0.1859 4.3666 -v 0.3784 -0.1859 2.5506 -v -0.5686 -0.1859 3.3931 -v -0.1526 -0.1859 1.2976 -v -0.3784 -0.1859 2.5525 -v 0.1526 -0.1859 1.2976 -v -0.5686 -0.3937 3.3931 -v -0.7072 -0.3937 4.0028 -v -0.3784 -0.3937 2.5525 -v 0.1526 -0.3937 1.2976 -v -0.1526 -0.3937 1.2976 -v 0.3784 -0.3937 2.5506 -v 0.5686 -0.1859 3.3970 -v -0.7350 -0.3937 4.1426 -v 0.7563 -0.3937 4.2628 -v -0.7706 -0.3937 4.4508 -v 0.7670 -0.1859 4.3633 -v 0.7132 -0.3937 4.0226 -v 0.7191 -0.3937 -0.1674 -v -0.5623 -0.3937 0.5727 -v -0.6121 -0.3937 0.5152 -v 0.7191 -0.1859 -0.1674 -v -0.5059 -0.1859 0.6271 -v -0.5623 -0.1859 0.5727 -v -0.7545 -0.3937 -0.0302 -v -0.7403 -0.3937 -0.1002 -v -0.6344 -0.1859 -0.3239 -v -0.5881 -0.1859 -0.3818 -v -0.5162 -0.3937 4.9958 -v -0.5722 -0.3937 4.9425 -v 0.3890 -0.1859 5.0831 -v 0.4517 -0.1859 5.0428 -v -0.0362 -0.1859 -0.6520 -v 0.0399 -0.1859 -0.6520 -v 0.5625 -0.3937 0.5727 -v 0.5061 -0.3937 0.6271 -v 0.2200 -0.1859 0.7893 -v 0.1138 -0.1859 0.8125 -v 0.0399 -0.3937 0.8193 -v -0.0362 -0.3937 0.8193 -v 0.0399 -0.3937 -0.6520 -v 0.1138 -0.3937 -0.6453 -v 0.6346 -0.3937 -0.3239 -v 0.5883 -0.3937 -0.3818 -v 0.6123 -0.1859 -0.3532 -v -0.3948 -0.3937 5.0831 -v -0.3298 -0.1859 5.1167 -v -0.3948 -0.1859 5.0831 -v 0.1125 -0.3937 5.1772 -v 0.0369 -0.3937 5.1839 -v -0.7403 -0.1859 -0.1002 -v -0.7403 -0.1859 0.2599 -v -0.7545 -0.1859 0.1897 -v 0.4207 -0.3937 5.0638 -v -0.7350 -0.1859 4.1426 -v -0.5162 -0.1859 4.9958 -v -0.6121 -0.3937 -0.3532 -v -0.0362 -0.3937 -0.6520 -v 0.7405 -0.3937 0.2599 -v 0.7547 -0.3937 0.1897 -v 0.7405 -0.1859 0.2599 -v 0.7191 -0.1859 0.3275 -v 0.6737 -0.1859 0.4242 -v 0.6907 -0.3937 0.3926 -v -0.5059 -0.3937 0.6271 -v -0.0362 -0.1859 0.8193 -v 0.5349 -0.1859 0.6005 -v 0.1852 -0.3937 0.7987 -v 0.1138 -0.1859 -0.6453 -v 0.5061 -0.1859 -0.4632 -v 0.5625 -0.1859 -0.4098 -v 0.5349 -0.3937 -0.4371 -v 0.1125 -0.1859 5.1772 -v 0.3567 -0.3937 5.1008 -v -0.6121 -0.1859 0.5152 -v -0.7403 -0.3937 0.2599 -v -0.5623 -0.3937 -0.4098 -v -0.5059 -0.3937 -0.4632 -v -0.5347 -0.1859 -0.4371 -v 0.7405 -0.1859 -0.1002 -v 0.7547 -0.1859 -0.0302 -v 0.7405 -0.3937 -0.1002 -v -0.7274 -0.3937 4.6997 -v -0.7142 -0.1859 4.7325 -v -0.7389 -0.1859 4.6662 -v 0.7563 -0.1859 4.5972 -v 0.7383 -0.3937 4.6662 -v 0.7563 -0.3937 4.5972 -v 0.7706 -0.1859 4.4508 -v 0.7706 -0.3937 4.4508 -v -0.0412 -0.3937 5.1839 -v 0.0369 -0.1859 5.1839 -v -0.0412 -0.1859 5.1839 -v -0.7565 -0.3937 4.5972 -v 0.6413 -0.3937 4.8567 -v 0.6620 -0.1859 4.8267 -v 0.6189 -0.1859 4.8860 -v 0.4768 -0.1859 0.6520 -v -0.1831 -0.1859 0.7987 -v -0.2527 -0.1859 0.7781 -v -0.1831 -0.3937 0.7987 -v -0.7545 -0.3937 0.1897 -v 0.7547 -0.3937 -0.0302 -v -0.7545 -0.1859 -0.0302 -v -0.4157 -0.1859 -0.5315 -v -0.3524 -0.1859 -0.5686 -v -0.3844 -0.3937 -0.5509 -v -0.1831 -0.3937 -0.6318 -v -0.2527 -0.3937 -0.6116 -v -0.1831 -0.1859 -0.6318 -v -0.1912 -0.3937 5.1638 -v -0.2619 -0.3937 5.1436 -v -0.1912 -0.1859 5.1638 -v -0.3844 -0.3937 0.7163 -v -0.3198 -0.3937 0.7507 -v -0.3844 -0.1859 0.7163 -v 0.4162 -0.3937 -0.5315 -v 0.3532 -0.3937 -0.5686 -v 0.3850 -0.1859 -0.5509 -v 0.3208 -0.3937 0.7507 -v 0.2542 -0.3937 0.7781 -v 0.2878 -0.1859 0.7653 -v -0.6216 -0.1859 4.8860 -v -0.5722 -0.1859 4.9425 -v -0.6216 -0.3937 4.8860 -v 0.5946 -0.3937 4.9146 -v 0.2542 -0.1859 -0.6116 -v 0.3208 -0.1859 -0.5846 -v 0.2878 -0.3937 -0.5989 -v 0.7547 -0.1859 0.1897 -v -0.7667 -0.3937 4.3666 -v 0.7266 -0.1859 4.6997 -v -0.2866 -0.1859 -0.5989 -v -0.7671 -0.3937 4.5254 -v -0.7565 -0.1859 4.5972 -v -0.7671 -0.1859 4.5254 -v -0.6904 -0.3937 -0.2320 -v -0.7189 -0.3937 -0.1674 -v -0.7189 -0.1859 -0.1674 -v 0.6907 -0.1859 -0.2320 -v -0.6904 -0.1859 0.3926 -v -0.7189 -0.1859 0.3275 -v -0.6904 -0.3937 0.3926 -v 0.7191 -0.3937 0.3275 -v 0.2559 -0.1859 5.1436 -v 0.3238 -0.1859 5.1167 -v 0.2902 -0.3937 5.1310 -v -0.6548 -0.3937 0.4552 -v -0.1109 -0.1859 0.8125 -v -0.1109 -0.3937 0.8125 -v -0.4569 -0.3937 5.0428 -v -0.1176 -0.1859 5.1772 -v -0.4464 -0.1859 0.6751 -v -0.4464 -0.3937 -0.5104 -v -0.6992 -0.3937 4.7646 -v -0.6735 -0.1859 -0.2633 -v 0.6737 -0.3937 -0.2633 -v 0.7132 -0.1859 4.0226 -v 0.7563 -0.1859 4.2628 -v 0.1855 -0.3937 5.1638 -v 0.1852 -0.3937 -0.6318 -v 0.6979 -0.1859 4.7646 -v 0.6808 -0.3937 4.7960 -v 0.7132 -0.3937 4.7325 -v 0.6346 -0.1859 0.4855 -v 0.5883 -0.1859 0.5443 -v 0.6123 -0.3937 0.5152 -v 0.7618 -0.1859 0.0423 -v 0.7618 -0.1859 0.1169 -v 0.7618 -0.3937 0.0423 -v -0.7616 -0.3937 0.1169 -v -0.7616 -0.3937 0.0423 -v -0.7616 -0.1859 0.0423 -v -0.7616 -0.1859 0.1169 -v 0.7618 -0.3937 0.1169 -v 0.4468 -0.3937 0.6751 -v 0.3850 -0.3937 0.7163 -v 0.4162 -0.1859 0.6966 -v 0.4468 -0.1859 -0.5104 -v 0.5117 -0.1859 4.9958 -v 0.4820 -0.3937 5.0201 -v 0.5408 -0.3937 4.9697 -v 0.5686 -0.1859 4.9425 -v -0.4765 -0.1859 -0.4877 -v 0.4768 -0.3937 -0.4877 -v -0.6639 -0.3937 4.8267 -v 0.1138 -0.3937 0.8125 -v -0.4569 -0.1859 5.0428 -v -0.6548 -0.3937 -0.2939 -v 0.6551 -0.1859 -0.2939 -v -0.6548 -0.1859 0.4552 -v 0.6551 -0.3937 0.4552 -v -0.1109 -0.3937 -0.6453 -v -0.4464 -0.3937 0.6751 -v 0.3532 -0.1859 0.7344 -v 0.1852 -0.1859 -0.6318 -v -0.1176 -0.3937 5.1772 -v 0.1855 -0.1859 5.1638 -v -0.7706 -0.1859 4.4508 -v -0.6639 -0.1859 4.8267 -v 0.7670 -0.3937 4.5254 -v 0.7670 -0.1859 4.5254 -v -0.7189 -0.3937 0.3275 -v -0.3198 -0.1859 0.7507 -v -0.2527 -0.3937 0.7781 -v -0.3298 -0.3937 5.1167 -v -0.2619 -0.1859 5.1436 -v -0.3198 -0.3937 -0.5846 -v 0.0399 -0.1859 0.8193 -v -0.1109 -0.1859 -0.6453 -# 210 vertices - -vn 0.0000 1.0000 0.0000 -vn -0.9751 0.0000 -0.2217 -vn -0.9753 0.0000 -0.2207 -vn -0.9842 0.0000 -0.1771 -vn 0.0000 0.0000 -1.0000 -vn 0.9841 0.0000 -0.1773 -vn 0.9757 0.0000 -0.2193 -vn 0.0000 -1.0000 -0.0000 -vn 0.7813 -0.0043 -0.6241 -vn -0.4591 -0.0000 0.8884 -vn -0.9799 0.0000 -0.1996 -vn 0.9750 0.0108 -0.2218 -vn 0.5412 0.0042 0.8409 -vn -0.9761 0.0154 -0.2167 -vn -0.6897 -0.0000 0.7241 -vn -0.7813 0.0043 -0.6241 -vn 0.9800 -0.0000 0.1988 -vn 0.9052 0.0091 0.4248 -vn -0.6943 -0.0000 0.7197 -vn 0.0000 -0.0000 1.0000 -vn 0.6944 -0.0040 0.7196 -vn 0.2131 0.0087 0.9770 -vn 0.0910 0.0000 -0.9959 -vn 0.6880 0.0040 -0.7257 -vn 0.0885 -0.0000 0.9961 -vn 0.5004 -0.0043 0.8658 -vn -0.7555 -0.0000 0.6551 -vn -0.9800 -0.0000 0.1988 -vn -0.6879 -0.0041 -0.7258 -vn 0.9799 0.0000 -0.1996 -vn -0.9370 0.0046 0.3493 -vn 0.9678 -0.0000 0.2517 -vn 0.9992 0.0000 -0.0410 -vn -0.9619 -0.0091 0.2731 -vn 0.8090 0.0045 0.5878 -vn 0.6629 0.0041 0.7487 -vn -0.2836 -0.0000 0.9589 -vn -0.5055 0.0043 -0.8628 -vn -0.2789 0.0000 -0.9603 -vn -0.2741 -0.0000 0.9617 -vn -0.4695 -0.0000 0.8829 -vn 0.5074 -0.0042 -0.8617 -vn 0.3812 -0.0044 0.9245 -vn -0.7531 -0.0000 0.6579 -vn 0.7786 -0.0044 0.6275 -vn 0.3754 0.0043 -0.9269 -vn 0.9970 -0.0148 -0.0761 -vn -0.9901 0.0000 -0.1401 -vn 0.9606 0.0092 0.2777 -vn -0.3027 0.0087 -0.9531 -vn -0.9893 -0.0000 0.1458 -vn -0.9150 0.0000 -0.4034 -vn 0.9150 0.0000 -0.4034 -vn -0.9162 -0.0000 0.4007 -vn 0.9162 -0.0000 0.4007 -vn 0.3684 0.0043 0.9297 -vn -0.8692 -0.0000 0.4945 -vn -0.0915 -0.0000 0.9958 -vn -0.1869 -0.0000 0.9824 -vn -0.5442 -0.0000 0.8390 -vn -0.1797 -0.0000 0.9837 -vn -0.5533 -0.0000 0.8330 -vn -0.5463 -0.0042 -0.8376 -vn -0.9169 -0.0046 0.3990 -vn 0.3341 0.0044 0.9425 -vn -0.9038 0.0091 -0.4278 -vn 0.9038 -0.0091 -0.4278 -vn 0.9843 0.0000 -0.1765 -vn 0.2987 -0.0086 0.9543 -vn 0.3051 -0.0086 -0.9523 -vn 0.8911 -0.0046 0.4537 -vn 0.7855 0.0043 0.6188 -vn 1.0000 0.0000 0.0000 -vn -1.0000 0.0000 0.0000 -vn 0.9143 0.0046 0.4050 -vn 0.5548 -0.0042 0.8320 -vn 0.5479 0.0042 -0.8366 -vn 0.6510 -0.0041 0.7590 -vn 0.6835 0.0041 0.7300 -vn -0.6558 0.0041 -0.7550 -vn 0.6562 -0.0040 -0.7546 -vn -0.8139 -0.0000 0.5810 -vn 0.1888 -0.0000 0.9820 -vn -0.6214 -0.0000 0.7835 -vn -0.8112 -0.0044 -0.5847 -vn 0.8112 0.0044 -0.5847 -vn -0.8147 -0.0000 0.5799 -vn 0.8147 -0.0044 0.5798 -vn -0.0899 0.0000 -0.9960 -vn -0.6284 -0.0000 0.7779 -vn 0.5142 0.0043 0.8576 -vn 0.1855 0.0000 -0.9826 -vn -0.0876 -0.0000 0.9962 -vn 0.1810 -0.0000 0.9835 -vn -0.9989 0.0000 -0.0470 -vn -0.8821 0.0091 0.4709 -vn 0.9988 -0.0000 0.0481 -vn 0.9889 -0.0000 0.1484 -vn -0.9536 -0.0000 0.3011 -vn -0.3788 -0.0000 0.9255 -vn -0.3682 -0.0000 0.9297 -vn -0.3729 -0.0043 -0.9278 -vn 0.0926 -0.0000 0.9957 -vn -0.1837 0.0000 -0.9830 -vn -0.9531 0.0000 -0.3027 -vn 0.9531 0.0000 -0.3027 -vn 0.9536 -0.0000 0.3011 -vn 0.4137 -0.0043 0.9104 -vn -0.4186 0.0043 -0.9082 -vn 0.4209 -0.0043 -0.9071 -vn 0.9350 -0.0046 0.3547 -vn 0.8656 0.0046 0.5007 -vn -0.9689 -0.0000 0.2476 -vn -0.8670 -0.0045 -0.4984 -vn 0.8670 0.0045 -0.4984 -vn -0.8694 -0.0000 0.4940 -vn 0.8692 -0.0045 0.4945 -vn -0.9952 0.0000 -0.0976 -vn 0.9952 0.0000 -0.0976 -vn -0.9952 -0.0000 0.0974 -vn 0.9952 -0.0000 0.0974 -vn 0.8381 -0.0045 0.5455 -vn 0.7472 0.0043 0.6645 -vn -0.8399 0.0045 -0.5427 -vn 0.8399 -0.0045 -0.5427 -vn -0.9989 -0.0000 0.0472 -vn 0.2860 -0.0044 0.9582 -vn 0.4272 0.0044 0.9041 -vn 0.8427 0.0044 0.5384 -vn -0.7506 -0.0043 -0.6608 -vn 0.7506 0.0043 -0.6608 -vn 0.2752 -0.0000 0.9614 -vn 0.7555 -0.0042 0.6551 -vn 0.2813 0.0000 -0.9596 -vn 0.4716 -0.0043 0.8818 -vn 0.4578 0.0043 0.8890 -vn -0.4629 -0.0043 -0.8864 -vn 0.5800 -0.0042 0.8146 -vn 0.5932 0.0042 0.8051 -vn -0.5850 0.0042 -0.8110 -vn 0.4650 0.0043 -0.8853 -vn 0.5862 -0.0041 -0.8101 -vn 0.7153 -0.0043 0.6988 -vn -0.9809 0.0000 -0.1947 -vn -0.7192 0.0042 -0.6948 -vn 0.6166 0.0041 0.7873 -vn 0.7192 -0.0042 -0.6948 -vn 0.7250 0.0042 0.6888 -vn -0.6215 -0.0041 -0.7834 -vn 0.6292 -0.0041 0.7772 -vn 0.6223 0.0041 -0.7827 -vn 0.9743 0.0000 -0.2252 -vn 0.9943 0.0000 -0.1065 -# 153 vertex normals - -vt 0.3140 0.8334 0.5000 -vt 0.0876 0.5515 0.5000 -vt 0.2749 0.6823 0.5000 -vt 0.1926 0.3570 0.5000 -vt 0.2373 0.5518 0.5000 -vt 0.1323 0.3570 0.5000 -vt 0.3023 0.7770 0.5000 -vt 0.0500 0.6829 0.5000 -vt 0.3078 0.7987 0.5000 -vt 0.0129 0.8173 0.5000 -vt 0.3148 0.8465 0.5000 -vt 0.0108 0.8329 0.5000 -vt 0.0214 0.7800 0.5000 -vt 0.0203 0.1296 0.5000 -vt 0.2736 0.2445 0.5000 -vt 0.2835 0.2356 0.5000 -vt 0.2625 0.2530 0.5000 -vt 0.3116 0.1509 0.5000 -vt 0.3088 0.1401 0.5000 -vt 0.2879 0.1054 0.5000 -vt 0.2787 0.0964 0.5000 -vt 0.2645 0.9311 0.5000 -vt 0.2756 0.9228 0.5000 -vt 0.0855 0.9447 0.5000 -vt 0.0732 0.9384 0.5000 -vt 0.1696 0.0544 0.5000 -vt 0.1546 0.0544 0.5000 -vt 0.0512 0.2445 0.5000 -vt 0.0624 0.2530 0.5000 -vt 0.1190 0.2781 0.5000 -vt 0.1400 0.2817 0.5000 -vt 0.1546 0.2828 0.5000 -vt 0.1696 0.2828 0.5000 -vt 0.1400 0.0555 0.5000 -vt 0.0370 0.1054 0.5000 -vt 0.0461 0.0964 0.5000 -vt 0.0414 0.1008 0.5000 -vt 0.2405 0.9447 0.5000 -vt 0.2277 0.9499 0.5000 -vt 0.1402 0.9593 0.5000 -vt 0.1552 0.9603 0.5000 -vt 0.3088 0.1960 0.5000 -vt 0.3116 0.1851 0.5000 -vt 0.0793 0.9417 0.5000 -vt 0.2835 0.1008 0.5000 -vt 0.0161 0.1960 0.5000 -vt 0.0132 0.1851 0.5000 -vt 0.0203 0.2065 0.5000 -vt 0.0292 0.2215 0.5000 -vt 0.0259 0.2166 0.5000 -vt 0.0567 0.2488 0.5000 -vt 0.1258 0.2796 0.5000 -vt 0.0624 0.0837 0.5000 -vt 0.0512 0.0920 0.5000 -vt 0.0567 0.0878 0.5000 -vt 0.0919 0.9474 0.5000 -vt 0.2736 0.0920 0.5000 -vt 0.2625 0.0837 0.5000 -vt 0.2682 0.0878 0.5000 -vt 0.0161 0.1401 0.5000 -vt 0.0132 0.1509 0.5000 -vt 0.3063 0.8851 0.5000 -vt 0.3037 0.8902 0.5000 -vt 0.3085 0.8799 0.5000 -vt 0.0129 0.8692 0.5000 -vt 0.0165 0.8799 0.5000 -vt 0.0101 0.8465 0.5000 -vt 0.1706 0.9603 0.5000 -vt 0.3120 0.8692 0.5000 -vt 0.0357 0.9095 0.5000 -vt 0.0316 0.9048 0.5000 -vt 0.0401 0.9141 0.5000 -vt 0.0682 0.2568 0.5000 -vt 0.1986 0.2796 0.5000 -vt 0.2124 0.2764 0.5000 -vt 0.2446 0.0731 0.5000 -vt 0.2321 0.0674 0.5000 -vt 0.2385 0.0701 0.5000 -vt 0.1986 0.0576 0.5000 -vt 0.2124 0.0607 0.5000 -vt 0.2003 0.9572 0.5000 -vt 0.2142 0.9540 0.5000 -vt 0.2385 0.2668 0.5000 -vt 0.2257 0.2721 0.5000 -vt 0.0802 0.0731 0.5000 -vt 0.0926 0.0674 0.5000 -vt 0.0863 0.0701 0.5000 -vt 0.0990 0.2721 0.5000 -vt 0.1122 0.2764 0.5000 -vt 0.1056 0.2744 0.5000 -vt 0.2853 0.9141 0.5000 -vt 0.0449 0.9185 0.5000 -vt 0.1122 0.0607 0.5000 -vt 0.0990 0.0649 0.5000 -vt 0.1056 0.0627 0.5000 -vt 0.0188 0.8851 0.5000 -vt 0.2191 0.0627 0.5000 -vt 0.3141 0.8581 0.5000 -vt 0.2990 0.1196 0.5000 -vt 0.3046 0.1296 0.5000 -vt 0.0259 0.1196 0.5000 -vt 0.2990 0.2166 0.5000 -vt 0.3046 0.2065 0.5000 -vt 0.1119 0.9540 0.5000 -vt 0.0984 0.9499 0.5000 -vt 0.1051 0.9521 0.5000 -vt 0.2919 0.2263 0.5000 -vt 0.1844 0.2817 0.5000 -vt 0.2528 0.9384 0.5000 -vt 0.1857 0.9593 0.5000 -vt 0.2507 0.2604 0.5000 -vt 0.2507 0.0764 0.5000 -vt 0.3007 0.8952 0.5000 -vt 0.2956 0.1148 0.5000 -vt 0.0292 0.1148 0.5000 -vt 0.1258 0.9572 0.5000 -vt 0.1258 0.0576 0.5000 -vt 0.0245 0.8952 0.5000 -vt 0.0278 0.9001 0.5000 -vt 0.0215 0.8902 0.5000 -vt 0.0370 0.2310 0.5000 -vt 0.0461 0.2401 0.5000 -vt 0.0414 0.2356 0.5000 -vt 0.0118 0.1622 0.5000 -vt 0.0118 0.1738 0.5000 -vt 0.3130 0.1738 0.5000 -vt 0.3130 0.1622 0.5000 -vt 0.0741 0.2604 0.5000 -vt 0.0863 0.2668 0.5000 -vt 0.0802 0.2638 0.5000 -vt 0.0741 0.0764 0.5000 -vt 0.0613 0.9311 0.5000 -vt 0.0672 0.9349 0.5000 -vt 0.0555 0.9271 0.5000 -vt 0.0500 0.9228 0.5000 -vt 0.2567 0.0799 0.5000 -vt 0.0682 0.0799 0.5000 -vt 0.2937 0.9048 0.5000 -vt 0.2919 0.1100 0.5000 -vt 0.0329 0.1100 0.5000 -vt 0.0329 0.2263 0.5000 -vt 0.1844 0.0555 0.5000 -vt 0.0926 0.2696 0.5000 -vt 0.0108 0.8581 0.5000 -vt 0.2257 0.0649 0.5000 -# 145 texture coords - -g exclamation -usemtl black -s off -f 5037/289/2854 5038/290/2854 5039/291/2854 -f 5040/292/2854 5041/293/2854 5042/294/2854 -usemtl wire_000000000 -f 5042/294/2854 5041/293/2854 5038/290/2854 -f 5038/290/2854 5041/293/2854 5039/291/2854 -usemtl black -f 5039/291/2855 5043/291/2855 5044/295/2855 -usemtl wire_000000000 -f 5043/291/2856 5039/291/2856 5041/293/2856 -f 5041/293/2856 5045/293/2856 5043/291/2856 -usemtl black -f 5045/293/2857 5041/293/2857 5040/292/2857 -f 5042/294/2858 5046/294/2858 5047/292/2858 -usemtl wire_000000000 -f 5046/294/2859 5042/294/2859 5038/290/2859 -f 5038/290/2859 5048/290/2859 5046/294/2859 -usemtl black -f 5048/290/2860 5038/290/2860 5049/296/2860 -f 5047/292/2861 5046/294/2861 5048/290/2861 -f 5043/291/2861 5045/293/2861 5050/297/2861 -f 5045/293/2861 5051/298/2861 5052/299/2861 -f 5037/289/2854 5053/300/2854 5038/290/2854 -f 5045/293/2861 5047/292/2861 5051/298/2861 -f 5047/292/2861 5048/290/2861 5054/301/2861 -f 5055/302/2861 5056/303/2861 5057/304/2861 -f 5058/302/2861 5059/305/2861 5060/303/2861 -f 5055/302/2861 5061/306/2861 5062/307/2861 -f 5058/302/2861 5063/308/2861 5064/309/2861 -f 5051/298/2861 5065/310/2861 5066/311/2861 -f 5037/289/2854 5067/312/2854 5068/313/2854 -f 5058/302/2861 5069/314/2861 5070/315/2861 -f 5055/302/2861 5071/316/2861 5072/317/2861 -f 5058/302/2861 5073/318/2861 5074/319/2861 -f 5055/302/2861 5075/320/2861 5076/321/2861 -f 5055/302/2861 5077/315/2861 5078/322/2861 -f 5079/323/2862 5080/324/2862 5081/325/2862 -f 5082/326/2863 5083/327/2863 5084/326/2863 -f 5051/298/2861 5085/328/2861 5086/329/2861 -f 5062/307/2864 5061/306/2864 5087/307/2864 -f 5058/302/2861 5088/330/2861 5089/331/2861 -f 5049/296/2865 5054/301/2865 5048/290/2865 -f 5090/332/2866 5068/313/2866 5067/312/2866 -f 5044/295/2867 5091/297/2867 5039/291/2867 -f 5092/310/2868 5066/311/2868 5065/310/2868 -f 5063/308/2869 5064/309/2869 5093/333/2869 -f 5069/314/2858 5070/315/2858 5094/314/2858 -f 5095/334/2870 5096/335/2870 5097/334/2870 -f 5098/336/2871 5099/337/2871 5100/338/2871 -f 5059/305/2872 5060/303/2872 5101/305/2872 -f 5076/321/2873 5075/320/2873 5102/321/2873 -f 5072/317/2874 5071/316/2874 5103/339/2874 -f 5073/318/2875 5074/319/2875 5104/340/2875 -f 5078/322/2876 5077/315/2876 5105/322/2876 -f 5106/341/2877 5107/342/2877 5108/343/2877 -f 5109/328/2878 5086/329/2878 5085/328/2878 -f 5067/312/2879 5110/344/2879 5090/332/2879 -f 5057/304/2880 5056/303/2880 5111/304/2880 -f 5088/330/2881 5089/331/2881 5112/330/2881 -f 5055/302/2861 5113/345/2861 5114/346/2861 -f 5114/346/2882 5113/345/2882 5115/347/2882 -f 5116/348/2883 5117/349/2883 5118/348/2883 -f 5058/302/2861 5098/336/2861 5099/337/2861 -f 5119/350/2884 5120/351/2884 5121/352/2884 -f 5037/289/2854 5084/326/2854 5083/327/2854 -f 5122/353/2885 5123/354/2885 5124/353/2885 -f 5051/298/2861 5090/332/2861 5110/344/2861 -f 5037/289/2854 5125/355/2854 5053/300/2854 -f 5126/355/2886 5053/300/2886 5125/355/2886 -f 5127/356/2873 5128/329/2873 5129/356/2873 -f 5037/289/2854 5129/356/2854 5128/329/2854 -f 5121/352/2887 5130/357/2887 5119/350/2887 -f 5051/298/2861 5119/350/2861 5130/357/2861 -f 5131/358/2888 5132/359/2888 5133/360/2888 -f 5037/289/2854 5133/360/2854 5132/359/2854 -f 5103/339/2889 5134/361/2889 5072/317/2889 -f 5058/302/2861 5103/339/2861 5134/361/2861 -f 5058/302/2861 5135/362/2861 5136/363/2861 -f 5135/362/2890 5136/363/2890 5137/362/2890 -f 5055/302/2861 5112/330/2861 5138/331/2861 -f 5138/331/2881 5112/330/2881 5089/331/2881 -f 5139/349/2883 5118/348/2883 5117/349/2883 -f 5055/302/2861 5096/335/2861 5095/334/2861 -f 5058/302/2861 5140/306/2861 5087/307/2861 -f 5140/306/2864 5087/307/2864 5061/306/2864 -f 5058/302/2861 5141/364/2861 5142/365/2861 -f 5141/364/2891 5142/365/2891 5143/366/2891 -f 5144/367/2892 5145/368/2892 5146/367/2892 -f 5055/302/2861 5145/368/2861 5144/367/2861 -f 5051/298/2861 5147/369/2861 5148/370/2861 -f 5149/369/2893 5148/370/2893 5147/369/2893 -f 5150/371/2894 5151/372/2894 5152/371/2894 -f 5055/302/2861 5151/372/2861 5150/371/2861 -f 5153/373/2895 5154/374/2895 5155/375/2895 -f 5055/302/2861 5154/374/2861 5153/373/2861 -f 5055/302/2861 5156/376/2861 5157/377/2861 -f 5157/377/2896 5156/376/2896 5158/378/2896 -f 5037/289/2854 5159/379/2854 5160/311/2854 -f 5161/379/2897 5160/311/2897 5159/379/2897 -f 5133/360/2898 5162/380/2898 5131/358/2898 -f 5051/298/2861 5131/358/2861 5162/380/2861 -f 5163/381/2899 5164/382/2899 5165/383/2899 -f 5058/302/2861 5163/381/2861 5164/382/2861 -f 5047/292/2858 5040/292/2858 5042/294/2858 -f 5040/292/2857 5047/292/2857 5045/293/2857 -f 5053/300/2900 5126/355/2900 5051/298/2900 -f 5051/298/2861 5124/353/2861 5123/354/2861 -f 5166/335/2870 5097/334/2870 5096/335/2870 -f 5058/302/2861 5166/335/2861 5097/334/2861 -f 5037/289/2901 5050/297/2901 5167/289/2901 -f 5045/293/2861 5167/289/2861 5050/297/2861 -f 5037/289/2854 5168/384/2854 5122/353/2854 -f 5123/354/2902 5122/353/2902 5168/384/2902 -f 5058/302/2861 5169/385/2861 5146/367/2861 -f 5169/385/2903 5146/367/2903 5145/368/2903 -f 5037/289/2854 5121/352/2854 5120/351/2854 -f 5170/386/2904 5171/357/2904 5172/386/2904 -f 5173/387/2905 5174/388/2905 5175/388/2905 -f 5055/302/2861 5174/388/2861 5173/387/2861 -f 5058/302/2861 5106/341/2861 5107/342/2861 -f 5176/389/2906 5058/302/2906 5055/302/2906 -f 5177/390/2907 5178/391/2907 5179/390/2907 -f 5058/302/2861 5177/390/2861 5178/391/2861 -f 5055/302/2861 5180/336/2861 5100/338/2861 -f 5100/338/2908 5180/336/2908 5098/336/2908 -f 5037/289/2854 5181/392/2854 5182/393/2854 -f 5183/394/2909 5182/393/2909 5181/392/2909 -f 5179/390/2910 5184/395/2910 5177/390/2910 -f 5055/302/2861 5184/395/2861 5179/390/2861 -f 5058/302/2861 5102/321/2861 5185/396/2861 -f 5102/321/2911 5185/396/2911 5076/321/2911 -f 5137/362/2912 5186/396/2912 5135/362/2912 -f 5055/302/2861 5186/396/2861 5137/362/2861 -f 5084/326/2913 5187/397/2913 5082/326/2913 -f 5051/298/2861 5082/326/2861 5187/397/2861 -f 5147/369/2914 5188/398/2914 5149/369/2914 -f 5037/289/2854 5149/369/2854 5188/398/2854 -f 5152/371/2915 5189/399/2915 5150/371/2915 -f 5058/302/2861 5152/371/2861 5189/399/2861 -f 5143/366/2916 5190/400/2916 5141/364/2916 -f 5055/302/2861 5190/400/2861 5143/366/2861 -f 5120/351/2917 5119/350/2917 5191/401/2917 -f 5051/298/2861 5191/401/2861 5119/350/2861 -f 5158/378/2918 5073/318/2918 5157/377/2918 -f 5058/302/2861 5158/378/2861 5073/318/2861 -f 5050/297/2901 5037/289/2901 5091/297/2901 -f 5037/289/2854 5039/291/2854 5091/297/2854 -f 5175/388/2919 5192/402/2919 5173/387/2919 -f 5058/302/2861 5175/388/2861 5192/402/2861 -f 5055/302/2861 5080/324/2861 5079/323/2861 -f 5055/302/2920 5193/403/2920 5176/389/2920 -f 5053/300/2854 5049/296/2854 5038/290/2854 -f 5051/298/2921 5194/301/2921 5195/298/2921 -f 5051/298/2861 5183/394/2861 5196/404/2861 -f 5181/392/2922 5196/404/2922 5183/394/2922 -f 5165/383/2923 5197/405/2923 5163/381/2923 -f 5055/302/2861 5197/405/2861 5165/383/2861 -f 5198/406/2924 5199/407/2924 5200/408/2924 -f 5051/298/2861 5200/408/2861 5199/407/2861 -f 5058/302/2861 5201/409/2861 5202/410/2861 -f 5201/409/2925 5202/410/2925 5203/411/2925 -f 5204/412/2926 5205/413/2926 5206/412/2926 -f 5058/302/2861 5204/412/2861 5205/413/2861 -f 5055/302/2861 5207/414/2861 5208/415/2861 -f 5208/415/2927 5207/414/2927 5209/415/2927 -f 5058/302/2861 5210/414/2861 5209/415/2861 -f 5210/414/2927 5209/415/2927 5207/414/2927 -f 5211/413/2926 5206/412/2926 5205/413/2926 -f 5055/302/2861 5206/412/2861 5211/413/2861 -f 5037/289/2854 5198/406/2854 5168/384/2854 -f 5200/408/2928 5168/384/2928 5198/406/2928 -f 5055/302/2861 5212/416/2861 5213/417/2861 -f 5213/417/2929 5212/416/2929 5214/418/2929 -f 5155/375/2930 5215/419/2930 5153/373/2930 -f 5058/302/2861 5155/375/2861 5215/419/2861 -f 5216/420/2931 5217/421/2931 5218/422/2931 -f 5051/298/2861 5218/422/2861 5217/421/2861 -f 5218/422/2932 5219/423/2932 5216/420/2932 -f 5037/289/2854 5216/420/2854 5219/423/2854 -f 5058/302/2861 5115/347/2861 5220/424/2861 -f 5115/347/2933 5220/424/2933 5114/346/2933 -f 5055/302/2861 5221/425/2861 5108/343/2861 -f 5108/343/2934 5221/425/2934 5106/341/2934 -f 5051/298/2861 5161/379/2861 5222/426/2861 -f 5159/379/2935 5222/426/2935 5161/379/2935 -f 5055/302/2861 5104/340/2861 5223/319/2861 -f 5223/319/2936 5104/340/2936 5074/319/2936 -f 5065/310/2937 5224/397/2937 5092/310/2937 -f 5037/289/2854 5092/310/2854 5224/397/2854 -f 5055/302/2861 5225/427/2861 5093/333/2861 -f 5093/333/2938 5225/427/2938 5063/308/2938 -f 5081/325/2939 5226/428/2939 5079/323/2939 -f 5058/302/2861 5081/325/2861 5226/428/2861 -f 5111/304/2940 5227/395/2940 5057/304/2940 -f 5058/302/2861 5111/304/2861 5227/395/2861 -f 5055/302/2861 5228/429/2861 5203/411/2861 -f 5203/411/2941 5228/429/2941 5201/409/2941 -f 5055/302/2861 5229/430/2861 5094/314/2861 -f 5094/314/2942 5229/430/2942 5069/314/2942 -f 5101/305/2943 5230/399/2943 5059/305/2943 -f 5055/302/2861 5230/399/2861 5101/305/2861 -f 5214/418/2944 5231/431/2944 5213/417/2944 -f 5058/302/2861 5214/418/2861 5231/431/2861 -f 5058/302/2861 5105/322/2861 5232/405/2861 -f 5105/322/2945 5232/405/2945 5078/322/2945 -f 5051/298/2861 5127/356/2861 5233/398/2861 -f 5129/356/2946 5233/398/2946 5127/356/2946 -f 5085/328/2947 5234/404/2947 5109/328/2947 -f 5037/289/2854 5109/328/2854 5234/404/2854 -f 5235/299/2948 5167/289/2948 5052/299/2948 -f 5045/293/2861 5052/299/2861 5167/289/2861 -f 5037/289/2854 5120/351/2854 5236/426/2854 -f 5191/401/2949 5236/426/2949 5120/351/2949 -f 5125/355/2950 5237/432/2950 5126/355/2950 -f 5051/298/2861 5126/355/2861 5237/432/2861 -f 5047/292/2861 5054/301/2861 5051/298/2861 -f 5194/301/2921 5051/298/2921 5054/301/2921 -f 5037/289/2854 5172/386/2854 5171/357/2854 -f 5167/289/2948 5235/299/2948 5037/289/2948 -f 5037/289/2854 5122/353/2854 5238/432/2854 -f 5124/353/2951 5238/432/2951 5122/353/2951 -f 5055/302/2861 5239/391/2861 5112/330/2861 -f 5112/330/2952 5239/391/2952 5088/330/2952 -f 5171/357/2904 5170/386/2904 5130/357/2904 -f 5051/298/2861 5130/357/2861 5170/386/2861 -f 5058/302/2861 5136/363/2861 5240/372/2861 -f 5136/363/2953 5240/372/2953 5241/363/2953 -f 5055/302/2861 5241/363/2861 5151/372/2861 -f 5151/372/2953 5241/363/2953 5240/372/2953 -f 5242/327/2954 5243/370/2954 5083/327/2954 -f 5037/289/2854 5083/327/2854 5243/370/2854 -f 5243/370/2954 5242/327/2954 5148/370/2954 -f 5051/298/2861 5148/370/2861 5242/327/2861 -f 5145/368/2955 5244/433/2955 5169/385/2955 -f 5055/302/2861 5244/433/2861 5145/368/2861 -f 5058/302/2861 5074/319/2861 5245/320/2861 -f 5074/319/2956 5245/320/2956 5223/319/2956 -f 5058/302/2861 5146/367/2861 5246/430/2861 -f 5146/367/2957 5246/430/2957 5144/367/2957 -f 5087/307/2958 5175/388/2958 5062/307/2958 -f 5058/302/2861 5087/307/2861 5175/388/2861 -f 5118/348/2959 5055/302/2959 5116/348/2959 -f 5055/302/2861 5118/348/2861 5139/349/2861 -f 5097/334/2960 5098/336/2960 5095/334/2960 -f 5058/302/2861 5097/334/2861 5098/336/2861 -f 5051/298/2861 5110/344/2861 5183/394/2861 -f 5182/393/2961 5183/394/2961 5110/344/2961 -f 5058/302/2861 5142/365/2861 5169/385/2861 -f 5142/365/2962 5169/385/2962 5244/433/2962 -f 5154/374/2963 5165/383/2963 5164/382/2963 -f 5055/302/2861 5165/383/2861 5154/374/2861 -f 5168/384/2964 5200/408/2964 5123/354/2964 -f 5051/298/2861 5123/354/2861 5200/408/2861 -f 5199/407/2965 5198/406/2965 5132/359/2965 -f 5037/289/2854 5132/359/2854 5198/406/2854 -f 5238/432/2951 5124/353/2951 5237/432/2951 -f 5051/298/2861 5237/432/2861 5124/353/2861 -f 5037/289/2854 5171/357/2854 5121/352/2854 -f 5130/357/2966 5121/352/2966 5171/357/2966 -f 5055/302/2861 5173/387/2861 5225/427/2861 -f 5225/427/2967 5173/387/2967 5192/402/2967 -f 5058/302/2861 5226/428/2861 5176/389/2861 -f 5226/428/2968 5176/389/2968 5193/403/2968 -f 5236/426/2969 5191/401/2969 5222/426/2969 -f 5051/298/2861 5222/426/2861 5191/401/2861 -f 5174/388/2958 5062/307/2958 5175/388/2958 -f 5055/302/2861 5062/307/2861 5174/388/2861 -f 5058/302/2959 5116/348/2959 5055/302/2959 -f 5058/302/2861 5116/348/2861 5117/349/2861 -f 5055/302/2861 5095/334/2861 5180/336/2861 -f 5180/336/2960 5095/334/2960 5098/336/2960 -f 5178/391/2952 5088/330/2952 5239/391/2952 -f 5058/302/2861 5178/391/2861 5088/330/2861 -f 5227/395/2910 5177/390/2910 5184/395/2910 -f 5058/302/2861 5227/395/2861 5177/390/2861 -f 5055/302/2861 5100/338/2861 5228/429/2861 -f 5228/429/2970 5100/338/2970 5099/337/2970 -f 5055/302/2861 5179/390/2861 5239/391/2861 -f 5239/391/2907 5179/390/2907 5178/391/2907 -f 5058/302/2861 5209/415/2861 5140/306/2861 -f 5209/415/2971 5140/306/2971 5208/415/2971 -f 5206/412/2972 5139/349/2972 5204/412/2972 -f 5055/302/2861 5139/349/2861 5206/412/2861 -f 5055/302/2861 5138/331/2861 5207/414/2861 -f 5207/414/2973 5138/331/2973 5210/414/2973 -f 5205/413/2974 5166/335/2974 5211/413/2974 -f 5058/302/2861 5205/413/2861 5166/335/2861 -f 5132/359/2975 5131/358/2975 5199/407/2975 -f 5051/298/2861 5199/407/2861 5131/358/2861 -f 5162/380/2976 5133/360/2976 5219/423/2976 -f 5037/289/2854 5219/423/2854 5133/360/2854 -f 5192/402/2977 5063/308/2977 5225/427/2977 -f 5058/302/2861 5192/402/2861 5063/308/2861 -f 5055/302/2861 5079/323/2861 5193/403/2861 -f 5193/403/2978 5079/323/2978 5226/428/2978 -f 5037/289/2854 5235/299/2854 5172/386/2854 -f 5052/299/2979 5172/386/2979 5235/299/2979 -f 5051/298/2861 5066/311/2861 5161/379/2861 -f 5160/311/2897 5161/379/2897 5066/311/2897 -f 5058/302/2861 5185/396/2861 5135/362/2861 -f 5185/396/2912 5135/362/2912 5186/396/2912 -f 5055/302/2861 5157/377/2861 5104/340/2861 -f 5104/340/2980 5157/377/2980 5073/318/2980 -f 5231/431/2981 5158/378/2981 5156/376/2981 -f 5058/302/2861 5231/431/2861 5158/378/2861 -f 5055/302/2861 5137/362/2861 5241/363/2861 -f 5241/363/2890 5137/362/2890 5136/363/2890 -f 5058/302/2861 5099/337/2861 5201/409/2861 -f 5099/337/2982 5201/409/2982 5228/429/2982 -f 5187/397/2913 5084/326/2913 5224/397/2913 -f 5037/289/2854 5224/397/2854 5084/326/2854 -f 5055/302/2861 5093/333/2861 5113/345/2861 -f 5113/345/2983 5093/333/2983 5064/309/2983 -f 5107/342/2984 5081/325/2984 5080/324/2984 -f 5058/302/2861 5107/342/2861 5081/325/2861 -f 5037/289/2854 5236/426/2854 5159/379/2854 -f 5222/426/2935 5159/379/2935 5236/426/2935 -f 5083/327/2863 5082/326/2863 5242/327/2863 -f 5051/298/2861 5242/327/2861 5082/326/2861 -f 5117/349/2972 5204/412/2972 5139/349/2972 -f 5058/302/2861 5117/349/2861 5204/412/2861 -f 5055/302/2861 5208/415/2861 5061/306/2861 -f 5061/306/2971 5208/415/2971 5140/306/2971 -f 5055/302/2861 5211/413/2861 5096/335/2861 -f 5096/335/2974 5211/413/2974 5166/335/2974 -f 5089/331/2973 5210/414/2973 5138/331/2973 -f 5058/302/2861 5089/331/2861 5210/414/2861 -f 5230/399/2915 5150/371/2915 5189/399/2915 -f 5055/302/2861 5150/371/2861 5230/399/2861 -f 5051/298/2861 5233/398/2861 5147/369/2861 -f 5188/398/2914 5147/369/2914 5233/398/2914 -f 5037/289/2854 5234/404/2854 5181/392/2854 -f 5196/404/2985 5181/392/2985 5234/404/2985 -f 5060/303/2880 5111/304/2880 5056/303/2880 -f 5058/302/2861 5060/303/2861 5111/304/2861 -f 5071/316/2986 5203/411/2986 5202/410/2986 -f 5055/302/2861 5203/411/2861 5071/316/2861 -f 5172/386/2979 5052/299/2979 5170/386/2979 -f 5051/298/2861 5170/386/2861 5052/299/2861 -f 5058/302/2861 5240/372/2861 5152/371/2861 -f 5240/372/2894 5152/371/2894 5151/372/2894 -f 5148/370/2893 5149/369/2893 5243/370/2893 -f 5037/289/2854 5243/370/2854 5149/369/2854 -f 5232/405/2987 5163/381/2987 5197/405/2987 -f 5058/302/2861 5232/405/2861 5163/381/2861 -f 5055/302/2861 5144/367/2861 5229/430/2861 -f 5229/430/2957 5144/367/2957 5246/430/2957 -f 5075/320/2956 5223/319/2956 5245/320/2956 -f 5055/302/2861 5223/319/2861 5075/320/2861 -f 5184/395/2940 5057/304/2940 5227/395/2940 -f 5055/302/2861 5057/304/2861 5184/395/2861 -f 5055/302/2861 5213/417/2861 5156/376/2861 -f 5156/376/2988 5213/417/2988 5231/431/2988 -f 5037/289/2854 5182/393/2854 5067/312/2854 -f 5110/344/2989 5067/312/2989 5182/393/2989 -f 5244/433/2990 5143/366/2990 5142/365/2990 -f 5055/302/2861 5143/366/2861 5244/433/2861 -f 5051/298/2861 5217/421/2861 5090/332/2861 -f 5068/313/2991 5090/332/2991 5217/421/2991 -f 5134/361/2992 5214/418/2992 5212/416/2992 -f 5058/302/2861 5134/361/2861 5214/418/2861 -f 5058/302/2861 5220/424/2861 5141/364/2861 -f 5220/424/2993 5141/364/2993 5190/400/2993 -f 5086/329/2878 5109/328/2878 5128/329/2878 -f 5037/289/2854 5128/329/2854 5109/328/2854 -f 5070/315/2876 5105/322/2876 5077/315/2876 -f 5058/302/2861 5070/315/2861 5105/322/2861 -f 5164/382/2994 5155/375/2994 5154/374/2994 -f 5058/302/2861 5164/382/2861 5155/375/2861 -f 5197/405/2945 5078/322/2945 5232/405/2945 -f 5055/302/2861 5078/322/2861 5197/405/2861 -f 5051/298/2861 5196/404/2861 5085/328/2861 -f 5234/404/2947 5085/328/2947 5196/404/2947 -f 5037/289/2854 5238/432/2854 5125/355/2854 -f 5237/432/2950 5125/355/2950 5238/432/2950 -f 5221/425/2995 5153/373/2995 5215/419/2995 -f 5055/302/2861 5153/373/2861 5221/425/2861 -f 5186/396/2911 5076/321/2911 5185/396/2911 -f 5055/302/2861 5076/321/2861 5186/396/2861 -f 5037/289/2854 5160/311/2854 5092/310/2854 -f 5066/311/2868 5092/310/2868 5160/311/2868 -f 5051/298/2861 5187/397/2861 5065/310/2861 -f 5224/397/2937 5065/310/2937 5187/397/2937 -f 5058/302/2861 5245/320/2861 5102/321/2861 -f 5245/320/2873 5102/321/2873 5075/320/2873 -f 5219/423/2996 5218/422/2996 5162/380/2996 -f 5051/298/2861 5162/380/2861 5218/422/2861 -f 5058/302/2861 5246/430/2861 5069/314/2861 -f 5246/430/2942 5069/314/2942 5229/430/2942 -f 5056/303/2872 5101/305/2872 5060/303/2872 -f 5055/302/2861 5101/305/2861 5056/303/2861 -f 5091/297/2997 5044/295/2997 5050/297/2997 -f 5044/295/2861 5043/291/2861 5050/297/2861 -f 5233/398/2946 5129/356/2946 5188/398/2946 -f 5037/289/2854 5188/398/2854 5129/356/2854 -f 5058/302/2861 5189/399/2861 5059/305/2861 -f 5189/399/2943 5059/305/2943 5230/399/2943 -f 5077/315/2858 5094/314/2858 5070/315/2858 -f 5055/302/2861 5094/314/2861 5077/315/2861 -f 5064/309/2998 5115/347/2998 5113/345/2998 -f 5058/302/2861 5064/309/2861 5115/347/2861 -f 5051/298/2861 5086/329/2861 5127/356/2861 -f 5128/329/2873 5127/356/2873 5086/329/2873 -f 5217/421/2999 5216/420/2999 5068/313/2999 -f 5037/289/2854 5068/313/2854 5216/420/2854 -f 5055/302/2861 5108/343/2861 5080/324/2861 -f 5080/324/3000 5108/343/3000 5107/342/3000 -f 5058/302/2861 5202/410/2861 5103/339/2861 -f 5202/410/3001 5103/339/3001 5071/316/3001 -f 5055/302/2861 5114/346/2861 5190/400/2861 -f 5190/400/3002 5114/346/3002 5220/424/3002 -f 5212/416/3003 5072/317/3003 5134/361/3003 -f 5055/302/2861 5072/317/2861 5212/416/2861 -f 5215/419/3004 5106/341/3004 5221/425/3004 -f 5058/302/2861 5215/419/2861 5106/341/2861 -f 5053/300/2854 5194/301/2854 5049/296/2854 -f 5054/301/3005 5049/296/3005 5194/301/3005 -f 5053/300/2854 5195/298/2854 5194/301/2854 -f 5051/298/3006 5195/298/3006 5053/300/3006 -# 0 polygons - 412 triangles - -# -# object inner_tri -# - -v -0.0000 -0.1969 7.3303 -v -5.1143 -0.1969 -1.5280 -v 5.1143 -0.1969 -1.5280 -v -0.0000 0.1969 7.3303 -v -5.1143 0.1969 -1.5280 -v 5.1143 0.1969 -1.5280 -# 6 vertices - -vn 0.0000 -1.0000 0.0000 -vn -0.8660 -0.0000 0.5000 -vn 0.0000 0.0000 -1.0000 -vn 0.8660 -0.0000 0.5000 -vn -0.0000 1.0000 -0.0000 -# 5 vertex normals - -vt 0.9560 0.5085 0.9995 -vt 0.7293 0.8978 0.9995 -vt 0.7293 0.1192 0.9995 -vt 0.7293 0.1192 0.5000 -vt 0.9560 0.1192 0.9995 -vt 0.9560 0.8978 0.9995 -vt 0.7293 0.8978 0.5000 -vt 0.7293 0.1192 0.0005 -vt 0.9560 0.1192 0.0005 -vt 0.9560 0.8978 0.0005 -vt 0.7293 0.8978 0.0005 -vt 0.9560 0.1192 0.5000 -vt 0.9560 0.8978 0.5000 -vt 0.7293 0.5085 0.0005 -# 14 texture coords - -g inner_tri -usemtl white -s 1 -f 5247/434/3007 5248/435/3007 5249/436/3007 -s off -f 5250/437/3008 5251/438/3008 5248/439/3008 5247/440/3008 -f 5251/441/3009 5252/442/3009 5249/443/3009 5248/444/3009 -f 5252/441/3010 5250/445/3010 5247/446/3010 5249/444/3010 -f 5250/447/3011 5252/442/3011 5251/443/3011 -# 3 polygons - 2 triangles - diff --git a/ground/gcs/src/plugins/modelview/modelview.pro b/ground/gcs/src/plugins/modelview/modelview.pro deleted file mode 100644 index 35af2c661..000000000 --- a/ground/gcs/src/plugins/modelview/modelview.pro +++ /dev/null @@ -1,25 +0,0 @@ -TEMPLATE = lib -TARGET = ModelViewGadget -include(../../plugin.pri) -include(../../plugins/coreplugin/coreplugin.pri) -include(../../libs/glc_lib/glc_lib.pri) -include(modelview_dependencies.pri) - -INCLUDEPATH += ../../libs/glc_lib -HEADERS += modelviewplugin.h \ - modelviewgadgetconfiguration.h \ - modelviewgadget.h \ - modelviewgadgetwidget.h \ - modelviewgadgetfactory.h \ - modelviewgadgetoptionspage.h -SOURCES += modelviewplugin.cpp \ - modelviewgadgetconfiguration.cpp \ - modelviewgadget.cpp \ - modelviewgadgetfactory.cpp \ - modelviewgadgetwidget.cpp \ - modelviewgadgetoptionspage.cpp -OTHER_FILES += ModelViewGadget.pluginspec -FORMS += modelviewoptionspage.ui - -RESOURCES += \ - modelview.qrc diff --git a/ground/gcs/src/plugins/modelview/modelview.qrc b/ground/gcs/src/plugins/modelview/modelview.qrc deleted file mode 100644 index 9875c32fa..000000000 --- a/ground/gcs/src/plugins/modelview/modelview.qrc +++ /dev/null @@ -1,7 +0,0 @@ - - - models/black.jpg - models/warning_sign.mtl - models/warning_sign.obj - - diff --git a/ground/gcs/src/plugins/modelview/modelview_dependencies.pri b/ground/gcs/src/plugins/modelview/modelview_dependencies.pri deleted file mode 100644 index 9da489f64..000000000 --- a/ground/gcs/src/plugins/modelview/modelview_dependencies.pri +++ /dev/null @@ -1,3 +0,0 @@ -include(../../plugins/uavobjects/uavobjects.pri) -include(../../plugins/coreplugin/coreplugin.pri) -include(../../libs/utils/utils.pri) diff --git a/ground/gcs/src/plugins/modelview/modelviewgadget.cpp b/ground/gcs/src/plugins/modelview/modelviewgadget.cpp deleted file mode 100644 index b84a6b5af..000000000 --- a/ground/gcs/src/plugins/modelview/modelviewgadget.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/** - ****************************************************************************** - * - * @file modelviewgadget.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @addtogroup GCSPlugins GCS Plugins - * @{ - * @addtogroup ModelViewPlugin ModelView Plugin - * @{ - * @brief A gadget that displays a 3D representation of the UAV - *****************************************************************************/ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include "modelviewgadget.h" -#include "modelviewgadgetwidget.h" -#include "modelviewgadgetconfiguration.h" - -ModelViewGadget::ModelViewGadget(QString classId, ModelViewGadgetWidget *widget, QWidget *parent) : - IUAVGadget(classId, parent), - m_widget(widget) -{} - -ModelViewGadget::~ModelViewGadget() -{ - delete m_widget; -} - -void ModelViewGadget::loadConfiguration(IUAVGadgetConfiguration *config) -{ - ModelViewGadgetConfiguration *m = qobject_cast(config); - - m_widget->setAcFilename(m->acFilename()); - m_widget->setBgFilename(m->bgFilename()); - m_widget->setVboEnable(m->vboEnabled()); - m_widget->reloadScene(); -} diff --git a/ground/gcs/src/plugins/modelview/modelviewgadgetconfiguration.cpp b/ground/gcs/src/plugins/modelview/modelviewgadgetconfiguration.cpp deleted file mode 100644 index 7e2f550ff..000000000 --- a/ground/gcs/src/plugins/modelview/modelviewgadgetconfiguration.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/** - ****************************************************************************** - * - * @file modelviewgadgetconfiguration.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @addtogroup GCSPlugins GCS Plugins - * @{ - * @addtogroup ModelViewPlugin ModelView Plugin - * @{ - * @brief A gadget that displays a 3D representation of the UAV - *****************************************************************************/ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "modelviewgadgetconfiguration.h" -#include "utils/pathutils.h" - -ModelViewGadgetConfiguration::ModelViewGadgetConfiguration(QString classId, QSettings *qSettings, QObject *parent) : - IUAVGadgetConfiguration(classId, parent), - m_acFilename(Utils::GetDataPath() + QString("models/planes/Easystar/EasyStar.3ds")), - m_bgFilename(""), - m_enableVbo(false) -{ - // if a saved configuration exists load it - if (qSettings != 0) { - QString modelFile = qSettings->value("acFilename").toString(); - QString bgFile = qSettings->value("bgFilename").toString(); - m_enableVbo = qSettings->value("enableVbo").toBool(); - m_acFilename = Utils::InsertDataPath(modelFile); - m_bgFilename = Utils::InsertDataPath(bgFile); - } -} - -IUAVGadgetConfiguration *ModelViewGadgetConfiguration::clone() -{ - ModelViewGadgetConfiguration *mv = new ModelViewGadgetConfiguration(this->classId()); - - mv->m_acFilename = m_acFilename; - mv->m_bgFilename = m_bgFilename; - mv->m_enableVbo = m_enableVbo; - return mv; -} - -/** - * Saves a configuration. - * - */ -void ModelViewGadgetConfiguration::saveConfig(QSettings *qSettings) const -{ - qSettings->setValue("acFilename", Utils::RemoveDataPath(m_acFilename)); - qSettings->setValue("bgFilename", Utils::RemoveDataPath(m_bgFilename)); - qSettings->setValue("enableVbo", m_enableVbo); -} diff --git a/ground/gcs/src/plugins/modelview/modelviewgadgetconfiguration.h b/ground/gcs/src/plugins/modelview/modelviewgadgetconfiguration.h deleted file mode 100644 index ce3b0a939..000000000 --- a/ground/gcs/src/plugins/modelview/modelviewgadgetconfiguration.h +++ /dev/null @@ -1,76 +0,0 @@ -/** - ****************************************************************************** - * - * @file modelviewgadgetconfiguration.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @addtogroup GCSPlugins GCS Plugins - * @{ - * @addtogroup ModelViewPlugin ModelView Plugin - * @{ - * @brief A gadget that displays a 3D representation of the UAV - *****************************************************************************/ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef MODELVIEWGADGETCONFIGURATION_H -#define MODELVIEWGADGETCONFIGURATION_H - -#include - -using namespace Core; - -class ModelViewGadgetConfiguration : public IUAVGadgetConfiguration { - Q_OBJECT -public: - explicit ModelViewGadgetConfiguration(QString classId, QSettings *qSettings = 0, QObject *parent = 0); - - void saveConfig(QSettings *settings) const; - IUAVGadgetConfiguration *clone(); - QString acFilename() - { - return m_acFilename; - } - void setAcFilename(QString acFile) - { - m_acFilename = acFile; - } - QString bgFilename() - { - return m_bgFilename; - } - void setBgFilename(QString bgFile) - { - m_bgFilename = bgFile; - } - bool vboEnabled() - { - return m_enableVbo; - } - void setVboEnabled(bool vboEnable) - { - m_enableVbo = vboEnable; - } -signals: - -public slots: - -private: - QString m_acFilename; - QString m_bgFilename; - bool m_enableVbo; // Vertex buffer objects, a few GPUs crash if enabled -}; - -#endif // MODELVIEWGADGETCONFIGURATION_H diff --git a/ground/gcs/src/plugins/modelview/modelviewgadgetfactory.cpp b/ground/gcs/src/plugins/modelview/modelviewgadgetfactory.cpp deleted file mode 100644 index bad149297..000000000 --- a/ground/gcs/src/plugins/modelview/modelviewgadgetfactory.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/** - ****************************************************************************** - * - * @file modelviewgadgetfactory.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @addtogroup GCSPlugins GCS Plugins - * @{ - * @addtogroup ModelViewPlugin ModelView Plugin - * @{ - * @brief A gadget that displays a 3D representation of the UAV - *****************************************************************************/ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include "modelviewgadgetfactory.h" -#include "modelviewgadgetwidget.h" -#include "modelviewgadget.h" -#include "modelviewgadgetconfiguration.h" -#include "modelviewgadgetoptionspage.h" -#include -#include - -ModelViewGadgetFactory::ModelViewGadgetFactory(QObject *parent) : - IUAVGadgetFactory(QString("ModelViewGadget"), tr("ModelView"), parent) -{} - -ModelViewGadgetFactory::~ModelViewGadgetFactory() -{} - -Core::IUAVGadget *ModelViewGadgetFactory::createGadget(QWidget *parent) -{ - ModelViewGadgetWidget *gadgetWidget = new ModelViewGadgetWidget(parent); - - return new ModelViewGadget(QString("ModelViewGadget"), gadgetWidget, parent); -} - -IUAVGadgetConfiguration *ModelViewGadgetFactory::createConfiguration(QSettings *qSettings) -{ - return new ModelViewGadgetConfiguration(QString("ModelViewGadget"), qSettings); -} - -IOptionsPage *ModelViewGadgetFactory::createOptionsPage(IUAVGadgetConfiguration *config) -{ - return new ModelViewGadgetOptionsPage(qobject_cast(config)); -} diff --git a/ground/gcs/src/plugins/modelview/modelviewgadgetfactory.h b/ground/gcs/src/plugins/modelview/modelviewgadgetfactory.h deleted file mode 100644 index 32267d845..000000000 --- a/ground/gcs/src/plugins/modelview/modelviewgadgetfactory.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - ****************************************************************************** - * - * @file modelviewgadgetfactory.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @addtogroup GCSPlugins GCS Plugins - * @{ - * @addtogroup ModelViewPlugin ModelView Plugin - * @{ - * @brief A gadget that displays a 3D representation of the UAV - *****************************************************************************/ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef MODELVIEWGADGETFACTORY_H_ -#define MODELVIEWGADGETFACTORY_H_ - -#include - -namespace Core { -class IUAVGadget; -class IUAVGadgetFactory; -} - -using namespace Core; - -class ModelViewGadgetFactory : public Core::IUAVGadgetFactory { - Q_OBJECT -public: - ModelViewGadgetFactory(QObject *parent = 0); - ~ModelViewGadgetFactory(); - - Core::IUAVGadget *createGadget(QWidget *parent); - IUAVGadgetConfiguration *createConfiguration(QSettings *qSettings); - IOptionsPage *createOptionsPage(IUAVGadgetConfiguration *config); -}; - -#endif // MODELVIEWGADGETFACTORY_H_ diff --git a/ground/gcs/src/plugins/modelview/modelviewgadgetoptionspage.cpp b/ground/gcs/src/plugins/modelview/modelviewgadgetoptionspage.cpp deleted file mode 100644 index 2822555a4..000000000 --- a/ground/gcs/src/plugins/modelview/modelviewgadgetoptionspage.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/** - ****************************************************************************** - * - * @file modelviewgadgetoptionspage.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @addtogroup GCSPlugins GCS Plugins - * @{ - * @addtogroup ModelViewPlugin ModelView Plugin - * @{ - * @brief A gadget that displays a 3D representation of the UAV - *****************************************************************************/ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "modelviewgadgetoptionspage.h" -#include "modelviewgadgetconfiguration.h" - -#include "ui_modelviewoptionspage.h" - - -ModelViewGadgetOptionsPage::ModelViewGadgetOptionsPage(ModelViewGadgetConfiguration *config, QObject *parent) : - IOptionsPage(parent), - m_config(config) -{} - -QWidget *ModelViewGadgetOptionsPage::createPage(QWidget *parent) -{ - m_page = new Ui::ModelViewOptionsPage(); - QWidget *w = new QWidget(parent); - m_page->setupUi(w); - - m_page->modelPathChooser->setExpectedKind(Utils::PathChooser::File); - m_page->modelPathChooser->setPromptDialogFilter(tr("3D model (*.dae *.3ds)")); - m_page->modelPathChooser->setPromptDialogTitle(tr("Choose 3D model")); - m_page->backgroundPathChooser->setExpectedKind(Utils::PathChooser::File); - m_page->backgroundPathChooser->setPromptDialogFilter(tr("Images (*.png *.jpg *.bmp *.xpm)")); - m_page->backgroundPathChooser->setPromptDialogTitle(tr("Choose background image")); - - - m_page->modelPathChooser->setPath(m_config->acFilename()); - m_page->backgroundPathChooser->setPath(m_config->bgFilename()); - m_page->enableVbo->setChecked(m_config->vboEnabled()); - - - return w; -} - -void ModelViewGadgetOptionsPage::apply() -{ - m_config->setAcFilename(m_page->modelPathChooser->path()); - m_config->setBgFilename(m_page->backgroundPathChooser->path()); - m_config->setVboEnabled(m_page->enableVbo->isChecked()); -} - -void ModelViewGadgetOptionsPage::finish() -{ - delete m_page; -} diff --git a/ground/gcs/src/plugins/modelview/modelviewgadgetoptionspage.h b/ground/gcs/src/plugins/modelview/modelviewgadgetoptionspage.h deleted file mode 100644 index 144dcc1d3..000000000 --- a/ground/gcs/src/plugins/modelview/modelviewgadgetoptionspage.h +++ /dev/null @@ -1,85 +0,0 @@ -/** - ****************************************************************************** - * - * @file modelviewgadgetoptionspage.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @addtogroup GCSPlugins GCS Plugins - * @{ - * @addtogroup ModelViewPlugin ModelView Plugin - * @{ - * @brief A gadget that displays a 3D representation of the UAV - *****************************************************************************/ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef MODELVIEWGADGETOPTIONSPAGE_H -#define MODELVIEWGADGETOPTIONSPAGE_H - -#include "coreplugin/dialogs/ioptionspage.h" -#include -#include -#include -#include -#include - -class ModelViewGadgetConfiguration; -class QFileDialog; -namespace Core { -class IUAVGadgetConfiguration; -} -namespace Ui { -class ModelViewOptionsPage; -} - -using namespace Core; - -class ModelViewGadgetOptionsPage : public IOptionsPage { - Q_OBJECT -public: - explicit ModelViewGadgetOptionsPage(ModelViewGadgetConfiguration *config, QObject *parent = 0); - QString id() const - { - return ""; - } - QString trName() const - { - return ""; - } - QString category() const - { - return ""; - } - QString trCategory() const - { - return ""; - } - - QWidget *createPage(QWidget *parent); - void apply(); - void finish(); -private: - -signals: - -public slots: -private slots: - -private: - ModelViewGadgetConfiguration *m_config; - Ui::ModelViewOptionsPage *m_page; -}; - -#endif // MODELVIEWGADGETOPTIONSPAGE_H diff --git a/ground/gcs/src/plugins/modelview/modelviewgadgetwidget.cpp b/ground/gcs/src/plugins/modelview/modelviewgadgetwidget.cpp deleted file mode 100644 index 6e5a666fb..000000000 --- a/ground/gcs/src/plugins/modelview/modelviewgadgetwidget.cpp +++ /dev/null @@ -1,352 +0,0 @@ -/** - ****************************************************************************** - * - * @file modelviewgadgetwidget.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @addtogroup GCSPlugins GCS Plugins - * @{ - * @addtogroup ModelViewPlugin ModelView Plugin - * @{ - * @brief A gadget that displays a 3D representation of the UAV - *****************************************************************************/ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include "QtDebug" -#ifdef __APPLE__ - #include "OpenGL/OpenGL.h" -#endif -#include "modelviewgadgetwidget.h" -#include "extensionsystem/pluginmanager.h" -#include "glc_context.h" -#include "glc_exception.h" -#include "glc_openglexception.h" -#include "viewport/glc_userinput.h" - -#include - -ModelViewGadgetWidget::ModelViewGadgetWidget(QWidget *parent) - : QGLWidget(new GLC_Context(QGLFormat(QGL::SampleBuffers)), parent) - , m_Light() - , m_World() - , m_GlView() - , m_MoverController() - , m_ModelBoundingBox() - , m_MotionTimer() - , acFilename() - , bgFilename() - , vboEnable(false) -{ - connect(&m_GlView, SIGNAL(updateOpenGL()), this, SLOT(updateGL())); - setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - - m_Light.setPosition(4000.0, 40000.0, 80000.0); - // m_GlView.setBackgroundColor(Qt::white); - m_Light.setAmbientColor(Qt::lightGray); - - m_GlView.cameraHandle()->setDefaultUpVector(glc::Z_AXIS); - m_GlView.cameraHandle()->setRearView(); - - QColor repColor; - repColor.setRgbF(1.0, 0.11372, 0.11372, 0.0); - m_MoverController = GLC_Factory::instance()->createDefaultMoverController(repColor, &m_GlView); - - CreateScene(); - // Get required UAVObjects - ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); - UAVObjectManager *objManager = pm->getObject(); - attState = AttitudeState::GetInstance(objManager); - - connect(&m_MotionTimer, SIGNAL(timeout()), this, SLOT(updateAttitude())); -} - -ModelViewGadgetWidget::~ModelViewGadgetWidget() -{} - - -void ModelViewGadgetWidget::setAcFilename(QString acf) -{ - if (QFile::exists(acf)) { - acFilename = acf; - } else { - acFilename = acf = ":/modelview/models/warning_sign.obj"; - m_GlView.cameraHandle()->setFrontView(); // set to front camera to see/read the warning sign - } -} - -void ModelViewGadgetWidget::setBgFilename(QString bgf) -{ - if (QFile::exists(bgFilename)) { - bgFilename = bgf; - } else { - qDebug() << "file " << bgf << " doesn't exists"; - bgFilename = ":/modelview/models/black.jpg"; // will put a black background if there's no background - } -} - -void ModelViewGadgetWidget::setVboEnable(bool eVbo) -{ - vboEnable = eVbo; - m_World.collection()->setVboUsage(vboEnable); -} - -//// Public funcitons //// -void ModelViewGadgetWidget::reloadScene() -{ - CreateScene(); -} - -//// Private functions //// -void ModelViewGadgetWidget::initializeGL() -{ - // For VSYNC problem under Mac OS X - #if defined(Q_OS_MAC) - const GLint swapInterval = 1; - CGLSetParameter(CGLGetCurrentContext(), kCGLCPSwapInterval, &swapInterval); - #endif - - // OpenGL initialization - m_GlView.initGl(); - // Reframe the scene - m_GlView.reframe(m_ModelBoundingBox); - - glEnable(GL_NORMALIZE); - // Enable antialiasing - glEnable(GL_MULTISAMPLE); - - m_MotionTimer.start(100); - setFocusPolicy(Qt::StrongFocus); // keyboard capture for camera switching -} - -void ModelViewGadgetWidget::paintGL() -{ - try { - // Clear screen - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - // OpenGL error handler - { - GLenum error = glGetError(); - if (error != GL_NO_ERROR) { - GLC_OpenGlException OpenGlException("ModelViewGadgetWidget::paintGL() ", error); - throw(OpenGlException); - } - } - - // Load identity matrix - GLC_Context::current()->glcLoadIdentity(); - - // Enable antialiasing - glEnable(GL_MULTISAMPLE); - - // Calculate camera depth of view - m_GlView.setDistMinAndMax(m_World.boundingBox()); - - // define view matrix - m_GlView.glExecuteCam(); - m_Light.glExecute(); - - // Display the collection of GLC_Object - m_World.render(0, glc::ShadingFlag); - m_World.render(0, glc::TransparentRenderFlag); - - // Display UI Info (orbit circle) - m_MoverController.drawActiveMoverRep(); - } catch(GLC_Exception &e) { - qDebug() << e.what(); - } -} - -void ModelViewGadgetWidget::resizeGL(int width, int height) -{ - m_GlView.setWinGLSize(width, height); // Compute window aspect ratio - // OpenGL error handler - { - GLenum error = glGetError(); - if (error != GL_NO_ERROR) { - GLC_OpenGlException OpenGlException("ModelViewGadgetWidget::resizeGL() ", error); - throw(OpenGlException); - } - } -} - -// Create GLC_Object to display -void ModelViewGadgetWidget::CreateScene() -{ - // put a black background if the 3D model is invalid or if the background image is also invalid - if (acFilename == ":/modelview/models/warning_sign.obj" or !QFile::exists(bgFilename)) { - bgFilename = ":/modelview/models/black.jpg"; - } - - - try { - m_GlView.loadBackGroundImage(bgFilename); - } catch(GLC_Exception e) { - qDebug("ModelView: background image file loading failed."); - } - - try { - if (QFile::exists(acFilename)) { - QFile aircraft(acFilename); - m_World = GLC_Factory::instance()->createWorldFromFile(aircraft); - m_ModelBoundingBox = m_World.boundingBox(); - m_GlView.reframe(m_ModelBoundingBox); // center 3D model in the scene - } else { - qDebug("ModelView: aircraft file not found."); - } - } catch(GLC_Exception e) { - qDebug("ModelView: aircraft file loading failed."); - } -} - -void ModelViewGadgetWidget::wheelEvent(QWheelEvent *e) -{ - double delta = m_GlView.cameraHandle()->distEyeTarget() - (e->delta() / 4); - - m_GlView.cameraHandle()->setDistEyeTarget(delta); - m_GlView.setDistMinAndMax(m_World.boundingBox()); -} - -void ModelViewGadgetWidget::mousePressEvent(QMouseEvent *e) -{ - GLC_UserInput userInput(e->x(), e->y()); - - if (m_MoverController.hasActiveMover()) { - return; - } - - switch (e->button()) { - case (Qt::LeftButton): - m_MotionTimer.stop(); - m_MoverController.setActiveMover(GLC_MoverController::TurnTable, userInput); - updateGL(); - break; - case (Qt::RightButton): - printf("VBO enabled: %s, VBO supported: %s, VBO used: %s\n", - vboEnable ? "yes" : "no", - GLC_State::vboSupported() ? "yes" : "no", - GLC_State::vboUsed() ? "yes" : "no"); - printf("Renderer - %s \n", (char *)glGetString(GL_RENDERER)); - printf("Extensions - %s\n", (char *)glGetString(GL_EXTENSIONS)); - break; - default: - break; - } -} - -void ModelViewGadgetWidget::mouseMoveEvent(QMouseEvent *e) -{ - GLC_UserInput userInput(e->x(), e->y()); - - if (not m_MoverController.hasActiveMover()) { - return; - } - m_MoverController.move(userInput); - m_GlView.setDistMinAndMax(m_World.boundingBox()); - updateGL(); -} - -void ModelViewGadgetWidget::mouseReleaseEvent(QMouseEvent *) -{ - if (not m_MoverController.hasActiveMover()) { - return; - } - m_MoverController.setNoMover(); - m_MotionTimer.start(); - updateGL(); -} - -void ModelViewGadgetWidget::keyPressEvent(QKeyEvent *e) // switch between camera -{ - if (e->key() == Qt::Key_1) { - m_GlView.cameraHandle()->setIsoView(); - updateGL(); - } - if (e->key() == Qt::Key_2) { - m_GlView.cameraHandle()->setFrontView(); - updateGL(); - } - if (e->key() == Qt::Key_3) { - m_GlView.cameraHandle()->setIsoView(); - m_GlView.cameraHandle()->rotateAroundTarget(glc::Z_AXIS, glc::toRadian(90)); - updateGL(); - } - if (e->key() == Qt::Key_4) { - m_GlView.cameraHandle()->setLeftView(); - updateGL(); - } - if (e->key() == Qt::Key_5) { - m_GlView.cameraHandle()->setTopView(); - m_GlView.cameraHandle()->rotateAroundTarget(glc::Z_AXIS, glc::toRadian(180)); - updateGL(); - } - if (e->key() == Qt::Key_6) { - m_GlView.cameraHandle()->setRightView();; - updateGL(); - } - if (e->key() == Qt::Key_7) { - m_GlView.cameraHandle()->setIsoView(); - m_GlView.cameraHandle()->rotateAroundTarget(glc::Z_AXIS, glc::toRadian(-90)); - updateGL(); - } - if (e->key() == Qt::Key_8) { - m_GlView.cameraHandle()->setRearView();; - updateGL(); - } - if (e->key() == Qt::Key_9) { - m_GlView.cameraHandle()->setIsoView(); - m_GlView.cameraHandle()->rotateAroundTarget(glc::Z_AXIS, glc::toRadian(180)); - updateGL(); - } - if (e->key() == Qt::Key_0) { - m_GlView.cameraHandle()->setBottomView(); - m_GlView.cameraHandle()->rotateAroundTarget(glc::Z_AXIS, glc::toRadian(180)); - updateGL(); - } -} - -////////////////////////////////////////////////////////////////////// -// Private slots Functions -////////////////////////////////////////////////////////////////////// -void ModelViewGadgetWidget::updateAttitude() -{ - AttitudeState::DataFields data = attState->getData(); // get attitude data - GLC_StructOccurence *rootObject = m_World.rootOccurence(); // get the full 3D model - double x = data.q3; - double y = data.q2; - double z = data.q4; - double w = data.q1; - - if (w == 0.0) { - w = 1.0; - } - // create and gives the product of 2 4x4 matrices to get the rotation of the 3D model's matrix - QMatrix4x4 m1; - m1.setRow(0, QVector4D(w, z, -y, x)); - m1.setRow(1, QVector4D(-z, w, x, y)); - m1.setRow(2, QVector4D(y, -x, w, z)); - m1.setRow(3, QVector4D(-x, -y, -z, w)); - QMatrix4x4 m2; - m2.setRow(0, QVector4D(w, z, -y, -x)); - m2.setRow(1, QVector4D(-z, w, x, -y)); - m2.setRow(2, QVector4D(y, -x, w, -z)); - m2.setRow(3, QVector4D(x, y, z, w)); - QMatrix4x4 m0 = m1 * m2; - // convert QMatrix4x4 to GLC_Matrix4x4 - GLC_Matrix4x4 rootObjectRotation(m0.data()); - rootObject->structInstance()->setMatrix(rootObjectRotation); - rootObject->updateChildrenAbsoluteMatrix(); - updateGL(); -} diff --git a/ground/gcs/src/plugins/modelview/modelviewgadgetwidget.h b/ground/gcs/src/plugins/modelview/modelviewgadgetwidget.h deleted file mode 100644 index d55c31895..000000000 --- a/ground/gcs/src/plugins/modelview/modelviewgadgetwidget.h +++ /dev/null @@ -1,95 +0,0 @@ -/** - ****************************************************************************** - * - * @file modelviewgadgetwidget.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @addtogroup GCSPlugins GCS Plugins - * @{ - * @addtogroup ModelViewPlugin ModelView Plugin - * @{ - * @brief A gadget that displays a 3D representation of the UAV - *****************************************************************************/ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef MODELVIEWGADGETWIDGET_H_ -#define MODELVIEWGADGETWIDGET_H_ - -#include -#include - -#include "glc_factory.h" -#include "viewport/glc_viewport.h" -#include "viewport/glc_movercontroller.h" -#include "shading/glc_light.h" -#include "sceneGraph/glc_world.h" -#include "glc_exception.h" - -#include "uavobjectmanager.h" -#include "attitudestate.h" - - -class ModelViewGadgetWidget : public QGLWidget { - Q_OBJECT - -public: - ModelViewGadgetWidget(QWidget *parent = 0); - ~ModelViewGadgetWidget(); - void setAcFilename(QString acf); - - void setBgFilename(QString bgf); - void setVboEnable(bool eVbo); - void reloadScene(); - void updateAttitude(int value); - -private: - void initializeGL(); - void paintGL(); - void resizeGL(int width, int height); - // Create GLC_Object to display - void CreateScene(); - - // Mouse events - void mousePressEvent(QMouseEvent *e); - void mouseMoveEvent(QMouseEvent *e); - void mouseReleaseEvent(QMouseEvent *e); - void wheelEvent(QWheelEvent *e); - void keyPressEvent(QKeyEvent *e); - -////////////////////////////////////////////////////////////////////// -// Private slots Functions -////////////////////////////////////////////////////////////////////// -private slots: - void updateAttitude(); - -private: - GLC_Factory *m_pFactory; - GLC_Light m_Light; - GLC_World m_World; - GLC_Viewport m_GlView; - GLC_MoverController m_MoverController; - GLC_BoundingBox m_ModelBoundingBox; - // ! The timer used for motion - QTimer m_MotionTimer; - - QString acFilename; - QString bgFilename; - bool vboEnable; - - AttitudeState *attState; -}; - -#endif /* MODELVIEWGADGETWIDGET_H_ */ diff --git a/ground/gcs/src/plugins/modelview/modelviewoptionspage.ui b/ground/gcs/src/plugins/modelview/modelviewoptionspage.ui deleted file mode 100644 index 5f7b930c8..000000000 --- a/ground/gcs/src/plugins/modelview/modelviewoptionspage.ui +++ /dev/null @@ -1,95 +0,0 @@ - - - ModelViewOptionsPage - - - - 0 - 0 - 378 - 300 - - - - Form - - - - 0 - - - - - 3D model: - - - - - - - Background image: - - - - - - - Select the image that is shown in the background. - - - - - - - Select the 3D model file here. - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Click to enable the use of Vertical Blanking. -It is not enabled by default because some graphic cards do not -support it, and crash the GCS. Enabling improves performance, though, so you can experiment at your own risk. - - - VBO allow for performance gains for GPUs that support it (most cards). This may cause cards with faulty drivers to crash. - - - - - - - - - - Enable VBOs: - - - - - - - - Utils::PathChooser - QWidget -
utils/pathchooser.h
- 1 -
-
- - -
diff --git a/ground/gcs/src/plugins/modelview/modelviewplugin.cpp b/ground/gcs/src/plugins/modelview/modelviewplugin.cpp deleted file mode 100644 index 5b27c5e70..000000000 --- a/ground/gcs/src/plugins/modelview/modelviewplugin.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/** - ****************************************************************************** - * - * @file modelviewplugin.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @addtogroup GCSPlugins GCS Plugins - * @{ - * @addtogroup ModelViewPlugin ModelView Plugin - * @{ - * @brief A gadget that displays a 3D representation of the UAV - *****************************************************************************/ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include "modelviewplugin.h" -#include "modelviewgadgetfactory.h" -#include -#include -#include -#include - - -ModelViewPlugin::ModelViewPlugin() -{ - // Do nothing -} - -ModelViewPlugin::~ModelViewPlugin() -{ - // Do nothing -} - -bool ModelViewPlugin::initialize(const QStringList & args, QString *errMsg) -{ - Q_UNUSED(args); - Q_UNUSED(errMsg); - mvf = new ModelViewGadgetFactory(this); - addAutoReleasedObject(mvf); - - return true; -} - -void ModelViewPlugin::extensionsInitialized() -{ - // Do nothing -} - -void ModelViewPlugin::shutdown() -{ - // Do nothing -} diff --git a/ground/gcs/src/plugins/notify/images/add.png b/ground/gcs/src/plugins/notify/images/add.png index 93257c816..fe3738ccc 100644 Binary files a/ground/gcs/src/plugins/notify/images/add.png and b/ground/gcs/src/plugins/notify/images/add.png differ diff --git a/ground/gcs/src/plugins/notify/images/delete.png b/ground/gcs/src/plugins/notify/images/delete.png index d91a52dc0..c20a7cc71 100644 Binary files a/ground/gcs/src/plugins/notify/images/delete.png and b/ground/gcs/src/plugins/notify/images/delete.png differ diff --git a/ground/gcs/src/plugins/notify/images/modify.png b/ground/gcs/src/plugins/notify/images/modify.png index 5f841381e..35b1b207c 100644 Binary files a/ground/gcs/src/plugins/notify/images/modify.png and b/ground/gcs/src/plugins/notify/images/modify.png differ diff --git a/ground/gcs/src/plugins/notify/images/play.png b/ground/gcs/src/plugins/notify/images/play.png index d7089dca5..ebc4eb6cd 100644 Binary files a/ground/gcs/src/plugins/notify/images/play.png and b/ground/gcs/src/plugins/notify/images/play.png differ diff --git a/ground/gcs/src/plugins/notify/images/play2.png b/ground/gcs/src/plugins/notify/images/play2.png index 581bf054d..a7d8e9e24 100644 Binary files a/ground/gcs/src/plugins/notify/images/play2.png and b/ground/gcs/src/plugins/notify/images/play2.png differ diff --git a/ground/gcs/src/plugins/notify/images/stop.png b/ground/gcs/src/plugins/notify/images/stop.png index e985587d6..2a1192dde 100644 Binary files a/ground/gcs/src/plugins/notify/images/stop.png and b/ground/gcs/src/plugins/notify/images/stop.png differ diff --git a/ground/gcs/src/plugins/notify/notify.pro b/ground/gcs/src/plugins/notify/notify.pro index 0619df41f..c1f90a003 100644 --- a/ground/gcs/src/plugins/notify/notify.pro +++ b/ground/gcs/src/plugins/notify/notify.pro @@ -1,21 +1,22 @@ - TEMPLATE = lib TARGET = NotifyPlugin +QT += widgets multimedia + include(../../plugin.pri) include(../../plugins/coreplugin/coreplugin.pri) include(notifyplugin_dependencies.pri) -QT += multimedia - -HEADERS += notifyplugin.h \ +HEADERS += \ + notifyplugin.h \ notifypluginoptionspage.h \ notifyitemdelegate.h \ notifytablemodel.h \ notificationitem.h \ notifylogging.h -SOURCES += notifyplugin.cpp \ +SOURCES += \ + notifyplugin.cpp \ notifypluginoptionspage.cpp \ notifyitemdelegate.cpp \ notifytablemodel.cpp \ @@ -29,5 +30,3 @@ FORMS += \ RESOURCES += \ res.qrc - - diff --git a/ground/gcs/src/plugins/notify/notifyplugin_dependencies.pri b/ground/gcs/src/plugins/notify/notifyplugin_dependencies.pri index 883e47127..c6c920832 100644 --- a/ground/gcs/src/plugins/notify/notifyplugin_dependencies.pri +++ b/ground/gcs/src/plugins/notify/notifyplugin_dependencies.pri @@ -1,3 +1,2 @@ include(../../plugins/uavtalk/uavtalk.pri) include(../../plugins/uavobjects/uavobjects.pri) - diff --git a/ground/gcs/src/plugins/ophid/inc/ophid_const.h b/ground/gcs/src/plugins/ophid/inc/ophid_const.h index e53cbf199..f852ea8d0 100644 --- a/ground/gcs/src/plugins/ophid/inc/ophid_const.h +++ b/ground/gcs/src/plugins/ophid/inc/ophid_const.h @@ -31,10 +31,10 @@ #include #ifdef OPHID_DEBUG_ON -#define OPHID_DEBUG(fmt, args ...) qDebug("[DEBUG] "fmt,##args) -#define OPHID_TRACE(fmt, args ...) qDebug("[TRACE] %s:%s:%d: "fmt, __FILE__, __func__, __LINE__,##args) -#define OPHID_ERROR(fmt, args ...) qDebug("[ERROR] %s:%s:%d: "fmt, __FILE__, __func__, __LINE__,##args) -#define OPHID_WARNING(fmt, args ...) qDebug("[WARNING] "fmt,##args) +#define OPHID_DEBUG(fmt, args ...) qDebug("[DEBUG] "##fmt, args) +#define OPHID_TRACE(fmt, args ...) qDebug("[TRACE] %s:%s:%d: "##fmt, __FILE__, __func__, __LINE__, args) +#define OPHID_ERROR(fmt, args ...) qDebug("[ERROR] %s:%s:%d: "##fmt, __FILE__, __func__, __LINE__, args) +#define OPHID_WARNING(fmt, args ...) qDebug("[WARNING] "##fmt, args) #else #define OPHID_DEBUG(fmt, args ...) #define OPHID_TRACE(fmt, args ...) diff --git a/ground/gcs/src/plugins/ophid/inc/ophid_usbmon.h b/ground/gcs/src/plugins/ophid/inc/ophid_usbmon.h index eda27387f..b55ffeb27 100644 --- a/ground/gcs/src/plugins/ophid/inc/ophid_usbmon.h +++ b/ground/gcs/src/plugins/ophid/inc/ophid_usbmon.h @@ -54,26 +54,10 @@ #include #include #include +extern "C" +{ #include - -// from working mingw hidsdi.h -#ifdef __cplusplus -extern "C" { -#endif - -HIDAPI VOID WINAPI HidD_GetHidGuid(LPGUID); -HIDAPI BOOL WINAPI HidD_GetPreparsedData(HANDLE, PHIDP_PREPARSED_DATA *); -HIDAPI BOOL WINAPI HidD_FreePreparsedData(PHIDP_PREPARSED_DATA); -HIDAPI BOOL WINAPI HidD_FlushQueue(HANDLE); -HIDAPI BOOL WINAPI HidD_GetConfiguration(HANDLE, PHIDD_CONFIGURATION, ULONG); -HIDAPI BOOL WINAPI HidD_SetConfiguration(HANDLE, PHIDD_CONFIGURATION, ULONG); -HIDAPI BOOL WINAPI HidD_GetPhysicalDescriptor(HANDLE, PVOID, ULONG); -HIDAPI BOOL WINAPI HidD_GetIndexedString(HANDLE, ULONG, PVOID, ULONG); -HIDAPI BOOL WINAPI HidD_GetSerialNumberString(HANDLE, PVOID, ULONG); - -#ifdef __cplusplus } -#endif #endif // if defined(Q_OS_MAC) diff --git a/ground/gcs/src/plugins/ophid/ophid.pro b/ground/gcs/src/plugins/ophid/ophid.pro index d41a0e6e2..4b2bd8ab6 100644 --- a/ground/gcs/src/plugins/ophid/ophid.pro +++ b/ground/gcs/src/plugins/ophid/ophid.pro @@ -1,6 +1,8 @@ TEMPLATE = lib TARGET = opHID +QT += widgets + DEFINES += OPHID_LIBRARY //DEFINES += OPHID_DEBUG_ON @@ -25,7 +27,9 @@ SOURCES += \ src/ophid_hidapi.cpp FORMS += + RESOURCES += + OTHER_FILES += opHID.pluginspec INCLUDEPATH += ./inc diff --git a/ground/gcs/src/plugins/opmap/flightdatamodel.cpp b/ground/gcs/src/plugins/opmap/flightdatamodel.cpp index 674f4e092..17f76257e 100644 --- a/ground/gcs/src/plugins/opmap/flightdatamodel.cpp +++ b/ground/gcs/src/plugins/opmap/flightdatamodel.cpp @@ -373,10 +373,10 @@ bool flightDataModel::insertRows(int row, int count, const QModelIndex & /*paren data->lngPosition = 0; data->disRelative = 0; data->beaRelative = 0; - data->altitudeRelative = 0; + data->altitudeRelative = defaultWaypointAltitude(); data->isRelative = true; data->altitude = 0; - data->velocity = 0; + data->velocity = defaultWaypointVelocity(); data->mode = 1; data->mode_params[0] = 0; data->mode_params[1] = 0; @@ -668,3 +668,23 @@ void flightDataModel::readFromFile(QString fileName) node = node.nextSibling(); } } + +qreal flightDataModel::defaultWaypointAltitude() const +{ + return m_defaultWaypointAltitude; +} + +qreal flightDataModel::defaultWaypointVelocity() const +{ + return m_defaultWaypointVelocity; +} + +void flightDataModel::setDefaultWaypointAltitude(qreal default_altitude) +{ + m_defaultWaypointAltitude = default_altitude; +} + +void flightDataModel::setDefaultWaypointVelocity(qreal default_velocity) +{ + m_defaultWaypointVelocity = default_velocity; +} diff --git a/ground/gcs/src/plugins/opmap/flightdatamodel.h b/ground/gcs/src/plugins/opmap/flightdatamodel.h index 3dcdf337c..14d3f3e1c 100644 --- a/ground/gcs/src/plugins/opmap/flightdatamodel.h +++ b/ground/gcs/src/plugins/opmap/flightdatamodel.h @@ -70,10 +70,17 @@ public: bool removeRows(int row, int count, const QModelIndex & parent = QModelIndex()); bool writeToFile(QString filename); void readFromFile(QString fileName); + qreal defaultWaypointAltitude() const; + qreal defaultWaypointVelocity() const; + + void setDefaultWaypointAltitude(qreal default_altitude); + void setDefaultWaypointVelocity(qreal default_velocity); private: QList dataStorage; QVariant getColumnByIndex(const pathPlanData *row, const int index) const; bool setColumnByIndex(pathPlanData *row, const int index, const QVariant value); + qreal m_defaultWaypointAltitude; + qreal m_defaultWaypointVelocity; }; #endif // FLIGHTDATAMODEL_H diff --git a/ground/gcs/src/plugins/opmap/images/Ekisho Deep Ocean HD1.png b/ground/gcs/src/plugins/opmap/images/Ekisho Deep Ocean HD1.png index 54cd51b00..067e67271 100644 Binary files a/ground/gcs/src/plugins/opmap/images/Ekisho Deep Ocean HD1.png and b/ground/gcs/src/plugins/opmap/images/Ekisho Deep Ocean HD1.png differ diff --git a/ground/gcs/src/plugins/opmap/images/button_bar.png b/ground/gcs/src/plugins/opmap/images/button_bar.png index 5e9b1b076..cd60ee9bb 100644 Binary files a/ground/gcs/src/plugins/opmap/images/button_bar.png and b/ground/gcs/src/plugins/opmap/images/button_bar.png differ diff --git a/ground/gcs/src/plugins/opmap/images/center_wp.png b/ground/gcs/src/plugins/opmap/images/center_wp.png index 75936bcba..2218e5ae1 100644 Binary files a/ground/gcs/src/plugins/opmap/images/center_wp.png and b/ground/gcs/src/plugins/opmap/images/center_wp.png differ diff --git a/ground/gcs/src/plugins/opmap/images/circle.png b/ground/gcs/src/plugins/opmap/images/circle.png index fa262a0d0..e23abf12e 100644 Binary files a/ground/gcs/src/plugins/opmap/images/circle.png and b/ground/gcs/src/plugins/opmap/images/circle.png differ diff --git a/ground/gcs/src/plugins/opmap/images/combobox_down_arrow.png b/ground/gcs/src/plugins/opmap/images/combobox_down_arrow.png index 5c42554cf..0880ded0f 100644 Binary files a/ground/gcs/src/plugins/opmap/images/combobox_down_arrow.png and b/ground/gcs/src/plugins/opmap/images/combobox_down_arrow.png differ diff --git a/ground/gcs/src/plugins/opmap/images/down_alt.png b/ground/gcs/src/plugins/opmap/images/down_alt.png index b77135526..8b92d013a 100644 Binary files a/ground/gcs/src/plugins/opmap/images/down_alt.png and b/ground/gcs/src/plugins/opmap/images/down_alt.png differ diff --git a/ground/gcs/src/plugins/opmap/images/down_alt2.png b/ground/gcs/src/plugins/opmap/images/down_alt2.png index b77135526..8b92d013a 100644 Binary files a/ground/gcs/src/plugins/opmap/images/down_alt2.png and b/ground/gcs/src/plugins/opmap/images/down_alt2.png differ diff --git a/ground/gcs/src/plugins/opmap/images/forward button white.png b/ground/gcs/src/plugins/opmap/images/forward button white.png index e34adc93a..91946197e 100644 Binary files a/ground/gcs/src/plugins/opmap/images/forward button white.png and b/ground/gcs/src/plugins/opmap/images/forward button white.png differ diff --git a/ground/gcs/src/plugins/opmap/images/forward_alt.png b/ground/gcs/src/plugins/opmap/images/forward_alt.png index ddd2e4261..95d5685e9 100644 Binary files a/ground/gcs/src/plugins/opmap/images/forward_alt.png and b/ground/gcs/src/plugins/opmap/images/forward_alt.png differ diff --git a/ground/gcs/src/plugins/opmap/images/gcs.png b/ground/gcs/src/plugins/opmap/images/gcs.png index a9e5a640b..945b0ed2c 100644 Binary files a/ground/gcs/src/plugins/opmap/images/gcs.png and b/ground/gcs/src/plugins/opmap/images/gcs.png differ diff --git a/ground/gcs/src/plugins/opmap/images/go.png b/ground/gcs/src/plugins/opmap/images/go.png index 8075e0dd2..30b33af5b 100644 Binary files a/ground/gcs/src/plugins/opmap/images/go.png and b/ground/gcs/src/plugins/opmap/images/go.png differ diff --git a/ground/gcs/src/plugins/opmap/images/hold.png b/ground/gcs/src/plugins/opmap/images/hold.png index 7ac42ad91..b829c6c18 100644 Binary files a/ground/gcs/src/plugins/opmap/images/hold.png and b/ground/gcs/src/plugins/opmap/images/hold.png differ diff --git a/ground/gcs/src/plugins/opmap/images/home.png b/ground/gcs/src/plugins/opmap/images/home.png index cd2fb1eef..f6528d21c 100644 Binary files a/ground/gcs/src/plugins/opmap/images/home.png and b/ground/gcs/src/plugins/opmap/images/home.png differ diff --git a/ground/gcs/src/plugins/opmap/images/home_wp.png b/ground/gcs/src/plugins/opmap/images/home_wp.png index b6ad7d2b1..dc27188f8 100644 Binary files a/ground/gcs/src/plugins/opmap/images/home_wp.png and b/ground/gcs/src/plugins/opmap/images/home_wp.png differ diff --git a/ground/gcs/src/plugins/opmap/images/hover.png b/ground/gcs/src/plugins/opmap/images/hover.png index 816619e3c..6b5127fa9 100644 Binary files a/ground/gcs/src/plugins/opmap/images/hover.png and b/ground/gcs/src/plugins/opmap/images/hover.png differ diff --git a/ground/gcs/src/plugins/opmap/images/left_but.png b/ground/gcs/src/plugins/opmap/images/left_but.png index 0766e62c9..4895a6241 100644 Binary files a/ground/gcs/src/plugins/opmap/images/left_but.png and b/ground/gcs/src/plugins/opmap/images/left_but.png differ diff --git a/ground/gcs/src/plugins/opmap/images/minus.png b/ground/gcs/src/plugins/opmap/images/minus.png index d0b6eb30d..3ed51c726 100644 Binary files a/ground/gcs/src/plugins/opmap/images/minus.png and b/ground/gcs/src/plugins/opmap/images/minus.png differ diff --git a/ground/gcs/src/plugins/opmap/images/minus2.png b/ground/gcs/src/plugins/opmap/images/minus2.png index c50924194..82b9b7a41 100644 Binary files a/ground/gcs/src/plugins/opmap/images/minus2.png and b/ground/gcs/src/plugins/opmap/images/minus2.png differ diff --git a/ground/gcs/src/plugins/opmap/images/move_to_wp.png b/ground/gcs/src/plugins/opmap/images/move_to_wp.png index 370171495..c44075e4a 100644 Binary files a/ground/gcs/src/plugins/opmap/images/move_to_wp.png and b/ground/gcs/src/plugins/opmap/images/move_to_wp.png differ diff --git a/ground/gcs/src/plugins/opmap/images/new archive.png b/ground/gcs/src/plugins/opmap/images/new archive.png index 326c2bb3a..caa1bbeb8 100644 Binary files a/ground/gcs/src/plugins/opmap/images/new archive.png and b/ground/gcs/src/plugins/opmap/images/new archive.png differ diff --git a/ground/gcs/src/plugins/opmap/images/next_waypoint.png b/ground/gcs/src/plugins/opmap/images/next_waypoint.png index 96b5b363f..2ea46d14c 100644 Binary files a/ground/gcs/src/plugins/opmap/images/next_waypoint.png and b/ground/gcs/src/plugins/opmap/images/next_waypoint.png differ diff --git a/ground/gcs/src/plugins/opmap/images/ok.png b/ground/gcs/src/plugins/opmap/images/ok.png index 15cd35d27..1c92d139e 100644 Binary files a/ground/gcs/src/plugins/opmap/images/ok.png and b/ground/gcs/src/plugins/opmap/images/ok.png differ diff --git a/ground/gcs/src/plugins/opmap/images/pause.png b/ground/gcs/src/plugins/opmap/images/pause.png index a6d804f07..4fb1e7226 100644 Binary files a/ground/gcs/src/plugins/opmap/images/pause.png and b/ground/gcs/src/plugins/opmap/images/pause.png differ diff --git a/ground/gcs/src/plugins/opmap/images/plus.png b/ground/gcs/src/plugins/opmap/images/plus.png index 56e9b4f90..2b77c6579 100644 Binary files a/ground/gcs/src/plugins/opmap/images/plus.png and b/ground/gcs/src/plugins/opmap/images/plus.png differ diff --git a/ground/gcs/src/plugins/opmap/images/plus2.png b/ground/gcs/src/plugins/opmap/images/plus2.png index f6d1d6e62..8dd5f63cd 100644 Binary files a/ground/gcs/src/plugins/opmap/images/plus2.png and b/ground/gcs/src/plugins/opmap/images/plus2.png differ diff --git a/ground/gcs/src/plugins/opmap/images/plus3.png b/ground/gcs/src/plugins/opmap/images/plus3.png index 63ce12ba2..7304350c9 100644 Binary files a/ground/gcs/src/plugins/opmap/images/plus3.png and b/ground/gcs/src/plugins/opmap/images/plus3.png differ diff --git a/ground/gcs/src/plugins/opmap/images/prev_waypoint.png b/ground/gcs/src/plugins/opmap/images/prev_waypoint.png index 53cedbe2c..94c20f8fe 100644 Binary files a/ground/gcs/src/plugins/opmap/images/prev_waypoint.png and b/ground/gcs/src/plugins/opmap/images/prev_waypoint.png differ diff --git a/ground/gcs/src/plugins/opmap/images/rewind button white.png b/ground/gcs/src/plugins/opmap/images/rewind button white.png index 549bd8057..d1955e109 100644 Binary files a/ground/gcs/src/plugins/opmap/images/rewind button white.png and b/ground/gcs/src/plugins/opmap/images/rewind button white.png differ diff --git a/ground/gcs/src/plugins/opmap/images/right_but.png b/ground/gcs/src/plugins/opmap/images/right_but.png index d0d78acd8..1c7cf3a83 100644 Binary files a/ground/gcs/src/plugins/opmap/images/right_but.png and b/ground/gcs/src/plugins/opmap/images/right_but.png differ diff --git a/ground/gcs/src/plugins/opmap/images/star.png b/ground/gcs/src/plugins/opmap/images/star.png index 25ef8b290..181272296 100644 Binary files a/ground/gcs/src/plugins/opmap/images/star.png and b/ground/gcs/src/plugins/opmap/images/star.png differ diff --git a/ground/gcs/src/plugins/opmap/images/stop.png b/ground/gcs/src/plugins/opmap/images/stop.png index 972b6d61a..58a3871f5 100644 Binary files a/ground/gcs/src/plugins/opmap/images/stop.png and b/ground/gcs/src/plugins/opmap/images/stop.png differ diff --git a/ground/gcs/src/plugins/opmap/images/stopb.png b/ground/gcs/src/plugins/opmap/images/stopb.png index 5dad7cdac..dcd9bebd4 100644 Binary files a/ground/gcs/src/plugins/opmap/images/stopb.png and b/ground/gcs/src/plugins/opmap/images/stopb.png differ diff --git a/ground/gcs/src/plugins/opmap/images/uav.png b/ground/gcs/src/plugins/opmap/images/uav.png index bee268370..3e1ad0380 100644 Binary files a/ground/gcs/src/plugins/opmap/images/uav.png and b/ground/gcs/src/plugins/opmap/images/uav.png differ diff --git a/ground/gcs/src/plugins/opmap/images/uav_heading.png b/ground/gcs/src/plugins/opmap/images/uav_heading.png index c8b701fad..f7cb991bd 100644 Binary files a/ground/gcs/src/plugins/opmap/images/uav_heading.png and b/ground/gcs/src/plugins/opmap/images/uav_heading.png differ diff --git a/ground/gcs/src/plugins/opmap/images/uav_trail.png b/ground/gcs/src/plugins/opmap/images/uav_trail.png index c28923c08..4ff967c81 100644 Binary files a/ground/gcs/src/plugins/opmap/images/uav_trail.png and b/ground/gcs/src/plugins/opmap/images/uav_trail.png differ diff --git a/ground/gcs/src/plugins/opmap/images/uav_trail_clear.png b/ground/gcs/src/plugins/opmap/images/uav_trail_clear.png index de985699a..b2a930959 100644 Binary files a/ground/gcs/src/plugins/opmap/images/uav_trail_clear.png and b/ground/gcs/src/plugins/opmap/images/uav_trail_clear.png differ diff --git a/ground/gcs/src/plugins/opmap/images/unarchive.png b/ground/gcs/src/plugins/opmap/images/unarchive.png index e74f0a31c..fba006a8d 100644 Binary files a/ground/gcs/src/plugins/opmap/images/unarchive.png and b/ground/gcs/src/plugins/opmap/images/unarchive.png differ diff --git a/ground/gcs/src/plugins/opmap/images/up_alt.png b/ground/gcs/src/plugins/opmap/images/up_alt.png index 4d8b67f59..4384307f8 100644 Binary files a/ground/gcs/src/plugins/opmap/images/up_alt.png and b/ground/gcs/src/plugins/opmap/images/up_alt.png differ diff --git a/ground/gcs/src/plugins/opmap/images/waypoint.png b/ground/gcs/src/plugins/opmap/images/waypoint.png index 7951fc743..92357903b 100644 Binary files a/ground/gcs/src/plugins/opmap/images/waypoint.png and b/ground/gcs/src/plugins/opmap/images/waypoint.png differ diff --git a/ground/gcs/src/plugins/opmap/images/waypoint_marker1.png b/ground/gcs/src/plugins/opmap/images/waypoint_marker1.png index 179be2007..bc5868740 100644 Binary files a/ground/gcs/src/plugins/opmap/images/waypoint_marker1.png and b/ground/gcs/src/plugins/opmap/images/waypoint_marker1.png differ diff --git a/ground/gcs/src/plugins/opmap/images/waypoint_marker2.png b/ground/gcs/src/plugins/opmap/images/waypoint_marker2.png index 7834aa543..8a0629a26 100644 Binary files a/ground/gcs/src/plugins/opmap/images/waypoint_marker2.png and b/ground/gcs/src/plugins/opmap/images/waypoint_marker2.png differ diff --git a/ground/gcs/src/plugins/opmap/images/waypoint_marker3.png b/ground/gcs/src/plugins/opmap/images/waypoint_marker3.png index bd86af025..c871317d8 100644 Binary files a/ground/gcs/src/plugins/opmap/images/waypoint_marker3.png and b/ground/gcs/src/plugins/opmap/images/waypoint_marker3.png differ diff --git a/ground/gcs/src/plugins/opmap/modelmapproxy.cpp b/ground/gcs/src/plugins/opmap/modelmapproxy.cpp index fb56c0081..0940217ff 100644 --- a/ground/gcs/src/plugins/opmap/modelmapproxy.cpp +++ b/ground/gcs/src/plugins/opmap/modelmapproxy.cpp @@ -293,10 +293,8 @@ void modelMapProxy::rowsInserted(const QModelIndex &parent, int first, int last) { Q_UNUSED(parent); - for (int x = first; x < last + 1; x++) { QModelIndex index; - WayPointItem *item; internals::PointLatLng latlng; distBearingAltitude distBearing; double altitude; @@ -318,9 +316,9 @@ void modelMapProxy::rowsInserted(const QModelIndex &parent, int first, int last) index = model->index(x, flightDataModel::ALTITUDE); altitude = index.data(Qt::DisplayRole).toDouble(); if (relative) { - item = myMap->WPInsert(distBearing, desc, x); + myMap->WPInsert(distBearing, desc, x); } else { - item = myMap->WPInsert(latlng, altitude, desc, x); + myMap->WPInsert(latlng, altitude, desc, x); } } diff --git a/ground/gcs/src/plugins/opmap/modeluavoproxy.cpp b/ground/gcs/src/plugins/opmap/modeluavoproxy.cpp index f85cf72c1..a9a13528a 100644 --- a/ground/gcs/src/plugins/opmap/modeluavoproxy.cpp +++ b/ground/gcs/src/plugins/opmap/modeluavoproxy.cpp @@ -27,6 +27,7 @@ #include "modeluavoproxy.h" #include "extensionsystem/pluginmanager.h" #include "uavobjecthelper.h" +#include "uavobjectmanager.h" #include #include diff --git a/ground/gcs/src/plugins/opmap/opmap.pro b/ground/gcs/src/plugins/opmap/opmap.pro index 8d1689635..6e1d1536f 100644 --- a/ground/gcs/src/plugins/opmap/opmap.pro +++ b/ground/gcs/src/plugins/opmap/opmap.pro @@ -1,10 +1,12 @@ -QT += xml TEMPLATE = lib +TARGET = OPMapGadget + +QT += widgets xml + PATHPLANNER { DEFINES += USE_PATHPLANNER } -TARGET = OPMapGadget include(../../plugin.pri) include(../../plugins/coreplugin/coreplugin.pri) include(../../libs/opmapcontrol/opmapcontrol.pri) @@ -13,7 +15,8 @@ include(../../plugins/uavobjectutil/uavobjectutil.pri) include(../../plugins/uavtalk/uavtalk.pri) include(../../libs/utils/utils.pri) -HEADERS += opmapplugin.h \ +HEADERS += \ + opmapplugin.h \ opmapgadgetoptionspage.h \ opmapgadgetfactory.h \ opmapgadgetconfiguration.h \ @@ -29,7 +32,8 @@ HEADERS += opmapplugin.h \ modeluavoproxy.h \ homeeditor.h -SOURCES += opmapplugin.cpp \ +SOURCES += \ + opmapplugin.cpp \ opmapgadgetwidget.cpp \ opmapgadgetoptionspage.cpp \ opmapgadgetfactory.cpp \ @@ -47,7 +51,8 @@ SOURCES += opmapplugin.cpp \ OTHER_FILES += OPMapGadget.pluginspec -FORMS += opmapgadgetoptionspage.ui \ +FORMS += \ + opmapgadgetoptionspage.ui \ opmap_widget.ui \ opmap_edit_waypoint_dialog.ui \ opmap_zoom_slider_widget.ui \ diff --git a/ground/gcs/src/plugins/opmap/opmap_overlay_widget.ui b/ground/gcs/src/plugins/opmap/opmap_overlay_widget.ui index f57514c92..010196ec4 100644 --- a/ground/gcs/src/plugins/opmap/opmap_overlay_widget.ui +++ b/ground/gcs/src/plugins/opmap/opmap_overlay_widget.ui @@ -20,7 +20,7 @@ true - Form + Form background-color: transparent; @@ -301,7 +301,7 @@ border-radius: 10px; QFrame::NoFrame - labelStatus + labelStatus Qt::AlignCenter @@ -366,7 +366,7 @@ border-radius: 3px; Qt::AlignCenter - %v + %v diff --git a/ground/gcs/src/plugins/opmap/opmap_statusbar_widget.ui b/ground/gcs/src/plugins/opmap/opmap_statusbar_widget.ui index 5ab0c93a3..40aacb3c2 100644 --- a/ground/gcs/src/plugins/opmap/opmap_statusbar_widget.ui +++ b/ground/gcs/src/plugins/opmap/opmap_statusbar_widget.ui @@ -17,7 +17,7 @@ - Form + Form background-color: rgba(0, 0, 0, 0); @@ -89,7 +89,7 @@ border-radius: 10px; QFrame::NoFrame - labelStatus + labelStatus Qt::AlignCenter @@ -154,7 +154,7 @@ border-radius: 3px; Qt::AlignCenter - %v + %v diff --git a/ground/gcs/src/plugins/opmap/opmapgadget.cpp b/ground/gcs/src/plugins/opmap/opmapgadget.cpp index 2c75814d3..a49472aed 100644 --- a/ground/gcs/src/plugins/opmap/opmapgadget.cpp +++ b/ground/gcs/src/plugins/opmap/opmapgadget.cpp @@ -69,4 +69,6 @@ void OPMapGadget::loadConfiguration(IUAVGadgetConfiguration *config) m_widget->setPosition(QPointF(m_config->longitude(), m_config->latitude())); m_widget->setHomePosition(QPointF(m_config->longitude(), m_config->latitude())); m_widget->setOverlayOpacity(m_config->opacity()); + m_widget->setDefaultWaypointAltitude(m_config->defaultWaypointAltitude()); + m_widget->setDefaultWaypointVelocity(m_config->defaultWaypointVelocity()); } diff --git a/ground/gcs/src/plugins/opmap/opmapgadgetconfiguration.cpp b/ground/gcs/src/plugins/opmap/opmapgadgetconfiguration.cpp index 9dba75bb8..29ca37516 100644 --- a/ground/gcs/src/plugins/opmap/opmapgadgetconfiguration.cpp +++ b/ground/gcs/src/plugins/opmap/opmapgadgetconfiguration.cpp @@ -43,7 +43,9 @@ OPMapGadgetConfiguration::OPMapGadgetConfiguration(QString classId, QSettings *q m_uavSymbol(QString::fromUtf8(":/uavs/images/mapquad.png")), m_maxUpdateRate(2000), // ms m_settings(qSettings), - m_opacity(1) + m_opacity(1), + m_defaultWaypointAltitude(15), + m_defaultWaypointVelocity(2) { // if a saved configuration exists load it if (qSettings != 0) { @@ -58,7 +60,8 @@ OPMapGadgetConfiguration::OPMapGadgetConfiguration(QString classId, QSettings *q QString cacheLocation = qSettings->value("cacheLocation").toString(); QString uavSymbol = qSettings->value("uavSymbol").toString(); int max_update_rate = qSettings->value("maxUpdateRate").toInt(); - + m_defaultWaypointAltitude = qSettings->value("defaultWaypointAltitude", 15).toReal(); + m_defaultWaypointVelocity = qSettings->value("defaultWaypointVelocity", 2).toReal(); m_opacity = qSettings->value("overlayOpacity", 1).toReal(); if (!mapProvider.isEmpty()) { @@ -102,6 +105,8 @@ IUAVGadgetConfiguration *OPMapGadgetConfiguration::clone() m->m_uavSymbol = m_uavSymbol; m->m_maxUpdateRate = m_maxUpdateRate; m->m_opacity = m_opacity; + m->m_defaultWaypointAltitude = m_defaultWaypointAltitude; + m->m_defaultWaypointVelocity = m_defaultWaypointVelocity; return m; } @@ -127,6 +132,9 @@ void OPMapGadgetConfiguration::saveConfig(QSettings *qSettings) const qSettings->setValue("cacheLocation", Utils::RemoveStoragePath(m_cacheLocation)); qSettings->setValue("maxUpdateRate", m_maxUpdateRate); qSettings->setValue("overlayOpacity", m_opacity); + + qSettings->setValue("defaultWaypointAltitude", m_defaultWaypointAltitude); + qSettings->setValue("defaultWaypointVelocity", m_defaultWaypointVelocity); } void OPMapGadgetConfiguration::setCacheLocation(QString cacheLocation) { diff --git a/ground/gcs/src/plugins/opmap/opmapgadgetconfiguration.h b/ground/gcs/src/plugins/opmap/opmapgadgetconfiguration.h index 8d0e1bbbe..d1634538e 100644 --- a/ground/gcs/src/plugins/opmap/opmapgadgetconfiguration.h +++ b/ground/gcs/src/plugins/opmap/opmapgadgetconfiguration.h @@ -46,6 +46,8 @@ class OPMapGadgetConfiguration : public IUAVGadgetConfiguration { Q_PROPERTY(QString uavSymbol READ uavSymbol WRITE setUavSymbol) Q_PROPERTY(int maxUpdateRate READ maxUpdateRate WRITE setMaxUpdateRate) Q_PROPERTY(qreal overlayOpacity READ opacity WRITE setOpacity) + Q_PROPERTY(qreal defaultWaypointAltitude READ defaultWaypointAltitude WRITE setDefaultWaypointAltitude) + Q_PROPERTY(qreal defaultWaypointVelocity READ defaultWaypointVelocity WRITE setDefaultWaypointVelocity) public: explicit OPMapGadgetConfiguration(QString classId, QSettings *qSettings = 0, QObject *parent = 0); @@ -101,6 +103,17 @@ public: { return m_opacity; } + + qreal defaultWaypointAltitude() const + { + return m_defaultWaypointAltitude; + } + + qreal defaultWaypointVelocity() const + { + return m_defaultWaypointVelocity; + } + void save() const; public slots: void setMapProvider(QString provider) @@ -149,6 +162,16 @@ public slots: m_maxUpdateRate = update_rate; } + void setDefaultWaypointAltitude(qreal default_altitude) + { + m_defaultWaypointAltitude = default_altitude; + } + + void setDefaultWaypointVelocity(qreal default_velocity) + { + m_defaultWaypointVelocity = default_velocity; + } + private: QString m_mapProvider; int m_defaultZoom; @@ -163,6 +186,8 @@ private: int m_maxUpdateRate; QSettings *m_settings; qreal m_opacity; + qreal m_defaultWaypointAltitude; + qreal m_defaultWaypointVelocity; }; #endif // OPMAP_GADGETCONFIGURATION_H diff --git a/ground/gcs/src/plugins/opmap/opmapgadgetoptionspage.cpp b/ground/gcs/src/plugins/opmap/opmapgadgetoptionspage.cpp index c6bee0c60..24993b51e 100644 --- a/ground/gcs/src/plugins/opmap/opmapgadgetoptionspage.cpp +++ b/ground/gcs/src/plugins/opmap/opmapgadgetoptionspage.cpp @@ -109,6 +109,8 @@ QWidget *OPMapGadgetOptionsPage::createPage(QWidget *parent) } } + m_page->defaultWaypointAltitude->setValue(m_config->defaultWaypointAltitude()); + m_page->defaultWaypointVelocity->setValue(m_config->defaultWaypointVelocity()); connect(m_page->pushButtonCacheDefaults, SIGNAL(clicked()), this, SLOT(on_pushButtonCacheDefaults_clicked())); return w; @@ -138,6 +140,8 @@ void OPMapGadgetOptionsPage::apply() m_config->setCacheLocation(m_page->lineEditCacheLocation->path()); m_config->setUavSymbol(m_page->uavSymbolComboBox->itemData(m_page->uavSymbolComboBox->currentIndex()).toString()); m_config->setMaxUpdateRate(m_page->maxUpdateRateComboBox->itemData(m_page->maxUpdateRateComboBox->currentIndex()).toInt()); + m_config->setDefaultWaypointAltitude(m_page->defaultWaypointAltitude->value()); + m_config->setDefaultWaypointVelocity(m_page->defaultWaypointVelocity->value()); } void OPMapGadgetOptionsPage::finish() diff --git a/ground/gcs/src/plugins/opmap/opmapgadgetoptionspage.ui b/ground/gcs/src/plugins/opmap/opmapgadgetoptionspage.ui index 5d5285811..d4fbdc6a2 100644 --- a/ground/gcs/src/plugins/opmap/opmapgadgetoptionspage.ui +++ b/ground/gcs/src/plugins/opmap/opmapgadgetoptionspage.ui @@ -26,7 +26,16 @@ Form - + + 0 + + + 0 + + + 0 + + 0 @@ -45,8 +54,8 @@ 0 0 - 564 - 391 + 549 + 401 @@ -56,178 +65,28 @@ - + 0 - - - - - - - 0 - 0 - - - - UAV Symbol - - - - - - - - 0 - 0 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Qt::Horizontal + + 0 + + + 0 + + + 0 + + + + + Waypoint Options + + + Qt::AlignCenter - - - - - - - 0 - 0 - - - - Cache location - - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - OpenHandCursor - - - Restore default server and cache settings - - - Default - - - false - - - false - - - false - - - - - - - - - - - Access mode - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 160 - 0 - - - - OpenHandCursor - - - true - - - - - - - true - - - - 0 - 0 - - - - - 0 - 0 - - - - Qt::RightToLeft - - - Use Memory Cache - - - - - @@ -463,7 +322,248 @@ - + + + + + + + 0 + 0 + + + + Default relative Altitude + + + + + + + 1 + + + -1000.000000000000000 + + + 1000.000000000000000 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + Default Velocity + + + + + + + 1 + + + 50.000000000000000 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 0 + + + + UAV Symbol + + + + + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Access mode + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 160 + 0 + + + + OpenHandCursor + + + true + + + + + + + true + + + + 0 + 0 + + + + + 0 + 0 + + + + Qt::RightToLeft + + + Use Memory Cache + + + + + + + + + + + + 0 + 0 + + + + Cache location + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + OpenHandCursor + + + Restore default server and cache settings + + + Default + + + false + + + false + + + false + + + + + + Server and Cache @@ -473,7 +573,7 @@ - + Qt::Vertical @@ -489,6 +589,20 @@ + + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + diff --git a/ground/gcs/src/plugins/opmap/opmapgadgetwidget.cpp b/ground/gcs/src/plugins/opmap/opmapgadgetwidget.cpp index a498784fc..0b6994bfb 100644 --- a/ground/gcs/src/plugins/opmap/opmapgadgetwidget.cpp +++ b/ground/gcs/src/plugins/opmap/opmapgadgetwidget.cpp @@ -220,6 +220,8 @@ OPMapGadgetWidget::OPMapGadgetWidget(QWidget *parent) : QWidget(parent) } #ifdef USE_PATHPLANNER model = new flightDataModel(this); + model->setDefaultWaypointAltitude(m_defaultWaypointAltitude); + model->setDefaultWaypointVelocity(m_defaultWaypointVelocity); table = new pathPlanner(); selectionModel = new QItemSelectionModel(model); mapProxy = new modelMapProxy(this, m_map, model, selectionModel); @@ -2372,3 +2374,19 @@ void OPMapGadgetWidget::on_leFind_returnPressed() { on_tbFind_clicked(); } + +void OPMapGadgetWidget::setDefaultWaypointAltitude(qreal default_altitude) +{ + m_defaultWaypointAltitude = default_altitude; + if (model) { + model->setDefaultWaypointAltitude(default_altitude); + } +} + +void OPMapGadgetWidget::setDefaultWaypointVelocity(qreal default_velocity) +{ + m_defaultWaypointVelocity = default_velocity; + if (model) { + model->setDefaultWaypointVelocity(default_velocity); + } +} diff --git a/ground/gcs/src/plugins/opmap/opmapgadgetwidget.h b/ground/gcs/src/plugins/opmap/opmapgadgetwidget.h index 7b6d1c361..13d597258 100644 --- a/ground/gcs/src/plugins/opmap/opmapgadgetwidget.h +++ b/ground/gcs/src/plugins/opmap/opmapgadgetwidget.h @@ -113,6 +113,8 @@ public: void setMaxUpdateRate(int update_rate); void setHomePosition(QPointF pos); void setOverlayOpacity(qreal value); + void setDefaultWaypointAltitude(qreal default_altitude); + void setDefaultWaypointVelocity(qreal default_velocity); bool getGPSPositionSensor(double &latitude, double &longitude, double &altitude); signals: void defaultLocationAndZoomChanged(double lng, double lat, double zoom); @@ -212,6 +214,9 @@ private slots: void on_leFind_returnPressed(); private: + qreal m_defaultWaypointAltitude; + qreal m_defaultWaypointVelocity; + int m_min_zoom; int m_max_zoom; double m_heading; // uav heading diff --git a/ground/gcs/src/plugins/pathactioneditor/pathactioneditor.pro b/ground/gcs/src/plugins/pathactioneditor/pathactioneditor.pro index a528bc791..281d82a54 100644 --- a/ground/gcs/src/plugins/pathactioneditor/pathactioneditor.pro +++ b/ground/gcs/src/plugins/pathactioneditor/pathactioneditor.pro @@ -1,33 +1,34 @@ TEMPLATE = lib TARGET = PathActionEditor +QT += widgets + include(../../plugin.pri) include(../../plugins/coreplugin/coreplugin.pri) include(../../plugins/uavobjects/uavobjects.pri) -HEADERS += pathactioneditorgadget.h -HEADERS += pathactioneditorgadgetwidget.h -HEADERS += pathactioneditorgadgetfactory.h -HEADERS += pathactioneditorplugin.h -HEADERS += pathactioneditortreemodel.h -HEADERS += treeitem.h -HEADERS += fieldtreeitem.h -HEADERS += browseritemdelegate.h - -SOURCES += pathactioneditorgadget.cpp -SOURCES += pathactioneditorgadgetwidget.cpp -SOURCES += pathactioneditorgadgetfactory.cpp -SOURCES += pathactioneditorplugin.cpp -SOURCES += pathactioneditortreemodel.cpp -SOURCES += treeitem.cpp -SOURCES += fieldtreeitem.cpp -SOURCES += browseritemdelegate.cpp +HEADERS += \ + pathactioneditorgadget.h \ + pathactioneditorgadgetwidget.h \ + pathactioneditorgadgetfactory.h \ + pathactioneditorplugin.h \ + pathactioneditortreemodel.h \ + treeitem.h \ + fieldtreeitem.h \ + browseritemdelegate.h +SOURCES += \ + pathactioneditorgadget.cpp \ + pathactioneditorgadgetwidget.cpp \ + pathactioneditorgadgetfactory.cpp \ + pathactioneditorplugin.cpp \ + pathactioneditortreemodel.cpp \ + treeitem.cpp \ + fieldtreeitem.cpp \ + browseritemdelegate.cpp OTHER_FILES += pathactioneditor.pluginspec FORMS += pathactioneditor.ui RESOURCES += - - diff --git a/ground/gcs/src/plugins/pathactioneditor/pathactioneditorgadgetwidget.cpp b/ground/gcs/src/plugins/pathactioneditor/pathactioneditorgadgetwidget.cpp index bddce34bb..f09b29c97 100644 --- a/ground/gcs/src/plugins/pathactioneditor/pathactioneditorgadgetwidget.cpp +++ b/ground/gcs/src/plugins/pathactioneditor/pathactioneditorgadgetwidget.cpp @@ -25,6 +25,10 @@ */ #include "pathactioneditorgadgetwidget.h" #include "ui_pathactioneditor.h" +#include "extensionsystem/pluginmanager.h" +#include "uavobjectmanager.h" + +#include "browseritemdelegate.h" #include #include @@ -33,9 +37,6 @@ #include #include #include -#include "browseritemdelegate.h" - -#include "extensionsystem/pluginmanager.h" PathActionEditorGadgetWidget::PathActionEditorGadgetWidget(QWidget *parent) : QLabel(parent) { diff --git a/ground/gcs/src/plugins/pathactioneditor/pathactioneditorgadgetwidget.h b/ground/gcs/src/plugins/pathactioneditor/pathactioneditorgadgetwidget.h index d68836a8e..349da13b0 100644 --- a/ground/gcs/src/plugins/pathactioneditor/pathactioneditorgadgetwidget.h +++ b/ground/gcs/src/plugins/pathactioneditor/pathactioneditorgadgetwidget.h @@ -27,12 +27,14 @@ #ifndef PathActionEditorGADGETWIDGET_H_ #define PathActionEditorGADGETWIDGET_H_ +#include "pathactioneditortreemodel.h" + +#include "pathaction.h" +#include "waypoint.h" + #include #include #include -#include "pathaction.h" -#include "waypoint.h" -#include "pathactioneditortreemodel.h" class Ui_PathActionEditor; diff --git a/ground/gcs/src/plugins/pfdqml/PfdResources.qrc b/ground/gcs/src/plugins/pfdqml/PfdResources.qrc deleted file mode 100644 index 5c802bcc5..000000000 --- a/ground/gcs/src/plugins/pfdqml/PfdResources.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - fonts/PTS75F.ttf - - diff --git a/ground/gcs/src/plugins/pfdqml/osgearth.cpp b/ground/gcs/src/plugins/pfdqml/osgearth.cpp deleted file mode 100644 index 593e46fea..000000000 --- a/ground/gcs/src/plugins/pfdqml/osgearth.cpp +++ /dev/null @@ -1,376 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "osgearth.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "utils/pathutils.h" - -OsgEarthItem::OsgEarthItem(QDeclarativeItem *parent) : - QDeclarativeItem(parent), - m_renderer(0), - m_rendererThread(0), - m_currentSize(640, 480), - m_roll(0.0), - m_pitch(0.0), - m_yaw(0.0), - m_latitude(-28.5), - m_longitude(153.0), - m_altitude(400.0), - m_fieldOfView(90.0), - m_sceneFile(QLatin1String("/usr/share/osgearth/maps/srtm.earth")) -{ - setSize(m_currentSize); - setFlag(ItemHasNoContents, false); -} - -OsgEarthItem::~OsgEarthItem() -{ - if (m_renderer) { - m_rendererThread->exit(); - // wait up to 10 seconds for renderer thread to exit - m_rendererThread->wait(10 * 1000); - - delete m_renderer; - delete m_rendererThread; - } -} - -QString OsgEarthItem::resolvedSceneFile() const -{ - QString sceneFile = m_sceneFile; - - // try to resolve the relative scene file name: - if (!QFileInfo(sceneFile).exists()) { - QDeclarativeView *view = qobject_cast(scene()->views().first()); - - if (view) { - QUrl baseUrl = view->engine()->baseUrl(); - sceneFile = baseUrl.resolved(sceneFile).toLocalFile(); - } - } - - return sceneFile; -} - -void OsgEarthItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) -{ - Q_UNUSED(oldGeometry); - Q_UNUSED(newGeometry); - - // Dynamic gyometry changes are not supported yet, - // terrain is rendered to fixed geompetry and scalled for now - - /* - qDebug() << Q_FUNC_INFO << newGeometry; - - int w = qRound(newGeometry.width()); - int h = qRound(newGeometry.height()); - - if (m_currentSize != QSize(w,h) && m_gw.get()) { - m_currentSize = QSize(w,h); - - m_gw->getEventQueue()->windowResize(0,0,w,h); - m_gw->resized(0,0,w,h); - - osg::Camera *camera = m_viewer->getCamera(); - camera->setViewport(new osg::Viewport(0,0,w,h)); - camera->setProjectionMatrixAsPerspective(m_fieldOfView, qreal(w)/h, 1.0f, 10000.0f); - } - */ -} - -void OsgEarthItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *style, QWidget *widget) -{ - Q_UNUSED(painter); - Q_UNUSED(style); - QGLWidget *glWidget = qobject_cast(widget); - - if (!m_renderer) { - m_renderer = new OsgEarthItemRenderer(this, glWidget); - connect(m_renderer, SIGNAL(frameReady()), - this, SLOT(updateView()), Qt::QueuedConnection); - - m_rendererThread = new QThread(this); - m_renderer->moveToThread(m_rendererThread); - m_rendererThread->start(); - - QMetaObject::invokeMethod(m_renderer, "initScene", Qt::QueuedConnection); - return; - } - - QGLFramebufferObject *fbo = m_renderer->lastFrame(); - - if (glWidget && fbo) { - glWidget->drawTexture(boundingRect(), fbo->texture()); - } -} - -void OsgEarthItem::updateView() -{ - update(); -} - -void OsgEarthItem::updateFrame() -{ - if (m_renderer) { - m_renderer->markDirty(); - QMetaObject::invokeMethod(m_renderer, "updateFrame", Qt::QueuedConnection); - } -} - -void OsgEarthItem::setRoll(qreal arg) -{ - if (!qFuzzyCompare(m_roll, arg)) { - m_roll = arg; - updateFrame(); - emit rollChanged(arg); - } -} - -void OsgEarthItem::setPitch(qreal arg) -{ - if (!qFuzzyCompare(m_pitch, arg)) { - m_pitch = arg; - updateFrame(); - emit pitchChanged(arg); - } -} - -void OsgEarthItem::setYaw(qreal arg) -{ - if (!qFuzzyCompare(m_yaw, arg)) { - m_yaw = arg; - updateFrame(); - emit yawChanged(arg); - } -} - -void OsgEarthItem::setLatitude(double arg) -{ - // not sure qFuzzyCompare is accurate enough for geo coordinates - if (m_latitude != arg) { - m_latitude = arg; - emit latitudeChanged(arg); - } -} - -void OsgEarthItem::setLongitude(double arg) -{ - if (m_longitude != arg) { - m_longitude = arg; - emit longitudeChanged(arg); - } -} - -void OsgEarthItem::setAltitude(double arg) -{ - if (!qFuzzyCompare(m_altitude, arg)) { - m_altitude = arg; - emit altitudeChanged(arg); - } -} - -// ! Camera vertical field of view in degrees -void OsgEarthItem::setFieldOfView(qreal arg) -{ - if (!qFuzzyCompare(m_fieldOfView, arg)) { - m_fieldOfView = arg; - emit fieldOfViewChanged(arg); - - // it should be a queued call to OsgEarthItemRenderer instead - /*if (m_viewer.get()) { - m_viewer->getCamera()->setProjectionMatrixAsPerspective( - m_fieldOfView, - qreal(m_currentSize.width())/m_currentSize.height(), - 1.0f, 10000.0f); - }*/ - - updateFrame(); - } -} - -void OsgEarthItem::setSceneFile(QString arg) -{ - if (m_sceneFile != arg) { - m_sceneFile = arg; - emit sceneFileChanged(arg); - } -} - -OsgEarthItemRenderer::OsgEarthItemRenderer(OsgEarthItem *item, QGLWidget *glWidget) : - QObject(0), - m_item(item), - m_lastFboNumber(0), - m_currentSize(640, 480), - m_cameraDirty(false) -{ - // make a shared gl widget to avoid - // osg rendering to mess with qpainter state - // this runs in the main thread - m_glWidget = new QGLWidget(0, glWidget); - m_glWidget.data()->setAttribute(Qt::WA_PaintOutsidePaintEvent); - - for (int i = 0; i < FboCount; i++) { - m_fbo[i] = new QGLFramebufferObject(m_currentSize, QGLFramebufferObject::CombinedDepthStencil); - QPainter p(m_fbo[i]); - p.fillRect(0, 0, m_currentSize.width(), m_currentSize.height(), Qt::gray); - } -} - -OsgEarthItemRenderer::~OsgEarthItemRenderer() -{ - m_glWidget.data()->makeCurrent(); - for (int i = 0; i < FboCount; i++) { - delete m_fbo[i]; - m_fbo[i] = 0; - } - m_glWidget.data()->doneCurrent(); - - delete m_glWidget.data(); -} - -QGLFramebufferObject *OsgEarthItemRenderer::lastFrame() -{ - return m_fbo[m_lastFboNumber]; -} - -void OsgEarthItemRenderer::initScene() -{ - Q_ASSERT(!m_viewer.get()); - - int w = m_currentSize.width(); - int h = m_currentSize.height(); - - QString sceneFile = m_item->resolvedSceneFile(); - m_model = osgDB::readNodeFile(sceneFile.toStdString()); - - // setup caching - osgEarth::MapNode *mapNode = osgEarth::MapNode::findMapNode(m_model.get()); - if (!mapNode) { - qWarning() << Q_FUNC_INFO << sceneFile << " doesn't look like an osgEarth file"; - } - - m_gw = new osgViewer::GraphicsWindowEmbedded(0, 0, w, h); - - m_viewer = new osgViewer::Viewer(); - m_viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded); - m_viewer->setSceneData(m_model); - m_viewer->getDatabasePager()->setDoPreCompile(true); - - osg::Camera *camera = m_viewer->getCamera(); - camera->setViewport(new osg::Viewport(0, 0, w, h)); - camera->setGraphicsContext(m_gw); - camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - // configure the near/far so we don't clip things that are up close - camera->setNearFarRatio(0.00002); - camera->setProjectionMatrixAsPerspective(m_item->fieldOfView(), qreal(w) / h, 1.0f, 10000.0f); - - updateFrame(); -} - -void OsgEarthItemRenderer::updateFrame() -{ - if (!m_cameraDirty || !m_viewer.get() || m_glWidget.isNull()) { - return; - } - - m_glWidget.data()->makeCurrent(); - - // To find a camera view matrix, find placer matrixes for two points - // onr at requested coords and another latitude shifted by 0.01 deg - osgEarth::Util::ObjectPlacer placer(m_viewer->getSceneData()); - - m_cameraDirty = false; - - osg::Matrixd positionMatrix; - placer.createPlacerMatrix(m_item->latitude(), m_item->longitude(), m_item->altitude(), positionMatrix); - osg::Matrixd positionMatrix2; - placer.createPlacerMatrix(m_item->latitude() + 0.01, m_item->longitude(), m_item->altitude(), positionMatrix2); - - osg::Vec3d eye(0.0f, 0.0f, 0.0f); - osg::Vec3d viewVector(0.0f, 0.0f, 0.0f); - osg::Vec3d upVector(0.0f, 0.0f, 1.0f); - - eye = positionMatrix.preMult(eye); - upVector = positionMatrix.preMult(upVector); - upVector.normalize(); - viewVector = positionMatrix2.preMult(viewVector) - eye; - viewVector.normalize(); - viewVector *= 10.0; - - // TODO: clarify the correct rotation order, - // currently assuming yaw, pitch, roll - osg::Quat q; - q.makeRotate(-m_item->yaw() * M_PI / 180.0, upVector); - upVector = q * upVector; - viewVector = q * viewVector; - - osg::Vec3d side = viewVector ^ upVector; - q.makeRotate(m_item->pitch() * M_PI / 180.0, side); - upVector = q * upVector; - viewVector = q * viewVector; - - q.makeRotate(m_item->roll() * M_PI / 180.0, viewVector); - upVector = q * upVector; - viewVector = q * viewVector; - - osg::Vec3d center = eye + viewVector; - -// qDebug() << "e " << eye.x() << eye.y() << eye.z(); -// qDebug() << "c " << center.x() << center.y() << center.z(); -// qDebug() << "up" << upVector.x() << upVector.y() << upVector.z(); - - m_viewer->getCamera()->setViewMatrixAsLookAt(osg::Vec3d(eye.x(), eye.y(), eye.z()), - osg::Vec3d(center.x(), center.y(), center.z()), - osg::Vec3d(upVector.x(), upVector.y(), upVector.z())); - - { - QGLFramebufferObject *fbo = m_fbo[(m_lastFboNumber + 1) % FboCount]; - QPainter fboPainter(fbo); - fboPainter.beginNativePainting(); - m_viewer->frame(); - fboPainter.endNativePainting(); - } - m_glWidget.data()->doneCurrent(); - - m_lastFboNumber = (m_lastFboNumber + 1) % FboCount; - - emit frameReady(); -} diff --git a/ground/gcs/src/plugins/pfdqml/osgearth.h b/ground/gcs/src/plugins/pfdqml/osgearth.h deleted file mode 100644 index 332c27156..000000000 --- a/ground/gcs/src/plugins/pfdqml/osgearth.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef OSGEARTH_H -#define OSGEARTH_H - -#include - -#include -#include - -class QGLFramebufferObject; -class QGLWidget; -class OsgEarthItemRenderer; - -class OsgEarthItem : public QDeclarativeItem { - Q_OBJECT Q_DISABLE_COPY(OsgEarthItem) - - Q_PROPERTY(QString sceneFile READ sceneFile WRITE setSceneFile NOTIFY sceneFileChanged) - Q_PROPERTY(qreal fieldOfView READ fieldOfView WRITE setFieldOfView NOTIFY fieldOfViewChanged) - - Q_PROPERTY(qreal roll READ roll WRITE setRoll NOTIFY rollChanged) - Q_PROPERTY(qreal pitch READ pitch WRITE setPitch NOTIFY pitchChanged) - Q_PROPERTY(qreal yaw READ yaw WRITE setYaw NOTIFY yawChanged) - - Q_PROPERTY(double latitude READ latitude WRITE setLatitude NOTIFY latitudeChanged) - Q_PROPERTY(double longitude READ longitude WRITE setLongitude NOTIFY longitudeChanged) - Q_PROPERTY(double altitude READ altitude WRITE setAltitude NOTIFY altitudeChanged) - -public: - OsgEarthItem(QDeclarativeItem *parent = 0); - ~OsgEarthItem(); - - QString sceneFile() const - { - return m_sceneFile; - } - QString resolvedSceneFile() const; - qreal fieldOfView() const - { - return m_fieldOfView; - } - - qreal roll() const - { - return m_roll; - } - qreal pitch() const - { - return m_pitch; - } - qreal yaw() const - { - return m_yaw; - } - - double latitude() const - { - return m_latitude; - } - double longitude() const - { - return m_longitude; - } - double altitude() const - { - return m_altitude; - } - -protected: - void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); - void paint(QPainter *painter, const QStyleOptionGraphicsItem *style, QWidget *widget); - -public slots: - void updateView(); - void setSceneFile(QString arg); - void setFieldOfView(qreal arg); - - void setRoll(qreal arg); - void setPitch(qreal arg); - void setYaw(qreal arg); - - void setLatitude(double arg); - void setLongitude(double arg); - void setAltitude(double arg); - -signals: - void rollChanged(qreal arg); - void pitchChanged(qreal arg); - void yawChanged(qreal arg); - - void latitudeChanged(double arg); - void longitudeChanged(double arg); - void altitudeChanged(double arg); - - void sceneFileChanged(QString arg); - void fieldOfViewChanged(qreal arg); - -private slots: - void updateFrame(); - -private: - OsgEarthItemRenderer *m_renderer; - QThread *m_rendererThread; - - QSize m_currentSize; - - qreal m_roll; - qreal m_pitch; - qreal m_yaw; - - double m_latitude; - double m_longitude; - double m_altitude; - - qreal m_fieldOfView; - QString m_sceneFile; -}; - -class OsgEarthItemRenderer : public QObject { - Q_OBJECT -public: - OsgEarthItemRenderer(OsgEarthItem *item, QGLWidget *glWidget); - ~OsgEarthItemRenderer(); - - QGLFramebufferObject *lastFrame(); - void markDirty() - { - m_cameraDirty = true; - } - -public slots: - void initScene(); - void updateFrame(); - -signals: - void frameReady(); - -private: - enum { FboCount = 3 }; - OsgEarthItem *m_item; - - osg::ref_ptr m_viewer; - osg::ref_ptr m_gw; - osg::ref_ptr m_model; - QWeakPointer m_glWidget; - - QGLFramebufferObject *m_fbo[FboCount]; - int m_lastFboNumber; - - QSize m_currentSize; - - bool m_cameraDirty; -}; - -QML_DECLARE_TYPE(OsgEarthItem) - -#endif // OSGEARTH_H diff --git a/ground/gcs/src/plugins/modelview/modelviewgadget.h b/ground/gcs/src/plugins/pfdqml/pfdqml.h similarity index 52% rename from ground/gcs/src/plugins/modelview/modelviewgadget.h rename to ground/gcs/src/plugins/pfdqml/pfdqml.h index 7ca4282aa..30510e1e4 100644 --- a/ground/gcs/src/plugins/modelview/modelviewgadget.h +++ b/ground/gcs/src/plugins/pfdqml/pfdqml.h @@ -1,15 +1,15 @@ /** ****************************************************************************** * - * @file modelviewgadget.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @addtogroup GCSPlugins GCS Plugins + * @file pfdqml.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @addtogroup * @{ - * @addtogroup ModelViewPlugin ModelView Plugin + * @addtogroup * @{ - * @brief A gadget that displays a 3D representation of the UAV - *****************************************************************************/ -/* + * @brief + *****************************************************************************//* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or @@ -25,34 +25,36 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef MODELVIEWGADGET_H_ -#define MODELVIEWGADGET_H_ +#ifndef PFDQML_H_ +#define PFDQML_H_ -#include -#include "modelviewgadgetwidget.h" +#include +#include -class IUAVGadget; -class QWidget; -class QString; -class ModelViewGadgetWidget; - -using namespace Core; - -class ModelViewGadget : public Core::IUAVGadget { +class ModelSelectionMode : public QObject { Q_OBJECT + public: - ModelViewGadget(QString classId, ModelViewGadgetWidget *widget, QWidget *parent = 0); - ~ModelViewGadget(); + enum Enum { Auto, Predefined }; + Q_ENUMS(Enum) // TODO switch to Q_ENUM once on Qt 5.5 - QWidget *widget() + static void registerQMLTypes() { - return m_widget; + qmlRegisterType("Pfd", 1, 0, "ModelSelectionMode"); } - void loadConfiguration(IUAVGadgetConfiguration *config); - -private: - ModelViewGadgetWidget *m_widget; }; +class TimeMode : public QObject { + Q_OBJECT -#endif // MODELVIEWGADGET_H_ +public: + enum Enum { Local, Predefined }; + Q_ENUMS(Enum) // TODO switch to Q_ENUM once on Qt 5.5 + + static void registerQMLTypes() + { + qmlRegisterType("Pfd", 1, 0, "TimeMode"); + } +}; + +#endif // PFDQML_H_ diff --git a/ground/gcs/src/plugins/pfdqml/pfdqml.pro b/ground/gcs/src/plugins/pfdqml/pfdqml.pro index e9e63e1a0..3af6c1ab1 100644 --- a/ground/gcs/src/plugins/pfdqml/pfdqml.pro +++ b/ground/gcs/src/plugins/pfdqml/pfdqml.pro @@ -1,17 +1,14 @@ TEMPLATE = lib TARGET = PfdQml -QT += svg -QT += opengl -QT += qml quick -OSG { - DEFINES += USE_OSG -} + +QT += svg qml quick quickwidgets include(../../plugin.pri) -include(../../plugins/coreplugin/coreplugin.pri) include(pfdqml_dependencies.pri) HEADERS += \ + pfdqml.h \ + pfdqmlcontext.h \ pfdqmlplugin.h \ pfdqmlgadget.h \ pfdqmlgadgetwidget.h \ @@ -20,6 +17,7 @@ HEADERS += \ pfdqmlgadgetoptionspage.h SOURCES += \ + pfdqmlcontext.cpp \ pfdqmlplugin.cpp \ pfdqmlgadget.cpp \ pfdqmlgadgetfactory.cpp \ @@ -27,19 +25,6 @@ SOURCES += \ pfdqmlgadgetconfiguration.cpp \ pfdqmlgadgetoptionspage.cpp - -contains(DEFINES,USE_OSG) { - LIBS += -losg -losgUtil -losgViewer -losgQt -losgDB -lOpenThreads -losgGA - LIBS += -losgEarth -losgEarthFeatures -losgEarthUtil - - HEADERS += osgearth.h - SOURCES += osgearth.cpp -} - OTHER_FILES += PfdQml.pluginspec FORMS += pfdqmlgadgetoptionspage.ui - -RESOURCES += \ - PfdResources.qrc - diff --git a/ground/gcs/src/plugins/pfdqml/pfdqml_dependencies.pri b/ground/gcs/src/plugins/pfdqml/pfdqml_dependencies.pri index 9aae5fbc0..bd0c552ce 100644 --- a/ground/gcs/src/plugins/pfdqml/pfdqml_dependencies.pri +++ b/ground/gcs/src/plugins/pfdqml/pfdqml_dependencies.pri @@ -1 +1,7 @@ +include(../../plugins/coreplugin/coreplugin.pri) include(../../plugins/uavobjects/uavobjects.pri) +include(../../libs/utils/utils.pri) + +# TODO get rid of this dependency +# it is only needed for one initialization call in pfdqmlplugin.cpp +include(../../libs/osgearth/osgearth.pri) diff --git a/ground/gcs/src/plugins/pfdqml/pfdqmlcontext.cpp b/ground/gcs/src/plugins/pfdqml/pfdqmlcontext.cpp new file mode 100644 index 000000000..22aa9bf81 --- /dev/null +++ b/ground/gcs/src/plugins/pfdqml/pfdqmlcontext.cpp @@ -0,0 +1,390 @@ +/** + ****************************************************************************** + * + * @file pfdqmlcontext.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************//* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "pfdqmlcontext.h" + +#include "extensionsystem/pluginmanager.h" +#include "uavobject.h" +#include "uavobjectmanager.h" +#include "utils/stringutils.h" +#include "utils/pathutils.h" + +#include "flightbatterysettings.h" + +#include +#include +#include + +const QString PfdQmlContext::CONTEXT_PROPERTY_NAME = "pfdContext"; + +PfdQmlContext::PfdQmlContext(QObject *parent) : QObject(parent), + m_speedUnit("m/s"), + m_speedFactor(1.0), + m_altitudeUnit("m"), + m_altitudeFactor(1.0), + m_terrainEnabled(false), + m_terrainFile(""), + m_latitude(39.657380), + m_longitude(19.805158), + m_altitude(100), + m_timeMode(TimeMode::Local), + m_dateTime(QDateTime()), + m_minAmbientLight(0.03), + m_modelFile(""), + m_modelIndex(0), + m_backgroundImageFile("") +{ + addModelDir("helis"); + addModelDir("multi"); + addModelDir("planes"); +} + +PfdQmlContext::~PfdQmlContext() +{} + +QString PfdQmlContext::speedUnit() const +{ + return m_speedUnit; +} + +void PfdQmlContext::setSpeedUnit(QString unit) +{ + if (m_speedUnit != unit) { + m_speedUnit = unit; + emit speedUnitChanged(speedUnit()); + } +} + +double PfdQmlContext::speedFactor() const +{ + return m_speedFactor; +} + +void PfdQmlContext::setSpeedFactor(double factor) +{ + if (m_speedFactor != factor) { + m_speedFactor = factor; + emit speedFactorChanged(speedFactor()); + } +} + +QString PfdQmlContext::altitudeUnit() const +{ + return m_altitudeUnit; +} + +void PfdQmlContext::setAltitudeUnit(QString unit) +{ + if (m_altitudeUnit != unit) { + m_altitudeUnit = unit; + emit altitudeUnitChanged(altitudeUnit()); + } +} + +double PfdQmlContext::altitudeFactor() const +{ + return m_altitudeFactor; +} + +void PfdQmlContext::setAltitudeFactor(double factor) +{ + if (m_altitudeFactor != factor) { + m_altitudeFactor = factor; + emit altitudeFactorChanged(altitudeFactor()); + } +} + +bool PfdQmlContext::terrainEnabled() const +{ + return m_terrainEnabled; +} + +void PfdQmlContext::setTerrainEnabled(bool arg) +{ + if (m_terrainEnabled != arg) { + m_terrainEnabled = arg; + emit terrainEnabledChanged(terrainEnabled()); + } +} + +QString PfdQmlContext::terrainFile() const +{ + return m_terrainFile; +} + +void PfdQmlContext::setTerrainFile(const QString &arg) +{ + if (m_terrainFile != arg) { + m_terrainFile = arg; + emit terrainFileChanged(terrainFile()); + } +} + +double PfdQmlContext::latitude() const +{ + return m_latitude; +} + +void PfdQmlContext::setLatitude(double arg) +{ + if (m_latitude != arg) { + m_latitude = arg; + emit latitudeChanged(latitude()); + } +} + +double PfdQmlContext::longitude() const +{ + return m_longitude; +} + +void PfdQmlContext::setLongitude(double arg) +{ + if (m_longitude != arg) { + m_longitude = arg; + emit longitudeChanged(longitude()); + } +} + +double PfdQmlContext::altitude() const +{ + return m_altitude; +} + +void PfdQmlContext::setAltitude(double arg) +{ + if (m_altitude != arg) { + m_altitude = arg; + emit altitudeChanged(altitude()); + } +} + +TimeMode::Enum PfdQmlContext::timeMode() const +{ + return m_timeMode; +} + +void PfdQmlContext::setTimeMode(TimeMode::Enum arg) +{ + if (m_timeMode != arg) { + m_timeMode = arg; + emit timeModeChanged(timeMode()); + } +} + +QDateTime PfdQmlContext::dateTime() const +{ + return m_dateTime; +} + +void PfdQmlContext::setDateTime(QDateTime arg) +{ + if (m_dateTime != arg) { + m_dateTime = arg; + emit dateTimeChanged(dateTime()); + } +} + +double PfdQmlContext::minimumAmbientLight() const +{ + return m_minAmbientLight; +} + +void PfdQmlContext::setMinimumAmbientLight(double arg) +{ + if (m_minAmbientLight != arg) { + m_minAmbientLight = arg; + emit minimumAmbientLightChanged(minimumAmbientLight()); + } +} + +QString PfdQmlContext::modelFile() const +{ + return m_modelFile; +} + +void PfdQmlContext::setModelFile(const QString &arg) +{ + if (m_modelFile != arg) { + m_modelFile = arg; + m_modelIndex = m_modelFileList.indexOf(m_modelFile); + if (m_modelIndex == -1) { + m_modelIndex = 0; + } + emit modelFileChanged(modelFile()); + } +} + +void PfdQmlContext::nextModel() +{ + m_modelIndex = (m_modelIndex + 1) % m_modelFileList.length(); + setModelFile(m_modelFileList[m_modelIndex]); +} + +void PfdQmlContext::previousModel() +{ + m_modelIndex = (m_modelFileList.length() + m_modelIndex - 1) % m_modelFileList.length(); + setModelFile(m_modelFileList[m_modelIndex]); +} + +QStringList PfdQmlContext::modelFileList() const +{ + return m_modelFileList; +} + +QString PfdQmlContext::backgroundImageFile() const +{ + return m_backgroundImageFile; +} + +void PfdQmlContext::setBackgroundImageFile(const QString &arg) +{ + if (m_backgroundImageFile != arg) { + m_backgroundImageFile = arg; + emit backgroundImageFileChanged(backgroundImageFile()); + } +} + +void PfdQmlContext::resetConsumedEnergy() +{ + ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); + UAVObjectManager *uavoManager = pm->getObject(); + + Q_ASSERT(uavoManager); + + FlightBatterySettings *batterySettings = FlightBatterySettings::GetInstance(uavoManager); + + batterySettings->setResetConsumedEnergy(true); + batterySettings->setData(batterySettings->getData()); +} + +void PfdQmlContext::loadConfiguration(PfdQmlGadgetConfiguration *config) +{ + setSpeedFactor(config->speedFactor()); + setSpeedUnit(config->speedUnit()); + setAltitudeFactor(config->altitudeFactor()); + setAltitudeUnit(config->altitudeUnit()); + + // terrain + setTerrainEnabled(config->terrainEnabled()); + setTerrainFile(config->terrainFile()); + + setLatitude(config->latitude()); + setLongitude(config->longitude()); + setAltitude(config->altitude()); + + // sky + setTimeMode(config->timeMode()); + setDateTime(config->dateTime()); + setMinimumAmbientLight(config->minAmbientLight()); + + // model + setModelFile(config->modelFile()); + + // background image + setBackgroundImageFile(config->backgroundImageFile()); +} + + +void PfdQmlContext::saveState(QSettings *settings) +{ + settings->setValue("modelFile", modelFile()); +} + +void PfdQmlContext::restoreState(QSettings *settings) +{ + QString file = settings->value("modelFile").toString(); + + if (!file.isEmpty()) { + setModelFile(file); + } +} + +void PfdQmlContext::apply(QQmlContext *context) +{ + QStringList objectsToExport; + + objectsToExport << + "VelocityState" << + "PositionState" << + "AttitudeState" << + "AccelState" << + "VelocityDesired" << + "PathDesired" << + "GPSPositionSensor" << + "GPSSatellites" << + "HomeLocation" << + "GCSTelemetryStats" << + "SystemAlarms" << + "NedAccel" << + "ActuatorDesired" << + "TakeOffLocation" << + "PathPlan" << + "WaypointActive" << + "OPLinkStatus" << + "FlightStatus" << + "SystemStats" << + "StabilizationDesired" << + "VtolPathFollowerSettings" << + "HwSettings" << + "ManualControlCommand" << + "SystemSettings" << + "RevoSettings" << + "MagState" << + "AuxMagSettings" << + "FlightBatterySettings" << + "FlightBatteryState" << + "ReceiverStatus"; + + ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); + UAVObjectManager *objManager = pm->getObject(); + + foreach(const QString &objectName, objectsToExport) { + UAVObject *object = objManager->getObject(objectName); + + if (object) { + // expose object with lower camel case name + context->setContextProperty(Utils::toLowerCamelCase(objectName), object); + } else { + qWarning() << "PfdQmlContext::apply - failed to load object" << objectName; + } + } + + // expose this context to Qml + context->setContextProperty(CONTEXT_PROPERTY_NAME, this); +} + +void PfdQmlContext::addModelDir(QString dir) +{ + QDirIterator it(Utils::GetDataPath() + "models/" + dir, QStringList("*.3ds"), QDir::NoFilter, QDirIterator::Subdirectories); + + while (it.hasNext()) { + QString file = QDir::toNativeSeparators(it.next()); + // qDebug() << file; + m_modelFileList.append(file); + } +} diff --git a/ground/gcs/src/plugins/pfdqml/pfdqmlcontext.h b/ground/gcs/src/plugins/pfdqml/pfdqmlcontext.h new file mode 100644 index 000000000..ca0e88730 --- /dev/null +++ b/ground/gcs/src/plugins/pfdqml/pfdqmlcontext.h @@ -0,0 +1,161 @@ +/** + ****************************************************************************** + * + * @file pfdqmlcontext.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************//* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PFDQMLCONTEXT_H_ +#define PFDQMLCONTEXT_H_ + +#include "pfdqml.h" +#include "pfdqmlgadgetconfiguration.h" + +class QQmlContext; +class QSettings; + +class PfdQmlContext : public QObject { + Q_OBJECT Q_PROPERTY(QString speedUnit READ speedUnit WRITE setSpeedUnit NOTIFY speedUnitChanged) + Q_PROPERTY(double speedFactor READ speedFactor WRITE setSpeedFactor NOTIFY speedFactorChanged) + Q_PROPERTY(QString altitudeUnit READ altitudeUnit WRITE setAltitudeUnit NOTIFY altitudeUnitChanged) + Q_PROPERTY(double altitudeFactor READ altitudeFactor WRITE setAltitudeFactor NOTIFY altitudeFactorChanged) + + // terrain + Q_PROPERTY(bool terrainEnabled READ terrainEnabled WRITE setTerrainEnabled NOTIFY terrainEnabledChanged) + Q_PROPERTY(QString terrainFile READ terrainFile WRITE setTerrainFile NOTIFY terrainFileChanged) + + Q_PROPERTY(double latitude READ latitude WRITE setLatitude NOTIFY latitudeChanged) + Q_PROPERTY(double longitude READ longitude WRITE setLongitude NOTIFY longitudeChanged) + Q_PROPERTY(double altitude READ altitude WRITE setAltitude NOTIFY altitudeChanged) + + Q_PROPERTY(TimeMode::Enum timeMode READ timeMode WRITE setTimeMode NOTIFY timeModeChanged) + Q_PROPERTY(QDateTime dateTime READ dateTime WRITE setDateTime NOTIFY dateTimeChanged) + Q_PROPERTY(double minimumAmbientLight READ minimumAmbientLight WRITE setMinimumAmbientLight NOTIFY minimumAmbientLightChanged) + + // model + Q_PROPERTY(QString modelFile READ modelFile NOTIFY modelFileChanged) + Q_PROPERTY(QStringList modelFileList READ modelFileList CONSTANT FINAL) + + // background + Q_PROPERTY(QString backgroundImageFile READ backgroundImageFile WRITE setBackgroundImageFile NOTIFY backgroundImageFileChanged) + +public: + PfdQmlContext(QObject *parent = 0); + virtual ~PfdQmlContext(); + + QString speedUnit() const; + void setSpeedUnit(QString unit); + double speedFactor() const; + void setSpeedFactor(double factor); + QString altitudeUnit() const; + void setAltitudeUnit(QString unit); + double altitudeFactor() const; + void setAltitudeFactor(double factor); + + bool terrainEnabled() const; + void setTerrainEnabled(bool arg); + QString terrainFile() const; + void setTerrainFile(const QString &arg); + + double latitude() const; + void setLatitude(double arg); + double longitude() const; + void setLongitude(double arg); + double altitude() const; + void setAltitude(double arg); + + TimeMode::Enum timeMode() const; + void setTimeMode(TimeMode::Enum arg); + QDateTime dateTime() const; + void setDateTime(QDateTime arg); + double minimumAmbientLight() const; + void setMinimumAmbientLight(double arg); + + // model + QString modelFile() const; + void setModelFile(const QString &arg); + QStringList modelFileList() const; + Q_INVOKABLE void nextModel(); + Q_INVOKABLE void previousModel(); + + // background + QString backgroundImageFile() const; + void setBackgroundImageFile(const QString &arg); + + Q_INVOKABLE void resetConsumedEnergy(); + + void loadConfiguration(PfdQmlGadgetConfiguration *config); + void saveState(QSettings *); + void restoreState(QSettings *); + + void apply(QQmlContext *context); + +signals: + void speedUnitChanged(QString arg); + void speedFactorChanged(double arg); + void altitudeUnitChanged(QString arg); + void altitudeFactorChanged(double arg); + + void terrainEnabledChanged(bool arg); + void terrainFileChanged(QString arg); + + void latitudeChanged(double arg); + void longitudeChanged(double arg); + void altitudeChanged(double arg); + + void timeModeChanged(TimeMode::Enum arg); + void dateTimeChanged(QDateTime arge); + void minimumAmbientLightChanged(double arg); + + void modelFileChanged(QString arg); + void backgroundImageFileChanged(QString arg); + +private: + // constants + static const QString CONTEXT_PROPERTY_NAME; + + QString m_speedUnit; + double m_speedFactor; + QString m_altitudeUnit; + double m_altitudeFactor; + + bool m_terrainEnabled; + QString m_terrainFile; + + double m_latitude; + double m_longitude; + double m_altitude; + + TimeMode::Enum m_timeMode; + QDateTime m_dateTime; + double m_minAmbientLight; + + QString m_modelFile; + int m_modelIndex; + QStringList m_modelFileList; + + QString m_backgroundImageFile; + + void addModelDir(QString dir); +}; +#endif /* PFDQMLCONTEXT_H_ */ diff --git a/ground/gcs/src/plugins/pfdqml/pfdqmlgadget.cpp b/ground/gcs/src/plugins/pfdqml/pfdqmlgadget.cpp index e28257ff5..176641260 100644 --- a/ground/gcs/src/plugins/pfdqml/pfdqmlgadget.cpp +++ b/ground/gcs/src/plugins/pfdqml/pfdqmlgadget.cpp @@ -1,4 +1,15 @@ -/* +/** + ****************************************************************************** + * + * @file pfdqmlgadget.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************//* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or @@ -18,51 +29,35 @@ #include "pfdqmlgadgetwidget.h" #include "pfdqmlgadgetconfiguration.h" -PfdQmlGadget::PfdQmlGadget(QString classId, PfdQmlGadgetWidget *widget, QWidget *parent) : - IUAVGadget(classId, parent), - m_widget(widget) +PfdQmlGadget::PfdQmlGadget(QString classId, QWidget *parent) : + IUAVGadget(classId, parent) { - m_container = NULL; - m_parent = parent; + m_qmlGadgetWidget = new PfdQmlGadgetWidget(parent); } PfdQmlGadget::~PfdQmlGadget() { - delete m_widget; + delete m_qmlGadgetWidget; +} + +QWidget *PfdQmlGadget::widget() +{ + return m_qmlGadgetWidget; } -/* - This is called when a configuration is loaded, and updates the plugin's settings. - Careful: the plugin is already drawn before the loadConfiguration method is called the - first time, so you have to be careful not to assume all the plugin values are initialized - the first time you use them - */ void PfdQmlGadget::loadConfiguration(IUAVGadgetConfiguration *config) { PfdQmlGadgetConfiguration *m = qobject_cast(config); - m_widget->setOpenGLEnabled(m->openGLEnabled()); - m_widget->setQmlFile(m->qmlFile()); - m_widget->setEarthFile(m->earthFile()); - m_widget->setTerrainEnabled(m->terrainEnabled()); - m_widget->setActualPositionUsed(m->actualPositionUsed()); - m_widget->setLatitude(m->latitude()); - m_widget->setLongitude(m->longitude()); - m_widget->setAltitude(m->altitude()); - m_widget->setSpeedFactor(m->speedFactor()); - m_widget->setSpeedUnit(m->speedUnit()); - m_widget->setAltitudeFactor(m->altitudeFactor()); - m_widget->setAltitudeUnit(m->altitudeUnit()); - - // setting OSGEARTH_CACHE_ONLY seems to work the most reliably - // between osgEarth versions I tried - if (m->cacheOnly()) { - qputenv("OSGEARTH_CACHE_ONLY", "true"); - } else { -#ifdef Q_OS_WIN32 - qputenv("OSGEARTH_CACHE_ONLY", ""); -#else - unsetenv("OSGEARTH_CACHE_ONLY"); -#endif - } + m_qmlGadgetWidget->loadConfiguration(m); +} + +void PfdQmlGadget::saveState(QSettings *settings) +{ + m_qmlGadgetWidget->saveState(settings); +} + +void PfdQmlGadget::restoreState(QSettings *settings) +{ + m_qmlGadgetWidget->restoreState(settings); } diff --git a/ground/gcs/src/plugins/pfdqml/pfdqmlgadget.h b/ground/gcs/src/plugins/pfdqml/pfdqmlgadget.h index 5e6fa96a6..812d17547 100644 --- a/ground/gcs/src/plugins/pfdqml/pfdqmlgadget.h +++ b/ground/gcs/src/plugins/pfdqml/pfdqmlgadget.h @@ -1,4 +1,15 @@ -/* +/** + ****************************************************************************** + * + * @file pfdqmlgadget.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************//* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or @@ -17,38 +28,29 @@ #ifndef PFDQMLGADGET_H_ #define PFDQMLGADGET_H_ -#include -#include "pfdqmlgadgetwidget.h" +#include "pfdqmlgadget.h" + +#include -class IUAVGadget; -class QWidget; -class QString; class PfdQmlGadgetWidget; using namespace Core; class PfdQmlGadget : public Core::IUAVGadget { Q_OBJECT -public: - PfdQmlGadget(QString classId, PfdQmlGadgetWidget *widget, QWidget *parent = 0); - ~PfdQmlGadget(); - QWidget *widget() - { - if (!m_container) { - m_container = QWidget::createWindowContainer(m_widget, m_parent); - m_container->setMinimumSize(64, 64); - m_container->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - } - return m_container; - } +public: + PfdQmlGadget(QString classId, QWidget *parent = 0); + virtual ~PfdQmlGadget(); + + QWidget *widget(); + void loadConfiguration(IUAVGadgetConfiguration *config); + void saveState(QSettings *); + void restoreState(QSettings *); private: - QWidget *m_container; - QWidget *m_parent; - PfdQmlGadgetWidget *m_widget; + PfdQmlGadgetWidget *m_qmlGadgetWidget; }; - #endif // PFDQMLGADGET_H_ diff --git a/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetconfiguration.cpp b/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetconfiguration.cpp index dd4638f50..f6df1b985 100644 --- a/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetconfiguration.cpp +++ b/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetconfiguration.cpp @@ -1,4 +1,15 @@ -/* +/** + ****************************************************************************** + * + * @file pfdqmlgadgetconfiguration.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************//* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or @@ -24,16 +35,21 @@ PfdQmlGadgetConfiguration::PfdQmlGadgetConfiguration(QString classId, QSettings *qSettings, QObject *parent) : IUAVGadgetConfiguration(classId, parent), m_qmlFile("Unknown"), - m_earthFile("Unknown"), - m_openGLEnabled(true), + m_speedFactor(1.0), + m_altitudeFactor(1.0), m_terrainEnabled(false), - m_actualPositionUsed(false), + m_terrainFile("Unknown"), + m_cacheOnly(false), m_latitude(0), m_longitude(0), m_altitude(0), - m_cacheOnly(false), - m_speedFactor(1.0), - m_altitudeFactor(1.0) + m_timeMode(TimeMode::Local), + m_dateTime(QDateTime()), + m_minAmbientLight(0), + m_modelEnabled(false), + m_modelFile("Unknown"), + m_modelSelectionMode(ModelSelectionMode::Auto), + m_backgroundImageFile("Unknown") { m_speedMap[1.0] = "m/s"; m_speedMap[3.6] = "km/h"; @@ -45,21 +61,36 @@ PfdQmlGadgetConfiguration::PfdQmlGadgetConfiguration(QString classId, QSettings // if a saved configuration exists load it if (qSettings != 0) { - m_qmlFile = qSettings->value("qmlFile").toString(); - m_qmlFile = Utils::InsertDataPath(m_qmlFile); + m_qmlFile = qSettings->value("qmlFile").toString(); + m_qmlFile = Utils::InsertDataPath(m_qmlFile); - m_earthFile = qSettings->value("earthFile").toString(); - m_earthFile = Utils::InsertDataPath(m_earthFile); + m_speedFactor = qSettings->value("speedFactor").toDouble(); + m_altitudeFactor = qSettings->value("altitudeFactor").toDouble(); - m_openGLEnabled = qSettings->value("openGLEnabled", true).toBool(); - m_terrainEnabled = qSettings->value("terrainEnabled").toBool(); - m_actualPositionUsed = qSettings->value("actualPositionUsed").toBool(); - m_latitude = qSettings->value("latitude").toDouble(); - m_longitude = qSettings->value("longitude").toDouble(); - m_altitude = qSettings->value("altitude").toDouble(); - m_cacheOnly = qSettings->value("cacheOnly").toBool(); - m_speedFactor = qSettings->value("speedFactor").toDouble(); - m_altitudeFactor = qSettings->value("altitudeFactor").toDouble(); + // terrain + m_terrainEnabled = qSettings->value("terrainEnabled").toBool(); + m_terrainFile = qSettings->value("earthFile").toString(); + m_terrainFile = Utils::InsertDataPath(m_terrainFile); + m_cacheOnly = qSettings->value("cacheOnly").toBool(); + + m_latitude = qSettings->value("latitude").toDouble(); + m_longitude = qSettings->value("longitude").toDouble(); + m_altitude = qSettings->value("altitude").toDouble(); + + // sky + m_timeMode = static_cast(qSettings->value("timeMode").toUInt()); + m_dateTime = qSettings->value("dateTime").toDateTime(); + m_minAmbientLight = qSettings->value("minAmbientLight").toDouble(); + + // model + m_modelEnabled = qSettings->value("modelEnabled").toBool(); + m_modelSelectionMode = static_cast(qSettings->value("modelSelectionMode").toUInt()); + m_modelFile = qSettings->value("modelFile").toString(); + m_modelFile = Utils::InsertDataPath(m_modelFile); + + // background image + m_backgroundImageFile = qSettings->value("backgroundImageFile").toString(); + m_backgroundImageFile = Utils::InsertDataPath(m_backgroundImageFile); } } @@ -71,17 +102,32 @@ IUAVGadgetConfiguration *PfdQmlGadgetConfiguration::clone() { PfdQmlGadgetConfiguration *m = new PfdQmlGadgetConfiguration(this->classId()); - m->m_qmlFile = m_qmlFile; - m->m_openGLEnabled = m_openGLEnabled; - m->m_earthFile = m_earthFile; - m->m_terrainEnabled = m_terrainEnabled; - m->m_actualPositionUsed = m_actualPositionUsed; - m->m_latitude = m_latitude; - m->m_longitude = m_longitude; - m->m_altitude = m_altitude; - m->m_cacheOnly = m_cacheOnly; - m->m_speedFactor = m_speedFactor; - m->m_altitudeFactor = m_altitudeFactor; + m->m_qmlFile = m_qmlFile; + + m->m_speedFactor = m_speedFactor; + m->m_altitudeFactor = m_altitudeFactor; + + // terrain + m->m_terrainEnabled = m_terrainEnabled; + m->m_terrainFile = m_terrainFile; + m->m_cacheOnly = m_cacheOnly; + + m->m_latitude = m_latitude; + m->m_longitude = m_longitude; + m->m_altitude = m_altitude; + + // sky + m->m_timeMode = m_timeMode; + m->m_dateTime = m_dateTime; + m->m_minAmbientLight = m_minAmbientLight; + + // model + m->m_modelEnabled = m_modelEnabled; + m->m_modelSelectionMode = m_modelSelectionMode; + m->m_modelFile = m_modelFile; + + // background image + m->m_backgroundImageFile = m_backgroundImageFile; return m; } @@ -92,19 +138,35 @@ IUAVGadgetConfiguration *PfdQmlGadgetConfiguration::clone() */ void PfdQmlGadgetConfiguration::saveConfig(QSettings *qSettings) const { - QString qmlFile = Utils::RemoveDataPath(m_qmlFile); + QString qmlFile = Utils::RemoveDataPath(m_qmlFile); qSettings->setValue("qmlFile", qmlFile); - QString earthFile = Utils::RemoveDataPath(m_earthFile); - qSettings->setValue("earthFile", earthFile); - qSettings->setValue("openGLEnabled", m_openGLEnabled); + qSettings->setValue("speedFactor", m_speedFactor); + qSettings->setValue("altitudeFactor", m_altitudeFactor); + + // terrain qSettings->setValue("terrainEnabled", m_terrainEnabled); - qSettings->setValue("actualPositionUsed", m_actualPositionUsed); + QString terrainFile = Utils::RemoveDataPath(m_terrainFile); + qSettings->setValue("earthFile", terrainFile); + qSettings->setValue("cacheOnly", m_cacheOnly); + qSettings->setValue("latitude", m_latitude); qSettings->setValue("longitude", m_longitude); qSettings->setValue("altitude", m_altitude); - qSettings->setValue("cacheOnly", m_cacheOnly); - qSettings->setValue("speedFactor", m_speedFactor); - qSettings->setValue("altitudeFactor", m_altitudeFactor); + + // sky + qSettings->setValue("timeMode", static_cast(m_timeMode)); + qSettings->setValue("dateTime", m_dateTime); + qSettings->setValue("minAmbientLight", m_minAmbientLight); + + // model + qSettings->setValue("modelEnabled", m_modelEnabled); + qSettings->setValue("modelSelectionMode", static_cast(m_modelSelectionMode)); + QString modelFile = Utils::RemoveDataPath(m_modelFile); + qSettings->setValue("modelFile", modelFile); + + // background image + QString backgroundImageFile = Utils::RemoveDataPath(m_backgroundImageFile); + qSettings->setValue("backgroundImageFile", backgroundImageFile); } diff --git a/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetconfiguration.h b/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetconfiguration.h index b3f8e9b34..9bcdc42a5 100644 --- a/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetconfiguration.h +++ b/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetconfiguration.h @@ -1,4 +1,15 @@ -/* +/** + ****************************************************************************** + * + * @file pfdqmlgadgetconfiguration.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************//* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or @@ -17,8 +28,11 @@ #ifndef PFDQMLGADGETCONFIGURATION_H #define PFDQMLGADGETCONFIGURATION_H +#include "pfdqml.h" #include + #include +#include using namespace Core; @@ -27,94 +41,13 @@ class PfdQmlGadgetConfiguration : public IUAVGadgetConfiguration { public: explicit PfdQmlGadgetConfiguration(QString classId, QSettings *qSettings = 0, QObject *parent = 0); - void setQmlFile(const QString &fileName) - { - m_qmlFile = fileName; - } - void setEarthFile(const QString &fileName) - { - m_earthFile = fileName; - } - void setOpenGLEnabled(bool flag) - { - m_openGLEnabled = flag; - } - void setTerrainEnabled(bool flag) - { - m_terrainEnabled = flag; - } - void setActualPositionUsed(bool flag) - { - m_actualPositionUsed = flag; - } - void setLatitude(double value) - { - m_latitude = value; - } - void setLongitude(double value) - { - m_longitude = value; - } - void setAltitude(double value) - { - m_altitude = value; - } - void setCacheOnly(bool flag) - { - m_cacheOnly = flag; - } - void setSpeedFactor(double factor) - { - m_speedFactor = factor; - } - void setAltitudeFactor(double factor) - { - m_altitudeFactor = factor; - } - QString qmlFile() const { return m_qmlFile; } - QString earthFile() const + void setQmlFile(const QString &fileName) { - return m_earthFile; - } - bool openGLEnabled() const - { - return m_openGLEnabled; - } - bool terrainEnabled() const - { - return m_terrainEnabled; - } - bool actualPositionUsed() const - { - return m_actualPositionUsed; - } - double latitude() const - { - return m_latitude; - } - double longitude() const - { - return m_longitude; - } - double altitude() const - { - return m_altitude; - } - bool cacheOnly() const - { - return m_cacheOnly; - } - double speedFactor() const - { - return m_speedFactor; - } - double altitudeFactor() const - { - return m_altitudeFactor; + m_qmlFile = fileName; } QString speedUnit() const @@ -122,11 +55,147 @@ public: return m_speedMap[m_speedFactor]; } + double speedFactor() const + { + return m_speedFactor; + } + void setSpeedFactor(double factor) + { + m_speedFactor = factor; + } + QString altitudeUnit() const { return m_altitudeMap[m_altitudeFactor]; } + double altitudeFactor() const + { + return m_altitudeFactor; + } + void setAltitudeFactor(double factor) + { + m_altitudeFactor = factor; + } + + bool terrainEnabled() const + { + return m_terrainEnabled; + } + void setTerrainEnabled(bool flag) + { + m_terrainEnabled = flag; + } + + QString terrainFile() const + { + return m_terrainFile; + } + void setTerrainFile(const QString &fileName) + { + m_terrainFile = fileName; + } + + + double latitude() const + { + return m_latitude; + } + void setLatitude(double value) + { + m_latitude = value; + } + + double longitude() const + { + return m_longitude; + } + void setLongitude(double value) + { + m_longitude = value; + } + + double altitude() const + { + return m_altitude; + } + void setAltitude(double value) + { + m_altitude = value; + } + + void setCacheOnly(bool flag) + { + m_cacheOnly = flag; + } + bool cacheOnly() const + { + return m_cacheOnly; + } + + TimeMode::Enum timeMode() const + { + return m_timeMode; + } + void setTimeMode(TimeMode::Enum timeMode) + { + m_timeMode = timeMode; + } + + QDateTime dateTime() const + { + return m_dateTime; + } + void setDateTime(QDateTime &dateTime) + { + m_dateTime = dateTime; + } + + double minAmbientLight() const + { + return m_minAmbientLight; + } + void setMinAmbientLight(double minAmbientLight) + { + m_minAmbientLight = minAmbientLight; + } + + bool modelEnabled() const + { + return m_modelEnabled; + } + void setModelEnabled(bool flag) + { + m_modelEnabled = flag; + } + + QString modelFile() const + { + return m_modelFile; + } + void setModelFile(const QString &fileName) + { + m_modelFile = fileName; + } + + ModelSelectionMode::Enum modelSelectionMode() const + { + return m_modelSelectionMode; + } + void setModelSelectionMode(ModelSelectionMode::Enum modelSelectionMode) + { + m_modelSelectionMode = modelSelectionMode; + } + + QString backgroundImageFile() const + { + return m_backgroundImageFile; + } + void setBackgroundImageFile(const QString &fileName) + { + m_backgroundImageFile = fileName; + } + QMapIterator speedMapIterator() { return QMapIterator(m_speedMap); @@ -142,18 +211,30 @@ public: private: QString m_qmlFile; // The name of the dial's SVG source file - QString m_earthFile; // The name of osgearth terrain file - bool m_openGLEnabled; + + double m_speedFactor; + double m_altitudeFactor; + bool m_terrainEnabled; - bool m_actualPositionUsed; + QString m_terrainFile; // The name of osgearth terrain file + bool m_cacheOnly; + double m_latitude; double m_longitude; double m_altitude; - bool m_cacheOnly; - double m_speedFactor; - double m_altitudeFactor; + + TimeMode::Enum m_timeMode; + QDateTime m_dateTime; + double m_minAmbientLight; + + bool m_modelEnabled; + QString m_modelFile; // The name of model file + ModelSelectionMode::Enum m_modelSelectionMode; + + QString m_backgroundImageFile; + QMap m_speedMap; QMap m_altitudeMap; }; -#endif // PfdQmlGADGETCONFIGURATION_H +#endif // PFDQMLGADGETCONFIGURATION_H diff --git a/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetfactory.cpp b/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetfactory.cpp index 197f1929d..67ad3b2be 100644 --- a/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetfactory.cpp +++ b/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetfactory.cpp @@ -1,4 +1,15 @@ -/* +/** + ****************************************************************************** + * + * @file pfdqmlgadgetfactory.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************//* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or @@ -13,8 +24,8 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + #include "pfdqmlgadgetfactory.h" -#include "pfdqmlgadgetwidget.h" #include "pfdqmlgadget.h" #include "pfdqmlgadgetconfiguration.h" #include "pfdqmlgadgetoptionspage.h" @@ -31,9 +42,7 @@ PfdQmlGadgetFactory::~PfdQmlGadgetFactory() Core::IUAVGadget *PfdQmlGadgetFactory::createGadget(QWidget *parent) { - PfdQmlGadgetWidget *gadgetWidget = new PfdQmlGadgetWidget(); - - return new PfdQmlGadget(QString("PfdQmlGadget"), gadgetWidget, parent); + return new PfdQmlGadget(QString("PfdQmlGadget"), parent); } IUAVGadgetConfiguration *PfdQmlGadgetFactory::createConfiguration(QSettings *qSettings) diff --git a/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetfactory.h b/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetfactory.h index 23e4610ed..d7bd061a3 100644 --- a/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetfactory.h +++ b/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetfactory.h @@ -1,4 +1,15 @@ -/* +/** + ****************************************************************************** + * + * @file pfdqmlgadgetfactory.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************//* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or @@ -37,4 +48,4 @@ public: IOptionsPage *createOptionsPage(IUAVGadgetConfiguration *config); }; -#endif // PfdQmlGADGETFACTORY_H_ +#endif // PFDQMLGADGETFACTORY_H_ diff --git a/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetoptionspage.cpp b/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetoptionspage.cpp index b7f2aab5e..af7d5a7db 100644 --- a/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetoptionspage.cpp +++ b/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetoptionspage.cpp @@ -1,4 +1,15 @@ -/* +/** + ****************************************************************************** + * + * @file pfdqmlgadgetoptionspage.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************//* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or @@ -21,14 +32,12 @@ #include "uavobjectmanager.h" #include "uavdataobject.h" - #include #include #include PfdQmlGadgetOptionsPage::PfdQmlGadgetOptionsPage(PfdQmlGadgetConfiguration *config, QObject *parent) : - IOptionsPage(parent), - m_config(config) + IOptionsPage(parent), options_page(NULL), m_config(config) {} // creates options page widget (uses the UI file) @@ -40,29 +49,13 @@ QWidget *PfdQmlGadgetOptionsPage::createPage(QWidget *parent) // main layout options_page->setupUi(optionsPageWidget); - // Restore the contents from the settings: + // QML file chooser options_page->qmlSourceFile->setExpectedKind(Utils::PathChooser::File); options_page->qmlSourceFile->setPromptDialogFilter(tr("QML file (*.qml)")); - options_page->qmlSourceFile->setPromptDialogTitle(tr("Choose QML file")); + options_page->qmlSourceFile->setPromptDialogTitle(tr("Choose QML File")); options_page->qmlSourceFile->setPath(m_config->qmlFile()); - // Restore the contents from the settings: - options_page->earthFile->setExpectedKind(Utils::PathChooser::File); - options_page->earthFile->setPromptDialogFilter(tr("OsgEarth (*.earth)")); - options_page->earthFile->setPromptDialogTitle(tr("Choose OsgEarth terrain file")); - options_page->earthFile->setPath(m_config->earthFile()); - - options_page->useOpenGL->setChecked(m_config->openGLEnabled()); - options_page->showTerrain->setChecked(m_config->terrainEnabled()); - - options_page->useActualLocation->setChecked(m_config->actualPositionUsed()); - options_page->usePredefinedLocation->setChecked(!m_config->actualPositionUsed()); - options_page->latitude->setText(QString::number(m_config->latitude())); - options_page->longitude->setText(QString::number(m_config->longitude())); - options_page->altitude->setText(QString::number(m_config->altitude())); - options_page->useOnlyCache->setChecked(m_config->cacheOnly()); - - // Setup units combos + // Speed Unit combo QMapIterator iter = m_config->speedMapIterator(); while (iter.hasNext()) { iter.next(); @@ -70,6 +63,7 @@ QWidget *PfdQmlGadgetOptionsPage::createPage(QWidget *parent) } options_page->speedUnitCombo->setCurrentIndex(options_page->speedUnitCombo->findData(m_config->speedFactor())); + // Altitude Unit combo iter = m_config->altitudeMapIterator(); while (iter.hasNext()) { iter.next(); @@ -77,11 +71,54 @@ QWidget *PfdQmlGadgetOptionsPage::createPage(QWidget *parent) } options_page->altUnitCombo->setCurrentIndex(options_page->altUnitCombo->findData(m_config->altitudeFactor())); + // Terrain check boxes + options_page->showTerrain->setChecked(m_config->terrainEnabled()); + + // Terrain file chooser + options_page->earthFile->setExpectedKind(Utils::PathChooser::File); + options_page->earthFile->setPromptDialogFilter(tr("OsgEarth (*.earth)")); + options_page->earthFile->setPromptDialogTitle(tr("Choose Terrain File")); + options_page->earthFile->setPath(m_config->terrainFile()); + + // Terrain position + options_page->latitude->setText(QString::number(m_config->latitude())); + options_page->longitude->setText(QString::number(m_config->longitude())); + options_page->altitude->setText(QString::number(m_config->altitude())); + + options_page->useOnlyCache->setChecked(m_config->cacheOnly()); + + // Sky options + options_page->useLocalTime->setChecked(m_config->timeMode() == TimeMode::Local); + options_page->usePredefinedTime->setChecked(m_config->timeMode() == TimeMode::Predefined); + options_page->dateEdit->setDate(m_config->dateTime().date()); + options_page->timeEdit->setTime(m_config->dateTime().time()); + options_page->minAmbientLightSpinBox->setValue(m_config->minAmbientLight()); + + // Model check boxes + options_page->showModel->setChecked(m_config->modelEnabled()); + options_page->useAutomaticModel->setChecked(m_config->modelSelectionMode() == ModelSelectionMode::Auto); + options_page->usePredefinedModel->setChecked(m_config->modelSelectionMode() == ModelSelectionMode::Predefined); + + // Model file chooser + options_page->modelFile->setExpectedKind(Utils::PathChooser::File); + options_page->modelFile->setPromptDialogFilter(tr("Model file (*.3ds)")); + options_page->modelFile->setPromptDialogTitle(tr("Choose Model File")); + options_page->modelFile->setPath(m_config->modelFile()); + + // Background image chooser + options_page->backgroundImageFile->setExpectedKind(Utils::PathChooser::File); + // options_page->backgroundImageFile->setPromptDialogFilter(tr("Image file")); + options_page->backgroundImageFile->setPromptDialogTitle(tr("Choose Background Image File")); + options_page->backgroundImageFile->setPath(m_config->backgroundImageFile()); + #ifndef USE_OSG options_page->showTerrain->setChecked(false); options_page->showTerrain->setVisible(false); #endif + QObject::connect(options_page->actualizeDateTimeButton, SIGNAL(clicked()), + this, SLOT(actualizeDateTime())); + return optionsPageWidget; } @@ -94,24 +131,54 @@ QWidget *PfdQmlGadgetOptionsPage::createPage(QWidget *parent) void PfdQmlGadgetOptionsPage::apply() { m_config->setQmlFile(options_page->qmlSourceFile->path()); - m_config->setEarthFile(options_page->earthFile->path()); - m_config->setOpenGLEnabled(options_page->useOpenGL->isChecked()); + + m_config->setSpeedFactor(options_page->speedUnitCombo->itemData(options_page->speedUnitCombo->currentIndex()).toDouble()); + m_config->setAltitudeFactor(options_page->altUnitCombo->itemData(options_page->altUnitCombo->currentIndex()).toDouble()); #ifdef USE_OSG m_config->setTerrainEnabled(options_page->showTerrain->isChecked()); -#else - m_config->setTerrainEnabled(false); -#endif + m_config->setTerrainFile(options_page->earthFile->path()); - m_config->setActualPositionUsed(options_page->useActualLocation->isChecked()); m_config->setLatitude(options_page->latitude->text().toDouble()); m_config->setLongitude(options_page->longitude->text().toDouble()); m_config->setAltitude(options_page->altitude->text().toDouble()); m_config->setCacheOnly(options_page->useOnlyCache->isChecked()); - m_config->setSpeedFactor(options_page->speedUnitCombo->itemData(options_page->speedUnitCombo->currentIndex()).toDouble()); - m_config->setAltitudeFactor(options_page->altUnitCombo->itemData(options_page->altUnitCombo->currentIndex()).toDouble()); + if (options_page->useLocalTime->isChecked()) { + m_config->setTimeMode(TimeMode::Local); + } else { + m_config->setTimeMode(TimeMode::Predefined); + } + QDateTime dateTime(options_page->dateEdit->date(), options_page->timeEdit->time()); + m_config->setDateTime(dateTime); + m_config->setMinAmbientLight(options_page->minAmbientLightSpinBox->value()); + +#else // ifdef USE_OSG + m_config->setTerrainEnabled(false); +#endif // ifdef USE_OSG + +#ifdef USE_OSG + m_config->setModelEnabled(options_page->showModel->isChecked()); + m_config->setModelFile(options_page->modelFile->path()); + + if (options_page->useAutomaticModel->isChecked()) { + m_config->setModelSelectionMode(ModelSelectionMode::Auto); + } else { + m_config->setModelSelectionMode(ModelSelectionMode::Predefined); + } + m_config->setBackgroundImageFile(options_page->backgroundImageFile->path()); +#else + m_config->setModelEnabled(false); +#endif } void PfdQmlGadgetOptionsPage::finish() {} + +void PfdQmlGadgetOptionsPage::actualizeDateTime() +{ + QDateTime dateTime = QDateTime::currentDateTime(); + + options_page->dateEdit->setDate(dateTime.date()); + options_page->timeEdit->setTime(dateTime.time()); +} diff --git a/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetoptionspage.h b/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetoptionspage.h index a324c0709..f63ba8b45 100644 --- a/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetoptionspage.h +++ b/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetoptionspage.h @@ -1,4 +1,15 @@ -/* +/** + ****************************************************************************** + * + * @file pfdqmlgadgetoptionspage.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************//* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or @@ -43,6 +54,9 @@ public: void apply(); void finish(); +private slots: + void actualizeDateTime(); + private: Ui::PfdQmlGadgetOptionsPage *options_page; PfdQmlGadgetConfiguration *m_config; @@ -50,4 +64,4 @@ private: private slots: }; -#endif // PfdQmlGADGETOPTIONSPAGE_H +#endif // PFDQMLGADGETOPTIONSPAGE_H diff --git a/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetoptionspage.ui b/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetoptionspage.ui index bb136c6e1..576752a96 100644 --- a/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetoptionspage.ui +++ b/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetoptionspage.ui @@ -20,7 +20,16 @@ Form - + + 0 + + + 0 + + + 0 + + 0 @@ -44,7 +53,16 @@ - + + 0 + + + 0 + + + 0 + + 0 @@ -56,7 +74,7 @@ QLayout::SetMaximumSize - 10 + 0 @@ -78,33 +96,23 @@ - - - Use OpenGL - - - true - - - - - + - - - Speed Unit: - - - - Altitude Unit: + + + + Speed Unit: + + + - + 150 @@ -114,7 +122,7 @@ - + 150 @@ -126,154 +134,385 @@ - - - Show Terrain: + + + 0 - - true - - - - - - 10 - - - QLayout::SetMaximumSize - - - 10 - - - - - OsgEarth file: - - - - - - - - 0 - 0 - - - - - - - - - - Use actual location - - - - - - - Use pre-defined location: - - - true - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 16 - 16 - - - - - - - - - - Latitude: - - - - - - - - - - Longitude: - - - - - - - - - - Altitude: - - - - - - - - - - - - Use only cache data - - - - - - - Qt::Horizontal - - - - 74 - 24 - - - - - - - - Pre seed terrain cache - - - - + + + Terrain + + + + + + Show Terrain + + + true + + + + + + 0 + + + QLayout::SetMaximumSize + + + 0 + + + + + Terrain file: + + + + + + + + 0 + 0 + + + + + + + + + + This location will be used if no GPS fix or Home location are available + + + + + + Default Location + + + + + + 6 + + + 0 + + + + + Latitude: + + + + + + + + + + Longitude: + + + + + + + + + + Altitude: + + + + + + + + + + + + + + + + + false + + + Use only cache data + + + true + + + + + + + Qt::Horizontal + + + + 74 + 24 + + + + + + + + false + + + Pre seed terrain cache + + + + + + + + + + + + Qt::Vertical + + + + 20 + 121 + + + + + + + + + Model + + + + + + Show Model + + + true + + + + + + false + + + Use automatic model selection + + + + + + + 0 + + + 0 + + + + + false + + + Use this model: + + + + + + + 6 + + + 0 + + + + + + 0 + 0 + + + + + + + + + + + + + + + + + Background image: + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + Environment + + + + + + Time + + + + + + Use local time + + + + + + + 0 + + + 0 + + + + + Use this time: + + + + + + + true + + + + + + + + + + Actualize + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + Minimum ambient light: + + + + + + + 1.000000000000000 + + + 0.010000000000000 + + + 0.030000000000000 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + - - - - Qt::Vertical - - - - 20 - 121 - - - - @@ -284,75 +523,10 @@ Utils::PathChooser QWidget -
utils/pathchooser.h
+
utils/pathchooser.h
1
- - - usePredefinedLocation - toggled(bool) - latitude - setEnabled(bool) - - - 167 - 188 - - - 260 - 222 - - - - - usePredefinedLocation - toggled(bool) - longitude - setEnabled(bool) - - - 181 - 188 - - - 282 - 255 - - - - - usePredefinedLocation - toggled(bool) - altitude - setEnabled(bool) - - - 207 - 188 - - - 308 - 288 - - - - - useOpenGL - toggled(bool) - showTerrain - setEnabled(bool) - - - 99 - 57 - - - 99 - 89 - - - - + diff --git a/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetwidget.cpp b/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetwidget.cpp index bce9246c2..6084c5610 100644 --- a/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetwidget.cpp +++ b/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetwidget.cpp @@ -1,4 +1,15 @@ -/* +/** + ****************************************************************************** + * + * @file pfdqmlgadgetwidget.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************//* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or @@ -15,226 +26,119 @@ */ #include "pfdqmlgadgetwidget.h" -#include "extensionsystem/pluginmanager.h" -#include "uavobjectmanager.h" -#include "uavobject.h" -#include "flightbatterysettings.h" -#include "utils/svgimageprovider.h" -#ifdef USE_OSG -#include "osgearth.h" -#endif -#include -#include -#include -#include -#include -#include +#include "pfdqmlcontext.h" +#include "utils/quickwidgetproxy.h" +#include "utils/svgimageprovider.h" + +#include +#include #include #include +#include -PfdQmlGadgetWidget::PfdQmlGadgetWidget(QWindow *parent) : - QQuickView(parent), - m_openGLEnabled(false), - m_terrainEnabled(false), - m_actualPositionUsed(false), - m_latitude(46.671478), - m_longitude(10.158932), - m_altitude(2000), - m_speedUnit("m/s"), - m_speedFactor(1.0), - m_altitudeUnit("m"), - m_altitudeFactor(1.0) +PfdQmlGadgetWidget::PfdQmlGadgetWidget(QWidget *parent) : + QWidget(parent), m_quickWidgetProxy(NULL), m_pfdQmlContext(NULL), m_qmlFileName() { - setResizeMode(SizeRootObjectToView); - - // setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); - - QStringList objectsToExport; - objectsToExport << - "VelocityState" << - "PositionState" << - "AttitudeState" << - "AccelState" << - "VelocityDesired" << - "PathDesired" << - "AltitudeHoldDesired" << - "GPSPositionSensor" << - "GPSSatellites" << - "GCSTelemetryStats" << - "SystemAlarms" << - "NedAccel" << - "FlightBatteryState" << - "ActuatorDesired" << - "TakeOffLocation" << - "PathPlan" << - "WaypointActive" << - "OPLinkStatus" << - "FlightStatus" << - "SystemStats" << - "StabilizationDesired" << - "VtolPathFollowerSettings" << - "HwSettings" << - "ManualControlCommand" << - "SystemSettings" << - "RevoSettings" << - "MagState" << - "FlightBatterySettings" << - "ReceiverStatus"; - - ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); - UAVObjectManager *objManager = pm->getObject(); - m_uavoManager = pm->getObject(); - Q_ASSERT(m_uavoManager); - - foreach(const QString &objectName, objectsToExport) { - UAVObject *object = objManager->getObject(objectName); - - if (object) { - engine()->rootContext()->setContextProperty(objectName, object); - } else { - qWarning() << "Failed to load object" << objectName; - } - } - - // to expose settings values - engine()->rootContext()->setContextProperty("qmlWidget", this); -#ifdef USE_OSG - qmlRegisterType("org.OpenPilot", 1, 0, "OsgEarth"); -#endif + setLayout(new QStackedLayout()); } PfdQmlGadgetWidget::~PfdQmlGadgetWidget() -{} +{ + if (m_pfdQmlContext) { + delete m_pfdQmlContext; + } +} + +void PfdQmlGadgetWidget::setSource(const QUrl &url) +{ + m_quickWidgetProxy->setSource(url); +} + +QQmlEngine *PfdQmlGadgetWidget::engine() const +{ + return m_quickWidgetProxy->engine(); +} + +QList PfdQmlGadgetWidget::errors() const +{ + return m_quickWidgetProxy->errors(); +} + +void PfdQmlGadgetWidget::loadConfiguration(PfdQmlGadgetConfiguration *config) +{ + // qDebug() << "PfdQmlGadgetWidget::loadConfiguration" << config->name(); + + if (!m_quickWidgetProxy) { + m_quickWidgetProxy = new QuickWidgetProxy(this); + +#if 0 + qDebug() << "PfdQmlGadgetWidget::PfdQmlGadgetWidget - persistent OpenGL context" << isPersistentOpenGLContext(); + qDebug() << "PfdQmlGadgetWidget::PfdQmlGadgetWidget - persistent scene graph" << isPersistentSceneGraph(); +#endif + + // expose context + m_pfdQmlContext = new PfdQmlContext(this); + m_pfdQmlContext->apply(engine()->rootContext()); + + // add widget + layout()->addWidget(m_quickWidgetProxy->widget()); + } + + clear(); + + m_pfdQmlContext->loadConfiguration(config); + + // go! + setQmlFile(config->qmlFile()); +} + +void PfdQmlGadgetWidget::saveState(QSettings *settings) +{ + m_pfdQmlContext->saveState(settings); +} + +void PfdQmlGadgetWidget::restoreState(QSettings *settings) +{ + m_pfdQmlContext->restoreState(settings); +} void PfdQmlGadgetWidget::setQmlFile(QString fn) { + qDebug() << "PfdQmlGadgetWidget::setQmlFile" << fn; + m_qmlFileName = fn; - engine()->removeImageProvider("svg"); + if (fn.isEmpty()) { + clear(); + return; + } SvgImageProvider *svgProvider = new SvgImageProvider(fn); engine()->addImageProvider("svg", svgProvider); - engine()->clearComponentCache(); - // it's necessary to allow qml side to query svg element position engine()->rootContext()->setContextProperty("svgRenderer", svgProvider); - engine()->setBaseUrl(QUrl::fromLocalFile(fn)); - qDebug() << Q_FUNC_INFO << fn; - setSource(QUrl::fromLocalFile(fn)); + QUrl url = QUrl::fromLocalFile(fn); + engine()->setBaseUrl(url); + + setSource(url); foreach(const QQmlError &error, errors()) { - qDebug() << error.description(); + qDebug() << "PfdQmlGadgetWidget - " << error.description(); } } -void PfdQmlGadgetWidget::resetConsumedEnergy() +void PfdQmlGadgetWidget::clear() { - FlightBatterySettings *mBatterySettings = FlightBatterySettings::GetInstance(m_uavoManager); + // qDebug() << "PfdQmlGadgetWidget::clear"; - mBatterySettings->setResetConsumedEnergy(true); - mBatterySettings->setData(mBatterySettings->getData()); -} - -void PfdQmlGadgetWidget::setEarthFile(QString arg) -{ - if (m_earthFile != arg) { - m_earthFile = arg; - emit earthFileChanged(arg); - } -} - -void PfdQmlGadgetWidget::setTerrainEnabled(bool arg) -{ - bool wasEnabled = terrainEnabled(); - - m_terrainEnabled = arg; - - if (wasEnabled != terrainEnabled()) { - emit terrainEnabledChanged(terrainEnabled()); - } -} - -void PfdQmlGadgetWidget::setSpeedUnit(QString unit) -{ - if (m_speedUnit != unit) { - m_speedUnit = unit; - emit speedUnitChanged(unit); - } -} - -void PfdQmlGadgetWidget::setSpeedFactor(double factor) -{ - if (m_speedFactor != factor) { - m_speedFactor = factor; - emit speedFactorChanged(factor); - } -} - -void PfdQmlGadgetWidget::setAltitudeUnit(QString unit) -{ - if (m_altitudeUnit != unit) { - m_altitudeUnit = unit; - emit altitudeUnitChanged(unit); - } -} - -void PfdQmlGadgetWidget::setAltitudeFactor(double factor) -{ - if (m_altitudeFactor != factor) { - m_altitudeFactor = factor; - emit altitudeFactorChanged(factor); - } -} - -void PfdQmlGadgetWidget::setOpenGLEnabled(bool arg) -{ - Q_UNUSED(arg); - setTerrainEnabled(m_terrainEnabled); -} - -// Switch between PositionState UAVObject position -// and pre-defined latitude/longitude/altitude properties -void PfdQmlGadgetWidget::setActualPositionUsed(bool arg) -{ - if (m_actualPositionUsed != arg) { - m_actualPositionUsed = arg; - emit actualPositionUsedChanged(arg); - } -} - -void PfdQmlGadgetWidget::mouseReleaseEvent(QMouseEvent *event) -{ - // Reload the schene on the middle mouse button click. - if (event->button() == Qt::MiddleButton) { - setQmlFile(m_qmlFileName); - } - - QQuickView::mouseReleaseEvent(event); -} - -void PfdQmlGadgetWidget::setLatitude(double arg) -{ - // not sure qFuzzyCompare is accurate enough for geo coordinates - if (m_latitude != arg) { - m_latitude = arg; - emit latitudeChanged(arg); - } -} - -void PfdQmlGadgetWidget::setLongitude(double arg) -{ - if (m_longitude != arg) { - m_longitude = arg; - emit longitudeChanged(arg); - } -} - -void PfdQmlGadgetWidget::setAltitude(double arg) -{ - if (!qFuzzyCompare(m_altitude, arg)) { - m_altitude = arg; - emit altitudeChanged(arg); - } + setSource(QUrl()); + + engine()->removeImageProvider("svg"); + engine()->rootContext()->setContextProperty("svgRenderer", NULL); + + // calling clearComponentCache() causes crashes (see https://bugreports.qt-project.org/browse/QTBUG-41465) + // but not doing it causes almost systematic crashes when switching PFD gadget to "Model View (Without Terrain)" configuration + engine()->clearComponentCache(); } diff --git a/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetwidget.h b/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetwidget.h index b971942e0..d706f2fac 100644 --- a/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetwidget.h +++ b/ground/gcs/src/plugins/pfdqml/pfdqmlgadgetwidget.h @@ -1,4 +1,15 @@ -/* +/** + ****************************************************************************** + * + * @file pfdqmlgadgetwidget.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************//* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or @@ -17,126 +28,39 @@ #ifndef PFDQMLGADGETWIDGET_H_ #define PFDQMLGADGETWIDGET_H_ +#include "pfdqml.h" #include "pfdqmlgadgetconfiguration.h" -#include "uavobjectmanager.h" -#include -class PfdQmlGadgetWidget : public QQuickView { - Q_OBJECT Q_PROPERTY(QString earthFile READ earthFile WRITE setEarthFile NOTIFY earthFileChanged) - Q_PROPERTY(bool terrainEnabled READ terrainEnabled WRITE setTerrainEnabled NOTIFY terrainEnabledChanged) +#include - Q_PROPERTY(bool actualPositionUsed READ actualPositionUsed WRITE setActualPositionUsed NOTIFY actualPositionUsedChanged) +class QQmlEngine; +class QSettings; +class QuickWidgetProxy; +class PfdQmlContext; - Q_PROPERTY(QString speedUnit READ speedUnit WRITE setSpeedUnit NOTIFY speedUnitChanged) - Q_PROPERTY(double speedFactor READ speedFactor WRITE setSpeedFactor NOTIFY speedFactorChanged) - Q_PROPERTY(QString altitudeUnit READ altitudeUnit WRITE setAltitudeUnit NOTIFY altitudeUnitChanged) - Q_PROPERTY(double altitudeFactor READ altitudeFactor WRITE setAltitudeFactor NOTIFY altitudeFactorChanged) - - // pre-defined fallback position - Q_PROPERTY(double latitude READ latitude WRITE setLatitude NOTIFY latitudeChanged) - Q_PROPERTY(double longitude READ longitude WRITE setLongitude NOTIFY longitudeChanged) - Q_PROPERTY(double altitude READ altitude WRITE setAltitude NOTIFY altitudeChanged) +class PfdQmlGadgetWidget : public QWidget { + Q_OBJECT public: - PfdQmlGadgetWidget(QWindow *parent = 0); - ~PfdQmlGadgetWidget(); - void setQmlFile(QString fn); + PfdQmlGadgetWidget(QWidget *parent = 0); + virtual ~PfdQmlGadgetWidget(); - QString earthFile() const - { - return m_earthFile; - } - bool terrainEnabled() const - { - return m_terrainEnabled && m_openGLEnabled; - } - - QString speedUnit() const - { - return m_speedUnit; - } - double speedFactor() const - { - return m_speedFactor; - } - QString altitudeUnit() const - { - return m_altitudeUnit; - } - double altitudeFactor() const - { - return m_altitudeFactor; - } - - bool actualPositionUsed() const - { - return m_actualPositionUsed; - } - double latitude() const - { - return m_latitude; - } - double longitude() const - { - return m_longitude; - } - double altitude() const - { - return m_altitude; - } - - Q_INVOKABLE void resetConsumedEnergy(); - -public slots: - void setEarthFile(QString arg); - void setTerrainEnabled(bool arg); - - void setSpeedUnit(QString unit); - void setSpeedFactor(double factor); - void setAltitudeUnit(QString unit); - void setAltitudeFactor(double factor); - - void setOpenGLEnabled(bool arg); - - void setLatitude(double arg); - void setLongitude(double arg); - void setAltitude(double arg); - - void setActualPositionUsed(bool arg); - -signals: - void earthFileChanged(QString arg); - void terrainEnabledChanged(bool arg); - - void actualPositionUsedChanged(bool arg); - void latitudeChanged(double arg); - void longitudeChanged(double arg); - void altitudeChanged(double arg); - - void speedUnitChanged(QString arg); - void speedFactorChanged(double arg); - void altitudeUnitChanged(QString arg); - void altitudeFactorChanged(double arg); - -protected: - void mouseReleaseEvent(QMouseEvent *event); + void loadConfiguration(PfdQmlGadgetConfiguration *config); + void saveState(QSettings *); + void restoreState(QSettings *); private: - UAVObjectManager *m_uavoManager; + QuickWidgetProxy *m_quickWidgetProxy; + + PfdQmlContext *m_pfdQmlContext; QString m_qmlFileName; - QString m_earthFile; - bool m_openGLEnabled; - bool m_terrainEnabled; - bool m_actualPositionUsed; - double m_latitude; - double m_longitude; - double m_altitude; + void setQmlFile(QString); + void clear(); - QString m_speedUnit; - double m_speedFactor; - QString m_altitudeUnit; - double m_altitudeFactor; + void setSource(const QUrl &url); + QQmlEngine *engine() const; + QList errors() const; }; #endif /* PFDQMLGADGETWIDGET_H_ */ diff --git a/ground/gcs/src/plugins/pfdqml/pfdqmlplugin.cpp b/ground/gcs/src/plugins/pfdqml/pfdqmlplugin.cpp index 4c5e84c39..8530ca1c7 100644 --- a/ground/gcs/src/plugins/pfdqml/pfdqmlplugin.cpp +++ b/ground/gcs/src/plugins/pfdqml/pfdqmlplugin.cpp @@ -1,4 +1,15 @@ -/* +/** + ****************************************************************************** + * + * @file pfdqmlplugin.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************//* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or @@ -14,13 +25,17 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "pfdqml.h" #include "pfdqmlplugin.h" #include "pfdqmlgadgetfactory.h" -#include -#include -#include #include +#ifdef USE_OSG +#include +#endif + +#include +#include PfdQmlPlugin::PfdQmlPlugin() { @@ -36,7 +51,18 @@ bool PfdQmlPlugin::initialize(const QStringList & args, QString *errMsg) { Q_UNUSED(args); Q_UNUSED(errMsg); - mf = new PfdQmlGadgetFactory(this); + +#ifdef USE_OSG + // TODO get rid of this call... + // this is the only place that references osgearth + // if this code goes away then the dependency to osgearth should be removed from pfdqml_dependencies.pri + OsgEarth::registerQmlTypes(); +#endif + + ModelSelectionMode::registerQMLTypes(); + TimeMode::registerQMLTypes(); + + PfdQmlGadgetFactory *mf = new PfdQmlGadgetFactory(this); addAutoReleasedObject(mf); return true; diff --git a/ground/gcs/src/plugins/pfdqml/pfdqmlplugin.h b/ground/gcs/src/plugins/pfdqml/pfdqmlplugin.h index 0f137feaf..52dd7c9c0 100644 --- a/ground/gcs/src/plugins/pfdqml/pfdqmlplugin.h +++ b/ground/gcs/src/plugins/pfdqml/pfdqmlplugin.h @@ -1,4 +1,15 @@ -/* +/** + ****************************************************************************** + * + * @file pfdqmlplugin.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @addtogroup + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************//* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or @@ -32,8 +43,6 @@ public: void extensionsInitialized(); bool initialize(const QStringList &arguments, QString *errorString); void shutdown(); -private: - PfdQmlGadgetFactory *mf; }; #endif /* PFDQMLPLUGIN_H_ */ diff --git a/ground/gcs/src/plugins/plugins.pro b/ground/gcs/src/plugins/plugins.pro index 7ed82023c..53c3c619f 100644 --- a/ground/gcs/src/plugins/plugins.pro +++ b/ground/gcs/src/plugins/plugins.pro @@ -77,12 +77,6 @@ plugin_uavobjectbrowser.depends = plugin_coreplugin plugin_uavobjectbrowser.depends += plugin_uavobjects SUBDIRS += plugin_uavobjectbrowser -# ModelView UAVGadget -plugin_modelview.subdir = modelview -plugin_modelview.depends = plugin_coreplugin -plugin_modelview.depends += plugin_uavobjects -SUBDIRS += plugin_modelview - #Qt 4.8.0 / phonon may crash on Mac, fixed in Qt 4.8.1, QTBUG-23128 macx:contains(QT_VERSION, ^4\\.8\\.0): CONFIG += disable_notify_plugin @@ -140,10 +134,10 @@ plugin_gpsdisplay.depends += plugin_uavobjects SUBDIRS += plugin_gpsdisplay # QML viewer gadget -plugin_qmlview.subdir = qmlview -plugin_qmlview.depends = plugin_coreplugin -plugin_qmlview.depends += plugin_uavobjects -SUBDIRS += plugin_qmlview +#plugin_qmlview.subdir = qmlview +#plugin_qmlview.depends = plugin_coreplugin +#plugin_qmlview.depends += plugin_uavobjects +#SUBDIRS += plugin_qmlview # PathAction Editor gadget plugin_pathactioneditor.subdir = pathactioneditor @@ -162,7 +156,7 @@ plugin_ipconnection.subdir = ipconnection plugin_ipconnection.depends = plugin_coreplugin SUBDIRS += plugin_ipconnection -#HITL Simulation gadget +# HITL Simulation gadget plugin_hitl.subdir = hitl plugin_hitl.depends = plugin_coreplugin plugin_hitl.depends += plugin_uavobjects @@ -194,12 +188,6 @@ SUBDIRS += plugin_gcscontrol #plugin_antennatrack.depends += plugin_uavobjects #SUBDIRS += plugin_antennatrack -# Scope OpenGL Gadget -#plugin_scopeogl.subdir = scopeogl -#plugin_scopeogl.depends = plugin_coreplugin -#plugin_scopeogl.depends += plugin_uavobjects -#SUBDIRS += plugin_scopeogl - # UAV Object Utility plugin plugin_uavobjectutil.subdir = uavobjectutil plugin_uavobjectutil.depends = plugin_coreplugin @@ -251,3 +239,9 @@ plugin_usagetracker.depends += plugin_uavtalk plugin_setupwizard.depends += plugin_uavobjectutil SUBDIRS += plugin_usagetracker +# Stream Service Plugin +plugin_streamservice.subdir = streamservice +plugin_streamservice.depends = plugin_coreplugin +plugin_streamservice.depends += plugin_uavobjects +plugin_streamservice.depends += plugin_uavtalk +SUBDIRS += plugin_streamservice diff --git a/ground/gcs/src/plugins/qmlview/qmlview.pro b/ground/gcs/src/plugins/qmlview/qmlview.pro index e172f898a..67510c412 100644 --- a/ground/gcs/src/plugins/qmlview/qmlview.pro +++ b/ground/gcs/src/plugins/qmlview/qmlview.pro @@ -1,8 +1,7 @@ TEMPLATE = lib TARGET = QMLView -QT += svg -QT += opengl -QT += qml quick + +QT += svg opengl qml quick include(../../plugin.pri) include(../../plugins/coreplugin/coreplugin.pri) diff --git a/ground/gcs/src/plugins/qmlview/qmlviewgadgetwidget.cpp b/ground/gcs/src/plugins/qmlview/qmlviewgadgetwidget.cpp index 808cf3e80..813061aa2 100644 --- a/ground/gcs/src/plugins/qmlview/qmlviewgadgetwidget.cpp +++ b/ground/gcs/src/plugins/qmlview/qmlviewgadgetwidget.cpp @@ -34,7 +34,6 @@ #include #include -#include #include #include diff --git a/ground/gcs/src/plugins/scope/scope.pro b/ground/gcs/src/plugins/scope/scope.pro index a580ce4c1..a8dd080fd 100644 --- a/ground/gcs/src/plugins/scope/scope.pro +++ b/ground/gcs/src/plugins/scope/scope.pro @@ -1,6 +1,8 @@ TEMPLATE = lib TARGET = ScopeGadget +QT += widgets + DEFINES += SCOPE_LIBRARY include(../../plugin.pri) diff --git a/ground/gcs/src/plugins/scope/scopegadgetoptionspage.ui b/ground/gcs/src/plugins/scope/scopegadgetoptionspage.ui index 7ae473fa1..8a9c3da0f 100644 --- a/ground/gcs/src/plugins/scope/scopegadgetoptionspage.ui +++ b/ground/gcs/src/plugins/scope/scopegadgetoptionspage.ui @@ -193,7 +193,7 @@ - Math window size + Math window size: diff --git a/ground/gcs/src/plugins/serialconnection/serialconnection.pro b/ground/gcs/src/plugins/serialconnection/serialconnection.pro index 7966af624..b80c1e0bb 100644 --- a/ground/gcs/src/plugins/serialconnection/serialconnection.pro +++ b/ground/gcs/src/plugins/serialconnection/serialconnection.pro @@ -1,15 +1,24 @@ TEMPLATE = lib TARGET = Serial + +QT += serialport widgets + include(../../plugin.pri) include(serial_dependencies.pri) -QT += serialport -HEADERS += serialplugin.h \ - serialpluginconfiguration.h \ - serialpluginoptionspage.h -SOURCES += serialplugin.cpp \ - serialpluginconfiguration.cpp \ - serialpluginoptionspage.cpp + +HEADERS += \ + serialplugin.h \ + serialpluginconfiguration.h \ + serialpluginoptionspage.h + +SOURCES += \ + serialplugin.cpp \ + serialpluginconfiguration.cpp \ + serialpluginoptionspage.cpp + FORMS += \ serialpluginoptions.ui + RESOURCES += + OTHER_FILES += Serial.pluginspec diff --git a/ground/gcs/src/plugins/serialconnection/serialplugin.cpp b/ground/gcs/src/plugins/serialconnection/serialplugin.cpp index 7ce9bb0d8..dcaed9919 100644 --- a/ground/gcs/src/plugins/serialconnection/serialplugin.cpp +++ b/ground/gcs/src/plugins/serialconnection/serialplugin.cpp @@ -30,12 +30,8 @@ #include #include -#include -#include - #include - SerialEnumerationThread::SerialEnumerationThread(SerialConnection *serial) : m_serial(serial), m_running(false) {} @@ -166,6 +162,9 @@ QIODevice *SerialConnection::openDevice(const QString &deviceName) // don't specify a parent when constructing the QSerialPort as this object will be moved // to a different thread later on (see telemetrymanager.cpp) serialHandle = new QSerialPort(port); + connect(serialHandle, static_cast(&QSerialPort::error), + [ = ](QSerialPort::SerialPortError error) { qWarning() << "serial port error:" << error; } + ); // we need to handle port settings here... if (serialHandle->open(QIODevice::ReadWrite)) { if (serialHandle->setBaudRate(m_config->speed().toInt()) @@ -176,6 +175,8 @@ QIODevice *SerialConnection::openDevice(const QString &deviceName) qDebug() << "Serial telemetry running at " << m_config->speed(); m_deviceOpened = true; } + // see https://librepilot.atlassian.net/browse/LP-341 + serialHandle->setDataTerminalReady(true); } return serialHandle; } diff --git a/ground/gcs/src/plugins/serialconnection/serialpluginconfiguration.cpp b/ground/gcs/src/plugins/serialconnection/serialpluginconfiguration.cpp index 54c896781..933a01f40 100644 --- a/ground/gcs/src/plugins/serialconnection/serialpluginconfiguration.cpp +++ b/ground/gcs/src/plugins/serialconnection/serialpluginconfiguration.cpp @@ -73,12 +73,12 @@ void SerialPluginConfiguration::restoresettings() { settings->beginGroup(QLatin1String("SerialConnection")); QString str = (settings->value(QLatin1String("speed"), tr("")).toString()); - qDebug() << "SerialPluginConfiguration::restoresettings - speed" << str; if (str.isEmpty()) { m_speed = "57600"; } else { m_speed = str; } + // qDebug() << "SerialPluginConfiguration::restoresettings - speed" << str; settings->endGroup(); } diff --git a/ground/gcs/src/plugins/setupwizard/connectiondiagram.cpp b/ground/gcs/src/plugins/setupwizard/connectiondiagram.cpp index 4038cb4d6..5ea7fea46 100644 --- a/ground/gcs/src/plugins/setupwizard/connectiondiagram.cpp +++ b/ground/gcs/src/plugins/setupwizard/connectiondiagram.cpp @@ -94,6 +94,9 @@ void ConnectionDiagram::setupGraphicsScene() case VehicleConfigurationSource::CONTROLLER_NANO: elementsToShow << "controller-nano"; break; + case VehicleConfigurationSource::CONTROLLER_SPARKY2: + elementsToShow << "controller-sparky2"; + break; case VehicleConfigurationSource::CONTROLLER_OPLINK: default: elementsToShow << "controller-cc"; @@ -181,6 +184,9 @@ void ConnectionDiagram::setupGraphicsScene() case VehicleConfigurationSource::CONTROLLER_NANO: prefix = "nano-"; break; + case VehicleConfigurationSource::CONTROLLER_SPARKY2: + prefix = "sparky2-"; + break; default: break; } @@ -201,6 +207,15 @@ void ConnectionDiagram::setupGraphicsScene() case VehicleConfigurationSource::INPUT_DSM: elementsToShow << QString("%1satellite").arg(prefix); break; + case VehicleConfigurationSource::INPUT_HOTT_SUMD: + elementsToShow << QString("%1hott").arg(prefix); + break; + case VehicleConfigurationSource::INPUT_EXBUS: + elementsToShow << QString("%1exbus").arg(prefix); + break; + case VehicleConfigurationSource::INPUT_IBUS: + elementsToShow << QString("%1ibus").arg(prefix); + break; default: break; } @@ -219,7 +234,8 @@ void ConnectionDiagram::setupGraphicsScene() } } - if (m_configSource->getInputType() == VehicleConfigurationSource::INPUT_SBUS) { + if ((m_configSource->getInputType() == VehicleConfigurationSource::INPUT_SBUS) && + (m_configSource->getControllerType() != VehicleConfigurationSource::CONTROLLER_SPARKY2)) { prefix = QString("flexi-%1").arg(prefix); } switch (m_configSource->getGpsType()) { @@ -231,9 +247,15 @@ void ConnectionDiagram::setupGraphicsScene() case VehicleConfigurationSource::GPS_PLATINUM: elementsToShow << QString("%1OPGPS-v9").arg(prefix); break; + case VehicleConfigurationSource::GPS_NAZA: + elementsToShow << QString("%1NazaGPS").arg(prefix); + break; case VehicleConfigurationSource::GPS_UBX: elementsToShow << QString("%1OPGPS-v8-ublox").arg(prefix); break; + case VehicleConfigurationSource::GPS_UBX_FLEXI_I2CMAG: + elementsToShow << QString("%1generic-ublox-mag").arg(prefix); + break; default: break; } diff --git a/ground/gcs/src/plugins/setupwizard/outputcalibrationutil.cpp b/ground/gcs/src/plugins/setupwizard/outputcalibrationutil.cpp index c212f25c1..eefcf9065 100644 --- a/ground/gcs/src/plugins/setupwizard/outputcalibrationutil.cpp +++ b/ground/gcs/src/plugins/setupwizard/outputcalibrationutil.cpp @@ -27,12 +27,16 @@ */ #include "outputcalibrationutil.h" + #include "uavobject.h" #include "uavobjectmanager.h" #include "extensionsystem/pluginmanager.h" #include "vehicleconfigurationhelper.h" + #include "manualcontrolsettings.h" +#include + bool OutputCalibrationUtil::c_prepared = false; ActuatorCommand::Metadata OutputCalibrationUtil::c_savedActuatorCommandMetaData; diff --git a/ground/gcs/src/plugins/setupwizard/outputcalibrationutil.h b/ground/gcs/src/plugins/setupwizard/outputcalibrationutil.h index b47764d4e..727dd8189 100644 --- a/ground/gcs/src/plugins/setupwizard/outputcalibrationutil.h +++ b/ground/gcs/src/plugins/setupwizard/outputcalibrationutil.h @@ -30,8 +30,8 @@ #define OUTPUTCALIBRATIONUTIL_H #include -#include "actuatorcommand.h" +#include "actuatorcommand.h" class OutputCalibrationUtil : public QObject { Q_OBJECT diff --git a/ground/gcs/src/plugins/setupwizard/pages/airspeedpage.cpp b/ground/gcs/src/plugins/setupwizard/pages/airspeedpage.cpp index 74ae4ef70..8182e2bd4 100644 --- a/ground/gcs/src/plugins/setupwizard/pages/airspeedpage.cpp +++ b/ground/gcs/src/plugins/setupwizard/pages/airspeedpage.cpp @@ -39,9 +39,17 @@ void AirSpeedPage::initializePage(VehicleConfigurationSource *settings) { // Enable all setItemDisabled(-1, false); - if (settings->getInputType() == VehicleConfigurationSource::INPUT_SBUS || - settings->getInputType() == VehicleConfigurationSource::INPUT_DSM) { - // Disable non estimated sensors if ports are taken by receivers + + bool isSparky = (getWizard()->getControllerType() == SetupWizard::CONTROLLER_SPARKY2); + + if ((!isSparky && (settings->getInputType() == VehicleConfigurationSource::INPUT_SBUS || + settings->getInputType() == VehicleConfigurationSource::INPUT_DSM || + settings->getInputType() == VehicleConfigurationSource::INPUT_SRXL || + settings->getInputType() == VehicleConfigurationSource::INPUT_HOTT_SUMD || + settings->getInputType() == VehicleConfigurationSource::INPUT_IBUS || + settings->getInputType() == VehicleConfigurationSource::INPUT_EXBUS)) || + settings->getGpsType() == VehicleConfigurationSource::GPS_UBX_FLEXI_I2CMAG) { + // Disable non estimated sensors if ports are taken by receivers or I2C Mag setItemDisabled(VehicleConfigurationSource::AIRSPEED_EAGLETREE, true); setItemDisabled(VehicleConfigurationSource::AIRSPEED_MS4525, true); if (getSelectedItem()->id() == VehicleConfigurationSource::AIRSPEED_EAGLETREE || @@ -66,6 +74,7 @@ void AirSpeedPage::setupSelection(Selection *selection) "software estimation technique and the other two utilize hardware sensors.\n\n" "Note: if previously selected input combinations use the Flexi-port for input, " "only estimated airspeed will be available.\n\n")); + selection->addItem(tr("Estimated"), tr("This option uses an intelligent estimation algorithm which utilizes the INS/GPS " "to estimate wind speed and subtract it from ground speed obtained from the GPS.\n\n" diff --git a/ground/gcs/src/plugins/setupwizard/pages/controllerpage.cpp b/ground/gcs/src/plugins/setupwizard/pages/controllerpage.cpp index 41f2f5022..2235220b4 100644 --- a/ground/gcs/src/plugins/setupwizard/pages/controllerpage.cpp +++ b/ground/gcs/src/plugins/setupwizard/pages/controllerpage.cpp @@ -117,6 +117,9 @@ SetupWizard::CONTROLLER_TYPE ControllerPage::getControllerType() case 0x0905: return SetupWizard::CONTROLLER_NANO; + case 0x9201: + return SetupWizard::CONTROLLER_SPARKY2; + default: return SetupWizard::CONTROLLER_UNKNOWN; } @@ -139,6 +142,7 @@ void ControllerPage::setupBoardTypes() ui->boardTypeCombo->addItem(tr("OpenPilot OPLink Radio Modem"), SetupWizard::CONTROLLER_OPLINK); ui->boardTypeCombo->addItem(tr("OpenPilot DiscoveryF4"), SetupWizard::CONTROLLER_DISCOVERYF4); ui->boardTypeCombo->addItem(tr("OpenPilot Nano"), SetupWizard::CONTROLLER_NANO); + ui->boardTypeCombo->addItem(tr("TauLabs Sparky 2.0"), SetupWizard::CONTROLLER_SPARKY2); } void ControllerPage::setControllerType(SetupWizard::CONTROLLER_TYPE type) @@ -225,6 +229,11 @@ void ControllerPage::connectionStatusChanged() ui->boardImg->setPixmap(boardPic.scaled(picSize, Qt::KeepAspectRatio)); break; + case SetupWizard::CONTROLLER_SPARKY2: + boardPic.load(":/configgadget/images/sparky2_top.png"); + ui->boardImg->setPixmap(boardPic.scaled(picSize, Qt::KeepAspectRatio)); + break; + default: ui->boardImg->setPixmap(QPixmap()); break; diff --git a/ground/gcs/src/plugins/setupwizard/pages/controllerpage.ui b/ground/gcs/src/plugins/setupwizard/pages/controllerpage.ui index 031cd240e..a6bafb057 100644 --- a/ground/gcs/src/plugins/setupwizard/pages/controllerpage.ui +++ b/ground/gcs/src/plugins/setupwizard/pages/controllerpage.ui @@ -67,6 +67,9 @@ p, li { white-space: pre-wrap; } + + QLayout::SetMaximumSize + 6 @@ -104,120 +107,97 @@ p, li { white-space: pre-wrap; } - - - Qt::Vertical + + + 0 - - - 20 - 9 - - - - - - - - - - - - - 150 - 0 - - - - - 10 - 50 - false - - - - Connection device: - - - - - - - - 0 - 0 - - - - - + + + + + 0 + 0 + + + - - - - - - - 150 - 0 - - - - - 10 - 50 - false - - - - Detected board type: - - - - - - - false - - - - 0 - 0 - - - - - + + + + + 150 + 0 + + + + + 10 + 50 + false + + + + Detected board type: + + - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 120 - 16777215 - - - - Connect - - - - + + + + + 150 + 0 + + + + + 10 + 50 + false + + + + Connection device: + + + + + + + false + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + 130 + 0 + + + + + 130 + 16777215 + + + + Connect + + diff --git a/ground/gcs/src/plugins/setupwizard/pages/esccalibrationpage.cpp b/ground/gcs/src/plugins/setupwizard/pages/esccalibrationpage.cpp index 720103151..874beeba2 100644 --- a/ground/gcs/src/plugins/setupwizard/pages/esccalibrationpage.cpp +++ b/ground/gcs/src/plugins/setupwizard/pages/esccalibrationpage.cpp @@ -2,7 +2,8 @@ ****************************************************************************** * * @file EscCalibrationPage.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014. * @addtogroup * @{ * @addtogroup EscCalibrationPage @@ -46,7 +47,7 @@ EscCalibrationPage::EscCalibrationPage(SetupWizard *wizard, QWidget *parent) : ui->outputHigh->setEnabled(false); ui->outputLow->setEnabled(true); ui->outputLevel->setEnabled(true); - ui->outputLevel->setText(QString(tr("%1 µs")).arg(OFF_PWM_OUTPUT_PULSE_LENGTH_MICROSECONDS)); + ui->outputLevel->setText(QString(tr("%1 µs")).arg(LOW_PWM_OUTPUT_PULSE_LENGTH_MICROSECONDS)); connect(ui->startButton, SIGNAL(clicked()), this, SLOT(startButtonClicked())); connect(ui->stopButton, SIGNAL(clicked()), this, SLOT(stopButtonClicked())); @@ -61,6 +62,11 @@ EscCalibrationPage::~EscCalibrationPage() delete ui; } +void EscCalibrationPage::initializePage() +{ + resetAllSecurityCheckboxes(); +} + bool EscCalibrationPage::validatePage() { return true; @@ -143,6 +149,7 @@ void EscCalibrationPage::stopButtonClicked() if (m_isCalibrating) { ui->stopButton->setEnabled(false); ui->outputHigh->setEnabled(false); + ui->outputLow->setEnabled(true); // Set to low pwm out m_outputUtil.setChannelOutputValue(LOW_PWM_OUTPUT_PULSE_LENGTH_MICROSECONDS); @@ -150,21 +157,10 @@ void EscCalibrationPage::stopButtonClicked() QApplication::processEvents(); QThread::msleep(2000); - // Ramp down to off pwm out - for (int i = LOW_PWM_OUTPUT_PULSE_LENGTH_MICROSECONDS; i >= OFF_PWM_OUTPUT_PULSE_LENGTH_MICROSECONDS; i -= 10) { - m_outputUtil.setChannelOutputValue(i); - ui->outputLevel->setText(QString(tr("%1 µs")).arg(i)); - QApplication::processEvents(); - QThread::msleep(200); - } - - // Stop output + // Stop output, back to minimal value (1000) defined in vehicleconfigurationsource.h m_outputUtil.stopChannelOutput(); OutputCalibrationUtil::stopOutputCalibration(); - ui->outputLevel->setText(QString(tr("%1 µs")).arg(OFF_PWM_OUTPUT_PULSE_LENGTH_MICROSECONDS)); - ui->outputHigh->setEnabled(false); - ui->outputLow->setEnabled(true); ui->nonconnectedLabel->setEnabled(true); ui->connectedLabel->setEnabled(false); m_outputChannels.clear(); @@ -180,9 +176,3 @@ void EscCalibrationPage::securityCheckBoxesToggled() ui->securityCheckBox2->isChecked() && ui->securityCheckBox3->isChecked()); } - - -void EscCalibrationPage::initializePage() -{ - resetAllSecurityCheckboxes(); -} diff --git a/ground/gcs/src/plugins/setupwizard/pages/esccalibrationpage.h b/ground/gcs/src/plugins/setupwizard/pages/esccalibrationpage.h index 0d9d9a94a..f9abf5b56 100644 --- a/ground/gcs/src/plugins/setupwizard/pages/esccalibrationpage.h +++ b/ground/gcs/src/plugins/setupwizard/pages/esccalibrationpage.h @@ -2,7 +2,8 @@ ****************************************************************************** * * @file biascalibrationpage.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. * @addtogroup * @{ * @addtogroup BiasCalibrationPage @@ -42,8 +43,8 @@ class EscCalibrationPage : public AbstractWizardPage { public: explicit EscCalibrationPage(SetupWizard *wizard, QWidget *parent = 0); ~EscCalibrationPage(); - bool validatePage(); void initializePage(); + bool validatePage(); private slots: void startButtonClicked(); @@ -53,8 +54,10 @@ private slots: void resetAllSecurityCheckboxes(); private: - static const int LOW_PWM_OUTPUT_PULSE_LENGTH_MICROSECONDS = 1050; static const int OFF_PWM_OUTPUT_PULSE_LENGTH_MICROSECONDS = 900; + + // Min value should match min value defined in vehicleconfigurationsource.h + static const int LOW_PWM_OUTPUT_PULSE_LENGTH_MICROSECONDS = 1000; static const int HIGH_PWM_OUTPUT_PULSE_LENGTH_MICROSECONDS = 1900; static const int HIGH_ONESHOT125_OUTPUT_PULSE_LENGTH_MICROSECONDS = 2000; Ui::EscCalibrationPage *ui; diff --git a/ground/gcs/src/plugins/setupwizard/pages/escpage.cpp b/ground/gcs/src/plugins/setupwizard/pages/escpage.cpp index fe1e85654..2bd35b1dd 100644 --- a/ground/gcs/src/plugins/setupwizard/pages/escpage.cpp +++ b/ground/gcs/src/plugins/setupwizard/pages/escpage.cpp @@ -2,7 +2,8 @@ ****************************************************************************** * * @file escpage.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014. * @addtogroup * @{ * @addtogroup EscPage @@ -42,6 +43,17 @@ EscPage::~EscPage() delete ui; } +void EscPage::initializePage() +{ + bool enabled = isSynchOrOneShotAvailable(); + + ui->oneshotESCButton->setEnabled(enabled); + if (ui->oneshotESCButton->isChecked() && !enabled) { + ui->oneshotESCButton->setChecked(false); + ui->rapidESCButton->setChecked(true); + } +} + bool EscPage::validatePage() { if (ui->oneshotESCButton->isChecked()) { @@ -59,18 +71,6 @@ bool EscPage::validatePage() return true; } - -void EscPage::initializePage() -{ - bool enabled = isSynchOrOneShotAvailable(); - - ui->oneshotESCButton->setEnabled(enabled); - if (ui->oneshotESCButton->isChecked() && !enabled) { - ui->oneshotESCButton->setChecked(false); - ui->rapidESCButton->setChecked(true); - } -} - bool EscPage::isSynchOrOneShotAvailable() { bool available = true; @@ -98,6 +98,7 @@ bool EscPage::isSynchOrOneShotAvailable() } break; case SetupWizard::CONTROLLER_REVO: + case SetupWizard::CONTROLLER_SPARKY2: available = true; break; default: diff --git a/ground/gcs/src/plugins/setupwizard/pages/escpage.h b/ground/gcs/src/plugins/setupwizard/pages/escpage.h index 093457860..a0e4ec0fb 100644 --- a/ground/gcs/src/plugins/setupwizard/pages/escpage.h +++ b/ground/gcs/src/plugins/setupwizard/pages/escpage.h @@ -40,8 +40,8 @@ class EscPage : public AbstractWizardPage { public: explicit EscPage(SetupWizard *wizard, QWidget *parent = 0); ~EscPage(); - bool validatePage(); void initializePage(); + bool validatePage(); private: Ui::EscPage *ui; diff --git a/ground/gcs/src/plugins/setupwizard/pages/escpage.ui b/ground/gcs/src/plugins/setupwizard/pages/escpage.ui index 33bac73b7..b26f440d2 100644 --- a/ground/gcs/src/plugins/setupwizard/pages/escpage.ui +++ b/ground/gcs/src/plugins/setupwizard/pages/escpage.ui @@ -59,7 +59,7 @@ p, li { white-space: pre-wrap; } - Standard ESC 50Hz + Standard ESC: Slow refresh rate (50Hz), not recommended for Multirotors. QToolButton { border: none } @@ -103,7 +103,7 @@ p, li { white-space: pre-wrap; } - Turbo PWM ESC 400Hz + Rapid ESC: Usually Simonk, 490Hz refresh rate. QToolButton { border: none } @@ -150,7 +150,7 @@ p, li { white-space: pre-wrap; } - Turbo PWM ESC 400Hz + OneShot ESC: BLHeli, Kiss... QToolButton { border: none } diff --git a/ground/gcs/src/plugins/setupwizard/pages/gpspage.cpp b/ground/gcs/src/plugins/setupwizard/pages/gpspage.cpp index 448d4bb91..2cba4670b 100644 --- a/ground/gcs/src/plugins/setupwizard/pages/gpspage.cpp +++ b/ground/gcs/src/plugins/setupwizard/pages/gpspage.cpp @@ -37,7 +37,24 @@ GpsPage::~GpsPage() void GpsPage::initializePage(VehicleConfigurationSource *settings) { - Q_UNUSED(settings); + // Enable all + setItemDisabled(-1, false); + + bool isSparky = (getWizard()->getControllerType() == SetupWizard::CONTROLLER_SPARKY2); + // All rcinputs are on rcvrport for sparky2, that leaves mainport/flexiport available for gps/auxmag + if (!isSparky && (settings->getInputType() == VehicleConfigurationSource::INPUT_SBUS || + settings->getInputType() == VehicleConfigurationSource::INPUT_DSM || + settings->getInputType() == VehicleConfigurationSource::INPUT_SRXL || + settings->getInputType() == VehicleConfigurationSource::INPUT_HOTT_SUMD || + settings->getInputType() == VehicleConfigurationSource::INPUT_IBUS || + settings->getInputType() == VehicleConfigurationSource::INPUT_EXBUS)) { + // Disable GPS+I2C Mag + setItemDisabled(VehicleConfigurationSource::GPS_UBX_FLEXI_I2CMAG, true); + if (getSelectedItem()->id() == VehicleConfigurationSource::GPS_UBX_FLEXI_I2CMAG) { + // If previously selected invalid GPS, reset to no GPS + setSelectedItem(VehicleConfigurationSource::GPS_DISABLED); + } + } } bool GpsPage::validatePage(SelectionItem *selectedItem) @@ -70,6 +87,17 @@ void GpsPage::setupSelection(Selection *selection) "OPGPS-v9", SetupWizard::GPS_PLATINUM); + selection->addItem(tr("Naza GPS"), + tr("Select this option to use the Naza GPS with integrated Magnetometer."), + "NazaGPS", + SetupWizard::GPS_NAZA); + + selection->addItem(tr("U-Blox Based + Magnetometer"), + tr("Select this option for the generic U-Blox chipset based GPS + I2C Magnetometer.\n\n" + "GPS is connected to MainPort and two wires I2C to FlexiPort."), + "generic-ublox-mag", + SetupWizard::GPS_UBX_FLEXI_I2CMAG); + selection->addItem(tr("U-Blox Based"), tr("Select this option for the OpenPilot V8 GPS or generic U-Blox chipset based GPS."), "OPGPS-v8-ublox", diff --git a/ground/gcs/src/plugins/setupwizard/pages/inputpage.cpp b/ground/gcs/src/plugins/setupwizard/pages/inputpage.cpp index 25ab2000a..87354fc14 100644 --- a/ground/gcs/src/plugins/setupwizard/pages/inputpage.cpp +++ b/ground/gcs/src/plugins/setupwizard/pages/inputpage.cpp @@ -1,14 +1,15 @@ /** - ****************************************************************************** + **************************************************************************************** * * @file inputpage.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. * @addtogroup * @{ * @addtogroup InputPage * @{ * @brief - *****************************************************************************/ + ***************************************************************************************/ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -45,6 +46,17 @@ InputPage::~InputPage() delete ui; } +void InputPage::initializePage() +{ + bool isSparky2 = (getWizard()->getControllerType() == SetupWizard::CONTROLLER_SPARKY2); + + ui->pwmButton->setEnabled(!isSparky2); + if (ui->pwmButton->isChecked() && isSparky2) { + ui->pwmButton->setChecked(false); + ui->ppmButton->setChecked(true); + } +} + bool InputPage::validatePage() { if (ui->pwmButton->isChecked()) { @@ -53,6 +65,12 @@ bool InputPage::validatePage() getWizard()->setInputType(SetupWizard::INPUT_PPM); } else if (ui->sbusButton->isChecked()) { getWizard()->setInputType(SetupWizard::INPUT_SBUS); + } else if (ui->graupnerButton->isChecked()) { + getWizard()->setInputType(SetupWizard::INPUT_HOTT_SUMD); + } else if (ui->jetiButton->isChecked()) { + getWizard()->setInputType(SetupWizard::INPUT_EXBUS); + } else if (ui->flyskyButton->isChecked()) { + getWizard()->setInputType(SetupWizard::INPUT_IBUS); } else if (ui->spectrumButton->isChecked()) { getWizard()->setInputType(SetupWizard::INPUT_DSM); } else if (ui->multiplexButton->isChecked()) { @@ -87,6 +105,18 @@ bool InputPage::restartNeeded(VehicleConfigurationSource::INPUT_TYPE selectedTyp case VehicleConfigurationSource::INPUT_SBUS: return data.CC_MainPort != HwSettings::CC_MAINPORT_SBUS; + case VehicleConfigurationSource::INPUT_SRXL: + return data.CC_FlexiPort != HwSettings::CC_FLEXIPORT_SRXL; + + case VehicleConfigurationSource::INPUT_HOTT_SUMD: + return data.CC_FlexiPort != HwSettings::CC_FLEXIPORT_HOTTSUMD; + + case VehicleConfigurationSource::INPUT_EXBUS: + return data.CC_FlexiPort != HwSettings::CC_FLEXIPORT_EXBUS; + + case VehicleConfigurationSource::INPUT_IBUS: + return data.CC_FlexiPort != HwSettings::CC_FLEXIPORT_IBUS; + case VehicleConfigurationSource::INPUT_DSM: // TODO: Handle all of the DSM types ?? Which is most common? return data.CC_MainPort != HwSettings::CC_MAINPORT_DSM; @@ -109,6 +139,15 @@ bool InputPage::restartNeeded(VehicleConfigurationSource::INPUT_TYPE selectedTyp case VehicleConfigurationSource::INPUT_SBUS: return data.RM_MainPort != HwSettings::RM_MAINPORT_SBUS; + case VehicleConfigurationSource::INPUT_HOTT_SUMD: + return data.RM_FlexiPort != HwSettings::RM_FLEXIPORT_HOTTSUMD; + + case VehicleConfigurationSource::INPUT_EXBUS: + return data.RM_FlexiPort != HwSettings::RM_FLEXIPORT_EXBUS; + + case VehicleConfigurationSource::INPUT_IBUS: + return data.RM_FlexiPort != HwSettings::RM_FLEXIPORT_IBUS; + case VehicleConfigurationSource::INPUT_SRXL: return data.RM_FlexiPort != HwSettings::RM_FLEXIPORT_SRXL; @@ -120,6 +159,35 @@ bool InputPage::restartNeeded(VehicleConfigurationSource::INPUT_TYPE selectedTyp } break; } + case SetupWizard::CONTROLLER_SPARKY2: + { + switch (selectedType) { + case VehicleConfigurationSource::INPUT_PPM: + return data.SPK2_RcvrPort != HwSettings::SPK2_RCVRPORT_PPM; + + case VehicleConfigurationSource::INPUT_SBUS: + return data.SPK2_RcvrPort != HwSettings::SPK2_RCVRPORT_SBUS; + + case VehicleConfigurationSource::INPUT_SRXL: + return data.SPK2_RcvrPort != HwSettings::SPK2_RCVRPORT_SRXL; + + case VehicleConfigurationSource::INPUT_DSM: + // TODO: Handle all of the DSM types ?? Which is most common? + return data.SPK2_RcvrPort != HwSettings::SPK2_RCVRPORT_DSM; + + case VehicleConfigurationSource::INPUT_HOTT_SUMD: + return data.SPK2_RcvrPort != HwSettings::SPK2_RCVRPORT_HOTTSUMD; + + case VehicleConfigurationSource::INPUT_EXBUS: + return data.SPK2_RcvrPort != HwSettings::SPK2_RCVRPORT_EXBUS; + + case VehicleConfigurationSource::INPUT_IBUS: + return data.SPK2_RcvrPort != HwSettings::SPK2_RCVRPORT_IBUS; + + default: return true; + } + break; + } default: return true; } } diff --git a/ground/gcs/src/plugins/setupwizard/pages/inputpage.h b/ground/gcs/src/plugins/setupwizard/pages/inputpage.h index 7b0221527..2c227e942 100644 --- a/ground/gcs/src/plugins/setupwizard/pages/inputpage.h +++ b/ground/gcs/src/plugins/setupwizard/pages/inputpage.h @@ -40,6 +40,7 @@ class InputPage : public AbstractWizardPage { public: explicit InputPage(SetupWizard *wizard, QWidget *parent = 0); ~InputPage(); + void initializePage(); bool validatePage(); private: diff --git a/ground/gcs/src/plugins/setupwizard/pages/inputpage.ui b/ground/gcs/src/plugins/setupwizard/pages/inputpage.ui index 64cc961ee..eb6147641 100644 --- a/ground/gcs/src/plugins/setupwizard/pages/inputpage.ui +++ b/ground/gcs/src/plugins/setupwizard/pages/inputpage.ui @@ -6,8 +6,8 @@ 0 0 - 600 - 400 + 753 + 494 @@ -50,7 +50,10 @@ p, li { white-space: pre-wrap; } - + + + 20 + @@ -177,6 +180,13 @@ p, li { white-space: pre-wrap; } + + + + + + 2 + @@ -259,6 +269,129 @@ p, li { white-space: pre-wrap; } + + + + + 10 + + + + Graupner HoTT + + + QToolButton { border: none } + + + HoTT + + + + :/setupwizard/resources/bttn-hott-up.png + :/setupwizard/resources/bttn-hott-down.png:/setupwizard/resources/bttn-hott-up.png + + + + 100 + 100 + + + + true + + + true + + + Qt::ToolButtonTextUnderIcon + + + true + + + + + + + + 10 + + + + Jeti EX.Bus + + + QToolButton { border: none } + + + EX.Bus + + + + :/setupwizard/resources/bttn-exbus-up.png + :/setupwizard/resources/bttn-exbus-down.png:/setupwizard/resources/bttn-exbus-up.png + + + + 100 + 100 + + + + true + + + true + + + Qt::ToolButtonTextUnderIcon + + + true + + + + + + + + 10 + + + + FlySky IBus + + + QToolButton { border: none } + + + IBus + + + + :/setupwizard/resources/bttn-ibus-up.png + :/setupwizard/resources/bttn-ibus-down.png:/setupwizard/resources/bttn-ibus-up.png + + + + 100 + 100 + + + + true + + + true + + + Qt::ToolButtonTextUnderIcon + + + true + + +
diff --git a/ground/gcs/src/plugins/setupwizard/pages/outputcalibrationpage.ui b/ground/gcs/src/plugins/setupwizard/pages/outputcalibrationpage.ui index 120dda01b..31e62c326 100644 --- a/ground/gcs/src/plugins/setupwizard/pages/outputcalibrationpage.ui +++ b/ground/gcs/src/plugins/setupwizard/pages/outputcalibrationpage.ui @@ -197,7 +197,7 @@ p, li { white-space: pre-wrap; } - + @@ -217,7 +217,7 @@ p, li { white-space: pre-wrap; } - + Qt::Vertical @@ -628,7 +628,7 @@ QSlider::handle:horizontal:hover { - + Min @@ -669,7 +669,7 @@ QSlider::handle:horizontal:hover { - + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> @@ -1130,7 +1130,7 @@ QSlider::handle:horizontal:hover { - + 6 @@ -1520,21 +1520,21 @@ QSlider::handle:horizontal:hover { - + Min - + Center - + Max diff --git a/ground/gcs/src/plugins/setupwizard/pages/savepage.cpp b/ground/gcs/src/plugins/setupwizard/pages/savepage.cpp index 8ab43e761..82a795bf3 100644 --- a/ground/gcs/src/plugins/setupwizard/pages/savepage.cpp +++ b/ground/gcs/src/plugins/setupwizard/pages/savepage.cpp @@ -26,11 +26,14 @@ */ #include + #include "savepage.h" #include "ui_savepage.h" #include "setupwizard.h" #include "vehicleconfigurationhelper.h" +#include + SavePage::SavePage(SetupWizard *wizard, QWidget *parent) : AbstractWizardPage(wizard, parent), ui(new Ui::SavePage), m_successfulWrite(false) diff --git a/ground/gcs/src/plugins/setupwizard/pages/selectionpage.ui b/ground/gcs/src/plugins/setupwizard/pages/selectionpage.ui index 772009a49..f90efc09d 100644 --- a/ground/gcs/src/plugins/setupwizard/pages/selectionpage.ui +++ b/ground/gcs/src/plugins/setupwizard/pages/selectionpage.ui @@ -24,7 +24,7 @@ - placeholder_text + placeholder_text Qt::PlainText @@ -40,7 +40,7 @@ - TextLabel + TextLabel true diff --git a/ground/gcs/src/plugins/setupwizard/pages/summarypage.h b/ground/gcs/src/plugins/setupwizard/pages/summarypage.h index daf5402b1..a27510df7 100644 --- a/ground/gcs/src/plugins/setupwizard/pages/summarypage.h +++ b/ground/gcs/src/plugins/setupwizard/pages/summarypage.h @@ -2,7 +2,8 @@ ****************************************************************************** * * @file summarypage.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. * @addtogroup * @{ * @addtogroup SummaryPage @@ -40,8 +41,8 @@ class SummaryPage : public AbstractWizardPage { public: explicit SummaryPage(SetupWizard *wizard, QWidget *parent = 0); ~SummaryPage(); - bool validatePage(); void initializePage(); + bool validatePage(); private: Ui::SummaryPage *ui; diff --git a/ground/gcs/src/plugins/setupwizard/pages/summarypage.ui b/ground/gcs/src/plugins/setupwizard/pages/summarypage.ui index 4d8806c84..f5306bae9 100644 --- a/ground/gcs/src/plugins/setupwizard/pages/summarypage.ui +++ b/ground/gcs/src/plugins/setupwizard/pages/summarypage.ui @@ -65,11 +65,23 @@ p, li { white-space: pre-wrap; } + + + 0 + 0 + + + + + 0 + 0 + + Show connection diagram for configuration - QToolButton { border: none } + @@ -80,8 +92,8 @@ p, li { white-space: pre-wrap; } - 170 - 170 + 210 + 210 diff --git a/ground/gcs/src/plugins/setupwizard/pages/surfacepage.ui b/ground/gcs/src/plugins/setupwizard/pages/surfacepage.ui deleted file mode 100644 index 068205184..000000000 --- a/ground/gcs/src/plugins/setupwizard/pages/surfacepage.ui +++ /dev/null @@ -1,38 +0,0 @@ - - - SurfacePage - - - - 0 - 0 - 600 - 400 - - - - WizardPage - - - - - 50 - 160 - 500 - 41 - - - - <html><head/><body><p align="center"><span style=" font-family:'MS Shell Dlg 2'; font-size:12pt; font-weight:600;">The Surface Vehicle section of the Setup Wizard is not yet implemented</span><br/></p></body></html> - - - Qt::AlignHCenter|Qt::AlignTop - - - true - - - - - - diff --git a/ground/gcs/src/plugins/setupwizard/pages/vehiclepage.cpp b/ground/gcs/src/plugins/setupwizard/pages/vehiclepage.cpp index a5cf5f109..6ce99f262 100644 --- a/ground/gcs/src/plugins/setupwizard/pages/vehiclepage.cpp +++ b/ground/gcs/src/plugins/setupwizard/pages/vehiclepage.cpp @@ -2,7 +2,8 @@ ****************************************************************************** * * @file vehiclepage.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. * @addtogroup * @{ * @addtogroup VehiclePage @@ -57,9 +58,3 @@ bool VehiclePage::validatePage() } return true; } - -void VehiclePage::initializePage() -{ - // ui->fixedwingButton->setEnabled(getWizard()->getControllerType() == SetupWizard::CONTROLLER_REVO || - // getWizard()->getControllerType() == SetupWizard::CONTROLLER_NANO); -} diff --git a/ground/gcs/src/plugins/setupwizard/pages/vehiclepage.h b/ground/gcs/src/plugins/setupwizard/pages/vehiclepage.h index 659ac74cd..5235387c9 100644 --- a/ground/gcs/src/plugins/setupwizard/pages/vehiclepage.h +++ b/ground/gcs/src/plugins/setupwizard/pages/vehiclepage.h @@ -2,7 +2,8 @@ ****************************************************************************** * * @file vehiclepage.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. * @addtogroup * @{ * @addtogroup VehiclePage @@ -41,7 +42,6 @@ public: explicit VehiclePage(SetupWizard *wizard, QWidget *parent = 0); ~VehiclePage(); bool validatePage(); - void initializePage(); private: Ui::VehiclePage *ui; diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-ESC-down.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-ESC-down.png index 26899fb5a..5e2d9ae21 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-ESC-down.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-ESC-down.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-ESC-up.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-ESC-up.png index 07016ddc1..addb196ee 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-ESC-up.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-ESC-up.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-calculate-down.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-calculate-down.png index 5681d474e..d12884ae6 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-calculate-down.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-calculate-down.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-calculate-up.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-calculate-up.png index c2e2add72..4d327c2e5 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-calculate-up.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-calculate-up.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-exbus-down.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-exbus-down.png new file mode 100644 index 000000000..ea78a50a9 Binary files /dev/null and b/ground/gcs/src/plugins/setupwizard/resources/bttn-exbus-down.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-exbus-up.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-exbus-up.png new file mode 100644 index 000000000..10e27c6dc Binary files /dev/null and b/ground/gcs/src/plugins/setupwizard/resources/bttn-exbus-up.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-flash-down.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-flash-down.png index 601c9e349..228d79f37 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-flash-down.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-flash-down.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-flash-up.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-flash-up.png index ca01e42e7..7959b6d97 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-flash-up.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-flash-up.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-heli-down.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-heli-down.png index 0d75a7ba8..d5b4c2a8c 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-heli-down.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-heli-down.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-heli-over.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-heli-over.png index d979da128..98af71368 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-heli-over.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-heli-over.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-heli-up.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-heli-up.png index 49236a2b6..f8b5eeb31 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-heli-up.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-heli-up.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-hott-down.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-hott-down.png new file mode 100644 index 000000000..828865abf Binary files /dev/null and b/ground/gcs/src/plugins/setupwizard/resources/bttn-hott-down.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-hott-up.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-hott-up.png new file mode 100644 index 000000000..31604bd85 Binary files /dev/null and b/ground/gcs/src/plugins/setupwizard/resources/bttn-hott-up.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-ibus-down.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-ibus-down.png new file mode 100644 index 000000000..762b30bd7 Binary files /dev/null and b/ground/gcs/src/plugins/setupwizard/resources/bttn-ibus-down.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-ibus-up.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-ibus-up.png new file mode 100644 index 000000000..a5b0333d4 Binary files /dev/null and b/ground/gcs/src/plugins/setupwizard/resources/bttn-ibus-up.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-illustration-color-down.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-illustration-color-down.png index 0ff718831..2c6d51d9d 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-illustration-color-down.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-illustration-color-down.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-illustration-color-up.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-illustration-color-up.png index f647c7d57..92204db15 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-illustration-color-up.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-illustration-color-up.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-land-down.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-land-down.png index ed2c66934..8301e35f1 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-land-down.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-land-down.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-land-over.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-land-over.png index 8d6336bc4..c4b40820a 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-land-over.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-land-over.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-land-up.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-land-up.png index 7d90f4a2d..5c5a3c27f 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-land-up.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-land-up.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-multi-down.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-multi-down.png index 7da5b4fdc..918d4de9c 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-multi-down.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-multi-down.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-multi-over.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-multi-over.png index 82a017767..f9aa1d257 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-multi-over.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-multi-over.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-multi-up.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-multi-up.png index 882d6edfa..1b4a731a1 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-multi-up.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-multi-up.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-oneshot-dwn.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-oneshot-dwn.png index 658b568a9..4c2366062 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-oneshot-dwn.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-oneshot-dwn.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-oneshot-up.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-oneshot-up.png index 00363c051..aae7e4ef8 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-oneshot-up.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-oneshot-up.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-oneshot125-down.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-oneshot125-down.png index 658b568a9..4c2366062 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-oneshot125-down.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-oneshot125-down.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-oneshot125-up.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-oneshot125-up.png index 00363c051..aae7e4ef8 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-oneshot125-up.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-oneshot125-up.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-plane-down.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-plane-down.png index 42bfddd28..3cb8883be 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-plane-down.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-plane-down.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-plane-over.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-plane-over.png index d99efed99..6b245686a 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-plane-over.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-plane-over.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-plane-up.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-plane-up.png index 4ccb6567d..82bbc5ae4 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-plane-up.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-plane-up.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-ppm-down.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-ppm-down.png index 03706d360..511fd0fac 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-ppm-down.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-ppm-down.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-ppm-up.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-ppm-up.png index f58e5596b..78c25b556 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-ppm-up.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-ppm-up.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-pwm-down.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-pwm-down.png index 72656896a..ae0a1f16d 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-pwm-down.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-pwm-down.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-pwm-up.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-pwm-up.png index 25d3624dd..cc7c39099 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-pwm-up.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-pwm-up.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-rapid-dwn.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-rapid-dwn.png index f9fa41961..49732b0dc 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-rapid-dwn.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-rapid-dwn.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-rapid-up.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-rapid-up.png index 7c6875f28..ccfc202af 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-rapid-up.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-rapid-up.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-sat-down.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-sat-down.png index 05bc35895..267b6d78b 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-sat-down.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-sat-down.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-sat-up.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-sat-up.png index 37e16c2cb..ae5b6679f 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-sat-up.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-sat-up.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-save-down.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-save-down.png index 13b6e3fa5..9a9339d0f 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-save-down.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-save-down.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-save-up.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-save-up.png index 9e6655d0c..18d56f604 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-save-up.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-save-up.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-sbus-down.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-sbus-down.png index ffea88361..64ec73b86 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-sbus-down.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-sbus-down.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-sbus-up.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-sbus-up.png index 9937ac0b4..46c5a841d 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-sbus-up.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-sbus-up.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-servo-digital-dwn.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-servo-digital-dwn.png index 90bac4ba1..1ce396d2f 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-servo-digital-dwn.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-servo-digital-dwn.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-servo-digital-up.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-servo-digital-up.png index 2302ae70e..b638063ba 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-servo-digital-up.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-servo-digital-up.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-servo-standard-dwn.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-servo-standard-dwn.png index dfbf34c45..fb1b55604 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-servo-standard-dwn.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-servo-standard-dwn.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-servo-standard-up.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-servo-standard-up.png index bd2d067a7..7d7c55adc 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-servo-standard-up.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-servo-standard-up.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-srxl-down.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-srxl-down.png index 9888fb0c2..bb63e3497 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-srxl-down.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-srxl-down.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-srxl-up.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-srxl-up.png index 022c77872..230c3012e 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-srxl-up.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-srxl-up.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-turbo-down.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-turbo-down.png index 2a6f0a8db..376b6bbc9 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-turbo-down.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-turbo-down.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-turbo-up.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-turbo-up.png index 7a8013432..afe1bff9e 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-turbo-up.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-turbo-up.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-txwizard-off.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-txwizard-off.png index 61570522e..d949e477a 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-txwizard-off.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-txwizard-off.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-txwizard-on.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-txwizard-on.png index 2e8806e0e..f156c6684 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-txwizard-on.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-txwizard-on.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-upgrade-down.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-upgrade-down.png index 603bac917..904668c9f 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-upgrade-down.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-upgrade-down.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/bttn-upgrade-up.png b/ground/gcs/src/plugins/setupwizard/resources/bttn-upgrade-up.png index c3177508b..0b284acd3 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/bttn-upgrade-up.png and b/ground/gcs/src/plugins/setupwizard/resources/bttn-upgrade-up.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/connected.png b/ground/gcs/src/plugins/setupwizard/resources/connected.png index d1fd2d044..521bd0702 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/connected.png and b/ground/gcs/src/plugins/setupwizard/resources/connected.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/connection-diagrams.svg b/ground/gcs/src/plugins/setupwizard/resources/connection-diagrams.svg index f8c5882ba..7a5acbdea 100644 --- a/ground/gcs/src/plugins/setupwizard/resources/connection-diagrams.svg +++ b/ground/gcs/src/plugins/setupwizard/resources/connection-diagrams.svg @@ -26,29 +26,29 @@ guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" - inkscape:window-width="1280" - inkscape:window-height="928" + inkscape:window-width="1920" + inkscape:window-height="983" id="namedview4616" showgrid="false" - inkscape:zoom="1.6073688" - inkscape:cx="845.3775" - inkscape:cy="601.39702" + inkscape:zoom="0.7387262" + inkscape:cx="699.29419" + inkscape:cy="537.41156" inkscape:window-x="0" inkscape:window-y="27" inkscape:window-maximized="1" - inkscape:current-layer="layer47" + inkscape:current-layer="layer79" fit-margin-top="15" fit-margin-left="15" fit-margin-right="15" fit-margin-bottom="15" inkscape:snap-grids="true" - showguides="true" + showguides="false" inkscape:guide-bbox="true" inkscape:snap-global="true" inkscape:snap-bbox="true" inkscape:object-paths="true" inkscape:snap-bbox-midpoints="true" - inkscape:snap-bbox-edge-midpoints="false" + inkscape:snap-bbox-edge-midpoints="true" inkscape:object-nodes="true" inkscape:snap-nodes="true"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -17858,7 +19299,7 @@ inkscape:groupmode="layer" id="layer52" inkscape:label="cc-pwm" - style="display:inline" + style="display:none" sodipodi:insensitive="true"> @@ -17886,25 +19327,25 @@ sodipodi:nodetypes="cccc" style="fill:none;stroke:#1f4697;stroke-width:5.61390018;stroke-linecap:butt;stroke-linejoin:round" inkscape:connector-curvature="0" - d="m 303.76407,219.75113 l 75.17593,-0.0948 l 0,-16.06759 l 51.4,-0.1488" + d="M 303.76407,219.75113 L 378.94,219.65633 L 378.94,203.58874 L 430.34,203.43994" id="path8856-5" /> @@ -17965,19 +19406,19 @@ id="text9734-2" transform="translate(0,31)"> @@ -17986,23 +19427,23 @@ id="text9734-2-6" transform="translate(0,31)"> @@ -18011,15 +19452,15 @@ id="text9734-2-6-4" transform="translate(0,31)"> @@ -18028,49 +19469,49 @@ id="text9734-2-6-4-2" transform="translate(0,31)"> @@ -18088,19 +19529,19 @@ transform="translate(3.9999998,1.0000001)"> @@ -18112,7 +19553,7 @@ id="path8856-5-47" /> @@ -18120,19 +19561,19 @@ sodipodi:nodetypes="cc" style="fill:none;stroke:#fac204;stroke-width:5.61399984;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" inkscape:connector-curvature="0" - d="m 387.93975,211.51434 l 42.62432,0" + d="M 387.93975,211.51434 L 430.56407,211.51434" id="path8856-5-1-4" /> @@ -18231,32 +19672,32 @@ id="text11303" transform="translate(-2,0)"> @@ -18275,77 +19716,77 @@ transform="translate(1,-2)"> @@ -18354,19 +19795,19 @@ id="text21611" transform="matrix(0.66455533,0,0,0.66455533,105.60136,63.655516)"> @@ -18378,7 +19819,7 @@ id="path8856-5-47-7" /> @@ -18386,19 +19827,19 @@ sodipodi:nodetypes="cc" style="display:inline;fill:none;stroke:#fac204;stroke-width:5.61399984;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" inkscape:connector-curvature="0" - d="m 388.93975,211.51434 l 42.62432,0" + d="M 388.93975,211.51434 L 431.56407,211.51434" id="path8856-5-1-4-3" /> @@ -18414,7 +19855,7 @@ transform="matrix(0,0.4,-0.4,0,931.4684,-115.45414)"> @@ -18484,44 +19925,392 @@ id="text20525-8-7" transform="matrix(0,-1,1,0,-68.75,2824.5001)"> + + + @@ -18616,13 +20405,13 @@ transform="matrix(0.4,0,0,0.4,-129.04473,-95.93132)"> @@ -18630,25 +20419,25 @@ sodipodi:nodetypes="cccc" style="fill:none;stroke:#1f4697;stroke-width:15.29999924;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" inkscape:connector-curvature="0" - d="m 1371.2889,1318.8556 l 0,-124.7594 l 225,0 l 0,-133.868" + d="M 1371.2889,1318.8556 L 1371.2889,1194.0962 L 1596.2889,1194.0962 L 1596.2889,1060.2282" id="path8856-5-6" /> @@ -18724,25 +20513,25 @@ sodipodi:nodetypes="cc" style="fill:none;stroke:#1f4697;stroke-width:5.61390018;stroke-linecap:butt;stroke-linejoin:round" inkscape:connector-curvature="0" - d="m 303.76407,219.75113 l 126.79968,-0.0948" + d="M 303.76407,219.75113 L 430.56375,219.65633" id="path8856-5-7" /> @@ -18809,19 +20598,19 @@ id="text9734-2-5" transform="translate(0,31)"> @@ -18830,23 +20619,23 @@ id="text9734-2-6-6" transform="translate(0,31)"> @@ -18855,15 +20644,15 @@ id="text9734-2-6-4-4" transform="translate(0,31)"> @@ -18872,49 +20661,49 @@ id="text9734-2-6-4-2-7" transform="translate(0,31)"> @@ -18932,19 +20721,19 @@ transform="translate(1.0000001,-19)"> @@ -18952,25 +20741,25 @@ sodipodi:nodetypes="cc" style="fill:none;stroke:#1f4697;stroke-width:5.61390018;stroke-linecap:butt;stroke-linejoin:round" inkscape:connector-curvature="0" - d="m 394.76407,219.75113 l 35.79968,-0.0948" + d="M 394.76407,219.75113 L 430.56375,219.65633" id="path8856-5-7-0" /> @@ -19056,7 +20845,7 @@ transform="matrix(0,0.4,-0.4,0,929.4684,-117.45414)"> @@ -19126,44 +20915,393 @@ id="text20525-8" transform="matrix(0,-1,1,0,-68.75,2824.5001)"> + + + @@ -19216,7 +21354,7 @@ x="1250" /> Futaba @@ -19385,7 +21523,7 @@ d="M 423.36407,324.13254 L 525.36407,323.72054 L 525.52367,240.51434" id="path8856-1-3-9" /> @@ -19393,8 +21531,8 @@ sodipodi:nodetypes="sssccccssssss" inkscape:connector-curvature="0" id="rect8853-0-8-1" - d="M 236.31357,289.05542 L 423.35356,289.05542 C 426.94348,289.05542 429.83356,291.9455 429.83356,295.53542 L 429.83356,304.37557 L 423.83356,304.37557 L 423.83356,426.73558 L 429.834,426.73558 L 429.83356,436.97542 C 429.83341,440.56534 426.94348,443.45542 423.35356,443.45542 L 236.31357,443.45542 C 232.72364,443.45542 229.83356,440.56534 229.83356,436.97542 L 229.83356,295.53542 C 229.83356,291.9455 232.72364,289.05542 236.31357,289.05542 z" - style="color:#000000;fill:url(#linearGradient13971);fill-rule:nonzero;stroke:#000000;stroke-width:3.09599996;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:accumulate" /> + d="M 236.31357,289.05542 L 423.35356,289.05542 C 426.94348,289.05542 429.83356,291.9455 429.83356,295.53542 L 429.83356,304.37557 L 423.83356,304.37557 L 423.83356,426.73558 L 429.834,426.73558 L 429.83356,436.97542 C 429.83341,440.56534 426.94348,443.45542 423.35356,443.45542 L 236.31357,443.45542 C 232.72364,443.45542 229.83356,440.56534 229.83356,436.97542 L 229.83356,295.53542 C 229.83356,291.9455 232.72364,289.05542 236.31357,289.05542 Z" + style="color:#000000;display:inline;fill:url(#linearGradient13971);fill-rule:nonzero;stroke:#000000;stroke-width:3.09599996;stroke-miterlimit:4;stroke-dasharray:none;enable-background:accumulate" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:22.39999962px;line-height:125%;font-family:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff"> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:22.39999962px;line-height:125%;font-family:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#488eff"> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:22.39999962px;line-height:125%;font-family:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffdc00"> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:22.39999962px;line-height:125%;font-family:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;fill:#73ff00;fill-rule:nonzero;enable-background:accumulate"> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:22.39999962px;line-height:125%;font-family:Sans;text-indent:0;text-align:end;text-decoration:none;text-decoration-line:none;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:end;fill:#ff7e00;fill-rule:nonzero;enable-background:accumulate"> @@ -19562,40 +21700,40 @@ sodipodi:nodetypes="ccc" style="display:inline;fill:none;stroke:#1f4697;stroke-width:5.61390018;stroke-linecap:butt;stroke-linejoin:miter" inkscape:connector-curvature="0" - d="m 423.36375,324.71873 l 110.57609,0 l -1.7e-4,-84.20439" + d="M 423.36375,324.71873 L 533.93984,324.71873 L 533.93967,240.51434" id="path8856-5-4-4" /> @@ -19604,62 +21742,62 @@ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:22.39999962px;line-height:125%;font-family:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff"> @@ -19667,43 +21805,43 @@ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:25.96601868px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Sans Bold';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#1f4697;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" id="text20057"> @@ -19721,7 +21859,7 @@ transform="matrix(-0.4,0,0,-0.4,1078.3424,590.20822)"> @@ -19791,44 +21929,393 @@ id="text20525" transform="matrix(-1,0,0,-1,2737.0002,2904.5)"> + + + @@ -19855,19 +22342,19 @@ sodipodi:nodetypes="cc" style="fill:#cccccc;stroke:#ec6004;stroke-width:15.29999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none" inkscape:connector-curvature="0" - d="m 1392.571,1323.8556 0,-171.0219" + d="M 1392.571,1323.8556 L 1392.571,1152.8337" id="path8856-5-1-7-1-9-5-4" /> Futaba Satellite + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + style="display:inline"> + style="fill:none;stroke:#545253;stroke-width:9.10000038;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> @@ -20039,15 +23457,15 @@ inkscape:connector-curvature="0" id="path6569-5" d="M 236.04807,504.14551 L 179.51554,504.14551" - style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> @@ -20055,7 +23473,7 @@ transform="translate(-69.961847,475.88605)" id="g6557-0"> @@ -20063,13 +23481,13 @@ inkscape:connector-curvature="0" id="path6561-82" d="M 236.04807,496.88936 L 179.51554,496.88936" - style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#545253;stroke-width:9.10000038;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> @@ -20077,15 +23495,15 @@ inkscape:connector-curvature="0" id="path6549-1" d="M 236.04807,504.14551 L 179.51554,504.14551" - style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> @@ -20093,7 +23511,7 @@ transform="translate(-69.961847,525.88605)" id="g6533-32"> @@ -20101,17 +23519,17 @@ inkscape:connector-curvature="0" id="path6531-7" d="M 236.04807,496.88936 L 179.51554,496.88936" - style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="display:inline;fill:#2e2f2e;fill-opacity:1;fill-rule:evenodd;stroke:none" /> + style="fill:none;stroke:#545253;stroke-width:9.10000038;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> @@ -20143,9 +23561,9 @@ inkscape:connector-curvature="0" id="path14351" d="M 236.04807,504.14551 L 179.51554,504.14551" - style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> @@ -20156,7 +23574,7 @@ height="9.1741314" width="24.794964" id="rect14355" - style="fill:#2e2f2e;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" /> + style="display:inline;fill:#2e2f2e;fill-opacity:1;fill-rule:evenodd;stroke:none" /> + style="fill:#dbddde;fill-opacity:1;fill-rule:evenodd;stroke:#393a3e;stroke-width:0.66049641;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> @@ -20424,7 +23842,7 @@ + style="fill:url(#radialGradient13230-7);fill-opacity:1;fill-rule:evenodd;stroke:#393a3e;stroke-width:0.58099997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:url(#radialGradient13234-2);fill-opacity:1;fill-rule:evenodd;stroke:#393a3e;stroke-width:0.58099997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:url(#radialGradient13236-2);fill-opacity:1;fill-rule:evenodd;stroke:#393a3e;stroke-width:0.58099997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:url(#radialGradient13240-6);fill-opacity:1;fill-rule:evenodd;stroke:#393a3e;stroke-width:0.58099997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:url(#radialGradient13244-6);fill-opacity:1;fill-rule:evenodd;stroke:#393a3e;stroke-width:0.58099997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + d="M 444.40744,1038.0272 C 452.57603,1038.0272 459.19798,1044.6491 459.19798,1052.8177 C 459.19798,1060.9863 452.57603,1067.6082 444.40744,1067.6082 C 436.23885,1067.6082 429.6169,1060.9863 429.6169,1052.8177 C 429.6169,1044.6491 436.23885,1038.0272 444.40744,1038.0272 Z" + style="fill:url(#radialGradient13246-3);fill-opacity:1;fill-rule:evenodd;stroke:#87878d;stroke-width:5.08913088;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:40px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';letter-spacing:0px;word-spacing:0px;fill:#545352;fill-opacity:1;stroke:none"> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:40px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"> + d="M 800.72981,535.98589 L 800.72981,738.12396 C 800.72981,744.79627 795.35824,750.16784 788.68594,750.16784 L 586.54788,750.16784 C 579.87557,750.16784 574.504,744.79627 574.504,738.12396 L 574.504,535.98589 C 574.504,529.31358 579.87557,523.94202 586.54788,523.94202 L 788.68594,523.94202 C 795.35824,523.94202 800.72981,529.31358 800.72981,535.98589 Z" + style="fill:#2d2b2c;fill-opacity:1;stroke:#ffd25c;stroke-width:4.97813463;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" /> - - + - + - + + style="fill:url(#linearGradient7362-5);fill-opacity:1;fill-rule:evenodd;stroke:#515454;stroke-width:4.19999981;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + cx="-36.611858" + cy="572.3067" + r="23.877298" /> + @@ -21282,24 +25060,24 @@ + d="M 97.729487,958.00538 L 100.73139,958.92472 C 100.06845,962.01418 98.905212,964.32188 97.241679,965.84785 C 95.590618,967.36131 93.576845,968.11803 91.200356,968.11803 C 89.111525,968.11803 87.322895,967.61146 85.834461,966.59832 C 84.358522,965.57268 83.145255,963.93414 82.194658,961.68271 C 81.256562,959.4313 80.787516,956.77337 80.787517,953.70892 C 80.787516,950.68202 81.256562,948.12415 82.194658,946.03531 C 83.145255,943.93401 84.427315,942.35176 86.040841,941.28856 C 87.654354,940.2129 89.455492,939.67506 91.44426,939.67504 C 93.620623,939.67506 95.490554,940.35675 97.05406,941.72008 C 98.61753,943.07096 99.711971,945.05972 100.33739,947.68636 L 97.410535,948.53064 C 96.409885,944.70324 94.402367,942.78953 91.387975,942.78951 C 89.887014,942.78953 88.586193,943.17728 87.485505,943.95274 C 86.384802,944.71575 85.502995,945.91025 84.840082,947.53626 C 84.189665,949.16231 83.86446,951.21986 83.864464,953.70892 C 83.86446,957.47381 84.527379,960.30059 85.853223,962.18928 C 87.179054,964.06547 88.942668,965.00357 91.14407,965.00356 C 92.770086,965.00357 94.170971,964.4282 95.34673,963.27747 C 96.534964,962.11424 97.329216,960.35688 97.729487,958.00538" /> + d="M 115.08422,956.86091 L 115.08422,953.63387 L 124.63401,953.61507 L 124.63401,963.82153 C 123.17056,965.24743 121.65711,966.32311 120.09364,967.04857 C 118.53013,967.76152 116.92287,968.11799 115.27184,968.11799 C 113.07043,968.11799 111.10669,967.56765 109.38061,966.46695 C 107.65451,965.36625 106.2849,963.75899 105.27176,961.64515 C 104.27112,959.53132 103.77081,956.99221 103.77081,954.02783 C 103.77081,951.02595 104.27738,948.41179 105.29052,946.18537 C 106.30366,943.95898 107.6295,942.32045 109.26804,941.26976 C 110.90657,940.20661 112.84529,939.67502 115.08422,939.675 C 116.73525,939.67502 118.17991,939.98147 119.41821,940.59433 C 120.65647,941.20724 121.67587,942.07654 122.4764,943.20223 C 123.27688,944.32796 123.87726,945.87269 124.27753,947.83641 L 121.59459,948.73698 C 121.23184,947.18602 120.7753,946.02904 120.22497,945.26603 C 119.6746,944.49057 118.94915,943.88393 118.04859,943.44613 C 117.14801,943.00838 116.13487,942.78949 115.00917,942.78947 C 113.37062,942.78949 111.95723,943.18974 110.76899,943.99023 C 109.59324,944.77825 108.64264,946.01028 107.91718,947.68632 C 107.20423,949.36239 106.84775,951.40744 106.84776,953.82145 C 106.84775,957.49878 107.61699,960.25678 109.15547,962.09543 C 110.69393,963.92159 112.6952,964.83467 115.15927,964.83467 C 116.33499,964.83467 117.53575,964.55324 118.76154,963.99038 C 119.99981,963.42753 120.98168,962.75836 121.70716,961.98286 L 121.70716,956.86087 L 115.08422,956.86087" /> + d="M 139.62475,956.86091 L 139.62475,953.63387 L 149.17454,953.61507 L 149.17454,963.82153 C 147.71109,965.24743 146.19763,966.32311 144.63416,967.04857 C 143.07066,967.76152 141.46339,968.11799 139.81236,968.11799 C 137.61096,968.11799 135.64722,967.56765 133.92114,966.46695 C 132.19504,965.36625 130.82542,963.75899 129.81229,961.64515 C 128.81165,959.53132 128.31133,956.99221 128.31134,954.02783 C 128.31133,951.02595 128.8179,948.41179 129.83105,946.18537 C 130.84418,943.95898 132.17002,942.32045 133.80856,941.26976 C 135.44709,940.20661 137.38582,939.67502 139.62475,939.675 C 141.27577,939.67502 142.72044,939.98147 143.95874,940.59433 C 145.197,941.20724 146.2164,942.07654 147.01692,943.20223 C 147.81741,944.32796 148.41779,945.87269 148.81806,947.83641 L 146.13511,948.73698 C 145.77237,947.18602 145.31583,946.02904 144.7655,945.26603 C 144.21513,944.49057 143.48967,943.88393 142.58912,943.44613 C 141.68854,943.00838 140.6754,942.78949 139.5497,942.78947 C 137.91115,942.78949 136.49776,943.18974 135.30951,943.99023 C 134.13376,944.77825 133.18316,946.01028 132.45771,947.68632 C 131.74475,949.36239 131.38828,951.40744 131.38828,953.82145 C 131.38828,957.49878 132.15751,960.25678 133.69599,962.09543 C 135.23446,963.92159 137.23572,964.83467 139.69979,964.83467 C 140.87552,964.83467 142.07628,964.55324 143.30207,963.99038 C 144.54034,963.42753 145.52221,962.75836 146.24769,961.98286 L 146.24769,956.86087 L 139.62475,956.86087" /> + d="M 153.54605,967.64899 L 153.54605,940.14408 L 162.04518,940.14408 C 164.04643,940.14411 165.52237,940.31922 166.47298,940.66942 C 167.77379,941.14474 168.81194,942.02655 169.58745,943.31484 C 170.36292,944.60318 170.75067,946.18543 170.75069,948.06159 C 170.75067,950.53818 170.11902,952.5582 168.85574,954.12168 C 167.59242,955.68518 165.4098,956.46692 162.30785,956.46691 L 156.52919,956.46691 L 156.52919,967.64899 L 153.54605,967.64899 M 156.52919,953.22111 L 162.36413,953.22111 C 164.20278,953.22112 165.54738,952.80836 166.39794,951.98282 C 167.24846,951.14481 167.67373,949.88777 167.67374,948.21169 C 167.67373,947.12352 167.46109,946.19168 167.03584,945.41617 C 166.62306,944.6407 166.11649,944.10912 165.51613,943.82141 C 164.92824,943.53375 163.85882,943.38991 162.30785,943.38989 L 156.52919,943.38989 L 156.52919,953.22111" /> + d="M 196.30436,964.40318 L 196.30436,967.64899 L 181.38867,967.64899 C 181.35117,966.33566 181.74514,964.86598 182.57067,963.23995 C 183.4087,961.61392 184.93466,959.69396 187.14856,957.48005 C 189.73769,954.90343 191.43251,952.91468 192.23303,951.51378 C 193.03353,950.1004 193.43378,948.78707 193.43379,947.57378 C 193.43378,946.17292 193.02102,945.0347 192.19551,944.15912 C 191.38248,943.27109 190.3756,942.82706 189.17485,942.82703 C 187.88652,942.82706 186.82961,943.30236 186.00409,944.25293 C 185.17856,945.20356 184.7658,946.56692 184.76581,948.34302 L 181.914,947.98655 C 182.11413,945.3474 182.85835,943.3649 184.14667,942.03903 C 185.44748,940.70071 187.15481,940.03154 189.26866,940.03151 C 191.5701,940.03154 193.3087,940.80703 194.48446,942.35798 C 195.67269,943.90899 196.26682,945.6726 196.26683,947.64883 C 196.26682,949.39996 195.80403,951.08227 194.87846,952.69578 C 193.95286,954.2968 192.1955,956.43565 189.60637,959.11234 C 187.95532,960.80091 186.88589,961.95164 186.39809,962.56452 C 185.92278,963.17741 185.53504,963.7903 185.23485,964.40318 L 196.30436,964.40318" /> + d="M 199.26873,960.44443 L 202.17682,960.14424 C 202.40196,961.89535 202.90853,963.20243 203.69654,964.06547 C 204.49704,964.91601 205.42262,965.34128 206.47329,965.34128 C 207.78661,965.34128 208.91858,964.7409 209.86919,963.54014 C 210.81978,962.32687 211.29508,960.67583 211.29509,958.587 C 211.29508,956.62327 210.83229,955.10356 209.90671,954.02787 C 208.99363,952.93969 207.8429,952.3956 206.45453,952.39559 C 205.61649,952.3956 204.82849,952.63325 204.09053,953.10854 C 203.36507,953.57134 202.78971,954.22175 202.36444,955.05977 L 199.75654,954.64701 L 201.95168,940.51932 L 213.15252,940.51932 L 213.15252,943.74636 L 204.16558,943.74636 L 202.94606,951.13854 C 204.2844,949.98783 205.70405,949.41247 207.20501,949.41245 C 209.09369,949.41247 210.73222,950.21923 212.12062,951.83273 C 213.52149,953.43376 214.22193,955.59762 214.22195,958.32434 C 214.22193,961.01354 213.52149,963.32125 212.12062,965.24747 C 210.73222,967.16118 208.86229,968.11803 206.51082,968.11803 C 204.55957,968.11803 202.90853,967.44261 201.55768,966.09175 C 200.21933,964.72839 199.45635,962.84595 199.26873,960.44443" /> + d="M 218.48088,967.64899 L 218.48088,963.8028 L 221.63288,963.8028 L 221.63288,967.64899 L 218.48088,967.64899" /> + d="M 234.48477,967.64899 L 234.48477,961.06357 L 224.70983,961.06357 L 224.70983,957.96786 L 235.0101,940.14408 L 237.26152,940.14408 L 237.26152,957.96786 L 240.31971,957.96786 L 240.31971,961.06357 L 237.26152,961.06357 L 237.26152,967.64899 L 234.48477,967.64899 M 234.48477,957.96786 L 234.48477,945.56626 L 227.4303,957.96786 L 234.48477,957.96786" /> + d="M 248.96892,967.64899 L 257.63691,940.14408 L 260.84519,940.14408 L 270.07603,967.64899 L 266.66137,967.64899 L 264.03471,959.31872 L 254.61625,959.31872 L 252.13968,967.64899 L 248.96892,967.64899 M 255.47929,956.35434 L 263.11537,956.35434 L 260.77014,948.73702 C 260.04467,946.39806 259.51308,944.49686 259.17538,943.03341 C 258.88769,944.79705 258.48118,946.54816 257.95586,948.28674 L 255.47929,956.35434" /> + d="M 278.36878,954.08415 C 278.36878,949.46875 278.98792,945.97279 280.2262,943.59627 C 281.47699,941.21979 283.31565,940.03154 285.74219,940.03151 C 287.89354,940.03154 289.58836,940.99465 290.82666,942.92084 C 292.32759,945.24733 293.07807,948.96844 293.07809,954.08415 C 293.07807,958.67457 292.45893,962.16427 291.22066,964.55328 C 289.98236,966.92978 288.1437,968.11803 285.70467,968.11803 C 283.5533,968.11803 281.78969,967.06737 280.41382,964.96604 C 279.05046,962.86471 278.36878,959.23742 278.36878,954.08415 M 281.20182,954.08415 C 281.20182,958.54949 281.62709,961.54513 282.47763,963.07109 C 283.34067,964.58455 284.44136,965.34128 285.77972,965.34128 C 287.04301,965.34128 288.09992,964.57204 288.95047,963.03357 C 289.801,961.4951 290.22627,958.51196 290.22628,954.08415 C 290.22627,949.60634 289.79474,946.6107 288.93171,945.09722 C 288.08116,943.58378 286.97421,942.82706 285.61086,942.82703 C 284.36006,942.82706 283.3094,943.59629 282.45887,945.13474 C 281.62083,946.67324 281.20182,949.65637 281.20182,954.08415" /> + d="M 310.52663,964.40318 L 310.52663,967.64899 L 295.61094,967.64899 C 295.57344,966.33566 295.96741,964.86598 296.79294,963.23995 C 297.63096,961.61392 299.15693,959.69396 301.37083,957.48005 C 303.95996,954.90343 305.65478,952.91468 306.4553,951.51378 C 307.25579,950.1004 307.65605,948.78707 307.65606,947.57378 C 307.65605,946.17292 307.24329,945.0347 306.41778,944.15912 C 305.60475,943.27109 304.59786,942.82706 303.39711,942.82703 C 302.10879,942.82706 301.05187,943.30236 300.22636,944.25293 C 299.40083,945.20356 298.98807,946.56692 298.98807,948.34302 L 296.13627,947.98655 C 296.33639,945.3474 297.08062,943.3649 298.36893,942.03903 C 299.66975,940.70071 301.37708,940.03154 303.49092,940.03151 C 305.79237,940.03154 307.53097,940.80703 308.70672,942.35798 C 309.89496,943.90899 310.48909,945.6726 310.4891,947.64883 C 310.48909,949.39996 310.02629,951.08227 309.10072,952.69578 C 308.17512,954.2968 306.41776,956.43565 303.82864,959.11234 C 302.17758,960.80091 301.10816,961.95164 300.62036,962.56452 C 300.14505,963.17741 299.75731,963.7903 299.45712,964.40318 L 310.52663,964.40318" /> @@ -21452,27 +25230,27 @@ id="g7839" transform="matrix(0.64801118,0,0,0.64801118,460.25235,105.32296)"> @@ -21481,17 +25259,17 @@ id="g7851" transform="matrix(0.64801118,0,0,0.64801118,461.02363,105.32296)"> @@ -21503,60 +25281,60 @@ + d="M 253.89355,989.09735 L 253.89355,979.21973 L 256.52129,979.21973 C 257.50051,979.21974 258.1406,979.26693 258.44157,979.36122 C 258.92219,979.51395 259.31747,979.83961 259.62742,980.3382 C 259.94184,980.83681 260.09906,981.47915 260.09907,982.26521 C 260.09906,982.97943 259.9643,983.57909 259.6948,984.06421 C 259.42528,984.54484 259.08839,984.88398 258.68413,985.08162 C 258.27985,985.27477 257.58361,985.37135 256.59541,985.37134 L 255.52409,985.37134 L 255.52409,989.09735 L 253.89355,989.09735 M 255.52409,980.8907 L 255.52409,983.69363 L 256.42696,983.69363 C 257.03336,983.69364 257.44437,983.65093 257.65998,983.56561 C 257.88008,983.48031 258.05975,983.32755 258.199,983.10744 C 258.33825,982.88285 258.40787,982.60885 258.40788,982.28543 C 258.40787,981.95753 258.33598,981.68128 258.19227,981.45668 C 258.04852,981.23209 257.87109,981.08161 257.65998,981.00525 C 257.44886,980.92885 257.00192,980.89071 256.31916,980.8907 L 255.52409,980.8907" /> + d="M 261.43315,989.09735 L 261.43315,979.21973 L 262.98959,979.21973 L 262.98959,989.09735 L 261.43315,989.09735" /> + d="M 265.74535,984.12485 L 264.33715,983.81491 C 264.50784,983.09173 264.78858,982.57291 265.17937,982.25848 C 265.57466,981.93956 266.14063,981.7801 266.8773,981.78009 C 267.53311,981.7801 268.03395,981.87219 268.37983,982.05634 C 268.7257,982.24052 268.97275,982.49206 269.12099,982.81098 C 269.26922,983.12541 269.34333,983.70037 269.34334,984.53586 L 269.32984,986.74586 C 269.32984,987.36574 269.35454,987.8284 269.40394,988.13384 C 269.45334,988.4348 269.54543,988.75597 269.68019,989.09735 L 268.14397,989.09735 L 267.94183,988.31577 C 267.67681,988.6302 267.39158,988.86602 267.08613,989.02324 C 266.78517,989.18045 266.464,989.25906 266.12263,989.25906 C 265.55216,989.25906 265.085,989.06815 264.72116,988.68634 C 264.35732,988.30004 264.1754,987.78797 264.1754,987.15012 C 264.1754,986.74586 264.2495,986.39325 264.39775,986.09229 C 264.54598,985.79134 264.75485,985.55102 265.02436,985.37134 C 265.29387,985.19167 265.72509,985.03221 266.31802,984.89296 C 267.03672,984.72676 267.53756,984.5718 267.82055,984.42805 C 267.82055,984.03277 267.79135,983.77449 267.73295,983.6532 C 267.67905,983.52744 267.57573,983.42637 267.42301,983.35 C 267.27478,983.2691 267.06366,983.22873 266.78966,983.22872 C 266.51116,983.22873 266.29106,983.29162 266.12935,983.41738 C 265.97214,983.54316 265.84412,983.77898 265.7453,984.12485 M 267.82054,985.66107 C 267.6229,985.74197 267.3152,985.83626 266.89746,985.94406 C 266.41683,986.06983 266.1024,986.20908 265.95417,986.3618 C 265.80594,986.51453 265.73182,986.71217 265.73182,986.95473 C 265.73182,987.22873 265.81262,987.46007 265.97438,987.64872 C 266.14058,987.83289 266.34721,987.92497 266.59426,987.92497 C 266.81436,987.92497 267.03222,987.85087 267.24783,987.70263 C 267.46344,987.5499 267.61167,987.37023 267.69252,987.1636 C 267.77792,986.95698 267.82054,986.58191 267.82054,986.03839 L 267.82054,985.66107" /> + d="M 273.57468,981.9418 L 273.57468,983.45107 L 272.51684,983.45107 L 272.51684,986.33485 C 272.51684,986.95922 272.53254,987.32082 272.56404,987.41964 C 272.62694,987.59931 272.75494,987.68915 272.94809,987.68915 C 273.09183,987.68915 273.29846,987.62855 273.56797,987.50723 L 273.70273,988.97607 C 273.34338,989.16473 272.93686,989.25906 272.48319,989.25906 C 272.0879,989.25906 271.77122,989.16476 271.53316,988.97607 C 271.29508,988.78741 271.13562,988.51565 271.05477,988.1608 C 270.99187,987.90027 270.96047,987.37023 270.96047,986.57067 L 270.96047,983.45107 L 270.24626,983.45107 L 270.24626,981.9418 L 270.96047,981.9418 L 270.96047,980.52012 L 272.5169,979.41512 L 272.5169,981.9418 L 273.57474,981.9418" /> + d="M 274.6662,980.97156 L 274.6662,979.21973 L 276.22264,979.21973 L 276.22264,980.97156 L 274.6662,980.97156 M 274.6662,989.09735 L 274.6662,981.9418 L 276.22264,981.9418 L 276.22264,989.09735 L 274.6662,989.09735" /> + d="M 283.15584,989.09735 L 281.59941,989.09735 L 281.59941,985.44546 C 281.5994,984.71329 281.57021,984.22592 281.51181,983.98336 C 281.45341,983.7408 281.34336,983.55439 281.18165,983.42412 C 281.02443,983.29386 280.84476,983.22873 280.64263,983.22872 C 280.3821,983.22873 280.14627,983.31412 279.93516,983.48476 C 279.72404,983.65096 279.57581,983.88229 279.49046,984.17875 C 279.40516,984.47522 279.36244,985.03446 279.36245,985.85647 L 279.36245,989.09735 L 277.80601,989.09735 L 277.80601,981.9418 L 279.2479,981.9418 L 279.2479,982.9929 C 279.50394,982.58864 279.79142,982.28544 280.11034,982.08329 C 280.43375,981.88117 280.79086,981.7801 281.18165,981.78009 C 281.63533,981.7801 282.01714,981.89913 282.32708,982.1372 C 282.64151,982.37078 282.85712,982.67398 282.97391,983.0468 C 283.09518,983.41514 283.15582,983.94967 283.15583,984.6504 L 283.15583,989.09735" /> + d="M 288.59999,989.09735 L 288.59999,988.02604 C 288.38437,988.41234 288.10139,988.71554 287.75103,988.93564 C 287.40066,989.15125 287.03457,989.25906 286.65276,989.25906 C 286.26646,989.25906 285.92059,989.15799 285.61514,988.95586 C 285.30969,988.75372 285.08061,988.46624 284.92788,988.09342 C 284.77965,987.72059 284.70554,987.17932 284.70554,986.46961 L 284.70554,981.9418 L 286.26197,981.9418 L 286.26197,985.22985 C 286.26197,986.16865 286.28447,986.76607 286.32937,987.02211 C 286.37877,987.27365 286.48434,987.46905 286.64605,987.6083 C 286.80775,987.74755 287.00315,987.81717 287.23223,987.81717 C 287.49276,987.81717 287.73307,987.72737 287.95318,987.54766 C 288.17328,987.36349 288.31702,987.12991 288.3844,986.84692 C 288.4563,986.55945 288.4922,985.93059 288.4922,984.96034 L 288.4922,981.9418 L 290.0419,981.9418 L 290.0419,989.09735 L 288.60001,989.09735" /> + d="M 291.55115,981.9418 L 292.97956,981.9418 L 292.97956,982.91878 C 293.2356,982.53698 293.51634,982.25175 293.82179,982.06308 C 294.12723,981.87443 294.45739,981.7801 294.81225,981.78009 C 295.18956,981.7801 295.51522,981.87439 295.78923,982.06308 C 296.06772,982.25175 296.29456,982.53698 296.46975,982.91878 C 296.73027,982.53698 297.00877,982.25175 297.30524,982.06308 C 297.60618,981.87443 297.92511,981.7801 298.262,981.78009 C 298.66177,981.7801 299.0054,981.87669 299.29289,982.06982 C 299.58485,982.25848 299.80495,982.53024 299.95319,982.88509 C 300.10591,983.23996 300.18227,983.78572 300.18228,984.52238 L 300.18228,989.09735 L 298.62585,989.09735 L 298.62585,985.0075 C 298.62584,984.2933 298.56295,983.81941 298.43719,983.58583 C 298.31141,983.34776 298.10029,983.22873 297.80383,983.22872 C 297.45795,983.22873 297.17946,983.39493 296.96835,983.72732 C 296.75722,984.05523 296.65166,984.69981 296.65167,985.66107 L 296.65167,989.09735 L 295.09524,989.09735 L 295.09524,985.17595 C 295.09523,984.39886 295.05254,983.89802 294.96722,983.67342 C 294.85492,983.37696 294.62808,983.22873 294.2867,983.22872 C 294.05761,983.22873 293.84649,983.30512 293.65334,983.45781 C 293.46019,983.61054 293.32094,983.83513 293.2356,984.13159 C 293.1503,984.42356 293.10758,984.91992 293.10758,985.62064 L 293.10758,989.09735 L 291.55115,989.09735 L 291.55115,981.9418" /> + d="M 308.65844,985.46567 L 308.65844,983.80143 L 312.18231,983.80143 L 312.18231,987.73631 C 311.82745,988.15406 311.32436,988.51341 310.67304,988.81436 C 310.02172,989.11532 309.36815,989.2658 308.71234,989.2658 C 307.91279,989.2658 307.20756,989.0704 306.59667,988.67961 C 305.98577,988.28432 305.50065,987.69589 305.1413,986.9143 C 304.78645,986.12823 304.60902,985.20515 304.60902,984.14506 C 304.60902,983.05804 304.78869,982.12822 305.14804,981.35561 C 305.51188,980.58302 305.98128,980.00581 306.55624,979.62399 C 307.13569,979.2422 307.82744,979.05129 308.63149,979.05128 C 309.59724,979.05129 310.36984,979.29834 310.94929,979.79244 C 311.53323,980.28206 311.9083,981.00301 312.07451,981.95528 L 310.45743,982.32586 C 310.33615,981.81828 310.1138,981.42973 309.79039,981.16021 C 309.46697,980.89071 309.08067,980.75595 308.63149,980.75595 C 307.93524,980.75595 307.37152,981.02771 306.9403,981.57122 C 306.50908,982.11025 306.29347,982.93451 306.29347,984.044 C 306.29347,985.23435 306.52704,986.13946 306.9942,986.75933 C 307.39397,987.29387 307.93524,987.56113 308.61801,987.56113 C 308.93693,987.56113 309.26708,987.48703 309.60847,987.33878 C 309.95434,987.18606 310.26203,986.97944 310.53155,986.71891 L 310.53155,985.46567 L 308.65844,985.46567" /> + d="M 313.69832,989.09735 L 313.69832,979.21973 L 316.32607,979.21973 C 317.30529,979.21974 317.94538,979.26693 318.24634,979.36122 C 318.72696,979.51395 319.12225,979.83961 319.43219,980.3382 C 319.74662,980.83681 319.90383,981.47915 319.90384,982.26521 C 319.90383,982.97943 319.76908,983.57909 319.49957,984.06421 C 319.23005,984.54484 318.89316,984.88398 318.4889,985.08162 C 318.08463,985.27477 317.38839,985.37135 316.40018,985.37134 L 315.32887,985.37134 L 315.32887,989.09735 L 313.69832,989.09735 M 315.32887,980.8907 L 315.32887,983.69363 L 316.23174,983.69363 C 316.83813,983.69364 317.24914,983.65093 317.46475,983.56561 C 317.68485,983.48031 317.86453,983.32755 318.00378,983.10744 C 318.14302,982.88285 318.21265,982.60885 318.21265,982.28543 C 318.21265,981.95753 318.14075,981.68128 317.99704,981.45668 C 317.8533,981.23209 317.67587,981.08161 317.46475,981.00525 C 317.25363,980.92885 316.80669,980.89071 316.12393,980.8907 L 315.32887,980.8907" /> + d="M 320.83366,985.88342 L 322.43052,985.69476 C 322.61019,986.95698 323.19863,987.58808 324.19583,987.58808 C 324.68993,987.58808 325.07847,987.46007 325.36147,987.20403 C 325.64445,986.9435 325.78594,986.62233 325.78595,986.24052 C 325.78594,986.01593 325.73655,985.82503 325.63772,985.66781 C 325.53892,985.5106 325.38841,985.38258 325.18628,985.28375 C 324.98414,985.18044 324.49453,985.00975 323.71744,984.77168 C 323.0212,984.56057 322.51137,984.33148 322.18796,984.08442 C 321.86454,983.83738 321.60626,983.51396 321.41311,983.11418 C 321.22445,982.70992 321.13012,982.27645 321.13012,981.81378 C 321.13012,981.27477 321.2514,980.78964 321.49396,980.35842 C 321.74102,979.92721 322.08015,979.60154 322.51137,979.38143 C 322.94259,979.16134 323.47488,979.05129 324.10823,979.05128 C 325.06051,979.05129 325.80391,979.30957 326.33845,979.82613 C 326.87297,980.3427 327.15596,981.08161 327.18741,982.04287 L 325.55012,982.13047 C 325.47822,981.60044 325.32328,981.22986 325.08522,981.01873 C 324.84714,980.80762 324.50801,980.70206 324.06781,980.70205 C 323.6276,980.70206 323.28846,980.79415 323.0504,980.9783 C 322.81233,981.16248 322.69329,981.39156 322.69329,981.66556 C 322.69329,981.93508 322.8011,982.16192 323.01671,982.34608 C 323.23232,982.53025 323.72867,982.73239 324.50576,982.95248 C 325.32777,983.19056 325.9207,983.4421 326.28455,983.70712 C 326.65287,983.96765 326.93361,984.30679 327.12677,984.72452 C 327.31991,985.13778 327.41649,985.64087 327.4165,986.23379 C 327.41649,987.09174 327.15147,987.81269 326.62144,988.39663 C 326.09588,988.98057 325.27162,989.27254 324.14866,989.27254 C 322.16325,989.27254 321.05825,988.14284 320.83366,985.88343" /> + points="186.194,11.031 181.129,13.319 186.083,4.74 191.036,13.319 " /> + d="M 172.76038,849.94598 L 171.14319,843.72333 L 172.45569,843.72333 L 173.41077,847.80145 L 174.28967,843.72333 L 175.59045,843.72333 L 176.44006,847.80145 L 177.41858,843.72333 L 178.74866,843.72333 L 177.10803,849.94598 L 175.81311,849.94598 L 174.9342,845.94403 L 174.06702,849.94598 L 172.76038,849.94598" /> + d="M 180.42444,849.94598 L 178.80725,843.72333 L 180.11975,843.72333 L 181.07483,847.80145 L 181.95374,843.72333 L 183.25452,843.72333 L 184.10413,847.80145 L 185.08264,843.72333 L 186.41272,843.72333 L 184.77209,849.94598 L 183.47717,849.94598 L 182.59827,845.94403 L 181.73108,849.94598 L 180.42444,849.94598" /> + d="M 188.0885,849.94598 L 186.47131,843.72333 L 187.78381,843.72333 L 188.73889,847.80145 L 189.6178,843.72333 L 190.91858,843.72333 L 191.76819,847.80145 L 192.7467,843.72333 L 194.07678,843.72333 L 192.43616,849.94598 L 191.14124,849.94598 L 190.26233,845.94403 L 189.39514,849.94598 L 188.0885,849.94598" /> + d="M 195.75256,849.94598 L 194.13538,843.72333 L 195.44788,843.72333 L 196.40295,847.80145 L 197.28186,843.72333 L 198.58264,843.72333 L 199.43225,847.80145 L 200.41077,843.72333 L 201.74084,843.72333 L 200.10022,849.94598 L 198.8053,849.94598 L 197.92639,845.94403 L 197.0592,849.94598 L 195.75256,849.94598" /> + d="M 202.1217,849.94598 L 202.1217,848.2995 L 203.47522,848.2995 L 203.47522,849.94598 L 202.1217,849.94598" /> + d="M 204.60022,845.7038 C 204.60022,844.68036 204.75061,843.83857 205.05139,843.17841 C 205.35608,842.51435 205.75256,842.02021 206.24084,841.69598 C 206.72912,841.37177 207.32092,841.20966 208.01624,841.20966 C 209.02404,841.20966 209.84435,841.59443 210.47717,842.36395 C 211.11388,843.13349 211.43224,844.22919 211.43225,845.65106 C 211.43224,847.08856 211.09631,848.21161 210.42444,849.0202 C 209.83459,849.73505 209.03381,850.09247 208.02209,850.09247 C 207.00256,850.09247 206.19787,849.73895 205.60803,849.03192 C 204.93616,848.22333 204.60022,847.11396 204.60022,845.7038 M 206.06506,845.6452 C 206.06506,846.63349 206.25256,847.37567 206.62756,847.87177 C 207.00256,848.36395 207.4674,848.61005 208.02209,848.61005 C 208.58068,848.61005 209.04357,848.36591 209.41077,847.87762 C 209.77795,847.38544 209.96154,846.63153 209.96155,845.61591 C 209.96154,844.61982 209.78185,843.88349 209.42249,843.40692 C 209.06701,842.93037 208.60022,842.69208 208.02209,842.69208 C 207.44397,842.69208 206.97326,842.93232 206.60999,843.41278 C 206.2467,843.89326 206.06506,844.6374 206.06506,845.6452" /> + d="M 212.49866,843.72333 L 213.75842,843.72333 L 213.75842,844.63739 C 213.9303,844.30927 214.15686,844.05146 214.43811,843.86395 C 214.71936,843.67646 215.02209,843.58271 215.34631,843.5827 C 215.92834,843.58271 216.42834,843.86005 216.84631,844.41473 C 217.26818,844.96943 217.47912,845.75653 217.47913,846.77606 C 217.47912,847.84638 217.26818,848.66669 216.84631,849.237 C 216.42443,849.80341 215.92248,850.08661 215.34045,850.08661 C 215.07092,850.08661 214.81897,850.02221 214.58459,849.89325 C 214.35412,849.76044 214.10998,849.52216 213.85217,849.17841 L 213.85217,852.31317 L 212.49866,852.31317 L 212.49866,843.72333 M 213.83459,846.72919 C 213.83459,847.43231 213.94787,847.94989 214.17444,848.28192 C 214.4049,848.61395 214.68225,848.77997 215.00647,848.77997 C 215.31506,848.77997 215.57483,848.62763 215.78577,848.32294 C 215.9967,848.01435 216.10217,847.51239 216.10217,846.81708 C 216.10217,846.15693 215.99279,845.6706 215.77405,845.35809 C 215.5592,845.04169 215.29553,844.88349 214.98303,844.88348 C 214.6549,844.88349 214.38147,845.03779 214.16272,845.34637 C 213.94397,845.65107 213.83459,846.112 213.83459,846.72919" /> + d="M 221.52209,847.96552 L 222.86389,848.24091 C 222.6842,848.86591 222.4049,849.33075 222.026,849.63544 C 221.64709,849.93622 221.18615,850.08661 220.64319,850.08661 C 219.88928,850.08661 219.30725,849.83466 218.89709,849.33075 C 218.41272,848.74481 218.17053,847.9245 218.17053,846.86981 C 218.17053,845.83075 218.41467,844.99872 218.90295,844.37372 C 219.31702,843.84638 219.85217,843.58271 220.50842,843.5827 C 221.23889,843.58271 221.81115,843.85224 222.22522,844.3913 C 222.70178,845.00849 222.94006,845.91864 222.94006,847.12177 L 222.93406,847.30927 L 219.5532,847.30927 C 219.5612,847.80145 219.67039,848.18231 219.88133,848.45184 C 220.09617,848.72138 220.35398,848.85614 220.65477,848.85614 C 221.08836,848.85614 221.37742,848.55927 221.52195,847.96552 M 221.59815,846.30145 C 221.58645,845.81708 221.48291,845.4538 221.2876,845.21161 C 221.09228,844.96552 220.85986,844.84247 220.59033,844.84247 C 220.30518,844.84247 220.06494,844.96943 219.86963,845.22333 C 219.67041,845.48114 219.57275,845.84052 219.57666,846.30145 L 221.59815,846.30145" /> + d="M 228.68811,849.94598 L 227.33459,849.94598 L 227.33459,846.7702 C 227.33459,846.13349 227.30919,845.70966 227.25839,845.49872 C 227.20759,845.28779 227.1119,845.12568 226.97128,845.01239 C 226.83456,844.89911 226.67831,844.84247 226.50253,844.84247 C 226.27597,844.84247 226.07089,844.91667 225.8873,845.06512 C 225.7037,845.20966 225.5748,845.41083 225.50058,845.66864 C 225.42638,845.92646 225.38925,846.41278 225.38925,847.12762 L 225.38925,849.94598 L 224.03574,849.94598 L 224.03574,843.72333 L 225.28964,843.72333 L 225.28964,844.63739 C 225.5123,844.28583 225.7623,844.02216 226.03964,843.84637 C 226.32089,843.6706 226.63144,843.58271 226.97128,843.5827 C 227.36581,843.58271 227.69784,843.68622 227.96738,843.89325 C 228.24081,844.09638 228.42831,844.36005 228.52988,844.68427 C 228.63534,845.00458 228.68808,845.46943 228.68808,846.0788 L 228.68808,849.94598" /> + d="M 230.07678,849.94598 L 230.07678,841.35614 L 232.36194,841.35614 C 233.2135,841.35615 233.77014,841.39714 234.03186,841.47919 C 234.44982,841.61201 234.79357,841.89521 235.06311,842.3288 C 235.33654,842.7624 235.47326,843.32099 235.47327,844.00458 C 235.47326,844.62568 235.35607,845.14716 235.1217,845.56903 C 234.88732,845.987 234.59436,846.28193 234.2428,846.4538 C 233.89123,846.62177 233.28576,846.70575 232.42639,846.70575 L 231.49475,846.70575 L 231.49475,849.94598 L 230.07678,849.94598 M 231.49475,842.80927 L 231.49475,845.24677 L 232.27991,845.24677 C 232.80725,845.24677 233.16467,845.20967 233.35217,845.13544 C 233.54357,845.06124 233.69982,844.92841 233.82092,844.737 C 233.94201,844.54169 234.00256,844.30341 234.00256,844.02216 C 234.00256,843.73701 233.94006,843.49677 233.81506,843.30145 C 233.69006,843.10615 233.53576,842.97529 233.35217,842.90887 C 233.16858,842.84247 232.7799,842.80927 232.18616,842.80927 L 231.49475,842.80927" /> + d="M 236.63342,842.87958 L 236.63342,841.35614 L 237.98694,841.35614 L 237.98694,842.87958 L 236.63342,842.87958 M 236.63342,849.94598 L 236.63342,843.72333 L 237.98694,843.72333 L 237.98694,849.94598 L 236.63342,849.94598" /> + d="M 239.37561,849.94598 L 239.37561,841.35614 L 240.72913,841.35614 L 240.72913,849.94598 L 239.37561,849.94598" /> + d="M 241.80139,846.74677 C 241.80139,846.13739 241.92248,845.58271 242.16467,845.0827 C 242.40686,844.58271 242.72327,844.20771 243.11389,843.9577 C 243.50451,843.70771 243.94397,843.58271 244.43225,843.5827 C 245.25256,843.58271 245.89709,843.90497 246.36584,844.5495 C 246.83459,845.19013 247.06896,845.94013 247.06897,846.7995 C 247.06896,847.44013 246.94592,848.01825 246.69983,848.53387 C 246.45764,849.0495 246.13732,849.43817 245.73889,849.69989 C 245.34436,849.9577 244.91076,850.08661 244.43811,850.08661 C 243.6803,850.08661 243.05139,849.79755 242.55139,849.21942 C 242.05139,848.6413 241.80139,847.81708 241.80139,846.74677 M 243.1842,846.83467 C 243.1842,847.46357 243.30725,847.94014 243.55334,848.26435 C 243.79944,848.58467 244.09631,848.74482 244.44397,848.74482 C 244.78381,848.74482 245.07483,848.58271 245.31702,848.25849 C 245.5592,847.93428 245.68029,847.45576 245.6803,846.82295 C 245.68029,846.20576 245.55725,845.73506 245.31116,845.41084 C 245.06506,845.08662 244.77014,844.92451 244.42639,844.92451 C 244.08655,844.92451 243.79358,845.08662 243.54749,845.41084 C 243.3053,845.73506 243.1842,846.20967 243.1842,846.83467" /> + d="M 250.47327,843.72333 L 250.47327,845.03583 L 249.55334,845.03583 L 249.55334,847.54364 C 249.55334,848.08661 249.56704,848.40106 249.59434,848.487 C 249.64904,848.64325 249.76035,848.72138 249.92832,848.72137 C 250.05332,848.72138 250.23301,848.66867 250.46739,848.56317 L 250.58457,849.84052 C 250.27207,850.00458 249.91856,850.08661 249.52403,850.08661 C 249.18028,850.08661 248.90489,850.00461 248.69786,849.84052 C 248.49082,849.67645 248.35215,849.44013 248.28184,849.13153 C 248.22714,848.90497 248.19984,848.44403 248.19984,847.74872 L 248.19984,845.03583 L 247.57875,845.03583 L 247.57875,843.72333 L 248.19984,843.72333 L 248.19984,842.487 L 249.55335,841.52606 L 249.55335,843.72333 L 250.47328,843.72333" /> + d="M 251.42249,849.94598 L 251.42249,848.2995 L 252.776,848.2995 L 252.776,849.94598 L 251.42249,849.94598" /> + d="M 253.84827,846.74677 C 253.84827,846.13739 253.96936,845.58271 254.21155,845.0827 C 254.45373,844.58271 254.77014,844.20771 255.16077,843.9577 C 255.55139,843.70771 255.99084,843.58271 256.47913,843.5827 C 257.29943,843.58271 257.94397,843.90497 258.41272,844.5495 C 258.88146,845.19013 259.11584,845.94013 259.11584,846.7995 C 259.11584,847.44013 258.99279,848.01825 258.7467,848.53387 C 258.50451,849.0495 258.1842,849.43817 257.78577,849.69989 C 257.39123,849.9577 256.95764,850.08661 256.48499,850.08661 C 255.72717,850.08661 255.09826,849.79755 254.59827,849.21942 C 254.09827,848.6413 253.84827,847.81708 253.84827,846.74677 M 255.23108,846.83467 C 255.23108,847.46357 255.35412,847.94014 255.60022,848.26435 C 255.84631,848.58467 256.14319,848.74482 256.49084,848.74482 C 256.83069,848.74482 257.1217,848.58271 257.36389,848.25849 C 257.60607,847.93428 257.72717,847.45576 257.72717,846.82295 C 257.72717,846.20576 257.60412,845.73506 257.35803,845.41084 C 257.11193,845.08662 256.81701,844.92451 256.47327,844.92451 C 256.13342,844.92451 255.84045,845.08662 255.59436,845.41084 C 255.35217,845.73506 255.23108,846.20967 255.23108,846.83467" /> + d="M 261.48303,849.94598 L 260.12952,849.94598 L 260.12952,843.72333 L 261.38342,843.72333 L 261.38342,844.60809 C 261.59826,844.19404 261.78967,843.9206 261.95764,843.78778 C 262.12951,843.65107 262.32678,843.58271 262.54944,843.5827 C 262.85803,843.58271 263.15295,843.68622 263.4342,843.89325 L 263.01233,845.3288 C 262.78967,845.14911 262.57873,845.05927 262.37952,845.05927 C 262.19201,845.05927 262.026,845.12957 261.88147,845.2702 C 261.74084,845.40693 261.63928,845.65693 261.57678,846.0202 C 261.51428,846.38349 261.48308,847.05146 261.48308,848.02411 L 261.48308,849.94598" /> + d="M 263.87952,850.35614 L 265.42639,850.58466 C 265.44979,850.81122 265.52009,850.97137 265.63733,851.06512 C 265.75842,851.16282 265.94787,851.21161 266.20569,851.21161 C 266.50256,851.21161 266.74279,851.16281 266.92639,851.06512 C 267.05529,850.99482 267.1549,850.87762 267.22522,850.71356 C 267.29552,850.5495 267.33068,850.26044 267.33069,849.84637 L 267.33069,848.93817 C 267.12756,849.27411 266.89904,849.52606 266.64514,849.69403 C 266.39123,849.862 266.10998,849.94598 265.80139,849.94598 C 265.23498,849.94598 264.75842,849.69012 264.3717,849.17841 C 263.92639,848.59247 263.70373,847.7995 263.70374,846.7995 C 263.70373,845.737 263.91272,844.93622 264.33069,844.39716 C 264.75256,843.85419 265.26233,843.58271 265.85999,843.5827 C 266.17639,843.58271 266.4635,843.6667 266.72131,843.83466 C 266.98303,844.00263 267.21545,844.25654 267.41858,844.59637 L 267.41858,843.72333 L 268.6842,843.72333 L 268.6842,849.30731 C 268.6842,850.20184 268.6022,850.85028 268.43811,851.25262 C 268.27404,851.65497 268.02014,851.9577 267.67639,852.16083 C 267.33654,852.36786 266.86389,852.47137 266.25842,852.47137 C 265.69983,852.47137 265.25256,852.39717 264.91663,852.24872 C 264.58069,852.10028 264.32287,851.87762 264.14319,851.58075 C 263.96741,851.28778 263.87952,850.94794 263.87952,850.56122 L 263.87952,850.35614 M 265.08655,846.70575 C 265.08655,847.36981 265.19201,847.85419 265.40295,848.15887 C 265.6178,848.46356 265.87561,848.61591 266.17639,848.61591 C 266.50061,848.61591 266.77795,848.46161 267.00842,848.15302 C 267.23889,847.84442 267.35412,847.37567 267.35413,846.74677 C 267.35412,846.09833 267.24279,845.61982 267.02014,845.31122 C 266.80139,844.99872 266.5299,844.84247 266.20569,844.84247 C 265.88537,844.84247 265.6178,844.99482 265.40295,845.2995 C 265.19201,845.60419 265.08655,846.07294 265.08655,846.70575" /> + + + + @@ -21654,7 +25770,7 @@ inkscape:connector-curvature="0" id="path6565-9-6" d="M 166.08622,950.31232 L 109.55369,950.31232" - style="fill:none;stroke:#545253;stroke-width:9.10000038;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#545253;stroke-width:9.10000038;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> @@ -21662,15 +25778,15 @@ inkscape:connector-curvature="0" id="path6569-5-8" d="M 236.04807,504.14551 L 179.51554,504.14551" - style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> @@ -21678,7 +25794,7 @@ transform="translate(-69.961847,475.88605)" id="g6557-0-2"> @@ -21686,13 +25802,13 @@ inkscape:connector-curvature="0" id="path6561-82-7" d="M 236.04807,496.88936 L 179.51554,496.88936" - style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#545253;stroke-width:9.10000038;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> @@ -21700,15 +25816,15 @@ inkscape:connector-curvature="0" id="path6549-1-2" d="M 236.04807,504.14551 L 179.51554,504.14551" - style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> @@ -21716,7 +25832,7 @@ transform="translate(-69.961847,525.88605)" id="g6533-32-1"> @@ -21724,17 +25840,17 @@ inkscape:connector-curvature="0" id="path6531-7-5" d="M 236.04807,496.88936 L 179.51554,496.88936" - style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="display:inline;fill:#2e2f2e;fill-opacity:1;fill-rule:evenodd;stroke:none" /> + style="fill:none;stroke:#545253;stroke-width:9.10000038;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> @@ -21766,9 +25882,9 @@ inkscape:connector-curvature="0" id="path14351-9" d="M 236.04807,504.14551 L 179.51554,504.14551" - style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> @@ -21779,7 +25895,7 @@ height="9.1741314" width="24.794964" id="rect14355-0" - style="fill:#2e2f2e;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" /> + style="display:inline;fill:#2e2f2e;fill-opacity:1;fill-rule:evenodd;stroke:none" /> + style="fill:url(#radialGradient13230-7-5);fill-opacity:1;fill-rule:evenodd;stroke:#393a3e;stroke-width:0.58099997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:url(#radialGradient13234-2-0);fill-opacity:1;fill-rule:evenodd;stroke:#393a3e;stroke-width:0.58099997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:url(#radialGradient13236-2-9);fill-opacity:1;fill-rule:evenodd;stroke:#393a3e;stroke-width:0.58099997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:url(#radialGradient13240-6-3);fill-opacity:1;fill-rule:evenodd;stroke:#393a3e;stroke-width:0.58099997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:url(#radialGradient13244-6-3);fill-opacity:1;fill-rule:evenodd;stroke:#393a3e;stroke-width:0.58099997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + d="M 444.40744,1038.0272 C 452.57603,1038.0272 459.19798,1044.6491 459.19798,1052.8177 C 459.19798,1060.9863 452.57603,1067.6082 444.40744,1067.6082 C 436.23885,1067.6082 429.6169,1060.9863 429.6169,1052.8177 C 429.6169,1044.6491 436.23885,1038.0272 444.40744,1038.0272 Z" + style="fill:url(#radialGradient13246-3-9);fill-opacity:1;fill-rule:evenodd;stroke:#87878d;stroke-width:5.08913088;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:40px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';letter-spacing:0px;word-spacing:0px;fill:#545352;fill-opacity:1;stroke:none"> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:40px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"> + d="M 751.7298,535.01081 L 751.7298,737.14902 C 751.7298,743.8214 746.35823,749.19302 739.68593,749.19302 L 537.54786,749.19302 C 530.87556,749.19302 525.50399,743.8214 525.50399,737.14902 L 525.50399,535.01081 C 525.50399,528.3385 530.87556,522.96694 537.54786,522.96694 L 739.68593,522.96694 C 746.35823,522.96694 751.7298,528.3385 751.7298,535.01081 Z" + style="fill:#2d2b2c;fill-opacity:1;stroke:#ffd25c;stroke-width:4.97813463;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:62.9418335px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none"> - - + - + - + + style="fill:url(#linearGradient7362-5-8);fill-opacity:1;fill-rule:evenodd;stroke:#515454;stroke-width:4.19999981;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + cx="-36.611858" + cy="572.3067" + r="23.877298" /> + @@ -23026,17 +27502,17 @@ inkscape:connector-curvature="0" id="path7806-9" style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:11.90251064px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none" - d="m 92.0595,965.29836 l 0,-1.43551 l 3.039557,0 l 0,3.39408 c -0.306093,0.36033 -0.740038,0.67029 -1.301837,0.92988 c -0.56181,0.2596 -1.125551,0.38939 -1.691226,0.38939 c -0.689667,0 -1.297965,-0.16854 -1.824896,-0.50562 c -0.526936,-0.34096 -0.945383,-0.84852 -1.255343,-1.52269 c -0.306088,-0.67803 -0.459131,-1.47425 -0.45913,-2.38863 c -10e-7,-0.93763 0.15498,-1.73966 0.464941,-2.40608 c 0.313835,-0.66641 0.718721,-1.16428 1.214661,-1.49362 c 0.49981,-0.32933 1.096484,-0.494 1.790026,-0.49401 c 0.833016,1e-5 1.499432,0.21311 1.99925,0.6393 c 0.50368,0.42233 0.827202,1.04419 0.970566,1.86558 l -1.394826,0.31965 c -0.104617,-0.43782 -0.296405,-0.77296 -0.575365,-1.00544 c -0.27897,-0.23246 -0.612178,-0.3487 -0.999625,-0.34871 c -0.600553,10e-6 -1.086804,0.23442 -1.458755,0.70323 c -0.371956,0.46495 -0.557932,1.17592 -0.55793,2.13292 c -2e-6,1.02675 0.201472,1.80746 0.604424,2.34214 c 0.344829,0.46107 0.811708,0.69161 1.400637,0.6916 c 0.275087,10e-6 0.559863,-0.0639 0.854331,-0.19178 c 0.298333,-0.13174 0.563737,-0.30996 0.796213,-0.53469 l 0,-1.08099 l -1.615673,0" /> + d="M 92.0595,965.29836 L 92.0595,963.86285 L 95.099057,963.86285 L 95.099057,967.25693 C 94.792964,967.61726 94.359019,967.92722 93.79722,968.18681 C 93.23541,968.44641 92.671669,968.5762 92.105994,968.5762 C 91.416327,968.5762 90.808029,968.40766 90.281098,968.07058 C 89.754162,967.72962 89.335715,967.22206 89.025755,966.54789 C 88.719667,965.86986 88.566624,965.07364 88.566625,964.15926 C 88.566624,963.22163 88.721605,962.4196 89.031566,961.75318 C 89.345401,961.08677 89.750287,960.5889 90.246227,960.25956 C 90.746037,959.93023 91.342711,959.76556 92.036253,959.76555 C 92.869269,959.76556 93.535685,959.97866 94.035503,960.40485 C 94.539183,960.82718 94.862705,961.44904 95.006069,962.27043 L 93.611243,962.59008 C 93.506626,962.15226 93.314838,961.81712 93.035878,961.58464 C 92.756908,961.35218 92.4237,961.23594 92.036253,961.23593 C 91.4357,961.23594 90.949449,961.47035 90.577498,961.93916 C 90.205542,962.40411 90.019566,963.11508 90.019568,964.07208 C 90.019566,965.09883 90.22104,965.87954 90.623992,966.41422 C 90.968821,966.87529 91.4357,967.10583 92.024629,967.10582 C 92.299716,967.10583 92.584492,967.04192 92.87896,966.91404 C 93.177293,966.7823 93.442697,966.60408 93.675173,966.37935 L 93.675173,965.29836 L 92.0595,965.29836" /> + d="M 96.406706,968.43091 L 96.406706,959.91085 L 98.673298,959.91085 C 99.517938,959.91086 100.07006,959.95155 100.32965,960.0329 C 100.74422,960.16464 101.08518,960.44554 101.35252,960.8756 C 101.62374,961.30568 101.75934,961.85974 101.75935,962.53777 C 101.75934,963.15382 101.64311,963.67107 101.41064,964.08951 C 101.17817,964.50409 100.88758,964.79662 100.53888,964.96709 C 100.19017,965.1337 99.589617,965.217 98.737227,965.217 L 97.813155,965.217 L 97.813155,968.43091 L 96.406706,968.43091 M 97.813155,961.35217 L 97.813155,963.76987 L 98.591933,963.76987 C 99.114989,963.76987 99.469507,963.73307 99.655487,963.65944 C 99.845334,963.58584 100.00031,963.4541 100.12043,963.26424 C 100.24053,963.07052 100.30059,962.83418 100.30059,962.55521 C 100.30059,962.27237 100.23859,962.03409 100.11462,961.84036 C 99.990629,961.64664 99.837585,961.51684 99.655487,961.45097 C 99.473381,961.38507 99.087867,961.35217 98.498944,961.35217 L 97.813155,961.35217" /> + d="M 102.56137,965.65869 L 103.93876,965.49596 C 104.09374,966.5847 104.6013,967.12907 105.46145,967.12907 C 105.88764,967.12907 106.22279,967.01865 106.46689,966.7978 C 106.71098,966.57308 106.83302,966.29605 106.83303,965.96672 C 106.83302,965.77299 106.79043,965.60833 106.70517,965.47272 C 106.61987,965.33711 106.49013,965.22669 106.31578,965.14144 C 106.14142,965.05234 105.7191,964.9051 105.04881,964.69975 C 104.44826,964.51765 104.0085,964.32005 103.72954,964.10695 C 103.45057,963.89386 103.22779,963.61489 103.06119,963.27005 C 102.89846,962.92135 102.81709,962.54746 102.81709,962.14838 C 102.81709,961.68345 102.9217,961.265 103.13093,960.89304 C 103.34402,960.52109 103.63655,960.24019 104.00851,960.05033 C 104.38046,959.86049 104.83959,959.76556 105.3859,959.76555 C 106.20729,959.76556 106.84852,959.98835 107.30959,960.43391 C 107.77065,960.87949 108.01475,961.51684 108.04188,962.34598 L 106.62961,962.42158 C 106.56761,961.96439 106.43395,961.64474 106.2286,961.46263 C 106.02325,961.28054 105.73072,961.18949 105.35102,961.18948 C 104.97132,961.18949 104.67879,961.26888 104.47345,961.42776 C 104.2681,961.58662 104.16542,961.78422 104.16542,962.02056 C 104.16542,962.25304 104.25842,962.4487 104.44439,962.60755 C 104.63036,962.76641 105.0585,962.94077 105.72879,963.13061 C 106.43782,963.33597 106.94926,963.55294 107.2631,963.78153 C 107.5808,964.00626 107.82296,964.29878 107.98957,964.65911 C 108.15617,965.01557 108.23947,965.44951 108.23948,965.96094 C 108.23947,966.70098 108.01087,967.32284 107.55369,967.82652 C 107.10036,968.33021 106.38939,968.58205 105.42077,968.58205 C 103.70823,968.58205 102.7551,967.60761 102.56137,965.65873" /> + d="M 147.50381,968.43091 L 147.50381,959.91085 L 149.7704,959.91085 C 150.61505,959.91086 151.16716,959.95155 151.42676,960.0329 C 151.84133,960.16464 152.18228,960.44554 152.44963,960.8756 C 152.72084,961.30568 152.85645,961.85974 152.85646,962.53777 C 152.85645,963.15382 152.74021,963.67107 152.50775,964.08951 C 152.27527,964.50409 151.98468,964.79662 151.63598,964.96709 C 151.28727,965.1337 150.68672,965.217 149.83433,965.217 L 148.91026,965.217 L 148.91026,968.43091 L 147.50381,968.43091 M 148.91026,961.35217 L 148.91026,963.76987 L 149.68904,963.76987 C 150.2121,963.76987 150.56661,963.73307 150.75259,963.65944 C 150.94244,963.58584 151.09742,963.4541 151.21754,963.26424 C 151.33764,963.07052 151.3977,962.83418 151.3977,962.55521 C 151.3977,962.27237 151.3357,962.03409 151.21172,961.84036 C 151.08774,961.64664 150.93469,961.51684 150.75259,961.45097 C 150.57049,961.38507 150.18497,961.35217 149.59605,961.35217 L 148.91026,961.35217" /> + d="M 153.69335,965.25768 C 153.69335,964.65326 153.81346,964.10308 154.05368,963.60714 C 154.2939,963.1112 154.60774,962.73925 154.99519,962.49128 C 155.38264,962.24331 155.81852,962.11933 156.30284,962.11932 C 157.11648,962.11933 157.75578,962.43898 158.22072,963.07827 C 158.68566,963.71369 158.91813,964.4576 158.91814,965.30999 C 158.91813,965.94541 158.79608,966.51884 158.55199,967.03027 C 158.31177,967.54171 157.99406,967.92722 157.59886,968.18681 C 157.20753,968.44253 156.77746,968.57039 156.30865,968.57039 C 155.55699,968.57039 154.93319,968.28368 154.43726,967.71025 C 153.94132,967.13682 153.69335,966.3193 153.69335,965.25768 M 155.06493,965.34488 C 155.06493,965.96868 155.18698,966.44137 155.43107,966.76295 C 155.67516,967.08066 155.96963,967.23952 156.31446,967.23951 C 156.65154,967.23952 156.94019,967.07872 157.18042,966.75714 C 157.42063,966.43555 157.54074,965.96093 157.54075,965.33325 C 157.54074,964.72108 157.41869,964.25421 157.1746,963.93262 C 156.93051,963.61104 156.63798,963.45024 156.29703,963.45024 C 155.95994,963.45024 155.66935,963.61104 155.42526,963.93262 C 155.18504,964.25421 155.06493,964.72496 155.06493,965.34488" /> + d="M 160.92901,968.43091 L 159.32496,962.25881 L 160.6268,962.25881 L 161.57412,966.3038 L 162.44588,962.25881 L 163.73609,962.25881 L 164.5788,966.3038 L 165.54937,962.25881 L 166.86864,962.25881 L 165.24134,968.43091 L 163.95694,968.43091 L 163.08518,964.46147 L 162.22503,968.43091 L 160.92901,968.43091" /> + d="M 170.51843,966.46653 L 171.84933,966.73968 C 171.6711,967.35961 171.39407,967.82067 171.01825,968.12288 C 170.64241,968.42122 170.18522,968.57039 169.64667,968.57039 C 168.89888,968.57039 168.32158,968.32048 167.91476,967.82067 C 167.43432,967.2395 167.1941,966.42585 167.1941,965.37973 C 167.1941,964.34911 167.43626,963.52384 167.92057,962.90391 C 168.33127,962.38086 168.86208,962.11933 169.513,962.11932 C 170.23753,962.11933 170.80514,962.38667 171.21585,962.92135 C 171.68853,963.53353 171.92488,964.43629 171.92488,965.62963 L 171.91888,965.81561 L 168.56549,965.81561 C 168.57349,966.3038 168.68172,966.68157 168.89095,966.94891 C 169.10404,967.21625 169.35976,967.34992 169.6581,967.34992 C 170.08817,967.34992 170.37488,967.05546 170.51824,966.46653 M 170.59384,964.81599 C 170.58224,964.33555 170.47954,963.97522 170.28581,963.735 C 170.09208,963.49091 169.86155,963.36886 169.59421,963.36885 C 169.31137,963.36886 169.07309,963.49478 168.87936,963.74662 C 168.68176,964.00234 168.5849,964.3588 168.58878,964.81599 L 170.59384,964.81599" /> + d="M 174.30771,968.43091 L 172.96519,968.43091 L 172.96519,962.25881 L 174.20891,962.25881 L 174.20891,963.13638 C 174.42201,962.72569 174.61186,962.45447 174.77846,962.32274 C 174.94894,962.18713 175.1446,962.11933 175.36545,962.11932 C 175.67154,962.11933 175.96406,962.222 176.24303,962.42735 L 175.82458,963.85123 C 175.60373,963.67301 175.39451,963.58389 175.19691,963.58389 C 175.01093,963.58389 174.84626,963.65359 174.70291,963.79311 C 174.56343,963.92873 174.46269,964.17669 174.4007,964.53702 C 174.3387,964.89735 174.3077,965.5599 174.3077,966.52465 L 174.3077,968.43091" /> + d="M 212.15979,968.43091 L 212.15979,959.91085 L 214.26946,959.91085 L 215.53643,965.72262 L 216.79177,959.91085 L 218.90725,959.91085 L 218.90725,968.43091 L 217.59961,968.43091 L 217.59961,961.72412 L 216.21059,968.43091 L 214.85064,968.43091 L 213.47325,961.72412 L 213.47325,968.43091 L 212.15979,968.43091" /> + d="M 224.78876,965.29836 L 226.15453,965.82723 C 225.94142,966.78037 225.58691,967.47778 225.09097,967.91947 C 224.59503,968.35729 223.9848,968.5762 223.26027,968.5762 C 222.34975,968.5762 221.61166,968.22556 221.04598,967.52427 C 220.39506,966.7145 220.0696,965.62189 220.0696,964.24643 C 220.0696,962.79349 220.397,961.65633 221.05179,960.83492 C 221.62134,960.12202 222.38656,959.76556 223.34744,959.76555 C 224.13009,959.76556 224.78488,960.0329 225.31182,960.56758 C 225.68764,960.94729 225.96273,961.51103 226.13709,962.25881 L 224.74227,962.66563 C 224.65317,962.20457 224.47492,961.85199 224.20758,961.60789 C 223.94411,961.35993 223.63221,961.23594 223.27189,961.23593 C 222.75657,961.23594 222.33619,961.46066 222.01073,961.9101 C 221.68527,962.35955 221.52254,963.10152 221.52255,964.13601 C 221.52254,965.20925 221.6814,965.97253 221.99911,966.42585 C 222.31682,966.87917 222.72945,967.10583 223.23702,967.10582 C 223.60897,967.10583 223.93055,966.96247 224.20177,966.67575 C 224.47298,966.38517 224.66865,965.92604 224.78876,965.29836" /> + d="M 227.34594,959.91085 L 228.75239,959.91085 L 228.75239,964.5254 C 228.75239,965.24219 228.76979,965.70906 228.80469,965.92603 C 228.86669,966.30186 229.01391,966.59245 229.24638,966.7978 C 229.48272,967.00315 229.79268,967.10583 230.17627,967.10582 C 230.50172,967.10583 230.76712,967.03412 230.97248,966.89079 C 231.17782,966.74356 231.31731,966.54208 231.39093,966.28636 C 231.46843,966.02677 231.50716,965.47272 231.50716,964.6242 L 231.50716,959.91085 L 232.91942,959.91085 L 232.91942,964.38591 C 232.91942,965.5289 232.85742,966.35611 232.73345,966.86754 C 232.61333,967.3751 232.33824,967.78774 231.90817,968.10545 C 231.48197,968.41928 230.91823,968.5762 230.21695,968.5762 C 229.48854,968.5762 228.91898,968.44641 228.50829,968.18681 C 228.10146,967.92335 227.80506,967.55527 227.61909,967.08258 C 227.43698,966.60601 227.34593,965.73037 227.34593,964.45566 L 227.34593,959.91085" /> + points="186.194,11.031 181.129,13.319 186.083,4.74 191.036,13.319 " /> @@ -23230,28 +27706,368 @@ sodipodi:nodetypes="ccccc" style="fill:none;stroke:#1f4697;stroke-width:7.25735998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" inkscape:connector-curvature="0" - d="m 639.00347,516.99639 l 0,-164.20356 l -43.99004,0 l 0,-88.94685 l 0,-24.04938" + d="M 639.00347,516.99639 L 639.00347,352.79283 L 595.01343,352.79283 L 595.01343,263.84598 L 595.01343,239.7966" id="path8856-5-6-5-6-7-2-8" /> + @@ -23662,7 +28478,7 @@ @@ -23972,47 +28788,47 @@ inkscape:connector-curvature="0" id="path13212-9" style="font-weight:normal;-inkscape-font-specification:'Arial Narrow Condensed'" - d="m 379.71034,1197.185 l 0,-1.8195 l 5.38448,-0.011 l 0,5.7547 c -0.82514,0.8039 -1.67847,1.4105 -2.56001,1.8195 c -0.88155,0.402 -1.78778,0.603 -2.71868,0.603 c -1.24122,0 -2.34844,-0.3103 -3.32166,-0.9309 c -0.97323,-0.6207 -1.74546,-1.5269 -2.3167,-2.7187 c -0.56419,-1.1919 -0.84628,-2.6235 -0.84628,-4.2949 c 0,-1.6926 0.28562,-3.1665 0.85686,-4.4218 c 0.57124,-1.2553 1.31879,-2.1792 2.24265,-2.7716 c 0.92385,-0.5994 2.01697,-0.8992 3.27934,-0.8992 c 0.93091,0 1.74545,0.1728 2.44364,0.5184 c 0.69818,0.3455 1.27294,0.8357 1.72431,1.4704 c 0.45133,0.6347 0.78985,1.5057 1.01553,2.6129 l -1.51273,0.5077 c -0.20452,-0.8744 -0.46194,-1.5268 -0.77223,-1.957 c -0.31031,-0.4372 -0.71935,-0.7793 -1.22711,-1.0261 c -0.50778,-0.2468 -1.07902,-0.3702 -1.71372,-0.3703 c -0.92386,10e-5 -1.72078,0.2257 -2.39075,0.6771 c -0.66292,0.4443 -1.1989,1.1389 -1.60793,2.0839 c -0.40199,0.9451 -0.60298,2.0981 -0.60298,3.4592 c 0,2.0734 0.43372,3.6285 1.30116,4.6652 c 0.86743,1.0296 1.99581,1.5444 3.38513,1.5444 c 0.66291,0 1.33994,-0.1587 2.03108,-0.476 c 0.69817,-0.3174 1.25178,-0.6947 1.66083,-1.1319 l 0,-2.888 l -3.73423,0" /> + d="M 379.71034,1197.185 L 379.71034,1195.3655 L 385.09482,1195.3545 L 385.09482,1201.1092 C 384.26968,1201.9131 383.41635,1202.5197 382.53481,1202.9287 C 381.65326,1203.3307 380.74703,1203.5317 379.81613,1203.5317 C 378.57491,1203.5317 377.46769,1203.2214 376.49447,1202.6008 C 375.52124,1201.9801 374.74901,1201.0739 374.17777,1199.8821 C 373.61358,1198.6902 373.33149,1197.2586 373.33149,1195.5872 C 373.33149,1193.8946 373.61711,1192.4207 374.18835,1191.1654 C 374.75959,1189.9101 375.50714,1188.9862 376.431,1188.3938 C 377.35485,1187.7944 378.44797,1187.4946 379.71034,1187.4946 C 380.64125,1187.4946 381.45579,1187.6674 382.15398,1188.013 C 382.85216,1188.3585 383.42692,1188.8487 383.87829,1189.4834 C 384.32962,1190.1181 384.66814,1190.9891 384.89382,1192.0963 L 383.38109,1192.604 C 383.17657,1191.7296 382.91915,1191.0772 382.60886,1190.647 C 382.29855,1190.2098 381.88951,1189.8677 381.38175,1189.6209 C 380.87397,1189.3741 380.30273,1189.2507 379.66803,1189.2506 C 378.74417,1189.2507 377.94725,1189.4763 377.27728,1189.9277 C 376.61436,1190.372 376.07838,1191.0666 375.66935,1192.0116 C 375.26736,1192.9567 375.06637,1194.1097 375.06637,1195.4708 C 375.06637,1197.5442 375.50009,1199.0993 376.36753,1200.136 C 377.23496,1201.1656 378.36334,1201.6804 379.75266,1201.6804 C 380.41557,1201.6804 381.0926,1201.5217 381.78374,1201.2044 C 382.48191,1200.887 383.03552,1200.5097 383.44457,1200.0725 L 383.44457,1197.1845 L 379.71034,1197.1845" /> + d="M 390.8178,1203.2677 L 390.8178,1189.5897 L 386.6287,1189.5897 L 386.6287,1187.7596 L 396.71004,1187.7596 L 396.71004,1189.5897 L 392.49979,1189.5897 L 392.49979,1203.2677 L 390.8178,1203.2677" /> + d="M 398.43434,1203.2677 L 398.43434,1187.7596 L 403.22642,1187.7596 C 404.35479,1187.7596 405.18697,1187.8586 405.72295,1188.0558 C 406.45639,1188.3238 407.04173,1188.821 407.47899,1189.5473 C 407.91622,1190.2738 408.13485,1191.1659 408.13486,1192.2237 C 408.13485,1193.6201 407.7787,1194.759 407.06643,1195.6406 C 406.35413,1196.5221 405.12349,1196.9629 403.37452,1196.9629 L 400.11633,1196.9629 L 400.11633,1203.2677 L 398.43434,1203.2677 M 400.11633,1195.1328 L 403.40625,1195.1328 C 404.44294,1195.1328 405.20107,1194.9001 405.68064,1194.4346 C 406.16019,1193.9621 406.39997,1193.2534 406.39998,1192.3083 C 406.39997,1191.6948 406.28008,1191.1694 406.04031,1190.7321 C 405.80757,1190.2949 405.52195,1189.9952 405.18345,1189.833 C 404.85198,1189.6708 404.249,1189.5897 403.37452,1189.5897 L 400.11633,1189.5897 L 400.11633,1195.1328" /> + d="M 407.59535,1203.2677 L 412.48263,1187.7596 L 414.29156,1187.7596 L 419.4962,1203.2677 L 417.57091,1203.2677 L 416.08991,1198.5708 L 410.77949,1198.5708 L 409.38312,1203.2677 L 407.59535,1203.2677 M 411.2661,1196.8994 L 415.57156,1196.8994 L 414.24925,1192.6045 C 413.8402,1191.2858 413.54048,1190.2138 413.35007,1189.3887 C 413.18786,1190.3831 412.95866,1191.3704 412.66247,1192.3507 L 411.2661,1196.8994" /> + d="M 420.19438,1195.6194 C 420.19438,1193.0171 420.54347,1191.046 421.24165,1189.706 C 421.94689,1188.3661 422.98358,1187.6961 424.35174,1187.6961 C 425.56474,1187.6961 426.52033,1188.2391 427.21852,1189.3252 C 428.0648,1190.6369 428.48794,1192.735 428.48795,1195.6194 C 428.48794,1198.2076 428.13885,1200.1752 427.44067,1201.5222 C 426.74248,1202.8622 425.70579,1203.5322 424.33059,1203.5322 C 423.11758,1203.5322 422.1232,1202.9398 421.34744,1201.755 C 420.57873,1200.5702 420.19438,1198.525 420.19438,1195.6194 M 421.79174,1195.6194 C 421.79174,1198.1371 422.03152,1199.8262 422.51108,1200.6865 C 422.99769,1201.5399 423.61829,1201.9665 424.3729,1201.9665 C 425.08518,1201.9665 425.68111,1201.5328 426.16067,1200.6654 C 426.64022,1199.7979 426.88,1198.116 426.88001,1195.6194 C 426.88,1193.0947 426.6367,1191.4057 426.15009,1190.5523 C 425.67053,1189.699 425.04639,1189.2723 424.27769,1189.2723 C 423.57245,1189.2723 422.98006,1189.706 422.5005,1190.5735 C 422.02799,1191.4409 421.79174,1193.1229 421.79174,1195.6194" /> + d="M 435.97755,1203.2677 L 434.41193,1203.2677 L 434.41193,1191.1341 C 434.05225,1191.5573 433.56916,1191.991 432.96267,1192.4353 C 432.35616,1192.8725 431.79903,1193.204 431.29126,1193.4297 L 431.29126,1191.589 C 432.15164,1191.0953 432.90977,1190.4924 433.56564,1189.7801 C 434.22856,1189.0678 434.69401,1188.3731 434.96201,1187.6961 L 435.97755,1187.6961 L 435.97755,1203.2677" /> + d="M 439.99739,1195.6194 C 439.99739,1193.0171 440.34648,1191.046 441.04466,1189.706 C 441.7499,1188.3661 442.78659,1187.6961 444.15475,1187.6961 C 445.36775,1187.6961 446.32334,1188.2391 447.02153,1189.3252 C 447.86781,1190.6369 448.29095,1192.735 448.29096,1195.6194 C 448.29095,1198.2076 447.94186,1200.1752 447.24368,1201.5222 C 446.54549,1202.8622 445.5088,1203.5322 444.13359,1203.5322 C 442.92059,1203.5322 441.92621,1202.9398 441.15045,1201.755 C 440.38174,1200.5702 439.99739,1198.525 439.99739,1195.6194 M 441.59475,1195.6194 C 441.59475,1198.1371 441.83452,1199.8262 442.31409,1200.6865 C 442.8007,1201.5399 443.4213,1201.9665 444.17591,1201.9665 C 444.88819,1201.9665 445.48411,1201.5328 445.96368,1200.6654 C 446.44323,1199.7979 446.68301,1198.116 446.68302,1195.6194 C 446.68301,1193.0947 446.43971,1191.4057 445.9531,1190.5523 C 445.47354,1189.699 444.8494,1189.2723 444.0807,1189.2723 C 443.37546,1189.2723 442.78307,1189.706 442.30351,1190.5735 C 441.831,1191.4409 441.59475,1193.1229 441.59475,1195.6194" /> @@ -24119,25 +28935,25 @@ sodipodi:nodetypes="cccc" style="fill:none;stroke:#000000;stroke-width:6.11999989;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" inkscape:connector-curvature="0" - d="m 593.04083,505.15991 l -2e-5,-81.45275 l 149.99998,0 l -3e-5,-100.54718" + d="M 593.04083,505.15991 L 593.04081,423.70716 L 743.04079,423.70716 L 743.04076,323.15998" id="path8856-1-5-7-7-6-6" /> @@ -24176,7 +28992,7 @@ d="M 642.05203,520.28388 L 642.05203,401.51436 L 855.00995,401.51436 L 855.00995,323.15957" id="path8856-5-1-7-1-9-5-3-6-4" /> + d="M 800.72981,535.98589 L 800.72981,738.12396 C 800.72981,744.79627 795.35824,750.16784 788.68594,750.16784 L 586.54788,750.16784 C 579.87557,750.16784 574.504,744.79627 574.504,738.12396 L 574.504,535.98589 C 574.504,529.31358 579.87557,523.94202 586.54788,523.94202 L 788.68594,523.94202 C 795.35824,523.94202 800.72981,529.31358 800.72981,535.98589 Z" + style="fill:#2d2b2c;fill-opacity:1;stroke:#ffd25c;stroke-width:4.97813463;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" /> - - + - + - + + style="fill:url(#linearGradient7362-5-5);fill-opacity:1;fill-rule:evenodd;stroke:#515454;stroke-width:4.19999981;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + cx="-36.611858" + cy="572.3067" + r="23.877298" /> @@ -24460,32 +29264,26 @@ y="520.27533" width="35.854359" height="26.855732" - style="fill:#f1a853;fill-opacity:1;stroke:#f1a853;stroke-width:3.93985224;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline" /> + style="display:inline;fill:#f1a853;fill-opacity:1;stroke:#f1a853;stroke-width:3.93985224;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /> - - + + style="fill:url(#linearGradient14767-2);fill-opacity:1;fill-rule:evenodd;stroke:#515454;stroke-width:4.19999981;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + cx="-36.611858" + cy="572.3067" + r="23.877298" /> + d="M 33.669218,653.89868 L 346.27969,653.89868 L 366.89017,673.89868 L 366.89017,820.50917 L 366.89017,987.11966 L 200.27969,987.11966 L 56.723807,987.11966 L 33.669218,958.8367 Z" + style="fill:#eaecec;fill-opacity:1;fill-rule:evenodd;stroke:#606062;stroke-width:0.40000001;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:38.42431259px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Condensed';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"> - - + + transform="matrix(0,-0.40146247,0.40146247,0,456.77534,524.10489)" + cx="-36.611858" + cy="572.3067" + r="23.877298" /> @@ -24707,27 +29499,27 @@ transform="matrix(0.64801118,0,0,0.64801118,460.25235,105.32296)"> @@ -24736,23 +29528,23 @@ transform="matrix(0.64801118,0,0,0.64801118,461.02363,105.32296)"> + d="M 559.59247,678.83043 C 559.38011,679.41762 558.84835,679.91641 558.24315,680.09613 C 557.67095,680.26604 556.4561,680.30337 556.3637,680.15393 C 556.2929,680.0394 556.54982,679.00979 556.73431,678.66865 C 556.93413,678.2992 556.96342,676.34396 556.77151,676.18469 C 556.6578,676.09039 556.63571,675.92438 556.68311,675.52083 C 556.75781,674.88506 556.58268,674.63007 556.20868,674.83022 C 555.78358,675.05775 555.47754,676.39957 555.82071,676.53123 C 555.9254,676.57133 555.95508,676.82949 555.94024,677.57086 C 555.91874,678.64505 555.60225,679.6738 555.25985,679.78248 C 555.16315,679.81328 555.00025,679.9308 554.89789,680.04395 C 554.72416,680.23592 554.57035,680.24957 552.58596,680.24957 C 551.25843,680.24957 550.38094,680.20717 550.24925,680.13673 C 550.09528,680.05433 549.95707,680.05753 549.73735,680.14833 C 549.27362,680.34039 548.91156,680.20623 548.91156,679.8419 C 548.91156,679.33562 548.60586,679.33631 548.17324,679.8419 C 547.89793,680.16484 547.74873,680.26341 547.61381,680.21158 C 547.48034,680.16068 547.44884,680.07699 547.49913,679.90792 C 547.676,679.31325 547.68185,678.93593 547.51633,678.79849 C 547.37914,678.68464 547.32016,678.6841 547.1862,678.79849 C 546.95256,678.99247 546.72439,679.46959 546.72439,679.7643 C 546.72439,679.90337 546.65819,680.07205 546.57731,680.13923 C 546.46854,680.22943 545.25425,680.25315 541.91652,680.23013 C 537.90318,680.20233 537.36699,680.17923 537.07977,680.02196 C 536.61039,679.76488 536.1264,679.17021 535.99778,678.69255 C 535.92258,678.41334 535.89554,676.3664 535.91528,672.45099 L 535.94468,666.62485 L 536.26147,666.17419 C 536.74273,665.48958 537.23593,665.25688 538.20999,665.2548 C 538.65393,665.2548 539.01716,665.2787 539.01716,665.3103 C 539.01716,665.3419 538.94196,665.51292 538.85014,665.69055 C 538.74027,665.90305 538.70394,666.14384 538.74397,666.39421 C 538.78257,666.63593 538.75297,666.84865 538.66397,666.97731 C 538.58647,667.08876 538.49042,667.32994 538.45052,667.51328 C 538.39362,667.77444 538.42232,667.88458 538.58241,668.02172 C 538.77212,668.18415 538.77583,668.22303 538.63401,668.56232 C 538.27561,669.42015 538.86679,669.78559 539.2417,668.93802 L 539.45453,668.45688 L 539.23811,668.16418 C 539.03682,667.89191 539.03243,667.84579 539.17531,667.50379 C 539.29649,667.21379 539.30352,667.08035 539.20851,666.87202 C 539.10941,666.65452 539.11951,666.5733 539.26531,666.4121 C 539.36281,666.30443 539.47026,666.04527 539.50418,665.83625 C 539.55188,665.54262 539.60531,665.46881 539.73954,665.51138 C 539.83504,665.54148 540.0045,665.49748 540.11607,665.41308 C 540.2594,665.30471 540.59781,665.25866 541.2696,665.25635 C 542.1413,665.25635 542.23341,665.27255 542.3779,665.48735 L 542.53549,665.72175 L 542.78788,665.48735 C 542.95567,665.33163 543.17014,665.25303 543.42772,665.25303 L 543.81517,665.25303 L 543.74627,665.77204 C 543.68977,666.19833 543.70797,666.30269 543.84817,666.35653 C 544.10143,666.45373 544.31869,666.21823 544.44738,665.70717 L 544.56174,665.25303 L 546.53083,665.25303 L 548.49992,665.25303 L 548.59592,665.50548 C 548.65142,665.65125 548.79291,665.77219 548.93117,665.79186 C 549.10428,665.81656 549.18527,665.91195 549.22401,666.13709 C 549.28081,666.46744 549.57369,666.61129 549.77652,666.40851 C 549.97957,666.20543 550.07521,666.28734 550.00552,666.60465 C 549.75924,667.72596 550.7246,667.57363 551.05441,666.43913 C 551.20677,665.91496 551.20655,665.84716 551.05141,665.61099 C 550.91478,665.40243 550.84532,665.37374 550.68492,665.45959 C 550.41959,665.60158 550.36918,665.59356 550.36918,665.40949 C 550.36918,665.27336 550.87472,665.25346 554.30091,665.255 C 558.18055,665.255 558.23812,665.263 558.64492,665.49025 C 558.87168,665.61867 559.19975,665.92649 559.37398,666.17431 L 559.69077,666.62498 L 559.71437,672.5267 C 559.73377,677.37183 559.71137,678.50078 559.59197,678.83213 Z M 556.1429,673.43521 C 555.9087,673.20097 555.60666,673.39281 555.36243,673.93069 C 555.02286,674.67854 555.13408,675.22763 555.60137,675.11031 C 555.76751,675.06861 555.91383,674.90978 556.02208,674.65355 C 556.35425,673.86752 556.37418,673.66645 556.1429,673.43521 Z M 555.3029,671.93774 C 554.857,671.87454 554.29064,673.02157 554.53894,673.4855 C 554.83808,674.04446 555.60572,673.21154 555.55221,672.38602 C 555.53051,672.05043 555.48191,671.96327 555.3029,671.93774 Z M 554.71116,670.62399 C 554.50604,670.34347 554.20552,670.46248 553.94144,670.92881 C 553.6574,671.43031 553.61592,672.20307 553.86784,672.29979 C 554.09236,672.38589 554.51256,671.94846 554.69372,671.44002 C 554.87737,670.92464 554.87889,670.85338 554.71112,670.62399 Z M 553.76131,669.11079 C 553.53213,668.92059 553.19783,669.15169 552.96693,669.66041 C 552.42923,670.84474 553.11922,671.48538 553.69015,670.33198 C 553.94545,669.81622 553.97616,669.28911 553.76135,669.11079 Z M 552.87894,667.86738 C 552.70702,667.59589 552.28027,667.81958 552.04562,668.30455 C 551.46026,669.51371 552.13182,670.18567 552.73916,668.99849 C 552.98381,668.52021 553.03419,668.1125 552.87894,667.86738 Z M 551.80789,666.56844 C 551.29192,666.24535 550.55714,667.96989 551.04003,668.37065 C 551.26401,668.55653 551.55675,668.35365 551.81803,667.83229 C 552.07456,667.32015 552.06985,666.7325 551.80793,666.56844 Z M 550.99828,674.10454 C 550.76114,674.10454 550.57801,674.39386 550.57801,674.76855 C 550.57801,675.11764 550.75429,675.20734 551.00118,674.9839 C 551.28339,674.72852 551.28133,674.10454 550.99818,674.10454 Z M 550.89938,675.46935 C 550.775,675.2729 550.49837,675.39455 550.35511,675.7093 C 550.10576,676.25661 550.58924,676.51407 550.86028,675.97833 C 551.01645,675.66966 551.01752,675.65593 550.89938,675.46935 Z M 550.82638,672.84479 C 550.68222,672.72516 550.6302,672.73981 550.46185,672.94775 C 550.35385,673.08111 550.26548,673.32569 550.26548,673.49113 C 550.26548,673.93077 550.64261,673.90601 550.83928,673.45333 C 551.02708,673.02125 551.02686,673.01099 550.82638,672.84454 Z M 550.03212,671.41534 C 549.6022,671.47624 549.38204,672.43808 549.79791,672.43808 C 550.00804,672.43808 550.26548,672.01996 550.26548,671.67866 C 550.26548,671.431 550.22698,671.38758 550.03212,671.41534 Z M 549.80659,675.9454 C 549.54952,675.8468 549.16988,676.4462 549.29045,676.76042 C 549.37715,676.98634 549.60381,676.95225 549.79089,676.68482 C 549.99276,676.39658 550.00075,676.0195 549.80659,675.94499 Z M 549.28502,670.05007 C 549.06054,669.86373 548.68461,670.31193 548.72449,670.71832 C 548.76369,671.11731 549.10644,671.14925 549.29747,670.77152 C 549.4702,670.43007 549.46623,670.2003 549.28507,670.0499 Z M 548.50382,675.88601 C 548.37944,675.68956 548.10281,675.81191 547.95955,676.12596 C 547.7102,676.67319 548.19367,676.93065 548.46472,676.39498 C 548.62089,676.08623 548.62195,676.07251 548.50382,675.88601 Z M 548.36122,668.81153 C 548.20162,668.67902 548.04837,668.76293 547.88558,669.07238 C 547.69034,669.44329 547.73277,669.83434 547.96828,669.83434 C 548.36915,669.83434 548.6652,669.06374 548.36126,668.81153 Z M 547.65713,672.27904 C 547.4907,672.17623 547.24508,672.43384 547.24508,672.7112 C 547.24508,672.88582 547.30398,672.95886 547.4447,672.95886 C 547.72987,672.95886 547.89613,672.42674 547.65713,672.27904 Z M 547.59843,667.91605 C 547.46437,667.56665 547.02135,667.85895 546.89884,668.37705 C 546.81664,668.72499 546.95764,668.93609 547.21715,668.85372 C 547.53501,668.75283 547.73285,668.2663 547.59843,667.91605 Z M 547.35397,671.29656 C 547.27167,671.16645 547.22682,671.17246 547.04311,671.33896 C 546.78445,671.57304 546.76674,671.79626 546.99971,671.88565 C 547.10459,671.92575 547.22574,671.87665 547.31217,671.75831 C 547.47796,671.53162 547.48104,671.49769 547.35387,671.29677 Z M 546.91572,675.18768 C 546.76491,675.09448 546.41183,675.51355 546.41183,675.78574 C 546.41183,676.03811 546.6782,676.14717 546.88185,675.97818 C 547.0655,675.82577 547.08829,675.29435 546.91575,675.18768 Z M 546.6329,667.0222 C 546.36947,667.0222 546.20575,667.24032 546.13309,667.68806 C 546.05469,668.17089 546.34187,668.32908 546.63636,667.96541 C 546.90002,667.63977 546.89775,667.0222 546.63336,667.0222 Z M 546.5274,678.07718 C 546.39316,677.86538 546.01811,678.02858 545.83786,678.37698 C 545.63297,678.7732 545.63439,679.40427 545.83986,679.48325 C 546.2648,679.64638 546.81183,678.52685 546.52692,678.07718 Z M 546.23621,669.96616 C 546.16831,669.94376 546.03382,670.04586 545.93747,670.19292 C 545.79472,670.41073 545.78662,670.48956 545.89367,670.61859 C 546.01067,670.75959 546.04679,670.75727 546.22303,670.59779 C 546.43383,670.40705 546.4416,670.03382 546.23623,669.96618 Z M 545.48208,674.41291 C 545.25483,674.53454 545.10667,675.02825 545.2534,675.17495 C 545.5192,675.44074 545.96122,674.85818 545.77025,674.49382 C 545.69655,674.35321 545.62902,674.33431 545.48208,674.41292 Z M 545.55908,666.10536 C 545.21258,666.03976 544.86649,666.8694 545.10913,667.18394 C 545.26185,667.38185 545.27203,667.37954 545.5319,667.08794 C 545.84102,666.74109 545.85704,666.16177 545.5591,666.10539 Z M 545.3442,677.09563 C 545.11848,677.01463 544.8932,677.2023 544.69902,677.63291 C 544.33318,678.44416 544.82362,678.97212 545.26722,678.24455 C 545.49793,677.86615 545.54473,677.16751 545.34422,677.09563 Z M 544.92238,669.20944 C 544.71374,669.20944 544.53701,669.43388 544.53701,669.6989 C 544.53701,669.86558 544.59781,669.93847 544.73665,669.93847 C 544.84644,669.93847 544.95991,669.87987 544.98879,669.80827 C 545.09283,669.55043 545.05509,669.20944 544.92239,669.20944 Z M 544.69915,673.47964 C 544.53174,673.47964 544.22456,673.86752 544.22456,674.07894 C 544.22456,674.27755 544.51461,674.35691 544.69458,674.20759 C 544.89769,674.03898 544.9012,673.47964 544.69958,673.47964 Z M 544.28102,676.19121 C 543.95015,675.91663 543.33968,676.98526 543.53567,677.49601 C 543.64096,677.77036 544.02868,677.62412 544.23892,677.23068 C 544.47148,676.79552 544.48897,676.36382 544.28102,676.19121 Z M 543.84498,672.26169 C 543.63588,672.18149 543.39135,672.48374 543.39135,672.82257 C 543.39135,672.99156 543.45175,673.06299 543.59447,673.06299 C 543.96441,673.06299 544.17529,672.38841 543.84498,672.26169 Z M 543.79218,669.56416 C 543.6369,669.46816 543.39137,669.80534 543.39137,670.11463 C 543.39137,670.3744 543.58605,670.43117 543.78715,670.23009 C 543.94614,670.07113 543.94924,669.66126 543.79215,669.56416 Z M 543.13622,670.97563 C 542.8949,671.17593 542.92265,671.70905 543.17442,671.70905 C 543.44381,671.70905 543.6305,671.19552 543.43621,670.98889 C 543.32268,670.86819 543.26858,670.8658 543.13625,670.97579 Z M 543.14222,675.19816 C 542.87894,675.19816 542.56729,675.63387 542.49002,676.11007 C 542.43982,676.41951 542.46382,676.51037 542.61104,676.56683 C 543.00335,676.71739 543.41191,676.17424 543.3664,675.56268 C 543.3457,675.28409 543.2928,675.19816 543.14222,675.19816 Z M 542.35875,674.21954 C 542.13652,673.8686 541.59906,674.49289 541.58024,675.12389 C 541.57024,675.44853 541.60584,675.51586 541.80037,675.54355 C 542.22101,675.60375 542.62636,674.64221 542.35875,674.21954 Z M 541.55755,673.22773 C 541.38048,672.76635 540.68468,673.39218 540.6838,674.01369 C 540.68303,674.6527 541.31057,674.53956 541.50546,673.86552 C 541.63095,673.43151 541.63179,673.42125 541.55756,673.22773 Z M 540.65737,671.8893 C 540.32161,671.77214 539.95434,672.27549 539.95434,672.85281 C 539.95434,673.30432 540.23233,673.38446 540.54359,673.02257 C 540.81258,672.70989 540.88693,671.96937 540.65737,671.8893 Z M 539.88224,670.68709 C 539.46077,670.62689 539.09327,671.83323 539.48698,671.98433 C 539.81415,672.1099 540.17107,671.58333 540.13245,671.03209 C 540.11615,670.79823 540.05305,670.71146 539.88224,670.68709 Z M 539.41033,669.33338 C 539.16443,669.28708 538.79627,669.90445 538.83242,670.30298 C 538.87232,670.74231 539.25434,670.79237 539.47747,670.38748 C 539.69042,670.00114 539.65079,669.37893 539.41037,669.33342 Z M 563.22616,629.40283 C 563.05251,630.04805 562.96205,630.24056 562.5192,630.90735 C 562.33856,631.17934 562.11929,631.40196 562.03193,631.40206 C 561.94453,631.40217 561.53458,631.06148 561.12084,630.64496 L 560.36858,629.88765 L 560.61177,629.52532 C 560.96942,628.99247 561.09716,628.5356 561.09716,627.78934 C 561.09716,626.37298 560.34109,625.67392 558.80918,625.67392 C 558.40635,625.67392 558.07676,625.70992 558.07676,625.75392 C 558.07676,625.79792 558.1853,625.9971 558.31795,626.19656 C 558.75513,626.85399 558.85816,627.24516 558.85235,628.22567 C 558.84635,629.25403 558.60382,629.97121 558.0349,630.64384 C 557.28752,631.52748 555.7658,631.88018 553.08196,631.79185 C 551.06721,631.72555 550.33192,631.525 549.56053,630.83146 C 548.87323,630.21352 548.57894,629.53003 548.51642,628.40651 C 548.46022,627.39808 548.60372,626.77969 549.03048,626.19062 C 549.40901,625.66808 549.40522,625.57517 548.98948,625.55036 L 548.65099,625.51776 L 548.65099,624.26794 L 548.65099,623.01811 L 554.11276,622.99111 C 558.76192,622.96811 559.66806,622.98811 560.20308,623.12516 C 561.74908,623.52123 562.80243,624.61342 563.23313,626.26693 C 563.42792,627.01483 563.42424,628.66679 563.22613,629.40287 Z M 556.24898,626.49722 C 556.16348,626.33195 555.89537,626.0908 555.65309,625.96136 C 555.25193,625.74701 555.07307,625.726 553.65031,625.726 C 551.93118,625.726 551.62642,625.813 551.16155,626.43665 C 550.85308,626.85048 550.85074,627.92883 551.15755,628.34819 C 551.58734,628.93595 552.02748,629.05885 553.70254,629.05885 C 555.06997,629.05885 555.25428,629.03665 555.65192,628.82417 C 556.4567,628.3941 556.71322,627.39464 556.24914,626.49722 Z M 559.26375,652.07095 C 558.88435,653.26476 558.02009,653.99393 556.72961,654.20896 C 555.42639,654.42616 554.27094,653.98683 553.62708,653.02921 C 553.12482,652.28224 553.05181,651.93175 552.98365,649.94131 L 552.92125,648.11865 L 552.31302,648.13135 C 551.17087,648.15515 550.7588,648.72577 550.80726,650.21633 C 550.83596,651.10056 550.86236,651.20188 551.17671,651.63941 C 551.36288,651.8985 551.5152,652.15085 551.5152,652.2002 C 551.5152,652.2496 551.20701,652.69334 550.72669,653.06847 L 549.93818,653.84697 L 549.48319,653.3492 C 548.79396,652.5951 548.5761,651.91792 548.51908,650.35253 C 548.46608,648.89729 548.56948,648.20875 548.97191,647.33751 C 549.30022,646.62673 549.74599,646.1515 550.42161,645.79197 L 550.94236,645.51486 L 555.13448,645.48436 L 559.32659,645.45386 L 559.32659,646.69699 C 559.32659,648.01371 559.30619,648.06654 558.79731,648.06654 C 558.58362,648.06654 558.52867,648.21999 558.70371,648.32815 C 558.76211,648.36415 558.9352,648.63648 559.08842,648.93316 C 559.32638,649.39391 559.37143,649.6245 559.39729,650.51411 C 559.41859,651.24615 559.37889,651.70874 559.26379,652.07092 Z M 557.02458,648.92983 C 556.74759,648.35764 556.34022,648.13675 555.52504,648.1278 L 554.90013,648.1188 L 554.87093,649.4459 C 554.83803,650.94628 554.93483,651.27759 555.49079,651.56506 C 556.07168,651.86544 556.88692,651.55276 557.14412,650.9309 C 557.31962,650.50661 557.25368,649.40334 557.02452,648.92998 Z M 559.29012,639.89065 C 559.04862,640.62224 558.696,641.20816 558.19746,641.70617 C 557.27717,642.62552 556.14867,642.95951 553.96277,642.95951 C 552.4923,642.95951 551.45504,642.79138 550.71488,642.43309 C 550.01561,642.09457 549.26264,641.2976 548.88112,640.49215 C 548.56003,639.81427 548.54692,639.73525 548.54813,638.4846 C 548.55013,636.77524 548.74859,636.23287 549.73509,635.24637 C 550.73918,634.24228 551.79975,633.90604 553.96277,633.90604 C 556.12579,633.90604 557.18635,634.24228 558.19044,635.24637 C 559.11813,636.17407 559.3503,636.76812 559.3949,638.32837 C 559.4164,639.0813 559.3805,639.61685 559.29012,639.89065 Z M 556.89318,637.72128 C 556.55179,636.90421 555.77569,636.60986 553.96277,636.60986 C 552.62993,636.60986 551.92044,636.75354 551.498,637.10901 C 550.59825,637.86609 550.72225,639.36748 551.73135,639.93463 C 552.60691,640.42671 555.31533,640.42856 556.18876,639.93763 C 556.93195,639.51994 557.23988,638.55103 556.89318,637.72125 Z M 559.31742,611.64108 C 559.09543,612.58329 558.49965,613.30687 557.60808,613.71708 C 557.18046,613.91382 556.91035,613.95664 556.09788,613.95647 C 554.92656,613.95626 554.49637,613.77844 553.82704,613.01805 C 553.16859,612.26999 553.29162,611.80946 552.98384,609.73868 L 552.92124,607.91602 L 552.40048,607.88762 C 551.2762,607.82632 550.78613,608.41272 550.78613,609.8193 C 550.78613,610.70655 550.97106,611.29147 551.35135,611.60708 C 551.44145,611.68188 551.5152,611.79707 551.5152,611.8631 C 551.5152,612.01853 550.0374,613.48813 549.88111,613.48813 C 549.55553,613.48813 548.79817,612.19077 548.59818,611.29046 C 548.42759,610.52251 548.51448,608.31176 548.74376,607.58721 C 549.12217,606.39132 550.07557,605.50456 551.24268,605.26298 C 551.57615,605.19398 553.17878,605.16298 555.52504,605.18038 L 559.27451,605.20808 L 559.27451,606.45791 L 559.27451,607.70773 L 559.01413,607.74263 C 558.60632,607.79713 558.57723,607.90018 558.86095,608.28475 C 559.00612,608.4815 559.1937,608.87422 559.27782,609.15744 C 559.44411,609.7174 559.46481,611.01554 559.31742,611.64113 Z M 556.941,608.50278 C 556.60959,608.03734 556.2104,607.86395 555.47027,607.86395 L 554.83232,607.86395 L 554.86622,609.33088 L 554.90012,610.79781 L 555.24026,611.10146 C 555.85169,611.64731 556.76879,611.46948 557.10029,610.7408 C 557.33186,610.23176 557.23854,608.92064 556.941,608.50278 Z M 559.26551,600.92389 C 559.087,601.66135 558.66761,602.74733 558.18301,603.01888 L 557.88951,603.30006 L 557.03712,602.47472 L 556.18473,601.64936 L 556.50949,601.13737 C 556.94547,600.45004 557.13952,599.74842 557.13883,598.86194 C 557.13683,597.89437 556.99478,597.41671 556.6076,597.09092 C 556.2625,596.80054 556.0328,596.76306 555.65452,596.93541 C 555.25123,597.11918 555.15102,597.40765 554.99266,598.84072 C 554.77441,600.81574 554.55819,601.47799 553.94628,602.04559 C 553.35951,602.58988 552.99882,602.70847 551.93182,602.70793 C 551.06041,602.70752 550.87913,602.67413 550.41224,602.4282 C 549.14643,601.76148 548.49844,600.42583 548.49604,598.47846 C 548.49404,596.89595 548.81873,595.66066 549.42418,594.94689 L 549.73151,594.58459 L 550.54268,595.39004 L 551.35385,596.19549 L 551.16187,596.5205 C 550.71392,597.27881 550.5403,598.78711 550.82385,599.45703 C 551.04162,599.97156 551.32879,600.17572 551.78106,600.13757 C 552.4187,600.08377 552.55653,599.7919 552.72922,598.12981 C 552.91542,596.33775 553.14329,595.68775 553.81539,595.03154 C 554.44624,594.41561 555.18421,594.17141 556.19592,594.24379 C 557.7726,594.3566 558.81091,595.32111 559.27539,597.10437 C 559.47441,597.86844 559.46868,600.08453 559.26539,600.92389 Z M 559.12995,658.56794 C 558.8921,659.25031 558.32918,659.84644 557.61927,660.16777 C 557.10877,660.39885 556.96459,660.40987 554.04111,660.44165 C 550.62347,660.47865 550.9439,660.39765 550.86678,661.24179 C 550.83828,661.55294 550.83528,661.55432 550.11133,661.58556 C 549.01306,661.63266 548.92868,661.59356 548.89106,661.00686 L 548.85936,660.51269 L 547.35346,660.48339 C 546.30882,660.46339 545.8228,660.41549 545.76674,660.3272 C 545.66147,660.16153 545.66147,658.05126 545.76674,657.88559 C 545.82284,657.79739 546.30889,657.75277 547.35346,657.7294 L 548.85936,657.7001 L 548.91146,656.81481 L 548.96356,655.92951 L 549.92696,655.89941 L 550.89037,655.86931 L 550.89037,656.64585 C 550.89037,657.07292 550.91887,657.49652 550.95357,657.58707 C 551.00907,657.73153 551.35389,657.75181 553.75164,657.75181 C 556.36067,657.75181 556.49908,657.74181 556.76089,657.53601 C 556.99933,657.34843 557.03552,657.2426 557.0369,656.72884 C 557.03767,656.40359 557.0768,656.0771 557.1236,656.00329 C 557.1859,655.90509 557.48546,655.87718 558.24164,655.89916 L 559.27455,655.92926 L 559.29895,656.97082 C 559.31765,657.76556 559.27755,658.14373 559.12996,658.56717 Z M 559.12295,618.17498 C 558.97813,618.59658 558.78542,618.87771 558.39303,619.23977 C 557.49703,620.06652 557.65634,620.04971 550.71507,620.04971 L 544.64109,620.04971 L 544.64109,618.69574 L 544.64109,617.34177 L 550.61167,617.34177 L 556.58225,617.34177 L 556.8087,617.10071 C 556.98914,616.90865 557.03516,616.73297 557.03516,616.23626 C 557.03516,615.89025 557.09076,615.55723 557.16014,615.48786 C 557.29065,615.35737 558.85671,615.30904 559.16175,615.42606 C 559.41342,615.52266 559.3868,617.40675 559.12295,618.17493 Z" + style="display:inline;fill:#242625;fill-opacity:1" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:12px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"> + + style="fill:none;stroke:#545253;stroke-width:9.10000038;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> @@ -24918,15 +30040,15 @@ inkscape:connector-curvature="0" id="path6569-5-8-5" d="M 236.04807,504.14551 L 179.51554,504.14551" - style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> @@ -24934,7 +30056,7 @@ transform="translate(-69.961847,475.88605)" id="g6557-0-2-4"> @@ -24942,13 +30064,13 @@ inkscape:connector-curvature="0" id="path6561-82-7-6" d="M 236.04807,496.88936 L 179.51554,496.88936" - style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#545253;stroke-width:9.10000038;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> @@ -24956,15 +30078,15 @@ inkscape:connector-curvature="0" id="path6549-1-2-3" d="M 236.04807,504.14551 L 179.51554,504.14551" - style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> @@ -24972,7 +30094,7 @@ transform="translate(-69.961847,525.88605)" id="g6533-32-1-5"> @@ -24980,17 +30102,17 @@ inkscape:connector-curvature="0" id="path6531-7-5-3" d="M 236.04807,496.88936 L 179.51554,496.88936" - style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="display:inline;fill:#2e2f2e;fill-opacity:1;fill-rule:evenodd;stroke:none" /> + style="fill:none;stroke:#545253;stroke-width:9.10000038;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> @@ -25022,9 +30144,9 @@ inkscape:connector-curvature="0" id="path14351-9-0" d="M 236.04807,504.14551 L 179.51554,504.14551" - style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> @@ -25035,7 +30157,7 @@ height="9.1741314" width="24.794964" id="rect14355-0-9" - style="fill:#2e2f2e;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" /> + style="display:inline;fill:#2e2f2e;fill-opacity:1;fill-rule:evenodd;stroke:none" /> + style="fill:url(#radialGradient13230-7-5-5);fill-opacity:1;fill-rule:evenodd;stroke:#393a3e;stroke-width:0.58099997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:url(#radialGradient13234-2-0-6);fill-opacity:1;fill-rule:evenodd;stroke:#393a3e;stroke-width:0.58099997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:url(#radialGradient13236-2-9-0);fill-opacity:1;fill-rule:evenodd;stroke:#393a3e;stroke-width:0.58099997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:url(#radialGradient13240-6-3-1);fill-opacity:1;fill-rule:evenodd;stroke:#393a3e;stroke-width:0.58099997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:url(#radialGradient13244-6-3-3);fill-opacity:1;fill-rule:evenodd;stroke:#393a3e;stroke-width:0.58099997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + d="M 444.40744,1038.0272 C 452.57603,1038.0272 459.19798,1044.6491 459.19798,1052.8177 C 459.19798,1060.9863 452.57603,1067.6082 444.40744,1067.6082 C 436.23885,1067.6082 429.6169,1060.9863 429.6169,1052.8177 C 429.6169,1044.6491 436.23885,1038.0272 444.40744,1038.0272 Z" + style="fill:url(#radialGradient13246-3-9-8);fill-opacity:1;fill-rule:evenodd;stroke:#87878d;stroke-width:5.08913088;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:40px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';letter-spacing:0px;word-spacing:0px;fill:#545352;fill-opacity:1;stroke:none"> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:40px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + style="display:inline"> @@ -26614,14 +34924,14 @@ @@ -26905,42 +35215,42 @@ sodipodi:nodetypes="ccc" style="fill:none;stroke:#000000;stroke-width:6.11999989;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" inkscape:connector-curvature="0" - d="m 557.56684,7.2342526 l -16.661,0 L 539.9592,131.04466" + d="M 557.56684,7.2342526 L 540.90584,7.2342526 L 539.9592,131.04466" id="path8856-1-5-7-7-6-2-4-1-7" /> @@ -26950,17 +35260,17 @@ style="display:inline;fill:#1f4697;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" transform="translate(225.07579,-457.5649)"> @@ -26970,17 +35280,17 @@ style="display:inline;fill:#ec6004;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" transform="translate(225.07579,-457.5649)"> @@ -26990,17 +35300,17 @@ style="display:inline;fill:#d81900;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" transform="translate(225.07579,-457.5649)"> @@ -27012,54 +35322,54 @@ + points="251.619,492.937 251.619,485.734 242.74,485.734 242.74,480.095 251.619,480.095 251.619,473.728 242.74,473.728 242.74,467.777 251.619,467.777 251.619,467.777 251.619,460.783 233.13,460.783 233.13,492.937 " /> + points="253.082,364.946 253.082,454.937 220.283,454.937 220.283,364.946 220.283,364.946 " /> + points="225.505,449.298 247.754,449.298 247.754,370.688 225.505,370.688 225.505,370.688 " /> @@ -27078,18 +35388,18 @@ @@ -27099,20 +35409,20 @@ transform="matrix(0.77129601,0,0,0.77129601,324.31484,-384.90486)"> @@ -27122,18 +35432,18 @@ @@ -27143,20 +35453,20 @@ id="g6537"> @@ -27191,43 +35501,43 @@ sodipodi:nodetypes="ccccccc" inkscape:connector-curvature="0" id="path3855-7" - d="m 571.01776,18.4088 l -3.63361,19.50674 l 0.95621,3.442371 l 7.07598,-6.119763 l 2.10367,-13.578227 l -3.82485,-2.868635 z" + d="M 571.01776,18.4088 L 567.38415,37.91554 L 568.34036,41.357911 L 575.41634,35.238148 L 577.52001,21.659921 L 573.69516,18.791286 Z" style="fill:#df181b;fill-opacity:1;stroke:#000000;stroke-width:0.77129602px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> @@ -28004,12 +36314,12 @@ @@ -28017,25 +36327,25 @@ sodipodi:nodetypes="ccccc" style="fill:none;stroke:#000000;stroke-width:6.11999989;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" inkscape:connector-curvature="0" - d="M 505.59448,19.583031 L 386.90584,19.234248 l -0.23664,78.952611 l 153.5266,-1.047395 l -0.23664,33.905196" + d="M 505.59448,19.583031 L 386.90584,19.234248 L 386.6692,98.186859 L 540.1958,97.139464 L 539.95916,131.04466" id="path8856-1-5-7-7-6-2-4-1-7-0" /> @@ -28090,17 +36400,17 @@ style="display:inline;fill:#ec6004;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" transform="translate(157.54014,-490.99384)"> @@ -28110,17 +36420,17 @@ style="display:inline;fill:#d81900;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" transform="translate(156.54014,-461.49384)"> @@ -28132,15 +36442,15 @@ + d="M -180.40365,849.14123 L -178.88227,848.99332 C -178.79067,849.50397 -178.60582,849.87903 -178.3276,850.1185 C -178.04587,850.35798 -177.66729,850.47772 -177.19185,850.47772 C -176.68825,850.47772 -176.30967,850.37207 -176.0561,850.16076 C -175.79902,849.94594 -175.67048,849.6959 -175.67048,849.41064 C -175.67048,849.22752 -175.72508,849.07256 -175.83423,848.94578 C -175.93989,848.81548 -176.12654,848.70278 -176.39419,848.60769 C -176.57732,848.54429 -176.99464,848.43161 -177.64615,848.26961 C -178.48432,848.06183 -179.07244,847.80651 -179.41053,847.50364 C -179.88596,847.07752 -180.12367,846.55807 -180.12367,845.94528 C -180.12367,845.55086 -180.01274,845.18284 -179.79087,844.84123 C -179.56548,844.49611 -179.24325,844.23374 -178.82416,844.05413 C -178.40156,843.87453 -177.89267,843.78473 -177.2975,843.78472 C -176.32552,843.78473 -175.59476,843.99779 -175.10524,844.42391 C -174.61221,844.85004 -174.35336,845.4188 -174.32871,846.13017 L -175.89234,846.19887 C -175.95924,845.80092 -176.10365,845.51566 -176.32551,845.34309 C -176.54386,845.16701 -176.87314,845.07897 -177.31335,845.07897 C -177.76765,845.07897 -178.12335,845.17227 -178.38043,845.35894 C -178.54595,845.47868 -178.62871,845.63892 -178.62871,845.83965 C -178.62871,846.02279 -178.55121,846.1795 -178.39627,846.3098 C -178.19906,846.47533 -177.72011,846.64789 -176.95942,846.82749 C -176.19874,847.0071 -175.63702,847.19375 -175.27428,847.38744 C -174.90803,847.57762 -174.62277,847.83999 -174.41851,848.17454 C -174.21074,848.50559 -174.10685,848.91586 -174.10684,849.40538 C -174.10685,849.84912 -174.23011,850.26468 -174.47662,850.65206 C -174.72314,851.03945 -175.07179,851.32823 -175.52256,851.5184 C -175.97335,851.70505 -176.53506,851.79838 -177.2077,851.79838 C -178.18674,851.79838 -178.93862,851.57299 -179.46335,851.12221 C -179.98809,850.66791 -180.30152,850.00759 -180.40365,849.14125" /> + d="M -167.82588,848.81371 L -166.30979,849.29443 C -166.54222,850.13964 -166.92961,850.76826 -167.47195,851.1803 C -168.01077,851.58882 -168.69574,851.79307 -169.52686,851.79307 C -170.5552,851.79307 -171.40041,851.44267 -172.06249,850.74185 C -172.72457,850.03751 -173.05561,849.07608 -173.05561,847.85757 C -173.05561,846.56863 -172.72281,845.56847 -172.05721,844.85708 C -171.39161,844.14218 -170.51646,843.78473 -169.43178,843.78472 C -168.48444,843.78473 -167.71495,844.0647 -167.1233,844.62465 C -166.77114,844.95569 -166.50701,845.43112 -166.33092,846.05094 L -167.8787,846.42071 C -167.9703,846.01925 -168.16221,845.70229 -168.4545,845.46985 C -168.74329,845.23743 -169.09546,845.12121 -169.51101,845.12121 C -170.08506,845.12121 -170.55168,845.32723 -170.91089,845.73926 C -171.26659,846.15131 -171.44443,846.81867 -171.44443,847.74135 C -171.44443,848.72039 -171.26835,849.41769 -170.91617,849.83325 C -170.56401,850.24881 -170.10619,850.45659 -169.54271,850.45659 C -169.12715,850.45659 -168.7697,850.32453 -168.47035,850.0604 C -168.17101,849.79627 -167.95619,849.38071 -167.82588,848.81371" /> + d="M -164.92047,851.66101 L -164.92047,843.98017 L -163.35684,843.98017 L -163.35684,850.35622 L -159.46887,850.35622 L -159.46887,851.66101 L -164.92047,851.66101" /> + points="233.13,492.937 251.619,492.937 251.619,485.734 242.74,485.734 242.74,480.095 251.619,480.095 251.619,473.728 242.74,473.728 242.74,467.777 251.619,467.777 251.619,467.777 251.619,460.783 233.13,460.783 " /> + points="220.283,364.946 220.283,364.946 253.082,364.946 253.082,454.937 220.283,454.937 " /> + points="225.505,370.688 225.505,370.688 225.505,449.298 247.754,449.298 247.754,370.688 " /> @@ -28211,17 +36521,17 @@ id="revo-ms4525-speed-sensor"> @@ -28284,14 +36594,14 @@ @@ -28575,25 +36885,25 @@ sodipodi:nodetypes="ccccc" style="fill:none;stroke:#000000;stroke-width:6.11999989;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" inkscape:connector-curvature="0" - d="m 270.62655,463.51435 l -43.33899,0 l 0,-108.45645 l 268.26296,0 l 0,-35.35396" + d="M 270.62655,463.51435 L 227.28756,463.51435 L 227.28756,355.0579 L 495.55052,355.0579 L 495.55052,319.70394" id="path8856-1-5-7-7-6-2-4-1" /> + points="251.619,467.777 251.619,460.783 233.13,460.783 233.13,492.937 251.619,492.937 251.619,485.734 242.74,485.734 242.74,480.095 251.619,480.095 251.619,473.728 242.74,473.728 242.74,467.777 251.619,467.777 " /> + points="220.283,454.937 220.283,364.946 220.283,364.946 253.082,364.946 253.082,454.937 " /> + points="247.754,370.688 225.505,370.688 225.505,370.688 225.505,449.298 247.754,449.298 " /> @@ -28677,17 +36987,17 @@ style="display:inline;fill:#ec6004;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" transform="translate(-68.822223,-0.49726981)"> @@ -28697,17 +37007,17 @@ style="display:inline;fill:#d81900;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" transform="translate(-68.822223,-0.49726981)"> @@ -28719,15 +37029,15 @@ + d="M -180.40365,849.14123 L -178.88227,848.99332 C -178.79067,849.50397 -178.60582,849.87903 -178.3276,850.1185 C -178.04587,850.35798 -177.66729,850.47772 -177.19185,850.47772 C -176.68825,850.47772 -176.30967,850.37207 -176.0561,850.16076 C -175.79902,849.94594 -175.67048,849.6959 -175.67048,849.41064 C -175.67048,849.22752 -175.72508,849.07256 -175.83423,848.94578 C -175.93989,848.81548 -176.12654,848.70278 -176.39419,848.60769 C -176.57732,848.54429 -176.99464,848.43161 -177.64615,848.26961 C -178.48432,848.06183 -179.07244,847.80651 -179.41053,847.50364 C -179.88596,847.07752 -180.12367,846.55807 -180.12367,845.94528 C -180.12367,845.55086 -180.01274,845.18284 -179.79087,844.84123 C -179.56548,844.49611 -179.24325,844.23374 -178.82416,844.05413 C -178.40156,843.87453 -177.89267,843.78473 -177.2975,843.78472 C -176.32552,843.78473 -175.59476,843.99779 -175.10524,844.42391 C -174.61221,844.85004 -174.35336,845.4188 -174.32871,846.13017 L -175.89234,846.19887 C -175.95924,845.80092 -176.10365,845.51566 -176.32551,845.34309 C -176.54386,845.16701 -176.87314,845.07897 -177.31335,845.07897 C -177.76765,845.07897 -178.12335,845.17227 -178.38043,845.35894 C -178.54595,845.47868 -178.62871,845.63892 -178.62871,845.83965 C -178.62871,846.02279 -178.55121,846.1795 -178.39627,846.3098 C -178.19906,846.47533 -177.72011,846.64789 -176.95942,846.82749 C -176.19874,847.0071 -175.63702,847.19375 -175.27428,847.38744 C -174.90803,847.57762 -174.62277,847.83999 -174.41851,848.17454 C -174.21074,848.50559 -174.10685,848.91586 -174.10684,849.40538 C -174.10685,849.84912 -174.23011,850.26468 -174.47662,850.65206 C -174.72314,851.03945 -175.07179,851.32823 -175.52256,851.5184 C -175.97335,851.70505 -176.53506,851.79838 -177.2077,851.79838 C -178.18674,851.79838 -178.93862,851.57299 -179.46335,851.12221 C -179.98809,850.66791 -180.30152,850.00759 -180.40365,849.14125" /> + d="M -167.82588,848.81371 L -166.30979,849.29443 C -166.54222,850.13964 -166.92961,850.76826 -167.47195,851.1803 C -168.01077,851.58882 -168.69574,851.79307 -169.52686,851.79307 C -170.5552,851.79307 -171.40041,851.44267 -172.06249,850.74185 C -172.72457,850.03751 -173.05561,849.07608 -173.05561,847.85757 C -173.05561,846.56863 -172.72281,845.56847 -172.05721,844.85708 C -171.39161,844.14218 -170.51646,843.78473 -169.43178,843.78472 C -168.48444,843.78473 -167.71495,844.0647 -167.1233,844.62465 C -166.77114,844.95569 -166.50701,845.43112 -166.33092,846.05094 L -167.8787,846.42071 C -167.9703,846.01925 -168.16221,845.70229 -168.4545,845.46985 C -168.74329,845.23743 -169.09546,845.12121 -169.51101,845.12121 C -170.08506,845.12121 -170.55168,845.32723 -170.91089,845.73926 C -171.26659,846.15131 -171.44443,846.81867 -171.44443,847.74135 C -171.44443,848.72039 -171.26835,849.41769 -170.91617,849.83325 C -170.56401,850.24881 -170.10619,850.45659 -169.54271,850.45659 C -169.12715,850.45659 -168.7697,850.32453 -168.47035,850.0604 C -168.17101,849.79627 -167.95619,849.38071 -167.82588,848.81371" /> + d="M -164.92047,851.66101 L -164.92047,843.98017 L -163.35684,843.98017 L -163.35684,850.35622 L -159.46887,850.35622 L -159.46887,851.66101 L -164.92047,851.66101" /> @@ -28745,18 +37055,18 @@ @@ -28766,20 +37076,20 @@ transform="matrix(0.77129601,0,0,0.77129601,-4.0324,109.23554)"> @@ -28789,18 +37099,18 @@ @@ -28810,20 +37120,20 @@ id="g6537-9"> @@ -28858,43 +37168,43 @@ sodipodi:nodetypes="ccccccc" inkscape:connector-curvature="0" id="path3855-7-3" - d="m 242.67052,512.5492 l -3.63361,19.50674 l 0.95621,3.44237 l 7.07598,-6.11976 l 2.10367,-13.57823 l -3.82485,-2.86863 z" + d="M 242.67052,512.5492 L 239.03691,532.05594 L 239.99312,535.49831 L 247.0691,529.37855 L 249.17277,515.80032 L 245.34792,512.93169 Z" style="fill:#df181b;fill-opacity:1;stroke:#000000;stroke-width:0.77129602px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> @@ -29671,12 +37981,12 @@ @@ -29684,25 +37994,25 @@ sodipodi:nodetypes="ccccc" style="fill:none;stroke:#000000;stroke-width:6.11999989;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" inkscape:connector-curvature="0" - d="m 176.01073,513.67503 l -117.9746,-0.34878 l -0.23664,-141.0474 l 438.23665,-1.0474 l -0.23664,-48.09479" + d="M 176.01073,513.67503 L 58.03613,513.32625 L 57.79949,372.27885 L 496.03614,371.23145 L 495.7995,323.13666" id="path8856-1-5-7-7-6-2-4-1-7-0-8" /> @@ -29757,17 +38067,17 @@ style="display:inline;fill:#ec6004;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" transform="translate(-170.54362,3.598122)"> @@ -29777,17 +38087,17 @@ style="display:inline;fill:#d81900;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" transform="translate(-170.54362,33.098117)"> @@ -29799,15 +38109,15 @@ + d="M -180.40365,849.14123 L -178.88227,848.99332 C -178.79067,849.50397 -178.60582,849.87903 -178.3276,850.1185 C -178.04587,850.35798 -177.66729,850.47772 -177.19185,850.47772 C -176.68825,850.47772 -176.30967,850.37207 -176.0561,850.16076 C -175.79902,849.94594 -175.67048,849.6959 -175.67048,849.41064 C -175.67048,849.22752 -175.72508,849.07256 -175.83423,848.94578 C -175.93989,848.81548 -176.12654,848.70278 -176.39419,848.60769 C -176.57732,848.54429 -176.99464,848.43161 -177.64615,848.26961 C -178.48432,848.06183 -179.07244,847.80651 -179.41053,847.50364 C -179.88596,847.07752 -180.12367,846.55807 -180.12367,845.94528 C -180.12367,845.55086 -180.01274,845.18284 -179.79087,844.84123 C -179.56548,844.49611 -179.24325,844.23374 -178.82416,844.05413 C -178.40156,843.87453 -177.89267,843.78473 -177.2975,843.78472 C -176.32552,843.78473 -175.59476,843.99779 -175.10524,844.42391 C -174.61221,844.85004 -174.35336,845.4188 -174.32871,846.13017 L -175.89234,846.19887 C -175.95924,845.80092 -176.10365,845.51566 -176.32551,845.34309 C -176.54386,845.16701 -176.87314,845.07897 -177.31335,845.07897 C -177.76765,845.07897 -178.12335,845.17227 -178.38043,845.35894 C -178.54595,845.47868 -178.62871,845.63892 -178.62871,845.83965 C -178.62871,846.02279 -178.55121,846.1795 -178.39627,846.3098 C -178.19906,846.47533 -177.72011,846.64789 -176.95942,846.82749 C -176.19874,847.0071 -175.63702,847.19375 -175.27428,847.38744 C -174.90803,847.57762 -174.62277,847.83999 -174.41851,848.17454 C -174.21074,848.50559 -174.10685,848.91586 -174.10684,849.40538 C -174.10685,849.84912 -174.23011,850.26468 -174.47662,850.65206 C -174.72314,851.03945 -175.07179,851.32823 -175.52256,851.5184 C -175.97335,851.70505 -176.53506,851.79838 -177.2077,851.79838 C -178.18674,851.79838 -178.93862,851.57299 -179.46335,851.12221 C -179.98809,850.66791 -180.30152,850.00759 -180.40365,849.14125" /> + d="M -167.82588,848.81371 L -166.30979,849.29443 C -166.54222,850.13964 -166.92961,850.76826 -167.47195,851.1803 C -168.01077,851.58882 -168.69574,851.79307 -169.52686,851.79307 C -170.5552,851.79307 -171.40041,851.44267 -172.06249,850.74185 C -172.72457,850.03751 -173.05561,849.07608 -173.05561,847.85757 C -173.05561,846.56863 -172.72281,845.56847 -172.05721,844.85708 C -171.39161,844.14218 -170.51646,843.78473 -169.43178,843.78472 C -168.48444,843.78473 -167.71495,844.0647 -167.1233,844.62465 C -166.77114,844.95569 -166.50701,845.43112 -166.33092,846.05094 L -167.8787,846.42071 C -167.9703,846.01925 -168.16221,845.70229 -168.4545,845.46985 C -168.74329,845.23743 -169.09546,845.12121 -169.51101,845.12121 C -170.08506,845.12121 -170.55168,845.32723 -170.91089,845.73926 C -171.26659,846.15131 -171.44443,846.81867 -171.44443,847.74135 C -171.44443,848.72039 -171.26835,849.41769 -170.91617,849.83325 C -170.56401,850.24881 -170.10619,850.45659 -169.54271,850.45659 C -169.12715,850.45659 -168.7697,850.32453 -168.47035,850.0604 C -168.17101,849.79627 -167.95619,849.38071 -167.82588,848.81371" /> + d="M -164.92047,851.66101 L -164.92047,843.98017 L -163.35684,843.98017 L -163.35684,850.35622 L -159.46887,850.35622 L -159.46887,851.66101 L -164.92047,851.66101" /> + points="233.13,492.937 251.619,492.937 251.619,485.734 242.74,485.734 242.74,480.095 251.619,480.095 251.619,473.728 242.74,473.728 242.74,467.777 251.619,467.777 251.619,467.777 251.619,460.783 233.13,460.783 " /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -33368,7 +49083,7 @@ + d="M 399.52159,854.64741 C 399.52159,855.82348 398.54605,856.77798 397.34404,856.77798 L 368.00816,856.77798 C 366.80616,856.77798 365.83062,855.82348 365.83062,854.64741 L 368.00816,853.21887 L 365.83062,850.95515 L 365.83062,817.93144 L 368.00816,815.4014 L 365.83062,814.02931 C 365.83062,812.85324 366.80616,811.89875 368.00816,811.89875 L 397.34513,811.89875 C 398.54713,811.89875 399.52267,812.85324 399.52267,814.02931 L 399.52267,854.64741 Z" /> @@ -33793,7 +49508,7 @@ + d="M 481.28621,675.07193 L 481.89919,676.91913 C 486.0583,675.4011 484.75177,668.65148 479.64107,670.096 C 484.01903,669.62089 484.08762,674.75874 481.28621,675.07193 Z" /> + d="M 479.90129,671.06754 L 479.28831,669.22034 C 475.1292,670.73837 476.43573,677.48799 481.54751,676.04347 C 477.16956,676.51858 477.10097,671.38073 479.90129,671.06754 Z" /> + d="M 468.75771,677.71276 L 467.02656,677.71276 L 465.41409,674.45833 L 465.24206,674.45833 L 465.24206,676.67731 L 463.66334,676.67731 L 463.66334,669.47494 C 464.07816,669.46494 465.06023,669.31728 465.52623,669.31728 C 466.00202,669.31728 466.55947,669.33748 467.04616,669.5836 C 467.84531,669.97989 468.28082,670.81294 468.22965,672.30859 C 468.1284,673.52727 467.68309,674.11105 467.00478,674.34967 L 468.75771,677.71276 Z M 466.64984,671.9709 C 466.64984,671.3573 466.42664,670.69363 465.75814,670.69363 C 465.58611,670.69363 465.39558,670.71283 465.24206,670.74263 L 465.24206,673.278 C 466.21324,673.63593 466.64984,672.8636 466.64984,671.9709 Z" /> + d="M 468.44196,676.67731 L 468.44196,669.47494 L 471.76272,669.47494 L 471.76272,670.83211 L 470.06205,670.83211 L 470.06205,672.40766 L 471.68215,672.40766 L 471.68215,673.69559 L 470.06205,673.69559 L 470.06205,675.27114 L 471.76272,675.27114 L 471.76272,676.67731 L 468.44196,676.67731 Z" /> + d="M 474.48574,674.46792 L 475.2555,669.47494 L 476.94636,669.47494 L 475.41773,676.67731 L 473.4035,676.67731 L 471.86397,669.47494 L 473.56464,669.47494 L 474.33549,674.46792 L 474.41609,675.07193 L 474.48579,674.46792 Z" /> + d="M 484.72564,676.67731 L 484.72564,669.47494 L 486.32505,669.47494 L 486.32505,675.27007 L 488.11717,675.27007 L 488.11717,676.67624 L 484.72564,676.67624 Z" /> + d="M 488.28919,674.69589 L 488.28919,669.47494 L 489.9082,669.47494 L 489.9082,674.6064 C 489.9182,675.09217 489.9496,675.4778 490.61699,675.4778 C 491.2844,675.4778 491.31598,675.09217 491.32578,674.6064 L 491.32578,669.47494 L 492.94478,669.47494 L 492.94478,674.69589 C 492.94478,676.16171 492.11405,676.8158 490.6159,676.8158 C 489.13952,676.8158 488.28919,676.16171 488.28919,674.69589 Z" /> + d="M 493.14947,670.83211 L 493.26053,669.47494 L 497.56335,669.47494 L 497.6951,670.83211 L 496.2884,670.83211 L 496.2884,676.67731 L 494.62802,676.67731 L 494.62802,670.83211 L 493.14947,670.83211 Z" /> + d="M 497.927,669.47494 L 499.57867,669.47494 L 499.57867,676.67731 L 497.927,676.67731 L 497.927,669.47494 Z" /> + d="M 499.85086,673.05109 C 499.85086,671.24864 500.54006,669.27787 502.68603,669.28745 C 504.8222,669.27745 505.51139,671.24864 505.50159,673.05109 C 505.50159,674.87379 504.85377,676.82538 502.68603,676.8158 C 500.50957,676.8258 499.87264,674.87379 499.85086,673.05109 Z M 501.55262,673.07129 C 501.55262,674.062 501.75513,675.48842 502.68603,675.52783 C 503.60822,675.48733 503.80964,674.062 503.80964,673.07129 C 503.80964,672.09017 503.60713,670.82248 502.68603,670.76283 C 501.75404,670.82253 501.55262,672.09017 501.55262,673.07129 Z" /> + d="M 505.7531,676.67731 L 505.7531,669.47494 L 507.1206,669.47494 L 508.66992,673.01168 L 508.66992,669.47494 L 510.23013,669.47494 L 510.23013,676.67731 L 508.93449,676.67731 L 507.33509,673.15016 L 507.33509,676.67731 L 505.7531,676.67731 Z" /> + d="M 1286.1956,653.36166 C 1286.1956,653.78235 1286.0277,654.13224 1285.692,654.41134 C 1285.3764,654.68236 1285.0043,654.81787 1284.5755,654.81786 C 1284.1427,654.81786 1283.7746,654.68438 1283.4712,654.41741 L 1281.4568,660.01166 C 1281.2667,660.54965 1280.937,660.81864 1280.4678,660.81864 C 1279.8368,660.81864 1279.4626,660.5456 1279.3453,659.99953 L 1278.3381,655.22439 L 1276.9729,659.26536 C 1276.8314,659.68604 1276.5603,660.02178 1276.1599,660.27256 C 1275.7837,660.51122 1275.3671,660.63055 1274.91,660.63055 L 1272.0279,660.63055 C 1272.2059,660.1856 1272.3576,659.87211 1272.483,659.69008 C 1272.7216,659.33817 1273.0007,659.16221 1273.3203,659.16221 C 1273.5144,659.16221 1273.8077,659.20471 1274.2001,659.28963 C 1274.5965,659.37053 1274.8958,659.41098 1275.0981,659.41098 C 1275.5228,659.41098 1275.8241,659.15007 1276.0021,658.62827 L 1277.8709,653.20997 C 1278.0287,652.74076 1278.1642,652.43941 1278.2775,652.30591 C 1278.4676,652.06322 1278.7669,651.94187 1279.1754,651.94186 C 1279.7862,651.94186 1280.1786,652.37266 1280.3525,653.23424 L 1281.1838,657.38443 L 1282.4398,653.85919 C 1282.9049,652.55671 1283.6128,651.90546 1284.5634,651.90545 C 1284.9922,651.90545 1285.3663,652.03895 1285.6859,652.30591 C 1286.0257,652.58907 1286.1956,652.94099 1286.1956,653.36166" /> + d="M 1291.7352,659.65974 C 1291.541,660.30695 1291.0455,660.63055 1290.2487,660.63055 L 1287.9491,660.63055 C 1287.2938,660.63055 1286.9661,660.42021 1286.9661,659.99953 C 1286.5252,660.50111 1285.9832,660.7519 1285.34,660.7519 C 1284.8668,660.7519 1284.4825,660.60628 1284.1872,660.31504 C 1283.8919,660.0238 1283.7443,659.64357 1283.7443,659.17434 C 1283.7443,658.32894 1284.0679,657.66151 1284.7151,657.17206 C 1285.3016,656.72712 1286.0277,656.50464 1286.8933,656.50464 L 1290.3579,656.50464 L 1289.2172,659.65974 L 1291.7352,659.65974 M 1287.8217,657.47544 L 1286.4807,657.47544 L 1286.056,658.88917 C 1286.032,658.97817 1286.02,659.05906 1286.02,659.13187 C 1286.02,659.48379 1286.3638,659.65974 1287.0515,659.65974 L 1287.8221,657.47544" /> + d="M 1300.0477,659.65974 C 1299.9425,660.01571 1299.7099,660.27863 1299.3499,660.44852 C 1299.0951,660.56987 1298.8221,660.63055 1298.5308,660.63055 L 1296.1099,660.63055 C 1295.5557,660.63055 1295.2786,660.44852 1295.2786,660.08447 C 1295.2786,659.96312 1295.3066,659.82155 1295.3636,659.65974 L 1295.8247,658.35523 L 1293.7375,660.12088 C 1293.248,660.46066 1292.8456,660.63055 1292.5301,660.63055 L 1291.4136,660.63055 L 1292.8638,656.50464 L 1295.0541,656.50464 L 1294.3685,658.44624 L 1296.2191,656.92936 C 1296.7207,656.52082 1297.2647,656.32464 1297.8513,656.34081 C 1298.2477,656.35701 1298.4459,656.56734 1298.4459,656.97183 C 1298.4459,657.1215 1298.4139,657.28937 1298.3489,657.47544 L 1297.5662,659.65974 L 1300.0478,659.65974" /> + d="M 1310.314,656.50464 C 1310.1521,657.15184 1309.6667,657.47544 1308.8578,657.47544 L 1305.0595,657.47544 C 1305.193,657.56444 1305.3022,657.72825 1305.3871,657.96691 C 1305.4721,658.20152 1305.5065,658.4058 1305.4903,658.57973 C 1305.4333,659.25525 1305.1363,659.78514 1304.5984,660.16942 C 1304.0846,660.53751 1303.4172,660.72358 1302.5961,660.72763 C 1301.6414,660.73563 1300.9073,660.54762 1300.3936,660.16335 C 1299.9365,659.82357 1299.7079,659.3766 1299.7079,658.82243 C 1299.7079,658.71322 1299.7179,658.604 1299.7379,658.49478 C 1299.843,657.88399 1300.1464,657.40465 1300.648,657.05678 C 1301.1819,656.68869 1301.8939,656.50464 1302.7838,656.50464 L 1310.3136,656.50464 M 1303.7,657.47544 L 1302.3105,657.47544 L 1301.7644,659.02873 C 1301.7364,659.10963 1301.7214,659.18648 1301.7214,659.25929 C 1301.7214,659.60716 1302.045,659.7811 1302.6923,659.7811 C 1302.7693,659.7811 1302.8358,659.7791 1302.8925,659.7751 L 1303.6995,657.47551" /> @@ -34696,19 +50411,19 @@ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:12px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none" id="text15590"> @@ -34727,7 +50442,7 @@ transform="translate(-1.2734354,-1.2734429)"> @@ -37311,7 +53026,7 @@ inkscape:groupmode="layer" id="layer58" inkscape:label="cc3d" - style="display:inline" + style="display:none" sodipodi:insensitive="true"> @@ -37333,13 +53048,13 @@ transform="matrix(1.0887723,0,0,1.065281,181.87665,-41.172881)"> @@ -37423,12 +53138,12 @@ @@ -39003,27 +54718,27 @@ id="g14221"> @@ -40552,15 +56267,15 @@ id="text18022"> diff --git a/ground/gcs/src/plugins/setupwizard/resources/not-connected.png b/ground/gcs/src/plugins/setupwizard/resources/not-connected.png index f816c0f0f..730a2cbd7 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/not-connected.png and b/ground/gcs/src/plugins/setupwizard/resources/not-connected.png differ diff --git a/ground/gcs/src/plugins/setupwizard/resources/sensor-shapes.svg b/ground/gcs/src/plugins/setupwizard/resources/sensor-shapes.svg index 6754e0cd2..f02908020 100644 --- a/ground/gcs/src/plugins/setupwizard/resources/sensor-shapes.svg +++ b/ground/gcs/src/plugins/setupwizard/resources/sensor-shapes.svg @@ -10,7 +10,7 @@ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="786.15344" + width="1470.7812" height="1201.2025" id="svg2" version="1.1" @@ -1269,6 +1269,70 @@ x2="451.91052" y2="440.24432" gradientUnits="userSpaceOnUse" /> + + + + + + + + + originx="-0.0155294" + originy="1006.9986" /> @@ -1341,7 +1405,7 @@ id="layer2" inkscape:label="Eagle_speed_sensor" style="display:inline" - transform="translate(-154.96554,-355.98347)"> + transform="translate(-159.51554,-355.98347)"> + d="M 236.04807,500.42627 L 179.51554,500.42627" + style="fill:none;stroke:#545253;stroke-width:9.10000038;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + d="M 236.04807,504.14551 L 179.51554,504.14551" + style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> @@ -1370,22 +1434,22 @@ id="g6553" transform="translate(0,-50)"> + d="M 236.04807,496.88936 L 179.51554,496.88936" + style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + d="M 236.04807,500.42627 L 179.51554,500.42627" + style="fill:none;stroke:#545253;stroke-width:9.10000038;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + d="M 236.04807,504.14551 L 179.51554,504.14551" + style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> @@ -1413,22 +1477,22 @@ + d="M 236.04807,496.88936 L 179.51554,496.88936" + style="fill:none;stroke:#6c6b6f;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:url(#linearGradient6623);fill-opacity:1;fill-rule:evenodd;stroke:#222223;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:url(#linearGradient6609);fill-opacity:1;stroke:#222223;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + d="M 331.50868,437.44706 L 336.71562,444.38965 L 362.50238,444.38965 L 370.43677,437.44706 L 370.93267,434.47166 L 332.00458,434.71961 Z" + style="fill:#df181b;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - + style="fill:#343535;fill-opacity:1;stroke:#222223;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + cx="374.15601" + cy="501.66602" + rx="5.4548922" + ry="5.2069426" /> + style="fill:#18181b;fill-opacity:1;fill-rule:evenodd;stroke:#171600;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:#2f3430;fill-opacity:1;fill-rule:evenodd;stroke:#171600;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:#949697;fill-opacity:1;fill-rule:evenodd;stroke:#171600;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:#18181b;fill-opacity:1;fill-rule:evenodd;stroke:#171600;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="opacity:0.87969923;fill:#2f3430;fill-opacity:1;fill-rule:evenodd;stroke:#171600;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:#949697;fill-opacity:1;fill-rule:evenodd;stroke:#171600;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> @@ -2276,12 +2338,12 @@ @@ -2292,7 +2354,7 @@ id="layer1" inkscape:label="MS4525-speed-sensor" style="display:inline" - transform="translate(4.5344706,8.3915228)"> + transform="translate(-0.0155294,8.3915228)"> @@ -2300,32 +2362,32 @@ id="g13998"> @@ -2352,7 +2414,7 @@ width="15.304846" y="-477.83289" x="149.4836" - style="fill:#e9dcdc;display:inline" + style="display:inline;fill:#e9dcdc" inkscape:transform-center-x="-52.764729" inkscape:transform-center-y="43.141303" /> @@ -2408,7 +2470,7 @@ height="127.94168" width="102.65967" id="rect4057" - style="opacity:0.87969923;fill:#0f62a8;fill-opacity:1;stroke:#6c6b6f;stroke-width:1.56537998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" /> + style="opacity:0.87969923;fill:#0f62a8;fill-opacity:1;stroke:#6c6b6f;stroke-width:1.56537998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:url(#linearGradient4376);fill-opacity:1;stroke:#3d3d3e;stroke-width:0.73051065;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:#a6acb0;fill-opacity:1;fill-rule:evenodd;stroke:#6a6c6c;stroke-width:1.56537998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:#a6acb0;fill-opacity:1;fill-rule:evenodd;stroke:#6a6c6c;stroke-width:1.56537998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:#a6acb0;fill-opacity:1;fill-rule:evenodd;stroke:#6a6c6c;stroke-width:1.56537998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:#a6acb0;fill-opacity:1;fill-rule:evenodd;stroke:#6a6c6c;stroke-width:1.56537998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> MS4525 + transform="translate(-4.55,3.9702315e-6)"> @@ -2685,21 +2747,21 @@ + style="fill:#1e1b1c;fill-opacity:1;stroke:#1e1b1c;stroke-width:1.10000002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter5841)" + d="M 195.67181,288.61495 C 195.8796,288.64395 196.17105,288.71435 196.31947,288.77148 C 196.46789,288.82868 196.76966,288.91067 196.99007,288.95377 C 197.21871,288.99847 197.47366,289.089 197.58376,289.16455 C 197.68987,289.23735 197.91414,289.34796 198.08212,289.41025 C 198.2501,289.47255 198.41848,289.56082 198.45631,289.6064 C 198.49411,289.652 198.62385,289.73927 198.74457,289.80039 C 199.02753,289.94365 199.80204,290.62695 200.16218,291.05105 C 200.31652,291.23278 200.52232,291.4717 200.61954,291.58199 C 200.71674,291.69227 200.82683,291.87069 200.86414,291.97848 C 200.90144,292.08627 201.00157,292.25371 201.0866,292.35057 C 201.1716,292.44747 201.27072,292.64545 201.30678,292.79063 C 201.34278,292.93581 201.43226,293.14186 201.50548,293.24852 C 201.59918,293.38496 201.6694,293.61699 201.74241,294.03112 C 201.79951,294.35488 201.88299,294.81407 201.92795,295.05154 C 202.06196,295.75928 202.04781,295.95528 201.74528,297.58329 C 201.67898,297.9403 201.58504,298.25898 201.50673,298.39286 C 201.43573,298.51431 201.34133,298.7351 201.29702,298.88353 C 201.25272,299.03195 201.13469,299.27757 201.03476,299.42934 C 200.93486,299.58112 200.81028,299.77542 200.75798,299.86112 C 200.51045,300.26667 200.38325,300.41946 199.86988,300.92797 C 199.18363,301.60772 198.98167,301.7749 198.63685,301.9487 C 198.48656,302.0244 198.33291,302.12341 198.29538,302.16863 C 198.25788,302.21383 198.10151,302.29125 197.94795,302.34065 C 197.7944,302.39005 197.58333,302.48792 197.47892,302.55813 C 197.36716,302.63333 197.07859,302.72943 196.77728,302.79189 C 196.49581,302.85029 196.15716,302.93659 196.02475,302.98377 C 195.37999,303.21352 193.8026,303.17528 193.15254,302.91417 C 193.07304,302.88227 192.80641,302.81787 192.56001,302.77112 C 192.28276,302.71852 192.03904,302.63558 191.92058,302.55349 C 191.81531,302.48059 191.61991,302.38796 191.48636,302.34777 C 191.35281,302.30757 191.1269,302.18566 190.98434,302.07684 C 190.84178,301.96802 190.69958,301.87899 190.66835,301.87899 C 190.63715,301.87899 190.5196,301.80009 190.4072,301.70358 C 190.2948,301.60708 190.00533,301.35816 189.76394,301.15037 C 189.52254,300.94258 189.2508,300.6572 189.16005,300.5162 C 189.06935,300.3752 188.97529,300.25984 188.95112,300.25984 C 188.92702,300.25984 188.85272,300.16874 188.78624,300.05745 C 188.71974,299.94613 188.6094,299.79399 188.54106,299.71936 C 188.47276,299.64476 188.37846,299.47472 188.33155,299.34155 C 188.28465,299.2084 188.18804,299.01445 188.11684,298.91055 C 188.04564,298.80666 187.95782,298.60021 187.92168,298.45179 C 187.88548,298.30337 187.78486,298.00276 187.69796,297.78376 C 187.48279,297.24147 187.40391,296.27546 187.48224,295.14172 C 187.52894,294.4666 187.56104,294.28227 187.67803,294.0182 C 187.75503,293.84445 187.85206,293.53662 187.89366,293.33412 C 187.93876,293.11443 188.01609,292.91614 188.08534,292.84243 C 188.14914,292.77453 188.25077,292.58801 188.31114,292.42802 C 188.37154,292.26802 188.47578,292.0764 188.54286,292.00219 C 188.60996,291.92799 188.72895,291.75462 188.80732,291.61694 C 188.94819,291.36948 189.86374,290.41361 190.28787,290.07119 C 190.4084,289.97389 190.58831,289.85449 190.68768,289.80588 C 190.78708,289.75728 190.93417,289.66318 191.01463,289.59679 C 191.09513,289.53039 191.27724,289.43252 191.41942,289.37928 C 191.56159,289.32608 191.76387,289.22667 191.86892,289.15847 C 191.97398,289.09027 192.27756,288.98753 192.54356,288.93015 C 192.80956,288.87285 193.12435,288.78379 193.24309,288.73243 C 193.63663,288.56217 194.86572,288.50273 195.67181,288.61498 Z M 201.19869,271.14147 C 201.06225,271.21257 200.91345,271.32744 200.86802,271.39677 C 200.82252,271.46607 200.70349,271.60821 200.60336,271.71255 C 200.3024,272.02617 199.66718,272.74048 199.38801,273.07921 C 198.74852,273.85515 197.84779,274.88195 196.9962,275.8058 C 196.77471,276.04608 196.57002,276.28512 196.54132,276.33701 C 196.51262,276.38891 196.30156,276.64099 196.07231,276.89721 C 195.84304,277.15343 195.62822,277.41396 195.59494,277.47616 C 195.56164,277.53846 195.48032,277.61935 195.41421,277.65613 C 195.29709,277.72133 195.15339,277.73973 193.86376,277.85515 C 193.52239,277.88565 193.16461,277.93425 193.06869,277.96305 C 192.97279,277.99185 192.53559,278.03135 192.0972,278.05095 L 191.30011,278.08655 L 190.99765,277.85266 C 190.6063,277.55004 190.29347,277.29094 190.01358,277.03761 C 189.57276,276.63862 189.11196,276.25313 188.54699,275.81072 C 188.3764,275.67714 188.1003,275.45049 187.93344,275.30705 C 187.76657,275.16362 187.53289,274.96306 187.41415,274.86138 C 187.29542,274.75971 187.11327,274.60292 187.00937,274.51298 C 186.81091,274.34117 186.48703,274.0747 185.92994,273.62487 C 185.38183,273.1823 185.04908,272.90169 184.87749,272.73736 C 184.78839,272.65206 184.60891,272.52924 184.47853,272.46442 L 184.2415,272.34653 L 183.93882,272.49275 C 183.77235,272.57315 183.58727,272.68353 183.52753,272.73799 C 183.46773,272.79239 183.29779,272.88961 183.14972,272.9539 C 183.00168,273.0182 182.81948,273.12774 182.74485,273.19732 C 182.67025,273.26692 182.50354,273.36109 182.37445,273.40664 C 182.24536,273.45214 182.05664,273.56242 181.95506,273.65161 C 181.85348,273.74081 181.73972,273.81377 181.70225,273.81377 C 181.66475,273.81377 181.46774,273.92306 181.26435,274.05664 C 181.06098,274.19022 180.86259,274.29951 180.8235,274.29951 C 180.7844,274.29951 180.66931,274.37251 180.56773,274.46168 C 180.46615,274.55088 180.28251,274.6593 180.15966,274.70265 C 180.03681,274.74595 179.80334,274.89624 179.64084,275.03652 C 179.29182,275.33786 179.28218,275.39791 179.47883,276.04579 C 179.55223,276.28755 179.64986,276.81324 179.6958,277.21398 C 179.7418,277.61472 179.83907,278.14903 179.9121,278.40135 C 179.9851,278.65367 180.0823,279.18799 180.12802,279.58873 C 180.17372,279.98946 180.27067,280.52596 180.34345,280.78095 C 180.41625,281.03593 180.51335,281.57025 180.55931,281.96833 C 180.60531,282.36639 180.70196,282.89854 180.77419,283.15086 C 181.01285,283.9846 181.01577,283.94617 180.66967,284.52617 C 180.50108,284.8087 180.34445,285.03986 180.32161,285.03986 C 180.29871,285.03986 180.21569,285.15816 180.13698,285.30277 C 180.05828,285.44736 179.95538,285.59763 179.90832,285.6367 C 179.86122,285.6758 179.76631,285.81854 179.69735,285.95399 C 179.62835,286.08943 179.50885,286.25912 179.43171,286.33109 C 179.35451,286.40309 179.29143,286.49152 179.29143,286.52767 C 179.29143,286.65792 178.67496,287.41313 178.50141,287.49547 C 178.40501,287.54117 178.04289,287.61581 177.69674,287.6612 C 177.3506,287.7066 176.87774,287.80365 176.64594,287.87687 C 176.41415,287.95007 175.94055,288.04725 175.5935,288.09276 C 175.24644,288.13826 174.77027,288.23624 174.53531,288.31046 C 174.30036,288.38466 173.82711,288.48027 173.48363,288.52288 C 173.14016,288.56548 172.66151,288.66278 172.41996,288.73908 C 172.17841,288.81538 171.69743,288.91289 171.3511,288.95577 C 170.66283,289.04097 170.08586,289.19654 169.90005,289.347 C 169.80425,289.4246 169.77269,289.52681 169.7378,289.8727 C 169.6838,290.40839 169.6459,290.62749 169.51869,291.14149 C 169.46319,291.36569 169.37931,291.97288 169.33231,292.49079 C 169.28331,293.03081 169.19055,293.6553 169.11485,293.95495 C 169.04225,294.24233 168.98286,294.57279 168.98286,294.68929 C 168.98286,294.88402 169.00766,294.91965 169.28997,295.13079 C 169.45889,295.25711 169.69183,295.39389 169.80763,295.43475 C 169.92342,295.47565 170.08805,295.56784 170.17348,295.63972 C 170.25888,295.71162 170.44814,295.81005 170.59399,295.8585 C 170.73983,295.9069 170.90176,295.99364 170.95382,296.05115 C 171.00592,296.10865 171.18481,296.20659 171.35146,296.26872 C 171.51811,296.33092 171.70327,296.42728 171.76294,296.48298 C 171.82264,296.53868 172.01507,296.64779 172.19062,296.72543 C 172.36618,296.80303 172.56782,296.91221 172.63871,296.96799 C 172.70961,297.02369 172.85718,297.09841 172.96664,297.13391 C 173.0761,297.16941 173.23632,297.24972 173.32269,297.31239 C 173.48142,297.42758 173.93107,297.66818 174.62394,298.00868 C 174.8323,298.11107 175.03454,298.23312 175.07335,298.27989 C 175.11215,298.32659 175.26425,298.40489 175.41131,298.45373 C 175.55837,298.50263 175.7469,298.59995 175.83028,298.6701 C 175.91368,298.7403 176.11327,298.8473 176.27387,298.90798 C 176.43447,298.96868 176.67759,299.12165 176.81412,299.24797 C 177.03295,299.45042 177.06935,299.51717 177.1211,299.81101 C 177.1534,299.99437 177.24282,300.27754 177.31982,300.44031 C 177.39682,300.60306 177.49507,300.92049 177.53816,301.1457 C 177.58116,301.3709 177.67423,301.67053 177.74478,301.81153 C 177.88903,302.09978 178.05009,302.76071 178.05009,303.0644 C 178.05009,303.35242 177.92048,303.74244 177.75086,303.96482 C 177.67036,304.0704 177.57225,304.26377 177.5329,304.39452 C 177.4935,304.52527 177.40137,304.71103 177.32806,304.80731 C 177.25476,304.90361 177.14344,305.1198 177.08068,305.28778 C 177.01798,305.45576 176.93198,305.62191 176.8897,305.657 C 176.8474,305.6921 176.76281,305.85448 176.70168,306.01786 C 176.64058,306.18123 176.53236,306.39153 176.46125,306.48519 C 176.39015,306.57889 176.28267,306.78571 176.22241,306.94488 C 176.16211,307.10405 176.07484,307.27632 176.02835,307.32769 C 175.98185,307.37899 175.88582,307.56911 175.81493,307.74999 C 175.74403,307.9309 175.62529,308.15937 175.55106,308.25772 C 175.47686,308.35602 175.39084,308.52951 175.35999,308.64316 C 175.32909,308.75679 175.24228,308.93057 175.16695,309.02933 C 175.09165,309.12813 174.97998,309.34256 174.91886,309.50593 C 174.85776,309.66931 174.77312,309.8317 174.73084,309.86678 C 174.68854,309.90188 174.60298,310.06683 174.54068,310.23335 C 174.47838,310.39986 174.35602,310.63316 174.26878,310.75179 C 174.01784,311.09303 174.0484,311.2321 174.47164,311.67483 C 174.67028,311.88262 175.06345,312.30765 175.34535,312.61933 C 175.62725,312.93102 176.05362,313.3932 176.29284,313.6464 C 176.53206,313.89961 176.97,314.36705 177.26604,314.68517 C 177.69493,315.14604 177.84256,315.27075 177.99256,315.29889 C 178.23626,315.34459 178.57289,315.25259 178.8844,315.055 C 179.02092,314.9684 179.223,314.88086 179.33346,314.86043 C 179.44393,314.83993 179.66009,314.75162 179.81384,314.66404 C 179.96757,314.57644 180.22004,314.46717 180.37487,314.42119 C 180.5297,314.37519 180.74771,314.27716 180.85933,314.20329 C 180.97095,314.12939 181.2009,314.03279 181.37034,313.98855 C 181.53977,313.94425 181.77022,313.84733 181.88244,313.77307 C 181.99465,313.69877 182.21307,313.60465 182.36781,313.56384 C 182.52255,313.52304 182.73816,313.43073 182.84692,313.35875 C 182.95568,313.28675 183.18658,313.18663 183.36003,313.1362 C 183.53348,313.0858 183.76747,312.98359 183.88003,312.9091 C 183.99259,312.8346 184.2233,312.73748 184.39275,312.69323 C 184.56218,312.64893 184.78996,312.55379 184.89891,312.48168 C 185.00786,312.40958 185.22214,312.31343 185.37507,312.26802 C 185.52803,312.22262 185.79427,312.11121 185.96673,312.02048 C 186.3247,311.83219 186.47946,311.83842 186.80565,312.05428 C 186.91722,312.12808 187.1362,312.21493 187.29228,312.24721 C 187.44836,312.27951 187.70072,312.37502 187.85307,312.45949 C 188.00542,312.54399 188.28472,312.65254 188.47374,312.70077 C 188.66276,312.74897 188.90747,312.84722 189.01754,312.91904 C 189.1276,312.99084 189.33405,313.07514 189.4763,313.10632 C 189.61855,313.13752 189.77645,313.17562 189.82719,313.19092 C 189.95719,313.23032 190.39723,313.91038 190.48812,314.21239 C 190.52992,314.35122 190.62499,314.55684 190.69943,314.66933 C 190.77383,314.78181 190.87327,315.00625 190.92031,315.16808 C 190.96731,315.32991 191.0654,315.54304 191.1382,315.6417 C 191.211,315.7404 191.30904,315.95349 191.35608,316.11532 C 191.40308,316.27715 191.5003,316.49823 191.57201,316.60659 C 191.64371,316.71496 191.73773,316.921 191.7809,317.06446 C 191.8241,317.20793 191.92031,317.41733 191.99474,317.52982 C 192.06924,317.6423 192.16858,317.86675 192.21563,318.02857 C 192.26263,318.1904 192.36072,318.40353 192.43352,318.50219 C 192.50632,318.60089 192.60213,318.80516 192.64644,318.9562 C 192.69074,319.10724 192.78666,319.31789 192.85954,319.42432 C 192.93244,319.53075 193.03089,319.75149 193.07837,319.91482 C 193.12577,320.07817 193.22427,320.29254 193.29706,320.3912 C 193.36986,320.4899 193.4685,320.70631 193.51629,320.87219 C 193.60899,321.19407 193.73259,321.36014 194.00426,321.52805 C 194.15835,321.62325 194.19275,321.62595 194.38649,321.55755 C 194.52719,321.50795 195.21146,321.45239 196.40394,321.39387 C 197.39643,321.34517 198.37287,321.28177 198.57378,321.25302 C 198.7747,321.22422 199.03455,321.20072 199.15123,321.20072 C 199.32743,321.20072 199.38579,321.17102 199.49574,321.02531 C 199.7016,320.75251 199.90905,320.20356 199.99726,319.69812 C 200.04156,319.44472 200.1353,319.10051 200.20572,318.93322 C 200.27612,318.76593 200.37204,318.4083 200.41885,318.13849 C 200.46565,317.86867 200.56617,317.51204 200.64221,317.34596 C 200.71821,317.17987 200.81464,316.83168 200.85641,316.5722 C 200.89821,316.31272 200.99187,315.96683 201.06458,315.80356 C 201.13728,315.6403 201.23585,315.28043 201.2836,315.00384 C 201.3313,314.72726 201.42972,314.36683 201.50222,314.20289 C 201.57472,314.03895 201.67263,313.68235 201.7198,313.41045 C 201.86266,312.58695 202.07901,312.30936 202.92537,311.86365 C 203.06629,311.78945 203.26485,311.66493 203.36662,311.58698 C 203.46839,311.50898 203.63979,311.41702 203.74753,311.38255 C 203.85525,311.34805 203.98449,311.27445 204.03473,311.21894 C 204.08493,311.16344 204.25183,311.06469 204.40555,310.99949 C 204.55929,310.93429 204.74612,310.82371 204.82075,310.75373 C 204.98795,310.59695 205.36176,310.46032 205.62285,310.46056 C 205.95437,310.46077 206.7581,310.6214 207.1313,310.76187 C 207.32648,310.83537 207.71812,310.93272 208.00161,310.9783 C 208.2851,311.0238 208.62445,311.10862 208.75573,311.16664 C 208.88701,311.22464 209.20274,311.30992 209.45736,311.35614 C 209.71197,311.40234 210.15103,311.51137 210.43303,311.59839 C 210.71503,311.68539 211.15451,311.79302 211.40964,311.83748 C 211.66477,311.88198 212.04567,311.97848 212.25608,312.052 C 212.4665,312.1255 212.8528,312.22234 213.11452,312.26715 C 213.37624,312.31195 213.68407,312.39011 213.79859,312.4408 C 214.00426,312.5318 214.01028,312.5311 214.29101,312.3841 C 214.50504,312.27204 214.59871,312.18316 214.67045,312.02406 C 214.72285,311.90788 214.81354,311.76959 214.87201,311.71677 C 214.93051,311.66397 215.034,311.51143 215.10207,311.37785 C 215.17007,311.24427 215.28895,311.0761 215.36609,311.00414 C 215.44329,310.93214 215.50636,310.84339 215.50636,310.80685 C 215.50636,310.77035 215.59106,310.63896 215.6947,310.51498 C 215.79828,310.391 215.92856,310.18833 215.98421,310.06461 C 216.03991,309.94089 216.14941,309.78078 216.22765,309.70882 C 216.30585,309.63682 216.36991,309.54807 216.36991,309.51153 C 216.36991,309.47503 216.45681,309.34104 216.56307,309.21388 C 216.66932,309.08672 216.81545,308.86584 216.88781,308.72303 C 216.96021,308.58023 217.0415,308.46338 217.06853,308.46338 C 217.13483,308.46338 217.39537,307.9051 217.39537,307.76295 C 217.39537,307.62175 217.21788,307.26712 217.09699,307.16679 C 217.04729,307.12559 216.92402,306.9693 216.82308,306.81959 C 216.72214,306.66988 216.53046,306.40167 216.39714,306.22356 C 216.26382,306.04545 216.11208,305.82893 216.05992,305.74239 C 216.00782,305.65589 215.88012,305.4885 215.77622,305.37048 C 215.67233,305.25247 215.53875,305.07754 215.47938,304.98177 C 215.31818,304.72171 215.07247,304.38474 214.84521,304.11208 C 214.73389,303.97852 214.64281,303.8462 214.64281,303.81806 C 214.64281,303.78986 214.56751,303.68816 214.47545,303.59196 C 214.38335,303.49576 214.27053,303.34418 214.22464,303.25512 C 214.17874,303.16602 214.05977,302.99776 213.96024,302.8811 C 213.86074,302.76445 213.77927,302.64148 213.77927,302.60785 C 213.77927,302.57425 213.70427,302.47537 213.61254,302.38819 C 213.52084,302.30099 213.40823,302.1568 213.36231,302.06775 C 213.31641,301.97875 213.19713,301.81469 213.09727,301.70329 C 212.99737,301.59189 212.91573,301.478 212.91573,301.45021 C 212.91573,301.42241 212.81863,301.28742 212.69984,301.15023 C 212.5811,301.01305 212.48396,300.87589 212.48396,300.84544 C 212.48396,300.81504 212.40956,300.68646 212.31858,300.5598 L 212.15321,300.32953 L 212.28919,299.76839 C 212.36399,299.45977 212.46397,298.78849 212.51138,298.27666 C 212.64558,296.82803 212.74861,296.52274 213.23555,296.13088 C 213.41998,295.98245 213.67241,295.77486 213.79651,295.66954 C 213.9206,295.56423 214.08286,295.43577 214.15707,295.38409 C 214.23127,295.33239 214.42889,295.18783 214.59621,295.06283 C 214.76353,294.93783 215.00386,294.7627 215.13029,294.67364 C 215.25672,294.58454 215.42342,294.44997 215.50073,294.37448 C 215.57803,294.29898 215.73237,294.18165 215.84369,294.11371 C 215.955,294.04581 216.04608,293.96892 216.04608,293.9429 C 216.04608,293.9169 216.16144,293.82936 216.30244,293.7484 C 216.44344,293.6674 216.64936,293.52675 216.76003,293.43579 C 216.87071,293.34479 217.07714,293.17844 217.21879,293.06607 C 217.36043,292.95371 217.59317,292.76548 217.73597,292.64779 C 217.87878,292.53011 218.01253,292.43383 218.0332,292.43383 C 218.0539,292.43383 218.20401,292.32453 218.36686,292.19095 C 218.5297,292.05737 218.68956,291.94808 218.72211,291.94808 C 218.75471,291.94808 218.85864,291.86308 218.95318,291.75918 C 219.04768,291.65529 219.14736,291.57028 219.1746,291.57028 C 219.2525,291.57028 219.84706,291.03283 219.88683,290.92646 C 219.94103,290.78154 219.79473,290.10409 219.64534,289.80838 C 219.57254,289.66426 219.47322,289.35317 219.42459,289.11706 C 219.37599,288.88095 219.27523,288.55464 219.20073,288.39193 C 219.12623,288.22921 219.02763,287.91379 218.98162,287.69099 C 218.93562,287.4682 218.84148,287.17448 218.77246,287.03828 C 218.70346,286.90209 218.60437,286.57612 218.5523,286.31391 C 218.40468,285.57059 218.18772,285.40162 217.40795,285.42269 C 216.75242,285.44039 214.88983,285.35469 214.69679,285.29798 C 214.49327,285.23818 213.59041,285.18994 210.91878,285.09625 L 209.21867,285.03665 L 208.72146,284.51197 C 208.44799,284.2234 208.02808,283.78084 207.78834,283.52853 C 206.92891,282.62402 206.64289,282.31229 206.56168,282.1916 C 206.49118,282.08685 206.48028,281.79256 206.48678,280.16766 C 206.49478,278.23919 206.57248,274.72014 206.62951,273.73016 C 206.65711,273.25082 206.64941,273.17828 206.56341,273.10481 C 206.36562,272.93591 205.73069,272.62747 205.40942,272.54421 C 205.22726,272.49701 204.98578,272.40004 204.87278,272.3287 C 204.75978,272.2574 204.50739,272.16191 204.3119,272.11658 C 204.11641,272.07128 203.86537,271.97469 203.75404,271.90204 C 203.64271,271.82934 203.39697,271.73047 203.20795,271.68225 C 203.01893,271.63405 202.73963,271.52575 202.58727,271.44164 C 202.43492,271.35754 202.21426,271.2719 202.0969,271.25135 C 201.97954,271.23085 201.79228,271.16745 201.68078,271.11056 C 201.44032,270.98789 201.5007,270.98403 201.19865,271.14136 Z" /> + style="fill:#1e1b1c;fill-opacity:1;stroke:#1e1b1c;stroke-width:1.10000002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter5845)" + d="M 152.89933,320.55212 C 153.09228,320.58432 153.45659,320.66972 153.70891,320.74209 C 153.96122,320.81449 154.33767,320.90006 154.54546,320.93229 C 154.75325,320.96449 155.0221,321.04872 155.14289,321.11939 C 155.26369,321.19009 155.52595,321.28577 155.7257,321.33209 C 155.92545,321.37839 156.17878,321.47786 156.28866,321.55308 C 156.39854,321.62828 156.61623,321.72733 156.77242,321.77315 C 156.92861,321.81895 157.12291,321.91116 157.20419,321.97802 C 157.28549,322.04482 157.45965,322.1418 157.59125,322.1934 C 157.72284,322.245 157.90186,322.34728 157.98906,322.42065 C 158.07626,322.49405 158.23575,322.59088 158.34348,322.63588 C 158.45122,322.68088 158.60008,322.77437 158.67429,322.84361 C 158.74849,322.91291 158.88408,323.00723 158.97558,323.05334 C 159.15149,323.14194 159.46444,323.37936 159.8548,323.72024 C 160.15485,323.98227 161.4929,325.32139 161.77766,325.64466 C 162.19909,326.12307 162.79998,326.95032 162.8549,327.1277 C 162.8762,327.1965 162.96257,327.33124 163.04688,327.42725 C 163.13118,327.52325 163.24254,327.7099 163.29434,327.84198 C 163.34614,327.97407 163.44283,328.14819 163.50921,328.2289 C 163.57551,328.3096 163.67157,328.5039 163.72253,328.66067 C 163.77353,328.81743 163.87152,329.0213 163.94041,329.11371 C 164.00931,329.20611 164.10432,329.44844 164.15158,329.65222 C 164.19878,329.85599 164.29945,330.12841 164.37515,330.25759 C 164.45825,330.39942 164.54147,330.66715 164.58519,330.93344 C 164.62499,331.17598 164.71744,331.53228 164.79061,331.72523 C 164.87441,331.94613 164.94562,332.2959 164.98302,332.66973 C 165.08422,333.68111 165.1515,334.96196 165.12305,335.33544 C 165.10815,335.53163 165.07075,336.05645 165.04005,336.50171 C 164.96945,337.52524 164.9095,337.90788 164.77055,338.222 C 164.70965,338.35961 164.62629,338.67963 164.58525,338.93314 C 164.53875,339.22055 164.45861,339.48286 164.37242,339.62992 C 164.29642,339.75963 164.20779,339.99533 164.17549,340.1537 C 164.14319,340.31207 164.04625,340.55798 163.96007,340.70019 C 163.87387,340.84239 163.7654,341.08929 163.71901,341.24887 C 163.67261,341.40845 163.59536,341.57141 163.54731,341.611 C 163.49931,341.6506 163.37957,341.85907 163.28133,342.07428 C 163.18313,342.28949 163.08064,342.46557 163.05369,342.46557 C 163.02669,342.46557 162.9408,342.59308 162.86274,342.74893 C 162.72847,343.01696 162.5411,343.28541 162.19836,343.70082 C 162.11536,343.80135 162.02166,343.93023 161.99003,343.98721 C 161.80906,344.31328 159.92509,346.19536 159.59712,346.37774 C 159.54292,346.40784 159.4164,346.50057 159.31586,346.5838 C 158.96479,346.87439 158.53792,347.16827 158.35121,347.24791 C 158.24773,347.29201 158.1139,347.37434 158.05383,347.43078 C 157.99383,347.48718 157.79913,347.59738 157.62132,347.67557 C 157.44351,347.75377 157.24946,347.86204 157.19009,347.91614 C 157.13079,347.97024 156.94961,348.05342 156.78761,348.10096 C 156.62561,348.14846 156.40703,348.24693 156.30187,348.31969 C 156.19671,348.39249 155.94233,348.49097 155.7366,348.53861 C 155.53087,348.58631 155.26371,348.68282 155.14291,348.75323 C 155.01559,348.82743 154.71913,348.91645 154.43754,348.96501 C 154.17038,349.01101 153.81269,349.09766 153.64267,349.15743 C 153.1589,349.32748 152.70932,349.37305 151.17226,349.40785 C 149.40292,349.44795 148.36124,349.38115 147.71808,349.18646 C 147.46576,349.11006 147.04074,349.01027 146.77358,348.96463 C 146.48391,348.91513 146.19695,348.8286 146.06269,348.7502 C 145.93885,348.6779 145.67169,348.58071 145.469,348.53423 C 145.2663,348.48773 145.01175,348.38884 144.90331,348.31443 C 144.79489,348.24003 144.58844,348.1439 144.44456,348.10081 C 144.30067,348.05771 144.08579,347.95355 143.96705,347.86931 C 143.84831,347.78511 143.66204,347.68717 143.55309,347.65175 C 143.44415,347.61635 143.32416,347.55018 143.28646,347.50475 C 143.24876,347.45925 143.08288,347.35371 142.91784,347.27005 C 142.7528,347.18635 142.55889,347.05479 142.48692,346.97761 C 142.41492,346.90041 142.32825,346.83727 142.29424,346.83727 C 142.26024,346.83727 142.13696,346.75717 142.0203,346.65931 C 141.90364,346.56141 141.73154,346.43392 141.63786,346.37596 C 141.13772,346.06651 139.35035,344.27475 139.13689,343.86884 C 139.09789,343.79464 138.97254,343.62727 138.85839,343.49693 C 138.74425,343.36659 138.65085,343.23118 138.65085,343.196 C 138.65085,343.1608 138.59205,343.07679 138.52014,343.00925 C 138.44824,342.94175 138.31789,342.73668 138.23045,342.55363 C 138.14305,342.37057 138.03305,342.18892 137.98612,342.14997 C 137.93912,342.11107 137.87141,341.99001 137.83551,341.88106 C 137.79961,341.77212 137.68909,341.56489 137.58988,341.42057 C 137.49068,341.27623 137.40951,341.11406 137.40951,341.06018 C 137.40951,341.00628 137.32401,340.7982 137.21952,340.59773 C 137.11503,340.39726 136.99262,340.07404 136.94749,339.87946 C 136.90239,339.68488 136.81499,339.44032 136.75331,339.336 C 136.69161,339.23168 136.59595,338.89591 136.54066,338.58987 C 136.48536,338.28382 136.37804,337.81022 136.30212,337.53742 C 136.01073,336.49032 136.00708,333.52744 136.29612,332.42686 C 136.37012,332.14486 136.47058,331.6834 136.51942,331.4014 C 136.56832,331.1194 136.67668,330.7308 136.76036,330.53785 C 136.84406,330.34491 136.93792,330.0656 136.96899,329.91718 C 137.00009,329.76876 137.11194,329.48162 137.21764,329.27909 C 137.32333,329.07657 137.40981,328.86739 137.40981,328.81426 C 137.40981,328.76116 137.48121,328.6278 137.56851,328.51797 C 137.65581,328.40814 137.76641,328.20023 137.81433,328.05595 C 137.86223,327.91166 137.93929,327.76223 137.98551,327.72386 C 138.03171,327.68546 138.13994,327.50883 138.22595,327.33128 C 138.31195,327.15372 138.40765,326.9928 138.4386,326.97367 C 138.4938,326.93957 138.66498,326.70376 139.06398,326.11219 C 139.17409,325.94892 139.32663,325.75129 139.40293,325.67299 C 139.47923,325.59469 139.65097,325.40731 139.78455,325.25658 C 140.37618,324.58899 141.31663,323.69506 141.63189,323.50065 C 141.72899,323.44075 141.90394,323.31165 142.0206,323.21377 C 142.13726,323.11587 142.26054,323.0358 142.29454,323.0358 C 142.32854,323.0358 142.41526,322.9721 142.48722,322.89437 C 142.55922,322.81657 142.72204,322.70783 142.84911,322.65271 C 142.97619,322.59751 143.17048,322.48207 143.28089,322.39603 C 143.39128,322.30993 143.56445,322.21218 143.66571,322.17871 C 143.76696,322.14521 143.92483,322.06096 144.01652,321.99143 C 144.10822,321.92193 144.30534,321.8247 144.45457,321.77542 C 144.6038,321.72612 144.81317,321.62652 144.91984,321.55404 C 145.02651,321.48154 145.27669,321.38447 145.47581,321.33829 C 145.67492,321.29209 145.93987,321.19454 146.06457,321.12145 C 146.20955,321.03645 146.47565,320.9591 146.80246,320.90684 C 147.08358,320.86184 147.52004,320.76204 147.77235,320.68498 C 148.05524,320.59858 148.4587,320.52728 148.8248,320.49903 C 149.59551,320.43953 152.44651,320.47673 152.89965,320.55213 Z M 147.94605,296.32129 C 147.87475,296.35039 147.77829,296.47622 147.71619,296.62108 C 147.65739,296.7584 147.56203,296.93069 147.50441,297.00393 C 147.44681,297.07713 147.36016,297.27301 147.31186,297.43912 C 147.26356,297.60525 147.16486,297.81878 147.09251,297.91364 C 147.02011,298.00844 146.92081,298.20481 146.87174,298.34989 C 146.82264,298.49497 146.72419,298.70239 146.65289,298.81082 C 146.58159,298.91926 146.48795,299.12535 146.44478,299.26881 C 146.40158,299.41227 146.30811,299.61755 146.23701,299.72498 C 146.16591,299.83241 146.07049,300.04575 146.02497,300.19906 C 145.97947,300.35236 145.86977,300.58054 145.78125,300.70613 C 145.69275,300.8317 145.59494,301.03223 145.56394,301.15175 C 145.53294,301.27127 145.4469,301.45129 145.37276,301.55178 C 145.29866,301.65229 145.19946,301.86691 145.15241,302.02874 C 145.10541,302.19057 145.00597,302.41501 144.93153,302.5275 C 144.85713,302.63999 144.76094,302.84913 144.71786,302.99226 C 144.67476,303.1354 144.58079,303.33813 144.50898,303.44277 C 144.43718,303.54741 144.32811,303.76868 144.26662,303.93447 C 144.13894,304.27878 144.00271,304.42668 143.69644,304.55356 C 143.57811,304.60256 143.37844,304.68918 143.25273,304.74601 C 143.12703,304.80291 142.83102,304.88598 142.59496,304.93076 C 142.35889,304.97556 142.03672,305.07066 141.87901,305.14215 C 141.72132,305.21365 141.38585,305.31076 141.13353,305.358 C 140.88121,305.4052 140.5588,305.50453 140.41707,305.57863 C 140.27534,305.65273 140.05566,305.72758 139.9289,305.74495 C 139.73273,305.77185 139.67334,305.75545 139.53002,305.63485 C 139.43742,305.55695 139.23206,305.4357 139.07369,305.36547 C 138.91533,305.29527 138.73768,305.18438 138.67892,305.1191 C 138.62012,305.0538 138.49047,304.96629 138.39074,304.92463 C 138.29104,304.88303 138.13579,304.78691 138.04581,304.7112 C 137.95581,304.6355 137.79406,304.53671 137.68633,304.49171 C 137.57859,304.44671 137.42973,304.35313 137.35552,304.28376 C 137.28132,304.21436 137.12061,304.10754 136.99842,304.04632 C 136.87622,303.98512 136.70621,303.87647 136.62061,303.80491 C 136.53501,303.73331 136.40874,303.65717 136.34001,303.63565 C 136.27121,303.61415 136.13439,303.52572 136.03583,303.43918 C 135.93733,303.35268 135.76279,303.24318 135.64809,303.19589 C 135.53337,303.14869 135.38401,303.05865 135.31617,302.99596 C 135.19782,302.88662 135.0637,302.80239 134.43978,302.44565 C 134.28403,302.35665 134.07766,302.21686 133.98116,302.13514 C 133.88466,302.05344 133.71187,301.94793 133.59716,301.90074 C 133.48245,301.85354 133.32789,301.75777 133.25368,301.68789 C 133.17948,301.61799 133.03349,301.52523 132.92929,301.4817 C 132.82508,301.4382 132.67299,301.34062 132.59131,301.26492 C 132.41425,301.10083 132.07328,300.9884 131.89125,301.03409 C 131.81925,301.05219 131.66528,301.14254 131.54903,301.23495 C 131.4328,301.32735 131.25268,301.43848 131.14878,301.4819 C 131.04489,301.5253 130.89916,301.6175 130.82495,301.68675 C 130.75075,301.75605 130.60921,301.85345 130.51044,301.90332 C 130.41164,301.95312 130.22158,302.0774 130.08802,302.17934 C 129.95447,302.28129 129.8144,302.36469 129.77674,302.36469 C 129.73904,302.36469 129.66202,302.41599 129.60547,302.47853 C 129.54887,302.54113 129.36907,302.65993 129.20581,302.74249 C 129.04255,302.82509 128.86471,302.94162 128.81062,303.00152 C 128.75652,303.06142 128.63508,303.14138 128.54076,303.1792 C 128.44646,303.217 128.299,303.3056 128.21313,303.37603 C 128.12723,303.44643 127.94,303.56337 127.79698,303.63585 C 127.44555,303.81393 127.39632,303.99294 127.47695,304.79947 C 127.53545,305.38435 127.56185,305.54734 127.71699,306.27763 C 127.76109,306.48542 127.83513,307.0926 127.88144,307.62692 C 127.92774,308.16124 128.02579,308.89115 128.0993,309.24894 C 128.1728,309.60673 128.26889,310.3232 128.31282,310.8411 C 128.35672,311.35899 128.43975,312.01143 128.49726,312.29096 C 128.55476,312.57047 128.58716,312.83763 128.56916,312.88465 C 128.53026,312.9863 128.22291,313.39485 128.03971,313.58835 C 127.63904,314.01153 126.36975,315.47469 126.08108,315.84613 C 125.98218,315.97342 125.80782,316.12521 125.69364,316.18345 C 125.4925,316.28608 125.35174,316.28936 121.15847,316.28936 L 116.83088,316.28936 L 116.5758,316.54572 C 116.38218,316.74032 116.29852,316.879 116.22861,317.12131 C 116.17801,317.29688 116.07687,317.52761 116.00399,317.63404 C 115.93109,317.74047 115.83523,317.95113 115.7909,318.10216 C 115.7466,318.2532 115.65077,318.4575 115.57797,318.55616 C 115.50517,318.65486 115.40713,318.86796 115.36009,319.02979 C 115.31309,319.19162 115.21365,319.41605 115.13921,319.52855 C 115.06481,319.64103 114.96854,319.85044 114.92536,319.9939 C 114.88216,320.13736 114.78538,320.34764 114.71022,320.4612 C 114.54456,320.71154 114.39056,321.30161 114.43973,321.49757 C 114.45943,321.57597 114.55355,321.72124 114.64894,321.82042 C 114.74434,321.91962 114.94381,322.15124 115.09223,322.33515 C 115.39974,322.71619 115.79579,323.1871 116.05128,323.47548 C 116.14718,323.58371 116.32279,323.78405 116.44152,323.92068 C 116.56026,324.0573 116.74241,324.26268 116.84631,324.37707 C 116.9502,324.49146 117.15665,324.73829 117.30507,324.92557 C 117.59872,325.2961 118.28972,326.11869 118.59655,326.463 C 118.79249,326.68287 118.88171,326.78494 119.64574,327.66326 C 119.92937,327.98933 120.09104,328.22351 120.11289,328.33995 C 120.15909,328.58619 120.04389,329.77251 119.92309,330.29498 C 119.81733,330.75233 119.73796,331.2844 119.65839,332.06932 C 119.60269,332.61832 119.52671,332.75549 119.15801,332.97212 C 119.02533,333.05012 118.85276,333.17787 118.77452,333.25611 C 118.69632,333.33431 118.5966,333.39835 118.553,333.39835 C 118.5094,333.39835 118.36388,333.48215 118.22964,333.58466 C 118.09539,333.68713 117.89154,333.81894 117.77663,333.87756 C 117.66172,333.93616 117.53452,334.02413 117.49397,334.07299 C 117.45337,334.12189 117.32621,334.20981 117.2113,334.26843 C 117.09639,334.32703 116.89254,334.45885 116.75829,334.56132 C 116.62405,334.6638 116.48388,334.74764 116.44679,334.74764 C 116.40969,334.74764 116.3205,334.81164 116.24853,334.8899 C 116.17653,334.9681 116.01555,335.0781 115.89071,335.13424 C 115.76588,335.19044 115.59587,335.29305 115.51291,335.3624 C 115.43001,335.4317 115.26331,335.53861 115.14259,335.59987 C 115.02187,335.66117 114.88991,335.75122 114.84936,335.80009 C 114.80876,335.84899 114.67685,335.9384 114.55613,335.99887 C 114.4354,336.05937 114.27591,336.16556 114.2017,336.23493 C 114.1275,336.30433 113.98128,336.39678 113.87677,336.44043 C 113.77228,336.48403 113.6387,336.57321 113.57993,336.63849 C 113.52113,336.70379 113.35165,336.81115 113.20322,336.87709 C 113.0548,336.94299 112.89846,337.03925 112.8558,337.09088 C 112.8132,337.14248 112.66553,337.24189 112.52779,337.31169 C 112.27676,337.4389 112.036,337.69703 111.96815,337.91171 C 111.94805,337.97531 112.00565,338.37222 112.09738,338.80224 C 112.18838,339.22896 112.29921,339.97883 112.34366,340.46863 C 112.38816,340.95842 112.46149,341.50488 112.50674,341.68299 C 112.55204,341.86109 112.63524,342.26183 112.69175,342.57352 C 112.8136,343.24554 112.8488,343.28596 113.39025,343.37539 C 113.60224,343.41039 113.88976,343.49868 114.02917,343.57156 C 114.16859,343.64446 114.48727,343.7429 114.73735,343.79033 C 114.98743,343.83773 115.30317,343.93279 115.43898,344.0015 C 115.5748,344.0702 115.89236,344.16766 116.14468,344.21805 C 116.397,344.26845 116.73258,344.36985 116.8904,344.44337 C 117.04823,344.51687 117.35979,344.61195 117.58276,344.65462 C 117.80572,344.69722 118.15018,344.80235 118.34824,344.88812 C 118.54628,344.97392 118.87564,345.07238 119.08012,345.10699 C 119.2846,345.14159 119.56997,345.22975 119.71428,345.30287 C 119.85859,345.37597 120.16395,345.47167 120.39287,345.51546 C 121.03541,345.6384 121.1372,345.68744 121.44912,346.02435 C 121.6729,346.26606 121.76043,346.41186 121.82947,346.65794 C 121.87887,346.83373 121.9794,347.05922 122.05304,347.15903 C 122.12664,347.25883 122.22541,347.4729 122.27245,347.63472 C 122.31945,347.79655 122.41666,348.01762 122.48838,348.126 C 122.56008,348.23437 122.65352,348.4385 122.696,348.57964 C 122.7385,348.72077 122.85439,348.9627 122.95361,349.11727 C 123.12241,349.38025 123.134,349.42815 123.134,349.8629 C 123.134,350.29207 123.1208,350.34879 122.96056,350.60674 C 122.86516,350.76033 122.74961,351.01227 122.70377,351.16661 C 122.65797,351.32095 122.55839,351.53677 122.48255,351.64621 C 122.40675,351.75565 122.31126,351.97178 122.27044,352.12652 C 122.22964,352.28124 122.13734,352.49683 122.06537,352.60559 C 121.99337,352.71435 121.89324,352.94526 121.84282,353.1187 C 121.79242,353.29214 121.69024,353.52609 121.6158,353.63858 C 121.5414,353.75106 121.44513,353.96047 121.40196,354.10393 C 121.35876,354.24739 121.26478,354.45343 121.19306,354.5618 C 121.12136,354.67017 121.02418,354.89124 120.97714,355.05307 C 120.93014,355.2149 120.83204,355.42803 120.75925,355.52669 C 120.68645,355.62539 120.58841,355.83849 120.54136,356.00032 C 120.49436,356.16214 120.39492,356.38658 120.32048,356.49907 C 120.24608,356.61156 120.14981,356.82096 120.10664,356.96442 C 120.06344,357.10788 119.96724,357.31728 119.89281,357.42976 C 119.74667,357.65058 119.63474,358.11158 119.68994,358.26523 C 119.70874,358.31753 119.79911,358.43587 119.89084,358.52836 C 119.98254,358.62086 120.1473,358.803 120.25691,358.93315 C 120.36652,359.06329 120.58511,359.32317 120.74266,359.51066 C 121.69458,360.64345 122.46287,361.51575 122.94996,362.01678 C 123.30806,362.38513 123.4088,362.40128 123.89968,362.16906 C 124.08333,362.08216 124.44764,361.97141 124.70925,361.92291 C 124.97086,361.87441 125.31427,361.77599 125.47238,361.70422 C 125.63048,361.63242 125.96641,361.53766 126.2189,361.49359 C 126.47139,361.44959 126.81046,361.35281 126.97239,361.27867 C 127.13433,361.20457 127.357,361.12934 127.46721,361.11157 C 127.9107,361.04007 128.22273,360.95762 128.52586,360.83185 C 128.70106,360.75915 129.05086,360.66366 129.30318,360.61961 C 129.55551,360.57561 129.8746,360.48245 130.01228,360.41269 C 130.14996,360.34299 130.48195,360.24799 130.75005,360.20172 C 131.01815,360.15552 131.34505,360.06881 131.47649,360.00918 C 131.79692,359.86382 131.99048,359.87042 132.18408,360.03328 C 132.27228,360.10748 132.37714,360.16821 132.41711,360.16821 C 132.45711,360.16821 132.605,360.25611 132.74581,360.36362 C 132.88661,360.47111 133.07719,360.59053 133.16931,360.62902 C 133.26141,360.66752 133.3849,360.75311 133.44366,360.81925 C 133.50246,360.88535 133.65265,360.98519 133.77749,361.04105 C 133.90232,361.09695 134.07234,361.19927 134.15529,361.26849 C 134.23829,361.33779 134.39112,361.43699 134.49501,361.48908 C 134.59891,361.54118 134.74463,361.63942 134.81884,361.70741 C 134.89304,361.77541 135.06867,361.88439 135.20911,361.94959 C 135.52282,362.09523 135.65381,362.29663 135.7355,362.75884 C 135.7696,362.95179 135.84277,363.29181 135.89812,363.51445 C 135.95342,363.73708 136.03806,364.32469 136.08612,364.82025 C 136.13422,365.31582 136.23107,365.95943 136.30143,366.2505 C 136.37183,366.54157 136.46879,367.18047 136.517,367.67026 C 136.5652,368.16005 136.66497,368.81218 136.7387,369.11943 C 136.8124,369.42668 136.89768,369.93671 136.92816,370.25283 C 137.02036,371.20865 137.0704,371.28925 137.65457,371.42199 C 137.86114,371.46899 138.20016,371.57653 138.40795,371.66111 C 138.61574,371.74571 138.91934,371.83205 139.0826,371.85303 C 139.24586,371.87403 139.53731,371.95966 139.73026,372.04338 C 139.92321,372.12708 140.29866,372.23632 140.56461,372.28608 C 140.83055,372.33588 141.16538,372.43785 141.30869,372.51278 C 141.45403,372.58878 141.74767,372.67472 141.97277,372.70715 L 142.3763,372.76525 L 142.70224,372.41707 C 142.8815,372.22559 143.11997,371.97175 143.23216,371.85302 C 143.53193,371.53577 145.01524,369.84261 145.247,369.55315 C 145.35663,369.41622 145.57493,369.1673 145.73214,368.99998 C 145.88933,368.83266 146.1151,368.58216 146.23383,368.44331 C 146.46161,368.17697 146.73989,367.86727 147.09738,367.48228 C 147.21611,367.35441 147.41042,367.13514 147.52915,366.99501 C 148.05989,366.36866 148.39341,366.06216 148.60858,366.00304 C 148.74663,365.96504 149.51793,365.94364 150.74775,365.94344 L 152.67103,365.94323 L 152.96058,366.18487 C 153.11984,366.31778 153.37158,366.5749 153.52,366.75625 C 153.89333,367.21242 155.03356,368.52153 155.53381,369.06833 C 155.76201,369.31777 156.02848,369.60921 156.12596,369.71599 C 156.48737,370.11185 157.57465,371.37367 157.7117,371.55627 C 157.7897,371.66016 158.0078,371.90803 158.19642,372.10707 C 158.38503,372.30611 158.57906,372.5247 158.62759,372.59281 C 158.76068,372.77964 159.32956,372.76271 159.80769,372.55771 C 160.00064,372.47501 160.3528,372.36577 160.59027,372.31502 C 160.82775,372.26422 161.18865,372.15596 161.39228,372.07433 C 161.59591,371.99273 161.96021,371.88864 162.20185,371.84308 C 162.44348,371.79758 162.75469,371.70275 162.8934,371.63248 C 163.03212,371.56228 163.31963,371.47597 163.53232,371.44084 C 163.74502,371.40574 163.96637,371.33839 164.0242,371.29123 C 164.1003,371.22923 164.15774,371.0489 164.2321,370.63877 C 164.2886,370.32708 164.37199,369.92634 164.41738,369.74823 C 164.46278,369.57013 164.53908,369.02367 164.58693,368.53387 C 164.63483,368.04408 164.73205,367.40047 164.80305,367.10363 C 164.87405,366.80678 164.96959,366.17532 165.01537,365.70037 C 165.06117,365.22542 165.158,364.58181 165.2306,364.27012 C 165.3032,363.95844 165.38899,363.43884 165.42127,363.11547 C 165.49767,362.34993 165.60528,362.15157 166.06839,361.92251 C 166.17228,361.87111 166.31801,361.77242 166.39222,361.70317 C 166.46642,361.63387 166.61732,361.5396 166.72753,361.49357 C 166.83774,361.44757 167.00775,361.34022 167.10533,361.25511 C 167.20293,361.17001 167.33899,361.0828 167.40773,361.06133 C 167.47653,361.03983 167.61334,360.9515 167.71191,360.86497 C 167.81041,360.77847 167.97676,360.67184 168.08147,360.6281 C 168.18619,360.5843 168.35224,360.47513 168.45049,360.3854 C 168.54869,360.2957 168.65679,360.22225 168.69062,360.22225 C 168.72452,360.22225 168.84381,360.14935 168.95587,360.06034 C 169.19727,359.86849 169.3617,359.85787 169.74584,360.00924 C 169.90052,360.07024 170.22323,360.15708 170.46296,360.20228 C 170.7027,360.24748 171.06885,360.35156 171.27664,360.43356 C 171.48443,360.51556 171.82672,360.61044 172.03728,360.64441 C 172.24784,360.67841 172.55313,360.76708 172.71571,360.8415 C 172.87828,360.9159 173.20465,361.01059 173.44098,361.05184 C 173.67732,361.09314 174.03229,361.19151 174.2298,361.27053 C 174.42733,361.34953 174.79088,361.45205 175.03768,361.4983 C 175.28449,361.5445 175.60989,361.64051 175.76078,361.71153 C 175.91168,361.78253 176.2499,361.87813 176.5124,361.92391 C 176.77489,361.96961 177.10075,362.06287 177.23651,362.131 C 177.88471,362.45623 178.00208,362.4086 178.72472,361.52707 C 178.78402,361.45467 178.92163,361.29536 179.03037,361.17311 C 179.13912,361.05085 179.3577,360.80323 179.51612,360.62283 C 179.67453,360.44244 179.87031,360.22385 179.95115,360.13709 C 180.08781,359.99045 180.54155,359.46226 181.2209,358.659 C 181.4523,358.38542 181.50426,358.28703 181.50426,358.12249 C 181.50426,357.85011 181.36188,357.38892 181.20424,357.15072 C 181.13314,357.04328 181.03965,356.83801 180.99648,356.69455 C 180.95328,356.55109 180.85707,356.34169 180.78263,356.2292 C 180.70823,356.11671 180.6088,355.89227 180.56175,355.73045 C 180.51475,355.56862 180.41666,355.35549 180.34387,355.25682 C 180.27107,355.15812 180.17526,354.95386 180.13094,354.80282 C 180.08664,354.65178 179.99124,354.44187 179.91899,354.33636 C 179.84669,354.23085 179.75137,354.02245 179.70707,353.87327 C 179.66277,353.72407 179.55286,353.47038 179.46284,353.30951 C 179.37284,353.14863 179.28271,352.92663 179.26259,352.81617 C 179.24249,352.7057 179.15653,352.50575 179.07161,352.37183 C 178.98671,352.2379 178.87937,351.99827 178.83315,351.83929 C 178.78695,351.68033 178.68957,351.46954 178.61678,351.37087 C 178.54398,351.27217 178.44793,351.0679 178.40331,350.91687 C 178.35871,350.76583 178.24893,350.53296 178.15939,350.39938 C 177.93223,350.06053 177.93141,349.70152 178.15739,349.36855 C 178.24589,349.23793 178.35704,348.99954 178.40435,348.83882 C 178.45165,348.67809 178.55,348.4595 178.62288,348.35307 C 178.69578,348.24664 178.79165,348.03599 178.83597,347.88495 C 178.88027,347.73391 178.9761,347.52961 179.0489,347.43095 C 179.1217,347.33225 179.21865,347.12289 179.26437,346.96563 C 179.31007,346.80837 179.4243,346.55121 179.51818,346.39418 C 179.61208,346.23713 179.7179,346.05952 179.75338,345.99948 C 179.85871,345.82125 180.32844,345.60176 180.79328,345.51359 C 181.03237,345.46829 181.35835,345.37144 181.51767,345.2985 C 181.677,345.2256 182.01064,345.12731 182.25909,345.08018 C 182.50755,345.03298 182.82378,344.93725 182.96184,344.86729 C 183.09989,344.79729 183.41106,344.7025 183.65335,344.65654 C 183.89561,344.61054 184.21135,344.51343 184.35497,344.44066 C 184.49859,344.36786 184.82072,344.26952 185.0708,344.22209 C 185.32088,344.17469 185.63578,344.07819 185.77057,344.00771 C 185.90537,343.93731 186.2309,343.83925 186.494,343.78995 C 186.75708,343.74065 187.0853,343.64307 187.22338,343.5731 C 187.36146,343.5031 187.57024,343.42946 187.68733,343.40937 C 188.24547,343.31367 188.29809,343.28522 188.44181,343.00161 C 188.61298,342.66384 188.66515,342.3886 188.76558,341.29344 C 188.80968,340.81203 188.905,340.14413 188.9773,339.80922 C 189.12744,339.11369 189.2506,338.05106 189.20303,337.86153 C 189.15113,337.65484 188.96011,337.45178 188.68761,337.3137 C 188.54767,337.2428 188.39989,337.14466 188.35922,337.09565 C 188.31862,337.04665 188.19124,336.95858 188.07633,336.89996 C 187.96142,336.84136 187.75756,336.70952 187.62332,336.60705 C 187.48908,336.50458 187.34473,336.42075 187.30254,336.42075 C 187.26034,336.42075 187.13572,336.33575 187.02557,336.23184 C 186.91543,336.12795 186.7958,336.04294 186.75972,336.04294 C 186.72372,336.04294 186.58431,335.95914 186.45006,335.85663 C 186.31582,335.75416 186.11196,335.62236 185.99706,335.56373 C 185.88214,335.50513 185.75495,335.41716 185.71439,335.3683 C 185.67379,335.3194 185.54664,335.23149 185.43172,335.17286 C 185.31681,335.11426 185.11296,334.98244 184.97871,334.87996 C 184.84447,334.77749 184.70429,334.69365 184.66722,334.69365 C 184.63012,334.69365 184.54092,334.62965 184.46896,334.5514 C 184.39696,334.4731 184.23597,334.3632 184.11114,334.30706 C 183.9863,334.25086 183.81629,334.14824 183.73334,334.0789 C 183.65034,334.0096 183.48374,333.90269 183.36302,333.84143 C 183.24229,333.78013 183.11024,333.68995 183.06956,333.64094 C 183.02896,333.59194 182.88479,333.49563 182.74934,333.42695 C 182.6139,333.35825 182.45986,333.25423 182.40703,333.19576 C 182.35423,333.13726 182.21259,333.04509 182.09234,332.99086 C 181.91985,332.91306 181.8419,332.82892 181.72298,332.59209 C 181.56323,332.27395 181.4956,331.88868 181.39552,330.72674 C 181.36482,330.37053 181.27664,329.81412 181.19952,329.49028 C 181.00125,328.6577 181.00286,328.39462 181.20752,328.15049 C 181.29652,328.04439 181.49087,327.80719 181.63929,327.62337 C 181.93546,327.25658 182.27513,326.85069 182.56519,326.51696 C 182.66838,326.39822 182.84229,326.1979 182.95166,326.07182 C 183.06102,325.94572 183.24764,325.73555 183.36638,325.60478 C 183.48512,325.47401 183.70371,325.21575 183.85213,325.03088 C 184.28522,324.49144 184.88612,323.78091 185.49378,323.08976 C 186.25665,322.22206 186.57037,321.8538 186.67981,321.69758 C 186.82304,321.4931 186.83993,321.23186 186.72451,321.00612 C 186.68061,320.92022 186.62821,320.77362 186.60816,320.68035 C 186.58816,320.58705 186.50095,320.39928 186.41454,320.26301 C 186.32814,320.12674 186.2196,319.88518 186.17338,319.72621 C 186.12718,319.56724 186.0298,319.35645 185.95701,319.25778 C 185.88421,319.15908 185.78616,318.94599 185.73912,318.78416 C 185.69212,318.62233 185.59491,318.40126 185.5232,318.29289 C 185.4515,318.18452 185.35748,317.97848 185.3143,317.83502 C 185.2711,317.69156 185.17721,317.48547 185.1056,317.37703 C 185.034,317.2686 184.94461,317.08273 184.90698,316.96399 C 184.80968,316.65687 184.71278,316.52121 184.51276,316.41191 C 184.35067,316.32331 184.01648,316.31431 179.94965,316.28935 L 175.56145,316.26235 L 175.23939,315.91153 C 175.06226,315.71858 174.81468,315.44519 174.6892,315.30398 C 174.19732,314.75045 174.07603,314.61302 173.88213,314.38941 C 173.7715,314.26183 173.59625,314.06031 173.49267,313.94157 C 172.92719,313.29334 172.75492,313.07276 172.72689,312.96111 C 172.68399,312.79004 172.85602,310.83501 172.95436,310.3766 C 173.11843,309.61173 173.14296,309.44211 173.2193,308.54441 C 173.2622,308.03978 173.35759,307.33192 173.43127,306.9714 C 173.55835,306.34945 173.73244,304.76815 173.73244,304.23578 C 173.73244,303.91374 173.64724,303.73646 173.45388,303.65638 C 173.36778,303.62068 173.20871,303.52113 173.10049,303.43513 C 172.99228,303.34913 172.80481,303.23449 172.68392,303.18037 C 172.56303,303.12627 172.41603,303.02787 172.35727,302.96173 C 172.29847,302.89563 172.17504,302.81001 172.08292,302.77151 C 171.99082,302.73301 171.80021,302.61359 171.65941,302.50611 C 171.5186,302.39863 171.36861,302.3107 171.32608,302.3107 C 171.28358,302.3107 171.17033,302.2357 171.07447,302.14413 C 170.97857,302.05253 170.81819,301.9433 170.71798,301.90142 C 170.61778,301.85952 170.45516,301.7545 170.35661,301.66797 C 170.25801,301.58147 170.12117,301.49314 170.05243,301.47174 C 169.98363,301.45034 169.83826,301.35282 169.72926,301.25502 C 169.59555,301.13506 169.4527,301.06547 169.29016,301.0411 C 169.03188,301.0024 168.90585,301.0461 168.63911,301.26827 C 168.55391,301.33917 168.39603,301.43399 168.28829,301.479 C 168.18056,301.524 168.0317,301.61896 167.95749,301.69002 C 167.88329,301.76112 167.73441,301.85604 167.62668,301.90104 C 167.51894,301.94604 167.36108,302.04107 167.27586,302.1122 C 167.19066,302.1833 167.03592,302.2848 166.93203,302.33768 C 166.82813,302.39058 166.67341,302.49202 166.58819,302.56315 C 166.50299,302.63425 166.34841,302.72794 166.24471,302.77127 C 166.141,302.81457 165.97552,302.92085 165.87696,303.00739 C 165.77836,303.09389 165.64153,303.18233 165.57279,303.20385 C 165.50399,303.22535 165.37756,303.30175 165.29169,303.37351 C 165.20579,303.44531 165.02215,303.56153 164.88352,303.63178 C 164.74488,303.70198 164.59689,303.80115 164.55465,303.85205 C 164.51245,303.90295 164.36822,303.99141 164.23421,304.04863 C 164.10022,304.10583 163.92986,304.21054 163.85565,304.28126 C 163.78145,304.35196 163.63378,304.44618 163.52752,304.49056 C 163.42126,304.53496 163.30135,304.61099 163.26105,304.65955 C 163.22075,304.70815 163.06482,304.80992 162.91453,304.88579 C 162.76425,304.96169 162.57157,305.08211 162.48635,305.15344 C 162.40115,305.22474 162.24717,305.31833 162.14421,305.36134 C 162.04124,305.40444 161.88559,305.49965 161.79831,305.57309 C 161.54752,305.78411 161.32336,305.79964 160.95785,305.63129 C 160.78542,305.55189 160.38436,305.42907 160.0666,305.35838 C 159.74885,305.28768 159.39057,305.1797 159.27042,305.1184 C 159.15027,305.0571 158.85164,304.96898 158.6068,304.92254 C 158.36197,304.87614 157.96172,304.75133 157.71737,304.64522 C 157.28964,304.4595 157.26517,304.43905 157.06058,304.09662 C 156.9437,303.90099 156.82368,303.64949 156.79387,303.53774 C 156.76407,303.42599 156.67769,303.2609 156.60193,303.17088 C 156.52623,303.08088 156.42692,302.88165 156.38135,302.72821 C 156.33585,302.57477 156.23952,302.36009 156.16742,302.25115 C 156.09532,302.14221 155.99786,301.92067 155.95081,301.75884 C 155.90381,301.59701 155.80461,301.38239 155.73046,301.28188 C 155.65636,301.18139 155.57032,301.00137 155.53935,300.88185 C 155.50845,300.76233 155.40278,300.53097 155.30468,300.3677 C 155.20658,300.20444 155.09518,299.97371 155.05712,299.85497 C 155.01912,299.73624 154.93306,299.56622 154.86599,299.47717 C 154.79889,299.38807 154.70488,299.17954 154.657,299.01366 C 154.6091,298.84778 154.5104,298.63134 154.43761,298.53267 C 154.36481,298.43397 154.26641,298.21964 154.21892,298.05629 C 154.17152,297.89295 154.07296,297.67222 154.00008,297.56579 C 153.92718,297.45936 153.83139,297.25084 153.78717,297.10242 C 153.73897,296.94056 153.61231,296.72457 153.47075,296.56271 L 153.23473,296.29285 L 150.65185,296.28205 C 149.15859,296.27605 148.01715,296.29235 147.94613,296.32125 Z" /> @@ -2710,23 +2772,23 @@ @@ -2839,40 +2901,40 @@ inkscape:groupmode="layer" id="layer9" inkscape:label="No-airspeed-sensor" - transform="translate(0,3.9351157e-6)"> + transform="translate(-4.55,3.9702315e-6)"> + d="M 142.73318,416.89169 C 142.73318,426.70873 134.53734,434.66702 124.42725,434.66702 C 114.31717,434.66702 106.12132,426.70873 106.12132,416.89169 C 106.12132,407.07465 114.31717,399.11637 124.42725,399.11637 C 134.53734,399.11637 142.73318,407.07465 142.73318,416.89169 Z" + style="fill:url(#linearGradient4135-2);fill-opacity:1;stroke:#e6e6e6;stroke-width:4.69614029;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" /> @@ -2884,20 +2946,20 @@ @@ -2937,20 +2999,20 @@ + style="fill:#a6acb0;fill-opacity:1;fill-rule:evenodd;stroke:#6a6c6c;stroke-width:1.56537998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:#a6acb0;fill-opacity:1;fill-rule:evenodd;stroke:#6a6c6c;stroke-width:1.56537998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:#a6acb0;fill-opacity:1;fill-rule:evenodd;stroke:#6a6c6c;stroke-width:1.56537998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:#a6acb0;fill-opacity:1;fill-rule:evenodd;stroke:#6a6c6c;stroke-width:1.56537998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:#aa7100;fill-opacity:1;fill-rule:evenodd;stroke:#6a6c6c;stroke-width:1.56537998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:36px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#e10000;fill-opacity:1;stroke:none" + d="M 185.05557,300.13361 L 185.05557,274.36407 L 189.20401,274.36407 L 197.85245,291.57306 L 197.85245,274.36407 L 201.8251,274.36407 L 201.8251,300.13361 L 197.53604,300.13361 L 189.02823,283.32892 L 189.02823,300.13361 L 185.05557,300.13361" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:36px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#e10000;fill-opacity:1;stroke:none" + d="M 205.46378,287.40704 C 205.46377,284.33675 205.91495,281.81136 206.81729,279.83087 C 207.73135,277.83871 208.9208,276.35629 210.38565,275.38361 C 211.85049,274.41098 213.62588,273.92465 215.71182,273.92462 C 218.73525,273.92465 221.19618,275.07894 223.09464,277.38751 C 225.00477,279.69613 225.95985,282.98323 225.95987,287.24884 C 225.95985,291.56135 224.95204,294.93049 222.93643,297.35626 C 221.16688,299.50079 218.76454,300.57306 215.7294,300.57306 C 212.6708,300.57306 210.25674,299.51251 208.48721,297.39142 C 206.47159,294.96564 205.46377,291.63752 205.46378,287.40704 M 209.85831,287.23126 C 209.8583,290.19612 210.4208,292.42268 211.54581,293.91095 C 212.6708,295.38752 214.06533,296.1258 215.7294,296.12579 C 217.40517,296.1258 218.79384,295.39338 219.89542,293.92853 C 220.99696,292.45197 221.54774,290.19026 221.54776,287.14337 C 221.54774,284.15511 221.00868,281.94612 219.93057,280.51642 C 218.86415,279.08675 217.46376,278.37191 215.7294,278.37189 C 213.99502,278.37191 212.58291,279.09261 211.49307,280.534 C 210.40322,281.97542 209.8583,284.20784 209.85831,287.23126" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:36px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#e10000;fill-opacity:1;stroke:none" + d="M 255.56143,300.13361 L 250.92081,300.13361 L 249.0751,294.28009 L 240.6376,294.28009 L 238.89737,300.13361 L 234.36221,300.13361 L 242.58878,274.36407 L 247.10635,274.36407 L 255.56143,300.13361 M 247.70401,289.93829 L 244.80362,280.37579 L 241.93839,289.93829 L 247.70401,289.93829" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:36px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#e10000;fill-opacity:1;stroke:none" + d="M 257.72354,300.13361 L 257.72354,274.36407 L 261.97745,274.36407 L 261.97745,300.13361 L 257.72354,300.13361" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:36px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#e10000;fill-opacity:1;stroke:none" + d="M 266.09073,300.13361 L 266.09073,274.36407 L 275.07315,274.36407 C 277.37001,274.3641 279.01064,274.59848 279.99503,275.0672 C 280.97938,275.52426 281.78798,276.32699 282.42081,277.4754 C 283.0536,278.61214 283.37001,279.97738 283.37003,281.57111 C 283.37001,283.58675 282.88368,285.20979 281.91104,286.44025 C 280.95009,287.67073 279.57899,288.44416 277.79776,288.76056 C 278.71181,289.41682 279.46767,290.13752 280.06534,290.92267 C 280.66298,291.69611 281.47743,293.09064 282.5087,295.10626 L 285.0751,300.13361 L 279.99503,300.13361 L 276.90128,294.52618 C 275.78798,292.49885 275.03212,291.23322 274.6337,290.72931 C 274.23525,290.21369 273.81338,289.86213 273.36807,289.67462 C 272.92275,289.47541 272.20791,289.3758 271.22354,289.37579 L 270.34464,289.37579 L 270.34464,300.13361 L 266.09073,300.13361 M 270.34464,285.26251 L 273.5087,285.26251 C 275.44228,285.26253 276.67275,285.18051 277.2001,285.01642 C 277.72743,284.84065 278.15517,284.49495 278.48331,283.97931 C 278.81142,283.4637 278.97548,282.77815 278.97549,281.92267 C 278.97548,281.10237 278.81142,280.44613 278.48331,279.95392 C 278.15517,279.45003 277.70986,279.10433 277.14737,278.91681 C 276.74892,278.78792 275.59462,278.72347 273.68448,278.72345 L 270.34464,278.72345 L 270.34464,285.26251" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:36px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#e10000;fill-opacity:1;stroke:none" + d="M 286.30557,291.74884 L 290.47159,291.25665 C 290.94033,294.54963 292.47549,296.19611 295.07706,296.19611 C 296.36611,296.19611 297.37978,295.86213 298.11807,295.19415 C 298.85634,294.51447 299.22548,293.67658 299.22549,292.68048 C 299.22548,292.09455 299.09657,291.59651 298.83878,291.18634 C 298.58095,290.77619 298.18837,290.44221 297.66104,290.18439 C 297.13369,289.91487 295.85634,289.46955 293.82901,288.84845 C 292.0126,288.29768 290.68252,287.70002 289.83878,287.05548 C 288.99502,286.41096 288.32119,285.56721 287.81729,284.52423 C 287.3251,283.46956 287.07901,282.3387 287.07901,281.13165 C 287.07901,279.72542 287.39541,278.4598 288.02823,277.33478 C 288.67276,276.2098 289.55752,275.36019 290.68253,274.78595 C 291.80752,274.21176 293.19619,273.92465 294.84854,273.92462 C 297.3329,273.92465 299.27236,274.59848 300.6669,275.94611 C 302.06142,277.29379 302.7997,279.22152 302.88174,281.72931 L 298.61026,281.95782 C 298.42275,280.57503 298.01845,279.60824 297.39737,279.05743 C 296.77626,278.50667 295.8915,278.23128 294.74307,278.23126 C 293.59463,278.23128 292.70986,278.47152 292.08878,278.95197 C 291.46768,279.43245 291.15713,280.03011 291.15714,280.74493 C 291.15713,281.44808 291.43838,282.03987 292.00089,282.52032 C 292.56338,283.00081 293.8583,283.52815 295.88565,284.10236 C 298.03017,284.72347 299.57704,285.37971 300.52628,286.07111 C 301.4872,286.75081 302.21962,287.63557 302.72354,288.7254 C 303.22743,289.80354 303.47938,291.11604 303.4794,292.6629 C 303.47938,294.90119 302.78798,296.78205 301.40518,298.30548 C 300.03407,299.82892 297.88368,300.59064 294.95401,300.59064 C 289.77432,300.59064 286.89151,297.64337 286.30557,291.74884" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:36px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#e10000;fill-opacity:1;stroke:none" + d="M 307.06534,300.13361 L 307.06534,274.36407 L 313.92081,274.36407 C 316.47548,274.3641 318.1454,274.48715 318.93057,274.73322 C 320.18446,275.13168 321.21571,275.98129 322.02432,277.28204 C 322.84462,278.58285 323.25477,280.25863 323.25479,282.30939 C 323.25477,284.17268 322.90321,285.73714 322.2001,287.00275 C 321.49696,288.25666 320.61806,289.14143 319.56339,289.65704 C 318.50868,290.16096 316.69228,290.41291 314.11417,290.4129 L 311.31924,290.4129 L 311.31924,300.13361 L 307.06534,300.13361 M 311.31924,278.72345 L 311.31924,286.03595 L 313.67471,286.03595 C 315.25673,286.03596 316.329,285.92464 316.89151,285.70197 C 317.46572,285.47932 317.93447,285.08089 318.29776,284.50665 C 318.66103,283.92073 318.84267,283.20589 318.84268,282.36212 C 318.84267,281.50667 318.65517,280.78597 318.28018,280.20001 C 317.90517,279.6141 317.44228,279.22152 316.89151,279.02228 C 316.34072,278.82308 315.1747,278.72347 313.39346,278.72345 L 311.31924,278.72345" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:36px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#e10000;fill-opacity:1;stroke:none" + d="M 326.77042,300.13361 L 326.77042,274.36407 L 342.4501,274.36407 L 342.4501,278.72345 L 331.02432,278.72345 L 331.02432,284.43634 L 341.64151,284.43634 L 341.64151,288.77814 L 331.02432,288.77814 L 331.02432,295.79181 L 342.83682,295.79181 L 342.83682,300.13361 L 326.77042,300.13361" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:36px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#e10000;fill-opacity:1;stroke:none" + d="M 346.45792,300.13361 L 346.45792,274.36407 L 362.1376,274.36407 L 362.1376,278.72345 L 350.71182,278.72345 L 350.71182,284.43634 L 361.32901,284.43634 L 361.32901,288.77814 L 350.71182,288.77814 L 350.71182,295.79181 L 362.52432,295.79181 L 362.52432,300.13361 L 346.45792,300.13361" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:36px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#e10000;fill-opacity:1;stroke:none" + d="M 366.11026,274.36407 L 373.89737,274.36407 C 375.86611,274.3641 377.34853,274.58676 378.34464,275.03204 C 379.35243,275.46566 380.27821,276.20394 381.12198,277.24689 C 381.96571,278.28988 382.62782,279.64339 383.10831,281.30743 C 383.58876,282.97151 383.82899,285.03987 383.82901,287.51251 C 383.82899,289.73909 383.57704,291.67854 383.07315,293.33087 C 382.56923,294.9715 381.93055,296.27228 381.15714,297.23322 C 380.38368,298.19415 379.44618,298.92072 378.34464,299.4129 C 377.25478,299.89337 375.84853,300.13361 374.12589,300.13361 L 366.11026,300.13361 L 366.11026,274.36407 M 370.36417,278.72345 L 370.36417,295.79181 L 373.56339,295.79181 C 374.93447,295.79181 375.9247,295.66291 376.53409,295.40509 C 377.15517,295.14728 377.65907,294.76056 378.04581,294.24493 C 378.44423,293.7176 378.77235,292.89143 379.03018,291.76642 C 379.28798,290.64143 379.41689,289.15901 379.4169,287.31915 C 379.41689,285.40901 379.28212,283.90315 379.0126,282.80157 C 378.75478,281.70003 378.34462,280.83284 377.78214,280.20001 C 377.23134,279.56722 376.55751,279.15121 375.76065,278.95197 C 375.16298,278.79964 374.00869,278.72347 372.29776,278.72345 L 370.36417,278.72345" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:36px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#e10000;fill-opacity:1;stroke:none" + d="M 222.81339,324.74884 L 226.9794,324.25665 C 227.44814,327.54963 228.9833,329.19611 231.58487,329.19611 C 232.87392,329.19611 233.88759,328.86213 234.62589,328.19415 C 235.36415,327.51447 235.73329,326.67658 235.73331,325.68048 C 235.73329,325.09455 235.60439,324.59651 235.34659,324.18634 C 235.08876,323.77619 234.69618,323.44221 234.16885,323.18439 C 233.6415,322.91487 232.36416,322.46955 230.33682,321.84845 C 228.52041,321.29768 227.19033,320.70002 226.34659,320.05548 C 225.50283,319.41096 224.82901,318.56721 224.3251,317.52423 C 223.83291,316.46956 223.58682,315.3387 223.58682,314.13165 C 223.58682,312.72542 223.90323,311.4598 224.53604,310.33478 C 225.18057,309.2098 226.06533,308.36019 227.19034,307.78595 C 228.31533,307.21176 229.704,306.92465 231.35635,306.92462 C 233.84072,306.92465 235.78017,307.59848 237.17471,308.94611 C 238.56923,310.29379 239.30751,312.22152 239.38956,314.72931 L 235.11807,314.95782 C 234.93056,313.57503 234.52626,312.60824 233.90518,312.05743 C 233.28408,311.50667 232.39931,311.23128 231.25089,311.23126 C 230.10244,311.23128 229.21767,311.47152 228.59659,311.95197 C 227.97549,312.43245 227.66494,313.03011 227.66495,313.74493 C 227.66494,314.44808 227.94619,315.03987 228.5087,315.52032 C 229.07119,316.00081 230.36611,316.52815 232.39346,317.10236 C 234.53798,317.72347 236.08486,318.37971 237.03409,319.07111 C 237.99501,319.75081 238.72743,320.63557 239.23135,321.7254 C 239.73524,322.80354 239.98719,324.11604 239.98721,325.6629 C 239.98719,327.90119 239.29579,329.78205 237.91299,331.30548 C 236.54189,332.82892 234.3915,333.59064 231.46182,333.59064 C 226.28213,333.59064 223.39932,330.64337 222.81339,324.74884" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:36px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#e10000;fill-opacity:1;stroke:none" + d="M 243.59073,333.13361 L 243.59073,307.36407 L 259.27042,307.36407 L 259.27042,311.72345 L 247.84464,311.72345 L 247.84464,317.43634 L 258.46182,317.43634 L 258.46182,321.77814 L 247.84464,321.77814 L 247.84464,328.79181 L 259.65714,328.79181 L 259.65714,333.13361 L 243.59073,333.13361" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:36px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#e10000;fill-opacity:1;stroke:none" + d="M 263.31339,333.13361 L 263.31339,307.36407 L 267.46182,307.36407 L 276.11026,324.57306 L 276.11026,307.36407 L 280.08292,307.36407 L 280.08292,333.13361 L 275.79385,333.13361 L 267.28604,316.32892 L 267.28604,333.13361 L 263.31339,333.13361" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:36px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#e10000;fill-opacity:1;stroke:none" + d="M 283.49307,324.74884 L 287.65909,324.25665 C 288.12783,327.54963 289.66299,329.19611 292.26456,329.19611 C 293.55361,329.19611 294.56728,328.86213 295.30557,328.19415 C 296.04384,327.51447 296.41298,326.67658 296.41299,325.68048 C 296.41298,325.09455 296.28407,324.59651 296.02628,324.18634 C 295.76845,323.77619 295.37587,323.44221 294.84854,323.18439 C 294.32119,322.91487 293.04384,322.46955 291.01651,321.84845 C 289.2001,321.29768 287.87002,320.70002 287.02628,320.05548 C 286.18252,319.41096 285.50869,318.56721 285.00479,317.52423 C 284.5126,316.46956 284.26651,315.3387 284.26651,314.13165 C 284.26651,312.72542 284.58291,311.4598 285.21573,310.33478 C 285.86026,309.2098 286.74502,308.36019 287.87003,307.78595 C 288.99502,307.21176 290.38369,306.92465 292.03604,306.92462 C 294.5204,306.92465 296.45986,307.59848 297.8544,308.94611 C 299.24892,310.29379 299.9872,312.22152 300.06924,314.72931 L 295.79776,314.95782 C 295.61025,313.57503 295.20595,312.60824 294.58487,312.05743 C 293.96376,311.50667 293.079,311.23128 291.93057,311.23126 C 290.78213,311.23128 289.89736,311.47152 289.27628,311.95197 C 288.65518,312.43245 288.34463,313.03011 288.34464,313.74493 C 288.34463,314.44808 288.62588,315.03987 289.18839,315.52032 C 289.75088,316.00081 291.0458,316.52815 293.07315,317.10236 C 295.21767,317.72347 296.76454,318.37971 297.71378,319.07111 C 298.6747,319.75081 299.40712,320.63557 299.91104,321.7254 C 300.41493,322.80354 300.66688,324.11604 300.6669,325.6629 C 300.66688,327.90119 299.97548,329.78205 298.59268,331.30548 C 297.22157,332.82892 295.07118,333.59064 292.14151,333.59064 C 286.96182,333.59064 284.07901,330.64337 283.49307,324.74884" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:36px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#e10000;fill-opacity:1;stroke:none" + d="M 303.40909,320.40704 C 303.40909,317.33675 303.86026,314.81136 304.7626,312.83087 C 305.67666,310.83871 306.86611,309.35629 308.33096,308.38361 C 309.7958,307.41098 311.57119,306.92465 313.65714,306.92462 C 316.68056,306.92465 319.14149,308.07894 321.03995,310.38751 C 322.95008,312.69613 323.90516,315.98323 323.90518,320.24884 C 323.90516,324.56135 322.89735,327.93049 320.88174,330.35626 C 319.1122,332.50079 316.70985,333.57306 313.67471,333.57306 C 310.61611,333.57306 308.20205,332.51251 306.43253,330.39142 C 304.4169,327.96564 303.40909,324.63752 303.40909,320.40704 M 307.80362,320.23126 C 307.80361,323.19612 308.36611,325.42268 309.49112,326.91095 C 310.61611,328.38752 312.01064,329.1258 313.67471,329.12579 C 315.35048,329.1258 316.73915,328.39338 317.84073,326.92853 C 318.94227,325.45197 319.49306,323.19026 319.49307,320.14337 C 319.49306,317.15511 318.95399,314.94612 317.87589,313.51642 C 316.80946,312.08675 315.40907,311.37191 313.67471,311.37189 C 311.94033,311.37191 310.52822,312.09261 309.43839,313.534 C 308.34854,314.97542 307.80361,317.20784 307.80362,320.23126" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:36px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#e10000;fill-opacity:1;stroke:none" + d="M 327.2626,333.13361 L 327.2626,307.36407 L 336.24503,307.36407 C 338.54189,307.3641 340.18251,307.59848 341.1669,308.0672 C 342.15126,308.52426 342.95985,309.32699 343.59268,310.4754 C 344.22548,311.61214 344.54188,312.97738 344.5419,314.57111 C 344.54188,316.58675 344.05555,318.20979 343.08292,319.44025 C 342.12196,320.67073 340.75087,321.44416 338.96964,321.76056 C 339.88368,322.41682 340.63954,323.13752 341.23721,323.92267 C 341.83485,324.69611 342.6493,326.09064 343.68057,328.10626 L 346.24698,333.13361 L 341.1669,333.13361 L 338.07315,327.52618 C 336.95986,325.49885 336.204,324.23322 335.80557,323.72931 C 335.40712,323.21369 334.98525,322.86213 334.53995,322.67462 C 334.09463,322.47541 333.37978,322.3758 332.39542,322.37579 L 331.51651,322.37579 L 331.51651,333.13361 L 327.2626,333.13361 M 331.51651,318.26251 L 334.68057,318.26251 C 336.61415,318.26253 337.84462,318.18051 338.37198,318.01642 C 338.89931,317.84065 339.32704,317.49495 339.65518,316.97931 C 339.98329,316.4637 340.14735,315.77815 340.14737,314.92267 C 340.14735,314.10237 339.98329,313.44613 339.65518,312.95392 C 339.32704,312.45003 338.88173,312.10433 338.31924,311.91681 C 337.92079,311.78792 336.7665,311.72347 334.85635,311.72345 L 331.51651,311.72345 L 331.51651,318.26251" /> @@ -3272,7 +3334,7 @@ inkscape:groupmode="layer" id="layer4" inkscape:label="GPS-v8" - transform="translate(4.5344706,8.3915228)" + transform="translate(-0.0155294,8.3915228)" style="display:inline"> + d="M 42.719849,646.08344 L 354.65593,646.08344 C 364.95253,646.08344 373.24184,654.37275 373.24184,664.66934 L 373.24184,976.60541 C 373.24184,986.902 364.95253,995.19131 354.65593,995.19131 L 42.719849,995.19131 C 32.423257,995.19131 24.133944,986.902 24.133944,976.60541 L 24.133944,664.66934 C 24.133944,654.37275 32.423257,646.08344 42.719849,646.08344 Z" + style="fill:#2d2b2c;fill-opacity:1;stroke:#ffd25c;stroke-width:7.68217373;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:62.9418335px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none"> + d="M 94.28441,672.04335 L 103.38147,672.04335 L 103.38147,696.4456 C 103.38146,700.31801 103.49415,702.8279 103.71954,703.97526 C 104.10881,705.81927 105.03081,707.30471 106.48554,708.43159 C 107.96072,709.538 109.96863,710.0912 112.50927,710.09119 C 115.09084,710.0912 117.03728,709.56873 118.3486,708.52379 C 119.65986,707.45838 120.44868,706.15734 120.71506,704.62066 C 120.98139,703.08401 121.11456,700.53315 121.1146,696.96807 L 121.1146,672.04335 L 130.21166,672.04335 L 130.21166,695.708 C 130.21162,701.11708 129.96575,704.93825 129.47406,707.17153 C 128.98229,709.40482 128.07053,711.2898 126.73879,712.82646 C 125.42747,714.36313 123.66543,715.59246 121.45266,716.51446 C 119.23983,717.41597 116.35091,717.86672 112.78587,717.86672 C 108.48318,717.86672 105.21521,717.37499 102.98194,716.39152 C 100.76913,715.38757 99.017332,714.09677 97.726542,712.51912 C 96.435736,710.921 95.585448,709.25116 95.175676,707.50959 C 94.581494,704.92801 94.284406,701.11708 94.28441,696.0768 L 94.28441,672.04335" /> + d="M 139.86192,672.04335 L 157.87164,672.04335 C 161.43668,672.04339 164.08999,672.19706 165.83157,672.50435 C 167.59358,672.79123 169.16098,673.4059 170.53377,674.34834 C 171.92698,675.29087 173.0846,676.55094 174.00664,678.12854 C 174.92859,679.68573 175.38959,681.43753 175.38963,683.38394 C 175.38959,685.49433 174.81591,687.43052 173.66857,689.19254 C 172.54164,690.95461 171.00498,692.27614 169.05857,693.15713 C 171.80404,693.95622 173.9144,695.31873 175.38963,697.24467 C 176.86479,699.17064 177.60239,701.43466 177.60243,704.03673 C 177.60239,706.08563 177.1209,708.08329 176.15797,710.02973 C 175.21544,711.95569 173.9144,713.50259 172.25484,714.67046 C 170.61569,715.81784 168.58729,716.5247 166.16964,716.79106 C 164.65343,716.95497 160.99617,717.05741 155.19785,717.09839 L 139.86192,717.09839 L 139.86192,672.04335 M 148.95898,679.54228 L 148.95898,689.96087 L 154.92125,689.96087 C 158.4658,689.9609 160.66835,689.90967 161.52891,689.8072 C 163.08604,689.62283 164.30512,689.09012 165.18617,688.20907 C 166.08765,687.30759 166.53841,686.12948 166.53844,684.67474 C 166.53841,683.28153 166.14912,682.15464 165.37057,681.29407 C 164.61246,680.41309 163.47532,679.88038 161.95917,679.69594 C 161.05764,679.59353 158.4658,679.54231 154.18365,679.54228 L 148.95898,679.54228 M 148.95898,697.4598 L 148.95898,709.50726 L 157.37991,709.50726 C 160.65811,709.50727 162.73772,709.41506 163.61877,709.23066 C 164.97101,708.9848 166.06716,708.39062 166.90724,707.44813 C 167.76774,706.48516 168.19801,705.20461 168.19804,703.60646 C 168.19801,702.25421 167.87018,701.10684 167.21457,700.16433 C 166.5589,699.22186 165.60616,698.53548 164.35637,698.1052 C 163.12701,697.67495 160.44297,697.45982 156.30424,697.4598 L 148.95898,697.4598" /> + d="M 185.56236,717.09839 L 185.56236,672.41215 L 194.65942,672.41215 L 194.65942,709.50726 L 217.27915,709.50726 L 217.27915,717.09839 L 185.56236,717.09839" /> + d="M 221.95061,694.84747 C 221.95061,690.25799 222.63698,686.40608 224.00974,683.29174 C 225.03418,680.99702 226.42742,678.93789 228.18947,677.11434 C 229.97199,675.29087 231.91843,673.93861 234.0288,673.05755 C 236.83576,671.86924 240.073,671.27506 243.74053,671.27501 C 250.3789,671.27506 255.68551,673.33419 259.66039,677.45241 C 263.65568,681.57071 265.65334,687.29735 265.65339,694.63233 C 265.65334,701.9059 263.67616,707.6018 259.72186,711.72006 C 255.76747,715.81784 250.48134,717.86672 243.86346,717.86672 C 237.16358,717.86672 231.83648,715.82808 227.88214,711.75079 C 223.92778,707.65303 221.95061,702.01859 221.95061,694.84747 M 231.32427,694.54013 C 231.32426,699.64188 232.50237,703.51428 234.8586,706.15733 C 237.2148,708.77991 240.20618,710.0912 243.83273,710.09119 C 247.45923,710.0912 250.43012,708.79016 252.74539,706.18806 C 255.08109,703.5655 256.24895,699.64188 256.24899,694.4172 C 256.24895,689.25403 255.11182,685.40213 252.83759,682.86147 C 250.58378,680.32089 247.58217,679.05058 243.83273,679.05054 C 240.08324,679.05058 237.06114,680.34138 234.7664,682.92294 C 232.47163,685.48408 231.32426,689.35648 231.32427,694.54013" /> + d="M 268.14279,717.09839 L 283.54018,693.5874 L 269.58725,672.04335 L 280.22098,672.04335 L 289.25658,686.51874 L 298.10777,672.04335 L 308.6493,672.04335 L 294.63491,693.92547 L 310.0323,717.09839 L 299.0605,717.09839 L 289.07218,701.5166 L 279.05312,717.09839 L 268.14279,717.09839" /> + d="M 43.451504,753.52476 C 43.451501,748.93528 44.137878,745.08337 45.510636,741.96903 C 46.535074,739.67431 47.928316,737.61518 49.690367,735.79163 C 51.472889,733.96817 53.41933,732.6159 55.529697,731.73484 C 58.336656,730.54653 61.573895,729.95235 65.241426,729.9523 C 71.879791,729.95235 77.186405,732.01148 81.161284,736.1297 C 85.156571,740.248 87.154234,745.97464 87.154281,753.30963 C 87.154234,760.58319 85.177059,766.2791 81.22275,770.39735 C 77.26836,774.49513 71.982235,776.54401 65.364359,776.54401 C 58.664478,776.54401 53.337375,774.50537 49.383034,770.42808 C 45.428676,766.33032 43.451501,760.69588 43.451504,753.52476 M 52.825165,753.21743 C 52.825153,758.31917 54.003263,762.19157 56.359497,764.83462 C 58.7157,767.4572 61.707073,768.76849 65.333625,768.76848 C 68.960129,768.76849 71.931013,767.46745 74.246287,764.86535 C 76.581984,762.24279 77.749849,758.31917 77.749886,753.09449 C 77.749849,747.93132 76.612717,744.07942 74.338487,741.53877 C 72.084679,738.99818 69.083062,737.72787 65.333625,737.72783 C 61.58414,737.72787 58.562033,739.01867 56.267297,741.60023 C 53.972529,744.16137 52.825153,748.03377 52.825165,753.21743" /> + d="M 94.222943,775.77568 L 94.222943,730.72064 L 108.82127,730.72064 C 114.35324,730.72068 117.95928,730.94606 119.6394,731.39677 C 122.22096,732.07295 124.38254,733.54815 126.12413,735.82237 C 127.86564,738.07618 128.73642,740.99584 128.73646,744.58136 C 128.73642,747.34739 128.23444,749.67288 127.23053,751.55783 C 126.22653,753.44283 124.94598,754.92827 123.38886,756.01416 C 121.85216,757.0796 120.28477,757.78646 118.68666,758.13476 C 116.51482,758.56504 113.36978,758.78017 109.25154,758.78016 L 103.32001,758.78016 L 103.32001,775.77568 L 94.222943,775.77568 M 103.32001,738.3425 L 103.32001,751.12756 L 108.2988,751.12756 C 111.88433,751.12758 114.28153,750.89196 115.4904,750.42069 C 116.69922,749.94948 117.6417,749.21188 118.31786,748.2079 C 119.01446,747.20397 119.36277,746.0361 119.3628,744.7043 C 119.36277,743.06522 118.88128,741.71295 117.91833,740.6475 C 116.95533,739.58211 115.73624,738.91623 114.26107,738.64983 C 113.17513,738.44498 110.99307,738.34254 107.71487,738.3425 L 103.32001,738.3425" /> + d="M 157.22624,759.21042 L 157.22624,751.61929 L 176.8341,751.61929 L 176.8341,769.56755 C 174.92859,771.41155 172.1626,773.04042 168.5361,774.45415 C 164.93003,775.84739 161.27277,776.54401 157.56431,776.54401 C 152.85185,776.54401 148.74383,775.56055 145.24025,773.59362 C 141.73664,771.6062 139.10382,768.77874 137.34179,765.11122 C 135.57974,761.42324 134.69872,757.41766 134.69872,753.09449 C 134.69872,748.40257 135.68218,744.23308 137.64912,740.58603 C 139.61605,736.93905 142.49473,734.14232 146.28518,732.19584 C 149.1741,730.70019 152.76989,729.95235 157.07258,729.9523 C 162.66601,729.95235 167.03014,731.13046 170.16497,733.48664 C 173.32022,735.82241 175.34861,739.05965 176.25017,743.19836 L 167.21457,744.8887 C 166.57938,742.67593 165.38078,740.93438 163.61877,739.66403 C 161.87719,738.37327 159.69513,737.72787 157.07258,737.72783 C 153.09771,737.72787 149.93219,738.98794 147.57598,741.50803 C 145.24024,744.0282 144.07237,747.76741 144.07238,752.72569 C 144.07237,758.07331 145.26073,762.08912 147.63745,764.77315 C 150.01414,767.43672 153.12845,768.76849 156.98038,768.76848 C 158.88582,768.76849 160.79128,768.39969 162.69677,767.66208 C 164.6227,766.90401 166.27205,765.99225 167.64484,764.92682 L 167.64484,759.21042 L 157.22624,759.21042" /> + d="M 185.19356,775.77568 L 185.19356,730.72064 L 199.79188,730.72064 C 205.32386,730.72068 208.9299,730.94606 210.61001,731.39677 C 213.19158,732.07295 215.35315,733.54815 217.09474,735.82237 C 218.83626,738.07618 219.70703,740.99584 219.70707,744.58136 C 219.70703,747.34739 219.20506,749.67288 218.20114,751.55783 C 217.19715,753.44283 215.9166,754.92827 214.35948,756.01416 C 212.82278,757.0796 211.25538,757.78646 209.65728,758.13476 C 207.48543,758.56504 204.34039,758.78017 200.22215,758.78016 L 194.29062,758.78016 L 194.29062,775.77568 L 185.19356,775.77568 M 194.29062,738.3425 L 194.29062,751.12756 L 199.26942,751.12756 C 202.85495,751.12758 205.25215,750.89196 206.46101,750.42069 C 207.66983,749.94948 208.61232,749.21188 209.28848,748.2079 C 209.98507,747.20397 210.33338,746.0361 210.33341,744.7043 C 210.33338,743.06522 209.85189,741.71295 208.88895,740.6475 C 207.92594,739.58211 206.70685,738.91623 205.23168,738.64983 C 204.14575,738.44498 201.96368,738.34254 198.68548,738.3425 L 194.29062,738.3425" /> + d="M 224.93174,761.11589 L 233.78294,760.25536 C 234.31564,763.22626 235.3913,765.40832 237.00994,766.80155 C 238.64903,768.1948 240.85158,768.89142 243.6176,768.89142 C 246.54748,768.89142 248.75004,768.27676 250.22526,767.04742 C 251.72092,765.79761 252.46876,764.3429 252.46879,762.68329 C 252.46876,761.61788 252.15119,760.71637 251.51606,759.97876 C 250.90137,759.22068 249.81546,758.56504 248.25833,758.01182 C 247.19288,757.64304 244.76495,756.9874 240.97453,756.04489 C 236.09817,754.83607 232.67653,753.35063 230.70961,751.58856 C 227.9436,749.10943 226.5606,746.08733 226.56061,742.52223 C 226.5606,740.22751 227.206,738.08643 228.49681,736.09897 C 229.80809,734.0911 231.68282,732.56468 234.121,731.5197 C 236.57966,730.47482 239.5403,729.95235 243.00293,729.9523 C 248.65784,729.95235 252.90928,731.19193 255.75726,733.67104 C 258.62567,736.15023 260.1316,739.45918 260.27506,743.5979 L 251.178,743.99743 C 250.78868,741.68222 249.94864,740.02262 248.65786,739.01863 C 247.38753,737.99423 245.47182,737.48201 242.91073,737.48197 C 240.26765,737.48201 238.19828,738.02496 236.7026,739.11083 C 235.73961,739.80749 235.25812,740.73973 235.25814,741.90757 C 235.25812,742.97302 235.70888,743.88477 236.6104,744.64283 C 237.75776,745.60584 240.54425,746.60979 244.96987,747.6547 C 249.39544,748.69966 252.66341,749.78556 254.77379,750.91243 C 256.9046,752.01885 258.5642,753.54527 259.75259,755.49169 C 260.9614,757.41766 261.56582,759.80462 261.56586,762.65255 C 261.56582,765.23416 260.84871,767.65185 259.41452,769.90562 C 257.98027,772.1594 255.95187,773.83948 253.32933,774.94588 C 250.70672,776.03179 247.43875,776.57475 243.5254,776.57475 C 237.82948,776.57475 233.4551,775.26346 230.40227,772.64088 C 227.34943,769.99782 225.52592,766.15616 224.93174,761.11589" /> + d="M 298.23071,775.77568 L 282.12645,730.72064 L 291.99185,730.72064 L 303.39391,764.06629 L 314.42717,730.72064 L 324.07743,730.72064 L 307.94244,775.77568 L 298.23071,775.77568" /> + d="M 334.2809,751.46563 C 332.0476,750.52316 330.41874,749.23237 329.3943,747.59323 C 328.39034,745.93366 327.88836,744.1204 327.88837,742.15343 C 327.88836,738.79329 329.05623,736.01705 331.39197,733.8247 C 333.74818,731.63244 337.08786,730.53628 341.41103,730.53624 C 345.69318,730.53628 349.01238,731.63244 351.36862,733.8247 C 353.7453,736.01705 354.93366,738.79329 354.93369,742.15343 C 354.93366,744.24333 354.3907,746.10781 353.30482,747.7469 C 352.21888,749.36554 350.69246,750.60512 348.72556,751.46563 C 351.22517,752.46961 353.12039,753.93456 354.41122,755.86049 C 355.72248,757.78646 356.37812,760.0095 356.37815,762.52962 C 356.37812,766.68887 355.04634,770.06953 352.38282,772.67162 C 349.73973,775.2737 346.21565,776.57475 341.81056,776.57475 C 337.71277,776.57475 334.30138,775.49908 331.57637,773.34775 C 328.35961,770.80713 326.75123,767.32403 326.75123,762.89842 C 326.75123,760.46026 327.35565,758.22697 328.5645,756.19856 C 329.77334,754.14969 331.6788,752.57205 334.2809,751.46563 M 336.06343,742.7681 C 336.06342,744.48919 336.54491,745.83122 337.5079,746.79416 C 338.49135,747.75717 339.79239,748.23866 341.41103,748.23863 C 343.05012,748.23866 344.36141,747.75717 345.34489,746.79416 C 346.32834,745.81073 346.82007,744.45846 346.82009,742.73736 C 346.82007,741.11878 346.32834,739.82798 345.34489,738.86497 C 344.38189,737.88154 343.10134,737.38981 341.50323,737.38977 C 339.84361,737.38981 338.52208,737.88154 337.53863,738.86497 C 336.55515,739.84847 336.06342,741.14951 336.06343,742.7681 M 335.26436,762.06862 C 335.26435,764.44534 335.86877,766.29958 337.07763,767.63135 C 338.30695,768.96314 339.83337,769.62902 341.65689,769.62902 C 343.43941,769.62902 344.9146,768.99387 346.08249,767.72355 C 347.25033,766.43276 347.83427,764.57852 347.83429,762.16082 C 347.83427,760.05048 347.24009,758.36015 346.05176,757.08982 C 344.86338,755.79904 343.35745,755.15365 341.53396,755.15362 C 339.42359,755.15365 337.84595,755.881 336.80103,757.33569 C 335.77657,758.79042 335.26435,760.36806 335.26436,762.06862" /> - - + - + - + + style="fill:url(#linearGradient7362);fill-opacity:1;fill-rule:evenodd;stroke:#515454;stroke-width:4.19999981;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + cx="-36.611858" + cy="572.3067" + r="23.877298" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:20px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';letter-spacing:0px;word-spacing:0px;fill:#e9eaed;fill-opacity:1;stroke:none" + d="M 54.226135,593.00714 L 54.226135,578.69073 L 58.864807,578.69073 C 60.622612,578.69075 61.768444,578.76233 62.302307,578.90558 C 63.122609,579.12044 63.809458,579.58919 64.362854,580.31183 C 64.916227,581.02799 65.19292,581.95572 65.192932,583.09503 C 65.19292,583.97395 65.033415,584.71288 64.714417,585.31183 C 64.395394,585.91079 63.988494,586.3828 63.493713,586.72784 C 63.005422,587.06639 62.507376,587.291 61.999573,587.40167 C 61.30946,587.5384 60.310112,587.60676 59.001526,587.60675 L 57.11676,587.60675 L 57.11676,593.00714 L 54.226135,593.00714 M 57.11676,581.11261 L 57.11676,585.17511 L 58.698792,585.17511 C 59.838107,585.17512 60.599825,585.10021 60.983948,584.9505 C 61.368054,584.80077 61.667533,584.56639 61.882385,584.24738 C 62.10373,583.92837 62.214407,583.55728 62.214417,583.13409 C 62.214407,582.61327 62.061412,582.18358 61.755432,581.84503 C 61.449434,581.5065 61.062064,581.29491 60.593323,581.21027 C 60.248263,581.14517 59.554905,581.11257 58.513245,581.11257 L 57.11676,581.11257" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:20px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';letter-spacing:0px;word-spacing:0px;fill:#e9eaed;fill-opacity:1;stroke:none" + d="M 66.931213,587.67511 C 66.931213,586.76366 67.155822,585.8815 67.605042,585.02863 C 68.054258,584.17577 68.689023,583.52473 69.509338,583.0755 C 70.336157,582.62629 71.25738,582.40168 72.27301,582.40167 C 73.842013,582.40168 75.127819,582.91275 76.130432,583.93488 C 77.133025,584.95051 77.634327,586.23631 77.634338,587.7923 C 77.634327,589.36131 77.126515,590.66339 76.110901,591.69855 C 75.101777,592.72719 73.828992,593.24152 72.292542,593.24152 C 71.342015,593.24152 70.433813,593.02667 69.567932,592.59698 C 68.708555,592.1673 68.054258,591.53904 67.605042,590.71222 C 67.155822,589.87889 66.931213,588.86652 66.931213,587.67511 M 69.743713,587.82159 C 69.74371,588.85024 69.98785,589.638 70.476135,590.18488 C 70.964412,590.73175 71.566625,591.00519 72.282776,591.00519 C 72.998915,591.00519 73.597873,590.73175 74.079651,590.18488 C 74.567924,589.638 74.812064,588.84373 74.812073,587.80206 C 74.812064,586.78644 74.567924,586.00519 74.079651,585.45831 C 73.597873,584.91145 72.998915,584.63801 72.282776,584.638 C 71.566625,584.63801 70.964412,584.91145 70.476135,585.45831 C 69.98785,586.00519 69.74371,586.79295 69.743713,587.82159" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:20px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';letter-spacing:0px;word-spacing:0px;fill:#e9eaed;fill-opacity:1;stroke:none" + d="M 81.726135,593.00714 L 78.444885,582.63605 L 81.110901,582.63605 L 83.05426,589.43292 L 84.84137,582.63605 L 87.487854,582.63605 L 89.21637,589.43292 L 91.198792,582.63605 L 93.90387,582.63605 L 90.573792,593.00714 L 87.937073,593.00714 L 86.149963,586.33722 L 84.392151,593.00714 L 81.726135,593.00714" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:20px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';letter-spacing:0px;word-spacing:0px;fill:#e9eaed;fill-opacity:1;stroke:none" + d="M 101.4234,589.70636 L 104.15778,590.16534 C 103.8062,591.16795 103.24956,591.93292 102.48785,592.46027 C 101.73264,592.9811 100.78537,593.24152 99.646057,593.24152 C 97.842668,593.24152 96.508034,592.65232 95.642151,591.47394 C 94.958556,590.52993 94.61676,589.33852 94.61676,587.89972 C 94.61676,586.18098 95.065978,584.83658 95.964417,583.86652 C 96.862851,582.88996 97.998918,582.40168 99.37262,582.40167 C 100.91558,582.40168 102.13303,582.91275 103.02496,583.93488 C 103.91688,584.95051 104.34331,586.50975 104.30426,588.61261 L 97.42926,588.61261 C 97.44879,589.42642 97.670142,590.06118 98.093323,590.51691 C 98.516495,590.96613 99.043839,591.19074 99.675354,591.19073 C 100.10504,591.19074 100.46636,591.07355 100.75934,590.83917 C 101.0523,590.6048 101.27365,590.2272 101.4234,589.70636 M 101.57965,586.93292 C 101.56015,586.13866 101.35503,585.53645 100.96442,585.12628 C 100.57378,584.70962 100.09852,584.50129 99.538635,584.50128 C 98.939672,584.50129 98.444881,584.71939 98.05426,585.15558 C 97.663632,585.59178 97.471574,586.18423 97.478088,586.93292 L 101.57965,586.93292" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:20px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';letter-spacing:0px;word-spacing:0px;fill:#e9eaed;fill-opacity:1;stroke:none" + d="M 109.17731,593.00714 L 106.43317,593.00714 L 106.43317,582.63605 L 108.98199,582.63605 L 108.98199,584.11066 C 109.41819,583.41405 109.80881,582.95507 110.15387,582.7337 C 110.50543,582.51236 110.90256,582.40168 111.34528,582.40167 C 111.97027,582.40168 112.57248,582.57421 113.15192,582.91925 L 112.30231,585.31183 C 111.84006,585.01236 111.41037,584.86262 111.01324,584.86261 C 110.62912,584.86262 110.3036,584.97004 110.03668,585.18488 C 109.76975,585.39322 109.55816,585.77408 109.40192,586.32745 C 109.25217,586.88085 109.1773,588.0397 109.17731,589.80402 L 109.17731,593.00714" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:20px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';letter-spacing:0px;word-spacing:0px;fill:#e9eaed;fill-opacity:1;stroke:none" + d="M 141.1961,587.99147 L 143.60567,587.75721 C 143.75068,588.56597 144.04351,589.15999 144.48415,589.53928 C 144.93036,589.91856 145.52996,590.1082 146.28296,590.1082 C 147.08056,590.1082 147.68016,589.94087 148.08176,589.60621 C 148.48892,589.26597 148.69251,588.86996 148.69252,588.41816 C 148.69251,588.12813 148.60602,587.88271 148.43316,587.68191 C 148.26582,587.47554 147.9702,587.29705 147.5463,587.14645 C 147.25625,587.04606 146.5953,586.86757 145.56344,586.61099 C 144.23594,586.28191 143.30447,585.87753 142.76901,585.39784 C 142.01602,584.72295 141.63953,583.90025 141.63953,582.92971 C 141.63953,582.30503 141.81523,581.72216 142.16662,581.18111 C 142.52359,580.63451 143.03395,580.21898 143.6977,579.9345 C 144.36702,579.65005 145.17299,579.50782 146.11563,579.5078 C 147.65506,579.50782 148.81243,579.84527 149.58773,580.52015 C 150.3686,581.19507 150.77856,582.09586 150.81762,583.22255 L 148.34112,583.33131 C 148.23514,582.70104 148.00645,582.24925 147.65506,581.97593 C 147.30924,581.69706 146.78773,581.55761 146.09052,581.5576 C 145.371,581.55761 144.80765,581.70543 144.40049,582.00103 C 144.13833,582.19069 144.00726,582.44447 144.00726,582.76239 C 144.00726,583.05243 144.12997,583.30064 144.37539,583.50701 C 144.68774,583.76917 145.4463,584.04247 146.65108,584.32693 C 147.85586,584.61139 148.7455,584.90702 149.32,585.21378 C 149.90008,585.51498 150.35187,585.93052 150.67538,586.4604 C 151.00446,586.9847 151.169,587.6345 151.16901,588.4098 C 151.169,589.11259 150.97378,589.77075 150.58335,590.3843 C 150.1929,590.99784 149.64071,591.45522 148.92678,591.75641 C 148.21283,592.05202 147.32319,592.19984 146.25785,592.19984 C 144.70725,592.19984 143.51642,591.84286 142.68535,591.12892 C 141.85427,590.4094 141.35786,589.36358 141.1961,587.99147" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:20px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';letter-spacing:0px;word-spacing:0px;fill:#e9eaed;fill-opacity:1;stroke:none" + d="M 156.02996,591.9823 L 156.02996,581.79187 L 152.39053,581.79187 L 152.39053,579.71697 L 162.13753,579.71697 L 162.13753,581.79187 L 158.50646,581.79187 L 158.50646,591.9823 L 156.02996,591.9823" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:20px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';letter-spacing:0px;word-spacing:0px;fill:#e9eaed;fill-opacity:1;stroke:none" + d="M 173.49928,591.9823 L 170.80526,591.9823 L 169.73434,589.19625 L 164.83155,589.19625 L 163.8192,591.9823 L 161.19211,591.9823 L 165.96941,579.71697 L 168.58813,579.71697 L 173.49928,591.9823 M 168.93952,587.12972 L 167.24949,582.57832 L 165.59291,587.12972 L 168.93952,587.12972" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:20px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';letter-spacing:0px;word-spacing:0px;fill:#e9eaed;fill-opacity:1;stroke:none" + d="M 176.3439,591.9823 L 176.3439,581.79187 L 172.70446,581.79187 L 172.70446,579.71697 L 182.45147,579.71697 L 182.45147,581.79187 L 178.8204,581.79187 L 178.8204,591.9823 L 176.3439,591.9823" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:20px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';letter-spacing:0px;word-spacing:0px;fill:#e9eaed;fill-opacity:1;stroke:none" + d="M 184.00764,579.71697 L 186.48414,579.71697 L 186.48414,586.35999 C 186.48413,587.41419 186.51484,588.09745 186.57614,588.4098 C 186.68211,588.91179 186.9331,589.31618 187.32913,589.62294 C 187.73071,589.92414 188.27733,590.07474 188.96897,590.07474 C 189.67175,590.07474 190.20163,589.93251 190.55861,589.64804 C 190.91558,589.358 191.13032,589.00382 191.20283,588.5855 C 191.27533,588.16717 191.31158,587.47275 191.31159,586.50223 L 191.31159,579.71697 L 193.78809,579.71697 L 193.78809,586.1592 C 193.78808,587.63171 193.72119,588.67195 193.58729,589.27991 C 193.45342,589.88788 193.20521,590.40103 192.84267,590.81936 C 192.48569,591.23768 192.00601,591.57235 191.40363,591.82334 C 190.80123,592.06876 190.01477,592.19147 189.04427,592.19147 C 187.87295,592.19147 186.98331,592.0576 186.37535,591.78987 C 185.77295,591.51657 185.29606,591.16518 184.94466,590.73569 C 184.59327,590.30063 184.36179,589.84605 184.25025,589.37195 C 184.08849,588.66916 184.00761,587.63171 184.00761,586.25959 L 184.00761,579.71697" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:20px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';letter-spacing:0px;word-spacing:0px;fill:#e9eaed;fill-opacity:1;stroke:none" + d="M 195.77935,587.99147 L 198.18892,587.75721 C 198.33394,588.56597 198.62676,589.15999 199.0674,589.53928 C 199.51361,589.91856 200.11321,590.1082 200.86621,590.1082 C 201.66381,590.1082 202.26341,589.94087 202.66501,589.60621 C 203.07217,589.26597 203.27576,588.86996 203.27577,588.41816 C 203.27576,588.12813 203.18927,587.88271 203.0164,587.68191 C 202.84906,587.47554 202.55345,587.29705 202.12955,587.14645 C 201.83951,587.04606 201.17854,586.86757 200.14668,586.61099 C 198.81919,586.28191 197.88771,585.87753 197.35226,585.39784 C 196.59927,584.72295 196.22278,583.90025 196.22278,582.92971 C 196.22278,582.30503 196.39847,581.72216 196.74987,581.18111 C 197.10685,580.63451 197.6172,580.21898 198.28095,579.9345 C 198.95027,579.65005 199.75624,579.50782 200.69888,579.5078 C 202.23831,579.50782 203.39568,579.84527 204.17098,580.52015 C 204.95185,581.19507 205.36181,582.09586 205.40087,583.22255 L 202.92437,583.33131 C 202.81839,582.70104 202.5897,582.24925 202.23831,581.97593 C 201.89249,581.69706 201.37098,581.55761 200.67378,581.5576 C 199.95425,581.55761 199.3909,581.70543 198.98373,582.00103 C 198.72158,582.19069 198.5905,582.44447 198.59051,582.76239 C 198.5905,583.05243 198.71321,583.30064 198.95864,583.50701 C 199.27098,583.76917 200.02955,584.04247 201.23434,584.32693 C 202.43911,584.61139 203.32875,584.90702 203.90326,585.21378 C 204.48332,585.51498 204.93512,585.93052 205.25863,586.4604 C 205.5877,586.9847 205.75225,587.6345 205.75226,588.4098 C 205.75225,589.11259 205.55703,589.77075 205.1666,590.3843 C 204.77615,590.99784 204.22396,591.45522 203.51003,591.75641 C 202.79607,592.05202 201.90643,592.19984 200.8411,592.19984 C 199.2905,592.19984 198.09967,591.84286 197.2686,591.12892 C 196.43752,590.4094 195.94111,589.36358 195.77935,587.99147" /> @@ -3536,13 +3586,13 @@ id="layer7" inkscape:label="No-GPS" style="display:inline" - transform="translate(1.9073488e-7,3.930618e-6)"> + transform="translate(-4.5499998,3.9657339e-6)"> - - + - + - + + transform="matrix(0.52050376,0,0,0.52050376,367.73876,862.48512)" + cx="-36.611858" + cy="572.3067" + r="23.877298" /> NO GPS + d="M 61.404526,601.51025 L 339.15488,601.51025 C 382.12949,601.51025 416.72639,634.21394 416.72639,674.83691 L 416.72639,962.19294 C 416.72639,1002.8159 382.12949,1035.5196 339.15488,1035.5196 L 61.404526,1035.5196 C 18.429909,1035.5196 -16.166985,1002.8159 -16.166985,962.19294 L -16.166985,674.83691 C -16.166985,634.21394 18.429909,601.51025 61.404526,601.51025 Z" + style="fill:none;stroke:#272727;stroke-width:6.54750299;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - - + - + - + + style="fill:url(#linearGradient10259);fill-opacity:1;fill-rule:evenodd;stroke:#515454;stroke-width:4.19999981;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + cx="-36.611858" + cy="572.3067" + r="23.877298" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:11.90251064px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none" + d="M 92.0595,965.29836 L 92.0595,963.86285 L 95.099057,963.86285 L 95.099057,967.25693 C 94.792964,967.61726 94.359019,967.92722 93.79722,968.18681 C 93.23541,968.44641 92.671669,968.5762 92.105994,968.5762 C 91.416327,968.5762 90.808029,968.40766 90.281098,968.07058 C 89.754162,967.72962 89.335715,967.22206 89.025755,966.54789 C 88.719667,965.86986 88.566624,965.07364 88.566625,964.15926 C 88.566624,963.22163 88.721605,962.4196 89.031566,961.75318 C 89.345401,961.08677 89.750287,960.5889 90.246227,960.25956 C 90.746037,959.93023 91.342711,959.76556 92.036253,959.76555 C 92.869269,959.76556 93.535685,959.97866 94.035503,960.40485 C 94.539183,960.82718 94.862705,961.44904 95.006069,962.27043 L 93.611243,962.59008 C 93.506626,962.15226 93.314838,961.81712 93.035878,961.58464 C 92.756908,961.35218 92.4237,961.23594 92.036253,961.23593 C 91.4357,961.23594 90.949449,961.47035 90.577498,961.93916 C 90.205542,962.40411 90.019566,963.11508 90.019568,964.07208 C 90.019566,965.09883 90.22104,965.87954 90.623992,966.41422 C 90.968821,966.87529 91.4357,967.10583 92.024629,967.10582 C 92.299716,967.10583 92.584492,967.04192 92.87896,966.91404 C 93.177293,966.7823 93.442697,966.60408 93.675173,966.37935 L 93.675173,965.29836 L 92.0595,965.29836" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:11.90251064px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none" + d="M 96.406706,968.43091 L 96.406706,959.91085 L 98.673298,959.91085 C 99.517938,959.91086 100.07006,959.95155 100.32965,960.0329 C 100.74422,960.16464 101.08518,960.44554 101.35252,960.8756 C 101.62374,961.30568 101.75934,961.85974 101.75935,962.53777 C 101.75934,963.15382 101.64311,963.67107 101.41064,964.08951 C 101.17817,964.50409 100.88758,964.79662 100.53888,964.96709 C 100.19017,965.1337 99.589617,965.217 98.737227,965.217 L 97.813155,965.217 L 97.813155,968.43091 L 96.406706,968.43091 M 97.813155,961.35217 L 97.813155,963.76987 L 98.591933,963.76987 C 99.114989,963.76987 99.469507,963.73307 99.655487,963.65944 C 99.845334,963.58584 100.00031,963.4541 100.12043,963.26424 C 100.24053,963.07052 100.30059,962.83418 100.30059,962.55521 C 100.30059,962.27237 100.23859,962.03409 100.11462,961.84036 C 99.990629,961.64664 99.837585,961.51684 99.655487,961.45097 C 99.473381,961.38507 99.087867,961.35217 98.498944,961.35217 L 97.813155,961.35217" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:11.90251064px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none" + d="M 102.56137,965.65869 L 103.93876,965.49596 C 104.09374,966.5847 104.6013,967.12907 105.46145,967.12907 C 105.88764,967.12907 106.22279,967.01865 106.46689,966.7978 C 106.71098,966.57308 106.83302,966.29605 106.83303,965.96672 C 106.83302,965.77299 106.79043,965.60833 106.70517,965.47272 C 106.61987,965.33711 106.49013,965.22669 106.31578,965.14144 C 106.14142,965.05234 105.7191,964.9051 105.04881,964.69975 C 104.44826,964.51765 104.0085,964.32005 103.72954,964.10695 C 103.45057,963.89386 103.22779,963.61489 103.06119,963.27005 C 102.89846,962.92135 102.81709,962.54746 102.81709,962.14838 C 102.81709,961.68345 102.9217,961.265 103.13093,960.89304 C 103.34402,960.52109 103.63655,960.24019 104.00851,960.05033 C 104.38046,959.86049 104.83959,959.76556 105.3859,959.76555 C 106.20729,959.76556 106.84852,959.98835 107.30959,960.43391 C 107.77065,960.87949 108.01475,961.51684 108.04188,962.34598 L 106.62961,962.42158 C 106.56761,961.96439 106.43395,961.64474 106.2286,961.46263 C 106.02325,961.28054 105.73072,961.18949 105.35102,961.18948 C 104.97132,961.18949 104.67879,961.26888 104.47345,961.42776 C 104.2681,961.58662 104.16542,961.78422 104.16542,962.02056 C 104.16542,962.25304 104.25842,962.4487 104.44439,962.60755 C 104.63036,962.76641 105.0585,962.94077 105.72879,963.13061 C 106.43782,963.33597 106.94926,963.55294 107.2631,963.78153 C 107.5808,964.00626 107.82296,964.29878 107.98957,964.65911 C 108.15617,965.01557 108.23947,965.44951 108.23948,965.96094 C 108.23947,966.70098 108.01087,967.32284 107.55369,967.82652 C 107.10036,968.33021 106.38939,968.58205 105.42077,968.58205 C 103.70823,968.58205 102.7551,967.60761 102.56137,965.65873" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:11.90251064px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none" + d="M 147.50381,968.43091 L 147.50381,959.91085 L 149.7704,959.91085 C 150.61505,959.91086 151.16716,959.95155 151.42676,960.0329 C 151.84133,960.16464 152.18228,960.44554 152.44963,960.8756 C 152.72084,961.30568 152.85645,961.85974 152.85646,962.53777 C 152.85645,963.15382 152.74021,963.67107 152.50775,964.08951 C 152.27527,964.50409 151.98468,964.79662 151.63598,964.96709 C 151.28727,965.1337 150.68672,965.217 149.83433,965.217 L 148.91026,965.217 L 148.91026,968.43091 L 147.50381,968.43091 M 148.91026,961.35217 L 148.91026,963.76987 L 149.68904,963.76987 C 150.2121,963.76987 150.56661,963.73307 150.75259,963.65944 C 150.94244,963.58584 151.09742,963.4541 151.21754,963.26424 C 151.33764,963.07052 151.3977,962.83418 151.3977,962.55521 C 151.3977,962.27237 151.3357,962.03409 151.21172,961.84036 C 151.08774,961.64664 150.93469,961.51684 150.75259,961.45097 C 150.57049,961.38507 150.18497,961.35217 149.59605,961.35217 L 148.91026,961.35217" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:11.90251064px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none" + d="M 153.69335,965.25768 C 153.69335,964.65326 153.81346,964.10308 154.05368,963.60714 C 154.2939,963.1112 154.60774,962.73925 154.99519,962.49128 C 155.38264,962.24331 155.81852,962.11933 156.30284,962.11932 C 157.11648,962.11933 157.75578,962.43898 158.22072,963.07827 C 158.68566,963.71369 158.91813,964.4576 158.91814,965.30999 C 158.91813,965.94541 158.79608,966.51884 158.55199,967.03027 C 158.31177,967.54171 157.99406,967.92722 157.59886,968.18681 C 157.20753,968.44253 156.77746,968.57039 156.30865,968.57039 C 155.55699,968.57039 154.93319,968.28368 154.43726,967.71025 C 153.94132,967.13682 153.69335,966.3193 153.69335,965.25768 M 155.06493,965.34488 C 155.06493,965.96868 155.18698,966.44137 155.43107,966.76295 C 155.67516,967.08066 155.96963,967.23952 156.31446,967.23951 C 156.65154,967.23952 156.94019,967.07872 157.18042,966.75714 C 157.42063,966.43555 157.54074,965.96093 157.54075,965.33325 C 157.54074,964.72108 157.41869,964.25421 157.1746,963.93262 C 156.93051,963.61104 156.63798,963.45024 156.29703,963.45024 C 155.95994,963.45024 155.66935,963.61104 155.42526,963.93262 C 155.18504,964.25421 155.06493,964.72496 155.06493,965.34488" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:11.90251064px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none" + d="M 160.92901,968.43091 L 159.32496,962.25881 L 160.6268,962.25881 L 161.57412,966.3038 L 162.44588,962.25881 L 163.73609,962.25881 L 164.5788,966.3038 L 165.54937,962.25881 L 166.86864,962.25881 L 165.24134,968.43091 L 163.95694,968.43091 L 163.08518,964.46147 L 162.22503,968.43091 L 160.92901,968.43091" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:11.90251064px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none" + d="M 170.51843,966.46653 L 171.84933,966.73968 C 171.6711,967.35961 171.39407,967.82067 171.01825,968.12288 C 170.64241,968.42122 170.18522,968.57039 169.64667,968.57039 C 168.89888,968.57039 168.32158,968.32048 167.91476,967.82067 C 167.43432,967.2395 167.1941,966.42585 167.1941,965.37973 C 167.1941,964.34911 167.43626,963.52384 167.92057,962.90391 C 168.33127,962.38086 168.86208,962.11933 169.513,962.11932 C 170.23753,962.11933 170.80514,962.38667 171.21585,962.92135 C 171.68853,963.53353 171.92488,964.43629 171.92488,965.62963 L 171.91888,965.81561 L 168.56549,965.81561 C 168.57349,966.3038 168.68172,966.68157 168.89095,966.94891 C 169.10404,967.21625 169.35976,967.34992 169.6581,967.34992 C 170.08817,967.34992 170.37488,967.05546 170.51824,966.46653 M 170.59384,964.81599 C 170.58224,964.33555 170.47954,963.97522 170.28581,963.735 C 170.09208,963.49091 169.86155,963.36886 169.59421,963.36885 C 169.31137,963.36886 169.07309,963.49478 168.87936,963.74662 C 168.68176,964.00234 168.5849,964.3588 168.58878,964.81599 L 170.59384,964.81599" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:11.90251064px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none" + d="M 174.30771,968.43091 L 172.96519,968.43091 L 172.96519,962.25881 L 174.20891,962.25881 L 174.20891,963.13638 C 174.42201,962.72569 174.61186,962.45447 174.77846,962.32274 C 174.94894,962.18713 175.1446,962.11933 175.36545,962.11932 C 175.67154,962.11933 175.96406,962.222 176.24303,962.42735 L 175.82458,963.85123 C 175.60373,963.67301 175.39451,963.58389 175.19691,963.58389 C 175.01093,963.58389 174.84626,963.65359 174.70291,963.79311 C 174.56343,963.92873 174.46269,964.17669 174.4007,964.53702 C 174.3387,964.89735 174.3077,965.5599 174.3077,966.52465 L 174.3077,968.43091" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:11.90251064px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none" + d="M 212.15979,968.43091 L 212.15979,959.91085 L 214.26946,959.91085 L 215.53643,965.72262 L 216.79177,959.91085 L 218.90725,959.91085 L 218.90725,968.43091 L 217.59961,968.43091 L 217.59961,961.72412 L 216.21059,968.43091 L 214.85064,968.43091 L 213.47325,961.72412 L 213.47325,968.43091 L 212.15979,968.43091" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:11.90251064px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none" + d="M 224.78876,965.29836 L 226.15453,965.82723 C 225.94142,966.78037 225.58691,967.47778 225.09097,967.91947 C 224.59503,968.35729 223.9848,968.5762 223.26027,968.5762 C 222.34975,968.5762 221.61166,968.22556 221.04598,967.52427 C 220.39506,966.7145 220.0696,965.62189 220.0696,964.24643 C 220.0696,962.79349 220.397,961.65633 221.05179,960.83492 C 221.62134,960.12202 222.38656,959.76556 223.34744,959.76555 C 224.13009,959.76556 224.78488,960.0329 225.31182,960.56758 C 225.68764,960.94729 225.96273,961.51103 226.13709,962.25881 L 224.74227,962.66563 C 224.65317,962.20457 224.47492,961.85199 224.20758,961.60789 C 223.94411,961.35993 223.63221,961.23594 223.27189,961.23593 C 222.75657,961.23594 222.33619,961.46066 222.01073,961.9101 C 221.68527,962.35955 221.52254,963.10152 221.52255,964.13601 C 221.52254,965.20925 221.6814,965.97253 221.99911,966.42585 C 222.31682,966.87917 222.72945,967.10583 223.23702,967.10582 C 223.60897,967.10583 223.93055,966.96247 224.20177,966.67575 C 224.47298,966.38517 224.66865,965.92604 224.78876,965.29836" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:11.90251064px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none" + d="M 227.34594,959.91085 L 228.75239,959.91085 L 228.75239,964.5254 C 228.75239,965.24219 228.76979,965.70906 228.80469,965.92603 C 228.86669,966.30186 229.01391,966.59245 229.24638,966.7978 C 229.48272,967.00315 229.79268,967.10583 230.17627,967.10582 C 230.50172,967.10583 230.76712,967.03412 230.97248,966.89079 C 231.17782,966.74356 231.31731,966.54208 231.39093,966.28636 C 231.46843,966.02677 231.50716,965.47272 231.50716,964.6242 L 231.50716,959.91085 L 232.91942,959.91085 L 232.91942,964.38591 C 232.91942,965.5289 232.85742,966.35611 232.73345,966.86754 C 232.61333,967.3751 232.33824,967.78774 231.90817,968.10545 C 231.48197,968.41928 230.91823,968.5762 230.21695,968.5762 C 229.48854,968.5762 228.91898,968.44641 228.50829,968.18681 C 228.10146,967.92335 227.80506,967.55527 227.61909,967.08258 C 227.43698,966.60601 227.34593,965.73037 227.34593,964.45566 L 227.34593,959.91085" /> + points="186.194,11.031 181.129,13.319 186.083,4.74 191.036,13.319 " /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + transform="translate(-4.5499998,3.9657339e-6)"> @@ -4173,7 +4654,7 @@ + style="fill:#dbddde;fill-opacity:1;fill-rule:evenodd;stroke:#393a3e;stroke-width:0.85634619;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> @@ -4425,7 +4906,7 @@ + style="fill:url(#radialGradient13230);fill-opacity:1;fill-rule:evenodd;stroke:#393a3e;stroke-width:0.58099997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:url(#radialGradient13234);fill-opacity:1;fill-rule:evenodd;stroke:#393a3e;stroke-width:0.58099997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:url(#radialGradient13236);fill-opacity:1;fill-rule:evenodd;stroke:#393a3e;stroke-width:0.58099997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:url(#radialGradient13240);fill-opacity:1;fill-rule:evenodd;stroke:#393a3e;stroke-width:0.58099997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="fill:url(#radialGradient13244);fill-opacity:1;fill-rule:evenodd;stroke:#393a3e;stroke-width:0.58099997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="font-weight:normal;-inkscape-font-specification:'Arial Narrow Condensed'" + d="M 379.71034,1197.185 L 379.71034,1195.3655 L 385.09482,1195.3545 L 385.09482,1201.1092 C 384.26968,1201.9131 383.41635,1202.5197 382.53481,1202.9287 C 381.65326,1203.3307 380.74703,1203.5317 379.81613,1203.5317 C 378.57491,1203.5317 377.46769,1203.2214 376.49447,1202.6008 C 375.52124,1201.9801 374.74901,1201.0739 374.17777,1199.8821 C 373.61358,1198.6902 373.33149,1197.2586 373.33149,1195.5872 C 373.33149,1193.8946 373.61711,1192.4207 374.18835,1191.1654 C 374.75959,1189.9101 375.50714,1188.9862 376.431,1188.3938 C 377.35485,1187.7944 378.44797,1187.4946 379.71034,1187.4946 C 380.64125,1187.4946 381.45579,1187.6674 382.15398,1188.013 C 382.85216,1188.3585 383.42692,1188.8487 383.87829,1189.4834 C 384.32962,1190.1181 384.66814,1190.9891 384.89382,1192.0963 L 383.38109,1192.604 C 383.17657,1191.7296 382.91915,1191.0772 382.60886,1190.647 C 382.29855,1190.2098 381.88951,1189.8677 381.38175,1189.6209 C 380.87397,1189.3741 380.30273,1189.2507 379.66803,1189.2506 C 378.74417,1189.2507 377.94725,1189.4763 377.27728,1189.9277 C 376.61436,1190.372 376.07838,1191.0666 375.66935,1192.0116 C 375.26736,1192.9567 375.06637,1194.1097 375.06637,1195.4708 C 375.06637,1197.5442 375.50009,1199.0993 376.36753,1200.136 C 377.23496,1201.1656 378.36334,1201.6804 379.75266,1201.6804 C 380.41557,1201.6804 381.0926,1201.5217 381.78374,1201.2044 C 382.48191,1200.887 383.03552,1200.5097 383.44457,1200.0725 L 383.44457,1197.1845 L 379.71034,1197.1845" /> + style="font-weight:normal;-inkscape-font-specification:'Arial Narrow Condensed'" + d="M 390.8178,1203.2677 L 390.8178,1189.5897 L 386.6287,1189.5897 L 386.6287,1187.7596 L 396.71004,1187.7596 L 396.71004,1189.5897 L 392.49979,1189.5897 L 392.49979,1203.2677 L 390.8178,1203.2677" /> + style="font-weight:normal;-inkscape-font-specification:'Arial Narrow Condensed'" + d="M 398.43434,1203.2677 L 398.43434,1187.7596 L 403.22642,1187.7596 C 404.35479,1187.7596 405.18697,1187.8586 405.72295,1188.0558 C 406.45639,1188.3238 407.04173,1188.821 407.47899,1189.5473 C 407.91622,1190.2738 408.13485,1191.1659 408.13486,1192.2237 C 408.13485,1193.6201 407.7787,1194.759 407.06643,1195.6406 C 406.35413,1196.5221 405.12349,1196.9629 403.37452,1196.9629 L 400.11633,1196.9629 L 400.11633,1203.2677 L 398.43434,1203.2677 M 400.11633,1195.1328 L 403.40625,1195.1328 C 404.44294,1195.1328 405.20107,1194.9001 405.68064,1194.4346 C 406.16019,1193.9621 406.39997,1193.2534 406.39998,1192.3083 C 406.39997,1191.6948 406.28008,1191.1694 406.04031,1190.7321 C 405.80757,1190.2949 405.52195,1189.9952 405.18345,1189.833 C 404.85198,1189.6708 404.249,1189.5897 403.37452,1189.5897 L 400.11633,1189.5897 L 400.11633,1195.1328" /> + style="font-weight:normal;-inkscape-font-specification:'Arial Narrow Condensed'" + d="M 407.59535,1203.2677 L 412.48263,1187.7596 L 414.29156,1187.7596 L 419.4962,1203.2677 L 417.57091,1203.2677 L 416.08991,1198.5708 L 410.77949,1198.5708 L 409.38312,1203.2677 L 407.59535,1203.2677 M 411.2661,1196.8994 L 415.57156,1196.8994 L 414.24925,1192.6045 C 413.8402,1191.2858 413.54048,1190.2138 413.35007,1189.3887 C 413.18786,1190.3831 412.95866,1191.3704 412.66247,1192.3507 L 411.2661,1196.8994" /> + style="font-weight:normal;-inkscape-font-specification:'Arial Narrow Condensed'" + d="M 420.19438,1195.6194 C 420.19438,1193.0171 420.54347,1191.046 421.24165,1189.706 C 421.94689,1188.3661 422.98358,1187.6961 424.35174,1187.6961 C 425.56474,1187.6961 426.52033,1188.2391 427.21852,1189.3252 C 428.0648,1190.6369 428.48794,1192.735 428.48795,1195.6194 C 428.48794,1198.2076 428.13885,1200.1752 427.44067,1201.5222 C 426.74248,1202.8622 425.70579,1203.5322 424.33059,1203.5322 C 423.11758,1203.5322 422.1232,1202.9398 421.34744,1201.755 C 420.57873,1200.5702 420.19438,1198.525 420.19438,1195.6194 M 421.79174,1195.6194 C 421.79174,1198.1371 422.03152,1199.8262 422.51108,1200.6865 C 422.99769,1201.5399 423.61829,1201.9665 424.3729,1201.9665 C 425.08518,1201.9665 425.68111,1201.5328 426.16067,1200.6654 C 426.64022,1199.7979 426.88,1198.116 426.88001,1195.6194 C 426.88,1193.0947 426.6367,1191.4057 426.15009,1190.5523 C 425.67053,1189.699 425.04639,1189.2723 424.27769,1189.2723 C 423.57245,1189.2723 422.98006,1189.706 422.5005,1190.5735 C 422.02799,1191.4409 421.79174,1193.1229 421.79174,1195.6194" /> + style="font-weight:normal;-inkscape-font-specification:'Arial Narrow Condensed'" + d="M 435.97755,1203.2677 L 434.41193,1203.2677 L 434.41193,1191.1341 C 434.05225,1191.5573 433.56916,1191.991 432.96267,1192.4353 C 432.35616,1192.8725 431.79903,1193.204 431.29126,1193.4297 L 431.29126,1191.589 C 432.15164,1191.0953 432.90977,1190.4924 433.56564,1189.7801 C 434.22856,1189.0678 434.69401,1188.3731 434.96201,1187.6961 L 435.97755,1187.6961 L 435.97755,1203.2677" /> + style="font-weight:normal;-inkscape-font-specification:'Arial Narrow Condensed'" + d="M 439.99739,1195.6194 C 439.99739,1193.0171 440.34648,1191.046 441.04466,1189.706 C 441.7499,1188.3661 442.78659,1187.6961 444.15475,1187.6961 C 445.36775,1187.6961 446.32334,1188.2391 447.02153,1189.3252 C 447.86781,1190.6369 448.29095,1192.735 448.29096,1195.6194 C 448.29095,1198.2076 447.94186,1200.1752 447.24368,1201.5222 C 446.54549,1202.8622 445.5088,1203.5322 444.13359,1203.5322 C 442.92059,1203.5322 441.92621,1202.9398 441.15045,1201.755 C 440.38174,1200.5702 439.99739,1198.525 439.99739,1195.6194 M 441.59475,1195.6194 C 441.59475,1198.1371 441.83452,1199.8262 442.31409,1200.6865 C 442.8007,1201.5399 443.4213,1201.9665 444.17591,1201.9665 C 444.88819,1201.9665 445.48411,1201.5328 445.96368,1200.6654 C 446.44323,1199.7979 446.68301,1198.116 446.68302,1195.6194 C 446.68301,1193.0947 446.43971,1191.4057 445.9531,1190.5523 C 445.47354,1189.699 444.8494,1189.2723 444.0807,1189.2723 C 443.37546,1189.2723 442.78307,1189.706 442.30351,1190.5735 C 441.831,1191.4409 441.59475,1193.1229 441.59475,1195.6194" /> + d="M 444.40744,1038.0272 C 452.57603,1038.0272 459.19798,1044.6491 459.19798,1052.8177 C 459.19798,1060.9863 452.57603,1067.6082 444.40744,1067.6082 C 436.23885,1067.6082 429.6169,1060.9863 429.6169,1052.8177 C 429.6169,1044.6491 436.23885,1038.0272 444.40744,1038.0272 Z" + style="fill:url(#radialGradient13246);fill-opacity:1;fill-rule:evenodd;stroke:#87878d;stroke-width:5.08913088;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:40px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';letter-spacing:0px;word-spacing:0px;fill:#545352;fill-opacity:1;stroke:none"> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:40px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"> diff --git a/ground/gcs/src/plugins/setupwizard/resources/wizard.png b/ground/gcs/src/plugins/setupwizard/resources/wizard.png index 59bcdba13..4d3ae0cfc 100644 Binary files a/ground/gcs/src/plugins/setupwizard/resources/wizard.png and b/ground/gcs/src/plugins/setupwizard/resources/wizard.png differ diff --git a/ground/gcs/src/plugins/setupwizard/setupwizard.cpp b/ground/gcs/src/plugins/setupwizard/setupwizard.cpp index 2f512fa82..acfb1734e 100644 --- a/ground/gcs/src/plugins/setupwizard/setupwizard.cpp +++ b/ground/gcs/src/plugins/setupwizard/setupwizard.cpp @@ -2,7 +2,8 @@ ****************************************************************************** * * @file setupwizard.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup Setup Wizard Plugin @@ -67,8 +68,8 @@ SetupWizard::SetupWizard(QWidget *parent) : QWizard(parent), VehicleConfiguratio m_actuatorSettings << actuatorChannelSettings(); } setWizardStyle(QWizard::ModernStyle); - setMinimumSize(780, 600); - resize(780, 600); + setMinimumSize(780, 560); + resize(780, 560); createPages(); } @@ -98,6 +99,7 @@ int SetupWizard::nextId() const case CONTROLLER_CC: case CONTROLLER_CC3D: case CONTROLLER_REVO: + case CONTROLLER_SPARKY2: case CONTROLLER_DISCOVERYF4: return PAGE_INPUT; @@ -156,6 +158,7 @@ int SetupWizard::nextId() const switch (getControllerType()) { case CONTROLLER_REVO: case CONTROLLER_NANO: + case CONTROLLER_SPARKY2: return PAGE_GPS; default: @@ -168,6 +171,7 @@ int SetupWizard::nextId() const switch (getControllerType()) { case CONTROLLER_REVO: case CONTROLLER_NANO: + case CONTROLLER_SPARKY2: return PAGE_GPS; default: @@ -213,6 +217,7 @@ int SetupWizard::nextId() const case CONTROLLER_CC3D: case CONTROLLER_REVO: case CONTROLLER_NANO: + case CONTROLLER_SPARKY2: case CONTROLLER_DISCOVERYF4: switch (getVehicleType()) { case VEHICLE_FIXEDWING: @@ -254,6 +259,9 @@ QString SetupWizard::getSummaryText() case CONTROLLER_NANO: summary.append(tr("OpenPilot Nano")); break; + case CONTROLLER_SPARKY2: + summary.append(tr("TauLabs Sparky 2.0")); + break; case CONTROLLER_OPLINK: summary.append(tr("OpenPilot OPLink Radio Modem")); break; @@ -377,6 +385,18 @@ QString SetupWizard::getSummaryText() case INPUT_DSM: summary.append(tr("Spektrum Satellite")); break; + case INPUT_SRXL: + summary.append(tr("Multiplex SRXL")); + break; + case INPUT_HOTT_SUMD: + summary.append(tr("Graupner HoTT")); + break; + case INPUT_EXBUS: + summary.append(tr("Jeti EX.Bus")); + break; + case INPUT_IBUS: + summary.append(tr("FlySky IBus")); + break; default: summary.append(tr("Unknown")); } @@ -418,13 +438,19 @@ QString SetupWizard::getSummaryText() } // Show GPS Type - if (getControllerType() == CONTROLLER_REVO || getControllerType() == CONTROLLER_NANO) { + if (getControllerType() == CONTROLLER_REVO || getControllerType() == CONTROLLER_NANO || getControllerType() == CONTROLLER_SPARKY2) { summary.append("
"); summary.append("").append(tr("GPS type: ")).append(""); switch (getGpsType()) { case GPS_PLATINUM: summary.append(tr("OpenPilot Platinum")); break; + case GPS_NAZA: + summary.append(tr("Naza GPS")); + break; + case GPS_UBX_FLEXI_I2CMAG: + summary.append(tr("Generic UBLOX + I2C Magnetometer")); + break; case GPS_UBX: summary.append(tr("OpenPilot v8 or Generic UBLOX GPS")); break; @@ -437,7 +463,8 @@ QString SetupWizard::getSummaryText() } // Show Airspeed sensor type - if ((getControllerType() == CONTROLLER_REVO || getControllerType() == CONTROLLER_NANO) && getVehicleType() == VEHICLE_FIXEDWING) { + if ((getControllerType() == CONTROLLER_REVO || getControllerType() == CONTROLLER_NANO || getControllerType() == CONTROLLER_SPARKY2) + && getVehicleType() == VEHICLE_FIXEDWING) { summary.append("
"); summary.append("").append(tr("Airspeed Sensor: ")).append(""); switch (getAirspeedType()) { diff --git a/ground/gcs/src/plugins/setupwizard/setupwizard.pro b/ground/gcs/src/plugins/setupwizard/setupwizard.pro index bcf1153ed..ef10ac510 100644 --- a/ground/gcs/src/plugins/setupwizard/setupwizard.pro +++ b/ground/gcs/src/plugins/setupwizard/setupwizard.pro @@ -1,8 +1,7 @@ - TEMPLATE = lib TARGET = SetupWizard -QT += svg +QT += widgets svg include(../../plugin.pri) include(../../plugins/coreplugin/coreplugin.pri) @@ -10,7 +9,9 @@ include(../../plugins/uavobjectutil/uavobjectutil.pri) include(../../plugins/config/config.pri) LIBS *= -l$$qtLibraryName(Uploader) -HEADERS += setupwizardplugin.h \ + +HEADERS += \ + setupwizardplugin.h \ setupwizard.h \ pages/opstartpage.h \ pages/opendpage.h \ @@ -44,7 +45,8 @@ HEADERS += setupwizardplugin.h \ vehicletemplateexportdialog.h \ vehicletemplateselectorwidget.h -SOURCES += setupwizardplugin.cpp \ +SOURCES += \ + setupwizardplugin.cpp \ setupwizard.cpp \ pages/opstartpage.cpp \ pages/opendpage.cpp \ @@ -87,7 +89,6 @@ FORMS += \ pages/vehiclepage.ui \ pages/notyetimplementedpage.ui \ pages/helipage.ui \ - pages/surfacepage.ui \ pages/inputpage.ui \ pages/summarypage.ui \ connectiondiagram.ui \ diff --git a/ground/gcs/src/plugins/setupwizard/vehicleconfigurationhelper.cpp b/ground/gcs/src/plugins/setupwizard/vehicleconfigurationhelper.cpp index 715c9e27e..71e73b264 100644 --- a/ground/gcs/src/plugins/setupwizard/vehicleconfigurationhelper.cpp +++ b/ground/gcs/src/plugins/setupwizard/vehicleconfigurationhelper.cpp @@ -1,5 +1,5 @@ /** - ****************************************************************************** + *********************************************************************************** * * @file vehicleconfigurationhelper.cpp * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. @@ -9,7 +9,7 @@ * @addtogroup VehicleConfigurationHelper * @{ * @brief - *****************************************************************************/ + **********************************************************************************/ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,6 +28,9 @@ #include "vehicleconfigurationhelper.h" #include "extensionsystem/pluginmanager.h" +#include "uavobjectutilmanager.h" +#include + #include "hwsettings.h" #include "actuatorsettings.h" #include "attitudesettings.h" @@ -42,10 +45,13 @@ #include "accelgyrosettings.h" #include "gpssettings.h" #include "airspeedsettings.h" -#include -#include #include "auxmagsettings.h" +#include +#include +#include +#include + VehicleConfigurationHelper::VehicleConfigurationHelper(VehicleConfigurationSource *configSource) : m_configSource(configSource), m_uavoManager(0), m_transactionOK(false), m_transactionTimeout(false), m_currentTransactionObjectID(-1), @@ -159,50 +165,112 @@ void VehicleConfigurationHelper::applyHardwareConfiguration() } break; case VehicleConfigurationSource::INPUT_SBUS: - // We have to set teletry on flexport since s.bus needs the mainport. + // We have to set telemetry on flexiport since s.bus needs the mainport. data.CC_MainPort = HwSettings::CC_MAINPORT_SBUS; data.CC_FlexiPort = HwSettings::CC_FLEXIPORT_TELEMETRY; break; case VehicleConfigurationSource::INPUT_DSM: data.CC_FlexiPort = HwSettings::CC_FLEXIPORT_DSM; break; + case VehicleConfigurationSource::INPUT_SRXL: + data.CC_FlexiPort = HwSettings::CC_FLEXIPORT_SRXL; + break; + case VehicleConfigurationSource::INPUT_HOTT_SUMD: + data.CC_FlexiPort = HwSettings::CC_FLEXIPORT_HOTTSUMD; + break; + case VehicleConfigurationSource::INPUT_EXBUS: + data.CC_FlexiPort = HwSettings::CC_FLEXIPORT_EXBUS; + break; + case VehicleConfigurationSource::INPUT_IBUS: + data.CC_FlexiPort = HwSettings::CC_FLEXIPORT_IBUS; + break; default: break; } break; case VehicleConfigurationSource::CONTROLLER_REVO: case VehicleConfigurationSource::CONTROLLER_NANO: + case VehicleConfigurationSource::CONTROLLER_SPARKY2: case VehicleConfigurationSource::CONTROLLER_DISCOVERYF4: // Reset all ports to their defaults - data.RM_RcvrPort = HwSettings::RM_RCVRPORT_DISABLED; - data.RM_FlexiPort = HwSettings::RM_FLEXIPORT_DISABLED; + if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_SPARKY2) { + data.SPK2_RcvrPort = HwSettings::SPK2_RCVRPORT_DISABLED; + data.SPK2_FlexiPort = HwSettings::SPK2_FLEXIPORT_DISABLED; + } else { + data.RM_RcvrPort = HwSettings::RM_RCVRPORT_DISABLED; + data.RM_FlexiPort = HwSettings::RM_FLEXIPORT_DISABLED; + } - // Revo uses inbuilt Modem do not set mainport to be active telemetry link for the Revo + // Revo/Sparky2 uses inbuilt Modem do not set mainport to be active telemetry link for Revo/Sparky2 if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_REVO) { data.RM_MainPort = HwSettings::RM_MAINPORT_DISABLED; + } else if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_SPARKY2) { + data.SPK2_MainPort = HwSettings::SPK2_MAINPORT_DISABLED; } else { data.RM_MainPort = HwSettings::RM_MAINPORT_TELEMETRY; } switch (m_configSource->getInputType()) { case VehicleConfigurationSource::INPUT_PWM: - data.RM_RcvrPort = HwSettings::RM_RCVRPORT_PWM; + if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_SPARKY2) { + // this should not happen, sparky2 does not allow pwm + data.SPK2_RcvrPort = HwSettings::SPK2_RCVRPORT_DISABLED; + } else { + data.RM_RcvrPort = HwSettings::RM_RCVRPORT_PWM; + } break; case VehicleConfigurationSource::INPUT_PPM: - data.RM_RcvrPort = HwSettings::RM_RCVRPORT_PPM; + if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_SPARKY2) { + data.SPK2_RcvrPort = HwSettings::SPK2_RCVRPORT_PPM; + } else { + data.RM_RcvrPort = HwSettings::RM_RCVRPORT_PPM; + } break; case VehicleConfigurationSource::INPUT_SBUS: - data.RM_MainPort = HwSettings::RM_MAINPORT_SBUS; - // We have to set telemetry on flexport since s.bus needs the mainport on all but Revo. - if (m_configSource->getControllerType() != VehicleConfigurationSource::CONTROLLER_REVO) { - data.RM_FlexiPort = HwSettings::RM_FLEXIPORT_TELEMETRY; + if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_SPARKY2) { + data.SPK2_RcvrPort = HwSettings::SPK2_RCVRPORT_SBUS; + } else { + data.RM_MainPort = HwSettings::RM_MAINPORT_SBUS; + // We have to set telemetry to flexiport on all except Revo (and except Sparky2) since s.bus needs mainport. + if (m_configSource->getControllerType() != VehicleConfigurationSource::CONTROLLER_REVO) { + data.RM_FlexiPort = HwSettings::RM_FLEXIPORT_TELEMETRY; + } } break; case VehicleConfigurationSource::INPUT_DSM: - data.RM_FlexiPort = HwSettings::RM_FLEXIPORT_DSM; + if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_SPARKY2) { + data.SPK2_RcvrPort = HwSettings::SPK2_RCVRPORT_DSM; + } else { + data.RM_FlexiPort = HwSettings::RM_FLEXIPORT_DSM; + } break; case VehicleConfigurationSource::INPUT_SRXL: - data.RM_FlexiPort = HwSettings::RM_FLEXIPORT_SRXL; + if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_SPARKY2) { + data.SPK2_RcvrPort = HwSettings::SPK2_RCVRPORT_SRXL; + } else { + data.RM_FlexiPort = HwSettings::RM_FLEXIPORT_SRXL; + } + break; + case VehicleConfigurationSource::INPUT_HOTT_SUMD: + if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_SPARKY2) { + data.SPK2_RcvrPort = HwSettings::SPK2_RCVRPORT_HOTTSUMD; + } else { + data.RM_FlexiPort = HwSettings::RM_FLEXIPORT_HOTTSUMD; + } + break; + case VehicleConfigurationSource::INPUT_EXBUS: + if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_SPARKY2) { + data.SPK2_RcvrPort = HwSettings::SPK2_RCVRPORT_EXBUS; + } else { + data.RM_FlexiPort = HwSettings::RM_FLEXIPORT_EXBUS; + } + break; + case VehicleConfigurationSource::INPUT_IBUS: + if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_SPARKY2) { + data.SPK2_RcvrPort = HwSettings::SPK2_RCVRPORT_IBUS; + } else { + data.RM_FlexiPort = HwSettings::RM_FLEXIPORT_IBUS; + } break; default: break; @@ -212,10 +280,16 @@ void VehicleConfigurationHelper::applyHardwareConfiguration() data.OptionalModules[HwSettings::OPTIONALMODULES_GPS] = 1; data.GPSSpeed = HwSettings::GPSSPEED_57600; - if (m_configSource->getInputType() == VehicleConfigurationSource::INPUT_SBUS) { - data.RM_FlexiPort = HwSettings::RM_FLEXIPORT_GPS; + // if using GPS and SBUS on Revo or Nano, we must use FlexiPort for GPS + // since we must use MainPort for SBUS + if (m_configSource->getControllerType() != VehicleConfigurationSource::CONTROLLER_SPARKY2) { + if (m_configSource->getInputType() == VehicleConfigurationSource::INPUT_SBUS) { + data.RM_FlexiPort = HwSettings::RM_FLEXIPORT_GPS; + } else { + data.RM_MainPort = HwSettings::RM_MAINPORT_GPS; + } } else { - data.RM_MainPort = HwSettings::RM_MAINPORT_GPS; + data.SPK2_MainPort = HwSettings::SPK2_MAINPORT_GPS; } GPSSettings *gpsSettings = GPSSettings::GetInstance(m_uavoManager); @@ -238,11 +312,44 @@ void VehicleConfigurationHelper::applyHardwareConfiguration() AuxMagSettings *magSettings = AuxMagSettings::GetInstance(m_uavoManager); Q_ASSERT(magSettings); AuxMagSettings::DataFields magsData = magSettings->getData(); + magsData.Type = AuxMagSettings::TYPE_GPSV9; magsData.Usage = AuxMagSettings::USAGE_AUXONLY; magSettings->setData(magsData); addModifiedObject(magSettings, tr("Writing External Mag sensor settings")); break; } + case VehicleConfigurationSource::GPS_NAZA: + { + gpsData.DataProtocol = GPSSettings::DATAPROTOCOL_DJI; + gpsData.UbxAutoConfig = GPSSettings::UBXAUTOCONFIG_DISABLED; + AuxMagSettings *magSettings = AuxMagSettings::GetInstance(m_uavoManager); + Q_ASSERT(magSettings); + AuxMagSettings::DataFields magsData = magSettings->getData(); + magsData.Type = AuxMagSettings::TYPE_DJI; + magsData.Usage = AuxMagSettings::USAGE_AUXONLY; + magSettings->setData(magsData); + addModifiedObject(magSettings, tr("Writing External Mag sensor settings")); + break; + } + case VehicleConfigurationSource::GPS_UBX_FLEXI_I2CMAG: + { + AuxMagSettings *magSettings = AuxMagSettings::GetInstance(m_uavoManager); + Q_ASSERT(magSettings); + AuxMagSettings::DataFields magsData = magSettings->getData(); + + gpsData.DataProtocol = GPSSettings::DATAPROTOCOL_UBX; + gpsData.UbxAutoConfig = GPSSettings::UBXAUTOCONFIG_AUTOBAUDANDCONFIGURE; + if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_SPARKY2) { + data.SPK2_FlexiPort = HwSettings::SPK2_FLEXIPORT_I2C; + } else { + data.RM_FlexiPort = HwSettings::RM_FLEXIPORT_I2C; + } + magsData.Type = AuxMagSettings::TYPE_FLEXI; + magsData.Usage = AuxMagSettings::USAGE_AUXONLY; + magSettings->setData(magsData); + addModifiedObject(magSettings, tr("Writing I2C Mag sensor settings")); + } + case VehicleConfigurationSource::GPS_DISABLED: // Should not be able to reach here break; @@ -267,12 +374,22 @@ void VehicleConfigurationHelper::applyHardwareConfiguration() break; case VehicleConfigurationSource::AIRSPEED_EAGLETREE: data.OptionalModules[HwSettings::OPTIONALMODULES_AIRSPEED] = 1; - data.RM_FlexiPort = HwSettings::RM_FLEXIPORT_I2C; + if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_SPARKY2) { + // sparky2: put I2C airspeed on flexiport, but it could be put on i2cport + data.SPK2_FlexiPort = HwSettings::SPK2_FLEXIPORT_I2C; + } else { + data.RM_FlexiPort = HwSettings::RM_FLEXIPORT_I2C; + } airspeedData.AirspeedSensorType = AirspeedSettings::AIRSPEEDSENSORTYPE_EAGLETREEAIRSPEEDV3; break; case VehicleConfigurationSource::AIRSPEED_MS4525: data.OptionalModules[HwSettings::OPTIONALMODULES_AIRSPEED] = 1; - data.RM_FlexiPort = HwSettings::RM_FLEXIPORT_I2C; + if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_SPARKY2) { + // sparky2: put I2C airspeed on flexiport, but it could be put on i2cport + data.SPK2_FlexiPort = HwSettings::SPK2_FLEXIPORT_I2C; + } else { + data.RM_FlexiPort = HwSettings::RM_FLEXIPORT_I2C; + } airspeedData.AirspeedSensorType = AirspeedSettings::AIRSPEEDSENSORTYPE_PIXHAWKAIRSPEEDMS4525DO; break; default: @@ -287,7 +404,10 @@ void VehicleConfigurationHelper::applyHardwareConfiguration() default: break; } - hwSettings->setData(data); + UAVObjectUpdaterHelper updateHelper; + hwSettings->setData(data, false); + updateHelper.doObjectAndWait(hwSettings); + addModifiedObject(hwSettings, tr("Writing hardware settings")); } @@ -435,7 +555,8 @@ void VehicleConfigurationHelper::applyActuatorConfiguration() // Servo always on channel 4 data.BankUpdateFreq[0] = escFrequence; data.BankMode[0] = bankMode; - if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_REVO) { + if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_REVO + || m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_SPARKY2) { data.BankUpdateFreq[1] = escFrequence; data.BankMode[1] = bankMode; data.BankUpdateFreq[2] = servoFrequence; @@ -453,7 +574,8 @@ void VehicleConfigurationHelper::applyActuatorConfiguration() data.BankMode[0] = bankMode; data.BankUpdateFreq[1] = escFrequence; data.BankMode[1] = bankMode; - if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_REVO) { + if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_REVO + || m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_SPARKY2) { data.BankUpdateFreq[2] = escFrequence; data.BankMode[2] = bankMode; } else if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_NANO) { @@ -517,7 +639,8 @@ void VehicleConfigurationHelper::applyActuatorConfiguration() if (i == 1) { data.BankUpdateFreq[i] = escFrequence; } - } else if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_REVO) { + } else if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_REVO + || m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_SPARKY2) { // Motor output4, bank3 if (i == 2) { data.BankUpdateFreq[i] = escFrequence; @@ -562,7 +685,8 @@ void VehicleConfigurationHelper::applyActuatorConfiguration() if (i == 1) { data.BankUpdateFreq[i] = escFrequence; } - } else if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_REVO) { + } else if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_REVO + || m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_SPARKY2) { // Motor output4, bank3 if (i == 1) { data.BankUpdateFreq[i] = escFrequence; @@ -627,9 +751,15 @@ void VehicleConfigurationHelper::applyFlightModeConfiguration() data.FlightModePosition[3] = FlightModeSettings::FLIGHTMODEPOSITION_STABILIZED4; data.FlightModePosition[4] = FlightModeSettings::FLIGHTMODEPOSITION_STABILIZED5; data.FlightModePosition[5] = FlightModeSettings::FLIGHTMODEPOSITION_STABILIZED6; - modeSettings->setData(data); + + UAVObjectUpdaterHelper updateHelper; + + modeSettings->setData(data, false); + updateHelper.doObjectAndWait(modeSettings); addModifiedObject(modeSettings, tr("Writing flight mode settings 1/2")); - controlSettings->setData(data2); + + controlSettings->setData(data2, false); + updateHelper.doObjectAndWait(controlSettings); addModifiedObject(controlSettings, tr("Writing flight mode settings 2/2")); } @@ -661,7 +791,6 @@ void VehicleConfigurationHelper::applySensorBiasConfiguration() Q_ASSERT(copterControlCalibration); AttitudeSettings::DataFields data = copterControlCalibration->getData(); - data.AccelTau = DEFAULT_ENABLED_ACCEL_TAU; data.BiasCorrectGyro = AttitudeSettings::BIASCORRECTGYRO_TRUE; copterControlCalibration->setData(data); @@ -670,6 +799,7 @@ void VehicleConfigurationHelper::applySensorBiasConfiguration() } case VehicleConfigurationSource::CONTROLLER_REVO: case VehicleConfigurationSource::CONTROLLER_NANO: + case VehicleConfigurationSource::CONTROLLER_SPARKY2: { RevoCalibration *revolutionCalibration = RevoCalibration::GetInstance(m_uavoManager); Q_ASSERT(revolutionCalibration); @@ -694,8 +824,10 @@ void VehicleConfigurationHelper::applyStabilizationConfiguration() Q_ASSERT(stabSettings); + UAVObjectUpdaterHelper updateHelper; StabilizationSettings defaultSettings; - stabSettings->setData(defaultSettings.getData()); + stabSettings->setData(defaultSettings.getData(), false); + updateHelper.doObjectAndWait(stabSettings); addModifiedObject(stabSettings, tr("Writing stabilization settings")); } @@ -753,30 +885,30 @@ void VehicleConfigurationHelper::applyMixerConfiguration(mixerChannelSettings ch case VehicleConfigurationSource::MULTI_ROTOR_HEXA: case VehicleConfigurationSource::MULTI_ROTOR_HEXA_H: case VehicleConfigurationSource::MULTI_ROTOR_HEXA_X: - mSettings->setMixerValueRoll(100); - mSettings->setMixerValuePitch(100); - mSettings->setMixerValueYaw(100); + mSettings->setMixerValueRoll((qint8)100); + mSettings->setMixerValuePitch((qint8)100); + mSettings->setMixerValueYaw((qint8)100); break; case VehicleConfigurationSource::MULTI_ROTOR_QUAD_X: - mSettings->setMixerValueRoll(50); - mSettings->setMixerValuePitch(50); - mSettings->setMixerValueYaw(50); + mSettings->setMixerValueRoll((qint8)50); + mSettings->setMixerValuePitch((qint8)50); + mSettings->setMixerValueYaw((qint8)50); break; case VehicleConfigurationSource::MULTI_ROTOR_QUAD_PLUS: - mSettings->setMixerValueRoll(100); - mSettings->setMixerValuePitch(100); - mSettings->setMixerValueYaw(50); + mSettings->setMixerValueRoll((qint8)100); + mSettings->setMixerValuePitch((qint8)100); + mSettings->setMixerValueYaw((qint8)50); break; case VehicleConfigurationSource::MULTI_ROTOR_HEXA_COAX_Y: - mSettings->setMixerValueRoll(100); - mSettings->setMixerValuePitch(50); - mSettings->setMixerValueYaw(66); + mSettings->setMixerValueRoll((qint8)86); + mSettings->setMixerValuePitch((qint8)100); + mSettings->setMixerValueYaw((qint8)100); break; case VehicleConfigurationSource::MULTI_ROTOR_OCTO: case VehicleConfigurationSource::MULTI_ROTOR_OCTO_X: - mSettings->setMixerValueRoll(100); - mSettings->setMixerValuePitch(100); - mSettings->setMixerValueYaw(100); + mSettings->setMixerValueRoll((qint8)100); + mSettings->setMixerValuePitch((qint8)100); + mSettings->setMixerValueYaw((qint8)100); break; case VehicleConfigurationSource::MULTI_ROTOR_OCTO_COAX_X: case VehicleConfigurationSource::MULTI_ROTOR_OCTO_COAX_PLUS: @@ -788,9 +920,9 @@ void VehicleConfigurationHelper::applyMixerConfiguration(mixerChannelSettings ch break; } case VehicleConfigurationSource::VEHICLE_FIXEDWING: - mSettings->setMixerValueRoll(100); - mSettings->setMixerValuePitch(100); - mSettings->setMixerValueYaw(100); + mSettings->setMixerValueRoll((qint8)100); + mSettings->setMixerValuePitch((qint8)100); + mSettings->setMixerValueYaw((qint8)100); maxThrottle = 1; break; case VehicleConfigurationSource::VEHICLE_HELI: @@ -799,22 +931,22 @@ void VehicleConfigurationHelper::applyMixerConfiguration(mixerChannelSettings ch { switch (m_configSource->getVehicleSubType()) { case VehicleConfigurationSource::GROUNDVEHICLE_MOTORCYCLE: - mSettings->setMixerValueRoll(100); - mSettings->setMixerValuePitch(100); - mSettings->setMixerValueYaw(100); + mSettings->setMixerValueRoll((qint8)100); + mSettings->setMixerValuePitch((qint8)100); + mSettings->setMixerValueYaw((qint8)100); maxThrottle = 1; break; case VehicleConfigurationSource::GROUNDVEHICLE_CAR: - mSettings->setMixerValueRoll(100); - mSettings->setMixerValuePitch(100); - mSettings->setMixerValueYaw(100); + mSettings->setMixerValueRoll((qint8)100); + mSettings->setMixerValuePitch((qint8)100); + mSettings->setMixerValueYaw((qint8)100); maxThrottle = 1; minThrottle = 0; break; case VehicleConfigurationSource::GROUNDVEHICLE_DIFFERENTIAL: - mSettings->setMixerValueRoll(100); - mSettings->setMixerValuePitch(100); - mSettings->setMixerValueYaw(100); + mSettings->setMixerValueRoll((qint8)100); + mSettings->setMixerValuePitch((qint8)100); + mSettings->setMixerValueYaw((qint8)100); maxThrottle = 0.8; minThrottle = 0; break; @@ -839,7 +971,9 @@ void VehicleConfigurationHelper::applyMixerConfiguration(mixerChannelSettings ch } // Apply updates - mSettings->setData(mSettings->getData()); + UAVObjectUpdaterHelper updateHelper; + mSettings->setData(mSettings->getData(), false); + updateHelper.doObjectAndWait(mSettings); addModifiedObject(mSettings, tr("Writing mixer settings")); } @@ -855,7 +989,9 @@ void VehicleConfigurationHelper::applyMultiGUISettings(SystemSettings::AirframeT data.GUIConfigData[i] = guiConfig.UAVObject[i]; } - sSettings->setData(data); + UAVObjectUpdaterHelper updateHelper; + sSettings->setData(data, false); + updateHelper.doObjectAndWait(sSettings); addModifiedObject(sSettings, tr("Writing vehicle settings")); } @@ -883,6 +1019,15 @@ void VehicleConfigurationHelper::applyManualControlDefaults() case VehicleConfigurationSource::INPUT_SRXL: channelType = ManualControlSettings::CHANNELGROUPS_SRXL; break; + case VehicleConfigurationSource::INPUT_HOTT_SUMD: + channelType = ManualControlSettings::CHANNELGROUPS_HOTT; + break; + case VehicleConfigurationSource::INPUT_EXBUS: + channelType = ManualControlSettings::CHANNELGROUPS_EXBUS; + break; + case VehicleConfigurationSource::INPUT_IBUS: + channelType = ManualControlSettings::CHANNELGROUPS_IBUS; + break; default: break; } @@ -1303,42 +1448,43 @@ void VehicleConfigurationHelper::setupHexaCopter() channels[0].throttle2 = 0; channels[0].roll = 100; channels[0].pitch = 25; - channels[0].yaw = -66; + channels[0].yaw = -66; + channels[1].type = MIXER_TYPE_MOTOR; channels[1].throttle1 = 100; channels[1].throttle2 = 0; channels[1].roll = 100; channels[1].pitch = 25; - channels[1].yaw = 66; + channels[1].yaw = 66; channels[2].type = MIXER_TYPE_MOTOR; channels[2].throttle1 = 100; channels[2].throttle2 = 0; channels[2].roll = -100; channels[2].pitch = 25; - channels[2].yaw = -66; + channels[2].yaw = -66; channels[3].type = MIXER_TYPE_MOTOR; channels[3].throttle1 = 100; channels[3].throttle2 = 0; channels[3].roll = -100; channels[3].pitch = 25; - channels[3].yaw = 66; + channels[3].yaw = 66; channels[4].type = MIXER_TYPE_MOTOR; channels[4].throttle1 = 100; channels[4].throttle2 = 0; channels[4].roll = 0; channels[4].pitch = -50; - channels[4].yaw = -66; + channels[4].yaw = -66; channels[5].type = MIXER_TYPE_MOTOR; channels[5].throttle1 = 100; channels[5].throttle2 = 0; channels[5].roll = 0; channels[5].pitch = -50; - channels[5].yaw = 66; + channels[5].yaw = 66; guiSettings.multi.VTOLMotorNW = 1; guiSettings.multi.VTOLMotorW = 2; @@ -1783,6 +1929,7 @@ void VehicleConfigurationHelper::setupOctoCopter() guiSettings.multi.VTOLMotorE = 3; guiSettings.multi.VTOLMotorSE = 4; guiSettings.multi.VTOLMotorS = 5; + guiSettings.multi.VTOLMotorSW = 6; guiSettings.multi.VTOLMotorW = 7; guiSettings.multi.VTOLMotorNW = 8; diff --git a/ground/gcs/src/plugins/setupwizard/vehicleconfigurationhelper.h b/ground/gcs/src/plugins/setupwizard/vehicleconfigurationhelper.h index 002518bf0..757dbe646 100644 --- a/ground/gcs/src/plugins/setupwizard/vehicleconfigurationhelper.h +++ b/ground/gcs/src/plugins/setupwizard/vehicleconfigurationhelper.h @@ -28,14 +28,17 @@ #ifndef VEHICLECONFIGURATIONHELPER_H #define VEHICLECONFIGURATIONHELPER_H -#include -#include #include "vehicleconfigurationsource.h" #include "uavobjectmanager.h" -#include "systemsettings.h" #include "cfg_vehicletypes/vehicleconfig.h" + +#include "systemsettings.h" #include "actuatorsettings.h" +#include +#include +#include + struct mixerChannelSettings { int type; int throttle1; @@ -73,8 +76,6 @@ signals: void saveProgress(int total, int current, QString description); private: - static const float DEFAULT_ENABLED_ACCEL_TAU = 0.1; - VehicleConfigurationSource *m_configSource; UAVObjectManager *m_uavoManager; diff --git a/ground/gcs/src/plugins/setupwizard/vehicleconfigurationsource.h b/ground/gcs/src/plugins/setupwizard/vehicleconfigurationsource.h index 44e2a8d81..00e2a88fb 100644 --- a/ground/gcs/src/plugins/setupwizard/vehicleconfigurationsource.h +++ b/ground/gcs/src/plugins/setupwizard/vehicleconfigurationsource.h @@ -57,7 +57,7 @@ class VehicleConfigurationSource { public: VehicleConfigurationSource(); - enum CONTROLLER_TYPE { CONTROLLER_UNKNOWN, CONTROLLER_CC, CONTROLLER_CC3D, CONTROLLER_REVO, CONTROLLER_NANO, CONTROLLER_OPLINK, CONTROLLER_DISCOVERYF4 }; + enum CONTROLLER_TYPE { CONTROLLER_UNKNOWN, CONTROLLER_CC, CONTROLLER_CC3D, CONTROLLER_REVO, CONTROLLER_NANO, CONTROLLER_SPARKY2, CONTROLLER_OPLINK, CONTROLLER_DISCOVERYF4 }; enum VEHICLE_TYPE { VEHICLE_UNKNOWN, VEHICLE_MULTI, VEHICLE_FIXEDWING, VEHICLE_HELI, VEHICLE_SURFACE }; enum VEHICLE_SUB_TYPE { MULTI_ROTOR_UNKNOWN, MULTI_ROTOR_TRI_Y, MULTI_ROTOR_QUAD_X, MULTI_ROTOR_QUAD_PLUS, MULTI_ROTOR_QUAD_H, MULTI_ROTOR_HEXA, MULTI_ROTOR_HEXA_H, MULTI_ROTOR_HEXA_X, MULTI_ROTOR_HEXA_COAX_Y, MULTI_ROTOR_OCTO, @@ -66,9 +66,9 @@ public: GROUNDVEHICLE_MOTORCYCLE, GROUNDVEHICLE_CAR, GROUNDVEHICLE_DIFFERENTIAL }; enum ESC_TYPE { ESC_ONESHOT, ESC_SYNCHED, ESC_RAPID, ESC_STANDARD, ESC_UNKNOWN }; enum SERVO_TYPE { SERVO_ANALOG, SERVO_DIGITAL, SERVO_UNKNOWN }; - enum INPUT_TYPE { INPUT_PWM, INPUT_PPM, INPUT_SBUS, INPUT_DSM, INPUT_SRXL, INPUT_UNKNOWN }; + enum INPUT_TYPE { INPUT_PWM, INPUT_PPM, INPUT_SBUS, INPUT_DSM, INPUT_SRXL, INPUT_HOTT_SUMD, INPUT_EXBUS, INPUT_IBUS, INPUT_UNKNOWN }; enum AIRSPEED_TYPE { AIRSPEED_ESTIMATE, AIRSPEED_EAGLETREE, AIRSPEED_MS4525, AIRSPEED_DISABLED }; - enum GPS_TYPE { GPS_PLATINUM, GPS_UBX, GPS_NMEA, GPS_DISABLED }; + enum GPS_TYPE { GPS_PLATINUM, GPS_NAZA, GPS_UBX_FLEXI_I2CMAG, GPS_UBX, GPS_NMEA, GPS_DISABLED }; enum RADIO_SETTING { RADIO_TELEMETRY, RADIO_DISABLED }; virtual VehicleConfigurationSource::CONTROLLER_TYPE getControllerType() const = 0; diff --git a/ground/gcs/src/plugins/setupwizard/vehicletemplateexportdialog.cpp b/ground/gcs/src/plugins/setupwizard/vehicletemplateexportdialog.cpp index 5e0dae3dd..51ee73f1c 100644 --- a/ground/gcs/src/plugins/setupwizard/vehicletemplateexportdialog.cpp +++ b/ground/gcs/src/plugins/setupwizard/vehicletemplateexportdialog.cpp @@ -361,10 +361,19 @@ QString VehicleTemplateExportDialog::getTypeDirectory() void VehicleTemplateExportDialog::updateStatus() { - bool enabled = m_autopilotConnected && ui->Name->text().length() > 3 && ui->Owner->text().length() > 2 && + bool enabled = m_autopilotConnected && ui->Name->text().length() > 2 && ui->Owner->text().length() > 2 && ui->ForumNick->text().length() > 2 && ui->Size->text().length() > 0 && ui->Weight->text().length() > 0; + ui->Motor->setEnabled(enabled); + ui->Esc->setEnabled(enabled); + ui->Servo->setEnabled(enabled); + ui->Battery->setEnabled(enabled); + ui->Propeller->setEnabled(enabled); + ui->Controllers->setEnabled(enabled); + ui->Comment->setEnabled(enabled); + ui->ImportButton->setEnabled(enabled); + ui->exportBtn->setEnabled(enabled); ui->saveAsBtn->setEnabled(enabled); } diff --git a/ground/gcs/src/plugins/setupwizard/vehicletemplateexportdialog.ui b/ground/gcs/src/plugins/setupwizard/vehicletemplateexportdialog.ui index d2069645c..dacb84f15 100644 --- a/ground/gcs/src/plugins/setupwizard/vehicletemplateexportdialog.ui +++ b/ground/gcs/src/plugins/setupwizard/vehicletemplateexportdialog.ui @@ -9,14 +9,14 @@ 0 0 - 610 - 700 + 600 + 560
- 610 - 700 + 600 + 560 @@ -247,6 +247,11 @@ Nano
+ + + Sparky2 + +
@@ -282,6 +287,18 @@ + + + 0 + 0 + + + + + 0 + 0 + + QFrame::NoFrame @@ -337,6 +354,12 @@ 0 + + + 0 + 0 + + Qt::ScrollBarAlwaysOn @@ -615,30 +638,6 @@
- - - - QFrame::NoFrame - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - - diff --git a/ground/gcs/src/plugins/setupwizard/vehicletemplateselectorwidget.ui b/ground/gcs/src/plugins/setupwizard/vehicletemplateselectorwidget.ui index c0a07e9ff..f8f644ef7 100644 --- a/ground/gcs/src/plugins/setupwizard/vehicletemplateselectorwidget.ui +++ b/ground/gcs/src/plugins/setupwizard/vehicletemplateselectorwidget.ui @@ -7,7 +7,7 @@ 0 0 626 - 461 + 400 @@ -31,7 +31,7 @@ Qt::Vertical - + 6 @@ -43,7 +43,7 @@ 0 - 300 + 250 diff --git a/ground/gcs/src/plugins/setupwizard/wizardResources.qrc b/ground/gcs/src/plugins/setupwizard/wizardResources.qrc index e6160c2f1..dffe4bac9 100644 --- a/ground/gcs/src/plugins/setupwizard/wizardResources.qrc +++ b/ground/gcs/src/plugins/setupwizard/wizardResources.qrc @@ -56,5 +56,11 @@ resources/bttn-oneshot-up.png resources/bttn-srxl-down.png resources/bttn-srxl-up.png + resources/bttn-hott-down.png + resources/bttn-hott-up.png + resources/bttn-exbus-down.png + resources/bttn-exbus-up.png + resources/bttn-ibus-down.png + resources/bttn-ibus-up.png diff --git a/ground/gcs/src/plugins/streamservice/StreamServicePlugin.pluginspec b/ground/gcs/src/plugins/streamservice/StreamServicePlugin.pluginspec new file mode 100644 index 000000000..cac8e96ec --- /dev/null +++ b/ground/gcs/src/plugins/streamservice/StreamServicePlugin.pluginspec @@ -0,0 +1,12 @@ + + The LibrePilot Project + (C) 2016 LibrePilot Project; (C) 2010 OpenPilot Project and Nokia + The GNU Public License (GPL) Version 3 + UAV Objects listener publishing changes in socket + http://www.librepilot.org + + + + + + diff --git a/ground/gcs/src/plugins/streamservice/streamservice.pro b/ground/gcs/src/plugins/streamservice/streamservice.pro new file mode 100644 index 000000000..0740459c1 --- /dev/null +++ b/ground/gcs/src/plugins/streamservice/streamservice.pro @@ -0,0 +1,18 @@ +TEMPLATE = lib +TARGET = StreamServicePlugin + +QT += network widgets + +include(../../plugin.pri) +include(../../plugins/coreplugin/coreplugin.pri) +include(../../plugins/uavtalk/uavtalk.pri) +include(../../plugins/uavobjects/uavobjects.pri) + +SOURCES += streamserviceplugin.cpp + +HEADERS += streamserviceplugin.h + +OTHER_FILES += + +DISTFILES += \ + StreamServicePlugin.pluginspec diff --git a/ground/gcs/src/plugins/streamservice/streamserviceplugin.cpp b/ground/gcs/src/plugins/streamservice/streamserviceplugin.cpp new file mode 100644 index 000000000..652acebd7 --- /dev/null +++ b/ground/gcs/src/plugins/streamservice/streamserviceplugin.cpp @@ -0,0 +1,155 @@ +/** + ****************************************************************************** + * + * @file streamserviceplugin.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * @addtogroup GCSPlugins GCS Plugins + * @{ + * @addtogroup StreamServicePlugin Plugin + * @{ + * @brief Data UAV Data objects TCP/IP stream service + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include "streamserviceplugin.h" + +#include +#include +#include +#include +#include +#include + +#include "extensionsystem/pluginmanager.h" +#include "../uavobjects/uavobjectmanager.h" +#include "../uavobjects/uavdataobject.h" + +StreamServicePlugin::StreamServicePlugin() : + port(7891), + isSubscribed(false) {} + +StreamServicePlugin::~StreamServicePlugin() +{ + if (pServer == Q_NULLPTR) { + return; + } + if (pServer->isListening()) { + foreach(QTcpSocket * client, activeClients) { + /* Disconnect the client discarding pending + * bytes */ + if (client->isOpen()) { + client->close(); + } + } + pServer->close(); + } +} + +bool StreamServicePlugin::initialize(const QStringList &arguments, QString *errorString) +{ + Q_UNUSED(arguments); + Q_UNUSED(errorString); + + pServer = new QTcpServer(); + + if (!pServer->listen(QHostAddress::Any, port)) { + *errorString = tr("Couldn't start StreamService: ") + pServer->errorString(); + return false; + } + + connect(pServer, &QTcpServer::newConnection, this, &StreamServicePlugin::clientConnected); + + return true; +} + +void StreamServicePlugin::extensionsInitialized() +{ + if (pServer == Q_NULLPTR) { + return; + } + + pServer->resumeAccepting(); +} + +void StreamServicePlugin::shutdown() +{ + if (pServer != Q_NULLPTR) { + pServer->pauseAccepting(); + } + + foreach(QTcpSocket * pClient, activeClients) { + pClient->disconnectFromHost(); + } +} + +void StreamServicePlugin::objectUpdated(UAVObject *pObj) +{ + QJsonObject qtjson; + + pObj->toJson(qtjson); + + // Adds timestamp: Milliseconds from epoch + qtjson.insert("gcs_timestamp_ms", QJsonValue(QDateTime::currentMSecsSinceEpoch())); + + QJsonDocument jsonDoc(qtjson); + QString strJson = QString(jsonDoc.toJson(QJsonDocument::Compact)) + "\n"; + + foreach(QTcpSocket * pClient, activeClients) { + if (pClient->isOpen()) { + if (pClient->write(strJson.toUtf8().constData(), strJson.length())) { + pClient->flush(); + } + } + } +} + +void StreamServicePlugin::clientConnected() +{ + QTcpSocket *pending = pServer->nextPendingConnection(); + + if (pending == Q_NULLPTR) { + return; + } + makeSureIsSubscribed(); + + connect(pending, &QTcpSocket::disconnected, this, &StreamServicePlugin::clientDisconnected); + activeClients.append(pending); +} + +void StreamServicePlugin::clientDisconnected() +{ + disconnect(sender()); + activeClients.removeAll((QTcpSocket *)sender()); +} + +inline void StreamServicePlugin::makeSureIsSubscribed() +{ + if (isSubscribed) { + return; + } + + ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); + UAVObjectManager *objManager = pm->getObject(); + Q_ASSERT(objManager); + + QList< QList > objList = objManager->getDataObjects(); + foreach(QList list, objList) { + foreach(UAVDataObject * obj, list) { + connect(obj, &UAVDataObject::objectUpdated, this, &StreamServicePlugin::objectUpdated); + } + } + isSubscribed = true; +} diff --git a/ground/gcs/src/plugins/streamservice/streamserviceplugin.h b/ground/gcs/src/plugins/streamservice/streamserviceplugin.h new file mode 100644 index 000000000..2a628b7d7 --- /dev/null +++ b/ground/gcs/src/plugins/streamservice/streamserviceplugin.h @@ -0,0 +1,67 @@ +/** + ****************************************************************************** + * + * @file streamserviceplugin.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * @addtogroup GCSPlugins GCS Plugins + * @{ + * @addtogroup StreamServicePlugin Plugin + * @{ + * @brief Data UAV Data objects TCP/IP stream service + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef STREAMSERVICEPLUGIN_H +#define STREAMSERVICEPLUGIN_H + +#include +#include "../uavobjects/uavobject.h" + +#include + +class QTcpServer; +class QTcpSocket; + +class StreamServicePlugin : public ExtensionSystem::IPlugin { + Q_OBJECT + Q_PLUGIN_METADATA(IID "Openpilot.StreamService") + +public: + StreamServicePlugin(); + ~StreamServicePlugin(); + + bool initialize(const QStringList &arguments, QString *errorString); + void extensionsInitialized(); + void shutdown(); + +public slots: + void objectUpdated(UAVObject *pObj); + +private slots: + void clientConnected(); + void clientDisconnected(); + +private: + quint16 port; + + QTcpServer *pServer; + QList activeClients; + bool isSubscribed; + + inline void makeSureIsSubscribed(); +}; + +#endif // STREAMSERVICEPLUGIN_H diff --git a/ground/gcs/src/plugins/systemhealth/html/Attitude-Critical.html b/ground/gcs/src/plugins/systemhealth/html/Attitude-Critical.html index b7676c6dd..3a763a567 100644 --- a/ground/gcs/src/plugins/systemhealth/html/Attitude-Critical.html +++ b/ground/gcs/src/plugins/systemhealth/html/Attitude-Critical.html @@ -9,8 +9,9 @@

One of the following conditions may be present:

    -
  • No data is received from the accelerometer
  • -
  • Waiting for good data from Magnetometer or GPS lock to perform module initialization.
  • +
  • Waiting for the board to be steady before gyro init.
  • +
  • No data is being received from the accelerometer.
  • +
  • Waiting for good data from magnetometer or GPS lock to perform module initialization.

diff --git a/ground/gcs/src/plugins/systemhealth/html/Attitude-Error.html b/ground/gcs/src/plugins/systemhealth/html/Attitude-Error.html index d1cbb4982..7ebc6ce75 100644 --- a/ground/gcs/src/plugins/systemhealth/html/Attitude-Error.html +++ b/ground/gcs/src/plugins/systemhealth/html/Attitude-Error.html @@ -9,8 +9,9 @@

One of the following conditions may be present:

    +
  • Waiting for the board to be steady before gyro init.
  • Failed to get an update from the accelerometer or gyros.
  • -
  • Attitude Estimation Algorithm set to "GPS Navigation (INS13)" and no Magnetometer : please set HomeLocation.
  • +
  • Attitude Estimation Algorithm set to "GPS Navigation (INS13)" and no magnetometer : please set HomeLocation.

diff --git a/ground/gcs/src/plugins/systemhealth/html/Attitude-Warning.html b/ground/gcs/src/plugins/systemhealth/html/Attitude-Warning.html new file mode 100644 index 000000000..61ab7f9a3 --- /dev/null +++ b/ground/gcs/src/plugins/systemhealth/html/Attitude-Warning.html @@ -0,0 +1,16 @@ + + + + + + + +

Attitude : Warning

+

+ One of the following conditions may be present: +

    +
  • Waiting for the board to be steady before gyro init.
  • +
+

+ + diff --git a/ground/gcs/src/plugins/systemhealth/html/GPS-Error.html b/ground/gcs/src/plugins/systemhealth/html/GPS-Error.html index 52769efc4..0d6fde2c8 100644 --- a/ground/gcs/src/plugins/systemhealth/html/GPS-Error.html +++ b/ground/gcs/src/plugins/systemhealth/html/GPS-Error.html @@ -9,9 +9,9 @@

The GPS has timed out, one of the following conditions may be present:

    -
  • there is no GPS plugged in
  • -
  • GPS is not powered using an external source (+5V)
  • -
  • there is a hardware issue with wiring
  • +
  • There is no GPS plugged in.
  • +
  • GPS is not powered using an external source. (+5V)
  • +
  • GPS device is not properly wired.

diff --git a/ground/gcs/src/plugins/systemhealth/html/I2C-Critical.html b/ground/gcs/src/plugins/systemhealth/html/I2C-Critical.html new file mode 100644 index 000000000..976a4646b --- /dev/null +++ b/ground/gcs/src/plugins/systemhealth/html/I2C-Critical.html @@ -0,0 +1,13 @@ + + + + + + + +

I2C: Critical

+

+ I2C port is working but there are acknowledgement errors. +

+ + diff --git a/ground/gcs/src/plugins/systemhealth/html/I2C-Error.html b/ground/gcs/src/plugins/systemhealth/html/I2C-Error.html new file mode 100644 index 000000000..39098173b --- /dev/null +++ b/ground/gcs/src/plugins/systemhealth/html/I2C-Error.html @@ -0,0 +1,18 @@ + + + + + + + +

I2C: Error

+

+ The I2C has timed out, one of the following conditions may be present: +

    +
  • I2C device is not connected.
  • +
  • I2C device is not powered using an external source. (+5V)
  • +
  • I2C device is not properly wired.
  • +
+

+ + diff --git a/ground/gcs/src/plugins/systemhealth/html/Sensors-Critical.html b/ground/gcs/src/plugins/systemhealth/html/Sensors-Critical.html index 9c0fb41cb..55e37f6d0 100644 --- a/ground/gcs/src/plugins/systemhealth/html/Sensors-Critical.html +++ b/ground/gcs/src/plugins/systemhealth/html/Sensors-Critical.html @@ -9,10 +9,9 @@

One of the following conditions may be present:

    -
  • Either the accelerometer, gyro or magnetometer tests failed.
  • -
  • Timed out waiting for data from the accelerometer or gyro.
  • +
  • The accelerometer, gyro or magnetometer test failed.
  • +
  • Timed out waiting for data from the accelerometer or gyro.
-

- \ No newline at end of file + diff --git a/ground/gcs/src/plugins/systemhealth/html/Stabilization-Critical.html b/ground/gcs/src/plugins/systemhealth/html/Stabilization-Critical.html index af674c0cb..468e40fc7 100644 --- a/ground/gcs/src/plugins/systemhealth/html/Stabilization-Critical.html +++ b/ground/gcs/src/plugins/systemhealth/html/Stabilization-Critical.html @@ -9,8 +9,10 @@

One of the following conditions may be present:

    -
  • Something is wrong with the Stabilization module
  • -
  • Waiting for good data from the Magnetometer or for GPS lock to perform module initialization.
  • +
  • Waiting for the board to be steady before gyro init.
  • +
  • Rate loop skipped more than 4 executions.
  • +
  • Missed 3 gyro updates.
  • +
  • Waiting for good data from the magnetometer or for GPS lock to perform module initialization.

diff --git a/ground/gcs/src/plugins/systemhealth/html/Stabilization-Error.html b/ground/gcs/src/plugins/systemhealth/html/Stabilization-Error.html new file mode 100644 index 000000000..896f0499e --- /dev/null +++ b/ground/gcs/src/plugins/systemhealth/html/Stabilization-Error.html @@ -0,0 +1,17 @@ + + + + + + + +

Stabilization: Error

+

+ One of the following conditions may be present: +

    +
  • Something is wrong with Stabilization module.
  • +
  • Gyro didn't update at all!
  • +
+

+ + diff --git a/ground/gcs/src/plugins/systemhealth/html/Stabilization-Warning.html b/ground/gcs/src/plugins/systemhealth/html/Stabilization-Warning.html index 8120f7503..daec7c102 100644 --- a/ground/gcs/src/plugins/systemhealth/html/Stabilization-Warning.html +++ b/ground/gcs/src/plugins/systemhealth/html/Stabilization-Warning.html @@ -7,7 +7,11 @@

Stabilization: Warning

- Timed out waiting for an attitude update. + One of the following conditions may be present: +

    +
  • Rate loop skipped more than 2 executions.
  • +
  • Missed one gyro update.
  • +

- \ No newline at end of file + diff --git a/ground/gcs/src/plugins/systemhealth/html/fr/Attitude-Critical.html b/ground/gcs/src/plugins/systemhealth/html/fr/Attitude-Critical.html index 77a583f99..c120c63a4 100644 --- a/ground/gcs/src/plugins/systemhealth/html/fr/Attitude-Critical.html +++ b/ground/gcs/src/plugins/systemhealth/html/fr/Attitude-Critical.html @@ -9,8 +9,9 @@

Une des conditions suivantes semble présente :

    -
  • Pas de données reçues en provenance des accéléromètres
  • -
  • En attente de données correctes du Magnétomètre ou d'une position GPS pour initialiser le module.
  • +
  • En attente d'une carte sans mouvement pour initialiser les gyros.
  • +
  • Pas de données reçues en provenance des accéléromètres.
  • +
  • En attente de données correctes du magnétomètre ou d'une position GPS pour initialiser le module.

diff --git a/ground/gcs/src/plugins/systemhealth/html/fr/Attitude-Error.html b/ground/gcs/src/plugins/systemhealth/html/fr/Attitude-Error.html index 476756b2e..f85acf6cf 100644 --- a/ground/gcs/src/plugins/systemhealth/html/fr/Attitude-Error.html +++ b/ground/gcs/src/plugins/systemhealth/html/fr/Attitude-Error.html @@ -9,6 +9,7 @@

Une des conditions suivantes semble présente :

    +
  • En attente d'une carte sans mouvement pour initialiser les gyros.
  • Échec de l'acquisition en provenance des accéléromètres ou gyroscopes.
  • Algorithme d'évaluation de l'attitude réglé à "GPS Navigation (INS13)" et pas de magnétomètre : veuillez fixer la position Home.
diff --git a/ground/gcs/src/plugins/systemhealth/html/fr/Attitude-Warning.html b/ground/gcs/src/plugins/systemhealth/html/fr/Attitude-Warning.html new file mode 100644 index 000000000..12c8360ec --- /dev/null +++ b/ground/gcs/src/plugins/systemhealth/html/fr/Attitude-Warning.html @@ -0,0 +1,16 @@ + + + + + + + +

Attitude : Avertissement

+

+ Une des conditions suivantes semble présente : +

    +
  • En attente d'une carte sans mouvement pour initialiser les gyros.
  • +
+

+ + diff --git a/ground/gcs/src/plugins/systemhealth/html/fr/GPS-Error.html b/ground/gcs/src/plugins/systemhealth/html/fr/GPS-Error.html index c70db0dc7..8aa4e9ae3 100644 --- a/ground/gcs/src/plugins/systemhealth/html/fr/GPS-Error.html +++ b/ground/gcs/src/plugins/systemhealth/html/fr/GPS-Error.html @@ -9,9 +9,9 @@

Le GPS a expiré pour une des raisons suivantes :

    -
  • il n'y a pas de GPS branché
  • -
  • le GPS n'est pas alimenté avec une source d'alimentation extérieure (+5V)
  • -
  • il y a un problème avec le câblage
  • +
  • Il n'y a pas de GPS branché
  • +
  • Le GPS n'est pas alimenté avec une source d'alimentation extérieure (+5V)
  • +
  • Il y a un problème avec le câblage

diff --git a/ground/gcs/src/plugins/systemhealth/html/fr/GPS-Warning.html b/ground/gcs/src/plugins/systemhealth/html/fr/GPS-Warning.html index fcb656d47..77de2574a 100644 --- a/ground/gcs/src/plugins/systemhealth/html/fr/GPS-Warning.html +++ b/ground/gcs/src/plugins/systemhealth/html/fr/GPS-Warning.html @@ -5,7 +5,7 @@ -

GPS: Avertissement

+

GPS : Avertissement

Le GPS a un fix et la navigation peut être utilisée. Cependant, la précision de la position est très faible (l'indication est < 7 satellites)

diff --git a/ground/gcs/src/plugins/systemhealth/html/fr/I2C-Critical.html b/ground/gcs/src/plugins/systemhealth/html/fr/I2C-Critical.html new file mode 100644 index 000000000..1b4148026 --- /dev/null +++ b/ground/gcs/src/plugins/systemhealth/html/fr/I2C-Critical.html @@ -0,0 +1,13 @@ + + + + + + + +

I2C : Critique

+

+ Le port I2C fonctionne mais il y a des erreurs d'ack. +

+ + diff --git a/ground/gcs/src/plugins/systemhealth/html/fr/I2C-Error.html b/ground/gcs/src/plugins/systemhealth/html/fr/I2C-Error.html new file mode 100644 index 000000000..bfb738921 --- /dev/null +++ b/ground/gcs/src/plugins/systemhealth/html/fr/I2C-Error.html @@ -0,0 +1,18 @@ + + + + + + + +

I2C : Erreur

+

+ Le port I2C a expiré pour une des raisons suivantes : +

    +
  • Le composant I2C n'est pas branché.
  • +
  • Le composant I2C n'est pas alimenté avec une source d'alimentation extérieure. (+5V)
  • +
  • Il y a un problème avec le câblage.
  • +
+

+ + diff --git a/ground/gcs/src/plugins/systemhealth/html/fr/Sensors-Critical.html b/ground/gcs/src/plugins/systemhealth/html/fr/Sensors-Critical.html index e2c70026e..33922ec1f 100644 --- a/ground/gcs/src/plugins/systemhealth/html/fr/Sensors-Critical.html +++ b/ground/gcs/src/plugins/systemhealth/html/fr/Sensors-Critical.html @@ -9,8 +9,8 @@

Une des conditions suivantes est peut-être présente :

    -
  • Un des tests d'accéléromètre, gyro ou magnétomètre a échoué.
  • -
  • Délai d'attente des données d'accéléromètre ou gyro dépassé.
  • +
  • Un des tests d'accéléromètre, gyro ou magnétomètre a échoué.
  • +
  • Délai d'attente des données d'accéléromètre ou gyro dépassé.

diff --git a/ground/gcs/src/plugins/systemhealth/html/fr/Stabilization-Critical.html b/ground/gcs/src/plugins/systemhealth/html/fr/Stabilization-Critical.html index fc7198c17..afae223ee 100644 --- a/ground/gcs/src/plugins/systemhealth/html/fr/Stabilization-Critical.html +++ b/ground/gcs/src/plugins/systemhealth/html/fr/Stabilization-Critical.html @@ -9,8 +9,10 @@

Une des conditions suivantes semble présente :

    -
  • Quelque chose ne va pas avec le module de stabilisation
  • -
  • En attente de données correctes du Magnétomètre ou d'une position GPS pour initialiser le module.
  • +
  • En attente d'une carte sans mouvement pour initialiser les gyros.
  • +
  • La boucle Rate a été ignorée plus de quatre fois.
  • +
  • Manqué trois mises à jour du gyro.
  • +
  • En attente de données correctes du magnétomètre ou d'une position GPS pour initialiser le module.

diff --git a/ground/gcs/src/plugins/systemhealth/html/fr/Stabilization-Error.html b/ground/gcs/src/plugins/systemhealth/html/fr/Stabilization-Error.html new file mode 100644 index 000000000..be2cdfade --- /dev/null +++ b/ground/gcs/src/plugins/systemhealth/html/fr/Stabilization-Error.html @@ -0,0 +1,17 @@ + + + + + + + +

Stabilisation : Erreur

+

+ Une des conditions suivantes semble présente : +

    +
  • Quelque chose ne va pas avec le module Stabilisation.
  • +
  • Aucune mise à jour des gyros !
  • +
+

+ + diff --git a/ground/gcs/src/plugins/systemhealth/html/fr/Stabilization-Warning.html b/ground/gcs/src/plugins/systemhealth/html/fr/Stabilization-Warning.html index 950e4fc33..dd1c446ba 100644 --- a/ground/gcs/src/plugins/systemhealth/html/fr/Stabilization-Warning.html +++ b/ground/gcs/src/plugins/systemhealth/html/fr/Stabilization-Warning.html @@ -5,9 +5,13 @@ -

Stabilisation: Avertissement

+

Stabilisation : Avertissement

- Délai d'attente d'une mise à jour de l'attitude dépassé. + Une des conditions suivantes semble présente : +

    +
  • La boucle Rate a été ignorée plus de deux fois.
  • +
  • Manqué une mise à jour du gyro.
  • +

diff --git a/ground/gcs/src/plugins/systemhealth/systemhealth.pro b/ground/gcs/src/plugins/systemhealth/systemhealth.pro index 0d492fea2..34bce280c 100644 --- a/ground/gcs/src/plugins/systemhealth/systemhealth.pro +++ b/ground/gcs/src/plugins/systemhealth/systemhealth.pro @@ -1,22 +1,30 @@ TEMPLATE = lib TARGET = SystemHealthGadget + QT += svg + include(../../plugin.pri) include(../../plugins/coreplugin/coreplugin.pri) include(systemhealth_dependencies.pri) -HEADERS += systemhealthplugin.h -HEADERS += systemhealthgadget.h -HEADERS += systemhealthgadgetwidget.h -HEADERS += systemhealthgadgetfactory.h -HEADERS += systemhealthgadgetconfiguration.h -HEADERS += systemhealthgadgetoptionspage.h -SOURCES += systemhealthplugin.cpp -SOURCES += systemhealthgadget.cpp -SOURCES += systemhealthgadgetfactory.cpp -SOURCES += systemhealthgadgetwidget.cpp -SOURCES += systemhealthgadgetconfiguration.cpp -SOURCES += systemhealthgadgetoptionspage.cpp + +HEADERS += \ + systemhealthplugin.h \ + systemhealthgadget.h \ + systemhealthgadgetwidget.h \ + systemhealthgadgetfactory.h \ + systemhealthgadgetconfiguration.h \ + systemhealthgadgetoptionspage.h + +SOURCES += \ + systemhealthplugin.cpp \ + systemhealthgadget.cpp \ + systemhealthgadgetfactory.cpp \ + systemhealthgadgetwidget.cpp \ + systemhealthgadgetconfiguration.cpp \ + systemhealthgadgetoptionspage.cpp + OTHER_FILES += SystemHealthGadget.pluginspec + FORMS += systemhealthgadgetoptionspage.ui RESOURCES += \ diff --git a/ground/gcs/src/plugins/systemhealth/systemhealth.qrc b/ground/gcs/src/plugins/systemhealth/systemhealth.qrc index 64f21cdd2..7b275f850 100644 --- a/ground/gcs/src/plugins/systemhealth/systemhealth.qrc +++ b/ground/gcs/src/plugins/systemhealth/systemhealth.qrc @@ -11,6 +11,7 @@ html/EventSystem-Warning.html html/FlightTime-Critical.html html/AlarmOK.html + html/Attitude-Warning.html html/Attitude-Critical.html html/Attitude-Error.html html/Battery-Critical.html @@ -20,10 +21,14 @@ html/GPS-Error.html html/GPS-Warning.html html/Guidance-Warning.html + html/I2C-Critical.html + html/I2C-Error.html html/OutOfMemory-Critical.html html/OutOfMemory-Warning.html html/Sensors-Critical.html html/Stabilization-Warning.html + html/Stabilization-Critical.html + html/Stabilization-Error.html html/StackOverflow-Critical.html html/Telemetry-Error.html html/SystemConfiguration-Critical.html @@ -48,6 +53,7 @@ html/fr/EventSystem-Warning.html html/fr/FlightTime-Critical.html html/fr/AlarmOK.html + html/fr/Attitude-Warning.html html/fr/Attitude-Critical.html html/fr/Attitude-Error.html html/fr/Battery-Critical.html @@ -57,10 +63,14 @@ html/fr/GPS-Error.html html/fr/GPS-Warning.html html/fr/Guidance-Warning.html + html/fr/I2C-Critical.html + html/fr/I2C-Error.html html/fr/OutOfMemory-Critical.html html/fr/OutOfMemory-Warning.html html/fr/Sensors-Critical.html html/fr/Stabilization-Warning.html + html/fr/Stabilization-Critical.html + html/fr/Stabilization-Error.html html/fr/StackOverflow-Critical.html html/fr/Telemetry-Error.html html/fr/SystemConfiguration-Critical.html diff --git a/ground/gcs/src/plugins/telemetry/monitorgadgetfactory.cpp b/ground/gcs/src/plugins/telemetry/monitorgadgetfactory.cpp index b6c33e7c5..89af56f0e 100644 --- a/ground/gcs/src/plugins/telemetry/monitorgadgetfactory.cpp +++ b/ground/gcs/src/plugins/telemetry/monitorgadgetfactory.cpp @@ -2,7 +2,8 @@ ****************************************************************************** * * @file monitorgadgetfactory.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @brief * @see The GNU Public License (GPL) Version 3 * @defgroup telemetryplugin @@ -57,11 +58,11 @@ MonitorWidget *MonitorGadgetFactory::createMonitorWidget(QWidget *parent) ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); TelemetryManager *tm = pm->getObject(); - connect(tm, SIGNAL(connected()), widget, SLOT(telemetryConnected())); - connect(tm, SIGNAL(disconnected()), widget, SLOT(telemetryDisconnected())); + // connect(tm, SIGNAL(connected()), widget, SLOT(telemetryConnected())); + // connect(tm, SIGNAL(disconnected()), widget, SLOT(telemetryDisconnected())); connect(tm, SIGNAL(telemetryUpdated(double, double)), widget, SLOT(telemetryUpdated(double, double))); - // and connect widget to connection manager (for retro compatibility) + // connect widget to connection manager Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager(); connect(cm, SIGNAL(deviceConnected(QIODevice *)), widget, SLOT(telemetryConnected())); diff --git a/ground/gcs/src/plugins/telemetry/monitorwidget.cpp b/ground/gcs/src/plugins/telemetry/monitorwidget.cpp index 3f9dcfb20..5049f4e0e 100644 --- a/ground/gcs/src/plugins/telemetry/monitorwidget.cpp +++ b/ground/gcs/src/plugins/telemetry/monitorwidget.cpp @@ -1,3 +1,30 @@ +/** + ****************************************************************************** + * + * @file monitorwidget.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @brief + * @see The GNU Public License (GPL) Version 3 + * @defgroup telemetryplugin + * @{ + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ #include "monitorwidget.h" #include @@ -198,21 +225,9 @@ MonitorWidget::~MonitorWidget() } } -/*! - \brief Enables/Disables OpenGL - */ -// void LineardialGadgetWidget::enableOpenGL(bool flag) -// { -// if (flag) { -// setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); -// } else { -// setViewport(new QWidget); -// } -// } - void MonitorWidget::telemetryConnected() { - qDebug() << "telemetry connected"; + qDebug() << "MonitorWidget::telemetryConnected"; if (!connected) { // flash the lights setToolTip(tr("Connected")); @@ -223,7 +238,7 @@ void MonitorWidget::telemetryConnected() void MonitorWidget::telemetryDisconnected() { - qDebug() << "telemetry disconnected"; + qDebug() << "MonitorWidget::telemetryDisconnected"; if (connected) { connected = false; diff --git a/ground/gcs/src/plugins/telemetry/monitorwidget.h b/ground/gcs/src/plugins/telemetry/monitorwidget.h index 729d25775..247138a7d 100644 --- a/ground/gcs/src/plugins/telemetry/monitorwidget.h +++ b/ground/gcs/src/plugins/telemetry/monitorwidget.h @@ -1,3 +1,30 @@ +/** + ****************************************************************************** + * + * @file monitorwidget.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @brief + * @see The GNU Public License (GPL) Version 3 + * @defgroup telemetryplugin + * @{ + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ #ifndef MONITORWIDGET_H #define MONITORWIDGET_H diff --git a/ground/gcs/src/plugins/telemetry/telemetry.pro b/ground/gcs/src/plugins/telemetry/telemetry.pro index a1d8a8ad9..6f79da813 100644 --- a/ground/gcs/src/plugins/telemetry/telemetry.pro +++ b/ground/gcs/src/plugins/telemetry/telemetry.pro @@ -7,7 +7,8 @@ QT += svg include(telemetry_dependencies.pri) include(../../libs/version_info/version_info.pri) -HEADERS += telemetry_global.h \ +HEADERS += \ + telemetry_global.h \ telemetryplugin.h \ monitorwidget.h \ monitorgadgetconfiguration.h \ @@ -15,7 +16,8 @@ HEADERS += telemetry_global.h \ monitorgadgetfactory.h \ monitorgadgetoptionspage.h -SOURCES += telemetryplugin.cpp \ +SOURCES += \ + telemetryplugin.cpp \ monitorwidget.cpp \ monitorgadgetconfiguration.cpp \ monitorgadget.cpp \ diff --git a/ground/gcs/src/plugins/uavobjectbrowser/browseritemdelegate.cpp b/ground/gcs/src/plugins/uavobjectbrowser/browseritemdelegate.cpp index 028dc82c3..017dd8b40 100644 --- a/ground/gcs/src/plugins/uavobjectbrowser/browseritemdelegate.cpp +++ b/ground/gcs/src/plugins/uavobjectbrowser/browseritemdelegate.cpp @@ -2,7 +2,8 @@ ****************************************************************************** * * @file browseritemdelegate.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup UAVObjectBrowserPlugin UAVObject Browser Plugin @@ -34,20 +35,19 @@ BrowserItemDelegate::BrowserItemDelegate(QObject *parent) : QWidget *BrowserItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem & option, - const QModelIndex & index) const + const QModelIndex &index) const { Q_UNUSED(option) - FieldTreeItem * item = static_cast(index.internalPointer()); + FieldTreeItem * item = static_cast(index.data(Qt::UserRole).value()); QWidget *editor = item->createEditor(parent); Q_ASSERT(editor); return editor; } - void BrowserItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { - FieldTreeItem *item = static_cast(index.internalPointer()); + FieldTreeItem *item = static_cast(index.data(Qt::UserRole).value()); QVariant value = index.model()->data(index, Qt::EditRole); item->setEditorValue(editor, value); @@ -56,15 +56,18 @@ void BrowserItemDelegate::setEditorData(QWidget *editor, void BrowserItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { - FieldTreeItem *item = static_cast(index.internalPointer()); + FieldTreeItem *item = static_cast(index.data(Qt::UserRole).value()); QVariant value = item->getEditorValue(editor); - model->setData(index, value, Qt::EditRole); + bool ret = model->setData(index, value, Qt::EditRole); + + Q_ASSERT(ret); } void BrowserItemDelegate::updateEditorGeometry(QWidget *editor, - const QStyleOptionViewItem &option, const QModelIndex & /* index */) const + const QStyleOptionViewItem &option, const QModelIndex &index) const { + Q_UNUSED(index); editor->setGeometry(option.rect); } diff --git a/ground/gcs/src/plugins/uavobjectbrowser/browseritemdelegate.h b/ground/gcs/src/plugins/uavobjectbrowser/browseritemdelegate.h index 17952b5db..b9d12af04 100644 --- a/ground/gcs/src/plugins/uavobjectbrowser/browseritemdelegate.h +++ b/ground/gcs/src/plugins/uavobjectbrowser/browseritemdelegate.h @@ -2,7 +2,8 @@ ****************************************************************************** * * @file browseritemdelegate.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup UAVObjectBrowserPlugin UAVObject Browser Plugin @@ -46,11 +47,6 @@ public: const QStyleOptionViewItem &option, const QModelIndex &index) const; QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex &index) const; - - -signals: - -public slots: }; #endif // BROWSERITEMDELEGATE_H diff --git a/ground/gcs/src/plugins/uavobjectbrowser/images/1343241276_eye.png b/ground/gcs/src/plugins/uavobjectbrowser/images/1343241276_eye.png index 72edb6b70..6eaf00ed3 100644 Binary files a/ground/gcs/src/plugins/uavobjectbrowser/images/1343241276_eye.png and b/ground/gcs/src/plugins/uavobjectbrowser/images/1343241276_eye.png differ diff --git a/ground/gcs/src/plugins/uavobjectbrowser/images/64 bit.png b/ground/gcs/src/plugins/uavobjectbrowser/images/64 bit.png index 749b17620..532f598cb 100644 Binary files a/ground/gcs/src/plugins/uavobjectbrowser/images/64 bit.png and b/ground/gcs/src/plugins/uavobjectbrowser/images/64 bit.png differ diff --git a/ground/gcs/src/plugins/uavobjectbrowser/images/down_alt.png b/ground/gcs/src/plugins/uavobjectbrowser/images/down_alt.png index b77135526..8b92d013a 100644 Binary files a/ground/gcs/src/plugins/uavobjectbrowser/images/down_alt.png and b/ground/gcs/src/plugins/uavobjectbrowser/images/down_alt.png differ diff --git a/ground/gcs/src/plugins/uavobjectbrowser/images/install.png b/ground/gcs/src/plugins/uavobjectbrowser/images/install.png index 355de1294..c0ce548f4 100644 Binary files a/ground/gcs/src/plugins/uavobjectbrowser/images/install.png and b/ground/gcs/src/plugins/uavobjectbrowser/images/install.png differ diff --git a/ground/gcs/src/plugins/uavobjectbrowser/images/remove.png b/ground/gcs/src/plugins/uavobjectbrowser/images/remove.png index 9aef8c8ab..0b259ab59 100644 Binary files a/ground/gcs/src/plugins/uavobjectbrowser/images/remove.png and b/ground/gcs/src/plugins/uavobjectbrowser/images/remove.png differ diff --git a/ground/gcs/src/plugins/uavobjectbrowser/images/trash.png b/ground/gcs/src/plugins/uavobjectbrowser/images/trash.png index 418d62910..ab126fec4 100644 Binary files a/ground/gcs/src/plugins/uavobjectbrowser/images/trash.png and b/ground/gcs/src/plugins/uavobjectbrowser/images/trash.png differ diff --git a/ground/gcs/src/plugins/uavobjectbrowser/images/up_alt.png b/ground/gcs/src/plugins/uavobjectbrowser/images/up_alt.png index 4d8b67f59..4384307f8 100644 Binary files a/ground/gcs/src/plugins/uavobjectbrowser/images/up_alt.png and b/ground/gcs/src/plugins/uavobjectbrowser/images/up_alt.png differ diff --git a/ground/gcs/src/plugins/uavobjectbrowser/treeitem.h b/ground/gcs/src/plugins/uavobjectbrowser/treeitem.h index bd8504870..253ec041c 100644 --- a/ground/gcs/src/plugins/uavobjectbrowser/treeitem.h +++ b/ground/gcs/src/plugins/uavobjectbrowser/treeitem.h @@ -259,7 +259,7 @@ public: DataObjectTreeItem *findDataObjectTreeItemByObjectId(quint32 objectId) { - return m_objectTreeItemsPerObjectIds.contains(objectId) ? m_objectTreeItemsPerObjectIds[objectId] : 0; + return m_objectTreeItemsPerObjectIds.value(objectId, 0); } void addMetaObjectTreeItem(quint32 objectId, MetaObjectTreeItem *oti) @@ -269,7 +269,7 @@ public: MetaObjectTreeItem *findMetaObjectTreeItemByObjectId(quint32 objectId) { - return m_metaObjectTreeItemsPerObjectIds.contains(objectId) ? m_metaObjectTreeItemsPerObjectIds[objectId] : 0; + return m_metaObjectTreeItemsPerObjectIds.value(objectId, 0); } QList getMetaObjectItems(); diff --git a/ground/gcs/src/plugins/uavobjectbrowser/uavobjectbrowser.pro b/ground/gcs/src/plugins/uavobjectbrowser/uavobjectbrowser.pro index fb68ed483..03fafd067 100644 --- a/ground/gcs/src/plugins/uavobjectbrowser/uavobjectbrowser.pro +++ b/ground/gcs/src/plugins/uavobjectbrowser/uavobjectbrowser.pro @@ -1,8 +1,13 @@ TEMPLATE = lib TARGET = UAVObjectBrowser + +QT += widgets + include(../../plugin.pri) include(uavobjectbrowser_dependencies.pri) -HEADERS += browserplugin.h \ + +HEADERS += \ + browserplugin.h \ uavobjectbrowserconfiguration.h \ uavobjectbrowser.h \ uavobjectbrowserwidget.h \ @@ -12,7 +17,9 @@ HEADERS += browserplugin.h \ treeitem.h \ browseritemdelegate.h \ fieldtreeitem.h -SOURCES += browserplugin.cpp \ + +SOURCES += \ + browserplugin.cpp \ uavobjectbrowserconfiguration.cpp \ uavobjectbrowser.cpp \ uavobjectbrowserfactory.cpp \ @@ -22,8 +29,11 @@ SOURCES += browserplugin.cpp \ treeitem.cpp \ browseritemdelegate.cpp \ fieldtreeitem.cpp + OTHER_FILES += UAVObjectBrowser.pluginspec -FORMS += uavobjectbrowser.ui \ + +FORMS += \ + uavobjectbrowser.ui \ uavobjectbrowseroptionspage.ui \ viewoptions.ui diff --git a/ground/gcs/src/plugins/uavobjectbrowser/uavobjectbrowser.ui b/ground/gcs/src/plugins/uavobjectbrowser/uavobjectbrowser.ui index 492ab119f..54a937b6f 100644 --- a/ground/gcs/src/plugins/uavobjectbrowser/uavobjectbrowser.ui +++ b/ground/gcs/src/plugins/uavobjectbrowser/uavobjectbrowser.ui @@ -204,6 +204,40 @@
+ + + + Qt::Horizontal + + + QSizePolicy::Preferred + + + + 10 + 20 + + + + + + + + type filter text + + + + + + + Clear + + + + .. + + + @@ -273,6 +307,7 @@ This space shows a description of the selected UAVObject.
+ diff --git a/ground/gcs/src/plugins/uavobjectbrowser/uavobjectbrowserwidget.cpp b/ground/gcs/src/plugins/uavobjectbrowser/uavobjectbrowserwidget.cpp index cea702e25..bd6d6ee90 100644 --- a/ground/gcs/src/plugins/uavobjectbrowser/uavobjectbrowserwidget.cpp +++ b/ground/gcs/src/plugins/uavobjectbrowser/uavobjectbrowserwidget.cpp @@ -2,7 +2,9 @@ ****************************************************************************** * * @file uavobjectbrowserwidget.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * Tau Labs, http://taulabs.org, Copyright (C) 2013 + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup UAVObjectBrowserPlugin UAVObject Browser Plugin @@ -43,39 +45,53 @@ UAVObjectBrowserWidget::UAVObjectBrowserWidget(QWidget *parent) : QWidget(parent) { - m_browser = new Ui_UAVObjectBrowser(); - m_viewoptions = new Ui_viewoptions(); m_viewoptionsDialog = new QDialog(this); + + m_viewoptions = new Ui_viewoptions(); m_viewoptions->setupUi(m_viewoptionsDialog); + + m_model = new UAVObjectTreeModel(this, + m_viewoptions->cbCategorized->isChecked(), + m_viewoptions->cbMetaData->isChecked(), + m_viewoptions->cbScientific->isChecked()); + + m_modelProxy = new TreeSortFilterProxyModel(this); + m_modelProxy->setSourceModel(m_model); + m_modelProxy->setDynamicSortFilter(true); + + m_browser = new Ui_UAVObjectBrowser(); m_browser->setupUi(this); - m_model = new UAVObjectTreeModel(); - m_browser->treeView->setModel(m_model); + m_browser->treeView->setModel(m_modelProxy); m_browser->treeView->setColumnWidth(0, 300); - BrowserItemDelegate *m_delegate = new BrowserItemDelegate(); - m_browser->treeView->setItemDelegate(m_delegate); + m_browser->treeView->setItemDelegate(new BrowserItemDelegate()); m_browser->treeView->setEditTriggers(QAbstractItemView::AllEditTriggers); m_browser->treeView->setSelectionBehavior(QAbstractItemView::SelectItems); + m_mustacheTemplate = loadFileIntoString(QString(":/uavobjectbrowser/resources/uavodescription.mustache")); - showMetaData(m_viewoptions->cbMetaData->isChecked()); + showDescription(m_viewoptions->cbDescription->isChecked()); + connect(m_browser->treeView->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(currentChanged(QModelIndex, QModelIndex)), Qt::UniqueConnection); - connect(m_viewoptions->cbMetaData, SIGNAL(toggled(bool)), this, SLOT(showMetaData(bool))); - connect(m_viewoptions->cbCategorized, SIGNAL(toggled(bool)), this, SLOT(categorize(bool))); - connect(m_viewoptions->cbDescription, SIGNAL(toggled(bool)), this, SLOT(showDescription(bool))); connect(m_browser->saveSDButton, SIGNAL(clicked()), this, SLOT(saveObject())); connect(m_browser->readSDButton, SIGNAL(clicked()), this, SLOT(loadObject())); - connect(m_browser->eraseSDButton, SIGNAL(clicked()), this, SLOT(eraseObject())); connect(m_browser->sendButton, SIGNAL(clicked()), this, SLOT(sendUpdate())); connect(m_browser->requestButton, SIGNAL(clicked()), this, SLOT(requestUpdate())); + connect(m_browser->eraseSDButton, SIGNAL(clicked()), this, SLOT(eraseObject())); connect(m_browser->tbView, SIGNAL(clicked()), this, SLOT(viewSlot())); - connect(m_viewoptions->cbScientific, SIGNAL(toggled(bool)), this, SLOT(useScientificNotation(bool))); - connect(m_viewoptions->cbScientific, SIGNAL(toggled(bool)), this, SLOT(viewOptionsChangedSlot())); - connect(m_viewoptions->cbMetaData, SIGNAL(toggled(bool)), this, SLOT(viewOptionsChangedSlot())); - connect(m_viewoptions->cbCategorized, SIGNAL(toggled(bool)), this, SLOT(viewOptionsChangedSlot())); - connect(m_viewoptions->cbDescription, SIGNAL(toggled(bool)), this, SLOT(viewOptionsChangedSlot())); connect(m_browser->splitter, SIGNAL(splitterMoved(int, int)), this, SLOT(splitterMoved())); + + connect(m_viewoptions->cbDescription, SIGNAL(toggled(bool)), this, SLOT(showDescription(bool))); + + connect(m_viewoptions->cbCategorized, SIGNAL(toggled(bool)), this, SLOT(updateViewOptions())); + connect(m_viewoptions->cbMetaData, SIGNAL(toggled(bool)), this, SLOT(updateViewOptions())); + connect(m_viewoptions->cbScientific, SIGNAL(toggled(bool)), this, SLOT(updateViewOptions())); + + // search field and button + connect(m_browser->searchLine, SIGNAL(textChanged(QString)), this, SLOT(searchLineChanged(QString))); + connect(m_browser->searchClearButton, SIGNAL(clicked(bool)), this, SLOT(searchTextCleared())); + enableSendRequest(false); } @@ -97,77 +113,45 @@ void UAVObjectBrowserWidget::setSplitterState(QByteArray state) m_browser->splitter->restoreState(state); } -void UAVObjectBrowserWidget::showMetaData(bool show) -{ - QList metaIndexes = m_model->getMetaDataIndexes(); - foreach(QModelIndex index, metaIndexes) { - m_browser->treeView->setRowHidden(index.row(), index.parent(), !show); - } -} - void UAVObjectBrowserWidget::showDescription(bool show) { m_browser->descriptionText->setVisible(show); -} -void UAVObjectBrowserWidget::categorize(bool categorize) -{ - UAVObjectTreeModel *tmpModel = m_model; - - m_model = new UAVObjectTreeModel(0, categorize, m_viewoptions->cbScientific->isChecked()); - m_model->setRecentlyUpdatedColor(m_recentlyUpdatedColor); - m_model->setManuallyChangedColor(m_manuallyChangedColor); - m_model->setRecentlyUpdatedTimeout(m_recentlyUpdatedTimeout); - m_model->setOnlyHilightChangedValues(m_onlyHilightChangedValues); - m_model->setUnknowObjectColor(m_unknownObjectColor); - m_browser->treeView->setModel(m_model); - showMetaData(m_viewoptions->cbMetaData->isChecked()); - connect(m_browser->treeView->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(currentChanged(QModelIndex, QModelIndex)), Qt::UniqueConnection); - - delete tmpModel; -} - -void UAVObjectBrowserWidget::useScientificNotation(bool scientific) -{ - UAVObjectTreeModel *tmpModel = m_model; - - m_model = new UAVObjectTreeModel(0, m_viewoptions->cbCategorized->isChecked(), scientific); - m_model->setRecentlyUpdatedColor(m_recentlyUpdatedColor); - m_model->setManuallyChangedColor(m_manuallyChangedColor); - m_model->setRecentlyUpdatedTimeout(m_recentlyUpdatedTimeout); - m_model->setUnknowObjectColor(m_unknownObjectColor); - m_browser->treeView->setModel(m_model); - showMetaData(m_viewoptions->cbMetaData->isChecked()); - connect(m_browser->treeView->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(currentChanged(QModelIndex, QModelIndex)), Qt::UniqueConnection); - - delete tmpModel; + // persist options + emit viewOptionsChanged(m_viewoptions->cbCategorized->isChecked(), m_viewoptions->cbScientific->isChecked(), + m_viewoptions->cbMetaData->isChecked(), m_viewoptions->cbDescription->isChecked()); } void UAVObjectBrowserWidget::sendUpdate() { + // TODO why steal focus ? this->setFocus(); + ObjectTreeItem *objItem = findCurrentObjectTreeItem(); - Q_ASSERT(objItem); - objItem->apply(); - UAVObject *obj = objItem->object(); - Q_ASSERT(obj); - obj->updated(); + + if (objItem != NULL) { + objItem->apply(); + UAVObject *obj = objItem->object(); + Q_ASSERT(obj); + obj->updated(); + } } void UAVObjectBrowserWidget::requestUpdate() { ObjectTreeItem *objItem = findCurrentObjectTreeItem(); - Q_ASSERT(objItem); - UAVObject *obj = objItem->object(); - Q_ASSERT(obj); - obj->requestUpdate(); + if (objItem != NULL) { + UAVObject *obj = objItem->object(); + Q_ASSERT(obj); + obj->requestUpdate(); + } } ObjectTreeItem *UAVObjectBrowserWidget::findCurrentObjectTreeItem() { QModelIndex current = m_browser->treeView->currentIndex(); - TreeItem *item = static_cast(current.internalPointer()); + TreeItem *item = static_cast(current.data(Qt::UserRole).value()); ObjectTreeItem *objItem = 0; while (item) { @@ -193,15 +177,20 @@ QString UAVObjectBrowserWidget::loadFileIntoString(QString fileName) void UAVObjectBrowserWidget::saveObject() { + // TODO why steal focus ? this->setFocus(); + // Send update so that the latest value is saved sendUpdate(); + // Save object ObjectTreeItem *objItem = findCurrentObjectTreeItem(); - Q_ASSERT(objItem); - UAVObject *obj = objItem->object(); - Q_ASSERT(obj); - updateObjectPersistance(ObjectPersistence::OPERATION_SAVE, obj); + + if (objItem != NULL) { + UAVObject *obj = objItem->object(); + Q_ASSERT(obj); + updateObjectPersistance(ObjectPersistence::OPERATION_SAVE, obj); + } } void UAVObjectBrowserWidget::loadObject() @@ -209,22 +198,24 @@ void UAVObjectBrowserWidget::loadObject() // Load object ObjectTreeItem *objItem = findCurrentObjectTreeItem(); - Q_ASSERT(objItem); - UAVObject *obj = objItem->object(); - Q_ASSERT(obj); - updateObjectPersistance(ObjectPersistence::OPERATION_LOAD, obj); - // Retrieve object so that latest value is displayed - requestUpdate(); + if (objItem != NULL) { + UAVObject *obj = objItem->object(); + Q_ASSERT(obj); + updateObjectPersistance(ObjectPersistence::OPERATION_LOAD, obj); + // Retrieve object so that latest value is displayed + requestUpdate(); + } } void UAVObjectBrowserWidget::eraseObject() { ObjectTreeItem *objItem = findCurrentObjectTreeItem(); - Q_ASSERT(objItem); - UAVObject *obj = objItem->object(); - Q_ASSERT(obj); - updateObjectPersistance(ObjectPersistence::OPERATION_DELETE, obj); + if (objItem != NULL) { + UAVObject *obj = objItem->object(); + Q_ASSERT(obj); + updateObjectPersistance(ObjectPersistence::OPERATION_DELETE, obj); + } } void UAVObjectBrowserWidget::updateObjectPersistance(ObjectPersistence::OperationOptions op, UAVObject *obj) @@ -248,9 +239,9 @@ void UAVObjectBrowserWidget::currentChanged(const QModelIndex ¤t, const QM { Q_UNUSED(previous); - TreeItem *item = static_cast(current.internalPointer()); + TreeItem *item = static_cast(current.data(Qt::UserRole).value()); bool enable = true; - if (current == QModelIndex()) { + if (!current.isValid()) { enable = false; } TopTreeItem *top = dynamic_cast(item); @@ -274,8 +265,30 @@ void UAVObjectBrowserWidget::viewSlot() } } -void UAVObjectBrowserWidget::viewOptionsChangedSlot() +void UAVObjectBrowserWidget::updateViewOptions() { + // TODO we should update the model instead of rebuilding it + // a side effect of rebuilding is that some state is lost (expand state, ...) + UAVObjectTreeModel *model = new UAVObjectTreeModel(this, + m_viewoptions->cbCategorized->isChecked(), + m_viewoptions->cbMetaData->isChecked(), + m_viewoptions->cbScientific->isChecked()); + + model->setManuallyChangedColor(m_manuallyChangedColor); + model->setRecentlyUpdatedTimeout(m_recentlyUpdatedTimeout); + model->setUnknowObjectColor(m_unknownObjectColor); + + UAVObjectTreeModel *tmpModel = m_model; + m_model = model; + m_modelProxy->setSourceModel(m_model); + delete tmpModel; + + // force an expand all if search text is not empty + if (!m_browser->searchLine->text().isEmpty()) { + searchLineChanged(m_browser->searchLine->text()); + } + + // persist options emit viewOptionsChanged(m_viewoptions->cbCategorized->isChecked(), m_viewoptions->cbScientific->isChecked(), m_viewoptions->cbMetaData->isChecked(), m_viewoptions->cbDescription->isChecked()); } @@ -388,3 +401,94 @@ void UAVObjectBrowserWidget::updateDescription() } m_browser->descriptionText->setText(""); } + +/** + * @brief UAVObjectBrowserWidget::searchTextChanged Looks for matching text in the UAVO fields + */ + +void UAVObjectBrowserWidget::searchLineChanged(QString searchText) +{ + m_modelProxy->setFilterRegExp(QRegExp(searchText, Qt::CaseInsensitive, QRegExp::FixedString)); + if (!searchText.isEmpty()) { + m_browser->treeView->expandAll(); + } else { + m_browser->treeView->collapseAll(); + } +} + +void UAVObjectBrowserWidget::searchTextCleared() +{ + m_browser->searchLine->clear(); +} + +TreeSortFilterProxyModel::TreeSortFilterProxyModel(QObject *p) : + QSortFilterProxyModel(p) +{ + Q_ASSERT(p); +} + +/** + * @brief TreeSortFilterProxyModel::filterAcceptsRow Taken from + * http://qt-project.org/forums/viewthread/7782. This proxy model + * will accept rows: + * - That match themselves, or + * - That have a parent that matches (on its own), or + * - That have a child that matches. + * @param sourceRow + * @param sourceParent + * @return + */ +bool TreeSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const +{ + if (filterAcceptsRowItself(source_row, source_parent)) { + return true; + } + + // accept if any of the parents is accepted on it's own merits + QModelIndex parent = source_parent; + while (parent.isValid()) { + if (filterAcceptsRowItself(parent.row(), parent.parent())) { + return true; + } + parent = parent.parent(); + } + + // accept if any of the children is accepted on it's own merits + if (hasAcceptedChildren(source_row, source_parent)) { + return true; + } + + return false; +} + +bool TreeSortFilterProxyModel::filterAcceptsRowItself(int source_row, const QModelIndex &source_parent) const +{ + return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent); +} + +bool TreeSortFilterProxyModel::hasAcceptedChildren(int source_row, const QModelIndex &source_parent) const +{ + QModelIndex item = sourceModel()->index(source_row, 0, source_parent); + + if (!item.isValid()) { + return false; + } + + // check if there are children + int childCount = item.model()->rowCount(item); + if (childCount == 0) { + return false; + } + + for (int i = 0; i < childCount; ++i) { + if (filterAcceptsRowItself(i, item)) { + return true; + } + + if (hasAcceptedChildren(i, item)) { + return true; + } + } + + return false; +} diff --git a/ground/gcs/src/plugins/uavobjectbrowser/uavobjectbrowserwidget.h b/ground/gcs/src/plugins/uavobjectbrowser/uavobjectbrowserwidget.h index 92cb4af3f..5ddc5c0a1 100644 --- a/ground/gcs/src/plugins/uavobjectbrowser/uavobjectbrowserwidget.h +++ b/ground/gcs/src/plugins/uavobjectbrowser/uavobjectbrowserwidget.h @@ -2,7 +2,9 @@ ****************************************************************************** * * @file uavobjectbrowserwidget.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * Tau Labs, http://taulabs.org, Copyright (C) 2013 + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup UAVObjectBrowserPlugin UAVObject Browser Plugin @@ -28,16 +30,30 @@ #ifndef UAVOBJECTBROWSERWIDGET_H_ #define UAVOBJECTBROWSERWIDGET_H_ +#include "uavobjecttreemodel.h" + +#include "objectpersistence.h" + #include #include -#include "objectpersistence.h" -#include "uavobjecttreemodel.h" +#include +#include class QPushButton; class ObjectTreeItem; class Ui_UAVObjectBrowser; class Ui_viewoptions; +class TreeSortFilterProxyModel : public QSortFilterProxyModel { +public: + TreeSortFilterProxyModel(QObject *parent); + +protected: + bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; + bool filterAcceptsRowItself(int source_row, const QModelIndex &source_parent) const; + bool hasAcceptedChildren(int source_row, const QModelIndex &source_parent) const; +}; + class UAVObjectBrowserWidget : public QWidget { Q_OBJECT @@ -72,11 +88,9 @@ public: } void setViewOptions(bool categorized, bool scientific, bool metadata, bool description); void setSplitterState(QByteArray state); + public slots: - void showMetaData(bool show); void showDescription(bool show); - void categorize(bool categorize); - void useScientificNotation(bool scientific); private slots: void sendUpdate(); @@ -86,19 +100,22 @@ private slots: void eraseObject(); void currentChanged(const QModelIndex ¤t, const QModelIndex &previous); void viewSlot(); - void viewOptionsChangedSlot(); + void updateViewOptions(); + void searchLineChanged(QString searchText); + void searchTextCleared(); void splitterMoved(); QString createObjectDescription(UAVObject *object); + signals: void viewOptionsChanged(bool categorized, bool scientific, bool metadata, bool description); void splitterChanged(QByteArray state); + private: - QPushButton *m_requestUpdate; - QPushButton *m_sendUpdate; Ui_UAVObjectBrowser *m_browser; Ui_viewoptions *m_viewoptions; QDialog *m_viewoptionsDialog; UAVObjectTreeModel *m_model; + TreeSortFilterProxyModel *m_modelProxy; int m_recentlyUpdatedTimeout; QColor m_unknownObjectColor; diff --git a/ground/gcs/src/plugins/uavobjectbrowser/uavobjecttreemodel.cpp b/ground/gcs/src/plugins/uavobjectbrowser/uavobjecttreemodel.cpp index 1e2b7c072..1a07bbea3 100644 --- a/ground/gcs/src/plugins/uavobjectbrowser/uavobjecttreemodel.cpp +++ b/ground/gcs/src/plugins/uavobjectbrowser/uavobjecttreemodel.cpp @@ -37,10 +37,11 @@ #include #include -UAVObjectTreeModel::UAVObjectTreeModel(QObject *parent, bool categorize, bool useScientificNotation) : +UAVObjectTreeModel::UAVObjectTreeModel(QObject *parent, bool categorize, bool showMetadata, bool useScientificNotation) : QAbstractItemModel(parent), - m_useScientificFloatNotation(useScientificNotation), m_categorize(categorize), + m_showMetadata(showMetadata), + m_useScientificFloatNotation(useScientificNotation), m_recentlyUpdatedTimeout(500), // ms m_recentlyUpdatedColor(QColor(255, 230, 230)), m_manuallyChangedColor(QColor(230, 230, 255)), @@ -68,20 +69,23 @@ UAVObjectTreeModel::~UAVObjectTreeModel() void UAVObjectTreeModel::setupModelData(UAVObjectManager *objManager) { + m_settingsTree = new TopTreeItem(tr("Settings")); + m_settingsTree->setHighlightManager(m_highlightManager); + connect(m_settingsTree, SIGNAL(updateHighlight(TreeItem *)), this, SLOT(updateHighlight(TreeItem *))); + + m_nonSettingsTree = new TopTreeItem(tr("Data Objects")); + m_nonSettingsTree->setHighlightManager(m_highlightManager); + connect(m_nonSettingsTree, SIGNAL(updateHighlight(TreeItem *)), this, SLOT(updateHighlight(TreeItem *))); + // root QList rootData; rootData << tr("Property") << tr("Value") << tr("Unit"); - m_rootItem = new TreeItem(rootData); - - m_settingsTree = new TopTreeItem(tr("Settings"), m_rootItem); - m_settingsTree->setHighlightManager(m_highlightManager); - m_rootItem->appendChild(m_settingsTree); - m_nonSettingsTree = new TopTreeItem(tr("Data Objects"), m_rootItem); - m_nonSettingsTree->setHighlightManager(m_highlightManager); - m_rootItem->appendChild(m_nonSettingsTree); + m_rootItem = new TreeItem(rootData); m_rootItem->setHighlightManager(m_highlightManager); - connect(m_settingsTree, SIGNAL(updateHighlight(TreeItem *)), this, SLOT(updateHighlight(TreeItem *))); - connect(m_nonSettingsTree, SIGNAL(updateHighlight(TreeItem *)), this, SLOT(updateHighlight(TreeItem *))); + + // tree item takes ownership of its children + m_rootItem->appendChild(m_settingsTree); + m_rootItem->appendChild(m_nonSettingsTree); QList< QList > objList = objManager->getDataObjects(); foreach(QList list, objList) { @@ -121,9 +125,11 @@ void UAVObjectTreeModel::addDataObject(UAVDataObject *obj) connect(dataTreeItem, SIGNAL(updateIsKnown(TreeItem *)), this, SLOT(updateIsKnown(TreeItem *))); parent->insertChild(dataTreeItem); root->addObjectTreeItem(obj->getObjID(), dataTreeItem); - UAVMetaObject *meta = obj->getMetaObject(); - MetaObjectTreeItem *metaTreeItem = addMetaObject(meta, dataTreeItem); - root->addMetaObjectTreeItem(meta->getObjID(), metaTreeItem); + if (m_showMetadata) { + UAVMetaObject *meta = obj->getMetaObject(); + MetaObjectTreeItem *metaTreeItem = addMetaObject(meta, dataTreeItem); + root->addMetaObjectTreeItem(meta->getObjID(), metaTreeItem); + } addInstance(obj, dataTreeItem); } } @@ -258,8 +264,7 @@ void UAVObjectTreeModel::addSingleField(int index, UAVObjectField *field, TreeIt parent->appendChild(item); } -QModelIndex UAVObjectTreeModel::index(int row, int column, const QModelIndex &parent) -const +QModelIndex UAVObjectTreeModel::index(int row, int column, const QModelIndex &parent) const { if (!hasIndex(row, column, parent)) { return QModelIndex(); @@ -306,10 +311,11 @@ QModelIndex UAVObjectTreeModel::parent(const QModelIndex &index) const return QModelIndex(); } - TreeItem *childItem = static_cast(index.internalPointer()); - TreeItem *parentItem = childItem->parent(); + TreeItem *item = static_cast(index.internalPointer()); - if (parentItem == m_rootItem) { + TreeItem *parentItem = item->parent(); + if (!parentItem) { + // item is root has no parent... return QModelIndex(); } @@ -363,50 +369,56 @@ QVariant UAVObjectTreeModel::data(const QModelIndex &index, int role) const TreeItem *item = static_cast(index.internalPointer()); - if (index.column() == TreeItem::DATA_COLUMN && role == Qt::EditRole) { + switch (role) { + case Qt::DisplayRole: + if (index.column() == TreeItem::DATA_COLUMN) { + EnumFieldTreeItem *fieldItem = dynamic_cast(item); + if (fieldItem) { + int enumIndex = fieldItem->data(index.column()).toInt(); + return fieldItem->enumOptions(enumIndex); + } + } return item->data(index.column()); - } - if (role == Qt::ToolTipRole) { + case Qt::EditRole: + if (index.column() == TreeItem::DATA_COLUMN) { + return item->data(index.column()); + } + return QVariant(); + + case Qt::ToolTipRole: return item->description(); - } - if (role == Qt::ForegroundRole) { + case Qt::ForegroundRole: if (!dynamic_cast(item) && !item->isKnown()) { - return QVariant(m_unknownObjectColor); + return m_unknownObjectColor; } - } + return QVariant(); - if (index.column() == 0 && role == Qt::BackgroundRole) { - if (!dynamic_cast(item) && item->highlighted()) { - return QVariant(m_recentlyUpdatedColor); + case Qt::BackgroundRole: + if (index.column() == TreeItem::TITLE_COLUMN) { + if (!dynamic_cast(item) && item->highlighted()) { + return m_recentlyUpdatedColor; + } + } else if (index.column() == TreeItem::DATA_COLUMN) { + FieldTreeItem *fieldItem = dynamic_cast(item); + if (fieldItem && fieldItem->highlighted()) { + return m_recentlyUpdatedColor; + } + if (fieldItem && fieldItem->changed()) { + return m_manuallyChangedColor; + } } - } + return QVariant(); - if (index.column() == TreeItem::DATA_COLUMN && role == Qt::BackgroundRole) { - FieldTreeItem *fieldItem = dynamic_cast(item); - if (fieldItem && fieldItem->highlighted()) { - return QVariant(m_recentlyUpdatedColor); - } + case Qt::UserRole: + // UserRole gives access to TreeItem + // cast to void* is necessary + return qVariantFromValue((void *)item); - if (fieldItem && fieldItem->changed()) { - return QVariant(m_manuallyChangedColor); - } - } - - if (role != Qt::DisplayRole) { + default: return QVariant(); } - - if (index.column() == TreeItem::DATA_COLUMN) { - EnumFieldTreeItem *fieldItem = dynamic_cast(item); - if (fieldItem) { - int enumIndex = fieldItem->data(index.column()).toInt(); - return fieldItem->enumOptions(enumIndex); - } - } - - return item->data(index.column()); } bool UAVObjectTreeModel::setData(const QModelIndex &index, const QVariant & value, int role) diff --git a/ground/gcs/src/plugins/uavobjectbrowser/uavobjecttreemodel.h b/ground/gcs/src/plugins/uavobjectbrowser/uavobjecttreemodel.h index 48466f4fa..b7c1d2e8a 100644 --- a/ground/gcs/src/plugins/uavobjectbrowser/uavobjecttreemodel.h +++ b/ground/gcs/src/plugins/uavobjectbrowser/uavobjecttreemodel.h @@ -48,7 +48,8 @@ class QTimer; class UAVObjectTreeModel : public QAbstractItemModel { Q_OBJECT public: - explicit UAVObjectTreeModel(QObject *parent = 0, bool categorize = false, bool useScientificNotation = false); + explicit UAVObjectTreeModel(QObject *parent, bool categorize, bool showMetadata, bool useScientificNotation); + explicit UAVObjectTreeModel(bool categorize, bool showMetadata, bool useScientificNotation); ~UAVObjectTreeModel(); QVariant data(const QModelIndex &index, int role) const; @@ -116,8 +117,9 @@ private: TreeItem *m_rootItem; TopTreeItem *m_settingsTree; TopTreeItem *m_nonSettingsTree; - bool m_useScientificFloatNotation; bool m_categorize; + bool m_showMetadata; + bool m_useScientificFloatNotation; int m_recentlyUpdatedTimeout; QColor m_recentlyUpdatedColor; QColor m_manuallyChangedColor; diff --git a/ground/gcs/src/plugins/uavobjects/uavobject.cpp b/ground/gcs/src/plugins/uavobjects/uavobject.cpp index df26259a5..63b07b8fc 100644 --- a/ground/gcs/src/plugins/uavobjects/uavobject.cpp +++ b/ground/gcs/src/plugins/uavobjects/uavobject.cpp @@ -31,7 +31,10 @@ #include #include -#include +#include +#include +#include +#include using namespace Utils; diff --git a/ground/gcs/src/plugins/uavobjects/uavobject.cpp.template b/ground/gcs/src/plugins/uavobjects/uavobject.cpp.template index a91754136..8ffc58bcc 100644 --- a/ground/gcs/src/plugins/uavobjects/uavobject.cpp.template +++ b/ground/gcs/src/plugins/uavobjects/uavobject.cpp.template @@ -33,6 +33,9 @@ #include "$(NAMELC).h" #include "uavobjectfield.h" +#include "uavobjectmanager.h" + +#include const QString $(NAME)::NAME = QString("$(NAME)"); const QString $(NAME)::DESCRIPTION = QString("$(DESCRIPTION)"); @@ -47,7 +50,7 @@ $(NAME)::$(NAME)(): UAVDataObject(OBJID, ISSINGLEINST, ISSETTINGS, NAME) QList fields; $(FIELDSINIT) // Initialize object - initializeFields(fields, (quint8 *)&data, NUMBYTES); + initializeFields(fields, (quint8 *)&data_, NUMBYTES); // Set the default field values setDefaultFieldValues(); // Set the object description @@ -86,7 +89,7 @@ UAVObject::Metadata $(NAME)::getDefaultMetadata() */ void $(NAME)::setDefaultFieldValues() { -$(INITFIELDS) +$(FIELDSDEFAULT) } /** @@ -95,28 +98,30 @@ $(INITFIELDS) $(NAME)::DataFields $(NAME)::getData() { QMutexLocker locker(mutex); - return data; + return data_; } /** - * Set the object data fields + * Set the object data fields and (optionaly) emit object update events */ -void $(NAME)::setData(const DataFields& data) +void $(NAME)::setData(const DataFields& data, bool emitUpdateEvents) { QMutexLocker locker(mutex); // Get metadata Metadata mdata = getMetadata(); // Update object if the access mode permits if (UAVObject::GetGcsAccess(mdata) == ACCESS_READWRITE) { - this->data = data; - emit objectUpdatedAuto(this); // trigger object updated event - emit objectUpdated(this); + this->data_ = data; + if (emitUpdateEvents) { + emit objectUpdatedAuto(this); // trigger object updated event + emit objectUpdated(this); + } } } void $(NAME)::emitNotifications() { - $(NOTIFY_PROPERTIES_CHANGED) +$(NOTIFY_PROPERTIES_CHANGED) } /** @@ -148,4 +153,11 @@ $(NAME) *$(NAME)::GetInstance(UAVObjectManager *objMngr, quint32 instID) return dynamic_cast<$(NAME) *>(objMngr->getObject($(NAME)::OBJID, instID)); } +/** + * Static function to register QML types. + */ +void $(NAME)::registerQMLTypes() { +$(REGISTER_QML_TYPES) +} + $(PROPERTIES_IMPL) diff --git a/ground/gcs/src/plugins/uavobjects/uavobject.h b/ground/gcs/src/plugins/uavobjects/uavobject.h index 1ad0e7a5b..26c24f037 100644 --- a/ground/gcs/src/plugins/uavobjects/uavobject.h +++ b/ground/gcs/src/plugins/uavobjects/uavobject.h @@ -37,9 +37,6 @@ #include #include #include -#include -#include -#include #include "uavobjectfield.h" @@ -53,6 +50,9 @@ #define UAVOBJ_UPDATE_MODE_MASK 0x3 class UAVObjectField; +class QXmlStreamWriter; +class QXmlStreamReader; +class QJsonObject; class UAVOBJECTS_EXPORT UAVObject : public QObject { Q_OBJECT diff --git a/ground/gcs/src/plugins/uavobjects/uavobject.h.template b/ground/gcs/src/plugins/uavobjects/uavobject.h.template index b800ebb8d..a702d9580 100644 --- a/ground/gcs/src/plugins/uavobjects/uavobject.h.template +++ b/ground/gcs/src/plugins/uavobjects/uavobject.h.template @@ -2,7 +2,8 @@ ****************************************************************************** * * @file $(NAMELC).h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @see The GNU Public License (GPL) Version 3 * @addtogroup GCSPlugins GCS Plugins * @{ @@ -34,13 +35,26 @@ #define $(NAMEUC)_H #include "uavdataobject.h" -#include "uavobjectmanager.h" + +class UAVObjectManager; + +class $(NAME)Constants : public QObject { + Q_OBJECT +public: + enum Enum { $(ENUMS_COUNT) }; + Q_ENUMS(Enum) // TODO switch to Q_ENUM once on Qt 5.5 +}; + +$(ENUMS) class UAVOBJECTS_EXPORT $(NAME): public UAVDataObject { Q_OBJECT $(PROPERTIES) + // Deprecated properties +$(DEPRECATED_PROPERTIES) + public: // Field structure typedef struct { @@ -49,7 +63,7 @@ $(DATAFIELDS) // Field information $(DATAFIELDINFO) - + // Constants static const quint32 OBJID = $(OBJIDHEX); static const QString NAME; @@ -63,13 +77,15 @@ $(DATAFIELDINFO) $(NAME)(); DataFields getData(); - void setData(const DataFields& data); + void setData(const DataFields& data, bool emitUpdateEvents = true); Metadata getDefaultMetadata(); UAVDataObject* clone(quint32 instID); - UAVDataObject* dirtyClone(); - + UAVDataObject* dirtyClone(); + static $(NAME)* GetInstance(UAVObjectManager* objMngr, quint32 instID = 0); + static void registerQMLTypes(); + $(PROPERTY_GETTERS) public slots: @@ -80,9 +96,9 @@ $(PROPERTY_NOTIFICATIONS) private slots: void emitNotifications(); - + private: - DataFields data; + DataFields data_; void setDefaultFieldValues(); diff --git a/ground/gcs/src/plugins/uavobjects/uavobjectfield.cpp b/ground/gcs/src/plugins/uavobjects/uavobjectfield.cpp index 14309f8e6..404b5798f 100644 --- a/ground/gcs/src/plugins/uavobjects/uavobjectfield.cpp +++ b/ground/gcs/src/plugins/uavobjects/uavobjectfield.cpp @@ -26,9 +26,13 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "uavobjectfield.h" + #include #include -#include +#include +#include +#include +#include UAVObjectField::UAVObjectField(const QString & name, const QString & description, const QString & units, FieldType type, quint32 numElements, const QStringList & options, const QString &limits) { diff --git a/ground/gcs/src/plugins/uavobjects/uavobjectfield.h b/ground/gcs/src/plugins/uavobjects/uavobjectfield.h index 6794c7308..42a3de076 100644 --- a/ground/gcs/src/plugins/uavobjects/uavobjectfield.h +++ b/ground/gcs/src/plugins/uavobjects/uavobjectfield.h @@ -30,16 +30,18 @@ #include "uavobjects_global.h" #include "uavobject.h" + #include #include #include #include -#include -#include -#include class UAVObject; +class QXmlStreamWriter; +class QXmlStreamReader; +class QJsonObject; + class UAVOBJECTS_EXPORT UAVObjectField : public QObject { Q_OBJECT diff --git a/ground/gcs/src/plugins/uavobjects/uavobjectmanager.cpp b/ground/gcs/src/plugins/uavobjects/uavobjectmanager.cpp index a90b18dd6..712586ea8 100644 --- a/ground/gcs/src/plugins/uavobjects/uavobjectmanager.cpp +++ b/ground/gcs/src/plugins/uavobjects/uavobjectmanager.cpp @@ -27,7 +27,8 @@ */ #include "uavobjectmanager.h" -#include +#include +#include /** * Constructor diff --git a/ground/gcs/src/plugins/uavobjects/uavobjects.pro b/ground/gcs/src/plugins/uavobjects/uavobjects.pro index 2eaedadb6..92be03832 100644 --- a/ground/gcs/src/plugins/uavobjects/uavobjects.pro +++ b/ground/gcs/src/plugins/uavobjects/uavobjects.pro @@ -3,6 +3,8 @@ TARGET = UAVObjects DEFINES += UAVOBJECTS_LIBRARY +QT += qml + include(../../plugin.pri) include(uavobjects_dependencies.pri) @@ -15,6 +17,7 @@ HEADERS += \ uavobjectfield.h \ uavobjectsinit.h \ uavobjectsplugin.h + SOURCES += \ uavobject.cpp \ uavmetaobject.cpp \ @@ -134,6 +137,8 @@ UAVOBJS = \ $${UAVOBJ_XML_DIR}/statusvtolautotakeoff.xml \ $${UAVOBJ_XML_DIR}/statusvtolland.xml \ $${UAVOBJ_XML_DIR}/systemalarms.xml \ + $${UAVOBJ_XML_DIR}/systemidentsettings.xml \ + $${UAVOBJ_XML_DIR}/systemidentstate.xml \ $${UAVOBJ_XML_DIR}/systemsettings.xml \ $${UAVOBJ_XML_DIR}/systemstats.xml \ $${UAVOBJ_XML_DIR}/takeofflocation.xml \ diff --git a/ground/gcs/src/plugins/uavobjects/uavobjectsplugin.cpp b/ground/gcs/src/plugins/uavobjects/uavobjectsplugin.cpp index 44d53f61a..06242bb1c 100644 --- a/ground/gcs/src/plugins/uavobjects/uavobjectsplugin.cpp +++ b/ground/gcs/src/plugins/uavobjects/uavobjectsplugin.cpp @@ -27,6 +27,7 @@ */ #include "uavobjectsplugin.h" #include "uavobjectsinit.h" +#include "uavobjectmanager.h" UAVObjectsPlugin::UAVObjectsPlugin() {} diff --git a/ground/gcs/src/plugins/uavobjects/uavobjectsplugin.h b/ground/gcs/src/plugins/uavobjects/uavobjectsplugin.h index a684dcc21..0a7b44882 100644 --- a/ground/gcs/src/plugins/uavobjects/uavobjectsplugin.h +++ b/ground/gcs/src/plugins/uavobjects/uavobjectsplugin.h @@ -30,8 +30,8 @@ #include "uavobjects_global.h" #include + #include -#include "uavobjectmanager.h" class UAVOBJECTS_EXPORT UAVObjectsPlugin : public ExtensionSystem::IPlugin { diff --git a/ground/gcs/src/plugins/uavobjectutil/devicedescriptorstruct.h b/ground/gcs/src/plugins/uavobjectutil/devicedescriptorstruct.h index a628ae1b3..bc118a8df 100644 --- a/ground/gcs/src/plugins/uavobjectutil/devicedescriptorstruct.h +++ b/ground/gcs/src/plugins/uavobjectutil/devicedescriptorstruct.h @@ -9,9 +9,9 @@ public: QString gitTag; QByteArray fwHash; QByteArray uavoHash; - int boardType; - int boardRevision; - static QString idToBoardName(int id) + quint8 boardType; + quint8 boardRevision; + static QString idToBoardName(quint16 id) { switch (id) { case 0x0101: @@ -26,7 +26,7 @@ public: break; case 0x0301: // OPLink Mini - return QString("OPLink"); + return QString("OPLinkMini"); break; case 0x0401: @@ -42,12 +42,12 @@ public: break; case 0x0901: - // Revolution + // old unreleased Revolution prototype return QString("Revolution"); break; case 0x0903: - // Revo Mini + // Revo also known as Revo Mini return QString("Revolution"); break; @@ -59,6 +59,10 @@ public: // Nano return QString("RevoNano"); + case 0x9201: + // Sparky 2.0 + return QString("Sparky2"); + default: return QString(""); diff --git a/ground/gcs/src/plugins/uavobjectutil/uavobjectutil.pro b/ground/gcs/src/plugins/uavobjectutil/uavobjectutil.pro index a7fae9bda..161c52cae 100644 --- a/ground/gcs/src/plugins/uavobjectutil/uavobjectutil.pro +++ b/ground/gcs/src/plugins/uavobjectutil/uavobjectutil.pro @@ -1,16 +1,20 @@ TEMPLATE = lib TARGET = UAVObjectUtil + DEFINES += UAVOBJECTUTIL_LIBRARY + include(../../plugin.pri) include(uavobjectutil_dependencies.pri) -HEADERS += uavobjectutil_global.h \ - uavobjectutilmanager.h \ +HEADERS += \ + uavobjectutil_global.h \ + uavobjectutilmanager.h \ uavobjectutilplugin.h \ - devicedescriptorstruct.h \ + devicedescriptorstruct.h \ uavobjecthelper.h -SOURCES += uavobjectutilmanager.cpp \ +SOURCES += \ + uavobjectutilmanager.cpp \ uavobjectutilplugin.cpp \ uavobjecthelper.cpp diff --git a/ground/gcs/src/plugins/uavobjectutil/uavobjectutilmanager.cpp b/ground/gcs/src/plugins/uavobjectutil/uavobjectutilmanager.cpp index 91f6d80cb..b4e2f7f64 100644 --- a/ground/gcs/src/plugins/uavobjectutil/uavobjectutilmanager.cpp +++ b/ground/gcs/src/plugins/uavobjectutil/uavobjectutilmanager.cpp @@ -30,15 +30,15 @@ #include "utils/homelocationutil.h" +#include "objectpersistence.h" +#include "firmwareiapobj.h" +#include "homelocation.h" +#include "gpspositionsensor.h" + #include #include #include #include -#include - -#include "firmwareiapobj.h" -#include "homelocation.h" -#include "gpspositionsensor.h" // ****************************** // constructor/destructor @@ -469,8 +469,8 @@ bool UAVObjectUtilManager::descriptionToStructure(QByteArray desc, deviceDescrip // TODO: check platform compatibility QByteArray targetPlatform = desc.mid(12, 2); - struc.boardType = (int)targetPlatform.at(0); - struc.boardRevision = (int)targetPlatform.at(1); + struc.boardType = (quint8)targetPlatform.at(0); + struc.boardRevision = (quint8)targetPlatform.at(1); struc.fwHash.clear(); struc.fwHash = desc.mid(40, 20); struc.uavoHash.clear(); diff --git a/ground/gcs/src/plugins/uavobjectutil/uavobjectutilmanager.h b/ground/gcs/src/plugins/uavobjectutil/uavobjectutilmanager.h index e8279e93e..2b298e3e3 100644 --- a/ground/gcs/src/plugins/uavobjectutil/uavobjectutilmanager.h +++ b/ground/gcs/src/plugins/uavobjectutil/uavobjectutilmanager.h @@ -34,16 +34,17 @@ #include "extensionsystem/pluginmanager.h" #include "uavobjectmanager.h" #include "uavobject.h" -#include "objectpersistence.h" #include "devicedescriptorstruct.h" + +#include "objectpersistence.h" +#include "firmwareiapobj.h" + #include #include #include #include #include -#include #include -#include class UAVOBJECTUTIL_EXPORT UAVObjectUtilManager : public QObject { Q_OBJECT diff --git a/ground/gcs/src/plugins/uavobjectwidgetutils/configtaskwidget.cpp b/ground/gcs/src/plugins/uavobjectwidgetutils/configtaskwidget.cpp index 57ca3968c..371b24e26 100644 --- a/ground/gcs/src/plugins/uavobjectwidgetutils/configtaskwidget.cpp +++ b/ground/gcs/src/plugins/uavobjectwidgetutils/configtaskwidget.cpp @@ -27,27 +27,84 @@ */ #include "configtaskwidget.h" -#include +#include +#include "uavobjectmanager.h" +#include "uavobject.h" +#include "uavobjectutilmanager.h" +#include "uavtalk/telemetrymanager.h" +#include "uavtalk/oplinkmanager.h" #include "uavsettingsimportexport/uavsettingsimportexportfactory.h" +#include "smartsavebutton.h" +#include "mixercurvewidget.h" -#include +#include +#include +#include +#include #include +#include +#include +#include #include +#include +#include -ConfigTaskWidget::ConfigTaskWidget(QWidget *parent) : QWidget(parent), m_currentBoardId(-1), m_isConnected(false), m_isWidgetUpdatesAllowed(true), m_wikiURL("Welcome"), - m_saveButton(NULL), m_isDirty(false), m_outOfLimitsStyle("background-color: rgb(255, 0, 0);"), m_realtimeUpdateTimer(NULL) +ConfigTaskWidget::ConfigTaskWidget(QWidget *parent, bool autopilot) : QWidget(parent), + m_currentBoardId(-1), m_isConnected(false), m_isWidgetUpdatesAllowed(true), m_isDirty(false), m_refreshing(false), + m_wikiURL("Welcome"), m_saveButton(NULL), m_outOfLimitsStyle("background-color: rgb(255, 0, 0);"), m_realtimeUpdateTimer(NULL) { + m_autopilot = autopilot; + m_pluginManager = ExtensionSystem::PluginManager::instance(); - TelemetryManager *telMngr = m_pluginManager->getObject(); + m_objectUtilManager = m_pluginManager->getObject(); - connect(telMngr, SIGNAL(connected()), this, SLOT(onAutopilotConnect()), Qt::UniqueConnection); - connect(telMngr, SIGNAL(disconnected()), this, SLOT(onAutopilotDisconnect()), Qt::UniqueConnection); - connect(telMngr, SIGNAL(connected()), this, SIGNAL(autoPilotConnected()), Qt::UniqueConnection); - connect(telMngr, SIGNAL(disconnected()), this, SIGNAL(autoPilotDisconnected()), Qt::UniqueConnection); UAVSettingsImportExportFactory *importexportplugin = m_pluginManager->getObject(); connect(importexportplugin, SIGNAL(importAboutToBegin()), this, SLOT(invalidateObjects())); + + m_saveButton = new SmartSaveButton(this); + connect(m_saveButton, SIGNAL(preProcessOperations()), this, SLOT(updateObjectsFromWidgets())); + connect(m_saveButton, SIGNAL(saveSuccessfull()), this, SLOT(clearDirty())); + connect(m_saveButton, SIGNAL(beginOp()), this, SLOT(disableObjectUpdates())); + connect(m_saveButton, SIGNAL(endOp()), this, SLOT(enableObjectUpdates())); + + if (m_autopilot) { + // connect to telemetry manager + TelemetryManager *tm = m_pluginManager->getObject(); + connect(tm, SIGNAL(connected()), this, SLOT(onConnect())); + connect(tm, SIGNAL(disconnected()), this, SLOT(onDisconnect())); + } else { + // connect to oplink manager + OPLinkManager *om = m_pluginManager->getObject(); + connect(om, SIGNAL(connected()), this, SLOT(onConnect())); + connect(om, SIGNAL(disconnected()), this, SLOT(onDisconnect())); + } } +ConfigTaskWidget::~ConfigTaskWidget() +{ + if (m_saveButton) { + delete m_saveButton; + } + QSet deleteSet = m_widgetBindingsPerWidget.values().toSet(); + foreach(WidgetBinding * binding, deleteSet) { + if (binding) { + delete binding; + } + } + if (m_realtimeUpdateTimer) { + delete m_realtimeUpdateTimer; + m_realtimeUpdateTimer = NULL; + } +} + +bool ConfigTaskWidget::expertMode() const +{ + Core::Internal::GeneralSettings *settings = m_pluginManager->getObject(); + + return settings->useExpertMode(); +} + + void ConfigTaskWidget::addWidget(QWidget *widget) { addWidgetBinding("", "", widget); @@ -124,10 +181,14 @@ void ConfigTaskWidget::addWidgetBinding(QString objectName, QString fieldName, Q void ConfigTaskWidget::doAddWidgetBinding(QString objectName, QString fieldName, QWidget *widget, int index, double scale, bool isLimited, QList *reloadGroupIDs, quint32 instID) { + // add a shadow binding to an existing binding (if any) if (addShadowWidgetBinding(objectName, fieldName, widget, index, scale, isLimited, reloadGroupIDs, instID)) { + // no need to go further if successful return; } + // qDebug() << "ConfigTaskWidget::doAddWidgetBinding - add binding for " << objectName << fieldName << widget; + UAVObject *object = NULL; UAVObjectField *field = NULL; if (!objectName.isEmpty()) { @@ -178,7 +239,7 @@ void ConfigTaskWidget::setWidgetBindingObjectEnabled(QString objectName, bool en Q_ASSERT(object); - bool dirtyBack = isDirty(); + m_refreshing = true; foreach(WidgetBinding * binding, m_widgetBindingsPerObject.values(object)) { binding->setIsEnabled(enabled); @@ -190,24 +251,8 @@ void ConfigTaskWidget::setWidgetBindingObjectEnabled(QString objectName, bool en } } } - setDirty(dirtyBack); -} -ConfigTaskWidget::~ConfigTaskWidget() -{ - if (m_saveButton) { - delete m_saveButton; - } - QSet deleteSet = m_widgetBindingsPerWidget.values().toSet(); - foreach(WidgetBinding * binding, deleteSet) { - if (binding) { - delete binding; - } - } - if (m_realtimeUpdateTimer) { - delete m_realtimeUpdateTimer; - m_realtimeUpdateTimer = NULL; - } + m_refreshing = true; } bool ConfigTaskWidget::isComboboxOptionSelected(QComboBox *combo, int optionValue) @@ -248,80 +293,70 @@ void ConfigTaskWidget::enableComboBoxOptionItem(QComboBox *combo, int optionValu !enable ? QVariant(0) : QVariant(1 | 32), Qt::UserRole - 1); } -void ConfigTaskWidget::saveObjectToSD(UAVObject *obj) -{ - // saveObjectToSD is now handled by the UAVUtils plugin in one - // central place (and one central queue) - ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); - UAVObjectUtilManager *utilMngr = pm->getObject(); - - utilMngr->saveObjectToSD(obj); -} - UAVObjectManager *ConfigTaskWidget::getObjectManager() { - ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); - UAVObjectManager *objMngr = pm->getObject(); + UAVObjectManager *objMngr = m_pluginManager->getObject(); Q_ASSERT(objMngr); return objMngr; } +bool ConfigTaskWidget::isConnected() const +{ + bool connected = false; -void ConfigTaskWidget::onAutopilotDisconnect() + if (m_autopilot) { + TelemetryManager *tm = m_pluginManager->getObject(); + connected = tm->isConnected(); + } else { + OPLinkManager *om = m_pluginManager->getObject(); + connected = om->isConnected(); + } + return connected; +} + +// dynamic widgets don't receive the connected signal. This should be called instead. +void ConfigTaskWidget::bind() +{ + if (isConnected()) { + onConnect(); + } else { + refreshWidgetsValues(); + updateEnableControls(); + } +} + +void ConfigTaskWidget::onConnect() +{ + if (m_autopilot) { + m_currentBoardId = m_objectUtilManager->getBoardModel(); + } + + m_isConnected = true; + + invalidateObjects(); + + resetLimits(); + updateEnableControls(); + + emit connected(); + + refreshWidgetsValues(); + + setDirty(false); +} + +void ConfigTaskWidget::onDisconnect() { m_isConnected = false; - // Reset board ID and clear bound combo box lists to force repopulation - // when we get another connected signal. This means that we get the - // correct values in combo boxes bound to fields with limits applied. + emit disconnected(); + + updateEnableControls(); + invalidateObjects(); + + // reset board ID m_currentBoardId = -1; - - foreach(WidgetBinding * binding, m_widgetBindingsPerObject) { - QComboBox *cb; - - if (binding->widget() && (cb = qobject_cast(binding->widget()))) { - cb->clear(); - } - } - - enableControls(false); - invalidateObjects(); -} - -// dynamic widgets don't recieve the connected signal. This should be called instead. -void ConfigTaskWidget::forceConnectedState() -{ - if (m_objectUtilManager) { - m_currentBoardId = m_objectUtilManager->getBoardModel(); - } - m_isConnected = true; - setDirty(false); -} - -void ConfigTaskWidget::onAutopilotConnect() -{ - if (m_objectUtilManager) { - m_currentBoardId = m_objectUtilManager->getBoardModel(); - } - invalidateObjects(); - m_isConnected = true; - setDirty(false); - enableControls(true); - refreshWidgetsValues(); -} - -void ConfigTaskWidget::populateWidgets() -{ - bool dirtyBack = isDirty(); - emit populateWidgetsRequested(); - - foreach(WidgetBinding * binding, m_widgetBindingsPerObject) { - if (binding->isEnabled() && binding->object() != NULL && binding->field() != NULL && binding->widget() != NULL) { - setWidgetFromField(binding->widget(), binding->field(), binding); - } - } - setDirty(dirtyBack); } void ConfigTaskWidget::refreshWidgetsValues(UAVObject *obj) @@ -330,11 +365,11 @@ void ConfigTaskWidget::refreshWidgetsValues(UAVObject *obj) return; } - bool dirtyBack = isDirty(); - emit refreshWidgetsValuesRequested(); + m_refreshing = true; + QList bindings = obj == NULL ? m_widgetBindingsPerObject.values() : m_widgetBindingsPerObject.values(obj); foreach(WidgetBinding * binding, bindings) { - if (binding->field() != NULL && binding->widget() != NULL) { + if (binding->field() && binding->widget()) { if (binding->isEnabled()) { setWidgetFromField(binding->widget(), binding->field(), binding); } else { @@ -342,18 +377,23 @@ void ConfigTaskWidget::refreshWidgetsValues(UAVObject *obj) } } } - setDirty(dirtyBack); + + // call specific implementation + refreshWidgetsValuesImpl(obj); + + m_refreshing = false; } void ConfigTaskWidget::updateObjectsFromWidgets() { - emit updateObjectsFromWidgetsRequested(); - foreach(WidgetBinding * binding, m_widgetBindingsPerObject) { - if (binding->object() != NULL && binding->field() != NULL) { + if (binding->object() && binding->field()) { binding->updateObjectFieldFromValue(); } } + + // call specific implementation + updateObjectsFromWidgetsImpl(); } void ConfigTaskWidget::helpButtonPressed() @@ -365,26 +405,15 @@ void ConfigTaskWidget::helpButtonPressed() } } -void ConfigTaskWidget::addApplySaveButtons(QPushButton *update, QPushButton *save) +void ConfigTaskWidget::addApplyButton(QPushButton *button) { - if (!m_saveButton) { - m_saveButton = new SmartSaveButton(this); - connect(m_saveButton, SIGNAL(preProcessOperations()), this, SLOT(updateObjectsFromWidgets())); - connect(m_saveButton, SIGNAL(saveSuccessfull()), this, SLOT(clearDirty())); - connect(m_saveButton, SIGNAL(beginOp()), this, SLOT(disableObjectUpdates())); - connect(m_saveButton, SIGNAL(endOp()), this, SLOT(enableObjectUpdates())); - } - if (update && save) { - m_saveButton->addButtons(save, update); - } else if (update) { - m_saveButton->addApplyButton(update); - } else if (save) { - m_saveButton->addSaveButton(save); - } - foreach(WidgetBinding * binding, m_widgetBindingsPerWidget) { - m_saveButton->addObject((UAVDataObject *)binding->object()); - } - updateEnableControls(); + m_saveButton->addApplyButton(button); + button->setVisible(expertMode()); +} + +void ConfigTaskWidget::addSaveButton(QPushButton *button) +{ + m_saveButton->addSaveButton(button); } void ConfigTaskWidget::enableControls(bool enable) @@ -405,6 +434,7 @@ void ConfigTaskWidget::enableControls(bool enable) } } } + emit enableControlsChanged(enable); } @@ -414,28 +444,6 @@ bool ConfigTaskWidget::shouldObjectBeSaved(UAVObject *object) return true; } -void ConfigTaskWidget::forceShadowUpdates() -{ - foreach(WidgetBinding * binding, m_widgetBindingsPerObject) { - if (!binding->isEnabled()) { - continue; - } - QVariant widgetValue = getVariantFromWidget(binding->widget(), binding); - - foreach(ShadowWidgetBinding * shadow, binding->shadows()) { - disconnectWidgetUpdatesToSlot(shadow->widget(), SLOT(widgetsContentsChanged())); - - checkWidgetsLimits(shadow->widget(), binding->field(), binding->index(), shadow->isLimited(), widgetValue, shadow->scale()); - - WidgetBinding tmpBinding(shadow->widget(), binding->object(), binding->field(), binding->index(), shadow->scale(), shadow->isLimited()); - setWidgetFromVariant(shadow->widget(), widgetValue, &tmpBinding); - - emit widgetContentsChanged(shadow->widget()); - connectWidgetUpdatesToSlot(shadow->widget(), SLOT(widgetsContentsChanged())); - } - } - setDirty(true); -} void ConfigTaskWidget::widgetsContentsChanged() { @@ -498,6 +506,9 @@ void ConfigTaskWidget::clearDirty() void ConfigTaskWidget::setDirty(bool value) { + if (m_refreshing) { + return; + } m_isDirty = value; } @@ -540,7 +551,10 @@ bool ConfigTaskWidget::allObjectsUpdated() bool result = true; foreach(UAVObject * object, m_updatedObjects.keys()) { - result = result & m_updatedObjects[object]; + result &= m_updatedObjects[object]; + if (!result) { + break; + } } return result; } @@ -585,6 +599,7 @@ bool ConfigTaskWidget::addShadowWidgetBinding(QString objectName, QString fieldN continue; } if (binding->matches(objectName, fieldName, index, instID)) { + // qDebug() << "ConfigTaskWidget::addShadowWidgetBinding - add shadow binding for " << objectName << fieldName << widget; binding->addShadow(widget, scale, isLimited); m_widgetBindingsPerWidget.insert(widget, binding); @@ -601,10 +616,9 @@ bool ConfigTaskWidget::addShadowWidgetBinding(QString objectName, QString fieldN return false; } -void ConfigTaskWidget::autoLoadWidgets() +void ConfigTaskWidget::addAutoBindings() { - QPushButton *saveButtonWidget = NULL; - QPushButton *applyButtonWidget = NULL; + // qDebug() << "ConfigTaskWidget::addAutoBindings() - auto binding" << this; foreach(QWidget * widget, this->findChildren()) { QVariant info = widget->property("objrelation"); @@ -660,19 +674,19 @@ void ConfigTaskWidget::autoLoadWidgets() uiRelation.url = str.mid(str.indexOf(":") + 1); } } - if (!(uiRelation.buttonType == none)) { + if (uiRelation.buttonType != none) { QPushButton *button = NULL; switch (uiRelation.buttonType) { case save_button: - saveButtonWidget = qobject_cast(widget); - if (saveButtonWidget) { - addApplySaveButtons(NULL, saveButtonWidget); + button = qobject_cast(widget); + if (button) { + addSaveButton(button); } break; case apply_button: - applyButtonWidget = qobject_cast(widget); - if (applyButtonWidget) { - addApplySaveButtons(applyButtonWidget, NULL); + button = qobject_cast(widget); + if (button) { + addApplyButton(button); } break; case default_button: @@ -708,12 +722,18 @@ void ConfigTaskWidget::autoLoadWidgets() } } } + foreach(WidgetBinding * binding, m_widgetBindingsPerWidget) { + if (binding->object()) { + m_saveButton->addObject((UAVDataObject *)binding->object()); + } + } } - refreshWidgetsValues(); - forceShadowUpdates(); + // qDebug() << "ConfigTaskWidget::addAutoBindings() - auto binding done for" << this; +} - /* - foreach(WidgetBinding * binding, m_widgetBindingsPerObject) { +void ConfigTaskWidget::dumpBindings() +{ + foreach(WidgetBinding * binding, m_widgetBindingsPerObject) { if (binding->widget()) { qDebug() << "Binding :" << binding->widget()->objectName(); qDebug() << " Object :" << binding->object()->getName(); @@ -727,8 +747,7 @@ void ConfigTaskWidget::autoLoadWidgets() qDebug() << " Scale :" << shadow->scale(); } } - } - */ + } } void ConfigTaskWidget::addWidgetToReloadGroups(QWidget *widget, QList *reloadGroupIDs) @@ -799,7 +818,7 @@ void ConfigTaskWidget::reloadButtonClicked() QList temp; foreach(WidgetBinding * binding, bindings) { - if (binding->isEnabled() && binding->object() != NULL) { + if (binding->isEnabled() && binding->object()) { objectComparator value; value.objid = binding->object()->getObjID(); value.objinstid = binding->object()->getInstID(); @@ -861,8 +880,12 @@ void ConfigTaskWidget::connectWidgetUpdatesToSlot(QWidget *widget, const char *f connect(cb, SIGNAL(clicked()), this, function, Qt::UniqueConnection); } else if (QToolButton * cb = qobject_cast(widget)) { connect(cb, SIGNAL(clicked()), this, function, Qt::UniqueConnection); + } else if (qobject_cast(widget)) { + // read only + } else if (qobject_cast(widget)) { + // read only } else { - qDebug() << __FUNCTION__ << "widget binding not implemented" << widget->metaObject()->className(); + qDebug() << __FUNCTION__ << "widget binding not implemented for" << widget->metaObject()->className(); } } @@ -891,8 +914,12 @@ void ConfigTaskWidget::disconnectWidgetUpdatesToSlot(QWidget *widget, const char disconnect(cb, SIGNAL(clicked()), this, function); } else if (QToolButton * cb = qobject_cast(widget)) { disconnect(cb, SIGNAL(clicked()), this, function); + } else if (qobject_cast(widget)) { + // read only + } else if (qobject_cast(widget)) { + // read only } else { - qDebug() << __FUNCTION__ << "widget binding not implemented" << widget->metaObject()->className(); + qDebug() << __FUNCTION__ << "widget binding not implemented for" << widget->metaObject()->className(); } } @@ -904,7 +931,7 @@ QVariant ConfigTaskWidget::getVariantFromWidget(QWidget *widget, WidgetBinding * if (binding->isInteger()) { return QVariant(getComboboxSelectedOption(cb)); } - return (QString)cb->currentText(); + return cb->currentText(); } else if (QDoubleSpinBox * cb = qobject_cast(widget)) { return (double)(cb->value() * scale); } else if (QSpinBox * cb = qobject_cast(widget)) { @@ -912,18 +939,17 @@ QVariant ConfigTaskWidget::getVariantFromWidget(QWidget *widget, WidgetBinding * } else if (QSlider * cb = qobject_cast(widget)) { return (double)(cb->value() * scale); } else if (QCheckBox * cb = qobject_cast(widget)) { - return (QString)(cb->isChecked() ? "TRUE" : "FALSE"); + return cb->isChecked() ? "True" : "False"; } else if (QLineEdit * cb = qobject_cast(widget)) { - QString value = (QString)cb->displayText(); + QString value = cb->displayText(); if (binding->units() == "hex") { bool ok; return value.toUInt(&ok, 16); } else { return value; } - } else { - return QVariant(); } + return QVariant(); } bool ConfigTaskWidget::setWidgetFromVariant(QWidget *widget, QVariant value, WidgetBinding *binding) @@ -939,10 +965,19 @@ bool ConfigTaskWidget::setWidgetFromVariant(QWidget *widget, QVariant value, Wid } return ok; } else if (QLabel * cb = qobject_cast(widget)) { - if (scale == 0) { - cb->setText(value.toString()); + if ((scale == 0) || (scale == 1)) { + if (binding->units() == "hex") { + if (value.toUInt()) { + cb->setText(QString::number(value.toUInt(), 16).toUpper()); + } else { + // display 0 as an empty string + cb->setText(""); + } + } else { + cb->setText(value.toString()); + } } else { - cb->setText(QString::number((value.toDouble() / scale))); + cb->setText(QString::number(value.toDouble() / scale)); } return true; } else if (QDoubleSpinBox * cb = qobject_cast(widget)) { @@ -955,23 +990,26 @@ bool ConfigTaskWidget::setWidgetFromVariant(QWidget *widget, QVariant value, Wid cb->setValue((int)qRound(value.toDouble() / scale)); return true; } else if (QCheckBox * cb = qobject_cast(widget)) { - bool bvalue = value.toString() == "TRUE"; - cb->setChecked(bvalue); + cb->setChecked(value.toString() == "True"); return true; } else if (QLineEdit * cb = qobject_cast(widget)) { if ((scale == 0) || (scale == 1)) { if (binding->units() == "hex") { - cb->setText(QString::number(value.toUInt(), 16).toUpper()); + if (value.toUInt()) { + cb->setText(QString::number(value.toUInt(), 16).toUpper()); + } else { + // display 0 as an empty string + cb->setText(""); + } } else { cb->setText(value.toString()); } } else { - cb->setText(QString::number((value.toDouble() / scale))); + cb->setText(QString::number(value.toDouble() / scale)); } return true; - } else { - return false; } + return false; } bool ConfigTaskWidget::setWidgetFromField(QWidget *widget, UAVObjectField *field, WidgetBinding *binding) @@ -990,11 +1028,25 @@ bool ConfigTaskWidget::setWidgetFromField(QWidget *widget, UAVObjectField *field if (result) { return true; } else { - qDebug() << __FUNCTION__ << "widget to uavobject relation not implemented" << widget->metaObject()->className(); + qDebug() << __FUNCTION__ << "widget to uavobject relation not implemented for" << widget->metaObject()->className(); return false; } } +void ConfigTaskWidget::resetLimits() +{ + // clear bound combo box lists to force repopulation + // when we get another connected signal. This means that we get the + // correct values in combo boxes bound to fields with limits applied. + foreach(WidgetBinding * binding, m_widgetBindingsPerObject) { + QComboBox *cb; + + if (binding->widget() && (cb = qobject_cast(binding->widget()))) { + cb->clear(); + } + } +} + void ConfigTaskWidget::checkWidgetsLimits(QWidget *widget, UAVObjectField *field, int index, bool hasLimits, QVariant value, double scale) { if (!hasLimits) { @@ -1041,26 +1093,16 @@ void ConfigTaskWidget::checkWidgetsLimits(QWidget *widget, UAVObjectField *field } } -void ConfigTaskWidget::loadWidgetLimits(QWidget *widget, UAVObjectField *field, int index, bool hasLimits, double scale) +void ConfigTaskWidget::loadWidgetLimits(QWidget *widget, UAVObjectField *field, int index, bool applyLimits, double scale) { if (!widget || !field) { return; } if (QComboBox * cb = qobject_cast(widget)) { cb->clear(); - QStringList options = field->getOptions(); - - for (int optionIndex = 0; optionIndex < options.count(); optionIndex++) { - if (hasLimits) { - if (m_currentBoardId > -1 && field->isWithinLimits(options.at(optionIndex), index, m_currentBoardId)) { - cb->addItem(options.at(optionIndex), QVariant(optionIndex)); - } - } else { - cb->addItem(options.at(optionIndex), QVariant(optionIndex)); - } - } + buildOptionComboBox(cb, field, index, applyLimits); } - if (!hasLimits) { + if (!applyLimits) { return; } else if (QDoubleSpinBox * cb = qobject_cast(widget)) { if (field->getMaxLimit(index).isValid()) { @@ -1098,11 +1140,24 @@ QString ConfigTaskWidget::mapObjectName(const QString objectName) void ConfigTaskWidget::updateEnableControls() { - TelemetryManager *telMngr = m_pluginManager->getObject(); + enableControls(isConnected()); +} - Q_ASSERT(telMngr); +void ConfigTaskWidget::buildOptionComboBox(QComboBox *combo, UAVObjectField *field, int index, bool applyLimits) +{ + QStringList options = field->getOptions(); - enableControls(telMngr->isConnected()); + // qDebug() << "buildOptionComboBox" << field << applyLimits << m_currentBoardId; + for (int optionIndex = 0; optionIndex < options.count(); optionIndex++) { + if (applyLimits) { + // qDebug() << " " << options.at(optionIndex) << field->isWithinLimits(options.at(optionIndex), index, m_currentBoardId); + if (m_currentBoardId > -1 && field->isWithinLimits(options.at(optionIndex), index, m_currentBoardId)) { + combo->addItem(options.at(optionIndex), QVariant(optionIndex)); + } + } else { + combo->addItem(options.at(optionIndex), QVariant(optionIndex)); + } + } } void ConfigTaskWidget::disableMouseWheelEvents() @@ -1235,11 +1290,6 @@ QVariant WidgetBinding::value() const void WidgetBinding::setValue(const QVariant &value) { m_value = value; - /* - if (m_object && m_field) { - qDebug() << "WidgetBinding" << m_object->getName() << ":" << m_field->getName() << "value =" << value.toString(); - } - */ } void WidgetBinding::updateObjectFieldFromValue() diff --git a/ground/gcs/src/plugins/uavobjectwidgetutils/configtaskwidget.h b/ground/gcs/src/plugins/uavobjectwidgetutils/configtaskwidget.h index 18fa3c3af..b0f0cc7eb 100644 --- a/ground/gcs/src/plugins/uavobjectwidgetutils/configtaskwidget.h +++ b/ground/gcs/src/plugins/uavobjectwidgetutils/configtaskwidget.h @@ -27,25 +27,24 @@ #ifndef CONFIGTASKWIDGET_H #define CONFIGTASKWIDGET_H -#include "extensionsystem/pluginmanager.h" -#include "uavobjectmanager.h" -#include "uavobject.h" -#include "uavobjectutilmanager.h" -#include +#include "uavobjectwidgetutils_global.h" + #include #include -#include -#include "smartsavebutton.h" -#include "mixercurvewidget.h" -#include -#include -#include -#include -#include -#include "uavobjectwidgetutils_global.h" -#include -#include -#include +#include + +namespace ExtensionSystem { +class PluginManager; +} +class UAVObject; +class UAVObjectField; +class UAVObjectManager; +class UAVObjectUtilManager; +class SmartSaveButton; + +class QComboBox; +class QPushButton; +class QEvent; class ShadowWidgetBinding : public QObject { Q_OBJECT @@ -101,9 +100,17 @@ class UAVOBJECTWIDGETUTILS_EXPORT ConfigTaskWidget : public QWidget { Q_OBJECT public: - ConfigTaskWidget(QWidget *parent = 0); + ConfigTaskWidget(QWidget *parent = 0, bool autopilot = true); virtual ~ConfigTaskWidget(); + void bind(); + + bool isDirty(); + void setDirty(bool value); + + virtual bool shouldObjectBeSaved(UAVObject *object); + +protected: // Combobox helper functions static bool isComboboxOptionSelected(QComboBox *combo, int optionValue); static int getComboboxSelectedOption(QComboBox *combo); @@ -114,12 +121,13 @@ public: void disableMouseWheelEvents(); bool eventFilter(QObject *obj, QEvent *evt); - void saveObjectToSD(UAVObject *obj); UAVObjectManager *getObjectManager(); void addUAVObject(QString objectName, QList *reloadGroups = NULL); void addUAVObject(UAVObject *objectName, QList *reloadGroups = NULL); +// TODO should be protected (see VehicleConfig::registerWidgets(ConfigTaskWidget &parent) +public: void addWidget(QWidget *widget); void addWidgetBinding(QString objectName, QString fieldName, QWidget *widget, int index = 0, double scale = 1, @@ -127,6 +135,9 @@ public: void addWidgetBinding(UAVObject *object, UAVObjectField *field, QWidget *widget, int index = 0, double scale = 1, bool isLimited = false, QList *reloadGroupIDs = 0, quint32 instID = 0); +protected: + void addAutoBindings(); + void addWidgetBinding(QString objectName, QString fieldName, QWidget *widget, QString elementName, double scale, bool isLimited = false, QList *reloadGroupIDs = 0, quint32 instID = 0); void addWidgetBinding(UAVObject *object, UAVObjectField *field, QWidget *widget, QString elementName, double scale, @@ -135,20 +146,11 @@ public: void addWidgetBinding(QString objectName, QString fieldName, QWidget *widget, QString elementName); void addWidgetBinding(UAVObject *object, UAVObjectField *field, QWidget *widget, QString elementName); - void addApplySaveButtons(QPushButton *update, QPushButton *save); - void addReloadButton(QPushButton *button, int buttonGroup); - void addDefaultButton(QPushButton *button, int buttonGroup); - void addWidgetToReloadGroups(QWidget *widget, QList *reloadGroupIDs); bool addShadowWidgetBinding(QString objectName, QString fieldName, QWidget *widget, int index = 0, double scale = 1, bool isLimited = false, QList *m_reloadGroups = NULL, quint32 instID = 0); - void autoLoadWidgets(); - - bool isDirty(); - virtual void setDirty(bool value); - bool allObjectsUpdated(); void setOutOfLimitsStyle(QString style) { @@ -156,38 +158,56 @@ public: } void addHelpButton(QPushButton *button, QString url); void setWikiURL(QString url); - void forceShadowUpdates(); - void forceConnectedState(); - virtual bool shouldObjectBeSaved(UAVObject *object); -public slots: - void onAutopilotDisconnect(); - void onAutopilotConnect(); - void invalidateObjects(); +protected slots: void apply(); void save(); - void setWidgetBindingObjectEnabled(QString objectName, bool enabled); signals: - // fired when a widgets contents changes + void connected(); + void disconnected(); void widgetContentsChanged(QWidget *widget); - // fired when the framework requests that the widgets values be populated, use for custom behaviour - void populateWidgetsRequested(); - // fired when the framework requests that the widgets values be refreshed, use for custom behaviour - void refreshWidgetsValuesRequested(); - // fired when the framework requests that the UAVObject values be updated from the widgets value, use for custom behaviour - void updateObjectsFromWidgetsRequested(); - // fired when the autopilot connects - void autoPilotConnected(); - // fired when the autopilot disconnects - void autoPilotDisconnected(); void defaultRequested(int group); void enableControlsChanged(bool enable); +protected: + int boardModel() const + { + return m_currentBoardId; + } + bool expertMode() const; + virtual void enableControls(bool enable); + virtual QString mapObjectName(const QString objectName); + virtual UAVObject *getObject(const QString name, quint32 instId = 0); + virtual void buildOptionComboBox(QComboBox *combo, UAVObjectField *field, int index, bool applyLimits); + void updateEnableControls(); + + bool isConnected() const; + + virtual void refreshWidgetsValuesImpl(UAVObject *) {}; + virtual void updateObjectsFromWidgetsImpl() {}; + +protected slots: + void setWidgetBindingObjectEnabled(QString objectName, bool enabled); + + void clearDirty(); + virtual void widgetsContentsChanged(); + // void populateWidgets(); + void refreshWidgetsValues(UAVObject *obj = NULL); + void updateObjectsFromWidgets(); + private slots: + void onConnect(); + void onDisconnect(); + + void disableObjectUpdates(); + void enableObjectUpdates(); void objectUpdated(UAVObject *object); + void invalidateObjects(); + void defaultButtonClicked(); void reloadButtonClicked(); + void helpButtonPressed(); private: struct objectComparator { @@ -212,12 +232,22 @@ private: bool haslimits; }; + // indicates if this is an "autopilot" widget (CC3D, Revolution, ...) or an OPLink widget + // TODO the logic that this flag controls should be moved to derived classes + bool m_autopilot; + + // only valid for "autopilot" widgets int m_currentBoardId; + bool m_isConnected; bool m_isWidgetUpdatesAllowed; + bool m_isDirty; + bool m_refreshing; + QStringList m_objects; - QString m_wikiURL; // Wiki address for help button - // Concatenated with WIKI_URL_ROOT + + // Wiki address for help button (will be concatenated with WIKI_URL_ROOT) + QString m_wikiURL; QMultiHash m_reloadGroups; QMultiHash m_widgetBindingsPerWidget; @@ -225,11 +255,13 @@ private: ExtensionSystem::PluginManager *m_pluginManager; UAVObjectUtilManager *m_objectUtilManager; - SmartSaveButton *m_saveButton; + QHash m_updatedObjects; + + SmartSaveButton *m_saveButton; QHash m_helpButtons; QList m_reloadButtons; - bool m_isDirty; + QString m_outOfLimitsStyle; QTimer *m_realtimeUpdateTimer; @@ -241,29 +273,23 @@ private: void connectWidgetUpdatesToSlot(QWidget *widget, const char *function); void disconnectWidgetUpdatesToSlot(QWidget *widget, const char *function); - void loadWidgetLimits(QWidget *widget, UAVObjectField *field, int index, bool hasLimits, double sclale); + void resetLimits(); + + void loadWidgetLimits(QWidget *widget, UAVObjectField *field, int index, bool applyLimits, double scale); + + void checkWidgetsLimits(QWidget *widget, UAVObjectField *field, int index, bool hasLimits, QVariant value, double scale); + + void dumpBindings(); int fieldIndexFromElementName(QString objectName, QString fieldName, QString elementName); void doAddWidgetBinding(QString objectName, QString fieldName, QWidget *widget, int index = 0, double scale = 1, bool isLimited = false, QList *reloadGroupIDs = 0, quint32 instID = 0); -protected slots: - virtual void disableObjectUpdates(); - virtual void enableObjectUpdates(); - virtual void clearDirty(); - virtual void widgetsContentsChanged(); - virtual void populateWidgets(); - virtual void refreshWidgetsValues(UAVObject *obj = NULL); - virtual void updateObjectsFromWidgets(); - virtual void helpButtonPressed(); - -protected: - virtual void enableControls(bool enable); - virtual QString mapObjectName(const QString objectName); - virtual UAVObject *getObject(const QString name, quint32 instId = 0); - void checkWidgetsLimits(QWidget *widget, UAVObjectField *field, int index, bool hasLimits, QVariant value, double scale); - void updateEnableControls(); + void addApplyButton(QPushButton *button); + void addSaveButton(QPushButton *button); + void addReloadButton(QPushButton *button, int buttonGroup); + void addDefaultButton(QPushButton *button, int buttonGroup); }; #endif // CONFIGTASKWIDGET_H diff --git a/ground/gcs/src/plugins/uavobjectwidgetutils/smartsavebutton.cpp b/ground/gcs/src/plugins/uavobjectwidgetutils/smartsavebutton.cpp index 454743191..41fbfb60a 100644 --- a/ground/gcs/src/plugins/uavobjectwidgetutils/smartsavebutton.cpp +++ b/ground/gcs/src/plugins/uavobjectwidgetutils/smartsavebutton.cpp @@ -30,23 +30,18 @@ SmartSaveButton::SmartSaveButton(ConfigTaskWidget *configTaskWidget) : configWidget(configTaskWidget) {} -void SmartSaveButton::addButtons(QPushButton *save, QPushButton *apply) -{ - buttonList.insert(save, save_button); - buttonList.insert(apply, apply_button); - connect(save, SIGNAL(clicked()), this, SLOT(processClick())); - connect(apply, SIGNAL(clicked()), this, SLOT(processClick())); -} void SmartSaveButton::addApplyButton(QPushButton *apply) { buttonList.insert(apply, apply_button); connect(apply, SIGNAL(clicked()), this, SLOT(processClick())); } + void SmartSaveButton::addSaveButton(QPushButton *save) { buttonList.insert(save, save_button); connect(save, SIGNAL(clicked()), this, SLOT(processClick())); } + void SmartSaveButton::processClick() { emit beginOp(); @@ -76,6 +71,9 @@ void SmartSaveButton::processOperation(QPushButton *button, bool save) ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); UAVObjectUtilManager *utilMngr = pm->getObject(); foreach(UAVDataObject * obj, objects) { + if (!obj) { + continue; + } UAVObject::Metadata mdata = obj->getMetadata(); // Should we really save this object to the board? @@ -165,24 +163,29 @@ void SmartSaveButton::setObjects(QList list) void SmartSaveButton::addObject(UAVDataObject *obj) { Q_ASSERT(obj); - if (!objects.contains(obj)) { + if (obj && !objects.contains(obj)) { objects.append(obj); } } + void SmartSaveButton::removeObject(UAVDataObject *obj) { - if (objects.contains(obj)) { + Q_ASSERT(obj); + if (obj && objects.contains(obj)) { objects.removeAll(obj); } } + void SmartSaveButton::removeAllObjects() { objects.clear(); } + void SmartSaveButton::clearObjects() { objects.clear(); } + void SmartSaveButton::transaction_finished(UAVObject *obj, bool result) { if (current_object == obj) { diff --git a/ground/gcs/src/plugins/uavobjectwidgetutils/smartsavebutton.h b/ground/gcs/src/plugins/uavobjectwidgetutils/smartsavebutton.h index eb9339458..9bdf6736f 100644 --- a/ground/gcs/src/plugins/uavobjectwidgetutils/smartsavebutton.h +++ b/ground/gcs/src/plugins/uavobjectwidgetutils/smartsavebutton.h @@ -46,7 +46,6 @@ public: public: SmartSaveButton(ConfigTaskWidget *configTaskWidget); - void addButtons(QPushButton *save, QPushButton *apply); void setObjects(QList); void addObject(UAVDataObject *); void clearObjects(); diff --git a/ground/gcs/src/plugins/uavobjectwidgetutils/uavobjectwidgetutils.pro b/ground/gcs/src/plugins/uavobjectwidgetutils/uavobjectwidgetutils.pro index 1e8151426..fdf33be25 100644 --- a/ground/gcs/src/plugins/uavobjectwidgetutils/uavobjectwidgetutils.pro +++ b/ground/gcs/src/plugins/uavobjectwidgetutils/uavobjectwidgetutils.pro @@ -1,12 +1,15 @@ TEMPLATE = lib TARGET = UAVObjectWidgetUtils + DEFINES += UAVOBJECTWIDGETUTILS_LIBRARY -QT += svg + +QT += widgets svg include(../../plugin.pri) include(uavobjectwidgetutils_dependencies.pri) -HEADERS += uavobjectwidgetutils_global.h \ +HEADERS += \ + uavobjectwidgetutils_global.h \ uavobjectwidgetutilsplugin.h \ configtaskwidget.h \ mixercurvewidget.h \ @@ -15,7 +18,8 @@ HEADERS += uavobjectwidgetutils_global.h \ smartsavebutton.h \ popupwidget.h -SOURCES += uavobjectwidgetutilsplugin.cpp \ +SOURCES += \ + uavobjectwidgetutilsplugin.cpp \ configtaskwidget.cpp \ mixercurvewidget.cpp \ mixercurvepoint.cpp \ diff --git a/ground/gcs/src/plugins/uavsettingsimportexport/importsummary.cpp b/ground/gcs/src/plugins/uavsettingsimportexport/importsummary.cpp index c70f028d5..6d7409bc4 100644 --- a/ground/gcs/src/plugins/uavsettingsimportexport/importsummary.cpp +++ b/ground/gcs/src/plugins/uavsettingsimportexport/importsummary.cpp @@ -27,6 +27,10 @@ */ #include "importsummary.h" +#include +#include +#include + ImportSummaryDialog::ImportSummaryDialog(QWidget *parent) : QDialog(parent), ui(new Ui::ImportSummaryDialog) @@ -79,8 +83,8 @@ void ImportSummaryDialog::addLine(QString uavObjectName, QString text, bool stat ui->importSummaryList->setItem(row, 2, new QTableWidgetItem(text)); // Disable editability and selectability in table elements - ui->importSummaryList->item(row, 1)->setFlags(!Qt::ItemIsEditable); - ui->importSummaryList->item(row, 2)->setFlags(!Qt::ItemIsEditable); + ui->importSummaryList->item(row, 1)->setFlags(ui->importSummaryList->item(row, 1)->flags() &= ~Qt::ItemIsEditable); + ui->importSummaryList->item(row, 2)->setFlags(ui->importSummaryList->item(row, 2)->flags() &= ~Qt::ItemIsEditable); if (status) { box->setChecked(true); diff --git a/ground/gcs/src/plugins/uavsettingsimportexport/importsummary.h b/ground/gcs/src/plugins/uavsettingsimportexport/importsummary.h index 524897c5b..5aa3f6fce 100644 --- a/ground/gcs/src/plugins/uavsettingsimportexport/importsummary.h +++ b/ground/gcs/src/plugins/uavsettingsimportexport/importsummary.h @@ -27,16 +27,13 @@ #ifndef IMPORTSUMMARY_H #define IMPORTSUMMARY_H -#include -#include -#include -#include #include "ui_importsummarydialog.h" #include "uavdataobject.h" #include "uavobjectmanager.h" #include "extensionsystem/pluginmanager.h" #include "uavobjectutil/uavobjectutilmanager.h" +#include namespace Ui { class ImportSummaryDialog; diff --git a/ground/gcs/src/plugins/uavsettingsimportexport/uavsettingsimportexport.cpp b/ground/gcs/src/plugins/uavsettingsimportexport/uavsettingsimportexport.cpp index 8b4fe1ec3..97a13bd25 100644 --- a/ground/gcs/src/plugins/uavsettingsimportexport/uavsettingsimportexport.cpp +++ b/ground/gcs/src/plugins/uavsettingsimportexport/uavsettingsimportexport.cpp @@ -27,28 +27,18 @@ #include "uavsettingsimportexport.h" -#include -#include -#include -#include -#include "importsummary.h" -// for menu item #include #include #include -#include -// for UAVObjects #include "uavdataobject.h" #include "uavobjectmanager.h" #include "extensionsystem/pluginmanager.h" -// for XML object -#include +#include "importsummary.h" -// for file dialog and error messages -#include -#include +#include +#include UAVSettingsImportExportPlugin::UAVSettingsImportExportPlugin() { diff --git a/ground/gcs/src/plugins/uavsettingsimportexport/uavsettingsimportexport.pro b/ground/gcs/src/plugins/uavsettingsimportexport/uavsettingsimportexport.pro index 80e0fbbb7..c415aae10 100644 --- a/ground/gcs/src/plugins/uavsettingsimportexport/uavsettingsimportexport.pro +++ b/ground/gcs/src/plugins/uavsettingsimportexport/uavsettingsimportexport.pro @@ -1,17 +1,21 @@ - TEMPLATE = lib -QT += xml - TARGET = UAVSettingsImportExport + +QT += widgets xml + DEFINES += UAVSETTINGSIMPORTEXPORT_LIBRARY + include(../../plugin.pri) include(uavsettingsimportexport_dependencies.pri) include(../../libs/version_info/version_info.pri) -HEADERS += uavsettingsimportexport.h \ +HEADERS += \ + uavsettingsimportexport.h \ importsummary.h \ uavsettingsimportexportfactory.h -SOURCES += uavsettingsimportexport.cpp \ + +SOURCES += \ + uavsettingsimportexport.cpp \ importsummary.cpp \ uavsettingsimportexportfactory.cpp diff --git a/ground/gcs/src/plugins/uavtalk/oplinkmanager.cpp b/ground/gcs/src/plugins/uavtalk/oplinkmanager.cpp new file mode 100644 index 000000000..0d598ef28 --- /dev/null +++ b/ground/gcs/src/plugins/uavtalk/oplinkmanager.cpp @@ -0,0 +1,131 @@ +/** + ****************************************************************************** + * + * @file oplinkmanager.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * @addtogroup GCSPlugins GCS Plugins + * @{ + * @addtogroup UAVTalkPlugin UAVTalk Plugin + * @{ + * @brief The UAVTalk protocol plugin + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "oplinkmanager.h" + +#include +#include +#include +#include + +#include + +#include + +OPLinkManager::OPLinkManager() : QObject(), m_isConnected(false), m_opLinkType(OPLinkManager::OPLINK_UNKNOWN) +{ + // connect to the connection manager + Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager(); + + connect(cm, SIGNAL(deviceConnected(QIODevice *)), this, SLOT(onDeviceConnect())); + connect(cm, SIGNAL(deviceDisconnected()), this, SLOT(onDeviceDisconnect())); + + if (cm->isConnected()) { + onDeviceConnect(); + } +} + +OPLinkManager::~OPLinkManager() +{} + +bool OPLinkManager::isConnected() const +{ + return m_isConnected; +} + +void OPLinkManager::onDeviceConnect() +{ + if (m_isConnected) { + return; + } + + ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); + Q_ASSERT(pm); + + UAVObjectManager *objManager = pm->getObject(); + Q_ASSERT(objManager); + + m_opLinkStatus = OPLinkStatus::GetInstance(objManager); + Q_ASSERT(m_opLinkStatus); + + // start monitoring OPLinkStatus + connect(m_opLinkStatus, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(onOPLinkStatusUpdate()), Qt::UniqueConnection); +} + +void OPLinkManager::onDeviceDisconnect() +{ + onOPLinkDisconnect(); +} + +void OPLinkManager::onOPLinkStatusUpdate() +{ + int type = m_opLinkStatus->boardType(); + + switch (type) { + case 0x03: + m_opLinkType = OPLINK_MINI; + onOPLinkConnect(); + break; + case 0x09: + m_opLinkType = OPLINK_REVOLUTION; + onOPLinkConnect(); + break; + case 0x92: + m_opLinkType = OPLINK_SPARKY2; + onOPLinkConnect(); + break; + default: + m_opLinkType = OPLINK_UNKNOWN; + // stop monitoring status updates... + m_opLinkStatus->disconnect(this); + break; + } +} + +void OPLinkManager::onOPLinkConnect() +{ + if (m_isConnected) { + return; + } + // stop monitoring status updates... + m_opLinkStatus->disconnect(this); + + m_isConnected = true; + emit connected(); +} + +void OPLinkManager::onOPLinkDisconnect() +{ + if (!m_isConnected) { + return; + } + // stop monitoring status updates... + m_opLinkStatus->disconnect(this); + + m_isConnected = false; + emit disconnected(); +} diff --git a/ground/gcs/src/plugins/uploader/oplinkwatchdog.h b/ground/gcs/src/plugins/uavtalk/oplinkmanager.h similarity index 64% rename from ground/gcs/src/plugins/uploader/oplinkwatchdog.h rename to ground/gcs/src/plugins/uavtalk/oplinkmanager.h index 1427a159b..0dc08cb92 100644 --- a/ground/gcs/src/plugins/uploader/oplinkwatchdog.h +++ b/ground/gcs/src/plugins/uavtalk/oplinkmanager.h @@ -1,13 +1,13 @@ /** ****************************************************************************** * - * @file oplinkwatchdog.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. - * @addtogroup [Group] + * @file oplinkmanager.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * @addtogroup GCSPlugins GCS Plugins * @{ - * @addtogroup OPLinkWatchdog + * @addtogroup UAVTalkPlugin UAVTalk Plugin * @{ - * @brief [Brief] + * @brief The UAVTalk protocol plugin *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify @@ -25,46 +25,51 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef OPLINKWATCHDOG_H -#define OPLINKWATCHDOG_H +#ifndef OPLINK_MANAGER_H +#define OPLINK_MANAGER_H -#include +#include "uavtalk_global.h" + +#include class OPLinkStatus; -class OPLinkWatchdog : public QObject { + +class UAVTALK_EXPORT OPLinkManager : public QObject { Q_OBJECT + public: enum OPLinkType { + OPLINK_UNKNOWN, OPLINK_MINI, OPLINK_REVOLUTION, - OPLINK_UNKNOWN + OPLINK_SPARKY2 }; - OPLinkWatchdog(); - ~OPLinkWatchdog(); - bool isConnected() const - { - return m_isConnected; - } - OPLinkWatchdog::OPLinkType opLinkType() const + OPLinkManager(); + ~OPLinkManager(); + + OPLinkManager::OPLinkType opLinkType() const { return m_opLinkType; } + bool isConnected() const; + signals: void connected(); - void opLinkMiniConnected(); - void opLinkRevolutionConnected(); void disconnected(); private slots: + void onDeviceConnect(); + void onDeviceDisconnect(); void onOPLinkStatusUpdate(); - void onTimeout(); + void onOPLinkConnect(); + void onOPLinkDisconnect(); private: bool m_isConnected; OPLinkType m_opLinkType; - QTimer *m_watchdog; OPLinkStatus *m_opLinkStatus; }; -#endif // OPLINKWATCHDOG_H + +#endif // OPLINK_MANAGER_H diff --git a/ground/gcs/src/plugins/uavtalk/telemetry.cpp b/ground/gcs/src/plugins/uavtalk/telemetry.cpp index 909714f2b..78602919f 100644 --- a/ground/gcs/src/plugins/uavtalk/telemetry.cpp +++ b/ground/gcs/src/plugins/uavtalk/telemetry.cpp @@ -607,12 +607,12 @@ ObjectTransactionInfo *Telemetry::findTransaction(UAVObject *obj) quint16 instId = obj->getInstID(); // Lookup the transaction in the transaction map - QMap *objTransactions = transMap.value(objId); + QMap *objTransactions = transMap.value(objId, NULL); if (objTransactions != NULL) { - ObjectTransactionInfo *trans = objTransactions->value(instId); + ObjectTransactionInfo *trans = objTransactions->value(instId, NULL); if (trans == NULL) { // see if there is an ALL_INSTANCES transaction - trans = objTransactions->value(UAVTalk::ALL_INSTANCES); + trans = objTransactions->value(UAVTalk::ALL_INSTANCES, NULL); } return trans; } @@ -624,7 +624,7 @@ void Telemetry::openTransaction(ObjectTransactionInfo *trans) quint32 objId = trans->obj->getObjID(); quint16 instId = trans->allInstances ? UAVTalk::ALL_INSTANCES : trans->obj->getInstID(); - QMap *objTransactions = transMap.value(objId); + QMap *objTransactions = transMap.value(objId, NULL); if (objTransactions == NULL) { objTransactions = new QMap(); transMap.insert(objId, objTransactions); @@ -637,7 +637,7 @@ void Telemetry::closeTransaction(ObjectTransactionInfo *trans) quint32 objId = trans->obj->getObjID(); quint16 instId = trans->allInstances ? UAVTalk::ALL_INSTANCES : trans->obj->getInstID(); - QMap *objTransactions = transMap.value(objId); + QMap *objTransactions = transMap.value(objId, NULL); if (objTransactions != NULL) { objTransactions->remove(instId); // Keep the map even if it is empty @@ -649,9 +649,9 @@ void Telemetry::closeTransaction(ObjectTransactionInfo *trans) void Telemetry::closeAllTransactions() { foreach(quint32 objId, transMap.keys()) { - QMap *objTransactions = transMap.value(objId); + QMap *objTransactions = transMap.value(objId, NULL); foreach(quint32 instId, objTransactions->keys()) { - ObjectTransactionInfo *trans = objTransactions->value(instId); + ObjectTransactionInfo *trans = objTransactions->value(instId, NULL); qWarning() << "Telemetry - closing active transaction for object" << trans->obj->toStringBrief(); objTransactions->remove(instId); diff --git a/ground/gcs/src/plugins/uavtalk/telemetrymanager.cpp b/ground/gcs/src/plugins/uavtalk/telemetrymanager.cpp index 37f8e5f0b..bf5a02e54 100644 --- a/ground/gcs/src/plugins/uavtalk/telemetrymanager.cpp +++ b/ground/gcs/src/plugins/uavtalk/telemetrymanager.cpp @@ -2,7 +2,8 @@ ****************************************************************************** * * @file telemetrymanager.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup UAVTalkPlugin UAVTalk Plugin @@ -32,9 +33,10 @@ #include #include -TelemetryManager::TelemetryManager() : m_connectionState(TELEMETRY_DISCONNECTED) +TelemetryManager::TelemetryManager() : QObject(), m_connectionState(TELEMETRY_DISCONNECTED) { moveToThread(Core::ICore::instance()->threadManager()->getRealTimeThread()); + // Get UAVObjectManager instance ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); m_uavobjectManager = pm->getObject(); diff --git a/ground/gcs/src/plugins/uavtalk/telemetrymanager.h b/ground/gcs/src/plugins/uavtalk/telemetrymanager.h index f42959283..63e9708c3 100644 --- a/ground/gcs/src/plugins/uavtalk/telemetrymanager.h +++ b/ground/gcs/src/plugins/uavtalk/telemetrymanager.h @@ -1,8 +1,9 @@ /** ****************************************************************************** * - * @file telemetrymanager.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @file telemetrymanager.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup UAVTalkPlugin UAVTalk Plugin @@ -25,8 +26,8 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef TELEMETRYMANAGER_H -#define TELEMETRYMANAGER_H +#ifndef TELEMETRY_MANAGER_H +#define TELEMETRY_MANAGER_H #include "uavtalk_global.h" #include "uavtalk.h" @@ -94,4 +95,4 @@ public slots: void read(); }; -#endif // TELEMETRYMANAGER_H +#endif // TELEMETRY_MANAGER_H diff --git a/ground/gcs/src/plugins/uavtalk/telemetrymonitor.cpp b/ground/gcs/src/plugins/uavtalk/telemetrymonitor.cpp index b488dc9b9..311398db6 100644 --- a/ground/gcs/src/plugins/uavtalk/telemetrymonitor.cpp +++ b/ground/gcs/src/plugins/uavtalk/telemetrymonitor.cpp @@ -2,7 +2,8 @@ ****************************************************************************** * * @file telemetrymonitor.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup UAVTalkPlugin UAVTalk Plugin @@ -88,8 +89,7 @@ void TelemetryMonitor::startRetrievingObjects() } } // Start retrieving - qDebug() << tr("Starting to retrieve meta and settings objects from the autopilot (%1 objects)") - .arg(queue.length()); + qDebug() << "TelemetryMonitor::startRetrievingObjects - retrieving" << queue.length() << "objects"; retrieveNextObject(); } @@ -98,7 +98,7 @@ void TelemetryMonitor::startRetrievingObjects() */ void TelemetryMonitor::stopRetrievingObjects() { - qDebug("Object retrieval has been cancelled"); + qDebug() << "TelemetryMonitor::stopRetrievingObjects - object retrieval has been cancelled"; queue.clear(); } @@ -109,7 +109,7 @@ void TelemetryMonitor::retrieveNextObject() { // If queue is empty return if (queue.isEmpty()) { - qDebug("Object retrieval completed"); + qDebug() << "TelemetryMonitor::retrieveNextObject - object retrieval completed"; if (firmwareIAPObj->getBoardType()) { emit connected(); } else { @@ -142,14 +142,16 @@ void TelemetryMonitor::transactionCompleted(UAVObject *obj, bool success) // Disconnect from sending object obj->disconnect(this); objPending = NULL; + // Process next object if telemetry is still available GCSTelemetryStats::DataFields gcsStats = gcsStatsObj->getData(); - if (gcsStats.Status == GCSTelemetryStats::STATUS_CONNECTED) { retrieveNextObject(); } else { stopRetrievingObjects(); } + } else { + qCritical() << "TelemetryMonitor::retrieveNextObject - unexpected object" << obj; } } @@ -252,13 +254,12 @@ void TelemetryMonitor::processStatsUpdates() // Act on new connections or disconnections if (gcsStats.Status == GCSTelemetryStats::STATUS_CONNECTED && gcsStats.Status != oldStatus) { statsTimer->setInterval(STATS_UPDATE_PERIOD_MS); - qDebug("Connection with the autopilot established"); + qDebug() << "TelemetryMonitor::processStatsUpdates - connection with the autopilot established"; startRetrievingObjects(); } if (gcsStats.Status == GCSTelemetryStats::STATUS_DISCONNECTED && gcsStats.Status != oldStatus) { statsTimer->setInterval(STATS_CONNECT_PERIOD_MS); - qDebug("Connection with the autopilot lost"); - qDebug("Trying to connect to the autopilot"); + qDebug() << "TelemetryMonitor::processStatsUpdates - connection with the autopilot lost"; emit disconnected(); } } diff --git a/ground/gcs/src/plugins/uavtalk/uavtalk.cpp b/ground/gcs/src/plugins/uavtalk/uavtalk.cpp index 08ac75935..8bb246d90 100644 --- a/ground/gcs/src/plugins/uavtalk/uavtalk.cpp +++ b/ground/gcs/src/plugins/uavtalk/uavtalk.cpp @@ -59,7 +59,9 @@ UAVTalk::UAVTalk(QIODevice *iodev, UAVObjectManager *objMngr) : io(iodev), objMn ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); Core::Internal::GeneralSettings *settings = pm->getObject(); useUDPMirror = settings->useUDPMirror(); - qDebug() << "USE UDP:::::::::::." << useUDPMirror; + if (useUDPMirror) { + qDebug() << "UAVTalk::UAVTalk -*** UDP mirror is enabled ***"; + } if (useUDPMirror) { udpSocketTx = new QUdpSocket(this); udpSocketRx = new QUdpSocket(this); @@ -815,12 +817,12 @@ bool UAVTalk::transmitSingleObject(quint8 type, quint32 objId, quint16 instId, U UAVTalk::Transaction *UAVTalk::findTransaction(quint32 objId, quint16 instId) { // Lookup the transaction in the transaction map - QMap *objTransactions = transMap.value(objId); + QMap *objTransactions = transMap.value(objId, NULL); if (objTransactions != NULL) { - Transaction *trans = objTransactions->value(instId); + Transaction *trans = objTransactions->value(instId, NULL); if (trans == NULL) { // see if there is an ALL_INSTANCES transaction - trans = objTransactions->value(ALL_INSTANCES); + trans = objTransactions->value(ALL_INSTANCES, NULL); } return trans; } @@ -835,7 +837,7 @@ void UAVTalk::openTransaction(quint8 type, quint32 objId, quint16 instId) trans->respObjId = objId; trans->respInstId = instId; - QMap *objTransactions = transMap.value(trans->respObjId); + QMap *objTransactions = transMap.value(trans->respObjId, NULL); if (objTransactions == NULL) { objTransactions = new QMap(); transMap.insert(trans->respObjId, objTransactions); @@ -845,7 +847,7 @@ void UAVTalk::openTransaction(quint8 type, quint32 objId, quint16 instId) void UAVTalk::closeTransaction(Transaction *trans) { - QMap *objTransactions = transMap.value(trans->respObjId); + QMap *objTransactions = transMap.value(trans->respObjId, NULL); if (objTransactions != NULL) { objTransactions->remove(trans->respInstId); // Keep the map even if it is empty @@ -857,9 +859,9 @@ void UAVTalk::closeTransaction(Transaction *trans) void UAVTalk::closeAllTransactions() { foreach(quint32 objId, transMap.keys()) { - QMap *objTransactions = transMap.value(objId); + QMap *objTransactions = transMap.value(objId, NULL); foreach(quint32 instId, objTransactions->keys()) { - Transaction *trans = objTransactions->value(instId); + Transaction *trans = objTransactions->value(instId, NULL); qWarning() << "UAVTalk - closing active transaction for object" << trans->respObjId; objTransactions->remove(instId); diff --git a/ground/gcs/src/plugins/uavtalk/uavtalk.pro b/ground/gcs/src/plugins/uavtalk/uavtalk.pro index e84b124e1..9b762192a 100644 --- a/ground/gcs/src/plugins/uavtalk/uavtalk.pro +++ b/ground/gcs/src/plugins/uavtalk/uavtalk.pro @@ -1,7 +1,7 @@ TEMPLATE = lib TARGET = UAVTalk -QT += network +QT += widgets network DEFINES += UAVTALK_LIBRARY @@ -12,18 +12,20 @@ include(../../plugin.pri) include(uavtalk_dependencies.pri) HEADERS += \ + uavtalk_global.h \ uavtalk.h \ - uavtalkplugin.h \ + telemetry.h \ telemetrymonitor.h \ telemetrymanager.h \ - uavtalk_global.h \ - telemetry.h + oplinkmanager.h \ + uavtalkplugin.h SOURCES += \ uavtalk.cpp \ - uavtalkplugin.cpp \ + telemetry.cpp \ telemetrymonitor.cpp \ telemetrymanager.cpp \ - telemetry.cpp + oplinkmanager.cpp \ + uavtalkplugin.cpp OTHER_FILES += UAVTalk.pluginspec diff --git a/ground/gcs/src/plugins/uavtalk/uavtalkplugin.cpp b/ground/gcs/src/plugins/uavtalk/uavtalkplugin.cpp index 472b00ed3..83484f3a6 100644 --- a/ground/gcs/src/plugins/uavtalk/uavtalkplugin.cpp +++ b/ground/gcs/src/plugins/uavtalk/uavtalkplugin.cpp @@ -2,7 +2,8 @@ ****************************************************************************** * * @file uavtalkplugin.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup UAVTalkPlugin UAVTalk Plugin @@ -26,14 +27,18 @@ */ #include "uavtalkplugin.h" +#include "telemetrymanager.h" +#include "oplinkmanager.h" + #include #include -UAVTalkPlugin::UAVTalkPlugin() +UAVTalkPlugin::UAVTalkPlugin() : telemetryManager(0) {} UAVTalkPlugin::~UAVTalkPlugin() {} + /** * Called once all the plugins which depend on us have been loaded */ @@ -50,15 +55,18 @@ bool UAVTalkPlugin::initialize(const QStringList & arguments, QString *errorStri Q_UNUSED(errorString); // Create TelemetryManager - telMngr = new TelemetryManager(); - addAutoReleasedObject(telMngr); + telemetryManager = new TelemetryManager(); + addAutoReleasedObject(telemetryManager); + + // Create OPLinkManager + OPLinkManager *opLinkManager = new OPLinkManager(); + addAutoReleasedObject(opLinkManager); // Connect to connection manager so we get notified when the user connect to his device Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager(); - QObject::connect(cm, SIGNAL(deviceConnected(QIODevice *)), - this, SLOT(onDeviceConnect(QIODevice *))); - QObject::connect(cm, SIGNAL(deviceAboutToDisconnect()), - this, SLOT(onDeviceDisconnect())); + QObject::connect(cm, SIGNAL(deviceConnected(QIODevice *)), this, SLOT(onDeviceConnect(QIODevice *))); + QObject::connect(cm, SIGNAL(deviceAboutToDisconnect()), this, SLOT(onDeviceDisconnect())); + return true; } @@ -67,10 +75,10 @@ void UAVTalkPlugin::shutdown() void UAVTalkPlugin::onDeviceConnect(QIODevice *dev) { - telMngr->start(dev); + telemetryManager->start(dev); } void UAVTalkPlugin::onDeviceDisconnect() { - telMngr->stop(); + telemetryManager->stop(); } diff --git a/ground/gcs/src/plugins/uavtalk/uavtalkplugin.h b/ground/gcs/src/plugins/uavtalk/uavtalkplugin.h index 58b23764d..5c72133b5 100644 --- a/ground/gcs/src/plugins/uavtalk/uavtalkplugin.h +++ b/ground/gcs/src/plugins/uavtalk/uavtalkplugin.h @@ -2,7 +2,8 @@ ****************************************************************************** * * @file uavtalkplugin.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup UAVTalkPlugin UAVTalk Plugin @@ -28,10 +29,9 @@ #define UAVTALKPLUGIN_H #include -#include -#include #include "uavtalk.h" -#include "telemetrymanager.h" + +class TelemetryManager; class UAVTALK_EXPORT UAVTalkPlugin : public ExtensionSystem::IPlugin { Q_OBJECT @@ -50,7 +50,7 @@ protected slots: void onDeviceDisconnect(); private: - TelemetryManager *telMngr; + TelemetryManager *telemetryManager; }; #endif // UAVTALKPLUGIN_H diff --git a/ground/gcs/src/plugins/uploader/devicewidget.cpp b/ground/gcs/src/plugins/uploader/devicewidget.cpp index 300ac4ee4..b4ac58a0a 100644 --- a/ground/gcs/src/plugins/uploader/devicewidget.cpp +++ b/ground/gcs/src/plugins/uploader/devicewidget.cpp @@ -2,7 +2,8 @@ ****************************************************************************** * * @file devicewidget.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup Uploader Serial and USB Uploader Plugin @@ -100,14 +101,21 @@ void DeviceWidget::populate() devicePic.load(":/uploader/images/gcs-board-cc3d.png"); break; case 0x0903: + // Revo devicePic.load(":/uploader/images/gcs-board-revo.png"); break; case 0x0904: + // DiscoveryF4Bare devicePic.load(":/uploader/images/gcs-board-revo.png"); break; case 0x0905: + // Nano devicePic.load(":/uploader/images/gcs-board-nano.png"); break; + case 0x9201: + // Sparky2 + devicePic.load(":/uploader/images/gcs-board-sparky2.png"); + break; default: // Clear devicePic.load(""); @@ -195,7 +203,7 @@ bool DeviceWidget::populateBoardStructuredDescription(QByteArray desc) myDevice->lblCertified->setToolTip(tr("Untagged or custom firmware build")); } - myDevice->lblBrdName->setText(deviceDescriptorStruct::idToBoardName(onBoardDescription.boardType << 8 | onBoardDescription.boardRevision)); + myDevice->lblBrdName->setText(deviceDescriptorStruct::idToBoardName(((quint16)onBoardDescription.boardType << 8) | onBoardDescription.boardRevision)); return true; } @@ -219,7 +227,7 @@ bool DeviceWidget::populateLoadedStructuredDescription(QByteArray desc) myDevice->lblCertifiedL->setPixmap(QPixmap(":uploader/images/warning.svg")); myDevice->lblCertifiedL->setToolTip(tr("Untagged or custom firmware build")); } - myDevice->lblBrdNameL->setText(deviceDescriptorStruct::idToBoardName(LoadedDescription.boardType << 8 | LoadedDescription.boardRevision)); + myDevice->lblBrdNameL->setText(deviceDescriptorStruct::idToBoardName(((quint16)LoadedDescription.boardType << 8) | LoadedDescription.boardRevision)); return true; } @@ -363,13 +371,16 @@ void DeviceWidget::uploadFirmware() // Now do sanity checking: // - Check whether board type matches firmware: int board = m_dfu->devices[deviceID].ID; - int firmwareBoard = ((desc.at(12) & 0xff) << 8) + (desc.at(13) & 0xff); - if ((board == 0x401 && firmwareBoard == 0x402) || - (board == 0x901 && firmwareBoard == 0x902) || // L3GD20 revo supports Revolution firmware - (board == 0x902 && firmwareBoard == 0x903)) { // RevoMini1 supporetd by RevoMini2 firmware + int firmwareBoard = ((quint16)(quint8)desc.at(12) << 8) + (quint16)(quint8)desc.at(13); + if ((board == 0x0401 && firmwareBoard == 0x0402) || + (board == 0x0901 && firmwareBoard == 0x0902) || // L3GD20 revo supports Revolution firmware + (board == 0x0902 && firmwareBoard == 0x0903) || // RevoMini1 supported by RevoMini2 firmware + (board == 0x0b01 && firmwareBoard == 0x9201)) { // Sparky2 before and after TL BL compatibility change // These firmwares are designed to be backwards compatible } else if (firmwareBoard != board) { - status("Error: firmware does not match board", STATUSICON_FAIL); + char buf[100]; + sprintf(buf, "Error: Device ID: firmware 0x%x does not match board 0x%x", firmwareBoard, board); + status(buf, STATUSICON_FAIL); updateButtons(true); return; } diff --git a/ground/gcs/src/plugins/uploader/devicewidget.ui b/ground/gcs/src/plugins/uploader/devicewidget.ui index daf488a6c..4ca3c24c5 100644 --- a/ground/gcs/src/plugins/uploader/devicewidget.ui +++ b/ground/gcs/src/plugins/uploader/devicewidget.ui @@ -68,28 +68,28 @@ - lblDevName + lblDevName - DeviceID + DeviceID - lblHWRev + lblHWRev - RW + RW @@ -328,35 +328,35 @@ - lblBrdName + lblBrdName - lblDescription + lblDescription - lblBuildDate + lblBuildDate - lblGitTag + lblGitTag - lblCRC + lblCRC @@ -365,7 +365,7 @@ - lblCertified + lblCertified false @@ -405,35 +405,35 @@ - lblBrdName + lblBrdName - lblDescritpionL + lblDescritpionL - lblBuildDate + lblBuildDate - lblGitTag + lblGitTag - lblCRC + lblCRC @@ -442,7 +442,7 @@ - lblCertifiedL + lblCertifiedL diff --git a/ground/gcs/src/plugins/uploader/images/gcs-board-cc.png b/ground/gcs/src/plugins/uploader/images/gcs-board-cc.png index ee6affc3c..4bafdda0a 100644 Binary files a/ground/gcs/src/plugins/uploader/images/gcs-board-cc.png and b/ground/gcs/src/plugins/uploader/images/gcs-board-cc.png differ diff --git a/ground/gcs/src/plugins/uploader/images/gcs-board-cc3d.png b/ground/gcs/src/plugins/uploader/images/gcs-board-cc3d.png index 24326c952..6fbb5ad45 100644 Binary files a/ground/gcs/src/plugins/uploader/images/gcs-board-cc3d.png and b/ground/gcs/src/plugins/uploader/images/gcs-board-cc3d.png differ diff --git a/ground/gcs/src/plugins/uploader/images/gcs-board-nano.png b/ground/gcs/src/plugins/uploader/images/gcs-board-nano.png index 15abf5a9c..ec4cafece 100644 Binary files a/ground/gcs/src/plugins/uploader/images/gcs-board-nano.png and b/ground/gcs/src/plugins/uploader/images/gcs-board-nano.png differ diff --git a/ground/gcs/src/plugins/uploader/images/gcs-board-oplink.png b/ground/gcs/src/plugins/uploader/images/gcs-board-oplink.png index 34cadf8bf..ebca186c2 100644 Binary files a/ground/gcs/src/plugins/uploader/images/gcs-board-oplink.png and b/ground/gcs/src/plugins/uploader/images/gcs-board-oplink.png differ diff --git a/ground/gcs/src/plugins/uploader/images/gcs-board-revo.png b/ground/gcs/src/plugins/uploader/images/gcs-board-revo.png index 7580003ba..089288dbd 100644 Binary files a/ground/gcs/src/plugins/uploader/images/gcs-board-revo.png and b/ground/gcs/src/plugins/uploader/images/gcs-board-revo.png differ diff --git a/ground/gcs/src/plugins/uploader/images/gcs-board-sparky2.png b/ground/gcs/src/plugins/uploader/images/gcs-board-sparky2.png new file mode 100644 index 000000000..645580c2e Binary files /dev/null and b/ground/gcs/src/plugins/uploader/images/gcs-board-sparky2.png differ diff --git a/ground/gcs/src/plugins/uploader/images/pipx.png b/ground/gcs/src/plugins/uploader/images/pipx.png index 47c8bb4e1..fc9864dea 100644 Binary files a/ground/gcs/src/plugins/uploader/images/pipx.png and b/ground/gcs/src/plugins/uploader/images/pipx.png differ diff --git a/ground/gcs/src/plugins/uploader/op_dfu.cpp b/ground/gcs/src/plugins/uploader/op_dfu.cpp index 58401b8a0..ee0cb8a32 100644 --- a/ground/gcs/src/plugins/uploader/op_dfu.cpp +++ b/ground/gcs/src/plugins/uploader/op_dfu.cpp @@ -574,7 +574,20 @@ OP_DFU::Status DFUObject::StatusRequest() buf[8] = 0; buf[9] = 0; - int result = sendData(buf, BUF_LEN); + int result = sendData(buf, BUF_LEN); + int retry_cnt = 0; + const int MaxSendRetry = 10, SendRetryIntervalMS = 1000; + while (result < 0 && retry_cnt < MaxSendRetry) { + retry_cnt++; + qWarning() << "StatusRequest failed, sleeping" << SendRetryIntervalMS << "ms"; + delay::msleep(SendRetryIntervalMS); + qWarning() << "StatusRequest retry attempt" << retry_cnt; + result = sendData(buf, BUF_LEN); + } + if (retry_cnt >= MaxSendRetry) { + qWarning() << "StatusRequest failed too many times, aborting"; + return OP_DFU::abort; + } if (debug) { qDebug() << "StatusRequest: " << result << " bytes sent"; } @@ -1071,11 +1084,12 @@ int DFUObject::receiveData(void *data, int size) } } -#define BOARD_ID_MB 1 -#define BOARD_ID_INS 2 -#define BOARD_ID_PIP 3 -#define BOARD_ID_CC 4 -#define BOARD_ID_REVO 9 +#define BOARD_ID_MB 1 +#define BOARD_ID_INS 2 +#define BOARD_ID_PIP 3 +#define BOARD_ID_CC 4 +#define BOARD_ID_REVO 9 +#define BOARD_ID_SPARKY2 0x92 /** Gets the type of board connected @@ -1104,6 +1118,9 @@ OP_DFU::eBoardType DFUObject::GetBoardType(int boardNum) case BOARD_ID_REVO: // Revo board brdType = eBoardRevo; break; + case BOARD_ID_SPARKY2: // Sparky2 board + brdType = eBoardSparky2; + break; } return brdType; } diff --git a/ground/gcs/src/plugins/uploader/op_dfu.h b/ground/gcs/src/plugins/uploader/op_dfu.h index 346582872..989c5c9f9 100644 --- a/ground/gcs/src/plugins/uploader/op_dfu.h +++ b/ground/gcs/src/plugins/uploader/op_dfu.h @@ -60,6 +60,7 @@ enum Status { }; enum Actions { + actionNone, actionProgram, actionProgramAndVerify, actionDownload, @@ -94,12 +95,13 @@ enum eBoardType { eBoardPip = 3, eBoardCC = 4, eBoardRevo = 9, + eBoardSparky2 = 0x92, }; struct device { - int ID; + quint16 ID; quint32 FW_CRC; - int BL_Version; + quint8 BL_Version; int SizeOfDesc; quint32 SizeOfCode; bool Readable; diff --git a/ground/gcs/src/plugins/uploader/oplinkwatchdog.cpp b/ground/gcs/src/plugins/uploader/oplinkwatchdog.cpp deleted file mode 100644 index e66d376ca..000000000 --- a/ground/gcs/src/plugins/uploader/oplinkwatchdog.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/** - ****************************************************************************** - * - * @file oplinkwatchdog.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. - * @addtogroup [Group] - * @{ - * @addtogroup OPLinkWatchdog - * @{ - * @brief [Brief] - *****************************************************************************/ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "oplinkwatchdog.h" -#include "extensionsystem/pluginmanager.h" -#include "uavobjects/uavobjectmanager.h" -#include "oplinkstatus.h" -#include - -OPLinkWatchdog::OPLinkWatchdog() : QObject(), - m_isConnected(false) -{ - ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); - - Q_ASSERT(pm); - UAVObjectManager *objManager = pm->getObject(); - Q_ASSERT(objManager); - m_opLinkStatus = OPLinkStatus::GetInstance(objManager); - Q_ASSERT(m_opLinkStatus); - connect(m_opLinkStatus, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(onOPLinkStatusUpdate())); - m_watchdog = new QTimer(this); - connect(m_watchdog, SIGNAL(timeout()), this, SLOT(onTimeout())); - onOPLinkStatusUpdate(); -} - -OPLinkWatchdog::~OPLinkWatchdog() -{} - -void OPLinkWatchdog::onOPLinkStatusUpdate() -{ - m_watchdog->stop(); - quint8 type = m_opLinkStatus->getBoardType(); - if (!m_isConnected) { - switch (type) { - case 3: - m_opLinkType = OPLINK_MINI; - m_isConnected = true; - emit connected(); - emit opLinkMiniConnected(); - break; - case 9: - m_opLinkType = OPLINK_REVOLUTION; - m_isConnected = true; - emit connected(); - emit opLinkRevolutionConnected(); - break; - default: - m_isConnected = false; - m_opLinkType = OPLINK_UNKNOWN; - return; - } - - qDebug() << "OPLinkWatchdog - OPLink connected"; - } - m_watchdog->start(m_opLinkStatus->getMetadata().flightTelemetryUpdatePeriod * 3); -} - -void OPLinkWatchdog::onTimeout() -{ - if (m_isConnected) { - m_isConnected = false; - m_opLinkType = OPLINK_UNKNOWN; - qDebug() << "OPLinkWatchdog - OPLink disconnected"; - emit disconnected(); - } -} diff --git a/ground/gcs/src/plugins/uploader/runningdevicewidget.cpp b/ground/gcs/src/plugins/uploader/runningdevicewidget.cpp index aa5caafcb..50d5490e7 100644 --- a/ground/gcs/src/plugins/uploader/runningdevicewidget.cpp +++ b/ground/gcs/src/plugins/uploader/runningdevicewidget.cpp @@ -2,7 +2,8 @@ ****************************************************************************** * * @file runningdevicewidget.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup Uploader Serial and USB Uploader Plugin @@ -65,7 +66,7 @@ void RunningDeviceWidget::populate() myDevice->lblDeviceID->setText(QString("Device ID: ") + QString::number(id, 16)); myDevice->lblBoardName->setText(deviceDescriptorStruct::idToBoardName(id)); myDevice->lblHWRev->setText(QString(tr("HW Revision: ")) + QString::number(id & 0x00FF, 16)); - qDebug() << "CRC" << utilMngr->getFirmwareCRC(); + // qDebug() << "CRC" << utilMngr->getFirmwareCRC(); myDevice->lblCRC->setText(QString(tr("Firmware CRC: ")) + QVariant(utilMngr->getFirmwareCRC()).toString()); // DeviceID tells us what sort of HW we have detected: // display a nice icon: @@ -86,11 +87,20 @@ void RunningDeviceWidget::populate() devicePic.load(":/uploader/images/gcs-board-cc3d.png"); break; case 0x0903: + // Revo + // fall through to DF4B + case 0x0904: + // DiscoveryF4Bare devicePic.load(":/uploader/images/gcs-board-revo.png"); break; case 0x0905: + // Nano devicePic.load(":/uploader/images/gcs-board-nano.png"); break; + case 0x9201: + // Sparky2 + devicePic.load(":/uploader/images/gcs-board-sparky2.png"); + break; default: // Clear devicePic.load(""); diff --git a/ground/gcs/src/plugins/uploader/runningdevicewidget.ui b/ground/gcs/src/plugins/uploader/runningdevicewidget.ui index 945b55dc5..e0d251916 100644 --- a/ground/gcs/src/plugins/uploader/runningdevicewidget.ui +++ b/ground/gcs/src/plugins/uploader/runningdevicewidget.ui @@ -77,7 +77,7 @@ - TextLabel + TextLabel @@ -90,7 +90,7 @@
- TextLabel + TextLabel @@ -103,7 +103,7 @@ - TextLabel + TextLabel @@ -116,7 +116,7 @@ - BlRevision + BlRevision @@ -141,7 +141,7 @@ - TextLabel + TextLabel Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse @@ -204,28 +204,28 @@ - TextLabel + TextLabel - TextLabel + TextLabel - TextLabel + TextLabel - TextLabel + TextLabel @@ -234,7 +234,7 @@ - TextLabel + TextLabel diff --git a/ground/gcs/src/plugins/uploader/uploader.pro b/ground/gcs/src/plugins/uploader/uploader.pro index fb70976ff..de5e3aff2 100644 --- a/ground/gcs/src/plugins/uploader/uploader.pro +++ b/ground/gcs/src/plugins/uploader/uploader.pro @@ -1,5 +1,6 @@ TEMPLATE = lib TARGET = Uploader + DEFINES += UPLOADER_LIBRARY QT += svg serialport @@ -15,7 +16,8 @@ macx { QMAKE_CXXFLAGS += -Wno-enum-compare } -HEADERS += uploadergadget.h \ +HEADERS += \ + uploadergadget.h \ uploadergadgetconfiguration.h \ uploadergadgetfactory.h \ uploadergadgetoptionspage.h \ @@ -31,10 +33,10 @@ HEADERS += uploadergadget.h \ runningdevicewidget.h \ uploader_global.h \ enums.h \ - rebootdialog.h \ - oplinkwatchdog.h + rebootdialog.h -SOURCES += uploadergadget.cpp \ +SOURCES += \ + uploadergadget.cpp \ uploadergadgetconfiguration.cpp \ uploadergadgetfactory.cpp \ uploadergadgetoptionspage.cpp \ @@ -47,8 +49,7 @@ SOURCES += uploadergadget.cpp \ SSP/qssp.cpp \ SSP/qsspt.cpp \ runningdevicewidget.cpp \ - rebootdialog.cpp \ - oplinkwatchdog.cpp + rebootdialog.cpp OTHER_FILES += Uploader.pluginspec diff --git a/ground/gcs/src/plugins/uploader/uploader.qrc b/ground/gcs/src/plugins/uploader/uploader.qrc index 642cca091..5c9e8eb26 100644 --- a/ground/gcs/src/plugins/uploader/uploader.qrc +++ b/ground/gcs/src/plugins/uploader/uploader.qrc @@ -19,5 +19,6 @@ images/gcs-board-oplink.png images/gcs-board-revo.png images/gcs-board-nano.png + images/gcs-board-sparky2.png diff --git a/ground/gcs/src/plugins/uploader/uploadergadgetoptionspage.cpp b/ground/gcs/src/plugins/uploader/uploadergadgetoptionspage.cpp index 46d27667f..fb7c845ca 100644 --- a/ground/gcs/src/plugins/uploader/uploadergadgetoptionspage.cpp +++ b/ground/gcs/src/plugins/uploader/uploadergadgetoptionspage.cpp @@ -2,7 +2,8 @@ ****************************************************************************** * * @file uploadergadgetoptionspage.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015 + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup YModemUploader YModem Serial Uploader Plugin @@ -26,7 +27,9 @@ */ #include "uploadergadgetoptionspage.h" + #include "uploadergadgetconfiguration.h" + #include #include #include diff --git a/ground/gcs/src/plugins/uploader/uploadergadgetoptionspage.h b/ground/gcs/src/plugins/uploader/uploadergadgetoptionspage.h index afbd235bf..650344c49 100644 --- a/ground/gcs/src/plugins/uploader/uploadergadgetoptionspage.h +++ b/ground/gcs/src/plugins/uploader/uploadergadgetoptionspage.h @@ -2,7 +2,8 @@ ****************************************************************************** * * @file uploadergadgetoptionspage.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015 + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup YModemUploader YModem Serial Uploader Plugin @@ -27,19 +28,19 @@ #ifndef UPLOADERGADGETOPTIONSPAGE_H #define UPLOADERGADGETOPTIONSPAGE_H -#include -#include + +#include "uploader_global.h" #include "coreplugin/dialogs/ioptionspage.h" -#include "QString" + +#include +#include #include #include -#include "uploader_global.h" +#include +#include -namespace Core { -class IUAVGadgetConfiguration; -} class UploaderGadgetConfiguration; -class QTextEdit; + class QComboBox; class QSpinBox; diff --git a/ground/gcs/src/plugins/uploader/uploadergadgetwidget.cpp b/ground/gcs/src/plugins/uploader/uploadergadgetwidget.cpp index 2db5c9a88..4adda452f 100644 --- a/ground/gcs/src/plugins/uploader/uploadergadgetwidget.cpp +++ b/ground/gcs/src/plugins/uploader/uploadergadgetwidget.cpp @@ -27,8 +27,9 @@ */ #include "uploadergadgetwidget.h" +#include "ui_uploader.h" + #include "flightstatus.h" -#include "oplinkstatus.h" #include "delay.h" #include "devicewidget.h" #include "runningdevicewidget.h" @@ -38,12 +39,13 @@ #include #include #include +#include +#include "rebootdialog.h" #include #include #include #include -#include "rebootdialog.h" #define DFU_DEBUG true @@ -675,16 +677,21 @@ bool UploaderGadgetWidget::autoUpdateCapable() bool UploaderGadgetWidget::autoUpdate(bool erase) { - if (m_oplinkwatchdog.isConnected() && - m_oplinkwatchdog.opLinkType() == OPLinkWatchdog::OPLINK_MINI) { + ExtensionSystem::PluginManager *pluginManager = ExtensionSystem::PluginManager::instance(); + + Q_ASSERT(pluginManager); + + OPLinkManager *opLinkManager = pluginManager->getObject(); + Q_ASSERT(opLinkManager); + + if (opLinkManager->isConnected() && + opLinkManager->opLinkType() == OPLinkManager::OPLINK_MINI) { emit progressUpdate(FAILURE, QVariant(tr("To upgrade the OPLinkMini board please disconnect it from the USB port, " - "press the Upgrade again button and follow instructions on screen."))); + "press the Upgrade button again and follow instructions on screen."))); emit autoUpdateFailed(); return false; } - ExtensionSystem::PluginManager *pluginManager = ExtensionSystem::PluginManager::instance(); - Q_ASSERT(pluginManager); TelemetryManager *telemetryManager = pluginManager->getObject(); Q_ASSERT(telemetryManager); @@ -751,28 +758,31 @@ bool UploaderGadgetWidget::autoUpdate(bool erase) QString filename; emit progressUpdate(LOADING_FW, QVariant()); switch (m_dfu->devices[0].ID) { - case 0x301: + case 0x0301: filename = "fw_oplinkmini"; break; - case 0x401: - case 0x402: + case 0x0401: + case 0x0402: filename = "fw_coptercontrol"; break; - case 0x501: + case 0x0501: filename = "fw_osd"; break; - case 0x902: + case 0x0902: filename = "fw_revoproto"; break; - case 0x903: + case 0x0903: filename = "fw_revolution"; break; - case 0x904: + case 0x0904: filename = "fw_discoveryf4bare"; break; - case 0x905: + case 0x0905: filename = "fw_revonano"; break; + case 0x9201: + filename = "fw_sparky2"; + break; default: emit progressUpdate(FAILURE, QVariant(tr("Unknown board id '0x%1'").arg(QString::number(m_dfu->devices[0].ID, 16)))); emit autoUpdateFailed(); @@ -821,11 +831,11 @@ bool UploaderGadgetWidget::autoUpdate(bool erase) // Wait for board to connect to GCS again after boot and erase // For older board like CC3D this can take some time // Theres a special case with OPLink - if (!telemetryManager->isConnected() && !m_oplinkwatchdog.isConnected()) { + if (!telemetryManager->isConnected() && !opLinkManager->isConnected()) { progressUpdate(erase ? BOOTING_AND_ERASING : BOOTING, QVariant()); ResultEventLoop eventLoop; connect(telemetryManager, SIGNAL(connected()), &eventLoop, SLOT(success())); - connect(&m_oplinkwatchdog, SIGNAL(opLinkMiniConnected()), &eventLoop, SLOT(success())); + connect(opLinkManager, SIGNAL(connected()), &eventLoop, SLOT(success())); if (eventLoop.run(REBOOT_TIMEOUT + (erase ? ERASE_TIMEOUT : 0)) != 0) { emit progressUpdate(FAILURE, QVariant(tr("Timed out while booting."))); @@ -833,7 +843,7 @@ bool UploaderGadgetWidget::autoUpdate(bool erase) return false; } - disconnect(&m_oplinkwatchdog, SIGNAL(opLinkMiniConnected()), &eventLoop, SLOT(success())); + disconnect(opLinkManager, SIGNAL(connected()), &eventLoop, SLOT(success())); disconnect(telemetryManager, SIGNAL(connected()), &eventLoop, SLOT(success())); } @@ -1020,7 +1030,8 @@ void UploaderGadgetWidget::startAutoUpdateErase() UAVObjectUtilManager *utilMngr = pm->getObject(); int id = utilMngr->getBoardModel(); - if (id == 0x905) { + // reset if Nano + if (id == 0x0905) { systemReset(); } } diff --git a/ground/gcs/src/plugins/uploader/uploadergadgetwidget.h b/ground/gcs/src/plugins/uploader/uploadergadgetwidget.h index 5490a9046..219ceccae 100644 --- a/ground/gcs/src/plugins/uploader/uploadergadgetwidget.h +++ b/ground/gcs/src/plugins/uploader/uploadergadgetwidget.h @@ -28,22 +28,21 @@ #ifndef UPLOADERGADGETWIDGET_H #define UPLOADERGADGETWIDGET_H -#include "ui_uploader.h" #include "uploader_global.h" #include "enums.h" #include "op_dfu.h" +#include #include -#include "oplinkwatchdog.h" using namespace OP_DFU; using namespace uploader; +class Ui_UploaderWidget; + class FlightStatus; class UAVObject; -class OPLinkStatus; -class OPLinkWatchdog; class TimedDialog : public QProgressDialog { Q_OBJECT @@ -146,7 +145,6 @@ private: DFUObject *m_dfu; IAPStep m_currentIAPStep; bool m_resetOnly; - OPLinkWatchdog m_oplinkwatchdog; bool m_autoUpdateClosing; void clearLog(); diff --git a/ground/gcs/src/plugins/usagetracker/usagetracker.pro b/ground/gcs/src/plugins/usagetracker/usagetracker.pro index eb3f9aea9..d5a0728ee 100644 --- a/ground/gcs/src/plugins/usagetracker/usagetracker.pro +++ b/ground/gcs/src/plugins/usagetracker/usagetracker.pro @@ -1,7 +1,7 @@ - TEMPLATE = lib TARGET = UsageTracker -QT += network + +QT += widgets network include(usagetracker.pri) include(../../plugin.pri) @@ -11,7 +11,10 @@ include(../../plugins/uavobjects/uavobjects.pri) include(../../plugins/uavobjectutil/uavobjectutil.pri) include(../../plugins/uavtalk/uavtalk.pri) -HEADERS += usagetrackerplugin.h -SOURCES += usagetrackerplugin.cpp +HEADERS += \ + usagetrackerplugin.h + +SOURCES += \ + usagetrackerplugin.cpp OTHER_FILES += usagetracker.pluginspec diff --git a/ground/gcs/src/plugins/usagetracker/usagetrackerplugin.cpp b/ground/gcs/src/plugins/usagetracker/usagetrackerplugin.cpp index b157566d6..232d0d733 100644 --- a/ground/gcs/src/plugins/usagetracker/usagetrackerplugin.cpp +++ b/ground/gcs/src/plugins/usagetracker/usagetrackerplugin.cpp @@ -78,19 +78,20 @@ void UsageTrackerPlugin::onAutopilotConnect() if (settings->collectUsageData()) { if (settings->showUsageDataDisclaimer()) { QMessageBox message; + // QMessageBox hack to define window size. + message.setStyleSheet("QLabel{min-width: 780px; max-height: 520px;}"); message.setWindowTitle(tr("Usage feedback")); - message.setIcon(QMessageBox::Information); message.addButton(tr("Yes, count me in"), QMessageBox::AcceptRole); message.addButton(tr("No, I will not help"), QMessageBox::RejectRole); - message.setText(tr("%1 has a function to collect limited anonymous information about " - "the usage of the application itself and the hardware connected to it.

" - "The intention is to not include anything that can be considered sensitive " + message.setText(tr("

%1 has a function to collect limited anonymous information about " + "the usage of the application itself and the hardware connected to it.

" + "

The intention is to not include anything that can be considered sensitive " "or a threat to the users integrity. The collected information will be sent " "using a secure protocol to an %2 web service and stored in a database " - "for later analysis and statistical purposes.
" + "for later analysis and statistical purposes. " "No information will be sold or given to any third party. The sole purpose is " "to collect statistics about the usage of our software and hardware to enable us " - "to make things better for you.

" + "to make things better for you.

" "The following things are collected:
    " "
  • Bootloader version
  • " "
  • Firmware version, tag and git hash
  • " @@ -99,11 +100,11 @@ void UsageTrackerPlugin::onAutopilotConnect() "
  • GCS version
  • " "
  • Operating system version and architecture
  • " "
  • Current local time
" - "The information is collected only at the time when a board is connecting to GCS.

" + "

The information is collected only at the time when a board is connecting to GCS. " "It is possible to enable or disable this functionality in the general " - "settings part of the options for the GCS application at any time.

" - "We need your help, with your feedback we know where to improve things and what " - "platforms are in use. This is a community project that depends on people being involved.
" + "settings part of the options for the GCS application at any time.

" + "

We need your help, with your feedback we know where to improve things and what " + "platforms are in use. This is a community project that depends on people being involved.

" "Thank You for helping us making things better and for supporting %2!").arg(GCS_BIG_NAME).arg(ORG_BIG_NAME)); QCheckBox *disclaimerCb = new QCheckBox(tr("&Don't show this message again.")); disclaimerCb->setChecked(true); @@ -194,6 +195,13 @@ void UsageTrackerPlugin::collectUsageParameters(QMap ¶mete parameters["conf_mport"] = getUAVFieldValue(objManager, "HwSettings", "RM_MainPort"); parameters["conf_fport"] = getUAVFieldValue(objManager, "HwSettings", "RM_FlexiPort"); parameters["conf_fusion"] = getUAVFieldValue(objManager, "RevoSettings", "FusionAlgorithm"); + } else if ((boardModel & 0xff00) == 0x9200) { + // Sparky2 + parameters["conf_rport"] = getUAVFieldValue(objManager, "HwSettings", "SPK2_RcvrPort"); + parameters["conf_mport"] = getUAVFieldValue(objManager, "HwSettings", "SPK2_MainPort"); + parameters["conf_fport"] = getUAVFieldValue(objManager, "HwSettings", "SPK2_FlexiPort"); + parameters["conf_iport"] = getUAVFieldValue(objManager, "HwSettings", "SPK2_I2CPort"); + parameters["conf_fusion"] = getUAVFieldValue(objManager, "RevoSettings", "FusionAlgorithm"); } parameters["conf_uport"] = getUAVFieldValue(objManager, "HwSettings", "USB_HIDPort"); diff --git a/ground/gcs/src/plugins/welcome/qml/images/bttn-export-template-off.png b/ground/gcs/src/plugins/welcome/qml/images/bttn-export-template-off.png index 72b6ba971..b0a784f40 100644 Binary files a/ground/gcs/src/plugins/welcome/qml/images/bttn-export-template-off.png and b/ground/gcs/src/plugins/welcome/qml/images/bttn-export-template-off.png differ diff --git a/ground/gcs/src/plugins/welcome/qml/images/bttn-export-template-on.png b/ground/gcs/src/plugins/welcome/qml/images/bttn-export-template-on.png index f2f3f0051..87131a993 100644 Binary files a/ground/gcs/src/plugins/welcome/qml/images/bttn-export-template-on.png and b/ground/gcs/src/plugins/welcome/qml/images/bttn-export-template-on.png differ diff --git a/ground/gcs/src/plugins/welcome/qml/images/bttn-txwizard-off.png b/ground/gcs/src/plugins/welcome/qml/images/bttn-txwizard-off.png index 61570522e..d949e477a 100644 Binary files a/ground/gcs/src/plugins/welcome/qml/images/bttn-txwizard-off.png and b/ground/gcs/src/plugins/welcome/qml/images/bttn-txwizard-off.png differ diff --git a/ground/gcs/src/plugins/welcome/qml/images/bttn-txwizard-on.png b/ground/gcs/src/plugins/welcome/qml/images/bttn-txwizard-on.png index 2e8806e0e..f156c6684 100644 Binary files a/ground/gcs/src/plugins/welcome/qml/images/bttn-txwizard-on.png and b/ground/gcs/src/plugins/welcome/qml/images/bttn-txwizard-on.png differ diff --git a/ground/gcs/src/plugins/welcome/qml/images/bttn-vehwizard-off.png b/ground/gcs/src/plugins/welcome/qml/images/bttn-vehwizard-off.png index a97119848..469b71b89 100644 Binary files a/ground/gcs/src/plugins/welcome/qml/images/bttn-vehwizard-off.png and b/ground/gcs/src/plugins/welcome/qml/images/bttn-vehwizard-off.png differ diff --git a/ground/gcs/src/plugins/welcome/qml/images/bttn-vehwizard-on.png b/ground/gcs/src/plugins/welcome/qml/images/bttn-vehwizard-on.png index 8967c2630..0157a1fd2 100644 Binary files a/ground/gcs/src/plugins/welcome/qml/images/bttn-vehwizard-on.png and b/ground/gcs/src/plugins/welcome/qml/images/bttn-vehwizard-on.png differ diff --git a/ground/gcs/src/plugins/welcome/qml/images/button-label-bottom.png b/ground/gcs/src/plugins/welcome/qml/images/button-label-bottom.png index a6d885658..3d9cc70e0 100644 Binary files a/ground/gcs/src/plugins/welcome/qml/images/button-label-bottom.png and b/ground/gcs/src/plugins/welcome/qml/images/button-label-bottom.png differ diff --git a/ground/gcs/src/plugins/welcome/qml/images/button-label.png b/ground/gcs/src/plugins/welcome/qml/images/button-label.png index b51247fbd..371812bca 100644 Binary files a/ground/gcs/src/plugins/welcome/qml/images/button-label.png and b/ground/gcs/src/plugins/welcome/qml/images/button-label.png differ diff --git a/ground/gcs/src/plugins/welcome/qml/images/config-off.png b/ground/gcs/src/plugins/welcome/qml/images/config-off.png index c353cbf2a..f1aedfd0d 100644 Binary files a/ground/gcs/src/plugins/welcome/qml/images/config-off.png and b/ground/gcs/src/plugins/welcome/qml/images/config-off.png differ diff --git a/ground/gcs/src/plugins/welcome/qml/images/config-on.png b/ground/gcs/src/plugins/welcome/qml/images/config-on.png index 5b0c67e56..6b404cb37 100644 Binary files a/ground/gcs/src/plugins/welcome/qml/images/config-on.png and b/ground/gcs/src/plugins/welcome/qml/images/config-on.png differ diff --git a/ground/gcs/src/plugins/welcome/qml/images/firmware-off.png b/ground/gcs/src/plugins/welcome/qml/images/firmware-off.png index 7523feb1c..eb233081f 100644 Binary files a/ground/gcs/src/plugins/welcome/qml/images/firmware-off.png and b/ground/gcs/src/plugins/welcome/qml/images/firmware-off.png differ diff --git a/ground/gcs/src/plugins/welcome/qml/images/firmware-on.png b/ground/gcs/src/plugins/welcome/qml/images/firmware-on.png index f8634a34e..d998eae91 100644 Binary files a/ground/gcs/src/plugins/welcome/qml/images/firmware-on.png and b/ground/gcs/src/plugins/welcome/qml/images/firmware-on.png differ diff --git a/ground/gcs/src/plugins/welcome/qml/images/flightdata-off.png b/ground/gcs/src/plugins/welcome/qml/images/flightdata-off.png index 04dbdba6d..0e674bd7f 100644 Binary files a/ground/gcs/src/plugins/welcome/qml/images/flightdata-off.png and b/ground/gcs/src/plugins/welcome/qml/images/flightdata-off.png differ diff --git a/ground/gcs/src/plugins/welcome/qml/images/flightdata-on.png b/ground/gcs/src/plugins/welcome/qml/images/flightdata-on.png index 3c01add87..ab13a83d9 100644 Binary files a/ground/gcs/src/plugins/welcome/qml/images/flightdata-on.png and b/ground/gcs/src/plugins/welcome/qml/images/flightdata-on.png differ diff --git a/ground/gcs/src/plugins/welcome/qml/images/hitl-off.png b/ground/gcs/src/plugins/welcome/qml/images/hitl-off.png index d6c6d9dd3..678e77b4b 100644 Binary files a/ground/gcs/src/plugins/welcome/qml/images/hitl-off.png and b/ground/gcs/src/plugins/welcome/qml/images/hitl-off.png differ diff --git a/ground/gcs/src/plugins/welcome/qml/images/hitl-on.png b/ground/gcs/src/plugins/welcome/qml/images/hitl-on.png index ce7fa3e1d..e2957d2a0 100644 Binary files a/ground/gcs/src/plugins/welcome/qml/images/hitl-on.png and b/ground/gcs/src/plugins/welcome/qml/images/hitl-on.png differ diff --git a/ground/gcs/src/plugins/welcome/qml/images/planner-off.png b/ground/gcs/src/plugins/welcome/qml/images/planner-off.png index d1b52c4e8..37efb1417 100644 Binary files a/ground/gcs/src/plugins/welcome/qml/images/planner-off.png and b/ground/gcs/src/plugins/welcome/qml/images/planner-off.png differ diff --git a/ground/gcs/src/plugins/welcome/qml/images/planner-on.png b/ground/gcs/src/plugins/welcome/qml/images/planner-on.png index ee1686162..3398edea7 100644 Binary files a/ground/gcs/src/plugins/welcome/qml/images/planner-on.png and b/ground/gcs/src/plugins/welcome/qml/images/planner-on.png differ diff --git a/ground/gcs/src/plugins/welcome/qml/images/refresh.png b/ground/gcs/src/plugins/welcome/qml/images/refresh.png index cb24256ed..7e6daaaa9 100644 Binary files a/ground/gcs/src/plugins/welcome/qml/images/refresh.png and b/ground/gcs/src/plugins/welcome/qml/images/refresh.png differ diff --git a/ground/gcs/src/plugins/welcome/qml/images/scopes-off.png b/ground/gcs/src/plugins/welcome/qml/images/scopes-off.png index 923ec4d3f..f1fd7417f 100644 Binary files a/ground/gcs/src/plugins/welcome/qml/images/scopes-off.png and b/ground/gcs/src/plugins/welcome/qml/images/scopes-off.png differ diff --git a/ground/gcs/src/plugins/welcome/qml/images/scopes-on.png b/ground/gcs/src/plugins/welcome/qml/images/scopes-on.png index 8de8ebd6e..fcaf12287 100644 Binary files a/ground/gcs/src/plugins/welcome/qml/images/scopes-on.png and b/ground/gcs/src/plugins/welcome/qml/images/scopes-on.png differ diff --git a/ground/gcs/src/plugins/welcome/qml/images/system-off.png b/ground/gcs/src/plugins/welcome/qml/images/system-off.png index 443c99bf1..29f8413fb 100644 Binary files a/ground/gcs/src/plugins/welcome/qml/images/system-off.png and b/ground/gcs/src/plugins/welcome/qml/images/system-off.png differ diff --git a/ground/gcs/src/plugins/welcome/qml/images/system-on.png b/ground/gcs/src/plugins/welcome/qml/images/system-on.png index 60b4afc14..c9722f100 100644 Binary files a/ground/gcs/src/plugins/welcome/qml/images/system-on.png and b/ground/gcs/src/plugins/welcome/qml/images/system-on.png differ diff --git a/ground/gcs/src/plugins/welcome/qml/images/welcome-lp-bg.png b/ground/gcs/src/plugins/welcome/qml/images/welcome-lp-bg.png index 83110bde7..35e24730e 100644 Binary files a/ground/gcs/src/plugins/welcome/qml/images/welcome-lp-bg.png and b/ground/gcs/src/plugins/welcome/qml/images/welcome-lp-bg.png differ diff --git a/ground/gcs/src/plugins/welcome/qml/images/welcome-lp-logo.png b/ground/gcs/src/plugins/welcome/qml/images/welcome-lp-logo.png index 768c8c5a7..3f1461856 100644 Binary files a/ground/gcs/src/plugins/welcome/qml/images/welcome-lp-logo.png and b/ground/gcs/src/plugins/welcome/qml/images/welcome-lp-logo.png differ diff --git a/ground/gcs/src/plugins/welcome/qml/images/welcome-news-bg.png b/ground/gcs/src/plugins/welcome/qml/images/welcome-news-bg.png index 4662dad73..7929bd342 100644 Binary files a/ground/gcs/src/plugins/welcome/qml/images/welcome-news-bg.png and b/ground/gcs/src/plugins/welcome/qml/images/welcome-news-bg.png differ diff --git a/ground/gcs/src/plugins/welcome/qml/images/wizard-off.png b/ground/gcs/src/plugins/welcome/qml/images/wizard-off.png index 7c199a767..b1569ebe6 100644 Binary files a/ground/gcs/src/plugins/welcome/qml/images/wizard-off.png and b/ground/gcs/src/plugins/welcome/qml/images/wizard-off.png differ diff --git a/ground/gcs/src/plugins/welcome/qml/images/wizard-on.png b/ground/gcs/src/plugins/welcome/qml/images/wizard-on.png index d8798469a..392f259f6 100644 Binary files a/ground/gcs/src/plugins/welcome/qml/images/wizard-on.png and b/ground/gcs/src/plugins/welcome/qml/images/wizard-on.png differ diff --git a/ground/gcs/src/plugins/welcome/welcome.pro b/ground/gcs/src/plugins/welcome/welcome.pro index 558c1114c..70d366364 100644 --- a/ground/gcs/src/plugins/welcome/welcome.pro +++ b/ground/gcs/src/plugins/welcome/welcome.pro @@ -1,16 +1,22 @@ TEMPLATE = lib TARGET = Welcome -QT += network qml quick + +QT += network qml quick quickwidgets include(../../plugin.pri) include(welcome_dependencies.pri) -HEADERS += welcomeplugin.h \ +HEADERS += \ + welcomeplugin.h \ welcomemode.h \ welcome_global.h -SOURCES += welcomeplugin.cpp \ + +SOURCES += \ + welcomeplugin.cpp \ welcomemode.cpp \ RESOURCES += welcome.qrc + DEFINES += WELCOME_LIBRARY + OTHER_FILES += Welcome.pluginspec diff --git a/ground/gcs/src/plugins/welcome/welcomemode.cpp b/ground/gcs/src/plugins/welcome/welcomemode.cpp index 438dce8ab..551074570 100644 --- a/ground/gcs/src/plugins/welcome/welcomemode.cpp +++ b/ground/gcs/src/plugins/welcome/welcomemode.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include @@ -49,7 +50,7 @@ #include #include -#include +#include #include #include @@ -59,27 +60,11 @@ using namespace ExtensionSystem; using namespace Utils; namespace Welcome { -struct WelcomeModePrivate { - WelcomeModePrivate(); - - QQuickView *quickView; -}; - -WelcomeModePrivate::WelcomeModePrivate() -{} - -// --- WelcomeMode WelcomeMode::WelcomeMode() : - m_d(new WelcomeModePrivate), + m_quickWidgetProxy(NULL), m_priority(Core::Constants::P_MODE_WELCOME), m_newVersionText("") { - m_d->quickView = new QQuickView; - m_d->quickView->setResizeMode(QQuickView::SizeRootObjectToView); - m_d->quickView->engine()->rootContext()->setContextProperty("welcomePlugin", this); - m_d->quickView->setSource(QUrl("qrc:/welcome/qml/main.qml")); - m_container = NULL; - QNetworkAccessManager *networkAccessManager = new QNetworkAccessManager; // Only attempt to request our version info if the network is accessible @@ -89,7 +74,7 @@ WelcomeMode::WelcomeMode() : // This will delete the network access manager instance when we're done connect(networkAccessManager, SIGNAL(finished(QNetworkReply *)), networkAccessManager, SLOT(deleteLater())); - networkAccessManager->get(QNetworkRequest(QUrl("https://github.com/librepilot/LibrePilot/raw/master/.STABLEVER"))); + networkAccessManager->get(QNetworkRequest(QUrl("http://www.librepilot.org/stable-version"))); } else { // No network, can delete this now as we don't need it. delete networkAccessManager; @@ -97,10 +82,7 @@ WelcomeMode::WelcomeMode() : } WelcomeMode::~WelcomeMode() -{ - delete m_d->quickView; - delete m_d; -} +{} QString WelcomeMode::name() const { @@ -119,12 +101,13 @@ int WelcomeMode::priority() const QWidget *WelcomeMode::widget() { - if (!m_container) { - m_container = QWidget::createWindowContainer(m_d->quickView); - m_container->setMinimumSize(64, 64); - m_container->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + if (!m_quickWidgetProxy) { + m_quickWidgetProxy = new QuickWidgetProxy(); + // qWidget->setResizeMode(QQuickWidget::SizeRootObjectToView); + m_quickWidgetProxy->engine()->rootContext()->setContextProperty("welcomePlugin", this); + m_quickWidgetProxy->setSource(QUrl("qrc:/welcome/qml/main.qml")); } - return m_container; + return m_quickWidgetProxy->widget(); } const char *WelcomeMode::uniqueModeName() const diff --git a/ground/gcs/src/plugins/welcome/welcomemode.h b/ground/gcs/src/plugins/welcome/welcomemode.h index 62272d70c..5bef4a07f 100644 --- a/ground/gcs/src/plugins/welcome/welcomemode.h +++ b/ground/gcs/src/plugins/welcome/welcomemode.h @@ -34,16 +34,14 @@ #include - QT_BEGIN_NAMESPACE +class QuickWidgetProxy; class QWidget; class QUrl; class QNetworkReply; QT_END_NAMESPACE namespace Welcome { -struct WelcomeModePrivate; - class WELCOME_EXPORT WelcomeMode : public Core::IMode { Q_OBJECT Q_PROPERTY(QString versionString READ versionString CONSTANT) Q_PROPERTY(QString newVersionText READ newVersionText NOTIFY newVersionTextChanged) @@ -86,8 +84,7 @@ public slots: void triggerAction(const QString &actionId); private: - QWidget *m_container; - WelcomeModePrivate *m_d; + QuickWidgetProxy *m_quickWidgetProxy; int m_priority; QString m_newVersionText; diff --git a/ground/gcs/src/plugins/welcome/welcomeplugin.cpp b/ground/gcs/src/plugins/welcome/welcomeplugin.cpp index 0dfbf91bd..aedfbd330 100644 --- a/ground/gcs/src/plugins/welcome/welcomeplugin.cpp +++ b/ground/gcs/src/plugins/welcome/welcomeplugin.cpp @@ -52,14 +52,10 @@ WelcomePlugin::WelcomePlugin() WelcomePlugin::~WelcomePlugin() { - // The below code is commented out to avoid having the application - // crash when it is terminated. TODO: Fix a real solution. - /* - if (m_welcomeMode) { + if (m_welcomeMode) { removeObject(m_welcomeMode); delete m_welcomeMode; - } - */ + } } /*! Initializes the plugin. Returns true on success. diff --git a/ground/gcs/src/share/models/backgrounds/default_background.png b/ground/gcs/src/share/backgrounds/default_background.png similarity index 100% rename from ground/gcs/src/share/models/backgrounds/default_background.png rename to ground/gcs/src/share/backgrounds/default_background.png diff --git a/ground/gcs/src/share/models/backgrounds/standard/01.png b/ground/gcs/src/share/backgrounds/standard/01.png similarity index 100% rename from ground/gcs/src/share/models/backgrounds/standard/01.png rename to ground/gcs/src/share/backgrounds/standard/01.png diff --git a/ground/gcs/src/share/models/backgrounds/standard/02.png b/ground/gcs/src/share/backgrounds/standard/02.png similarity index 100% rename from ground/gcs/src/share/models/backgrounds/standard/02.png rename to ground/gcs/src/share/backgrounds/standard/02.png diff --git a/ground/gcs/src/share/models/backgrounds/standard/03.png b/ground/gcs/src/share/backgrounds/standard/03.png similarity index 100% rename from ground/gcs/src/share/models/backgrounds/standard/03.png rename to ground/gcs/src/share/backgrounds/standard/03.png diff --git a/ground/gcs/src/share/models/backgrounds/standard/04.png b/ground/gcs/src/share/backgrounds/standard/04.png similarity index 100% rename from ground/gcs/src/share/models/backgrounds/standard/04.png rename to ground/gcs/src/share/backgrounds/standard/04.png diff --git a/ground/gcs/src/share/models/backgrounds/standard/05.png b/ground/gcs/src/share/backgrounds/standard/05.png similarity index 100% rename from ground/gcs/src/share/models/backgrounds/standard/05.png rename to ground/gcs/src/share/backgrounds/standard/05.png diff --git a/ground/gcs/src/share/models/backgrounds/standard/06.png b/ground/gcs/src/share/backgrounds/standard/06.png similarity index 100% rename from ground/gcs/src/share/models/backgrounds/standard/06.png rename to ground/gcs/src/share/backgrounds/standard/06.png diff --git a/ground/gcs/src/share/models/backgrounds/standard/07.png b/ground/gcs/src/share/backgrounds/standard/07.png similarity index 100% rename from ground/gcs/src/share/models/backgrounds/standard/07.png rename to ground/gcs/src/share/backgrounds/standard/07.png diff --git a/ground/gcs/src/share/models/backgrounds/standard/08.png b/ground/gcs/src/share/backgrounds/standard/08.png similarity index 100% rename from ground/gcs/src/share/models/backgrounds/standard/08.png rename to ground/gcs/src/share/backgrounds/standard/08.png diff --git a/ground/gcs/src/share/models/backgrounds/standard/09.png b/ground/gcs/src/share/backgrounds/standard/09.png similarity index 100% rename from ground/gcs/src/share/models/backgrounds/standard/09.png rename to ground/gcs/src/share/backgrounds/standard/09.png diff --git a/ground/gcs/src/share/models/backgrounds/standard/10.png b/ground/gcs/src/share/backgrounds/standard/10.png similarity index 100% rename from ground/gcs/src/share/models/backgrounds/standard/10.png rename to ground/gcs/src/share/backgrounds/standard/10.png diff --git a/ground/gcs/src/share/models/backgrounds/standard/11.png b/ground/gcs/src/share/backgrounds/standard/11.png similarity index 100% rename from ground/gcs/src/share/models/backgrounds/standard/11.png rename to ground/gcs/src/share/backgrounds/standard/11.png diff --git a/ground/gcs/src/share/models/backgrounds/standard/12.png b/ground/gcs/src/share/backgrounds/standard/12.png similarity index 100% rename from ground/gcs/src/share/models/backgrounds/standard/12.png rename to ground/gcs/src/share/backgrounds/standard/12.png diff --git a/ground/gcs/src/share/models/backgrounds/standard/13.jpg b/ground/gcs/src/share/backgrounds/standard/13.jpg similarity index 100% rename from ground/gcs/src/share/models/backgrounds/standard/13.jpg rename to ground/gcs/src/share/backgrounds/standard/13.jpg diff --git a/ground/gcs/src/share/models/backgrounds/wide/01w.png b/ground/gcs/src/share/backgrounds/wide/01w.png similarity index 100% rename from ground/gcs/src/share/models/backgrounds/wide/01w.png rename to ground/gcs/src/share/backgrounds/wide/01w.png diff --git a/ground/gcs/src/share/models/backgrounds/wide/02w.png b/ground/gcs/src/share/backgrounds/wide/02w.png similarity index 100% rename from ground/gcs/src/share/models/backgrounds/wide/02w.png rename to ground/gcs/src/share/backgrounds/wide/02w.png diff --git a/ground/gcs/src/share/models/backgrounds/wide/03w.png b/ground/gcs/src/share/backgrounds/wide/03w.png similarity index 100% rename from ground/gcs/src/share/models/backgrounds/wide/03w.png rename to ground/gcs/src/share/backgrounds/wide/03w.png diff --git a/ground/gcs/src/share/models/backgrounds/wide/04w.png b/ground/gcs/src/share/backgrounds/wide/04w.png similarity index 100% rename from ground/gcs/src/share/models/backgrounds/wide/04w.png rename to ground/gcs/src/share/backgrounds/wide/04w.png diff --git a/ground/gcs/src/share/models/backgrounds/wide/05w.png b/ground/gcs/src/share/backgrounds/wide/05w.png similarity index 100% rename from ground/gcs/src/share/models/backgrounds/wide/05w.png rename to ground/gcs/src/share/backgrounds/wide/05w.png diff --git a/ground/gcs/src/share/models/backgrounds/wide/06w.png b/ground/gcs/src/share/backgrounds/wide/06w.png similarity index 100% rename from ground/gcs/src/share/models/backgrounds/wide/06w.png rename to ground/gcs/src/share/backgrounds/wide/06w.png diff --git a/ground/gcs/src/share/models/backgrounds/wide/07w.png b/ground/gcs/src/share/backgrounds/wide/07w.png similarity index 100% rename from ground/gcs/src/share/models/backgrounds/wide/07w.png rename to ground/gcs/src/share/backgrounds/wide/07w.png diff --git a/ground/gcs/src/share/models/backgrounds/wide/08w.png b/ground/gcs/src/share/backgrounds/wide/08w.png similarity index 100% rename from ground/gcs/src/share/models/backgrounds/wide/08w.png rename to ground/gcs/src/share/backgrounds/wide/08w.png diff --git a/ground/gcs/src/share/models/backgrounds/wide/09w.png b/ground/gcs/src/share/backgrounds/wide/09w.png similarity index 100% rename from ground/gcs/src/share/models/backgrounds/wide/09w.png rename to ground/gcs/src/share/backgrounds/wide/09w.png diff --git a/ground/gcs/src/share/models/backgrounds/wide/10w.png b/ground/gcs/src/share/backgrounds/wide/10w.png similarity index 100% rename from ground/gcs/src/share/models/backgrounds/wide/10w.png rename to ground/gcs/src/share/backgrounds/wide/10w.png diff --git a/ground/gcs/src/share/models/backgrounds/wide/11w.png b/ground/gcs/src/share/backgrounds/wide/11w.png similarity index 100% rename from ground/gcs/src/share/models/backgrounds/wide/11w.png rename to ground/gcs/src/share/backgrounds/wide/11w.png diff --git a/ground/gcs/src/share/models/backgrounds/wide/12w.png b/ground/gcs/src/share/backgrounds/wide/12w.png similarity index 100% rename from ground/gcs/src/share/models/backgrounds/wide/12w.png rename to ground/gcs/src/share/backgrounds/wide/12w.png diff --git a/ground/gcs/src/share/models/backgrounds/wide/13w.jpg b/ground/gcs/src/share/backgrounds/wide/13w.jpg similarity index 100% rename from ground/gcs/src/share/models/backgrounds/wide/13w.jpg rename to ground/gcs/src/share/backgrounds/wide/13w.jpg diff --git a/ground/gcs/src/share/configurations/default.xml b/ground/gcs/src/share/configurations/default.xml index 33bac006d..a5136e1bb 100644 --- a/ground/gcs/src/share/configurations/default.xml +++ b/ground/gcs/src/share/configurations/default.xml @@ -1542,272 +1542,6 @@
- - - - false - 0.0.0 - - - %%DATAPATH%%models/multi/aeroquad/aeroquad_+.3ds - %%DATAPATH%%models/backgrounds/default_background.png - false - - - - - false - 0.0.0 - - - %%DATAPATH%%models/boards/CopterControl/CopterControl.3ds - %%DATAPATH%%models/backgrounds/default_background.png - false - - - - - false - 0.0.0 - - - %%DATAPATH%%models/boards/CC3D/CC3D.3ds - %%DATAPATH%%models/backgrounds/default_background.png - false - - - - - false - 0.0.0 - - - %%DATAPATH%%models/boards/Revolution/revolution.3ds - %%DATAPATH%%models/backgrounds/default_background.png - false - - - - - false - 0.0.0 - - - %%DATAPATH%%models/multi/blackout/BlackoutMiniHQuad.3DS - %%DATAPATH%%models/backgrounds/default_background.png - false - - - - - false - 0.0.0 - - - %%DATAPATH%%models/planes/zagi/zagi.3ds - %%DATAPATH%%models/backgrounds/default_background.png - false - - - - - false - 0.0.0 - - - %%DATAPATH%%models/multi/easy_quad/easy_quad_X.3ds - %%DATAPATH%%models/backgrounds/default_background.png - false - - - - - false - 0.0.0 - - - %%DATAPATH%%models/planes/Easystar/easystar.3ds - %%DATAPATH%%models/backgrounds/default_background.png - false - - - - - false - 0.0.0 - - - %%DATAPATH%%models/planes/firecracker/firecracker.3ds - %%DATAPATH%%models/backgrounds/default_background.png - false - - - - - false - 0.0.0 - - - %%DATAPATH%%models/planes/funjet/funjet.3ds - %%DATAPATH%%models/backgrounds/default_background.png - false - - - - - false - 0.0.0 - - - %%DATAPATH%%models/multi/gaui_330x/gaui_330x.3ds - %%DATAPATH%%models/backgrounds/default_background.png - false - - - - - false - 0.0.0 - - - %%DATAPATH%%models/helis/t-rex/t-rex_450_xl.3ds - %%DATAPATH%%models/backgrounds/default_background.png - false - - - - - false - 0.0.0 - - - %%DATAPATH%%models/multi/mikrokopter/MK_Hexa.3ds - %%DATAPATH%%models/backgrounds/default_background.png - false - - - - - false - 0.0.0 - - - %%DATAPATH%%models/multi/joes_cnc/J14-Q_+.3DS - %%DATAPATH%%models/backgrounds/default_background.png - false - - - - - false - 0.0.0 - - - %%DATAPATH%%models/multi/joes_cnc/J14-Q_X.3DS - %%DATAPATH%%models/backgrounds/default_background.png - false - - - - - false - 0.0.0 - - - %%DATAPATH%%models/multi/joes_cnc/J14-QT_+.3DS - %%DATAPATH%%models/backgrounds/default_background.png - false - - - - - false - 0.0.0 - - - %%DATAPATH%%models/multi/joes_cnc/J14-QT_X.3DS - %%DATAPATH%%models/backgrounds/default_background.png - false - - - - - false - 0.0.0 - - - %%DATAPATH%%models/multi/mikrokopter/MK_L4-ME.3ds - %%DATAPATH%%models/backgrounds/default_background.png - false - - - - - false - 0.0.0 - - - %%DATAPATH%%models/multi/ricoo/ricoo.3DS - %%DATAPATH%%models/backgrounds/default_background.png - false - - - - - false - 0.0.0 - - - %%DATAPATH%%models/multi/scorpion_tricopter/scorpion_tricopter.3ds - %%DATAPATH%%models/backgrounds/default_background.png - false - - - - - false - 0.0.0 - - - %%DATAPATH%%models/multi/mattL_Y6/mattL_Y6.3ds - %%DATAPATH%%models/backgrounds/default_background.png - false - - - - - false - 0.0.0 - - - %%DATAPATH%%models/multi/test_quad/test_quad_+.3ds - %%DATAPATH%%models/backgrounds/default_background.png - false - - - - - false - 0.0.0 - - - %%DATAPATH%%models/multi/test_quad/test_quad_X.3ds - %%DATAPATH%%models/backgrounds/default_background.png - false - - - - - false - 0.0.0 - - - %%DATAPATH%%models/multi/dankers_quad/dankers_quad.3ds - %%DATAPATH%%models/backgrounds/default_background.png - false - - - @@ -1820,7 +1554,7 @@ 0 0 2 - GoogleSatellite + GoogleHybrid 2000 1 false @@ -1871,55 +1605,175 @@ - + false 0.0.0 - false - 2000 + %%DATAPATH%%qml/Pfd.qml 1 - false - %%DATAPATH%%pfd/default/readymap.earth - 46.6715 - 10.1589 - true - %%DATAPATH%%pfd/default/Pfd.qml 1 false - - - - - false - 0.0.0 - - - false - 2000 + %%DATAPATH%%osgearth/readymap.earth false - %%DATAPATH%%pfd/default/readymap.earth - 46.6715 - 10.1589 - true - %%DATAPATH%%pfd/default/Pfd.qml - false + 39.6576 + 19.8046 + 90 + 0 + @Variant(AAAAEAAlfhEClAez/w==) + 0.50 + false + 1 + %%DATAPATH%%models/multi/test_quad/test_quad_x.3ds + %%DATAPATH%%backgrounds/default_background.png - - - - + + false 0.0.0 - Unknown - true + %%DATAPATH%%qml/PfdTerrain.qml + 1 + 1 + true + %%DATAPATH%%osgearth/readymap.earth + false + 39.6576 + 19.8046 + 90 + 0 + @Variant(AAAAEAAlfhEClAez/w==) + 0.50 + false + 1 + %%DATAPATH%%models/multi/test_quad/test_quad_x.3ds + %%DATAPATH%%backgrounds/default_background.png - - + + + + false + 0.0.0 + + + %%DATAPATH%%qml/PfdTerrain.qml + 1 + 1 + true + %%DATAPATH%%osgearth/arcgis.earth + false + 39.6576 + 19.8046 + 90 + 0 + @Variant(AAAAEAAlfhEClAez/w==) + 0.50 + false + 1 + %%DATAPATH%%models/multi/test_quad/test_quad_x.3ds + %%DATAPATH%%backgrounds/default_background.png + + + + + false + 0.0.0 + + + %%DATAPATH%%qml/Model.qml + 1 + 1 + false + %%DATAPATH%%osgearth/arcgis.earth + false + 39.6576 + 19.8046 + 90 + 0 + @Variant(AAAAEAAlfhEClAez/w==) + 0.50 + true + 1 + %%DATAPATH%%models/multi/test_quad/test_quad_x.3ds + %%DATAPATH%%backgrounds/default_background.png + + + + + false + 0.0.0 + + + %%DATAPATH%%qml/ModelTerrain.qml + 1 + 1 + true + %%DATAPATH%%osgearth/readymap.earth + false + 39.6576 + 19.8046 + 90 + 0 + @Variant(AAAAEAAlfhEClAez/w==) + 0.50 + true + 1 + %%DATAPATH%%models/multi/test_quad/test_quad_x.3ds + %%DATAPATH%%backgrounds/default_background.png + + + + + false + 0.0.0 + + + %%DATAPATH%%qml/ModelTerrain.qml + 1 + 1 + true + %%DATAPATH%%osgearth/arcgis.earth + false + 39.6576 + 19.8046 + 90 + 0 + @Variant(AAAAEAAlfhEClAez/w==) + 0.50 + true + 1 + %%DATAPATH%%models/multi/test_quad/test_quad_x.3ds + %%DATAPATH%%backgrounds/default_background.png + + + + + false + 0.0.0 + + + %%DATAPATH%%qml/Earth.qml + 1 + 1 + true + %%DATAPATH%%osgearth/arcgis.earth + false + 39.6576 + 19.8046 + 90 + 0 + @Variant(AAAAEAAlfhEClAez/w==) + 0.50 + false + 1 + %%DATAPATH%%models/multi/test_quad/test_quad_x.3ds + %%DATAPATH%%backgrounds/default_background.png + + + @@ -1974,12 +1828,14 @@ false false + 1000 20 - 4294901760 + 4278190080 + true None - Channel-4 + Channel-0 ActuatorCommand 0 1 @@ -1987,9 +1843,10 @@ 0 - 4294901760 + 4289352960 + true None - Channel-5 + Channel-1 ActuatorCommand 0 1 @@ -1997,9 +1854,10 @@ 0 - 4289374847 + 4294901760 + true None - Channel-6 + Channel-2 ActuatorCommand 0 1 @@ -2007,7 +1865,52 @@ 0 - 4289374847 + 4294923520 + true + None + Channel-3 + ActuatorCommand + 0 + 1 + 0 + 0 + + + 4294967040 + true + None + Channel-4 + ActuatorCommand + 0 + 1 + 0 + 0 + + + 4283825920 + true + None + Channel-5 + ActuatorCommand + 0 + 1 + 0 + 0 + + + 4278190335 + true + None + Channel-6 + ActuatorCommand + 0 + 1 + 0 + 0 + + + 4289331455 + true None Channel-7 ActuatorCommand @@ -2015,8 +1918,8 @@ 1 0 0 - - 4 + + 8 1 100 @@ -2074,10 +1977,34 @@ false false + 1000 60 + 4278212095 + true + None + Altitude + BaroSensor + 0 + 1 + 0 + 0 + + + 4294901760 + true + None + Temperature + BaroSensor + 0 + 1 + 0 + 0 + + 4278190080 + true None Pressure BaroSensor @@ -2085,12 +2012,138 @@ 1 0 0 - - 1 + + 3 1 - 1000 + 300 + + + false + 0.0.0 + + + false + false + + 1000 + 60 + + 4294901760 + true + None + Satellites + GPSPositionSensor + 0 + 1 + 0 + 0 + + + 4278255615 + true + None + AutoConfigStatus + GPSPositionSensor + 0 + 1 + 0 + 0 + + + 4283804415 + true + None + BaudRate + GPSPositionSensor + 0 + 1 + 0 + 0 + + + 4294923520 + true + None + SatsInView + GPSSatellites + 0 + 1 + 0 + 0 + + + 4294967040 + true + None + Status + GPSPositionSensor + 0 + 1 + 0 + 0 + + + 4294901887 + true + None + Groundspeed + GPSPositionSensor + 0 + 1 + 0 + 0 + + + 4283804287 + true + None + PDOP + GPSPositionSensor + 0 + 1 + 0 + 0 + + + 4283826047 + true + None + HDOP + GPSPositionSensor + 0 + 1 + 0 + 0 + + + 4289396607 + true + None + VDOP + GPSPositionSensor + 0 + 1 + 0 + 0 + + + 4289353215 + true + None + Alarm-GPS + SystemAlarms + 0 + 1 + 0 + 0 + + 10 + 1 + 100 + + false @@ -2099,12 +2152,14 @@ false false + 1000 40 - 4278190207 + 4278190080 + true None - Channel-1 + Channel-0 ManualControlCommand 0 1 @@ -2112,9 +2167,10 @@ 0 - 4294901760 + 4289352960 + true None - Channel-4 + Channel-1 ManualControlCommand 0 1 @@ -2123,36 +2179,7 @@ 4294901760 - None - Channel-5 - ManualControlCommand - 0 - 1 - 0 - 0 - - - 4294901760 - None - Channel-6 - ManualControlCommand - 0 - 1 - 0 - 0 - - - 4294901760 - None - Channel-7 - ManualControlCommand - 0 - 1 - 0 - 0 - - - 4283825920 + true None Channel-2 ManualControlCommand @@ -2160,9 +2187,10 @@ 1 0 0 - - + + 4294923520 + true None Channel-3 ManualControlCommand @@ -2170,11 +2198,45 @@ 1 0 0 + + + 4294967040 + true + None + Channel-4 + ManualControlCommand + 0 + 1 + 0 + 0 + + + 4278255360 + true + None + Channel-5 + ManualControlCommand + 0 + 1 + 0 + 0 + + + 4278190335 + true + None + Channel-6 + ManualControlCommand + 0 + 1 + 0 + 0 - 4294967040 + 4289331455 + true None - Channel-0 + Channel-7 ManualControlCommand 0 1 @@ -2186,6 +2248,77 @@ 200 + + + false + 0.0.0 + + + false + false + + 1000 + 60 + + 4278212095 + true + None + LinkState + OPLinkStatus + 0 + 1 + 0 + 0 + + + 4278255615 + true + None + RSSI + OPLinkStatus + 0 + 1 + 0 + 0 + + + 4294967040 + true + None + LinkQuality + OPLinkStatus + 0 + 1 + 0 + 0 + + + 4294901760 + true + None + TXRate + OPLinkStatus + 0 + 1 + 0 + 0 + + + 4278255360 + true + None + RXRate + OPLinkStatus + 0 + 1 + 0 + 0 + + 5 + 1 + 100 + + false @@ -2276,7 +2409,7 @@ 500
- + false 0.0.0 @@ -2284,10 +2417,94 @@ false false + + 1000 + 40 + + 4278233600 + true + None + x + MagSensor + 0 + 1 + 0 + 0 + + + 4278233855 + true + None + y + MagSensor + 0 + 1 + 0 + 0 + + + 4294967167 + true + None + z + MagSensor + 0 + 1 + 0 + 0 + + + 4278255360 + true + None + x + AuxMagSensor + 0 + 1 + 0 + 0 + + + 4278255615 + true + None + y + AuxMagSensor + 0 + 1 + 0 + 0 + + + 4294967040 + true + None + z + AuxMagSensor + 0 + 1 + 0 + 0 + + 6 + 1 + 200 + + + + + false + 0.0.0 + + + false + false + 1000 60 - 4294901760 + 4278233600 + true None x MagState @@ -2297,7 +2514,8 @@ 0 - 4283782655 + 4278190335 + true None y MagState @@ -2307,7 +2525,8 @@ 0 - 4283804160 + 4294967040 + true None z MagState @@ -2316,11 +2535,33 @@ 0 0 - 3 + + 4294901760 + true + None + Alarm-Magnetometer + SystemAlarms + 0 + 1 + 0 + 0 + + + 4283826175 + true + None + Source + MagState + 0 + 1 + 0 + 0 + + 5 1 500 - + false @@ -2569,16 +2810,16 @@ PfdQmlGadget - NoTerrain + PFD uavGadget - ModelViewGadget + PfdQmlGadget - Blackout_MiniH - + Model View + uavGadget @@ -2714,7 +2955,7 @@ PfdQmlGadget - NoTerrain + PFD uavGadget diff --git a/ground/gcs/src/share/copydata.pro b/ground/gcs/src/share/copydata.pro index 330f95732..ee8f36672 100644 --- a/ground/gcs/src/share/copydata.pro +++ b/ground/gcs/src/share/copydata.pro @@ -2,7 +2,7 @@ include(../../gcs.pri) TEMPLATE = aux -DATACOLLECTIONS = vehicletemplates configurations dials models pfd sounds diagrams mapicons stylesheets +DATACOLLECTIONS = vehicletemplates configurations dials models backgrounds qml sounds diagrams mapicons stylesheets osgearth equals(copydata, 1) { for(dir, DATACOLLECTIONS) { diff --git a/ground/gcs/src/share/models/boards/CC3D/CC3D.3ds b/ground/gcs/src/share/models/boards/cc3d/cc3d.3ds similarity index 60% rename from ground/gcs/src/share/models/boards/CC3D/CC3D.3ds rename to ground/gcs/src/share/models/boards/cc3d/cc3d.3ds index 615698212..a7fd86895 100644 Binary files a/ground/gcs/src/share/models/boards/CC3D/CC3D.3ds and b/ground/gcs/src/share/models/boards/cc3d/cc3d.3ds differ diff --git a/ground/gcs/src/share/models/boards/cc3d/cc3d.jpg b/ground/gcs/src/share/models/boards/cc3d/cc3d.jpg new file mode 100644 index 000000000..b9389265b Binary files /dev/null and b/ground/gcs/src/share/models/boards/cc3d/cc3d.jpg differ diff --git a/ground/gcs/src/share/models/boards/CC3D/TEXTURE.PNG b/ground/gcs/src/share/models/boards/cc3d/texture-old.png similarity index 100% rename from ground/gcs/src/share/models/boards/CC3D/TEXTURE.PNG rename to ground/gcs/src/share/models/boards/cc3d/texture-old.png diff --git a/ground/gcs/src/share/models/boards/cc3d/texture.png b/ground/gcs/src/share/models/boards/cc3d/texture.png new file mode 100644 index 000000000..168ddb9d0 Binary files /dev/null and b/ground/gcs/src/share/models/boards/cc3d/texture.png differ diff --git a/ground/gcs/src/share/models/boards/CopterControl/CopterControl.3ds b/ground/gcs/src/share/models/boards/coptercontrol/coptercontrol.3ds similarity index 56% rename from ground/gcs/src/share/models/boards/CopterControl/CopterControl.3ds rename to ground/gcs/src/share/models/boards/coptercontrol/coptercontrol.3ds index c158dba99..54a7915f0 100644 Binary files a/ground/gcs/src/share/models/boards/CopterControl/CopterControl.3ds and b/ground/gcs/src/share/models/boards/coptercontrol/coptercontrol.3ds differ diff --git a/ground/gcs/src/share/models/boards/CopterControl/TEXTURE.PNG b/ground/gcs/src/share/models/boards/coptercontrol/texture.png similarity index 100% rename from ground/gcs/src/share/models/boards/CopterControl/TEXTURE.PNG rename to ground/gcs/src/share/models/boards/coptercontrol/texture.png diff --git a/ground/gcs/src/share/models/boards/op_gps_v9/op_gps_v9.3ds b/ground/gcs/src/share/models/boards/op_gps_v9/op_gps_v9.3ds new file mode 100755 index 000000000..6f31789ba Binary files /dev/null and b/ground/gcs/src/share/models/boards/op_gps_v9/op_gps_v9.3ds differ diff --git a/ground/gcs/src/share/models/boards/op_gps_v9/op_gps_v9.jpg b/ground/gcs/src/share/models/boards/op_gps_v9/op_gps_v9.jpg new file mode 100644 index 000000000..b9cac9f44 Binary files /dev/null and b/ground/gcs/src/share/models/boards/op_gps_v9/op_gps_v9.jpg differ diff --git a/ground/gcs/src/share/models/boards/op_gps_v9/texture.jpg b/ground/gcs/src/share/models/boards/op_gps_v9/texture.jpg new file mode 100644 index 000000000..4665c5f06 Binary files /dev/null and b/ground/gcs/src/share/models/boards/op_gps_v9/texture.jpg differ diff --git a/ground/gcs/src/share/models/boards/Revolution/Revolution.3DS b/ground/gcs/src/share/models/boards/revolution/revolution.3ds old mode 100644 new mode 100755 similarity index 69% rename from ground/gcs/src/share/models/boards/Revolution/Revolution.3DS rename to ground/gcs/src/share/models/boards/revolution/revolution.3ds index 58cfe8d6d..c290bdadf Binary files a/ground/gcs/src/share/models/boards/Revolution/Revolution.3DS and b/ground/gcs/src/share/models/boards/revolution/revolution.3ds differ diff --git a/ground/gcs/src/share/models/boards/revolution/revolution.jpg b/ground/gcs/src/share/models/boards/revolution/revolution.jpg new file mode 100644 index 000000000..8d55053b0 Binary files /dev/null and b/ground/gcs/src/share/models/boards/revolution/revolution.jpg differ diff --git a/ground/gcs/src/share/models/boards/Revolution/TEXTURE.PNG b/ground/gcs/src/share/models/boards/revolution/texture.png similarity index 100% rename from ground/gcs/src/share/models/boards/Revolution/TEXTURE.PNG rename to ground/gcs/src/share/models/boards/revolution/texture.png diff --git a/ground/gcs/src/share/models/helis/t-rex/t-rex_450_xl.3ds b/ground/gcs/src/share/models/helis/t-rex/t-rex_450_xl.3ds index 87ed5e132..f366f5c38 100644 Binary files a/ground/gcs/src/share/models/helis/t-rex/t-rex_450_xl.3ds and b/ground/gcs/src/share/models/helis/t-rex/t-rex_450_xl.3ds differ diff --git a/ground/gcs/src/share/models/helis/t-rex/TEXTURE.JPG b/ground/gcs/src/share/models/helis/t-rex/texture.jpg similarity index 100% rename from ground/gcs/src/share/models/helis/t-rex/TEXTURE.JPG rename to ground/gcs/src/share/models/helis/t-rex/texture.jpg diff --git a/ground/gcs/src/share/models/multi/aeroquad/aeroquad_+.3ds b/ground/gcs/src/share/models/multi/aeroquad/aeroquad_+.3ds index f8c6b995a..a12921643 100644 Binary files a/ground/gcs/src/share/models/multi/aeroquad/aeroquad_+.3ds and b/ground/gcs/src/share/models/multi/aeroquad/aeroquad_+.3ds differ diff --git a/ground/gcs/src/share/models/multi/aeroquad/TEXTURE.JPG b/ground/gcs/src/share/models/multi/aeroquad/texture.jpg similarity index 100% rename from ground/gcs/src/share/models/multi/aeroquad/TEXTURE.JPG rename to ground/gcs/src/share/models/multi/aeroquad/texture.jpg diff --git a/ground/gcs/src/share/models/multi/blackout/BlackoutMiniHQuad.3DS b/ground/gcs/src/share/models/multi/blackout/blackout_mini_h_quad.3ds similarity index 62% rename from ground/gcs/src/share/models/multi/blackout/BlackoutMiniHQuad.3DS rename to ground/gcs/src/share/models/multi/blackout/blackout_mini_h_quad.3ds index 1217e54de..e7adcdb88 100644 Binary files a/ground/gcs/src/share/models/multi/blackout/BlackoutMiniHQuad.3DS and b/ground/gcs/src/share/models/multi/blackout/blackout_mini_h_quad.3ds differ diff --git a/ground/gcs/src/share/models/multi/blackout/BlackoutMiniHQuad.jpg b/ground/gcs/src/share/models/multi/blackout/blackout_mini_h_quad.jpg similarity index 100% rename from ground/gcs/src/share/models/multi/blackout/BlackoutMiniHQuad.jpg rename to ground/gcs/src/share/models/multi/blackout/blackout_mini_h_quad.jpg diff --git a/ground/gcs/src/share/models/multi/blackout/TEXTURE.PNG b/ground/gcs/src/share/models/multi/blackout/texture.png similarity index 100% rename from ground/gcs/src/share/models/multi/blackout/TEXTURE.PNG rename to ground/gcs/src/share/models/multi/blackout/texture.png diff --git a/ground/gcs/src/share/models/multi/dankers_quad/dankers_quad.3ds b/ground/gcs/src/share/models/multi/dankers_quad/dankers_quad.3ds index b2e727be6..e5721bad7 100644 Binary files a/ground/gcs/src/share/models/multi/dankers_quad/dankers_quad.3ds and b/ground/gcs/src/share/models/multi/dankers_quad/dankers_quad.3ds differ diff --git a/ground/gcs/src/share/models/multi/dankers_quad/TEXTURE.jpg b/ground/gcs/src/share/models/multi/dankers_quad/texture.jpg similarity index 100% rename from ground/gcs/src/share/models/multi/dankers_quad/TEXTURE.jpg rename to ground/gcs/src/share/models/multi/dankers_quad/texture.jpg diff --git a/ground/gcs/src/share/models/multi/easy_quad/BOARDS.JPG b/ground/gcs/src/share/models/multi/easy_quad/boards.jpg similarity index 100% rename from ground/gcs/src/share/models/multi/easy_quad/BOARDS.JPG rename to ground/gcs/src/share/models/multi/easy_quad/boards.jpg diff --git a/ground/gcs/src/share/models/multi/easy_quad/easy_quad_X.jpg b/ground/gcs/src/share/models/multi/easy_quad/easy_quad_X.jpg deleted file mode 100644 index 15192ba5c..000000000 Binary files a/ground/gcs/src/share/models/multi/easy_quad/easy_quad_X.jpg and /dev/null differ diff --git a/ground/gcs/src/share/models/multi/easy_quad/easy_quad_X.3ds b/ground/gcs/src/share/models/multi/easy_quad/easy_quad_x.3ds similarity index 56% rename from ground/gcs/src/share/models/multi/easy_quad/easy_quad_X.3ds rename to ground/gcs/src/share/models/multi/easy_quad/easy_quad_x.3ds index b9b3ee09c..775f1811d 100644 Binary files a/ground/gcs/src/share/models/multi/easy_quad/easy_quad_X.3ds and b/ground/gcs/src/share/models/multi/easy_quad/easy_quad_x.3ds differ diff --git a/ground/gcs/src/share/models/multi/easy_quad/easy_quad_x.jpg b/ground/gcs/src/share/models/multi/easy_quad/easy_quad_x.jpg new file mode 100644 index 000000000..b5830c96f Binary files /dev/null and b/ground/gcs/src/share/models/multi/easy_quad/easy_quad_x.jpg differ diff --git a/ground/gcs/src/share/models/multi/easy_quad/LOGO.JPG b/ground/gcs/src/share/models/multi/easy_quad/logo.jpg similarity index 100% rename from ground/gcs/src/share/models/multi/easy_quad/LOGO.JPG rename to ground/gcs/src/share/models/multi/easy_quad/logo.jpg diff --git a/ground/gcs/src/share/models/multi/easy_quad/TEXTURE.JPG b/ground/gcs/src/share/models/multi/easy_quad/texture.jpg similarity index 100% rename from ground/gcs/src/share/models/multi/easy_quad/TEXTURE.JPG rename to ground/gcs/src/share/models/multi/easy_quad/texture.jpg diff --git a/ground/gcs/src/share/models/multi/gaui_330x/gaui_330x.3ds b/ground/gcs/src/share/models/multi/gaui_330x/gaui_330x.3ds index a9af453ba..785e4505b 100644 Binary files a/ground/gcs/src/share/models/multi/gaui_330x/gaui_330x.3ds and b/ground/gcs/src/share/models/multi/gaui_330x/gaui_330x.3ds differ diff --git a/ground/gcs/src/share/models/multi/joes_cnc/J14-QT_+.3DS b/ground/gcs/src/share/models/multi/joes_cnc/J14-QT_+.3DS deleted file mode 100644 index 9d0d2de8c..000000000 Binary files a/ground/gcs/src/share/models/multi/joes_cnc/J14-QT_+.3DS and /dev/null differ diff --git a/ground/gcs/src/share/models/multi/joes_cnc/J14-QT_X.3DS b/ground/gcs/src/share/models/multi/joes_cnc/J14-QT_X.3DS deleted file mode 100644 index a29de2543..000000000 Binary files a/ground/gcs/src/share/models/multi/joes_cnc/J14-QT_X.3DS and /dev/null differ diff --git a/ground/gcs/src/share/models/multi/joes_cnc/J14-Q_+.3DS b/ground/gcs/src/share/models/multi/joes_cnc/J14-Q_+.3DS deleted file mode 100644 index d4bb3dfbf..000000000 Binary files a/ground/gcs/src/share/models/multi/joes_cnc/J14-Q_+.3DS and /dev/null differ diff --git a/ground/gcs/src/share/models/multi/joes_cnc/J14-Q_X.3DS b/ground/gcs/src/share/models/multi/joes_cnc/J14-Q_X.3DS deleted file mode 100644 index cb0f3e995..000000000 Binary files a/ground/gcs/src/share/models/multi/joes_cnc/J14-Q_X.3DS and /dev/null differ diff --git a/ground/gcs/src/share/models/multi/joes_cnc/TEXTURE.JPG b/ground/gcs/src/share/models/multi/joes_cnc/TEXTURE.JPG deleted file mode 100644 index 9e5500340..000000000 Binary files a/ground/gcs/src/share/models/multi/joes_cnc/TEXTURE.JPG and /dev/null differ diff --git a/ground/gcs/src/share/models/multi/ricoo/CC.PNG b/ground/gcs/src/share/models/multi/joes_cnc/cc.png similarity index 100% rename from ground/gcs/src/share/models/multi/ricoo/CC.PNG rename to ground/gcs/src/share/models/multi/joes_cnc/cc.png diff --git a/ground/gcs/src/share/models/multi/joes_cnc/j14-q_+.3ds b/ground/gcs/src/share/models/multi/joes_cnc/j14-q_+.3ds new file mode 100644 index 000000000..c87474b1a Binary files /dev/null and b/ground/gcs/src/share/models/multi/joes_cnc/j14-q_+.3ds differ diff --git a/ground/gcs/src/share/models/multi/joes_cnc/J14-Q_+.jpg b/ground/gcs/src/share/models/multi/joes_cnc/j14-q_+.jpg similarity index 100% rename from ground/gcs/src/share/models/multi/joes_cnc/J14-Q_+.jpg rename to ground/gcs/src/share/models/multi/joes_cnc/j14-q_+.jpg diff --git a/ground/gcs/src/share/models/multi/joes_cnc/j14-q_x.3ds b/ground/gcs/src/share/models/multi/joes_cnc/j14-q_x.3ds new file mode 100644 index 000000000..2051c90dc Binary files /dev/null and b/ground/gcs/src/share/models/multi/joes_cnc/j14-q_x.3ds differ diff --git a/ground/gcs/src/share/models/multi/joes_cnc/J14-Q_X.jpg b/ground/gcs/src/share/models/multi/joes_cnc/j14-q_x.jpg similarity index 100% rename from ground/gcs/src/share/models/multi/joes_cnc/J14-Q_X.jpg rename to ground/gcs/src/share/models/multi/joes_cnc/j14-q_x.jpg diff --git a/ground/gcs/src/share/models/multi/joes_cnc/j14-qt_+.3ds b/ground/gcs/src/share/models/multi/joes_cnc/j14-qt_+.3ds new file mode 100644 index 000000000..fe75bfb43 Binary files /dev/null and b/ground/gcs/src/share/models/multi/joes_cnc/j14-qt_+.3ds differ diff --git a/ground/gcs/src/share/models/multi/joes_cnc/J14-QT_+.jpg b/ground/gcs/src/share/models/multi/joes_cnc/j14-qt_+.jpg similarity index 100% rename from ground/gcs/src/share/models/multi/joes_cnc/J14-QT_+.jpg rename to ground/gcs/src/share/models/multi/joes_cnc/j14-qt_+.jpg diff --git a/ground/gcs/src/share/models/multi/joes_cnc/j14-qt_x.3ds b/ground/gcs/src/share/models/multi/joes_cnc/j14-qt_x.3ds new file mode 100644 index 000000000..76ede1744 Binary files /dev/null and b/ground/gcs/src/share/models/multi/joes_cnc/j14-qt_x.3ds differ diff --git a/ground/gcs/src/share/models/multi/joes_cnc/J14-QT_X.jpg b/ground/gcs/src/share/models/multi/joes_cnc/j14-qt_x.jpg similarity index 100% rename from ground/gcs/src/share/models/multi/joes_cnc/J14-QT_X.jpg rename to ground/gcs/src/share/models/multi/joes_cnc/j14-qt_x.jpg diff --git a/ground/gcs/src/share/models/multi/joes_cnc/texture.png b/ground/gcs/src/share/models/multi/joes_cnc/texture.png new file mode 100644 index 000000000..5d26bb120 Binary files /dev/null and b/ground/gcs/src/share/models/multi/joes_cnc/texture.png differ diff --git a/ground/gcs/src/share/models/multi/mattL_Y6/mattL_Y6.3ds b/ground/gcs/src/share/models/multi/mattl_y6/mattl_y6.3ds similarity index 75% rename from ground/gcs/src/share/models/multi/mattL_Y6/mattL_Y6.3ds rename to ground/gcs/src/share/models/multi/mattl_y6/mattl_y6.3ds index d7f54398b..d2eda5587 100644 Binary files a/ground/gcs/src/share/models/multi/mattL_Y6/mattL_Y6.3ds and b/ground/gcs/src/share/models/multi/mattl_y6/mattl_y6.3ds differ diff --git a/ground/gcs/src/share/models/multi/mattL_Y6/mattL_Y6.jpg b/ground/gcs/src/share/models/multi/mattl_y6/mattl_y6.jpg similarity index 100% rename from ground/gcs/src/share/models/multi/mattL_Y6/mattL_Y6.jpg rename to ground/gcs/src/share/models/multi/mattl_y6/mattl_y6.jpg diff --git a/ground/gcs/src/share/models/multi/mattL_Y6/TEXTURE.PNG b/ground/gcs/src/share/models/multi/mattl_y6/texture.png similarity index 100% rename from ground/gcs/src/share/models/multi/mattL_Y6/TEXTURE.PNG rename to ground/gcs/src/share/models/multi/mattl_y6/texture.png diff --git a/ground/gcs/src/share/models/multi/mikrokopter/MK_Hexa.3ds b/ground/gcs/src/share/models/multi/mikrokopter/mk_hexa.3ds similarity index 73% rename from ground/gcs/src/share/models/multi/mikrokopter/MK_Hexa.3ds rename to ground/gcs/src/share/models/multi/mikrokopter/mk_hexa.3ds index 60ae9bc69..db2621bf5 100644 Binary files a/ground/gcs/src/share/models/multi/mikrokopter/MK_Hexa.3ds and b/ground/gcs/src/share/models/multi/mikrokopter/mk_hexa.3ds differ diff --git a/ground/gcs/src/share/models/multi/mikrokopter/MK_Hexa.jpg b/ground/gcs/src/share/models/multi/mikrokopter/mk_hexa.jpg similarity index 100% rename from ground/gcs/src/share/models/multi/mikrokopter/MK_Hexa.jpg rename to ground/gcs/src/share/models/multi/mikrokopter/mk_hexa.jpg diff --git a/ground/gcs/src/share/models/multi/mikrokopter/MK_L4-ME.3ds b/ground/gcs/src/share/models/multi/mikrokopter/mk_l4-me.3ds similarity index 65% rename from ground/gcs/src/share/models/multi/mikrokopter/MK_L4-ME.3ds rename to ground/gcs/src/share/models/multi/mikrokopter/mk_l4-me.3ds index 5c9cbb8e3..1c74cb026 100644 Binary files a/ground/gcs/src/share/models/multi/mikrokopter/MK_L4-ME.3ds and b/ground/gcs/src/share/models/multi/mikrokopter/mk_l4-me.3ds differ diff --git a/ground/gcs/src/share/models/multi/mikrokopter/MK_L4-ME.jpg b/ground/gcs/src/share/models/multi/mikrokopter/mk_l4-me.jpg similarity index 100% rename from ground/gcs/src/share/models/multi/mikrokopter/MK_L4-ME.jpg rename to ground/gcs/src/share/models/multi/mikrokopter/mk_l4-me.jpg diff --git a/ground/gcs/src/share/models/multi/mikrokopter/MK_Okto.3ds b/ground/gcs/src/share/models/multi/mikrokopter/mk_okto.3ds similarity index 65% rename from ground/gcs/src/share/models/multi/mikrokopter/MK_Okto.3ds rename to ground/gcs/src/share/models/multi/mikrokopter/mk_okto.3ds index 4cd407e96..5add03e19 100644 Binary files a/ground/gcs/src/share/models/multi/mikrokopter/MK_Okto.3ds and b/ground/gcs/src/share/models/multi/mikrokopter/mk_okto.3ds differ diff --git a/ground/gcs/src/share/models/multi/mikrokopter/MK_Okto.jpg b/ground/gcs/src/share/models/multi/mikrokopter/mk_okto.jpg similarity index 100% rename from ground/gcs/src/share/models/multi/mikrokopter/MK_Okto.jpg rename to ground/gcs/src/share/models/multi/mikrokopter/mk_okto.jpg diff --git a/ground/gcs/src/share/models/multi/mikrokopter/MK_Okto2.3ds b/ground/gcs/src/share/models/multi/mikrokopter/mk_okto2.3ds similarity index 64% rename from ground/gcs/src/share/models/multi/mikrokopter/MK_Okto2.3ds rename to ground/gcs/src/share/models/multi/mikrokopter/mk_okto2.3ds index 5d1e31ebe..73e21cc18 100644 Binary files a/ground/gcs/src/share/models/multi/mikrokopter/MK_Okto2.3ds and b/ground/gcs/src/share/models/multi/mikrokopter/mk_okto2.3ds differ diff --git a/ground/gcs/src/share/models/multi/mikrokopter/MK_Okto2.jpg b/ground/gcs/src/share/models/multi/mikrokopter/mk_okto2.jpg similarity index 100% rename from ground/gcs/src/share/models/multi/mikrokopter/MK_Okto2.jpg rename to ground/gcs/src/share/models/multi/mikrokopter/mk_okto2.jpg diff --git a/ground/gcs/src/share/models/multi/mikrokopter/TEXTURE.JPG b/ground/gcs/src/share/models/multi/mikrokopter/texture.jpg similarity index 100% rename from ground/gcs/src/share/models/multi/mikrokopter/TEXTURE.JPG rename to ground/gcs/src/share/models/multi/mikrokopter/texture.jpg diff --git a/ground/gcs/src/share/models/multi/ricoo/cc.png b/ground/gcs/src/share/models/multi/ricoo/cc.png new file mode 100644 index 000000000..467f34a97 Binary files /dev/null and b/ground/gcs/src/share/models/multi/ricoo/cc.png differ diff --git a/ground/gcs/src/share/models/multi/ricoo/ricoo.3DS b/ground/gcs/src/share/models/multi/ricoo/ricoo.3ds similarity index 57% rename from ground/gcs/src/share/models/multi/ricoo/ricoo.3DS rename to ground/gcs/src/share/models/multi/ricoo/ricoo.3ds index 226920061..2d20a1d8a 100644 Binary files a/ground/gcs/src/share/models/multi/ricoo/ricoo.3DS and b/ground/gcs/src/share/models/multi/ricoo/ricoo.3ds differ diff --git a/ground/gcs/src/share/models/multi/ricoo/TEXTURE.PNG b/ground/gcs/src/share/models/multi/ricoo/texture.png similarity index 100% rename from ground/gcs/src/share/models/multi/ricoo/TEXTURE.PNG rename to ground/gcs/src/share/models/multi/ricoo/texture.png diff --git a/ground/gcs/src/share/models/multi/scorpion_tricopter/scorpion_tricopter.3ds b/ground/gcs/src/share/models/multi/scorpion_tricopter/scorpion_tricopter.3ds index 845bfb03c..5e4ed10c5 100644 Binary files a/ground/gcs/src/share/models/multi/scorpion_tricopter/scorpion_tricopter.3ds and b/ground/gcs/src/share/models/multi/scorpion_tricopter/scorpion_tricopter.3ds differ diff --git a/ground/gcs/src/share/models/multi/test_quad/TEXTURE.PNG b/ground/gcs/src/share/models/multi/test_quad/TEXTURE.PNG deleted file mode 100644 index 3623b4fd2..000000000 Binary files a/ground/gcs/src/share/models/multi/test_quad/TEXTURE.PNG and /dev/null differ diff --git a/ground/gcs/src/share/models/multi/test_quad/test_quad_+-old.3ds b/ground/gcs/src/share/models/multi/test_quad/test_quad_+-old.3ds new file mode 100755 index 000000000..bb5f7fa87 Binary files /dev/null and b/ground/gcs/src/share/models/multi/test_quad/test_quad_+-old.3ds differ diff --git a/ground/gcs/src/share/models/multi/test_quad/test_quad_+-old.jpg b/ground/gcs/src/share/models/multi/test_quad/test_quad_+-old.jpg new file mode 100644 index 000000000..b59a6217b Binary files /dev/null and b/ground/gcs/src/share/models/multi/test_quad/test_quad_+-old.jpg differ diff --git a/ground/gcs/src/share/models/multi/test_quad/test_quad_+.3ds b/ground/gcs/src/share/models/multi/test_quad/test_quad_+.3ds index 863e061e2..a8ddc4a9d 100644 Binary files a/ground/gcs/src/share/models/multi/test_quad/test_quad_+.3ds and b/ground/gcs/src/share/models/multi/test_quad/test_quad_+.3ds differ diff --git a/ground/gcs/src/share/models/multi/test_quad/test_quad_+.jpg b/ground/gcs/src/share/models/multi/test_quad/test_quad_+.jpg index 53ede1d4a..5de62b360 100644 Binary files a/ground/gcs/src/share/models/multi/test_quad/test_quad_+.jpg and b/ground/gcs/src/share/models/multi/test_quad/test_quad_+.jpg differ diff --git a/ground/gcs/src/share/models/multi/test_quad/test_quad_X.jpg b/ground/gcs/src/share/models/multi/test_quad/test_quad_X.jpg deleted file mode 100644 index 52dc28a7d..000000000 Binary files a/ground/gcs/src/share/models/multi/test_quad/test_quad_X.jpg and /dev/null differ diff --git a/ground/gcs/src/share/models/multi/test_quad/test_quad_x-old.3ds b/ground/gcs/src/share/models/multi/test_quad/test_quad_x-old.3ds new file mode 100755 index 000000000..3fe941fcb Binary files /dev/null and b/ground/gcs/src/share/models/multi/test_quad/test_quad_x-old.3ds differ diff --git a/ground/gcs/src/share/models/multi/test_quad/test_quad_x-old.jpg b/ground/gcs/src/share/models/multi/test_quad/test_quad_x-old.jpg new file mode 100644 index 000000000..69f72e858 Binary files /dev/null and b/ground/gcs/src/share/models/multi/test_quad/test_quad_x-old.jpg differ diff --git a/ground/gcs/src/share/models/multi/test_quad/test_quad_X.3ds b/ground/gcs/src/share/models/multi/test_quad/test_quad_x.3ds similarity index 57% rename from ground/gcs/src/share/models/multi/test_quad/test_quad_X.3ds rename to ground/gcs/src/share/models/multi/test_quad/test_quad_x.3ds index cc205f954..0c80b7d4b 100644 Binary files a/ground/gcs/src/share/models/multi/test_quad/test_quad_X.3ds and b/ground/gcs/src/share/models/multi/test_quad/test_quad_x.3ds differ diff --git a/ground/gcs/src/share/models/multi/test_quad/test_quad_x.jpg b/ground/gcs/src/share/models/multi/test_quad/test_quad_x.jpg new file mode 100644 index 000000000..b5a35cc12 Binary files /dev/null and b/ground/gcs/src/share/models/multi/test_quad/test_quad_x.jpg differ diff --git a/ground/gcs/src/share/models/multi/test_quad/TEXTURE.JPG b/ground/gcs/src/share/models/multi/test_quad/texture.jpg similarity index 100% rename from ground/gcs/src/share/models/multi/test_quad/TEXTURE.JPG rename to ground/gcs/src/share/models/multi/test_quad/texture.jpg diff --git a/ground/gcs/src/share/models/multi/test_quad/texture.png b/ground/gcs/src/share/models/multi/test_quad/texture.png new file mode 100644 index 000000000..168ddb9d0 Binary files /dev/null and b/ground/gcs/src/share/models/multi/test_quad/texture.png differ diff --git a/ground/gcs/src/share/models/planes/Easystar/easystar.3ds b/ground/gcs/src/share/models/planes/easystar/easystar.3ds similarity index 64% rename from ground/gcs/src/share/models/planes/Easystar/easystar.3ds rename to ground/gcs/src/share/models/planes/easystar/easystar.3ds index a09088399..7f4cf8cb4 100644 Binary files a/ground/gcs/src/share/models/planes/Easystar/easystar.3ds and b/ground/gcs/src/share/models/planes/easystar/easystar.3ds differ diff --git a/ground/gcs/src/share/models/planes/Easystar/easystar.jpg b/ground/gcs/src/share/models/planes/easystar/easystar.jpg similarity index 100% rename from ground/gcs/src/share/models/planes/Easystar/easystar.jpg rename to ground/gcs/src/share/models/planes/easystar/easystar.jpg diff --git a/ground/gcs/src/share/models/planes/Easystar/TEXTURE.JPG b/ground/gcs/src/share/models/planes/easystar/texture.jpg similarity index 100% rename from ground/gcs/src/share/models/planes/Easystar/TEXTURE.JPG rename to ground/gcs/src/share/models/planes/easystar/texture.jpg diff --git a/ground/gcs/src/share/models/planes/firecracker/firecracker.3ds b/ground/gcs/src/share/models/planes/firecracker/firecracker.3ds index 2bbd247f6..d99f7d320 100644 Binary files a/ground/gcs/src/share/models/planes/firecracker/firecracker.3ds and b/ground/gcs/src/share/models/planes/firecracker/firecracker.3ds differ diff --git a/ground/gcs/src/share/models/planes/firecracker/TEXTURE.JPG b/ground/gcs/src/share/models/planes/firecracker/texture.jpg similarity index 100% rename from ground/gcs/src/share/models/planes/firecracker/TEXTURE.JPG rename to ground/gcs/src/share/models/planes/firecracker/texture.jpg diff --git a/ground/gcs/src/share/models/planes/funjet/funjet.3ds b/ground/gcs/src/share/models/planes/funjet/funjet.3ds index 50d17d073..b5f921ea5 100644 Binary files a/ground/gcs/src/share/models/planes/funjet/funjet.3ds and b/ground/gcs/src/share/models/planes/funjet/funjet.3ds differ diff --git a/ground/gcs/src/share/models/planes/funjet/TEXTURE.JPG b/ground/gcs/src/share/models/planes/funjet/texture.jpg similarity index 100% rename from ground/gcs/src/share/models/planes/funjet/TEXTURE.JPG rename to ground/gcs/src/share/models/planes/funjet/texture.jpg diff --git a/ground/gcs/src/share/models/planes/zagi/zagi.3ds b/ground/gcs/src/share/models/planes/zagi/zagi.3ds index 232cdef5d..a770105c4 100644 Binary files a/ground/gcs/src/share/models/planes/zagi/zagi.3ds and b/ground/gcs/src/share/models/planes/zagi/zagi.3ds differ diff --git a/ground/gcs/src/share/models/test/cube.3ds b/ground/gcs/src/share/models/test/cube.3ds new file mode 100644 index 000000000..7cbbf78fc Binary files /dev/null and b/ground/gcs/src/share/models/test/cube.3ds differ diff --git a/ground/gcs/src/share/osgearth/arcgis.earth b/ground/gcs/src/share/osgearth/arcgis.earth new file mode 100644 index 000000000..020cbf9d1 --- /dev/null +++ b/ground/gcs/src/share/osgearth/arcgis.earth @@ -0,0 +1,20 @@ + + + + + + + + + + + 255 255 255 1 + http://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer + http://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/100/0/0.jpeg + + + + http://readymap.org/readymap/tiles/1.0.0/9/ + + + diff --git a/ground/gcs/src/share/osgearth/bing.earth b/ground/gcs/src/share/osgearth/bing.earth new file mode 100644 index 000000000..1609bafbb --- /dev/null +++ b/ground/gcs/src/share/osgearth/bing.earth @@ -0,0 +1,23 @@ + + + + + + + + + + As489Vq5Fma4_GfQvtBzpPgXqJFjB3v0ZNMICy7wDVDMeBZyK2PqH2_tYLfBhpKT + AerialWithLabels + + diff --git a/ground/gcs/src/share/osgearth/data/moon_1024x512.jpg b/ground/gcs/src/share/osgearth/data/moon_1024x512.jpg new file mode 100644 index 000000000..e20464700 Binary files /dev/null and b/ground/gcs/src/share/osgearth/data/moon_1024x512.jpg differ diff --git a/ground/gcs/src/share/osgearth/mapquest_open_aerial.earth b/ground/gcs/src/share/osgearth/mapquest_open_aerial.earth new file mode 100644 index 000000000..15d6b964a --- /dev/null +++ b/ground/gcs/src/share/osgearth/mapquest_open_aerial.earth @@ -0,0 +1,25 @@ + + + + + + http://oatile[1234].mqcdn.com/tiles/1.0.0/sat/{z}/{x}/{y}.jpg + spherical-mercator + + http://oatile3.mqcdn.com/tiles/1.0.0/sat/13/636/6210.jpg + + + + false + + + diff --git a/ground/gcs/src/share/osgearth/mapquest_osm.earth b/ground/gcs/src/share/osgearth/mapquest_osm.earth new file mode 100644 index 000000000..b27a919fd --- /dev/null +++ b/ground/gcs/src/share/osgearth/mapquest_osm.earth @@ -0,0 +1,22 @@ + + + + + + http://otile[1234].mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.jpg + global-mercator + + + + http://readymap.org/readymap/tiles/1.0.0/9/ + + + diff --git a/ground/gcs/src/share/pfd/default/readymap.earth b/ground/gcs/src/share/osgearth/readymap.earth similarity index 56% rename from ground/gcs/src/share/pfd/default/readymap.earth rename to ground/gcs/src/share/osgearth/readymap.earth index 55adca838..385787888 100644 --- a/ground/gcs/src/share/pfd/default/readymap.earth +++ b/ground/gcs/src/share/osgearth/readymap.earth @@ -7,29 +7,21 @@ is a great base map that provides global context for your own local datasets. It works "out of the box" with osgEarth applications. **** NOTICE **** -YOU ARE RESPONSIBLE for abiding by the TERMS AND CONDITIONS outlined at: -http://readymap.org - +YOU ARE RESPONSIBLE for abiding by the TERMS AND CONDITIONS outlined at: http://readymap.org --> - + - + + + + + + http://readymap.org/readymap/tiles/1.0.0/7/ - - http://readymap.org/readymap/tiles/1.0.0/35/ - - - + http://readymap.org/readymap/tiles/1.0.0/9/ - - - - false - 6.0 - - - - + + diff --git a/ground/gcs/src/share/pfd/default/PfdIndicators.qml b/ground/gcs/src/share/pfd/default/PfdIndicators.qml deleted file mode 100644 index 47f147e0e..000000000 --- a/ground/gcs/src/share/pfd/default/PfdIndicators.qml +++ /dev/null @@ -1,67 +0,0 @@ -import QtQuick 2.0 - -Item { - id: sceneItem - property variant sceneSize - - //telemetry status arrow - SvgElementImage { - id: telemetry_status - elementName: "gcstelemetry-"+statusName - sceneSize: sceneItem.sceneSize - - property string statusName : ["Disconnected","HandshakeReq","HandshakeAck","Connected"][GCSTelemetryStats.Status] - - scaledBounds: svgRenderer.scaledElementBounds("pfd.svg", "gcstelemetry-Disconnected") - x: Math.floor(scaledBounds.x * sceneItem.width) - y: Math.floor(scaledBounds.y * sceneItem.height) - } - - //telemetry rate text - Text { - id: telemetry_rate - text: GCSTelemetryStats.TxDataRate.toFixed()+"/"+GCSTelemetryStats.RxDataRate.toFixed() - color: "white" - font.family: pt_bold.name - font.pixelSize: telemetry_status.height * 0.75 - - anchors.top: telemetry_status.bottom - anchors.horizontalCenter: telemetry_status.horizontalCenter - } - - Text { - id: gps_text - text: "GPS: " + GPSPositionSensor.Satellites + "\nPDP: " + Math.round(GPSPositionSensor.PDOP*10)/10 - color: "white" - font.family: pt_bold.name - font.pixelSize: telemetry_status.height * 0.75 - - visible: GPSPositionSensor.Satellites > 0 - - property variant scaledBounds: svgRenderer.scaledElementBounds("pfd.svg", "gps-txt") - x: Math.floor(scaledBounds.x * sceneItem.width) - y: Math.floor(scaledBounds.y * sceneItem.height) - } - - Text { - id: battery_text - - text: FlightBatteryState.Voltage.toFixed(2)+" V\n" + - FlightBatteryState.Current.toFixed(2)+" A\n" + - FlightBatteryState.ConsumedEnergy.toFixed()+" mAh" - - - color: "white" - font.family: pt_bold.name - - //I think it should be pixel size, - //but making it more consistent with C++ version instead - font.pointSize: scaledBounds.height * sceneItem.height - - visible: FlightBatteryState.Voltage > 0 || FlightBatteryState.Current > 0 - - property variant scaledBounds: svgRenderer.scaledElementBounds("pfd.svg", "battery-txt") - x: Math.floor(scaledBounds.x * sceneItem.width) - y: Math.floor(scaledBounds.y * sceneItem.height) - } -} diff --git a/ground/gcs/src/share/pfd/default/PfdTerrainView.qml b/ground/gcs/src/share/pfd/default/PfdTerrainView.qml deleted file mode 100644 index 21355d16f..000000000 --- a/ground/gcs/src/share/pfd/default/PfdTerrainView.qml +++ /dev/null @@ -1,20 +0,0 @@ -import QtQuick 2.0 -import org.OpenPilot 1.0 - -OsgEarth { - id: earthView - - sceneFile: qmlWidget.earthFile - fieldOfView: 90 - - yaw: AttitudeState.Yaw - pitch: AttitudeState.Pitch - roll: AttitudeState.Roll - - latitude: qmlWidget.actualPositionUsed ? - GPSPositionSensor.Latitude/10000000.0 : qmlWidget.latitude - longitude: qmlWidget.actualPositionUsed ? - GPSPositionSensor.Longitude/10000000.0 : qmlWidget.longitude - altitude: qmlWidget.actualPositionUsed ? - GPSPositionSensor.Altitude : qmlWidget.altitude -} diff --git a/ground/gcs/src/share/pfd/default/PfdWorldView.qml b/ground/gcs/src/share/pfd/default/PfdWorldView.qml deleted file mode 100644 index f72ddd9df..000000000 --- a/ground/gcs/src/share/pfd/default/PfdWorldView.qml +++ /dev/null @@ -1,95 +0,0 @@ -import QtQuick 2.0 - -Item { - id: worldView - property real horizontCenter : horizontCenterItem.horizontCenter - - Rectangle { - // using rectange instead of svg rendered to pixmap - // as it's much more memory efficient - id: world - smooth: true - - property variant scaledBounds: svgRenderer.scaledElementBounds("pfd.svg", "horizon") - width: Math.round(sceneItem.width*scaledBounds.width/2)*2 - height: Math.round(sceneItem.height*scaledBounds.height/2)*3 - - property double pitch1DegScaledHeight: (svgRenderer.scaledElementBounds("pfd.svg", "pitch-90").y - - svgRenderer.scaledElementBounds("pfd.svg", "pitch90").y)/180.0 - - property double pitch1DegHeight: sceneItem.height*pitch1DegScaledHeight - - gradient: Gradient { - GradientStop { position: 0.4000; color: "#013163" } - GradientStop { position: 0.4999; color: "#0164CC" } - GradientStop { position: 0.5001; color: "#653300" } - GradientStop { position: 0.6000; color: "#3C1E00" } - } - - transform: [ - Translate { - id: pitchTranslate - x: Math.round((world.parent.width - world.width)/2) - // y is centered around world_center element - y: Math.round(horizontCenter - world.height/2 + - AttitudeState.Pitch*world.pitch1DegHeight) - }, - Rotation { - angle: -AttitudeState.Roll - origin.x : world.parent.width/2 - origin.y : horizontCenter - } - ] - - SvgElementImage { - id: horizont_line - elementName: "center-line" - - //worldView is loaded with Loader, so background element is visible - sceneSize: background.sceneSize - anchors.centerIn: parent - border: 1 - smooth: true - } - - SvgElementImage { - id: pitch_0 - elementName: "pitch0" - - sceneSize: background.sceneSize - anchors.centerIn: parent - border: 1 - smooth: true - } - } - - Item { - id: pitch_window - property variant scaledBounds: svgRenderer.scaledElementBounds("pfd.svg", "pitch-window") - - x: Math.floor(scaledBounds.x * sceneItem.width) - y: Math.floor(scaledBounds.y * sceneItem.height) - width: Math.floor(scaledBounds.width * sceneItem.width) - height: Math.floor(scaledBounds.height * sceneItem.height) - - rotation: -AttitudeState.Roll - transformOrigin: Item.Center - - smooth: true - clip: true - - SvgElementImage { - id: pitch_scale - elementName: "pitch-scale" - //worldView is loaded with Loader, so background element is visible - sceneSize: background.sceneSize - anchors.centerIn: parent - //see comment for world transform - anchors.verticalCenterOffset: AttitudeState.Pitch*world.pitch1DegHeight - border: 64 //sometimes numbers are excluded from bounding rect - - smooth: true - } - } - -} diff --git a/ground/gcs/src/share/pfd/default/RollScale.qml b/ground/gcs/src/share/pfd/default/RollScale.qml deleted file mode 100644 index f5ab5df1a..000000000 --- a/ground/gcs/src/share/pfd/default/RollScale.qml +++ /dev/null @@ -1,32 +0,0 @@ -import QtQuick 2.0 -import "." - -Item { - id: sceneItem - property variant sceneSize - property real horizontCenter - - onHorizontCenterChanged: console.log("horizont center:"+horizontCenter) - - SvgElementImage { - id: rollscale - elementName: "roll-scale" - sceneSize: sceneItem.sceneSize - - width: scaledBounds.width * sceneItem.width - height: scaledBounds.height * sceneItem.height - - x: scaledBounds.x * sceneItem.width - y: scaledBounds.y * sceneItem.height - - smooth: true - - //rotate it around the center of horizon - transform: Rotation { - angle: -AttitudeState.Roll - origin.y : rollscale.height*2.4 - origin.x : rollscale.width/2 - } - } - -} diff --git a/ground/gcs/src/share/pfd/default/SvgElementPositionItem.qml b/ground/gcs/src/share/pfd/default/SvgElementPositionItem.qml deleted file mode 100644 index cc43a024b..000000000 --- a/ground/gcs/src/share/pfd/default/SvgElementPositionItem.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.0 - -Item { - id: sceneItem - property variant sceneSize - property string elementName - property string svgFileName: "pfd.svg" - property variant scaledBounds: svgRenderer.scaledElementBounds(svgFileName, elementName) - - x: Math.floor(scaledBounds.x * sceneSize.width) - y: Math.floor(scaledBounds.y * sceneSize.height) - width: Math.floor(scaledBounds.width * sceneSize.width) - height: Math.floor(scaledBounds.height * sceneSize.height) -} diff --git a/ground/gcs/src/share/pfd/default/TooltipArea.qml b/ground/gcs/src/share/pfd/default/TooltipArea.qml deleted file mode 100644 index 2d6824460..000000000 --- a/ground/gcs/src/share/pfd/default/TooltipArea.qml +++ /dev/null @@ -1,27 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Controls 1.2 -import QtQuick.Controls.Private 1.0 -import QtQuick.Controls.Styles 1.1 - -// TooltipArea.qml -// This file contains private Qt Quick modules that might change in future versions of Qt -// Tested on: Qt 5.4.1 -// https://www.kullo.net/blog/tooltiparea-the-missing-tooltip-component-of-qt-quick/ - - -MouseArea { - id: _root - property string text: "" - - anchors.fill: parent - hoverEnabled: _root.enabled - - onExited: Tooltip.hideText() - onCanceled: Tooltip.hideText() - - Timer { - interval: 1000 - running: _root.enabled && _root.containsMouse && _root.text.length - onTriggered: Tooltip.showText(_root, Qt.point(_root.mouseX, _root.mouseY), _root.text) - } -} diff --git a/ground/gcs/src/share/pfd/default/srtm.earth b/ground/gcs/src/share/pfd/default/srtm.earth deleted file mode 100644 index bd17c7eb0..000000000 --- a/ground/gcs/src/share/pfd/default/srtm.earth +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - http://demo.pelicanmapping.com/rmweb/data/bluemarble-tms/tms.xml - - - - http://demo.pelicanmapping.com/rmweb/data/srtm30_plus_tms/tms.xml - - - - true - - 1 - - - - - diff --git a/ground/gcs/src/share/pfd/default/yahoo_readymap.earth b/ground/gcs/src/share/pfd/default/yahoo_readymap.earth deleted file mode 100644 index 6846feb27..000000000 --- a/ground/gcs/src/share/pfd/default/yahoo_readymap.earth +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - satellite - - - - - http://readymap.org/readymap/tiles/1.0.0/9/ - - - - - false - 6.0 - - - diff --git a/ground/gcs/src/share/pfd/default/yahoo_srtm.earth b/ground/gcs/src/share/pfd/default/yahoo_srtm.earth deleted file mode 100644 index 1033290b5..000000000 --- a/ground/gcs/src/share/pfd/default/yahoo_srtm.earth +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - satellite - - - - http://demo.pelicanmapping.com/rmweb/data/srtm30_plus_tms/tms.xml - - - - false - - 2 - - - - - diff --git a/ground/gcs/src/share/qml/Cube.qml b/ground/gcs/src/share/qml/Cube.qml new file mode 100644 index 000000000..bb08a1b94 --- /dev/null +++ b/ground/gcs/src/share/qml/Cube.qml @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2016 The LibrePilot Project + * Contact: http://www.librepilot.org + * + * This file is part of LibrePilot GCS. + * + * LibrePilot GCS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LibrePilot GCS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LibrePilot GCS. If not, see . + */ +import QtQuick 2.4 + +import OsgQtQuick 1.0 + +Item { + OSGViewport { + anchors.fill: parent + focus: true + sceneData: cubeNode + camera: camera + + OSGCubeNode { + id: cubeNode + } + + OSGCamera { + id: camera + fieldOfView: 90 + } + } +} diff --git a/ground/gcs/src/share/qml/Earth.qml b/ground/gcs/src/share/qml/Earth.qml new file mode 100644 index 000000000..9ab53291d --- /dev/null +++ b/ground/gcs/src/share/qml/Earth.qml @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2016 The LibrePilot Project + * Contact: http://www.librepilot.org + * + * This file is part of LibrePilot GCS. + * + * LibrePilot GCS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LibrePilot GCS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LibrePilot GCS. If not, see . + */ +import QtQuick 2.4 +import QtQuick.Controls 1.4 + +import Pfd 1.0 +import OsgQtQuick 1.0 + +import "js/common.js" as Utils + +Item { + OSGViewport { + id: osgViewport + + anchors.fill: parent + focus: true + + sceneNode: skyNode + camera: camera + manipulator: earthManipulator + incrementalCompile: true + + OSGCamera { + id: camera + fieldOfView: 90 + } + + OSGEarthManipulator { + id: earthManipulator + } + + OSGSkyNode { + id: skyNode + sceneNode: terrainNode + viewport: osgViewport + dateTime: Utils.getDateTime() + minimumAmbientLight: pfdContext.minimumAmbientLight + } + + OSGFileNode { + id: terrainNode + source: pfdContext.terrainFile + async: false + } + + } + + BusyIndicator { + width: 24 + height: 24 + anchors.right: parent.right + anchors.top: parent.top + anchors.margins: 4 + + running: osgViewport.busy + } +} diff --git a/ground/gcs/src/share/qml/Model.qml b/ground/gcs/src/share/qml/Model.qml new file mode 100644 index 000000000..a31c91a3b --- /dev/null +++ b/ground/gcs/src/share/qml/Model.qml @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2016 The LibrePilot Project + * Contact: http://www.librepilot.org + * + * This file is part of LibrePilot GCS. + * + * LibrePilot GCS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LibrePilot GCS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LibrePilot GCS. If not, see . + */ +import QtQuick 2.4 + +import "model" + +ModelView { +} diff --git a/ground/gcs/src/share/qml/ModelTerrain.qml b/ground/gcs/src/share/qml/ModelTerrain.qml new file mode 100644 index 000000000..8ec9abc56 --- /dev/null +++ b/ground/gcs/src/share/qml/ModelTerrain.qml @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2016 The LibrePilot Project + * Contact: http://www.librepilot.org + * + * This file is part of LibrePilot GCS. + * + * LibrePilot GCS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LibrePilot GCS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LibrePilot GCS. If not, see . + */ +import QtQuick 2.4 + +import "model" + +ModelTerrainView { +} diff --git a/ground/gcs/src/share/qml/Pfd.qml b/ground/gcs/src/share/qml/Pfd.qml new file mode 100644 index 000000000..c7a004730 --- /dev/null +++ b/ground/gcs/src/share/qml/Pfd.qml @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2016 The LibrePilot Project + * Contact: http://www.librepilot.org + * + * This file is part of LibrePilot GCS. + * + * LibrePilot GCS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LibrePilot GCS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LibrePilot GCS. If not, see . + */ +import QtQuick 2.4 + +import "pfd" + +PfdView { + worldFile: "PfdSimpleWorld.qml" +} diff --git a/ground/gcs/src/share/qml/PfdTerrain.qml b/ground/gcs/src/share/qml/PfdTerrain.qml new file mode 100644 index 000000000..8c92bbeae --- /dev/null +++ b/ground/gcs/src/share/qml/PfdTerrain.qml @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2016 The LibrePilot Project + * Contact: http://www.librepilot.org + * + * This file is part of LibrePilot GCS. + * + * LibrePilot GCS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LibrePilot GCS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LibrePilot GCS. If not, see . + */ +import QtQuick 2.4 + +import "pfd" + +PfdView { + opaque: false + worldFile: "PfdTerrainWorld.qml" +} diff --git a/ground/gcs/src/share/qml/js/common.js b/ground/gcs/src/share/qml/js/common.js new file mode 100644 index 000000000..8fdacd345 --- /dev/null +++ b/ground/gcs/src/share/qml/js/common.js @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2016 The LibrePilot Project + * Contact: http://www.librepilot.org + * + * This file is part of LibrePilot GCS. + * + * LibrePilot GCS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LibrePilot GCS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LibrePilot GCS. If not, see . + */ + +// *********************** +// Common javascript utils +// *********************** + +// Get date +function getDateTime() { + switch(pfdContext.timeMode) { + case TimeMode.Local: + return new Date(); + case TimeMode.Predefined: + return pfdContext.dateTime; + } +} + +// Format time with two digits +function formatTime(time) { + if (time === 0) + return "00"; + if (time < 10) + return "0" + time; + else + return time.toString(); +} + +// Returns a formated time value +// In: 119 (seconds) +// Out: 00:01:59 +function formatFlightTime(timeValue) { + var timeHour = 0; + var timeMinutes = 0; + var timeSeconds = 0; + + if (timeValue > 0) { + timeHour = Math.floor(timeValue / 3600); + timeMinutes = Math.floor((timeValue - timeHour * 3600) / 60); + timeSeconds = Math.floor(timeValue - timeHour * 3600 - timeMinutes * 60); + } + + return formatTime(timeHour) + ":" + formatTime(timeMinutes) + ":" + formatTime(timeSeconds); +} + +// Returns a formated ETA +function estimatedTimeOfArrival(distance, velocity) { + var etaValue = 0; + var etaHour = 0; + var etaMinutes = 0; + var etaSeconds = 0; + + if ((distance > 0) && (velocity > 0)) { + etaValue = Math.round(distance/velocity); + } + + return formatFlightTime(etaValue); +} + diff --git a/ground/gcs/src/share/qml/js/uav.js b/ground/gcs/src/share/qml/js/uav.js new file mode 100644 index 000000000..b92ed926f --- /dev/null +++ b/ground/gcs/src/share/qml/js/uav.js @@ -0,0 +1,530 @@ +/* + * Copyright (C) 2016 The LibrePilot Project + * Contact: http://www.librepilot.org + * + * This file is part of LibrePilot GCS. + * + * LibrePilot GCS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LibrePilot GCS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LibrePilot GCS. If not, see . + */ + +// *************************** +// Common javascript uav utils +// *************************** + +// Settings +// +// Control +.import UAVTalk.VtolPathFollowerSettings 1.0 as VtolPathFollowerSettings + +// Navigation +.import UAVTalk.HomeLocation 1.0 as HomeLocation +.import UAVTalk.TakeOffLocation 1.0 as TakeOffLocation + +// Sensors +.import UAVTalk.AuxMagSettings 1.0 as AuxMagSettings +.import UAVTalk.FlightBatterySettings 1.0 as FlightBatterySettings + +// State +.import UAVTalk.RevoSettings 1.0 as RevoSettings + +// System +.import UAVTalk.HwSettings 1.0 as HwSettings +.import UAVTalk.SystemSettings 1.0 as SystemSettings + +// Data +// +// Control +.import UAVTalk.FlightStatus 1.0 as FlightStatus +.import UAVTalk.ManualControlCommand 1.0 as ManualControlCommand +.import UAVTalk.StabilizationDesired 1.0 as StabilizationDesired +.import UAVTalk.VelocityDesired 1.0 as VelocityDesired + +// Navigation +.import UAVTalk.PathDesired 1.0 as PathDesired +.import UAVTalk.WaypointActive 1.0 as WaypointActive + +// Sensors +.import UAVTalk.FlightBatteryState 1.0 as FlightBatteryState +.import UAVTalk.GPSPositionSensor 1.0 as GPSPositionSensor +.import UAVTalk.GPSSatellites 1.0 as GPSSatellites + +// State +.import UAVTalk.AttitudeState 1.0 as AttitudeState +.import UAVTalk.MagState 1.0 as MagState +.import UAVTalk.NedAccel 1.0 as NedAccel +.import UAVTalk.PositionState 1.0 as PositionState +.import UAVTalk.VelocityState 1.0 as VelocityState + +// System +.import UAVTalk.OPLinkStatus 1.0 as OPLinkStatus +.import UAVTalk.ReceiverStatus 1.0 as ReceiverStatus +.import UAVTalk.SystemAlarms 1.0 as SystemAlarms + +Qt.include("common.js") + +// End Import + + +/* + * State functions + * +*/ + +function attitude() { + return Qt.vector3d(attitudeState.roll, attitudeState.pitch, attitudeState.yaw); +} + +function attitudeRoll() { + return attitudeState.roll; +} + +function attitudePitch() { + return attitudeState.pitch; +} + +function attitudeYaw() { + return attitudeState.yaw; +} + +function currentVelocity() { + return Math.sqrt(Math.pow(velocityState.north, 2) + Math.pow(velocityState.east, 2)); +} + +function positionStateDown() { + return positionState.down; +} + +function velocityStateDown() { + return velocityState.down; +} + +function nedAccelDown() { + return nedAccel.down; +} + +function position() { + switch(gpsPositionSensor.status) { + case GPSPositionSensor.Status.Fix2D: + case GPSPositionSensor.Status.Fix3D: + return gpsPosition(); + case GPSPositionSensor.Status.NoFix: + case GPSPositionSensor.Status.NoGPS: + default: + return (homeLocation.set == HomeLocation.Set.True) ? homePosition() : defaultPosition(); + } +} + +function gpsPosition() { + return Qt.vector3d( + gpsPositionSensor.longitude / 10000000.0, + gpsPositionSensor.latitude / 10000000.0, + gpsPositionSensor.altitude); +} + +function homePosition() { + return Qt.vector3d( + homeLocation.longitude / 10000000.0, + homeLocation.latitude / 10000000.0, + homeLocation.altitude); +} + +function defaultPosition() { + return Qt.vector3d(pfdContext.longitude, pfdContext.latitude, pfdContext.altitude); +} + +/* + * System + * +*/ +function isCC3D() { + // Hack: detect Coptercontrol with mem free + return (freeMemoryBytes() < 3096); +} + +function frameType() { + var frameTypeText = ["FixedWing", "FixedWingElevon", "FixedWingVtail", "VTOL", "HeliCP", "QuadX", "QuadP", + "Hexa+", "Octo+", "Custom", "HexaX", "HexaH", "OctoV", "OctoCoaxP", "OctoCoaxX", "OctoX", "HexaCoax", + "Tricopter", "GroundVehicleCar", "GroundVehicleDiff", "GroundVehicleMoto"]; + + if (frameTypeText.length != SystemSettings.SystemSettingsConstants.AirframeTypeCount) { + console.log("uav.js: frameType() do not match systemSettings.airframeType uavo"); + return "FixMe" + } + return frameTypeText[systemSettings.airframeType] +} + +function isVtolOrMultirotor() { + return ((systemSettings.airframeType > SystemSettings.AirframeType.FixedWingVtail) && + (systemSettings.airframeType < SystemSettings.AirframeType.GroundVehicleCar)); +} + +function isFixedWing() { + return (systemSettings.airframeType <= SystemSettings.AirframeType.FixedWingVtail); +} + +function isGroundVehicle() { + return (systemSettings.airframeType >= SystemSettings.AirframeType.GroundVehicleCar); +} + +function freeMemoryBytes() { + return systemStats.heapRemaining; +} + +function freeMemoryKBytes() { + return (systemStats.heapRemaining / 1024).toFixed(2); +} + +function freeMemory() { + return (freeMemoryBytes() > 1024) ? freeMemoryKBytes() + "Kb" : freeMemoryBytes() + "bytes"; +} + +function cpuLoad() { + return systemStats.cpuLoad; +} + +function cpuTemp() { + return systemStats.cpuTemp; +} + +function flightTimeValue() { + return Math.round(systemStats.flightTime / 1000) +} + +/* + * Sensors + * +*/ +function isAttitudeValid() { + return (systemAlarms.alarmAttitude == SystemAlarms.Alarm.OK); +} + +function isAttitudeNotInitialised() { + return (systemAlarms.alarmAttitude == SystemAlarms.Alarm.Uninitialised); +} + +function isGpsValid() { + return (systemAlarms.alarmGPS == SystemAlarms.Alarm.OK); +} + +function isGpsNotInitialised() { + return (systemAlarms.alarmGPS == SystemAlarms.Alarm.Uninitialised); +} + +function isGpsStatusFix3D() { + return (gpsPositionSensor.status == GPSPositionSensor.Status.Fix3D); +} + +function isOplmConnected() { + return (opLinkStatus.linkState == OPLinkStatus.LinkState.Connected); +} + +function magSourceName() { + var auxMagTypeText = ["GPSv9", "Flexi", "I2C", "DJI"]; + var magStateSourceText = ["Invalid", "OnBoard", "ExtMag"]; + + if ((auxMagTypeText.length != AuxMagSettings.AuxMagSettingsConstants.TypeCount) || + (magStateSourceText.length != MagState.MagStateConstants.SourceCount)) { + console.log("uav.js: magSourceName() do not match magState.source or auxMagSettings.type uavo"); + return "FixMe" + } + return [magState.source == MagState.Source.Aux ? auxMagTypeText[auxMagSettings.type] + " " : ""] + magStateSourceText[magState.source]; +} + +function gpsSensorType() { + var gpsSensorTypeText = ["Unknown", "NMEA", "UBX", "UBX7", "UBX8", "DJI"]; + + if (gpsSensorTypeText.length != GPSPositionSensor.GPSPositionSensorConstants.SensorTypeCount) { + console.log("uav.js: gpsSensorType() do not match gpsPositionSensor.sensorType uavo"); + return "FixMe" + } + return gpsSensorTypeText[gpsPositionSensor.sensorType]; +} + +function gpsNumSat() { + return gpsPositionSensor.satellites; +} + +function gpsSatsInView() { + return gpsSatellites.satsInView; +} + +function gpsHdopInfo() { + return gpsPositionSensor.hdop.toFixed(2) + "/" + gpsPositionSensor.vdop.toFixed(2) + "/" + gpsPositionSensor.pdop.toFixed(2); +} + +function gpsAltitude() { + return gpsPositionSensor.altitude.toFixed(2); +} + +function gpsStatus() { + var gpsStatusText = ["NO GPS", "NO FIX", "2D", "3D"]; + + if (gpsStatusText.length != GPSPositionSensor.GPSPositionSensorConstants.StatusCount) { + console.log("uav.js: gpsStatus() do not match gpsPositionSensor.status uavo"); + return "FixMe" + } + return gpsStatusText[gpsPositionSensor.status]; +} + +function fusionAlgorithm() { + var fusionAlgorithmText = ["None", "Basic (No Nav)", "CompMag", "Comp+Mag+GPS", "EKFIndoor", "GPSNav (INS13)"]; + + if (fusionAlgorithmText.length != RevoSettings.RevoSettingsConstants.FusionAlgorithmCount) { + console.log("uav.js: fusionAlgorithm() do not match revoSettings.fusionAlgorithm uavo"); + return "FixMe" + } + return fusionAlgorithmText[revoSettings.fusionAlgorithm]; +} + +function receiverQuality() { + return (receiverStatus.quality > 0) ? receiverStatus.quality + "%" : "?? %"; +} + +function oplmLinkState() { + var oplmLinkStateText = ["Disabled", "Enabled", "Binding", "Bound", "Disconnected", "Connecting", "Connected"]; + + if (oplmLinkStateText.length != OPLinkStatus.OPLinkStatusConstants.LinkStateCount) { + console.log("uav.js: oplmLinkState() do not match opLinkStatus.linkState uavo"); + return "FixMe" + } + return oplmLinkStateText[opLinkStatus.linkState]; +} + +/* + * Battery + * +*/ +function batteryModuleEnabled() { + return (hwSettings.optionalModulesBattery == HwSettings.OptionalModules.Enabled); +} + +function batteryNbCells() { + return flightBatterySettings.nbCells; +} + +function batteryVoltage() { + return flightBatteryState.voltage.toFixed(2); +} + +function batteryCurrent() { + return flightBatteryState.current.toFixed(2); +} + +function batteryConsumedEnergy() { + return flightBatteryState.consumedEnergy.toFixed(0); +} + +function estimatedFlightTimeValue() { + return Math.round(flightBatteryState.estimatedFlightTime); +} + +function batteryAlarmColor() { + // Uninitialised, Ok, Warning, Critical, Error + return ["#2c2929", "green", "orange", "red", "red"][systemAlarms.alarmBattery]; +} + +function estimatedTimeAlarmColor() { + return ((estimatedFlightTimeValue() <= 120) && (estimatedFlightTimeValue() > 60)) ? "orange" : + (estimatedFlightTimeValue() <= 60) ? "red" : batteryAlarmColor(); +} + +/* + * Pathplan and Waypoints + * +*/ +function isPathPlanEnabled() { + return (flightStatus.flightMode == FlightStatus.FlightMode.PathPlanner); +} + +function isPathPlanValid() { + return (systemAlarms.alarmPathPlan == SystemAlarms.Alarm.OK); +} + +function isPathDesiredActive() { + return ((pathDesired.endEast != 0.0) || (pathDesired.endNorth != 0.0) || (pathDesired.endingVelocity != 0.0)) +} + +function isTakeOffLocationValid() { + return (takeOffLocation.status == TakeOffLocation.Status.Valid); +} + +function pathModeDesired() { + var pathModeDesiredText = ["GOTO ENDPOINT","FOLLOW VECTOR","CIRCLE RIGHT","CIRCLE LEFT","FIXED ATTITUDE", + "SET ACCESSORY","DISARM ALARM","LAND","BRAKE","VELOCITY","AUTO TAKEOFF"]; + + if (pathModeDesiredText.length != PathDesired.PathDesiredConstants.ModeCount) { + console.log("uav.js: pathModeDesired() do not match pathDesired.mode uavo"); + return "FixMe" + } + return pathModeDesiredText[pathDesired.mode]; +} + +function velocityDesiredDown() { + return velocityDesired.down; +} + +function pathDesiredEndDown() { + return pathDesired.endDown; +} + +function pathDesiredEndingVelocity() { + return pathDesired.endingVelocity; +} + +function currentWaypointActive() { + return (waypointActive.index + 1); +} + +function waypointCount() { + return pathPlan.waypointCount; +} + +function homeHeading() { + return 180 / 3.1415 * Math.atan2(takeOffLocation.east - positionState.east, takeOffLocation.north - positionState.north); +} + +function waypointHeading() { + return 180 / 3.1415 * Math.atan2(pathDesired.endEast - positionState.east, pathDesired.endNorth - positionState.north); +} + +function homeDistance() { + return Math.sqrt(Math.pow((takeOffLocation.east - positionState.east), 2) + + Math.pow((takeOffLocation.north - positionState.north), 2)); +} + +function waypointDistance() { + return Math.sqrt(Math.pow((pathDesired.endEast - positionState.east), 2) + + Math.pow((pathDesired.endNorth - positionState.north), 2)); +} + +/* + * FlightModes, Stabilization, Thrust modes + * +*/ +function isFlightModeManual() { + return (flightStatus.flightMode == FlightStatus.FlightMode.Manual); +} + +function isFlightModeAssisted() { + return (flightStatus.flightMode > FlightStatus.FlightMode.Stabilized6); +} + +function isVtolPathFollowerSettingsThrustAuto() { + return (vtolPathFollowerSettings.thrustControl == VtolPathFollowerSettings.ThrustControl.Auto); +} + +function flightModeName() { + var flightModeNameText = ["MANUAL", "STAB 1", "STAB 2", "STAB 3", "STAB 4", "STAB 5", "STAB 6", + "POS HOLD", "COURSELOCK", "VEL ROAM", "HOME LEASH", "ABS POS", "RTB", + "LAND", "PATHPLAN", "POI", "AUTOCRUISE", "AUTOTAKEOFF", "AUTOTUNE"]; + + if (flightModeNameText.length != FlightStatus.FlightStatusConstants.FlightModeCount) { + console.log("uav.js: flightModeName() do not match flightStatus.flightMode uavo"); + return "FixMe" + } + return flightModeNameText[flightStatus.flightMode]; +} + +function flightModeColor() { + var flightModeColorText = ["gray", "green", "green", "green", "green", "green", "green", + "cyan", "cyan", "cyan", "cyan", "cyan", "cyan", + "cyan", "cyan", "cyan", "cyan", "cyan", "cyan"]; + + if (flightModeColorText.length != FlightStatus.FlightStatusConstants.FlightModeCount) { + console.log("uav.js: flightModeColor() do not match flightStatus.flightMode uavo"); + return "gray" + } + return flightModeColorText[flightStatus.flightMode]; +} + +function thrustMode() { + return !isFlightModeAssisted() ? stabilizationDesired.stabilizationModeThrust : + (isFlightModeAssisted() && isVtolOrMultirotor() && isVtolPathFollowerSettingsThrustAuto()) ? + StabilizationDesired.StabilizationDesiredConstants.StabilizationModeCount : (isFlightModeAssisted() && isFixedWing()) ? + StabilizationDesired.StabilizationDesiredConstants.StabilizationModeCount : 0; +} + +function thrustModeName() { + // Lower case modes are never displayed/used for Thrust + var thrustModeNameText = ["MANUAL", "rate", "ratetrainer", "attitude", "axislock", "weakleveling", "virtualbar", "acro+ ", "rattitude", + "ALT HOLD", "ALT VARIO", "CRUISECTRL", "systemident"]; + + // Last "Auto" Thrust mode is added to current UAVO enum list for display. + thrustModeNameText.push("AUTO"); + + if (thrustModeNameText.length != StabilizationDesired.StabilizationDesiredConstants.StabilizationModeCount + 1) { + console.log("uav.js: thrustModeName() do not match stabilizationDesired.StabilizationMode uavo"); + return "FixMe" + } + return thrustModeNameText[thrustMode()]; +} + +function thrustModeColor() { + var thrustModeColorText = ["green", "grey", "grey", "grey", "grey", "grey", "grey", "grey", "grey", + "green", "green", "green", "grey"]; + + // Add the cyan color for AUTO + thrustModeColorText.push("cyan"); + + if (thrustModeColorText.length != StabilizationDesired.StabilizationDesiredConstants.StabilizationModeCount + 1) { + console.log("uav.js: thrustModeColor() do not match stabilizationDesired.StabilizationMode uavo"); + return "gray" + } + return thrustModeColorText[thrustMode()]; +} + +function armStatusName() { + var armStatusNameText = ["DISARMED","ARMING","ARMED"]; + + if (armStatusNameText.length != FlightStatus.FlightStatusConstants.ArmedCount) { + console.log("uav.js: armStatusName() do not match flightStatus.armed uavo"); + return "FixMe" + } + return armStatusNameText[flightStatus.armed]; +} + +function armStatusColor() { + var armStatusColorText = ["gray", "orange", "green"]; + + if (armStatusColorText.length != FlightStatus.FlightStatusConstants.ArmedCount) { + console.log("uav.js: armStatusColor() do not match flightStatus.armed uavo"); + return "gray" + } + return armStatusColorText[flightStatus.armed]; +} + +/* + * Alarms + * +*/ +function autopilotStatusColor() { + return statusColor(systemAlarms.alarmGuidance) +} + +function rcInputStatusColor() { + return statusColor(systemAlarms.alarmManualControl) +} + +function statusColor(module) { + return ["gray", "green", "red", "red", "red"][module]; +} + +function masterCautionWarning() { + return ((systemAlarms.alarmBootFault > SystemAlarms.Alarm.OK) || + (systemAlarms.alarmOutOfMemory > SystemAlarms.Alarm.OK) || + (systemAlarms.alarmStackOverflow > SystemAlarms.Alarm.OK) || + (systemAlarms.alarmCPUOverload > SystemAlarms.Alarm.OK) || + (systemAlarms.alarmEventSystem > SystemAlarms.Alarm.OK)) +} + diff --git a/ground/gcs/src/share/qml/model/ModelTerrainView.qml b/ground/gcs/src/share/qml/model/ModelTerrainView.qml new file mode 100644 index 000000000..2f5a12410 --- /dev/null +++ b/ground/gcs/src/share/qml/model/ModelTerrainView.qml @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2016 The LibrePilot Project + * Contact: http://www.librepilot.org + * + * This file is part of LibrePilot GCS. + * + * LibrePilot GCS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LibrePilot GCS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LibrePilot GCS. If not, see . + */ +import QtQuick 2.4 +import QtQuick.Controls 1.4 + +import Pfd 1.0 +import OsgQtQuick 1.0 + +import "../js/common.js" as Utils +import "../js/uav.js" as UAV + +Item { + OSGViewport { + id: osgViewport + + anchors.fill: parent + focus: true + + sceneNode: skyNode + camera: camera + manipulator: nodeTrackerManipulator + //incrementalCompile: true + + OSGCamera { + id: camera + fieldOfView: 90 + logarithmicDepthBuffer: true + } + + OSGNodeTrackerManipulator { + id: nodeTrackerManipulator + // use model to compute camera home position + sceneNode: modelTransformNode + // model will be tracked + trackNode: modelTransformNode + } + + OSGSkyNode { + id: skyNode + sceneNode: sceneGroup + viewport: osgViewport + dateTime: Utils.getDateTime() + minimumAmbientLight: pfdContext.minimumAmbientLight + } + + OSGGroup { + id: sceneGroup + children: [ terrainFileNode, modelNode ] + } + + OSGGeoTransformNode { + id: modelNode + + sceneNode: terrainFileNode + children: [ modelTransformNode ] + + clampToTerrain: true + + position: UAV.position() + } + + OSGTransformNode { + id: modelTransformNode + + children: [ modelFileNode ] + + // model dimensions are in mm, scale to meters + scale: Qt.vector3d(0.001, 0.001, 0.001) + attitude: UAV.attitude() + } + + OSGFileNode { + id: terrainFileNode + source: pfdContext.terrainFile + } + + OSGFileNode { + id: modelFileNode + + // use ShaderGen pseudoloader to generate the shaders expected by osgEarth + // see http://docs.osgearth.org/en/latest/faq.html#i-added-a-node-but-it-has-no-texture-lighting-etc-in-osgearth-why + source: pfdContext.modelFile + ".osgearth_shadergen" + + optimizeMode: OptimizeMode.OptimizeAndCheck + } + + Keys.onUpPressed: { + pfdContext.nextModel(); + } + + Keys.onDownPressed: { + pfdContext.previousModel(); + } + + BusyIndicator { + width: 24 + height: 24 + anchors.right: parent.right + anchors.top: parent.top + anchors.margins: 4 + + running: osgViewport.busy + } + + } +} diff --git a/ground/gcs/src/share/qml/model/ModelView.qml b/ground/gcs/src/share/qml/model/ModelView.qml new file mode 100644 index 000000000..4dbf9566a --- /dev/null +++ b/ground/gcs/src/share/qml/model/ModelView.qml @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2016 The LibrePilot Project + * Contact: http://www.librepilot.org + * + * This file is part of LibrePilot GCS. + * + * LibrePilot GCS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LibrePilot GCS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LibrePilot GCS. If not, see . + */ +import QtQuick 2.4 + +import OsgQtQuick 1.0 + +import "../js/uav.js" as UAV + +Item { + + OSGViewport { + anchors.fill: parent + focus: true + + sceneNode: sceneNode + camera: camera + manipulator: trackballManipulator + + OSGCamera { + id: camera + fieldOfView: 90 + } + + OSGTrackballManipulator { + id: trackballManipulator + sceneNode: transformNode + } + + OSGGroup { + id: sceneNode + children: [ transformNode, backgroundNode ] + } + + OSGBillboardNode { + id: backgroundNode + children: [ backgroundImageNode ] + } + + OSGImageNode { + id: backgroundImageNode + imageFile: pfdContext.backgroundImageFile + } + + OSGTransformNode { + id: transformNode + + children: [ fileNode ] + + attitude: UAV.attitude() + } + + OSGFileNode { + id: fileNode + source: pfdContext.modelFile + async: false + optimizeMode: OptimizeMode.OptimizeAndCheck + } + + Keys.onUpPressed: { + pfdContext.nextModel(); + } + + Keys.onDownPressed: { + pfdContext.previousModel(); + } + } + +} diff --git a/ground/gcs/src/share/pfd/default/AltitudeScale.qml b/ground/gcs/src/share/qml/pfd/AltitudeScale.qml similarity index 69% rename from ground/gcs/src/share/pfd/default/AltitudeScale.qml rename to ground/gcs/src/share/qml/pfd/AltitudeScale.qml index 35a57dba8..8a38935af 100644 --- a/ground/gcs/src/share/pfd/default/AltitudeScale.qml +++ b/ground/gcs/src/share/qml/pfd/AltitudeScale.qml @@ -1,10 +1,32 @@ -import QtQuick 2.0 +/* + * Copyright (C) 2016 The LibrePilot Project + * Contact: http://www.librepilot.org + * + * This file is part of LibrePilot GCS. + * + * LibrePilot GCS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LibrePilot GCS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LibrePilot GCS. If not, see . + */ +import QtQuick 2.4 + +import "../js/common.js" as Utils +import "../js/uav.js" as UAV Item { id: sceneItem property variant sceneSize - property real altitude : -qmlWidget.altitudeFactor * PositionState.Down + property real altitude : -pfdContext.altitudeFactor * UAV.positionStateDown() SvgElementImage { id: altitude_window @@ -12,9 +34,9 @@ Item { sceneSize: sceneItem.sceneSize clip: true - visible: qmlWidget.altitudeUnit != 0 + visible: pfdContext.altitudeUnit != 0 - property variant scaledBounds: svgRenderer.scaledElementBounds("pfd.svg", "altitude-window") + property variant scaledBounds: svgRenderer.scaledElementBounds("pfd/pfd.svg", "altitude-window") x: Math.floor(scaledBounds.x * sceneItem.width) y: Math.floor(scaledBounds.y * sceneItem.height) @@ -60,7 +82,7 @@ Item { elementName: "altitude-vector" sceneSize: sceneItem.sceneSize - height: -NedAccel.Down * altitude_scale.height/10 + height: -UAV.nedAccelDown() * altitude_scale.height / 10 anchors.left: parent.left anchors.bottom: parent.verticalCenter @@ -70,12 +92,13 @@ Item { id: altitude_waypoint elementName: "altitude-waypoint" sceneSize: sceneItem.sceneSize - visible: PathDesired.End_Down !== 0.0 + visible: (UAV.isFlightModeAssisted() && (UAV.pathDesiredEndDown() != 0.0)) anchors.left: parent.left anchors.verticalCenter: parent.verticalCenter - anchors.verticalCenterOffset: -altitude_scale.height/10 * (PositionState.Down - PathDesired.End_Down) * qmlWidget.altitudeFactor + anchors.verticalCenterOffset: -altitude_scale.height / 10 * + (UAV.positionStateDown() - UAV.pathDesiredEndDown()) * pfdContext.altitudeFactor } } @@ -83,12 +106,12 @@ Item { id: altitude_box clip: true - visible: qmlWidget.altitudeUnit != 0 + visible: pfdContext.altitudeUnit != 0 elementName: "altitude-box" sceneSize: sceneItem.sceneSize - property variant scaledBounds: svgRenderer.scaledElementBounds("pfd.svg", "altitude-box") + property variant scaledBounds: svgRenderer.scaledElementBounds("pfd/pfd.svg", "altitude-box") x: scaledBounds.x * sceneItem.width y: scaledBounds.y * sceneItem.height @@ -97,7 +120,7 @@ Item { Text { id: altitude_text - text: " " +altitude.toFixed(1) + text: " " + altitude.toFixed(1) color: "white" font { family: pt_bold.name @@ -113,7 +136,7 @@ Item { elementName: "altitude-unit-box" sceneSize: sceneItem.sceneSize - visible: qmlWidget.altitudeUnit != 0 + visible: pfdContext.altitudeUnit != 0 anchors.top: altitude_window.bottom anchors.right: altitude_window.right @@ -122,7 +145,7 @@ Item { Text { id: altitude_unit_text - text: qmlWidget.altitudeUnit + text: pfdContext.altitudeUnit color: "cyan" font { family: pt_bold.name diff --git a/ground/gcs/src/share/pfd/default/Compass.qml b/ground/gcs/src/share/qml/pfd/Compass.qml similarity index 62% rename from ground/gcs/src/share/pfd/default/Compass.qml rename to ground/gcs/src/share/qml/pfd/Compass.qml index 2340c74f5..81dec7daf 100644 --- a/ground/gcs/src/share/pfd/default/Compass.qml +++ b/ground/gcs/src/share/qml/pfd/Compass.qml @@ -1,5 +1,25 @@ -import QtQuick 2.0 -import "." +/* + * Copyright (C) 2016 The LibrePilot Project + * Contact: http://www.librepilot.org + * + * This file is part of LibrePilot GCS. + * + * LibrePilot GCS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LibrePilot GCS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LibrePilot GCS. If not, see . + */ +import QtQuick 2.4 + +import "../js/uav.js" as UAV Item { id: sceneItem @@ -27,14 +47,13 @@ Item { id: compass_wheel elementName: "compass-wheel" sceneSize: sceneItem.sceneSize + smooth: true x: Math.floor(scaledBounds.x * sceneItem.width) y: Math.floor(scaledBounds.y * sceneItem.height) - rotation: -AttitudeState.Yaw + rotation: -UAV.attitudeYaw() transformOrigin: Item.Center - - smooth: true } SvgElementImage { @@ -46,37 +65,31 @@ Item { x: Math.floor(scaledBounds.x * sceneItem.width) y: Math.floor(scaledBounds.y * sceneItem.height) - property real home_degrees: 180/3.1415 * Math.atan2(TakeOffLocation.East - PositionState.East, TakeOffLocation.North - PositionState.North) - - rotation: -AttitudeState.Yaw + home_degrees + rotation: -UAV.attitudeYaw() + UAV.homeHeading() transformOrigin: Item.Bottom - visible: TakeOffLocation.Status == 0 + visible: UAV.isTakeOffLocationValid() } SvgElementImage { id: compass_waypoint // Double Purple arrow elementName: "compass-waypoint" sceneSize: sceneItem.sceneSize + smooth: true x: Math.floor(scaledBounds.x * sceneItem.width) y: Math.floor(scaledBounds.y * sceneItem.height) - property real course_degrees: 180/3.1415 * Math.atan2(PathDesired.End_East - PositionState.East, PathDesired.End_North - PositionState.North) - - rotation: -AttitudeState.Yaw + course_degrees + rotation: -UAV.attitudeYaw() + UAV.waypointHeading() transformOrigin: Item.Center - smooth: true - visible: PathDesired.End_East !== 0.0 && PathDesired.End_East !== 0.0 + visible: (UAV.isFlightModeAssisted() && UAV.isPathDesiredActive()) } - - Item { id: compass_text_box - property variant scaledBounds: svgRenderer.scaledElementBounds("pfd.svg", "compass-text") + property variant scaledBounds: svgRenderer.scaledElementBounds("pfd/pfd.svg", "compass-text") x: scaledBounds.x * sceneItem.width y: scaledBounds.y * sceneItem.height @@ -85,7 +98,7 @@ Item { Text { id: compass_text - text: Math.floor(AttitudeState.Yaw).toFixed() + text: Math.floor(UAV.attitudeYaw()).toFixed() color: "white" font { family: pt_bold.name diff --git a/ground/gcs/src/share/pfd/default/HorizontCenter.qml b/ground/gcs/src/share/qml/pfd/HorizontCenter.qml similarity index 52% rename from ground/gcs/src/share/pfd/default/HorizontCenter.qml rename to ground/gcs/src/share/qml/pfd/HorizontCenter.qml index 6dee7b633..ad83f0ca1 100644 --- a/ground/gcs/src/share/pfd/default/HorizontCenter.qml +++ b/ground/gcs/src/share/qml/pfd/HorizontCenter.qml @@ -1,4 +1,23 @@ -import QtQuick 2.0 +/* + * Copyright (C) 2016 The LibrePilot Project + * Contact: http://www.librepilot.org + * + * This file is part of LibrePilot GCS. + * + * LibrePilot GCS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LibrePilot GCS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LibrePilot GCS. If not, see . + */ +import QtQuick 2.4 Item { id: sceneItem diff --git a/ground/gcs/src/share/pfd/default/Info.qml b/ground/gcs/src/share/qml/pfd/Info.qml similarity index 68% rename from ground/gcs/src/share/pfd/default/Info.qml rename to ground/gcs/src/share/qml/pfd/Info.qml index 2bf543903..0a0fb911e 100644 --- a/ground/gcs/src/share/pfd/default/Info.qml +++ b/ground/gcs/src/share/qml/pfd/Info.qml @@ -1,12 +1,31 @@ -import QtQuick 2.0 +/* + * Copyright (C) 2016 The LibrePilot Project + * Contact: http://www.librepilot.org + * + * This file is part of LibrePilot GCS. + * + * LibrePilot GCS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LibrePilot GCS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LibrePilot GCS. If not, see . + */ +import QtQuick 2.4 + +import "../js/common.js" as Utils +import "../js/uav.js" as UAV Item { id: info property variant sceneSize - // Uninitialised, Ok, Warning, Critical, Error - property variant batColors : ["black", "green", "orange", "red", "red"] - // // Waypoint functions // @@ -18,38 +37,14 @@ Item { property bool init_dist: false - property real home_heading: 180/3.1415 * Math.atan2(TakeOffLocation.East - PositionState.East, - TakeOffLocation.North - PositionState.North) - - property real home_distance: Math.sqrt(Math.pow((TakeOffLocation.East - PositionState.East),2) + - Math.pow((TakeOffLocation.North - PositionState.North),2)) - - property real wp_heading: 180/3.1415 * Math.atan2(PathDesired.End_East - PositionState.East, - PathDesired.End_North - PositionState.North) - - property real wp_distance: Math.sqrt(Math.pow((PathDesired.End_East - PositionState.East),2) + - Math.pow(( PathDesired.End_North - PositionState.North),2)) - - property real current_velocity: Math.sqrt(Math.pow(VelocityState.North,2)+Math.pow(VelocityState.East,2)) - - property real home_eta: (home_distance > 0 && current_velocity > 0 ? Math.round(home_distance/current_velocity) : 0) - property real home_eta_h: (home_eta > 0 ? Math.floor(home_eta / 3600) : 0 ) - property real home_eta_m: (home_eta > 0 ? Math.floor((home_eta - home_eta_h*3600)/60) : 0) - property real home_eta_s: (home_eta > 0 ? Math.floor(home_eta - home_eta_h*3600 - home_eta_m*60) : 0) - - property real wp_eta: (wp_distance > 0 && current_velocity > 0 ? Math.round(wp_distance/current_velocity) : 0) - property real wp_eta_h: (wp_eta > 0 ? Math.floor(wp_eta / 3600) : 0 ) - property real wp_eta_m: (wp_eta > 0 ? Math.floor((wp_eta - wp_eta_h*3600)/60) : 0) - property real wp_eta_s: (wp_eta > 0 ? Math.floor(wp_eta - wp_eta_h*3600 - wp_eta_m*60) : 0) - function reset_distance() { total_distance = 0; } function compute_distance(posEast,posNorth) { if (total_distance == 0 && !init_dist) { init_dist = "true"; posEast_old = posEast; posNorth_old = posNorth; } - if (posEast > posEast_old+3 || posEast < posEast_old-3 || posNorth > posNorth_old+3 || posNorth < posNorth_old-3) { - total_distance += Math.sqrt(Math.pow((posEast - posEast_old ),2) + Math.pow((posNorth - posNorth_old),2)); + if (posEast > posEast_old+3 || posEast < posEast_old - 3 || posNorth > posNorth_old + 3 || posNorth < posNorth_old - 3) { + total_distance += Math.sqrt(Math.pow((posEast - posEast_old ), 2) + Math.pow((posNorth - posNorth_old), 2)); total_distance_km = total_distance / 1000; posEast_old = posEast; @@ -58,15 +53,6 @@ Item { } } - function formatTime(time) { - if (time === 0) - return "00" - if (time < 10) - return "0" + time; - else - return time.toString(); - } - // End Functions // // Start Drawing @@ -76,7 +62,7 @@ Item { sceneSize: info.sceneSize elementName: "info-bg" width: parent.width - opacity: qmlWidget.terrainEnabled ? 0.3 : 1 + opacity: opaque ? 1 : 0.3 } // @@ -84,16 +70,13 @@ Item { // property real bar_width: (info_bg.height + info_bg.width) / 110 - property int satsInView: String(GPSSatellites.SatsInView).charCodeAt(0) - property variant gps_tooltip: "Altitude : "+GPSPositionSensor.Altitude.toFixed(2) +"m\n"+ - "H/V/P DOP : "+GPSPositionSensor.HDOP.toFixed(2)+"/"+GPSPositionSensor.VDOP.toFixed(2)+"/"+GPSPositionSensor.PDOP.toFixed(2)+"m\n"+ - satsInView+" Sats in view" + + property variant gps_tooltip: "Altitude : " + UAV.gpsAltitude() + "m\n" + + "H/V/P DOP : " + UAV.gpsHdopInfo() + + [UAV.gpsSensorType() == "DJI" ? "" : "\n" + UAV.gpsSatsInView() + " Sats in view"] Repeater { id: satNumberBar - //smooth: true - // hack, qml/js treats qint8 as a char, necessary to convert it back to integer value - property int satNumber : String(GPSPositionSensor.Satellites).charCodeAt(0) model: 13 Rectangle { @@ -105,11 +88,11 @@ Item { text: gps_tooltip } - x: Math.round((bar_width*4.5) + (bar_width * 1.6 * index)) + x: Math.round((bar_width * 4.5) + (bar_width * 1.6 * index)) height: bar_width * index * 0.6 - y: (bar_width*8) - height + y: (bar_width * 8) - height color: "green" - opacity: satNumberBar.satNumber >= minSatNumber ? 1 : 0.4 + opacity: UAV.gpsNumSat() >= minSatNumber ? 1 : 0.4 } } @@ -122,10 +105,7 @@ Item { } Text { - property int satNumber : String(GPSPositionSensor.Satellites).charCodeAt(0) - - text: [satNumber > 5 ? " " + satNumber.toString() + " sats - " : ""] + - ["NO GPS", "NO FIX", "2D", "3D"][GPSPositionSensor.Status] + text: [UAV.gpsNumSat() > 5 ? " " + UAV.gpsNumSat().toString() + " sats - " : ""] + UAV.gpsStatus() anchors.centerIn: parent font.pixelSize: parent.height*1.3 font.family: pt_bold.name @@ -154,7 +134,7 @@ Item { width: scaledBounds.width * sceneItem.width height: scaledBounds.height * sceneItem.height y: Math.floor(scaledBounds.y * sceneItem.height) - visible: SystemAlarms.Alarm_PathPlan == 1 + visible: UAV.isPathPlanEnabled() } SvgElementPositionItem { @@ -163,10 +143,10 @@ Item { width: scaledBounds.width * sceneItem.width height: scaledBounds.height * sceneItem.height y: Math.floor(scaledBounds.y * sceneItem.height) - visible: SystemAlarms.Alarm_PathPlan == 1 + visible: UAV.isPathPlanEnabled() Text { - text: " "+wp_heading.toFixed(1)+"°" + text: UAV.isPathPlanValid() ? " " + UAV.waypointHeading().toFixed(1) + "°" : " 0°" anchors.centerIn: parent color: "cyan" @@ -184,10 +164,10 @@ Item { width: scaledBounds.width * sceneItem.width height: scaledBounds.height * sceneItem.height y: Math.floor(scaledBounds.y * sceneItem.height) - visible: SystemAlarms.Alarm_PathPlan == 1 + visible: UAV.isPathPlanEnabled() Text { - text: " "+wp_distance.toFixed(0)+" m" + text: UAV.isPathPlanValid() ? " " + UAV.waypointDistance().toFixed(0) + " m" : " 0 m" anchors.centerIn: parent color: "cyan" @@ -205,7 +185,7 @@ Item { width: scaledBounds.width * sceneItem.width height: scaledBounds.height * sceneItem.height y: Math.floor(scaledBounds.y * sceneItem.height) - visible: SystemAlarms.Alarm_PathPlan == 1 + visible: UAV.isPathPlanEnabled() MouseArea { id: total_dist_mouseArea; anchors.fill: parent; cursorShape: Qt.PointingHandCursor; onClicked: reset_distance()} @@ -223,7 +203,7 @@ Item { Timer { interval: 1000; running: true; repeat: true; - onTriggered: {if (GPSPositionSensor.Status == 3) compute_distance(PositionState.East,PositionState.North)} + onTriggered: { if (UAV.isGpsStatusFix3D()) compute_distance(positionState.east, positionState.north) } } } @@ -233,10 +213,10 @@ Item { width: scaledBounds.width * sceneItem.width height: scaledBounds.height * sceneItem.height y: Math.floor(scaledBounds.y * sceneItem.height) - visible: SystemAlarms.Alarm_PathPlan == 1 + visible: UAV.isPathPlanEnabled() Text { - text: formatTime(wp_eta_h) + ":" + formatTime(wp_eta_m) + ":" + formatTime(wp_eta_s) + text: UAV.isPathPlanValid() ? Utils.estimatedTimeOfArrival(UAV.waypointDistance(), UAV.currentVelocity()) : "00:00:00" anchors.centerIn: parent color: "cyan" @@ -254,10 +234,10 @@ Item { width: scaledBounds.width * sceneItem.width height: scaledBounds.height * sceneItem.height y: Math.floor(scaledBounds.y * sceneItem.height) - visible: SystemAlarms.Alarm_PathPlan == 1 + visible: UAV.isPathPlanEnabled() Text { - text: (WaypointActive.Index+1)+" / "+PathPlan.WaypointCount + text: UAV.isPathPlanValid() ? UAV.currentWaypointActive() + " / " + UAV.waypointCount() : "0 / 0" anchors.centerIn: parent color: "cyan" @@ -275,10 +255,10 @@ Item { width: scaledBounds.width * sceneItem.width height: scaledBounds.height * sceneItem.height y: Math.floor(scaledBounds.y * sceneItem.height) - visible: SystemAlarms.Alarm_PathPlan == 1 + visible: UAV.isPathPlanEnabled() Text { - text: ["GOTO ENDPOINT","FOLLOW VECTOR","CIRCLE RIGHT","CIRCLE LEFT","FIXED ATTITUDE","SET ACCESSORY","DISARM ALARM","LAND","BRAKE","VELOCITY","AUTO TAKEOFF"][PathDesired.Mode] + text: UAV.isPathPlanValid() ? UAV.pathModeDesired() : "" anchors.centerIn: parent color: "cyan" @@ -301,11 +281,11 @@ Item { width: scaledBounds.width * sceneItem.width height: scaledBounds.height * sceneItem.height y: scaledBounds.y * sceneItem.height - visible: (SystemAlarms.Alarm_PathPlan != 1) && (HwSettings.OptionalModules_Battery == 1) + visible: (!UAV.isPathPlanEnabled() && UAV.batteryModuleEnabled()) Rectangle { anchors.fill: parent - color: FlightBatterySettings.NbCells > 0 ? info.batColors[SystemAlarms.Alarm_Battery] : "black" + color: (UAV.batteryNbCells() > 0) ? UAV.batteryAlarmColor() : "black" } } @@ -316,7 +296,7 @@ Item { width: scaledBounds.width * sceneItem.width height: scaledBounds.height * sceneItem.height y: Math.floor(scaledBounds.y * sceneItem.height) - visible: (SystemAlarms.Alarm_PathPlan != 1) && (HwSettings.OptionalModules_Battery == 1) + visible: (!UAV.isPathPlanEnabled() && UAV.batteryModuleEnabled()) } SvgElementPositionItem { @@ -327,14 +307,14 @@ Item { width: scaledBounds.width * sceneItem.width height: scaledBounds.height * sceneItem.height y: scaledBounds.y * sceneItem.height - visible: (SystemAlarms.Alarm_PathPlan != 1) && (HwSettings.OptionalModules_Battery == 1) + visible: (!UAV.isPathPlanEnabled() && UAV.batteryModuleEnabled()) Rectangle { anchors.fill: parent color: "transparent" Text { - text: FlightBatteryState.Voltage.toFixed(2) + text: UAV.batteryVoltage() anchors.centerIn: parent color: "white" font { @@ -354,14 +334,14 @@ Item { width: scaledBounds.width * sceneItem.width height: scaledBounds.height * sceneItem.height y: scaledBounds.y * sceneItem.height - visible: (SystemAlarms.Alarm_PathPlan != 1) && (HwSettings.OptionalModules_Battery == 1) + visible: (!UAV.isPathPlanEnabled() && UAV.batteryModuleEnabled()) Rectangle { anchors.fill: parent color: "transparent" Text { - text: FlightBatteryState.Current.toFixed(2) + text: UAV.batteryCurrent() anchors.centerIn: parent color: "white" font { @@ -381,7 +361,7 @@ Item { width: scaledBounds.width * sceneItem.width height: scaledBounds.height * sceneItem.height y: scaledBounds.y * sceneItem.height - visible: (SystemAlarms.Alarm_PathPlan != 1) && (HwSettings.OptionalModules_Battery == 1) + visible: (!UAV.isPathPlanEnabled() && UAV.batteryModuleEnabled()) Rectangle { anchors.fill: parent @@ -390,23 +370,22 @@ Item { text: "Reset consumed energy" } - MouseArea { - id: reset_consumed_energy_mouseArea; + MouseArea { + id: reset_consumed_energy_mouseArea; anchors.fill: parent; - cursorShape: Qt.PointingHandCursor; - onClicked: qmlWidget.resetConsumedEnergy(); + cursorShape: Qt.PointingHandCursor; + onClicked: pfdContext.resetConsumedEnergy(); } - // Alarm based on FlightBatteryState.EstimatedFlightTime < 120s orange, < 60s red - color: (FlightBatteryState.EstimatedFlightTime <= 120 && FlightBatteryState.EstimatedFlightTime > 60 ? "orange" : - (FlightBatteryState.EstimatedFlightTime <= 60 ? "red": info.batColors[SystemAlarms.Alarm_Battery])) + // Alarm based on estimatedFlightTime < 120s orange, < 60s red + color: UAV.estimatedTimeAlarmColor() border.color: "white" border.width: topbattery_volt.width * 0.01 radius: border.width * 4 Text { - text: FlightBatteryState.ConsumedEnergy.toFixed(0) + text: UAV.batteryConsumedEnergy() anchors.centerIn: parent color: "white" font { @@ -427,7 +406,7 @@ Item { width: scaledBounds.width * sceneItem.width height: scaledBounds.height * sceneItem.height y: Math.floor(scaledBounds.y * sceneItem.height) - visible: SystemAlarms.Alarm_PathPlan != 1 + visible: !UAV.isPathPlanEnabled() } SvgElementPositionItem { @@ -436,7 +415,7 @@ Item { width: scaledBounds.width * sceneItem.width height: scaledBounds.height * sceneItem.height y: Math.floor(scaledBounds.y * sceneItem.height) - visible: SystemAlarms.Alarm_PathPlan != 1 + visible: !UAV.isPathPlanEnabled() TooltipArea { text: "Reset distance counter" @@ -458,7 +437,7 @@ Item { Timer { interval: 1000; running: true; repeat: true; - onTriggered: {if (GPSPositionSensor.Status == 3) compute_distance(PositionState.East,PositionState.North)} + onTriggered: { if (UAV.isGpsStatusFix3D()) compute_distance(positionState.east, positionState.north) } } } @@ -473,11 +452,11 @@ Item { x: Math.floor(scaledBounds.x * sceneItem.width) y: Math.floor(scaledBounds.y * sceneItem.height) - opacity: qmlWidget.terrainEnabled ? 0.6 : 1 + opacity: opaque ? 1 : 0.6 states: State { name: "fading" - when: TakeOffLocation.Status == 0 + when: UAV.isTakeOffLocationValid() PropertyChanges { target: home_bg; x: Math.floor(scaledBounds.x * sceneItem.width) - home_bg.width; } } @@ -498,7 +477,7 @@ Item { states: State { name: "fading_heading" - when: TakeOffLocation.Status == 0 + when: UAV.isTakeOffLocationValid() PropertyChanges { target: home_heading_text; x: Math.floor(scaledBounds.x * sceneItem.width) - home_bg.width; } } @@ -509,7 +488,7 @@ Item { } Text { - text: " "+home_heading.toFixed(1)+"°" + text: " " + UAV.homeHeading().toFixed(1) + "°" anchors.centerIn: parent color: "cyan" font { @@ -529,7 +508,7 @@ Item { states: State { name: "fading_distance" - when: TakeOffLocation.Status == 0 + when: UAV.isTakeOffLocationValid() PropertyChanges { target: home_distance_text; x: Math.floor(scaledBounds.x * sceneItem.width) - home_bg.width; } } @@ -540,7 +519,7 @@ Item { } Text { - text: home_distance.toFixed(0)+" m" + text: UAV.homeDistance().toFixed(0) + " m" anchors.centerIn: parent color: "cyan" font { @@ -560,7 +539,7 @@ Item { states: State { name: "fading_distance" - when: TakeOffLocation.Status == 0 + when: UAV.isTakeOffLocationValid() PropertyChanges { target: home_eta_text; x: Math.floor(scaledBounds.x * sceneItem.width) - home_bg.width; } } @@ -571,7 +550,7 @@ Item { } Text { - text: formatTime(home_eta_h) + ":" + formatTime(home_eta_m) + ":" + formatTime(home_eta_s) + text: Utils.estimatedTimeOfArrival(UAV.homeDistance(), UAV.currentVelocity()) anchors.centerIn: parent color: "cyan" font { diff --git a/ground/gcs/src/share/pfd/default/Panels.qml b/ground/gcs/src/share/qml/pfd/Panels.qml similarity index 74% rename from ground/gcs/src/share/pfd/default/Panels.qml rename to ground/gcs/src/share/qml/pfd/Panels.qml index 09b5f61bd..e9a865de0 100644 --- a/ground/gcs/src/share/pfd/default/Panels.qml +++ b/ground/gcs/src/share/qml/pfd/Panels.qml @@ -1,23 +1,31 @@ +/* + * Copyright (C) 2016 The LibrePilot Project + * Contact: http://www.librepilot.org + * + * This file is part of LibrePilot GCS. + * + * LibrePilot GCS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LibrePilot GCS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LibrePilot GCS. If not, see . + */ import QtQuick 2.0 +import "../js/common.js" as Utils +import "../js/uav.js" as UAV + Item { id: panels property variant sceneSize - property real est_flight_time: Math.round(FlightBatteryState.EstimatedFlightTime) - property real est_time_h: (est_flight_time > 0 ? Math.floor(est_flight_time / 3600) : 0 ) - property real est_time_m: (est_flight_time > 0 ? Math.floor((est_flight_time - est_time_h*3600)/60) : 0) - property real est_time_s: (est_flight_time > 0 ? Math.floor(est_flight_time - est_time_h*3600 - est_time_m*60) : 0) - - function formatTime(time) { - if (time === 0) - return "00" - if (time < 10) - return "0" + time; - else - return time.toString(); - } - // // Panel functions // @@ -75,21 +83,13 @@ Item { system_bg.z = 40 } - // Uninitialised, Ok, Warning, Critical, Error - property variant batColors : ["#2c2929", "green", "orange", "red", "red"] - property real smeter_angle - property real memory_free : SystemStats.HeapRemaining > 1024 ? SystemStats.HeapRemaining / 1024 : SystemStats.HeapRemaining - - // Needed to get correctly int8 value - property int cpuTemp : SystemStats.CPUTemp - // Needed to get correctly int8 value, reset value (-127) on disconnect - property int oplm0_db: telemetry_link == 1 ? OPLinkStatus.PairSignalStrengths_0 : -127 - property int oplm1_db: telemetry_link == 1 ? OPLinkStatus.PairSignalStrengths_1 : -127 - property int oplm2_db: telemetry_link == 1 ? OPLinkStatus.PairSignalStrengths_2 : -127 - property int oplm3_db: telemetry_link == 1 ? OPLinkStatus.PairSignalStrengths_3 : -127 + property int oplm0_db: (telemetry_link == 1) ? opLinkStatus.pairSignalStrengths0 : -127 + property int oplm1_db: (telemetry_link == 1) ? opLinkStatus.pairSignalStrengths1 : -127 + property int oplm2_db: (telemetry_link == 1) ? opLinkStatus.pairSignalStrengths2 : -127 + property int oplm3_db: (telemetry_link == 1) ? opLinkStatus.pairSignalStrengths3 : -127 property real telemetry_sum property real telemetry_sum_old @@ -98,9 +98,9 @@ Item { // Hack : check if telemetry is active. Works with real link and log replay function telemetry_check() { - telemetry_sum = OPLinkStatus.RXRate + OPLinkStatus.RXRate + telemetry_sum = opLinkStatus.rxRate + opLinkStatus.txRate - if (telemetry_sum != telemetry_sum_old || OPLinkStatus.LinkState == 4) { + if (telemetry_sum != telemetry_sum_old || UAV.isOplmConnected()) { telemetry_link = 1 } else { telemetry_link = 0 @@ -141,7 +141,7 @@ Item { } property int smeter_filter - property variant oplm_pair_id : OPLinkStatus.PairIDs_0 + property variant oplm_pair_id : opLinkStatus.pairIDs0 function select_oplm(index){ smeter_filter0.running = false; @@ -153,22 +153,22 @@ Item { case 0: smeter_filter0.running = true; smeter_filter = 0; - oplm_pair_id = OPLinkStatus.PairIDs_0 + oplm_pair_id = opLinkStatus.pairIDs0 break; case 1: smeter_filter1.running = true; smeter_filter = 1; - oplm_pair_id = OPLinkStatus.PairIDs_1 + oplm_pair_id = opLinkStatus.pairIDs1 break; case 2: smeter_filter2.running = true; smeter_filter = 2; - oplm_pair_id = OPLinkStatus.PairIDs_2 + oplm_pair_id = opLinkStatus.pairIDs2 break; case 3: smeter_filter3.running = true; smeter_filter = 3; - oplm_pair_id = OPLinkStatus.PairIDs_3 + oplm_pair_id = opLinkStatus.pairIDs3 break; } } @@ -183,10 +183,8 @@ Item { property double offset_value: close_bg.width * 0.85 - property int anim_type: Easing.InOutExpo //Easing.InOutSine Easing.InOutElastic - property real anim_amplitude: 1.2 - property real anim_period: 2 - property int duration_value: 1600 + property int anim_type: Easing.OutExpo + property int anim_duration: 1600 // // Close - Open panel @@ -206,10 +204,10 @@ Item { } transitions: Transition { - SequentialAnimation { - id: close_anim - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } - } + SequentialAnimation { + id: close_anim + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } + } } } @@ -218,7 +216,7 @@ Item { elementName: "panel-open-icon" sceneSize: panels.sceneSize y: Math.floor(scaledBounds.y * sceneItem.height) - z: close_bg.z+1 + z: close_bg.z + 1 opacity: show_panels == true ? 0 : 1 states: State { @@ -229,10 +227,10 @@ Item { } transitions: Transition { - SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } - PropertyAnimation { property: "opacity"; duration: 500; } - } + SequentialAnimation { + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } + PropertyAnimation { property: "opacity"; duration: 500; } + } } } @@ -241,7 +239,7 @@ Item { elementName: "close-panel-mousearea" sceneSize: panels.sceneSize y: Math.floor(scaledBounds.y * sceneItem.height) - z: close_bg.z+100 + z: close_bg.z + 100 TooltipArea { text: show_panels == true ? "Close panels" : "Open panels" @@ -250,7 +248,7 @@ Item { MouseArea { id: hidedisp_close; anchors.fill: parent; - cursorShape: Qt.PointingHandCursor + cursorShape: Qt.PointingHandCursor onClicked: close_panels() } @@ -262,7 +260,7 @@ Item { transitions: Transition { SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } } } } @@ -286,8 +284,7 @@ Item { transitions: Transition { SequentialAnimation { - id: rc_input_anim - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } } } } @@ -297,7 +294,7 @@ Item { elementName: "rc-input-labels" sceneSize: panels.sceneSize y: Math.floor(scaledBounds.y * sceneItem.height) - z: rc_input_bg.z+1 + z: rc_input_bg.z + 1 states: State { name: "fading" @@ -306,9 +303,9 @@ Item { } transitions: Transition { - SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } - } + SequentialAnimation { + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } + } } } @@ -317,7 +314,7 @@ Item { elementName: "rc-input-panel-mousearea" sceneSize: panels.sceneSize y: Math.floor(scaledBounds.y * sceneItem.height) - z: rc_input_bg.z+1 + z: rc_input_bg.z + 1 TooltipArea { text: "RC panel" @@ -337,9 +334,9 @@ Item { } transitions: Transition { - SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } - } + SequentialAnimation { + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } + } } } @@ -350,7 +347,7 @@ Item { z: rc_input_bg.z+2 width: scaledBounds.width * sceneItem.width - height: (scaledBounds.height * sceneItem.height) * (ManualControlCommand.Throttle) + height: (scaledBounds.height * sceneItem.height) * (manualControlCommand.throttle) x: scaledBounds.x * sceneItem.width y: (scaledBounds.y * sceneItem.height) - rc_throttle.height + (scaledBounds.height * sceneItem.height) @@ -364,9 +361,9 @@ Item { } transitions: Transition { - SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } - } + SequentialAnimation { + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } + } } } @@ -379,13 +376,13 @@ Item { width: scaledBounds.width * sceneItem.width height: scaledBounds.height * sceneItem.height - y: (scaledBounds.y * sceneItem.height) + (ManualControlCommand.Pitch * rc_stick.width * 2.5) + y: (scaledBounds.y * sceneItem.height) + (manualControlCommand.pitch * rc_stick.width * 2.5) smooth: true //rotate it around his center transform: Rotation { - angle: ManualControlCommand.Yaw * 90 + angle: manualControlCommand.yaw * 90 origin.y : rc_stick.height / 2 origin.x : rc_stick.width / 2 } @@ -393,13 +390,13 @@ Item { states: State { name: "fading" when: show_panels == true - PropertyChanges { target: rc_stick; x: Math.floor(scaledBounds.x * sceneItem.width) + (ManualControlCommand.Roll * rc_stick.width * 2.5) + offset_value; } + PropertyChanges { target: rc_stick; x: Math.floor(scaledBounds.x * sceneItem.width) + (manualControlCommand.roll * rc_stick.width * 2.5) + offset_value; } } transitions: Transition { - SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } - } + SequentialAnimation { + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } + } } } @@ -421,9 +418,9 @@ Item { } transitions: Transition { - SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } - } + SequentialAnimation { + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } + } } } @@ -431,7 +428,7 @@ Item { id: battery_volt sceneSize: panels.sceneSize elementName: "battery-volt-text" - z: battery_bg.z+1 + z: battery_bg.z + 1 width: scaledBounds.width * sceneItem.width height: scaledBounds.height * sceneItem.height @@ -445,19 +442,19 @@ Item { transitions: Transition { SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } } } Rectangle { anchors.fill: parent - color: panels.batColors[SystemAlarms.Alarm_Battery] + color: UAV.batteryAlarmColor() border.color: "white" border.width: battery_volt.width * 0.01 radius: border.width * 4 Text { - text: FlightBatteryState.Voltage.toFixed(2) + text: UAV.batteryVoltage() anchors.centerIn: parent color: "white" font { @@ -486,19 +483,19 @@ Item { transitions: Transition { SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } } } Rectangle { anchors.fill: parent - color: panels.batColors[SystemAlarms.Alarm_Battery] + color: UAV.batteryAlarmColor() border.color: "white" border.width: battery_volt.width * 0.01 radius: border.width * 4 Text { - text: FlightBatteryState.Current.toFixed(2) + text: UAV.batteryCurrent() anchors.centerIn: parent color: "white" font { @@ -527,7 +524,7 @@ Item { transitions: Transition { SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } } } @@ -539,24 +536,23 @@ Item { visible: display_bat == true ? 1 : 0 } - MouseArea { - id: reset_panel_consumed_energy_mouseArea; + MouseArea { + id: reset_panel_consumed_energy_mouseArea; anchors.fill: parent; cursorShape: Qt.PointingHandCursor; visible: display_bat == true ? 1 : 0 - onClicked: qmlWidget.resetConsumedEnergy(); + onClicked: pfdContext.resetConsumedEnergy(); } - // Alarm based on FlightBatteryState.EstimatedFlightTime < 120s orange, < 60s red - color: (FlightBatteryState.EstimatedFlightTime <= 120 && FlightBatteryState.EstimatedFlightTime > 60 ? "orange" : - (FlightBatteryState.EstimatedFlightTime <= 60 ? "red": panels.batColors[SystemAlarms.Alarm_Battery])) + // Alarm based on estimatedFlightTime < 120s orange, < 60s red + color: UAV.estimatedTimeAlarmColor() border.color: "white" border.width: battery_volt.width * 0.01 radius: border.width * 4 Text { - text: FlightBatteryState.ConsumedEnergy.toFixed(0) + text: UAV.batteryConsumedEnergy() anchors.centerIn: parent color: "white" font { @@ -585,37 +581,35 @@ Item { transitions: Transition { SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } } } Rectangle { anchors.fill: parent - //color: panels.batColors[SystemAlarms.Alarm_Battery] TooltipArea { text: "Reset consumed energy" visible: display_bat == true ? 1 : 0 } - MouseArea { - id: reset_panel_consumed_energy_mouseArea2; + MouseArea { + id: reset_panel_consumed_energy_mouseArea2; anchors.fill: parent; - cursorShape: Qt.PointingHandCursor; + cursorShape: Qt.PointingHandCursor; visible: display_bat == true ? 1 : 0 - onClicked: qmlWidget.resetConsumedEnergy(); + onClicked: pfdContext.resetConsumedEnergy(); } - // Alarm based on FlightBatteryState.EstimatedFlightTime < 120s orange, < 60s red - color: (FlightBatteryState.EstimatedFlightTime <= 120 && FlightBatteryState.EstimatedFlightTime > 60 ? "orange" : - (FlightBatteryState.EstimatedFlightTime <= 60 ? "red": panels.batColors[SystemAlarms.Alarm_Battery])) + // Alarm based on estimatedFlightTime < 120s orange, < 60s red + color: UAV.estimatedTimeAlarmColor() border.color: "white" border.width: battery_volt.width * 0.01 radius: border.width * 4 Text { - text: formatTime(est_time_h) + ":" + formatTime(est_time_m) + ":" + formatTime(est_time_s) + text: Utils.formatFlightTime(UAV.estimatedFlightTimeValue()) anchors.centerIn: parent color: "white" font { @@ -641,7 +635,7 @@ Item { transitions: Transition { SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } } } } @@ -672,7 +666,7 @@ Item { transitions: Transition { SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } } } } @@ -695,9 +689,9 @@ Item { } transitions: Transition { - SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } - } + SequentialAnimation { + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } + } } } @@ -706,7 +700,7 @@ Item { elementName: "smeter-bg" sceneSize: panels.sceneSize y: Math.floor(scaledBounds.y * sceneItem.height) - z: oplm_bg.z+1 + z: oplm_bg.z + 1 states: State { name: "fading" @@ -716,7 +710,7 @@ Item { transitions: Transition { SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } } } } @@ -726,7 +720,7 @@ Item { elementName: "smeter-scale" sceneSize: panels.sceneSize y: Math.floor(scaledBounds.y * sceneItem.height) - z: oplm_bg.z+2 + z: oplm_bg.z + 2 states: State { name: "fading" @@ -736,7 +730,7 @@ Item { transitions: Transition { SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } } } } @@ -746,7 +740,7 @@ Item { elementName: "smeter-needle" sceneSize: panels.sceneSize y: Math.floor(scaledBounds.y * sceneItem.height) - z: oplm_bg.z+3 + z: oplm_bg.z + 3 states: State { name: "fading" @@ -756,7 +750,7 @@ Item { transitions: Transition { SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } } } @@ -774,7 +768,7 @@ Item { width: smeter_scale.width * 1.09 //anchors.horizontalCenter: smeter_scale - z: oplm_bg.z+4 + z: oplm_bg.z + 4 states: State { name: "fading" @@ -784,7 +778,7 @@ Item { transitions: Transition { SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } } } } @@ -796,7 +790,7 @@ Item { y: Math.floor(scaledBounds.y * sceneItem.height) width: smeter_mask.width - z: oplm_bg.z+5 + z: oplm_bg.z + 5 states: State { name: "fading" @@ -806,7 +800,7 @@ Item { transitions: Transition { SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } } } } @@ -815,7 +809,7 @@ Item { model: 4 SvgElementImage { - z: oplm_bg.z+5 + z: oplm_bg.z + 5 property variant idButton_oplm: "oplm_button_" + index property variant idButton_oplm_mousearea: "oplm_button_mousearea" + index property variant button_color: "button"+index+"_color" @@ -850,7 +844,7 @@ Item { transitions: Transition { SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } } } } @@ -861,7 +855,7 @@ Item { elementName: "oplm-id-label" sceneSize: panels.sceneSize y: Math.floor(scaledBounds.y * sceneItem.height) - z: oplm_bg.z+6 + z: oplm_bg.z + 6 states: State { name: "fading" @@ -871,7 +865,7 @@ Item { transitions: Transition { SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } } } } @@ -880,7 +874,7 @@ Item { id: oplm_id_text sceneSize: panels.sceneSize elementName: "oplm-id-text" - z: oplm_bg.z+7 + z: oplm_bg.z + 7 width: scaledBounds.width * sceneItem.width height: scaledBounds.height * sceneItem.height @@ -894,7 +888,7 @@ Item { transitions: Transition { SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } } } @@ -916,7 +910,7 @@ Item { elementName: "rx-quality-label" sceneSize: panels.sceneSize y: Math.floor(scaledBounds.y * sceneItem.height) - z: oplm_bg.z+8 + z: oplm_bg.z + 8 states: State { name: "fading" @@ -926,7 +920,7 @@ Item { transitions: Transition { SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } } } } @@ -935,7 +929,7 @@ Item { id: rx_quality_text sceneSize: panels.sceneSize elementName: "rx-quality-text" - z: oplm_bg.z+9 + z: oplm_bg.z + 9 width: scaledBounds.width * sceneItem.width height: scaledBounds.height * sceneItem.height @@ -949,13 +943,67 @@ Item { transitions: Transition { SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } } } Text { - text: ReceiverStatus.Quality > 0 ? ReceiverStatus.Quality+"%" : "?? %" - anchors.centerIn: parent + text: UAV.receiverQuality() + anchors.right: parent.right + color: "white" + font { + family: pt_bold.name + pixelSize: Math.floor(parent.height * 1.4) + weight: Font.DemiBold + } + } + } + + SvgElementImage { + id: cnx_state_label + elementName: "cnx-state-label" + sceneSize: panels.sceneSize + y: Math.floor(scaledBounds.y * sceneItem.height) + z: oplm_bg.z + 8 + + states: State { + name: "fading" + when: show_panels == true + PropertyChanges { target: cnx_state_label; x: Math.floor(scaledBounds.x * sceneItem.width) + offset_value; } + } + + transitions: Transition { + SequentialAnimation { + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } + } + } + } + + SvgElementPositionItem { + id: cnx_state_text + sceneSize: panels.sceneSize + elementName: "cnx-state-text" + z: oplm_bg.z + 9 + + width: scaledBounds.width * sceneItem.width + height: scaledBounds.height * sceneItem.height + y: scaledBounds.y * sceneItem.height + + states: State { + name: "fading" + when: show_panels == true + PropertyChanges { target: cnx_state_text; x: Math.floor(scaledBounds.x * sceneItem.width) + offset_value; } + } + + transitions: Transition { + SequentialAnimation { + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } + } + } + + Text { + text: UAV.oplmLinkState() + anchors.right: parent.right color: "white" font { family: pt_bold.name @@ -991,7 +1039,7 @@ Item { transitions: Transition { SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } } } } @@ -1004,7 +1052,7 @@ Item { id: system_bg elementName: "system-bg" sceneSize: panels.sceneSize - y: Math.floor(scaledBounds.y * sceneItem.height) + y: scaledBounds.y * sceneItem.height z: 40 states: State { @@ -1015,8 +1063,7 @@ Item { transitions: Transition { SequentialAnimation { - id: system_anim - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } } } } @@ -1025,8 +1072,8 @@ Item { id: system_frametype elementName: "system-frame-type" sceneSize: panels.sceneSize - y: Math.floor(scaledBounds.y * sceneItem.height) - z: system_bg.z+1 + y: scaledBounds.y * sceneItem.height + z: system_bg.z + 1 states: State { name: "fading" @@ -1036,14 +1083,12 @@ Item { transitions: Transition { SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } } } Text { - text: ["FixedWing", "FixedWingElevon", "FixedWingVtail", "VTOL", "HeliCP", "QuadX", "QuadP", - "Hexa+", "Octo+", "Custom", "HexaX", "HexaH", "OctoV", "OctoCoaxP", "OctoCoaxX", "OctoX", "HexaCoax", - "Tricopter", "GroundVehicleCar", "GroundVehicleDiff", "GroundVehicleMoto"][SystemSettings.AirframeType] + text: UAV.frameType() anchors.right: parent.right color: "white" font { @@ -1058,8 +1103,8 @@ Item { id: system_cpuloadtemp elementName: "system-cpu-load-temp" sceneSize: panels.sceneSize - y: Math.floor(scaledBounds.y * sceneItem.height) - z: system_bg.z+1 + y: scaledBounds.y * sceneItem.height + z: system_bg.z + 1 states: State { name: "fading" @@ -1069,14 +1114,13 @@ Item { transitions: Transition { SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } } } Text { - // Coptercontrol detect with mem free : Only display Cpu load, no temperature available. - text: SystemStats.CPULoad+"%"+ - [SystemStats.HeapRemaining < 3000 ? "" : " | "+cpuTemp+"°C"] + // CC3D: Only display Cpu load, no temperature available. + text: UAV.cpuLoad() + "%" + [UAV.isCC3D() ? "" : " | " + UAV.cpuTemp() + "°C"] anchors.right: parent.right color: "white" font { @@ -1091,8 +1135,8 @@ Item { id: system_memfree elementName: "system-mem-free" sceneSize: panels.sceneSize - y: Math.floor(scaledBounds.y * sceneItem.height) - z: system_bg.z+1 + y: scaledBounds.y * sceneItem.height + z: system_bg.z + 1 states: State { name: "fading" @@ -1102,12 +1146,12 @@ Item { transitions: Transition { SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } } } Text { - text: SystemStats.HeapRemaining > 1024 ? memory_free.toFixed(2) +"Kb" : memory_free +"bytes" + text: UAV.freeMemory() anchors.right: parent.right color: "white" font { @@ -1122,8 +1166,8 @@ Item { id: system_fusion_algo elementName: "system-attitude-estimation-algo" sceneSize: panels.sceneSize - y: Math.floor(scaledBounds.y * sceneItem.height) - z: system_bg.z+1 + y: scaledBounds.y * sceneItem.height + z: system_bg.z + 1 states: State { name: "fading" @@ -1133,12 +1177,12 @@ Item { transitions: Transition { SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } } } Text { - text: ["None", "Basic (No Nav)", "CompMag", "Comp+Mag+GPS", "EKFIndoor", "GPS Nav (INS13)"][RevoSettings.FusionAlgorithm] + text: UAV.fusionAlgorithm() anchors.right: parent.right color: "white" font { @@ -1153,8 +1197,8 @@ Item { id: system_mag_used elementName: "system-mag-used" sceneSize: panels.sceneSize - y: Math.floor(scaledBounds.y * sceneItem.height) - z: system_bg.z+1 + y: scaledBounds.y * sceneItem.height + z: system_bg.z + 1 states: State { name: "fading" @@ -1164,12 +1208,12 @@ Item { transitions: Transition { SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } } } Text { - text: ["Invalid", "OnBoard", "External"][MagState.Source] + text: UAV.magSourceName() anchors.right: parent.right color: "white" font { @@ -1184,8 +1228,8 @@ Item { id: system_gpstype elementName: "system-gps-type" sceneSize: panels.sceneSize - y: Math.floor(scaledBounds.y * sceneItem.height) - z: system_bg.z+1 + y: scaledBounds.y * sceneItem.height + z: system_bg.z + 1 states: State { name: "fading" @@ -1195,12 +1239,12 @@ Item { transitions: Transition { SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } } } Text { - text: ["Unknown", "NMEA", "UBX", "UBX7", "UBX8"][GPSPositionSensor.SensorType] + text: UAV.gpsSensorType() anchors.right: parent.right color: "white" font { @@ -1216,7 +1260,7 @@ Item { elementName: "system-panel-mousearea" sceneSize: panels.sceneSize y: Math.floor(scaledBounds.y * sceneItem.height) - z: system_bg.z+1 + z: system_bg.z + 1 TooltipArea { text: "System panel" @@ -1237,7 +1281,7 @@ Item { transitions: Transition { SequentialAnimation { - PropertyAnimation { property: "x"; easing.type: anim_type; easing.amplitude: anim_amplitude; easing.period: anim_period; duration: duration_value } + PropertyAnimation { property: "x"; easing.type: anim_type; duration: anim_duration } } } } diff --git a/ground/gcs/src/share/qml/pfd/PfdSimpleWorld.qml b/ground/gcs/src/share/qml/pfd/PfdSimpleWorld.qml new file mode 100644 index 000000000..a238ff777 --- /dev/null +++ b/ground/gcs/src/share/qml/pfd/PfdSimpleWorld.qml @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2016 The LibrePilot Project + * Contact: http://www.librepilot.org + * + * This file is part of LibrePilot GCS. + * + * LibrePilot GCS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LibrePilot GCS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LibrePilot GCS. If not, see . + */ +import QtQuick 2.4 + +import "../js/uav.js" as UAV + +Item { + id: worldView + property real horizontCenter : horizontCenterItem.horizontCenter + + Rectangle { + // using rectange instead of svg rendered to pixmap + // as it's much more memory efficient + id: world + smooth: true + + property variant scaledBounds: svgRenderer.scaledElementBounds("pfd/pfd.svg", "horizon") + width: Math.round(sceneItem.width * scaledBounds.width / 2) * 2 + height: Math.round(sceneItem.height * scaledBounds.height / 2) * 3 + + property double pitch1DegScaledHeight: ((svgRenderer.scaledElementBounds("pfd/pfd.svg", "pitch-90").y - + svgRenderer.scaledElementBounds("pfd/pfd.svg", "pitch90").y) * 1.03) / 180.0 + + property double pitch1DegHeight: sceneItem.height*pitch1DegScaledHeight + + gradient: Gradient { + GradientStop { position: 0.4000; color: "#013163" } + GradientStop { position: 0.4999; color: "#0164CC" } + GradientStop { position: 0.5001; color: "#653300" } + GradientStop { position: 0.6000; color: "#3C1E00" } + } + + transform: [ + Translate { + id: pitchTranslate + x: Math.round((world.parent.width - world.width) / 2) + // y is centered around world_center element + y: Math.round(horizontCenter - world.height / 2 + UAV.attitudePitch() * world.pitch1DegHeight) + }, + Rotation { + angle: -UAV.attitudeRoll() + origin.x : world.parent.width / 2 + origin.y : horizontCenter + } + ] + + SvgElementImage { + id: horizont_line + elementName: "center-line" + + // worldView is loaded with Loader, so background element is visible + sceneSize: background.sceneSize + anchors.centerIn: parent + border: 1 + smooth: true + } + + SvgElementImage { + id: pitch_0 + elementName: "pitch0" + + sceneSize: background.sceneSize + anchors.centerIn: parent + border: 1 + smooth: true + } + } + + Item { + id: pitch_window + property variant scaledBounds: svgRenderer.scaledElementBounds("pfd/pfd.svg", "pitch-window") + + x: Math.floor(scaledBounds.x * sceneItem.width) + y: Math.floor(scaledBounds.y * sceneItem.height) + width: Math.floor(scaledBounds.width * sceneItem.width) + height: Math.floor(scaledBounds.height * sceneItem.height) + + rotation: -UAV.attitudeRoll() + transformOrigin: Item.Center + + smooth: true + clip: true + + SvgElementImage { + id: pitch_scale + elementName: "pitch-scale" + // worldView is loaded with Loader, so background element is visible + sceneSize: background.sceneSize + anchors.centerIn: parent + // see comment for world transform + anchors.verticalCenterOffset: UAV.attitudePitch() * world.pitch1DegHeight + border: 64 //sometimes numbers are excluded from bounding rect + + smooth: true + } + } + +} diff --git a/ground/gcs/src/share/qml/pfd/PfdTerrainWorld.qml b/ground/gcs/src/share/qml/pfd/PfdTerrainWorld.qml new file mode 100644 index 000000000..726b13676 --- /dev/null +++ b/ground/gcs/src/share/qml/pfd/PfdTerrainWorld.qml @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2016 The LibrePilot Project + * Contact: http://www.librepilot.org + * + * This file is part of LibrePilot GCS. + * + * LibrePilot GCS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LibrePilot GCS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LibrePilot GCS. If not, see . + */ +import QtQuick 2.4 + +import Pfd 1.0 +import OsgQtQuick 1.0 + +import "../js/common.js" as Utils +import "../js/uav.js" as UAV + +OSGViewport { + id: osgViewport + + //anchors.fill: parent + focus: true + + readonly property real horizontCenter : horizontCenterItem.horizontCenter + + // Factor for OSGViewer vertical offset + readonly property double factor: 0.04 + + // Stretch height and apply offset + //height: height * (1 + factor) + y: -height * factor + + sceneNode: skyNode + camera: camera + manipulator: geoTransformManipulator + //incrementalCompile: true + + OSGCamera { + id: camera + + fieldOfView: 100 + logarithmicDepthBuffer: true + } + + OSGGeoTransformManipulator { + id: geoTransformManipulator + + sceneNode: terrainFileNode + clampToTerrain: true + + attitude: UAV.attitude() + position: UAV.position() + } + + OSGSkyNode { + id: skyNode + sceneNode: terrainFileNode + viewport: osgViewport + dateTime: Utils.getDateTime() + minimumAmbientLight: pfdContext.minimumAmbientLight + } + + OSGFileNode { + id: terrainFileNode + source: pfdContext.terrainFile + async: false + } + + Rectangle { + // using rectangle instead of svg rendered to pixmap + // as it's much more memory efficient + id: world + smooth: true + opacity: 0 + + property variant scaledBounds: svgRenderer.scaledElementBounds("pfd/pfd.svg", "horizon") + width: Math.round(sceneItem.width * scaledBounds.width / 2) * 2 + height: Math.round(sceneItem.height * scaledBounds.height / 2) * 3 + + property double pitch1DegScaledHeight: (svgRenderer.scaledElementBounds("pfd/pfd.svg", "pitch-90").y - + svgRenderer.scaledElementBounds("pfd/pfd.svg", "pitch90").y) / 180.0 + + property double pitch1DegHeight: sceneItem.height * pitch1DegScaledHeight + + transform: [ + Translate { + id: pitchTranslate + x: Math.round((world.parent.width - world.width)/2) + // y is centered around world_center element + y: Math.round(horizontCenter - world.height / 2 + UAV.attitudePitch() * world.pitch1DegHeight) + }, + Rotation { + angle: -UAV.attitudeRoll() + origin.x : world.parent.width / 2 + origin.y : horizontCenter + } + ] + + } + + Item { + id: pitch_window + property variant scaledBounds: svgRenderer.scaledElementBounds("pfd/pfd.svg", "pitch-window-terrain") + + x: Math.floor(scaledBounds.x * sceneItem.width) + y: Math.floor(scaledBounds.y * sceneItem.height) - osgViewport.y + width: Math.floor(scaledBounds.width * sceneItem.width) + height: Math.floor(scaledBounds.height * sceneItem.height) + + rotation: -UAV.attitudeRoll() + transformOrigin: Item.Center + + smooth: true + clip: true + + SvgElementImage { + id: pitch_scale + elementName: "pitch-scale" + + //worldView is loaded with Loader, so background element is visible + sceneSize: background.sceneSize + anchors.centerIn: parent + //see comment for world transform + anchors.verticalCenterOffset: attitudeState.pitch * world.pitch1DegHeight + border: 64 // sometimes numbers are excluded from bounding rect + + smooth: true + } + + SvgElementImage { + id: horizont_line + elementName: "center-line" + + opacity: 0.5 + + // worldView is loaded with Loader, so background element is visible + sceneSize: background.sceneSize + anchors.centerIn: parent + + anchors.verticalCenterOffset: UAV.attitudePitch() * world.pitch1DegHeight + border: 1 + smooth: true + } + + SvgElementImage { + id: pitch_0 + elementName: "pitch0" + + sceneSize: background.sceneSize + anchors.centerIn: parent + anchors.verticalCenterOffset: UAV.attitudePitch() * world.pitch1DegHeight + border: 1 + smooth: true + } + } +} diff --git a/ground/gcs/src/share/pfd/default/Pfd.qml b/ground/gcs/src/share/qml/pfd/PfdView.qml similarity index 69% rename from ground/gcs/src/share/pfd/default/Pfd.qml rename to ground/gcs/src/share/qml/pfd/PfdView.qml index 2b9aacb76..3d60dffb5 100644 --- a/ground/gcs/src/share/pfd/default/Pfd.qml +++ b/ground/gcs/src/share/qml/pfd/PfdView.qml @@ -1,7 +1,30 @@ -import QtQuick 2.0 +/* + * Copyright (C) 2016 The LibrePilot Project + * Contact: http://www.librepilot.org + * + * This file is part of LibrePilot GCS. + * + * LibrePilot GCS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LibrePilot GCS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LibrePilot GCS. If not, see . + */ +import QtQuick 2.4 Rectangle { - color: "#666666" + + color: "#515151" + + property string worldFile: "PfdSimpleWorld.qml" + property bool opaque: true SvgElementImage { id: background @@ -9,16 +32,16 @@ Rectangle { fillMode: Image.PreserveAspectFit anchors.fill: parent sceneSize: Qt.size(width, height) - + Rectangle { width: Math.floor(parent.paintedHeight * 1.319) height: Math.floor(parent.paintedHeight - parent.paintedHeight * 0.008) - + color: "transparent" border.color: "white" border.width: Math.floor(parent.paintedHeight * 0.008) radius: Math.floor(parent.paintedHeight * 0.01) - anchors.centerIn: parent + anchors.centerIn: parent } Item { @@ -26,7 +49,7 @@ Rectangle { FontLoader { id: pt_bold - source: "qrc:/pfdqml/fonts/PTS75F.ttf" + source: "qrc:/utils/fonts/PTS75F.ttf" } width: Math.floor((parent.paintedHeight * 1.32) - (parent.paintedHeight * 0.013)) @@ -35,11 +58,12 @@ Rectangle { anchors.centerIn: parent clip: true - + Loader { id: worldLoader anchors.fill: parent - source: qmlWidget.terrainEnabled ? "PfdTerrainView.qml" : "PfdWorldView.qml" + focus: true + source: worldFile } HorizontCenter { @@ -81,7 +105,7 @@ Rectangle { VsiScale { anchors.fill: parent sceneSize: sceneItem.viewportSize - visible: qmlWidget.altitudeUnit != 0 + visible: pfdContext.altitudeUnit != 0 } Info { diff --git a/ground/gcs/src/share/qml/pfd/RollScale.qml b/ground/gcs/src/share/qml/pfd/RollScale.qml new file mode 100644 index 000000000..9aed9ba02 --- /dev/null +++ b/ground/gcs/src/share/qml/pfd/RollScale.qml @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2016 The LibrePilot Project + * Contact: http://www.librepilot.org + * + * This file is part of LibrePilot GCS. + * + * LibrePilot GCS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LibrePilot GCS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LibrePilot GCS. If not, see . + */ +import QtQuick 2.4 + +import "../js/uav.js" as UAV + +Item { + id: sceneItem + + property variant sceneSize + property real horizontCenter + + //onHorizontCenterChanged: console.log("horizont center:" + horizontCenter) + + SvgElementImage { + id: rollscale + elementName: "roll-scale" + sceneSize: sceneItem.sceneSize + + width: scaledBounds.width * sceneItem.width + height: scaledBounds.height * sceneItem.height + + x: scaledBounds.x * sceneItem.width + y: scaledBounds.y * sceneItem.height + + smooth: true + + // rotate it around the center of horizon + transform: Rotation { + angle: -UAV.attitudeRoll() + origin.y : rollscale.height * 2.4 + origin.x : rollscale.width / 2 + } + } + +} diff --git a/ground/gcs/src/share/pfd/default/SpeedScale.qml b/ground/gcs/src/share/qml/pfd/SpeedScale.qml similarity index 71% rename from ground/gcs/src/share/pfd/default/SpeedScale.qml rename to ground/gcs/src/share/qml/pfd/SpeedScale.qml index a8b8153df..ed5606bfb 100644 --- a/ground/gcs/src/share/pfd/default/SpeedScale.qml +++ b/ground/gcs/src/share/qml/pfd/SpeedScale.qml @@ -1,10 +1,30 @@ -import QtQuick 2.0 +/* + * Copyright (C) 2016 The LibrePilot Project + * Contact: http://www.librepilot.org + * + * This file is part of LibrePilot GCS. + * + * LibrePilot GCS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LibrePilot GCS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LibrePilot GCS. If not, see . + */ +import QtQuick 2.4 + +import "../js/uav.js" as UAV Item { id: sceneItem property variant sceneSize - property real groundSpeed : qmlWidget.speedFactor * Math.sqrt(Math.pow(VelocityState.North,2)+ - Math.pow(VelocityState.East,2)) + property real groundSpeed : pfdContext.speedFactor * UAV.currentVelocity() SvgElementImage { id: speed_window @@ -12,7 +32,7 @@ Item { sceneSize: sceneItem.sceneSize clip: true - visible: qmlWidget.speedUnit != 0 + visible: pfdContext.speedUnit != 0 x: Math.floor(scaledBounds.x * sceneItem.width) y: Math.floor(scaledBounds.y * sceneItem.height) @@ -63,12 +83,12 @@ Item { id: speed_waypoint elementName: "speed-waypoint" sceneSize: sceneItem.sceneSize - visible: PathDesired.EndingVelocity !== 0.0 + visible: (UAV.isFlightModeAssisted() && UAV.isPathDesiredActive()) anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter - anchors.verticalCenterOffset: speed_scale.height/10 * (sceneItem.groundSpeed - (PathDesired.EndingVelocity * qmlWidget.speedFactor)) + anchors.verticalCenterOffset: speed_scale.height / 10 * (sceneItem.groundSpeed - (UAV.pathDesiredEndingVelocity() * pfdContext.speedFactor)) } } @@ -78,7 +98,7 @@ Item { elementName: "speed-box" sceneSize: sceneItem.sceneSize - visible: qmlWidget.speedUnit != 0 + visible: pfdContext.speedUnit != 0 x: scaledBounds.x * sceneItem.width y: scaledBounds.y * sceneItem.height @@ -103,7 +123,7 @@ Item { elementName: "speed-unit-box" sceneSize: sceneItem.sceneSize - visible: qmlWidget.speedUnit != 0 + visible: pfdContext.speedUnit != 0 anchors.top: speed_window.bottom anchors.right: speed_window.right @@ -112,7 +132,7 @@ Item { Text { id: speed_unit_text - text: qmlWidget.speedUnit + text: pfdContext.speedUnit color: "cyan" font { family: pt_bold.name diff --git a/ground/gcs/src/share/pfd/default/SvgElementImage.qml b/ground/gcs/src/share/qml/pfd/SvgElementImage.qml similarity index 60% rename from ground/gcs/src/share/pfd/default/SvgElementImage.qml rename to ground/gcs/src/share/qml/pfd/SvgElementImage.qml index 6006380f0..c7f07eeac 100644 --- a/ground/gcs/src/share/pfd/default/SvgElementImage.qml +++ b/ground/gcs/src/share/qml/pfd/SvgElementImage.qml @@ -1,10 +1,29 @@ -import QtQuick 2.0 +/* + * Copyright (C) 2016 The LibrePilot Project + * Contact: http://www.librepilot.org + * + * This file is part of LibrePilot GCS. + * + * LibrePilot GCS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LibrePilot GCS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LibrePilot GCS. If not, see . + */ +import QtQuick 2.4 Image { id: sceneItem property variant sceneSize property string elementName - property string svgFileName: "pfd.svg" + property string svgFileName: "pfd/pfd.svg" property int vSlice: 0 property int vSliceCount: 0 property int hSlice: 0 diff --git a/ground/gcs/src/share/qml/pfd/SvgElementPositionItem.qml b/ground/gcs/src/share/qml/pfd/SvgElementPositionItem.qml new file mode 100644 index 000000000..dac70ffbe --- /dev/null +++ b/ground/gcs/src/share/qml/pfd/SvgElementPositionItem.qml @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2016 The LibrePilot Project + * Contact: http://www.librepilot.org + * + * This file is part of LibrePilot GCS. + * + * LibrePilot GCS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LibrePilot GCS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LibrePilot GCS. If not, see . + */ +import QtQuick 2.4 + +Item { + id: sceneItem + property variant sceneSize + property string elementName + property string svgFileName: "pfd/pfd.svg" + property variant scaledBounds: svgRenderer.scaledElementBounds(svgFileName, elementName) + + x: Math.floor(scaledBounds.x * sceneSize.width) + y: Math.floor(scaledBounds.y * sceneSize.height) + width: Math.floor(scaledBounds.width * sceneSize.width) + height: Math.floor(scaledBounds.height * sceneSize.height) +} diff --git a/ground/gcs/src/share/qml/pfd/TooltipArea.qml b/ground/gcs/src/share/qml/pfd/TooltipArea.qml new file mode 100644 index 000000000..d971ff295 --- /dev/null +++ b/ground/gcs/src/share/qml/pfd/TooltipArea.qml @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2016 The LibrePilot Project + * Contact: http://www.librepilot.org + * + * This file is part of LibrePilot GCS. + * + * LibrePilot GCS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LibrePilot GCS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LibrePilot GCS. If not, see . + */ +import QtQuick 2.4 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Private 1.0 +import QtQuick.Controls.Styles 1.1 + +// TooltipArea.qml +// This file contains private Qt Quick modules that might change in future versions of Qt +// Tested on: Qt 5.4.1 +// https://www.kullo.net/blog/tooltiparea-the-missing-tooltip-component-of-qt-quick/ + + +MouseArea { + id: _root + property string text: "" + + anchors.fill: parent + hoverEnabled: _root.enabled + + onExited: Tooltip.hideText() + onCanceled: Tooltip.hideText() + + Timer { + interval: 1000 + running: _root.enabled && _root.containsMouse && _root.text.length + onTriggered: Tooltip.showText(_root, Qt.point(_root.mouseX, _root.mouseY), _root.text) + } +} diff --git a/ground/gcs/src/share/pfd/default/VsiScale.qml b/ground/gcs/src/share/qml/pfd/VsiScale.qml similarity index 57% rename from ground/gcs/src/share/pfd/default/VsiScale.qml rename to ground/gcs/src/share/qml/pfd/VsiScale.qml index 0a177032d..3ee9c73eb 100644 --- a/ground/gcs/src/share/pfd/default/VsiScale.qml +++ b/ground/gcs/src/share/qml/pfd/VsiScale.qml @@ -1,4 +1,25 @@ -import QtQuick 2.0 +/* + * Copyright (C) 2016 The LibrePilot Project + * Contact: http://www.librepilot.org + * + * This file is part of LibrePilot GCS. + * + * LibrePilot GCS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LibrePilot GCS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LibrePilot GCS. If not, see . + */ +import QtQuick 2.4 + +import "../js/uav.js" as UAV Item { id: sceneItem @@ -7,7 +28,7 @@ Item { Timer { interval: 100; running: true; repeat: true - onTriggered: vert_velocity = (0.9 * vert_velocity) + (0.1 * VelocityState.Down) + onTriggered: vert_velocity = (0.9 * vert_velocity) + (0.1 * UAV.velocityStateDown()) } SvgElementImage { @@ -22,12 +43,12 @@ Item { y: scaledBounds.y * sceneItem.height smooth: true - visible: VelocityDesired.Down !== 0.0 && FlightStatus.FlightMode > 7 + visible: (UAV.isFlightModeAssisted() && (UAV.velocityDesiredDown() != 0.0)) - //rotate it around the center + // rotate it around the center transform: Rotation { - angle: -VelocityDesired.Down * 5 - origin.y : vsi_waypoint.height / 2 + angle: -UAV.velocityDesiredDown() * 5 + origin.y : vsi_waypoint.height / 2 origin.x : vsi_waypoint.width * 33 } } @@ -35,7 +56,7 @@ Item { SvgElementImage { id: vsi_scale_meter - visible: qmlWidget.altitudeUnit == "m" + visible: (pfdContext.altitudeUnit == "m") elementName: "vsi-scale-meter" sceneSize: sceneItem.sceneSize @@ -47,7 +68,7 @@ Item { SvgElementImage { id: vsi_scale_ft - visible: qmlWidget.altitudeUnit == "ft" + visible: (pfdContext.altitudeUnit == "ft") elementName: "vsi-scale-ft" sceneSize: sceneItem.sceneSize @@ -69,10 +90,10 @@ Item { smooth: true - //rotate it around the center + // rotate it around the center, limit value to +/-6m/s transform: Rotation { - angle: -vert_velocity * 5 - origin.y : vsi_arrow.height / 2 + angle: (vert_velocity > 6) ? -30 : (vert_velocity < -6) ? 30 : -vert_velocity * 5 + origin.y : vsi_arrow.height / 2 origin.x : vsi_arrow.width * 3.15 } } @@ -83,7 +104,7 @@ Item { sceneSize: sceneItem.sceneSize Text { - text: qmlWidget.altitudeUnit == "m" ? "m/s" : "ft/s" + text: (pfdContext.altitudeUnit == "m") ? "m/s" : "ft/s" color: "cyan" font { family: pt_bold.name diff --git a/ground/gcs/src/share/pfd/default/Warnings.qml b/ground/gcs/src/share/qml/pfd/Warnings.qml similarity index 54% rename from ground/gcs/src/share/pfd/default/Warnings.qml rename to ground/gcs/src/share/qml/pfd/Warnings.qml index 9026f7be5..bb399a50b 100644 --- a/ground/gcs/src/share/pfd/default/Warnings.qml +++ b/ground/gcs/src/share/qml/pfd/Warnings.qml @@ -1,50 +1,30 @@ -import QtQuick 2.0 +/* + * Copyright (C) 2016 The LibrePilot Project + * Contact: http://www.librepilot.org + * + * This file is part of LibrePilot GCS. + * + * LibrePilot GCS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LibrePilot GCS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LibrePilot GCS. If not, see . + */ +import QtQuick 2.4 + +import "../js/common.js" as Utils +import "../js/uav.js" as UAV Item { id: warnings - property variant sceneSize - // Uninitialised, OK, Warning, Error, Critical - property variant statusColors : ["gray", "green", "red", "red", "red"] - - // DisArmed , Arming, Armed - property variant armColors : ["gray", "orange", "green"] - - // All 'manual modes' are green, 'assisted' modes in cyan - // "MANUAL","STAB 1","STAB 2", "STAB 3", "STAB 4", "STAB 5", "STAB 6", - // "POS HOLD", "COURSELOCK","VEL ROAM", "HOME LEASH", "ABS POS", "RTB", "LAND", "PATHPLAN", "POI", "AUTOCRUISE", "AUTOTAKEOFF" - - property variant flightmodeColors : ["gray", "green", "green", "green", "green", "green", "green", - "cyan", "cyan", "cyan", "cyan", "cyan", "cyan", "cyan", "cyan", "cyan", "cyan", "cyan"] - - // Manual,Rate,RateTrainer,Attitude,AxisLock,WeakLeveling,VirtualBar,Acro+,Rattitude, - // AltitudeHold,AltitudeVario,CruiseControl" + Auto mode (VTOL/Wing pathfollower) - // grey : 'disabled' modes - - property variant thrustmodeColors : ["green", "grey", "grey", "grey", "grey", "grey", "grey", "grey", "grey", - "green", "green", "green", "cyan"] - - // SystemSettings.AirframeType 3 - 17 : VtolPathFollower, check ThrustControl - - property var thrust_mode: FlightStatus.FlightMode < 7 ? StabilizationDesired.StabilizationMode_Thrust : - FlightStatus.FlightMode > 6 && SystemSettings.AirframeType > 2 && SystemSettings.AirframeType < 18 - && VtolPathFollowerSettings.ThrustControl == 1 ? 12 : - FlightStatus.FlightMode > 6 && SystemSettings.AirframeType < 3 ? 12: 0 - - - property real flight_time: Math.round(SystemStats.FlightTime / 1000) - property real time_h: (flight_time > 0 ? Math.floor(flight_time / 3600) : 0 ) - property real time_m: (flight_time > 0 ? Math.floor((flight_time - time_h*3600)/60) : 0) - property real time_s: (flight_time > 0 ? Math.floor(flight_time - time_h*3600 - time_m*60) : 0) - - function formatTime(time) { - if (time === 0) - return "00" - if (time < 10) - return "0" + time; - else - return time.toString(); - } SvgElementImage { id: warning_bg @@ -65,11 +45,11 @@ Item { Rectangle { anchors.fill: parent - color: (SystemStats.FlightTime > 0 ? "green" : "grey") + color: (UAV.flightTimeValue() > 0) ? "green" : "grey" Text { anchors.centerIn: parent - text: formatTime(time_h) + ":" + formatTime(time_m) + ":" + formatTime(time_s) + text: Utils.formatFlightTime(UAV.flightTimeValue()) font { family: pt_bold.name pixelSize: Math.floor(parent.height * 0.8) @@ -90,11 +70,11 @@ Item { Rectangle { anchors.fill: parent - color: warnings.armColors[FlightStatus.Armed] + color: UAV.armStatusColor() Text { anchors.centerIn: parent - text: ["DISARMED","ARMING","ARMED"][FlightStatus.Armed] + text: UAV.armStatusName() font { family: pt_bold.name pixelSize: Math.floor(parent.height * 0.74) @@ -115,7 +95,7 @@ Item { Rectangle { anchors.fill: parent - color: warnings.statusColors[SystemAlarms.Alarm_ManualControl] + color: UAV.rcInputStatusColor() Text { anchors.centerIn: parent @@ -138,15 +118,10 @@ Item { x: scaledBounds.x * sceneItem.width y: scaledBounds.y * sceneItem.height - property bool warningActive: (SystemAlarms.Alarm_BootFault > 1 || - SystemAlarms.Alarm_OutOfMemory > 1 || - SystemAlarms.Alarm_StackOverflow > 1 || - SystemAlarms.Alarm_CPUOverload > 1 || - SystemAlarms.Alarm_EventSystem > 1) Rectangle { anchors.fill: parent - color: parent.warningActive ? "red" : "red" - opacity: parent.warningActive ? 1.0 : 0.4 + color: "red" + opacity: UAV.masterCautionWarning() ? 1.0 : 0.4 Text { anchors.centerIn: parent @@ -172,7 +147,7 @@ Item { Rectangle { anchors.fill: parent - color: warnings.statusColors[SystemAlarms.Alarm_Guidance] + color: UAV.autopilotStatusColor() Text { anchors.centerIn: parent @@ -197,14 +172,11 @@ Item { Rectangle { anchors.fill: parent - color: warnings.flightmodeColors[FlightStatus.FlightMode] - // Manual,Stabilized1,Stabilized2,Stabilized3,Stabilized4,Stabilized5,Stabilized6,PositionHold,CourseLock, - // VelocityRoam,HomeLeash,AbsolutePosition,ReturnToBase,Land,PathPlanner,POI,AutoCruise,AutoTakeoff + color: UAV.flightModeColor() Text { anchors.centerIn: parent - text: ["MANUAL","STAB 1","STAB 2", "STAB 3", "STAB 4", "STAB 5", "STAB 6", "POS HOLD", "COURSELOCK", - "VEL ROAM", "HOME LEASH", "ABS POS", "RTB", "LAND", "PATHPLAN", "POI", "AUTOCRUISE", "AUTOTAKEOFF"][FlightStatus.FlightMode] + text: UAV.flightModeName() font { family: pt_bold.name pixelSize: Math.floor(parent.height * 0.74) @@ -225,15 +197,12 @@ Item { Rectangle { anchors.fill: parent - color: FlightStatus.FlightMode < 1 ? "grey" : warnings.thrustmodeColors[thrust_mode.toString()] + color: UAV.isFlightModeManual() ? "grey" : UAV.thrustModeColor() - // Manual,Rate,RateTrainer,Attitude,AxisLock,WeakLeveling,VirtualBar,Acro+,Rattitude, - // AltitudeHold,AltitudeVario,CruiseControl - // grey : 'disabled' modes + // grey : 'disabled' modes Text { anchors.centerIn: parent - text: ["MANUAL"," "," ", " ", " ", " ", " ", " ", " ", - "ALT HOLD", "ALT VARIO", "CRUISECTRL", "AUTO"][thrust_mode.toString()] + text: UAV.thrustModeName() font { family: pt_bold.name pixelSize: Math.floor(parent.height * 0.74) @@ -248,7 +217,7 @@ Item { elementName: "warning-gps" sceneSize: warnings.sceneSize - visible: SystemAlarms.Alarm_GPS > 1 + visible: UAV.isGpsNotInitialised() ? false : !UAV.isGpsValid() } SvgElementImage { @@ -256,6 +225,6 @@ Item { elementName: "warning-attitude" sceneSize: warnings.sceneSize anchors.centerIn: background.centerIn - visible: SystemAlarms.Alarm_Attitude > 1 + visible: UAV.isAttitudeNotInitialised() ? false : !UAV.isAttitudeValid() } } diff --git a/ground/gcs/src/share/pfd/default/pfd.svg b/ground/gcs/src/share/qml/pfd/pfd.svg similarity index 80% rename from ground/gcs/src/share/pfd/default/pfd.svg rename to ground/gcs/src/share/qml/pfd/pfd.svg index 3f92fa1d8..086af8938 100644 --- a/ground/gcs/src/share/pfd/default/pfd.svg +++ b/ground/gcs/src/share/qml/pfd/pfd.svg @@ -297,7 +297,7 @@ xlink:href="#linearGradient5081" id="linearGradient5140" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.72681147,0,0,0.72681203,51.886659,97.24824)" + gradientTransform="matrix(0.72681147,0,0,0.72681203,51.886659,94.396308)" x1="173.84364" y1="306.16443" x2="192.77324" @@ -357,22 +357,22 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="4.2956737" - inkscape:cx="-47.945175" - inkscape:cy="97.731657" + inkscape:zoom="1.51875" + inkscape:cx="22.734908" + inkscape:cy="51.173186" inkscape:document-units="px" - inkscape:current-layer="layer54" + inkscape:current-layer="layer76" showgrid="false" fit-margin-top="0" fit-margin-left="0" fit-margin-right="0" fit-margin-bottom="0" inkscape:window-width="1280" - inkscape:window-height="928" + inkscape:window-height="927" inkscape:window-x="0" inkscape:window-y="27" inkscape:window-maximized="1" - showguides="true" + showguides="false" inkscape:guide-bbox="true" inkscape:object-nodes="false" inkscape:object-paths="true" @@ -425,7 +425,7 @@ image/svg+xml - + @@ -2109,8 +2109,7 @@ inkscape:groupmode="layer" id="layer59" inkscape:label="system-panel" - style="display:inline" - sodipodi:insensitive="true"> + style="display:inline"> - - - - + transform="translate(-0.82096087,25.618099)"> + transform="translate(-0.43424217,23.541402)"> + transform="translate(-0.72721087,21.476425)"> + transform="translate(0.18099223,-34.35974)"> + transform="translate(-0.72721087,-36.430577)"> @@ -2350,43 +2322,43 @@ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.34432793px;line-height:125%;font-family:Arial;-inkscape-font-specification:Arial;letter-spacing:0px;word-spacing:0px;display:inline;fill:#e6e6e6;fill-opacity:1;stroke:none" inkscape:connector-curvature="0" id="path4995" - d="m 35.617,417.76968 l 0,-0.85731 c -0.454396,0.65947 -1.071854,0.98921 -1.852379,0.98921 c -0.344461,0 -0.666931,-0.066 -0.967413,-0.19784 c -0.296823,-0.1319 -0.518522,-0.29677 -0.665098,-0.4946 c -0.142915,-0.20151 -0.243687,-0.44698 -0.302317,-0.73642 c -0.04031,-0.19417 -0.06046,-0.50193 -0.06046,-0.92326 l 0,-3.61612 l 0.9894,0 l 0,3.23692 c -2e-6,0.51659 0.02015,0.86464 0.06046,1.04417 c 0.06229,0.26013 0.194214,0.46529 0.395761,0.6155 c 0.201542,0.14655 0.450725,0.21983 0.747547,0.21983 c 0.296818,0 0.575315,-0.0751 0.835494,-0.22532 c 0.260173,-0.15387 0.443395,-0.36088 0.549667,-0.62101 c 0.10993,-0.26378 0.164897,-0.64481 0.164901,-1.14308 l 0,-3.12701 l 0.989401,0 l 0,5.83634 l -0.884964,0" /> + d="M 35.617,417.76968 L 35.617,416.91237 C 35.162604,417.57184 34.545146,417.90158 33.764621,417.90158 C 33.42016,417.90158 33.09769,417.83558 32.797208,417.70374 C 32.500385,417.57184 32.278686,417.40697 32.13211,417.20914 C 31.989195,417.00763 31.888423,416.76216 31.829793,416.47272 C 31.789483,416.27855 31.769333,415.97079 31.769333,415.54946 L 31.769333,411.93334 L 32.758733,411.93334 L 32.758733,415.17026 C 32.758731,415.68685 32.778883,416.0349 32.819193,416.21443 C 32.881483,416.47456 33.013407,416.67972 33.214954,416.82993 C 33.416496,416.97648 33.665679,417.04976 33.962501,417.04976 C 34.259319,417.04976 34.537816,416.97466 34.797995,416.82444 C 35.058168,416.67057 35.24139,416.46356 35.347662,416.20343 C 35.457592,415.93965 35.512559,415.55862 35.512563,415.06035 L 35.512563,411.93334 L 36.501964,411.93334 L 36.501964,417.76968 L 35.617,417.76968" /> + d="M 37.661762,416.02757 L 38.64017,415.8737 C 38.69514,416.26572 38.847209,416.56615 39.096394,416.77498 C 39.349238,416.98381 39.701025,417.08823 40.151754,417.08823 C 40.606143,417.08823 40.943272,416.99663 41.163142,416.81345 C 41.383005,416.6266 41.492938,416.4086 41.492942,416.15947 C 41.492938,415.93598 41.395832,415.76012 41.201618,415.6319 C 41.06603,415.544 40.728901,415.43222 40.190231,415.29666 C 39.464668,415.11348 38.960807,414.95593 38.678646,414.82404 C 38.400147,414.68848 38.187609,414.50346 38.041032,414.26898 C 37.898118,414.03084 37.826662,413.76888 37.826662,413.48311 C 37.826662,413.22299 37.885292,412.98301 38.002555,412.76319 C 38.123481,412.5397 38.28655,412.35468 38.491759,412.20813 C 38.645665,412.09456 38.854538,411.9993 39.118379,411.92235 C 39.385883,411.84175 39.67171,411.80146 39.97586,411.80145 C 40.433913,411.80146 40.835171,411.86745 41.179631,411.99929 C 41.52775,412.13119 41.78426,412.31072 41.949166,412.53787 C 42.114061,412.76136 42.227658,413.06178 42.28996,413.43914 L 41.322545,413.57103 C 41.278565,413.27062 41.150313,413.03613 40.937778,412.8676 C 40.728901,412.69907 40.432082,412.6148 40.047317,412.6148 C 39.592924,412.6148 39.268621,412.6899 39.074407,412.84012 C 38.880189,412.99034 38.783082,413.1662 38.783083,413.3677 C 38.783082,413.49594 38.823393,413.61135 38.90401,413.71393 C 38.98463,413.82017 39.111049,413.90811 39.28328,413.97771 C 39.38222,414.01431 39.673541,414.09862 40.157251,414.23051 C 40.857157,414.41736 41.344528,414.57124 41.619366,414.69215 C 41.897858,414.80938 42.115894,414.98158 42.273469,415.20873 C 42.431036,415.43589 42.50982,415.71799 42.509826,416.05506 C 42.50982,416.3848 42.412716,416.69621 42.218501,416.98931 C 42.027946,417.27875 41.75128,417.50406 41.388505,417.66527 C 41.025722,417.82281 40.615303,417.90158 40.157251,417.90158 C 39.398708,417.90158 38.819726,417.74404 38.420303,417.42895 C 38.024541,417.11388 37.771694,416.64675 37.661762,416.02757" /> + d="M 47.682194,415.89018 L 48.704574,416.01658 C 48.543334,416.61377 48.244681,417.07724 47.808617,417.40697 C 47.372544,417.73671 46.815547,417.90158 46.137628,417.90158 C 45.28381,417.90158 44.605888,417.63962 44.103861,417.11571 C 43.605495,416.58813 43.356313,415.84988 43.356314,414.90097 C 43.356313,413.9191 43.609159,413.15704 44.114854,412.6148 C 44.620547,412.07258 45.276482,411.80146 46.082663,411.80145 C 46.863186,411.80146 47.500798,412.06707 47.995503,412.59832 C 48.490199,413.12956 48.737548,413.87697 48.737554,414.84052 C 48.737548,414.89912 48.735754,414.98708 48.732054,415.10432 L 44.378691,415.10432 C 44.415331,415.74547 44.596723,416.23641 44.922861,416.57714 C 45.248994,416.91787 45.655746,417.08823 46.143121,417.08823 C 46.505898,417.08823 46.815543,416.99293 47.072058,416.80246 C 47.328566,416.61195 47.531942,416.30785 47.68219,415.89018 M 44.433656,414.29097 L 47.693183,414.29097 C 47.649203,413.80002 47.524614,413.43182 47.319409,413.18635 C 47.004263,412.80532 46.595677,412.6148 46.093652,412.6148 C 45.639257,412.6148 45.256323,412.76685 44.944847,413.07094 C 44.637032,413.37503 44.466635,413.78171 44.433656,414.29097" /> + d="M 53.739527,417.76968 L 53.739527,417.03328 C 53.369413,417.61215 52.825242,417.90158 52.107016,417.90158 C 51.641628,417.90158 51.212887,417.77335 50.820794,417.51689 C 50.432361,417.26043 50.130045,416.90321 49.913843,416.44525 C 49.701304,415.98361 49.595035,415.45421 49.595036,414.85701 C 49.595035,414.27448 49.692146,413.7469 49.88636,413.27427 C 50.080576,412.79799 50.371898,412.43345 50.76033,412.18065 C 51.148761,411.92786 51.582996,411.80146 52.063042,411.80145 C 52.414825,411.80146 52.728135,411.87655 53.002973,412.02677 C 53.277803,412.17333 53.501334,412.36567 53.673567,412.60381 L 53.673567,409.71311 L 54.65747,409.71311 L 54.65747,417.76968 L 53.739527,417.76968 M 50.61192,414.85701 C 50.61192,415.60441 50.769489,416.16314 51.084635,416.53317 C 51.399775,416.90321 51.771716,417.08823 52.200459,417.08823 C 52.632861,417.08823 52.999304,416.91237 53.299793,416.56066 C 53.603938,416.20527 53.756011,415.66486 53.756016,414.93945 C 53.756011,414.14075 53.602106,413.55455 53.294295,413.18085 C 52.986479,412.80716 52.60721,412.62031 52.156484,412.6203 C 51.716749,412.62031 51.348472,412.79982 51.051654,413.15886 C 50.758496,413.51792 50.61192,414.08397 50.61192,414.85701" /> + transform="translate(-0.47525777,-36.122523)"> @@ -2400,254 +2372,254 @@ style="display:inline"> + transform="matrix(1.0095471,0,0,1.0763898,-142.7577,-23.226107)"> + transform="matrix(1.049406,0,0,1.1188878,-162.01338,-37.298718)"> + transform="matrix(1.0830555,0,0,1.1547652,-143.62608,-50.656378)"> + transform="matrix(0.99659066,0,0,1.0936248,-169.10999,-90.044225)"> + transform="matrix(1.0687763,0,0,1.1395406,-153.95309,-110.22277)"> + transform="matrix(1.0830555,0,0,1.0830555,-167.19044,-85.863098)"> @@ -2685,7 +2657,7 @@ @@ -2742,7 +2714,7 @@ ry="3.9999998" /> @@ -2796,11 +2768,11 @@ sodipodi:nodetypes="cc" inkscape:connector-curvature="0" id="path4785" - d="m 133.42882,312.44292 l -3.95142,7.77485" + d="M 133.42882,312.44292 L 129.4774,320.21777" style="fill:none;stroke:#000000;stroke-width:0.74074072px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /> @@ -2808,11 +2780,11 @@ sodipodi:nodetypes="cc" inkscape:connector-curvature="0" id="path4789" - d="m 149.24954,324.42277 l -6.3686,5.9558" + d="M 149.24954,324.42277 L 142.88094,330.37857" style="fill:none;stroke:#000000;stroke-width:0.74074072px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /> @@ -2826,12 +2798,12 @@ sodipodi:cy="347.5" sodipodi:rx="52.5" sodipodi:ry="52.5" - d="m 14.015468,318.08325 a 52.5,52.5 0 0 1 6.899844,-8.23708" + d="M 14.015468,318.08325 A 52.5,52.5 0 0 1 20.915312,309.84617" transform="matrix(0.95695029,0.08372205,-0.08414287,0.96175464,81.727104,24.47046)" sodipodi:open="true" /> @@ -2839,11 +2811,11 @@ sodipodi:nodetypes="cc" inkscape:connector-curvature="0" id="path4797" - d="m 98.60121,306.91389 l 1.360788,8.62041" + d="M 98.60121,306.91389 L 99.961998,315.5343" style="fill:none;stroke:#000000;stroke-width:0.74074072px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /> @@ -2851,11 +2823,11 @@ sodipodi:nodetypes="cc" inkscape:connector-curvature="0" id="path4801" - d="m 87.076675,310.01949 l 3.118798,8.1479" + d="M 87.076675,310.01949 L 90.195473,318.16739" style="fill:none;stroke:#000000;stroke-width:0.74074072px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /> @@ -2863,11 +2835,11 @@ sodipodi:nodetypes="cc" inkscape:connector-curvature="0" id="path4805" - d="m 76.44715,315.47142 l 4.734393,7.30915" + d="M 76.44715,315.47142 L 81.181543,322.78057" style="fill:none;stroke:#000000;stroke-width:0.74074072px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /> @@ -2888,11 +2860,11 @@ sodipodi:nodetypes="cc" inkscape:connector-curvature="0" id="path4809" - d="m 67.173673,323.02142 l 6.15024,6.165" + d="M 67.173673,323.02142 L 73.323913,329.18642" style="fill:none;stroke:#000000;stroke-width:0.74074072px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /> @@ -2900,7 +2872,7 @@ sodipodi:nodetypes="cc" inkscape:connector-curvature="0" id="path4813" - d="m 59.662758,332.34302 l 7.329767,4.72019" + d="M 59.662758,332.34302 L 66.992525,337.06321" style="fill:none;stroke:#000000;stroke-width:0.74074072px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /> @@ -2995,17 +2967,17 @@ inkscape:connector-curvature="0" id="path5240" style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:6px;line-height:125%;font-family:'Arial Narrow';-inkscape-font-specification:'Arial Narrow Bold Condensed';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none" - d="m 84.037888,342.20654 l 0,-1.11621 l -0.922852,0 l 0,-0.77051 l 0.922852,0 l 0,-1.11621 l 0.615234,0 l 0,1.11621 l 0.925781,0 l 0,0.77051 l -0.925781,0 l 0,1.11621 l -0.615234,0" /> + d="M 84.037888,342.20654 L 84.037888,341.09033 L 83.115036,341.09033 L 83.115036,340.31982 L 84.037888,340.31982 L 84.037888,339.20361 L 84.653122,339.20361 L 84.653122,340.31982 L 85.578903,340.31982 L 85.578903,341.09033 L 84.653122,341.09033 L 84.653122,342.20654 L 84.037888,342.20654" /> + d="M 87.720505,342.82471 L 87.046677,342.82471 L 87.046677,339.72217 C 86.794723,340.00537 86.503707,340.21338 86.17363,340.34619 L 86.17363,339.59912 C 86.361129,339.52292 86.555465,339.38721 86.756638,339.19189 C 86.957808,338.99463 87.097457,338.76807 87.175583,338.51221 L 87.720505,338.51221 L 87.720505,342.82471" /> + d="M 89.876755,338.51221 C 90.21855,338.51221 90.494917,338.6753 90.705856,339.00146 C 90.916791,339.32569 91.02226,339.89405 91.022263,340.70654 C 91.02226,341.51709 90.916791,342.08545 90.705856,342.41162 C 90.494917,342.73584 90.219527,342.89795 89.879684,342.89795 C 89.537887,342.89795 89.26152,342.73682 89.050583,342.41455 C 88.839645,342.09229 88.734176,341.52002 88.734177,340.69775 C 88.734176,339.89112 88.839645,339.32569 89.050583,339.00146 C 89.26152,338.6753 89.53691,338.51221 89.876755,338.51221 M 89.876755,339.19482 C 89.743941,339.19483 89.637496,339.28272 89.557419,339.4585 C 89.479289,339.63428 89.44023,340.0503 89.440231,340.70654 C 89.44023,341.36279 89.479291,341.77881 89.557419,341.95459 C 89.637499,342.12842 89.743941,342.21533 89.876755,342.21533 C 90.011519,342.21533 90.117964,342.12743 90.196091,341.95166 C 90.274211,341.77588 90.313276,341.36084 90.313278,340.70654 C 90.313276,340.0503 90.274218,339.63428 90.196091,339.4585 C 90.117961,339.28272 90.011519,339.19483 89.876755,339.19482" /> + d="M 93.76445,342.20654 L 93.76445,341.09033 L 92.841599,341.09033 L 92.841599,340.31982 L 93.76445,340.31982 L 93.76445,339.20361 L 94.379684,339.20361 L 94.379684,340.31982 L 95.305466,340.31982 L 95.305466,341.09033 L 94.379684,341.09033 L 94.379684,342.20654 L 93.76445,342.20654" /> + d="M 98.000778,342.06006 L 98.000778,342.82471 L 95.633591,342.82471 C 95.658981,342.53564 95.73613,342.26123 95.865036,342.00146 C 95.995895,341.73975 96.248824,341.39697 96.623825,340.97314 C 96.920699,340.63526 97.103316,340.40674 97.171677,340.2876 C 97.273237,340.11377 97.324019,339.93897 97.32402,339.76318 C 97.324019,339.57569 97.28203,339.43409 97.198044,339.33838 C 97.114054,339.24268 97.003706,339.19483 96.866989,339.19482 C 96.56816,339.19483 96.407027,339.41846 96.383591,339.86572 L 95.712692,339.78372 C 95.753712,339.34622 95.874801,339.02494 96.075974,338.81985 C 96.279098,338.61478 96.548629,338.51224 96.884567,338.51224 C 97.253706,338.51224 97.532026,338.63236 97.719528,338.87259 C 97.907026,339.11283 98.000776,339.38822 98.000778,339.69876 C 98.000776,339.87454 97.976358,340.04544 97.927538,340.21146 C 97.880658,340.37552 97.807419,340.54154 97.707811,340.7095 C 97.608201,340.87552 97.442185,341.08841 97.209765,341.34817 C 96.992966,341.59232 96.855271,341.75345 96.796679,341.83157 C 96.740039,341.90967 96.694138,341.98587 96.658983,342.06009 L 98.00078,342.06009" /> + d="M 99.603317,338.51221 C 99.945112,338.51221 100.22148,338.6753 100.43242,339.00146 C 100.64335,339.32569 100.74882,339.89405 100.74883,340.70654 C 100.74882,341.51709 100.64335,342.08545 100.43242,342.41162 C 100.22148,342.73584 99.946089,342.89795 99.606247,342.89795 C 99.264449,342.89795 98.988082,342.73682 98.777145,342.41455 C 98.566208,342.09229 98.460739,341.52002 98.460739,340.69775 C 98.460739,339.89112 98.566208,339.32569 98.777145,339.00146 C 98.988082,338.6753 99.263473,338.51221 99.603317,338.51221 M 99.603317,339.19482 C 99.470504,339.19483 99.364058,339.28272 99.283981,339.4585 C 99.205851,339.63428 99.166793,340.0503 99.166794,340.70654 C 99.166793,341.36279 99.205854,341.77881 99.283981,341.95459 C 99.364061,342.12842 99.470504,342.21533 99.603317,342.21533 C 99.738081,342.21533 99.844527,342.12743 99.922653,341.95166 C 100.00078,341.77588 100.03984,341.36084 100.03984,340.70654 C 100.03984,340.0503 100.00074,339.63428 99.922653,339.4585 C 99.844523,339.28272 99.738081,339.19483 99.603317,339.19482" /> + d="M 103.49101,342.20654 L 103.49101,341.09033 L 102.56816,341.09033 L 102.56816,340.31982 L 103.49101,340.31982 L 103.49101,339.20361 L 104.10625,339.20361 L 104.10625,340.31982 L 105.03203,340.31982 L 105.03203,341.09033 L 104.10625,341.09033 L 104.10625,342.20654 L 103.49101,342.20654" /> + d="M 105.42168,341.68506 L 106.075,341.58836 C 106.0926,341.79148 106.1482,341.94676 106.24199,342.05418 C 106.33569,342.1616 106.44609,342.21531 106.57304,342.21531 C 106.71171,342.21531 106.8289,342.15181 106.92461,342.02488 C 107.02031,341.89793 107.06816,341.72215 107.06816,341.49754 C 107.06816,341.28856 107.02226,341.12449 106.93047,341.00535 C 106.83867,340.88621 106.72734,340.82664 106.59648,340.82664 C 106.51058,340.82664 106.408,340.84714 106.28886,340.88814 L 106.36216,340.21725 C 106.53598,340.22125 106.67368,340.17425 106.77524,340.07662 C 106.87484,339.97902 106.92465,339.84127 106.92466,339.66353 C 106.92465,339.5151 106.88856,339.39889 106.81626,339.3149 C 106.74396,339.2309 106.65122,339.18893 106.53794,339.18892 C 106.42466,339.18893 106.32602,339.23772 106.24204,339.33541 C 106.16004,339.43111 106.11118,339.57369 106.09555,339.76314 L 105.47153,339.63424 C 105.53593,339.24166 105.66196,338.95651 105.84946,338.77877 C 106.03696,338.60104 106.27329,338.51217 106.55845,338.51217 C 106.87876,338.51217 107.13266,338.62643 107.32016,338.85494 C 107.50961,339.08346 107.60434,339.33639 107.60434,339.61373 C 107.60434,339.80123 107.56134,339.97018 107.47544,340.12057 C 107.39144,340.27096 107.2645,340.40279 107.09458,340.51607 C 107.29184,340.56877 107.452,340.68502 107.57505,340.86471 C 107.70004,341.0444 107.76254,341.269 107.76255,341.53853 C 107.76254,341.93111 107.64536,342.25631 107.41098,342.51412 C 107.17856,342.76998 106.90122,342.89791 106.57895,342.89791 C 106.27036,342.89791 106.00864,342.78951 105.7938,342.57271 C 105.58091,342.35592 105.45688,342.06002 105.42173,341.68502" /> + d="M 109.32988,338.51221 C 109.67167,338.51221 109.94804,338.6753 110.15898,339.00146 C 110.36992,339.32569 110.47539,339.89405 110.47539,340.70654 C 110.47539,341.51709 110.36992,342.08545 110.15898,342.41162 C 109.94804,342.73584 109.67265,342.89795 109.33281,342.89795 C 108.99101,342.89795 108.71464,342.73682 108.50371,342.41455 C 108.29277,342.09229 108.1873,341.52002 108.1873,340.69775 C 108.1873,339.89112 108.29277,339.32569 108.50371,339.00146 C 108.71464,338.6753 108.99004,338.51221 109.32988,338.51221 M 109.32988,339.19482 C 109.19707,339.19483 109.09062,339.28272 109.01054,339.4585 C 108.93244,339.63428 108.89336,340.0503 108.89336,340.70654 C 108.89336,341.36279 108.93246,341.77881 109.01054,341.95459 C 109.09064,342.12842 109.19707,342.21533 109.32988,342.21533 C 109.46464,342.21533 109.57109,342.12743 109.64922,341.95166 C 109.72732,341.77588 109.7664,341.36084 109.7664,340.70654 C 109.7664,340.0503 109.7273,339.63428 109.64922,339.4585 C 109.57112,339.28272 109.46464,339.19483 109.32988,339.19482" /> + d="M 113.21758,342.20654 L 113.21758,341.09033 L 112.29472,341.09033 L 112.29472,340.31982 L 113.21758,340.31982 L 113.21758,339.20361 L 113.83281,339.20361 L 113.83281,340.31982 L 114.75859,340.31982 L 114.75859,341.09033 L 113.83281,341.09033 L 113.83281,342.20654 L 113.21758,342.20654" /> + d="M 116.4959,342.82471 L 116.4959,341.96045 L 115.05449,341.96045 L 115.05449,341.23975 L 116.58086,338.51221 L 117.14922,338.51221 L 117.14922,341.23682 L 117.58574,341.23682 L 117.58574,341.96045 L 117.14922,341.96045 L 117.14922,342.82471 L 116.4959,342.82471 M 116.4959,341.23682 L 116.4959,339.76904 L 115.6873,341.23682 L 116.4959,341.23682" /> + d="M 119.05644,338.51221 C 119.39824,338.51221 119.6746,338.6753 119.88554,339.00146 C 120.09648,339.32569 120.20195,339.89405 120.20195,340.70654 C 120.20195,341.51709 120.09648,342.08545 119.88554,342.41162 C 119.6746,342.73584 119.39921,342.89795 119.05937,342.89795 C 118.71757,342.89795 118.44121,342.73682 118.23027,342.41455 C 118.01933,342.09229 117.91386,341.52002 117.91386,340.69775 C 117.91386,339.89112 118.01933,339.32569 118.23027,339.00146 C 118.44121,338.6753 118.7166,338.51221 119.05644,338.51221 M 119.05644,339.19482 C 118.92363,339.19483 118.81718,339.28272 118.73711,339.4585 C 118.65901,339.63428 118.61992,340.0503 118.61992,340.70654 C 118.61992,341.36279 118.65902,341.77881 118.73711,341.95459 C 118.81721,342.12842 118.92363,342.21533 119.05644,342.21533 C 119.19121,342.21533 119.29765,342.12743 119.37578,341.95166 C 119.45388,341.77588 119.49296,341.36084 119.49297,340.70654 C 119.49296,340.0503 119.45387,339.63428 119.37578,339.4585 C 119.29768,339.28272 119.19121,339.19483 119.05644,339.19482" /> + d="M 122.94414,342.20654 L 122.94414,341.09033 L 122.02129,341.09033 L 122.02129,340.31982 L 122.94414,340.31982 L 122.94414,339.20361 L 123.55937,339.20361 L 123.55937,340.31982 L 124.48515,340.31982 L 124.48515,341.09033 L 123.55937,341.09033 L 123.55937,342.20654 L 122.94414,342.20654" /> + d="M 124.90996,341.72021 L 125.58379,341.63521 C 125.60139,341.82271 125.65899,341.97018 125.75664,342.0776 C 125.85434,342.18502 125.96171,342.23873 126.0789,342.23873 C 126.21757,342.23873 126.33671,342.17033 126.43633,342.03365 C 126.53593,341.89498 126.58574,341.68307 126.58574,341.39791 C 126.58574,341.12838 126.53594,340.92916 126.43633,340.80025 C 126.33863,340.67135 126.21367,340.6069 126.06133,340.60689 C 125.86796,340.6069 125.69414,340.71139 125.53984,340.92037 L 124.99199,340.82367 L 125.33769,338.58832 L 127.12187,338.58832 L 127.12187,339.35883 L 125.85039,339.35883 L 125.74199,340.08832 C 125.89433,339.99652 126.04863,339.95063 126.20488,339.95062 C 126.48222,339.95063 126.71757,340.06 126.91093,340.27875 C 127.15507,340.55805 127.27714,340.92621 127.27715,341.38324 C 127.27714,341.76019 127.17265,342.10687 126.96367,342.42328 C 126.75664,342.73969 126.45976,342.89789 126.07304,342.89789 C 125.76054,342.89789 125.49882,342.79633 125.28789,342.5932 C 125.0789,342.38812 124.95293,342.09711 124.90996,341.72015" /> + d="M 128.783,338.51221 C 129.1248,338.51221 129.40117,338.6753 129.61211,339.00146 C 129.82304,339.32569 129.92851,339.89405 129.92851,340.70654 C 129.92851,341.51709 129.82304,342.08545 129.61211,342.41162 C 129.40117,342.73584 129.12578,342.89795 128.78593,342.89795 C 128.44414,342.89795 128.16777,342.73682 127.95683,342.41455 C 127.7459,342.09229 127.64043,341.52002 127.64043,340.69775 C 127.64043,339.89112 127.7459,339.32569 127.95683,339.00146 C 128.16777,338.6753 128.44316,338.51221 128.783,338.51221 M 128.783,339.19482 C 128.65019,339.19483 128.54375,339.28272 128.46367,339.4585 C 128.38557,339.63428 128.34648,340.0503 128.34648,340.70654 C 128.34648,341.36279 128.38558,341.77881 128.46367,341.95459 C 128.54377,342.12842 128.65019,342.21533 128.783,342.21533 C 128.91777,342.21533 129.02421,342.12743 129.10234,341.95166 C 129.18044,341.77588 129.21953,341.36084 129.21953,340.70654 C 129.21953,340.0503 129.18043,339.63428 129.10234,339.4585 C 129.02424,339.28272 128.91777,339.19483 128.783,339.19482" /> + d="M 132.6707,342.20654 L 132.6707,341.09033 L 131.74785,341.09033 L 131.74785,340.31982 L 132.6707,340.31982 L 132.6707,339.20361 L 133.28593,339.20361 L 133.28593,340.31982 L 134.21172,340.31982 L 134.21172,341.09033 L 133.28593,341.09033 L 133.28593,342.20654 L 132.6707,342.20654" /> + d="M 136.91289,339.58154 L 136.25957,339.66944 C 136.22837,339.34913 136.10039,339.18898 135.87578,339.18897 C 135.72929,339.18898 135.60722,339.26907 135.50957,339.42921 C 135.41387,339.58937 135.35332,339.91261 135.32793,340.39894 C 135.41193,340.27784 135.50566,340.18702 135.60918,340.12647 C 135.71269,340.06597 135.82695,340.03567 135.95195,340.03567 C 136.22734,340.03568 136.46757,340.16458 136.67265,340.42239 C 136.87773,340.67825 136.98027,341.01907 136.98027,341.44485 C 136.98027,341.89798 136.87187,342.25345 136.65508,342.51126 C 136.43828,342.76907 136.16972,342.89798 135.84941,342.89798 C 135.49785,342.89798 135.20586,342.73099 134.97343,342.397 C 134.74297,342.06107 134.62773,341.5054 134.62773,340.73001 C 134.62773,339.9429 134.74785,339.3765 134.98808,339.03079 C 135.22832,338.68509 135.53691,338.51224 135.91386,338.51224 C 136.17363,338.51224 136.39238,338.60114 136.57011,338.77884 C 136.7498,338.95462 136.86406,339.2222 136.91289,339.58157 M 135.38652,341.37747 C 135.38652,341.64896 135.43632,341.85696 135.53593,342.00149 C 135.6375,342.14407 135.75273,342.21536 135.88164,342.21536 C 136.00664,342.21536 136.11015,342.15576 136.19218,342.03665 C 136.27618,341.91751 136.31816,341.7222 136.31816,341.45071 C 136.31816,341.16947 136.27326,340.96439 136.1834,340.83548 C 136.0935,340.70658 135.98222,340.64212 135.84941,340.64212 C 135.7205,340.64212 135.61113,340.70362 135.52129,340.82669 C 135.43149,340.94974 135.38652,341.13333 135.38652,341.37747" /> + d="M 138.50957,338.51221 C 138.85136,338.51221 139.12773,338.6753 139.33867,339.00146 C 139.5496,339.32569 139.65507,339.89405 139.65508,340.70654 C 139.65507,341.51709 139.5496,342.08545 139.33867,342.41162 C 139.12773,342.73584 138.85234,342.89795 138.5125,342.89795 C 138.1707,342.89795 137.89433,342.73682 137.6834,342.41455 C 137.47246,342.09229 137.36699,341.52002 137.36699,340.69775 C 137.36699,339.89112 137.47246,339.32569 137.6834,339.00146 C 137.89433,338.6753 138.16972,338.51221 138.50957,338.51221 M 138.50957,339.19482 C 138.37675,339.19483 138.27031,339.28272 138.19023,339.4585 C 138.11213,339.63428 138.07304,340.0503 138.07304,340.70654 C 138.07304,341.36279 138.11214,341.77881 138.19023,341.95459 C 138.27033,342.12842 138.37675,342.21533 138.50957,342.21533 C 138.64433,342.21533 138.75078,342.12743 138.8289,341.95166 C 138.907,341.77588 138.94609,341.36084 138.94609,340.70654 C 138.94609,340.0503 138.90699,339.63428 138.8289,339.4585 C 138.7508,339.28272 138.64433,339.19483 138.50957,339.19482" /> @@ -3169,11 +3141,11 @@ sodipodi:nodetypes="ccccccc" inkscape:connector-curvature="0" id="path5524" - d="m 105.81964,316.81754 l -1.74737,-6.03282 l -1.25263,6.18907 l 1.25,24.24219 l 2.75,24.16408 l 0.25,-24.32031 z" + d="M 105.81964,316.81754 L 104.07227,310.78472 L 102.81964,316.97379 L 104.06964,341.21598 L 106.81964,365.38006 L 107.06964,341.05975 Z" style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:none;stroke:#000000;stroke-width:0.44444445;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate" /> @@ -3181,7 +3153,7 @@ sodipodi:nodetypes="cc" inkscape:connector-curvature="0" id="path5528" - d="m 104.08793,312.53421 l 2.73969,52.85567" + d="M 104.08793,312.53421 L 106.82762,365.38988" style="fill:none;stroke:#000000;stroke-width:0.22222222;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> @@ -3195,7 +3167,7 @@ transform="matrix(1.35,0,0,1.35,-232.42552,-108.3337)"> @@ -3325,31 +3297,31 @@ id="oplm-id-label" transform="translate(-172,-5.5678281)"> @@ -3358,46 +3330,81 @@ id="rx-quality-label" transform="translate(-20.43483,0)"> + + + + + + + + + id="rx-quality-text" + transform="translate(0,-2)"> + + + + + + + + + + + Impossible de passer les arguments de la ligne de commande à l'instance en cours d'exécution. Elle semble ne pas répondre. - + + Failed to open log file %1 + Échec de l'ouverture du fichier log %1 + + + Could not find 'Core.pluginspec' in %1 [Platypus]Ajout de "est" 'Core.pluginspec' est introuvable dans %1 @@ -1446,17 +1451,17 @@ Raison : %3 Welcome::WelcomeMode - + Welcome Accueil - + Update Available: %1 Mise à jour disponible : %1 - + %1 Version: %2 %1 Version: %2 @@ -1968,54 +1973,6 @@ Raison : %3 Utiliser OpenGL - - ModelViewOptionsPage - - - Form - Formulaire - - - - 3D model: - Modèle 3D : - - - - Background image: - Image d'arrière plan : - - - - VBO allow for performance gains for GPUs that support it (most cards). This may cause cards with faulty drivers to crash. - Les VBOs (de l'anglais Vertex Buffer Object dont une traduction pourrait être objet tampon de vertex) @Wikipedia - VBO permet des gains de performance avec les cartes graphiques le supportant (la plupart). Cela peut entraîner des plantages avec des pilotes défectueux. - - - - Enable VBOs: - Activer les VBOs : - - - - Select the image that is shown in the background. - Sélectionner l'image affichée en fond. - - - - Select the 3D model file here. - Sélectionner ici le modèle 3D. - - - - Click to enable the use of Vertical Blanking. -It is not enabled by default because some graphic cards do not -support it, and crash the GCS. Enabling improves performance, though, so you can experiment at your own risk. - Cocher pour activer VBO. -Ce n'est pas activé par défaut car certaines cartes ne le supportent pas et plantent GCS. -Cela améliore les performances, mais c'est à utiliser à vos risques et périls. - - NotifyPluginOptionsPage @@ -2515,6 +2472,21 @@ p, li { white-space: pre-wrap; } Default Max Update Rate Fréquence d'Actualisation Maximale par Défaut + + + Waypoint Options + Options Waypoint + + + + Default relative Altitude + Altitude relative par défaut + + + + Default Velocity + Vitesse par défaut + ScopeGadgetOptionsPage @@ -2576,7 +2548,6 @@ p, li { white-space: pre-wrap; } Add a new curve to the scope, or update it if the UAVObject and UAVField is the same. - Oscilloscope ? Ajoute une nouvelle courbe au graphique, ou l'actualise si UAVObject et UAVField sont identiques. @@ -2595,12 +2566,6 @@ p, li { white-space: pre-wrap; } Y-axis scale factor: Facteur d'échelle Axe Y : - - - Math window size - Typo Should be fixed in code add ":" like others in form - Plage calcul : - samples @@ -2652,6 +2617,11 @@ p, li { white-space: pre-wrap; } Remove Supprimer + + + Math window size: + Plage calcul : + SystemHealthGadgetOptionsPage @@ -2723,6 +2693,16 @@ p, li { white-space: pre-wrap; } This space shows a description of the selected UAVObject. Cet espace affiche une description de l'UAVObject sélectionné. + + + type filter text + entrez le mot à rechercher + + + + Clear + Effacer + UAVObjectBrowserOptionsPage @@ -2758,14 +2738,6 @@ uniquement lorsque les valeurs changent Couleur d'objet inconnu : - - QuaZipFile - - - ZIP/UNZIP API error %1 - Erreur %1 de l'API ZIP/UNZIP - - ConfigGadgetFactory @@ -2799,7 +2771,7 @@ uniquement lorsque les valeurs changent Core::UAVGadgetInstanceManager - + Migrating UAVGadgetConfigurations from version 1.1.0 to Migration des configurations UAVGadget depuis la version 1.1.0 vers @@ -2863,29 +2835,6 @@ uniquement lorsque les valeurs changent Simulation HITL - - ModelViewGadgetOptionsPage - - - 3D model (*.dae *.3ds) - Modèle 3D (*.dae *.3ds) - - - - Choose 3D model - Choisir le modèle 3D - - - - Images (*.png *.jpg *.bmp *.xpm) - - - - - Choose background image - Choisir l'image d'arrière plan - - NotifyPluginFactory @@ -2897,7 +2846,7 @@ uniquement lorsque les valeurs changent OPMapGadgetWidget - + &Zoom &Zoom @@ -3380,7 +3329,7 @@ uniquement lorsque les valeurs changent UAVObjectTreeModel - + Property Propriété @@ -3395,17 +3344,17 @@ uniquement lorsque les valeurs changent Unité - + Settings Paramètres - + Data Objects Objets Données - + Meta Data Métadonnées @@ -3521,14 +3470,6 @@ uniquement lorsque les valeurs changent - - TelemetryMonitor - - - Starting to retrieve meta and settings objects from the autopilot (%1 objects) - Démarrage de la récupération des objets meta et paramètres depuis l'autopilote (%1 objets) - - DialGadgetOptionsPage @@ -4002,47 +3943,7 @@ uniquement lorsque les valeurs changent LibrePilot GCS Edit Waypoint - Éditeur Waypoint LibrePilot GCS - - - - opmap_overlay_widget - - - Form - Formulaire - - - - labelStatus - Pas toucher - - - - - %v - Pas toucher - - - - - opmap_statusbar_widget - - - Form - Formulaire - - - - labelStatus - Pas toucher - - - - - %v - Pas toucher - + Éditeur Waypoint LibrePilot GCS @@ -4218,7 +4119,7 @@ uniquement lorsque les valeurs changent Tous les Gadgets - + GCS Settings file (*.xml) Fichier Paramètres GCS (*.xml) @@ -4259,12 +4160,7 @@ uniquement lorsque les valeurs changent . Redémarrer le programme. - - http://wiki.openpilot.org/x/OQBj - - - - + All your settings will be deleted! Tous vos réglages seront effacés ! @@ -4536,36 +4432,6 @@ uniquement lorsque les valeurs changent Attitude Tuning: Réglage Attitude : - - - objname:RelayTuningSettings - Pas toucher ! - - - - - fieldname:RateGain - Pas toucher ! - - - - - scale:0.01 - Pas toucher ! - - - - - haslimits:no - Pas toucher ! - - - - - fieldname:AttitudeGain - Pas toucher ! - - Measured Properties @@ -4582,30 +4448,6 @@ uniquement lorsque les valeurs changent 0 - - - objname:RelayTuning - Pas toucher ! - - - - - fieldname:Period - Pas toucher ! - - - - - element:Roll - Pas toucher ! - - - - - fieldname:Gain - Pas toucher ! - - Period (ms) @@ -4621,12 +4463,6 @@ uniquement lorsque les valeurs changent Pitch - - - element:Pitch - Pas toucher ! - - Computed Values @@ -4667,12 +4503,6 @@ uniquement lorsque les valeurs changent Step Size Taille Sautillements - - - fieldname:Amplitude - Pas toucher ! - - The Apply and Save buttons below save the autotuning settings which @@ -4690,18 +4520,6 @@ Useful if you have accidentally changed some settings. Reload Board Data Recharger Données Carte - - - button:reload - Pas toucher - - - - - buttongroup:10 - Pas toucher - - Send settings to the board but do not save to the non-volatile memory @@ -4712,12 +4530,6 @@ Useful if you have accidentally changed some settings. Apply Appliquer - - - button:apply - Pas toucher ! - - Send settings to the board and save to the non-volatile memory @@ -4730,18 +4542,17 @@ Useful if you have accidentally changed some settings. - button:save - Pas toucher ! - + After enabling the module, you must power cycle before using and configuring. + Après activation du module, vous devez redémarrer la carte avant de l'utiliser et le configurer. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Lucida Grande'; font-size:20pt; font-weight:600; color:#ff0000;">WARNING:</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Lucida Grande'; font-size:13pt;"></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Lucida Grande'; font-size:13pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Lucida Grande'; font-size:13pt;"><br /></span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Lucida Grande'; font-size:13pt;"><br /></span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Lucida Grande'; font-size:13pt;">This is an experimental plugin for the GCS that is going to make your aircraft shake, etc, so test with lots of space and be </span><span style=" font-family:'Lucida Grande'; font-size:13pt; font-weight:600;">very very wary</span><span style=" font-family:'Lucida Grande'; font-size:13pt;"> for it creating bad tuning values.  Basically there is no reason to think this will work at all.<br /><br />To use autotuning, here are the steps:<br /></span></p> @@ -4767,11 +4578,6 @@ p, li { white-space: pre-wrap; } <li style=" font-family:'Lucida Grande'; font-size:13pt;" style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Tester les nouveau paramètres en vol.</li> <li style=" font-family:'Lucida Grande'; font-size:13pt;" style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Si vous êtes prêt à continuer, cochez <span style=" font-style:italic;">Activer le module Autotune</span> ci-dessus, <span style=" font-style:italic;">enregistrez</span> et passez à l'onglet suivant.</li></ul></body></html> - - - After enabling the module, you must power cycle before using and configuring. - Après activation du module, vous devez redémarrer la carte avant de l'utiliser et le configurer. - CameraStabilizationWidget @@ -4815,42 +4621,6 @@ have to define channel output range using Output configuration tab. Cette valeur doit être ajustée en fonction de la nacelle et du servo. Vous devez également ajuster la plage de sortie du canal dans l'onglet Output. - - - objname:CameraStabSettings - Pas toucher ! - - - - - fieldname:OutputRange - Pas toucher ! - - - - - element:Yaw - Pas toucher ! - - - - - haslimits:no - Pas toucher ! - - - - - scale:1 - Pas toucher ! - - - - - buttongroup:1 - Pas toucher ! - - Camera pitch angle for 100% output value, deg. @@ -4861,12 +4631,6 @@ have to define channel output range using Output configuration tab. Cette valeur doit être ajustée en fonction de la nacelle et du servo. Vous devez également ajuster la plage de sortie du canal dans l'onglet Output. - - - element:Pitch - Pas toucher ! - - Camera roll angle for 100% output value, deg. @@ -4877,12 +4641,6 @@ have to define channel output range using Output configuration tab. Cette valeur doit être ajustée en fonction de la nacelle et du servo. Vous devez également ajuster la plage de sortie du canal dans l'onglet Output. - - - element:Roll - Pas toucher ! - - Yaw output channel for camera gimbal @@ -4941,12 +4699,6 @@ Don't forget to map this channel using Input configuration tab. N'oubliez pas de déclarer ce canal dans l'onglet Input. - - - fieldname:Input - Pas toucher ! - - Input channel to control camera pitch @@ -4981,12 +4733,6 @@ AxisLock: camera remembers tracking attitude. Input controls the rate of deflect Attitude: La caméra reste de niveau sur les axes. L'entrée contrôle la déviation angulaire. AxisLock: La caméra se souvient de l'orientation. L'entrée contrôle la vitesse de la correction. - - - fieldname:StabilizationMode - Pas toucher ! - - Attitude @@ -4998,29 +4744,11 @@ AxisLock: La caméra se souvient de l'orientation. L'entrée contrôle Maximum camera yaw deflection for 100% input in Attitude mode, deg. Déviation maximale de la caméra sur le Yaw pour une entrée de 100% en mode Attitude, en degrés. - - - fieldname:InputRange - Pas toucher ! - - Maximum camera yaw rate for 100% input in AxisLock mode, deg/s. Vitesse maximale sur le Yaw pour une entrée de 100% en mode AxisLock, en degrés/s. - - - fieldname:InputRate - Pas toucher ! - - - - - fieldname:ResponseTime - Pas toucher ! - - Maximum camera pitch deflection for 100% input in Attitude mode, deg. @@ -5075,12 +4803,6 @@ dépendante de la valeur d'entrée. Si vous avez une dérive dans vos contrôles Tx, vous pouvez augmenter cette valeur. - - - fieldname:MaxAxisLockRate - Pas toucher ! - - Messages @@ -5091,12 +4813,6 @@ valeur. Ctrl+S - - - button:help - Pas toucher ! - - Load default CameraStabilization settings except output channels into GCS. @@ -5113,12 +4829,6 @@ sur Appliquer ou Enregistrer par la suite. Reset To Defaults Restaurer les paramètres par défaut - - - button:default - Pas toucher ! - - Reloads saved CameraStabilization settings except output channels @@ -5138,12 +4848,6 @@ sur Appliquer ou Enregistrer par la suite. Reload Board Data Recharger Données Carte - - - button:reload - Pas toucher ! - - Send settings to the board but do not save to the non-volatile memory @@ -5154,12 +4858,6 @@ sur Appliquer ou Enregistrer par la suite. Apply Appliquer - - - button:apply - Pas toucher ! - - Send settings to the board and save to the non-volatile memory @@ -5170,12 +4868,6 @@ sur Appliquer ou Enregistrer par la suite. Save Enregistrer - - - button:save - Pas toucher ! - - Output Range (Angle) @@ -5270,12 +4962,6 @@ Plage : 0-25, 0 désactive feed forward sur l'axe (defaut). 2-7 est une bonne valeur de départ. Une valeur trop élevée peut griller votre servo ! - - - fieldname:FeedForward - Pas toucher ! - - Pitch servo feed forward acceleration @@ -5320,12 +5006,6 @@ Range: 0-50ms, default is 5. Plage : 0-50ms, 5 par défaut. - - - fieldname:AccelTime - Pas toucher ! - - Pitch servo feed forward acceleration time constant @@ -5358,12 +5038,6 @@ Range: 0-50ms, default is 5. Plage : 0-50ms, 5 par défaut. - - - fieldname:DecelTime - Pas toucher ! - - Pitch servo feed forward deceleration time constant @@ -5398,12 +5072,6 @@ Generic type provides no limit. Utilisé pour limiter l'accélération feed forward aux grands angles. Le type générique ne propose pas de limitation. - - - fieldname:GimbalType - Pas toucher ! - - Yaw-Roll-Pitch @@ -5427,16 +5095,10 @@ Plage : 0-1000, 500 par défaut. La même valeur est utilisé pour tous les axes. - - - fieldname:MaxAccel - Pas toucher ! - - Input configuration also provides smoothing for controls. Look for RT options on the RC Input tab. - La configuration des entrées fournit également un lissage des contrôles. Recherchez les options RT dans l'onglet Entrées RC. + La configuration des entrées fournit également un lissage des contrôles. Recherchez les options RT dans l'onglet Entrées Télécommande. @@ -5471,11 +5133,6 @@ La même valeur est utilisé pour tous les axes. GPS speed: Vitesse GPS : - - - ComUsbBridge speed: - Vitesse COMUsbBridge : - Select the speed here. @@ -5511,27 +5168,27 @@ Méfiez-vous de ne pas vous verrouiller l'accès ! USB HID Port - + Fonction HID USB USB VCP Port - + Fonction HID USB Main Port - + Port Main Flexi Port - + Port Flexi Receiver Port - + Port Récepteur @@ -5563,11 +5220,6 @@ Méfiez-vous de ne pas vous verrouiller l'accès ! Calibration Calibration - - - Place aircraft very flat, and then click level to compute the accelerometer and gyro bias - Placer l'appareil bien à plat et cliquer ensuite sur Niveau pour calculer les ajustements des accéléromètres et gyroscopes - Launch horizontal calibration. @@ -5578,19 +5230,6 @@ Méfiez-vous de ne pas vous verrouiller l'accès ! Level Niveau - - - If enabled, a fast recalibration of gyro zero point will be done -whenever the frame is armed. Do not move the airframe while -arming it in that case! - Si activé, une recalibration rapide des gyros est effectuée à chaque fois que -la carte est armée. Dans ce cas ne bougez pas l'appareil lors de l'armement ! - - - - Zero gyros while arming aircraft - Mettre les gyros à zéro lors de l'armement - Accelerometer filtering. @@ -5648,281 +5287,8 @@ accéléromètres dans la mémoire Flash de la carte. Roll - - - - - Yaw - - - - - Pitch - - - - - ccpmWidget - - - Form - Formulaire - - - - Swashplate config: - Configuration plateau cyclique : - - - - Select aircraft type here - Sélectionner ici le type d'appareil - - - - Basic settings - Paramètres de base - - - - Tail Rotor - Rotor Queue - - - - Engine - Moteur - - - - Servo W - - - Servo X - - - - - Front - Avant - - - - Right - Droite - - - - Rear - Arrière - - - - Left - Gauche - - - - 1st Servo - 1er Servo - - - - Servo Z - - - - - Servo Y - - - - - Swashplate Servo Angles - Angles Servos Plateau - - - - Angle W - - - - - Angle X - - - - - Angle Y - - - - - Angle Z - - - - - Correction Angle - Angle Correction - - - - CCPM Options - Options CCPM - - - - Collective Pass through - - - - - Link Roll/Pitch - Lier Roll/Pitch - - - - Link Cyclic/Collective - Lier Cyclique/Collectif - - - - Swashplate Layout - Agencement Plateau Cyclique - - - - REVO - - - - - 100% - - - - - 0% - - - - - CCPM - CCPM - - - - Collective - Collectif - - - - Cyclic - Cyclique - - - - Pitch - - - - - Roll - - - - - Swashplate Levelling - Niveau Plateau Cyclique - - - - Commands - Commandes - - - - Start - Démarrer - - - - Next - Suivant - - - - Cancel - Annuler - - - - Finish - Terminer - - - - Status - Statut - - - - Neutral - Neutre - - - - Max - Maxi - - - - Min - Mini - - - - Verify - Vérifier - - - - Position - Position - - - - Swashplate Adjustment - Réglage Plateau Cyclique - - - - Curve settings - Paramètres de la courbe - - - - Advanced settings - Paramètres avancés - - - - Channel - Canal - - - - Curve 1 - Courbe 1 - - - - Curve 2 - Courbe 2 - Yaw @@ -5930,72 +5296,36 @@ accéléromètres dans la mémoire Flash de la carte. - - + Pitch - Motor outputs - Sorties moteurs + Place vehicle very flat, and then click level to compute the accelerometer and gyro bias + Placer l'appareil bien à plat et cliquer ensuite sur Niveau pour calculer les ajustements des accéléromètres et gyroscopes - Swashplate outputs - Sorties plateau cyclique - - - - defaultattitude - - - Form - Formulaire + If enabled, this option prevents gyro initialization while the board is moving. + Si activé, cette option empêche l'initialisation des gyros lorsque la carte est en mouvement. - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt; font-weight:600;">Attitude Calibration</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu'; font-size:11pt; font-weight:600;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt;">This panel will be updated to provide the relevant controls to let you calibrate your flight controller, depending on the board which is detected once telemetry is connected and running.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu'; font-size:11pt;"><br /></p></body></html> - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt; font-weight:600;">Calibration Attitude</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu'; font-size:11pt; font-weight:600;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt;">Ce panneau sera mis à jour pour vous fournir les contrôles pertinents afin de vous permettre de calibrer votre contrôleur de vol en fonction de la carte détectée, une fois que la télémétrie est connectée et en cours d'exécution.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu'; font-size:11pt;"><br /></p></body></html> - - - - defaulthwsettings - - - Form - Formulaire + Wait until the board is steady + Attendre jusqu'à ce que la carte soit stable - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt; font-weight:600;">Hardware Configuration</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu'; font-size:11pt; font-weight:600;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt;">This panel will be updated to provide the relevant controls to let you configure your hardware once telemetry is connected and running.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu'; font-size:11pt;"><br /></p></body></html> - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt; font-weight:600;">Configuration Matérielle</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu'; font-size:11pt; font-weight:600;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt;">Ce panneau sera mis à jour pour vous fournir les contrôles pertinents afin de vous permettre de configurer votre matériel, une fois que la télémétrie est connectée et en cours d'exécution.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu'; font-size:11pt;"><br /></p></body></html> + If enabled, a fast recalibration of gyro zero point will be done +whenever the board is armed. Do not move the vehicle while +arming it in that case! + Si activé, une recalibration rapide des gyros est effectuée à chaque fois que +la carte est armée. Dans ce cas ne bougez pas l'appareil lors de l'armement ! + + + + Zero gyros while arming + Mettre les gyros à zéro lors de l'armement @@ -6005,11 +5335,6 @@ p, li { white-space: pre-wrap; } Form Formulaire - - - RC Input - Entrées RC - Roll/Pitch/Yaw stick deadband @@ -6087,7 +5412,7 @@ Setup the flight mode channel on the RC Input tab if you have not done so alread Le curseur se déplace lorsque vous bougez l'inter de mode de vol sur votre radiocommande. Il affiche le mode actif en cours. -Configurez le canal de mode de vol dans l'onglet Entrées RC si vous ne l'avez pas déjà fait. +Configurez le canal de mode de vol dans l'onglet Entrées Télécommande si vous ne l'avez pas déjà fait. @@ -6127,13 +5452,12 @@ du canal de sortie pour chaque mode de vol. Indicate the control used for arming the airframe, in addition to setting the throttle to its minimum position. In other terms "Throttle Off". - Indique la combinaison utilisée pour armer l'appareil en plus de -placer les gaz au minimum. Autrement dit, manche des gaz à zéro. + Indique la combinaison utilisée pour armer l'appareil en plus de placer les gaz au minimum. Autrement dit, manche des gaz à zéro. Arming timeout: - Temps de latence d'armement : + Délai d'expiration de l'armement : @@ -6212,77 +5536,11 @@ Applique et Enregistre tous les paramètres sur la SD Flight Mode Mode de Vol - - - objname:StabilizationSettings - Pas toucher ! - - - - - index:0 - Pas toucher ! - - - - - haslimits:no - Pas toucher ! - - - - - scale:1 - Pas toucher ! - - - - - buttongroup:16 - Pas toucher ! - - - - - index:1 - Pas toucher ! - - - - - index:2 - Pas toucher ! - - - - - index:3 - Pas toucher ! - - - - - index:4 - Pas toucher ! - - - - - index:5 - Pas toucher ! - - <html><head/><body><p>Select which set of roll rates / max bank angles / PIDs you want active on this switch position.</p></body></html> <html><head/><body><p>Sélectionnez quels paramètres de vitesse / angle d'inclinaison / PID vous souhaitez utiliser pour cette position d'interrupteur.</p></body></html> - - - fieldname:FlightModeMap - Pas toucher ! - - Input Channel Configuration @@ -6338,18 +5596,6 @@ Applique et Enregistre tous les paramètres sur la SD Assisted Control Pilotage Assisté - - - fieldname:FlightModeAssistMap - Do not translate ! - - - - - haslimits:yes - Do not translate ! - - <html><head/><body><p>Never select &quot;Manual&quot; as Flight Mode when flying a multitrotor! Never select &quot;Altitude&quot; or &quot;CruiseControl&quot; in Stabilization Modes when using a fixed wing!</p></body></html> @@ -6367,6 +5613,72 @@ Be sure to set the Neutral position on all sliders before sending! Envoie vers la carte mais n'écrit pas dans la SD. Soyez certain de régler la position de tous les curseurs avant d'envoyer ! + + + Remote Control Input + Entrées Télécommande + + + + Config Status + Statut Config + + + + Failsafe Settings + Paramètres Failsafe + + + + On failsafe change flight mode to: + Lors du failsafe, basculer sur le mode de vol : + + + + When triggering failsafe switch to this flight mode. + Lorsque le failsafe est activé, basculer sur ce mode de vol. + + + + Default + Défaut + + + + Channel input settings on failsafe: + Paramètres des canaux d'entrée lors du failsafe : + + + + Failsafe Information + Information Failsafe + + + + Failsafe is a function that is triggered when the connection between the transmitter and receiver is lost. Failsafe gives the user a chance to configure some basic behaviour and specify what input the flight controller should get even if no control signals from the transmitter is present. +The failsafe is triggered differently for different receivers. Failsafe should always be tested before every flight. + Le failsafe est une fonction qui est activée lorsque la connexion entre l'émetteur et le récepteur est coupée. +Le failsafe donne l'occasion à l'utilisateur de configurer le comportement et les entrées reçues par le contrôleur si le signal de l'émetteur disparait. +Le failsafe est activé différement suivant les récepteurs. +Le failsafe doit toujours être testé avant chaque vol. + + + + Receiver Activity + Activité Récepteur + + + + Show receiver activity, input and channel +while moving one stick or switch at once. + Affiche l'activité du récepteur, entrée et canal +lorsqu'un seul manche ou interrupteur bouge à la fois. + + + + No activity + Pas d'activité + MixerCurve @@ -6386,21 +5698,6 @@ Soyez certain de régler la position de tous les curseurs avant d'envoyer ! Max Maxi - - - 4 - - - - - 3 - - - - - 2 - - Min @@ -6411,31 +5708,6 @@ Soyez certain de régler la position de tous les curseurs avant d'envoyer ! Value Valeur - - - 1.0 - - - - - .75 - - - - - .50 - - - - - .25 - - - - - .00 - - Linear @@ -6504,11 +5776,6 @@ Soyez certain de régler la position de tous les curseurs avant d'envoyer ! Update rate: Fréquence de rafraîchissement : - - - Motors spin at neutral output when armed and throttle below zero (be careful) - Armés, les moteurs tournent avec la sortie au neutre et les gaz à zéro (soyez prudent) - Move the servos using the sliders. Two important things: @@ -6587,6 +5854,22 @@ Be sure to set the Neutral position on all sliders before sending! Envoie vers la carte mais n'écrit pas dans la SD. Soyez certain de régler la position de tous les curseurs avant d'envoyer ! + + + Motors spin at neutral output when armed and throttle below zero (Be careful). + Armés, les moteurs tournent avec la sortie au neutre et les gaz à zéro (Soyez prudent). + + + + Multirotor is Always Stabilized When Armed using: + Le Multirotor est Toujours Stabilisé Lorsque Armé avec : ? + Le Multirotor est Always Stabilized When Armed avec : + + + + (Really be careful!). + (Soyez très prudent !). + outputChannelForm @@ -6716,7 +5999,7 @@ Soyez certain de régler la position de tous les curseurs avant d'envoyer ! Ctrl+S - + @@ -6818,85 +6101,26 @@ Une valeur de 0.00 désactive le filtre. Latitude: Latitude : - - - objname:HomeLocation - Pas toucher ! - - - - - fieldname:g_e - Pas toucher ! - - - - - fieldname:Latitude - Pas toucher ! - - Altitude: Altitude : - - - fieldname:Altitude - Pas toucher ! - - Magnetic field vector: Vecteur champ magnétique : - - - <html><head/><body><p>This information must be set to enable calibration the Revolution controllers sensors. <br/>Set home location using context menu in the map widget.</p></body></html> - <html><head/><body><p>Cette information doit être définie pour permettre la calibration des capteurs du contrôleur Revolution. <br/>Indiquez la position du home en utilisant le menu contextuel sur la carte.</p></body></html> - - - - fieldname:Longitude - Pas toucher ! - - Is Set Est Réglé - - - fieldname:Set - Pas toucher ! - - Longitude: Longitude : - - - button:help - Pas toucher ! - - - - - button:apply - Pas toucher ! - - - - - button:save - Pas toucher ! - - Calibration status @@ -6967,58 +6191,214 @@ Une valeur de 0.00 désactive le filtre. <range> - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600;"><br /></p></body></html> - Blank text ? - - Help Aide + + + Magnetometer + Magnétomètre + + + + Auxiliary Magnetometer Orientation Help + Aide Orientation Magnétomètre Auxiliaire + + + + Y axis + Axe Y + + + + Z axis + Axe Z + + + + Difference on Z axis + Différence sur l'axe Z + + + + %v + Do not translate + + + + + Difference on Y axis + Différence sur l'axe Y + + + + Difference on X axis + Différence sur l'axe X + + + + X axis + Axe X + + + + Magnetometer Settings + Paramètres Magnétomètre + + + + Mag type: + Type de Mag : + + + + Mag usage: + Utilisation Mag : + + + + Select the magnetometer type. + Sélectionner le type de magnétomètre. + + + + Select how to use available magnetometers. + Sélectionner comment utiliser les magnétomètres disponibles. + + + + Warning level in percent (default 5%) + Niveau d'Alerte en pourcent (défaut 5%) + + + + Error level in percent (default 15%) + Niveau d'Erreur en pourcent (défaut 15%) + + + + Warning / Error levels: + Niveaux d'Alerte / Erreur : + + + + Magnetometer Status + Statut Magnétomètre + + + + Onboard + Interne + + + + AuxMag + Auxiliaire + + + + Mag source: + Source Mag : + + + + Mag alarms: + Alarmes Mag : + + + + Auxiliary Magnetometer Orientation + Orientation Magnétomètre Auxiliaire + + + + <html><head/><body><p>This information must be set to enable calibration the Revolution controller's sensors. <br/>Set home location using context menu in the map widget.</p></body></html> + <html><head/><body><p>Cette information doit être définie pour permettre la calibration des capteurs du contrôleur Revolution. <br/>Indiquez la position du home en utilisant le menu contextuel sur la carte.</p></body></html> + + + + Gyro Initialization + Initialisation Gyro + + + + If enabled, a fast recalibration of gyro zero point will be done +whenever the board is armed. Do not move the vehicle while +arming it in that case! + Si activé, une recalibration rapide des gyros est effectuée à chaque fois que +la carte est armée. Dans ce cas ne bougez pas l'appareil lors de l'armement ! + + + + Zero gyros while arming + Mettre les gyros à zéro lors de l'armement + + + + If enabled, this option prevents gyro initialization while the board is moving. + Si activé, cette option empêche l'initialisation des gyros lorsque la carte est en mouvement. + + + + Wait until the board is steady + Attendre jusqu'à ce que la carte soit stable + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:14pt; font-weight:600;">Help</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">Steps 1, 2 and 3 are necessary.</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">Step 4 is optional but may help achieve the best possible results.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600; font-style:italic;">Step 1: Accelerometer and Magnetometer calibration</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">This step will calibrate the scale for the Magnetometer and the Accelerometer sensors. </span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">Press </span><span style=" font-size:11pt; font-style:italic;">Start</span><span style=" font-size:11pt;"> to begin, and follow the instructions for each step. </span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">For best results with the accelerometer calibration, it is advised that it be performed with a free unmounted flight controller as this allows one to accurately position the board for each orientation in the sequence.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">The magnetometer calibration must be performed with the board mounted in the airframe in order for the measurements to incorporate any bias produced by local onboard metal/magnetic elements.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">Note 1: Before the magnetometer or the accelerometer calibration is performed your Home Location must be set. This step is needed in order to determine the local magnetic field vector (Be) and acceleration due to gravity (g_e).</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">Note 2: There is no need to align the airframe exactly south, north, east or west during the individual steps. The directions indicated serve only to tell you in which direction the airframe should be positioned relative to some point. One can simply assume that North is in front of you, East is to the right, West is to the left and South is pointing at you.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600; font-style:italic;">Step 2: Board level calibration</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">This step will ensure that board leveling is accurate. Place the airframe as horizontally as possible (use a spirit level if necessary), then press </span><span style=" font-size:11pt; font-style:italic;">Start</span><span style=" font-size:11pt;">. Do not move the airframe at all until the end of the calibration.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600; font-style:italic;">Step 3: Gyro bias calculation</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">This step will allow you to calibrate the gyro measured value when the board is steady. To perform the calibration leave the board/airframe completely stationary and press </span><span style=" font-size:11pt; font-style:italic;">Start</span><span style=" font-size:11pt;">. </span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600; font-style:italic;">Step 4: Thermal calibration</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">The calibration will compute sensors bias variations at different temperatures while the board warms up.</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">This allows a certain amount of correction of those bias variations against temperature changes. It improves altitude hold accuracy and reduces yaw drift.</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">To perform this calibration disconnect any power from the board and leave it to cool down at room temperature for 15-20 minutes. Then attach the usb connector to the board and press </span><span style=" font-size:11pt; font-style:italic;">Start</span><span style=" font-size:11pt;">, leaving the board completely stationary. Wait until complete.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p></body></html> +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">The bargraphs show the difference between the onboard and auxiliary magnetometer measurements. </span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">When the auxiliary magnetometer rotation is set correctlly, all bargraphs should show all zero (bargraph centered) </span><a name="result_box"></a><span style=" font-family:'Cantarell';">w</span><span style=" font-family:'Cantarell';">hatever the vehicle's orientation.</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">This assumes both magnetometers are calibrated and without alarm.</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">Les barres horizontales ci-dessous affichent la différence de mesure entre le magnétomètre interne et le magnétomètre auxiliaire. </span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">Lorsque l'orientation du magnétomètre auxiliaire est ajustée correctement, toutes les barres restent à zéro (centrées) quelque soit l'orientation ou la position du véhicule.</span></p> +<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">Cela suppose que les deux magnétomètres sont calibrés et sans aucune alarme.</span></p></body></html> + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:14pt; font-weight:600;">Help</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">Steps 1, 2 and 3 are necessary.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">Step 4 is optional but may help achieve the best possible results.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:12pt; font-weight:600; font-style:italic;">Step 1: Accelerometer and Magnetometer calibration</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">This step will calibrate the scale for the Magnetometer and the Accelerometer sensors. </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">Press </span><span style=" font-family:'MS Shell Dlg 2'; font-style:italic;">Start</span><span style=" font-family:'MS Shell Dlg 2';"> to begin, and follow the instructions for each step. </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">For best results with the accelerometer calibration, it is advised that it be performed with a free unmounted flight controller as this allows one to accurately position the board for each orientation in the sequence.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">The magnetometer calibration must be performed with the board mounted in the airframe in order for the measurements to incorporate any bias produced by local onboard metal/magnetic elements.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">Note 1: Before the magnetometer or the accelerometer calibration is performed your Home Location must be set. This step is needed in order to determine the local magnetic field vector (Be) and acceleration due to gravity (g_e).</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">Note 2: There is no need to align the airframe exactly south, north, east or west during the individual steps. The directions indicated serve only to tell you in which direction the airframe should be positioned relative to some point. One can simply assume that North is in front of you, East is to the right, West is to the left and South is pointing at you.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:12pt; font-weight:600; font-style:italic;">Step 2: Board level calibration</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">This step will ensure that board leveling is accurate. Place the airframe as horizontally as possible (use a spirit level if necessary), then press </span><span style=" font-family:'MS Shell Dlg 2'; font-style:italic;">Start</span><span style=" font-family:'MS Shell Dlg 2';">. Do not move the airframe at all until the end of the calibration.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:12pt; font-weight:600; font-style:italic;">Step 3: Gyro bias calculation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">This step will allow you to calibrate the gyro measured value when the board is steady. To perform the calibration leave the board/airframe completely stationary and press </span><span style=" font-family:'MS Shell Dlg 2'; font-style:italic;">Start</span><span style=" font-family:'MS Shell Dlg 2';">. </span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:12pt; font-weight:600; font-style:italic;">Step 4: Thermal calibration</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">The calibration will compute sensors bias variations at different temperatures while the board warms up.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">This allows a certain amount of correction of those bias variations against temperature changes. It improves altitude hold accuracy and reduces yaw drift.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">To perform this calibration disconnect any power from the board and leave it to cool down at room temperature for 15-20 minutes. Then attach the usb connector to the board and press </span><span style=" font-family:'MS Shell Dlg 2'; font-style:italic;">Start</span><span style=" font-family:'MS Shell Dlg 2';">, leaving the board completely stationary. Wait until complete.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } @@ -7088,18 +6468,6 @@ p, li { white-space: pre-wrap; } Default Défaut - - - button:default - pas toucher ? - - - - - buttongroup:1 - pas toucher ? - - Roll @@ -7127,54 +6495,6 @@ Then lower the value by 5 or so. Augmentez doucement Proportionnel jusqu'à commencer à observer des oscillations claires en vol. Baissez ensuite la valeur de 5 ou plus. - - - objname:StabilizationSettings - pas toucher ! - - - - - fieldname:RollRatePID - pas toucher ! - - - - - element:Kp - pas toucher ! - - - - - haslimits:yes - pas toucher ! - - - - - scale:0.0001 - pas toucher ! - - - - - buttongroup:1,10 - pas toucher ! - - - - - fieldname:PitchRatePID - pas toucher ! - - - - - fieldname:YawRatePID - pas toucher ! - - Integral @@ -7187,186 +6507,31 @@ value as the Kp. En règle générale, vous pouvez définir l'intégrale à peu près à la même valeur que Kp. - - - element:Ki - pas toucher ! - - Attitude Stabilization (Outer Loop) Stabilisation Attitude (Boucle Extérieure) - - - buttongroup:2 - pas toucher ! - - - - - fieldname:RollPI - pas toucher ! - - - - - scale:0.1 - pas toucher ! - - - - - buttongroup:2,10 - pas toucher ! - - - - - fieldname:PitchPI - pas toucher ! - - - - - fieldname:YawPI - pas toucher ! - - Zero the integral when throttle is low Mettre l'intégrale à zéro lorsque les gaz sont bas - - - fieldname:LowThrottleZeroIntegral - pas toucher ! - - Advanced Avancé - - - buttongroup:4 - pas toucher ! - - - - - element:Kd - pas toucher ! - - - - - haslimits:no - pas toucher ! - - - - - scale:1 - pas toucher ! - - - - - buttongroup:4,20 - pas toucher ! - - Derivative Dérivée - - - buttongroup:5 - pas toucher ! - - - - - buttongroup:5,20 - pas toucher ! - - - - - buttongroup:6 - pas toucher ! - - - - - fieldname:PitchMax - pas toucher ! - - - - - buttongroup:6,20 - - - - - fieldname:MaximumRate - pas toucher ! - - - - - element:Roll - pas toucher ! - - - - - fieldname:ManualRate - pas toucher ! - - - - - element:Yaw - pas toucher ! - - - - - fieldname:YawMax - pas toucher ! - - - - - element:Pitch - pas toucher ! - - - - - fieldname:RollMax - pas toucher ! - - Expert Expert - - - buttongroup:10 - pas toucher ! - - Weak Leveling Rate @@ -7382,82 +6547,16 @@ value as the Kp. Max Axis Lock Rate - - - fieldname:WeakLevelingKp - pas toucher ! - - - - - fieldname:MaxWeakLevelingRate - pas toucher ! - - - - - fieldname:MaxAxisLock - pas toucher ! - - - - - fieldname:MaxAxisLockRate - pas toucher ! - - Sensor Tuning Réglages Capteurs - - - buttongroup:8 - pas toucher ! - - - - - objname:AttitudeSettings - pas toucher ! - - - - - fieldname:AccelKp - pas toucher ! - - - - - buttongroup:8,10 - pas toucher ! - - - - - fieldname:GyroTau - pas toucher ! - - - - - fieldname:AccelKi - pas toucher ! - - Takes you to the wiki page Vous renvoie à la page wiki - - - button:help - Pas toucher - - Reloads the saved settings into GCS. @@ -7469,12 +6568,6 @@ Useful if you have accidentally changed some settings. Reload Board Data Recharger Données Carte - - - button:reload - Pas toucher - - Send settings to the board but do not save to the non-volatile memory @@ -7485,12 +6578,6 @@ Useful if you have accidentally changed some settings. Apply Appliquer - - - button:apply - Pas toucher - - Send settings to the board and save to the non-volatile memory @@ -7501,12 +6588,6 @@ Useful if you have accidentally changed some settings. Save Enregistrer - - - button:save - Pas toucher - - Responsiveness @@ -7633,18 +6714,6 @@ Useful if you have accidentally changed some settings. Tuning Réglages - - - objname:AltitudeHoldSettings - Pas toucher - - - - - buttongroup:99 - Pas toucher - - Vario Altitude @@ -7711,29 +6780,11 @@ Useful if you have accidentally changed some settings. <html><head/><body><p>This adjusts how much stability your vehicle will have when flying tilted (ie forward flight) in Attitude Mode. Adding Ki in Attitude when Ki is present in Rate is not recommended.</p></body></html> <html><head/><body><p>Ceci ajuste le niveau de stabilité que votre véhicule aura en vol incliné (ex. vol en avançant) en mode Attitude. Ajouter une valeur d'intégrale en mode Attitude lorsque une intégrale est présente en mode Rate n'est pas recommandé.</p></body></html> - - - objname:StabilizationSettingsBankX - Pas toucher ! - - Rattitude - - - buttongroup:15 - Pas toucher ! - - - - - buttongroup:98 - Pas toucher ! - - Velocity Proportional @@ -7749,12 +6800,6 @@ Useful if you have accidentally changed some settings. Velocity Integral Intégrale Vitesse Verticale - - - scale:0.01 - Pas toucher ! - - Control Coefficients @@ -7765,35 +6810,11 @@ Useful if you have accidentally changed some settings. Cruise Control - - - buttongroup:16 - Pas toucher ! - - - - - fieldname:CruiseControlMaxAngle - Pas toucher ! - - - - - fieldname:CruiseControlMaxPowerFactor - Pas toucher ! - - PowerTrim AjustPuissance - - - fieldname:CruiseControlPowerTrim - Pas toucher ! - - MaxPowerFactor @@ -7809,28 +6830,6 @@ Useful if you have accidentally changed some settings. InvertedPower PuissanceRenversé - - - buttongroup:98,10 - Pas toucher ! - - - - - buttongroup:99,10 - Pas toucher ! - - - - - Use Basic Configuration - Utiliser Configuration Basique - - - - Use Advanced Configuration - Utiliser Configuration Avancée - <html><head/><body><p>How much the vehicle should throttle up or down to compensate or achieve a certain vertical speed. Higher values lead to more aggressive throttle changes and could lead to oscillations. This is the most likely candidate to change depending on the crafts engine thrust. Heavy craft with weak engines might require higher values.</p></body></html> @@ -7841,23 +6840,11 @@ Useful if you have accidentally changed some settings. <html><head/><body><p>Percentage of full stick where the transition from Attitude to Rate occurs. This transition always occurs when the aircraft is exactly inverted (bank angle 180 degrees). Small values are dangerous because they cause flips at small stick angles. Values significantly over 100 act like attitude mode and can never flip.</p></body></html> <html><head/><body><p>Pourcentage d'une position de manche à fond où la transition du mode Attitude vers le mode Rate intervient. Cette transition intervient à chaque fois lorsque l'appareil est exactement à l'envers (inclinaison d'un angle de 180 degrés). Des valeurs faibles sont dangereuses car elles provoquent des pirouettes avec de petits mouvements aux manches. Des valeurs significativement au dessus de 100 font que l'appareil ne peut jamais se retourner et reviennent à fonctionner en mode Attitude.</p></body></html> - - - fieldname:RattitudeModeTransition - Pas toucher ! - - <html><head/><body><p>CP helis can set this to Reversed to automatically reverse the direction of thrust when inverted. Fixed pitch copters, including multicopters, should leave this set at Unreversed. Unreversed direction with Boosted power may be dangerous because it adds power and the thrust direction moves the aircraft towards the ground.</p></body></html> <html><head/><body><p>Les hélicos CP peuvent régler ceci à Reversed pour inverser automatiquement la direction de la poussée en vol dos. Les hélicos à pas fixe, multicoptères inclus, doivent laisser ce paramètre à Unreversed. L'association du paramètre Unreversed avec Boosted ci-dessous peut-être dangereuse car elle ajoute de la puissance et la direction de la poussée déplace l'appareil vers le sol.</p></body></html> - - - fieldname:CruiseControlInvertedThrustReversing - Pas toucher ! - - InvrtdThrustRev @@ -7888,34 +6875,16 @@ Useful if you have accidentally changed some settings. <html><head/><body><p>Throttle/Collective stick below this amount disables Cruise Control. Also, by default Cruise Control forces the use of this value for thrust when InvertedPower setting is Zero and the copter is inverted. CP helis probably want this set to -100%. For safety with fixed pitch copters (including multicopters), never set this so low that the trimmed throttle stick cannot get below it or your motor(s) will still run with the throttle stick all the way down. Fixed pitch throttle sticks go from -100 to 0 in the first tiny bit of throttle stick (and then up to 100 using the rest of the throttle range), so for example, a lot of &quot;high throttle trim&quot; will keep the stick from ever commanding less than 5% so it won't be possible to stop the motors with the throttle stick. Banking the copter in your hand in this state will make the motors speed up.</p></body></html> <html><head/><body><p>Lorsque le manche de gaz/collectif est en dessous de cette valeur, cela désactive Cruise Control. En outre, Cruize Control impose l'utilisation de cette valeur de manche de gaz lorsque le paramètre PuissanceInversé est à zéro et l'hélicoptère est à l'envers.</p><p>Les hélicos CP auront besoin probablement d'une valeur fixée à -100. Par mesure de sécurité avec les pas fixes (multicoptères inclus), ne jamais définir une valeur trop basse pour qu'un manche de gaz baissé puisse descendre en dessous de cette valeur ou le(s) moteur(s) continuent de tourner avec le manche de gaz au mini. Le manche de gaz pour pas fixe va de -100 à 0 dans la première petite plage de la course du manche (puis jusqu'à 100 dans la plage de gaz restante) donc par exemple un &quot;trim élevé sur le manche de gaz&quot; va maintenir les gaz au dessus de 5% si bien qu'il ne sera pas possible d'arrêter les moteurs avec la manche des gaz. Le fait d'incliner l'appareil à la main dans cet état fera accélérer les moteurs.</p></body></html> - - - fieldname:CruiseControlMinThrust - Pas toucher ! - - <html><head/><body><p>Multi-copters should probably use 80% to 90% to leave some headroom for stabilization. CP helis can set this to 100%.</p></body></html> <html><head/><body><p>Les multicoptères devraient probablement utiliser une valeur de 80% à 90% afin de laisser une certaine marge pour la stabilisation. Les hélicos CP peuvent définir cette valeur à 100%.</p></body></html> - - - fieldname:CruiseControlMaxThrust - Pas toucher ! - - MaxThrust PousséeMaxi - - - fieldname:CruiseControlPowerDelayComp - Pas toucher ! - - <html><head/><body><p>If you find that quickly moving the stick around a lot makes the copter climb a bit, adjust this number down a little. It will be a compromise between climbing a little with lots of stick motion and descending a little with minimal stick motion.</p></body></html> @@ -7926,29 +6895,11 @@ Useful if you have accidentally changed some settings. <html><head/><body><p>The amount of power used when in inverted mode. Zero (min throttle stick for fixed pitch copters includding multicopters, neutral collective for CP), Normal (uses stick value), or Boosted (boosted according to bank angle). Beginning multicopter pilots should leave this set to Zero to automatically reduce throttle during flips. Boosted power with Unreversed direction may be dangerous because it adds power and the thrust direction moves the aircraft towards the ground.</p></body></html> <html><head/><body><p>La quantité de puissance utilisée en vol dos. Zero (PousséeMini pour les hélicos à pas fixe, multicoptères inclus, collectif au neutre pour hélicos CP), Normal (utilise la valeur du manche), ou Boosted (boosté en fonction de l'angle d'inclinaison). Les pilotes débutants en multicoptère devraient laisser ce paramètre à Zero pour automatiquement reduire les gaz durant les flips. L'association du paramètre Boosted avec Unreversed ci-dessus peut-être dangereuse car elle ajoute de la puissance et la direction de la poussée déplace l'appareil vers le sol.</p></body></html> - - - fieldname:CruiseControlInvertedPowerOutput - Pas toucher ! - - - - - fieldname:ThrustRate - Pas toucher ! - - <html><head/><body><p>Thrust exponential value.</p></body></html> <html><head/><body><p>Valeur exponentielle de la poussée.</p></body></html> - - - fieldname:ThrustExp - Pas toucher ! - - Throttle/Collective Stick Response @@ -7964,12 +6915,6 @@ Useful if you have accidentally changed some settings. Weak Leveling - - - buttongroup:25 - Pas toucher ! - - Weak Leveling Gain @@ -7980,12 +6925,6 @@ Useful if you have accidentally changed some settings. Axis Lock - - - buttongroup:31 - Pas toucher ! - - Mode Transition @@ -8011,45 +6950,21 @@ Useful if you have accidentally changed some settings. Thrust PID Scaling - - - fieldname:EnableThrustPIDScaling - Pas toucher ! - - Source Source - - - fieldname:ThrustPIDScaleSource - Pas toucher ! - - Targets Cible(s) - - - fieldname:ThrustPIDScaleTarget - Pas toucher ! - - Axis Axe(s) - - - fieldname:ThrustPIDScaleAxes - Pas toucher ! - - Rate mode @@ -8074,47 +6989,18 @@ response (deg) Enable TPS - Activer TPS + Activer TPS Acro+ - - - buttongroup:77 - Pas toucher ! - - - - - <html><head/><body><p>The Acro + slider can be adjusted to change the amount of manual control blending.</p></body></html> - <html><head/><body><p>Le curseur Acro+ peut être ajusté pour modifier la quantité de mixage du contrôle manuel.</p></body></html> - - - - fieldname:AcroInsanityFactor - Pas toucher ! - - Expo - - - fieldname:StickExpo - Pas toucher ! - - - - - buttongroup:66 - Pas toucher ! - - <html><head/><body><p>This graph shows the Expo curves for all axis. The color of the curves corresponds with the colors of the slider labels below.</p></body></html> @@ -8138,12 +7024,7 @@ response (deg) Rate - - - - - Rate yaw - + @@ -8160,18 +7041,6 @@ response (deg) Enable pirouette compensation Activer compensation pirouette - - - fieldname:EnablePiroComp - Pas toucher ! - - - - - buttongroup:55 - Pas toucher ! - - <html><head/><body><p>This adjusts how much stability your vehicle will have when flying tilted (ie forward flight) in Rate mode. A good starting point for Integral is double the Proportional value</p></body></html> @@ -8187,23 +7056,11 @@ response (deg) <html><head/><body><p>This adjusts how much yaw stability your vehicle will have in Rate mode. A good starting point for Integral is double the Proportional value</p></body></html> <html><head/><body><p>Ceci ajuste le niveau de stabilité en lacet de votre véhicule en mode Rate. Un bon point de départ pour l'Intégrale est le double de la valeur Proportionnel</p></body></html> - - - fieldname:VerticalPosP - Pas toucher ! - - <html><head/><body><p>How fast the vehicle should attain its target velocity. For neutral throttle estimation, the altitude module assumes that when engaged the throttle thrust limit neutral setting is in the range required to hover. If the throttle required is a lot higher or lower, it needs to adjust this &quot;throttle trim&quot;. Higher values make it do this adjustment faster, but this could lead to ugly oscillations. Leave at default unless you know what you are doing.</p></body></html> <html><head/><body><p>Détermine la rapidité à laquelle le véhicule doit atteindre la vitesse désirée. Pour l'estimation du neutre de manche des gaz, le module Altitude suppose que lorsqu'il est activé le manche des gaz est dans la zone nécessaire à un vol stabilisé. Si la valeur de gaz est beaucoup plus haute ou basse, il doit ajuster son &quot;Trim de Gaz&quot;. Des valeurs élevées donneront un ajustement plus rapide mais cela peut entrainer de vilaines oscillations. Laissez par défaut si vous ne savez pas ce que vous faites.</p></body></html> - - - fieldname:VerticalVelPID - Pas toucher ! - - Velocity Derivative @@ -8224,12 +7081,6 @@ response (deg) <html><head/><body><p>The beta value applies a setpoint weighting that reduces the sensitivity to quick changes in the desired velocity. Transitions from altitude hold to descent/climb can be made smooth applying a Beta value of around 80 to 90%.</p></body></html> <html><head/><body><p>La valeur de Beta applique une pondération de consigne qui réduit la sensibilité à des changements rapides de la vitesse souhaitée. Les transitions montée/descente en maintien d'altitude peuvent être adoucies en mettant une valeur de Beta entre 80 et 90%.</p></body></html> - - - element:Beta - Pas toucher ! - - <html><head/><body><p>How fast the vehicle should climb or descent to compensate a certain altitude difference. Higher values could result in more accurate altitude hold but also more violent control actions, lower values are safer and ensure smoother flight. The default value should be fine for the majority of crafts.</p></body></html> @@ -8255,6 +7106,61 @@ response (deg) Pitch Factor Facteur Pitch + + + FPV Camera Tilt Compensation + Compensation Angle Caméra FPV + + + + Reset value to GCS defaults + Raz à la valeur par défaut de GCS + + + + Camera Tilt Angle (deg) + Angle Inclinaison Caméra (degrés) + + + + Camera tilt angle from 0 to 50 degrees (0 to disable compensation). + Angle d'inclinaison de la caméra, de 0 à 50degrés (0 pour désactiver le compensation). + + + + <html><head/><body><p>When this option is selected the simplified version of the configuration view will be used. </p><p>This view hides some settings that are considered advanced and will make it easier for users to get a first working configuration.</p></body></html> + <html><head/><body><p>Lorsque cette option est sélectionnée, la version simplifiée de la visualisation de configuration sera utilisée. </p><p>Cette visualisation cache certains paramètres considérés comme avancés et facilite la mise en oeuvre par les utilisateurs lors d'une première configuration.</p></body></html> + + + + Use Basic Configuration View + Utiliser la Vue de Configuration Basique + + + + Rate Yaw + + + + + <html><head/><body><p>The Acro+ slider can be adjusted to change the amount of manual control blending.</p></body></html> + <html><head/><body><p>Le curseur Acro+ peut être ajusté pour modifier la quantité de mixage du contrôle manuel.</p></body></html> + + + + Yaw Factor + Facteur Yaw + + + + <html><head/><body><p>When this option is selected the advanced version of the configuration view will be used. </p><p>This view shows all settings that are considered advanced and will enable users to to tweak all possible settings to fine tune configuration.</p></body></html> + <html><head/><body><p>Lorsque cette option est sélectionnée, la version avancée de la visualisation de configuration sera utilisée. </p><p>Cette visualisation affiche tous les paramètres qui sont considérés comme avancés et donne la possibilité aux utilisateurs d'ajuster tous les paramètres possibles pour des réglages fins.</p></body></html> + + + + Use Advanced Configuration View + Utiliser la Vue de Configuration Avancée + TxPIDWidget @@ -8420,12 +7326,6 @@ d'une valeur de gaz supérieure ou égale à la la valeur maximale des gaz. Messages - - - button:help - Pas toucher. - - Send settings to the board but do not save to the non-volatile memory @@ -8494,64 +7394,16 @@ uniquement lorsque le système est armé, sans désactiver le module.Default Défaut - - - button:default - Do not translate ! - - - - - buttongroup:10 - Do not translate ! - - Roll/Pitch I Factor Facteur I Roll/Pitch - - - objname:TxPIDSettings - Do not translate ! - - - - - fieldname:EasyTunePitchRollRateFactors - Do not translate ! - - - - - scale:0.1 - Do not translate ! - - - - - element:I - Do not translate ! - - Roll/Pitch D Factor Facteur D Roll/Pitch - - - scale:1 - Do not translate ! - - - - - element:D - Do not translate ! - - Calculate Yaw PIDs based on Roll/Pitch PIDs @@ -8562,35 +7414,11 @@ uniquement lorsque le système est armé, sans désactiver le module.AutoCalc Yaw Calcul Auto Yaw - - - fieldname:EasyTuneRatePIDRecalculateYaw - Do not translate ! - - - - - buttongroup:11 - Do not translate ! - - Yaw P Factor Facteur P Yaw - - - fieldname:EasyTuneYawRateFactors - Do not translate ! - - - - - element:P - Do not translate ! - - Yaw I Factor @@ -8977,31 +7805,6 @@ uniquement lorsque le système est armé, sans désactiver le module.QML file: Fichier QML : - - - Use OpenGL - Utiliser OpenGL - - - - Show Terrain: - Afficher terrain : - - - - OsgEarth file: - Fichier OsgEarth : - - - - Use actual location - Utiliser la position actuelle - - - - Use pre-defined location: - Utiliser une position prédéfinie : - Latitude: @@ -9029,24 +7832,39 @@ les données en cache Précharger le cache terrain - + QML file (*.qml) Fichier QML (*.qml) - Choose QML file - Choisir un fichier QML + Choose QML File + Sélectionner un fichier QML - - OsgEarth (*.earth) - + + Choose Terrain File + Sélectionner le fichier Terrain + + + + Model file (*.3ds) + Modèle 3D (*.3ds) - Choose OsgEarth terrain file - Choisir un fichier de terrain OsgEarth + Choose Model File + Sélectionner le fichier Modèle 3D + + + + Choose Background Image File + Sélectionner le fichier d'Image de Fond + + + + OsgEarth (*.earth) + @@ -9058,6 +7876,86 @@ les données en cache Altitude Unit: Unité d'Altitude : + + + Terrain + Terrain + + + + Show Terrain + Afficher Terrain + + + + Terrain file: + Fichier Terrain : + + + + This location will be used if no GPS fix or Home location are available + Cette position sera utilisée si un fix GPS ou une position Home ne sont pas disponibles + + + + Default Location + Position par Défaut + + + + Model + Modèle + + + + Show Model + Afficher Modèle + + + + Use automatic model selection + Utiliser la sélection automatique du modèle + + + + Use this model: + Utiliser ce modèle : + + + + Background image: + Image d'arrière plan : + + + + Environment + Environnement + + + + Time + Date/Heure + + + + Use local time + Utiliser la date/heure locale + + + + Use this time: + Utiliser cette date/heure : + + + + Actualize + Actualiser + + + + Minimum ambient light: + Lumière ambiante minimale : + QmlViewGadgetOptionsPage @@ -9133,7 +8031,7 @@ les données en cache Diagramme de Connexion - + Save File Enregistrer Fichier @@ -9264,12 +8162,12 @@ p, li { white-space: pre-wrap; } - + Connect Connecter - + <Unknown> <Inconnu> @@ -9303,6 +8201,11 @@ p, li { white-space: pre-wrap; } OpenPilot Nano + + + TauLabs Sparky 2.0 + + Disconnect @@ -9472,6 +8375,36 @@ p, li { white-space: pre-wrap; } <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:10pt;">Le contrôleur de vol supporte plusieurs types de signaux d'entrée. Veuillez sélectionner le type d'entrée qui correspond à votre configuration de récepteur. Si vous avez un doute, laissez l'option sélectionnée par défaut et continuez l'assistant.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:10pt;">Certaines configurations demandent un redémarrage du contrôleur de vol pour que les changements soient effectifs. Vous serrez informé si un redémarrage est nécessaire à l'écran suivant de cet assistant.</span></p></body></html> + + + Graupner HoTT + + + + + HoTT + + + + + Jeti EX.Bus + + + + + EX.Bus + + + + + FlySky IBus + + + + + IBus + + MultiPage @@ -9789,7 +8722,7 @@ p, li { white-space: pre-wrap; } <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:10pt;">Appuyer sur le bouton Enregistrer pour enregistrer la configuration.</span></p></body></html> - + A compatible flight controller must be connected to your computer to save the configuration. Please connect your flight controller to your computer and try again. Un contrôleur de vol compatible doit être connecté à votre PC pour enregistrer la configuration. @@ -9831,11 +8764,6 @@ p, li { white-space: pre-wrap; } SurfacePage - - - WizardPage - Page d'Assistant - Ground Vehicle Configuration @@ -9880,11 +8808,6 @@ Veuillez sélectionner le type de véhicule terrestre dont vous voulez créer la This setup currently expects a motorcyle setup, using one motor and one servo for steering. Cette configuration correspond à une moto utilisant un moteur et un servo pour la direction. - - - <html><head/><body><p align="center"><span style=" font-family:'MS Shell Dlg 2'; font-size:12pt; font-weight:600;">The Surface Vehicle section of the Setup Wizard is not yet implemented</span><br/></p></body></html> - - VehiclePage @@ -10016,15 +8939,10 @@ persistant de la carte, et ensuite ferme la boite de dialogue. Fermer - + Import Summary Sommaire d'Importation - - - http://wiki.openpilot.org/display/Doc/UAV+Settings+import-export - - deviceWidget @@ -10038,30 +8956,6 @@ persistant de la carte, et ensuite ferme la boite de dialogue. Device Information Information Périphérique - - - lblDevName - Pas toucher - - - - - DeviceID - Champs. Pas toucher ? - - - - - lblHWRev - Pas toucher - - - - - RW - Pas toucher - - BL Version @@ -10149,59 +9043,11 @@ persistant de la carte, et ensuite ferme la boite de dialogue. On Device Sur la Carte - - - lblBrdName - Pas toucher - - - - - lblDescription - Pas toucher - - - - - lblBuildDate - Pas toucher - - - - - lblGitTag - Pas toucher - - - - - lblCRC - Pas toucher - - - - - lblCertified - Pas toucher - - Loaded Chargé - - - lblDescritpionL - Pas toucher - - - - - lblCertifiedL - Pas toucher - - Custom description: @@ -10230,11 +9076,6 @@ persistant de la carte, et ensuite ferme la boite de dialogue. Device Information Information Périphérique - - - TextLabel - - CPU Serial: @@ -10245,11 +9086,6 @@ persistant de la carte, et ensuite ferme la boite de dialogue. Firmware Information Information Firmware - - - BlRevision - - UploaderWidget @@ -10482,7 +9318,7 @@ p, li { white-space: pre-wrap; } ConfigMultiRotorWidget - + Input Entrée @@ -10492,7 +9328,7 @@ p, li { white-space: pre-wrap; } Sortie - + @@ -10500,18 +9336,18 @@ p, li { white-space: pre-wrap; } - + Configuration OK Configuration OK - + <font color='red'>ERROR: Assign a Yaw channel</font> <font color='red'>ERREUR : Veuillez affecter le canal de Yaw</font> - + Duplicate channel in motor outputs Canaux en double dans le sorties moteur @@ -10534,12 +9370,12 @@ p, li { white-space: pre-wrap; } ConfigCCHWWidget - + Enable GPS module and reboot the board to be able to select GPS protocol Activez le module GPS et redémarrez la carte pour pouvoir choisir le protocole GPS - + Warning: you have configured more than one DebugConsole, this currently is not supported Attention : vous avez configuré plus d'une DebugConsole, ce n'est actuellement pas possible @@ -10563,7 +9399,7 @@ p, li { white-space: pre-wrap; } ConfigCCAttitudeWidget - + Calibration timed out before receiving required updates. Temps d'attente dépassé avant d'avoir reçu les mises à jour demandées. @@ -10571,13 +9407,32 @@ p, li { white-space: pre-wrap; } ConfigGadgetWidget - + + + Hardware + Do not translate ? + + + + + + Attitude + Attitude + + + + + OPLink Configuration + Configuration OPLink + + + Unsaved changes Modifications non sauvegardées - The tab you are leaving has unsaved changes,if you proceed they will be lost. + The tab you are leaving has unsaved changes, if you proceed they will be lost. Do you still want to proceed? L'onglet que vous quittez contient des modifications non sauvegardées, si vous continuez elles seront perdues. Voulez-vous toujours continuer ? @@ -10586,7 +9441,7 @@ Voulez-vous toujours continuer ? ConfigInputWidget - + Arming Settings are now set to 'Always Disarmed' for your safety. Contexte : Onglet "Paramètres d'Armement" Pour des raisons de sécurité les Paramètres d'Armement ont été modifiés à 'Toujours Désarmé'. @@ -10598,7 +9453,7 @@ Voulez-vous toujours continuer ? Vous devrez reconfigurer manuellement les paramètres d'armement lorsque l'assistant sera terminé. Après la dernière étape de l'assistant, vous serez redirigé vers l'écran des Paramètres d'Armement. - + Next Suivant @@ -10671,7 +9526,7 @@ Voulez-vous toujours continuer ? Pour un Quadricoptère : Profondeur correspond à la Rotation Avant, Ailerons à Roulis et Dérive correspond à Lacet. - + <p>Please enable throttle hold mode.</p><p>Move the Collective Pitch stick.</p> <p>Veuillez activer les gaz en position maintenue.</p><p>Bougez le manche du Collectif de tangage.</p> @@ -10696,17 +9551,53 @@ Voulez-vous toujours continuer ? <p>Vous avez la possibilité d'appuyer sur Suivant pour ignorer ce canal.</p> - + + Config OK + + + + + All fine, no config alarm! + Tout va bien, pas d'alarme de configuration ! + + + + Config error + Erreur config + + + + There is something wrong with your config, +usually a Thrust mode or Assisted mode not supported. + +Tip: Reduce the Flight Mode Count to find the culprit. + Il y a quelque choose d'incorrect dans votre configuration, +généralement un mode de poussée ou un mode d'assistance non-supporté. + +Conseil : Réduire le nombre de modes de vol pour trouver le coupable. + + + Ground Vehicle Véhicule terrestre <p>Please <b>center</b> throttle control and press OK when ready.</p> - <p>Veuillez <b>centrer</b> le contrôle des gaz et appuyez sur OK lorsque vous êtes prêt.</p> + <p>Veuillez <b>centrer</b> le contrôle des gaz et appuyez sur OK lorsque vous êtes prêt.</p> - + + %1 input - Channel %2 + Entrée %1 - Canal %2 + + + + No activity + Pas d'activité + + + Please center all controls and trims and press Next when ready. For a ground vehicle, this center position will be used as neutral value of each channel. @@ -10715,12 +9606,12 @@ For a ground vehicle, this center position will be used as neutral value of each Pour un véhicule terrestre, ces positions centrales seront utilisées comme neutre de chaque canal. - + Next / Skip Suivant / Sauter - + Stop Manual Calibration Arrêter Calibration Manuelle @@ -10735,7 +9626,7 @@ Pour un véhicule terrestre, ces positions centrales seront utilisées comme neu Vous devrez reconfigurer les paramètres d'armement manuellement lorsque la calibration manuelle sera terminée. - + Start Manual Calibration Démarrer Calibration Manuelle @@ -10753,7 +9644,7 @@ Pour un véhicule terrestre, ces positions centrales seront utilisées comme neu Core::ConnectionManager - + USB: OPLinkMini USB : OPLinkMini @@ -10763,13 +9654,13 @@ Pour un véhicule terrestre, ces positions centrales seront utilisées comme neu Connexions : - + Disconnect Déconnecter - - + + Connect Connecter @@ -10785,7 +9676,7 @@ Pour un véhicule terrestre, ces positions centrales seront utilisées comme neu DebugGadgetWidget - + Save log File As Enregistrer Fichier Journal Sous @@ -10853,18 +9744,10 @@ Pour un véhicule terrestre, ces positions centrales seront utilisées comme neu Journal OpenPilot (*.opl) - - LoggingThread - - - Logging: retrieve settings objects from the autopilot (%1 objects) - Journalisation : récupération des objets de configuration de l'autopilote (%1 objets) - - LoggingPlugin - + Start Log Démarrer Journal @@ -10898,14 +9781,6 @@ Pour un véhicule terrestre, ces positions centrales seront utilisées comme neu Waypoint Magique - - ModelViewGadgetFactory - - - ModelView - VueModèle - - NotificationItem @@ -11052,12 +9927,12 @@ Double clic sur la légende ou le tracé pour afficher/cacher la légende. SetupWizard - + Setup Wizard Assistant de Configuration - + Controller type: Type de contrôleur : @@ -11081,6 +9956,11 @@ Double clic sur la légende ou le tracé pour afficher/cacher la légende.OpenPilot Nano + + + TauLabs Sparky 2.0 + + OpenPilot OPLink Radio Modem @@ -11097,15 +9977,15 @@ Double clic sur la légende ou le tracé pour afficher/cacher la légende. - + - + Unknown Inconnu - + Vehicle type: Type de véhicule : @@ -11246,6 +10126,26 @@ Double clic sur la légende ou le tracé pour afficher/cacher la légende.Spektrum Satellite + + + Multiplex SRXL + + + + + Graupner HoTT + + + + + Jeti EX.Bus + + + + + FlySky IBus + + Speed Controller (ESC) type: @@ -11296,6 +10196,16 @@ Double clic sur la légende ou le tracé pour afficher/cacher la légende.OpenPilot Platinum + + + Naza GPS + GPS Naza + + + + Generic UBLOX + I2C Magnetometer + UBlox générique + Magnétomètre I2C + OpenPilot v8 or Generic UBLOX GPS @@ -11312,7 +10222,7 @@ Double clic sur la légende ou le tracé pour afficher/cacher la légende.Aucun - + Airspeed Sensor: Capteur Vitesse Air : @@ -11348,7 +10258,7 @@ Double clic sur la légende ou le tracé pour afficher/cacher la légende. VehicleConfigurationHelper - + Done! Terminé ! @@ -11360,9 +10270,15 @@ Double clic sur la légende ou le tracé pour afficher/cacher la légende.Échoué ! - + + Writing External Mag sensor settings - Écriture paramètres Compas Externe + Écriture paramètres Magnétomètre Externe + + + + Writing I2C Mag sensor settings + Écriture paramètres Magnétomètre I2C @@ -11370,29 +10286,29 @@ Double clic sur la légende ou le tracé pour afficher/cacher la légende.Écriture paramètres capteur GPS - + Writing Airspeed sensor settings Écriture paramètres capteur Vitesse Air - + Writing hardware settings Écriture paramètres matériels - - - + + + Writing actuator settings Écriture paramètres actionneurs - + Writing flight mode settings 1/2 Écriture paramètres mode de vol 1/2 - + Writing flight mode settings 2/2 Écriture paramètres mode de vol 2/2 @@ -11402,28 +10318,28 @@ Double clic sur la légende ou le tracé pour afficher/cacher la légende.Écriture paramètres d'ajustement gyro et accéléromètres - + Writing board settings Écriture paramètres carte - + Writing stabilization settings Écriture paramètres de stabilisation - + Writing mixer settings Écriture paramètres mixeur - + Writing vehicle settings Écriture paramètres véhicule - + Writing manual control defaults Écriture contrôles manuels par défaut @@ -11462,7 +10378,7 @@ Double clic sur la légende ou le tracé pour afficher/cacher la légende. UAVObjectField - + 0 @@ -11625,7 +10541,7 @@ Double clic sur la légende ou le tracé pour afficher/cacher la légende. UploaderGadgetWidget - + Connected Device Périphérique Connecté @@ -11642,40 +10558,30 @@ Double clic sur la légende ou le tracé pour afficher/cacher la légende. - + Device Périphérique - - http://wiki.openpilot.org/display/Doc/Erase+board+settings - - - - + Running En cours d'exécution - + Timed out while waiting for all boards to be disconnected! Bof Expiration du temps d'attente de la déconnexion de toutes les cartes ! - - + + Timed out while waiting for a board to be connected! Bof Expiration du temps dans l'attente d'une connexion de carte ! - - To upgrade the OPLinkMini board please disconnect it from the USB port, press the Upgrade again button and follow instructions on screen. - Pour mettre à jour une carte OPLinkMini veuillez la déconnecterdu port USB, appuyez à nouveau sur le bouton de mise à jour et suivez les instructions à l'écran. - - - + Timed out while waiting for a board to be fully connected! Expiration du temps dans l'attente d'une connexion complète de carte ! @@ -11686,7 +10592,7 @@ Double clic sur la légende ou le tracé pour afficher/cacher la légende.Échec du passage en mode bootloader. - + Unknown board id '0x%1' Carte inconnue id '0x%1' @@ -11734,7 +10640,7 @@ Double clic sur la légende ou le tracé pour afficher/cacher la légende.La carte doit être connectée à un port USB ! - + Timing out in %1 seconds Expiration dans %1 secondes @@ -11780,7 +10686,12 @@ Double clic sur la légende ou le tracé pour afficher/cacher la légende.Préparation du téléversement firmware sur la carte. - + + To upgrade the OPLinkMini board please disconnect it from the USB port, press the Upgrade button again and follow instructions on screen. + Pour mettre à jour une carte OPLinkMini veuillez la déconnecter du port USB, appuyez à nouveau sur le bouton de Mise à jour et suivez les instructions à l'écran. + + + Please disconnect your board. Veuillez déconnecter votre carte. @@ -11790,7 +10701,7 @@ Double clic sur la légende ou le tracé pour afficher/cacher la légende.Veuillez connecter votre carte. - + Waiting for all boards to be disconnected from USB. Attente de la déconnexion de toutes les cartes connectées en USB. @@ -11810,12 +10721,7 @@ Double clic sur la légende ou le tracé pour afficher/cacher la légende.Téléversement de la description du nouveau firmware sur la carte. - - http://wiki.openpilot.org/x/AoBZ - - - - + Confirm Settings Erase? Confirmer l'Effacement des Paramètres ? @@ -11862,7 +10768,7 @@ La carte sera redémarrée et tous les paramètres effacés. Veuillez vérifier que la carte n'est pas armée et appuyez à nouveau Réinitialiser pour continuer ou allumer/éteindre la carte pour forcer la réinitialisation. - + Annuler @@ -12440,6 +11346,96 @@ La carte sera redémarrée et tous les paramètres effacés. 0 + + + Select output curve for Accessory1 RcInput + Sélectionnez la courbe de mixage pour l'entrée RC Accessory1 + + + + Select output channel for Accessory0 RcInput + Sélectionnez le canal de sortie pour l'entrée RC Accessory0 + + + + Accessory0 + + + + + RC Input + Entrées RC + + + + Accessory1 + + + + + RcOutput channels + Canaux de sortie RC + + + + RC Output 1 + Sortie RC 1 + + + + Select output channel for Accessory2 RcInput + Sélectionnez le canal de sortie pour l'entrée RC Accessory2 + + + + Select output channel for Accessory1 RcInput + Sélectionnez le canal de sortie pour l'entrée RC Accessory1 + + + + Accessory2 + + + + + RcOutput curve + Courbe de sortie RC + + + + Curve + Courbe + + + + Select output curve for Accessory0 RcInput + Sélectionnez la courbe de mixage pour l'entrée RC Accessory0 + + + + Select output curve for Accessory3 RcInput + Sélectionnez la courbe de mixage pour l'entrée RC Accessory3 + + + + Select output curve for Accessory2 RcInput + Sélectionnez la courbe de mixage pour l'entrée RC Accessory2 + + + + Accessory3 + + + + + Select output channel for Accessory3 RcInput + Sélectionnez le canal de sortie pour l'entrée RC Accessory3 + + + + RC Output 2 + Sortie RC 2 + GroundConfigWidget @@ -12600,51 +11596,11 @@ Les valeurs classiques sont de 50% en configuration + et X sur les quadricoptèr Motor output channels Canaux de sortie moteurs - - - 1 - 1 - Assign your motor output channels using the drawing above as a reference. Respect propeller rotation. Affecter les canaux de sortie des moteurs en utilisant le dessin ci-dessus comme référence. Respectez le sens des moteurs. - - - 2 - 2 - - - - 3 - 3 - - - - 4 - 4 - - - - 5 - 5 - - - - 6 - 6 - - - - 7 - 7 - - - - 8 - 8 - Multirotor Motor Direction @@ -12767,6 +11723,46 @@ Les valeurs classiques sont de 100% en configuration + et 50% en configuration X Select output curve for Accessory3 RcInput Sélectionnez la courbe de mixage pour l'entrée RC Accessory3 + + + Pos5 + + + + + Pos6 + + + + + Pos7 + + + + + Pos8 + + + + + Pos1 + + + + + Pos2 + + + + + Pos3 + + + + + Pos4 + + RevoHWWidget @@ -12783,7 +11779,7 @@ Les valeurs classiques sont de 100% en configuration + et 50% en configuration X USB HID Function - + Fonction HID USB @@ -12793,27 +11789,27 @@ Les valeurs classiques sont de 100% en configuration + et 50% en configuration X Flexi Port - + Port Flexi Main Port - + Port Main Sonar Port - + Port Sonar Receiver Port - + Port Récepteur USB VCP Function - + Fonction VCP USB @@ -12862,27 +11858,11 @@ Méfiez-vous de ne pas vous verrouiller l'accès ! Form Formulaire - - - button:help - Pas toucher ! - - - - - Send settings to the board but do not save to the non-volatile memory - Envoyer les paramètres sur la carte sans enregistrer dans la mémoire non volatile - Apply Appliquer - - - Send settings to the board and save to the non-volatile memory - Envoyer les paramètres sur la carte et enregistrer dans la mémoire non volatile - Save @@ -12893,26 +11873,11 @@ Méfiez-vous de ne pas vous verrouiller l'accès ! Status Statut - - - 12345678 - - Link State État Liaison - - - The modems current state - L'état actuel du modem - - - - Disconnected - Déconnecté - Firmware Ver. @@ -12951,7 +11916,7 @@ Méfiez-vous de ne pas vous verrouiller l'accès ! TX Seq. No. - Seq Tx N° + Seq TX N° @@ -12961,7 +11926,7 @@ Méfiez-vous de ne pas vous verrouiller l'accès ! RX Seq. No. - Seq. Rx N° + Seq. RX N° @@ -13008,11 +11973,6 @@ Méfiez-vous de ne pas vous verrouiller l'accès ! TX Dropped Tx Perdus - - - Tx Failure - TX Défaillants - Free Heap @@ -13048,21 +12008,6 @@ Méfiez-vous de ne pas vous verrouiller l'accès ! %v dBm %v dBm - - - Bind - Associer - - - - This modem will be a coordinator and other modems will bind to it. - Ce modem sera coordinateur et les autres modems s'associeront avec lui. - - - - Coordinator - Coordinateur - Configuration @@ -13081,62 +12026,22 @@ Méfiez-vous de ne pas vous verrouiller l'accès ! VCP Port - - - - - Choose the function for the flexi port - Choisir la fonction pour le flexi port + Port VCP Main Port - - - - - Choose the function for the main port - Choisir la fonction pour le main port - - - - Set the maximum TX output power the modem will use (mW) - Ajuste la puissance maximale de sortie utilisée par le modem (mW) + Port Main Max Power Puissance Maxi - - - Choose the function for the USB virtual com port - Choisir la fonction pour le USB virtual com port - - - - FlexiIO Port - - Flexi Port - - - - - If selected, data will only be transmitted from the coordinator to the Rx modem. - Si coché, les données sont uniquement transmises du coordinateur vers le modem Rx. - - - - Only PPM packets will be transmitted. - Seulement les paquets PPM seront transmis. - - - - PPM Only - PPM Seul + Port Flexi @@ -13148,41 +12053,11 @@ Méfiez-vous de ne pas vous verrouiller l'accès ! Min Chan Canal Mini - - - PPM packets will be received by this modem. Must be selected if Coordinator modem is configured for PPM. - Les paquets PPM sont reçus par ce modem. Doit être sélectionné si le modem coordinateur est configuré en PPM. - - - - PPM - - - - - OPLink configuration - Configuration OPLink - - - - One-Way - Unidirectionnel - - - - Remote modems - Modems distants - Coordinator ID ID Coordinateur - - - <html><head/><body><p>This is the coordinator id we currently are bound to.</p><p>To manually bind to a specific coordinator, just type</p><p>or paste its device id in this box and save.</p><p>The device must be rebooted for the binding to take place.</p></body></html> - <html><head/><body><p>Ceci est l'identifiant coordinateur avec lequel vous êtes associé.</p><p>Pour s'associer manuellement avec un coordinateur particulier, tapez simplement ou copier/coller l'identifiant de l'appareil dans ce champ puis enregistrer.</p><p>L'appareil doit être redémarré pour que l'association soit effective.</p></body></html> - Channel 0 is 430 MHz, channel 250 is 440 MHz, and the channel spacing is 40 KHz. @@ -13198,6 +12073,120 @@ Méfiez-vous de ne pas vous verrouiller l'accès ! 430.000 (MHz) + + + OPLink Configuration + Configuration OPLink + + + + The modems current state. + L'état actuel du modem. + + + + TX Failure + TX Défaillants + + + + TX Packet Rate + Paquets TX/s + + + + RX Packet Rate + Paquets RX/s + + + + RX Level + Niveau RX + + + + Choose the function for the main port. + Choisir la fonction pour le main port. + + + + Set the maximum TX output power the modem will use (mW) +0 to disable the modem. + Ajuste la puissance de sortie maximale utilisée par le modem (mW) +0 pour désactiver le modem. + + + + Enter your custom ID for this device as a hexadecimal value, +this allows device clones. Be sure only one device with this +ID transmits at the same time! +Leave blank to use autogenerated Device ID. + Entrez la valeur hexadécimale de l'ID personnalisé pour cet appareil, +cela permet de cloner des appareils. Soyez certain que seulement un +seul appareil avec cet ID va émettre à un moment donné ! +Laisser vide pour utiliser l'ID automatiquement généré. + + + + This is the coordinator ID we currently are bound to. +To manually bind to a specific coordinator, just type +or paste its device ID in this box and save. +The device must be rebooted for the binding to take place. + Ceci est l'ID du coordinateur avec lequel vous êtes associé. +Pour vous associer avec un modem coordinateur particulier, +tapez ou collez son ID dans cette case et enregistrez. +L'appareil doit être redémarré pour que l'association soit effective. + + + + Choose the function for the flexi port. + Choisir la fonction pour le flexi port. + + + + Choose the function for the USB virtual com port. + Choisir la fonction pour le port com virtuel USB. + + + + Send settings to the board but do not save to the non-volatile memory. + Envoyer les paramètres sur la carte sans enregistrer dans la mémoire. + + + + Send settings to the board and save to the non-volatile memory. + Envoyer les paramètres sur la carte et enregistrer dans la mémoire. + + + + Clear the binding/coordinator ID + Effacer l'association / ID du coordinateur + + + + Unbind + Dissocier + + + + Set the modem protocol + Ajuste le protocole du modem + + + + Protocol + Protocole + + + + Link Type + Type Lien + + + + Configure what type of packets will be sent over the link + Configure le type de paquets qui vont être envoyés à travers la liaison + PathActionEditor @@ -13339,18 +12328,18 @@ p, li { white-space: pre-wrap; } ConfigOutputWidget - + - - - + %1 Hz %1 Hz - + The actuator module is in an error state. This can also occur because there are no inputs. Please fix these before testing outputs. Le module actionneur est en erreur. Cela peut aussi arriver lorsque il n'y a pas d'entrées (Rx radiocommande). Veuillez corriger cela avant de tester les sorties. @@ -13365,7 +12354,17 @@ p, li { white-space: pre-wrap; } Vous pouvez enregistrer vos changements des réglages de neutre. - + + AlwaysStabilizeWhenArmed is <b>ACTIVE</b>. This prevents arming!. + AlwaysStabilizeWhenArmed est <b>ACTIF</b>. Ceci empêche l'armement !. + + + + (Really be careful!). + (Soyez très prudent !). + + + OneShot and PWMSync output only works with Receiver Port settings marked with '+OneShot'<br>When using Receiver Port setting 'PPM_PIN8+OneShot' <b><font color='%1'>Bank %2</font></b> must be set to PWM OneShot et PWMSync fonctionnent uniquement avec les ports récepteur marqués avec '+OneShot'<br>Lors de l'utilisation de la configuration 'PPM_PIN8+OneShot' <b><font color='%1'>la Banque %2</font></b> doit être réglée sur PWM @@ -13373,7 +12372,7 @@ p, li { white-space: pre-wrap; } ConfigRevoHWWidget - + Disabled Désactivé @@ -13442,7 +12441,7 @@ p, li { white-space: pre-wrap; } PfdQmlGadgetFactory - + PFD @@ -13458,7 +12457,7 @@ p, li { white-space: pre-wrap; } DeviceWidget - + Device ID: ID Périphérique : @@ -13468,7 +12467,7 @@ p, li { white-space: pre-wrap; } Révision Matériel : - + Flash access: Accès flash : @@ -13553,7 +12552,7 @@ p, li { white-space: pre-wrap; } Firmware chargé : - + Select firmware file Sélectionner le fichier de firmware @@ -13572,7 +12571,7 @@ p, li { white-space: pre-wrap; } RunningDeviceWidget - + HW Revision: Révision Matériel : @@ -13582,7 +12581,7 @@ p, li { white-space: pre-wrap; } CRC Firmware : - + BL version: Version BL : @@ -13663,36 +12662,46 @@ Veuillez sélectionner une zone de la carte à télécharger avec <CTRL>+C AboutDialog - + LibrePilot Ground Control Station Station de Contrôle au Sol LibrePilot (GCS) - + + Revision: <b>%1</b><br/>UAVO Hash: <b>%2</b><br/><br/>Built from %3<br/>Built on %4 at %5<br/>Based on Qt %6 (%7 bit)<br/><br/>u00A9 The %8 Project, 2015-%9. All rights reserved.<br/>u00A9 The OpenPilot Project, 2010-2015. All rights reserved.<br/> + Révision : <b>%1</b><br/>Hash UAVO : <b>%2</b><br/><br/>Compilé depuis %3<br/>Compilé le %4 à %5<br/>Basé sur Qt %6 (%7 bit)<br/><br/>u00A9 Le Projet %8, 2015-%9. Tous droits réservés.<br/>u00A9 Le Projet OpenPilot, 2010-2015 . Tout droits réservés.<br/> + + + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Ce programme est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier dans le cadre des termes de la licence GNU General Public Licence publiée par la Free Software Foundation; soit à la version 3 de la Licence, ou (en option) à une version ultérieure. Le programme est fourni EN L'ÉTAT sans AUCUNE GARANTIE D'UN QUELCONQUE TYPE, COMPRENANT LA GARANTIE DE DESIGN, DE COMMERCIALISATION ET D'ERGONOMIE POUR UN USAGE PARTICULIER. - + Contributors Contributeurs - + + Credits + Crédits + + + + License + Licence + + + Ok - + About %1 A propos de %1 - - - Revision: <b>%1</b><br/>UAVO Hash: <b>%2</b><br/><br/>Built from %3<br/>Built on %4 at %5<br/>Based on Qt %6 (%7 bit)<br/><br/>&copy; The %8 Project, %9. All rights reserved.<br/>&copy; The OpenPilot Project 2010-2015. All rights reserved.<br/> - Révision : <b>%1</b><br/>Hash UAVO : <b>%2</b><br/><br/>Compilé depuis %3<br/>Compilé le %4 à %5<br/>Basé sur Qt %6 (%7 bit)<br/><br/>&copy; Le Projet %8, %9. Tous droits réservés.<br/>&copy; Le Projet OpenPilot 2010-2015 . Tout droits réservés.<br/> - OPEndPage @@ -14175,7 +13184,7 @@ Veuillez vérifier le fichier. MonitorGadgetFactory - + Telemetry Monitor Moniteur de Télémétrie @@ -14183,7 +13192,7 @@ Veuillez vérifier le fichier. MonitorWidget - + Connected Connecté @@ -14196,12 +13205,12 @@ Veuillez vérifier le fichier. ConfigStabilizationWidget - + Settings Bank %1 Banque Paramètres %1 - + Thrust Poussée @@ -14211,7 +13220,7 @@ Veuillez vérifier le fichier. Facteur d'ajustement - + all to saved tout vers enregistré @@ -14278,7 +13287,7 @@ pas seulement les champs visibles à l'écran. avec %1 - + Input % Entrée % @@ -14291,7 +13300,7 @@ pas seulement les champs visibles à l'écran. ModelUavoProxy - + Path Plan Upload Failed Échec Téléversement Projet de Trajet @@ -14455,7 +13464,7 @@ Des valeurs trop élevées pour les contrôles principaux peuvent entraîner des et même conduire au crash. A utiliser avec prudence. - + Chan %1 Canal %1 @@ -14474,6 +13483,11 @@ et même conduire au crash. A utiliser avec prudence. Channel Value Valeur Canal + + + Channel input value (µs) + Valeur Canal d'Entrée (µs) + ConfigVehicleTypeWidget @@ -14519,7 +13533,7 @@ et même conduire au crash. A utiliser avec prudence. OpenPilot::LevelCalibrationModel - + Place horizontally and press Save Position... Positionner horizontalement et cliquer sur le bouton Enregistrer Position... @@ -14542,7 +13556,7 @@ et même conduire au crash. A utiliser avec prudence. OpenPilot::SixPointCalibrationModel - + Place horizontally, nose pointing north and press Save Position... Positionner horizontalement, le nez en direction du nord et cliquer sur le bouton Enregistrer Position... @@ -14612,7 +13626,7 @@ et même conduire au crash. A utiliser avec prudence. Étalonnage abandonné ! - + Hold... Maintenir en position... @@ -14671,7 +13685,7 @@ et même conduire au crash. A utiliser avec prudence. TimedDialog - + Cancel Annuler @@ -14777,7 +13791,7 @@ et même conduire au crash. A utiliser avec prudence. ConfigRevoWidget - + Temperature: %1°C Température : %1°C @@ -14791,6 +13805,31 @@ et même conduire au crash. A utiliser avec prudence. Sampled range: %1°C Plage d'échantillonnage : %1°C + + + Source invalid + Source invalide + + + + Currently no attitude estimation algorithm uses magnetometer or there is something wrong + Actuellement l'algorithme d'estimation de l'attitude n'utilise pas de magnétomètre ou quelque chose ne va pas + + + + Onboard magnetometer + Magnétomètre interne + + + + Auxiliary magnetometer + Magnétomètre auxiliaire + + + + Unknown + Inconnu + AirframeInitialTuningPage @@ -14822,22 +13861,11 @@ p, li { white-space: pre-wrap; } WizardPage Page d'Assistant - - - Standard ESC 50Hz - Variateur Standard 50Hz - Standard ESC Variateur Standard - - - Turbo PWM ESC 400Hz - or 500Hz ? - Variateur Turbo PWM 400Hz - Rapid ESC @@ -14865,6 +13893,21 @@ p, li { white-space: pre-wrap; } <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:10pt;">Afin de régler de manière optimale la configuration des signaux de sortie qui pilotent vos moteurs, l'assistant doit connaître le type de contrôleur de vitesse (ESC) utilisé et leurs capacités.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:10pt;">Veuillez sélectionner une des options ci-dessous. En cas de doute sur les possibilités de vos ESC, laissez l'option sélectionnée par défaut et continuez l'assistant.</span></p></body></html> + + + Standard ESC: Slow refresh rate (50Hz), not recommended for Multirotors. + Esc Standard : Vitesse de rafraîchissement lente (50Hz), non recommandé pour les multirotors. + + + + Rapid ESC: Usually Simonk, 490Hz refresh rate. + Esc rapide : Généralement Simonk, vitesse de rafraîchissement de 490Hz. + + + + OneShot ESC: BLHeli, Kiss... + ESC OneShot : BLHeli, Kiss... + SelectionPage @@ -14873,18 +13916,6 @@ p, li { white-space: pre-wrap; } WizardPage Page d'Assistant - - - placeholder_text - Pas toucher - - - - - TextLabel - Pas toucher - - Select: @@ -15247,16 +14278,21 @@ Veuillez essayer à nouveau. Import Importer + + + Sparky2 + + AirSpeedPage - + Estimated Estimée - + Airspeed Sensor Selection Sélection Capteur Vitesse Air @@ -15274,7 +14310,7 @@ Note : si une configuration d'entrée Rc utilise le port Flexi, seule l&apo - + This option uses an intelligent estimation algorithm which utilizes the INS/GPS to estimate wind speed and subtract it from ground speed obtained from the GPS. This solution is highly accurate in normal level flight with the drawback of being less accurate in rapid altitude changes. @@ -15318,7 +14354,7 @@ Le choix de cette option va paramétrer le Flexi-Port de votre carte en mode I2C GpsPage - + Please select the type of GPS you wish to use. As well as OpenPilot hardware, 3rd party GPSs are supported also, although please note that performance could be less than optimal as not all GPSs are created equal. Note: NMEA only GPSs perform poorly on VTOL aircraft and are not recommended for Helis and MultiRotors. @@ -15355,7 +14391,32 @@ Note: for the OpenPilot v8 GPS please select the U-Blox option. A noter : Pour le GPS OpenPilot v8, veuillez choisir l'option GPS U-Blox. - + + Naza GPS + GPS Naza + + + + Select this option to use the Naza GPS with integrated Magnetometer. + Sélectionnez cette option pour utiliser le GPS Naza avec Magnétomètre intégré. + + + + U-Blox Based + Magnetometer + GPS U-Blox + Magnétomètre + + + + Select this option for the generic U-Blox chipset based GPS + I2C Magnetometer. + +GPS is connected to MainPort and two wires I2C to FlexiPort. + Sélectionnez cette option pour utiliser le GPS U-Blox générique + Magnétomètre I2C. + +Le GPS est connecté au port Main et les deux fils de l'I2C sur le port Flexi. + + + + Select this option for the OpenPilot V8 GPS or generic U-Blox chipset based GPS. Sélectionnez cette option pour utiliser le GPS OpenPilot v8 ou un GPS U-Blox générique. @@ -15370,12 +14431,12 @@ A noter : Pour le GPS OpenPilot v8, veuillez choisir l'option GPS U-Blox.Basé sur U-Blox - + GPS Selection Sélection GPS - + NMEA Based Basé sur NMEA @@ -15393,8 +14454,8 @@ A noter : Pour le GPS OpenPilot v8, veuillez choisir l'option GPS U-Blox.Démarrer - - + + @@ -15462,7 +14523,7 @@ p, li { white-space: pre-wrap; } UAVObjectBrowserWidget - + Name Nom @@ -15591,36 +14652,10 @@ p, li { white-space: pre-wrap; } ConfigOPLinkWidget - - - - - Unbind - Dissocier - - - - - - - Bind - Associer - - - + Unknown Inconnu - - - Information - Information - - - - To apply the changes when binding/unbinding the board must be rebooted or power cycled. - Pour appliquer les changements d'association/dissociation la carte doit être redémarrée ou débranchée/rebranchée. - InputWizardWidget @@ -15740,18 +14775,18 @@ IMPORTANT : Ces nouveaux paramètres ne sont pas encore enregistrés sur la cart Surface: has reversible motor controlled by throttle stick, plus yaw control (2 channels) - Terrestre : A un moteur inversable contrôlé par le manche des gaz plus une direction Yaw (2 canaux) + Terrestre : possède un moteur inversable contrôlé par le manche des gaz plus une direction (2 canaux) <html><head/><body><p>If selecting the Helicopter option, please engage throttle hold now.</p><p>If selecting the Surface option, the <b>Flight Mode Count</b> will be set to be 1.</p></body></html> - <html><head/><body><p>Si l'option Hélicoptère est sélectionnée, veuillez maintenir le manche des gaz maintenant.</p><p>Si l'option Terrestre est sélectionnée, le nombre de <b>Modes de Vol</b> sera fixé à 1.</p></body></html> + <html><head/><body><p>Si l'option Hélicoptère est sélectionnée, veuillez maintenir le manche des gaz maintenant.</p><p>Si l'option Terrestre est sélectionnée, le nombre de <b>Modes de Vol</b> sera fixé à 1.</p></body></html> ConfigCcpmWidget - + <h1>Swashplate Leveling Routine</h1> @@ -15796,7 +14831,7 @@ IMPORTANT : Ces nouveaux paramètres ne sont pas encore enregistrés sur la cart - + <font color=red><h1>Warning!!!</h2></font> @@ -15969,12 +15004,12 @@ Il est suggéré que si cela est une première configuration de votre contrôleu UsageTrackerPlugin - + Usage feedback Retour d'utilisation - + Yes, count me in Oui, comptez sur moi @@ -15985,8 +15020,8 @@ Il est suggéré que si cela est une première configuration de votre contrôleu - %1 has a function to collect limited anonymous information about the usage of the application itself and the hardware connected to it.<p>The intention is to not include anything that can be considered sensitive or a threat to the users integrity. The collected information will be sent using a secure protocol to an %2 web service and stored in a database for later analysis and statistical purposes.<br>No information will be sold or given to any third party. The sole purpose is to collect statistics about the usage of our software and hardware to enable us to make things better for you.<p>The following things are collected:<ul><li>Bootloader version</li><li>Firmware version, tag and git hash</li><li>Hardware type, revision and mcu serial number</li><li>Selected configuration parameters</li><li>GCS version</li><li>Operating system version and architecture</li><li>Current local time</li></ul>The information is collected only at the time when a board is connecting to GCS.<p>It is possible to enable or disable this functionality in the general settings part of the options for the GCS application at any time.<p>We need your help, with your feedback we know where to improve things and what platforms are in use. This is a community project that depends on people being involved.<br>Thank You for helping us making things better and for supporting %2! - %1 possède une fonction qui permet de collecter les informations de manière anonyme sur l'utilisation de l'application en elle-même ainsi que le matériel connecté dessus.<p>Il n'est pas question de collecter des informations sensibles ou pouvant représenter une menace pour l'intégrité des utilisateurs. Les informations collectées seront envoyées vers un site web %2 en utilisant un protocole sécurisé et stockées dans une base de données pour une analyse et des statistiques ultérieures.<br>Aucune information ne sera vendue ou donnée à une quelconque tierce partie. Le seul but est de collecter des informations à propos de l'utilisation de notre logiciel / matériel pour nous permettre de l'améliorer.<p>Les éléments suivants sont collectés :<ul><li>Version bootloader</li><li>Version firmware, tag et git hash</li><li>Type de matériel, révision et numéro de série CPU</li><li>Paramètres de configuration sélectionnés</li><li>Version GCS</li><li>Système d'exploitation et architecture</li><li>Fuseau horaire</li></ul>Les informations sont collectées au moment de la connexion de la carte avec GCS.<p>Il est possible d'activer ou de désactiver cette fonctionnalité à tout moment dans le menu Options > Paramètres généraux de GCS.<p>Nous avons besoin de votre aide, avec votre participation nous connaîtrons où apporter des améliorations et quelle plateforme vous utilisez. C'est un projet communautaire qui dépend de l'implication des utilisateurs.<br>Merci de nous aider à rendre les choses meilleures et soutenir %2 ! + <p>%1 has a function to collect limited anonymous information about the usage of the application itself and the hardware connected to it.</p><p>The intention is to not include anything that can be considered sensitive or a threat to the users integrity. The collected information will be sent using a secure protocol to an %2 web service and stored in a database for later analysis and statistical purposes. No information will be sold or given to any third party. The sole purpose is to collect statistics about the usage of our software and hardware to enable us to make things better for you.</p>The following things are collected:<ul><li>Bootloader version</li><li>Firmware version, tag and git hash</li><li>Hardware type, revision and mcu serial number</li><li>Selected configuration parameters</li><li>GCS version</li><li>Operating system version and architecture</li><li>Current local time</li></ul><p>The information is collected only at the time when a board is connecting to GCS. It is possible to enable or disable this functionality in the general settings part of the options for the GCS application at any time.</p><p>We need your help, with your feedback we know where to improve things and what platforms are in use. This is a community project that depends on people being involved.</p>Thank You for helping us making things better and for supporting %2! + <p>%1 possède une fonction qui permet de collecter les informations de manière anonyme sur l'utilisation de l'application en elle-même ainsi que le matériel connecté dessus.</p><p>Il n'est pas question de collecter des informations sensibles ou pouvant représenter une menace pour l'intégrité des utilisateurs. Les informations collectées seront envoyées vers un site web %2 en utilisant un protocole sécurisé et stockées dans une base de données pour une analyse et des statistiques ultérieures. Aucune information ne sera vendue ou donnée à une quelconque tierce partie. Le seul but est de collecter des informations à propos de l'utilisation de notre logiciel / matériel pour nous permettre de l'améliorer.</p>Les éléments suivants sont collectés :<ul><li>Version bootloader</li><li>Version firmware, tag et git hash</li><li>Type de matériel, révision et numéro de série CPU</li><li>Paramètres de configuration sélectionnés</li><li>Version GCS</li><li>Système d'exploitation et architecture</li><li>Fuseau horaire</li></ul><p>Les informations sont collectées au moment de la connexion de la carte avec GCS. Il est possible d'activer ou de désactiver cette fonctionnalité à tout moment dans le menu Options > Paramètres généraux de GCS.</p><p>Nous avons besoin de votre aide, avec votre participation nous connaîtrons où apporter des améliorations et quelle plateforme vous utilisez. C'est un projet communautaire qui dépend de l'implication des utilisateurs.</p>Merci de nous aider à rendre les choses meilleures et soutenir %2 ! @@ -15994,7 +15029,7 @@ Il est suggéré que si cela est une première configuration de votre contrôleu &Ne pas afficher ce message à nouveau. - + Unknown Inconnu @@ -16024,22 +15059,22 @@ Il est suggéré que si cela est une première configuration de votre contrôleu Receiver Port - + Port Récepteur USB HID Function - + Fonction HID USB USB VCP Function - + Fonction VCP USB Main Port - + Port Main @@ -16049,7 +15084,7 @@ Il est suggéré que si cela est une première configuration de votre contrôleu Flexi Port - + Port Flexi @@ -16084,7 +15119,7 @@ Méfiez-vous de ne pas vous verrouiller l'accès ! ConfigFixedWingWidget - + Rudders are optional for Elevon frame Les dérives sont optionnelles sur une aile volante (elevon) @@ -16115,8 +15150,199 @@ Méfiez-vous de ne pas vous verrouiller l'accès ! + + Channel already used Canal déjà utilisé + + + Select first output channel for Accessory%1 RcInput + Sélectionnez le premier canal de sortie pour l'entrée RC Accessory%1 + + + + Select second output channel for Accessory%1 RcInput + Sélectionnez le deuxième canal de sortie pour l'entrée RC Accessory%1 + + + + Sparky2HWWidget + + + Form + Formulaire + + + + HW settings + Paramètres Matériels + + + + Changes on this page only take effect after board reset or power cycle + Les changements sur cette page ne prendront effet qu'après un reset ou une coupure d'alimentation + + + + I2C (under) + I2C (en dessous) + + + + Speed + Vitesse + + + + USB VCP Function + Fonction VCP USB + + + + USB HID Function + Fonction HID USB + + + + Receiver Port + Port Récepteur + + + + Flexi Port + Port Flexi + + + + Protocol + Protocole + + + + Main Port + Port Main + + + + Takes you to the wiki page + Vous renvoie à la page wiki + + + + Send to board but don't write in SD. +Beware of not locking yourself out! + Envoie vers la carte mais n'écrit pas dans la SD. +Méfiez-vous de ne pas vous verrouiller l'accès ! + + + + Apply + Appliquer + + + + Applies and Saves all settings to SD. +Beware of not locking yourself out! + Applique et Enregistre tous les paramètres dans la SD. +Méfiez-vous de ne pas vous verrouiller l'accès ! + + + + Save + Enregistrer + + + + FailsafeChannelForm + + + Form + Formulaire + + + + Channel value + Valeur canal + + + + Channel Value relative to channel Neutral + Valeur Canal, relative au Neutre + + + + Value + Valeur + + + + Channel value in % + Valeur canal en % + + + + % + + + + + Channel function + Fonction canal + + + + Function + Fonction + + + + Text + Texte + + + + StreamServicePlugin + + + Couldn't start StreamService: + Impossible de démarrer le service de diffusion : + + + + defaultconfig + + + Form + Formulaire + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">This panel will be updated to provide the relevant controls to let you configure your device once it is connected and running.</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Ce panneau sera mis à jour pour vous fournir les contrôles pertinents afin de vous permettre de configurer votre matériel, une fois que la télémétrie est connectée et en cours d'exécution.</span></p></body></html> + + + + Takes you to the wiki page + Vous renvoie à la page wiki + + + + Apply + Appliquer + + + + Save + Enregistrer + diff --git a/ground/gcs/src/share/vehicletemplates/fixedwing/EPPIndoorFizz-FixedWing-Aileron-668c9bf1112.optmpl b/ground/gcs/src/share/vehicletemplates/fixedwing/EPPIndoorFizz-FixedWing-Aileron-668c9bf1112.optmpl new file mode 100644 index 000000000..caa326cfb --- /dev/null +++ b/ground/gcs/src/share/vehicletemplates/fixedwing/EPPIndoorFizz-FixedWing-Aileron-668c9bf1112.optmpl @@ -0,0 +1,2232 @@ +{ + "battery": "480mAh - 2S", + "comment": "Aileron - one servo", + "controller": "Revolution", + "esc": "12A", + "motor": "1500Kv - 100W", + "name": "EPP Indoor Fizz", + "nick": "f5soh", + "objects": [ + { + "fields": [ + { + "name": "VbarSensitivity", + "type": "float32", + "unit": "frac", + "values": [ + { + "name": "Roll", + "value": 0.5 + }, + { + "name": "Pitch", + "value": 0.5 + }, + { + "name": "Yaw", + "value": 0.5 + } + ] + }, + { + "name": "VbarRollPI", + "type": "float32", + "unit": "1/(deg/s)", + "values": [ + { + "name": "Kp", + "value": 0.004999999888241291 + }, + { + "name": "Ki", + "value": 0.0020000000949949026 + } + ] + }, + { + "name": "VbarPitchPI", + "type": "float32", + "unit": "1/(deg/s)", + "values": [ + { + "name": "Kp", + "value": 0.004999999888241291 + }, + { + "name": "Ki", + "value": 0.0020000000949949026 + } + ] + }, + { + "name": "VbarYawPI", + "type": "float32", + "unit": "1/(deg/s)", + "values": [ + { + "name": "Kp", + "value": 0.004999999888241291 + }, + { + "name": "Ki", + "value": 0.0020000000949949026 + } + ] + }, + { + "name": "VbarTau", + "type": "float32", + "unit": "sec", + "values": [ + { + "name": "0", + "value": 0.5 + } + ] + }, + { + "name": "GyroTau", + "type": "float32", + "unit": "", + "values": [ + { + "name": "0", + "value": 0.0030000000260770321 + } + ] + }, + { + "name": "DerivativeGamma", + "type": "float32", + "unit": "", + "values": [ + { + "name": "0", + "value": 1 + } + ] + }, + { + "name": "AxisLockKp", + "type": "float32", + "unit": "", + "values": [ + { + "name": "0", + "value": 2.5 + } + ] + }, + { + "name": "WeakLevelingKp", + "type": "float32", + "unit": "(deg/s)/deg", + "values": [ + { + "name": "0", + "value": 0.10000000149011612 + } + ] + }, + { + "name": "CruiseControlMaxPowerFactor", + "type": "float32", + "unit": "x", + "values": [ + { + "name": "0", + "value": 3 + } + ] + }, + { + "name": "CruiseControlPowerTrim", + "type": "float32", + "unit": "%", + "values": [ + { + "name": "0", + "value": 100 + } + ] + }, + { + "name": "CruiseControlPowerDelayComp", + "type": "float32", + "unit": "sec", + "values": [ + { + "name": "0", + "value": 0.25 + } + ] + }, + { + "name": "ScaleToAirspeed", + "type": "float32", + "unit": "m/s", + "values": [ + { + "name": "0", + "value": 0 + } + ] + }, + { + "name": "ScaleToAirspeedLimits", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Min", + "value": 0.05000000074505806 + }, + { + "name": "Max", + "value": 3 + } + ] + }, + { + "name": "FlightModeMap", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Bank1" + }, + { + "name": "1", + "value": "Bank1" + }, + { + "name": "2", + "value": "Bank1" + }, + { + "name": "3", + "value": "Bank1" + }, + { + "name": "4", + "value": "Bank1" + }, + { + "name": "5", + "value": "Bank1" + } + ] + }, + { + "name": "VbarGyroSuppress", + "type": "int8", + "unit": "%", + "values": [ + { + "name": "0", + "value": 30 + } + ] + }, + { + "name": "VbarPiroComp", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "False" + } + ] + }, + { + "name": "VbarMaxAngle", + "type": "uint8", + "unit": "deg", + "values": [ + { + "name": "0", + "value": 10 + } + ] + }, + { + "name": "DerivativeCutoff", + "type": "uint8", + "unit": "Hz", + "values": [ + { + "name": "0", + "value": 20 + } + ] + }, + { + "name": "MaxAxisLock", + "type": "uint8", + "unit": "deg", + "values": [ + { + "name": "0", + "value": 30 + } + ] + }, + { + "name": "MaxAxisLockRate", + "type": "uint8", + "unit": "deg/s", + "values": [ + { + "name": "0", + "value": 2 + } + ] + }, + { + "name": "MaxWeakLevelingRate", + "type": "uint8", + "unit": "deg/s", + "values": [ + { + "name": "0", + "value": 5 + } + ] + }, + { + "name": "RattitudeModeTransition", + "type": "uint8", + "unit": "%", + "values": [ + { + "name": "0", + "value": 80 + } + ] + }, + { + "name": "CruiseControlMinThrust", + "type": "int8", + "unit": "%", + "values": [ + { + "name": "0", + "value": 5 + } + ] + }, + { + "name": "CruiseControlMaxThrust", + "type": "uint8", + "unit": "%", + "values": [ + { + "name": "0", + "value": 100 + } + ] + }, + { + "name": "CruiseControlMaxAngle", + "type": "uint8", + "unit": "deg", + "values": [ + { + "name": "0", + "value": 105 + } + ] + }, + { + "name": "CruiseControlFlightModeSwitchPosEnable", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "False" + }, + { + "name": "1", + "value": "False" + }, + { + "name": "2", + "value": "False" + }, + { + "name": "3", + "value": "False" + }, + { + "name": "4", + "value": "False" + }, + { + "name": "5", + "value": "False" + } + ] + }, + { + "name": "CruiseControlInvertedThrustReversing", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Unreversed" + } + ] + }, + { + "name": "CruiseControlInvertedPowerOutput", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Zero" + } + ] + }, + { + "name": "LowThrottleZeroIntegral", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "True" + } + ] + }, + { + "name": "FlightModeAssistMap", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "None" + }, + { + "name": "1", + "value": "None" + }, + { + "name": "2", + "value": "None" + }, + { + "name": "3", + "value": "None" + }, + { + "name": "4", + "value": "None" + }, + { + "name": "5", + "value": "None" + } + ] + }, + { + "name": "MeasureBasedDTerm", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "True" + } + ] + } + ], + "id": "F4D8AECC", + "instance": 0, + "name": "StabilizationSettings", + "setting": true + }, + { + "fields": [ + { + "name": "RollRatePID", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 0.002199999988079071 + }, + { + "name": "Ki", + "value": 0.0065000001341104507 + }, + { + "name": "Kd", + "value": 4.9999998736893758e-05 + }, + { + "name": "ILimit", + "value": 0.30000001192092896 + } + ] + }, + { + "name": "PitchRatePID", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 0.0030000000260770321 + }, + { + "name": "Ki", + "value": 0.0065000001341104507 + }, + { + "name": "Kd", + "value": 4.9999998736893758e-05 + }, + { + "name": "ILimit", + "value": 0.30000001192092896 + } + ] + }, + { + "name": "YawRatePID", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 0.0062000001780688763 + }, + { + "name": "Ki", + "value": 0.0099999997764825821 + }, + { + "name": "Kd", + "value": 4.9999998736893758e-05 + }, + { + "name": "ILimit", + "value": 0.30000001192092896 + } + ] + }, + { + "name": "RollPI", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 2.5 + }, + { + "name": "Ki", + "value": 0 + }, + { + "name": "ILimit", + "value": 50 + } + ] + }, + { + "name": "PitchPI", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 2.5 + }, + { + "name": "Ki", + "value": 0 + }, + { + "name": "ILimit", + "value": 50 + } + ] + }, + { + "name": "YawPI", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 2.5 + }, + { + "name": "Ki", + "value": 0 + }, + { + "name": "ILimit", + "value": 50 + } + ] + }, + { + "name": "ManualRate", + "type": "uint16", + "unit": "degrees/sec", + "values": [ + { + "name": "Roll", + "value": 360 + }, + { + "name": "Pitch", + "value": 360 + }, + { + "name": "Yaw", + "value": 220 + } + ] + }, + { + "name": "MaximumRate", + "type": "uint16", + "unit": "degrees/sec", + "values": [ + { + "name": "Roll", + "value": 300 + }, + { + "name": "Pitch", + "value": 300 + }, + { + "name": "Yaw", + "value": 300 + } + ] + }, + { + "name": "RollMax", + "type": "uint8", + "unit": "degrees", + "values": [ + { + "name": "0", + "value": 90 + } + ] + }, + { + "name": "PitchMax", + "type": "uint8", + "unit": "degrees", + "values": [ + { + "name": "0", + "value": 85 + } + ] + }, + { + "name": "YawMax", + "type": "uint8", + "unit": "degrees", + "values": [ + { + "name": "0", + "value": 35 + } + ] + }, + { + "name": "StickExpo", + "type": "int8", + "unit": "percent", + "values": [ + { + "name": "Roll", + "value": 0 + }, + { + "name": "Pitch", + "value": 0 + }, + { + "name": "Yaw", + "value": 0 + } + ] + }, + { + "name": "AcroInsanityFactor", + "type": "uint8", + "unit": "percent", + "values": [ + { + "name": "Roll", + "value": 60 + }, + { + "name": "Pitch", + "value": 60 + }, + { + "name": "Yaw", + "value": 40 + } + ] + }, + { + "name": "EnablePiroComp", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "False" + } + ] + }, + { + "name": "FpvCamTiltCompensation", + "type": "uint8", + "unit": "deg", + "values": [ + { + "name": "0", + "value": 0 + } + ] + }, + { + "name": "EnableThrustPIDScaling", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "False" + } + ] + }, + { + "name": "ThrustPIDScaleCurve", + "type": "int8", + "unit": "percent", + "values": [ + { + "name": "0", + "value": 30 + }, + { + "name": "25", + "value": 15 + }, + { + "name": "50", + "value": 0 + }, + { + "name": "75", + "value": -15 + }, + { + "name": "100", + "value": -30 + } + ] + }, + { + "name": "ThrustPIDScaleSource", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "ActuatorDesiredThrust" + } + ] + }, + { + "name": "ThrustPIDScaleTarget", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "PID" + } + ] + }, + { + "name": "ThrustPIDScaleAxes", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Roll Pitch" + } + ] + } + ], + "id": "CAC270DC", + "instance": 0, + "name": "StabilizationSettingsBank1", + "setting": true + }, + { + "fields": [ + { + "name": "RollRatePID", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 0.0030000000260770321 + }, + { + "name": "Ki", + "value": 0.0065000001341104507 + }, + { + "name": "Kd", + "value": 3.3000000257743523e-05 + }, + { + "name": "ILimit", + "value": 0.30000001192092896 + } + ] + }, + { + "name": "PitchRatePID", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 0.0030000000260770321 + }, + { + "name": "Ki", + "value": 0.0065000001341104507 + }, + { + "name": "Kd", + "value": 3.3000000257743523e-05 + }, + { + "name": "ILimit", + "value": 0.30000001192092896 + } + ] + }, + { + "name": "YawRatePID", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 0.0062000001780688763 + }, + { + "name": "Ki", + "value": 0.0099999997764825821 + }, + { + "name": "Kd", + "value": 4.9999998736893758e-05 + }, + { + "name": "ILimit", + "value": 0.30000001192092896 + } + ] + }, + { + "name": "RollPI", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 2.5 + }, + { + "name": "Ki", + "value": 0 + }, + { + "name": "ILimit", + "value": 50 + } + ] + }, + { + "name": "PitchPI", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 2.5 + }, + { + "name": "Ki", + "value": 0 + }, + { + "name": "ILimit", + "value": 50 + } + ] + }, + { + "name": "YawPI", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 2.5 + }, + { + "name": "Ki", + "value": 0 + }, + { + "name": "ILimit", + "value": 50 + } + ] + }, + { + "name": "ManualRate", + "type": "uint16", + "unit": "degrees/sec", + "values": [ + { + "name": "Roll", + "value": 220 + }, + { + "name": "Pitch", + "value": 220 + }, + { + "name": "Yaw", + "value": 220 + } + ] + }, + { + "name": "MaximumRate", + "type": "uint16", + "unit": "degrees/sec", + "values": [ + { + "name": "Roll", + "value": 300 + }, + { + "name": "Pitch", + "value": 300 + }, + { + "name": "Yaw", + "value": 300 + } + ] + }, + { + "name": "RollMax", + "type": "uint8", + "unit": "degrees", + "values": [ + { + "name": "0", + "value": 55 + } + ] + }, + { + "name": "PitchMax", + "type": "uint8", + "unit": "degrees", + "values": [ + { + "name": "0", + "value": 55 + } + ] + }, + { + "name": "YawMax", + "type": "uint8", + "unit": "degrees", + "values": [ + { + "name": "0", + "value": 35 + } + ] + }, + { + "name": "StickExpo", + "type": "int8", + "unit": "percent", + "values": [ + { + "name": "Roll", + "value": 0 + }, + { + "name": "Pitch", + "value": 0 + }, + { + "name": "Yaw", + "value": 0 + } + ] + }, + { + "name": "AcroInsanityFactor", + "type": "uint8", + "unit": "percent", + "values": [ + { + "name": "Roll", + "value": 40 + }, + { + "name": "Pitch", + "value": 40 + }, + { + "name": "Yaw", + "value": 40 + } + ] + }, + { + "name": "EnablePiroComp", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "True" + } + ] + }, + { + "name": "FpvCamTiltCompensation", + "type": "uint8", + "unit": "deg", + "values": [ + { + "name": "0", + "value": 0 + } + ] + }, + { + "name": "EnableThrustPIDScaling", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "False" + } + ] + }, + { + "name": "ThrustPIDScaleCurve", + "type": "int8", + "unit": "percent", + "values": [ + { + "name": "0", + "value": 30 + }, + { + "name": "25", + "value": 15 + }, + { + "name": "50", + "value": 0 + }, + { + "name": "75", + "value": -15 + }, + { + "name": "100", + "value": -30 + } + ] + }, + { + "name": "ThrustPIDScaleSource", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "ActuatorDesiredThrust" + } + ] + }, + { + "name": "ThrustPIDScaleTarget", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "PID" + } + ] + }, + { + "name": "ThrustPIDScaleAxes", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Roll Pitch" + } + ] + } + ], + "id": "E039134", + "instance": 0, + "name": "StabilizationSettingsBank2", + "setting": true + }, + { + "fields": [ + { + "name": "RollRatePID", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 0.0030000000260770321 + }, + { + "name": "Ki", + "value": 0.0065000001341104507 + }, + { + "name": "Kd", + "value": 3.3000000257743523e-05 + }, + { + "name": "ILimit", + "value": 0.30000001192092896 + } + ] + }, + { + "name": "PitchRatePID", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 0.0030000000260770321 + }, + { + "name": "Ki", + "value": 0.0065000001341104507 + }, + { + "name": "Kd", + "value": 3.3000000257743523e-05 + }, + { + "name": "ILimit", + "value": 0.30000001192092896 + } + ] + }, + { + "name": "YawRatePID", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 0.0062000001780688763 + }, + { + "name": "Ki", + "value": 0.0099999997764825821 + }, + { + "name": "Kd", + "value": 4.9999998736893758e-05 + }, + { + "name": "ILimit", + "value": 0.30000001192092896 + } + ] + }, + { + "name": "RollPI", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 2.5 + }, + { + "name": "Ki", + "value": 0 + }, + { + "name": "ILimit", + "value": 50 + } + ] + }, + { + "name": "PitchPI", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 2.5 + }, + { + "name": "Ki", + "value": 0 + }, + { + "name": "ILimit", + "value": 50 + } + ] + }, + { + "name": "YawPI", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 2.5 + }, + { + "name": "Ki", + "value": 0 + }, + { + "name": "ILimit", + "value": 50 + } + ] + }, + { + "name": "ManualRate", + "type": "uint16", + "unit": "degrees/sec", + "values": [ + { + "name": "Roll", + "value": 220 + }, + { + "name": "Pitch", + "value": 220 + }, + { + "name": "Yaw", + "value": 220 + } + ] + }, + { + "name": "MaximumRate", + "type": "uint16", + "unit": "degrees/sec", + "values": [ + { + "name": "Roll", + "value": 300 + }, + { + "name": "Pitch", + "value": 300 + }, + { + "name": "Yaw", + "value": 300 + } + ] + }, + { + "name": "RollMax", + "type": "uint8", + "unit": "degrees", + "values": [ + { + "name": "0", + "value": 55 + } + ] + }, + { + "name": "PitchMax", + "type": "uint8", + "unit": "degrees", + "values": [ + { + "name": "0", + "value": 55 + } + ] + }, + { + "name": "YawMax", + "type": "uint8", + "unit": "degrees", + "values": [ + { + "name": "0", + "value": 35 + } + ] + }, + { + "name": "StickExpo", + "type": "int8", + "unit": "percent", + "values": [ + { + "name": "Roll", + "value": 0 + }, + { + "name": "Pitch", + "value": 0 + }, + { + "name": "Yaw", + "value": 0 + } + ] + }, + { + "name": "AcroInsanityFactor", + "type": "uint8", + "unit": "percent", + "values": [ + { + "name": "Roll", + "value": 40 + }, + { + "name": "Pitch", + "value": 40 + }, + { + "name": "Yaw", + "value": 40 + } + ] + }, + { + "name": "EnablePiroComp", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "True" + } + ] + }, + { + "name": "FpvCamTiltCompensation", + "type": "uint8", + "unit": "deg", + "values": [ + { + "name": "0", + "value": 0 + } + ] + }, + { + "name": "EnableThrustPIDScaling", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "False" + } + ] + }, + { + "name": "ThrustPIDScaleCurve", + "type": "int8", + "unit": "percent", + "values": [ + { + "name": "0", + "value": 30 + }, + { + "name": "25", + "value": 15 + }, + { + "name": "50", + "value": 0 + }, + { + "name": "75", + "value": -15 + }, + { + "name": "100", + "value": -30 + } + ] + }, + { + "name": "ThrustPIDScaleSource", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "ActuatorDesiredThrust" + } + ] + }, + { + "name": "ThrustPIDScaleTarget", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "PID" + } + ] + }, + { + "name": "ThrustPIDScaleAxes", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Roll Pitch" + } + ] + } + ], + "id": "5C80D844", + "instance": 0, + "name": "StabilizationSettingsBank3", + "setting": true + }, + { + "fields": [ + { + "name": "ThrottleCurve1", + "type": "float32", + "unit": "percent", + "values": [ + { + "name": "0", + "value": 0 + }, + { + "name": "25", + "value": 0.25 + }, + { + "name": "50", + "value": 0.5 + }, + { + "name": "75", + "value": 0.75 + }, + { + "name": "100", + "value": 1 + } + ] + }, + { + "name": "ThrottleCurve2", + "type": "float32", + "unit": "percent", + "values": [ + { + "name": "0", + "value": 0 + }, + { + "name": "25", + "value": 0.25 + }, + { + "name": "50", + "value": 0.5 + }, + { + "name": "75", + "value": 0.75 + }, + { + "name": "100", + "value": 1 + } + ] + }, + { + "name": "MixerValueRoll", + "type": "int8", + "unit": "percent", + "values": [ + { + "name": "0", + "value": 100 + } + ] + }, + { + "name": "MixerValuePitch", + "type": "int8", + "unit": "percent", + "values": [ + { + "name": "0", + "value": 100 + } + ] + }, + { + "name": "MixerValueYaw", + "type": "int8", + "unit": "percent", + "values": [ + { + "name": "0", + "value": 100 + } + ] + }, + { + "name": "RollDifferential", + "type": "int8", + "unit": "percent", + "values": [ + { + "name": "0", + "value": 0 + } + ] + }, + { + "name": "FirstRollServo", + "type": "uint8", + "unit": "", + "values": [ + { + "name": "0", + "value": 0 + } + ] + }, + { + "name": "Curve2Source", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Throttle" + } + ] + }, + { + "name": "Mixer1Type", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Servo" + } + ] + }, + { + "name": "Mixer1Vector", + "type": "int8", + "unit": "", + "values": [ + { + "name": "ThrottleCurve1", + "value": 0 + }, + { + "name": "ThrottleCurve2", + "value": 0 + }, + { + "name": "Roll", + "value": 127 + }, + { + "name": "Pitch", + "value": 0 + }, + { + "name": "Yaw", + "value": 0 + } + ] + }, + { + "name": "Mixer2Type", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Servo" + } + ] + }, + { + "name": "Mixer2Vector", + "type": "int8", + "unit": "", + "values": [ + { + "name": "ThrottleCurve1", + "value": 0 + }, + { + "name": "ThrottleCurve2", + "value": 0 + }, + { + "name": "Roll", + "value": 0 + }, + { + "name": "Pitch", + "value": 127 + }, + { + "name": "Yaw", + "value": 0 + } + ] + }, + { + "name": "Mixer3Type", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Servo" + } + ] + }, + { + "name": "Mixer3Vector", + "type": "int8", + "unit": "", + "values": [ + { + "name": "ThrottleCurve1", + "value": 0 + }, + { + "name": "ThrottleCurve2", + "value": 0 + }, + { + "name": "Roll", + "value": 0 + }, + { + "name": "Pitch", + "value": 0 + }, + { + "name": "Yaw", + "value": -127 + } + ] + }, + { + "name": "Mixer4Type", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Motor" + } + ] + }, + { + "name": "Mixer4Vector", + "type": "int8", + "unit": "", + "values": [ + { + "name": "ThrottleCurve1", + "value": 127 + }, + { + "name": "ThrottleCurve2", + "value": 0 + }, + { + "name": "Roll", + "value": 0 + }, + { + "name": "Pitch", + "value": 0 + }, + { + "name": "Yaw", + "value": 0 + } + ] + }, + { + "name": "Mixer5Type", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Disabled" + } + ] + }, + { + "name": "Mixer5Vector", + "type": "int8", + "unit": "", + "values": [ + { + "name": "ThrottleCurve1", + "value": 0 + }, + { + "name": "ThrottleCurve2", + "value": 0 + }, + { + "name": "Roll", + "value": 0 + }, + { + "name": "Pitch", + "value": 0 + }, + { + "name": "Yaw", + "value": 0 + } + ] + }, + { + "name": "Mixer6Type", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Disabled" + } + ] + }, + { + "name": "Mixer6Vector", + "type": "int8", + "unit": "", + "values": [ + { + "name": "ThrottleCurve1", + "value": 0 + }, + { + "name": "ThrottleCurve2", + "value": 0 + }, + { + "name": "Roll", + "value": 0 + }, + { + "name": "Pitch", + "value": 0 + }, + { + "name": "Yaw", + "value": 0 + } + ] + }, + { + "name": "Mixer7Type", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Disabled" + } + ] + }, + { + "name": "Mixer7Vector", + "type": "int8", + "unit": "", + "values": [ + { + "name": "ThrottleCurve1", + "value": 0 + }, + { + "name": "ThrottleCurve2", + "value": 0 + }, + { + "name": "Roll", + "value": 0 + }, + { + "name": "Pitch", + "value": 0 + }, + { + "name": "Yaw", + "value": 0 + } + ] + }, + { + "name": "Mixer8Type", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Disabled" + } + ] + }, + { + "name": "Mixer8Vector", + "type": "int8", + "unit": "", + "values": [ + { + "name": "ThrottleCurve1", + "value": 0 + }, + { + "name": "ThrottleCurve2", + "value": 0 + }, + { + "name": "Roll", + "value": 0 + }, + { + "name": "Pitch", + "value": 0 + }, + { + "name": "Yaw", + "value": 0 + } + ] + }, + { + "name": "Mixer9Type", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Disabled" + } + ] + }, + { + "name": "Mixer9Vector", + "type": "int8", + "unit": "", + "values": [ + { + "name": "ThrottleCurve1", + "value": 0 + }, + { + "name": "ThrottleCurve2", + "value": 0 + }, + { + "name": "Roll", + "value": 0 + }, + { + "name": "Pitch", + "value": 0 + }, + { + "name": "Yaw", + "value": 0 + } + ] + }, + { + "name": "Mixer10Type", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Disabled" + } + ] + }, + { + "name": "Mixer10Vector", + "type": "int8", + "unit": "", + "values": [ + { + "name": "ThrottleCurve1", + "value": 0 + }, + { + "name": "ThrottleCurve2", + "value": 0 + }, + { + "name": "Roll", + "value": 0 + }, + { + "name": "Pitch", + "value": 0 + }, + { + "name": "Yaw", + "value": 0 + } + ] + }, + { + "name": "Mixer11Type", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Disabled" + } + ] + }, + { + "name": "Mixer11Vector", + "type": "int8", + "unit": "", + "values": [ + { + "name": "ThrottleCurve1", + "value": 0 + }, + { + "name": "ThrottleCurve2", + "value": 0 + }, + { + "name": "Roll", + "value": 0 + }, + { + "name": "Pitch", + "value": 0 + }, + { + "name": "Yaw", + "value": 0 + } + ] + }, + { + "name": "Mixer12Type", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Disabled" + } + ] + }, + { + "name": "Mixer12Vector", + "type": "int8", + "unit": "", + "values": [ + { + "name": "ThrottleCurve1", + "value": 0 + }, + { + "name": "ThrottleCurve2", + "value": 0 + }, + { + "name": "Roll", + "value": 0 + }, + { + "name": "Pitch", + "value": 0 + }, + { + "name": "Yaw", + "value": 0 + } + ] + } + ], + "id": "810D3A5E", + "instance": 0, + "name": "MixerSettings", + "setting": true + }, + { + "fields": [ + { + "name": "P", + "type": "float32", + "unit": "1^2", + "values": [ + { + "name": "PositionNorth", + "value": 10 + }, + { + "name": "PositionEast", + "value": 10 + }, + { + "name": "PositionDown", + "value": 10 + }, + { + "name": "VelocityNorth", + "value": 1 + }, + { + "name": "VelocityEast", + "value": 1 + }, + { + "name": "VelocityDown", + "value": 1 + }, + { + "name": "AttitudeQ1", + "value": 0.0070000002160668373 + }, + { + "name": "AttitudeQ2", + "value": 0.0070000002160668373 + }, + { + "name": "AttitudeQ3", + "value": 0.0070000002160668373 + }, + { + "name": "AttitudeQ4", + "value": 0.0070000002160668373 + }, + { + "name": "GyroDriftX", + "value": 9.9999999747524271e-07 + }, + { + "name": "GyroDriftY", + "value": 9.9999999747524271e-07 + }, + { + "name": "GyroDriftZ", + "value": 9.9999999747524271e-07 + } + ] + }, + { + "name": "Q", + "type": "float32", + "unit": "1^2", + "values": [ + { + "name": "GyroX", + "value": 0.0099999997764825821 + }, + { + "name": "GyroY", + "value": 0.0099999997764825821 + }, + { + "name": "GyroZ", + "value": 0.0099999997764825821 + }, + { + "name": "AccelX", + "value": 0.0099999997764825821 + }, + { + "name": "AccelY", + "value": 0.0099999997764825821 + }, + { + "name": "AccelZ", + "value": 0.0099999997764825821 + }, + { + "name": "GyroDriftX", + "value": 9.9999999747524271e-07 + }, + { + "name": "GyroDriftY", + "value": 9.9999999747524271e-07 + }, + { + "name": "GyroDriftZ", + "value": 9.9999999747524271e-07 + } + ] + }, + { + "name": "R", + "type": "float32", + "unit": "1^2", + "values": [ + { + "name": "GPSPosNorth", + "value": 1 + }, + { + "name": "GPSPosEast", + "value": 1 + }, + { + "name": "GPSPosDown", + "value": 1000000 + }, + { + "name": "GPSVelNorth", + "value": 0.0010000000474974513 + }, + { + "name": "GPSVelEast", + "value": 0.0010000000474974513 + }, + { + "name": "GPSVelDown", + "value": 0.0010000000474974513 + }, + { + "name": "MagX", + "value": 10 + }, + { + "name": "MagY", + "value": 10 + }, + { + "name": "MagZ", + "value": 10 + }, + { + "name": "BaroZ", + "value": 0.0099999997764825821 + } + ] + }, + { + "name": "FakeR", + "type": "float32", + "unit": "1^2", + "values": [ + { + "name": "FakeGPSPosIndoor", + "value": 10 + }, + { + "name": "FakeGPSVelIndoor", + "value": 1 + }, + { + "name": "FakeGPSVelAirspeed", + "value": 1000 + } + ] + } + ], + "id": "5E91213C", + "instance": 0, + "name": "EKFConfiguration", + "setting": true + } + ], + "owner": "f5soh", + "photo": "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BY9d6xRvVCXEQiQaYouDD3suqoOGUnWvvj+a9Zj6611QSrtrNsmarDJ714ZM5wtknMAnlambK6O1bmZqPitsP3pLWhWTqhBALApniSsZYkwUQDAkkWT169/55udf/GS0SjW56ar9WjM3RZ8NO3txtbraXAG3syUcH+N0QV60gUfJgTG4OHeYqvXaIMtNGF0EgtTBsBnC3gVZCuLOODu40JkYHc4nshARfRpNlIUuaoLkKeBowq4lSMIbz0AaH13g0QlZVt/6bBnGfusMCzgaUlnGcmzHFogjgIvABCiZCo78698qVBSKZ84kFbmLwfaRcwEgE4Uib/rgr9djCB0LRkmUPF+vB8Y0T0gDopf9ZgxebNtQFiUlTwErUR02tQ2WOR5smh/WV6vu5gVKm5khqooXNYGWPqbJpEpky0rHMXadI1LGBEL+y985LXK3G/urfds0XE9i340KdLd1+z29et6bFjJQdcLvfXyQyfhLX6sOT6Add6gFZsI4d3xckPVxjE+e7cq8ZgApRMF4xvTJmRq2IyM2OSm32z4r+fxU7q7b2bxolmZxPHnx5LzM4MHDA9jGqebrbm+duLzYt71vMjEpc67gereLmIABQDqc5ssC759kh7NsMSltNybPuMhkDZWWN/3Vfkv93kdJs8PF58+em0hf//jgol3LUglLgYQB7wm9TbZFClxWfAyWa269KaalIHbzsp82jfXp5npo27Tf07aN2ZTVS33ddttXAQz+40+OD7Razha73eiBnr/s8yrbDz5CWLVtRGpKffH5vsmLg+nk5ro1FpqCJ8RM5RAoEHCNmlgmZcBkyclCEA9FzesJH0drgstyKcStzs6QieC85EJKKYQIzqVEQmkXXDMrvbe29zymz3/8k9dXm3v37scATV2/FS6+QoK/i193PX7v/hhCICLGuBAiJbLWmfHWKZJuN+GXD/suofBLqP1VUsydabwFTIxAYI2JEYsiv10O/ZC8IwJiepMUhARAt0D/bh0VEfitvoJvITikJy9urs/52RJ//R8tD5fx73786r/75799cJRzLhGBcX67SvGeLPPzW/H2H7yj6xNAwkQRhs5cXL5ebc//1e/9mx8//VsfXkqA9Y3lwDiDTCslRde65BiQ7XYBkBOSt8kFGL3fD8EjThY4zclvE5+LG2PDgJNJ3ig0bRggmQExsXv3qr7thdAn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", + "propeller": "8x4", + "servo": "Towerpro 9g", + "size": "830mm", + "subtype": 15, + "type": 2, + "uuid": "{f7489cdb-b4b6-42ea-aee0-3668c9bf1112}", + "weight": "160g" +} diff --git a/ground/gcs/src/share/vehicletemplates/fixedwing/SoniModelMako-FixedWing-Elevon-7134e8ae5ce.optmpl b/ground/gcs/src/share/vehicletemplates/fixedwing/SoniModelMako-FixedWing-Elevon-7134e8ae5ce.optmpl index 298ffb12f..95d6b69e2 100644 --- a/ground/gcs/src/share/vehicletemplates/fixedwing/SoniModelMako-FixedWing-Elevon-7134e8ae5ce.optmpl +++ b/ground/gcs/src/share/vehicletemplates/fixedwing/SoniModelMako-FixedWing-Elevon-7134e8ae5ce.optmpl @@ -1598,7 +1598,7 @@ "values": [ { "name": "0", - "value": "Motor" + "value": "Disabled" } ] }, @@ -1609,7 +1609,7 @@ "values": [ { "name": "ThrottleCurve1", - "value": 127 + "value": 0 }, { "name": "ThrottleCurve2", @@ -1636,7 +1636,7 @@ "values": [ { "name": "0", - "value": "Disabled" + "value": "Motor" } ] }, @@ -1647,7 +1647,7 @@ "values": [ { "name": "ThrottleCurve1", - "value": 0 + "value": 127 }, { "name": "ThrottleCurve2", @@ -2163,4 +2163,4 @@ "type": 2, "uuid": "{8e22621f-8a3d-4df4-a55a-07134e8ae5ce}", "weight": "700g" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/fixedwing/Toro900-VoilureFixe-Elevon-d4a58d2cd50.optmpl b/ground/gcs/src/share/vehicletemplates/fixedwing/Toro900-VoilureFixe-Elevon-d4a58d2cd50.optmpl index a1377ff9c..7512ead90 100644 --- a/ground/gcs/src/share/vehicletemplates/fixedwing/Toro900-VoilureFixe-Elevon-d4a58d2cd50.optmpl +++ b/ground/gcs/src/share/vehicletemplates/fixedwing/Toro900-VoilureFixe-Elevon-d4a58d2cd50.optmpl @@ -1567,7 +1567,7 @@ "values": [ { "name": "0", - "value": "Motor" + "value": "Disabled" } ] }, @@ -1578,7 +1578,7 @@ "values": [ { "name": "ThrottleCurve1", - "value": 127 + "value": 0 }, { "name": "ThrottleCurve2", @@ -1605,7 +1605,7 @@ "values": [ { "name": "0", - "value": "Disabled" + "value": "Motor" } ] }, @@ -1616,7 +1616,7 @@ "values": [ { "name": "ThrottleCurve1", - "value": 0 + "value": 127 }, { "name": "ThrottleCurve2", @@ -2132,4 +2132,4 @@ "type": 2, "uuid": "{0847bef4-6b0b-42c9-8b4a-2d4a58d2cd50}", "weight": "500g" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/(RACE)FPV260HobbyKin-Multirotor-QuadrocopterX-0482b7a25f7.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/(RACE)FPV260HobbyKin-Multirotor-QuadrocopterX-0482b7a25f7.optmpl index 3bb7e21d0..826f8605d 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/(RACE)FPV260HobbyKin-Multirotor-QuadrocopterX-0482b7a25f7.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/(RACE)FPV260HobbyKin-Multirotor-QuadrocopterX-0482b7a25f7.optmpl @@ -1428,19 +1428,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1455,19 +1455,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2163,4 +2163,4 @@ "type": 1, "uuid": "{7ad6f2cb-0cb4-4995-b5c5-50482b7a25f7}", "weight": "420" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/(STOCK)HobbyKingFPV2-Multirotor-QuadrocopterX-0bb44b68883.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/(STOCK)HobbyKingFPV2-Multirotor-QuadrocopterX-0bb44b68883.optmpl index 64c35803f..320b4d360 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/(STOCK)HobbyKingFPV2-Multirotor-QuadrocopterX-0bb44b68883.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/(STOCK)HobbyKingFPV2-Multirotor-QuadrocopterX-0bb44b68883.optmpl @@ -1428,19 +1428,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1455,19 +1455,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2163,4 +2163,4 @@ "type": 1, "uuid": "{3a4b31e7-d087-48d4-8aae-10bb44b68883}", "weight": "420" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/ARRISX-SPEEDFPV250-Unsupported-2cbaaa14a01.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/ARRISX-SPEEDFPV250-Unsupported-2cbaaa14a01.optmpl index 6974e5967..914e7bfbb 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/ARRISX-SPEEDFPV250-Unsupported-2cbaaa14a01.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/ARRISX-SPEEDFPV250-Unsupported-2cbaaa14a01.optmpl @@ -1428,19 +1428,19 @@ }, { "name": "25", - "value": 0.44999998807907104 + "value": 0.25 }, { "name": "50", - "value": 0.61000001430511475 + "value": 0.5 }, { "name": "75", - "value": 0.7504696249961853 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2163,4 +2163,4 @@ "type": 0, "uuid": "{bb3dbbc6-72fc-426f-abdc-92cbaaa14a01}", "weight": "320" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/BlackOutB330-Multirotor-QuadrocopterX-e9980c55302.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/BlackOutB330-Multirotor-QuadrocopterX-e9980c55302.optmpl index 737863247..832d76c5b 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/BlackOutB330-Multirotor-QuadrocopterX-e9980c55302.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/BlackOutB330-Multirotor-QuadrocopterX-e9980c55302.optmpl @@ -1428,19 +1428,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1455,19 +1455,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2162,4 +2162,4 @@ "type": 1, "uuid": "{5bf30e57-f44b-427d-bfd6-9e9980c55302}", "weight": "1003" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/BlackOutMiniH-Multirotor-QuadrocopterX-d415c242154.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/BlackOutMiniH-Multirotor-QuadrocopterX-d415c242154.optmpl index afaca5df2..a4b125af5 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/BlackOutMiniH-Multirotor-QuadrocopterX-d415c242154.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/BlackOutMiniH-Multirotor-QuadrocopterX-d415c242154.optmpl @@ -1428,19 +1428,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1455,19 +1455,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2163,4 +2163,4 @@ "type": 1, "uuid": "{866002c8-1df9-4adc-8366-cd415c242154}", "weight": "490" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/DJIF450-Multirotor-QuadrocopterX-cfa8ec67993.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/DJIF450-Multirotor-QuadrocopterX-cfa8ec67993.optmpl index 298b25b16..03fb1ae6f 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/DJIF450-Multirotor-QuadrocopterX-cfa8ec67993.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/DJIF450-Multirotor-QuadrocopterX-cfa8ec67993.optmpl @@ -1428,19 +1428,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1455,19 +1455,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2163,4 +2163,4 @@ "type": 1, "uuid": "{61a45b74-2bbc-4e13-9650-0cfa8ec67993}", "weight": "1010" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/DroneframesDRQ250-cf-rc5 Multirotor-QuadrocopterX-425b90123f1.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/DroneframesDRQ250-cf-rc5 Multirotor-QuadrocopterX-425b90123f1.optmpl index deee7475b..a32dbd3a4 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/DroneframesDRQ250-cf-rc5 Multirotor-QuadrocopterX-425b90123f1.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/DroneframesDRQ250-cf-rc5 Multirotor-QuadrocopterX-425b90123f1.optmpl @@ -1397,19 +1397,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67500001192092896 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1424,19 +1424,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67500001192092896 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2132,4 +2132,4 @@ "type": 1, "uuid": "{f4735900-1ec8-470a-8457-f425b90123f1}", "weight": "570" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/DroneframesDRQ430G-revo-rc5Multirotor-QuadrocopterX-fae90503b3f.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/DroneframesDRQ430G-revo-rc5Multirotor-QuadrocopterX-fae90503b3f.optmpl index 98a375b00..058461e2b 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/DroneframesDRQ430G-revo-rc5Multirotor-QuadrocopterX-fae90503b3f.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/DroneframesDRQ430G-revo-rc5Multirotor-QuadrocopterX-fae90503b3f.optmpl @@ -1397,19 +1397,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67500001192092896 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1424,19 +1424,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67500001192092896 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2132,4 +2132,4 @@ "type": 1, "uuid": "{be6845b5-83df-448f-8795-4fae90503b3f}", "weight": "1200gr" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/EachineER250-Multirotor-QuadrocopterX-028a6476885.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/EachineER250-Multirotor-QuadrocopterX-028a6476885.optmpl new file mode 100644 index 000000000..8991ca6d6 --- /dev/null +++ b/ground/gcs/src/share/vehicletemplates/multirotor/EachineER250-Multirotor-QuadrocopterX-028a6476885.optmpl @@ -0,0 +1,2232 @@ +{ + "battery": "1500-3S", + "comment": "Stock Eachine ER250 Racer", + "controller": "CC3D", + "esc": "12A Simonk", + "motor": "2204 - 2300Kv", + "name": "Eachine ER250", + "nick": "LibrePilot", + "objects": [ + { + "fields": [ + { + "name": "VbarSensitivity", + "type": "float32", + "unit": "frac", + "values": [ + { + "name": "Roll", + "value": 0.5 + }, + { + "name": "Pitch", + "value": 0.5 + }, + { + "name": "Yaw", + "value": 0.5 + } + ] + }, + { + "name": "VbarRollPI", + "type": "float32", + "unit": "1/(deg/s)", + "values": [ + { + "name": "Kp", + "value": 0.004999999888241291 + }, + { + "name": "Ki", + "value": 0.0020000000949949026 + } + ] + }, + { + "name": "VbarPitchPI", + "type": "float32", + "unit": "1/(deg/s)", + "values": [ + { + "name": "Kp", + "value": 0.004999999888241291 + }, + { + "name": "Ki", + "value": 0.0020000000949949026 + } + ] + }, + { + "name": "VbarYawPI", + "type": "float32", + "unit": "1/(deg/s)", + "values": [ + { + "name": "Kp", + "value": 0.004999999888241291 + }, + { + "name": "Ki", + "value": 0.0020000000949949026 + } + ] + }, + { + "name": "VbarTau", + "type": "float32", + "unit": "sec", + "values": [ + { + "name": "0", + "value": 0.5 + } + ] + }, + { + "name": "GyroTau", + "type": "float32", + "unit": "", + "values": [ + { + "name": "0", + "value": 0.0030000000260770321 + } + ] + }, + { + "name": "DerivativeGamma", + "type": "float32", + "unit": "", + "values": [ + { + "name": "0", + "value": 1 + } + ] + }, + { + "name": "AxisLockKp", + "type": "float32", + "unit": "", + "values": [ + { + "name": "0", + "value": 2.5 + } + ] + }, + { + "name": "WeakLevelingKp", + "type": "float32", + "unit": "(deg/s)/deg", + "values": [ + { + "name": "0", + "value": 0.10000000149011612 + } + ] + }, + { + "name": "CruiseControlMaxPowerFactor", + "type": "float32", + "unit": "x", + "values": [ + { + "name": "0", + "value": 3 + } + ] + }, + { + "name": "CruiseControlPowerTrim", + "type": "float32", + "unit": "%", + "values": [ + { + "name": "0", + "value": 100 + } + ] + }, + { + "name": "CruiseControlPowerDelayComp", + "type": "float32", + "unit": "sec", + "values": [ + { + "name": "0", + "value": 0.25 + } + ] + }, + { + "name": "ScaleToAirspeed", + "type": "float32", + "unit": "m/s", + "values": [ + { + "name": "0", + "value": 0 + } + ] + }, + { + "name": "ScaleToAirspeedLimits", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Min", + "value": 0.05000000074505806 + }, + { + "name": "Max", + "value": 3 + } + ] + }, + { + "name": "FlightModeMap", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Bank1" + }, + { + "name": "1", + "value": "Bank1" + }, + { + "name": "2", + "value": "Bank2" + }, + { + "name": "3", + "value": "Bank1" + }, + { + "name": "4", + "value": "Bank1" + }, + { + "name": "5", + "value": "Bank1" + } + ] + }, + { + "name": "VbarGyroSuppress", + "type": "int8", + "unit": "%", + "values": [ + { + "name": "0", + "value": 30 + } + ] + }, + { + "name": "VbarPiroComp", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "False" + } + ] + }, + { + "name": "VbarMaxAngle", + "type": "uint8", + "unit": "deg", + "values": [ + { + "name": "0", + "value": 10 + } + ] + }, + { + "name": "DerivativeCutoff", + "type": "uint8", + "unit": "Hz", + "values": [ + { + "name": "0", + "value": 20 + } + ] + }, + { + "name": "MaxAxisLock", + "type": "uint8", + "unit": "deg", + "values": [ + { + "name": "0", + "value": 30 + } + ] + }, + { + "name": "MaxAxisLockRate", + "type": "uint8", + "unit": "deg/s", + "values": [ + { + "name": "0", + "value": 2 + } + ] + }, + { + "name": "MaxWeakLevelingRate", + "type": "uint8", + "unit": "deg/s", + "values": [ + { + "name": "0", + "value": 5 + } + ] + }, + { + "name": "RattitudeModeTransition", + "type": "uint8", + "unit": "%", + "values": [ + { + "name": "0", + "value": 80 + } + ] + }, + { + "name": "CruiseControlMinThrust", + "type": "int8", + "unit": "%", + "values": [ + { + "name": "0", + "value": 5 + } + ] + }, + { + "name": "CruiseControlMaxThrust", + "type": "uint8", + "unit": "%", + "values": [ + { + "name": "0", + "value": 100 + } + ] + }, + { + "name": "CruiseControlMaxAngle", + "type": "uint8", + "unit": "deg", + "values": [ + { + "name": "0", + "value": 105 + } + ] + }, + { + "name": "CruiseControlFlightModeSwitchPosEnable", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "False" + }, + { + "name": "1", + "value": "False" + }, + { + "name": "2", + "value": "False" + }, + { + "name": "3", + "value": "False" + }, + { + "name": "4", + "value": "False" + }, + { + "name": "5", + "value": "False" + } + ] + }, + { + "name": "CruiseControlInvertedThrustReversing", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Unreversed" + } + ] + }, + { + "name": "CruiseControlInvertedPowerOutput", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Zero" + } + ] + }, + { + "name": "LowThrottleZeroIntegral", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "True" + } + ] + }, + { + "name": "FlightModeAssistMap", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "None" + }, + { + "name": "1", + "value": "None" + }, + { + "name": "2", + "value": "None" + }, + { + "name": "3", + "value": "None" + }, + { + "name": "4", + "value": "None" + }, + { + "name": "5", + "value": "None" + } + ] + }, + { + "name": "MeasureBasedDTerm", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "True" + } + ] + } + ], + "id": "F4D8AECC", + "instance": 0, + "name": "StabilizationSettings", + "setting": true + }, + { + "fields": [ + { + "name": "RollRatePID", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 0.0034000000450760126 + }, + { + "name": "Ki", + "value": 0.011900000274181366 + }, + { + "name": "Kd", + "value": 4.6000001020729542e-05 + }, + { + "name": "ILimit", + "value": 0.30000001192092896 + } + ] + }, + { + "name": "PitchRatePID", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 0.0044999998062849045 + }, + { + "name": "Ki", + "value": 0.015900000929832458 + }, + { + "name": "Kd", + "value": 6.0999998822808266e-05 + }, + { + "name": "ILimit", + "value": 0.30000001192092896 + } + ] + }, + { + "name": "YawRatePID", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 0.0078999996185302734 + }, + { + "name": "Ki", + "value": 0.01510000042617321 + }, + { + "name": "Kd", + "value": 6.7000000854022801e-05 + }, + { + "name": "ILimit", + "value": 0.30000001192092896 + } + ] + }, + { + "name": "RollPI", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 2 + }, + { + "name": "Ki", + "value": 0 + }, + { + "name": "ILimit", + "value": 50 + } + ] + }, + { + "name": "PitchPI", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 2 + }, + { + "name": "Ki", + "value": 0 + }, + { + "name": "ILimit", + "value": 50 + } + ] + }, + { + "name": "YawPI", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 2.5 + }, + { + "name": "Ki", + "value": 0 + }, + { + "name": "ILimit", + "value": 50 + } + ] + }, + { + "name": "ManualRate", + "type": "uint16", + "unit": "degrees/sec", + "values": [ + { + "name": "Roll", + "value": 220 + }, + { + "name": "Pitch", + "value": 220 + }, + { + "name": "Yaw", + "value": 220 + } + ] + }, + { + "name": "MaximumRate", + "type": "uint16", + "unit": "degrees/sec", + "values": [ + { + "name": "Roll", + "value": 300 + }, + { + "name": "Pitch", + "value": 300 + }, + { + "name": "Yaw", + "value": 300 + } + ] + }, + { + "name": "RollMax", + "type": "uint8", + "unit": "degrees", + "values": [ + { + "name": "0", + "value": 55 + } + ] + }, + { + "name": "PitchMax", + "type": "uint8", + "unit": "degrees", + "values": [ + { + "name": "0", + "value": 55 + } + ] + }, + { + "name": "YawMax", + "type": "uint8", + "unit": "degrees", + "values": [ + { + "name": "0", + "value": 35 + } + ] + }, + { + "name": "StickExpo", + "type": "int8", + "unit": "percent", + "values": [ + { + "name": "Roll", + "value": 0 + }, + { + "name": "Pitch", + "value": 0 + }, + { + "name": "Yaw", + "value": 0 + } + ] + }, + { + "name": "AcroInsanityFactor", + "type": "uint8", + "unit": "percent", + "values": [ + { + "name": "Roll", + "value": 55 + }, + { + "name": "Pitch", + "value": 55 + }, + { + "name": "Yaw", + "value": 40 + } + ] + }, + { + "name": "EnablePiroComp", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "True" + } + ] + }, + { + "name": "FpvCamTiltCompensation", + "type": "uint8", + "unit": "deg", + "values": [ + { + "name": "0", + "value": 10 + } + ] + }, + { + "name": "EnableThrustPIDScaling", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "False" + } + ] + }, + { + "name": "ThrustPIDScaleCurve", + "type": "int8", + "unit": "percent", + "values": [ + { + "name": "0", + "value": 30 + }, + { + "name": "25", + "value": 15 + }, + { + "name": "50", + "value": 0 + }, + { + "name": "75", + "value": -15 + }, + { + "name": "100", + "value": -30 + } + ] + }, + { + "name": "ThrustPIDScaleSource", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "ActuatorDesiredThrust" + } + ] + }, + { + "name": "ThrustPIDScaleTarget", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "PID" + } + ] + }, + { + "name": "ThrustPIDScaleAxes", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Roll Pitch" + } + ] + } + ], + "id": "CAC270DC", + "instance": 0, + "name": "StabilizationSettingsBank1", + "setting": true + }, + { + "fields": [ + { + "name": "RollRatePID", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 0.0034000000450760126 + }, + { + "name": "Ki", + "value": 0.011900000274181366 + }, + { + "name": "Kd", + "value": 4.6000001020729542e-05 + }, + { + "name": "ILimit", + "value": 0.30000001192092896 + } + ] + }, + { + "name": "PitchRatePID", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 0.0044999998062849045 + }, + { + "name": "Ki", + "value": 0.015900000929832458 + }, + { + "name": "Kd", + "value": 6.0999998822808266e-05 + }, + { + "name": "ILimit", + "value": 0.30000001192092896 + } + ] + }, + { + "name": "YawRatePID", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 0.0078999996185302734 + }, + { + "name": "Ki", + "value": 0.01510000042617321 + }, + { + "name": "Kd", + "value": 6.7000000854022801e-05 + }, + { + "name": "ILimit", + "value": 0.30000001192092896 + } + ] + }, + { + "name": "RollPI", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 2 + }, + { + "name": "Ki", + "value": 0 + }, + { + "name": "ILimit", + "value": 50 + } + ] + }, + { + "name": "PitchPI", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 2 + }, + { + "name": "Ki", + "value": 0 + }, + { + "name": "ILimit", + "value": 50 + } + ] + }, + { + "name": "YawPI", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 2.5 + }, + { + "name": "Ki", + "value": 0 + }, + { + "name": "ILimit", + "value": 50 + } + ] + }, + { + "name": "ManualRate", + "type": "uint16", + "unit": "degrees/sec", + "values": [ + { + "name": "Roll", + "value": 400 + }, + { + "name": "Pitch", + "value": 400 + }, + { + "name": "Yaw", + "value": 220 + } + ] + }, + { + "name": "MaximumRate", + "type": "uint16", + "unit": "degrees/sec", + "values": [ + { + "name": "Roll", + "value": 500 + }, + { + "name": "Pitch", + "value": 500 + }, + { + "name": "Yaw", + "value": 300 + } + ] + }, + { + "name": "RollMax", + "type": "uint8", + "unit": "degrees", + "values": [ + { + "name": "0", + "value": 55 + } + ] + }, + { + "name": "PitchMax", + "type": "uint8", + "unit": "degrees", + "values": [ + { + "name": "0", + "value": 55 + } + ] + }, + { + "name": "YawMax", + "type": "uint8", + "unit": "degrees", + "values": [ + { + "name": "0", + "value": 35 + } + ] + }, + { + "name": "StickExpo", + "type": "int8", + "unit": "percent", + "values": [ + { + "name": "Roll", + "value": 30 + }, + { + "name": "Pitch", + "value": 30 + }, + { + "name": "Yaw", + "value": 0 + } + ] + }, + { + "name": "AcroInsanityFactor", + "type": "uint8", + "unit": "percent", + "values": [ + { + "name": "Roll", + "value": 55 + }, + { + "name": "Pitch", + "value": 55 + }, + { + "name": "Yaw", + "value": 40 + } + ] + }, + { + "name": "EnablePiroComp", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "True" + } + ] + }, + { + "name": "FpvCamTiltCompensation", + "type": "uint8", + "unit": "deg", + "values": [ + { + "name": "0", + "value": 10 + } + ] + }, + { + "name": "EnableThrustPIDScaling", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "False" + } + ] + }, + { + "name": "ThrustPIDScaleCurve", + "type": "int8", + "unit": "percent", + "values": [ + { + "name": "0", + "value": 30 + }, + { + "name": "25", + "value": 15 + }, + { + "name": "50", + "value": 0 + }, + { + "name": "75", + "value": -15 + }, + { + "name": "100", + "value": -30 + } + ] + }, + { + "name": "ThrustPIDScaleSource", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "ActuatorDesiredThrust" + } + ] + }, + { + "name": "ThrustPIDScaleTarget", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "PID" + } + ] + }, + { + "name": "ThrustPIDScaleAxes", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Roll Pitch" + } + ] + } + ], + "id": "E039134", + "instance": 0, + "name": "StabilizationSettingsBank2", + "setting": true + }, + { + "fields": [ + { + "name": "RollRatePID", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 0.0034000000450760126 + }, + { + "name": "Ki", + "value": 0.011900000274181366 + }, + { + "name": "Kd", + "value": 4.6000001020729542e-05 + }, + { + "name": "ILimit", + "value": 0.30000001192092896 + } + ] + }, + { + "name": "PitchRatePID", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 0.0044999998062849045 + }, + { + "name": "Ki", + "value": 0.015900000929832458 + }, + { + "name": "Kd", + "value": 6.0999998822808266e-05 + }, + { + "name": "ILimit", + "value": 0.30000001192092896 + } + ] + }, + { + "name": "YawRatePID", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 0.0078999996185302734 + }, + { + "name": "Ki", + "value": 0.01510000042617321 + }, + { + "name": "Kd", + "value": 6.7000000854022801e-05 + }, + { + "name": "ILimit", + "value": 0.30000001192092896 + } + ] + }, + { + "name": "RollPI", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 2 + }, + { + "name": "Ki", + "value": 0 + }, + { + "name": "ILimit", + "value": 50 + } + ] + }, + { + "name": "PitchPI", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 2 + }, + { + "name": "Ki", + "value": 0 + }, + { + "name": "ILimit", + "value": 50 + } + ] + }, + { + "name": "YawPI", + "type": "float32", + "unit": "", + "values": [ + { + "name": "Kp", + "value": 2.5 + }, + { + "name": "Ki", + "value": 0 + }, + { + "name": "ILimit", + "value": 50 + } + ] + }, + { + "name": "ManualRate", + "type": "uint16", + "unit": "degrees/sec", + "values": [ + { + "name": "Roll", + "value": 220 + }, + { + "name": "Pitch", + "value": 220 + }, + { + "name": "Yaw", + "value": 220 + } + ] + }, + { + "name": "MaximumRate", + "type": "uint16", + "unit": "degrees/sec", + "values": [ + { + "name": "Roll", + "value": 300 + }, + { + "name": "Pitch", + "value": 300 + }, + { + "name": "Yaw", + "value": 300 + } + ] + }, + { + "name": "RollMax", + "type": "uint8", + "unit": "degrees", + "values": [ + { + "name": "0", + "value": 55 + } + ] + }, + { + "name": "PitchMax", + "type": "uint8", + "unit": "degrees", + "values": [ + { + "name": "0", + "value": 55 + } + ] + }, + { + "name": "YawMax", + "type": "uint8", + "unit": "degrees", + "values": [ + { + "name": "0", + "value": 35 + } + ] + }, + { + "name": "StickExpo", + "type": "int8", + "unit": "percent", + "values": [ + { + "name": "Roll", + "value": 0 + }, + { + "name": "Pitch", + "value": 0 + }, + { + "name": "Yaw", + "value": 0 + } + ] + }, + { + "name": "AcroInsanityFactor", + "type": "uint8", + "unit": "percent", + "values": [ + { + "name": "Roll", + "value": 55 + }, + { + "name": "Pitch", + "value": 55 + }, + { + "name": "Yaw", + "value": 40 + } + ] + }, + { + "name": "EnablePiroComp", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "True" + } + ] + }, + { + "name": "FpvCamTiltCompensation", + "type": "uint8", + "unit": "deg", + "values": [ + { + "name": "0", + "value": 10 + } + ] + }, + { + "name": "EnableThrustPIDScaling", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "False" + } + ] + }, + { + "name": "ThrustPIDScaleCurve", + "type": "int8", + "unit": "percent", + "values": [ + { + "name": "0", + "value": 30 + }, + { + "name": "25", + "value": 15 + }, + { + "name": "50", + "value": 0 + }, + { + "name": "75", + "value": -15 + }, + { + "name": "100", + "value": -30 + } + ] + }, + { + "name": "ThrustPIDScaleSource", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "ActuatorDesiredThrust" + } + ] + }, + { + "name": "ThrustPIDScaleTarget", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "PID" + } + ] + }, + { + "name": "ThrustPIDScaleAxes", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Roll Pitch" + } + ] + } + ], + "id": "5C80D844", + "instance": 0, + "name": "StabilizationSettingsBank3", + "setting": true + }, + { + "fields": [ + { + "name": "ThrottleCurve1", + "type": "float32", + "unit": "percent", + "values": [ + { + "name": "0", + "value": 0 + }, + { + "name": "25", + "value": 0.25 + }, + { + "name": "50", + "value": 0.5 + }, + { + "name": "75", + "value": 0.75 + }, + { + "name": "100", + "value": 1 + } + ] + }, + { + "name": "ThrottleCurve2", + "type": "float32", + "unit": "percent", + "values": [ + { + "name": "0", + "value": 0 + }, + { + "name": "25", + "value": 0.25 + }, + { + "name": "50", + "value": 0.5 + }, + { + "name": "75", + "value": 0.75 + }, + { + "name": "100", + "value": 1 + } + ] + }, + { + "name": "MixerValueRoll", + "type": "int8", + "unit": "percent", + "values": [ + { + "name": "0", + "value": 50 + } + ] + }, + { + "name": "MixerValuePitch", + "type": "int8", + "unit": "percent", + "values": [ + { + "name": "0", + "value": 50 + } + ] + }, + { + "name": "MixerValueYaw", + "type": "int8", + "unit": "percent", + "values": [ + { + "name": "0", + "value": 50 + } + ] + }, + { + "name": "RollDifferential", + "type": "int8", + "unit": "percent", + "values": [ + { + "name": "0", + "value": 0 + } + ] + }, + { + "name": "FirstRollServo", + "type": "uint8", + "unit": "", + "values": [ + { + "name": "0", + "value": 0 + } + ] + }, + { + "name": "Curve2Source", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Throttle" + } + ] + }, + { + "name": "Mixer1Type", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Motor" + } + ] + }, + { + "name": "Mixer1Vector", + "type": "int8", + "unit": "", + "values": [ + { + "name": "ThrottleCurve1", + "value": 127 + }, + { + "name": "ThrottleCurve2", + "value": 0 + }, + { + "name": "Roll", + "value": 64 + }, + { + "name": "Pitch", + "value": 64 + }, + { + "name": "Yaw", + "value": -64 + } + ] + }, + { + "name": "Mixer2Type", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Motor" + } + ] + }, + { + "name": "Mixer2Vector", + "type": "int8", + "unit": "", + "values": [ + { + "name": "ThrottleCurve1", + "value": 127 + }, + { + "name": "ThrottleCurve2", + "value": 0 + }, + { + "name": "Roll", + "value": -64 + }, + { + "name": "Pitch", + "value": 64 + }, + { + "name": "Yaw", + "value": 64 + } + ] + }, + { + "name": "Mixer3Type", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Motor" + } + ] + }, + { + "name": "Mixer3Vector", + "type": "int8", + "unit": "", + "values": [ + { + "name": "ThrottleCurve1", + "value": 127 + }, + { + "name": "ThrottleCurve2", + "value": 0 + }, + { + "name": "Roll", + "value": -64 + }, + { + "name": "Pitch", + "value": -64 + }, + { + "name": "Yaw", + "value": -64 + } + ] + }, + { + "name": "Mixer4Type", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Motor" + } + ] + }, + { + "name": "Mixer4Vector", + "type": "int8", + "unit": "", + "values": [ + { + "name": "ThrottleCurve1", + "value": 127 + }, + { + "name": "ThrottleCurve2", + "value": 0 + }, + { + "name": "Roll", + "value": 64 + }, + { + "name": "Pitch", + "value": -64 + }, + { + "name": "Yaw", + "value": 64 + } + ] + }, + { + "name": "Mixer5Type", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Disabled" + } + ] + }, + { + "name": "Mixer5Vector", + "type": "int8", + "unit": "", + "values": [ + { + "name": "ThrottleCurve1", + "value": 0 + }, + { + "name": "ThrottleCurve2", + "value": 0 + }, + { + "name": "Roll", + "value": 0 + }, + { + "name": "Pitch", + "value": 0 + }, + { + "name": "Yaw", + "value": 0 + } + ] + }, + { + "name": "Mixer6Type", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Disabled" + } + ] + }, + { + "name": "Mixer6Vector", + "type": "int8", + "unit": "", + "values": [ + { + "name": "ThrottleCurve1", + "value": 0 + }, + { + "name": "ThrottleCurve2", + "value": 0 + }, + { + "name": "Roll", + "value": 0 + }, + { + "name": "Pitch", + "value": 0 + }, + { + "name": "Yaw", + "value": 0 + } + ] + }, + { + "name": "Mixer7Type", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Disabled" + } + ] + }, + { + "name": "Mixer7Vector", + "type": "int8", + "unit": "", + "values": [ + { + "name": "ThrottleCurve1", + "value": 0 + }, + { + "name": "ThrottleCurve2", + "value": 0 + }, + { + "name": "Roll", + "value": 0 + }, + { + "name": "Pitch", + "value": 0 + }, + { + "name": "Yaw", + "value": 0 + } + ] + }, + { + "name": "Mixer8Type", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Disabled" + } + ] + }, + { + "name": "Mixer8Vector", + "type": "int8", + "unit": "", + "values": [ + { + "name": "ThrottleCurve1", + "value": 0 + }, + { + "name": "ThrottleCurve2", + "value": 0 + }, + { + "name": "Roll", + "value": 0 + }, + { + "name": "Pitch", + "value": 0 + }, + { + "name": "Yaw", + "value": 0 + } + ] + }, + { + "name": "Mixer9Type", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Disabled" + } + ] + }, + { + "name": "Mixer9Vector", + "type": "int8", + "unit": "", + "values": [ + { + "name": "ThrottleCurve1", + "value": 0 + }, + { + "name": "ThrottleCurve2", + "value": 0 + }, + { + "name": "Roll", + "value": 0 + }, + { + "name": "Pitch", + "value": 0 + }, + { + "name": "Yaw", + "value": 0 + } + ] + }, + { + "name": "Mixer10Type", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Disabled" + } + ] + }, + { + "name": "Mixer10Vector", + "type": "int8", + "unit": "", + "values": [ + { + "name": "ThrottleCurve1", + "value": 0 + }, + { + "name": "ThrottleCurve2", + "value": 0 + }, + { + "name": "Roll", + "value": 0 + }, + { + "name": "Pitch", + "value": 0 + }, + { + "name": "Yaw", + "value": 0 + } + ] + }, + { + "name": "Mixer11Type", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Disabled" + } + ] + }, + { + "name": "Mixer11Vector", + "type": "int8", + "unit": "", + "values": [ + { + "name": "ThrottleCurve1", + "value": 0 + }, + { + "name": "ThrottleCurve2", + "value": 0 + }, + { + "name": "Roll", + "value": 0 + }, + { + "name": "Pitch", + "value": 0 + }, + { + "name": "Yaw", + "value": 0 + } + ] + }, + { + "name": "Mixer12Type", + "type": "enum", + "unit": "", + "values": [ + { + "name": "0", + "value": "Disabled" + } + ] + }, + { + "name": "Mixer12Vector", + "type": "int8", + "unit": "", + "values": [ + { + "name": "ThrottleCurve1", + "value": 0 + }, + { + "name": "ThrottleCurve2", + "value": 0 + }, + { + "name": "Roll", + "value": 0 + }, + { + "name": "Pitch", + "value": 0 + }, + { + "name": "Yaw", + "value": 0 + } + ] + } + ], + "id": "810D3A5E", + "instance": 0, + "name": "MixerSettings", + "setting": true + }, + { + "fields": [ + { + "name": "P", + "type": "float32", + "unit": "1^2", + "values": [ + { + "name": "PositionNorth", + "value": 10 + }, + { + "name": "PositionEast", + "value": 10 + }, + { + "name": "PositionDown", + "value": 10 + }, + { + "name": "VelocityNorth", + "value": 1 + }, + { + "name": "VelocityEast", + "value": 1 + }, + { + "name": "VelocityDown", + "value": 1 + }, + { + "name": "AttitudeQ1", + "value": 0.0070000002160668373 + }, + { + "name": "AttitudeQ2", + "value": 0.0070000002160668373 + }, + { + "name": "AttitudeQ3", + "value": 0.0070000002160668373 + }, + { + "name": "AttitudeQ4", + "value": 0.0070000002160668373 + }, + { + "name": "GyroDriftX", + "value": 9.9999999747524271e-07 + }, + { + "name": "GyroDriftY", + "value": 9.9999999747524271e-07 + }, + { + "name": "GyroDriftZ", + "value": 9.9999999747524271e-07 + } + ] + }, + { + "name": "Q", + "type": "float32", + "unit": "1^2", + "values": [ + { + "name": "GyroX", + "value": 0.0099999997764825821 + }, + { + "name": "GyroY", + "value": 0.0099999997764825821 + }, + { + "name": "GyroZ", + "value": 0.0099999997764825821 + }, + { + "name": "AccelX", + "value": 0.0099999997764825821 + }, + { + "name": "AccelY", + "value": 0.0099999997764825821 + }, + { + "name": "AccelZ", + "value": 0.0099999997764825821 + }, + { + "name": "GyroDriftX", + "value": 9.9999999747524271e-07 + }, + { + "name": "GyroDriftY", + "value": 9.9999999747524271e-07 + }, + { + "name": "GyroDriftZ", + "value": 9.9999999747524271e-07 + } + ] + }, + { + "name": "R", + "type": "float32", + "unit": "1^2", + "values": [ + { + "name": "GPSPosNorth", + "value": 1 + }, + { + "name": "GPSPosEast", + "value": 1 + }, + { + "name": "GPSPosDown", + "value": 1000000 + }, + { + "name": "GPSVelNorth", + "value": 0.0010000000474974513 + }, + { + "name": "GPSVelEast", + "value": 0.0010000000474974513 + }, + { + "name": "GPSVelDown", + "value": 0.0010000000474974513 + }, + { + "name": "MagX", + "value": 10 + }, + { + "name": "MagY", + "value": 10 + }, + { + "name": "MagZ", + "value": 10 + }, + { + "name": "BaroZ", + "value": 0.0099999997764825821 + } + ] + }, + { + "name": "FakeR", + "type": "float32", + "unit": "1^2", + "values": [ + { + "name": "FakeGPSPosIndoor", + "value": 10 + }, + { + "name": "FakeGPSVelIndoor", + "value": 1 + }, + { + "name": "FakeGPSVelAirspeed", + "value": 1000 + } + ] + } + ], + "id": "5E91213C", + "instance": 0, + "name": "EKFConfiguration", + "setting": true + } + ], + "owner": "LibrePilot", + "photo": "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bcWxORE1NIyFwkB4/fr1N3/96wDw8Y9//Iorr+T8YclCR8lCzBH5Tz355M6dOxXgvLlzb7v9+xXxuLIsMvT288/7n7vvvueen2XczAMPLFrw1lOjkUiQxQ8sWvSHp5/WgOFI5LrrrqusqnrmT3967LeP3vb97x/ZBy2Xzd15553zTzopEo0c+t3i0q1ly5b91623EvP1/3LDJR/6IAw/VBucE2TQLsSoN0LD/d57781kMldccUVZJByPxU477bTu/fu3bNly8803K6U8173t1lsfeeQRANBaJ5PJefPnX3TRRddcc81TTz1144033nLLLfX19X19feeee+7jjz3+4Y9cftH73tfX2+26LgCk0+k/PfNsTU1tsbTheV5/fz8AuK4b5BojcGHIzMBB9hnff+mll5AhEon8y2c/F4/HCdEAKktZyrniqn965dVXNm1cv3nz5q59+1paWpi5defOBx98kIhsrT772c8uXbr0+eef933ftm3f94/sg8bAGzdufOKJxy/90IfU4VssMAB6rjs0OMiIuVwO4MDnhfzsn2CajpTbhRjlRlC4B0WMYCidzWa/8pWvKKUgn7GwePHi888//5GHH54xY0bbzh2PPfwbJFJKEVEmMfSD2275+je+UVU15oorPhwOO9/59rdOOWXBj+/86UMPPXTPPfdcdPF7x9TWfP6mrwAAkEkmEstXrW6aOAHUgRIHFEb0wY157RzAfOE7kU73dfegofFjGyZNnoS2VvmJh8BKxSsr58yZs2XDBjeT6exob5k8EZh/++jDif4+h+GDl39w7brVzzz7R6UUIAMSACFD8X94ozKIAlYHJmciATAWpvOAoeAYhaVQAS+652dnvvXUcRMmGGBSKhiVawJNgIyMYJB8NMycL8QE71yvnT2jUBGw1GWEGL1G4gHVRCIxduzY4DQiALPvea2trS0TJ959992LFy++9957g/o1AGitmfnF51/47GdueOyRR9avWVsZi+/aubMqXnnzzV9vampqaWlp2727cNAUmSgcDo8fP76ioiJ/lHJYhHHxSOawOd5BskOhFwIChkKhYGiMxSObCMxcXl4eXFwwKDbGvPTSSwigtZ47b97ixYuLB3UP9SaC9JCKfPGdCUFrPXXqNGLet6/r1w895PtecNz4b2Dm4P2scKuCBm3EpABfd+9CIcSIN4JG7kU7duxQ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", + "propeller": "5x3", + "servo": "", + "size": "250mm", + "subtype": 2, + "type": 1, + "uuid": "{8c71fffa-afd4-41f6-b14d-0028a6476885}", + "weight": "530g" +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/EmaxNighthawk-Multirotor-QuadrocopterX-9a3aa9d9726.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/EmaxNighthawk-Multirotor-QuadrocopterX-9a3aa9d9726.optmpl index 0baaad4c2..89173ec12 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/EmaxNighthawk-Multirotor-QuadrocopterX-9a3aa9d9726.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/EmaxNighthawk-Multirotor-QuadrocopterX-9a3aa9d9726.optmpl @@ -1428,19 +1428,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1455,19 +1455,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2163,4 +2163,4 @@ "type": 1, "uuid": "{839c14d8-cc25-4b7b-8af5-09a3aa9d9726}", "weight": "514" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/FlipFPVPro-Multirotor-QuadrocopterX-9eb7b719244.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/FlipFPVPro-Multirotor-QuadrocopterX-9eb7b719244.optmpl index 38503d985..c23a69cbf 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/FlipFPVPro-Multirotor-QuadrocopterX-9eb7b719244.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/FlipFPVPro-Multirotor-QuadrocopterX-9eb7b719244.optmpl @@ -2163,4 +2163,4 @@ "type": 1, "uuid": "{5da3b162-548d-4cf5-af8d-59eb7b719244}", "weight": "1265g no battery" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/FlipFpvPro-Multirotor-QuadrocopterX-c117d151f95.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/FlipFpvPro-Multirotor-QuadrocopterX-c117d151f95.optmpl index 3f520103f..906e3e1ec 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/FlipFpvPro-Multirotor-QuadrocopterX-c117d151f95.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/FlipFpvPro-Multirotor-QuadrocopterX-c117d151f95.optmpl @@ -1428,19 +1428,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1455,19 +1455,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2163,4 +2163,4 @@ "type": 1, "uuid": "{91b3241f-464a-4f5f-b4e4-6c117d151f95}", "weight": "1625g" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/FlipSport-Multirotor-QuadrocopterX-c27ae7b79ca.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/FlipSport-Multirotor-QuadrocopterX-c27ae7b79ca.optmpl index 675b6f7f8..fb47e9798 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/FlipSport-Multirotor-QuadrocopterX-c27ae7b79ca.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/FlipSport-Multirotor-QuadrocopterX-c27ae7b79ca.optmpl @@ -1428,19 +1428,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1455,19 +1455,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2163,4 +2163,4 @@ "type": 1, "uuid": "{463124d4-1ee6-42c4-9573-2c27ae7b79ca}", "weight": "733g" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/FlyingCinemaCinetan-Multirotor-QuadrocopterX-2c3f9181872.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/FlyingCinemaCinetan-Multirotor-QuadrocopterX-2c3f9181872.optmpl index 7f63c56fd..19d383e47 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/FlyingCinemaCinetan-Multirotor-QuadrocopterX-2c3f9181872.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/FlyingCinemaCinetan-Multirotor-QuadrocopterX-2c3f9181872.optmpl @@ -1428,19 +1428,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1455,19 +1455,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2163,4 +2163,4 @@ "type": 1, "uuid": "{6558d7a5-fcd4-4699-b7f1-22c3f9181872}", "weight": "1120" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/FlyingCinemaTankitoM-Multirotor-QuadrocopterX-385d9ac9ae1.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/FlyingCinemaTankitoM-Multirotor-QuadrocopterX-385d9ac9ae1.optmpl index 04b873911..41a7951ec 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/FlyingCinemaTankitoM-Multirotor-QuadrocopterX-385d9ac9ae1.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/FlyingCinemaTankitoM-Multirotor-QuadrocopterX-385d9ac9ae1.optmpl @@ -1428,19 +1428,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1455,19 +1455,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2163,4 +2163,4 @@ "type": 1, "uuid": "{9e606633-bbdb-4f2a-ad2a-3385d9ac9ae1}", "weight": "1020" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/GenericHexa-Multirotor-Hexacopter+-c50a904f4a3.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/GenericHexa-Multirotor-Hexacopter+-c50a904f4a3.optmpl index c28bb0bed..074db626e 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/GenericHexa-Multirotor-Hexacopter+-c50a904f4a3.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/GenericHexa-Multirotor-Hexacopter+-c50a904f4a3.optmpl @@ -1397,19 +1397,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1424,19 +1424,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2132,4 +2132,4 @@ "type": 1, "uuid": "{e0fc5ce5-1fab-4502-818b-7c50a904f4a3}", "weight": "Generic" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/GenericHexaH-Multirotor-HexacopterH-6cc3fed9073.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/GenericHexaH-Multirotor-HexacopterH-6cc3fed9073.optmpl index 6659e3c60..3cc25c836 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/GenericHexaH-Multirotor-HexacopterH-6cc3fed9073.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/GenericHexaH-Multirotor-HexacopterH-6cc3fed9073.optmpl @@ -1397,19 +1397,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1424,19 +1424,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2132,4 +2132,4 @@ "type": 1, "uuid": "{8e596489-7260-417d-b94f-f6cc3fed9073}", "weight": "Generic" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/GenericHexaX-Multirotor-HexacopterX-b3b8c1d2f3c.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/GenericHexaX-Multirotor-HexacopterX-b3b8c1d2f3c.optmpl index 9ef23c1e1..5a2544920 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/GenericHexaX-Multirotor-HexacopterX-b3b8c1d2f3c.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/GenericHexaX-Multirotor-HexacopterX-b3b8c1d2f3c.optmpl @@ -1397,19 +1397,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1424,19 +1424,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2132,4 +2132,4 @@ "type": 1, "uuid": "{8505a811-a23a-4649-971d-cb3b8c1d2f3c}", "weight": "Generic" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/GenericHexaY6-Multirotor-HexacopterY6-0b5dc6bae4f.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/GenericHexaY6-Multirotor-HexacopterY6-0b5dc6bae4f.optmpl index 06068a19a..2714b9626 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/GenericHexaY6-Multirotor-HexacopterY6-0b5dc6bae4f.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/GenericHexaY6-Multirotor-HexacopterY6-0b5dc6bae4f.optmpl @@ -1397,19 +1397,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1424,19 +1424,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2132,4 +2132,4 @@ "type": 1, "uuid": "{82dc9de8-af44-4544-81ba-c0b5dc6bae4f}", "weight": "Generic" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/GenericQuad+-Multirotor-Quadrocopter+-a87a4226820.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/GenericQuad+-Multirotor-Quadrocopter+-a87a4226820.optmpl index 02f2511c4..62b18f569 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/GenericQuad+-Multirotor-Quadrocopter+-a87a4226820.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/GenericQuad+-Multirotor-Quadrocopter+-a87a4226820.optmpl @@ -1397,19 +1397,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1424,19 +1424,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2132,4 +2132,4 @@ "type": 1, "uuid": "{94827284-1e55-48c9-9747-fa87a4226820}", "weight": "Generic" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/GenericQuadX-Multirotor-QuadrocopterX-5fce7315a5b.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/GenericQuadX-Multirotor-QuadrocopterX-5fce7315a5b.optmpl index 276ab0e17..8133946b9 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/GenericQuadX-Multirotor-QuadrocopterX-5fce7315a5b.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/GenericQuadX-Multirotor-QuadrocopterX-5fce7315a5b.optmpl @@ -1397,19 +1397,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1424,19 +1424,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2132,4 +2132,4 @@ "type": 1, "uuid": "{06d0042b-b8dd-4b93-bae4-55fce7315a5b}", "weight": "Generic" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/GenericTricopter-Multirotor-Tricopter-5f46bc37c31.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/GenericTricopter-Multirotor-Tricopter-5f46bc37c31.optmpl index 38cbce5d2..d565b1e93 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/GenericTricopter-Multirotor-Tricopter-5f46bc37c31.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/GenericTricopter-Multirotor-Tricopter-5f46bc37c31.optmpl @@ -1397,19 +1397,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1424,19 +1424,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2132,4 +2132,4 @@ "type": 1, "uuid": "{b393ef08-3028-40d6-b1f9-05f46bc37c31}", "weight": "Generic" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/GuerrillaDronesToadQ-Multirotor-QuadrocopterX-8f838e43432.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/GuerrillaDronesToadQ-Multirotor-QuadrocopterX-8f838e43432.optmpl index e5e80da7d..7168305db 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/GuerrillaDronesToadQ-Multirotor-QuadrocopterX-8f838e43432.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/GuerrillaDronesToadQ-Multirotor-QuadrocopterX-8f838e43432.optmpl @@ -1428,19 +1428,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1455,19 +1455,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2163,4 +2163,4 @@ "type": 1, "uuid": "{461117e0-82c8-4636-8862-48f838e43432}", "weight": "634" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/HKingDYS250CarbonFib-Multirotor-QuadrocopterX-969354c51c1.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/HKingDYS250CarbonFib-Multirotor-QuadrocopterX-969354c51c1.optmpl index aa625443b..cc2aace41 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/HKingDYS250CarbonFib-Multirotor-QuadrocopterX-969354c51c1.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/HKingDYS250CarbonFib-Multirotor-QuadrocopterX-969354c51c1.optmpl @@ -1428,19 +1428,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1455,19 +1455,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2163,4 +2163,4 @@ "type": 1, "uuid": "{57f8cb14-95bc-4ae0-9773-8969354c51c1}", "weight": "410" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/HKingDYS320CarbonFib-Multirotor-QuadrocopterX-0b41edda68f.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/HKingDYS320CarbonFib-Multirotor-QuadrocopterX-0b41edda68f.optmpl index eced8c58b..2e35e9060 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/HKingDYS320CarbonFib-Multirotor-QuadrocopterX-0b41edda68f.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/HKingDYS320CarbonFib-Multirotor-QuadrocopterX-0b41edda68f.optmpl @@ -1428,19 +1428,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1455,19 +1455,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2163,4 +2163,4 @@ "type": 1, "uuid": "{90300d44-3050-4539-847e-a0b41edda68f}", "weight": "530" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/HoverThingsFLIPFPV-Multirotor-QuadrocopterX-32bf14a10fc.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/HoverThingsFLIPFPV-Multirotor-QuadrocopterX-32bf14a10fc.optmpl index 2f1caac3e..bccbe2899 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/HoverThingsFLIPFPV-Multirotor-QuadrocopterX-32bf14a10fc.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/HoverThingsFLIPFPV-Multirotor-QuadrocopterX-32bf14a10fc.optmpl @@ -1397,19 +1397,19 @@ }, { "name": "25", - "value": 0.28999999165534973 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.597648024559021 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1424,19 +1424,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67500001192092896 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2132,4 +2132,4 @@ "type": 1, "uuid": "{380ea6e6-81bf-4554-8590-532bf14a10fc}", "weight": "1280" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/InventorsSparrowRace-Multirotor-QuadrocopterX-314fff867fd.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/InventorsSparrowRace-Multirotor-QuadrocopterX-314fff867fd.optmpl index 1c4380b26..23e48a2b3 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/InventorsSparrowRace-Multirotor-QuadrocopterX-314fff867fd.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/InventorsSparrowRace-Multirotor-QuadrocopterX-314fff867fd.optmpl @@ -1428,19 +1428,19 @@ }, { "name": "25", - "value": 0.28999999165534973 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.59558922052383423 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1455,19 +1455,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67500001192092896 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2163,4 +2163,4 @@ "type": 1, "uuid": "{1532c3d9-19d8-4a34-9041-2314fff867fd}", "weight": "562" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/QAV250-Multirotor-QuadrocopterX-181dab0df01.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/QAV250-Multirotor-QuadrocopterX-181dab0df01.optmpl index ae68fc51f..4ebef59b9 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/QAV250-Multirotor-QuadrocopterX-181dab0df01.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/QAV250-Multirotor-QuadrocopterX-181dab0df01.optmpl @@ -1397,19 +1397,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1424,19 +1424,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2132,4 +2132,4 @@ "type": 1, "uuid": "{a0b2ad97-e1c4-48b7-a5c4-0181dab0df01}", "weight": "438g Excluding battery" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/QAV400-Multirotor-QuadrocopterX-90a90b9fb50.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/QAV400-Multirotor-QuadrocopterX-90a90b9fb50.optmpl index f4c55db0f..2fe36131f 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/QAV400-Multirotor-QuadrocopterX-90a90b9fb50.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/QAV400-Multirotor-QuadrocopterX-90a90b9fb50.optmpl @@ -1428,19 +1428,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1455,19 +1455,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2163,4 +2163,4 @@ "type": 1, "uuid": "{77d72db0-f6ca-4ed4-ac23-290a90b9fb50}", "weight": "1050" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/QAV500-Multirotor-QuadrocopterX-6da440c4d7c.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/QAV500-Multirotor-QuadrocopterX-6da440c4d7c.optmpl index 0892a7407..2ef9f6d10 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/QAV500-Multirotor-QuadrocopterX-6da440c4d7c.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/QAV500-Multirotor-QuadrocopterX-6da440c4d7c.optmpl @@ -1428,19 +1428,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1455,19 +1455,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2163,4 +2163,4 @@ "type": 1, "uuid": "{fc2edf84-3f5a-4184-8f58-56da440c4d7c}", "weight": "1679" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/QUADI250-Multirotor-QuadrocopterX-c6c6cfc4cf9.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/QUADI250-Multirotor-QuadrocopterX-c6c6cfc4cf9.optmpl index 214b5b1f6..d34049eff 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/QUADI250-Multirotor-QuadrocopterX-c6c6cfc4cf9.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/QUADI250-Multirotor-QuadrocopterX-c6c6cfc4cf9.optmpl @@ -1397,19 +1397,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67500001192092896 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1424,19 +1424,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67500001192092896 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2132,4 +2132,4 @@ "type": 1, "uuid": "{2a77626e-ab2d-4c4d-9c8a-cc6c6cfc4cf9}", "weight": "AUW 670 Grams" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/RCExplorerV3Tricopte-Multirotor-Tricopter-dcbce3f069c.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/RCExplorerV3Tricopte-Multirotor-Tricopter-dcbce3f069c.optmpl index 8b03cf11b..1239575c0 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/RCExplorerV3Tricopte-Multirotor-Tricopter-dcbce3f069c.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/RCExplorerV3Tricopte-Multirotor-Tricopter-dcbce3f069c.optmpl @@ -1428,19 +1428,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1455,19 +1455,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2163,4 +2163,4 @@ "type": 1, "uuid": "{a78f49a6-3b21-4bc1-ba3d-7dcbce3f069c}", "weight": "1160 g" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/XhoverMXP230Elite-Multirotor-QuadrocopterX-3b169a4fd1b.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/XhoverMXP230Elite-Multirotor-QuadrocopterX-3b169a4fd1b.optmpl index 7916743e0..28026cbb9 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/XhoverMXP230Elite-Multirotor-QuadrocopterX-3b169a4fd1b.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/XhoverMXP230Elite-Multirotor-QuadrocopterX-3b169a4fd1b.optmpl @@ -1397,19 +1397,19 @@ }, { "name": "25", - "value": 0.2199999988079071 + "value": 0.25 }, { "name": "50", - "value": 0.33000001311302185 + "value": 0.5 }, { "name": "75", - "value": 0.54958653450012207 + "value": 0.75 }, { "name": "100", - "value": 0.80000001192092896 + "value": 1 } ] }, @@ -1424,19 +1424,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2132,4 +2132,4 @@ "type": 1, "uuid": "{7ef69ab5-77ae-46aa-b70c-3aff957f5880}", "weight": "574" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/ZMR250( Attitude mode)-ChineseQAV250-Multirotor-QuadrocopterX-5d318c0526c (1).optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/ZMR250( Attitude mode)-ChineseQAV250-Multirotor-QuadrocopterX-5d318c0526c (1).optmpl index c8be3640e..bcbc0ab40 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/ZMR250( Attitude mode)-ChineseQAV250-Multirotor-QuadrocopterX-5d318c0526c (1).optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/ZMR250( Attitude mode)-ChineseQAV250-Multirotor-QuadrocopterX-5d318c0526c (1).optmpl @@ -1397,19 +1397,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67500001192092896 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1424,19 +1424,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67500001192092896 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2132,4 +2132,4 @@ "type": 1, "uuid": "{462ee325-6581-43ce-9223-45d318c0526c}", "weight": "312 w/o battery" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/ZMR250(4s race)-Multirotor-QuadrocopterX-fac61e7adb8.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/ZMR250(4s race)-Multirotor-QuadrocopterX-fac61e7adb8.optmpl index 33377e757..a5e647e17 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/ZMR250(4s race)-Multirotor-QuadrocopterX-fac61e7adb8.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/ZMR250(4s race)-Multirotor-QuadrocopterX-fac61e7adb8.optmpl @@ -1397,19 +1397,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1424,19 +1424,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2131,4 +2131,4 @@ "type": 1, "uuid": "{0fda3830-6fd3-4ceb-908b-dfac61e7adb8}", "weight": "530g (with Mobius)" -} \ No newline at end of file +} diff --git a/ground/gcs/src/share/vehicletemplates/multirotor/ZMR250(Race acro +)-Multirotor-QuadrocopterX-895b222d670.optmpl b/ground/gcs/src/share/vehicletemplates/multirotor/ZMR250(Race acro +)-Multirotor-QuadrocopterX-895b222d670.optmpl index 647f4a4cf..f2a5b5c0d 100644 --- a/ground/gcs/src/share/vehicletemplates/multirotor/ZMR250(Race acro +)-Multirotor-QuadrocopterX-895b222d670.optmpl +++ b/ground/gcs/src/share/vehicletemplates/multirotor/ZMR250(Race acro +)-Multirotor-QuadrocopterX-895b222d670.optmpl @@ -1428,19 +1428,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -1455,19 +1455,19 @@ }, { "name": "25", - "value": 0.22499999403953552 + "value": 0.25 }, { "name": "50", - "value": 0.44999998807907104 + "value": 0.5 }, { "name": "75", - "value": 0.67499995231628418 + "value": 0.75 }, { "name": "100", - "value": 0.89999997615814209 + "value": 1 } ] }, @@ -2162,4 +2162,4 @@ "type": 1, "uuid": "{65b347bb-5e6d-466f-895e-5895b222d670}", "weight": "630 with battery" -} \ No newline at end of file +} diff --git a/ground/uavobjgenerator/generators/gcs/uavobjectgeneratorgcs.cpp b/ground/uavobjgenerator/generators/gcs/uavobjectgeneratorgcs.cpp index e5fc3a354..1796f1a1d 100644 --- a/ground/uavobjgenerator/generators/gcs/uavobjectgeneratorgcs.cpp +++ b/ground/uavobjgenerator/generators/gcs/uavobjectgeneratorgcs.cpp @@ -2,7 +2,8 @@ ****************************************************************************** * * @file uavobjectgeneratorgcs.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @brief produce gcs code for uavobjects * * @see The GNU Public License (GPL) Version 3 @@ -25,16 +26,531 @@ */ #include "uavobjectgeneratorgcs.h" + +#define VERBOSE false +#define DEPRECATED true + +#define DEFAULT_ENUM_PREFIX "E_" + using namespace std; +void error(QString msg) +{ + cerr << "error: " << msg.toStdString() << endl; +} + +void warning(ObjectInfo *object, QString msg) +{ + cerr << "warning: " << object->filename.toStdString() << ": " << msg.toStdString() << endl; +} + +void info(ObjectInfo *object, QString msg) +{ + if (VERBOSE) { + cout << "info: " << object->filename.toStdString() << ": " << msg.toStdString() << endl; + } +} + +struct Context { + ObjectInfo *object; + // enums + QString enums; + QString enumsCount; + QString registerImpl; + // interface + QString fields; + QString fieldsInfo; + QString properties; + QString deprecatedProperties; + QString getters; + QString setters; + QString notifications; + // implementation + QString fieldsInit; + QString fieldsDefault; + QString propertiesImpl; + QString notificationsImpl; +}; + +struct FieldContext { + FieldInfo *field; + // field + QString fieldName; + QString fieldType; + // property + QString propName; + QString ucPropName; + QString propType; + QString propRefType; + // deprecation + bool hasDeprecatedProperty; + bool hasDeprecatedGetter; + bool hasDeprecatedSetter; + bool hasDeprecatedNotification; +}; + +QString fieldTypeStrCPP(int type) +{ + QStringList fieldTypeStrCPP; + + fieldTypeStrCPP << "qint8" << "qint16" << "qint32" << "quint8" << "quint16" << "quint32" << "float" << "quint8"; + return fieldTypeStrCPP[type]; +} + +QString fieldTypeStrCPPClass(int type) +{ + QStringList fieldTypeStrCPPClass; + + fieldTypeStrCPPClass << "INT8" << "INT16" << "INT32" << "UINT8" << "UINT16" << "UINT32" << "FLOAT32" << "ENUM"; + return fieldTypeStrCPPClass[type]; +} + +QString toPropertyName(const QString & name) +{ + QString str = name; + + // make sure 1st letter is upper case + str[0] = str[0].toUpper(); + + // handle underscore + int p = str.indexOf('_'); + while (p != -1) { + str.remove(p, 1); + str[p] = str[p].toUpper(); + p = str.indexOf('_', p); + } + + return str; +} + +/* + * Convert a string to lower camel case. + * Handles following cases : + * - Property -> property + * - MyProperty -> myProperty + * - MYProperty -> myProperty + * - MY_Property -> my_Property + * - MY -> my + */ +QString toLowerCamelCase(const QString & name) +{ + QString str = name; + + for (int i = 0; i < str.length(); ++i) { + if (str[i].isLower() || !str[i].isLetter()) { + break; + } + if (i > 0 && i < str.length() - 1) { + // after first, look ahead one + if (str[i + 1].isLower()) { + break; + } + } + str[i] = str[i].toLower(); + } + + return str; +} + +QString toEnumName(ObjectInfo *object, FieldInfo *field, int index) +{ + QString option = field->options[index]; + + if (option.contains(QRegExp(ENUM_SPECIAL_CHARS))) { + info(object, "Enumeration value \"" + option + "\" contains special chars, cleaning."); + option.replace(QRegExp(ENUM_SPECIAL_CHARS), ""); + } + if (option[0].isDigit()) { + info(object, "Enumeration value \"" + option + "\" starts with a digit, prefixing with \"" + DEFAULT_ENUM_PREFIX "\"."); + option = DEFAULT_ENUM_PREFIX + option; + } + if (option == option.toLower()) { + warning(object, "Enumeration value \"" + option + "\" is all lower case, consider capitalizing."); + } + if (option[0].isLower()) { + warning(object, "Enumeration value \"" + option + "\" does not start with an upper case letter."); + option[0] = option[0].toUpper(); + } + if (option == "FALSE") { + warning(object, "Invalid enumeration name FALSE, converting to False."); + option = "False"; + } + if (option == "TRUE") { + warning(object, "Invalid enumeration name TRUE, converting to True."); + option = "True"; + } + return option; +} + +QString toEnumStringList(ObjectInfo *object, FieldInfo *field) +{ + QString enumListString; + + for (int m = 0; m < field->options.length(); ++m) { + if (m > 0) { + enumListString.append(", "); + } + QString option = toEnumName(object, field, m); + enumListString.append(option); + } + + return enumListString; +} + + +QString generate(Context &ctxt, const QString &fragment) +{ + QString str = fragment; + + str.replace(":ClassName", ctxt.object->name); + str.replace(":className", ctxt.object->namelc); + + return str; +} + +QString generate(Context &ctxt, FieldContext &fieldCtxt, const QString &fragment) +{ + QString str = generate(ctxt, fragment); + + str.replace(":PropName", fieldCtxt.ucPropName); + str.replace(":propName", fieldCtxt.propName); + str.replace(":propType", fieldCtxt.propType); + str.replace(":propRefType", fieldCtxt.propRefType); + + str.replace(":fieldName", fieldCtxt.fieldName); + str.replace(":fieldType", fieldCtxt.fieldType); + str.replace(":fieldDesc", fieldCtxt.field->description); + str.replace(":fieldUnits", fieldCtxt.field->units); + str.replace(":fieldLimitValues", fieldCtxt.field->limitValues); + + str.replace(":elementCount", QString::number(fieldCtxt.field->numElements)); + str.replace(":enumCount", QString::number(fieldCtxt.field->numOptions)); + + return str; +} + +void generateFieldInfo(Context &ctxt, FieldContext &fieldCtxt) +{ + ctxt.fieldsInfo += generate(ctxt, fieldCtxt, " // :fieldName\n"); + + if (fieldCtxt.field->type == FIELDTYPE_ENUM) { + QStringList options = fieldCtxt.field->options; + ctxt.fieldsInfo += " typedef enum { "; + for (int m = 0; m < options.length(); ++m) { + if (m > 0) { + ctxt.fieldsInfo.append(", "); + } + ctxt.fieldsInfo += generate(ctxt, fieldCtxt, "%1_%2=%3") + .arg(fieldCtxt.field->name.toUpper()) + .arg(options[m].toUpper().replace(QRegExp(ENUM_SPECIAL_CHARS), "")) + .arg(m); + } + ctxt.fieldsInfo += generate(ctxt, fieldCtxt, " } :fieldNameOptions;\n"); + } + + // Generate element names (only if field has more than one element) + if (fieldCtxt.field->numElements > 1 && !fieldCtxt.field->defaultElementNames) { + QStringList elemNames = fieldCtxt.field->elementNames; + ctxt.fieldsInfo += " typedef enum { "; + for (int m = 0; m < elemNames.length(); ++m) { + if (m > 0) { + ctxt.fieldsInfo.append(", "); + } + ctxt.fieldsInfo += QString("%1_%2=%3") + .arg(fieldCtxt.field->name.toUpper()) + .arg(elemNames[m].toUpper()) + .arg(m); + } + ctxt.fieldsInfo += generate(ctxt, fieldCtxt, " } :fieldNameElem;\n"); + } + + // Generate array information + if (fieldCtxt.field->numElements > 1) { + ctxt.fieldsInfo += generate(ctxt, fieldCtxt, " static const quint32 %1_NUMELEM = :elementCount;\n") + .arg(fieldCtxt.field->name.toUpper()); + } +} + +void generateFieldInit(Context &ctxt, FieldContext &fieldCtxt) +{ + ctxt.fieldsInit += generate(ctxt, fieldCtxt, " // :fieldName\n"); + + // Setup element names + ctxt.fieldsInit += generate(ctxt, fieldCtxt, " QStringList :fieldNameElemNames;\n"); + QStringList elemNames = fieldCtxt.field->elementNames; + ctxt.fieldsInit += generate(ctxt, fieldCtxt, " :fieldNameElemNames"); + for (int m = 0; m < elemNames.length(); ++m) { + ctxt.fieldsInit += QString(" << \"%1\"").arg(elemNames[m]); + } + ctxt.fieldsInit += ";\n"; + + if (fieldCtxt.field->type == FIELDTYPE_ENUM) { + ctxt.fieldsInit += generate(ctxt, fieldCtxt, " QStringList :fieldNameEnumOptions;\n"); + QStringList options = fieldCtxt.field->options; + ctxt.fieldsInit += generate(ctxt, fieldCtxt, " :fieldNameEnumOptions"); + for (int m = 0; m < options.length(); ++m) { + ctxt.fieldsInit += QString(" << \"%1\"").arg(options[m]); + } + ctxt.fieldsInit += ";\n"; + ctxt.fieldsInit += generate(ctxt, fieldCtxt, + " fields.append(new UAVObjectField(\":fieldName\", tr(\":fieldDesc\"), \":fieldUnits\", UAVObjectField::ENUM, :fieldNameElemNames, :fieldNameEnumOptions, \":fieldLimitValues\"));\n"); + } else { + ctxt.fieldsInit += generate(ctxt, fieldCtxt, + " fields.append(new UAVObjectField(\":fieldName\", tr(\":fieldDesc\"), \":fieldUnits\", UAVObjectField::%1, :fieldNameElemNames, QStringList(), \":fieldLimitValues\"));\n") + .arg(fieldTypeStrCPPClass(fieldCtxt.field->type)); + } +} + +void generateFieldDefault(Context &ctxt, FieldContext &fieldCtxt) +{ + if (!fieldCtxt.field->defaultValues.isEmpty()) { + // For non-array fields + if (fieldCtxt.field->numElements == 1) { + ctxt.fieldsDefault += generate(ctxt, fieldCtxt, " // :fieldName\n"); + if (fieldCtxt.field->type == FIELDTYPE_ENUM) { + ctxt.fieldsDefault += generate(ctxt, fieldCtxt, " data_.:fieldName = %1;\n") + .arg(fieldCtxt.field->options.indexOf(fieldCtxt.field->defaultValues[0])); + } else if (fieldCtxt.field->type == FIELDTYPE_FLOAT32) { + ctxt.fieldsDefault += generate(ctxt, fieldCtxt, " data_.:fieldName = %1;\n") + .arg(fieldCtxt.field->defaultValues[0].toFloat()); + } else { + ctxt.fieldsDefault += generate(ctxt, fieldCtxt, " data_.:fieldName = %1;\n") + .arg(fieldCtxt.field->defaultValues[0].toInt()); + } + } else { + // Initialize all fields in the array + ctxt.fieldsDefault += generate(ctxt, fieldCtxt, " // :fieldName\n"); + for (int idx = 0; idx < fieldCtxt.field->numElements; ++idx) { + if (fieldCtxt.field->type == FIELDTYPE_ENUM) { + ctxt.fieldsDefault += generate(ctxt, fieldCtxt, " data_.:fieldName[%1] = %2;\n") + .arg(idx) + .arg(fieldCtxt.field->options.indexOf(fieldCtxt.field->defaultValues[idx])); + } else if (fieldCtxt.field->type == FIELDTYPE_FLOAT32) { + ctxt.fieldsDefault += generate(ctxt, fieldCtxt, " data_.:fieldName[%1] = %2;\n") + .arg(idx) + .arg(fieldCtxt.field->defaultValues[idx].toFloat()); + } else { + ctxt.fieldsDefault += generate(ctxt, fieldCtxt, " data_.:fieldName[%1] = %2;\n") + .arg(idx) + .arg(fieldCtxt.field->defaultValues[idx].toInt()); + } + } + } + } +} + +void generateField(Context &ctxt, FieldContext &fieldCtxt) +{ + if (fieldCtxt.field->numElements > 1) { + ctxt.fields += generate(ctxt, fieldCtxt, " :fieldType :fieldName[:elementCount];\n"); + } else { + ctxt.fields += generate(ctxt, fieldCtxt, " :fieldType :fieldName;\n"); + } + generateFieldInfo(ctxt, fieldCtxt); + generateFieldInit(ctxt, fieldCtxt); + generateFieldDefault(ctxt, fieldCtxt); +} + +void generateEnum(Context &ctxt, FieldContext &fieldCtxt) +{ + Q_ASSERT(fieldCtxt.field->type == FIELDTYPE_ENUM); + + QString enumStringList = toEnumStringList(ctxt.object, fieldCtxt.field); + + ctxt.enums += generate(ctxt, fieldCtxt, + "class :ClassName_:PropName : public QObject {\n" + " Q_OBJECT\n" + "public:\n" + " enum Enum { %1 };\n" + " Q_ENUMS(Enum) // TODO switch to Q_ENUM once on Qt 5.5\n" + "};\n\n").arg(enumStringList); + + ctxt.enumsCount += generate(ctxt, fieldCtxt, ":PropNameCount = :enumCount, "); + + ctxt.registerImpl += generate(ctxt, fieldCtxt, + " qmlRegisterType<:ClassName_:PropName>(\"%1.:ClassName\", 1, 0, \":PropName\");\n").arg("UAVTalk"); +} + +void generateBaseProperty(Context &ctxt, FieldContext &fieldCtxt) +{ + ctxt.properties += generate(ctxt, fieldCtxt, + " Q_PROPERTY(:propType :propName READ :propName WRITE set:PropName NOTIFY :propNameChanged)\n"); + + ctxt.getters += generate(ctxt, fieldCtxt, " :propType :propName() const;\n"); + ctxt.setters += generate(ctxt, fieldCtxt, " void set:PropName(const :propRefType value);\n"); + + ctxt.notifications += generate(ctxt, fieldCtxt, " void :propNameChanged(const :propRefType value);\n"); + ctxt.notificationsImpl += generate(ctxt, fieldCtxt, " emit :propNameChanged(:propName());\n"); + + if (DEPRECATED) { + // generate deprecated property for retro compatibility + if (fieldCtxt.hasDeprecatedProperty) { + ctxt.deprecatedProperties += generate(ctxt, fieldCtxt, + " /*DEPRECATED*/ Q_PROPERTY(:fieldType :fieldName READ get:fieldName WRITE set:fieldName NOTIFY :fieldNameChanged);\n"); + } + if (fieldCtxt.hasDeprecatedGetter) { + ctxt.getters += generate(ctxt, fieldCtxt, + " /*DEPRECATED*/ Q_INVOKABLE :fieldType get:fieldName() const { return static_cast<:fieldType>(:propName()); }\n"); + } + if (fieldCtxt.hasDeprecatedSetter) { + ctxt.setters += generate(ctxt, fieldCtxt, + " /*DEPRECATED*/ void set:fieldName(:fieldType value) { set:PropName(static_cast<:propType>(value)); }\n"); + } + if (fieldCtxt.hasDeprecatedNotification) { + ctxt.notifications += generate(ctxt, fieldCtxt, + " /*DEPRECATED*/ void :fieldNameChanged(:fieldType value);\n"); + + ctxt.notificationsImpl += generate(ctxt, fieldCtxt, + " /*DEPRECATED*/ emit :fieldNameChanged(get:fieldName());\n"); + } + } +} + +void generateSimpleProperty(Context &ctxt, FieldContext &fieldCtxt) +{ + if (fieldCtxt.field->type == FIELDTYPE_ENUM) { + generateEnum(ctxt, fieldCtxt); + } + + generateBaseProperty(ctxt, fieldCtxt); + + // getter implementation + ctxt.propertiesImpl += generate(ctxt, fieldCtxt, + ":propType :ClassName:::propName() const\n" + "{\n" + " QMutexLocker locker(mutex);\n" + " return static_cast<:propType>(data_.:fieldName);\n" + "}\n"); + + // emitters + QString emitters = generate(ctxt, fieldCtxt, "emit :propNameChanged(value);"); + + if (fieldCtxt.hasDeprecatedNotification) { + emitters += " "; + emitters += generate(ctxt, fieldCtxt, "emit :fieldNameChanged(static_cast<:fieldType>(value));"); + } + + // setter implementation + ctxt.propertiesImpl += generate(ctxt, fieldCtxt, + "void :ClassName::set:PropName(const :propRefType value)\n" + "{\n" + " mutex->lock();\n" + " bool changed = (data_.:fieldName != static_cast<:fieldType>(value));\n" + " data_.:fieldName = static_cast<:fieldType>(value);\n" + " mutex->unlock();\n" + " if (changed) { %1 }\n" + "}\n\n").arg(emitters); +} + +void generateIndexedProperty(Context &ctxt, FieldContext &fieldCtxt) +{ + if (fieldCtxt.field->type == FIELDTYPE_ENUM) { + generateEnum(ctxt, fieldCtxt); + } + + // indexed getter/setter + ctxt.getters += generate(ctxt, fieldCtxt, " Q_INVOKABLE :propType :propName(quint32 index) const;\n"); + ctxt.setters += generate(ctxt, fieldCtxt, " Q_INVOKABLE void set:PropName(quint32 index, const :propRefType value);\n"); + + // getter implementation + ctxt.propertiesImpl += generate(ctxt, fieldCtxt, + ":propType :ClassName:::propName(quint32 index) const\n" + "{\n" + " QMutexLocker locker(mutex);\n" + " return static_cast<:propType>(data_.:fieldName[index]);\n" + "}\n"); + + // emitters + QString emitters = generate(ctxt, fieldCtxt, "emit :propNameChanged(index, value);"); + + if (fieldCtxt.hasDeprecatedNotification) { + emitters += " "; + emitters += generate(ctxt, fieldCtxt, "emit :fieldNameChanged(index, static_cast<:fieldType>(value));"); + } + + // setter implementation + ctxt.propertiesImpl += generate(ctxt, fieldCtxt, + "void :ClassName::set:PropName(quint32 index, const :propRefType value)\n" + "{\n" + " mutex->lock();\n" + " bool changed = (data_.:fieldName[index] != static_cast<:fieldType>(value));\n" + " data_.:fieldName[index] = static_cast<:fieldType>(value);\n" + " mutex->unlock();\n" + " if (changed) { %1 }\n" + "}\n\n").arg(emitters); + + ctxt.notifications += generate(ctxt, fieldCtxt, " void :propNameChanged(quint32 index, const :propRefType value);\n"); + + if (DEPRECATED) { + // backward compatibility + if (fieldCtxt.hasDeprecatedGetter) { + ctxt.getters += generate(ctxt, fieldCtxt, + " /*DEPRECATED*/ Q_INVOKABLE :fieldType get:fieldName(quint32 index) const { return static_cast<:fieldType>(:propName(index)); }\n"); + } + if (fieldCtxt.hasDeprecatedSetter) { + ctxt.setters += generate(ctxt, fieldCtxt, + " /*DEPRECATED*/ void set:fieldName(quint32 index, :fieldType value) { set:PropName(index, static_cast<:propType>(value)); }\n"); + } + + if (fieldCtxt.hasDeprecatedNotification) { + ctxt.notifications += generate(ctxt, fieldCtxt, + " /*DEPRECATED*/ void :fieldNameChanged(quint32 index, :fieldType value);\n"); + } + } + + for (int elementIndex = 0; elementIndex < fieldCtxt.field->numElements; elementIndex++) { + QString elementName = fieldCtxt.field->elementNames[elementIndex]; + + QString sep; + if (fieldCtxt.propName.right(1)[0].isDigit() && elementName[0].isDigit()) { + info(ctxt.object, "Property \"" + fieldCtxt.propName + "\" and element \"" + elementName + "\" have digit conflict, consider fixing it."); + sep = "_"; + } + + FieldContext elementCtxt; + elementCtxt.field = fieldCtxt.field; + elementCtxt.fieldName = fieldCtxt.fieldName + "_" + elementName; + elementCtxt.fieldType = fieldCtxt.fieldType; + elementCtxt.propName = fieldCtxt.propName + sep + elementName; + elementCtxt.ucPropName = fieldCtxt.ucPropName + sep + elementName; + elementCtxt.propType = fieldCtxt.propType; + elementCtxt.propRefType = fieldCtxt.propRefType; + // deprecation + elementCtxt.hasDeprecatedProperty = (elementCtxt.fieldName != elementCtxt.propName) && DEPRECATED; + elementCtxt.hasDeprecatedGetter = DEPRECATED; + elementCtxt.hasDeprecatedSetter = ((elementCtxt.fieldName != elementCtxt.ucPropName) || (elementCtxt.fieldType != elementCtxt.propType)) && DEPRECATED; + elementCtxt.hasDeprecatedNotification = ((elementCtxt.fieldName != elementCtxt.propName) || (elementCtxt.fieldType != elementCtxt.propType)) && DEPRECATED; + + + generateBaseProperty(ctxt, elementCtxt); + + ctxt.propertiesImpl += generate(ctxt, elementCtxt, + ":propType :ClassName:::propName() const { return %1(%2); }\n").arg(fieldCtxt.propName).arg(elementIndex); + + ctxt.propertiesImpl += generate(ctxt, elementCtxt, + "void :ClassName::set:PropName(const :propRefType value) { set%1(%2, value); }\n").arg(fieldCtxt.ucPropName).arg(elementIndex); + } +} + +void generateProperty(Context &ctxt, FieldContext &fieldCtxt) +{ + // do some checks + QString fieldName = fieldCtxt.fieldName; + + if (fieldName[0].isLower()) { + info(ctxt.object, "Field \"" + fieldName + "\" does not start with an upper case letter."); + } + + // generate all properties + if (fieldCtxt.field->numElements > 1) { + generateIndexedProperty(ctxt, fieldCtxt); + } else { + generateSimpleProperty(ctxt, fieldCtxt); + } +} + bool UAVObjectGeneratorGCS::generate(UAVObjectParser *parser, QString templatepath, QString outputpath) { - fieldTypeStrCPP << "qint8" << "qint16" << "qint32" << - "quint8" << "quint16" << "quint32" << "float" << "quint8"; - - fieldTypeStrCPPClass << "INT8" << "INT16" << "INT32" - << "UINT8" << "UINT16" << "UINT32" << "FLOAT32" << "ENUM"; - gcsCodePath = QDir(templatepath + QString(GCS_CODE_DIR)); gcsOutputPath = QDir(outputpath); gcsOutputPath.mkpath(gcsOutputPath.absolutePath()); @@ -44,7 +560,7 @@ bool UAVObjectGeneratorGCS::generate(UAVObjectParser *parser, QString templatepa QString gcsInitTemplate = readFile(gcsCodePath.absoluteFilePath("uavobjectsinit.cpp.template")); if (gcsCodeTemplate.isEmpty() || gcsIncludeTemplate.isEmpty() || gcsInitTemplate.isEmpty()) { - std::cerr << "Problem reading gcs code templates" << endl; + error("Error: Failed to read gcs code templates."); return false; } @@ -52,31 +568,44 @@ bool UAVObjectGeneratorGCS::generate(UAVObjectParser *parser, QString templatepa QString gcsObjInit; for (int objidx = 0; objidx < parser->getNumObjects(); ++objidx) { - ObjectInfo *info = parser->getObjectByIndex(objidx); - process_object(info); + ObjectInfo *object = parser->getObjectByIndex(objidx); + process_object(object); - gcsObjInit.append(" objMngr->registerObject( new " + info->name + "() );\n"); - objInc.append("#include \"" + info->namelc + ".h\"\n"); + Context ctxt; + ctxt.object = object; + + objInc.append(QString("#include \"%1.h\"\n").arg(object->namelc)); + + gcsObjInit += ::generate(ctxt, " objMngr->registerObject( new :ClassName() );\n"); + gcsObjInit += ::generate(ctxt, " :ClassName::registerQMLTypes();\n"); } - // Write the gcs object inialization files - gcsInitTemplate.replace(QString("$(OBJINC)"), objInc); - gcsInitTemplate.replace(QString("$(OBJINIT)"), gcsObjInit); + // Write the gcs object initialization files + gcsInitTemplate.replace("$(OBJINC)", objInc); + gcsInitTemplate.replace("$(OBJINIT)", gcsObjInit); + bool res = writeFileIfDifferent(gcsOutputPath.absolutePath() + "/uavobjectsinit.cpp", gcsInitTemplate); if (!res) { - cout << "Error: Could not write output files" << endl; + error("Error: Could not write output files"); return false; } - return true; // if we come here everything should be fine + return true; } /** * Generate the GCS object files + * + * TODO add getter to get enum names + * + * TODO handle "char" unit + * TODO handle "bool" unit + * TODO handle "hex" unit + * TODO handle Vector */ -bool UAVObjectGeneratorGCS::process_object(ObjectInfo *info) +bool UAVObjectGeneratorGCS::process_object(ObjectInfo *object) { - if (info == NULL) { + if (object == NULL) { return false; } @@ -85,300 +614,88 @@ bool UAVObjectGeneratorGCS::process_object(ObjectInfo *info) QString outCode = gcsCodeTemplate; // Replace common tags - replaceCommonTags(outInclude, info); - replaceCommonTags(outCode, info); - - // Replace the $(DATAFIELDS) tag - QString type; - QString fields; - for (int n = 0; n < info->fields.length(); ++n) { - // Determine type - type = fieldTypeStrCPP[info->fields[n]->type]; - // Append field - if (info->fields[n]->numElements > 1) { - fields.append(QString(" %1 %2[%3];\n").arg(type).arg(info->fields[n]->name) - .arg(info->fields[n]->numElements)); - } else { - fields.append(QString(" %1 %2;\n").arg(type).arg(info->fields[n]->name)); - } - } - outInclude.replace(QString("$(DATAFIELDS)"), fields); - - // Replace $(PROPERTIES) and related tags - QString properties; - QString propertiesImpl; - QString propertyGetters; - QString propertySetters; - QString propertyNotifications; - QString propertyNotificationsImpl; + replaceCommonTags(outInclude, object); + replaceCommonTags(outCode, object); // to avoid name conflicts QStringList reservedProperties; reservedProperties << "Description" << "Metadata"; - for (int n = 0; n < info->fields.length(); ++n) { - FieldInfo *field = info->fields[n]; + Context ctxt; + ctxt.object = object; + + ctxt.registerImpl += ::generate(ctxt, + " qmlRegisterType<:ClassName>(\"%1.:ClassName\", 1, 0, \":ClassName\");\n").arg("UAVTalk"); + + ctxt.registerImpl += ::generate(ctxt, + " qmlRegisterType<:ClassNameConstants>(\"%1.:ClassName\", 1, 0, \":ClassNameConstants\");\n").arg("UAVTalk"); + + for (int n = 0; n < object->fields.length(); ++n) { + FieldInfo *field = object->fields[n]; + + // field context + FieldContext fieldCtxt; + fieldCtxt.field = field; + + // field properties + fieldCtxt.fieldName = field->name; + fieldCtxt.fieldType = fieldTypeStrCPP(field->type); + + fieldCtxt.ucPropName = toPropertyName(field->name); + fieldCtxt.propName = toLowerCamelCase(fieldCtxt.ucPropName); + fieldCtxt.propType = fieldCtxt.fieldType; + if (field->type == FIELDTYPE_INT8) { + fieldCtxt.propType = fieldTypeStrCPP(FIELDTYPE_INT16); + } else if (field->type == FIELDTYPE_UINT8) { + fieldCtxt.propType = fieldTypeStrCPP(FIELDTYPE_UINT16); + } else if (field->type == FIELDTYPE_ENUM) { + QString enumClassName = object->name + "_" + fieldCtxt.ucPropName; + fieldCtxt.propType = enumClassName + "::Enum"; + } + // reference type + fieldCtxt.propRefType = fieldCtxt.propType; + + // deprecation + fieldCtxt.hasDeprecatedProperty = (fieldCtxt.fieldName != fieldCtxt.propName) && DEPRECATED; + fieldCtxt.hasDeprecatedGetter = DEPRECATED; + fieldCtxt.hasDeprecatedSetter = ((fieldCtxt.fieldName != fieldCtxt.ucPropName) || (fieldCtxt.fieldType != fieldCtxt.propType)) && DEPRECATED; + fieldCtxt.hasDeprecatedNotification = ((fieldCtxt.fieldName != fieldCtxt.propName) || (fieldCtxt.fieldType != fieldCtxt.propType)) && DEPRECATED; + + generateField(ctxt, fieldCtxt); if (reservedProperties.contains(field->name)) { + warning(object, "Ignoring reserved property " + field->name + "."); continue; } - // Determine type - type = fieldTypeStrCPP[field->type]; - // Append field - if (field->numElements > 1) { - // add both field(elementIndex)/setField(elemntIndex,value) and field_element properties - // field_element is more convenient if only certain element is used - // and much easier to use from the qml side - propertyGetters += - QString(" Q_INVOKABLE %1 get%2(quint32 index) const;\n") - .arg(type).arg(field->name); - propertiesImpl += - QString("%1 %2::get%3(quint32 index) const\n" - "{\n" - " QMutexLocker locker(mutex);\n" - " return data.%3[index];\n" - "}\n") - .arg(type).arg(info->name).arg(field->name); - propertySetters += - QString(" void set%1(quint32 index, %2 value);\n") - .arg(field->name).arg(type); - propertiesImpl += - QString("void %1::set%2(quint32 index, %3 value)\n" - "{\n" - " mutex->lock();\n" - " bool changed = data.%2[index] != value;\n" - " data.%2[index] = value;\n" - " mutex->unlock();\n" - " if (changed) emit %2Changed(index,value);\n" - "}\n\n") - .arg(info->name).arg(field->name).arg(type); - propertyNotifications += - QString(" void %1Changed(quint32 index, %2 value);\n") - .arg(field->name).arg(type); - - for (int elementIndex = 0; elementIndex < field->numElements; elementIndex++) { - QString elementName = field->elementNames[elementIndex]; - properties += QString(" Q_PROPERTY(%1 %2 READ get%2 WRITE set%2 NOTIFY %2Changed);\n") - .arg(type).arg(field->name + "_" + elementName); - propertyGetters += - QString(" Q_INVOKABLE %1 get%2_%3() const;\n") - .arg(type).arg(field->name).arg(elementName); - propertiesImpl += - QString("%1 %2::get%3_%4() const\n" - "{\n" - " QMutexLocker locker(mutex);\n" - " return data.%3[%5];\n" - "}\n") - .arg(type).arg(info->name).arg(field->name).arg(elementName).arg(elementIndex); - propertySetters += - QString(" void set%1_%2(%3 value);\n") - .arg(field->name).arg(elementName).arg(type); - propertiesImpl += - QString("void %1::set%2_%3(%4 value)\n" - "{\n" - " mutex->lock();\n" - " bool changed = data.%2[%5] != value;\n" - " data.%2[%5] = value;\n" - " mutex->unlock();\n" - " if (changed) emit %2_%3Changed(value);\n" - "}\n\n") - .arg(info->name).arg(field->name).arg(elementName).arg(type).arg(elementIndex); - propertyNotifications += - QString(" void %1_%2Changed(%3 value);\n") - .arg(field->name).arg(elementName).arg(type); - propertyNotificationsImpl += - QString(" //if (data.%1[%2] != oldData.%1[%2])\n" - " emit %1_%3Changed(data.%1[%2]);\n") - .arg(field->name).arg(elementIndex).arg(elementName); - } - } else { - properties += QString(" Q_PROPERTY(%1 %2 READ get%2 WRITE set%2 NOTIFY %2Changed);\n") - .arg(type).arg(field->name); - propertyGetters += - QString(" Q_INVOKABLE %1 get%2() const;\n") - .arg(type).arg(field->name); - propertiesImpl += - QString("%1 %2::get%3() const\n" - "{\n" - " QMutexLocker locker(mutex);\n" - " return data.%3;\n" - "}\n") - .arg(type).arg(info->name).arg(field->name); - propertySetters += - QString(" void set%1(%2 value);\n") - .arg(field->name).arg(type); - propertiesImpl += - QString("void %1::set%2(%3 value)\n" - "{\n" - " mutex->lock();\n" - " bool changed = data.%2 != value;\n" - " data.%2 = value;\n" - " mutex->unlock();\n" - " if (changed) emit %2Changed(value);\n" - "}\n\n") - .arg(info->name).arg(field->name).arg(type); - propertyNotifications += - QString(" void %1Changed(%2 value);\n") - .arg(field->name).arg(type); - propertyNotificationsImpl += - QString(" //if (data.%1 != oldData.%1)\n" - " emit %1Changed(data.%1);\n") - .arg(field->name); - } + generateProperty(ctxt, fieldCtxt); } - outInclude.replace(QString("$(PROPERTIES)"), properties); - outInclude.replace(QString("$(PROPERTY_GETTERS)"), propertyGetters); - outInclude.replace(QString("$(PROPERTY_SETTERS)"), propertySetters); - outInclude.replace(QString("$(PROPERTY_NOTIFICATIONS)"), propertyNotifications); + outInclude.replace("$(ENUMS)", ctxt.enums); + outInclude.replace("$(ENUMS_COUNT)", ctxt.enumsCount); + outInclude.replace("$(DATAFIELDS)", ctxt.fields); + outInclude.replace("$(DATAFIELDINFO)", ctxt.fieldsInfo); + outInclude.replace("$(PROPERTIES)", ctxt.properties); + outInclude.replace("$(DEPRECATED_PROPERTIES)", ctxt.deprecatedProperties); + outInclude.replace("$(PROPERTY_GETTERS)", ctxt.getters); + outInclude.replace("$(PROPERTY_SETTERS)", ctxt.setters); + outInclude.replace("$(PROPERTY_NOTIFICATIONS)", ctxt.notifications); - outCode.replace(QString("$(PROPERTIES_IMPL)"), propertiesImpl); - outCode.replace(QString("$(NOTIFY_PROPERTIES_CHANGED)"), propertyNotificationsImpl); - - // Replace the $(FIELDSINIT) tag - QString finit; - for (int n = 0; n < info->fields.length(); ++n) { - // Setup element names - QString varElemName = info->fields[n]->name + "ElemNames"; - finit.append(QString(" QStringList %1;\n").arg(varElemName)); - QStringList elemNames = info->fields[n]->elementNames; - for (int m = 0; m < elemNames.length(); ++m) { - finit.append(QString(" %1.append(\"%2\");\n") - .arg(varElemName) - .arg(elemNames[m])); - } - - // Only for enum types - if (info->fields[n]->type == FIELDTYPE_ENUM) { - QString varOptionName = info->fields[n]->name + "EnumOptions"; - finit.append(QString(" QStringList %1;\n").arg(varOptionName)); - QStringList options = info->fields[n]->options; - for (int m = 0; m < options.length(); ++m) { - finit.append(QString(" %1.append(\"%2\");\n") - .arg(varOptionName) - .arg(options[m])); - } - finit.append(QString(" fields.append( new UAVObjectField(QString(\"%1\"), tr(\"%2\"), QString(\"%3\"), UAVObjectField::ENUM, %4, %5, QString(\"%6\")));\n") - .arg(info->fields[n]->name) - .arg(info->fields[n]->description) - .arg(info->fields[n]->units) - .arg(varElemName) - .arg(varOptionName) - .arg(info->fields[n]->limitValues)); - } - // For all other types - else { - finit.append(QString(" fields.append( new UAVObjectField(QString(\"%1\"), tr(\"%2\"), QString(\"%3\"), UAVObjectField::%4, %5, QStringList(), QString(\"%6\")));\n") - .arg(info->fields[n]->name) - .arg(info->fields[n]->description) - .arg(info->fields[n]->units) - .arg(fieldTypeStrCPPClass[info->fields[n]->type]) - .arg(varElemName) - .arg(info->fields[n]->limitValues)); - } - } - outCode.replace(QString("$(FIELDSINIT)"), finit); - - // Replace the $(DATAFIELDINFO) tag - QString name; - QString enums; - for (int n = 0; n < info->fields.length(); ++n) { - enums.append(QString(" // Field %1 information\n").arg(info->fields[n]->name)); - // Only for enum types - if (info->fields[n]->type == FIELDTYPE_ENUM) { - enums.append(QString(" /* Enumeration options for field %1 */\n").arg(info->fields[n]->name)); - enums.append(" typedef enum { "); - // Go through each option - QStringList options = info->fields[n]->options; - for (int m = 0; m < options.length(); ++m) { - QString s = (m != (options.length() - 1)) ? "%1_%2=%3, " : "%1_%2=%3"; - enums.append(s.arg(info->fields[n]->name.toUpper()) - .arg(options[m].toUpper().replace(QRegExp(ENUM_SPECIAL_CHARS), "")) - .arg(m)); - } - enums.append(QString(" } %1Options;\n") - .arg(info->fields[n]->name)); - } - // Generate element names (only if field has more than one element) - if (info->fields[n]->numElements > 1 && !info->fields[n]->defaultElementNames) { - enums.append(QString(" /* Array element names for field %1 */\n").arg(info->fields[n]->name)); - enums.append(" typedef enum { "); - // Go through the element names - QStringList elemNames = info->fields[n]->elementNames; - for (int m = 0; m < elemNames.length(); ++m) { - QString s = (m != (elemNames.length() - 1)) ? "%1_%2=%3, " : "%1_%2=%3"; - enums.append(s.arg(info->fields[n]->name.toUpper()) - .arg(elemNames[m].toUpper()) - .arg(m)); - } - enums.append(QString(" } %1Elem;\n") - .arg(info->fields[n]->name)); - } - // Generate array information - if (info->fields[n]->numElements > 1) { - enums.append(QString(" /* Number of elements for field %1 */\n").arg(info->fields[n]->name)); - enums.append(QString(" static const quint32 %1_NUMELEM = %2;\n") - .arg(info->fields[n]->name.toUpper()) - .arg(info->fields[n]->numElements)); - } - } - outInclude.replace(QString("$(DATAFIELDINFO)"), enums); - - // Replace the $(INITFIELDS) tag - QString initfields; - for (int n = 0; n < info->fields.length(); ++n) { - if (!info->fields[n]->defaultValues.isEmpty()) { - // For non-array fields - if (info->fields[n]->numElements == 1) { - if (info->fields[n]->type == FIELDTYPE_ENUM) { - initfields.append(QString(" data.%1 = %2;\n") - .arg(info->fields[n]->name) - .arg(info->fields[n]->options.indexOf(info->fields[n]->defaultValues[0]))); - } else if (info->fields[n]->type == FIELDTYPE_FLOAT32) { - initfields.append(QString(" data.%1 = %2;\n") - .arg(info->fields[n]->name) - .arg(info->fields[n]->defaultValues[0].toFloat())); - } else { - initfields.append(QString(" data.%1 = %2;\n") - .arg(info->fields[n]->name) - .arg(info->fields[n]->defaultValues[0].toInt())); - } - } else { - // Initialize all fields in the array - for (int idx = 0; idx < info->fields[n]->numElements; ++idx) { - if (info->fields[n]->type == FIELDTYPE_ENUM) { - initfields.append(QString(" data.%1[%2] = %3;\n") - .arg(info->fields[n]->name) - .arg(idx) - .arg(info->fields[n]->options.indexOf(info->fields[n]->defaultValues[idx]))); - } else if (info->fields[n]->type == FIELDTYPE_FLOAT32) { - initfields.append(QString(" data.%1[%2] = %3;\n") - .arg(info->fields[n]->name) - .arg(idx) - .arg(info->fields[n]->defaultValues[idx].toFloat())); - } else { - initfields.append(QString(" data.%1[%2] = %3;\n") - .arg(info->fields[n]->name) - .arg(idx) - .arg(info->fields[n]->defaultValues[idx].toInt())); - } - } - } - } - } - - outCode.replace(QString("$(INITFIELDS)"), initfields); + outCode.replace("$(FIELDSINIT)", ctxt.fieldsInit); + outCode.replace("$(FIELDSDEFAULT)", ctxt.fieldsDefault); + outCode.replace("$(PROPERTIES_IMPL)", ctxt.propertiesImpl); + outCode.replace("$(NOTIFY_PROPERTIES_CHANGED)", ctxt.notificationsImpl); + outCode.replace("$(REGISTER_QML_TYPES)", ctxt.registerImpl); // Write the GCS code - bool res = writeFileIfDifferent(gcsOutputPath.absolutePath() + "/" + info->namelc + ".cpp", outCode); + bool res = writeFileIfDifferent(gcsOutputPath.absolutePath() + "/" + object->namelc + ".cpp", outCode); if (!res) { - cout << "Error: Could not write gcs output files" << endl; + error("Error: Could not write gcs output files"); return false; } - res = writeFileIfDifferent(gcsOutputPath.absolutePath() + "/" + info->namelc + ".h", outInclude); + res = writeFileIfDifferent(gcsOutputPath.absolutePath() + "/" + object->namelc + ".h", outInclude); if (!res) { - cout << "Error: Could not write gcs output files" << endl; + error("Error: Could not write gcs output files"); return false; } diff --git a/ground/uavobjgenerator/generators/gcs/uavobjectgeneratorgcs.h b/ground/uavobjgenerator/generators/gcs/uavobjectgeneratorgcs.h index 767db14bf..6936eea4b 100644 --- a/ground/uavobjgenerator/generators/gcs/uavobjectgeneratorgcs.h +++ b/ground/uavobjgenerator/generators/gcs/uavobjectgeneratorgcs.h @@ -39,7 +39,6 @@ private: bool process_object(ObjectInfo *info); QString gcsCodeTemplate, gcsIncludeTemplate; - QStringList fieldTypeStrCPP, fieldTypeStrCPPClass; QDir gcsCodePath; QDir gcsOutputPath; }; diff --git a/ground/uavobjgenerator/uavobjectparser.cpp b/ground/uavobjgenerator/uavobjectparser.cpp index 50a70bef5..33466eacf 100644 --- a/ground/uavobjgenerator/uavobjectparser.cpp +++ b/ground/uavobjgenerator/uavobjectparser.cpp @@ -2,7 +2,8 @@ ****************************************************************************** * * @file uavobjectparser.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @brief Parses XML files and extracts object information. * * @see The GNU Public License (GPL) Version 3 @@ -545,7 +546,8 @@ QString UAVObjectParser::processObjectFields(QDomNode & childNode, ObjectInfo *i } } } - if (field->options.length() == 0) { + field->numOptions = field->options.size(); + if (field->numOptions == 0) { return QString("Object:field:options attribute/element is missing"); } } diff --git a/ground/uavobjgenerator/uavobjectparser.h b/ground/uavobjgenerator/uavobjectparser.h index 368b2ebde..ee9d9460c 100644 --- a/ground/uavobjgenerator/uavobjectparser.h +++ b/ground/uavobjgenerator/uavobjectparser.h @@ -2,7 +2,8 @@ ****************************************************************************** * * @file uavobjectparser.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @brief Parses XML files and extracts object information. * * @see The GNU Public License (GPL) Version 3 @@ -46,15 +47,16 @@ typedef enum { } FieldType; typedef struct { - QString name; - QString description; - QString units; - FieldType type; - int numElements; - int numBytes; + QString name; + QString description; + QString units; + FieldType type; + int numElements; + int numOptions; + int numBytes; QStringList elementNames; QStringList options; // for enums only - bool defaultElementNames; + bool defaultElementNames; QStringList defaultValues; QString limitValues; } FieldInfo; diff --git a/ground/uavobjgenerator/uavobjgenerator.pro b/ground/uavobjgenerator/uavobjgenerator.pro index 4a03832df..1ac5d95cf 100644 --- a/ground/uavobjgenerator/uavobjgenerator.pro +++ b/ground/uavobjgenerator/uavobjgenerator.pro @@ -6,7 +6,12 @@ QT += xml QT -= gui macx { - QMAKE_CXXFLAGS += -fpermissive + CONFIG += warn_on + !warn_off { + QMAKE_CXXFLAGS_WARN_ON += -Werror + QMAKE_CFLAGS_WARN_ON += -Werror + QMAKE_CXXFLAGS += -fpermissive + } } # use ccache when available QMAKE_CC = $$(CCACHE) $$QMAKE_CC diff --git a/make/3rdparty/3rdparty.mk b/make/3rdparty/3rdparty.mk new file mode 100644 index 000000000..8e259e7c2 --- /dev/null +++ b/make/3rdparty/3rdparty.mk @@ -0,0 +1,2 @@ +-include $(ROOT_DIR)/make/3rdparty/osgearth/osgearth.mk +-include $(ROOT_DIR)/make/3rdparty/marble/marble.mk diff --git a/make/3rdparty/marble/googlesat.patch b/make/3rdparty/marble/googlesat.patch new file mode 100644 index 000000000..05b10bba1 --- /dev/null +++ b/make/3rdparty/marble/googlesat.patch @@ -0,0 +1,13 @@ +diff --git a/googlesat.dgml b/googlesat.dgml +index 6e9fbd3..42f5e72 100644 +--- a/googlesat.dgml ++++ b/googlesat.dgml +@@ -26,7 +26,7 @@ + earth/googlesat + + +- ++ + + + earth/googlesat/streets diff --git a/make/3rdparty/marble/marble-15.08.1.patch b/make/3rdparty/marble/marble-15.08.1.patch new file mode 100644 index 000000000..c18352060 --- /dev/null +++ b/make/3rdparty/marble/marble-15.08.1.patch @@ -0,0 +1,13 @@ +diff --git a/src/apps/marble-qt/QtMainWindow.cpp b/src/apps/marble-qt/QtMainWindow.cpp +index da9f44f..b3f4ee3 100644 +--- a/src/apps/marble-qt/QtMainWindow.cpp ++++ b/src/apps/marble-qt/QtMainWindow.cpp +@@ -432,7 +432,7 @@ void MainWindow::createActions() + void MainWindow::createMenus( const QList &panelActions ) + { + #ifdef Q_OS_WIN +- m_downloadAction.setEnabled( false ); ++ m_downloadAction->setEnabled( false ); + #endif + + m_fileMenu = menuBar()->addMenu(tr("&File")); diff --git a/make/3rdparty/marble/marble.mk b/make/3rdparty/marble/marble.mk new file mode 100644 index 000000000..01a214f3b --- /dev/null +++ b/make/3rdparty/marble/marble.mk @@ -0,0 +1,152 @@ +################################ +# Targets to build Marble +# +################################ +# +# $ make all_marble +# +################################ + +MARBLE_NAME_PREFIX := +MARBLE_NAME_SUFIX := -qt-$(QT_VERSION) + +################################ +# +# Marble +# +################################ + +MARBLE_VERSION := 15.08.1 +MARBLE_GIT_BRANCH := v$(MARBLE_VERSION) + +MARBLE_BASE_NAME := marble-$(MARBLE_VERSION) +MARBLE_BUILD_CONF := Release + +ifeq ($(UNAME), Linux) + ifeq ($(ARCH), x86_64) + MARBLE_NAME := $(MARBLE_BASE_NAME)-linux-x64 + else + MARBLE_NAME := $(MARBLE_BASE_NAME)-linux-x86 + endif + MARBLE_DATA_BASE_DIR := share/marble/data + MARBLE_CMAKE_GENERATOR := "Unix Makefiles" + # for some reason Qt is not added to the path in make/tools.mk + MARBLE_BUILD_PATH := $(QT_SDK_PREFIX)/bin:$(PATH) +else ifeq ($(UNAME), Darwin) + MARBLE_NAME := $(MARBLE_BASE_NAME)-clang_64 + MARBLE_DATA_BASE_DIR := share/marble/data + MARBLE_CMAKE_GENERATOR := "Unix Makefiles" + # for some reason Qt is not added to the path in make/tools.mk + MARBLE_BUILD_PATH := $(QT_SDK_PREFIX)/bin:$(PATH) +else ifeq ($(UNAME), Windows) + MARBLE_NAME := $(MARBLE_BASE_NAME)-$(QT_SDK_ARCH) + MARBLE_DATA_BASE_DIR := data + MARBLE_CMAKE_GENERATOR := "MinGW Makefiles" +endif + +MARBLE_NAME := $(MARBLE_NAME_PREFIX)$(MARBLE_NAME)$(MARBLE_NAME_SUFIX) +MARBLE_SRC_DIR := $(ROOT_DIR)/3rdparty/marble +MARBLE_BUILD_DIR := $(BUILD_DIR)/3rdparty/$(MARBLE_NAME) +MARBLE_INSTALL_DIR := $(BUILD_DIR)/3rdparty/install/$(MARBLE_NAME) +MARBLE_DATA_DIR := $(MARBLE_INSTALL_DIR)/$(MARBLE_DATA_BASE_DIR) +MARBLE_PATCH_FILE := $(ROOT_DIR)/make/3rdparty/marble/marble-$(MARBLE_VERSION).patch + +GOOGLE_SAT_PATCH_FILE := $(ROOT_DIR)/make/3rdparty/marble/googlesat.patch + +.PHONY: marble +marble: + @$(ECHO) "Building marble $(call toprel, $(MARBLE_SRC_DIR)) into $(call toprel, $(MARBLE_BUILD_DIR))" + $(V1) $(MKDIR) -p $(MARBLE_BUILD_DIR) + $(V1) ( $(CD) $(MARBLE_BUILD_DIR) && \ + if [ -n "$(MARBLE_BUILD_PATH)" ]; then \ + PATH=$(MARBLE_BUILD_PATH) ; \ + fi ; \ + $(CMAKE) -Wno-dev -G $(MARBLE_CMAKE_GENERATOR) -DCMAKE_BUILD_TYPE=$(MARBLE_BUILD_CONF) \ + -DCMAKE_MAKE_PROGRAM=$(MAKE) \ + -DWITH_KF5=FALSE -DQT5BUILD=ON -DBUILD_WITH_DBUS=OFF -DMARBLE_NO_WEBKIT=TRUE -DWITH_DESIGNER_PLUGIN=NO \ + -DCMAKE_INSTALL_PREFIX=$(MARBLE_INSTALL_DIR) $(MARBLE_SRC_DIR) && \ + $(MAKE) && \ + $(MAKE) install ; \ + ) + @$(ECHO) "Copying restricted maps to $(call toprel, $(MARBLE_DATA_DIR))" + @$(ECHO) "Copying Google Maps" + $(V1) $(MKDIR) -p $(MARBLE_DATA_DIR)/maps/earth/googlemaps + $(V1) $(CP) $(MARBLE_SRC_DIR)/googlemaps/googlemaps.dgml $(MARBLE_DATA_DIR)/maps/earth/googlemaps/ + $(V1) $(CP) $(MARBLE_SRC_DIR)/googlemaps/preview.png $(MARBLE_DATA_DIR)/maps/earth/googlemaps/ + $(V1) $(CP) -R $(MARBLE_SRC_DIR)/googlemaps/0 $(MARBLE_DATA_DIR)/maps/earth/googlemaps/ + @$(ECHO) "Copying Google Sat" + $(V1) $(MKDIR) -p $(MARBLE_DATA_DIR)/maps/earth/googlesat + $(V1) $(CP) $(MARBLE_SRC_DIR)/googlesat/googlesat.dgml $(MARBLE_DATA_DIR)/maps/earth/googlesat/ + $(V1) $(CP) $(MARBLE_SRC_DIR)/googlesat/preview.png $(MARBLE_DATA_DIR)/maps/earth/googlesat/ + $(V1) $(CP) -R $(MARBLE_SRC_DIR)/googlesat/0 $(MARBLE_DATA_DIR)/maps/earth/googlesat/ + $(V1) $(CP) -R $(MARBLE_SRC_DIR)/googlesat/streets $(MARBLE_DATA_DIR)/maps/earth/googlesat/ + +.PHONY: package_marble +package_marble: + @$(ECHO) "Packaging $(call toprel, $(MARBLE_INSTALL_DIR)) into $(notdir $(MARBLE_INSTALL_DIR)).tar" + #$(V1) $(CP) $(ROOT_DIR)/make/3rdparty/marble/LibrePilotReadme.txt $(MARBLE_INSTALL_DIR)/ + $(V1) ( \ + $(CD) $(MARBLE_INSTALL_DIR)/.. && \ + $(TAR) cf $(notdir $(MARBLE_INSTALL_DIR)).tar $(notdir $(MARBLE_INSTALL_DIR)) && \ + $(ZIP) -f $(notdir $(MARBLE_INSTALL_DIR)).tar && \ + $(call MD5_GEN_TEMPLATE,$(notdir $(MARBLE_INSTALL_DIR)).tar.gz) ; \ + ) + +.NOTPARALLEL: +.PHONY: prepare_marble +prepare_marble: clone_marble + +.PHONY: clone_marble +clone_marble: + $(V1) if [ ! -d "$(MARBLE_SRC_DIR)" ]; then \ + $(ECHO) "Cloning marble..." ; \ + $(GIT) clone --no-checkout git://anongit.kde.org/marble $(MARBLE_SRC_DIR) ; \ + fi + @$(ECHO) "Fetching marble..." + $(V1) ( $(CD) $(MARBLE_SRC_DIR) && $(GIT) fetch ; ) + @$(ECHO) "Checking out marble $(MARBLE_GIT_BRANCH)" + $(V1) ( $(CD) $(MARBLE_SRC_DIR) && $(GIT) fetch --tags ; ) + $(V1) ( $(CD) $(MARBLE_SRC_DIR) && $(GIT) checkout --quiet --force $(MARBLE_GIT_BRANCH) ; ) + $(V1) if [ -e $(MARBLE_PATCH_FILE) ]; then \ + $(ECHO) "Patching marble..." ; \ + ( $(CD) $(MARBLE_SRC_DIR) && $(GIT) apply $(MARBLE_PATCH_FILE) ; ) \ + fi + + $(V1) if [ ! -d "$(MARBLE_SRC_DIR)/googlemaps" ]; then \ + $(ECHO) "Cloning googlemaps to $(call toprel, $(MARBLE_SRC_DIR)/googlemaps)" ; \ + $(GIT) clone https://gitlab.com/marble-restricted-maps/googlemaps.git $(MARBLE_SRC_DIR)/googlemaps ; \ + fi + @$(ECHO) "Fetching googlemaps..." + $(V1) ( $(CD) $(MARBLE_SRC_DIR)/googlemaps && $(GIT) fetch ; ) + @$(ECHO) "Checking out googlemaps" + $(V1) ( $(CD) $(MARBLE_SRC_DIR)/googlemaps && $(GIT) checkout --quiet --force master ; ) + + $(V1) if [ ! -d "$(MARBLE_SRC_DIR)/googlesat" ]; then \ + $(ECHO) "Cloning googlesat to $(call toprel, $(MARBLE_SRC_DIR)/googlesat)" ; \ + $(GIT) clone https://gitlab.com/marble-restricted-maps/googlesat.git $(MARBLE_SRC_DIR)/googlesat ; \ + fi + @$(ECHO) "Fetching googlesat..." + $(V1) ( $(CD) $(MARBLE_SRC_DIR)/googlesat && $(GIT) fetch ; ) + @$(ECHO) "Checking out googlesat" + $(V1) ( $(CD) $(MARBLE_SRC_DIR)/googlesat && $(GIT) checkout --quiet --force master ; ) + $(V1) if [ -e $(GOOGLE_SAT_PATCH_FILE) ]; then \ + $(ECHO) "Patching google sat..." ; \ + ( $(CD) $(MARBLE_SRC_DIR)/googlesat && $(GIT) apply $(GOOGLE_SAT_PATCH_FILE) ; ) \ + fi + +.PHONY: clean_marble +clean_marble: + @$(ECHO) $(MSG_CLEANING) $(call toprel, $(MARBLE_BUILD_DIR)) + $(V1) [ ! -d "$(MARBLE_BUILD_DIR)" ] || $(RM) -r "$(MARBLE_BUILD_DIR)" + @$(ECHO) $(MSG_CLEANING) $(call toprel, $(MARBLE_INSTALL_DIR)) + $(V1) [ ! -d "$(MARBLE_INSTALL_DIR)" ] || $(RM) -r "$(MARBLE_INSTALL_DIR)" + +.PHONY: clean_all_marble +clean_all_marble: clean_marble + @$(ECHO) $(MSG_CLEANING) $(call toprel, $(MARBLE_SRC_DIR)) + $(V1) [ ! -d "$(MARBLE_SRC_DIR)" ] || $(RM) -r "$(MARBLE_SRC_DIR)" + +.NOTPARALLEL: +.PHONY: all_marble +all_marble: prepare_marble marble package_marble + diff --git a/make/3rdparty/osgearth/README.TXT b/make/3rdparty/osgearth/README.TXT new file mode 100644 index 000000000..07009056f --- /dev/null +++ b/make/3rdparty/osgearth/README.TXT @@ -0,0 +1,107 @@ +This document describes how to build osg and osgEarth. + +Building osgEarth requires: +* osgEarth (http://osgearth.org/) +* OpenSceneGraph (http://www.openscenegraph.org/) +* GDAL (http://www.gdal.org/) +* zlib, png, etc... + +Make sure all LibrePilot SDKs are up to date as the osgEarth build relies on them. + +More details can be found in osgearth.mk. + + +Linux prerequisites +---------------------------------- + +$ sudo apt-get install libzip-dev libpng-dev lipjpeg-dev libtiff5-dev libcurl4-openssl-dev +$ sudo apt-get install libgeos++-dev libgdal-dev + +Alternative (not tested recently but could work): +$ sudo apt-get build-dep openscenegraph + +Tested with: + +$ curl --version +curl 7.35.0 (i686-pc-linux-gnu) libcurl/7.35.0 OpenSSL/1.0.1f zlib/1.2.8 libidn/1.28 librtmp/2.3 + +$ gdal-config --version +1.10.1 + + +OSX prerequisites +---------------------------------- + +brew install cmake +brew install gdal + +Windows prerequisites +---------------------------------- + +pacman -S mingw-w64-i686-cmake mingw-w64-i686-gdal-minimal + +To build minimal gdal + +From a MSYS shell: + +$ pacman -S base-devel + +Follow these instructions : http://sourceforge.net/p/msys2/wiki/Contributing%20to%20MSYS2/ +With : +- LibrePilot package repository : ??? + +$ pacman -U mingw-w64-i686-gdal-minimal-2.0.1-2-any.pkg.tar.xz + +Notes: +- uninstall any previously installed gdal package. + +Todo +- declare provides= and conflicts with origina gdal in PKGBUILD file + (allows to substitute the minimal package when anything depends on the original package) + +Building +---------------------------------- + +$ make all_osg + +This will: +- clone osg and osgearth git repositories in ./3rdparty +- build osg and osgEarth libraries in ./build/3rdparty +- create distribution files (tar & md5) in ./build/3rdparty/install + +Installing +---------------------------------- + +Copy the built osg and osgearth libraries into the tools directory: + +cp -R build/3rdparty/install/osg*[.0-9][0-9] tools/ + +Configure LibrePilot GCS to use osg and osgearth: + +echo "override GCS_EXTRA_CONF=osg osgearth copy_osg" > config + +You'll then need to do a full rebuild of LibrePilot GCS. + +Building LibrePilot GCS +---------------------------------- + +Clean and build all + +make clean +make -j8 all + +Replace the 8 in "-j8" with the number of CPU cores your PC has (maybe one more or less than your PC has). + +Running LibrePilot GCS +---------------------------------- + +Start LibrePilot GCS with: + +./build/librepilot-gcs_release/bin/librepilot-gcs -reset & + +Only use the -reset option once (if at all). +It will reset your LibrePilot GCS setup to factory defaults which is necessary to see new gadget configuration options. +Your setup for workspaces, gadgets, scopes, etc. will be lost. + +In LibrePilot GCS, go to the Flight data workspace and use menu Window/Edit Gadgets Mode, +Select PFD gadget in one of the gadget panes and choose the PFD (ArcGis) or PFD (ReadyMap) configuration. diff --git a/make/3rdparty/osgearth/osg-3.4.0.patch b/make/3rdparty/osgearth/osg-3.4.0.patch new file mode 100644 index 000000000..e8ebd4457 --- /dev/null +++ b/make/3rdparty/osgearth/osg-3.4.0.patch @@ -0,0 +1,24 @@ +diff --git a/include/osg/OperationThread b/include/osg/OperationThread +index a62157e..75adfba 100644 +--- a/include/osg/OperationThread ++++ b/include/osg/OperationThread +@@ -80,6 +80,7 @@ protected: + _keep(false) {} + + Operation(const Operation& op): ++ Referenced(), + _name(op._name), + _keep(op._keep) {} + +diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt +index 33edf57..d2ea025 100644 +--- a/src/CMakeLists.txt ++++ b/src/CMakeLists.txt +@@ -27,7 +27,6 @@ FOREACH( mylibfolder + osgUI + osgVolume + osgWrappers/serializers +- osgWrappers/deprecated-dotosg + osgPlugins + ) + diff --git a/make/3rdparty/osgearth/osg-3.4.patch b/make/3rdparty/osgearth/osg-3.4.patch new file mode 100644 index 000000000..e8ebd4457 --- /dev/null +++ b/make/3rdparty/osgearth/osg-3.4.patch @@ -0,0 +1,24 @@ +diff --git a/include/osg/OperationThread b/include/osg/OperationThread +index a62157e..75adfba 100644 +--- a/include/osg/OperationThread ++++ b/include/osg/OperationThread +@@ -80,6 +80,7 @@ protected: + _keep(false) {} + + Operation(const Operation& op): ++ Referenced(), + _name(op._name), + _keep(op._keep) {} + +diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt +index 33edf57..d2ea025 100644 +--- a/src/CMakeLists.txt ++++ b/src/CMakeLists.txt +@@ -27,7 +27,6 @@ FOREACH( mylibfolder + osgUI + osgVolume + osgWrappers/serializers +- osgWrappers/deprecated-dotosg + osgPlugins + ) + diff --git a/make/3rdparty/osgearth/osg-3.5.1.patch b/make/3rdparty/osgearth/osg-3.5.1.patch new file mode 100644 index 000000000..1fe01b80e --- /dev/null +++ b/make/3rdparty/osgearth/osg-3.5.1.patch @@ -0,0 +1,13 @@ +diff --git a/include/osgViewer/View b/include/osgViewer/View +index 472b489..07ef9ce 100644 +--- a/include/osgViewer/View ++++ b/include/osgViewer/View +@@ -127,7 +127,7 @@ class OSGVIEWER_EXPORT View : public osg::View, public osgGA::GUIActionAdapter + /** Set the View's image pager.*/ + void setImagePager(osgDB::ImagePager* ip); + +- template void setImagePager(const osg::ref_ptr* ip) { setImagePager(ip.get()); } ++ template void setImagePager(const osg::ref_ptr& ip) { setImagePager(ip.get()); } + + /** Get the View's image pager.*/ + osgDB::ImagePager* getImagePager(); diff --git a/make/3rdparty/osgearth/osg-3.5.3.patch b/make/3rdparty/osgearth/osg-3.5.3.patch new file mode 100644 index 000000000..df10de9d5 --- /dev/null +++ b/make/3rdparty/osgearth/osg-3.5.3.patch @@ -0,0 +1,13 @@ +diff --git a/src/osgPlugins/cfg/CMakeLists.txt b/src/osgPlugins/cfg/CMakeLists.txt +index 972675f..4f7062b 100644 +--- a/src/osgPlugins/cfg/CMakeLists.txt ++++ b/src/osgPlugins/cfg/CMakeLists.txt +@@ -20,7 +20,7 @@ SET(TARGET_H + + # lex/yacc generated files use register that causes warnings with CLang under OSX so disable this warnings. + IF(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") +- SET(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -Wno-deprecated-register) ++ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-register") + ENDIF() + + # diff --git a/make/3rdparty/osgearth/osgearth-2.7.patch b/make/3rdparty/osgearth/osgearth-2.7.patch new file mode 100644 index 000000000..d6ef84719 --- /dev/null +++ b/make/3rdparty/osgearth/osgearth-2.7.patch @@ -0,0 +1,66 @@ +diff --git a/src/osgEarth/ElevationQuery b/src/osgEarth/ElevationQuery +index d8e4d14..50db567 100644 +--- a/src/osgEarth/ElevationQuery ++++ b/src/osgEarth/ElevationQuery +@@ -37,7 +37,11 @@ namespace osgEarth + + void pruneUnusedDatabaseCache(); + ++#if OSG_VERSION_GREATER_OR_EQUAL(3,5,0) ++ virtual osg::ref_ptr readNodeFile(const std::string& filename); ++#else + virtual osg::Node* readNodeFile(const std::string& filename); ++#endif + + protected: + +diff --git a/src/osgEarth/ElevationQuery.cpp b/src/osgEarth/ElevationQuery.cpp +index 5fb8222..8c03309 100644 +--- a/src/osgEarth/ElevationQuery.cpp ++++ b/src/osgEarth/ElevationQuery.cpp +@@ -55,7 +55,11 @@ void ElevationQueryCacheReadCallback::pruneUnusedDatabaseCache() + { + } + ++#if OSG_VERSION_GREATER_OR_EQUAL(3,5,0) ++osg::ref_ptr ElevationQueryCacheReadCallback::readNodeFile(const std::string& filename) ++#else + osg::Node* ElevationQueryCacheReadCallback::readNodeFile(const std::string& filename) ++#endif + { + // first check to see if file is already loaded. + { +@@ -71,7 +75,7 @@ osg::Node* ElevationQueryCacheReadCallback::readNodeFile(const std::string& file + } + + // now load the file. +- osg::ref_ptr node = osgDB::readNodeFile(filename); ++ osg::ref_ptr node = osgDB::readRefNodeFile(filename); + + // insert into the cache. + if (node.valid()) +@@ -105,7 +109,11 @@ osg::Node* ElevationQueryCacheReadCallback::readNodeFile(const std::string& file + } + } + ++#if OSG_VERSION_GREATER_OR_EQUAL(3,5,0) ++ return node; ++#else + return node.release(); ++#endif + } + + ElevationQuery::ElevationQuery(const Map* map) : +diff --git a/src/osgEarthSymbology/Resource b/src/osgEarthSymbology/Resource +index a8a1441..934fc7d 100644 +--- a/src/osgEarthSymbology/Resource ++++ b/src/osgEarthSymbology/Resource +@@ -33,7 +33,7 @@ namespace osgEarth { namespace Symbology + class OSGEARTHSYMBOLOGY_EXPORT Resource : public Taggable + { + protected: +- Resource(const Resource& rhs,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) {}; ++ Resource(const Resource& rhs,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) : Taggable() {}; + Resource( const Config& config =Config() ); + + /** dtor */ diff --git a/make/3rdparty/osgearth/osgearth.mk b/make/3rdparty/osgearth/osgearth.mk new file mode 100644 index 000000000..44866e7d5 --- /dev/null +++ b/make/3rdparty/osgearth/osgearth.mk @@ -0,0 +1,292 @@ +################################ +# Targets to build osg and osgearth +# +################################ +# +# $ make all_osg +# +# This will: +# - clone the git repositories into the ./3rdparty directory +# - build osg in the build/3rdparty directory +# - intall osg in the build/3rdparty/install directory +# - create distribution files (tar.gz and md5) in the build/3rdparty/install directory +# - [TODO] upload distribution files to the librepilot tools repository +# +################################ + +################################ +# +# common stuff +# +################################ + +OSG_BUILD_CONF := Release + +OSG_NAME_PREFIX := +OSG_NAME_SUFIX := -qt-$(QT_VERSION) + +################################ +# +# osg +# +################################ + +OSG_VERSION := 3.5.3 +OSG_GIT_TAG := OpenSceneGraph-$(OSG_VERSION) + +OSG_BASE_NAME := osg-$(OSG_VERSION) + +ifeq ($(UNAME), Linux) + ifeq ($(ARCH), x86_64) + OSG_NAME := $(OSG_BASE_NAME)-linux-x64 + else + OSG_NAME := $(OSG_BASE_NAME)-linux-x86 + endif + OSG_CMAKE_GENERATOR := "Unix Makefiles" + OSG_CMAKE_MAKE_PROGRAM := make + OSG_WINDOWING_SYSTEM := "X11" + # for some reason Qt is not added to the path in make/tools.mk + OSG_BUILD_PATH := $(QT_SDK_PREFIX)/bin:$(PATH) +else ifeq ($(UNAME), Darwin) + OSG_NAME := $(OSG_BASE_NAME)-clang_64 + OSG_CMAKE_GENERATOR := "Unix Makefiles" + OSG_CMAKE_MAKE_PROGRAM := make + OSG_WINDOWING_SYSTEM := "Cocoa" + OSG_BUILD_PATH := $(QT_SDK_PREFIX)/bin:$(PATH) +else ifeq ($(UNAME), Windows) + OSG_NAME := $(OSG_BASE_NAME)-$(QT_SDK_ARCH) + OSG_CMAKE_GENERATOR := "MinGW Makefiles" +endif + +OSG_NAME := $(OSG_NAME_PREFIX)$(OSG_NAME)$(OSG_NAME_SUFIX) +OSG_SRC_DIR := $(ROOT_DIR)/3rdparty/osg +OSG_BUILD_DIR := $(BUILD_DIR)/3rdparty/$(OSG_NAME) +OSG_INSTALL_DIR := $(BUILD_DIR)/3rdparty/install/$(OSG_NAME) +OSG_PATCH_FILE := $(ROOT_DIR)/make/3rdparty/osgearth/osg-$(OSG_VERSION).patch + +.PHONY: osg +osg: + @$(ECHO) "Building osg $(call toprel, $(OSG_SRC_DIR)) into $(call toprel, $(OSG_BUILD_DIR))" + $(V1) $(MKDIR) -p $(OSG_BUILD_DIR) + $(V1) ( $(CD) $(OSG_BUILD_DIR) && \ + if [ -n "$(OSG_BUILD_PATH)" ]; then \ + PATH=$(OSG_BUILD_PATH) ; \ + fi ; \ + $(CMAKE) -G $(OSG_CMAKE_GENERATOR) -DCMAKE_BUILD_TYPE=$(OSG_BUILD_CONF) \ + -DCMAKE_MAKE_PROGRAM=$(MAKE) \ + -DOSG_USE_QT=ON \ + -DBUILD_OSG_APPLICATIONS=ON \ + -DBUILD_OSG_EXAMPLES=OFF \ + -DBUILD_OPENTHREADS_WITH_QT=OFF \ + -DOSG_GL3_AVAILABLE=OFF \ + -DOSG_PLUGIN_SEARCH_INSTALL_DIR_FOR_PLUGINS=OFF \ + -DCMAKE_OSX_ARCHITECTURES="x86_64" \ + -DOSG_WINDOWING_SYSTEM=$(OSG_WINDOWING_SYSTEM) \ + -DCMAKE_INSTALL_NAME_DIR=@executable_path/../Plugins \ + -DCMAKE_INSTALL_PREFIX=$(OSG_INSTALL_DIR) $(OSG_SRC_DIR) && \ + $(MAKE) && \ + $(MAKE) install ; \ + ) + +.PHONY: package_osg +package_osg: + @$(ECHO) "Packaging $(call toprel, $(OSG_INSTALL_DIR)) into $(notdir $(OSG_INSTALL_DIR)).tar" + #$(V1) $(CP) $(ROOT_DIR)/make/3rdparty/osgearth/LibrePilotReadme.txt $(OSG_INSTALL_DIR)/ + $(V1) ( \ + $(CD) $(OSG_INSTALL_DIR)/.. && \ + $(TAR) cf $(notdir $(OSG_INSTALL_DIR)).tar $(notdir $(OSG_INSTALL_DIR)) && \ + $(ZIP) -f $(notdir $(OSG_INSTALL_DIR)).tar && \ + $(call MD5_GEN_TEMPLATE,$(notdir $(OSG_INSTALL_DIR)).tar.gz) ; \ + ) + +.PHONY: install_win_osg +install_win_osg: + # curl + $(V1) $(CP) /mingw32/bin/libcurl-4.dll $(OSG_INSTALL_DIR)/bin/ + $(V1) $(CP) /mingw32/bin/libidn-11.dll $(OSG_INSTALL_DIR)/bin/ + $(V1) $(CP) /mingw32/bin/librtmp-1.dll $(OSG_INSTALL_DIR)/bin/ + $(V1) $(CP) /mingw32/bin/libgmp-10.dll $(OSG_INSTALL_DIR)/bin/ + $(V1) $(CP) /mingw32/bin/libgnutls-30.dll $(OSG_INSTALL_DIR)/bin/ + $(V1) $(CP) /mingw32/bin/libp11-kit-0.dll $(OSG_INSTALL_DIR)/bin/ + $(V1) $(CP) /mingw32/bin/libffi-6.dll $(OSG_INSTALL_DIR)/bin/ + $(V1) $(CP) /mingw32/bin/libtasn1-6.dll $(OSG_INSTALL_DIR)/bin/ + $(V1) $(CP) /mingw32/bin/libhogweed-4-1.dll $(OSG_INSTALL_DIR)/bin/ + $(V1) $(CP) /mingw32/bin/libnettle-6-1.dll $(OSG_INSTALL_DIR)/bin/ + $(V1) $(CP) /mingw32/bin/libssh2-1.dll $(OSG_INSTALL_DIR)/bin/ + # gdal + $(V1) $(CP) /mingw32/bin/libgdal-20.dll $(OSG_INSTALL_DIR)/bin/ + $(V1) $(CP) /mingw32/bin/libgeos_c.dll $(OSG_INSTALL_DIR)/bin/ + $(V1) $(CP) /mingw32/bin/libgeos.dll $(OSG_INSTALL_DIR)/bin/ + $(V1) $(CP) /mingw32/bin/libjpeg-8.dll $(OSG_INSTALL_DIR)/bin/ + $(V1) $(CP) /mingw32/bin/libtiff-5.dll $(OSG_INSTALL_DIR)/bin/ + $(V1) $(CP) /mingw32/bin/liblzma-5.dll $(OSG_INSTALL_DIR)/bin/ + $(V1) $(CP) /mingw32/bin/libiconv-2.dll $(OSG_INSTALL_DIR)/bin/ + $(V1) $(CP) /mingw32/bin/zlib1.dll $(OSG_INSTALL_DIR)/bin/ + # other + $(V1) $(CP) /mingw32/bin/libproj-9.dll $(OSG_INSTALL_DIR)/bin/ + $(V1) $(CP) /mingw32/bin/libfreetype-6.dll $(OSG_INSTALL_DIR)/bin/ + $(V1) $(CP) /mingw32/bin/libpng16-16.dll $(OSG_INSTALL_DIR)/bin/ + +.NOTPARALLEL: +.PHONY: prepare_osg +prepare_osg: clone_osg + +.PHONY: clone_osg +clone_osg: + $(V1) if [ -d "$(OSG_SRC_DIR)" ]; then \ + $(ECHO) "Deleting osg clone..." ; \ + $(RM) -rf $(OSG_SRC_DIR) ; \ + fi + @$(ECHO) "Cloning osg..." + $(V1) $(GIT) clone --depth 1 --no-checkout -b $(OSG_GIT_TAG) git://github.com/openscenegraph/osg.git $(OSG_SRC_DIR) + @$(ECHO) "Checkout osg $(OSG_GIT_TAG)" + $(V1) ( $(CD) $(OSG_SRC_DIR) && $(GIT) checkout --force tags/$(OSG_GIT_TAG) ; ) + $(V1) if [ -e $(OSG_PATCH_FILE) ]; then \ + $(ECHO) "Patching osg..." ; \ + ( $(CD) $(OSG_SRC_DIR) && $(GIT) apply $(OSG_PATCH_FILE) ; ) \ + fi + +.PHONY: clean_osg +clean_osg: + @$(ECHO) $(MSG_CLEANING) $(call toprel, $(OSG_BUILD_DIR)) + $(V1) [ ! -d "$(OSG_BUILD_DIR)" ] || $(RM) -r "$(OSG_BUILD_DIR)" + @$(ECHO) $(MSG_CLEANING) $(call toprel, $(OSG_INSTALL_DIR)) + $(V1) [ ! -d "$(OSG_INSTALL_DIR)" ] || $(RM) -r "$(OSG_INSTALL_DIR)" + +.PHONY: clean_all_osg +clean_all_osg: clean_osg + @$(ECHO) $(MSG_CLEANING) $(call toprel, $(OSG_SRC_DIR)) + $(V1) [ ! -d "$(OSG_SRC_DIR)" ] || $(RM) -r "$(OSG_SRC_DIR)" + + +################################ +# +# osgearth +# +################################ +# TODO +# fix Debug build +# add option to not build the applications (in Debug mode in particular) + +OSGEARTH_VERSION := 2.7 +OSGEARTH_GIT_TAG := osgearth-$(OSGEARTH_VERSION) + +OSGEARTH_BASE_NAME := osgearth-$(OSGEARTH_VERSION) +OSGEARTH_BUILD_CONF := $(OSG_BUILD_CONF) + +# osgearth cmake script calls the osgversion executable to find the osg version +# this makes it necessary to have osg in the path (bin and lib) to make sure the correct one is found +ifeq ($(UNAME), Linux) + ifeq ($(ARCH), x86_64) + OSGEARTH_NAME := $(OSGEARTH_BASE_NAME)-linux-x64 + else + OSGEARTH_NAME := $(OSGEARTH_BASE_NAME)-linux-x86 + endif + OSGEARTH_CMAKE_GENERATOR := "Unix Makefiles" + OSGEARTH_CMAKE_MAKE_PROGRAM := make + # for some reason Qt is not added to the path in make/tools.mk + OSGEARTH_BUILD_PATH := $(QT_SDK_PREFIX)/bin:$(OSG_INSTALL_DIR)/bin:$(PATH) + ifeq ($(ARCH), x86_64) + OSGEARTH_LIB_PATH := $(OSG_INSTALL_DIR)/lib64 + else + OSGEARTH_LIB_PATH := $(OSG_INSTALL_DIR)/lib + endif +else ifeq ($(UNAME), Darwin) + OSGEARTH_NAME := $(OSGEARTH_BASE_NAME)-clang_64 + OSGEARTH_CMAKE_GENERATOR := "Unix Makefiles" + OSGEARTH_CMAKE_MAKE_PROGRAM := make + OSGEARTH_BUILD_PATH := $(QT_SDK_PREFIX)/bin:$(OSG_INSTALL_DIR)/bin:$(PATH) + OSGEARTH_LIB_PATH := $(OSG_INSTALL_DIR)/lib +else ifeq ($(UNAME), Windows) + OSGEARTH_NAME := $(OSGEARTH_BASE_NAME)-$(QT_SDK_ARCH) + OSGEARTH_CMAKE_GENERATOR := "MinGW Makefiles" + OSGEARTH_LIB_PATH := $(OSG_INSTALL_DIR)/lib +endif + +OSGEARTH_NAME := $(OSG_NAME_PREFIX)$(OSGEARTH_NAME)$(OSG_NAME_SUFIX) +OSGEARTH_SRC_DIR := $(ROOT_DIR)/3rdparty/osgearth +OSGEARTH_BUILD_DIR := $(BUILD_DIR)/3rdparty/$(OSGEARTH_NAME) +OSGEARTH_INSTALL_DIR := $(BUILD_DIR)/3rdparty/install/$(OSGEARTH_NAME) +OSGEARTH_PATCH_FILE := $(ROOT_DIR)/make/3rdparty/osgearth/osgearth-$(OSGEARTH_VERSION).patch + +.PHONY: osgearth +osgearth: + @$(ECHO) "Building osgEarth $(call toprel, $(OSGEARTH_SRC_DIR)) into $(call toprel, $(OSGEARTH_BUILD_DIR))" + $(V1) $(MKDIR) -p $(OSGEARTH_BUILD_DIR) + $(V1) ( $(CD) $(OSGEARTH_BUILD_DIR) && \ + if [ -n "$(OSGEARTH_BUILD_PATH)" ]; then \ + PATH=$(OSGEARTH_BUILD_PATH) ; \ + fi ; \ + LD_LIBRARY_PATH=$(OSGEARTH_LIB_PATH) && \ + export DYLD_LIBRARY_PATH=$(OSGEARTH_LIB_PATH) && \ + unset OSG_NOTIFY_LEVEL && \ + $(CMAKE) -G $(OSGEARTH_CMAKE_GENERATOR) -DCMAKE_BUILD_TYPE=$(OSGEARTH_BUILD_CONF) \ + -DCMAKE_MAKE_PROGRAM=$(MAKE) \ + -DOSGEARTH_USE_QT=ON \ + -DINSTALL_TO_OSG_DIR=OFF \ + -DOSG_DIR=$(OSG_INSTALL_DIR) \ + -DCMAKE_INCLUDE_PATH=$(OSG_INSTALL_DIR)/include \ + -DCMAKE_LIBRARY_PATH=$(OSGEARTH_LIB_PATH) \ + -DCMAKE_PREFIX_PATH=$(OSGEARTH_LIB_PATH) \ + -DCMAKE_OSX_ARCHITECTURES="x86_64" \ + -DCMAKE_INSTALL_NAME_DIR=@executable_path/../Plugins \ + -DCMAKE_INSTALL_PREFIX=$(OSGEARTH_INSTALL_DIR) $(OSGEARTH_SRC_DIR) && \ + $(MAKE) && \ + $(MAKE) install ; \ + ) + +.PHONY: package_osgearth +package_osgearth: + @$(ECHO) "Packaging $(call toprel, $(OSGEARTH_INSTALL_DIR)) into $(notdir $(OSGEARTH_INSTALL_DIR)).tar" + $(V1) ( \ + $(CD) $(OSGEARTH_INSTALL_DIR)/.. && \ + $(TAR) cf $(notdir $(OSGEARTH_INSTALL_DIR)).tar $(notdir $(OSGEARTH_INSTALL_DIR)) && \ + $(ZIP) -f $(notdir $(OSGEARTH_INSTALL_DIR)).tar && \ + $(call MD5_GEN_TEMPLATE,$(notdir $(OSGEARTH_INSTALL_DIR)).tar.gz) ; \ + ) + +.NOTPARALLEL: +.PHONY: prepare_osgearth +prepare_osgearth: clone_osgearth + +.PHONY: clone_osgearth +clone_osgearth: + $(V1) if [ -d "$(OSGEARTH_SRC_DIR)" ]; then \ + $(ECHO) "Deleting osgearth clone..." ; \ + $(RM) -rf $(OSGEARTH_SRC_DIR) ; \ + fi + @$(ECHO) "Cloning osgearth..." + $(V1) $(GIT) clone --depth 1 --no-checkout -b $(OSGEARTH_GIT_TAG) git://github.com/gwaldron/osgearth.git $(OSGEARTH_SRC_DIR) + @$(ECHO) "Checkout osgearth $(OSGEARTH_GIT_TAG)" + $(V1) ( $(CD) $(OSGEARTH_SRC_DIR) && $(GIT) checkout --force tags/$(OSGEARTH_GIT_TAG) ; ) + $(V1) if [ -e $(OSGEARTH_PATCH_FILE) ]; then \ + $(ECHO) "Patching osgearth..." ; \ + ( $(CD) $(OSGEARTH_SRC_DIR) && $(GIT) apply $(OSGEARTH_PATCH_FILE) ; ) \ + fi + +.PHONY: clean_osgearth +clean_osgearth: + @$(ECHO) $(MSG_CLEANING) $(call toprel, $(OSGEARTH_BUILD_DIR)) + $(V1) [ ! -d "$(OSGEARTH_BUILD_DIR)" ] || $(RM) -r "$(OSGEARTH_BUILD_DIR)" + @$(ECHO) $(MSG_CLEANING) $(call toprel, $(OSGEARTH_INSTALL_DIR)) + $(V1) [ ! -d "$(OSGEARTH_INSTALL_DIR)" ] || $(RM) -r "$(OSGEARTH_INSTALL_DIR)" + +.PHONY: clean_all_osgearth +clean_all_osgearth: clean_osgearth + @$(ECHO) $(MSG_CLEANING) $(call toprel, $(OSGEARTH_SRC_DIR)) + $(V1) [ ! -d "$(OSGEARTH_SRC_DIR)" ] || $(RM) -r "$(OSGEARTH_SRC_DIR)" + +################################ +# +# all +# +################################ + +.NOTPARALLEL: +.PHONY: all_osg + +ifeq ($(UNAME), Windows) +all_osg: prepare_osg prepare_osgearth osg osgearth install_win_osg package_osg package_osgearth +else +all_osg: prepare_osg prepare_osgearth osg osgearth package_osg package_osgearth +endif diff --git a/make/doxygen/Doxyfile.ground b/make/doxygen/Doxyfile.ground index 8009ac9c0..d2188073e 100644 --- a/make/doxygen/Doxyfile.ground +++ b/make/doxygen/Doxyfile.ground @@ -1330,7 +1330,7 @@ PAPER_TYPE = a4 # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. -EXTRA_PACKAGES = +EXTRA_PACKAGES = amsmath, amssymb # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until diff --git a/make/functions.mk b/make/functions.mk index 5b39e23b5..ff54375cf 100644 --- a/make/functions.mk +++ b/make/functions.mk @@ -16,6 +16,21 @@ # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # +# Make sure we know few things about the architecture before including +# the tools.mk to ensure that we download/install the right tools. +UNAME := $(shell uname) +# Here and everywhere if not Linux or Mac then assume Windows +ifeq ($(filter Linux Darwin, $(UNAME)), ) + UNAME := Windows + CC := gcc# because cc doesn't exist +endif + +ifeq ($(UNAME),Windows) + system_path = $(shell cygpath -w $(1)) +else + system_path = $(1) +endif + # Function for converting Windows style slashes into Unix style slashfix = $(subst \,/,$(1)) @@ -36,3 +51,4 @@ endef smallify = $(subst $(SPACE),-,$(call lc,$1)) +get_arch = $(shell $(CC) -dumpmachine | sed s/-.*//) diff --git a/make/scripts/asan_symbolize.py b/make/scripts/asan_symbolize.py new file mode 100755 index 000000000..8e6fb61f7 --- /dev/null +++ b/make/scripts/asan_symbolize.py @@ -0,0 +1,490 @@ +#!/usr/bin/env python +#===- lib/asan/scripts/asan_symbolize.py -----------------------------------===# +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +#===------------------------------------------------------------------------===# +import argparse +import bisect +import getopt +import os +import re +import subprocess +import sys + +symbolizers = {} +DEBUG = False +demangle = False +binutils_prefix = None +sysroot_path = None +binary_name_filter = None +fix_filename_patterns = None +logfile = sys.stdin +allow_system_symbolizer = True + +# FIXME: merge the code that calls fix_filename(). +def fix_filename(file_name): + if fix_filename_patterns: + for path_to_cut in fix_filename_patterns: + file_name = re.sub('.*' + path_to_cut, '', file_name) + file_name = re.sub('.*asan_[a-z_]*.cc:[0-9]*', '_asan_rtl_', file_name) + file_name = re.sub('.*crtstuff.c:0', '???:0', file_name) + return file_name + +def sysroot_path_filter(binary_name): + return sysroot_path + binary_name + +def guess_arch(addr): + # Guess which arch we're running. 10 = len('0x') + 8 hex digits. + if len(addr) > 10: + return 'x86_64' + else: + return 'i386' + +class Symbolizer(object): + def __init__(self): + pass + + def symbolize(self, addr, binary, offset): + """Symbolize the given address (pair of binary and offset). + + Overriden in subclasses. + Args: + addr: virtual address of an instruction. + binary: path to executable/shared object containing this instruction. + offset: instruction offset in the @binary. + Returns: + list of strings (one string for each inlined frame) describing + the code locations for this instruction (that is, function name, file + name, line and column numbers). + """ + return None + + +class LLVMSymbolizer(Symbolizer): + def __init__(self, symbolizer_path, default_arch, system, dsym_hints=[]): + super(LLVMSymbolizer, self).__init__() + self.symbolizer_path = symbolizer_path + self.default_arch = default_arch + self.system = system + self.dsym_hints = dsym_hints + self.pipe = self.open_llvm_symbolizer() + + def open_llvm_symbolizer(self): + cmd = [self.symbolizer_path, + '--use-symbol-table=true', + '--demangle=%s' % demangle, + '--functions=linkage', + '--inlining=true', + '--default-arch=%s' % self.default_arch] + if self.system == 'Darwin': + for hint in self.dsym_hints: + cmd.append('--dsym-hint=%s' % hint) + if DEBUG: + print ' '.join(cmd) + try: + result = subprocess.Popen(cmd, stdin=subprocess.PIPE, + stdout=subprocess.PIPE) + except OSError: + result = None + return result + + def symbolize(self, addr, binary, offset): + """Overrides Symbolizer.symbolize.""" + if not self.pipe: + return None + result = [] + try: + symbolizer_input = '"%s" %s' % (binary, offset) + if DEBUG: + print symbolizer_input + print >> self.pipe.stdin, symbolizer_input + while True: + function_name = self.pipe.stdout.readline().rstrip() + if not function_name: + break + file_name = self.pipe.stdout.readline().rstrip() + file_name = fix_filename(file_name) + if (not function_name.startswith('??') or + not file_name.startswith('??')): + # Append only non-trivial frames. + result.append('%s in %s %s' % (addr, function_name, + file_name)) + except Exception: + result = [] + if not result: + result = None + return result + + +def LLVMSymbolizerFactory(system, default_arch, dsym_hints=[]): + symbolizer_path = os.getenv('LLVM_SYMBOLIZER_PATH') + if not symbolizer_path: + symbolizer_path = os.getenv('ASAN_SYMBOLIZER_PATH') + if not symbolizer_path: + # Assume llvm-symbolizer is in PATH. + symbolizer_path = 'llvm-symbolizer' + return LLVMSymbolizer(symbolizer_path, default_arch, system, dsym_hints) + + +class Addr2LineSymbolizer(Symbolizer): + def __init__(self, binary): + super(Addr2LineSymbolizer, self).__init__() + self.binary = binary + self.pipe = self.open_addr2line() + self.output_terminator = -1 + + def open_addr2line(self): + addr2line_tool = 'addr2line' + if binutils_prefix: + addr2line_tool = binutils_prefix + addr2line_tool + cmd = [addr2line_tool, '-fi'] + if demangle: + cmd += ['--demangle'] + cmd += ['-e', self.binary] + if DEBUG: + print ' '.join(cmd) + return subprocess.Popen(cmd, + stdin=subprocess.PIPE, stdout=subprocess.PIPE) + + def symbolize(self, addr, binary, offset): + """Overrides Symbolizer.symbolize.""" + if self.binary != binary: + return None + lines = [] + try: + print >> self.pipe.stdin, offset + print >> self.pipe.stdin, self.output_terminator + is_first_frame = True + while True: + function_name = self.pipe.stdout.readline().rstrip() + file_name = self.pipe.stdout.readline().rstrip() + if is_first_frame: + is_first_frame = False + elif function_name in ['', '??']: + assert file_name == function_name + break + lines.append((function_name, file_name)); + except Exception: + lines.append(('??', '??:0')) + return ['%s in %s %s' % (addr, function, fix_filename(file)) for (function, file) in lines] + +class UnbufferedLineConverter(object): + """ + Wrap a child process that responds to each line of input with one line of + output. Uses pty to trick the child into providing unbuffered output. + """ + def __init__(self, args, close_stderr=False): + # Local imports so that the script can start on Windows. + import pty + import termios + pid, fd = pty.fork() + if pid == 0: + # We're the child. Transfer control to command. + if close_stderr: + dev_null = os.open('/dev/null', 0) + os.dup2(dev_null, 2) + os.execvp(args[0], args) + else: + # Disable echoing. + attr = termios.tcgetattr(fd) + attr[3] = attr[3] & ~termios.ECHO + termios.tcsetattr(fd, termios.TCSANOW, attr) + # Set up a file()-like interface to the child process + self.r = os.fdopen(fd, "r", 1) + self.w = os.fdopen(os.dup(fd), "w", 1) + + def convert(self, line): + self.w.write(line + "\n") + return self.readline() + + def readline(self): + return self.r.readline().rstrip() + + +class DarwinSymbolizer(Symbolizer): + def __init__(self, addr, binary): + super(DarwinSymbolizer, self).__init__() + self.binary = binary + self.arch = guess_arch(addr) + self.open_atos() + + def open_atos(self): + if DEBUG: + print 'atos -o %s -arch %s' % (self.binary, self.arch) + cmdline = ['atos', '-o', self.binary, '-arch', self.arch] + self.atos = UnbufferedLineConverter(cmdline, close_stderr=True) + + def symbolize(self, addr, binary, offset): + """Overrides Symbolizer.symbolize.""" + if self.binary != binary: + return None + atos_line = self.atos.convert('0x%x' % int(offset, 16)) + while "got symbolicator for" in atos_line: + atos_line = self.atos.readline() + # A well-formed atos response looks like this: + # foo(type1, type2) (in object.name) (filename.cc:80) + match = re.match('^(.*) \(in (.*)\) \((.*:\d*)\)$', atos_line) + if DEBUG: + print 'atos_line: ', atos_line + if match: + function_name = match.group(1) + function_name = re.sub('\(.*?\)', '', function_name) + file_name = fix_filename(match.group(3)) + return ['%s in %s %s' % (addr, function_name, file_name)] + else: + return ['%s in %s' % (addr, atos_line)] + + +# Chain several symbolizers so that if one symbolizer fails, we fall back +# to the next symbolizer in chain. +class ChainSymbolizer(Symbolizer): + def __init__(self, symbolizer_list): + super(ChainSymbolizer, self).__init__() + self.symbolizer_list = symbolizer_list + + def symbolize(self, addr, binary, offset): + """Overrides Symbolizer.symbolize.""" + for symbolizer in self.symbolizer_list: + if symbolizer: + result = symbolizer.symbolize(addr, binary, offset) + if result: + return result + return None + + def append_symbolizer(self, symbolizer): + self.symbolizer_list.append(symbolizer) + + +def BreakpadSymbolizerFactory(binary): + suffix = os.getenv('BREAKPAD_SUFFIX') + if suffix: + filename = binary + suffix + if os.access(filename, os.F_OK): + return BreakpadSymbolizer(filename) + return None + + +def SystemSymbolizerFactory(system, addr, binary): + if system == 'Darwin': + return DarwinSymbolizer(addr, binary) + elif system == 'Linux' or system == 'FreeBSD': + return Addr2LineSymbolizer(binary) + + +class BreakpadSymbolizer(Symbolizer): + def __init__(self, filename): + super(BreakpadSymbolizer, self).__init__() + self.filename = filename + lines = file(filename).readlines() + self.files = [] + self.symbols = {} + self.address_list = [] + self.addresses = {} + # MODULE mac x86_64 A7001116478B33F18FF9BEDE9F615F190 t + fragments = lines[0].rstrip().split() + self.arch = fragments[2] + self.debug_id = fragments[3] + self.binary = ' '.join(fragments[4:]) + self.parse_lines(lines[1:]) + + def parse_lines(self, lines): + cur_function_addr = '' + for line in lines: + fragments = line.split() + if fragments[0] == 'FILE': + assert int(fragments[1]) == len(self.files) + self.files.append(' '.join(fragments[2:])) + elif fragments[0] == 'PUBLIC': + self.symbols[int(fragments[1], 16)] = ' '.join(fragments[3:]) + elif fragments[0] in ['CFI', 'STACK']: + pass + elif fragments[0] == 'FUNC': + cur_function_addr = int(fragments[1], 16) + if not cur_function_addr in self.symbols.keys(): + self.symbols[cur_function_addr] = ' '.join(fragments[4:]) + else: + # Line starting with an address. + addr = int(fragments[0], 16) + self.address_list.append(addr) + # Tuple of symbol address, size, line, file number. + self.addresses[addr] = (cur_function_addr, + int(fragments[1], 16), + int(fragments[2]), + int(fragments[3])) + self.address_list.sort() + + def get_sym_file_line(self, addr): + key = None + if addr in self.addresses.keys(): + key = addr + else: + index = bisect.bisect_left(self.address_list, addr) + if index == 0: + return None + else: + key = self.address_list[index - 1] + sym_id, size, line_no, file_no = self.addresses[key] + symbol = self.symbols[sym_id] + filename = self.files[file_no] + if addr < key + size: + return symbol, filename, line_no + else: + return None + + def symbolize(self, addr, binary, offset): + if self.binary != binary: + return None + res = self.get_sym_file_line(int(offset, 16)) + if res: + function_name, file_name, line_no = res + result = ['%s in %s %s:%d' % ( + addr, function_name, file_name, line_no)] + print result + return result + else: + return None + + +class SymbolizationLoop(object): + def __init__(self, binary_name_filter=None, dsym_hint_producer=None): + if sys.platform == 'win32': + # ASan on Windows uses dbghelp.dll to symbolize in-process, which works + # even in sandboxed processes. Nothing needs to be done here. + self.process_line = self.process_line_echo + else: + # Used by clients who may want to supply a different binary name. + # E.g. in Chrome several binaries may share a single .dSYM. + self.binary_name_filter = binary_name_filter + self.dsym_hint_producer = dsym_hint_producer + self.system = os.uname()[0] + if self.system not in ['Linux', 'Darwin', 'FreeBSD']: + raise Exception('Unknown system') + self.llvm_symbolizers = {} + self.last_llvm_symbolizer = None + self.dsym_hints = set([]) + self.frame_no = 0 + self.process_line = self.process_line_posix + + def symbolize_address(self, addr, binary, offset): + # On non-Darwin (i.e. on platforms without .dSYM debug info) always use + # a single symbolizer binary. + # On Darwin, if the dsym hint producer is present: + # 1. check whether we've seen this binary already; if so, + # use |llvm_symbolizers[binary]|, which has already loaded the debug + # info for this binary (might not be the case for + # |last_llvm_symbolizer|); + # 2. otherwise check if we've seen all the hints for this binary already; + # if so, reuse |last_llvm_symbolizer| which has the full set of hints; + # 3. otherwise create a new symbolizer and pass all currently known + # .dSYM hints to it. + if not binary in self.llvm_symbolizers: + use_new_symbolizer = True + if self.system == 'Darwin' and self.dsym_hint_producer: + dsym_hints_for_binary = set(self.dsym_hint_producer(binary)) + use_new_symbolizer = bool(dsym_hints_for_binary - self.dsym_hints) + self.dsym_hints |= dsym_hints_for_binary + if self.last_llvm_symbolizer and not use_new_symbolizer: + self.llvm_symbolizers[binary] = self.last_llvm_symbolizer + else: + self.last_llvm_symbolizer = LLVMSymbolizerFactory( + self.system, guess_arch(addr), self.dsym_hints) + self.llvm_symbolizers[binary] = self.last_llvm_symbolizer + # Use the chain of symbolizers: + # Breakpad symbolizer -> LLVM symbolizer -> addr2line/atos + # (fall back to next symbolizer if the previous one fails). + if not binary in symbolizers: + symbolizers[binary] = ChainSymbolizer( + [BreakpadSymbolizerFactory(binary), self.llvm_symbolizers[binary]]) + result = symbolizers[binary].symbolize(addr, binary, offset) + if result is None: + if not allow_system_symbolizer: + raise Exception('Failed to launch or use llvm-symbolizer.') + # Initialize system symbolizer only if other symbolizers failed. + symbolizers[binary].append_symbolizer( + SystemSymbolizerFactory(self.system, addr, binary)) + result = symbolizers[binary].symbolize(addr, binary, offset) + # The system symbolizer must produce some result. + assert result + return result + + def get_symbolized_lines(self, symbolized_lines): + if not symbolized_lines: + return [self.current_line] + else: + result = [] + for symbolized_frame in symbolized_lines: + result.append(' #%s %s' % (str(self.frame_no), symbolized_frame.rstrip())) + self.frame_no += 1 + return result + + def process_logfile(self): + self.frame_no = 0 + for line in logfile: + processed = self.process_line(line) + print '\n'.join(processed) + + def process_line_echo(self, line): + return [line.rstrip()] + + def process_line_posix(self, line): + self.current_line = line.rstrip() + #0 0x7f6e35cf2e45 (/blah/foo.so+0x11fe45) + stack_trace_line_format = ( + '^( *#([0-9]+) *)(0x[0-9a-f]+) *\((.*)\+(0x[0-9a-f]+)\)') + match = re.match(stack_trace_line_format, line) + if not match: + return [self.current_line] + if DEBUG: + print line + _, frameno_str, addr, binary, offset = match.groups() + if frameno_str == '0': + # Assume that frame #0 is the first frame of new stack trace. + self.frame_no = 0 + original_binary = binary + if self.binary_name_filter: + binary = self.binary_name_filter(binary) + symbolized_line = self.symbolize_address(addr, binary, offset) + if not symbolized_line: + if original_binary != binary: + symbolized_line = self.symbolize_address(addr, binary, offset) + return self.get_symbolized_lines(symbolized_line) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + formatter_class=argparse.RawDescriptionHelpFormatter, + description='ASan symbolization script', + epilog='Example of use:\n' + 'asan_symbolize.py -c "$HOME/opt/cross/bin/arm-linux-gnueabi-" ' + '-s "$HOME/SymbolFiles" < asan.log') + parser.add_argument('path_to_cut', nargs='*', + help='pattern to be cut from the result file path ') + parser.add_argument('-d','--demangle', action='store_true', + help='demangle function names') + parser.add_argument('-s', metavar='SYSROOT', + help='set path to sysroot for sanitized binaries') + parser.add_argument('-c', metavar='CROSS_COMPILE', + help='set prefix for binutils') + parser.add_argument('-l','--logfile', default=sys.stdin, + type=argparse.FileType('r'), + help='set log file name to parse, default is stdin') + args = parser.parse_args() + if args.path_to_cut: + fix_filename_patterns = args.path_to_cut + if args.demangle: + demangle = True + if args.s: + binary_name_filter = sysroot_path_filter + sysroot_path = args.s + if args.c: + binutils_prefix = args.c + if args.logfile: + logfile = args.logfile + else: + logfile = sys.stdin + loop = SymbolizationLoop(binary_name_filter) + loop.process_logfile() diff --git a/make/scripts/version-info.py b/make/scripts/version-info.py index 140ec7c85..a06e96b21 100644 --- a/make/scripts/version-info.py +++ b/make/scripts/version-info.py @@ -195,6 +195,25 @@ class Repo: except: return None + def version_four_num(self): + """Return package version in format X.X.X.X using only numbers""" + + try: + (release, junk, candidate) = self._last_tag.partition("-RC") + (year, dot, month_and_patch) = release.partition(".") + (month, dot, patch) = month_and_patch.partition(".") + + if candidate == "": + candidate = "64" # Need to stay below 65536 for last part + + if patch == "": + patch = "0" + + return "{}.{}.{}.{}{:0>3.3}".format(year,month,patch,candidate,self._num_commits_past_tag) + except: + return None + + def revision(self): """Return full revison string (tag if defined, or branch:hash date time if no tag)""" try: @@ -233,8 +252,29 @@ class Repo: json_data['dirty'] = False json_path = os.path.join(path, 'version-info.json') - with open(json_path, 'w') as json_file: - json.dump(json_data, json_file) + + write_if_different(json_path, json.dumps(json_data)) + + +def write_if_different(out_name, out): + """Write ouput to file only if it differs from current""" + + # Check if output file already exists + try: + of = open(out_name, "rb") + except IOError: + # No file - create new + of = open(out_name, "wb") + of.write(out) + of.close() + else: + # File exists - overwite only if content is different + inp = of.read() + of.close() + if inp != out: + of = open(out_name, "wb") + of.write(out) + of.close() def escape_dict(dictionary): """Escapes dictionary values for C""" @@ -281,22 +321,8 @@ def file_from_template(tpl_name, out_name, dictionary): # Replace placeholders using dictionary out = Template(tpl).substitute(dictionary) - # Check if output file already exists - try: - of = open(out_name, "rb") - except IOError: - # No file - create new - of = open(out_name, "wb") - of.write(out) - of.close() - else: - # File exists - overwite only if content is different - inp = of.read() - of.close() - if inp != out: - of = open(out_name, "wb") - of.write(out) - of.close() + write_if_different(out_name, out) + def sha1(file): """Provides C source representation of sha1 sum of file""" @@ -340,30 +366,31 @@ def get_hash_of_dirs(directory, verbose = 0, raw = 0, n = 40): files.sort() for names in files: - if verbose == 1: - print 'Hashing', names - filepath = os.path.join(root, names) - try: - f1 = open(filepath, 'rU') - except: - # You can't open the file for some reason - continue + if names.endswith('.xml'): + if verbose == 1: + print 'Hashing', names + filepath = os.path.join(root, names) + try: + f1 = open(filepath, 'rU') + except: + # You can't open the file for some reason + continue - # Compute file hash. Same as running "sha1sum ". - f1hash = hashlib.sha1() - while 1: - # Read file in as little chunks - buf = f1.read(4096) - if not buf: - break - f1hash.update(buf) - f1.close() + # Compute file hash. Same as running "sha1sum ". + f1hash = hashlib.sha1() + while 1: + # Read file in as little chunks + buf = f1.read(4096) + if not buf: + break + f1hash.update(buf) + f1.close() - if verbose == 1: - print 'Hash is', f1hash.hexdigest() + if verbose == 1: + print 'Hash is', f1hash.hexdigest() - # Append the hex representation of the current file's hash into the cumulative hash - SHAhash.update(f1hash.hexdigest()) + # Append the hex representation of the current file's hash into the cumulative hash + SHAhash.update(f1hash.hexdigest()) except: import traceback @@ -463,6 +490,7 @@ string given. TAG_OR_BRANCH = r.tag(r.branch('unreleased')), TAG_OR_HASH8 = r.tag(r.hash(8, 'untagged')), LABEL = r.label(), + VERSION_FOUR_NUM = r.version_four_num(), REVISION = r.revision(), DIRTY = r.dirty(), FWTAG = xtrim(r.tag(r.branch('unreleased')), r.dirty(), 25), diff --git a/make/tool_install/qt-install.qs b/make/tool_install/qt-install.qs new file mode 100644 index 000000000..4e98de846 --- /dev/null +++ b/make/tool_install/qt-install.qs @@ -0,0 +1,252 @@ +/* +silent installer script + +known to work with Qt 5.6.0 and QtIFW 2.1.0 + +known issues: +- silent but not headless (QtIFW 2.1.0 should support gui.setSilent(true)) +- cannot disable forced components (QtCreator, ...) + - cannot disable virtual components (doc, examples, ...) + - cannot disable shortcuts creation + - if user presses the 'Show Details' button then the installer does not end automatically +*/ +function Controller() +{ + console.log("*** Silent Installer ***"); + console.log("Installing on " + installer.value("os")); + + var qtInstallTargetDir = installer.environmentVariable("QT_INSTALL_TARGET_DIR"); + if (qtInstallTargetDir == "") { + qtInstallTargetDir = installer.environmentVariable("PWD") + "/tools/qt-5.6.0"; + console.log("Environment variable QT_INSTALL_TARGET_DIR not set, using default " + qtInstallTargetDir); + } + installer.setValue("TargetDir", qtInstallTargetDir); + console.log("Installing to " + installer.value("TargetDir")); + + installer.autoRejectMessageBoxes(); + installer.setMessageBoxAutomaticAnswer("OverwriteTargetDirectory", QMessageBox.Yes); + installer.setMessageBoxAutomaticAnswer("stopProcessesForUpdates", QMessageBox.Ignore); + + // pages that are not visible are actually removed from the wizard + // some pages must not be removed otherwise the installer starts to mishbehave + installer.setDefaultPageVisible(QInstaller.Welcome, false); + installer.setDefaultPageVisible(QInstaller.Credentials, false); // QInstaller.Credentials is 0... so this is a NOP! + //installer.setDefaultPageVisible(QInstaller.Introduction, false); // Fails to skip Credentials if Introduction is removed? + installer.setDefaultPageVisible(QInstaller.TargetDirectory, false); + //installer.setDefaultPageVisible(QInstaller.ComponentSelection, false); + //installer.setDefaultPageVisible(QInstaller.LicenseAgreementCheck, false); + //installer.setDefaultPageVisible(QInstaller.StartMenuSelection, false); + installer.setDefaultPageVisible(QInstaller.ReadyForInstallation, false); + //installer.setDefaultPageVisible(QInstaller.PerformInstallation, false); + installer.setDefaultPageVisible(QInstaller.FinishedPage, false); + + installer.componentAdded.connect(onComponentAdded); + installer.aboutCalculateComponentsToInstall.connect(onAboutCalculateComponentsToInstall); + installer.finishedCalculateComponentsToInstall.connect(onFinishedCalculateComponentsToInstall); +} + +// installer callbacks + +onComponentAdded = function(component) +{ + console.log("Component added: " + component.name); + dumpComponents(); +} + +onAboutCalculateComponentsToInstall = function() +{ + console.log("onAboutCalculateComponentsToInstall"); + //dumpComponents(); +} + +onFinishedCalculateComponentsToInstall = function() +{ + console.log("onFinishedCalculateComponentsToInstall"); + //dumpComponents(); +} + +// page callbacks +// used to setup wizard pages and move the wizard forward + +Controller.prototype.WelcomePageCallback = function() +{ + logCallback(); + + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.CredentialsPageCallback = function() +{ + logCallback(); + + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.IntroductionPageCallback = function() +{ + logCallback(); + + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.ComponentSelectionPageCallback = function() +{ + logCallback(); + + var page = gui.currentPageWidget(); + page.deselectAll() + if (installer.value("os") == "win") { + selectComponent(page, "qt.56.win32_mingw492"); + selectComponent(page, "qt.tools.win32_mingw492"); + } + else if (installer.value("os") == "x11") { + selectComponent(page, "qt.56.gcc"); + selectComponent(page, "qt.56.gcc_64"); + } + else if (installer.value("os") == "mac") { + selectComponent(page, "qt.56.clang_64"); + } + selectComponent(page, "qt.56.qtquickcontrols"); + selectComponent(page, "qt.56.qtscript"); + + //installer.componentByName("qt.tools.qtcreator").setValue("ForcedInstallation", "false"); + + gui.clickButton(buttons.NextButton); +} + + +function selectComponent(page, name) +{ + component = installer.componentByName(name); + if (component) { + console.log("component " + name + " : " + component); + page.selectComponent(name); + } + else { + console.log("Failed to find component " + name + "!"); + } +} + +Controller.prototype.LicenseAgreementPageCallback = function() +{ + logCallback(); + + setChecked("AcceptLicenseRadioButton", true); + + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.StartMenuDirectoryPageCallback = function() +{ + logCallback(); + + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.PerformInstallationPageCallback = function() +{ + logCallback(); + + // show details and hide button + click("DetailsButton"); + setVisible("DetailsButton", false); + + // showing details will disable automated page switch, so re-enable it + installer.setAutomatedPageSwitchEnabled(true); +} + +Controller.prototype.FinishedPageCallback = function() +{ + logCallback(); + + setChecked("launchQtCreatorCheckBox", false); + + gui.clickButton(buttons.FinishButton); +} + +// utilities + +function logCallback() +{ + var page = gui.currentPageWidget(); + console.log(">>> " + page.objectName + "Callback"); +} + +function dumpComponents() +{ + dumpComponentsArray(installer.components()); +} + +function dumpComponentsArray(components) +{ + var arrayLength = components.length; + for (var i = 0; i < arrayLength; i++) { + dumpComponent(components[i]); + } +} + +function dumpComponent(component) +{ + console.log(component.name + " (" + component.displayName + ")"); + console.log(" Virtual: " + component.value("Virtual", "false")); + console.log(" ForcedInstallation: " + component.value("ForcedInstallation", "false")); + console.log(" Default: " + component.default); + console.log(" Enabled: " + component.enabled); +} + +// UI utilities + +function click(name) +{ + var page = gui.currentPageWidget(); + var button = gui.findChild(page, name); + if (button) { + console.log("button " + name + " : " + button); + button.click(); + } + else { + console.log("Failed to find button " + name + "!"); + } +} + +function setVisible(name, visible) +{ + var page = gui.currentPageWidget(); + var button = gui.findChild(page, name); + if (button) { + console.log("button " + name + " : " + button); + button.visible = visible; + console.log("button " + name + " visible : " + button.visible); + } + else { + console.log("Failed to find button " + name + "!"); + } +} + +function setEnabled(name, enabled) +{ + var page = gui.currentPageWidget(); + var button = gui.findChild(page, name); + if (button) { + console.log("button " + name + " : " + button); + button.enabled = enabled; + console.log("button " + name + " enabled : " + button.enabled); + } + else { + console.log("Failed to find button " + name + "!"); + } +} + +function setChecked(name, checked) +{ + var page = gui.currentPageWidget(); + var button = gui.findChild(page, name); + if (button) { + console.log("button " + name + " : " + button); + button.checked = checked; + console.log("button " + name + " checked : " + button.checked); + } + else { + console.log("Failed to find button " + name + "!"); + } +} diff --git a/make/tools.mk b/make/tools.mk index ea5ee97a9..ecf0462e0 100644 --- a/make/tools.mk +++ b/make/tools.mk @@ -11,8 +11,6 @@ # arm_sdk_install # qt_sdk_install # nsis_install (Windows only) -# sdl_install (Windows only) -# openssl_install (Windows only) # mesawin_install (Windows only) # uncrustify_install # doxygen_install @@ -86,90 +84,90 @@ $(TOOL_REMOVE_TARGETS): # ############################## +TOOLS_URL := http://librepilot.github.io/tools + +QT_SHORT_VERSION := 5.6 +QT_VERSION := 5.6.1 + ifeq ($(UNAME), Linux) ifeq ($(ARCH), x86_64) - QT_SDK_URL := http://download.qt.io/official_releases/qt/5.4/5.4.1/qt-opensource-linux-x64-5.4.1.run - QT_SDK_MD5_URL := http://download.qt.io/official_releases/qt/5.4/5.4.1/qt-opensource-linux-x64-5.4.1.run.md5 - QT_SDK_ARCH := gcc_64 - OSG_URL := http://librepilot.github.io/tools/osg-3.4-linux-x64-qt-5.4.1.tar.gz + QT_SDK_ARCH := gcc_64 + QT_SDK_URL := http://download.qt.io/official_releases/qt/$(QT_SHORT_VERSION)/$(QT_VERSION)/qt-opensource-linux-x64-$(QT_VERSION).run + QT_SDK_MD5_URL := http://download.qt.io/official_releases/qt/$(QT_SHORT_VERSION)/$(QT_VERSION)/md5sums.txt + OSG_URL := $(TOOLS_URL)/osg-3.5.3-linux-x64-qt-$(QT_VERSION).tar.gz + OSGEARTH_URL := $(TOOLS_URL)/osgearth-2.7-linux-x64-qt-$(QT_VERSION).tar.gz else - QT_SDK_URL := http://download.qt.io/official_releases/qt/5.4/5.4.1/qt-opensource-linux-x86-5.4.1.run - QT_SDK_MD5_URL := http://download.qt.io/official_releases/qt/5.4/5.4.1/qt-opensource-linux-x86-5.4.1.run.md5 - QT_SDK_ARCH := gcc - OSG_URL := http://librepilot.github.io/tools/osg-3.4-linux-x86-qt-5.4.1.tar.gz + # x32 for linux no longer provided as pre-built binaries. endif - UNCRUSTIFY_URL := http://librepilot.github.io/tools/uncrustify-0.60.tar.gz - DOXYGEN_URL := http://librepilot.github.io/tools/doxygen-1.8.3.1.src.tar.gz + UNCRUSTIFY_URL := $(TOOLS_URL)/uncrustify-0.60.tar.gz + DOXYGEN_URL := $(TOOLS_URL)/doxygen-1.8.3.1.src.tar.gz else ifeq ($(UNAME), Darwin) - QT_SDK_URL := http://download.qt.io/official_releases/qt/5.4/5.4.1/qt-opensource-mac-x64-clang-5.4.1.dmg - QT_SDK_MD5_URL := http://download.qt.io/official_releases/qt/5.4/5.4.1/qt-opensource-mac-x64-clang-5.4.1.dmg.md5 - QT_SDK_ARCH := clang_64 - QT_SDK_MAINTENANCE_TOOL := /Volumes/qt-opensource-mac-x64-clang-5.4.1/qt-opensource-mac-x64-clang-5.4.1.app/Contents/MacOS/qt-opensource-mac-x64-clang-5.4.1 - QT_SDK_MOUNT_DIR := /Volumes/qt-opensource-mac-x64-clang-5.4.1 - QT_SDK_INSTALLER_DAT := /Volumes/qt-opensource-mac-x64-clang-5.4.1/qt-opensource-mac-x64-clang-5.4.1.app/Contents/Resources/installer.dat - UNCRUSTIFY_URL := http://librepilot.github.io/tools/uncrustify-0.60.tar.gz - DOXYGEN_URL := http://librepilot.github.io/tools/doxygen-1.8.3.1.src.tar.gz - OSG_URL := + QT_SDK_ARCH := clang_64 + QT_SDK_URL := http://download.qt.io/official_releases/qt/$(QT_SHORT_VERSION)/$(QT_VERSION)/qt-opensource-mac-x64-clang-$(QT_VERSION).dmg + QT_SDK_MD5_URL := http://download.qt.io/official_releases/qt/$(QT_SHORT_VERSION)/$(QT_VERSION)/md5sums.txt + QT_SDK_MOUNT_DIR := /Volumes/qt-opensource-mac-x64-clang-$(QT_VERSION) + QT_SDK_MAINTENANCE_TOOL := /Volumes/qt-opensource-mac-x64-clang-$(QT_VERSION)/qt-opensource-mac-x64-clang-$(QT_VERSION).app/Contents/MacOS/qt-opensource-mac-x64-clang-$(QT_VERSION) + UNCRUSTIFY_URL := $(TOOLS_URL)/uncrustify-0.60.tar.gz + DOXYGEN_URL := $(TOOLS_URL)/doxygen-1.8.3.1.src.tar.gz + OSG_URL := $(TOOLS_URL)/osg-3.5.3-clang_64-qt-$(QT_VERSION).tar.gz + OSGEARTH_URL := $(TOOLS_URL)/osgearth-2.7-clang_64-qt-$(QT_VERSION).tar.gz else ifeq ($(UNAME), Windows) - QT_SDK_URL := http://download.qt.io/official_releases/qt/5.4/5.4.1/qt-opensource-windows-x86-mingw491_opengl-5.4.1.exe - QT_SDK_MD5_URL := http://download.qt.io/official_releases/qt/5.4/5.4.1/qt-opensource-windows-x86-mingw491_opengl-5.4.1.exe.md5 - QT_SDK_ARCH := mingw491_32 - NSIS_URL := http://librepilot.github.io/tools/nsis-2.46-unicode.tar.bz2 - SDL_URL := http://librepilot.github.io/tools/SDL-devel-1.2.15-mingw32.tar.gz - OPENSSL_URL := http://librepilot.github.io/tools/openssl-1.0.1e-win32.tar.bz2 - UNCRUSTIFY_URL := http://librepilot.github.io/tools/uncrustify-0.60-windows.tar.bz2 - DOXYGEN_URL := http://librepilot.github.io/tools/doxygen-1.8.3.1-windows.tar.bz2 - MESAWIN_URL := http://librepilot.github.io/tools/mesawin.tar.gz - CMAKE_URL := http://www.cmake.org/files/v2.8/cmake-2.8.12.2-win32-x86.zip - CMAKE_MD5_URL := http://librepilot.github.io/tools/cmake-2.8.12.2-win32-x86.zip.md5 - MSYS_URL := http://librepilot.github.io/tools/MSYS-1.0.11.zip - OSG_URL := http://librepilot.github.io/tools/osg-3.4-mingw491_32-qt-5.4.1.tar.gz + QT_SDK_ARCH := mingw492_32 + QT_SDK_URL := http://download.qt.io/official_releases/qt/$(QT_SHORT_VERSION)/$(QT_VERSION)/qt-opensource-windows-x86-mingw492-$(QT_VERSION).exe + QT_SDK_MD5_URL := http://download.qt.io/official_releases/qt/$(QT_SHORT_VERSION)/$(QT_VERSION)/md5sums.txt + NSIS_URL := $(TOOLS_URL)/nsis-2.46-unicode.tar.bz2 + MESAWIN_URL := $(TOOLS_URL)/mesawin.tar.gz + UNCRUSTIFY_URL := $(TOOLS_URL)/uncrustify-0.60-windows.tar.bz2 + DOXYGEN_URL := $(TOOLS_URL)/doxygen-1.8.3.1-windows.tar.bz2 endif -GTEST_URL := http://librepilot.github.io/tools/gtest-1.6.0.zip +GTEST_URL := $(TOOLS_URL)/gtest-1.7.0.zip CCACHE_URL := http://samba.org/ftp/ccache/ccache-3.2.2.tar.bz2 -CCACHE_MD5_URL := http://librepilot.github.io/tools/ccache-3.2.2.tar.bz2.md5 +CCACHE_MD5_URL := $(TOOLS_URL)/ccache-3.2.2.tar.bz2.md5 -QT_SDK_DIR := $(TOOLS_DIR)/qt-5.4.1 +QT_SDK_DIR := $(TOOLS_DIR)/qt-$(QT_VERSION) UNCRUSTIFY_DIR := $(TOOLS_DIR)/uncrustify-0.60 DOXYGEN_DIR := $(TOOLS_DIR)/doxygen-1.8.3.1 -GTEST_DIR := $(TOOLS_DIR)/gtest-1.6.0 +GTEST_DIR := $(TOOLS_DIR)/gtest-1.7.0 CCACHE_DIR := $(TOOLS_DIR)/ccache -OSG_TOOLS_DIR := $(TOOLS_DIR) ifeq ($(UNAME), Linux) ifeq ($(ARCH), x86_64) - OSG_SDK_DIR := $(OSG_TOOLS_DIR)/osg-3.4-linux-x64-qt-5.4.1 + OSG_SDK_DIR := $(TOOLS_DIR)/osg-3.5.3-linux-x64-qt-$(QT_VERSION) + OSGEARTH_SDK_DIR := $(TOOLS_DIR)/osgearth-2.7-linux-x64-qt-$(QT_VERSION) else - OSG_SDK_DIR := $(OSG_TOOLS_DIR)/osg-3.4-linux-x86-qt-5.4.1 + OSG_SDK_DIR := $(TOOLS_DIR)/osg-3.5.3-linux-x86-qt-$(QT_VERSION) + OSGEARTH_SDK_DIR := $(TOOLS_DIR)/osgearth-2.7-linux-x86-qt-$(QT_VERSION) endif else ifeq ($(UNAME), Darwin) - OSG_SDK_DIR := $(OSG_TOOLS_DIR)/osg-3.4-clang_64-qt-5.4.1 + OSG_SDK_DIR := $(TOOLS_DIR)/osg-3.5.3-clang_64-qt-$(QT_VERSION) + OSGEARTH_SDK_DIR := $(TOOLS_DIR)/osgearth-2.7-clang_64-qt-$(QT_VERSION) else ifeq ($(UNAME), Windows) - MINGW_DIR := $(QT_SDK_DIR)/Tools/$(QT_SDK_ARCH) + ifeq ($(ARCH), x86_64) + MINGW_DIR := /mingw64 + else + MINGW_DIR := /mingw32 + endif # When changing PYTHON_DIR, you must also update it in ground/gcs/src/python.pri - PYTHON_DIR := $(QT_SDK_DIR)/Tools/$(QT_SDK_ARCH)/opt/bin + PYTHON_DIR := $(MINGW_DIR)/bin + OSG_SDK_DIR := $(MINGW_DIR) + OSGEARTH_SDK_DIR := $(MINGW_DIR) NSIS_DIR := $(TOOLS_DIR)/nsis-2.46-unicode - # When changing SDL_DIR or OPENSSL_DIR, you must also update them in ground/gcs/gcs.pri - SDL_DIR := $(TOOLS_DIR)/SDL-1.2.15 - OPENSSL_DIR := $(TOOLS_DIR)/openssl-1.0.1e-win32 MESAWIN_DIR := $(TOOLS_DIR)/mesawin - CMAKE_DIR := $(TOOLS_DIR)/cmake-2.8.12.2-win32-x86 - MSYS_DIR := $(TOOLS_DIR)/msys - OSG_SDK_DIR := $(OSG_TOOLS_DIR)/osg-3.4-mingw491_32-qt-5.4.1 endif -QT_SDK_PREFIX := $(QT_SDK_DIR) - ############################## # # Build only and all toolchains available for the platform # ############################## -BUILD_SDK_TARGETS := arm_sdk qt_sdk +BUILD_SDK_TARGETS := arm_sdk ifeq ($(UNAME), Windows) - BUILD_SDK_TARGETS += osg sdl nsis mesawin openssl ccache + BUILD_SDK_TARGETS += nsis mesawin +endif +ifeq ($(UNAME), Darwin) + BUILD_SDK_TARGETS += qt_sdk osg endif ALL_SDK_TARGETS := $(BUILD_SDK_TARGETS) gtest uncrustify doxygen @@ -211,6 +209,7 @@ JAVAC := javac JAR := jar CD := cd GREP := grep +CMAKE := cmake ifneq ($(UNAME), Windows) SEVENZIP := 7za else @@ -220,6 +219,11 @@ ifneq ($(shell $(SEVENZIP) --version >/dev/null 2>&1 && $(ECHO) "found"), found) SEVENZIP = $(TOOLS_DIR)/bin/7za.exe endif endif +ifneq ($(UNAME), Windows) + MAKE := make +else + MAKE := mingw32-make +endif # Echo in recipes is a bit tricky in a Windows Git Bash window in some cases. # It does not work if make started under msysGit installed into a path with spaces. @@ -304,7 +308,7 @@ endif ############################## define MD5_CHECK_TEMPLATE -"`test -f \"$(1)\" && $(OPENSSL) dgst -md5 \"$(1)\" | $(CUT) -f2 -d' '`" $(2) "`$(CUT) -f1 -d' ' < \"$(1).md5\"`" +"`test -f \"$(1)\" && $(OPENSSL) dgst -md5 \"$(1)\" | $(CUT) -f2 -d' '`" $(2) "`$(GREP) $(notdir $(1)) $(1).md5 | $(CUT) -f1 -d' '`" endef ############################## @@ -395,207 +399,6 @@ $(1)_distclean: endef -############################## -# -# Windows QT install template -# $(1) = tool temp extract/build directory -# $(2) = tool install directory -# $(3) = tool distribution URL -# $(4) = tool distribution .md5 URL -# $(5) = tool distribution file -# $(6) = QT architecture -# $(7) = optional extra build recipes template -# $(8) = optional extra clean recipes template -# -############################## - -define WIN_QT_INSTALL_TEMPLATE - -.PHONY: $(addprefix qt_sdk_, install clean distclean) - -qt_sdk_install: qt_sdk_clean | $(DL_DIR) $(TOOLS_DIR) - $(V1) if ! $(SEVENZIP) >/dev/null 2>&1; then \ - $(ECHO) $(MSG_NOTICE) "Missing 7zip. Run ./make/scripts/win_sdk_install.sh [] to get it." && \ - exit 1; \ - fi - $(call DOWNLOAD_TEMPLATE,$(3),$(5),"$(4)") -# Explode .run file into install packages - @$(ECHO) $(MSG_EXTRACTING) $$(call toprel, $(1)) - $(V1) $(MKDIR) -p $$(call toprel, $(dir $(1))) - $(V1) chmod +x $(DL_DIR)/$(5) - $(V1) $(DL_DIR)/$(5) --dump-binary-data -o $(1) -# Extract packages under tool directory - $(V1) $(MKDIR) -p $$(call toprel, $(dir $(2))) - $(V1) $(SEVENZIP) -y -o$(2) x "$(1)/qt.54.win32_mingw491/5.4.1-0qt5_essentials.7z" | grep -v Extracting - $(V1) $(SEVENZIP) -y -o$(2) x "$(1)/qt.54.win32_mingw491/5.4.1-0i686-4.9.1-release-posix-dwarf-rt_v3-rev2-runtime.7z" | grep -v Extracting - $(V1) $(SEVENZIP) -y -o$(2) x "$(1)/qt.54.win32_mingw491/5.4.1-0icu_53_1_mingw_builds_4_9_1_posix_dwarf_32.7z" | grep -v Extracting - $(V1) $(SEVENZIP) -y -o$(2) x "$(1)/qt.54.win32_mingw491/5.4.1-0qt5_addons.7z" | grep -v Extracting - $(V1) $(SEVENZIP) -y -o$(2) x "$(1)/qt.tools.win32_mingw491/4.9.1-2i686-4.9.1-release-posix-dwarf-rt_v3-rev2.7z" | grep -v Extracting -# Run patcher - @$(ECHO) - @$(ECHO) "Executing QtPatch in" $$(call toprel, $(QT_SDK_PREFIX)) - $(V1) $(CD) $(QT_SDK_PREFIX) - $(V1) $(DL_DIR)/$(5) --runoperation QtPatch windows $(QT_SDK_PREFIX) qt5 - -# Execute post build templates - $(7) - -# Clean up temporary files - @$(ECHO) $(MSG_CLEANING) $$(call toprel, $(1)) - $(V1) [ ! -d "$(1)" ] || $(RM) -rf "$(1)" - -qt_sdk_clean: - @$(ECHO) $(MSG_CLEANING) $$(call toprel, $(1)) - $(V1) [ ! -d "$(1)" ] || $(RM) -rf "$(1)" - @$(ECHO) $(MSG_CLEANING) $$(call toprel, "$(2)") - $(V1) [ ! -d "$(2)" ] || $(RM) -rf "$(2)" - - $(8) - -qt_sdk_distclean: - @$(ECHO) $(MSG_DISTCLEANING) $$(call toprel, $(DL_DIR)/$(5)) - $(V1) [ ! -f "$(DL_DIR)/$(5)" ] || $(RM) "$(DL_DIR)/$(5)" - $(V1) [ ! -f "$(DL_DIR)/$(5).md5" ] || $(RM) "$(DL_DIR)/$(5).md5" - -endef - -############################## -# -# Linux QT install template -# $(1) = tool temp extract/build directory -# $(2) = tool install directory -# $(3) = tool distribution URL -# $(4) = tool distribution .md5 URL -# $(5) = tool distribution file -# $(6) = QT architecture -# $(7) = optional extra build recipes template -# $(8) = optional extra clean recipes template -# -############################## - -define LINUX_QT_INSTALL_TEMPLATE - -.PHONY: $(addprefix qt_sdk_, install clean distclean) - -qt_sdk_install: qt_sdk_clean | $(DL_DIR) $(TOOLS_DIR) - $(V1) if ! $(SEVENZIP) >/dev/null 2>&1; then \ - $(ECHO) $(MSG_NOTICE) "Please install the p7zip for your distribution. i.e.: sudo apt-get install p7zip-full" && \ - exit 1; \ - fi - $(call DOWNLOAD_TEMPLATE,$(3),$(5),"$(4)") -# Explode .run file into install packages - @$(ECHO) $(MSG_EXTRACTING) $$(call toprel, $(1)) - $(V1) $(MKDIR) -p $$(call toprel, $(dir $(1))) - $(V1) chmod +x $(DL_DIR)/$(5) - $(V1) $(DL_DIR)/$(5) --dump-binary-data -o $(1) -# Extract packages under tool directory - $(V1) $(MKDIR) -p $$(call toprel, $(dir $(2))) - $(V1) $(SEVENZIP) -y -o$(2) x "$(1)/qt.54.$(6)/5.4.1-0qt5_essentials.7z" | grep -v Extracting - $(V1) if [ -f "$(1)/qt.54.$(6)/5.4.1-0icu_53_1_ubuntu_11_10_64.7z" ]; then $(SEVENZIP) -y -o$(2) x "$(1)/qt.54.$(6)/5.4.1-0icu_53_1_ubuntu_11_10_64.7z" | grep -v Extracting; fi - $(V1) if [ -f "$(1)/qt.54.$(6)/5.4.1-0icu_53_1_ubuntu_11_10_32.7z" ]; then $(SEVENZIP) -y -o$(2) x "$(1)/qt.54.$(6)/5.4.1-0icu_53_1_ubuntu_11_10_32.7z" | grep -v Extracting; fi - $(V1) $(SEVENZIP) -y -o$(2) x "$(1)/qt.54.$(6)/5.4.1-0qt5_addons.7z" | grep -v Extracting -# Run patcher - @$(ECHO) - @$(ECHO) "Executing QtPatch in" $$(call toprel, $(QT_SDK_PREFIX)) - $(V1) $(CD) $(QT_SDK_PREFIX) - $(V1) $(DL_DIR)/$(5) --runoperation QtPatch linux $(QT_SDK_PREFIX) qt5 - -# Execute post build templates - $(7) - -# Clean up temporary files - @$(ECHO) $(MSG_CLEANING) $$(call toprel, $(1)) - $(V1) [ ! -d "$(1)" ] || $(RM) -rf "$(1)" - -qt_sdk_clean: - @$(ECHO) $(MSG_CLEANING) $$(call toprel, $(1)) - $(V1) [ ! -d "$(1)" ] || $(RM) -rf "$(1)" - @$(ECHO) $(MSG_CLEANING) $$(call toprel, "$(2)") - $(V1) [ ! -d "$(2)" ] || $(RM) -rf "$(2)" - - $(8) - -qt_sdk_distclean: - @$(ECHO) $(MSG_DISTCLEANING) $$(call toprel, $(DL_DIR)/$(5)) - $(V1) [ ! -f "$(DL_DIR)/$(5)" ] || $(RM) "$(DL_DIR)/$(5)" - $(V1) [ ! -f "$(DL_DIR)/$(5).md5" ] || $(RM) "$(DL_DIR)/$(5).md5" - -endef - -############################## -# -# Mac QT install template -# $(1) = tool temp extract/build directory -# $(2) = tool install directory -# $(3) = tool distribution URL -# $(4) = tool distribution .md5 URL -# $(5) = tool distribution file -# $(6) = QT architecture -# $(7) = optional extra build recipes template -# $(8) = optional extra clean recipes template -# -############################## - -define MAC_QT_INSTALL_TEMPLATE - -.PHONY: $(addprefix qt_sdk_, install clean distclean) - -qt_sdk_install: qt_sdk_clean | $(DL_DIR) $(TOOLS_DIR) - $(V1) if ! $(SEVENZIP) >/dev/null 2>&1; then \ - $(ECHO) $(MSG_NOTICE) "Please install the p7zip for your distribution. i.e.: brew install p7zip." && \ - exit 1; \ - fi - $(call DOWNLOAD_TEMPLATE,$(3),$(5),"$(4)") -# Mount .dmg file - $(V1) hdiutil attach -nobrowse $(DL_DIR)/$(5) -# Explode .dmg file into install packages - @$(ECHO) $(MSG_EXTRACTING) $$(call toprel, $(1)) - $(V1) $(MKDIR) -p $$(call toprel, $(dir $(1))) - $(V1) $(QT_SDK_MAINTENANCE_TOOL) --dump-binary-data -i $(QT_SDK_INSTALLER_DAT) -o $(1) -# Extract packages under tool directory - $(V1) $(MKDIR) -p $$(call toprel, $(dir $(2))) - #$(V1) $(SEVENZIP) -y -o$(2) x "$(1)/qt.readme/1.0.0-0qt-project-url.7z" | grep -v Extracting - #$(V1) $(SEVENZIP) -y -o$(2) x "$(1)/qt/5.4.1ThirdPartySoftware_Listing.7z" | grep -v Extracting - #$(V1) $(SEVENZIP) -y -o$(2) x "$(1)/qt.readme/1.0.0-0readme.7z" | grep -v Extracting - $(V1) $(SEVENZIP) -y -o$(2) x "$(1)/qt.54.$(6)/5.4.1-0qt5_essentials.7z" | grep -v Extracting -# $(V1) $(SEVENZIP) -y -o$(2) x "$(1)/qt.54.$(6).essentials/5.4.1icu_path_patcher.sh.7z" | grep -v Extracting - $(V1) $(SEVENZIP) -y -o$(2) x "$(1)/qt.54.$(6)/5.4.1-0qt5_addons.7z" | grep -v Extracting - - -# go to OpenPilot/tools/5.4/gcc_64 and call patcher.sh - @$(ECHO) - @$(ECHO) "Running patcher in" $$(call toprel, $(QT_SDK_PREFIX)) - $(V1) $(CD) $(QT_SDK_PREFIX) -# $(V1) "$(QT_SDK_PREFIX)/patcher.sh" $(QT_SDK_PREFIX) -# call qmake patcher - @$(ECHO) "Executing QtPatch in" $$(call toprel, $(QT_SDK_PREFIX)) - $(V1) $(QT_SDK_MAINTENANCE_TOOL) --runoperation QtPatch mac $(QT_SDK_PREFIX) qt5 - -#Unmount the .dmg file - $(V1) hdiutil detach $(QT_SDK_MOUNT_DIR) - -# Execute post build templates - $(7) - -# Clean up temporary files - @$(ECHO) $(MSG_CLEANING) $$(call toprel, $(1)) - $(V1) [ ! -d "$(1)" ] || $(RM) -rf "$(1)" - -qt_sdk_clean: - @$(ECHO) $(MSG_CLEANING) $$(call toprel, $(1)) - $(V1) [ ! -d "$(1)" ] || $(RM) -rf "$(1)" - @$(ECHO) $(MSG_CLEANING) $$(call toprel, "$(2)") - $(V1) [ ! -d "$(2)" ] || $(RM) -rf "$(2)" - - $(8) - -qt_sdk_distclean: - @$(ECHO) $(MSG_DISTCLEANING) $$(call toprel, $(DL_DIR)/$(5)) - $(V1) [ ! -f "$(DL_DIR)/$(5)" ] || $(RM) "$(DL_DIR)/$(5)" - $(V1) [ ! -f "$(DL_DIR)/$(5).md5" ] || $(RM) "$(DL_DIR)/$(5).md5" - -endef - ############################## # # ARM SDK @@ -623,6 +426,84 @@ define ARM_GCC_VERSION_CHECK_TEMPLATE fi endef +############################## +# +# Qt install template +# $(1) = tool install directory +# $(2) = tool distribution URL +# $(3) = tool distribution .md5 URL +# $(4) = tool distribution file +# $(5) = Qt architecture +# $(6) = optional extra build recipes template +# $(7) = optional extra clean recipes template +# +############################## + +define QT_INSTALL_TEMPLATE + +.PHONY: $(addprefix qt_sdk_, install clean distclean) + +qt_sdk_install: qt_sdk_clean | $(DL_DIR) $(TOOLS_DIR) + $(call DOWNLOAD_TEMPLATE,$(2),$(4),"$(3)") +# Silently install Qt under tools directory + @$(ECHO) $(MSG_EXTRACTING) $(4) to $$(call toprel, $(1)) + $(V1) ( export QT_INSTALL_TARGET_DIR=$(1) && \ + chmod +x $(DL_DIR)/$(4) && \ + $(DL_DIR)/$(4) --script $(ROOT_DIR)/make/tool_install/qt-install.qs ; \ + ) +# Execute post build templates + $(6) + +qt_sdk_clean: + @$(ECHO) $(MSG_CLEANING) $$(call toprel, $(1)) + $(V1) [ ! -d "$(1)" ] || $(RM) -rf "$(1)" + $(7) + +qt_sdk_distclean: + @$(ECHO) $(MSG_DISTCLEANING) $$(call toprel, $(DL_DIR)/$(4)) + $(V1) [ ! -f "$(DL_DIR)/$(4)" ] || $(RM) "$(DL_DIR)/$(4)" + $(V1) [ ! -f "$(DL_DIR)/$(4).md5" ] || $(RM) "$(DL_DIR)/$(4).md5" + +endef + +############################## +# +# Mac QT install template +# $(1) = tool install directory +# $(2) = tool distribution URL +# $(3) = tool distribution .md5 URL +# $(4) = tool distribution file +# $(5) = QT architecture +# $(6) = optional extra build recipes template +# $(7) = optional extra clean recipes template +# +############################## + +define MAC_QT_INSTALL_TEMPLATE + +.PHONY: $(addprefix qt_sdk_, install clean distclean) + +qt_sdk_install: qt_sdk_clean | $(DL_DIR) $(TOOLS_DIR) + $(call DOWNLOAD_TEMPLATE,$(2),$(4),"$(3)") +# Mount .dmg file + $(V1) hdiutil attach -nobrowse $(DL_DIR)/$(4) +# Silently install Qt under tools directory + @$(ECHO) $(MSG_EXTRACTING) $(4) to $$(call toprel, $(1)) + $(V1) ( export QT_INSTALL_TARGET_DIR=$(1) && \ + $(QT_SDK_MAINTENANCE_TOOL) --script $(ROOT_DIR)/make/tool_install/qt-install.qs ; \ + ) +# Unmount the .dmg file + $(V1) hdiutil detach $(QT_SDK_MOUNT_DIR) +# Execute post build templates + $(6) + +qt_sdk_clean: + @$(ECHO) $(MSG_CLEANING) $$(call toprel, $(1)) + $(V1) [ ! -d "$(1)" ] || $(RM) -rf "$(1)" + $(7) + +endef + ############################## # # Qt SDK @@ -631,30 +512,18 @@ endef ifeq ($(UNAME), Windows) -QT_SDK_PREFIX := $(QT_SDK_DIR)/5.4/$(QT_SDK_ARCH) - -# This additional configuration step should not be necessary -# but it is needed as a workaround to https://bugreports.qt-project.org/browse/QTBUG-33254 -define QT_SDK_CONFIGURE_TEMPLATE - @$(ECHO) $(MSG_CONFIGURING) $(call toprel, $(QT_SDK_DIR)) - $(V1) $(ECHO) $(QUOTE)[Paths]$(QUOTE) > $(QT_SDK_PREFIX)/bin/qt.conf - $(V1) $(ECHO) $(QUOTE)Prefix = $(QT_SDK_PREFIX)$(QUOTE) >> $(QT_SDK_PREFIX)/bin/qt.conf -endef - -QT_BUILD_DIR := $(BUILD_DIR)/QT_BUILD - $(eval $(call WIN_QT_INSTALL_TEMPLATE,$(QT_BUILD_DIR),$(QT_SDK_DIR),$(QT_SDK_URL),$(QT_SDK_MD5_URL),$(notdir $(QT_SDK_URL)),$(QT_SDK_ARCH),$(QT_SDK_CONFIGURE_TEMPLATE))) + QT_SDK_PREFIX := $(QT_SDK_DIR)/$(QT_SHORT_VERSION)/$(QT_SDK_ARCH) + $(eval $(call QT_INSTALL_TEMPLATE,$(QT_SDK_DIR),$(QT_SDK_URL),$(QT_SDK_MD5_URL),$(notdir $(QT_SDK_URL)),$(QT_SDK_ARCH))) else ifeq ($(UNAME), Linux) -QT_SDK_PREFIX := "$(QT_SDK_DIR)/5.4/$(QT_SDK_ARCH)" -QT_BUILD_DIR := $(BUILD_DIR)/QT_BUILD - $(eval $(call LINUX_QT_INSTALL_TEMPLATE,$(QT_BUILD_DIR),$(QT_SDK_DIR),$(QT_SDK_URL),$(QT_SDK_MD5_URL),$(notdir $(QT_SDK_URL)),$(QT_SDK_ARCH))) + QT_SDK_PREFIX := "$(QT_SDK_DIR)/$(QT_SHORT_VERSION)/$(QT_SDK_ARCH)" + $(eval $(call QT_INSTALL_TEMPLATE,$(QT_SDK_DIR),$(QT_SDK_URL),$(QT_SDK_MD5_URL),$(notdir $(QT_SDK_URL)),$(QT_SDK_ARCH))) else ifeq ($(UNAME), Darwin) -QT_SDK_PREFIX := "$(QT_SDK_DIR)/5.4/$(QT_SDK_ARCH)" -QT_BUILD_DIR := $(BUILD_DIR)/QT_BUILD - $(eval $(call MAC_QT_INSTALL_TEMPLATE,$(QT_BUILD_DIR),$(QT_SDK_DIR),$(QT_SDK_URL),$(QT_SDK_MD5_URL),$(notdir $(QT_SDK_URL)),$(QT_SDK_ARCH))) + QT_SDK_PREFIX := "$(QT_SDK_DIR)/$(QT_SHORT_VERSION)/$(QT_SDK_ARCH)" + $(eval $(call MAC_QT_INSTALL_TEMPLATE,$(QT_SDK_DIR),$(QT_SDK_URL),$(QT_SDK_MD5_URL),$(notdir $(QT_SDK_URL)),$(QT_SDK_ARCH))) else @@ -663,7 +532,7 @@ QT_SDK_PREFIX := $(QT_SDK_DIR) .PHONY: qt_sdk_install qt_sdk_install: @$(ECHO) $(MSG_NOTICE) -------------------------------------------------------- - @$(ECHO) $(MSG_NOTICE) Please install native Qt 5.4.x SDK using package manager + @$(ECHO) $(MSG_NOTICE) Please install native Qt 5.6.x SDK using package manager @$(ECHO) $(MSG_NOTICE) -------------------------------------------------------- .PHONY: qt_sdk_clean @@ -684,9 +553,15 @@ ifeq ($(shell [ -d "$(QT_SDK_DIR)" ] && $(ECHO) "exists"), exists) export LD_LIBRARY_PATH := $(QT_SDK_DIR)/lib:$(LD_LIBRARY_PATH) endif else - # not installed, hope it's in the path... - # $(info $(EMPTY) WARNING $(call toprel, $(QT_SDK_DIR)) not found (make qt_sdk_install), using system PATH) - QMAKE ?= qmake + OPT_QT := qt56 + OPT_QT_ENV_SH := /opt/$(OPT_QT)/bin/$(OPT_QT)-env.sh + ifneq ($(wildcard $(OPT_QT_ENV_SH)),) + SHELL := /bin/bash + QMAKE := . $(OPT_QT_ENV_SH) && qmake + else + # not installed, hope it's in the path... + QMAKE := qmake + endif endif .PHONY: qt_sdk_version @@ -713,16 +588,14 @@ endif .PHONY: mingw_version mingw_version: gcc_version -else # Linux or Mac - -all_sdk_version: gcc_version - endif .PHONY: gcc_version gcc_version: -$(V1) gcc --version | head -n1 +all_sdk_version: gcc_version + ############################## # # Python @@ -770,29 +643,6 @@ nsis_version: endif -############################## -# -# SDL (Windows only) -# -############################## - -ifeq ($(UNAME), Windows) - -$(eval $(call TOOL_INSTALL_TEMPLATE,sdl,$(SDL_DIR),$(SDL_URL),,$(notdir $(SDL_URL)))) - -ifeq ($(shell [ -d "$(SDL_DIR)" ] && $(ECHO) "exists"), exists) - export SDL_DIR := $(SDL_DIR) -else - # not installed, hope it's in the path... - $(info $(EMPTY) WARNING $(call toprel, $(SDL_DIR)) not found (make sdl_install), using system PATH) -endif - -.PHONY: sdl_version -sdl_version: - -$(V1) $(ECHO) "SDL 1.2.15" - -endif - ################################## # # Mesa OpenGL DLL (Windows only) @@ -816,31 +666,6 @@ mesawin_version: endif -############################## -# -# OpenSSL (Windows only) -# -############################## - -ifeq ($(UNAME), Windows) - -$(eval $(call TOOL_INSTALL_TEMPLATE,openssl,$(OPENSSL_DIR),$(OPENSSL_URL),,$(notdir $(OPENSSL_URL)))) - -ifeq ($(shell [ -d "$(OPENSSL_DIR)" ] && $(ECHO) "exists"), exists) - export OPENSSL := $(OPENSSL_DIR)/bin/openssl - export OPENSSL_CONF := $(OPENSSL_DIR)/bin/openssl.cfg - export OPENSSL_DIR -else - # not installed, hope it's in the path... - # $(info $(EMPTY) WARNING $(call toprel, $(OPENSSL_DIR)) not found (make openssl_install), using system PATH) -endif - -.PHONY: openssl_version -openssl_version: - -$(V1) $(ECHO) "OpenSSL `$(OPENSSL) version`" - -endif - ############################## # # Uncrustify @@ -951,27 +776,6 @@ export GTEST_DIR gtest_version: -$(V1) $(SED) -n "s/^PACKAGE_STRING='\(.*\)'/\1/p" < $(GTEST_DIR)/configure -############################## -# -# CMake -# -############################## - -$(eval $(call TOOL_INSTALL_TEMPLATE,cmake,$(CMAKE_DIR),$(CMAKE_URL),$(CMAKE_MD5_URL),$(notdir $(CMAKE_URL)))) - -ifeq ($(shell [ -d "$(CMAKE_DIR)" ] && $(ECHO) "exists"), exists) - export CMAKE := $(CMAKE_DIR)/bin/cmake - export PATH := $(CMAKE_DIR)/bin:$(PATH) -else - # not installed, hope it's in the path... - #$(info $(EMPTY) WARNING $(call toprel, $(CMAKE_DIR)) not found (make cmake_install), using system PATH) - export CMAKE := cmake -endif - -.PHONY: cmake_version -cmake_version: - -$(V1) $(CMAKE) --version - ############################## # # CCACHE @@ -1010,47 +814,51 @@ endef $(eval $(call TOOL_INSTALL_TEMPLATE,ccache,$(CCACHE_BUILD_DIR),$(CCACHE_URL),$(CCACHE_MD5_URL),$(notdir $(CCACHE_URL)),$(CCACHE_BUILD_TEMPLATE),$(CCACHE_CLEAN_TEMPLATE))) -############################## -# -# MSYS -# -############################## - -ifeq ($(UNAME), Windows) - -$(eval $(call TOOL_INSTALL_TEMPLATE,msys,$(MSYS_DIR),$(MSYS_URL),,$(notdir $(MSYS_URL)))) - -ifeq ($(shell [ -d "$(MSYS_DIR)" ] && $(ECHO) "exists"), exists) - export MSYS_DIR -else - # not installed, hope it's in the path... - #$(info $(EMPTY) WARNING $(call toprel, $(MSYS_DIR)) not found (make msys_install), using system PATH) -endif - -.PHONY: msys_version -msys_version: - -endif - ############################## # # osg # ############################## -$(eval $(call TOOL_INSTALL_TEMPLATE,osg,$(OSG_SDK_DIR),$(OSG_URL),,$(notdir $(OSG_URL)))) +ifneq ($(UNAME), Windows) + + $(eval $(call TOOL_INSTALL_TEMPLATE,osg,$(OSG_SDK_DIR),$(OSG_URL),,$(notdir $(OSG_URL)))) + +endif ifeq ($(shell [ -d "$(OSG_SDK_DIR)" ] && $(ECHO) "exists"), exists) export OSG_SDK_DIR := $(OSG_SDK_DIR) else # not installed, hope it's in the path... - $(info $(EMPTY) WARNING $(call toprel, $(OSG_SDK_DIR)) not found (make osg_install), using system PATH) + # $(info $(EMPTY) WARNING $(call toprel, $(OSG_SDK_DIR)) not found (make osg_install), using system PATH) endif .PHONY: osg_version osg_version: -$(V1) $(ECHO) "`$(OSG_SDK_DIR)/bin/osgversion`" - -$(V1) $(ECHO) "`$(OSG_SDK_DIR)/bin/osgearth_version`" + +############################## +# +# osgearth +# +############################## + +ifneq ($(UNAME), Windows) + + $(eval $(call TOOL_INSTALL_TEMPLATE,osgearth,$(OSGEARTH_SDK_DIR),$(OSGEARTH_URL),,$(notdir $(OSGEARTH_URL)))) + +endif + +ifeq ($(shell [ -d "$(OSGEARTH_SDK_DIR)" ] && $(ECHO) "exists"), exists) + export OSGEARTH_SDK_DIR := $(OSGEARTH_SDK_DIR) +else + # not installed, hope it's in the path... + # $(info $(EMPTY) WARNING $(call toprel, $(OSGEARTH_SDK_DIR)) not found (make osgearth_install), using system PATH) +endif + +.PHONY: osgearth_version +osgearth_version: + -$(V1) $(ECHO) "`$(OSGEARTH_SDK_DIR)/bin/osgearth_version`" ############################## # diff --git a/package/Darwin.mk b/package/Darwin.mk index 4df9f8f1e..38284ed76 100644 --- a/package/Darwin.mk +++ b/package/Darwin.mk @@ -17,9 +17,11 @@ endif BUILD_DIR="$(BUILD_DIR)" \ GCS_BIG_NAME="$(GCS_BIG_NAME)" \ GCS_SMALL_NAME="$(GCS_SMALL_NAME)" \ + WIKI_URL_ROOT="${WIKI_URL_ROOT}" \ PACKAGE_LBL="$(PACKAGE_LBL)" \ PACKAGE_DIR="$(PACKAGE_DIR)" \ PACKAGE_NAME="$(PACKAGE_NAME)" \ PACKAGE_SEP="$(PACKAGE_SEP)" \ + QT_DIR="$(QT_SDK_PREFIX)/lib" \ "$(ROOT_DIR)/package/osx/package" \ ) diff --git a/package/Linux.mk b/package/Linux.mk index 42fef4f97..72a64510c 100644 --- a/package/Linux.mk +++ b/package/Linux.mk @@ -16,15 +16,17 @@ s,,$(GITWEB_URL),g; \ # Are we using a debian based distro? ifneq ($(wildcard /etc/apt/sources.list),) - include $(ROOT_DIR)/package/linux/deb.mk + PKG_TYPE := deb # Are we using a rpm based distro? else ifneq ($(wildcard /etc/yum.repos.d/*),) - include $(ROOT_DIR)/package/linux/rpm.mk + PKG_TYPE := rpm # Are we using an Arch based distro? else ifneq ($(wildcard /etc/pacman.conf),) $(info TODO: built in arch package) endif +-include $(ROOT_DIR)/package/linux/$(PKG_TYPE).mk + ############################## # # Install Linux Target @@ -52,9 +54,9 @@ install: uninstall $(V1) $(MKDIR) -p $(DESTDIR)$(datadir) $(V1) $(MKDIR) -p $(DESTDIR)$(datadir)/applications $(V1) $(MKDIR) -p $(DESTDIR)$(datadir)/pixmaps - $(V1) $(INSTALL) $(BUILD_DIR)/$(GCS_SMALL_NAME)_$(GCS_BUILD_CONF)/bin/$(GCS_SMALL_NAME) $(DESTDIR)$(bindir) - $(V1) $(INSTALL) $(BUILD_DIR)/$(GCS_SMALL_NAME)_$(GCS_BUILD_CONF)/$(libbasename)/$(GCS_SMALL_NAME) $(DESTDIR)$(libdir) - $(V1) $(INSTALL) $(BUILD_DIR)/$(GCS_SMALL_NAME)_$(GCS_BUILD_CONF)/share/$(GCS_SMALL_NAME) $(DESTDIR)$(datadir) + $(V1) $(INSTALL) $(GCS_DIR)/bin/$(GCS_SMALL_NAME) $(DESTDIR)$(bindir) + $(V1) $(INSTALL) $(GCS_DIR)/$(libbasename)/$(GCS_SMALL_NAME) $(DESTDIR)$(libdir) + $(V1) $(INSTALL) $(GCS_DIR)/share/$(GCS_SMALL_NAME) $(DESTDIR)$(datadir) $(V1) $(INSTALL) -T $(ROOT_DIR)/package/linux/gcs.desktop $(DESTDIR)$(datadir)/applications/$(ORG_SMALL_NAME).desktop $(V1) $(INSTALL) -T $(ROOT_DIR)/ground/gcs/src/plugins/coreplugin/images/$(ORG_SMALL_NAME)_logo_128.png \ $(DESTDIR)$(datadir)/pixmaps/$(ORG_SMALL_NAME).png diff --git a/package/Windows.mk b/package/Windows.mk index 705fb186a..ee6e50c0e 100644 --- a/package/Windows.mk +++ b/package/Windows.mk @@ -6,31 +6,36 @@ ifndef TOP_LEVEL_MAKEFILE $(error Top level Makefile must be used to build this target) endif -VERSION_CMD := $(VERSION_INFO) +PACKAGE_EXE := $(BUILD_DIR)/$(PACKAGE_FULL_NAME)_$(ARCH).exe -NSIS_OPTS := /V3 +NSIS_OPTS := -V3 NSIS_WINX86 := $(ROOT_DIR)/package/winx86 NSIS_SCRIPT := $(NSIS_WINX86)/gcs.nsi -NSIS_TEMPLATE := $(NSIS_WINX86)/gcs.tpl -NSIS_HEADER := $(OPGCSSYNTHDIR)/gcs.nsh + +ifeq ($(ARCH),x86_64) +WIN_DEF = -DW64 +endif .PHONY: package -package: gcs uavobjects_matlab | $(PACKAGE_DIR) +package: $(PACKAGE_EXE) + +$(PACKAGE_EXE): $(NSIS_SCRIPT) gcs 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 - $(V1) mkdir -p "$(dir $(NSIS_HEADER))" - $(VERSION_CMD) \ - --template='$(NSIS_TEMPLATE)' \ - --outfile='$(NSIS_HEADER)' \ - ORG_BIG_NAME='$(ORG_BIG_NAME)' \ - GCS_BIG_NAME='$(GCS_BIG_NAME)' \ - GCS_SMALL_NAME='$(GCS_SMALL_NAME)' \ - PACKAGE_LBL='$(PACKAGE_LBL)' \ - PACKAGE_NAME='$(PACKAGE_NAME)' \ - PACKAGE_SEP='$(PACKAGE_SEP)' $(V1) echo "Building Windows installer, please wait..." $(V1) echo "If you have a script error in line 1 - use Unicode NSIS 2.46+" $(V1) echo " http://www.scratchpaper.com" - $(NSIS) $(NSIS_OPTS) $(NSIS_SCRIPT) + $(NSIS) $(NSIS_OPTS) \ + -DORG_BIG_NAME='$(ORG_BIG_NAME)' \ + -DGCS_BIG_NAME='$(GCS_BIG_NAME)' \ + -DGCS_SMALL_NAME='$(GCS_SMALL_NAME)' \ + -DPACKAGE_LBL='$(PACKAGE_LBL)' \ + -DVERSION_FOUR_NUM='$(shell $(VERSION_INFO) --format=\$${VERSION_FOUR_NUM})' \ + -DOUT_FILE='$(call system_path,$(PACKAGE_EXE))' \ + -DPROJECT_ROOT='$(call system_path,$(ROOT_DIR))' \ + -DGCS_BUILD_TREE='$(call system_path,$(GCS_DIR))' \ + -DUAVO_SYNTH_TREE='$(call system_path,$(UAVOBJ_OUT_DIR))' \ + $(WIN_DEF) \ + $(NSIS_SCRIPT) diff --git a/package/linux/45-uav.rules b/package/linux/45-uav.rules index fdca37665..22d78904f 100644 --- a/package/linux/45-uav.rules +++ b/package/linux/45-uav.rules @@ -14,6 +14,9 @@ SUBSYSTEM=="usb", ATTRS{idVendor}=="20a0", ATTRS{idProduct}=="415c", GOTO="op_ru # OpenPilot Revolution board SUBSYSTEM=="usb", ATTRS{idVendor}=="20a0", ATTRS{idProduct}=="415e", GOTO="op_rules" +# Taulabs Sparky2 board +SUBSYSTEM=="usb", ATTRS{idVendor}=="20a0", ATTRS{idProduct}=="41d0", GOTO="op_rules" + # Other OpenPilot reserved pids SUBSYSTEM=="usb", ATTRS{idVendor}=="20a0", ATTRS{idProduct}=="415d", GOTO="op_rules" SUBSYSTEM=="usb", ATTRS{idVendor}=="20a0", ATTRS{idProduct}=="4194", GOTO="op_rules" diff --git a/package/linux/deb.mk b/package/linux/deb.mk index e7d0912cd..42c31eeeb 100644 --- a/package/linux/deb.mk +++ b/package/linux/deb.mk @@ -1,7 +1,4 @@ -# Get some info about the distro --include /etc/lsb-release - -DEB_DIST := $(DISTRIB_CODENAME) +DEB_DIST := $(shell lsb_release -c -s) # Instead of RELEASE-15.01-RC1 debian wants 15.01~RC1 UPSTREAM_VER := $(subst -,~,$(subst RELEASE-,,$(PACKAGE_LBL))) ifeq ($(DEB_DIST), unstable) # This should be set manually for a submission to Debian or similar @@ -11,6 +8,8 @@ DEB_REV := 0$(DEB_DIST)1 endif DEB_NAME := $(ORG_SMALL_NAME) DEB_ORIG_SRC := $(PACKAGE_DIR)/$(DEB_NAME)_$(UPSTREAM_VER).orig.tar.gz +DEB_ORIG_FW := $(PACKAGE_DIR)/$(DEB_NAME)_$(UPSTREAM_VER).orig-firmware.tar.gz +DEB_SRC_CHANGES := $(PACKAGE_DIR)/$(DEB_NAME)_$(UPSTREAM_VER)-$(DEB_REV)_source.changes DEB_PACKAGE_DIR := $(PACKAGE_DIR)/$(DEB_NAME)-$(UPSTREAM_VER) DEB_ARCH := $(shell dpkg --print-architecture) DEB_PACKAGE_NAME := $(DEB_NAME)_$(UPSTREAM_VER)-$(DEB_REV)_$(DEB_ARCH) @@ -22,19 +21,14 @@ SED_SCRIPT := $(SED_SCRIPT)' \ s//$(SED_DATE_STRG)/g; \ s//$(DEB_DIST)/g; \ s//$(DEB_NAME)/g; \ - s//$(DESCRIPTION_SHORT)\n $(subst $(NEWLINE),\n ,$(DESCRIPTION_LONG))/g; \ + s//$(DESCRIPTION_SHORT)\n $(subst ','"'"',$(subst $(NEWLINE),\n ,$(DESCRIPTION_LONG)))/g; \ ' -# Ubuntu 14.04 (Trusty Tahr) has different names for the qml-modules -TRUSTY_DEPS_SED := s/qml-module-qtquick-controls/qtdeclarative5-controls-plugin/g; \ - s/qml-module-qtquick-dialogs/qtdeclarative5-dialogs-plugin/g; \ - s/qml-module-qtquick-localstorage/qtdeclarative5-localstorage-plugin/g; \ - s/qml-module-qtquick-particles2/qtdeclarative5-particles-plugin/g; \ - s/qml-module-qtquick2/qtdeclarative5-qtquick2-plugin/g; \ - s/qml-module-qtquick-window2/qtdeclarative5-window-plugin/g; \ - s/qml-module-qtquick-xmllistmodel/qtdeclarative5-xmllistmodel-plugin/g; +# Ubuntu 14.04 (Trusty Tahr) use qt in /opt PPA +TRUSTY_DEPS_SED := s/qml-module-.*/$(OPT_QT)quickcontrols/g; \ + s/qt5-default.*/$(OPT_QT)-meta-minimal, $(OPT_QT)svg, $(OPT_QT)script, $(OPT_QT)serialport, $(OPT_QT)multimedia, $(OPT_QT)translations, $(OPT_QT)tools/g; -# Leave off Qt and ARM compiler dependencies if calling package target under the assumption that +# Leave off Qt and OSG dependencies if calling package target under the assumption that # OP is providing them or the user already has them installed because OP is already built. PACKAGE_DEPS_SED := s/python.*/python/;s/{misc:Depends}.*/{misc:Depends}/; @@ -42,30 +36,51 @@ PACKAGE_DEPS_SED := s/python.*/python/;s/{misc:Depends}.*/{misc:Depends}/; package: debian @$(ECHO) "Building Linux package, please wait..." $(V1) sed -i -e "$(PACKAGE_DEPS_SED)" debian/control + $(V1) sed -i -e 's,config_new.*, --help > /dev/null,' debian/rules $(V1) dpkg-buildpackage -b -us -uc -nc $(V1) mv $(ROOT_DIR)/../$(DEB_PACKAGE_NAME).deb $(BUILD_DIR) $(V1) mv $(ROOT_DIR)/../$(DEB_PACKAGE_NAME).changes $(BUILD_DIR) $(V1) rm -r debian +DEBIAN_DIR_FILES := changelog compat control copyright rules source/format .PHONY: debian debian: $(DEB_DIR) - $(V1) rm -rf debian - $(V1) cp -r $(DEB_DIR) debian + $(V1) rm -rf debian && mkdir debian + $(V1) cd $(DEB_DIR) $(foreach file,$(DEBIAN_DIR_FILES), && cp --parents $(file) $(ROOT_DIR)/debian) $(V1) cp -T package/linux/45-uav.rules debian/$(DEB_NAME).udev $(V1) $(SED_SCRIPT) debian/changelog debian/control ifeq ($(DEB_DIST), trusty) - $(V1) sed -i -e "$(TRUSTY_DEPS_SED)" debian/control + $(V1) sed -i -e '$(TRUSTY_DEPS_SED)' debian/control endif .PHONY: package_src -package_src: $(DEB_ORIG_SRC_NAME) $(DEB_PACKAGE_DIR) - $(V1) cd $(DEB_PACKAGE_DIR) && dpkg-buildpackage -S -us -uc +package_src: $(DEB_SRC_CHANGES) + +.PHONY: package_src_upload +package_src_upload: $(DEB_SRC_CHANGES) + $(V1) debsign $(DEB_SRC_CHANGES) + $(V1) dput $(DPUT_URL) $(DEB_SRC_CHANGES) + +# Only include the orig if it we haven't alreadly built it, +# because if we have it is likely to be uploaded already +ifeq ($(wildcard $(DEB_ORIG_SRC)),) +DPKG_INCLUDE_ORIG := -sa +else +DPKG_INCLUDE_ORIG := -sd +endif + +$(DEB_SRC_CHANGES): $(DEB_ORIG_SRC_NAME) $(DEB_PACKAGE_DIR) + $(V1) cd $(DEB_PACKAGE_DIR) && dpkg-buildpackage -S -us -uc $(DPKG_INCLUDE_ORIG) $(DEB_ORIG_SRC): $(DIST_TAR_GZ) | $(PACKAGE_DIR) $(V1) cp $(DIST_TAR_GZ) $(DEB_ORIG_SRC) -$(DEB_PACKAGE_DIR): $(DEB_ORIG_SRC) debian | $(PACKAGE_DIR) +$(DEB_ORIG_FW): $(FW_DIST_TAR_GZ) | $(PACKAGE_DIR) + $(V1) cp $(FW_DIST_TAR_GZ) $(DEB_ORIG_FW) + +$(DEB_PACKAGE_DIR): $(DEB_ORIG_SRC) $(DEB_ORIG_FW) debian | $(PACKAGE_DIR) $(V1) tar -xf $(DEB_ORIG_SRC) -C $(PACKAGE_DIR) + $(V1) tar -xf $(DEB_ORIG_FW) -C $(PACKAGE_DIR)/$(PACKAGE_NAME) $(V1) mv debian $(PACKAGE_DIR)/$(PACKAGE_NAME) $(V1) rm -rf $(DEB_PACKAGE_DIR) && mv $(PACKAGE_DIR)/$(PACKAGE_NAME) $(DEB_PACKAGE_DIR) diff --git a/package/linux/debian/changelog b/package/linux/debian/changelog index 4cff7b219..adfc40a8c 100644 --- a/package/linux/debian/changelog +++ b/package/linux/debian/changelog @@ -2,4 +2,4 @@ * Release from upstream Git repository - -- James Duley + -- The LibrePilot Project <> diff --git a/package/linux/debian/control b/package/linux/debian/control index 64ee9e6c9..943829425 100644 --- a/package/linux/debian/control +++ b/package/linux/debian/control @@ -2,7 +2,7 @@ Source: Section: electronics Priority: optional Maintainer: The LibrePilot Project <> -Build-Depends: debhelper (>= 9), libudev-dev, libusb-1.0-0-dev, libsdl1.2-dev, python, gcc-arm-none-eabi (>=4.9), qt5-default, qttools5-dev-tools, libqt5svg5-dev, qtdeclarative5-dev, qml-module-qtquick-controls, libqt5serialport5-dev, qtmultimedia5-dev, qtscript5-dev, libqt5opengl5-dev +Build-Depends: debhelper (>= 9), libudev-dev, libusb-1.0-0-dev, libsdl1.2-dev, python, libopenscenegraph-dev, libosgearth-dev, qt5-default, qttools5-dev-tools, libqt5svg5-dev, qtdeclarative5-dev, qml-module-qtquick-controls, libqt5serialport5-dev, qtmultimedia5-dev, qtscript5-dev, libqt5opengl5-dev Standards-Version: 3.9.5 Homepage: Vcs-Git: @@ -10,5 +10,5 @@ Vcs-Browser: Package: Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, qml-module-qtquick-controls, qml-module-qtquick-dialogs, qml-module-qtquick-xmllistmodel, qml-module-qtquick-localstorage, qml-module-qtquick-particles2, qml-module-qtquick-window2, qml-module-qtquick2 +Depends: ${shlibs:Depends}, ${misc:Depends}, openscenegraph-plugin-osgearth, qml-module-qtquick-controls, qml-module-qtquick-dialogs, qml-module-qtquick-xmllistmodel, qml-module-qtquick-localstorage, qml-module-qtquick-particles2, qml-module-qtquick-window2, qml-module-qtquick2 Description: diff --git a/package/linux/debian/rules b/package/linux/debian/rules index 6b2ce35ee..e636c8a1d 100755 --- a/package/linux/debian/rules +++ b/package/linux/debian/rules @@ -11,6 +11,9 @@ export DH_OPTIONS %: dh $@ +override_dh_auto_configure: + $(MAKE) config_new WITH_PREBUILT_FW=$(CURDIR)/firmware + override_dh_auto_build: dh_auto_build -- opfw_resource gcs diff --git a/package/linux/rpm.mk b/package/linux/rpm.mk index 4fb2c71e2..4528bcdd7 100644 --- a/package/linux/rpm.mk +++ b/package/linux/rpm.mk @@ -2,8 +2,8 @@ RPM_NAME := $(PACKAGE_NAME) UPSTREAM_VER := $(subst -,~,$(subst RELEASE-,,$(DIST_LBL))) RPM_REL := 1 RPM_ARCH := $(shell rpm --eval '%{_arch}') -RPM_PACKAGE_NAME := $(RPM_NAME)-$(UPSTREAM_VER)-$(RPM_REL)$(shell rpm --eval '%{?dist}').$(RPM_ARCH).rpm -RPM_PACKAGE_FILE := $(PACKAGE_DIR)/RPMS/$(RPM_ARCH)/$(RPM_PACKAGE_NAME) +RPM_PACKAGE_NAME := $(RPM_NAME)-$(UPSTREAM_VER)-$(RPM_REL) +RPM_PACKAGE_FILE := $(PACKAGE_DIR)/RPMS/$(RPM_ARCH)/$(RPM_PACKAGE_NAME)$(shell rpm --eval '%{?dist}').$(RPM_ARCH).rpm RPM_PACKAGE_SRC := $(PACKAGE_DIR)/SRPMS/$(RPM_PACKAGE_NAME).src.rpm SED_SCRIPT := $(SED_SCRIPT)' \ @@ -13,7 +13,7 @@ SED_SCRIPT := $(SED_SCRIPT)' \ s//$(notdir $(DIST_TAR_GZ))/g; \ s//$(notdir $(FW_DIST_TAR_GZ))/g; \ s//$(DESCRIPTION_SHORT)/g; \ - s//$(subst $(NEWLINE),\n,$(DESCRIPTION_LONG))/g; \ + s//$(subst ','"'"',$(subst $(NEWLINE),\n,$(DESCRIPTION_LONG)))/g; \ ' RPM_DIRS := $(addprefix $(PACKAGE_DIR)/,BUILD RPMS SOURCES SPECS SRPMS) @@ -25,7 +25,7 @@ SPEC_FILE_IN := $(ROOT_DIR)/package/linux/rpmspec.in .PHONY: rpmspec rpmspec: $(SPEC_FILE) -$(SPEC_FILE): $(SPEC_FILE_IN) | $(RPM_DIRS) +$(SPEC_FILE): $(SPEC_FILE_IN) $(DIST_VER_INFO) | $(RPM_DIRS) $(V1) cp -f $(SPEC_FILE_IN) $(SPEC_FILE) $(V1) $(SED_SCRIPT) $(SPEC_FILE) @@ -38,6 +38,10 @@ $(RPM_PACKAGE_FILE): RPMBUILD_OPTS := -bb package_src: $(RPM_PACKAGE_SRC) $(RPM_PACKAGE_SRC): RPMBUILD_OPTS := -bs +.PHONY: package_src_upload +package_src_upload: $(RPM_PACKAGE_SRC) + copr-cli build --nowait $(COPR_PROJECT) $(RPM_PACKAGE_SRC) + $(RPM_PACKAGE_FILE) $(RPM_PACKAGE_SRC): $(SPEC_FILE) $(DIST_TAR_GZ) $(FW_DIST_TAR_GZ) | $(RPM_DIRS) @$(ECHO) "Building $(call toprel,$@), please wait..." $(V1) ln -sf $(DIST_TAR_GZ) $(PACKAGE_DIR)/SOURCES diff --git a/package/linux/rpmspec.in b/package/linux/rpmspec.in index d175b4d26..35cbc4aca 100644 --- a/package/linux/rpmspec.in +++ b/package/linux/rpmspec.in @@ -24,6 +24,8 @@ BuildRequires: qt5-qtserialport-devel BuildRequires: qt5-qtsvg-devel BuildRequires: qt5-qttools-devel BuildRequires: qt5-qttranslations +BuildRequires: OpenSceneGraph-devel +BuildRequires: osgearth-devel BuildRequires: dwz BuildRequires: pkgconfig BuildRequires: python @@ -38,6 +40,8 @@ Requires: qt5-qtmultimedia Requires: qt5-qtscript Requires: qt5-qtserialport Requires: qt5-qtsvg +Requires: OpenSceneGraph-libs +Requires: osgearth %description @@ -77,26 +81,10 @@ rm -rf $RPM_BUILD_ROOT %defattr(-,root,root) %doc README.md CREDITS.txt WHATSNEW.txt %doc GPLv3.txt -%{_bindir}/librepilot-gcs -%{_udevrulesdir}/45-librepilot.rules -%{_datadir}/applications/librepilot.desktop -%{_datadir}/librepilot-gcs/* -%{_datadir}/pixmaps/librepilot.png -%{_libdir}/librepilot-gcs/plugins/LibrePilot/*.pluginspec -%{_libdir}/librepilot-gcs/plugins/LibrePilot/*.so -# -%{_libdir}/librepilot-gcs/libAggregation.so.1* -%{_libdir}/librepilot-gcs/libExtensionSystem.so.1* -%{_libdir}/librepilot-gcs/libGLC_lib.so.1* -%{_libdir}/librepilot-gcs/libopmapwidget.so.1* -%{_libdir}/librepilot-gcs/libQScienceSpinBox.so.1* -%{_libdir}/librepilot-gcs/libQtConcurrent.so.1* -%{_libdir}/librepilot-gcs/libQwt.so.1* -%{_libdir}/librepilot-gcs/libsdlgamepad.so.1* -%{_libdir}/librepilot-gcs/libUtils.so.1* -%{_libdir}/librepilot-gcs/libVersionInfo.so.1* -# -%{_libdir}/librepilot-gcs/lib*.so +%{_bindir}/* +%{_udevrulesdir}/* +%{_datadir}/* +%{_libdir}/* %changelog diff --git a/package/osx/dmg/Getting Started.webloc b/package/osx/dmg/Getting Started.webloc index 330e929d0..232b07451 100644 --- a/package/osx/dmg/Getting Started.webloc +++ b/package/osx/dmg/Getting Started.webloc @@ -3,6 +3,6 @@ URL - http://wiki.openpilot.org/display/Doc/Getting+Started+Guide + @URL@ diff --git a/package/osx/libraries b/package/osx/libraries index b6ce04af2..78431fa5e 100755 --- a/package/osx/libraries +++ b/package/osx/libraries @@ -4,7 +4,6 @@ APP="${1?}" PLUGINS="${APP}/Contents/Plugins" OP_PLUGINS="${APP}/Contents/Plugins/OpenPilot" QT_LIBS="QtCore QtGui QtMultimedia QtMultimediaWidgets QtNetwork QtOpenGL QtPrintSupport QtQml QtQuick QtScript QtSerialPort QtSql QtSvg QtWidgets QtV8 QtXml" -QT_DIR=$(otool -L "${APP}/Contents/MacOS/${GCS_BIG_NAME}" | sed -n -e 's/\/QtCore\.framework.*//p' | sed -n -E 's:^.::p') QT_EXTRA="accessible/libqtaccessiblewidgets.dylib bearer/libqgenericbearer.dylib imageformats/libqgif.dylib imageformats/libqico.dylib imageformats/libqjpeg.dylib imageformats/libqmng.dylib imageformats/libqtiff.dylib imageformats/libqsvg.dylib qmltooling/libqmldbg_tcp.dylib sqldrivers/libqsqlodbc.dylib sqldrivers/libqsqlpsql.dylib sqldrivers/libqsqlite.dylib imageformats/libqtga.dylib iconengines/libqsvgicon.dylib" OSG_EXTRA="libosgViewer.90.dylib" diff --git a/package/osx/package b/package/osx/package index 80de04875..3fb8f3012 100755 --- a/package/osx/package +++ b/package/osx/package @@ -16,6 +16,7 @@ rm -rf "${OUT_FILE}" # copy base dmg structure cp -r "${ROOT_DIR}/package/osx/dmg/" "${SRC_DIR}" +sed -i '' s/@URL@/$(echo ${WIKI_URL_ROOT} | sed -e 's/\\/\\\\/g' -e 's/\//\\\//g' -e 's/&/\\\&/g')/ "${SRC_DIR}/Getting Started.webloc" # packaging goes here cp -a "${APP_PATH}" "${SRC_DIR}" diff --git a/package/winx86/gcs.nsi b/package/winx86/gcs.nsi index 4cd8b96af..158ac2290 100644 --- a/package/winx86/gcs.nsi +++ b/package/winx86/gcs.nsi @@ -1,7 +1,8 @@ # -# Project: OpenPilot -# NSIS configuration file for OpenPilot GCS +# Project: LibrePilot +# NSIS configuration file for LibrePilot GCS # The OpenPilot Team, http://www.openpilot.org, Copyright (C) 2010-2015. +# The LibrePilot Team, http://www.librepilot.org, Copyright (C) 2015-2016. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -29,20 +30,19 @@ ; Includes !include "x64.nsh" -!include "..\..\build\gcs-synthetics\gcs.nsh" ;-------------------------------- ; Paths - ; Tree root locations (relative to this script location) - !define PROJECT_ROOT "..\.." !define NSIS_DATA_TREE "." - !define GCS_BUILD_TREE "..\..\build\${GCS_SMALL_NAME}_release" - !define UAVO_SYNTH_TREE "..\..\build\uavobject-synthetics" !define AEROSIMRC_TREE "${GCS_BUILD_TREE}\misc\AeroSIM-RC" ; Default installation folder - InstallDir "$PROGRAMFILES\${ORG_BIG_NAME}" +!ifdef W64 + InstallDir "$PROGRAMFILES64\${ORG_BIG_NAME}" +!else + InstallDir "$PROGRAMFILES32\${ORG_BIG_NAME}" +!endif ; Get installation folder from registry if available InstallDirRegKey HKLM "Software\${ORG_BIG_NAME}" "Install Location" @@ -50,21 +50,15 @@ ;-------------------------------- ; Version information - ; Program name and installer file - !define PRODUCT_NAME "${GCS_BIG_NAME}" - !define INSTALLER_NAME "${GCS_BIG_NAME} Installer" + Name "${GCS_BIG_NAME}" + OutFile "${OUT_FILE}" - Name "${PRODUCT_NAME}" - OutFile "${PACKAGE_DIR}\..\${OUT_FILE}" - - VIProductVersion ${PRODUCT_VERSION} - VIAddVersionKey "ProductName" "${INSTALLER_NAME}" - VIAddVersionKey "FileVersion" "${FILE_VERSION}" - VIAddVersionKey "Comments" "${INSTALLER_NAME}. ${BUILD_DESCRIPTION}" + VIProductVersion ${VERSION_FOUR_NUM} + VIAddVersionKey "ProductName" "${GCS_BIG_NAME}" + VIAddVersionKey "ProductVersion" "${VERSION_FOUR_NUM}" VIAddVersionKey "CompanyName" "The LibrePilot Team, http://www.librepilot.org" - VIAddVersionKey "LegalTrademarks" "${PRODUCT_NAME} is a trademark of The LibrePilot Team" - VIAddVersionKey "LegalCopyright" "© 2015 The LibrePilot Team" - VIAddVersionKey "FileDescription" "${INSTALLER_NAME}" + VIAddVersionKey "LegalCopyright" "© 2015-2016 The LibrePilot Team" + VIAddVersionKey "FileDescription" "${GCS_BIG_NAME} Installer" ;-------------------------------- ; Installer interface and base settings @@ -84,7 +78,7 @@ ;-------------------------------- ; Branding - BrandingText "© 2015 The LibrePilot Team, http://www.librepilot.org" + BrandingText "© 2015-2016 The LibrePilot Team, http://www.librepilot.org" !define MUI_ICON "${NSIS_DATA_TREE}\resources\installer_icon.ico" !define MUI_HEADERIMAGE @@ -162,7 +156,7 @@ ; Installer sections ; Copy GCS core files -Section "Core files" InSecCore +Section "${GCS_BIG_NAME}" InSecCore SectionIn RO SetOutPath "$INSTDIR\bin" File /r "${GCS_BUILD_TREE}\bin\*" @@ -182,8 +176,8 @@ Section "-Plugins" InSecPlugins File /r "${GCS_BUILD_TREE}\lib\${GCS_SMALL_NAME}\plugins\*.pluginspec" SectionEnd -; Copy OSG libs -Section "-OsgLibs" InSecOsgLibs +; Copy GCS third party libs +Section "-Libs" InSecLibs SectionIn RO SetOutPath "$INSTDIR\lib\${GCS_SMALL_NAME}\osg" File /r "${GCS_BUILD_TREE}\lib\${GCS_SMALL_NAME}\osg\*.dll" @@ -201,14 +195,47 @@ Section "-Utilities" InSecUtilities File "/oname=OPLogConvert-${PACKAGE_LBL}.m" "${UAVO_SYNTH_TREE}\matlab\OPLogConvert.m" SectionEnd -; Copy driver files -Section "-Drivers" InSecDrivers - SetOutPath "$INSTDIR\drivers" - File /r "${PROJECT_ROOT}\flight\Project\Windows USB\*" +Section "Shortcuts" InSecShortcuts + ; Create desktop and start menu shortcuts + SetOutPath "$INSTDIR" + CreateDirectory "$SMPROGRAMS\${ORG_BIG_NAME}" + CreateShortCut "$SMPROGRAMS\${ORG_BIG_NAME}\${GCS_BIG_NAME}.lnk" "$INSTDIR\bin\${GCS_SMALL_NAME}.exe" \ + "" "$INSTDIR\bin\${GCS_SMALL_NAME}.exe" 0 + CreateShortCut "$SMPROGRAMS\${ORG_BIG_NAME}\${GCS_BIG_NAME} (clean configuration).lnk" "$INSTDIR\bin\${GCS_SMALL_NAME}.exe" \ + "-reset" "$INSTDIR\bin\${GCS_SMALL_NAME}.exe" 0 + CreateShortCut "$SMPROGRAMS\${ORG_BIG_NAME}\License.lnk" "$INSTDIR\LICENSE.txt" \ + "" "$INSTDIR\bin\${GCS_SMALL_NAME}.exe" 0 + CreateShortCut "$SMPROGRAMS\${ORG_BIG_NAME}\ReadMe.lnk" "$INSTDIR\README.txt" \ + "" "$INSTDIR\bin\${GCS_SMALL_NAME}.exe" 0 + CreateShortCut "$SMPROGRAMS\${ORG_BIG_NAME}\ReleaseNotes.lnk" "$INSTDIR\WHATSNEW.txt" \ + "" "$INSTDIR\bin\${GCS_SMALL_NAME}.exe" 0 + CreateShortCut "$SMPROGRAMS\${ORG_BIG_NAME}\Milestones.lnk" "$INSTDIR\MILESTONES.txt" \ + "" "$INSTDIR\bin\${GCS_SMALL_NAME}.exe" 0 + CreateShortCut "$SMPROGRAMS\${ORG_BIG_NAME}\Website.lnk" "http://www.librepilot.org" \ + "" "$INSTDIR\bin\${GCS_SMALL_NAME}.exe" 0 + CreateShortCut "$SMPROGRAMS\${ORG_BIG_NAME}\Wiki.lnk" "https://librepilot.atlassian.net/wiki/display/LPDOC/LibrePilot+Documentation" \ + "" "$INSTDIR\bin\${GCS_SMALL_NAME}.exe" 0 + CreateShortCut "$SMPROGRAMS\${ORG_BIG_NAME}\Forums.lnk" "http://forum.librepilot.org" \ + "" "$INSTDIR\bin\${GCS_SMALL_NAME}.exe" 0 + CreateShortCut "$DESKTOP\${GCS_BIG_NAME}.lnk" "$INSTDIR\bin\${GCS_SMALL_NAME}.exe" \ + "" "$INSTDIR\bin\${GCS_SMALL_NAME}.exe" 0 + CreateShortCut "$SMPROGRAMS\${ORG_BIG_NAME}\Uninstall.lnk" "$INSTDIR\Uninstall.exe" "" "$INSTDIR\Uninstall.exe" 0 SectionEnd -; Preinstall OpenPilot CDC driver -Section "CDC driver" InSecInstallDrivers +; AeroSimRC plugin files +Section "AeroSimRC plugin" InSecAeroSimRC + SetOutPath "$INSTDIR\misc\AeroSIM-RC" + File /r "${AEROSIMRC_TREE}\*" +SectionEnd + +; Copy driver files (hidden, driver is always copied to install directory) +Section "-Drivers" InSecDrivers + SetOutPath "$INSTDIR\drivers" + File /r "${PROJECT_ROOT}\flight\Project\WindowsUSB\*" +SectionEnd + +; Preinstall OpenPilot CDC driver (disabled by default) +Section /o "CDC driver" InSecInstallDrivers InitPluginsDir SetOutPath "$PLUGINSDIR" ${If} ${RunningX64} @@ -222,40 +249,7 @@ SectionEnd ; Copy Opengl32.dll if needed (disabled by default) Section /o "Mesa OpenGL driver" InSecInstallOpenGL SetOutPath "$INSTDIR\bin" - File /r "${GCS_BUILD_TREE}\bin\opengl32_32\opengl32.dll" -SectionEnd - -; AeroSimRC plugin files -Section "AeroSimRC plugin" InSecAeroSimRC - SetOutPath "$INSTDIR\misc\AeroSIM-RC" - File /r "${AEROSIMRC_TREE}\*" -SectionEnd - -Section "Shortcuts" InSecShortcuts - ; Create desktop and start menu shortcuts - SetOutPath "$INSTDIR" - CreateDirectory "$SMPROGRAMS\${ORG_BIG_NAME}" - CreateShortCut "$SMPROGRAMS\${ORG_BIG_NAME}\${GCS_BIG_NAME}.lnk" "$INSTDIR\bin\${GCS_SMALL_NAME}.exe" \ - "" "$INSTDIR\bin\${GCS_SMALL_NAME}.exe" 0 "" "" "${PRODUCT_NAME} ${PRODUCT_VERSION}. ${BUILD_DESCRIPTION}" - CreateShortCut "$SMPROGRAMS\${ORG_BIG_NAME}\${GCS_BIG_NAME} (clean configuration).lnk" "$INSTDIR\bin\${GCS_SMALL_NAME}.exe" \ - "-reset" "$INSTDIR\bin\${GCS_SMALL_NAME}.exe" 0 "" "" "${PRODUCT_NAME} ${PRODUCT_VERSION}. ${BUILD_DESCRIPTION}" - CreateShortCut "$SMPROGRAMS\${ORG_BIG_NAME}\License.lnk" "$INSTDIR\LICENSE.txt" \ - "" "$INSTDIR\bin\${GCS_SMALL_NAME}.exe" 0 - CreateShortCut "$SMPROGRAMS\${ORG_BIG_NAME}\ReadMe.lnk" "$INSTDIR\README.txt" \ - "" "$INSTDIR\bin\${GCS_SMALL_NAME}.exe" 0 - CreateShortCut "$SMPROGRAMS\${ORG_BIG_NAME}\ReleaseNotes.lnk" "$INSTDIR\WHATSNEW.txt" \ - "" "$INSTDIR\bin\${GCS_SMALL_NAME}.exe" 0 - CreateShortCut "$SMPROGRAMS\${ORG_BIG_NAME}\Milestones.lnk" "$INSTDIR\MILESTONES.txt" \ - "" "$INSTDIR\bin\${GCS_SMALL_NAME}.exe" 0 - CreateShortCut "$SMPROGRAMS\${ORG_BIG_NAME}\Website.lnk" "http://www.librepilot.org" \ - "" "$INSTDIR\bin\${GCS_SMALL_NAME}.exe" 0 - CreateShortCut "$SMPROGRAMS\${ORG_BIG_NAME}\Wiki.lnk" "http://wiki.openpilot.org" \ - "" "$INSTDIR\bin\${GCS_SMALL_NAME}.exe" 0 - CreateShortCut "$SMPROGRAMS\${ORG_BIG_NAME}\Forums.lnk" "http://forums.librepilot.org" \ - "" "$INSTDIR\bin\${GCS_SMALL_NAME}.exe" 0 - CreateShortCut "$DESKTOP\${GCS_BIG_NAME}.lnk" "$INSTDIR\bin\${GCS_SMALL_NAME}.exe" \ - "" "$INSTDIR\bin\${GCS_SMALL_NAME}.exe" 0 "" "" "${PRODUCT_NAME} ${PRODUCT_VERSION}. ${BUILD_DESCRIPTION}" - CreateShortCut "$SMPROGRAMS\${ORG_BIG_NAME}\Uninstall.lnk" "$INSTDIR\Uninstall.exe" "" "$INSTDIR\Uninstall.exe" 0 + File /r "${GCS_BUILD_TREE}\bin\opengl32\opengl32.dll" SectionEnd Section ; create uninstall info @@ -268,7 +262,7 @@ Section ; create uninstall info WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${ORG_BIG_NAME}" "DisplayIcon" '"$INSTDIR\bin\${GCS_SMALL_NAME}.exe"' WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${ORG_BIG_NAME}" "Publisher" "LibrePilot Team" WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${ORG_BIG_NAME}" "URLInfoAbout" "http://www.librepilot.org" - WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${ORG_BIG_NAME}" "HelpLink" "http://wiki.openpilot.org" + WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${ORG_BIG_NAME}" "HelpLink" "https://librepilot.atlassian.net/wiki/display/LPDOC/LibrePilot+Documentation" WriteRegDWORD HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${ORG_BIG_NAME}" "EstimatedSize" 100600 WriteRegDWORD HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${ORG_BIG_NAME}" "NoModify" 1 WriteRegDWORD HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${ORG_BIG_NAME}" "NoRepair" 1 @@ -283,6 +277,7 @@ SectionEnd !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${InSecCore} $(DESC_InSecCore) !insertmacro MUI_DESCRIPTION_TEXT ${InSecPlugins} $(DESC_InSecPlugins) + !insertmacro MUI_DESCRIPTION_TEXT ${InSecLibs} $(DESC_InSecLibs) !insertmacro MUI_DESCRIPTION_TEXT ${InSecResources} $(DESC_InSecResources) !insertmacro MUI_DESCRIPTION_TEXT ${InSecUtilities} $(DESC_InSecUtilities) !insertmacro MUI_DESCRIPTION_TEXT ${InSecDrivers} $(DESC_InSecDrivers) @@ -332,9 +327,12 @@ Section "un.${GCS_BIG_NAME}" UnSecProgram SectionEnd Section "un.Maps cache" UnSecCache - ; Remove maps cache + ; Remove local app data (maps cache, ...) SetShellVarContext current + ; disable status updates as there is potentially a lot of cached files... + SetDetailsPrint none RMDir /r /rebootok "$LOCALAPPDATA\${ORG_BIG_NAME}\${GCS_BIG_NAME}" + SetDetailsPrint both ; Only remove if no other versions have data here RMDir /rebootok "$LOCALAPPDATA\${ORG_BIG_NAME}" SectionEnd diff --git a/package/winx86/gcs.tpl b/package/winx86/gcs.tpl deleted file mode 100644 index 24067201b..000000000 --- a/package/winx86/gcs.tpl +++ /dev/null @@ -1,28 +0,0 @@ -# -# ***************************************************************************** -# -# @file ${OUTFILENAME} -# @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2011-2015. -# @brief Autogenerated NSIS header file, built using template -# ${TEMPLATE} -# -# @see The GNU Public License (GPL) Version 3 -# -# ***************************************************************************** -# - -; Some names, paths and constants -!define ORG_BIG_NAME "${ORG_BIG_NAME}" -!define GCS_BIG_NAME "${GCS_BIG_NAME}" -!define GCS_SMALL_NAME "${GCS_SMALL_NAME}" -!define PACKAGE_LBL "${PACKAGE_LBL}" -!define PACKAGE_NAME "${PACKAGE_NAME}" -!define PACKAGE_SEP "${PACKAGE_SEP}" -!define PACKAGE_DIR "..\..\build\package" -!define FIRMWARE_DIR "firmware" -!define OUT_FILE "$${PACKAGE_NAME}$${PACKAGE_SEP}$${PACKAGE_LBL}$${PACKAGE_SEP}win32.exe" - -; Installer version info -!define PRODUCT_VERSION "0.0.0.0" -!define FILE_VERSION "${TAG_OR_BRANCH}:${HASH8}${DIRTY} ${DATETIME}" -!define BUILD_DESCRIPTION "${PACKAGE_LBL} built from ${ORIGIN}, committed ${DATETIME} as ${HASH}" diff --git a/package/winx86/translations/strings_de.nsh b/package/winx86/translations/strings_de.nsh index 718fe8254..982ca1ade 100644 --- a/package/winx86/translations/strings_de.nsh +++ b/package/winx86/translations/strings_de.nsh @@ -1,7 +1,8 @@ # -# Project: OpenPilot -# NSIS header file for OpenPilot GCS +# Project: LibrePilot +# NSIS header file for LibrePilot GCS # The OpenPilot Team, http://www.openpilot.org, Copyright (C) 2010-2011. +# The LibrePilot Team, http://www.librepilot.org, Copyright (C) 2015-2016. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -27,11 +28,12 @@ LangString DESC_InSecCore ${LANG_GERMAN} "GCS Kernkomponenten (Programm und Bibliotheken)." LangString DESC_InSecPlugins ${LANG_GERMAN} "GCS Plugins (Der Großteil der GCS Funktionalität)." + LangString DESC_InSecLibs ${LANG_GERMAN} "GCS third party libraries." LangString DESC_InSecResources ${LANG_GERMAN} "GCS Resourcen (Diagramme, Ziffernblätter, Kartensymbole, 3d-Modelle, PFD)." LangString DESC_InSecSounds ${LANG_GERMAN} "GCS Sounddateien (benötigt für akustische Ereignisbenachrichtigungen)." LangString DESC_InSecLocalization ${LANG_GERMAN} "GCS Lokalisierung (für unterstützte Sprachen)." - LangString DESC_InSecFirmware ${LANG_GERMAN} "OpenPilot firmware binaries." - LangString DESC_InSecUtilities ${LANG_GERMAN} "OpenPilot Dienstprogramme (Matlab Log Parser)." + LangString DESC_InSecFirmware ${LANG_GERMAN} "LibrePilot firmware binaries." + LangString DESC_InSecUtilities ${LANG_GERMAN} "LibrePilot Dienstprogramme (Matlab Log Parser)." LangString DESC_InSecDrivers ${LANG_GERMAN} "OpenPilot Hardware Treiberdateien (optionaler OpenPilot CDC Treiber)." LangString DESC_InSecInstallDrivers ${LANG_GERMAN} "OpenPilot CDC Treiber (optional)." LangString DESC_InSecInstallOpenGL ${LANG_GERMAN} "Optional OpenGL32.dll for old video cards." @@ -41,6 +43,6 @@ ;-------------------------------- ; Uninstaller section descriptions - LangString DESC_UnSecProgram ${LANG_GERMAN} "OpenPilot GCS Programm inklusive aller Komponenten." - LangString DESC_UnSecCache ${LANG_GERMAN} "OpenPilot GCS zwischengespeichertes Kartenmaterial." - LangString DESC_UnSecConfig ${LANG_GERMAN} "OpenPilot GCS gespeicherte Konfigurationsdaten." + LangString DESC_UnSecProgram ${LANG_GERMAN} "LibrePilot GCS Programm inklusive aller Komponenten." + LangString DESC_UnSecCache ${LANG_GERMAN} "LibrePilot GCS zwischengespeichertes Kartenmaterial." + LangString DESC_UnSecConfig ${LANG_GERMAN} "LibrePilot GCS gespeicherte Konfigurationsdaten." diff --git a/package/winx86/translations/strings_en.nsh b/package/winx86/translations/strings_en.nsh index 42d497f29..c3d4561f8 100644 --- a/package/winx86/translations/strings_en.nsh +++ b/package/winx86/translations/strings_en.nsh @@ -1,7 +1,8 @@ # -# Project: OpenPilot -# NSIS header file for OpenPilot GCS +# Project: LibrePilot +# NSIS header file for LibrePilot GCS # The OpenPilot Team, http://www.openpilot.org, Copyright (C) 2010-2011. +# The LibrePilot Team, http://www.librepilot.org, Copyright (C) 2015-2016. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -27,11 +28,12 @@ LangString DESC_InSecCore ${LANG_ENGLISH} "Core GCS components (executable and libraries)." LangString DESC_InSecPlugins ${LANG_ENGLISH} "GCS plugins (provide most of GCS functionality)." + LangString DESC_InSecLibs ${LANG_ENGLISH} "GCS third party libraries." LangString DESC_InSecResources ${LANG_ENGLISH} "GCS resources (diagrams, dials, mapicons, 3d-models, PFD)." LangString DESC_InSecSounds ${LANG_ENGLISH} "GCS sound files (used for audible event notifications)." LangString DESC_InSecLocalization ${LANG_ENGLISH} "GCS localization (for supported languages)." - LangString DESC_InSecFirmware ${LANG_ENGLISH} "OpenPilot firmware binaries." - LangString DESC_InSecUtilities ${LANG_ENGLISH} "OpenPilot utilities (Matlab log parser)." + LangString DESC_InSecFirmware ${LANG_ENGLISH} "LibrePilot firmware binaries." + LangString DESC_InSecUtilities ${LANG_ENGLISH} "LibrePilot utilities (Matlab log parser)." LangString DESC_InSecDrivers ${LANG_ENGLISH} "OpenPilot hardware driver files (optional OpenPilot CDC driver)." LangString DESC_InSecInstallDrivers ${LANG_ENGLISH} "Optional OpenPilot CDC driver (virtual USB COM port)." LangString DESC_InSecInstallOpenGL ${LANG_ENGLISH} "Optional OpenGL32.dll for old video cards." @@ -41,6 +43,6 @@ ;-------------------------------- ; Uninstaller section descriptions - LangString DESC_UnSecProgram ${LANG_ENGLISH} "OpenPilot GCS application and all components." - LangString DESC_UnSecCache ${LANG_ENGLISH} "OpenPilot GCS cached maps data." - LangString DESC_UnSecConfig ${LANG_ENGLISH} "OpenPilot GCS layout files." + LangString DESC_UnSecProgram ${LANG_ENGLISH} "LibrePilot GCS application and all components." + LangString DESC_UnSecCache ${LANG_ENGLISH} "LibrePilot GCS cached maps data." + LangString DESC_UnSecConfig ${LANG_ENGLISH} "LibrePilot GCS layout files." diff --git a/package/winx86/translations/strings_es.nsh b/package/winx86/translations/strings_es.nsh index bc671b372..b15afe3dd 100644 --- a/package/winx86/translations/strings_es.nsh +++ b/package/winx86/translations/strings_es.nsh @@ -1,7 +1,8 @@ # -# Project: OpenPilot -# NSIS header file for OpenPilot GCS +# Project: LibrePilot +# NSIS header file for LibrePilot GCS # The OpenPilot Team, http://www.openpilot.org, Copyright (C) 2010-2011. +# The LibrePilot Team, http://www.librepilot.org, Copyright (C) 2015-2016. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -27,11 +28,12 @@ LangString DESC_InSecCore ${LANG_SPANISH} "Componentes principales del GCS (librerías y ejecutables)." LangString DESC_InSecPlugins ${LANG_SPANISH} "Plugins del GCS (funcionalidades del GCS)." + LangString DESC_InSecLibs ${LANG_SPANISH} "GCS third party libraries." LangString DESC_InSecResources ${LANG_SPANISH} "Recursos del GCS (diagramas, marcadores, iconos del mapa, modelos, PFD)." LangString DESC_InSecSounds ${LANG_SPANISH} "Archivos de sonido del GCS (usados para los eventos y notificaciones audibles)." LangString DESC_InSecLocalization ${LANG_SPANISH} "Localización GCS (idiomas soportados)." - LangString DESC_InSecFirmware ${LANG_SPANISH} "OpenPilot firmware binaries." - LangString DESC_InSecUtilities ${LANG_SPANISH} "OpenPilot utilities (Matlab log parser)." + LangString DESC_InSecFirmware ${LANG_SPANISH} "LibrePilot firmware binaries." + LangString DESC_InSecUtilities ${LANG_SPANISH} "LibrePilot utilities (Matlab log parser)." LangString DESC_InSecDrivers ${LANG_SPANISH} "OpenPilot hardware driver files (optional OpenPilot CDC driver)." LangString DESC_InSecInstallDrivers ${LANG_SPANISH} "Optional OpenPilot CDC driver (virtual USB COM port)." LangString DESC_InSecInstallOpenGL ${LANG_SPANISH} "Optional OpenGL32.dll for old video cards." @@ -41,6 +43,6 @@ ;-------------------------------- ; Uninstaller section descriptions - LangString DESC_UnSecProgram ${LANG_SPANISH} "Aplicación OpenPilot GCS y todos sus componentes." - LangString DESC_UnSecCache ${LANG_SPANISH} "Datos de mapas en caché del OpenPilot GCS." - LangString DESC_UnSecConfig ${LANG_SPANISH} "Archivos de configuración del OpenPilot GCS." + LangString DESC_UnSecProgram ${LANG_SPANISH} "Aplicación LibrePilot GCS y todos sus componentes." + LangString DESC_UnSecCache ${LANG_SPANISH} "Datos de mapas en caché del LibrePilot GCS." + LangString DESC_UnSecConfig ${LANG_SPANISH} "Archivos de configuración del LibrePilot GCS." diff --git a/package/winx86/translations/strings_fr.nsh b/package/winx86/translations/strings_fr.nsh index 5f9a9434c..0cd4930c9 100644 --- a/package/winx86/translations/strings_fr.nsh +++ b/package/winx86/translations/strings_fr.nsh @@ -1,7 +1,8 @@ # -# Project: OpenPilot -# NSIS header file for OpenPilot GCS +# Project: LibrePilot +# NSIS header file for LibrePilot GCS # The OpenPilot Team, http://www.openpilot.org, Copyright (C) 2010-2011. +# The LibrePilot Team, http://www.librepilot.org, Copyright (C) 2015-2016. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -27,11 +28,12 @@ LangString DESC_InSecCore ${LANG_FRENCH} "Composants GCS principaux (executable et librairies)." LangString DESC_InSecPlugins ${LANG_FRENCH} "Plugins GCS (fournissent la plupart des fonctions)." + LangString DESC_InSecLibs ${LANG_FRENCH} "Librairies tierces GCS (fournissent des fonctions supplémentaires)." LangString DESC_InSecResources ${LANG_FRENCH} "Ressources GCS (diagrammes, cadrans, modèles 3d, PFD)." LangString DESC_InSecSounds ${LANG_FRENCH} "Fichiers son GCS (pour les notifications sonores)." LangString DESC_InSecLocalization ${LANG_FRENCH} "Fichiers de localisation (langues supportées)." - LangString DESC_InSecFirmware ${LANG_FRENCH} "OpenPilot firmware binaries." - LangString DESC_InSecUtilities ${LANG_FRENCH} "OpenPilot utilities (Matlab log parser)." + LangString DESC_InSecFirmware ${LANG_FRENCH} "LibrePilot firmware binaries." + LangString DESC_InSecUtilities ${LANG_FRENCH} "LibrePilot utilities (Matlab log parser)." LangString DESC_InSecDrivers ${LANG_FRENCH} "OpenPilot hardware driver files (optional OpenPilot CDC driver)." LangString DESC_InSecInstallDrivers ${LANG_FRENCH} "Optional OpenPilot CDC driver (virtual USB COM port)." LangString DESC_InSecInstallOpenGL ${LANG_FRENCH} "Optional OpenGL32.dll for old video cards." @@ -41,6 +43,6 @@ ;-------------------------------- ; Uninstaller section descriptions - LangString DESC_UnSecProgram ${LANG_FRENCH} "Application OpenPilot GCS et ses composants." - LangString DESC_UnSecCache ${LANG_FRENCH} "Données en cache OpenPilot GCS." - LangString DESC_UnSecConfig ${LANG_FRENCH} "Fichiers de configuration OpenPilot GCS." + LangString DESC_UnSecProgram ${LANG_FRENCH} "Application LibrePilot GCS et ses composants." + LangString DESC_UnSecCache ${LANG_FRENCH} "Données en cache LibrePilot GCS." + LangString DESC_UnSecConfig ${LANG_FRENCH} "Fichiers de configuration LibrePilot GCS." diff --git a/package/winx86/translations/strings_ru.nsh b/package/winx86/translations/strings_ru.nsh index d161a67f3..ebd20e1d1 100644 --- a/package/winx86/translations/strings_ru.nsh +++ b/package/winx86/translations/strings_ru.nsh @@ -1,7 +1,8 @@ # -# Project: OpenPilot -# NSIS header file for OpenPilot GCS +# Project: LibrePilot +# NSIS header file for LibrePilot GCS # The OpenPilot Team, http://www.openpilot.org, Copyright (C) 2010-2011. +# The LibrePilot Team, http://www.librepilot.org, Copyright (C) 2015-2016. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -27,10 +28,11 @@ LangString DESC_InSecCore ${LANG_RUSSIAN} "Основные компоненты GCS (исполняемый файл и библиотеки)." LangString DESC_InSecPlugins ${LANG_RUSSIAN} "Плагины GCS (обеспечивают большую часть функций GCS)." + LangString DESC_InSecLibs ${LANG_RUSSIAN} "GCS third party libraries." LangString DESC_InSecResources ${LANG_RUSSIAN} "Ресурсы GCS (диаграммы, приборы, пиктограммы, 3d-модели, PFD)." LangString DESC_InSecSounds ${LANG_RUSSIAN} "Звуковые файлы (используются для звуковых уведомлений о событиях)." LangString DESC_InSecLocalization ${LANG_RUSSIAN} "Файлы языковой поддержки (для поддерживаемых языков)." - LangString DESC_InSecFirmware ${LANG_RUSSIAN} "Файлы прошивок OpenPilot." + LangString DESC_InSecFirmware ${LANG_RUSSIAN} "Файлы прошивок LibrePilot." LangString DESC_InSecUtilities ${LANG_RUSSIAN} "Утилиты (конвертор логов для Matlab)." LangString DESC_InSecDrivers ${LANG_RUSSIAN} "Файлы драйверов (опциональный драйвер CDC порта)." LangString DESC_InSecInstallDrivers ${LANG_RUSSIAN} "Опциональный OpenPilot CDC драйвер (виртуальный USB COM порт)." @@ -41,6 +43,6 @@ ;-------------------------------- ; Uninstaller section descriptions - LangString DESC_UnSecProgram ${LANG_RUSSIAN} "Основное приложение OpenPilot GCS и все его компоненты." - LangString DESC_UnSecCache ${LANG_RUSSIAN} "Кешированные карты OpenPilot GCS." - LangString DESC_UnSecConfig ${LANG_RUSSIAN} "Пользовательская конфигурация OpenPilot GCS." + LangString DESC_UnSecProgram ${LANG_RUSSIAN} "Основное приложение LibrePilot GCS и все его компоненты." + LangString DESC_UnSecCache ${LANG_RUSSIAN} "Кешированные карты LibrePilot GCS." + LangString DESC_UnSecConfig ${LANG_RUSSIAN} "Пользовательская конфигурация LibrePilot GCS." diff --git a/package/winx86/translations/strings_zh_CN.nsh b/package/winx86/translations/strings_zh_CN.nsh index 3b012a917..8ee404708 100644 --- a/package/winx86/translations/strings_zh_CN.nsh +++ b/package/winx86/translations/strings_zh_CN.nsh @@ -1,7 +1,8 @@ # -# Project: OpenPilot -# NSIS header file for OpenPilot GCS +# Project: LibrePilot +# NSIS header file for LibrePilot GCS # The OpenPilot Team, http://www.openpilot.org, Copyright (C) 2010-2011. +# The LibrePilot Team, http://www.librepilot.org, Copyright (C) 2015-2016. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -27,11 +28,12 @@ LangString DESC_InSecCore ${LANG_TRADCHINESE} "地面站核心组件 (可执行文件和库文件)." LangString DESC_InSecPlugins ${LANG_TRADCHINESE} "地面站插件(提供地面站大部分功能)." + LangString DESC_InSecLibs ${LANG_TRADCHINESE} "GCS third party libraries." LangString DESC_InSecResources ${LANG_TRADCHINESE} "地面站资源库(图表,地图,模型,PFD(主要飞行数据图))." LangString DESC_InSecSounds ${LANG_TRADCHINESE} "地面站音频文件(用于对于特定事件的提醒)." LangString DESC_InSecLocalization ${LANG_TRADCHINESE} "地面站本土化(适用于它所支持的语言)." - LangString DESC_InSecFirmware ${LANG_TRADCHINESE} "OpenPilot firmware binaries." - LangString DESC_InSecUtilities ${LANG_TRADCHINESE} "OpenPilot utilities (Matlab log parser)." + LangString DESC_InSecFirmware ${LANG_TRADCHINESE} "LibrePilot firmware binaries." + LangString DESC_InSecUtilities ${LANG_TRADCHINESE} "LibrePilot utilities (Matlab log parser)." LangString DESC_InSecDrivers ${LANG_TRADCHINESE} "OpenPilot hardware driver files (optional OpenPilot CDC driver)." LangString DESC_InSecInstallDrivers ${LANG_TRADCHINESE} "Optional OpenPilot CDC driver (virtual USB COM port)." LangString DESC_InSecInstallOpenGL ${LANG_TRADCHINESE} "Optional OpenGL32.dll for old video cards." @@ -41,6 +43,6 @@ ;-------------------------------- ; Uninstaller section descriptions - LangString DESC_UnSecProgram ${LANG_TRADCHINESE} "OpenPilot GCS(地面站)程序及其所有的文件." - LangString DESC_UnSecCache ${LANG_TRADCHINESE} "OpenPilot GCS(地面站)缓存的地图数据." - LangString DESC_UnSecConfig ${LANG_TRADCHINESE} "OpenPilot GCS(地面站)配置文件." + LangString DESC_UnSecProgram ${LANG_TRADCHINESE} "LibrePilot GCS(地面站)程序及其所有的文件." + LangString DESC_UnSecCache ${LANG_TRADCHINESE} "LibrePilot GCS(地面站)缓存的地图数据." + LangString DESC_UnSecConfig ${LANG_TRADCHINESE} "LibrePilot GCS(地面站)配置文件." diff --git a/shared/uavobjectdefinition/actuatorsettings.xml b/shared/uavobjectdefinition/actuatorsettings.xml index 24c1decb0..6aaed72f7 100644 --- a/shared/uavobjectdefinition/actuatorsettings.xml +++ b/shared/uavobjectdefinition/actuatorsettings.xml @@ -2,17 +2,17 @@ Settings for the @ref ActuatorModule that controls the channel assignments for the mixer based on AircraftType - + - - + + - + diff --git a/shared/uavobjectdefinition/altitudefiltersettings.xml b/shared/uavobjectdefinition/altitudefiltersettings.xml index 4bbfa33e5..fc6541083 100644 --- a/shared/uavobjectdefinition/altitudefiltersettings.xml +++ b/shared/uavobjectdefinition/altitudefiltersettings.xml @@ -4,7 +4,7 @@ - + diff --git a/shared/uavobjectdefinition/altitudeholdsettings.xml b/shared/uavobjectdefinition/altitudeholdsettings.xml index fc38bf025..1417620af 100644 --- a/shared/uavobjectdefinition/altitudeholdsettings.xml +++ b/shared/uavobjectdefinition/altitudeholdsettings.xml @@ -6,7 +6,7 @@ - + diff --git a/shared/uavobjectdefinition/attitudesettings.xml b/shared/uavobjectdefinition/attitudesettings.xml index 2a725e679..e45ec747d 100644 --- a/shared/uavobjectdefinition/attitudesettings.xml +++ b/shared/uavobjectdefinition/attitudesettings.xml @@ -7,10 +7,12 @@ - + - - + + + + diff --git a/shared/uavobjectdefinition/auxmagsettings.xml b/shared/uavobjectdefinition/auxmagsettings.xml index fda802031..092e2d596 100644 --- a/shared/uavobjectdefinition/auxmagsettings.xml +++ b/shared/uavobjectdefinition/auxmagsettings.xml @@ -5,8 +5,9 @@ - - + + diff --git a/shared/uavobjectdefinition/barosensor.xml b/shared/uavobjectdefinition/barosensor.xml index 0730f3078..cb6f64beb 100644 --- a/shared/uavobjectdefinition/barosensor.xml +++ b/shared/uavobjectdefinition/barosensor.xml @@ -3,7 +3,7 @@ The raw data from the barometric sensor with pressure, temperature and altitude estimate. - + diff --git a/shared/uavobjectdefinition/callbackinfo.xml b/shared/uavobjectdefinition/callbackinfo.xml index 598e4988a..17d32018e 100644 --- a/shared/uavobjectdefinition/callbackinfo.xml +++ b/shared/uavobjectdefinition/callbackinfo.xml @@ -12,6 +12,7 @@ PathPlanner0 PathPlanner1 ManualControl + DebugLog @@ -25,6 +26,7 @@ PathPlanner0 PathPlanner1 ManualControl + DebugLog @@ -42,6 +44,7 @@ PathPlanner0 PathPlanner1 ManualControl + DebugLog diff --git a/shared/uavobjectdefinition/camerastabsettings.xml b/shared/uavobjectdefinition/camerastabsettings.xml index c0b27c647..0dd6f8c0e 100644 --- a/shared/uavobjectdefinition/camerastabsettings.xml +++ b/shared/uavobjectdefinition/camerastabsettings.xml @@ -13,8 +13,8 @@ - - + + diff --git a/shared/uavobjectdefinition/fixedwingpathfollowersettings.xml b/shared/uavobjectdefinition/fixedwingpathfollowersettings.xml index 8a7e5d064..4e880a11f 100644 --- a/shared/uavobjectdefinition/fixedwingpathfollowersettings.xml +++ b/shared/uavobjectdefinition/fixedwingpathfollowersettings.xml @@ -3,54 +3,43 @@ Settings for the @ref FixedWingPathFollowerModule - - - - - - + + + - - - - + + - - - - + + + + - - + - - - - - - - - + + + + - - - - - - - - - + + + + + + + + + + + diff --git a/shared/uavobjectdefinition/fixedwingpathfollowerstatus.xml b/shared/uavobjectdefinition/fixedwingpathfollowerstatus.xml index fe31830db..26fd4cdfc 100644 --- a/shared/uavobjectdefinition/fixedwingpathfollowerstatus.xml +++ b/shared/uavobjectdefinition/fixedwingpathfollowerstatus.xml @@ -4,7 +4,7 @@ - + diff --git a/shared/uavobjectdefinition/flightbatterysettings.xml b/shared/uavobjectdefinition/flightbatterysettings.xml index a7fa762f4..b5a81a869 100644 --- a/shared/uavobjectdefinition/flightbatterysettings.xml +++ b/shared/uavobjectdefinition/flightbatterysettings.xml @@ -7,7 +7,7 @@ - + diff --git a/shared/uavobjectdefinition/flightmodesettings.xml b/shared/uavobjectdefinition/flightmodesettings.xml index 162f96d6c..394d814a6 100644 --- a/shared/uavobjectdefinition/flightmodesettings.xml +++ b/shared/uavobjectdefinition/flightmodesettings.xml @@ -2,62 +2,62 @@ Settings to control arming and flight mode - + @@ -66,7 +66,7 @@ units="" type="enum" elements="6" - options="Manual,Stabilized1,Stabilized2,Stabilized3,Stabilized4,Stabilized5,Stabilized6,PositionHold,CourseLock,VelocityRoam,HomeLeash,AbsolutePosition,ReturnToBase,Land,PathPlanner,POI,AutoCruise,AutoTakeoff" + options="Manual,Stabilized1,Stabilized2,Stabilized3,Stabilized4,Stabilized5,Stabilized6,PositionHold,CourseLock,VelocityRoam,HomeLeash,AbsolutePosition,ReturnToBase,Land,PathPlanner,POI,AutoCruise,AutoTakeoff,AutoTune" defaultvalue="Stabilized1,Stabilized2,Stabilized3,Stabilized4,Stabilized5,Stabilized6" limits="%NE:POI:AutoCruise; \ %NE:POI:AutoCruise; \ @@ -75,18 +75,27 @@ %NE:POI:AutoCruise; \ %NE:POI:AutoCruise;" /> - + + - + + + diff --git a/shared/uavobjectdefinition/flightstatus.xml b/shared/uavobjectdefinition/flightstatus.xml index 7703f38ca..c758d84ff 100644 --- a/shared/uavobjectdefinition/flightstatus.xml +++ b/shared/uavobjectdefinition/flightstatus.xml @@ -4,13 +4,16 @@ - + + + + - + Stabilization PathFollower diff --git a/shared/uavobjectdefinition/gpspositionsensor.xml b/shared/uavobjectdefinition/gpspositionsensor.xml index 54034a717..566678a4b 100644 --- a/shared/uavobjectdefinition/gpspositionsensor.xml +++ b/shared/uavobjectdefinition/gpspositionsensor.xml @@ -12,8 +12,8 @@ - - + + diff --git a/shared/uavobjectdefinition/gpssettings.xml b/shared/uavobjectdefinition/gpssettings.xml index 57f02f492..0e0be02c9 100644 --- a/shared/uavobjectdefinition/gpssettings.xml +++ b/shared/uavobjectdefinition/gpssettings.xml @@ -1,7 +1,7 @@ GPS Module specific settings - + + diff --git a/shared/uavobjectdefinition/gyrosensor.xml b/shared/uavobjectdefinition/gyrosensor.xml index 3107f952e..d51efd1a1 100644 --- a/shared/uavobjectdefinition/gyrosensor.xml +++ b/shared/uavobjectdefinition/gyrosensor.xml @@ -1,10 +1,11 @@ Calibrated sensor data from 3 axis gyroscope in deg/s. - - - + + + + diff --git a/shared/uavobjectdefinition/gyrostate.xml b/shared/uavobjectdefinition/gyrostate.xml index a4d497578..35e7c1da8 100644 --- a/shared/uavobjectdefinition/gyrostate.xml +++ b/shared/uavobjectdefinition/gyrostate.xml @@ -1,9 +1,10 @@ The filtered rotation sensor data. - - - + + + + diff --git a/shared/uavobjectdefinition/homelocation.xml b/shared/uavobjectdefinition/homelocation.xml index 64527c7e8..36f113bf0 100644 --- a/shared/uavobjectdefinition/homelocation.xml +++ b/shared/uavobjectdefinition/homelocation.xml @@ -1,7 +1,7 @@ HomeLocation setting which contains the constants to translate from longitude and latitude to NED reference frame. Automatically set by @ref GPSModule after acquiring a 3D lock. Used by @ref AHRSCommsModule. - + diff --git a/shared/uavobjectdefinition/hwsettings.xml b/shared/uavobjectdefinition/hwsettings.xml index 9d705d2cc..a9d7b5877 100644 --- a/shared/uavobjectdefinition/hwsettings.xml +++ b/shared/uavobjectdefinition/hwsettings.xml @@ -2,29 +2,35 @@ Selection of optional hardware configurations. - - - + + - - - - - + + + + + - - - + limits="%0905NE:PPM+PWM:PPM+Telemetry:PPM+DebugConsole:PPM+ComBridge:PPM+MSP:PPM+MAVLink:PPM+GPS:Telemetry:DebugConsole:ComBridge:MSP:MAVLink:GPS;"/> + + + + + + + - + + + - + Settings to indicate how to decode receiver input by @ref ManualControlModule. + options="PWM,PPM,DSM (MainPort),DSM (FlexiPort),DSM (RcvrPort),S.Bus,EX.Bus,HoTT,SRXL,IBus,GCS,OPLink,OpenLRS,None" defaultvalue="None"/> A receiver channel group carried over the OPLink radio. - + diff --git a/shared/uavobjectdefinition/oplinksettings.xml b/shared/uavobjectdefinition/oplinksettings.xml index ac631616c..dbf450360 100644 --- a/shared/uavobjectdefinition/oplinksettings.xml +++ b/shared/uavobjectdefinition/oplinksettings.xml @@ -1,18 +1,36 @@ OPLink configurations options. - - - - + + - - - + + + + + + + + + + + + + + + + + + + + + + + diff --git a/shared/uavobjectdefinition/oplinkstatus.xml b/shared/uavobjectdefinition/oplinkstatus.xml index 5a225ff28..fdb3d5053 100644 --- a/shared/uavobjectdefinition/oplinkstatus.xml +++ b/shared/uavobjectdefinition/oplinkstatus.xml @@ -18,18 +18,20 @@ - + - + + + - + diff --git a/shared/uavobjectdefinition/receiveractivity.xml b/shared/uavobjectdefinition/receiveractivity.xml index 8724b3f51..927966da0 100644 --- a/shared/uavobjectdefinition/receiveractivity.xml +++ b/shared/uavobjectdefinition/receiveractivity.xml @@ -2,7 +2,7 @@ Monitors which receiver channels have been active within the last second. diff --git a/shared/uavobjectdefinition/revocalibration.xml b/shared/uavobjectdefinition/revocalibration.xml index a23342e2d..52161644a 100644 --- a/shared/uavobjectdefinition/revocalibration.xml +++ b/shared/uavobjectdefinition/revocalibration.xml @@ -6,7 +6,7 @@ defaultvalue="1,0,0,0,1,0,0,0,1"/> - + diff --git a/shared/uavobjectdefinition/revosettings.xml b/shared/uavobjectdefinition/revosettings.xml index 0d926f711..116b842cf 100644 --- a/shared/uavobjectdefinition/revosettings.xml +++ b/shared/uavobjectdefinition/revosettings.xml @@ -3,7 +3,6 @@ Settings for the revo to control the algorithm and what is updated - + diff --git a/shared/uavobjectdefinition/stabilizationsettings.xml b/shared/uavobjectdefinition/stabilizationsettings.xml index ca16ccd68..ebec36efb 100644 --- a/shared/uavobjectdefinition/stabilizationsettings.xml +++ b/shared/uavobjectdefinition/stabilizationsettings.xml @@ -15,7 +15,7 @@ - + @@ -32,22 +32,24 @@ - + - + - + + + diff --git a/shared/uavobjectdefinition/stabilizationsettingsbank1.xml b/shared/uavobjectdefinition/stabilizationsettingsbank1.xml index 7d8842006..a7bd0c105 100644 --- a/shared/uavobjectdefinition/stabilizationsettingsbank1.xml +++ b/shared/uavobjectdefinition/stabilizationsettingsbank1.xml @@ -18,9 +18,11 @@ - + - + + + diff --git a/shared/uavobjectdefinition/stabilizationsettingsbank2.xml b/shared/uavobjectdefinition/stabilizationsettingsbank2.xml index 8c1d7554e..fdf0ad5c3 100644 --- a/shared/uavobjectdefinition/stabilizationsettingsbank2.xml +++ b/shared/uavobjectdefinition/stabilizationsettingsbank2.xml @@ -18,9 +18,11 @@ - + - + + + diff --git a/shared/uavobjectdefinition/stabilizationsettingsbank3.xml b/shared/uavobjectdefinition/stabilizationsettingsbank3.xml index ad7ac0e41..056b9ef30 100644 --- a/shared/uavobjectdefinition/stabilizationsettingsbank3.xml +++ b/shared/uavobjectdefinition/stabilizationsettingsbank3.xml @@ -18,9 +18,11 @@ - + - + + + diff --git a/shared/uavobjectdefinition/stabilizationstatus.xml b/shared/uavobjectdefinition/stabilizationstatus.xml index 5126ed9c1..4f78fc8f3 100644 --- a/shared/uavobjectdefinition/stabilizationstatus.xml +++ b/shared/uavobjectdefinition/stabilizationstatus.xml @@ -3,7 +3,7 @@ Contains status information to control submodules for stabilization. - + Roll Pitch @@ -11,7 +11,7 @@ Thrust - + Roll Pitch diff --git a/shared/uavobjectdefinition/systemalarms.xml b/shared/uavobjectdefinition/systemalarms.xml index ba4cd24de..7cf9d55ed 100644 --- a/shared/uavobjectdefinition/systemalarms.xml +++ b/shared/uavobjectdefinition/systemalarms.xml @@ -37,6 +37,7 @@ + diff --git a/shared/uavobjectdefinition/systemidentsettings.xml b/shared/uavobjectdefinition/systemidentsettings.xml new file mode 100644 index 000000000..8f4928898 --- /dev/null +++ b/shared/uavobjectdefinition/systemidentsettings.xml @@ -0,0 +1,83 @@ + + + The input to and results of the PID tuning. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/shared/uavobjectdefinition/systemidentstate.xml b/shared/uavobjectdefinition/systemidentstate.xml new file mode 100644 index 000000000..b0269c201 --- /dev/null +++ b/shared/uavobjectdefinition/systemidentstate.xml @@ -0,0 +1,20 @@ + + + Used for logging PID tuning. + + + + + + + + + + + + + + + + + diff --git a/shared/uavobjectdefinition/systemstats.xml b/shared/uavobjectdefinition/systemstats.xml index 4de866eb2..8d4163a99 100644 --- a/shared/uavobjectdefinition/systemstats.xml +++ b/shared/uavobjectdefinition/systemstats.xml @@ -6,6 +6,8 @@ + + diff --git a/shared/uavobjectdefinition/taskinfo.xml b/shared/uavobjectdefinition/taskinfo.xml index 893660676..1d7a2f4f1 100644 --- a/shared/uavobjectdefinition/taskinfo.xml +++ b/shared/uavobjectdefinition/taskinfo.xml @@ -31,6 +31,9 @@ GPS OSDGen + UAVOMSPBridge + AutoTune + UAVOMAVLinkBridge @@ -63,6 +66,9 @@ GPS OSDGen + UAVOMSPBridge + AutoTune + UAVOMAVLinkBridge @@ -99,6 +105,9 @@ GPS OSDGen + UAVOMSPBridge + AutoTune + UAVOMAVLinkBridge diff --git a/shared/uavobjectdefinition/txpidsettings.xml b/shared/uavobjectdefinition/txpidsettings.xml index 3bcc81067..332fd81cd 100644 --- a/shared/uavobjectdefinition/txpidsettings.xml +++ b/shared/uavobjectdefinition/txpidsettings.xml @@ -30,7 +30,7 @@ - + diff --git a/shared/uavobjectdefinition/vtolpathfollowersettings.xml b/shared/uavobjectdefinition/vtolpathfollowersettings.xml index 06ccb3e1d..0fd22f4ce 100644 --- a/shared/uavobjectdefinition/vtolpathfollowersettings.xml +++ b/shared/uavobjectdefinition/vtolpathfollowersettings.xml @@ -11,9 +11,9 @@ - - - + + + diff --git a/tool_install.sh b/tool_install.sh index 1ad5244f4..670b35730 100755 --- a/tool_install.sh +++ b/tool_install.sh @@ -76,12 +76,7 @@ function download_file #2 The output directory function zip_extract { - if [ "$uname" = Windows ] - then - 7za.exe x -o"$2" "$1" - else - unzip "$1" -d "$2" - fi + unzip -q "$1" -d "$2" } ## Extracts a 7zip file